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"
16 #include "ui/console.h"
18 #include "standard-headers/linux/input.h"
20 #define VIRTIO_ID_NAME_KEYBOARD "QEMU Virtio Keyboard"
21 #define VIRTIO_ID_NAME_MOUSE "QEMU Virtio Mouse"
22 #define VIRTIO_ID_NAME_TABLET "QEMU Virtio Tablet"
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
,
36 static const unsigned short axismap_rel
[INPUT_AXIS__MAX
] = {
37 [INPUT_AXIS_X
] = REL_X
,
38 [INPUT_AXIS_Y
] = REL_Y
,
41 static const unsigned short axismap_abs
[INPUT_AXIS__MAX
] = {
42 [INPUT_AXIS_X
] = ABS_X
,
43 [INPUT_AXIS_Y
] = ABS_Y
,
46 /* ----------------------------------------------------------------- */
48 static void virtio_input_key_config(VirtIOInput
*vinput
,
49 const unsigned short *keymap
,
52 virtio_input_config keys
;
53 int i
, bit
, byte
, bmax
= 0;
55 memset(&keys
, 0, sizeof(keys
));
56 for (i
= 0; i
< mapsize
; i
++) {
63 keys
.u
.bitmap
[byte
] |= (1 << bit
);
68 keys
.select
= VIRTIO_INPUT_CFG_EV_BITS
;
71 virtio_input_add_config(vinput
, &keys
);
74 static void virtio_input_handle_event(DeviceState
*dev
, QemuConsole
*src
,
77 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(dev
);
78 VirtIOInput
*vinput
= VIRTIO_INPUT(dev
);
79 virtio_input_event event
;
86 case INPUT_EVENT_KIND_KEY
:
87 key
= evt
->u
.key
.data
;
88 qcode
= qemu_input_key_value_to_qcode(key
->key
);
89 if (qcode
< qemu_input_map_qcode_to_linux_len
&&
90 qemu_input_map_qcode_to_linux
[qcode
]) {
91 event
.type
= cpu_to_le16(EV_KEY
);
92 event
.code
= cpu_to_le16(qemu_input_map_qcode_to_linux
[qcode
]);
93 event
.value
= cpu_to_le32(key
->down
? 1 : 0);
94 virtio_input_send(vinput
, &event
);
97 fprintf(stderr
, "%s: unmapped key: %d [%s]\n", __func__
,
98 qcode
, QKeyCode_str(qcode
));
102 case INPUT_EVENT_KIND_BTN
:
103 btn
= evt
->u
.btn
.data
;
104 if (vhid
->wheel_axis
&&
105 (btn
->button
== INPUT_BUTTON_WHEEL_UP
||
106 btn
->button
== INPUT_BUTTON_WHEEL_DOWN
) &&
108 event
.type
= cpu_to_le16(EV_REL
);
109 event
.code
= cpu_to_le16(REL_WHEEL
);
110 event
.value
= cpu_to_le32(btn
->button
== INPUT_BUTTON_WHEEL_UP
112 virtio_input_send(vinput
, &event
);
113 } else if (keymap_button
[btn
->button
]) {
114 event
.type
= cpu_to_le16(EV_KEY
);
115 event
.code
= cpu_to_le16(keymap_button
[btn
->button
]);
116 event
.value
= cpu_to_le32(btn
->down
? 1 : 0);
117 virtio_input_send(vinput
, &event
);
120 fprintf(stderr
, "%s: unmapped button: %d [%s]\n", __func__
,
122 InputButton_str(btn
->button
));
126 case INPUT_EVENT_KIND_REL
:
127 move
= evt
->u
.rel
.data
;
128 event
.type
= cpu_to_le16(EV_REL
);
129 event
.code
= cpu_to_le16(axismap_rel
[move
->axis
]);
130 event
.value
= cpu_to_le32(move
->value
);
131 virtio_input_send(vinput
, &event
);
133 case INPUT_EVENT_KIND_ABS
:
134 move
= evt
->u
.abs
.data
;
135 event
.type
= cpu_to_le16(EV_ABS
);
136 event
.code
= cpu_to_le16(axismap_abs
[move
->axis
]);
137 event
.value
= cpu_to_le32(move
->value
);
138 virtio_input_send(vinput
, &event
);
146 static void virtio_input_handle_sync(DeviceState
*dev
)
148 VirtIOInput
*vinput
= VIRTIO_INPUT(dev
);
149 virtio_input_event event
= {
150 .type
= cpu_to_le16(EV_SYN
),
151 .code
= cpu_to_le16(SYN_REPORT
),
155 virtio_input_send(vinput
, &event
);
158 static void virtio_input_hid_realize(DeviceState
*dev
, Error
**errp
)
160 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(dev
);
162 vhid
->hs
= qemu_input_handler_register(dev
, vhid
->handler
);
163 if (vhid
->display
&& vhid
->hs
) {
164 qemu_input_handler_bind(vhid
->hs
, vhid
->display
, vhid
->head
, NULL
);
168 static void virtio_input_hid_unrealize(DeviceState
*dev
, Error
**errp
)
170 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(dev
);
171 qemu_input_handler_unregister(vhid
->hs
);
174 static void virtio_input_hid_change_active(VirtIOInput
*vinput
)
176 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(vinput
);
178 if (vinput
->active
) {
179 qemu_input_handler_activate(vhid
->hs
);
181 qemu_input_handler_deactivate(vhid
->hs
);
185 static void virtio_input_hid_handle_status(VirtIOInput
*vinput
,
186 virtio_input_event
*event
)
188 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(vinput
);
191 switch (le16_to_cpu(event
->type
)) {
193 if (event
->code
== LED_NUML
) {
194 ledbit
= QEMU_NUM_LOCK_LED
;
195 } else if (event
->code
== LED_CAPSL
) {
196 ledbit
= QEMU_CAPS_LOCK_LED
;
197 } else if (event
->code
== LED_SCROLLL
) {
198 ledbit
= QEMU_SCROLL_LOCK_LED
;
201 vhid
->ledstate
|= ledbit
;
203 vhid
->ledstate
&= ~ledbit
;
205 kbd_put_ledstate(vhid
->ledstate
);
208 fprintf(stderr
, "%s: unknown type %d\n", __func__
,
209 le16_to_cpu(event
->type
));
214 static Property virtio_input_hid_properties
[] = {
215 DEFINE_PROP_STRING("display", VirtIOInputHID
, display
),
216 DEFINE_PROP_UINT32("head", VirtIOInputHID
, head
, 0),
217 DEFINE_PROP_END_OF_LIST(),
220 static void virtio_input_hid_class_init(ObjectClass
*klass
, void *data
)
222 DeviceClass
*dc
= DEVICE_CLASS(klass
);
223 VirtIOInputClass
*vic
= VIRTIO_INPUT_CLASS(klass
);
225 dc
->props
= virtio_input_hid_properties
;
226 vic
->realize
= virtio_input_hid_realize
;
227 vic
->unrealize
= virtio_input_hid_unrealize
;
228 vic
->change_active
= virtio_input_hid_change_active
;
229 vic
->handle_status
= virtio_input_hid_handle_status
;
232 static const TypeInfo virtio_input_hid_info
= {
233 .name
= TYPE_VIRTIO_INPUT_HID
,
234 .parent
= TYPE_VIRTIO_INPUT
,
235 .instance_size
= sizeof(VirtIOInputHID
),
236 .class_init
= virtio_input_hid_class_init
,
240 /* ----------------------------------------------------------------- */
242 static QemuInputHandler virtio_keyboard_handler
= {
243 .name
= VIRTIO_ID_NAME_KEYBOARD
,
244 .mask
= INPUT_EVENT_MASK_KEY
,
245 .event
= virtio_input_handle_event
,
246 .sync
= virtio_input_handle_sync
,
249 static struct virtio_input_config virtio_keyboard_config
[] = {
251 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
252 .size
= sizeof(VIRTIO_ID_NAME_KEYBOARD
),
253 .u
.string
= VIRTIO_ID_NAME_KEYBOARD
,
255 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
256 .size
= sizeof(struct virtio_input_devids
),
258 .bustype
= const_le16(BUS_VIRTUAL
),
259 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
260 .product
= const_le16(0x0001),
261 .version
= const_le16(0x0001),
264 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
268 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
272 (1 << LED_NUML
) | (1 << LED_CAPSL
) | (1 << LED_SCROLLL
),
275 { /* end of list */ },
278 static void virtio_keyboard_init(Object
*obj
)
280 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(obj
);
281 VirtIOInput
*vinput
= VIRTIO_INPUT(obj
);
283 vhid
->handler
= &virtio_keyboard_handler
;
284 virtio_input_init_config(vinput
, virtio_keyboard_config
);
285 virtio_input_key_config(vinput
, qemu_input_map_qcode_to_linux
,
286 qemu_input_map_qcode_to_linux_len
);
289 static const TypeInfo virtio_keyboard_info
= {
290 .name
= TYPE_VIRTIO_KEYBOARD
,
291 .parent
= TYPE_VIRTIO_INPUT_HID
,
292 .instance_size
= sizeof(VirtIOInputHID
),
293 .instance_init
= virtio_keyboard_init
,
296 /* ----------------------------------------------------------------- */
298 static QemuInputHandler virtio_mouse_handler
= {
299 .name
= VIRTIO_ID_NAME_MOUSE
,
300 .mask
= INPUT_EVENT_MASK_BTN
| INPUT_EVENT_MASK_REL
,
301 .event
= virtio_input_handle_event
,
302 .sync
= virtio_input_handle_sync
,
305 static struct virtio_input_config virtio_mouse_config_v1
[] = {
307 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
308 .size
= sizeof(VIRTIO_ID_NAME_MOUSE
),
309 .u
.string
= VIRTIO_ID_NAME_MOUSE
,
311 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
312 .size
= sizeof(struct virtio_input_devids
),
314 .bustype
= const_le16(BUS_VIRTUAL
),
315 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
316 .product
= const_le16(0x0002),
317 .version
= const_le16(0x0001),
320 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
324 (1 << REL_X
) | (1 << REL_Y
),
327 { /* end of list */ },
330 static struct virtio_input_config virtio_mouse_config_v2
[] = {
332 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
333 .size
= sizeof(VIRTIO_ID_NAME_MOUSE
),
334 .u
.string
= VIRTIO_ID_NAME_MOUSE
,
336 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
337 .size
= sizeof(struct virtio_input_devids
),
339 .bustype
= const_le16(BUS_VIRTUAL
),
340 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
341 .product
= const_le16(0x0002),
342 .version
= const_le16(0x0002),
345 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
349 (1 << REL_X
) | (1 << REL_Y
),
350 (1 << (REL_WHEEL
- 8))
353 { /* end of list */ },
356 static Property virtio_mouse_properties
[] = {
357 DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID
, wheel_axis
, true),
358 DEFINE_PROP_END_OF_LIST(),
361 static void virtio_mouse_class_init(ObjectClass
*klass
, void *data
)
363 DeviceClass
*dc
= DEVICE_CLASS(klass
);
365 dc
->props
= virtio_mouse_properties
;
368 static void virtio_mouse_init(Object
*obj
)
370 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(obj
);
371 VirtIOInput
*vinput
= VIRTIO_INPUT(obj
);
373 vhid
->handler
= &virtio_mouse_handler
;
374 virtio_input_init_config(vinput
, vhid
->wheel_axis
375 ? virtio_mouse_config_v2
376 : virtio_mouse_config_v1
);
377 virtio_input_key_config(vinput
, keymap_button
,
378 ARRAY_SIZE(keymap_button
));
381 static const TypeInfo virtio_mouse_info
= {
382 .name
= TYPE_VIRTIO_MOUSE
,
383 .parent
= TYPE_VIRTIO_INPUT_HID
,
384 .instance_size
= sizeof(VirtIOInputHID
),
385 .instance_init
= virtio_mouse_init
,
386 .class_init
= virtio_mouse_class_init
,
389 /* ----------------------------------------------------------------- */
391 static QemuInputHandler virtio_tablet_handler
= {
392 .name
= VIRTIO_ID_NAME_TABLET
,
393 .mask
= INPUT_EVENT_MASK_BTN
| INPUT_EVENT_MASK_ABS
,
394 .event
= virtio_input_handle_event
,
395 .sync
= virtio_input_handle_sync
,
398 static struct virtio_input_config virtio_tablet_config_v1
[] = {
400 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
401 .size
= sizeof(VIRTIO_ID_NAME_TABLET
),
402 .u
.string
= VIRTIO_ID_NAME_TABLET
,
404 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
405 .size
= sizeof(struct virtio_input_devids
),
407 .bustype
= const_le16(BUS_VIRTUAL
),
408 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
409 .product
= const_le16(0x0003),
410 .version
= const_le16(0x0001),
413 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
417 (1 << ABS_X
) | (1 << ABS_Y
),
420 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
422 .size
= sizeof(virtio_input_absinfo
),
423 .u
.abs
.min
= const_le32(INPUT_EVENT_ABS_MIN
),
424 .u
.abs
.max
= const_le32(INPUT_EVENT_ABS_MAX
),
426 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
428 .size
= sizeof(virtio_input_absinfo
),
429 .u
.abs
.min
= const_le32(INPUT_EVENT_ABS_MIN
),
430 .u
.abs
.max
= const_le32(INPUT_EVENT_ABS_MAX
),
432 { /* end of list */ },
435 static struct virtio_input_config virtio_tablet_config_v2
[] = {
437 .select
= VIRTIO_INPUT_CFG_ID_NAME
,
438 .size
= sizeof(VIRTIO_ID_NAME_TABLET
),
439 .u
.string
= VIRTIO_ID_NAME_TABLET
,
441 .select
= VIRTIO_INPUT_CFG_ID_DEVIDS
,
442 .size
= sizeof(struct virtio_input_devids
),
444 .bustype
= const_le16(BUS_VIRTUAL
),
445 .vendor
= const_le16(0x0627), /* same we use for usb hid devices */
446 .product
= const_le16(0x0003),
447 .version
= const_le16(0x0002),
450 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
454 (1 << ABS_X
) | (1 << ABS_Y
),
457 .select
= VIRTIO_INPUT_CFG_EV_BITS
,
462 (1 << (REL_WHEEL
- 8))
465 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
467 .size
= sizeof(virtio_input_absinfo
),
468 .u
.abs
.min
= const_le32(INPUT_EVENT_ABS_MIN
),
469 .u
.abs
.max
= const_le32(INPUT_EVENT_ABS_MAX
),
471 .select
= VIRTIO_INPUT_CFG_ABS_INFO
,
473 .size
= sizeof(virtio_input_absinfo
),
474 .u
.abs
.min
= const_le32(INPUT_EVENT_ABS_MIN
),
475 .u
.abs
.max
= const_le32(INPUT_EVENT_ABS_MAX
),
477 { /* end of list */ },
480 static Property virtio_tablet_properties
[] = {
481 DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID
, wheel_axis
, true),
482 DEFINE_PROP_END_OF_LIST(),
485 static void virtio_tablet_class_init(ObjectClass
*klass
, void *data
)
487 DeviceClass
*dc
= DEVICE_CLASS(klass
);
489 dc
->props
= virtio_tablet_properties
;
492 static void virtio_tablet_init(Object
*obj
)
494 VirtIOInputHID
*vhid
= VIRTIO_INPUT_HID(obj
);
495 VirtIOInput
*vinput
= VIRTIO_INPUT(obj
);
497 vhid
->handler
= &virtio_tablet_handler
;
498 virtio_input_init_config(vinput
, vhid
->wheel_axis
499 ? virtio_tablet_config_v2
500 : virtio_tablet_config_v1
);
501 virtio_input_key_config(vinput
, keymap_button
,
502 ARRAY_SIZE(keymap_button
));
505 static const TypeInfo virtio_tablet_info
= {
506 .name
= TYPE_VIRTIO_TABLET
,
507 .parent
= TYPE_VIRTIO_INPUT_HID
,
508 .instance_size
= sizeof(VirtIOInputHID
),
509 .instance_init
= virtio_tablet_init
,
510 .class_init
= virtio_tablet_class_init
,
513 /* ----------------------------------------------------------------- */
515 static void virtio_register_types(void)
517 type_register_static(&virtio_input_hid_info
);
518 type_register_static(&virtio_keyboard_info
);
519 type_register_static(&virtio_mouse_info
);
520 type_register_static(&virtio_tablet_info
);
523 type_init(virtio_register_types
)