qemu,qmp: add keydown and keyup command for qmp
PATCH v2 1/1 qemu,qmp: add keydown and keyup command for qmp
sendkey is a very good command for human using it in their monitor, but it is not a good idea to port it to qmp, because qmp is a machine protocol. So we introduce keydown and keyup command for qmp, they simulate the events that keyboard send to the system.
Example, simulates ctrl+alt+f1:
{ "execute": "keydown", "arguments": { "keycode": 29 } } #press down ctrl
{ "execute": "keydown", "arguments": { "keycode": 56 } } #press down alt
{ "execute": "keydown", "arguments": { "keycode": 59 } } #press down f1
{ "execute": "keyup", "arguments": { "keycode": 59 } } #release f1
{ "execute": "keyup", "arguments": { "keycode": 56 } } #release alt
{ "execute": "keyup", "arguments": { "keycode": 29 } } #release ctrl---
monitor.c +45 -12
@@ -1810,16 +1810,25 @@ static uint8_t keycodes[MAX_KEYCODES];static int nb_pending_keycodes;static QEMUTimer *key_timer; -static void release_keys (void *opaque) +static void keydown (uint8_t keycode) { -int keycode; +if (keycode &0x80 ) +kbd_put_keycode (0xe0 ); +kbd_put_keycode (keycode &0x7f ); +} +static void keyup (uint8_t keycode) +{ +if (keycode &0x80 ) +kbd_put_keycode (0xe0 ); +kbd_put_keycode (keycode |0x80 ); +} + +static void release_keys (void *opaque) +{while (nb_pending_keycodes >0 ) { nb_pending_keycodes--; - keycode = keycodes[nb_pending_keycodes]; -if (keycode &0x80 ) -kbd_put_keycode (0xe0 ); -kbd_put_keycode (keycode |0x80 ); +keyup (keycodes[nb_pending_keycodes]); } }
@@ -1866,17 +1875,41 @@ static void do_sendkey(Monitor *mon, const QDict *qdict) } nb_pending_keycodes = i;/* key down events */ -for (i =0 ; i < nb_pending_keycodes; i++) { - keycode = keycodes[i]; -if (keycode &0x80 ) -kbd_put_keycode (0xe0 ); -kbd_put_keycode (keycode &0x7f ); - } +for (i =0 ; i < nb_pending_keycodes; i++) +keydown (keycodes[i]);/* delayed key up events */ qemu_mod_timer (key_timer,qemu_get_clock (vm_clock) +muldiv64 (get_ticks_per_sec (), hold_time,1000 )); } +static int qmp_keyaction (const QDict *qdict,int down) +{ +int keycode =qdict_get_int (qdict,"keycode" ); + +if (keycode <0 || keycode >=256 ) { +qerror_report (QERR_INVALID_PARAMETER_VALUE ,"keycode" , +"a valid keycode" ); +return -1 ; + } + +if (down) +keydown (keycode); +else +keyup (keycode); + +return 0 ; +} + +static int qmp_keydown (Monitor *mon,const QDict *qdict,QObject **ret_data) +{ +return qmp_keyaction (qdict,1 ); +} + +static int qmp_keyup (Monitor *mon,const QDict *qdict,QObject **ret_data) +{ +return qmp_keyaction (qdict,0 ); +} +static int mouse_button_state;static void do_mouse_move (Monitor *mon,const QDict *qdict)
qmp-commands.hx +52 -0
58 lines not on this page · raw message
Re: [Qemu-devel] [PATCH V2] qemu, qmp: add keydown and keyup command for qmp
Quoted 142 lines · Lai Jiangshan
sendkey is a very good command for human using it in their monitor, but it is not a good idea to port it to qmp, because qmp is a machine protocol. So we introduce keydown and keyup command for qmp, they simulate the events that keyboard send to the system.
Example, simulates ctrl+alt+f1:
{ "execute": "keydown", "arguments": { "keycode": 29 } } #press down ctrl { "execute": "keydown", "arguments": { "keycode": 56 } } #press down alt { "execute": "keydown", "arguments": { "keycode": 59 } } #press down f1 { "execute": "keyup", "arguments": { "keycode": 59 } } #release f1 { "execute": "keyup", "arguments": { "keycode": 56 } } #release alt { "execute": "keyup", "arguments": { "keycode": 29 } } #release ctrlSigned-off-by Lai Jiangshan<[email protected]>---
monitor.c +45
-12@@ -1810,16 +1810,25 @@ static uint8_t keycodes[MAX_KEYCODES];static int nb_pending_keycodes;static QEMUTimer *key_timer; -static void release_keys (void *opaque) +static void keydown (uint8_t keycode) { -int keycode; +if (keycode&0x80 ) +kbd_put_keycode (0xe0 ); +kbd_put_keycode (keycode&0x7f ); +} +static void keyup (uint8_t keycode) +{ +if (keycode&0x80 ) +kbd_put_keycode (0xe0 ); +kbd_put_keycode (keycode |0x80 ); +} + +static void release_keys (void *opaque) +{while (nb_pending_keycodes>0 ) { nb_pending_keycodes--; - keycode = keycodes[nb_pending_keycodes]; -if (keycode&0x80 ) -kbd_put_keycode (0xe0 ); -kbd_put_keycode (keycode |0x80 ); +keyup (keycodes[nb_pending_keycodes]); } }@@ -1866,17 +1875,41 @@ static void do_sendkey(Monitor *mon, const QDict *qdict) } nb_pending_keycodes = i;/* key down events */ -for (i =0 ; i< nb_pending_keycodes; i++) { - keycode = keycodes[i]; -if (keycode&0x80 ) -kbd_put_keycode (0xe0 ); -kbd_put_keycode (keycode&0x7f ); - } +for (i =0 ; i< nb_pending_keycodes; i++) +keydown (keycodes[i]);/* delayed key up events */ qemu_mod_timer (key_timer,qemu_get_clock (vm_clock) +muldiv64 (get_ticks_per_sec (), hold_time,1000 )); } +static int qmp_keyaction (const QDict *qdict,int down) +{ +int keycode =qdict_get_int (qdict,"keycode" ); + +if (keycode<0 || keycode>=256 ) { +qerror_report (QERR_INVALID_PARAMETER_VALUE ,"keycode" , +"a valid keycode" ); +return -1 ; + } + +if (down) +keydown (keycode); +else +keyup (keycode); + +return 0 ; +} + +static int qmp_keydown (Monitor *mon,const QDict *qdict,QObject **ret_data) +{ +return qmp_keyaction (qdict,1 ); +} + +static int qmp_keyup (Monitor *mon,const QDict *qdict,QObject **ret_data) +{ +return qmp_keyaction (qdict,0 ); +} +static int mouse_button_state;static void do_mouse_move (Monitor *mon,const QDict *qdict)qmp-commands.hx +33
-0@@ -338,6 +338,58 @@ Example: EQMP { + .name = "keydown", + .args_type = "keycode:i", + .params = "keycode", + .help = "press down a key", + .user_print = monitor_user_noop, + .mhandler.cmd_new = qmp_keydown, + }, + +SQMP +keydown +--- + +Press down a key. + +Arguments: + +- "keycode": the code of the key to press down (json-int) + +Example: + +-> { "execute": "keydown", "arguments": { "keycode": 16 } } +<- { "return": {} } + +EQMP + + { + .name = "keyup", + .args_type = "keycode:i", + .params = "keycode", + .help = "release a key", + .user_print = monitor_user_noop, + .mhandler.cmd_new = qmp_keyup, + },
qmp-commands.hx Example: · line 383
Quoted 10 lines
qmp-commands.hx +10
-0+ +SQMP +keyup +--- + +Release a key. + +Arguments: + +- "keycode": the code of the key to release (json-int)
What is the value of "keycode" and what happens if you pass an invalid keycode?
This interface uses QEMU-style compressed XT scan codes. I'd suggest making the interface take two optional arguments one being the an integer keycode and then another being a symbolic name where the symbolic name used the current keymap to translate the keycode.
For the XT scan code, I wouldn't use the one-byte encoding. I'd use a 32-bit encoding.
Regards,
Anthony Liguori
Quoted 12 lines
qmp-commands.hx +8
-0+Example: + +-> { "execute": "keyup", "arguments": { "keycode": 16 } } +<- { "return": {} } + +EQMP + + { .name = "cpu", .args_type = "index:i", .params = "index",