Commit c8256f9d23bba4fac3b0b6a9e6e3dc12362cbe0b

Authored by balrog
1 parent 7dd9e556

Enhance sendkey with key hold time (Jan Kiszka).

Current key injection via the monitor basically generates no key hold
time. This is fine for keyboard emulations that have their own queues,
but it causes troubles for those how don't (like the MusicPal - it
simply does not work with injected keys). Moreover, I would like to use
this mechanism to simulate pressed buttons during power-up.

Therefore, this patch enhances the key injection with a configurable
release delay (by default 100 virtual milliseconds).

This feature allows to get rid of the initial sleep() in musicpal_init
because one can now simply start qemu with -S and issue "sendkey m 1000"
and "continue" in the monitor to achieve the desired effect of a pressed
menu button during power-up. So there is no need for a per-musicpal or
even qemu-wide "-hold-button" switch.

Signed-off-by: Jan Kiszka <jan.kiszka@web.de>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4701 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 39 additions and 25 deletions
hw/musicpal.c
@@ -1504,12 +1504,6 @@ static void musicpal_init(ram_addr_t ram_size, int vga_ram_size, @@ -1504,12 +1504,6 @@ static void musicpal_init(ram_addr_t ram_size, int vga_ram_size,
1504 1504
1505 qemu_add_kbd_event_handler(musicpal_key_event, pic[MP_GPIO_IRQ]); 1505 qemu_add_kbd_event_handler(musicpal_key_event, pic[MP_GPIO_IRQ]);
1506 1506
1507 - /*  
1508 - * Wait a bit to catch menu button during U-Boot start-up  
1509 - * (to trigger emergency update).  
1510 - */  
1511 - sleep(1);  
1512 -  
1513 mv88w8618_eth_init(&nd_table[0], MP_ETH_BASE, pic[MP_ETH_IRQ]); 1507 mv88w8618_eth_init(&nd_table[0], MP_ETH_BASE, pic[MP_ETH_IRQ]);
1514 1508
1515 mixer_i2c = musicpal_audio_init(MP_AUDIO_BASE, pic[MP_AUDIO_IRQ]); 1509 mixer_i2c = musicpal_audio_init(MP_AUDIO_BASE, pic[MP_AUDIO_IRQ]);
monitor.c
@@ -35,10 +35,7 @@ @@ -35,10 +35,7 @@
35 #include "audio/audio.h" 35 #include "audio/audio.h"
36 #include "disas.h" 36 #include "disas.h"
37 #include <dirent.h> 37 #include <dirent.h>
38 -  
39 -#ifdef CONFIG_PROFILER  
40 -#include "qemu-timer.h" /* for ticks_per_sec */  
41 -#endif 38 +#include "qemu-timer.h"
42 39
43 //#define DEBUG 40 //#define DEBUG
44 //#define DEBUG_COMPLETION 41 //#define DEBUG_COMPLETION
@@ -920,14 +917,37 @@ static int get_keycode(const char *key) @@ -920,14 +917,37 @@ static int get_keycode(const char *key)
920 return -1; 917 return -1;
921 } 918 }
922 919
923 -static void do_sendkey(const char *string) 920 +#define MAX_KEYCODES 16
  921 +static uint8_t keycodes[MAX_KEYCODES];
  922 +static int nb_pending_keycodes;
  923 +static QEMUTimer *key_timer;
  924 +
  925 +static void release_keys(void *opaque)
  926 +{
  927 + int keycode;
  928 +
  929 + while (nb_pending_keycodes > 0) {
  930 + nb_pending_keycodes--;
  931 + keycode = keycodes[nb_pending_keycodes];
  932 + if (keycode & 0x80)
  933 + kbd_put_keycode(0xe0);
  934 + kbd_put_keycode(keycode | 0x80);
  935 + }
  936 +}
  937 +
  938 +static void do_sendkey(const char *string, int has_hold_time, int hold_time)
924 { 939 {
925 - uint8_t keycodes[16];  
926 - int nb_keycodes = 0;  
927 char keyname_buf[16]; 940 char keyname_buf[16];
928 char *separator; 941 char *separator;
929 int keyname_len, keycode, i; 942 int keyname_len, keycode, i;
930 943
  944 + if (nb_pending_keycodes > 0) {
  945 + qemu_del_timer(key_timer);
  946 + release_keys(NULL);
  947 + }
  948 + if (!has_hold_time)
  949 + hold_time = 100;
  950 + i = 0;
931 while (1) { 951 while (1) {
932 separator = strchr(string, '-'); 952 separator = strchr(string, '-');
933 keyname_len = separator ? separator - string : strlen(string); 953 keyname_len = separator ? separator - string : strlen(string);
@@ -937,7 +957,7 @@ static void do_sendkey(const char *string) @@ -937,7 +957,7 @@ static void do_sendkey(const char *string)
937 term_printf("invalid key: '%s...'\n", keyname_buf); 957 term_printf("invalid key: '%s...'\n", keyname_buf);
938 return; 958 return;
939 } 959 }
940 - if (nb_keycodes == sizeof(keycodes)) { 960 + if (i == MAX_KEYCODES) {
941 term_printf("too many keys\n"); 961 term_printf("too many keys\n");
942 return; 962 return;
943 } 963 }
@@ -947,26 +967,23 @@ static void do_sendkey(const char *string) @@ -947,26 +967,23 @@ static void do_sendkey(const char *string)
947 term_printf("unknown key: '%s'\n", keyname_buf); 967 term_printf("unknown key: '%s'\n", keyname_buf);
948 return; 968 return;
949 } 969 }
950 - keycodes[nb_keycodes++] = keycode; 970 + keycodes[i++] = keycode;
951 } 971 }
952 if (!separator) 972 if (!separator)
953 break; 973 break;
954 string = separator + 1; 974 string = separator + 1;
955 } 975 }
  976 + nb_pending_keycodes = i;
956 /* key down events */ 977 /* key down events */
957 - for(i = 0; i < nb_keycodes; i++) { 978 + for (i = 0; i < nb_pending_keycodes; i++) {
958 keycode = keycodes[i]; 979 keycode = keycodes[i];
959 if (keycode & 0x80) 980 if (keycode & 0x80)
960 kbd_put_keycode(0xe0); 981 kbd_put_keycode(0xe0);
961 kbd_put_keycode(keycode & 0x7f); 982 kbd_put_keycode(keycode & 0x7f);
962 } 983 }
963 - /* key up events */  
964 - for(i = nb_keycodes - 1; i >= 0; i--) {  
965 - keycode = keycodes[i];  
966 - if (keycode & 0x80)  
967 - kbd_put_keycode(0xe0);  
968 - kbd_put_keycode(keycode | 0x80);  
969 - } 984 + /* delayed key up events */
  985 + qemu_mod_timer(key_timer,
  986 + qemu_get_clock(vm_clock) + ticks_per_sec * hold_time);
970 } 987 }
971 988
972 static int mouse_button_state; 989 static int mouse_button_state;
@@ -1353,8 +1370,8 @@ static term_cmd_t term_cmds[] = { @@ -1353,8 +1370,8 @@ static term_cmd_t term_cmds[] = {
1353 { "i", "/ii.", do_ioport_read, 1370 { "i", "/ii.", do_ioport_read,
1354 "/fmt addr", "I/O port read" }, 1371 "/fmt addr", "I/O port read" },
1355 1372
1356 - { "sendkey", "s", do_sendkey,  
1357 - "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" }, 1373 + { "sendkey", "si?", do_sendkey,
  1374 + "keys [hold_ms]", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms)" },
1358 { "system_reset", "", do_system_reset, 1375 { "system_reset", "", do_system_reset,
1359 "", "reset the system" }, 1376 "", "reset the system" },
1360 { "system_powerdown", "", do_system_powerdown, 1377 { "system_powerdown", "", do_system_powerdown,
@@ -2638,6 +2655,9 @@ void monitor_init(CharDriverState *hd, int show_banner) @@ -2638,6 +2655,9 @@ void monitor_init(CharDriverState *hd, int show_banner)
2638 int i; 2655 int i;
2639 2656
2640 if (is_first_init) { 2657 if (is_first_init) {
  2658 + key_timer = qemu_new_timer(vm_clock, release_keys, NULL);
  2659 + if (!key_timer)
  2660 + return;
2641 for (i = 0; i < MAX_MON; i++) { 2661 for (i = 0; i < MAX_MON; i++) {
2642 monitor_hd[i] = NULL; 2662 monitor_hd[i] = NULL;
2643 } 2663 }