2 * This work is licensed under the terms of the GNU GPL, version 2 or
3 * (at your option) any later version. See the COPYING file in the
7 #include "qemu/osdep.h"
9 #include "qemu/module.h"
11 #include "hw/virtio/virtio.h"
12 #include "hw/qdev-properties.h"
13 #include "hw/virtio/virtio-input.h"
15 #include "ui/console.h"
17 #include "standard-headers/linux/input.h"
19 #define VIRTIO_ID_NAME_KEYBOARD "QEMU Virtio Keyboard"
20 #define VIRTIO_ID_NAME_MOUSE "QEMU Virtio Mouse"
21 #define VIRTIO_ID_NAME_TABLET "QEMU Virtio Tablet"
22 #define VIRTIO_ID_NAME_MULTITOUCH "QEMU Virtio MultiTouch"
24 /* ----------------------------------------------------------------- */
26 static const unsigned short keymap_button
[INPUT_BUTTON__MAX
] = {
27 [INPUT_BUTTON_LEFT
] = BTN_LEFT
,
28 [INPUT_BUTTON_RIGHT
] = BTN_RIGHT
,
29 [INPUT_BUTTON_MIDDLE
] = BTN_MIDDLE
,
30 [INPUT_BUTTON_WHEEL_UP
] = BTN_GEAR_UP
,
31 [INPUT_BUTTON_WHEEL_DOWN
] = BTN_GEAR_DOWN
,
32 [INPUT_BUTTON_SIDE
] = BTN_SIDE
,
33 [INPUT_BUTTON_EXTRA
] = BTN_EXTRA
,
34 [INPUT_BUTTON_TOUCH
] = BTN_TOUCH
,
37 static const unsigned short axismap_rel
[INPUT_AXIS__MAX
] = {
38 [INPUT_AXIS_X
] = REL_X
,
39 [INPUT_AXIS_Y
] = REL_Y
,
42 static const unsigned short axismap_abs
[INPUT_AXIS__MAX
] = {
43 [INPUT_AXIS_X
] = ABS_X
,
44 [INPUT_AXIS_Y
] = ABS_Y
,
47 static const unsigned short axismap_tch
[INPUT_AXIS__MAX
] = {
48 [INPUT_AXIS_X
] = ABS_MT_POSITION_X
,
49 [INPUT_AXIS_Y
] = ABS_MT_POSITION_Y
,
52 /* ----------------------------------------------------------------- */
54 static void virtio_input_extend_config(VirtIOInput
*vinput
,
55 const unsigned short *map
,
57 uint8_t select
, uint8_t subsel
)
59 virtio_input_config ext
;
60 int i
, bit
, byte
, bmax
= 0;
62 memset(&ext
, 0, sizeof(ext
));
63 for (i
= 0; i
< mapsize
; i
++) {
70 ext
.u
.bitmap
[byte
] |= (1 << bit
);
78 virtio_input_add_config(vinput
, &ext
);
81 static void virtio_input_handle_event(DeviceState
*dev
, QemuConsole
*src
,
84 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(dev
);
85 VirtIOInput
*vinput
= VIRTIO_INPUT(dev
);
86 virtio_input_event event
;
91 InputMultiTouchEvent
*mtt
;
94 case INPUT_EVENT_KIND_KEY
:
95 key
= evt
->u
.key
.data
;
96 qcode
= qemu_input_key_value_to_qcode(key
->key
);
97 if (qcode
< qemu_input_map_qcode_to_linux_len
&&
98 qemu_input_map_qcode_to_linux
[qcode
]) {
99 event
.type
= cpu_to_le16(EV_KEY
);
100 event
.code
= cpu_to_le16(qemu_input_map_qcode_to_linux
[qcode
]);
101 event
.value
= cpu_to_le32(key
->down
? 1 : 0);
102 virtio_input_send(vinput
, &event
);
105 fprintf(stderr
, "%s: unmapped key: %d [%s]\n", __func__
,
106 qcode
, QKeyCode_str(qcode
));
110 case INPUT_EVENT_KIND_BTN
:
111 btn
= evt
->u
.btn
.data
;
112 if (vhid
->wheel_axis
&&
113 (btn
->button
== INPUT_BUTTON_WHEEL_UP
||
114 btn
->button
== INPUT_BUTTON_WHEEL_DOWN
) &&
116 event
.type
= cpu_to_le16(EV_REL
);
117 event
.code
= cpu_to_le16(REL_WHEEL
);
118 event
.value
= cpu_to_le32(btn
->button
== INPUT_BUTTON_WHEEL_UP
120 virtio_input_send(vinput
, &event
);
121 } else if (keymap_button
[btn
->button
]) {
122 event
.type
= cpu_to_le16(EV_KEY
);
123 event
.code
= cpu_to_le16(keymap_button
[btn
->button
]);
124 event
.value
= cpu_to_le32(btn
->down
? 1 : 0);
125 virtio_input_send(vinput
, &event
);
128 fprintf(stderr
, "%s: unmapped button: %d [%s]\n", __func__
,
130 InputButton_str(btn
->button
));
134 case INPUT_EVENT_KIND_REL
:
135 move
= evt
->u
.rel
.data
;
136 event
.type
= cpu_to_le16(EV_REL
);
137 event
.code
= cpu_to_le16(axismap_rel
[move
->axis
]);
138 event
.value
= cpu_to_le32(move
->value
);
139 virtio_input_send(vinput
, &event
);
141 case INPUT_EVENT_KIND_ABS
:
142 move
= evt
->u
.abs
.data
;
143 event
.type
= cpu_to_le16(EV_ABS
);
144 event
.code
= cpu_to_le16(axismap_abs
[move
->axis
]);
145 event
.value
= cpu_to_le32(move
->value
);
146 virtio_input_send(vinput
, &event
);
148 case INPUT_EVENT_KIND_MTT
:
149 mtt
= evt
->u
.mtt
.data
;
150 if (mtt
->type
== INPUT_MULTI_TOUCH_TYPE_DATA
) {
151 event
.type
= cpu_to_le16(EV_ABS
);
152 event
.code
= cpu_to_le16(axismap_tch
[mtt
->axis
]);
153 event
.value
= cpu_to_le32(mtt
->value
);
154 virtio_input_send(vinput
, &event
);
156 event
.type
= cpu_to_le16(EV_ABS
);
157 event
.code
= cpu_to_le16(ABS_MT_SLOT
);
158 event
.value
= cpu_to_le32(mtt
->slot
);
159 virtio_input_send(vinput
, &event
);
160 event
.type
= cpu_to_le16(EV_ABS
);
161 event
.code
= cpu_to_le16(ABS_MT_TRACKING_ID
);
162 event
.value
= cpu_to_le32(mtt
->tracking_id
);
163 virtio_input_send(vinput
, &event
);
172 static void virtio_input_handle_sync(DeviceState
*dev
)
174 VirtIOInput
*vinput
= VIRTIO_INPUT(dev
);
175 virtio_input_event event
= {
176 .type
= cpu_to_le16(EV_SYN
),
177 .code
= cpu_to_le16(SYN_REPORT
),
181 virtio_input_send(vinput
, &event
);
184 static void virtio_input_hid_realize(DeviceState
*dev
, Error
**errp
)
186 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(dev
);
188 vhid
->hs
= qemu_input_handler_register(dev
, vhid
->handler
);
189 if (vhid
->display
&& vhid
->hs
) {
190 qemu_input_handler_bind(vhid
->hs
, vhid
->display
, vhid
->head
, NULL
);
194 static void virtio_input_hid_unrealize(DeviceState
*dev
)
196 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(dev
);
197 qemu_input_handler_unregister(vhid
->hs
);
200 static void virtio_input_hid_change_active(VirtIOInput
*vinput
)
202 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(vinput
);
204 if (vinput
->active
) {
205 qemu_input_handler_activate(vhid
->hs
);
207 qemu_input_handler_deactivate(vhid
->hs
);
211 static void virtio_input_hid_handle_status(VirtIOInput
*vinput
,
212 virtio_input_event
*event
)
214 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(vinput
);
217 switch (le16_to_cpu(event
->type
)) {
219 if (event
->code
== LED_NUML
) {
220 ledbit
= QEMU_NUM_LOCK_LED
;
221 } else if (event
->code
== LED_CAPSL
) {
222 ledbit
= QEMU_CAPS_LOCK_LED
;
223 } else if (event
->code
== LED_SCROLLL
) {
224 ledbit
= QEMU_SCROLL_LOCK_LED
;
227 vhid
->ledstate
|= ledbit
;
229 vhid
->ledstate
&= ~ledbit
;
231 kbd_put_ledstate(vhid
->ledstate
);
234 fprintf(stderr
, "%s: unknown type %d\n", __func__
,
235 le16_to_cpu(event
->type
));
240 static Property virtio_input_hid_properties
[] = {
241 DEFINE_PROP_STRING("display", VirtIOInputHID
, display
),
242 DEFINE_PROP_UINT32("head", VirtIOInputHID
, head
, 0),
243 DEFINE_PROP_END_OF_LIST(),
246 static void virtio_input_hid_class_init(ObjectClass
*klass
, void *data
)
248 DeviceClass
*dc
= DEVICE_CLASS(klass
);
249 VirtIOInputClass
*vic
= VIRTIO_INPUT_CLASS(klass
);
251 device_class_set_props(dc
, virtio_input_hid_properties
);
252 vic
->realize
= virtio_input_hid_realize
;
253 vic
->unrealize
= virtio_input_hid_unrealize
;
254 vic
->change_active
= virtio_input_hid_change_active
;
255 vic
->handle_status
= virtio_input_hid_handle_status
;
258 static const TypeInfo virtio_input_hid_info
= {
259 .name
= TYPE_VIRTIO_INPUT_HID
,
260 .parent
= TYPE_VIRTIO_INPUT
,
261 .instance_size
= sizeof(VirtIOInputHID
),
262 .class_init
= virtio_input_hid_class_init
,
266 /* ----------------------------------------------------------------- */
268 static QemuInputHandler virtio_keyboard_handler
= {
269 .name
= VIRTIO_ID_NAME_KEYBOARD
,
270 .mask
= INPUT_EVENT_MASK_KEY
,
271 .event
= virtio_input_handle_event
,
272 .sync
= virtio_input_handle_sync
,
275 static struct virtio_input_config virtio_keyboard_config
[] = {
277 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
278 .size
= sizeof(VIRTIO_ID_NAME_KEYBOARD
),
279 .u
.string
= VIRTIO_ID_NAME_KEYBOARD
,
281 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
282 .size
= sizeof(struct virtio_input_devids
),
284 .bustype
= const_le16(BUS_VIRTUAL
),
285 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
286 .product
= const_le16(0x0001),
287 .version
= const_le16(0x0001),
290 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
294 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
298 (1 << LED_NUML
) | (1 << LED_CAPSL
) | (1 << LED_SCROLLL
),
301 { /* end of list */ },
304 static void virtio_keyboard_init(Object
*obj
)
306 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(obj
);
307 VirtIOInput
*vinput
= VIRTIO_INPUT(obj
);
309 vhid
->handler
= &virtio_keyboard_handler
;
310 virtio_input_init_config(vinput
, virtio_keyboard_config
);
311 virtio_input_extend_config(vinput
, qemu_input_map_qcode_to_linux
,
312 qemu_input_map_qcode_to_linux_len
,
313 VIRTIO_INPUT_CFG_EV_BITS
, EV_KEY
);
316 static const TypeInfo virtio_keyboard_info
= {
317 .name
= TYPE_VIRTIO_KEYBOARD
,
318 .parent
= TYPE_VIRTIO_INPUT_HID
,
319 .instance_size
= sizeof(VirtIOInputHID
),
320 .instance_init
= virtio_keyboard_init
,
323 /* ----------------------------------------------------------------- */
325 static QemuInputHandler virtio_mouse_handler
= {
326 .name
= VIRTIO_ID_NAME_MOUSE
,
327 .mask
= INPUT_EVENT_MASK_BTN
| INPUT_EVENT_MASK_REL
,
328 .event
= virtio_input_handle_event
,
329 .sync
= virtio_input_handle_sync
,
332 static struct virtio_input_config virtio_mouse_config_v1
[] = {
334 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
335 .size
= sizeof(VIRTIO_ID_NAME_MOUSE
),
336 .u
.string
= VIRTIO_ID_NAME_MOUSE
,
338 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
339 .size
= sizeof(struct virtio_input_devids
),
341 .bustype
= const_le16(BUS_VIRTUAL
),
342 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
343 .product
= const_le16(0x0002),
344 .version
= const_le16(0x0001),
347 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
351 (1 << REL_X
) | (1 << REL_Y
),
354 { /* end of list */ },
357 static struct virtio_input_config virtio_mouse_config_v2
[] = {
359 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
360 .size
= sizeof(VIRTIO_ID_NAME_MOUSE
),
361 .u
.string
= VIRTIO_ID_NAME_MOUSE
,
363 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
364 .size
= sizeof(struct virtio_input_devids
),
366 .bustype
= const_le16(BUS_VIRTUAL
),
367 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
368 .product
= const_le16(0x0002),
369 .version
= const_le16(0x0002),
372 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
376 (1 << REL_X
) | (1 << REL_Y
),
377 (1 << (REL_WHEEL
- 8))
380 { /* end of list */ },
383 static Property virtio_mouse_properties
[] = {
384 DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID
, wheel_axis
, true),
385 DEFINE_PROP_END_OF_LIST(),
388 static void virtio_mouse_class_init(ObjectClass
*klass
, void *data
)
390 DeviceClass
*dc
= DEVICE_CLASS(klass
);
392 device_class_set_props(dc
, virtio_mouse_properties
);
395 static void virtio_mouse_init(Object
*obj
)
397 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(obj
);
398 VirtIOInput
*vinput
= VIRTIO_INPUT(obj
);
400 vhid
->handler
= &virtio_mouse_handler
;
401 virtio_input_init_config(vinput
, vhid
->wheel_axis
402 ? virtio_mouse_config_v2
403 : virtio_mouse_config_v1
);
404 virtio_input_extend_config(vinput
, keymap_button
,
405 ARRAY_SIZE(keymap_button
),
406 VIRTIO_INPUT_CFG_EV_BITS
, EV_KEY
);
409 static const TypeInfo virtio_mouse_info
= {
410 .name
= TYPE_VIRTIO_MOUSE
,
411 .parent
= TYPE_VIRTIO_INPUT_HID
,
412 .instance_size
= sizeof(VirtIOInputHID
),
413 .instance_init
= virtio_mouse_init
,
414 .class_init
= virtio_mouse_class_init
,
417 /* ----------------------------------------------------------------- */
419 static QemuInputHandler virtio_tablet_handler
= {
420 .name
= VIRTIO_ID_NAME_TABLET
,
421 .mask
= INPUT_EVENT_MASK_BTN
| INPUT_EVENT_MASK_ABS
,
422 .event
= virtio_input_handle_event
,
423 .sync
= virtio_input_handle_sync
,
426 static struct virtio_input_config virtio_tablet_config_v1
[] = {
428 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
429 .size
= sizeof(VIRTIO_ID_NAME_TABLET
),
430 .u
.string
= VIRTIO_ID_NAME_TABLET
,
432 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
433 .size
= sizeof(struct virtio_input_devids
),
435 .bustype
= const_le16(BUS_VIRTUAL
),
436 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
437 .product
= const_le16(0x0003),
438 .version
= const_le16(0x0001),
441 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
445 (1 << ABS_X
) | (1 << ABS_Y
),
448 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
450 .size
= sizeof(virtio_input_absinfo
),
451 .u
.abs
.min
= const_le32(INPUT_EVENT_ABS_MIN
),
452 .u
.abs
.max
= const_le32(INPUT_EVENT_ABS_MAX
),
454 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
456 .size
= sizeof(virtio_input_absinfo
),
457 .u
.abs
.min
= const_le32(INPUT_EVENT_ABS_MIN
),
458 .u
.abs
.max
= const_le32(INPUT_EVENT_ABS_MAX
),
460 { /* end of list */ },
463 static struct virtio_input_config virtio_tablet_config_v2
[] = {
465 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
466 .size
= sizeof(VIRTIO_ID_NAME_TABLET
),
467 .u
.string
= VIRTIO_ID_NAME_TABLET
,
469 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
470 .size
= sizeof(struct virtio_input_devids
),
472 .bustype
= const_le16(BUS_VIRTUAL
),
473 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
474 .product
= const_le16(0x0003),
475 .version
= const_le16(0x0002),
478 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
482 (1 << ABS_X
) | (1 << ABS_Y
),
485 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
490 (1 << (REL_WHEEL
- 8))
493 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
495 .size
= sizeof(virtio_input_absinfo
),
496 .u
.abs
.min
= const_le32(INPUT_EVENT_ABS_MIN
),
497 .u
.abs
.max
= const_le32(INPUT_EVENT_ABS_MAX
),
499 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
501 .size
= sizeof(virtio_input_absinfo
),
502 .u
.abs
.min
= const_le32(INPUT_EVENT_ABS_MIN
),
503 .u
.abs
.max
= const_le32(INPUT_EVENT_ABS_MAX
),
505 { /* end of list */ },
508 static Property virtio_tablet_properties
[] = {
509 DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID
, wheel_axis
, true),
510 DEFINE_PROP_END_OF_LIST(),
513 static void virtio_tablet_class_init(ObjectClass
*klass
, void *data
)
515 DeviceClass
*dc
= DEVICE_CLASS(klass
);
517 device_class_set_props(dc
, virtio_tablet_properties
);
520 static void virtio_tablet_init(Object
*obj
)
522 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(obj
);
523 VirtIOInput
*vinput
= VIRTIO_INPUT(obj
);
525 vhid
->handler
= &virtio_tablet_handler
;
526 virtio_input_init_config(vinput
, vhid
->wheel_axis
527 ? virtio_tablet_config_v2
528 : virtio_tablet_config_v1
);
529 virtio_input_extend_config(vinput
, keymap_button
,
530 ARRAY_SIZE(keymap_button
),
531 VIRTIO_INPUT_CFG_EV_BITS
, EV_KEY
);
534 static const TypeInfo virtio_tablet_info
= {
535 .name
= TYPE_VIRTIO_TABLET
,
536 .parent
= TYPE_VIRTIO_INPUT_HID
,
537 .instance_size
= sizeof(VirtIOInputHID
),
538 .instance_init
= virtio_tablet_init
,
539 .class_init
= virtio_tablet_class_init
,
542 /* ----------------------------------------------------------------- */
544 static QemuInputHandler virtio_multitouch_handler
= {
545 .name
= VIRTIO_ID_NAME_MULTITOUCH
,
546 .mask
= INPUT_EVENT_MASK_BTN
| INPUT_EVENT_MASK_MTT
,
547 .event
= virtio_input_handle_event
,
548 .sync
= virtio_input_handle_sync
,
551 static struct virtio_input_config virtio_multitouch_config
[] = {
553 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
554 .size
= sizeof(VIRTIO_ID_NAME_MULTITOUCH
),
555 .u
.string
= VIRTIO_ID_NAME_MULTITOUCH
,
557 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
558 .size
= sizeof(struct virtio_input_devids
),
560 .bustype
= const_le16(BUS_VIRTUAL
),
561 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
562 .product
= const_le16(0x0003),
563 .version
= const_le16(0x0001),
566 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
567 .subsel
= ABS_MT_SLOT
,
568 .size
= sizeof(virtio_input_absinfo
),
569 .u
.abs
.min
= const_le32(INPUT_EVENT_SLOTS_MIN
),
570 .u
.abs
.max
= const_le32(INPUT_EVENT_SLOTS_MAX
),
572 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
573 .subsel
= ABS_MT_TRACKING_ID
,
574 .size
= sizeof(virtio_input_absinfo
),
575 .u
.abs
.min
= const_le32(INPUT_EVENT_SLOTS_MIN
),
576 .u
.abs
.max
= const_le32(INPUT_EVENT_SLOTS_MAX
),
578 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
579 .subsel
= ABS_MT_POSITION_X
,
580 .size
= sizeof(virtio_input_absinfo
),
581 .u
.abs
.min
= const_le32(INPUT_EVENT_ABS_MIN
),
582 .u
.abs
.max
= const_le32(INPUT_EVENT_ABS_MAX
),
584 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
585 .subsel
= ABS_MT_POSITION_Y
,
586 .size
= sizeof(virtio_input_absinfo
),
587 .u
.abs
.min
= const_le32(INPUT_EVENT_ABS_MIN
),
588 .u
.abs
.max
= const_le32(INPUT_EVENT_ABS_MAX
),
590 { /* end of list */ },
593 static void virtio_multitouch_init(Object
*obj
)
595 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(obj
);
596 VirtIOInput
*vinput
= VIRTIO_INPUT(obj
);
597 unsigned short abs_props
[] = {
600 unsigned short abs_bits
[] = {
607 vhid
->handler
= &virtio_multitouch_handler
;
608 virtio_input_init_config(vinput
, virtio_multitouch_config
);
609 virtio_input_extend_config(vinput
, keymap_button
,
610 ARRAY_SIZE(keymap_button
),
611 VIRTIO_INPUT_CFG_EV_BITS
, EV_KEY
);
612 virtio_input_extend_config(vinput
, abs_props
,
613 ARRAY_SIZE(abs_props
),
614 VIRTIO_INPUT_CFG_PROP_BITS
, 0);
615 virtio_input_extend_config(vinput
, abs_bits
,
616 ARRAY_SIZE(abs_bits
),
617 VIRTIO_INPUT_CFG_EV_BITS
, EV_ABS
);
620 static const TypeInfo virtio_multitouch_info
= {
621 .name
= TYPE_VIRTIO_MULTITOUCH
,
622 .parent
= TYPE_VIRTIO_INPUT_HID
,
623 .instance_size
= sizeof(VirtIOInputHID
),
624 .instance_init
= virtio_multitouch_init
,
627 /* ----------------------------------------------------------------- */
629 static void virtio_register_types(void)
631 type_register_static(&virtio_input_hid_info
);
632 type_register_static(&virtio_keyboard_info
);
633 type_register_static(&virtio_mouse_info
);
634 type_register_static(&virtio_tablet_info
);
635 type_register_static(&virtio_multitouch_info
);
638 type_init(virtio_register_types
)