* [Qemu-devel] [PATCH V2] qemu, qmp: add keydown and keyup command for qmp
@ 2011-03-09 8:24 Lai Jiangshan
2011-03-09 13:11 ` Anthony Liguori
0 siblings, 1 reply; 2+ messages in thread
From: Lai Jiangshan @ 2011-03-09 8:24 UTC (permalink / raw)
To: Luiz Capitulino
Cc: Lai Jiangshan, kvm, qemu-devel, Markus Armbruster, Avi Kivity
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
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
---
diff --git a/monitor.c b/monitor.c
index 22ae3bb..725df83 100644
--- a/monitor.c
+++ b/monitor.c
@@ -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)
diff --git a/qmp-commands.hx b/qmp-commands.hx
index df40a3d..4c449bb 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -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,
+ },
+
+SQMP
+keyup
+---
+
+Release a key.
+
+Arguments:
+
+- "keycode": the code of the key to release (json-int)
+
+Example:
+
+-> { "execute": "keyup", "arguments": { "keycode": 16 } }
+<- { "return": {} }
+
+EQMP
+
+ {
.name = "cpu",
.args_type = "index:i",
.params = "index",
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [Qemu-devel] [PATCH V2] qemu, qmp: add keydown and keyup command for qmp
2011-03-09 8:24 [Qemu-devel] [PATCH V2] qemu, qmp: add keydown and keyup command for qmp Lai Jiangshan
@ 2011-03-09 13:11 ` Anthony Liguori
0 siblings, 0 replies; 2+ messages in thread
From: Anthony Liguori @ 2011-03-09 13:11 UTC (permalink / raw)
To: Lai Jiangshan
Cc: Lai Jiangshan, kvm, Markus Armbruster, qemu-devel, Avi Kivity,
Luiz Capitulino
On 03/09/2011 02:24 AM, Lai Jiangshan wrote:
> 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
>
> Signed-off-by: Lai Jiangshan<laijs@cn.fujitsu.com>
> ---
> diff --git a/monitor.c b/monitor.c
> index 22ae3bb..725df83 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -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)
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index df40a3d..4c449bb 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -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,
> + },
> +
> +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
> +Example:
> +
> +-> { "execute": "keyup", "arguments": { "keycode": 16 } }
> +<- { "return": {} }
> +
> +EQMP
> +
> + {
> .name = "cpu",
> .args_type = "index:i",
> .params = "index",
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-03-09 13:11 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-09 8:24 [Qemu-devel] [PATCH V2] qemu, qmp: add keydown and keyup command for qmp Lai Jiangshan
2011-03-09 13:11 ` Anthony Liguori
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).