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