xref: /qemu/hw/input/virtio-input-hid.c (revision 55a1d80a41032d6133adec041c0096820beaa1b7)
1*55a1d80aSGerd Hoffmann /*
2*55a1d80aSGerd Hoffmann  * This work is licensed under the terms of the GNU GPL, version 2 or
3*55a1d80aSGerd Hoffmann  * (at your option) any later version.  See the COPYING file in the
4*55a1d80aSGerd Hoffmann  * top-level directory.
5*55a1d80aSGerd Hoffmann  */
6*55a1d80aSGerd Hoffmann 
7*55a1d80aSGerd Hoffmann #include "qemu/iov.h"
8*55a1d80aSGerd Hoffmann 
9*55a1d80aSGerd Hoffmann #include "hw/qdev.h"
10*55a1d80aSGerd Hoffmann #include "hw/virtio/virtio.h"
11*55a1d80aSGerd Hoffmann #include "hw/virtio/virtio-input.h"
12*55a1d80aSGerd Hoffmann 
13*55a1d80aSGerd Hoffmann #undef CONFIG_CURSES
14*55a1d80aSGerd Hoffmann #include "ui/console.h"
15*55a1d80aSGerd Hoffmann 
16*55a1d80aSGerd Hoffmann #include "standard-headers/linux/input.h"
17*55a1d80aSGerd Hoffmann 
18*55a1d80aSGerd Hoffmann #define VIRTIO_ID_NAME_KEYBOARD "QEMU Virtio Keyboard"
19*55a1d80aSGerd Hoffmann #define VIRTIO_ID_NAME_MOUSE    "QEMU Virtio Mouse"
20*55a1d80aSGerd Hoffmann #define VIRTIO_ID_NAME_TABLET   "QEMU Virtio Tablet"
21*55a1d80aSGerd Hoffmann 
22*55a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
23*55a1d80aSGerd Hoffmann 
24*55a1d80aSGerd Hoffmann static const unsigned int keymap_qcode[Q_KEY_CODE_MAX] = {
25*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_ESC]                 = KEY_ESC,
26*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_1]                   = KEY_1,
27*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_2]                   = KEY_2,
28*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_3]                   = KEY_3,
29*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_4]                   = KEY_4,
30*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_5]                   = KEY_5,
31*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_6]                   = KEY_6,
32*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_7]                   = KEY_7,
33*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_8]                   = KEY_8,
34*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_9]                   = KEY_9,
35*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_0]                   = KEY_0,
36*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_MINUS]               = KEY_MINUS,
37*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_EQUAL]               = KEY_EQUAL,
38*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_BACKSPACE]           = KEY_BACKSPACE,
39*55a1d80aSGerd Hoffmann 
40*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_TAB]                 = KEY_TAB,
41*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_Q]                   = KEY_Q,
42*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_W]                   = KEY_W,
43*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_E]                   = KEY_E,
44*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_R]                   = KEY_R,
45*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_T]                   = KEY_T,
46*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_Y]                   = KEY_Y,
47*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_U]                   = KEY_U,
48*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_I]                   = KEY_I,
49*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_O]                   = KEY_O,
50*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_P]                   = KEY_P,
51*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_BRACKET_LEFT]        = KEY_LEFTBRACE,
52*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_BRACKET_RIGHT]       = KEY_RIGHTBRACE,
53*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_RET]                 = KEY_ENTER,
54*55a1d80aSGerd Hoffmann 
55*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_CTRL]                = KEY_LEFTCTRL,
56*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_A]                   = KEY_A,
57*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_S]                   = KEY_S,
58*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_D]                   = KEY_D,
59*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_F]                   = KEY_F,
60*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_G]                   = KEY_G,
61*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_H]                   = KEY_H,
62*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_J]                   = KEY_J,
63*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_K]                   = KEY_K,
64*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_L]                   = KEY_L,
65*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_SEMICOLON]           = KEY_SEMICOLON,
66*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_APOSTROPHE]          = KEY_APOSTROPHE,
67*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_GRAVE_ACCENT]        = KEY_GRAVE,
68*55a1d80aSGerd Hoffmann 
69*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_SHIFT]               = KEY_LEFTSHIFT,
70*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_BACKSLASH]           = KEY_BACKSLASH,
71*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_LESS]                = KEY_102ND,
72*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_Z]                   = KEY_Z,
73*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_X]                   = KEY_X,
74*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_C]                   = KEY_C,
75*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_V]                   = KEY_V,
76*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_B]                   = KEY_B,
77*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_N]                   = KEY_N,
78*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_M]                   = KEY_M,
79*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_COMMA]               = KEY_COMMA,
80*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_DOT]                 = KEY_DOT,
81*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_SLASH]               = KEY_SLASH,
82*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_SHIFT_R]             = KEY_RIGHTSHIFT,
83*55a1d80aSGerd Hoffmann 
84*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_ALT]                 = KEY_LEFTALT,
85*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_SPC]                 = KEY_SPACE,
86*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_CAPS_LOCK]           = KEY_CAPSLOCK,
87*55a1d80aSGerd Hoffmann 
88*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_F1]                  = KEY_F1,
89*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_F2]                  = KEY_F2,
90*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_F3]                  = KEY_F3,
91*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_F4]                  = KEY_F4,
92*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_F5]                  = KEY_F5,
93*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_F6]                  = KEY_F6,
94*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_F7]                  = KEY_F7,
95*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_F8]                  = KEY_F8,
96*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_F9]                  = KEY_F9,
97*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_F10]                 = KEY_F10,
98*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_NUM_LOCK]            = KEY_NUMLOCK,
99*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_SCROLL_LOCK]         = KEY_SCROLLLOCK,
100*55a1d80aSGerd Hoffmann 
101*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_0]                = KEY_KP0,
102*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_1]                = KEY_KP1,
103*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_2]                = KEY_KP2,
104*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_3]                = KEY_KP3,
105*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_4]                = KEY_KP4,
106*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_5]                = KEY_KP5,
107*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_6]                = KEY_KP6,
108*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_7]                = KEY_KP7,
109*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_8]                = KEY_KP8,
110*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_9]                = KEY_KP9,
111*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_SUBTRACT]         = KEY_KPMINUS,
112*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_ADD]              = KEY_KPPLUS,
113*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_DECIMAL]          = KEY_KPDOT,
114*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_ENTER]            = KEY_KPENTER,
115*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_DIVIDE]           = KEY_KPSLASH,
116*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_KP_MULTIPLY]         = KEY_KPASTERISK,
117*55a1d80aSGerd Hoffmann 
118*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_F11]                 = KEY_F11,
119*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_F12]                 = KEY_F12,
120*55a1d80aSGerd Hoffmann 
121*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_CTRL_R]              = KEY_RIGHTCTRL,
122*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_SYSRQ]               = KEY_SYSRQ,
123*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_ALT_R]               = KEY_RIGHTALT,
124*55a1d80aSGerd Hoffmann 
125*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_HOME]                = KEY_HOME,
126*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_UP]                  = KEY_UP,
127*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_PGUP]                = KEY_PAGEUP,
128*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_LEFT]                = KEY_LEFT,
129*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_RIGHT]               = KEY_RIGHT,
130*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_END]                 = KEY_END,
131*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_DOWN]                = KEY_DOWN,
132*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_PGDN]                = KEY_PAGEDOWN,
133*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_INSERT]              = KEY_INSERT,
134*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_DELETE]              = KEY_DELETE,
135*55a1d80aSGerd Hoffmann 
136*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_META_L]              = KEY_LEFTMETA,
137*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_META_R]              = KEY_RIGHTMETA,
138*55a1d80aSGerd Hoffmann     [Q_KEY_CODE_MENU]                = KEY_MENU,
139*55a1d80aSGerd Hoffmann };
140*55a1d80aSGerd Hoffmann 
141*55a1d80aSGerd Hoffmann static const unsigned int keymap_button[INPUT_BUTTON_MAX] = {
142*55a1d80aSGerd Hoffmann     [INPUT_BUTTON_LEFT]              = BTN_LEFT,
143*55a1d80aSGerd Hoffmann     [INPUT_BUTTON_RIGHT]             = BTN_RIGHT,
144*55a1d80aSGerd Hoffmann     [INPUT_BUTTON_MIDDLE]            = BTN_MIDDLE,
145*55a1d80aSGerd Hoffmann     [INPUT_BUTTON_WHEEL_UP]          = BTN_GEAR_UP,
146*55a1d80aSGerd Hoffmann     [INPUT_BUTTON_WHEEL_DOWN]        = BTN_GEAR_DOWN,
147*55a1d80aSGerd Hoffmann };
148*55a1d80aSGerd Hoffmann 
149*55a1d80aSGerd Hoffmann static const unsigned int axismap_rel[INPUT_AXIS_MAX] = {
150*55a1d80aSGerd Hoffmann     [INPUT_AXIS_X]                   = REL_X,
151*55a1d80aSGerd Hoffmann     [INPUT_AXIS_Y]                   = REL_Y,
152*55a1d80aSGerd Hoffmann };
153*55a1d80aSGerd Hoffmann 
154*55a1d80aSGerd Hoffmann static const unsigned int axismap_abs[INPUT_AXIS_MAX] = {
155*55a1d80aSGerd Hoffmann     [INPUT_AXIS_X]                   = ABS_X,
156*55a1d80aSGerd Hoffmann     [INPUT_AXIS_Y]                   = ABS_Y,
157*55a1d80aSGerd Hoffmann };
158*55a1d80aSGerd Hoffmann 
159*55a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
160*55a1d80aSGerd Hoffmann 
161*55a1d80aSGerd Hoffmann static void virtio_input_key_config(VirtIOInput *vinput,
162*55a1d80aSGerd Hoffmann                                     const unsigned int *keymap,
163*55a1d80aSGerd Hoffmann                                     size_t mapsize)
164*55a1d80aSGerd Hoffmann {
165*55a1d80aSGerd Hoffmann     virtio_input_config keys;
166*55a1d80aSGerd Hoffmann     int i, bit, byte, bmax = 0;
167*55a1d80aSGerd Hoffmann 
168*55a1d80aSGerd Hoffmann     memset(&keys, 0, sizeof(keys));
169*55a1d80aSGerd Hoffmann     for (i = 0; i < mapsize; i++) {
170*55a1d80aSGerd Hoffmann         bit = keymap[i];
171*55a1d80aSGerd Hoffmann         if (!bit) {
172*55a1d80aSGerd Hoffmann             continue;
173*55a1d80aSGerd Hoffmann         }
174*55a1d80aSGerd Hoffmann         byte = bit / 8;
175*55a1d80aSGerd Hoffmann         bit  = bit % 8;
176*55a1d80aSGerd Hoffmann         keys.u.bitmap[byte] |= (1 << bit);
177*55a1d80aSGerd Hoffmann         if (bmax < byte+1) {
178*55a1d80aSGerd Hoffmann             bmax = byte+1;
179*55a1d80aSGerd Hoffmann         }
180*55a1d80aSGerd Hoffmann     }
181*55a1d80aSGerd Hoffmann     keys.select = VIRTIO_INPUT_CFG_EV_BITS;
182*55a1d80aSGerd Hoffmann     keys.subsel = EV_KEY;
183*55a1d80aSGerd Hoffmann     keys.size   = bmax;
184*55a1d80aSGerd Hoffmann     virtio_input_add_config(vinput, &keys);
185*55a1d80aSGerd Hoffmann }
186*55a1d80aSGerd Hoffmann 
187*55a1d80aSGerd Hoffmann static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,
188*55a1d80aSGerd Hoffmann                                       InputEvent *evt)
189*55a1d80aSGerd Hoffmann {
190*55a1d80aSGerd Hoffmann     VirtIOInput *vinput = VIRTIO_INPUT(dev);
191*55a1d80aSGerd Hoffmann     virtio_input_event event;
192*55a1d80aSGerd Hoffmann     int qcode;
193*55a1d80aSGerd Hoffmann 
194*55a1d80aSGerd Hoffmann     switch (evt->kind) {
195*55a1d80aSGerd Hoffmann     case INPUT_EVENT_KIND_KEY:
196*55a1d80aSGerd Hoffmann         qcode = qemu_input_key_value_to_qcode(evt->key->key);
197*55a1d80aSGerd Hoffmann         if (qcode && keymap_qcode[qcode]) {
198*55a1d80aSGerd Hoffmann             event.type  = cpu_to_le16(EV_KEY);
199*55a1d80aSGerd Hoffmann             event.code  = cpu_to_le16(keymap_qcode[qcode]);
200*55a1d80aSGerd Hoffmann             event.value = cpu_to_le32(evt->key->down ? 1 : 0);
201*55a1d80aSGerd Hoffmann             virtio_input_send(vinput, &event);
202*55a1d80aSGerd Hoffmann         } else {
203*55a1d80aSGerd Hoffmann             if (evt->key->down) {
204*55a1d80aSGerd Hoffmann                 fprintf(stderr, "%s: unmapped key: %d [%s]\n", __func__,
205*55a1d80aSGerd Hoffmann                         qcode, QKeyCode_lookup[qcode]);
206*55a1d80aSGerd Hoffmann             }
207*55a1d80aSGerd Hoffmann         }
208*55a1d80aSGerd Hoffmann         break;
209*55a1d80aSGerd Hoffmann     case INPUT_EVENT_KIND_BTN:
210*55a1d80aSGerd Hoffmann         if (keymap_button[evt->btn->button]) {
211*55a1d80aSGerd Hoffmann             event.type  = cpu_to_le16(EV_KEY);
212*55a1d80aSGerd Hoffmann             event.code  = cpu_to_le16(keymap_button[evt->btn->button]);
213*55a1d80aSGerd Hoffmann             event.value = cpu_to_le32(evt->btn->down ? 1 : 0);
214*55a1d80aSGerd Hoffmann             virtio_input_send(vinput, &event);
215*55a1d80aSGerd Hoffmann         } else {
216*55a1d80aSGerd Hoffmann             if (evt->btn->down) {
217*55a1d80aSGerd Hoffmann                 fprintf(stderr, "%s: unmapped button: %d [%s]\n", __func__,
218*55a1d80aSGerd Hoffmann                         evt->btn->button, InputButton_lookup[evt->btn->button]);
219*55a1d80aSGerd Hoffmann             }
220*55a1d80aSGerd Hoffmann         }
221*55a1d80aSGerd Hoffmann         break;
222*55a1d80aSGerd Hoffmann     case INPUT_EVENT_KIND_REL:
223*55a1d80aSGerd Hoffmann         event.type  = cpu_to_le16(EV_REL);
224*55a1d80aSGerd Hoffmann         event.code  = cpu_to_le16(axismap_rel[evt->rel->axis]);
225*55a1d80aSGerd Hoffmann         event.value = cpu_to_le32(evt->rel->value);
226*55a1d80aSGerd Hoffmann         virtio_input_send(vinput, &event);
227*55a1d80aSGerd Hoffmann         break;
228*55a1d80aSGerd Hoffmann     case INPUT_EVENT_KIND_ABS:
229*55a1d80aSGerd Hoffmann         event.type  = cpu_to_le16(EV_ABS);
230*55a1d80aSGerd Hoffmann         event.code  = cpu_to_le16(axismap_abs[evt->abs->axis]);
231*55a1d80aSGerd Hoffmann         event.value = cpu_to_le32(evt->abs->value);
232*55a1d80aSGerd Hoffmann         virtio_input_send(vinput, &event);
233*55a1d80aSGerd Hoffmann         break;
234*55a1d80aSGerd Hoffmann     default:
235*55a1d80aSGerd Hoffmann         /* keep gcc happy */
236*55a1d80aSGerd Hoffmann         break;
237*55a1d80aSGerd Hoffmann     }
238*55a1d80aSGerd Hoffmann }
239*55a1d80aSGerd Hoffmann 
240*55a1d80aSGerd Hoffmann static void virtio_input_handle_sync(DeviceState *dev)
241*55a1d80aSGerd Hoffmann {
242*55a1d80aSGerd Hoffmann     VirtIOInput *vinput = VIRTIO_INPUT(dev);
243*55a1d80aSGerd Hoffmann     virtio_input_event event = {
244*55a1d80aSGerd Hoffmann         .type  = cpu_to_le16(EV_SYN),
245*55a1d80aSGerd Hoffmann         .code  = cpu_to_le16(SYN_REPORT),
246*55a1d80aSGerd Hoffmann         .value = 0,
247*55a1d80aSGerd Hoffmann     };
248*55a1d80aSGerd Hoffmann 
249*55a1d80aSGerd Hoffmann     virtio_input_send(vinput, &event);
250*55a1d80aSGerd Hoffmann }
251*55a1d80aSGerd Hoffmann 
252*55a1d80aSGerd Hoffmann static void virtio_input_hid_realize(DeviceState *dev, Error **errp)
253*55a1d80aSGerd Hoffmann {
254*55a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev);
255*55a1d80aSGerd Hoffmann     vhid->hs = qemu_input_handler_register(dev, vhid->handler);
256*55a1d80aSGerd Hoffmann }
257*55a1d80aSGerd Hoffmann 
258*55a1d80aSGerd Hoffmann static void virtio_input_hid_unrealize(DeviceState *dev, Error **errp)
259*55a1d80aSGerd Hoffmann {
260*55a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev);
261*55a1d80aSGerd Hoffmann     qemu_input_handler_unregister(vhid->hs);
262*55a1d80aSGerd Hoffmann }
263*55a1d80aSGerd Hoffmann 
264*55a1d80aSGerd Hoffmann static void virtio_input_hid_change_active(VirtIOInput *vinput)
265*55a1d80aSGerd Hoffmann {
266*55a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(vinput);
267*55a1d80aSGerd Hoffmann 
268*55a1d80aSGerd Hoffmann     if (vinput->active) {
269*55a1d80aSGerd Hoffmann         qemu_input_handler_activate(vhid->hs);
270*55a1d80aSGerd Hoffmann     } else {
271*55a1d80aSGerd Hoffmann         qemu_input_handler_deactivate(vhid->hs);
272*55a1d80aSGerd Hoffmann     }
273*55a1d80aSGerd Hoffmann }
274*55a1d80aSGerd Hoffmann 
275*55a1d80aSGerd Hoffmann static void virtio_input_hid_handle_status(VirtIOInput *vinput,
276*55a1d80aSGerd Hoffmann                                            virtio_input_event *event)
277*55a1d80aSGerd Hoffmann {
278*55a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(vinput);
279*55a1d80aSGerd Hoffmann     int ledbit = 0;
280*55a1d80aSGerd Hoffmann 
281*55a1d80aSGerd Hoffmann     switch (le16_to_cpu(event->type)) {
282*55a1d80aSGerd Hoffmann     case EV_LED:
283*55a1d80aSGerd Hoffmann         if (event->code == LED_NUML) {
284*55a1d80aSGerd Hoffmann             ledbit = QEMU_NUM_LOCK_LED;
285*55a1d80aSGerd Hoffmann         } else if (event->code == LED_CAPSL) {
286*55a1d80aSGerd Hoffmann             ledbit = QEMU_CAPS_LOCK_LED;
287*55a1d80aSGerd Hoffmann         } else if (event->code == LED_SCROLLL) {
288*55a1d80aSGerd Hoffmann             ledbit = QEMU_SCROLL_LOCK_LED;
289*55a1d80aSGerd Hoffmann         }
290*55a1d80aSGerd Hoffmann         if (event->value) {
291*55a1d80aSGerd Hoffmann             vhid->ledstate |= ledbit;
292*55a1d80aSGerd Hoffmann         } else {
293*55a1d80aSGerd Hoffmann             vhid->ledstate &= ~ledbit;
294*55a1d80aSGerd Hoffmann         }
295*55a1d80aSGerd Hoffmann         kbd_put_ledstate(vhid->ledstate);
296*55a1d80aSGerd Hoffmann         break;
297*55a1d80aSGerd Hoffmann     default:
298*55a1d80aSGerd Hoffmann         fprintf(stderr, "%s: unknown type %d\n", __func__,
299*55a1d80aSGerd Hoffmann                 le16_to_cpu(event->type));
300*55a1d80aSGerd Hoffmann         break;
301*55a1d80aSGerd Hoffmann     }
302*55a1d80aSGerd Hoffmann }
303*55a1d80aSGerd Hoffmann 
304*55a1d80aSGerd Hoffmann static void virtio_input_hid_class_init(ObjectClass *klass, void *data)
305*55a1d80aSGerd Hoffmann {
306*55a1d80aSGerd Hoffmann     VirtIOInputClass *vic = VIRTIO_INPUT_CLASS(klass);
307*55a1d80aSGerd Hoffmann 
308*55a1d80aSGerd Hoffmann     vic->realize       = virtio_input_hid_realize;
309*55a1d80aSGerd Hoffmann     vic->unrealize     = virtio_input_hid_unrealize;
310*55a1d80aSGerd Hoffmann     vic->change_active = virtio_input_hid_change_active;
311*55a1d80aSGerd Hoffmann     vic->handle_status = virtio_input_hid_handle_status;
312*55a1d80aSGerd Hoffmann }
313*55a1d80aSGerd Hoffmann 
314*55a1d80aSGerd Hoffmann static const TypeInfo virtio_input_hid_info = {
315*55a1d80aSGerd Hoffmann     .name          = TYPE_VIRTIO_INPUT_HID,
316*55a1d80aSGerd Hoffmann     .parent        = TYPE_VIRTIO_INPUT,
317*55a1d80aSGerd Hoffmann     .instance_size = sizeof(VirtIOInputHID),
318*55a1d80aSGerd Hoffmann     .class_init    = virtio_input_hid_class_init,
319*55a1d80aSGerd Hoffmann     .abstract      = true,
320*55a1d80aSGerd Hoffmann };
321*55a1d80aSGerd Hoffmann 
322*55a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
323*55a1d80aSGerd Hoffmann 
324*55a1d80aSGerd Hoffmann static QemuInputHandler virtio_keyboard_handler = {
325*55a1d80aSGerd Hoffmann     .name  = VIRTIO_ID_NAME_KEYBOARD,
326*55a1d80aSGerd Hoffmann     .mask  = INPUT_EVENT_MASK_KEY,
327*55a1d80aSGerd Hoffmann     .event = virtio_input_handle_event,
328*55a1d80aSGerd Hoffmann     .sync  = virtio_input_handle_sync,
329*55a1d80aSGerd Hoffmann };
330*55a1d80aSGerd Hoffmann 
331*55a1d80aSGerd Hoffmann static struct virtio_input_config virtio_keyboard_config[] = {
332*55a1d80aSGerd Hoffmann     {
333*55a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_NAME,
334*55a1d80aSGerd Hoffmann         .size      = sizeof(VIRTIO_ID_NAME_KEYBOARD),
335*55a1d80aSGerd Hoffmann         .u.string  = VIRTIO_ID_NAME_KEYBOARD,
336*55a1d80aSGerd Hoffmann     },{
337*55a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
338*55a1d80aSGerd Hoffmann         .size      = sizeof(struct virtio_input_devids),
339*55a1d80aSGerd Hoffmann         .u.ids     = {
340*55a1d80aSGerd Hoffmann             .bustype = const_le16(BUS_VIRTUAL),
341*55a1d80aSGerd Hoffmann             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
342*55a1d80aSGerd Hoffmann             .product = const_le16(0x0001),
343*55a1d80aSGerd Hoffmann             .version = const_le16(0x0001),
344*55a1d80aSGerd Hoffmann         },
345*55a1d80aSGerd Hoffmann     },{
346*55a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
347*55a1d80aSGerd Hoffmann         .subsel    = EV_REP,
348*55a1d80aSGerd Hoffmann         .size      = 1,
349*55a1d80aSGerd Hoffmann     },{
350*55a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
351*55a1d80aSGerd Hoffmann         .subsel    = EV_LED,
352*55a1d80aSGerd Hoffmann         .size      = 1,
353*55a1d80aSGerd Hoffmann         .u.bitmap  = {
354*55a1d80aSGerd Hoffmann             (1 << LED_NUML) | (1 << LED_CAPSL) | (1 << LED_SCROLLL),
355*55a1d80aSGerd Hoffmann         },
356*55a1d80aSGerd Hoffmann     },
357*55a1d80aSGerd Hoffmann     { /* end of list */ },
358*55a1d80aSGerd Hoffmann };
359*55a1d80aSGerd Hoffmann 
360*55a1d80aSGerd Hoffmann static void virtio_keyboard_init(Object *obj)
361*55a1d80aSGerd Hoffmann {
362*55a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
363*55a1d80aSGerd Hoffmann     VirtIOInput *vinput = VIRTIO_INPUT(obj);
364*55a1d80aSGerd Hoffmann 
365*55a1d80aSGerd Hoffmann     vhid->handler = &virtio_keyboard_handler;
366*55a1d80aSGerd Hoffmann     virtio_input_init_config(vinput, virtio_keyboard_config);
367*55a1d80aSGerd Hoffmann     virtio_input_key_config(vinput, keymap_qcode,
368*55a1d80aSGerd Hoffmann                             ARRAY_SIZE(keymap_qcode));
369*55a1d80aSGerd Hoffmann }
370*55a1d80aSGerd Hoffmann 
371*55a1d80aSGerd Hoffmann static const TypeInfo virtio_keyboard_info = {
372*55a1d80aSGerd Hoffmann     .name          = TYPE_VIRTIO_KEYBOARD,
373*55a1d80aSGerd Hoffmann     .parent        = TYPE_VIRTIO_INPUT_HID,
374*55a1d80aSGerd Hoffmann     .instance_size = sizeof(VirtIOInputHID),
375*55a1d80aSGerd Hoffmann     .instance_init = virtio_keyboard_init,
376*55a1d80aSGerd Hoffmann };
377*55a1d80aSGerd Hoffmann 
378*55a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
379*55a1d80aSGerd Hoffmann 
380*55a1d80aSGerd Hoffmann static QemuInputHandler virtio_mouse_handler = {
381*55a1d80aSGerd Hoffmann     .name  = VIRTIO_ID_NAME_MOUSE,
382*55a1d80aSGerd Hoffmann     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
383*55a1d80aSGerd Hoffmann     .event = virtio_input_handle_event,
384*55a1d80aSGerd Hoffmann     .sync  = virtio_input_handle_sync,
385*55a1d80aSGerd Hoffmann };
386*55a1d80aSGerd Hoffmann 
387*55a1d80aSGerd Hoffmann static struct virtio_input_config virtio_mouse_config[] = {
388*55a1d80aSGerd Hoffmann     {
389*55a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_NAME,
390*55a1d80aSGerd Hoffmann         .size      = sizeof(VIRTIO_ID_NAME_MOUSE),
391*55a1d80aSGerd Hoffmann         .u.string  = VIRTIO_ID_NAME_MOUSE,
392*55a1d80aSGerd Hoffmann     },{
393*55a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
394*55a1d80aSGerd Hoffmann         .size      = sizeof(struct virtio_input_devids),
395*55a1d80aSGerd Hoffmann         .u.ids     = {
396*55a1d80aSGerd Hoffmann             .bustype = const_le16(BUS_VIRTUAL),
397*55a1d80aSGerd Hoffmann             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
398*55a1d80aSGerd Hoffmann             .product = const_le16(0x0002),
399*55a1d80aSGerd Hoffmann             .version = const_le16(0x0001),
400*55a1d80aSGerd Hoffmann         },
401*55a1d80aSGerd Hoffmann     },{
402*55a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
403*55a1d80aSGerd Hoffmann         .subsel    = EV_REL,
404*55a1d80aSGerd Hoffmann         .size      = 1,
405*55a1d80aSGerd Hoffmann         .u.bitmap  = {
406*55a1d80aSGerd Hoffmann             (1 << REL_X) | (1 << REL_Y),
407*55a1d80aSGerd Hoffmann         },
408*55a1d80aSGerd Hoffmann     },
409*55a1d80aSGerd Hoffmann     { /* end of list */ },
410*55a1d80aSGerd Hoffmann };
411*55a1d80aSGerd Hoffmann 
412*55a1d80aSGerd Hoffmann static void virtio_mouse_init(Object *obj)
413*55a1d80aSGerd Hoffmann {
414*55a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
415*55a1d80aSGerd Hoffmann     VirtIOInput *vinput = VIRTIO_INPUT(obj);
416*55a1d80aSGerd Hoffmann 
417*55a1d80aSGerd Hoffmann     vhid->handler = &virtio_mouse_handler;
418*55a1d80aSGerd Hoffmann     virtio_input_init_config(vinput, virtio_mouse_config);
419*55a1d80aSGerd Hoffmann     virtio_input_key_config(vinput, keymap_button,
420*55a1d80aSGerd Hoffmann                             ARRAY_SIZE(keymap_button));
421*55a1d80aSGerd Hoffmann }
422*55a1d80aSGerd Hoffmann 
423*55a1d80aSGerd Hoffmann static const TypeInfo virtio_mouse_info = {
424*55a1d80aSGerd Hoffmann     .name          = TYPE_VIRTIO_MOUSE,
425*55a1d80aSGerd Hoffmann     .parent        = TYPE_VIRTIO_INPUT_HID,
426*55a1d80aSGerd Hoffmann     .instance_size = sizeof(VirtIOInputHID),
427*55a1d80aSGerd Hoffmann     .instance_init = virtio_mouse_init,
428*55a1d80aSGerd Hoffmann };
429*55a1d80aSGerd Hoffmann 
430*55a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
431*55a1d80aSGerd Hoffmann 
432*55a1d80aSGerd Hoffmann static QemuInputHandler virtio_tablet_handler = {
433*55a1d80aSGerd Hoffmann     .name  = VIRTIO_ID_NAME_TABLET,
434*55a1d80aSGerd Hoffmann     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS,
435*55a1d80aSGerd Hoffmann     .event = virtio_input_handle_event,
436*55a1d80aSGerd Hoffmann     .sync  = virtio_input_handle_sync,
437*55a1d80aSGerd Hoffmann };
438*55a1d80aSGerd Hoffmann 
439*55a1d80aSGerd Hoffmann static struct virtio_input_config virtio_tablet_config[] = {
440*55a1d80aSGerd Hoffmann     {
441*55a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_NAME,
442*55a1d80aSGerd Hoffmann         .size      = sizeof(VIRTIO_ID_NAME_TABLET),
443*55a1d80aSGerd Hoffmann         .u.string  = VIRTIO_ID_NAME_TABLET,
444*55a1d80aSGerd Hoffmann     },{
445*55a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
446*55a1d80aSGerd Hoffmann         .size      = sizeof(struct virtio_input_devids),
447*55a1d80aSGerd Hoffmann         .u.ids     = {
448*55a1d80aSGerd Hoffmann             .bustype = const_le16(BUS_VIRTUAL),
449*55a1d80aSGerd Hoffmann             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
450*55a1d80aSGerd Hoffmann             .product = const_le16(0x0003),
451*55a1d80aSGerd Hoffmann             .version = const_le16(0x0001),
452*55a1d80aSGerd Hoffmann         },
453*55a1d80aSGerd Hoffmann     },{
454*55a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
455*55a1d80aSGerd Hoffmann         .subsel    = EV_ABS,
456*55a1d80aSGerd Hoffmann         .size      = 1,
457*55a1d80aSGerd Hoffmann         .u.bitmap  = {
458*55a1d80aSGerd Hoffmann             (1 << ABS_X) | (1 << ABS_Y),
459*55a1d80aSGerd Hoffmann         },
460*55a1d80aSGerd Hoffmann     },{
461*55a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
462*55a1d80aSGerd Hoffmann         .subsel    = ABS_X,
463*55a1d80aSGerd Hoffmann         .size      = sizeof(virtio_input_absinfo),
464*55a1d80aSGerd Hoffmann         .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE),
465*55a1d80aSGerd Hoffmann     },{
466*55a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
467*55a1d80aSGerd Hoffmann         .subsel    = ABS_Y,
468*55a1d80aSGerd Hoffmann         .size      = sizeof(virtio_input_absinfo),
469*55a1d80aSGerd Hoffmann         .u.abs.max = const_le32(INPUT_EVENT_ABS_SIZE),
470*55a1d80aSGerd Hoffmann     },
471*55a1d80aSGerd Hoffmann     { /* end of list */ },
472*55a1d80aSGerd Hoffmann };
473*55a1d80aSGerd Hoffmann 
474*55a1d80aSGerd Hoffmann static void virtio_tablet_init(Object *obj)
475*55a1d80aSGerd Hoffmann {
476*55a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
477*55a1d80aSGerd Hoffmann     VirtIOInput *vinput = VIRTIO_INPUT(obj);
478*55a1d80aSGerd Hoffmann 
479*55a1d80aSGerd Hoffmann     vhid->handler = &virtio_tablet_handler;
480*55a1d80aSGerd Hoffmann     virtio_input_init_config(vinput, virtio_tablet_config);
481*55a1d80aSGerd Hoffmann     virtio_input_key_config(vinput, keymap_button,
482*55a1d80aSGerd Hoffmann                             ARRAY_SIZE(keymap_button));
483*55a1d80aSGerd Hoffmann }
484*55a1d80aSGerd Hoffmann 
485*55a1d80aSGerd Hoffmann static const TypeInfo virtio_tablet_info = {
486*55a1d80aSGerd Hoffmann     .name          = TYPE_VIRTIO_TABLET,
487*55a1d80aSGerd Hoffmann     .parent        = TYPE_VIRTIO_INPUT_HID,
488*55a1d80aSGerd Hoffmann     .instance_size = sizeof(VirtIOInputHID),
489*55a1d80aSGerd Hoffmann     .instance_init = virtio_tablet_init,
490*55a1d80aSGerd Hoffmann };
491*55a1d80aSGerd Hoffmann 
492*55a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
493*55a1d80aSGerd Hoffmann 
494*55a1d80aSGerd Hoffmann static void virtio_register_types(void)
495*55a1d80aSGerd Hoffmann {
496*55a1d80aSGerd Hoffmann     type_register_static(&virtio_input_hid_info);
497*55a1d80aSGerd Hoffmann     type_register_static(&virtio_keyboard_info);
498*55a1d80aSGerd Hoffmann     type_register_static(&virtio_mouse_info);
499*55a1d80aSGerd Hoffmann     type_register_static(&virtio_tablet_info);
500*55a1d80aSGerd Hoffmann }
501*55a1d80aSGerd Hoffmann 
502*55a1d80aSGerd Hoffmann type_init(virtio_register_types)
503