input.c (17106B)
1#include "qemu/osdep.h" 2#include "sysemu/sysemu.h" 3#include "qapi/error.h" 4#include "qapi/qapi-commands-ui.h" 5#include "qapi/qmp/qdict.h" 6#include "qemu/error-report.h" 7#include "trace.h" 8#include "ui/input.h" 9#include "ui/console.h" 10#include "sysemu/replay.h" 11#include "sysemu/runstate.h" 12 13struct QemuInputHandlerState { 14 DeviceState *dev; 15 QemuInputHandler *handler; 16 int id; 17 int events; 18 QemuConsole *con; 19 QTAILQ_ENTRY(QemuInputHandlerState) node; 20}; 21 22typedef struct QemuInputEventQueue QemuInputEventQueue; 23typedef QTAILQ_HEAD(QemuInputEventQueueHead, QemuInputEventQueue) 24 QemuInputEventQueueHead; 25 26struct QemuInputEventQueue { 27 enum { 28 QEMU_INPUT_QUEUE_DELAY = 1, 29 QEMU_INPUT_QUEUE_EVENT, 30 QEMU_INPUT_QUEUE_SYNC, 31 } type; 32 QEMUTimer *timer; 33 uint32_t delay_ms; 34 QemuConsole *src; 35 InputEvent *evt; 36 QTAILQ_ENTRY(QemuInputEventQueue) node; 37}; 38 39static QTAILQ_HEAD(, QemuInputHandlerState) handlers = 40 QTAILQ_HEAD_INITIALIZER(handlers); 41static NotifierList mouse_mode_notifiers = 42 NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers); 43 44static QemuInputEventQueueHead kbd_queue = QTAILQ_HEAD_INITIALIZER(kbd_queue); 45static QEMUTimer *kbd_timer; 46static uint32_t kbd_default_delay_ms = 10; 47static uint32_t queue_count; 48static uint32_t queue_limit = 1024; 49 50QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev, 51 QemuInputHandler *handler) 52{ 53 QemuInputHandlerState *s = g_new0(QemuInputHandlerState, 1); 54 static int id = 1; 55 56 s->dev = dev; 57 s->handler = handler; 58 s->id = id++; 59 QTAILQ_INSERT_TAIL(&handlers, s, node); 60 61 qemu_input_check_mode_change(); 62 return s; 63} 64 65void qemu_input_handler_activate(QemuInputHandlerState *s) 66{ 67 QTAILQ_REMOVE(&handlers, s, node); 68 QTAILQ_INSERT_HEAD(&handlers, s, node); 69 qemu_input_check_mode_change(); 70} 71 72void qemu_input_handler_deactivate(QemuInputHandlerState *s) 73{ 74 QTAILQ_REMOVE(&handlers, s, node); 75 QTAILQ_INSERT_TAIL(&handlers, s, node); 76 qemu_input_check_mode_change(); 77} 78 79void qemu_input_handler_unregister(QemuInputHandlerState *s) 80{ 81 QTAILQ_REMOVE(&handlers, s, node); 82 g_free(s); 83 qemu_input_check_mode_change(); 84} 85 86void qemu_input_handler_bind(QemuInputHandlerState *s, 87 const char *device_id, int head, 88 Error **errp) 89{ 90 QemuConsole *con; 91 Error *err = NULL; 92 93 con = qemu_console_lookup_by_device_name(device_id, head, &err); 94 if (err) { 95 error_propagate(errp, err); 96 return; 97 } 98 99 s->con = con; 100} 101 102static QemuInputHandlerState* 103qemu_input_find_handler(uint32_t mask, QemuConsole *con) 104{ 105 QemuInputHandlerState *s; 106 107 QTAILQ_FOREACH(s, &handlers, node) { 108 if (s->con == NULL || s->con != con) { 109 continue; 110 } 111 if (mask & s->handler->mask) { 112 return s; 113 } 114 } 115 116 QTAILQ_FOREACH(s, &handlers, node) { 117 if (s->con != NULL) { 118 continue; 119 } 120 if (mask & s->handler->mask) { 121 return s; 122 } 123 } 124 return NULL; 125} 126 127void qmp_input_send_event(bool has_device, const char *device, 128 bool has_head, int64_t head, 129 InputEventList *events, Error **errp) 130{ 131 InputEventList *e; 132 QemuConsole *con; 133 Error *err = NULL; 134 135 con = NULL; 136 if (has_device) { 137 if (!has_head) { 138 head = 0; 139 } 140 con = qemu_console_lookup_by_device_name(device, head, &err); 141 if (err) { 142 error_propagate(errp, err); 143 return; 144 } 145 } 146 147 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { 148 error_setg(errp, "VM not running"); 149 return; 150 } 151 152 for (e = events; e != NULL; e = e->next) { 153 InputEvent *event = e->value; 154 155 if (!qemu_input_find_handler(1 << event->type, con)) { 156 error_setg(errp, "Input handler not found for " 157 "event type %s", 158 InputEventKind_str(event->type)); 159 return; 160 } 161 } 162 163 for (e = events; e != NULL; e = e->next) { 164 InputEvent *evt = e->value; 165 166 if (evt->type == INPUT_EVENT_KIND_KEY && 167 evt->u.key.data->key->type == KEY_VALUE_KIND_NUMBER) { 168 KeyValue *key = evt->u.key.data->key; 169 QKeyCode code = qemu_input_key_number_to_qcode(key->u.number.data); 170 qemu_input_event_send_key_qcode(con, code, evt->u.key.data->down); 171 } else { 172 qemu_input_event_send(con, evt); 173 } 174 } 175 176 qemu_input_event_sync(); 177} 178 179static int qemu_input_transform_invert_abs_value(int value) 180{ 181 return (int64_t)INPUT_EVENT_ABS_MAX - value + INPUT_EVENT_ABS_MIN; 182} 183 184static void qemu_input_transform_abs_rotate(InputEvent *evt) 185{ 186 InputMoveEvent *move = evt->u.abs.data; 187 switch (graphic_rotate) { 188 case 90: 189 if (move->axis == INPUT_AXIS_X) { 190 move->axis = INPUT_AXIS_Y; 191 } else if (move->axis == INPUT_AXIS_Y) { 192 move->axis = INPUT_AXIS_X; 193 move->value = qemu_input_transform_invert_abs_value(move->value); 194 } 195 break; 196 case 180: 197 move->value = qemu_input_transform_invert_abs_value(move->value); 198 break; 199 case 270: 200 if (move->axis == INPUT_AXIS_X) { 201 move->axis = INPUT_AXIS_Y; 202 move->value = qemu_input_transform_invert_abs_value(move->value); 203 } else if (move->axis == INPUT_AXIS_Y) { 204 move->axis = INPUT_AXIS_X; 205 } 206 break; 207 } 208} 209 210static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt) 211{ 212 const char *name; 213 int qcode, idx = -1; 214 InputKeyEvent *key; 215 InputBtnEvent *btn; 216 InputMoveEvent *move; 217 218 if (src) { 219 idx = qemu_console_get_index(src); 220 } 221 switch (evt->type) { 222 case INPUT_EVENT_KIND_KEY: 223 key = evt->u.key.data; 224 switch (key->key->type) { 225 case KEY_VALUE_KIND_NUMBER: 226 qcode = qemu_input_key_number_to_qcode(key->key->u.number.data); 227 name = QKeyCode_str(qcode); 228 trace_input_event_key_number(idx, key->key->u.number.data, 229 name, key->down); 230 break; 231 case KEY_VALUE_KIND_QCODE: 232 name = QKeyCode_str(key->key->u.qcode.data); 233 trace_input_event_key_qcode(idx, name, key->down); 234 break; 235 case KEY_VALUE_KIND__MAX: 236 /* keep gcc happy */ 237 break; 238 } 239 break; 240 case INPUT_EVENT_KIND_BTN: 241 btn = evt->u.btn.data; 242 name = InputButton_str(btn->button); 243 trace_input_event_btn(idx, name, btn->down); 244 break; 245 case INPUT_EVENT_KIND_REL: 246 move = evt->u.rel.data; 247 name = InputAxis_str(move->axis); 248 trace_input_event_rel(idx, name, move->value); 249 break; 250 case INPUT_EVENT_KIND_ABS: 251 move = evt->u.abs.data; 252 name = InputAxis_str(move->axis); 253 trace_input_event_abs(idx, name, move->value); 254 break; 255 case INPUT_EVENT_KIND__MAX: 256 /* keep gcc happy */ 257 break; 258 } 259} 260 261static void qemu_input_queue_process(void *opaque) 262{ 263 QemuInputEventQueueHead *queue = opaque; 264 QemuInputEventQueue *item; 265 266 g_assert(!QTAILQ_EMPTY(queue)); 267 item = QTAILQ_FIRST(queue); 268 g_assert(item->type == QEMU_INPUT_QUEUE_DELAY); 269 QTAILQ_REMOVE(queue, item, node); 270 queue_count--; 271 g_free(item); 272 273 while (!QTAILQ_EMPTY(queue)) { 274 item = QTAILQ_FIRST(queue); 275 switch (item->type) { 276 case QEMU_INPUT_QUEUE_DELAY: 277 timer_mod(item->timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) 278 + item->delay_ms); 279 return; 280 case QEMU_INPUT_QUEUE_EVENT: 281 qemu_input_event_send(item->src, item->evt); 282 qapi_free_InputEvent(item->evt); 283 break; 284 case QEMU_INPUT_QUEUE_SYNC: 285 qemu_input_event_sync(); 286 break; 287 } 288 QTAILQ_REMOVE(queue, item, node); 289 queue_count--; 290 g_free(item); 291 } 292} 293 294static void qemu_input_queue_delay(QemuInputEventQueueHead *queue, 295 QEMUTimer *timer, uint32_t delay_ms) 296{ 297 QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1); 298 bool start_timer = QTAILQ_EMPTY(queue); 299 300 item->type = QEMU_INPUT_QUEUE_DELAY; 301 item->delay_ms = delay_ms; 302 item->timer = timer; 303 QTAILQ_INSERT_TAIL(queue, item, node); 304 queue_count++; 305 306 if (start_timer) { 307 timer_mod(item->timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) 308 + item->delay_ms); 309 } 310} 311 312static void qemu_input_queue_event(QemuInputEventQueueHead *queue, 313 QemuConsole *src, InputEvent *evt) 314{ 315 QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1); 316 317 item->type = QEMU_INPUT_QUEUE_EVENT; 318 item->src = src; 319 item->evt = evt; 320 QTAILQ_INSERT_TAIL(queue, item, node); 321 queue_count++; 322} 323 324static void qemu_input_queue_sync(QemuInputEventQueueHead *queue) 325{ 326 QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1); 327 328 item->type = QEMU_INPUT_QUEUE_SYNC; 329 QTAILQ_INSERT_TAIL(queue, item, node); 330 queue_count++; 331} 332 333void qemu_input_event_send_impl(QemuConsole *src, InputEvent *evt) 334{ 335 QemuInputHandlerState *s; 336 337 qemu_input_event_trace(src, evt); 338 339 /* pre processing */ 340 if (graphic_rotate && (evt->type == INPUT_EVENT_KIND_ABS)) { 341 qemu_input_transform_abs_rotate(evt); 342 } 343 344 /* send event */ 345 s = qemu_input_find_handler(1 << evt->type, src); 346 if (!s) { 347 return; 348 } 349 s->handler->event(s->dev, src, evt); 350 s->events++; 351} 352 353void qemu_input_event_send(QemuConsole *src, InputEvent *evt) 354{ 355 /* Expect all parts of QEMU to send events with QCodes exclusively. 356 * Key numbers are only supported as end-user input via QMP */ 357 assert(!(evt->type == INPUT_EVENT_KIND_KEY && 358 evt->u.key.data->key->type == KEY_VALUE_KIND_NUMBER)); 359 360 361 /* 362 * 'sysrq' was mistakenly added to hack around the fact that 363 * the ps2 driver was not generating correct scancodes sequences 364 * when 'alt+print' was pressed. This flaw is now fixed and the 365 * 'sysrq' key serves no further purpose. We normalize it to 366 * 'print', so that downstream receivers of the event don't 367 * neeed to deal with this mistake 368 */ 369 if (evt->type == INPUT_EVENT_KIND_KEY && 370 evt->u.key.data->key->u.qcode.data == Q_KEY_CODE_SYSRQ) { 371 evt->u.key.data->key->u.qcode.data = Q_KEY_CODE_PRINT; 372 } 373 374 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { 375 return; 376 } 377 378 replay_input_event(src, evt); 379} 380 381void qemu_input_event_sync_impl(void) 382{ 383 QemuInputHandlerState *s; 384 385 trace_input_event_sync(); 386 387 QTAILQ_FOREACH(s, &handlers, node) { 388 if (!s->events) { 389 continue; 390 } 391 if (s->handler->sync) { 392 s->handler->sync(s->dev); 393 } 394 s->events = 0; 395 } 396} 397 398void qemu_input_event_sync(void) 399{ 400 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { 401 return; 402 } 403 404 replay_input_sync_event(); 405} 406 407static InputEvent *qemu_input_event_new_key(KeyValue *key, bool down) 408{ 409 InputEvent *evt = g_new0(InputEvent, 1); 410 evt->u.key.data = g_new0(InputKeyEvent, 1); 411 evt->type = INPUT_EVENT_KIND_KEY; 412 evt->u.key.data->key = key; 413 evt->u.key.data->down = down; 414 return evt; 415} 416 417void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down) 418{ 419 InputEvent *evt; 420 evt = qemu_input_event_new_key(key, down); 421 if (QTAILQ_EMPTY(&kbd_queue)) { 422 qemu_input_event_send(src, evt); 423 qemu_input_event_sync(); 424 qapi_free_InputEvent(evt); 425 } else if (queue_count < queue_limit) { 426 qemu_input_queue_event(&kbd_queue, src, evt); 427 qemu_input_queue_sync(&kbd_queue); 428 } else { 429 qapi_free_InputEvent(evt); 430 } 431} 432 433void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down) 434{ 435 QKeyCode code = qemu_input_key_number_to_qcode(num); 436 qemu_input_event_send_key_qcode(src, code, down); 437} 438 439void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down) 440{ 441 KeyValue *key = g_new0(KeyValue, 1); 442 key->type = KEY_VALUE_KIND_QCODE; 443 key->u.qcode.data = q; 444 qemu_input_event_send_key(src, key, down); 445} 446 447void qemu_input_event_send_key_delay(uint32_t delay_ms) 448{ 449 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { 450 return; 451 } 452 453 if (!kbd_timer) { 454 kbd_timer = timer_new_full(NULL, QEMU_CLOCK_VIRTUAL, 455 SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL, 456 qemu_input_queue_process, &kbd_queue); 457 } 458 if (queue_count < queue_limit) { 459 qemu_input_queue_delay(&kbd_queue, kbd_timer, 460 delay_ms ? delay_ms : kbd_default_delay_ms); 461 } 462} 463 464void qemu_input_queue_btn(QemuConsole *src, InputButton btn, bool down) 465{ 466 InputBtnEvent bevt = { 467 .button = btn, 468 .down = down, 469 }; 470 InputEvent evt = { 471 .type = INPUT_EVENT_KIND_BTN, 472 .u.btn.data = &bevt, 473 }; 474 475 qemu_input_event_send(src, &evt); 476} 477 478void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map, 479 uint32_t button_old, uint32_t button_new) 480{ 481 InputButton btn; 482 uint32_t mask; 483 484 for (btn = 0; btn < INPUT_BUTTON__MAX; btn++) { 485 mask = button_map[btn]; 486 if ((button_old & mask) == (button_new & mask)) { 487 continue; 488 } 489 qemu_input_queue_btn(src, btn, button_new & mask); 490 } 491} 492 493bool qemu_input_is_absolute(void) 494{ 495 QemuInputHandlerState *s; 496 497 s = qemu_input_find_handler(INPUT_EVENT_MASK_REL | INPUT_EVENT_MASK_ABS, 498 NULL); 499 return (s != NULL) && (s->handler->mask & INPUT_EVENT_MASK_ABS); 500} 501 502int qemu_input_scale_axis(int value, 503 int min_in, int max_in, 504 int min_out, int max_out) 505{ 506 int64_t range_in = (int64_t)max_in - min_in; 507 int64_t range_out = (int64_t)max_out - min_out; 508 509 if (range_in < 1) { 510 return min_out + range_out / 2; 511 } 512 return ((int64_t)value - min_in) * range_out / range_in + min_out; 513} 514 515void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value) 516{ 517 InputMoveEvent move = { 518 .axis = axis, 519 .value = value, 520 }; 521 InputEvent evt = { 522 .type = INPUT_EVENT_KIND_REL, 523 .u.rel.data = &move, 524 }; 525 526 qemu_input_event_send(src, &evt); 527} 528 529void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value, 530 int min_in, int max_in) 531{ 532 InputMoveEvent move = { 533 .axis = axis, 534 .value = qemu_input_scale_axis(value, min_in, max_in, 535 INPUT_EVENT_ABS_MIN, 536 INPUT_EVENT_ABS_MAX), 537 }; 538 InputEvent evt = { 539 .type = INPUT_EVENT_KIND_ABS, 540 .u.abs.data = &move, 541 }; 542 543 qemu_input_event_send(src, &evt); 544} 545 546void qemu_input_check_mode_change(void) 547{ 548 static int current_is_absolute; 549 int is_absolute; 550 551 is_absolute = qemu_input_is_absolute(); 552 553 if (is_absolute != current_is_absolute) { 554 trace_input_mouse_mode(is_absolute); 555 notifier_list_notify(&mouse_mode_notifiers, NULL); 556 } 557 558 current_is_absolute = is_absolute; 559} 560 561void qemu_add_mouse_mode_change_notifier(Notifier *notify) 562{ 563 notifier_list_add(&mouse_mode_notifiers, notify); 564} 565 566void qemu_remove_mouse_mode_change_notifier(Notifier *notify) 567{ 568 notifier_remove(notify); 569} 570 571MouseInfoList *qmp_query_mice(Error **errp) 572{ 573 MouseInfoList *mice_list = NULL; 574 MouseInfo *info; 575 QemuInputHandlerState *s; 576 bool current = true; 577 578 QTAILQ_FOREACH(s, &handlers, node) { 579 if (!(s->handler->mask & 580 (INPUT_EVENT_MASK_REL | INPUT_EVENT_MASK_ABS))) { 581 continue; 582 } 583 584 info = g_new0(MouseInfo, 1); 585 info->index = s->id; 586 info->name = g_strdup(s->handler->name); 587 info->absolute = s->handler->mask & INPUT_EVENT_MASK_ABS; 588 info->current = current; 589 590 current = false; 591 QAPI_LIST_PREPEND(mice_list, info); 592 } 593 594 return mice_list; 595} 596 597void hmp_mouse_set(Monitor *mon, const QDict *qdict) 598{ 599 QemuInputHandlerState *s; 600 int index = qdict_get_int(qdict, "index"); 601 int found = 0; 602 603 QTAILQ_FOREACH(s, &handlers, node) { 604 if (s->id != index) { 605 continue; 606 } 607 if (!(s->handler->mask & (INPUT_EVENT_MASK_REL | 608 INPUT_EVENT_MASK_ABS))) { 609 error_report("Input device '%s' is not a mouse", s->handler->name); 610 return; 611 } 612 found = 1; 613 qemu_input_handler_activate(s); 614 break; 615 } 616 617 if (!found) { 618 error_report("Mouse at index '%d' not found", index); 619 } 620 621 qemu_input_check_mode_change(); 622}