xref: /openbmc/qemu/hw/input/hid.c (revision 90ce6e26)
1 /*
2  * QEMU HID devices
3  *
4  * Copyright (c) 2005 Fabrice Bellard
5  * Copyright (c) 2007 OpenMoko, Inc.  (andrew@openedhand.com)
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  */
25 #include "qemu/osdep.h"
26 #include "hw/hw.h"
27 #include "ui/console.h"
28 #include "qemu/timer.h"
29 #include "hw/input/hid.h"
30 
31 #define HID_USAGE_ERROR_ROLLOVER        0x01
32 #define HID_USAGE_POSTFAIL              0x02
33 #define HID_USAGE_ERROR_UNDEFINED       0x03
34 
35 /* Indices are QEMU keycodes, values are from HID Usage Table.  Indices
36  * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d.  */
37 static const uint8_t hid_usage_keys[0x100] = {
38     0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
39     0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
40     0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
41     0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
42     0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
43     0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
44     0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
45     0xe2, 0x2c, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
46     0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
47     0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
48     0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x64, 0x44,
49     0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
50     0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
51     0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
52     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53     0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
54 
55     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58     0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
59     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61     0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
62     0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63     0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
64     0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
65     0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
66     0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x00, 0x00,
67     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 };
72 
73 bool hid_has_events(HIDState *hs)
74 {
75     return hs->n > 0 || hs->idle_pending;
76 }
77 
78 static void hid_idle_timer(void *opaque)
79 {
80     HIDState *hs = opaque;
81 
82     hs->idle_pending = true;
83     hs->event(hs);
84 }
85 
86 static void hid_del_idle_timer(HIDState *hs)
87 {
88     if (hs->idle_timer) {
89         timer_del(hs->idle_timer);
90         timer_free(hs->idle_timer);
91         hs->idle_timer = NULL;
92     }
93 }
94 
95 void hid_set_next_idle(HIDState *hs)
96 {
97     if (hs->idle) {
98         uint64_t expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
99                                get_ticks_per_sec() * hs->idle * 4 / 1000;
100         if (!hs->idle_timer) {
101             hs->idle_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, hid_idle_timer, hs);
102         }
103         timer_mod_ns(hs->idle_timer, expire_time);
104     } else {
105         hid_del_idle_timer(hs);
106     }
107 }
108 
109 static void hid_pointer_event(DeviceState *dev, QemuConsole *src,
110                               InputEvent *evt)
111 {
112     static const int bmap[INPUT_BUTTON__MAX] = {
113         [INPUT_BUTTON_LEFT]   = 0x01,
114         [INPUT_BUTTON_RIGHT]  = 0x02,
115         [INPUT_BUTTON_MIDDLE] = 0x04,
116     };
117     HIDState *hs = (HIDState *)dev;
118     HIDPointerEvent *e;
119 
120     assert(hs->n < QUEUE_LENGTH);
121     e = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK];
122 
123     switch (evt->type) {
124     case INPUT_EVENT_KIND_REL:
125         if (evt->u.rel->axis == INPUT_AXIS_X) {
126             e->xdx += evt->u.rel->value;
127         } else if (evt->u.rel->axis == INPUT_AXIS_Y) {
128             e->ydy += evt->u.rel->value;
129         }
130         break;
131 
132     case INPUT_EVENT_KIND_ABS:
133         if (evt->u.rel->axis == INPUT_AXIS_X) {
134             e->xdx = evt->u.rel->value;
135         } else if (evt->u.rel->axis == INPUT_AXIS_Y) {
136             e->ydy = evt->u.rel->value;
137         }
138         break;
139 
140     case INPUT_EVENT_KIND_BTN:
141         if (evt->u.btn->down) {
142             e->buttons_state |= bmap[evt->u.btn->button];
143             if (evt->u.btn->button == INPUT_BUTTON_WHEELUP) {
144                 e->dz--;
145             } else if (evt->u.btn->button == INPUT_BUTTON_WHEELDOWN) {
146                 e->dz++;
147             }
148         } else {
149             e->buttons_state &= ~bmap[evt->u.btn->button];
150         }
151         break;
152 
153     default:
154         /* keep gcc happy */
155         break;
156     }
157 
158 }
159 
160 static void hid_pointer_sync(DeviceState *dev)
161 {
162     HIDState *hs = (HIDState *)dev;
163     HIDPointerEvent *prev, *curr, *next;
164     bool event_compression = false;
165 
166     if (hs->n == QUEUE_LENGTH-1) {
167         /*
168          * Queue full.  We are losing information, but we at least
169          * keep track of most recent button state.
170          */
171         return;
172     }
173 
174     prev = &hs->ptr.queue[(hs->head + hs->n - 1) & QUEUE_MASK];
175     curr = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK];
176     next = &hs->ptr.queue[(hs->head + hs->n + 1) & QUEUE_MASK];
177 
178     if (hs->n > 0) {
179         /*
180          * No button state change between previous and current event
181          * (and previous wasn't seen by the guest yet), so there is
182          * motion information only and we can combine the two event
183          * into one.
184          */
185         if (curr->buttons_state == prev->buttons_state) {
186             event_compression = true;
187         }
188     }
189 
190     if (event_compression) {
191         /* add current motion to previous, clear current */
192         if (hs->kind == HID_MOUSE) {
193             prev->xdx += curr->xdx;
194             curr->xdx = 0;
195             prev->ydy += curr->ydy;
196             curr->ydy = 0;
197         } else {
198             prev->xdx = curr->xdx;
199             prev->ydy = curr->ydy;
200         }
201         prev->dz += curr->dz;
202         curr->dz = 0;
203     } else {
204         /* prepate next (clear rel, copy abs + btns) */
205         if (hs->kind == HID_MOUSE) {
206             next->xdx = 0;
207             next->ydy = 0;
208         } else {
209             next->xdx = curr->xdx;
210             next->ydy = curr->ydy;
211         }
212         next->dz = 0;
213         next->buttons_state = curr->buttons_state;
214         /* make current guest visible, notify guest */
215         hs->n++;
216         hs->event(hs);
217     }
218 }
219 
220 static void hid_keyboard_event(DeviceState *dev, QemuConsole *src,
221                                InputEvent *evt)
222 {
223     HIDState *hs = (HIDState *)dev;
224     int scancodes[3], i, count;
225     int slot;
226 
227     count = qemu_input_key_value_to_scancode(evt->u.key->key,
228                                              evt->u.key->down,
229                                              scancodes);
230     if (hs->n + count > QUEUE_LENGTH) {
231         fprintf(stderr, "usb-kbd: warning: key event queue full\n");
232         return;
233     }
234     for (i = 0; i < count; i++) {
235         slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++;
236         hs->kbd.keycodes[slot] = scancodes[i];
237     }
238     hs->event(hs);
239 }
240 
241 static void hid_keyboard_process_keycode(HIDState *hs)
242 {
243     uint8_t hid_code, index, key;
244     int i, keycode, slot;
245 
246     if (hs->n == 0) {
247         return;
248     }
249     slot = hs->head & QUEUE_MASK; QUEUE_INCR(hs->head); hs->n--;
250     keycode = hs->kbd.keycodes[slot];
251 
252     key = keycode & 0x7f;
253     index = key | ((hs->kbd.modifiers & (1 << 8)) >> 1);
254     hid_code = hid_usage_keys[index];
255     hs->kbd.modifiers &= ~(1 << 8);
256 
257     switch (hid_code) {
258     case 0x00:
259         return;
260 
261     case 0xe0:
262         assert(key == 0x1d);
263         if (hs->kbd.modifiers & (1 << 9)) {
264             /* The hid_codes for the 0xe1/0x1d scancode sequence are 0xe9/0xe0.
265              * Here we're processing the second hid_code.  By dropping bit 9
266              * and setting bit 8, the scancode after 0x1d will access the
267              * second half of the table.
268              */
269             hs->kbd.modifiers ^= (1 << 8) | (1 << 9);
270             return;
271         }
272         /* fall through to process Ctrl_L */
273     case 0xe1 ... 0xe7:
274         /* Ctrl_L/Ctrl_R, Shift_L/Shift_R, Alt_L/Alt_R, Win_L/Win_R.
275          * Handle releases here, or fall through to process presses.
276          */
277         if (keycode & (1 << 7)) {
278             hs->kbd.modifiers &= ~(1 << (hid_code & 0x0f));
279             return;
280         }
281         /* fall through */
282     case 0xe8 ... 0xe9:
283         /* USB modifiers are just 1 byte long.  Bits 8 and 9 of
284          * hs->kbd.modifiers implement a state machine that detects the
285          * 0xe0 and 0xe1/0x1d sequences.  These bits do not follow the
286          * usual rules where bit 7 marks released keys; they are cleared
287          * elsewhere in the function as the state machine dictates.
288          */
289         hs->kbd.modifiers |= 1 << (hid_code & 0x0f);
290         return;
291 
292     case 0xea ... 0xef:
293         abort();
294 
295     default:
296         break;
297     }
298 
299     if (keycode & (1 << 7)) {
300         for (i = hs->kbd.keys - 1; i >= 0; i--) {
301             if (hs->kbd.key[i] == hid_code) {
302                 hs->kbd.key[i] = hs->kbd.key[-- hs->kbd.keys];
303                 hs->kbd.key[hs->kbd.keys] = 0x00;
304                 break;
305             }
306         }
307         if (i < 0) {
308             return;
309         }
310     } else {
311         for (i = hs->kbd.keys - 1; i >= 0; i--) {
312             if (hs->kbd.key[i] == hid_code) {
313                 break;
314             }
315         }
316         if (i < 0) {
317             if (hs->kbd.keys < sizeof(hs->kbd.key)) {
318                 hs->kbd.key[hs->kbd.keys++] = hid_code;
319             }
320         } else {
321             return;
322         }
323     }
324 }
325 
326 static inline int int_clamp(int val, int vmin, int vmax)
327 {
328     if (val < vmin) {
329         return vmin;
330     } else if (val > vmax) {
331         return vmax;
332     } else {
333         return val;
334     }
335 }
336 
337 void hid_pointer_activate(HIDState *hs)
338 {
339     if (!hs->ptr.mouse_grabbed) {
340         qemu_input_handler_activate(hs->s);
341         hs->ptr.mouse_grabbed = 1;
342     }
343 }
344 
345 int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
346 {
347     int dx, dy, dz, l;
348     int index;
349     HIDPointerEvent *e;
350 
351     hs->idle_pending = false;
352 
353     hid_pointer_activate(hs);
354 
355     /* When the buffer is empty, return the last event.  Relative
356        movements will all be zero.  */
357     index = (hs->n ? hs->head : hs->head - 1);
358     e = &hs->ptr.queue[index & QUEUE_MASK];
359 
360     if (hs->kind == HID_MOUSE) {
361         dx = int_clamp(e->xdx, -127, 127);
362         dy = int_clamp(e->ydy, -127, 127);
363         e->xdx -= dx;
364         e->ydy -= dy;
365     } else {
366         dx = e->xdx;
367         dy = e->ydy;
368     }
369     dz = int_clamp(e->dz, -127, 127);
370     e->dz -= dz;
371 
372     if (hs->n &&
373         !e->dz &&
374         (hs->kind == HID_TABLET || (!e->xdx && !e->ydy))) {
375         /* that deals with this event */
376         QUEUE_INCR(hs->head);
377         hs->n--;
378     }
379 
380     /* Appears we have to invert the wheel direction */
381     dz = 0 - dz;
382     l = 0;
383     switch (hs->kind) {
384     case HID_MOUSE:
385         if (len > l) {
386             buf[l++] = e->buttons_state;
387         }
388         if (len > l) {
389             buf[l++] = dx;
390         }
391         if (len > l) {
392             buf[l++] = dy;
393         }
394         if (len > l) {
395             buf[l++] = dz;
396         }
397         break;
398 
399     case HID_TABLET:
400         if (len > l) {
401             buf[l++] = e->buttons_state;
402         }
403         if (len > l) {
404             buf[l++] = dx & 0xff;
405         }
406         if (len > l) {
407             buf[l++] = dx >> 8;
408         }
409         if (len > l) {
410             buf[l++] = dy & 0xff;
411         }
412         if (len > l) {
413             buf[l++] = dy >> 8;
414         }
415         if (len > l) {
416             buf[l++] = dz;
417         }
418         break;
419 
420     default:
421         abort();
422     }
423 
424     return l;
425 }
426 
427 int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len)
428 {
429     hs->idle_pending = false;
430 
431     if (len < 2) {
432         return 0;
433     }
434 
435     hid_keyboard_process_keycode(hs);
436 
437     buf[0] = hs->kbd.modifiers & 0xff;
438     buf[1] = 0;
439     if (hs->kbd.keys > 6) {
440         memset(buf + 2, HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
441     } else {
442         memcpy(buf + 2, hs->kbd.key, MIN(8, len) - 2);
443     }
444 
445     return MIN(8, len);
446 }
447 
448 int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len)
449 {
450     if (len > 0) {
451         int ledstate = 0;
452         /* 0x01: Num Lock LED
453          * 0x02: Caps Lock LED
454          * 0x04: Scroll Lock LED
455          * 0x08: Compose LED
456          * 0x10: Kana LED */
457         hs->kbd.leds = buf[0];
458         if (hs->kbd.leds & 0x04) {
459             ledstate |= QEMU_SCROLL_LOCK_LED;
460         }
461         if (hs->kbd.leds & 0x01) {
462             ledstate |= QEMU_NUM_LOCK_LED;
463         }
464         if (hs->kbd.leds & 0x02) {
465             ledstate |= QEMU_CAPS_LOCK_LED;
466         }
467         kbd_put_ledstate(ledstate);
468     }
469     return 0;
470 }
471 
472 void hid_reset(HIDState *hs)
473 {
474     switch (hs->kind) {
475     case HID_KEYBOARD:
476         memset(hs->kbd.keycodes, 0, sizeof(hs->kbd.keycodes));
477         memset(hs->kbd.key, 0, sizeof(hs->kbd.key));
478         hs->kbd.keys = 0;
479         break;
480     case HID_MOUSE:
481     case HID_TABLET:
482         memset(hs->ptr.queue, 0, sizeof(hs->ptr.queue));
483         break;
484     }
485     hs->head = 0;
486     hs->n = 0;
487     hs->protocol = 1;
488     hs->idle = 0;
489     hs->idle_pending = false;
490     hid_del_idle_timer(hs);
491 }
492 
493 void hid_free(HIDState *hs)
494 {
495     qemu_input_handler_unregister(hs->s);
496     hid_del_idle_timer(hs);
497 }
498 
499 static QemuInputHandler hid_keyboard_handler = {
500     .name  = "QEMU HID Keyboard",
501     .mask  = INPUT_EVENT_MASK_KEY,
502     .event = hid_keyboard_event,
503 };
504 
505 static QemuInputHandler hid_mouse_handler = {
506     .name  = "QEMU HID Mouse",
507     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
508     .event = hid_pointer_event,
509     .sync  = hid_pointer_sync,
510 };
511 
512 static QemuInputHandler hid_tablet_handler = {
513     .name  = "QEMU HID Tablet",
514     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS,
515     .event = hid_pointer_event,
516     .sync  = hid_pointer_sync,
517 };
518 
519 void hid_init(HIDState *hs, int kind, HIDEventFunc event)
520 {
521     hs->kind = kind;
522     hs->event = event;
523 
524     if (hs->kind == HID_KEYBOARD) {
525         hs->s = qemu_input_handler_register((DeviceState *)hs,
526                                             &hid_keyboard_handler);
527         qemu_input_handler_activate(hs->s);
528     } else if (hs->kind == HID_MOUSE) {
529         hs->s = qemu_input_handler_register((DeviceState *)hs,
530                                             &hid_mouse_handler);
531     } else if (hs->kind == HID_TABLET) {
532         hs->s = qemu_input_handler_register((DeviceState *)hs,
533                                             &hid_tablet_handler);
534     }
535 }
536 
537 static int hid_post_load(void *opaque, int version_id)
538 {
539     HIDState *s = opaque;
540 
541     hid_set_next_idle(s);
542 
543     if (s->n == QUEUE_LENGTH && (s->kind == HID_TABLET ||
544                                  s->kind == HID_MOUSE)) {
545         /*
546          * Handle ptr device migration from old qemu with full queue.
547          *
548          * Throw away everything but the last event, so we propagate
549          * at least the current button state to the guest.  Also keep
550          * current position for the tablet, signal "no motion" for the
551          * mouse.
552          */
553         HIDPointerEvent evt;
554         evt = s->ptr.queue[(s->head+s->n) & QUEUE_MASK];
555         if (s->kind == HID_MOUSE) {
556             evt.xdx = 0;
557             evt.ydy = 0;
558         }
559         s->ptr.queue[0] = evt;
560         s->head = 0;
561         s->n = 1;
562     }
563     return 0;
564 }
565 
566 static const VMStateDescription vmstate_hid_ptr_queue = {
567     .name = "HIDPointerEventQueue",
568     .version_id = 1,
569     .minimum_version_id = 1,
570     .fields = (VMStateField[]) {
571         VMSTATE_INT32(xdx, HIDPointerEvent),
572         VMSTATE_INT32(ydy, HIDPointerEvent),
573         VMSTATE_INT32(dz, HIDPointerEvent),
574         VMSTATE_INT32(buttons_state, HIDPointerEvent),
575         VMSTATE_END_OF_LIST()
576     }
577 };
578 
579 const VMStateDescription vmstate_hid_ptr_device = {
580     .name = "HIDPointerDevice",
581     .version_id = 1,
582     .minimum_version_id = 1,
583     .post_load = hid_post_load,
584     .fields = (VMStateField[]) {
585         VMSTATE_STRUCT_ARRAY(ptr.queue, HIDState, QUEUE_LENGTH, 0,
586                              vmstate_hid_ptr_queue, HIDPointerEvent),
587         VMSTATE_UINT32(head, HIDState),
588         VMSTATE_UINT32(n, HIDState),
589         VMSTATE_INT32(protocol, HIDState),
590         VMSTATE_UINT8(idle, HIDState),
591         VMSTATE_END_OF_LIST(),
592     }
593 };
594 
595 const VMStateDescription vmstate_hid_keyboard_device = {
596     .name = "HIDKeyboardDevice",
597     .version_id = 1,
598     .minimum_version_id = 1,
599     .post_load = hid_post_load,
600     .fields = (VMStateField[]) {
601         VMSTATE_UINT32_ARRAY(kbd.keycodes, HIDState, QUEUE_LENGTH),
602         VMSTATE_UINT32(head, HIDState),
603         VMSTATE_UINT32(n, HIDState),
604         VMSTATE_UINT16(kbd.modifiers, HIDState),
605         VMSTATE_UINT8(kbd.leds, HIDState),
606         VMSTATE_UINT8_ARRAY(kbd.key, HIDState, 16),
607         VMSTATE_INT32(kbd.keys, HIDState),
608         VMSTATE_INT32(protocol, HIDState),
609         VMSTATE_UINT8(idle, HIDState),
610         VMSTATE_END_OF_LIST(),
611     }
612 };
613