1 /* 2 * QEMU System Emulator 3 * 4 * Copyright (c) 2003-2008 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #include "sysemu/sysemu.h" 26 #include "monitor/monitor.h" 27 #include "ui/console.h" 28 #include "qapi/error.h" 29 #include "qmp-commands.h" 30 #include "qapi-types.h" 31 32 struct QEMUPutMouseEntry { 33 QEMUPutMouseEvent *qemu_put_mouse_event; 34 void *qemu_put_mouse_event_opaque; 35 int qemu_put_mouse_event_absolute; 36 char *qemu_put_mouse_event_name; 37 38 int index; 39 40 /* used internally by qemu for handling mice */ 41 QTAILQ_ENTRY(QEMUPutMouseEntry) node; 42 }; 43 44 struct QEMUPutKbdEntry { 45 QEMUPutKBDEvent *put_kbd; 46 void *opaque; 47 QTAILQ_ENTRY(QEMUPutKbdEntry) next; 48 }; 49 50 struct QEMUPutLEDEntry { 51 QEMUPutLEDEvent *put_led; 52 void *opaque; 53 QTAILQ_ENTRY(QEMUPutLEDEntry) next; 54 }; 55 56 static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = 57 QTAILQ_HEAD_INITIALIZER(led_handlers); 58 static QTAILQ_HEAD(, QEMUPutKbdEntry) kbd_handlers = 59 QTAILQ_HEAD_INITIALIZER(kbd_handlers); 60 static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers = 61 QTAILQ_HEAD_INITIALIZER(mouse_handlers); 62 static NotifierList mouse_mode_notifiers = 63 NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers); 64 65 static const int key_defs[] = { 66 [Q_KEY_CODE_SHIFT] = 0x2a, 67 [Q_KEY_CODE_SHIFT_R] = 0x36, 68 69 [Q_KEY_CODE_ALT] = 0x38, 70 [Q_KEY_CODE_ALT_R] = 0xb8, 71 [Q_KEY_CODE_ALTGR] = 0x64, 72 [Q_KEY_CODE_ALTGR_R] = 0xe4, 73 [Q_KEY_CODE_CTRL] = 0x1d, 74 [Q_KEY_CODE_CTRL_R] = 0x9d, 75 76 [Q_KEY_CODE_MENU] = 0xdd, 77 78 [Q_KEY_CODE_ESC] = 0x01, 79 80 [Q_KEY_CODE_1] = 0x02, 81 [Q_KEY_CODE_2] = 0x03, 82 [Q_KEY_CODE_3] = 0x04, 83 [Q_KEY_CODE_4] = 0x05, 84 [Q_KEY_CODE_5] = 0x06, 85 [Q_KEY_CODE_6] = 0x07, 86 [Q_KEY_CODE_7] = 0x08, 87 [Q_KEY_CODE_8] = 0x09, 88 [Q_KEY_CODE_9] = 0x0a, 89 [Q_KEY_CODE_0] = 0x0b, 90 [Q_KEY_CODE_MINUS] = 0x0c, 91 [Q_KEY_CODE_EQUAL] = 0x0d, 92 [Q_KEY_CODE_BACKSPACE] = 0x0e, 93 94 [Q_KEY_CODE_TAB] = 0x0f, 95 [Q_KEY_CODE_Q] = 0x10, 96 [Q_KEY_CODE_W] = 0x11, 97 [Q_KEY_CODE_E] = 0x12, 98 [Q_KEY_CODE_R] = 0x13, 99 [Q_KEY_CODE_T] = 0x14, 100 [Q_KEY_CODE_Y] = 0x15, 101 [Q_KEY_CODE_U] = 0x16, 102 [Q_KEY_CODE_I] = 0x17, 103 [Q_KEY_CODE_O] = 0x18, 104 [Q_KEY_CODE_P] = 0x19, 105 [Q_KEY_CODE_BRACKET_LEFT] = 0x1a, 106 [Q_KEY_CODE_BRACKET_RIGHT] = 0x1b, 107 [Q_KEY_CODE_RET] = 0x1c, 108 109 [Q_KEY_CODE_A] = 0x1e, 110 [Q_KEY_CODE_S] = 0x1f, 111 [Q_KEY_CODE_D] = 0x20, 112 [Q_KEY_CODE_F] = 0x21, 113 [Q_KEY_CODE_G] = 0x22, 114 [Q_KEY_CODE_H] = 0x23, 115 [Q_KEY_CODE_J] = 0x24, 116 [Q_KEY_CODE_K] = 0x25, 117 [Q_KEY_CODE_L] = 0x26, 118 [Q_KEY_CODE_SEMICOLON] = 0x27, 119 [Q_KEY_CODE_APOSTROPHE] = 0x28, 120 [Q_KEY_CODE_GRAVE_ACCENT] = 0x29, 121 122 [Q_KEY_CODE_BACKSLASH] = 0x2b, 123 [Q_KEY_CODE_Z] = 0x2c, 124 [Q_KEY_CODE_X] = 0x2d, 125 [Q_KEY_CODE_C] = 0x2e, 126 [Q_KEY_CODE_V] = 0x2f, 127 [Q_KEY_CODE_B] = 0x30, 128 [Q_KEY_CODE_N] = 0x31, 129 [Q_KEY_CODE_M] = 0x32, 130 [Q_KEY_CODE_COMMA] = 0x33, 131 [Q_KEY_CODE_DOT] = 0x34, 132 [Q_KEY_CODE_SLASH] = 0x35, 133 134 [Q_KEY_CODE_ASTERISK] = 0x37, 135 136 [Q_KEY_CODE_SPC] = 0x39, 137 [Q_KEY_CODE_CAPS_LOCK] = 0x3a, 138 [Q_KEY_CODE_F1] = 0x3b, 139 [Q_KEY_CODE_F2] = 0x3c, 140 [Q_KEY_CODE_F3] = 0x3d, 141 [Q_KEY_CODE_F4] = 0x3e, 142 [Q_KEY_CODE_F5] = 0x3f, 143 [Q_KEY_CODE_F6] = 0x40, 144 [Q_KEY_CODE_F7] = 0x41, 145 [Q_KEY_CODE_F8] = 0x42, 146 [Q_KEY_CODE_F9] = 0x43, 147 [Q_KEY_CODE_F10] = 0x44, 148 [Q_KEY_CODE_NUM_LOCK] = 0x45, 149 [Q_KEY_CODE_SCROLL_LOCK] = 0x46, 150 151 [Q_KEY_CODE_KP_DIVIDE] = 0xb5, 152 [Q_KEY_CODE_KP_MULTIPLY] = 0x37, 153 [Q_KEY_CODE_KP_SUBTRACT] = 0x4a, 154 [Q_KEY_CODE_KP_ADD] = 0x4e, 155 [Q_KEY_CODE_KP_ENTER] = 0x9c, 156 [Q_KEY_CODE_KP_DECIMAL] = 0x53, 157 [Q_KEY_CODE_SYSRQ] = 0x54, 158 159 [Q_KEY_CODE_KP_0] = 0x52, 160 [Q_KEY_CODE_KP_1] = 0x4f, 161 [Q_KEY_CODE_KP_2] = 0x50, 162 [Q_KEY_CODE_KP_3] = 0x51, 163 [Q_KEY_CODE_KP_4] = 0x4b, 164 [Q_KEY_CODE_KP_5] = 0x4c, 165 [Q_KEY_CODE_KP_6] = 0x4d, 166 [Q_KEY_CODE_KP_7] = 0x47, 167 [Q_KEY_CODE_KP_8] = 0x48, 168 [Q_KEY_CODE_KP_9] = 0x49, 169 170 [Q_KEY_CODE_LESS] = 0x56, 171 172 [Q_KEY_CODE_F11] = 0x57, 173 [Q_KEY_CODE_F12] = 0x58, 174 175 [Q_KEY_CODE_PRINT] = 0xb7, 176 177 [Q_KEY_CODE_HOME] = 0xc7, 178 [Q_KEY_CODE_PGUP] = 0xc9, 179 [Q_KEY_CODE_PGDN] = 0xd1, 180 [Q_KEY_CODE_END] = 0xcf, 181 182 [Q_KEY_CODE_LEFT] = 0xcb, 183 [Q_KEY_CODE_UP] = 0xc8, 184 [Q_KEY_CODE_DOWN] = 0xd0, 185 [Q_KEY_CODE_RIGHT] = 0xcd, 186 187 [Q_KEY_CODE_INSERT] = 0xd2, 188 [Q_KEY_CODE_DELETE] = 0xd3, 189 #ifdef NEED_CPU_H 190 #if defined(TARGET_SPARC) && !defined(TARGET_SPARC64) 191 [Q_KEY_CODE_STOP] = 0xf0, 192 [Q_KEY_CODE_AGAIN] = 0xf1, 193 [Q_KEY_CODE_PROPS] = 0xf2, 194 [Q_KEY_CODE_UNDO] = 0xf3, 195 [Q_KEY_CODE_FRONT] = 0xf4, 196 [Q_KEY_CODE_COPY] = 0xf5, 197 [Q_KEY_CODE_OPEN] = 0xf6, 198 [Q_KEY_CODE_PASTE] = 0xf7, 199 [Q_KEY_CODE_FIND] = 0xf8, 200 [Q_KEY_CODE_CUT] = 0xf9, 201 [Q_KEY_CODE_LF] = 0xfa, 202 [Q_KEY_CODE_HELP] = 0xfb, 203 [Q_KEY_CODE_META_L] = 0xfc, 204 [Q_KEY_CODE_META_R] = 0xfd, 205 [Q_KEY_CODE_COMPOSE] = 0xfe, 206 #endif 207 #endif 208 [Q_KEY_CODE_MAX] = 0, 209 }; 210 211 int index_from_key(const char *key) 212 { 213 int i; 214 215 for (i = 0; QKeyCode_lookup[i] != NULL; i++) { 216 if (!strcmp(key, QKeyCode_lookup[i])) { 217 break; 218 } 219 } 220 221 /* Return Q_KEY_CODE_MAX if the key is invalid */ 222 return i; 223 } 224 225 int index_from_keycode(int code) 226 { 227 int i; 228 229 for (i = 0; i < Q_KEY_CODE_MAX; i++) { 230 if (key_defs[i] == code) { 231 break; 232 } 233 } 234 235 /* Return Q_KEY_CODE_MAX if the code is invalid */ 236 return i; 237 } 238 239 static int *keycodes; 240 static int keycodes_size; 241 static QEMUTimer *key_timer; 242 243 static int keycode_from_keyvalue(const KeyValue *value) 244 { 245 if (value->kind == KEY_VALUE_KIND_QCODE) { 246 return key_defs[value->qcode]; 247 } else { 248 assert(value->kind == KEY_VALUE_KIND_NUMBER); 249 return value->number; 250 } 251 } 252 253 static void free_keycodes(void) 254 { 255 g_free(keycodes); 256 keycodes = NULL; 257 keycodes_size = 0; 258 } 259 260 static void release_keys(void *opaque) 261 { 262 while (keycodes_size > 0) { 263 if (keycodes[--keycodes_size] & 0x80) { 264 kbd_put_keycode(0xe0); 265 } 266 kbd_put_keycode(keycodes[keycodes_size] | 0x80); 267 } 268 269 free_keycodes(); 270 } 271 272 void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time, 273 Error **errp) 274 { 275 int keycode; 276 KeyValueList *p; 277 278 if (!key_timer) { 279 key_timer = qemu_new_timer_ns(vm_clock, release_keys, NULL); 280 } 281 282 if (keycodes != NULL) { 283 qemu_del_timer(key_timer); 284 release_keys(NULL); 285 } 286 287 if (!has_hold_time) { 288 hold_time = 100; 289 } 290 291 for (p = keys; p != NULL; p = p->next) { 292 /* key down events */ 293 keycode = keycode_from_keyvalue(p->value); 294 if (keycode < 0x01 || keycode > 0xff) { 295 error_setg(errp, "invalid hex keycode 0x%x", keycode); 296 free_keycodes(); 297 return; 298 } 299 300 if (keycode & 0x80) { 301 kbd_put_keycode(0xe0); 302 } 303 kbd_put_keycode(keycode & 0x7f); 304 305 keycodes = g_realloc(keycodes, sizeof(int) * (keycodes_size + 1)); 306 keycodes[keycodes_size++] = keycode; 307 } 308 309 /* delayed key up events */ 310 qemu_mod_timer(key_timer, qemu_get_clock_ns(vm_clock) + 311 muldiv64(get_ticks_per_sec(), hold_time, 1000)); 312 } 313 314 QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) 315 { 316 QEMUPutKbdEntry *entry; 317 318 entry = g_malloc0(sizeof(QEMUPutKbdEntry)); 319 entry->put_kbd = func; 320 entry->opaque = opaque; 321 QTAILQ_INSERT_HEAD(&kbd_handlers, entry, next); 322 return entry; 323 } 324 325 void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry) 326 { 327 QTAILQ_REMOVE(&kbd_handlers, entry, next); 328 } 329 330 static void check_mode_change(void) 331 { 332 static int current_is_absolute, current_has_absolute; 333 int is_absolute; 334 int has_absolute; 335 336 is_absolute = kbd_mouse_is_absolute(); 337 has_absolute = kbd_mouse_has_absolute(); 338 339 if (is_absolute != current_is_absolute || 340 has_absolute != current_has_absolute) { 341 notifier_list_notify(&mouse_mode_notifiers, NULL); 342 } 343 344 current_is_absolute = is_absolute; 345 current_has_absolute = has_absolute; 346 } 347 348 QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, 349 void *opaque, int absolute, 350 const char *name) 351 { 352 QEMUPutMouseEntry *s; 353 static int mouse_index = 0; 354 355 s = g_malloc0(sizeof(QEMUPutMouseEntry)); 356 357 s->qemu_put_mouse_event = func; 358 s->qemu_put_mouse_event_opaque = opaque; 359 s->qemu_put_mouse_event_absolute = absolute; 360 s->qemu_put_mouse_event_name = g_strdup(name); 361 s->index = mouse_index++; 362 363 QTAILQ_INSERT_TAIL(&mouse_handlers, s, node); 364 365 check_mode_change(); 366 367 return s; 368 } 369 370 void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry) 371 { 372 QTAILQ_REMOVE(&mouse_handlers, entry, node); 373 QTAILQ_INSERT_HEAD(&mouse_handlers, entry, node); 374 375 check_mode_change(); 376 } 377 378 void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry) 379 { 380 QTAILQ_REMOVE(&mouse_handlers, entry, node); 381 382 g_free(entry->qemu_put_mouse_event_name); 383 g_free(entry); 384 385 check_mode_change(); 386 } 387 388 QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func, 389 void *opaque) 390 { 391 QEMUPutLEDEntry *s; 392 393 s = g_malloc0(sizeof(QEMUPutLEDEntry)); 394 395 s->put_led = func; 396 s->opaque = opaque; 397 QTAILQ_INSERT_TAIL(&led_handlers, s, next); 398 return s; 399 } 400 401 void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry) 402 { 403 if (entry == NULL) 404 return; 405 QTAILQ_REMOVE(&led_handlers, entry, next); 406 g_free(entry); 407 } 408 409 void kbd_put_keycode(int keycode) 410 { 411 QEMUPutKbdEntry *entry = QTAILQ_FIRST(&kbd_handlers); 412 413 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { 414 return; 415 } 416 if (entry) { 417 entry->put_kbd(entry->opaque, keycode); 418 } 419 } 420 421 void kbd_put_ledstate(int ledstate) 422 { 423 QEMUPutLEDEntry *cursor; 424 425 QTAILQ_FOREACH(cursor, &led_handlers, next) { 426 cursor->put_led(cursor->opaque, ledstate); 427 } 428 } 429 430 void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) 431 { 432 QEMUPutMouseEntry *entry; 433 QEMUPutMouseEvent *mouse_event; 434 void *mouse_event_opaque; 435 int width, height; 436 437 if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) { 438 return; 439 } 440 if (QTAILQ_EMPTY(&mouse_handlers)) { 441 return; 442 } 443 444 entry = QTAILQ_FIRST(&mouse_handlers); 445 446 mouse_event = entry->qemu_put_mouse_event; 447 mouse_event_opaque = entry->qemu_put_mouse_event_opaque; 448 449 if (mouse_event) { 450 if (entry->qemu_put_mouse_event_absolute) { 451 width = 0x7fff; 452 height = 0x7fff; 453 } else { 454 width = graphic_width - 1; 455 height = graphic_height - 1; 456 } 457 458 switch (graphic_rotate) { 459 case 0: 460 mouse_event(mouse_event_opaque, 461 dx, dy, dz, buttons_state); 462 break; 463 case 90: 464 mouse_event(mouse_event_opaque, 465 width - dy, dx, dz, buttons_state); 466 break; 467 case 180: 468 mouse_event(mouse_event_opaque, 469 width - dx, height - dy, dz, buttons_state); 470 break; 471 case 270: 472 mouse_event(mouse_event_opaque, 473 dy, height - dx, dz, buttons_state); 474 break; 475 } 476 } 477 } 478 479 int kbd_mouse_is_absolute(void) 480 { 481 if (QTAILQ_EMPTY(&mouse_handlers)) { 482 return 0; 483 } 484 485 return QTAILQ_FIRST(&mouse_handlers)->qemu_put_mouse_event_absolute; 486 } 487 488 int kbd_mouse_has_absolute(void) 489 { 490 QEMUPutMouseEntry *entry; 491 492 QTAILQ_FOREACH(entry, &mouse_handlers, node) { 493 if (entry->qemu_put_mouse_event_absolute) { 494 return 1; 495 } 496 } 497 498 return 0; 499 } 500 501 MouseInfoList *qmp_query_mice(Error **errp) 502 { 503 MouseInfoList *mice_list = NULL; 504 QEMUPutMouseEntry *cursor; 505 bool current = true; 506 507 QTAILQ_FOREACH(cursor, &mouse_handlers, node) { 508 MouseInfoList *info = g_malloc0(sizeof(*info)); 509 info->value = g_malloc0(sizeof(*info->value)); 510 info->value->name = g_strdup(cursor->qemu_put_mouse_event_name); 511 info->value->index = cursor->index; 512 info->value->absolute = !!cursor->qemu_put_mouse_event_absolute; 513 info->value->current = current; 514 515 current = false; 516 517 info->next = mice_list; 518 mice_list = info; 519 } 520 521 return mice_list; 522 } 523 524 void do_mouse_set(Monitor *mon, const QDict *qdict) 525 { 526 QEMUPutMouseEntry *cursor; 527 int index = qdict_get_int(qdict, "index"); 528 int found = 0; 529 530 if (QTAILQ_EMPTY(&mouse_handlers)) { 531 monitor_printf(mon, "No mouse devices connected\n"); 532 return; 533 } 534 535 QTAILQ_FOREACH(cursor, &mouse_handlers, node) { 536 if (cursor->index == index) { 537 found = 1; 538 qemu_activate_mouse_event_handler(cursor); 539 break; 540 } 541 } 542 543 if (!found) { 544 monitor_printf(mon, "Mouse at given index not found\n"); 545 } 546 547 check_mode_change(); 548 } 549 550 void qemu_add_mouse_mode_change_notifier(Notifier *notify) 551 { 552 notifier_list_add(&mouse_mode_notifiers, notify); 553 } 554 555 void qemu_remove_mouse_mode_change_notifier(Notifier *notify) 556 { 557 notifier_remove(notify); 558 } 559