xref: /openbmc/qemu/hw/input/hid.c (revision 63785678)
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                                NANOSECONDS_PER_SECOND * 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     InputMoveEvent *move;
120     InputBtnEvent *btn;
121 
122     assert(hs->n < QUEUE_LENGTH);
123     e = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK];
124 
125     switch (evt->type) {
126     case INPUT_EVENT_KIND_REL:
127         move = evt->u.rel.data;
128         if (move->axis == INPUT_AXIS_X) {
129             e->xdx += move->value;
130         } else if (move->axis == INPUT_AXIS_Y) {
131             e->ydy += move->value;
132         }
133         break;
134 
135     case INPUT_EVENT_KIND_ABS:
136         move = evt->u.abs.data;
137         if (move->axis == INPUT_AXIS_X) {
138             e->xdx = move->value;
139         } else if (move->axis == INPUT_AXIS_Y) {
140             e->ydy = move->value;
141         }
142         break;
143 
144     case INPUT_EVENT_KIND_BTN:
145         btn = evt->u.btn.data;
146         if (btn->down) {
147             e->buttons_state |= bmap[btn->button];
148             if (btn->button == INPUT_BUTTON_WHEEL_UP) {
149                 e->dz--;
150             } else if (btn->button == INPUT_BUTTON_WHEEL_DOWN) {
151                 e->dz++;
152             }
153         } else {
154             e->buttons_state &= ~bmap[btn->button];
155         }
156         break;
157 
158     default:
159         /* keep gcc happy */
160         break;
161     }
162 
163 }
164 
165 static void hid_pointer_sync(DeviceState *dev)
166 {
167     HIDState *hs = (HIDState *)dev;
168     HIDPointerEvent *prev, *curr, *next;
169     bool event_compression = false;
170 
171     if (hs->n == QUEUE_LENGTH-1) {
172         /*
173          * Queue full.  We are losing information, but we at least
174          * keep track of most recent button state.
175          */
176         return;
177     }
178 
179     prev = &hs->ptr.queue[(hs->head + hs->n - 1) & QUEUE_MASK];
180     curr = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK];
181     next = &hs->ptr.queue[(hs->head + hs->n + 1) & QUEUE_MASK];
182 
183     if (hs->n > 0) {
184         /*
185          * No button state change between previous and current event
186          * (and previous wasn't seen by the guest yet), so there is
187          * motion information only and we can combine the two event
188          * into one.
189          */
190         if (curr->buttons_state == prev->buttons_state) {
191             event_compression = true;
192         }
193     }
194 
195     if (event_compression) {
196         /* add current motion to previous, clear current */
197         if (hs->kind == HID_MOUSE) {
198             prev->xdx += curr->xdx;
199             curr->xdx = 0;
200             prev->ydy += curr->ydy;
201             curr->ydy = 0;
202         } else {
203             prev->xdx = curr->xdx;
204             prev->ydy = curr->ydy;
205         }
206         prev->dz += curr->dz;
207         curr->dz = 0;
208     } else {
209         /* prepate next (clear rel, copy abs + btns) */
210         if (hs->kind == HID_MOUSE) {
211             next->xdx = 0;
212             next->ydy = 0;
213         } else {
214             next->xdx = curr->xdx;
215             next->ydy = curr->ydy;
216         }
217         next->dz = 0;
218         next->buttons_state = curr->buttons_state;
219         /* make current guest visible, notify guest */
220         hs->n++;
221         hs->event(hs);
222     }
223 }
224 
225 static void hid_keyboard_event(DeviceState *dev, QemuConsole *src,
226                                InputEvent *evt)
227 {
228     HIDState *hs = (HIDState *)dev;
229     int scancodes[3], i, count;
230     int slot;
231     InputKeyEvent *key = evt->u.key.data;
232 
233     count = qemu_input_key_value_to_scancode(key->key,
234                                              key->down,
235                                              scancodes);
236     if (hs->n + count > QUEUE_LENGTH) {
237         fprintf(stderr, "usb-kbd: warning: key event queue full\n");
238         return;
239     }
240     for (i = 0; i < count; i++) {
241         slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++;
242         hs->kbd.keycodes[slot] = scancodes[i];
243     }
244     hs->event(hs);
245 }
246 
247 static void hid_keyboard_process_keycode(HIDState *hs)
248 {
249     uint8_t hid_code, index, key;
250     int i, keycode, slot;
251 
252     if (hs->n == 0) {
253         return;
254     }
255     slot = hs->head & QUEUE_MASK; QUEUE_INCR(hs->head); hs->n--;
256     keycode = hs->kbd.keycodes[slot];
257 
258     key = keycode & 0x7f;
259     index = key | ((hs->kbd.modifiers & (1 << 8)) >> 1);
260     hid_code = hid_usage_keys[index];
261     hs->kbd.modifiers &= ~(1 << 8);
262 
263     switch (hid_code) {
264     case 0x00:
265         return;
266 
267     case 0xe0:
268         assert(key == 0x1d);
269         if (hs->kbd.modifiers & (1 << 9)) {
270             /* The hid_codes for the 0xe1/0x1d scancode sequence are 0xe9/0xe0.
271              * Here we're processing the second hid_code.  By dropping bit 9
272              * and setting bit 8, the scancode after 0x1d will access the
273              * second half of the table.
274              */
275             hs->kbd.modifiers ^= (1 << 8) | (1 << 9);
276             return;
277         }
278         /* fall through to process Ctrl_L */
279     case 0xe1 ... 0xe7:
280         /* Ctrl_L/Ctrl_R, Shift_L/Shift_R, Alt_L/Alt_R, Win_L/Win_R.
281          * Handle releases here, or fall through to process presses.
282          */
283         if (keycode & (1 << 7)) {
284             hs->kbd.modifiers &= ~(1 << (hid_code & 0x0f));
285             return;
286         }
287         /* fall through */
288     case 0xe8 ... 0xe9:
289         /* USB modifiers are just 1 byte long.  Bits 8 and 9 of
290          * hs->kbd.modifiers implement a state machine that detects the
291          * 0xe0 and 0xe1/0x1d sequences.  These bits do not follow the
292          * usual rules where bit 7 marks released keys; they are cleared
293          * elsewhere in the function as the state machine dictates.
294          */
295         hs->kbd.modifiers |= 1 << (hid_code & 0x0f);
296         return;
297 
298     case 0xea ... 0xef:
299         abort();
300 
301     default:
302         break;
303     }
304 
305     if (keycode & (1 << 7)) {
306         for (i = hs->kbd.keys - 1; i >= 0; i--) {
307             if (hs->kbd.key[i] == hid_code) {
308                 hs->kbd.key[i] = hs->kbd.key[-- hs->kbd.keys];
309                 hs->kbd.key[hs->kbd.keys] = 0x00;
310                 break;
311             }
312         }
313         if (i < 0) {
314             return;
315         }
316     } else {
317         for (i = hs->kbd.keys - 1; i >= 0; i--) {
318             if (hs->kbd.key[i] == hid_code) {
319                 break;
320             }
321         }
322         if (i < 0) {
323             if (hs->kbd.keys < sizeof(hs->kbd.key)) {
324                 hs->kbd.key[hs->kbd.keys++] = hid_code;
325             }
326         } else {
327             return;
328         }
329     }
330 }
331 
332 static inline int int_clamp(int val, int vmin, int vmax)
333 {
334     if (val < vmin) {
335         return vmin;
336     } else if (val > vmax) {
337         return vmax;
338     } else {
339         return val;
340     }
341 }
342 
343 void hid_pointer_activate(HIDState *hs)
344 {
345     if (!hs->ptr.mouse_grabbed) {
346         qemu_input_handler_activate(hs->s);
347         hs->ptr.mouse_grabbed = 1;
348     }
349 }
350 
351 int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
352 {
353     int dx, dy, dz, l;
354     int index;
355     HIDPointerEvent *e;
356 
357     hs->idle_pending = false;
358 
359     hid_pointer_activate(hs);
360 
361     /* When the buffer is empty, return the last event.  Relative
362        movements will all be zero.  */
363     index = (hs->n ? hs->head : hs->head - 1);
364     e = &hs->ptr.queue[index & QUEUE_MASK];
365 
366     if (hs->kind == HID_MOUSE) {
367         dx = int_clamp(e->xdx, -127, 127);
368         dy = int_clamp(e->ydy, -127, 127);
369         e->xdx -= dx;
370         e->ydy -= dy;
371     } else {
372         dx = e->xdx;
373         dy = e->ydy;
374     }
375     dz = int_clamp(e->dz, -127, 127);
376     e->dz -= dz;
377 
378     if (hs->n &&
379         !e->dz &&
380         (hs->kind == HID_TABLET || (!e->xdx && !e->ydy))) {
381         /* that deals with this event */
382         QUEUE_INCR(hs->head);
383         hs->n--;
384     }
385 
386     /* Appears we have to invert the wheel direction */
387     dz = 0 - dz;
388     l = 0;
389     switch (hs->kind) {
390     case HID_MOUSE:
391         if (len > l) {
392             buf[l++] = e->buttons_state;
393         }
394         if (len > l) {
395             buf[l++] = dx;
396         }
397         if (len > l) {
398             buf[l++] = dy;
399         }
400         if (len > l) {
401             buf[l++] = dz;
402         }
403         break;
404 
405     case HID_TABLET:
406         if (len > l) {
407             buf[l++] = e->buttons_state;
408         }
409         if (len > l) {
410             buf[l++] = dx & 0xff;
411         }
412         if (len > l) {
413             buf[l++] = dx >> 8;
414         }
415         if (len > l) {
416             buf[l++] = dy & 0xff;
417         }
418         if (len > l) {
419             buf[l++] = dy >> 8;
420         }
421         if (len > l) {
422             buf[l++] = dz;
423         }
424         break;
425 
426     default:
427         abort();
428     }
429 
430     return l;
431 }
432 
433 int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len)
434 {
435     hs->idle_pending = false;
436 
437     if (len < 2) {
438         return 0;
439     }
440 
441     hid_keyboard_process_keycode(hs);
442 
443     buf[0] = hs->kbd.modifiers & 0xff;
444     buf[1] = 0;
445     if (hs->kbd.keys > 6) {
446         memset(buf + 2, HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2);
447     } else {
448         memcpy(buf + 2, hs->kbd.key, MIN(8, len) - 2);
449     }
450 
451     return MIN(8, len);
452 }
453 
454 int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len)
455 {
456     if (len > 0) {
457         int ledstate = 0;
458         /* 0x01: Num Lock LED
459          * 0x02: Caps Lock LED
460          * 0x04: Scroll Lock LED
461          * 0x08: Compose LED
462          * 0x10: Kana LED */
463         hs->kbd.leds = buf[0];
464         if (hs->kbd.leds & 0x04) {
465             ledstate |= QEMU_SCROLL_LOCK_LED;
466         }
467         if (hs->kbd.leds & 0x01) {
468             ledstate |= QEMU_NUM_LOCK_LED;
469         }
470         if (hs->kbd.leds & 0x02) {
471             ledstate |= QEMU_CAPS_LOCK_LED;
472         }
473         kbd_put_ledstate(ledstate);
474     }
475     return 0;
476 }
477 
478 void hid_reset(HIDState *hs)
479 {
480     switch (hs->kind) {
481     case HID_KEYBOARD:
482         memset(hs->kbd.keycodes, 0, sizeof(hs->kbd.keycodes));
483         memset(hs->kbd.key, 0, sizeof(hs->kbd.key));
484         hs->kbd.keys = 0;
485         break;
486     case HID_MOUSE:
487     case HID_TABLET:
488         memset(hs->ptr.queue, 0, sizeof(hs->ptr.queue));
489         break;
490     }
491     hs->head = 0;
492     hs->n = 0;
493     hs->protocol = 1;
494     hs->idle = 0;
495     hs->idle_pending = false;
496     hid_del_idle_timer(hs);
497 }
498 
499 void hid_free(HIDState *hs)
500 {
501     qemu_input_handler_unregister(hs->s);
502     hid_del_idle_timer(hs);
503 }
504 
505 static QemuInputHandler hid_keyboard_handler = {
506     .name  = "QEMU HID Keyboard",
507     .mask  = INPUT_EVENT_MASK_KEY,
508     .event = hid_keyboard_event,
509 };
510 
511 static QemuInputHandler hid_mouse_handler = {
512     .name  = "QEMU HID Mouse",
513     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
514     .event = hid_pointer_event,
515     .sync  = hid_pointer_sync,
516 };
517 
518 static QemuInputHandler hid_tablet_handler = {
519     .name  = "QEMU HID Tablet",
520     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS,
521     .event = hid_pointer_event,
522     .sync  = hid_pointer_sync,
523 };
524 
525 void hid_init(HIDState *hs, int kind, HIDEventFunc event)
526 {
527     hs->kind = kind;
528     hs->event = event;
529 
530     if (hs->kind == HID_KEYBOARD) {
531         hs->s = qemu_input_handler_register((DeviceState *)hs,
532                                             &hid_keyboard_handler);
533         qemu_input_handler_activate(hs->s);
534     } else if (hs->kind == HID_MOUSE) {
535         hs->s = qemu_input_handler_register((DeviceState *)hs,
536                                             &hid_mouse_handler);
537     } else if (hs->kind == HID_TABLET) {
538         hs->s = qemu_input_handler_register((DeviceState *)hs,
539                                             &hid_tablet_handler);
540     }
541 }
542 
543 static int hid_post_load(void *opaque, int version_id)
544 {
545     HIDState *s = opaque;
546 
547     hid_set_next_idle(s);
548 
549     if (s->n == QUEUE_LENGTH && (s->kind == HID_TABLET ||
550                                  s->kind == HID_MOUSE)) {
551         /*
552          * Handle ptr device migration from old qemu with full queue.
553          *
554          * Throw away everything but the last event, so we propagate
555          * at least the current button state to the guest.  Also keep
556          * current position for the tablet, signal "no motion" for the
557          * mouse.
558          */
559         HIDPointerEvent evt;
560         evt = s->ptr.queue[(s->head+s->n) & QUEUE_MASK];
561         if (s->kind == HID_MOUSE) {
562             evt.xdx = 0;
563             evt.ydy = 0;
564         }
565         s->ptr.queue[0] = evt;
566         s->head = 0;
567         s->n = 1;
568     }
569     return 0;
570 }
571 
572 static const VMStateDescription vmstate_hid_ptr_queue = {
573     .name = "HIDPointerEventQueue",
574     .version_id = 1,
575     .minimum_version_id = 1,
576     .fields = (VMStateField[]) {
577         VMSTATE_INT32(xdx, HIDPointerEvent),
578         VMSTATE_INT32(ydy, HIDPointerEvent),
579         VMSTATE_INT32(dz, HIDPointerEvent),
580         VMSTATE_INT32(buttons_state, HIDPointerEvent),
581         VMSTATE_END_OF_LIST()
582     }
583 };
584 
585 const VMStateDescription vmstate_hid_ptr_device = {
586     .name = "HIDPointerDevice",
587     .version_id = 1,
588     .minimum_version_id = 1,
589     .post_load = hid_post_load,
590     .fields = (VMStateField[]) {
591         VMSTATE_STRUCT_ARRAY(ptr.queue, HIDState, QUEUE_LENGTH, 0,
592                              vmstate_hid_ptr_queue, HIDPointerEvent),
593         VMSTATE_UINT32(head, HIDState),
594         VMSTATE_UINT32(n, HIDState),
595         VMSTATE_INT32(protocol, HIDState),
596         VMSTATE_UINT8(idle, HIDState),
597         VMSTATE_END_OF_LIST(),
598     }
599 };
600 
601 const VMStateDescription vmstate_hid_keyboard_device = {
602     .name = "HIDKeyboardDevice",
603     .version_id = 1,
604     .minimum_version_id = 1,
605     .post_load = hid_post_load,
606     .fields = (VMStateField[]) {
607         VMSTATE_UINT32_ARRAY(kbd.keycodes, HIDState, QUEUE_LENGTH),
608         VMSTATE_UINT32(head, HIDState),
609         VMSTATE_UINT32(n, HIDState),
610         VMSTATE_UINT16(kbd.modifiers, HIDState),
611         VMSTATE_UINT8(kbd.leds, HIDState),
612         VMSTATE_UINT8_ARRAY(kbd.key, HIDState, 16),
613         VMSTATE_INT32(kbd.keys, HIDState),
614         VMSTATE_INT32(protocol, HIDState),
615         VMSTATE_UINT8(idle, HIDState),
616         VMSTATE_END_OF_LIST(),
617     }
618 };
619