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"
23 /* ----------------------------------------------------------------- */
25 static const unsigned short keymap_button
[INPUT_BUTTON__MAX
] = {
26 [INPUT_BUTTON_LEFT
] = BTN_LEFT
,
27 [INPUT_BUTTON_RIGHT
] = BTN_RIGHT
,
28 [INPUT_BUTTON_MIDDLE
] = BTN_MIDDLE
,
29 [INPUT_BUTTON_WHEEL_UP
] = BTN_GEAR_UP
,
30 [INPUT_BUTTON_WHEEL_DOWN
] = BTN_GEAR_DOWN
,
31 [INPUT_BUTTON_SIDE
] = BTN_SIDE
,
32 [INPUT_BUTTON_EXTRA
] = BTN_EXTRA
,
35 static const unsigned short axismap_rel
[INPUT_AXIS__MAX
] = {
36 [INPUT_AXIS_X
] = REL_X
,
37 [INPUT_AXIS_Y
] = REL_Y
,
40 static const unsigned short axismap_abs
[INPUT_AXIS__MAX
] = {
41 [INPUT_AXIS_X
] = ABS_X
,
42 [INPUT_AXIS_Y
] = ABS_Y
,
45 /* ----------------------------------------------------------------- */
47 static void virtio_input_key_config(VirtIOInput
*vinput
,
48 const unsigned short *keymap
,
51 virtio_input_config keys
;
52 int i
, bit
, byte
, bmax
= 0;
54 memset(&keys
, 0, sizeof(keys
));
55 for (i
= 0; i
< mapsize
; i
++) {
62 keys
.u
.bitmap
[byte
] |= (1 << bit
);
67 keys
.select
= VIRTIO_INPUT_CFG_EV_BITS
;
70 virtio_input_add_config(vinput
, &keys
);
73 static void virtio_input_handle_event(DeviceState
*dev
, QemuConsole
*src
,
76 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(dev
);
77 VirtIOInput
*vinput
= VIRTIO_INPUT(dev
);
78 virtio_input_event event
;
85 case INPUT_EVENT_KIND_KEY
:
86 key
= evt
->u
.key
.data
;
87 qcode
= qemu_input_key_value_to_qcode(key
->key
);
88 if (qcode
< qemu_input_map_qcode_to_linux_len
&&
89 qemu_input_map_qcode_to_linux
[qcode
]) {
90 event
.type
= cpu_to_le16(EV_KEY
);
91 event
.code
= cpu_to_le16(qemu_input_map_qcode_to_linux
[qcode
]);
92 event
.value
= cpu_to_le32(key
->down
? 1 : 0);
93 virtio_input_send(vinput
, &event
);
96 fprintf(stderr
, "%s: unmapped key: %d [%s]\n", __func__
,
97 qcode
, QKeyCode_str(qcode
));
101 case INPUT_EVENT_KIND_BTN
:
102 btn
= evt
->u
.btn
.data
;
103 if (vhid
->wheel_axis
&&
104 (btn
->button
== INPUT_BUTTON_WHEEL_UP
||
105 btn
->button
== INPUT_BUTTON_WHEEL_DOWN
) &&
107 event
.type
= cpu_to_le16(EV_REL
);
108 event
.code
= cpu_to_le16(REL_WHEEL
);
109 event
.value
= cpu_to_le32(btn
->button
== INPUT_BUTTON_WHEEL_UP
111 virtio_input_send(vinput
, &event
);
112 } else if (keymap_button
[btn
->button
]) {
113 event
.type
= cpu_to_le16(EV_KEY
);
114 event
.code
= cpu_to_le16(keymap_button
[btn
->button
]);
115 event
.value
= cpu_to_le32(btn
->down
? 1 : 0);
116 virtio_input_send(vinput
, &event
);
119 fprintf(stderr
, "%s: unmapped button: %d [%s]\n", __func__
,
121 InputButton_str(btn
->button
));
125 case INPUT_EVENT_KIND_REL
:
126 move
= evt
->u
.rel
.data
;
127 event
.type
= cpu_to_le16(EV_REL
);
128 event
.code
= cpu_to_le16(axismap_rel
[move
->axis
]);
129 event
.value
= cpu_to_le32(move
->value
);
130 virtio_input_send(vinput
, &event
);
132 case INPUT_EVENT_KIND_ABS
:
133 move
= evt
->u
.abs
.data
;
134 event
.type
= cpu_to_le16(EV_ABS
);
135 event
.code
= cpu_to_le16(axismap_abs
[move
->axis
]);
136 event
.value
= cpu_to_le32(move
->value
);
137 virtio_input_send(vinput
, &event
);
145 static void virtio_input_handle_sync(DeviceState
*dev
)
147 VirtIOInput
*vinput
= VIRTIO_INPUT(dev
);
148 virtio_input_event event
= {
149 .type
= cpu_to_le16(EV_SYN
),
150 .code
= cpu_to_le16(SYN_REPORT
),
154 virtio_input_send(vinput
, &event
);
157 static void virtio_input_hid_realize(DeviceState
*dev
, Error
**errp
)
159 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(dev
);
161 vhid
->hs
= qemu_input_handler_register(dev
, vhid
->handler
);
162 if (vhid
->display
&& vhid
->hs
) {
163 qemu_input_handler_bind(vhid
->hs
, vhid
->display
, vhid
->head
, NULL
);
167 static void virtio_input_hid_unrealize(DeviceState
*dev
)
169 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(dev
);
170 qemu_input_handler_unregister(vhid
->hs
);
173 static void virtio_input_hid_change_active(VirtIOInput
*vinput
)
175 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(vinput
);
177 if (vinput
->active
) {
178 qemu_input_handler_activate(vhid
->hs
);
180 qemu_input_handler_deactivate(vhid
->hs
);
184 static void virtio_input_hid_handle_status(VirtIOInput
*vinput
,
185 virtio_input_event
*event
)
187 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(vinput
);
190 switch (le16_to_cpu(event
->type
)) {
192 if (event
->code
== LED_NUML
) {
193 ledbit
= QEMU_NUM_LOCK_LED
;
194 } else if (event
->code
== LED_CAPSL
) {
195 ledbit
= QEMU_CAPS_LOCK_LED
;
196 } else if (event
->code
== LED_SCROLLL
) {
197 ledbit
= QEMU_SCROLL_LOCK_LED
;
200 vhid
->ledstate
|= ledbit
;
202 vhid
->ledstate
&= ~ledbit
;
204 kbd_put_ledstate(vhid
->ledstate
);
207 fprintf(stderr
, "%s: unknown type %d\n", __func__
,
208 le16_to_cpu(event
->type
));
213 static Property virtio_input_hid_properties
[] = {
214 DEFINE_PROP_STRING("display", VirtIOInputHID
, display
),
215 DEFINE_PROP_UINT32("head", VirtIOInputHID
, head
, 0),
216 DEFINE_PROP_END_OF_LIST(),
219 static void virtio_input_hid_class_init(ObjectClass
*klass
, void *data
)
221 DeviceClass
*dc
= DEVICE_CLASS(klass
);
222 VirtIOInputClass
*vic
= VIRTIO_INPUT_CLASS(klass
);
224 device_class_set_props(dc
, virtio_input_hid_properties
);
225 vic
->realize
= virtio_input_hid_realize
;
226 vic
->unrealize
= virtio_input_hid_unrealize
;
227 vic
->change_active
= virtio_input_hid_change_active
;
228 vic
->handle_status
= virtio_input_hid_handle_status
;
231 static const TypeInfo virtio_input_hid_info
= {
232 .name
= TYPE_VIRTIO_INPUT_HID
,
233 .parent
= TYPE_VIRTIO_INPUT
,
234 .instance_size
= sizeof(VirtIOInputHID
),
235 .class_init
= virtio_input_hid_class_init
,
239 /* ----------------------------------------------------------------- */
241 static QemuInputHandler virtio_keyboard_handler
= {
242 .name
= VIRTIO_ID_NAME_KEYBOARD
,
243 .mask
= INPUT_EVENT_MASK_KEY
,
244 .event
= virtio_input_handle_event
,
245 .sync
= virtio_input_handle_sync
,
248 static struct virtio_input_config virtio_keyboard_config
[] = {
250 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
251 .size
= sizeof(VIRTIO_ID_NAME_KEYBOARD
),
252 .u
.string
= VIRTIO_ID_NAME_KEYBOARD
,
254 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
255 .size
= sizeof(struct virtio_input_devids
),
257 .bustype
= const_le16(BUS_VIRTUAL
),
258 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
259 .product
= const_le16(0x0001),
260 .version
= const_le16(0x0001),
263 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
267 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
271 (1 << LED_NUML
) | (1 << LED_CAPSL
) | (1 << LED_SCROLLL
),
274 { /* end of list */ },
277 static void virtio_keyboard_init(Object
*obj
)
279 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(obj
);
280 VirtIOInput
*vinput
= VIRTIO_INPUT(obj
);
282 vhid
->handler
= &virtio_keyboard_handler
;
283 virtio_input_init_config(vinput
, virtio_keyboard_config
);
284 virtio_input_key_config(vinput
, qemu_input_map_qcode_to_linux
,
285 qemu_input_map_qcode_to_linux_len
);
288 static const TypeInfo virtio_keyboard_info
= {
289 .name
= TYPE_VIRTIO_KEYBOARD
,
290 .parent
= TYPE_VIRTIO_INPUT_HID
,
291 .instance_size
= sizeof(VirtIOInputHID
),
292 .instance_init
= virtio_keyboard_init
,
295 /* ----------------------------------------------------------------- */
297 static QemuInputHandler virtio_mouse_handler
= {
298 .name
= VIRTIO_ID_NAME_MOUSE
,
299 .mask
= INPUT_EVENT_MASK_BTN
| INPUT_EVENT_MASK_REL
,
300 .event
= virtio_input_handle_event
,
301 .sync
= virtio_input_handle_sync
,
304 static struct virtio_input_config virtio_mouse_config_v1
[] = {
306 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
307 .size
= sizeof(VIRTIO_ID_NAME_MOUSE
),
308 .u
.string
= VIRTIO_ID_NAME_MOUSE
,
310 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
311 .size
= sizeof(struct virtio_input_devids
),
313 .bustype
= const_le16(BUS_VIRTUAL
),
314 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
315 .product
= const_le16(0x0002),
316 .version
= const_le16(0x0001),
319 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
323 (1 << REL_X
) | (1 << REL_Y
),
326 { /* end of list */ },
329 static struct virtio_input_config virtio_mouse_config_v2
[] = {
331 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
332 .size
= sizeof(VIRTIO_ID_NAME_MOUSE
),
333 .u
.string
= VIRTIO_ID_NAME_MOUSE
,
335 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
336 .size
= sizeof(struct virtio_input_devids
),
338 .bustype
= const_le16(BUS_VIRTUAL
),
339 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
340 .product
= const_le16(0x0002),
341 .version
= const_le16(0x0002),
344 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
348 (1 << REL_X
) | (1 << REL_Y
),
349 (1 << (REL_WHEEL
- 8))
352 { /* end of list */ },
355 static Property virtio_mouse_properties
[] = {
356 DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID
, wheel_axis
, true),
357 DEFINE_PROP_END_OF_LIST(),
360 static void virtio_mouse_class_init(ObjectClass
*klass
, void *data
)
362 DeviceClass
*dc
= DEVICE_CLASS(klass
);
364 device_class_set_props(dc
, virtio_mouse_properties
);
367 static void virtio_mouse_init(Object
*obj
)
369 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(obj
);
370 VirtIOInput
*vinput
= VIRTIO_INPUT(obj
);
372 vhid
->handler
= &virtio_mouse_handler
;
373 virtio_input_init_config(vinput
, vhid
->wheel_axis
374 ? virtio_mouse_config_v2
375 : virtio_mouse_config_v1
);
376 virtio_input_key_config(vinput
, keymap_button
,
377 ARRAY_SIZE(keymap_button
));
380 static const TypeInfo virtio_mouse_info
= {
381 .name
= TYPE_VIRTIO_MOUSE
,
382 .parent
= TYPE_VIRTIO_INPUT_HID
,
383 .instance_size
= sizeof(VirtIOInputHID
),
384 .instance_init
= virtio_mouse_init
,
385 .class_init
= virtio_mouse_class_init
,
388 /* ----------------------------------------------------------------- */
390 static QemuInputHandler virtio_tablet_handler
= {
391 .name
= VIRTIO_ID_NAME_TABLET
,
392 .mask
= INPUT_EVENT_MASK_BTN
| INPUT_EVENT_MASK_ABS
,
393 .event
= virtio_input_handle_event
,
394 .sync
= virtio_input_handle_sync
,
397 static struct virtio_input_config virtio_tablet_config_v1
[] = {
399 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
400 .size
= sizeof(VIRTIO_ID_NAME_TABLET
),
401 .u
.string
= VIRTIO_ID_NAME_TABLET
,
403 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
404 .size
= sizeof(struct virtio_input_devids
),
406 .bustype
= const_le16(BUS_VIRTUAL
),
407 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
408 .product
= const_le16(0x0003),
409 .version
= const_le16(0x0001),
412 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
416 (1 << ABS_X
) | (1 << ABS_Y
),
419 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
421 .size
= sizeof(virtio_input_absinfo
),
422 .u
.abs
.min
= const_le32(INPUT_EVENT_ABS_MIN
),
423 .u
.abs
.max
= const_le32(INPUT_EVENT_ABS_MAX
),
425 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
427 .size
= sizeof(virtio_input_absinfo
),
428 .u
.abs
.min
= const_le32(INPUT_EVENT_ABS_MIN
),
429 .u
.abs
.max
= const_le32(INPUT_EVENT_ABS_MAX
),
431 { /* end of list */ },
434 static struct virtio_input_config virtio_tablet_config_v2
[] = {
436 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
437 .size
= sizeof(VIRTIO_ID_NAME_TABLET
),
438 .u
.string
= VIRTIO_ID_NAME_TABLET
,
440 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
441 .size
= sizeof(struct virtio_input_devids
),
443 .bustype
= const_le16(BUS_VIRTUAL
),
444 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
445 .product
= const_le16(0x0003),
446 .version
= const_le16(0x0002),
449 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
453 (1 << ABS_X
) | (1 << ABS_Y
),
456 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
461 (1 << (REL_WHEEL
- 8))
464 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
466 .size
= sizeof(virtio_input_absinfo
),
467 .u
.abs
.min
= const_le32(INPUT_EVENT_ABS_MIN
),
468 .u
.abs
.max
= const_le32(INPUT_EVENT_ABS_MAX
),
470 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
472 .size
= sizeof(virtio_input_absinfo
),
473 .u
.abs
.min
= const_le32(INPUT_EVENT_ABS_MIN
),
474 .u
.abs
.max
= const_le32(INPUT_EVENT_ABS_MAX
),
476 { /* end of list */ },
479 static Property virtio_tablet_properties
[] = {
480 DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID
, wheel_axis
, true),
481 DEFINE_PROP_END_OF_LIST(),
484 static void virtio_tablet_class_init(ObjectClass
*klass
, void *data
)
486 DeviceClass
*dc
= DEVICE_CLASS(klass
);
488 device_class_set_props(dc
, virtio_tablet_properties
);
491 static void virtio_tablet_init(Object
*obj
)
493 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(obj
);
494 VirtIOInput
*vinput
= VIRTIO_INPUT(obj
);
496 vhid
->handler
= &virtio_tablet_handler
;
497 virtio_input_init_config(vinput
, vhid
->wheel_axis
498 ? virtio_tablet_config_v2
499 : virtio_tablet_config_v1
);
500 virtio_input_key_config(vinput
, keymap_button
,
501 ARRAY_SIZE(keymap_button
));
504 static const TypeInfo virtio_tablet_info
= {
505 .name
= TYPE_VIRTIO_TABLET
,
506 .parent
= TYPE_VIRTIO_INPUT_HID
,
507 .instance_size
= sizeof(VirtIOInputHID
),
508 .instance_init
= virtio_tablet_init
,
509 .class_init
= virtio_tablet_class_init
,
512 /* ----------------------------------------------------------------- */
514 static void virtio_register_types(void)
516 type_register_static(&virtio_input_hid_info
);
517 type_register_static(&virtio_keyboard_info
);
518 type_register_static(&virtio_mouse_info
);
519 type_register_static(&virtio_tablet_info
);
522 type_init(virtio_register_types
)