From patchwork Thu Sep 20 18:18:00 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Capitulino X-Patchwork-Id: 185439 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 35B422C0094 for ; Fri, 21 Sep 2012 04:17:39 +1000 (EST) Received: from localhost ([::1]:36176 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TElJh-0005ZJ-78 for incoming@patchwork.ozlabs.org; Thu, 20 Sep 2012 14:17:37 -0400 Received: from eggs.gnu.org ([208.118.235.92]:49406) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TElJP-0005FY-UN for qemu-devel@nongnu.org; Thu, 20 Sep 2012 14:17:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TElJO-0004zv-Jh for qemu-devel@nongnu.org; Thu, 20 Sep 2012 14:17:19 -0400 Received: from mx1.redhat.com ([209.132.183.28]:61709) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TElJO-0004zn-6V for qemu-devel@nongnu.org; Thu, 20 Sep 2012 14:17:18 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q8KIHHEi031353 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 20 Sep 2012 14:17:17 -0400 Received: from localhost (ovpn-113-86.phx2.redhat.com [10.3.113.86]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q8KIHGgc004067; Thu, 20 Sep 2012 14:17:17 -0400 From: Luiz Capitulino To: qemu-devel@nongnu.org Date: Thu, 20 Sep 2012 15:18:00 -0300 Message-Id: <1348165081-28292-3-git-send-email-lcapitulino@redhat.com> In-Reply-To: <1348165081-28292-1-git-send-email-lcapitulino@redhat.com> References: <1348165081-28292-1-git-send-email-lcapitulino@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: akong@redhat.com, eblake@redhat.com, avi@redhat.com Subject: [Qemu-devel] [PATCH 2/3] qmp: qmp_send_key(): accept key codes in hex X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Before the qapi conversion, the sendkey command could be used to send key codes in hex directly to the guest. This doesn't work with the current implemention, as it will only send to the guest QKeyCode values. That's a regression. This commit fixes the problem by adding hex value support down the QMP interface, qmp_send_key(). In more detail, this commit: 1. Adds the KeyValue union. This can represent an hex value or a QKeyCode value 2. *Changes* the QMP send-key command to take an KeyValue argument instead of a QKeyCode one. 3. Adapt hmp_send_key() to the QMP interface changes Item 2 is an incompatible change, but as we're development phase (and this command has been merged a few weeks ago) this shouldn't be a problem. Lastly, it's not possible to split this commit without breaking the build. Reported-by: Avi Kivity Signed-off-by: Luiz Capitulino Reviewed-by: Eric Blake --- hmp.c | 43 +++++++++++++++++++++++++++++-------------- input.c | 23 ++++++++++++++++++++--- qapi-schema.json | 19 ++++++++++++++++--- 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/hmp.c b/hmp.c index ba6fbd3..3e64913 100644 --- a/hmp.c +++ b/hmp.c @@ -1109,13 +1109,13 @@ void hmp_closefd(Monitor *mon, const QDict *qdict) void hmp_send_key(Monitor *mon, const QDict *qdict) { const char *keys = qdict_get_str(qdict, "keys"); - QKeyCodeList *keylist, *head = NULL, *tmp = NULL; + KeyValueList *keylist, *head = NULL, *tmp = NULL; int has_hold_time = qdict_haskey(qdict, "hold-time"); int hold_time = qdict_get_try_int(qdict, "hold-time", -1); Error *err = NULL; char keyname_buf[16]; char *separator; - int keyname_len, idx; + int keyname_len; while (1) { separator = strchr(keys, '-'); @@ -1129,15 +1129,8 @@ void hmp_send_key(Monitor *mon, const QDict *qdict) } keyname_buf[keyname_len] = 0; - idx = index_from_key(keyname_buf); - if (idx == Q_KEY_CODE_MAX) { - monitor_printf(mon, "invalid parameter: %s\n", keyname_buf); - break; - } - keylist = g_malloc0(sizeof(*keylist)); - keylist->value = idx; - keylist->next = NULL; + keylist->value = g_malloc0(sizeof(*keylist->value)); if (!head) { head = keylist; @@ -1147,17 +1140,39 @@ void hmp_send_key(Monitor *mon, const QDict *qdict) } tmp = keylist; + if (strstart(keyname_buf, "0x", NULL)) { + char *endp; + int value = strtoul(keyname_buf, &endp, 0); + if (*endp != '\0') { + goto err_out; + } + keylist->value->kind = KEY_VALUE_KIND_HEX; + keylist->value->hex = value; + } else { + int idx = index_from_key(keyname_buf); + if (idx == Q_KEY_CODE_MAX) { + goto err_out; + } + keylist->value->kind = KEY_VALUE_KIND_QCODE; + keylist->value->qcode = idx; + } + if (!separator) { break; } keys = separator + 1; } - if (idx != Q_KEY_CODE_MAX) { - qmp_send_key(head, has_hold_time, hold_time, &err); - } + qmp_send_key(head, has_hold_time, hold_time, &err); hmp_handle_error(mon, &err); - qapi_free_QKeyCodeList(head); + +out: + qapi_free_KeyValueList(head); + return; + +err_out: + monitor_printf(mon, "invalid parameter: %s\n", keyname_buf); + goto out; } void hmp_screen_dump(Monitor *mon, const QDict *qdict) diff --git a/input.c b/input.c index 32c6057..187a131 100644 --- a/input.c +++ b/input.c @@ -228,6 +228,16 @@ static int *keycodes; static int keycodes_size; static QEMUTimer *key_timer; +static int keycode_from_keyvalue(const KeyValue *value) +{ + if (value->kind == KEY_VALUE_KIND_QCODE) { + return key_defs[value->qcode]; + } else { + assert(value->kind == KEY_VALUE_KIND_HEX); + return value->hex; + } +} + static void release_keys(void *opaque) { int i; @@ -244,11 +254,11 @@ static void release_keys(void *opaque) keycodes_size = 0; } -void qmp_send_key(QKeyCodeList *keys, bool has_hold_time, int64_t hold_time, +void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time, Error **errp) { int keycode; - QKeyCodeList *p; + KeyValueList *p; if (!key_timer) { key_timer = qemu_new_timer_ns(vm_clock, release_keys, NULL); @@ -265,7 +275,14 @@ void qmp_send_key(QKeyCodeList *keys, bool has_hold_time, int64_t hold_time, for (p = keys; p != NULL; p = p->next) { /* key down events */ - keycode = key_defs[p->value]; + keycode = keycode_from_keyvalue(p->value); + if (keycode < 0x01 || keycode > 0xff) { + error_setg(errp, "invalid hex keycode 0x%x\n", keycode); + g_free(keycodes); + keycodes_size = 0; + return; + } + if (keycode & 0x80) { kbd_put_keycode(0xe0); } diff --git a/qapi-schema.json b/qapi-schema.json index 14e4419..688230f 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2588,12 +2588,25 @@ 'lf', 'help', 'meta_l', 'meta_r', 'compose' ] } ## +# @KeyValue +# +# Represents a keyboard key. +# +# Since: 1.3.0 +## +{ 'union': 'KeyValue', + 'data': { + 'hex': 'int', + 'qcode': 'QKeyCode' } } + +## # @send-key: # # Send keys to guest. # -# @keys: key sequence. 'keys' is the name of the key. Use a JSON array to -# press several keys simultaneously. +# @keys: An array of @KeyValue elements. All @KeyValues in this array are +# simultaneously sent to the guest. A @KeyValue.hex value is sent +# directly to the guest # # @hold-time: #optional time to delay key up events, milliseconds. Defaults # to 100 @@ -2605,7 +2618,7 @@ # ## { 'command': 'send-key', - 'data': { 'keys': ['QKeyCode'], '*hold-time': 'int' } } + 'data': { 'keys': ['KeyValue'], '*hold-time': 'int' } } ## # @screendump: