From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=43628 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PxJBE-0006Fa-JY for qemu-devel@nongnu.org; Wed, 09 Mar 2011 08:11:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PxJBD-0005Gc-2a for qemu-devel@nongnu.org; Wed, 09 Mar 2011 08:11:56 -0500 Received: from mail-yw0-f45.google.com ([209.85.213.45]:47489) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PxJBC-0005GN-RN for qemu-devel@nongnu.org; Wed, 09 Mar 2011 08:11:55 -0500 Received: by ywl41 with SMTP id 41so279640ywl.4 for ; Wed, 09 Mar 2011 05:11:54 -0800 (PST) Message-ID: <4D777C98.9010104@codemonkey.ws> Date: Wed, 09 Mar 2011 07:11:52 -0600 From: Anthony Liguori MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH V2] qemu, qmp: add keydown and keyup command for qmp References: <4D773943.60803@cn.fujitsu.com> In-Reply-To: <4D773943.60803@cn.fujitsu.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Lai Jiangshan Cc: Lai Jiangshan , kvm@vger.kernel.org, Markus Armbruster , qemu-devel@nongnu.org, 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 > --- > 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", >