Commit a3a91a355bc6107b7d06d722fb97d2b80065ee0b
1 parent
ab2572d7
sendkey command
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@883 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
168 additions
and
0 deletions
monitor.c
| ... | ... | @@ -476,6 +476,161 @@ static void do_print(int count, int format, int size, int val) |
| 476 | 476 | term_printf("\n"); |
| 477 | 477 | } |
| 478 | 478 | |
| 479 | +typedef struct { | |
| 480 | + int keycode; | |
| 481 | + const char *name; | |
| 482 | +} KeyDef; | |
| 483 | + | |
| 484 | +static const KeyDef key_defs[] = { | |
| 485 | + { 0x2a, "shift" }, | |
| 486 | + { 0x36, "shift_r" }, | |
| 487 | + | |
| 488 | + { 0x38, "alt" }, | |
| 489 | + { 0xb8, "alt_r" }, | |
| 490 | + { 0x1d, "ctrl" }, | |
| 491 | + { 0x9d, "ctrl_r" }, | |
| 492 | + | |
| 493 | + { 0xdd, "menu" }, | |
| 494 | + | |
| 495 | + { 0x01, "esc" }, | |
| 496 | + | |
| 497 | + { 0x02, "1" }, | |
| 498 | + { 0x03, "2" }, | |
| 499 | + { 0x04, "3" }, | |
| 500 | + { 0x05, "4" }, | |
| 501 | + { 0x06, "5" }, | |
| 502 | + { 0x07, "6" }, | |
| 503 | + { 0x08, "7" }, | |
| 504 | + { 0x09, "8" }, | |
| 505 | + { 0x0a, "9" }, | |
| 506 | + { 0x0b, "0" }, | |
| 507 | + { 0x0e, "backspace" }, | |
| 508 | + | |
| 509 | + { 0x0f, "tab" }, | |
| 510 | + { 0x10, "q" }, | |
| 511 | + { 0x11, "w" }, | |
| 512 | + { 0x12, "e" }, | |
| 513 | + { 0x13, "r" }, | |
| 514 | + { 0x14, "t" }, | |
| 515 | + { 0x15, "y" }, | |
| 516 | + { 0x16, "u" }, | |
| 517 | + { 0x17, "i" }, | |
| 518 | + { 0x18, "o" }, | |
| 519 | + { 0x19, "p" }, | |
| 520 | + | |
| 521 | + { 0x1c, "ret" }, | |
| 522 | + | |
| 523 | + { 0x1e, "a" }, | |
| 524 | + { 0x1f, "s" }, | |
| 525 | + { 0x20, "d" }, | |
| 526 | + { 0x21, "f" }, | |
| 527 | + { 0x22, "g" }, | |
| 528 | + { 0x23, "h" }, | |
| 529 | + { 0x24, "j" }, | |
| 530 | + { 0x25, "k" }, | |
| 531 | + { 0x26, "l" }, | |
| 532 | + | |
| 533 | + { 0x2c, "z" }, | |
| 534 | + { 0x2d, "x" }, | |
| 535 | + { 0x2e, "c" }, | |
| 536 | + { 0x2f, "v" }, | |
| 537 | + { 0x30, "b" }, | |
| 538 | + { 0x31, "n" }, | |
| 539 | + { 0x32, "m" }, | |
| 540 | + | |
| 541 | + { 0x39, "spc" }, | |
| 542 | + | |
| 543 | + { 0x3b, "f1" }, | |
| 544 | + { 0x3c, "f2" }, | |
| 545 | + { 0x3d, "f3" }, | |
| 546 | + { 0x3e, "f4" }, | |
| 547 | + { 0x3f, "f5" }, | |
| 548 | + { 0x40, "f6" }, | |
| 549 | + { 0x41, "f7" }, | |
| 550 | + { 0x42, "f8" }, | |
| 551 | + { 0x43, "f9" }, | |
| 552 | + { 0x44, "f10" }, | |
| 553 | + | |
| 554 | + { 0x46, "scroll_lock" }, | |
| 555 | + | |
| 556 | + { 0x56, "<" }, | |
| 557 | + | |
| 558 | + { 0x57, "f11" }, | |
| 559 | + { 0x58, "f12" }, | |
| 560 | + | |
| 561 | + { 0xb7, "print" }, | |
| 562 | + | |
| 563 | + { 0xc7, "home" }, | |
| 564 | + { 0xc9, "pgup" }, | |
| 565 | + { 0xd1, "pgdn" }, | |
| 566 | + { 0xcf, "end" }, | |
| 567 | + | |
| 568 | + { 0xcb, "left" }, | |
| 569 | + { 0xc8, "up" }, | |
| 570 | + { 0xd0, "down" }, | |
| 571 | + { 0xcd, "right" }, | |
| 572 | + | |
| 573 | + { 0xd2, "insert" }, | |
| 574 | + { 0xd3, "delete" }, | |
| 575 | + { 0, NULL }, | |
| 576 | +}; | |
| 577 | + | |
| 578 | +static int get_keycode(const char *key) | |
| 579 | +{ | |
| 580 | + const KeyDef *p; | |
| 581 | + | |
| 582 | + for(p = key_defs; p->name != NULL; p++) { | |
| 583 | + if (!strcmp(key, p->name)) | |
| 584 | + return p->keycode; | |
| 585 | + } | |
| 586 | + return -1; | |
| 587 | +} | |
| 588 | + | |
| 589 | +static void do_send_key(const char *string) | |
| 590 | +{ | |
| 591 | + char keybuf[16], *q; | |
| 592 | + uint8_t keycodes[16]; | |
| 593 | + const char *p; | |
| 594 | + int nb_keycodes, keycode, i; | |
| 595 | + | |
| 596 | + nb_keycodes = 0; | |
| 597 | + p = string; | |
| 598 | + while (*p != '\0') { | |
| 599 | + q = keybuf; | |
| 600 | + while (*p != '\0' && *p != '-') { | |
| 601 | + if ((q - keybuf) < sizeof(keybuf) - 1) { | |
| 602 | + *q++ = *p; | |
| 603 | + } | |
| 604 | + p++; | |
| 605 | + } | |
| 606 | + *q = '\0'; | |
| 607 | + keycode = get_keycode(keybuf); | |
| 608 | + if (keycode < 0) { | |
| 609 | + term_printf("unknown key: '%s'\n", keybuf); | |
| 610 | + return; | |
| 611 | + } | |
| 612 | + keycodes[nb_keycodes++] = keycode; | |
| 613 | + if (*p == '\0') | |
| 614 | + break; | |
| 615 | + p++; | |
| 616 | + } | |
| 617 | + /* key down events */ | |
| 618 | + for(i = 0; i < nb_keycodes; i++) { | |
| 619 | + keycode = keycodes[i]; | |
| 620 | + if (keycode & 0x80) | |
| 621 | + kbd_put_keycode(0xe0); | |
| 622 | + kbd_put_keycode(keycode & 0x7f); | |
| 623 | + } | |
| 624 | + /* key up events */ | |
| 625 | + for(i = nb_keycodes - 1; i >= 0; i--) { | |
| 626 | + keycode = keycodes[i]; | |
| 627 | + if (keycode & 0x80) | |
| 628 | + kbd_put_keycode(0xe0); | |
| 629 | + kbd_put_keycode(keycode | 0x80); | |
| 630 | + } | |
| 631 | +} | |
| 632 | + | |
| 633 | + | |
| 479 | 634 | static term_cmd_t term_cmds[] = { |
| 480 | 635 | { "help|?", "s?", do_help, |
| 481 | 636 | "[cmd]", "show the help" }, |
| ... | ... | @@ -511,6 +666,8 @@ static term_cmd_t term_cmds[] = { |
| 511 | 666 | "/fmt addr", "physical memory dump starting at 'addr'", }, |
| 512 | 667 | { "p|print", "/i", do_print, |
| 513 | 668 | "/fmt expr", "print expression value (use $reg for CPU register access)", }, |
| 669 | + { "sendkey", "s", do_send_key, | |
| 670 | + "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" }, | |
| 514 | 671 | { NULL, NULL, }, |
| 515 | 672 | }; |
| 516 | 673 | ... | ... |
qemu-doc.texi
| ... | ... | @@ -484,6 +484,17 @@ Dump 80 16 bit values at the start of the video memory. |
| 484 | 484 | Print expression value. Only the @var{format} part of @var{fmt} is |
| 485 | 485 | used. |
| 486 | 486 | |
| 487 | +@item sendkey keys | |
| 488 | + | |
| 489 | +Send @var{keys} to the emulator. Use @code{-} to press several keys | |
| 490 | +simultaneously. Example: | |
| 491 | +@example | |
| 492 | +sendkey ctrl-alt-f1 | |
| 493 | +@end example | |
| 494 | + | |
| 495 | +This command is useful to send keys that your graphical user interface | |
| 496 | +intercepts at low level, such as @code{ctrl-alt-f1} in X Window. | |
| 497 | + | |
| 487 | 498 | @end table |
| 488 | 499 | |
| 489 | 500 | @subsection Integer expressions | ... | ... |