master
c 421 lines 12.5 KB
Raw
1 /*
2 * QEMU ADB keyboard support
3 *
4 * Copyright (c) 2004 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25 #include "qemu/osdep.h"
26 #include "hw/input/adb.h"
27 #include "migration/vmstate.h"
28 #include "qemu/module.h"
29 #include "standard-headers/linux/input-event-codes.h"
30 #include "ui/input.h"
31 #include "hw/input/adb-keys.h"
32 #include "adb-internal.h"
33 #include "trace.h"
34 #include "qom/object.h"
35
36 OBJECT_DECLARE_TYPE(KBDState, ADBKeyboardClass, ADB_KEYBOARD)
37
38 struct KBDState {
39 /*< private >*/
40 ADBDevice parent_obj;
41 /*< public >*/
42
43 QemuInputHandlerState *hs;
44 uint8_t data[128];
45 int rptr, wptr, count;
46 };
47
48
49 struct ADBKeyboardClass {
50 /*< private >*/
51 ADBDeviceClass parent_class;
52 /*< public >*/
53
54 DeviceRealize parent_realize;
55 DeviceUnrealize parent_unrealize;
56 };
57
58 /* The adb keyboard doesn't have every key imaginable */
59 #define NO_KEY 0xff
60
61 int linux_to_adb_keycode[] = {
62 /* Make sure future additions are automatically set to NO_KEY */
63 [0 ... KEY_MAX] = NO_KEY,
64
65 [KEY_LEFTSHIFT] = ADB_KEY_LEFT_SHIFT,
66 [KEY_RIGHTSHIFT] = ADB_KEY_RIGHT_SHIFT,
67 [KEY_LEFTALT] = ADB_KEY_LEFT_OPTION,
68 [KEY_RIGHTALT] = ADB_KEY_RIGHT_OPTION,
69 [KEY_LEFTCTRL] = ADB_KEY_LEFT_CONTROL,
70 [KEY_RIGHTCTRL] = ADB_KEY_RIGHT_CONTROL,
71 [KEY_LEFTMETA] = ADB_KEY_COMMAND,
72 [KEY_RIGHTMETA] = ADB_KEY_COMMAND,
73 [KEY_SPACE] = ADB_KEY_SPACEBAR,
74
75 [KEY_ESC] = ADB_KEY_ESC,
76 [KEY_1] = ADB_KEY_1,
77 [KEY_2] = ADB_KEY_2,
78 [KEY_3] = ADB_KEY_3,
79 [KEY_4] = ADB_KEY_4,
80 [KEY_5] = ADB_KEY_5,
81 [KEY_6] = ADB_KEY_6,
82 [KEY_7] = ADB_KEY_7,
83 [KEY_8] = ADB_KEY_8,
84 [KEY_9] = ADB_KEY_9,
85 [KEY_0] = ADB_KEY_0,
86 [KEY_MINUS] = ADB_KEY_MINUS,
87 [KEY_EQUAL] = ADB_KEY_EQUAL,
88 [KEY_BACKSPACE] = ADB_KEY_DELETE,
89 [KEY_TAB] = ADB_KEY_TAB,
90 [KEY_Q] = ADB_KEY_Q,
91 [KEY_W] = ADB_KEY_W,
92 [KEY_E] = ADB_KEY_E,
93 [KEY_R] = ADB_KEY_R,
94 [KEY_T] = ADB_KEY_T,
95 [KEY_Y] = ADB_KEY_Y,
96 [KEY_U] = ADB_KEY_U,
97 [KEY_I] = ADB_KEY_I,
98 [KEY_O] = ADB_KEY_O,
99 [KEY_P] = ADB_KEY_P,
100 [KEY_LEFTBRACE] = ADB_KEY_LEFT_BRACKET,
101 [KEY_RIGHTBRACE] = ADB_KEY_RIGHT_BRACKET,
102 [KEY_ENTER] = ADB_KEY_RETURN,
103 [KEY_A] = ADB_KEY_A,
104 [KEY_S] = ADB_KEY_S,
105 [KEY_D] = ADB_KEY_D,
106 [KEY_F] = ADB_KEY_F,
107 [KEY_G] = ADB_KEY_G,
108 [KEY_H] = ADB_KEY_H,
109 [KEY_J] = ADB_KEY_J,
110 [KEY_K] = ADB_KEY_K,
111 [KEY_L] = ADB_KEY_L,
112 [KEY_SEMICOLON] = ADB_KEY_SEMICOLON,
113 [KEY_APOSTROPHE] = ADB_KEY_APOSTROPHE,
114 [KEY_GRAVE] = ADB_KEY_GRAVE_ACCENT,
115 [KEY_BACKSLASH] = ADB_KEY_BACKSLASH,
116 [KEY_Z] = ADB_KEY_Z,
117 [KEY_X] = ADB_KEY_X,
118 [KEY_C] = ADB_KEY_C,
119 [KEY_V] = ADB_KEY_V,
120 [KEY_B] = ADB_KEY_B,
121 [KEY_N] = ADB_KEY_N,
122 [KEY_M] = ADB_KEY_M,
123 [KEY_COMMA] = ADB_KEY_COMMA,
124 [KEY_DOT] = ADB_KEY_PERIOD,
125 [KEY_SLASH] = ADB_KEY_FORWARD_SLASH,
126 [KEY_CAPSLOCK] = ADB_KEY_CAPS_LOCK,
127
128 [KEY_F1] = ADB_KEY_F1,
129 [KEY_F2] = ADB_KEY_F2,
130 [KEY_F3] = ADB_KEY_F3,
131 [KEY_F4] = ADB_KEY_F4,
132 [KEY_F5] = ADB_KEY_F5,
133 [KEY_F6] = ADB_KEY_F6,
134 [KEY_F7] = ADB_KEY_F7,
135 [KEY_F8] = ADB_KEY_F8,
136 [KEY_F9] = ADB_KEY_F9,
137 [KEY_F10] = ADB_KEY_F10,
138 [KEY_F11] = ADB_KEY_F11,
139 [KEY_F12] = ADB_KEY_F12,
140 [KEY_SYSRQ] = ADB_KEY_F13,
141 [KEY_SCROLLLOCK] = ADB_KEY_F14,
142 [KEY_PAUSE] = ADB_KEY_F15,
143
144 [KEY_NUMLOCK] = ADB_KEY_KP_CLEAR,
145 [KEY_KPEQUAL] = ADB_KEY_KP_EQUAL,
146 [KEY_KPSLASH] = ADB_KEY_KP_DIVIDE,
147 [KEY_KPASTERISK] = ADB_KEY_KP_MULTIPLY,
148 [KEY_KPMINUS] = ADB_KEY_KP_SUBTRACT,
149 [KEY_KPPLUS] = ADB_KEY_KP_PLUS,
150 [KEY_KPENTER] = ADB_KEY_KP_ENTER,
151 [KEY_KPDOT] = ADB_KEY_KP_PERIOD,
152 [KEY_KP0] = ADB_KEY_KP_0,
153 [KEY_KP1] = ADB_KEY_KP_1,
154 [KEY_KP2] = ADB_KEY_KP_2,
155 [KEY_KP3] = ADB_KEY_KP_3,
156 [KEY_KP4] = ADB_KEY_KP_4,
157 [KEY_KP5] = ADB_KEY_KP_5,
158 [KEY_KP6] = ADB_KEY_KP_6,
159 [KEY_KP7] = ADB_KEY_KP_7,
160 [KEY_KP8] = ADB_KEY_KP_8,
161 [KEY_KP9] = ADB_KEY_KP_9,
162
163 [KEY_UP] = ADB_KEY_UP,
164 [KEY_DOWN] = ADB_KEY_DOWN,
165 [KEY_LEFT] = ADB_KEY_LEFT,
166 [KEY_RIGHT] = ADB_KEY_RIGHT,
167
168 [KEY_HELP] = ADB_KEY_HELP,
169 [KEY_INSERT] = ADB_KEY_HELP,
170 [KEY_DELETE] = ADB_KEY_FORWARD_DELETE,
171 [KEY_HOME] = ADB_KEY_HOME,
172 [KEY_END] = ADB_KEY_END,
173 [KEY_PAGEUP] = ADB_KEY_PAGE_UP,
174 [KEY_PAGEDOWN] = ADB_KEY_PAGE_DOWN,
175
176 [KEY_POWER] = ADB_KEY_POWER
177 };
178
179 static void adb_kbd_put_keycode(void *opaque, int keycode)
180 {
181 KBDState *s = opaque;
182
183 if (s->count < sizeof(s->data)) {
184 s->data[s->wptr] = keycode;
185 if (++s->wptr == sizeof(s->data)) {
186 s->wptr = 0;
187 }
188 s->count++;
189 }
190 }
191
192 static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
193 {
194 KBDState *s = ADB_KEYBOARD(d);
195 int keycode;
196
197 if (s->count == 0) {
198 return 0;
199 }
200 keycode = s->data[s->rptr];
201 s->rptr++;
202 if (s->rptr == sizeof(s->data)) {
203 s->rptr = 0;
204 }
205 s->count--;
206 /*
207 * The power key is the only two byte value key, so it is a special case.
208 * Since 0x7f is not a used keycode for ADB we overload it to indicate the
209 * power button when we're storing keycodes in our internal buffer, and
210 * expand it out to two bytes when we send to the guest.
211 */
212 if (keycode == 0x7f) {
213 obuf[0] = 0x7f;
214 obuf[1] = 0x7f;
215 } else {
216 obuf[0] = keycode;
217 /* NOTE: the power key key-up is the two byte sequence 0xff 0xff;
218 * otherwise we could in theory send a second keycode in the second
219 * byte, but choose not to bother.
220 */
221 obuf[1] = 0xff;
222 }
223
224 return 2;
225 }
226
227 static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
228 const uint8_t *buf, int len)
229 {
230 KBDState *s = ADB_KEYBOARD(d);
231 int cmd, reg, olen;
232
233 if ((buf[0] & 0x0f) == ADB_FLUSH) {
234 /* flush keyboard fifo */
235 s->wptr = s->rptr = s->count = 0;
236 return 0;
237 }
238
239 cmd = buf[0] & 0xc;
240 reg = buf[0] & 0x3;
241 olen = 0;
242 switch (cmd) {
243 case ADB_WRITEREG:
244 trace_adb_device_kbd_writereg(reg, buf[1]);
245 switch (reg) {
246 case 2:
247 /* LED status */
248 break;
249 case 3:
250 switch (buf[2]) {
251 case ADB_CMD_SELF_TEST:
252 break;
253 case ADB_CMD_CHANGE_ID:
254 case ADB_CMD_CHANGE_ID_AND_ACT:
255 case ADB_CMD_CHANGE_ID_AND_ENABLE:
256 d->devaddr = buf[1] & 0xf;
257 trace_adb_device_kbd_request_change_addr(d->devaddr);
258 break;
259 default:
260 d->devaddr = buf[1] & 0xf;
261 /*
262 * we support handlers:
263 * 1: Apple Standard Keyboard
264 * 2: Apple Extended Keyboard (LShift = RShift)
265 * 3: Apple Extended Keyboard (LShift != RShift)
266 */
267 if (buf[2] == 1 || buf[2] == 2 || buf[2] == 3) {
268 d->handler = buf[2];
269 }
270
271 trace_adb_device_kbd_request_change_addr_and_handler(
272 d->devaddr, d->handler);
273 break;
274 }
275 }
276 break;
277 case ADB_READREG:
278 switch (reg) {
279 case 0:
280 olen = adb_kbd_poll(d, obuf);
281 break;
282 case 1:
283 break;
284 case 2:
285 obuf[0] = 0x00; /* XXX: check this */
286 obuf[1] = 0x07; /* led status */
287 olen = 2;
288 break;
289 case 3:
290 obuf[0] = d->devaddr;
291 obuf[1] = d->handler;
292 olen = 2;
293 break;
294 }
295 trace_adb_device_kbd_readreg(reg, obuf[0], obuf[1]);
296 break;
297 }
298 return olen;
299 }
300
301 static bool adb_kbd_has_data(ADBDevice *d)
302 {
303 KBDState *s = ADB_KEYBOARD(d);
304
305 return s->count > 0;
306 }
307
308 /* This is where keyboard events enter this file */
309 static void adb_keyboard_event(DeviceState *dev, QemuConsole *src,
310 QemuInputEvent *evt)
311 {
312 KBDState *s = (KBDState *)dev;
313 int keycode;
314
315 if (evt->key.key >= ARRAY_SIZE(linux_to_adb_keycode)) {
316 return;
317 }
318 /* FIXME: take handler into account when translating evt->key.key */
319 keycode = linux_to_adb_keycode[evt->key.key];
320 if (keycode == NO_KEY) { /* We don't want to send this to the guest */
321 trace_adb_device_kbd_no_key();
322 return;
323 }
324 if (evt->key.down == false) { /* if key release event */
325 keycode = keycode | 0x80; /* create keyboard break code */
326 }
327
328 adb_kbd_put_keycode(s, keycode);
329 }
330
331 static const VMStateDescription vmstate_adb_kbd = {
332 .name = "adb_kbd",
333 .version_id = 2,
334 .minimum_version_id = 2,
335 .fields = (const VMStateField[]) {
336 VMSTATE_STRUCT(parent_obj, KBDState, 0, vmstate_adb_device, ADBDevice),
337 VMSTATE_BUFFER(data, KBDState),
338 VMSTATE_INT32(rptr, KBDState),
339 VMSTATE_INT32(wptr, KBDState),
340 VMSTATE_INT32(count, KBDState),
341 VMSTATE_END_OF_LIST()
342 }
343 };
344
345 static void adb_kbd_reset(DeviceState *dev)
346 {
347 ADBDevice *d = ADB_DEVICE(dev);
348 KBDState *s = ADB_KEYBOARD(dev);
349
350 d->handler = 1;
351 d->devaddr = ADB_DEVID_KEYBOARD;
352 memset(s->data, 0, sizeof(s->data));
353 s->rptr = 0;
354 s->wptr = 0;
355 s->count = 0;
356 }
357
358 static const QemuInputHandler adb_keyboard_handler = {
359 .name = "QEMU ADB Keyboard",
360 .mask = INPUT_EVENT_MASK_KEY,
361 .event = adb_keyboard_event,
362 };
363
364 static void adb_kbd_realizefn(DeviceState *dev, Error **errp)
365 {
366 KBDState *s = ADB_KEYBOARD(dev);
367 ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev);
368
369 akc->parent_realize(dev, errp);
370 s->hs = qemu_input_handler_register(dev, &adb_keyboard_handler);
371 }
372
373 static void adb_kbd_unrealizefn(DeviceState *dev)
374 {
375 KBDState *s = ADB_KEYBOARD(dev);
376 ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev);
377
378 g_clear_pointer(&s->hs, qemu_input_handler_unregister);
379 akc->parent_unrealize(dev);
380 }
381
382 static void adb_kbd_initfn(Object *obj)
383 {
384 ADBDevice *d = ADB_DEVICE(obj);
385
386 d->devaddr = ADB_DEVID_KEYBOARD;
387 }
388
389 static void adb_kbd_class_init(ObjectClass *oc, const void *data)
390 {
391 DeviceClass *dc = DEVICE_CLASS(oc);
392 ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc);
393 ADBKeyboardClass *akc = ADB_KEYBOARD_CLASS(oc);
394
395 device_class_set_parent_realize(dc, adb_kbd_realizefn,
396 &akc->parent_realize);
397 device_class_set_parent_unrealize(dc, adb_kbd_unrealizefn,
398 &akc->parent_unrealize);
399 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
400
401 adc->devreq = adb_kbd_request;
402 adc->devhasdata = adb_kbd_has_data;
403 device_class_set_legacy_reset(dc, adb_kbd_reset);
404 dc->vmsd = &vmstate_adb_kbd;
405 }
406
407 static const TypeInfo adb_kbd_type_info = {
408 .name = TYPE_ADB_KEYBOARD,
409 .parent = TYPE_ADB_DEVICE,
410 .instance_size = sizeof(KBDState),
411 .instance_init = adb_kbd_initfn,
412 .class_init = adb_kbd_class_init,
413 .class_size = sizeof(ADBKeyboardClass),
414 };
415
416 static void adb_kbd_register_types(void)
417 {
418 type_register_static(&adb_kbd_type_info);
419 }
420
421 type_init(adb_kbd_register_types)