fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/arch/macplus/keyboard.c *
7 * Created: 2007-11-20 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2007-2014 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include "main.h"
24#include "keyboard.h"
25
26#include <stdlib.h>
27
28#include <lib/log.h>
29#include <lib/sysdep.h>
30
31#include <drivers/video/keys.h>
32
33
34static mac_kbd_map_t key_map_us[] = {
35 { PCE_KEY_BACKQUOTE, 1, { 0x65 }, 1, { 0xe5 } },
36 { PCE_KEY_1, 1, { 0x25 }, 1, { 0xa5 } },
37 { PCE_KEY_2, 1, { 0x27 }, 1, { 0xa7 } },
38 { PCE_KEY_3, 1, { 0x29 }, 1, { 0xa9 } },
39 { PCE_KEY_4, 1, { 0x2b }, 1, { 0xab } },
40 { PCE_KEY_5, 1, { 0x2f }, 1, { 0xaf } },
41 { PCE_KEY_6, 1, { 0x2d }, 1, { 0xad } },
42 { PCE_KEY_7, 1, { 0x35 }, 1, { 0xb5 } },
43 { PCE_KEY_8, 1, { 0x39 }, 1, { 0xb9 } },
44 { PCE_KEY_9, 1, { 0x33 }, 1, { 0xb3 } },
45 { PCE_KEY_0, 1, { 0x3b }, 1, { 0xbb } },
46 { PCE_KEY_MINUS, 1, { 0x37 }, 1, { 0xb7 } },
47 { PCE_KEY_EQUAL, 1, { 0x31 }, 1, { 0xb1 } },
48 { PCE_KEY_BACKSPACE, 1, { 0x67 }, 1, { 0xe7 } },
49 { PCE_KEY_TAB, 1, { 0x61 }, 1, { 0xe1 } },
50 { PCE_KEY_Q, 1, { 0x19 }, 1, { 0x99 } },
51 { PCE_KEY_W, 1, { 0x1b }, 1, { 0x9b } },
52 { PCE_KEY_E, 1, { 0x1d }, 1, { 0x9d } },
53 { PCE_KEY_R, 1, { 0x1f }, 1, { 0x9f } },
54 { PCE_KEY_T, 1, { 0x23 }, 1, { 0xa3 } },
55 { PCE_KEY_Y, 1, { 0x21 }, 1, { 0xa1 } },
56 { PCE_KEY_U, 1, { 0x41 }, 1, { 0xc1 } },
57 { PCE_KEY_I, 1, { 0x45 }, 1, { 0xc5 } },
58 { PCE_KEY_O, 1, { 0x3f }, 1, { 0xbf } },
59 { PCE_KEY_P, 1, { 0x47 }, 1, { 0xc7 } },
60 { PCE_KEY_LBRACKET, 1, { 0x43 }, 1, { 0xc3 } },
61 { PCE_KEY_RBRACKET, 1, { 0x3d }, 1, { 0xbd } },
62 { PCE_KEY_BACKSLASH, 1, { 0x55 }, 1, { 0xd5 } },
63 { PCE_KEY_RETURN, 1, { 0x49 }, 1, { 0xc9 } },
64 { PCE_KEY_CAPSLOCK, 1, { 0x73 }, 1, { 0xf3 } },
65 { PCE_KEY_A, 1, { 0x01 }, 1, { 0x81 } },
66 { PCE_KEY_S, 1, { 0x03 }, 1, { 0x83 } },
67 { PCE_KEY_D, 1, { 0x05 }, 1, { 0x85 } },
68 { PCE_KEY_F, 1, { 0x07 }, 1, { 0x87 } },
69 { PCE_KEY_G, 1, { 0x0b }, 1, { 0x8b } },
70 { PCE_KEY_H, 1, { 0x09 }, 1, { 0x89 } },
71 { PCE_KEY_J, 1, { 0x4d }, 1, { 0xcd } },
72 { PCE_KEY_K, 1, { 0x51 }, 1, { 0xd1 } },
73 { PCE_KEY_L, 1, { 0x4b }, 1, { 0xcb } },
74 { PCE_KEY_SEMICOLON, 1, { 0x53 }, 1, { 0xd3 } },
75 { PCE_KEY_QUOTE, 1, { 0x4f }, 1, { 0xcf } },
76 { PCE_KEY_LSHIFT, 1, { 0x71 }, 1, { 0xf1 } },
77 { PCE_KEY_RSHIFT, 1, { 0x71 }, 1, { 0xf1 } },
78 { PCE_KEY_Z, 1, { 0x0d }, 1, { 0x8d } },
79 { PCE_KEY_X, 1, { 0x0f }, 1, { 0x8f } },
80 { PCE_KEY_C, 1, { 0x11 }, 1, { 0x91 } },
81 { PCE_KEY_V, 1, { 0x13 }, 1, { 0x93 } },
82 { PCE_KEY_B, 1, { 0x17 }, 1, { 0x97 } },
83 { PCE_KEY_N, 1, { 0x5b }, 1, { 0xdb } },
84 { PCE_KEY_M, 1, { 0x5d }, 1, { 0xdd } },
85 { PCE_KEY_COMMA, 1, { 0x57 }, 1, { 0xd7 } },
86 { PCE_KEY_PERIOD, 1, { 0x5f }, 1, { 0xdf } },
87 { PCE_KEY_SLASH, 1, { 0x59 }, 1, { 0xd9 } },
88 { PCE_KEY_LCTRL, 1, { 0x75 }, 1, { 0xf5 } },
89 { PCE_KEY_LSUPER, 1, { 0x6f }, 1, { 0xef } },
90 { PCE_KEY_RCTRL, 1, { 0x75 }, 1, { 0xf5 } },
91 { PCE_KEY_LALT, 1, { 0x75 }, 1, { 0xf5 } },
92 { PCE_KEY_RALT, 1, { 0x69 }, 1, { 0xe9 } },
93 { PCE_KEY_MODE, 1, { 0x75 }, 1, { 0xf5 } },
94 { PCE_KEY_SPACE, 1, { 0x63 }, 1, { 0xe3 } },
95 { PCE_KEY_NUMLOCK, 2, { 0x79, 0x0f }, 2, { 0x79, 0x8f } },
96 { PCE_KEY_KP_SLASH, 3, { 0x71, 0x79, 0x1b }, 3, { 0x79, 0x9b, 0xf1 } },
97 { PCE_KEY_KP_STAR, 3, { 0x71, 0x79, 0x05 }, 3, { 0x79, 0x85, 0xf1 } },
98 { PCE_KEY_KP_MINUS, 2, { 0x79, 0x1d }, 2, { 0x79, 0x9d } },
99 { PCE_KEY_KP_7, 2, { 0x79, 0x33 }, 2, { 0x79, 0xb3 } },
100 { PCE_KEY_KP_8, 2, { 0x79, 0x37 }, 2, { 0x79, 0xb7 } },
101 { PCE_KEY_KP_9, 2, { 0x79, 0x39 }, 2, { 0x79, 0xb9 } },
102 { PCE_KEY_KP_PLUS, 3, { 0x71, 0x79, 0x0d }, 3, { 0x79, 0x8d, 0xf1 } },
103 { PCE_KEY_KP_4, 2, { 0x79, 0x2d }, 2, { 0x79, 0xad } },
104 { PCE_KEY_KP_5, 2, { 0x79, 0x2f }, 2, { 0x79, 0xaf } },
105 { PCE_KEY_KP_6, 2, { 0x79, 0x31 }, 2, { 0x79, 0xb1 } },
106 { PCE_KEY_KP_1, 2, { 0x79, 0x27 }, 2, { 0x79, 0xa7 } },
107 { PCE_KEY_KP_2, 2, { 0x79, 0x29 }, 2, { 0x79, 0xa9 } },
108 { PCE_KEY_KP_3, 2, { 0x79, 0x2b }, 2, { 0x79, 0xab } },
109 { PCE_KEY_KP_ENTER, 2, { 0x79, 0x19 }, 2, { 0x79, 0x99 } },
110 { PCE_KEY_KP_0, 2, { 0x79, 0x25 }, 2, { 0x79, 0xa5 } },
111 { PCE_KEY_KP_PERIOD, 2, { 0x79, 0x03 }, 2, { 0x79, 0x83 } },
112 { PCE_KEY_UP, 2, { 0x79, 0x1b }, 2, { 0x79, 0x9b } },
113 { PCE_KEY_LEFT, 2, { 0x79, 0x0d }, 2, { 0x79, 0x8d } },
114 { PCE_KEY_RIGHT, 2, { 0x79, 0x05 }, 2, { 0x79, 0x85 } },
115 { PCE_KEY_DOWN, 2, { 0x79, 0x11 }, 2, { 0x79, 0x91 } },
116
117 { PCE_KEY_HOME, 2, { 0x79, 0x67 }, 2, { 0x79, 0xe7 } },
118 { PCE_KEY_END, 2, { 0x79, 0x6f }, 2, { 0x79, 0xef } },
119 { PCE_KEY_PAGEUP, 2, { 0x79, 0x69 }, 2, { 0x79, 0xe9 } },
120 { PCE_KEY_PAGEDN, 2, { 0x79, 0x73 }, 2, { 0x79, 0xf3 } },
121 { PCE_KEY_INS, 2, { 0x79, 0x65 }, 2, { 0x79, 0x65 } },
122 { PCE_KEY_DEL, 2, { 0x79, 0x6b }, 2, { 0x79, 0xeb } },
123
124 { PCE_KEY_NONE, 0, { 0 }, 0, { 0 } }
125};
126
127static mac_kbd_map_t key_map_intl[] = {
128 { PCE_KEY_BACKQUOTE, 1, { 0x65 }, 1, { 0xe5 } },
129 { PCE_KEY_1, 1, { 0x27 }, 1, { 0xa7 } },
130 { PCE_KEY_2, 1, { 0x27 }, 1, { 0xa7 } },
131 { PCE_KEY_3, 1, { 0x29 }, 1, { 0xa9 } },
132 { PCE_KEY_4, 1, { 0x2b }, 1, { 0xab } },
133 { PCE_KEY_5, 1, { 0x2f }, 1, { 0xaf } },
134 { PCE_KEY_6, 1, { 0x2d }, 1, { 0xad } },
135 { PCE_KEY_7, 1, { 0x35 }, 1, { 0xb5 } },
136 { PCE_KEY_8, 1, { 0x39 }, 1, { 0xb9 } },
137 { PCE_KEY_9, 1, { 0x33 }, 1, { 0xb3 } },
138 { PCE_KEY_0, 1, { 0x3b }, 1, { 0xbb } },
139 { PCE_KEY_MINUS, 1, { 0x37 }, 1, { 0xb7 } },
140 { PCE_KEY_EQUAL, 1, { 0x31 }, 1, { 0xb1 } },
141 { PCE_KEY_BACKSPACE, 1, { 0x67 }, 1, { 0xe7 } },
142 { PCE_KEY_TAB, 1, { 0x61 }, 1, { 0xe1 } },
143 { PCE_KEY_Q, 1, { 0x19 }, 1, { 0x99 } },
144 { PCE_KEY_W, 1, { 0x1b }, 1, { 0x9b } },
145 { PCE_KEY_E, 1, { 0x1d }, 1, { 0x9d } },
146 { PCE_KEY_R, 1, { 0x1f }, 1, { 0x9f } },
147 { PCE_KEY_T, 1, { 0x23 }, 1, { 0xa3 } },
148 { PCE_KEY_Y, 1, { 0x21 }, 1, { 0xa1 } },
149 { PCE_KEY_U, 1, { 0x41 }, 1, { 0xc1 } },
150 { PCE_KEY_I, 1, { 0x45 }, 1, { 0xc5 } },
151 { PCE_KEY_O, 1, { 0x3f }, 1, { 0xbf } },
152 { PCE_KEY_P, 1, { 0x47 }, 1, { 0xc7 } },
153 { PCE_KEY_LBRACKET, 1, { 0x43 }, 1, { 0xc3 } },
154 { PCE_KEY_RBRACKET, 1, { 0x3d }, 1, { 0xbd } },
155 { PCE_KEY_RETURN, 1, { 0x55 }, 1, { 0xd5 } },
156 { PCE_KEY_CAPSLOCK, 1, { 0x73 }, 1, { 0xf3 } },
157 { PCE_KEY_A, 1, { 0x01 }, 1, { 0x81 } },
158 { PCE_KEY_S, 1, { 0x03 }, 1, { 0x83 } },
159 { PCE_KEY_D, 1, { 0x05 }, 1, { 0x85 } },
160 { PCE_KEY_F, 1, { 0x07 }, 1, { 0x87 } },
161 { PCE_KEY_G, 1, { 0x0b }, 1, { 0x8b } },
162 { PCE_KEY_H, 1, { 0x09 }, 1, { 0x89 } },
163 { PCE_KEY_J, 1, { 0x4d }, 1, { 0xcd } },
164 { PCE_KEY_K, 1, { 0x51 }, 1, { 0xd1 } },
165 { PCE_KEY_L, 1, { 0x4b }, 1, { 0xcb } },
166 { PCE_KEY_SEMICOLON, 1, { 0x53 }, 1, { 0xd3 } },
167 { PCE_KEY_QUOTE, 1, { 0x4f }, 1, { 0xcf } },
168 { PCE_KEY_BACKSLASH, 1, { 0x49 }, 1, { 0xc9 } },
169 { PCE_KEY_LSHIFT, 1, { 0x71 }, 1, { 0xf1 } },
170 { PCE_KEY_RSHIFT, 1, { 0x71 }, 1, { 0xf1 } },
171 { PCE_KEY_LESS, 1, { 0x0d }, 1, { 0x8d } },
172 { PCE_KEY_Z, 1, { 0x0f }, 1, { 0x8f } },
173 { PCE_KEY_X, 1, { 0x11 }, 1, { 0x91 } },
174 { PCE_KEY_C, 1, { 0x13 }, 1, { 0x93 } },
175 { PCE_KEY_V, 1, { 0x17 }, 1, { 0x97 } },
176 { PCE_KEY_B, 1, { 0x5b }, 1, { 0xdb } },
177 { PCE_KEY_N, 1, { 0x5d }, 1, { 0xdd } },
178 { PCE_KEY_M, 1, { 0x57 }, 1, { 0xd7 } },
179 { PCE_KEY_COMMA, 1, { 0x5f }, 1, { 0xdf } },
180 { PCE_KEY_PERIOD, 1, { 0x59 }, 1, { 0xd9 } },
181 { PCE_KEY_SLASH, 1, { 0x15 }, 1, { 0x95 } },
182 { PCE_KEY_LCTRL, 1, { 0x75 }, 1, { 0xf5 } },
183 { PCE_KEY_RCTRL, 1, { 0x75 }, 1, { 0xf5 } },
184 { PCE_KEY_LALT, 1, { 0x6f }, 1, { 0xef } },
185 { PCE_KEY_RALT, 1, { 0x63 }, 1, { 0xe3 } },
186 { PCE_KEY_MODE, 1, { 0x75 }, 1, { 0xf5 } },
187 { PCE_KEY_SPACE, 1, { 0x69 }, 1, { 0xe9 } },
188 { PCE_KEY_NUMLOCK, 2, { 0x79, 0x0f }, 2, { 0x79, 0x8f } },
189 { PCE_KEY_KP_SLASH, 3, { 0x71, 0x79, 0x1b }, 3, { 0x79, 0x9b, 0xf1 } },
190 { PCE_KEY_KP_STAR, 3, { 0x71, 0x79, 0x05 }, 3, { 0x79, 0x85, 0xf1 } },
191 { PCE_KEY_KP_MINUS, 2, { 0x79, 0x1d }, 2, { 0x79, 0x9d } },
192 { PCE_KEY_KP_7, 2, { 0x79, 0x33 }, 2, { 0x79, 0xb3 } },
193 { PCE_KEY_KP_8, 2, { 0x79, 0x37 }, 2, { 0x79, 0xb7 } },
194 { PCE_KEY_KP_9, 2, { 0x79, 0x39 }, 2, { 0x79, 0xb9 } },
195 { PCE_KEY_KP_PLUS, 3, { 0x71, 0x79, 0x0d }, 3, { 0x79, 0x8d, 0xf1 } },
196 { PCE_KEY_KP_4, 2, { 0x79, 0x2d }, 2, { 0x79, 0xad } },
197 { PCE_KEY_KP_5, 2, { 0x79, 0x2f }, 2, { 0x79, 0xaf } },
198 { PCE_KEY_KP_6, 2, { 0x79, 0x31 }, 2, { 0x79, 0xb1 } },
199 { PCE_KEY_KP_1, 2, { 0x79, 0x27 }, 2, { 0x79, 0xa7 } },
200 { PCE_KEY_KP_2, 2, { 0x79, 0x29 }, 2, { 0x79, 0xa9 } },
201 { PCE_KEY_KP_3, 2, { 0x79, 0x2b }, 2, { 0x79, 0xab } },
202 { PCE_KEY_KP_ENTER, 2, { 0x79, 0x19 }, 2, { 0x79, 0x99 } },
203 { PCE_KEY_KP_0, 2, { 0x79, 0x25 }, 2, { 0x79, 0xa5 } },
204 { PCE_KEY_KP_PERIOD, 2, { 0x79, 0x03 }, 2, { 0x79, 0x83 } },
205 { PCE_KEY_UP, 2, { 0x79, 0x1b }, 2, { 0x79, 0x9b } },
206 { PCE_KEY_LEFT, 2, { 0x79, 0x0d }, 2, { 0x79, 0x8d } },
207 { PCE_KEY_RIGHT, 2, { 0x79, 0x05 }, 2, { 0x79, 0x85 } },
208 { PCE_KEY_DOWN, 2, { 0x79, 0x11 }, 2, { 0x79, 0x91 } },
209
210 { PCE_KEY_HOME, 2, { 0x79, 0x67 }, 2, { 0x79, 0xe7 } },
211 { PCE_KEY_END, 2, { 0x79, 0x6f }, 2, { 0x79, 0xef } },
212 { PCE_KEY_PAGEUP, 2, { 0x79, 0x69 }, 2, { 0x79, 0xe9 } },
213 { PCE_KEY_PAGEDN, 2, { 0x79, 0x73 }, 2, { 0x79, 0xf3 } },
214 { PCE_KEY_INS, 2, { 0x79, 0x65 }, 2, { 0x79, 0xe5 } },
215 { PCE_KEY_DEL, 2, { 0x79, 0x6b }, 2, { 0x79, 0xeb } },
216
217 { PCE_KEY_NONE, 0, { 0x00 }, 0, { 0x00 } }
218};
219
220/* keypad to motion, motion keys to keypad */
221static mac_kbd_map_t key_fix_keypad1[] = {
222 { PCE_KEY_KP_7, 2, { 0x79, 0x67 }, 2, { 0x79, 0xe7 } },
223 { PCE_KEY_KP_8, 2, { 0x79, 0x1b }, 2, { 0x79, 0x9b } },
224 { PCE_KEY_KP_9, 2, { 0x79, 0x69 }, 2, { 0x79, 0xe9 } },
225 { PCE_KEY_KP_4, 2, { 0x79, 0x0d }, 2, { 0x79, 0x8d } },
226 { PCE_KEY_KP_5, 2, { 0x79, 0x19 }, 2, { 0x79, 0x99 } },
227 { PCE_KEY_KP_6, 2, { 0x79, 0x05 }, 2, { 0x79, 0x85 } },
228 { PCE_KEY_KP_1, 2, { 0x79, 0x6f }, 2, { 0x79, 0xef } },
229 { PCE_KEY_KP_2, 2, { 0x79, 0x11 }, 2, { 0x79, 0x91 } },
230 { PCE_KEY_KP_3, 2, { 0x79, 0x73 }, 2, { 0x79, 0xf3 } },
231 { PCE_KEY_KP_0, 2, { 0x79, 0x65 }, 2, { 0x79, 0x65 } },
232 { PCE_KEY_KP_PERIOD, 2, { 0x79, 0x6b }, 2, { 0x79, 0xeb } },
233 { PCE_KEY_KP_ENTER, 1, { 0x49 }, 1, { 0xc9 } },
234
235 { PCE_KEY_HOME, 2, { 0x79, 0x33 }, 2, { 0x79, 0xb3 } },
236 { PCE_KEY_UP, 2, { 0x79, 0x37 }, 2, { 0x79, 0xb7 } },
237 { PCE_KEY_PAGEUP, 2, { 0x79, 0x39 }, 2, { 0x79, 0xb9 } },
238 { PCE_KEY_LEFT, 2, { 0x79, 0x2d }, 2, { 0x79, 0xad } },
239 { PCE_KEY_RIGHT, 2, { 0x79, 0x31 }, 2, { 0x79, 0xb1 } },
240 { PCE_KEY_END, 2, { 0x79, 0x27 }, 2, { 0x79, 0xa7 } },
241 { PCE_KEY_DOWN, 2, { 0x79, 0x29 }, 2, { 0x79, 0xa9 } },
242 { PCE_KEY_PAGEDN, 2, { 0x79, 0x2b }, 2, { 0x79, 0xab } },
243 { PCE_KEY_INS, 2, { 0x79, 0x25 }, 2, { 0x79, 0xa5 } },
244 { PCE_KEY_DEL, 2, { 0x79, 0x03 }, 2, { 0x79, 0x83 } },
245
246 { PCE_KEY_NONE, 0, { 0 }, 0, { 0 } }
247};
248
249/* keypad to keypad, motion to motion */
250static mac_kbd_map_t key_fix_keypad2[] = {
251 { PCE_KEY_KP_7, 2, { 0x79, 0x33 }, 2, { 0x79, 0xb3 } },
252 { PCE_KEY_KP_8, 2, { 0x79, 0x37 }, 2, { 0x79, 0xb7 } },
253 { PCE_KEY_KP_9, 2, { 0x79, 0x39 }, 2, { 0x79, 0xb9 } },
254 { PCE_KEY_KP_4, 2, { 0x79, 0x2d }, 2, { 0x79, 0xad } },
255 { PCE_KEY_KP_5, 2, { 0x79, 0x2f }, 2, { 0x79, 0xaf } },
256 { PCE_KEY_KP_6, 2, { 0x79, 0x31 }, 2, { 0x79, 0xb1 } },
257 { PCE_KEY_KP_1, 2, { 0x79, 0x27 }, 2, { 0x79, 0xa7 } },
258 { PCE_KEY_KP_2, 2, { 0x79, 0x29 }, 2, { 0x79, 0xa9 } },
259 { PCE_KEY_KP_3, 2, { 0x79, 0x2b }, 2, { 0x79, 0xab } },
260 { PCE_KEY_KP_0, 2, { 0x79, 0x25 }, 2, { 0x79, 0xa5 } },
261 { PCE_KEY_KP_PERIOD, 2, { 0x79, 0x03 }, 2, { 0x79, 0x83 } },
262 { PCE_KEY_KP_ENTER, 2, { 0x79, 0x19 }, 2, { 0x79, 0x99 } },
263
264 { PCE_KEY_HOME, 2, { 0x79, 0x67 }, 2, { 0x79, 0xe7 } },
265 { PCE_KEY_UP, 2, { 0x79, 0x1b }, 2, { 0x79, 0x9b } },
266 { PCE_KEY_PAGEUP, 2, { 0x79, 0x69 }, 2, { 0x79, 0xe9 } },
267 { PCE_KEY_LEFT, 2, { 0x79, 0x0d }, 2, { 0x79, 0x8d } },
268 { PCE_KEY_RIGHT, 2, { 0x79, 0x05 }, 2, { 0x79, 0x85 } },
269 { PCE_KEY_END, 2, { 0x79, 0x6f }, 2, { 0x79, 0xef } },
270 { PCE_KEY_DOWN, 2, { 0x79, 0x11 }, 2, { 0x79, 0x91 } },
271 { PCE_KEY_PAGEDN, 2, { 0x79, 0x73 }, 2, { 0x79, 0xf3 } },
272 { PCE_KEY_INS, 2, { 0x79, 0x65 }, 2, { 0x79, 0x65 } },
273 { PCE_KEY_DEL, 2, { 0x79, 0x6b }, 2, { 0x79, 0xeb } },
274
275 { PCE_KEY_NONE, 0, { 0 }, 0, { 0 } }
276};
277
278
279static
280void mac_kbd_fix_map (mac_kbd_map_t *dst, const mac_kbd_map_t *src)
281{
282 mac_kbd_map_t *tmp;
283
284 while (src->pcekey != PCE_KEY_NONE) {
285 tmp = dst;
286 while (tmp->pcekey != PCE_KEY_NONE) {
287 if (tmp->pcekey == src->pcekey) {
288 *tmp = *src;
289 break;
290 }
291
292 tmp += 1;
293 }
294
295 src += 1;
296 }
297}
298
299void mac_kbd_init (mac_kbd_t *kbd)
300{
301 kbd->set_data_ext = NULL;
302 kbd->set_data = NULL;
303
304 kbd->set_intr_ext = NULL;
305 kbd->set_intr = NULL;
306
307 kbd->data = 0;
308 kbd->timeout = 0;
309
310 kbd->send_byte = 0;
311
312 kbd->buf_i = 0;
313 kbd->buf_n = 0;
314
315 kbd->model = 0;
316
317 kbd->keypad_mode = 0;
318
319 kbd->keymap = key_map_us;
320}
321
322void mac_kbd_free (mac_kbd_t *kbd)
323{
324}
325
326mac_kbd_t *mac_kbd_new (void)
327{
328 mac_kbd_t *kbd;
329
330 kbd = malloc (sizeof (mac_kbd_t));
331
332 if (kbd == NULL) {
333 return (NULL);
334 }
335
336 mac_kbd_init (kbd);
337
338 return (kbd);
339}
340
341void mac_kbd_del (mac_kbd_t *kbd)
342{
343 if (kbd != NULL) {
344 mac_kbd_free (kbd);
345 free (kbd);
346 }
347}
348
349void mac_kbd_set_data_fct (mac_kbd_t *kbd, void *ext, void *fct)
350{
351 kbd->set_data_ext = ext;
352 kbd->set_data = fct;
353}
354
355void mac_kbd_set_intr_fct (mac_kbd_t *kbd, void *ext, void *fct)
356{
357 kbd->set_intr_ext = ext;
358 kbd->set_intr = fct;
359}
360
361int mac_kbd_set_model (mac_kbd_t *kbd, unsigned model, int intl)
362{
363 kbd->model = model;
364
365 if (intl) {
366 kbd->keymap = key_map_intl;
367 }
368 else {
369 kbd->keymap = key_map_us;
370 }
371
372 return (0);
373}
374
375void mac_kbd_set_keypad_mode (mac_kbd_t *kbd, int motion)
376{
377 if (motion) {
378 mac_kbd_fix_map (kbd->keymap, key_fix_keypad1);
379 kbd->keypad_mode = 0;
380 }
381 else {
382 mac_kbd_fix_map (kbd->keymap, key_fix_keypad2);
383 kbd->keypad_mode = 1;
384 }
385}
386
387static
388void mac_kbd_set_data_out (mac_kbd_t *kbd, unsigned char val)
389{
390 if (kbd->set_data != NULL) {
391 pce_get_interval_us (&kbd->last_data_set);
392 kbd->set_data (kbd->set_data_ext, val);
393 }
394}
395
396static
397void mac_kbd_buf_set_byte (mac_kbd_t *kbd, unsigned char val)
398{
399 unsigned i;
400
401 if (kbd->buf_n >= MAC_KBD_BUFSIZE) {
402 return;
403 }
404
405 i = (kbd->buf_i + kbd->buf_n) % MAC_KBD_BUFSIZE;
406
407 kbd->buf[i] = val;
408
409 kbd->buf_n += 1;
410}
411
412static
413void mac_kbd_set_sequence (mac_kbd_t *kbd, unsigned char *buf, unsigned cnt)
414{
415 unsigned i;
416
417 for (i = 0; i < cnt; i++) {
418 mac_kbd_buf_set_byte (kbd, buf[i]);
419 }
420}
421
422void mac_kbd_set_key (mac_kbd_t *kbd, unsigned event, pce_key_t key)
423{
424 mac_kbd_map_t *map;
425
426#ifdef DEBUG_KBD
427 mac_log_deb ("kbd: set key: %u %u\n", event, (unsigned) key);
428#endif
429
430 if (key == PCE_KEY_F1) {
431 key = PCE_KEY_LCTRL;
432 }
433 else if (key == PCE_KEY_F2) {
434 key = PCE_KEY_LALT;
435 }
436
437 map = kbd->keymap;
438
439 while (map->pcekey != PCE_KEY_NONE) {
440 if (map->pcekey == key) {
441 break;
442 }
443
444 map += 1;
445 }
446
447 if (map->pcekey == PCE_KEY_NONE) {
448 const char *str;
449
450 str = pce_key_to_string (key);
451
452 pce_log (MSG_INF, "ignoring pce key: %04x (%s)\n",
453 (unsigned) key,
454 (str != NULL) ? str : "<none>"
455 );
456
457 return;
458 }
459
460 switch (event) {
461 case PCE_KEY_EVENT_DOWN:
462 mac_kbd_set_sequence (kbd, map->down, map->down_cnt);
463 break;
464
465 case PCE_KEY_EVENT_UP:
466 mac_kbd_set_sequence (kbd, map->up, map->up_cnt);
467 break;
468 }
469}
470
471void mac_kbd_set_uint8 (mac_kbd_t *kbd, unsigned char val)
472{
473 switch (val) {
474 case 0x10: /* inquiry, must be acked within 0.5 seconds */
475 kbd->timeout = MAC_CPU_CLOCK / 4;
476 kbd->send_byte = 1;
477 break;
478
479 case 0x14: /* instant */
480 kbd->timeout = 0;
481 kbd->send_byte = 1;
482 break;
483
484 case 0x16: /* model number */
485#ifdef DEBUG_KBD
486 mac_log_deb ("kbd: command: model number (%02X)\n", val);
487#endif
488 kbd->buf_i = 0;
489 kbd->buf_n = 1;
490 kbd->buf[0] = ((kbd->model & 7) << 1) | 0x01;
491 kbd->timeout = 0;
492 kbd->send_byte = 1;
493 break;
494
495 default:
496 mac_log_deb ("kbd: unknown command (%02X)\n", val);
497 break;
498 }
499}
500
501void mac_kbd_set_data (mac_kbd_t *kbd, unsigned char val)
502{
503 kbd->data = val;
504}
505
506void mac_kbd_clock (mac_kbd_t *kbd, unsigned cnt)
507{
508 unsigned char val;
509 unsigned long now_us;
510
511 if (kbd->data == 0) {
512 return;
513 }
514
515 if (kbd->send_byte == 0) {
516 return;
517 }
518
519 pce_get_interval_us (&now_us);
520 if (now_us - kbd->last_data_set < 1000)
521 return;
522
523 if (kbd->buf_n > 0) {
524 val = kbd->buf[kbd->buf_i];
525
526#ifdef DEBUG_KBD
527 mac_log_deb ("kbd: send response (%02X)\n", val);
528#endif
529
530 mac_kbd_set_data_out (kbd, val);
531
532 kbd->buf_i = (kbd->buf_i + 1) % MAC_KBD_BUFSIZE;
533 kbd->buf_n -= 1;
534
535 kbd->send_byte = 0;
536 kbd->timeout = 0;
537 }
538 else {
539 if (cnt < kbd->timeout) {
540 kbd->timeout -= cnt;
541 }
542 else {
543 mac_kbd_set_data_out (kbd, 0x7b);
544 kbd->send_byte = 0;
545 }
546 }
547}