From patchwork Fri Mar 11 02:32:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Programmingkid X-Patchwork-Id: 8561341 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id DECC6C0553 for ; Fri, 11 Mar 2016 02:32:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CAC0B20165 for ; Fri, 11 Mar 2016 02:32:43 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 918022014A for ; Fri, 11 Mar 2016 02:32:42 +0000 (UTC) Received: from localhost ([::1]:52234 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aeCsb-0003xU-QZ for patchwork-qemu-devel@patchwork.kernel.org; Thu, 10 Mar 2016 21:32:41 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44799) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aeCsU-0003wm-7G for qemu-devel@nongnu.org; Thu, 10 Mar 2016 21:32:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aeCsP-0001mO-1t for qemu-devel@nongnu.org; Thu, 10 Mar 2016 21:32:34 -0500 Received: from mail-io0-x244.google.com ([2607:f8b0:4001:c06::244]:35646) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aeCsO-0001mH-Qo for qemu-devel@nongnu.org; Thu, 10 Mar 2016 21:32:28 -0500 Received: by mail-io0-x244.google.com with SMTP id n190so9892678iof.2 for ; Thu, 10 Mar 2016 18:32:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:content-transfer-encoding:subject:date:message-id:cc:to :mime-version; bh=jMlBu9DGaphTNET5PDdw3kcH8oVbYpYr586EUL2xn/0=; b=BULOAiX5eAqp/UUP9JaiHCoo7iEKlZ2nlvmPNXZarai65rPXLVEu/43PXxTKCpbqBn DvvqoMLCCTme7nug0j5JrenNO21YulCjwqg+Jr621lEmf86KnCte8GRicqjxsEhoLomb xwv2or4m0o8iHTJ6KJszlR1WfAIuR6Bn1jdz755TjJmFvUPQNIQ8Joj18vuxz9dS94Fx VZYYEOX8TT1oKz6UM5IQMa2eXnhUuiV+Zh6UZA/fTvjE6yUK2nuGuDao06plS/+2cYUD 3JuyDk6NZ34ickDSV/UtDXUlX7c8IuCxVfdmJTnHzMP0dw/OBXq8sSWrMYdZiv9NWZzb EfhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:content-transfer-encoding:subject:date :message-id:cc:to:mime-version; bh=jMlBu9DGaphTNET5PDdw3kcH8oVbYpYr586EUL2xn/0=; b=FhsyHD/+NImYkKGABzVSBNxiTctiosZ63B3zcp8Qqf/zOgmB++7XbQ+XKAyCzRyRgp OExiYu9pjPoISI/A8DEHpSAktw0qoNZ3fPKiP1weU0wzU4dx7YH5j7dFCRYTUsNwAchs ah4EcrbFPxgviIJjHEHVDwX5zImhvDJtW6a/FjLttpC8JcC55/NQV2ZGF4Se3yjvhtYs pKKHVe3ePhquzXZAQd6UM7BS7tsia2ucvjANoXa3c7Y9mig6rWZ9Fb9BfzrlnAPfBK4W rhC8FAkdhdrSZ/Nq+H3CZSBfTy4LBsgCmFycBSiSikczrMdEIJUVLJO/XfKICx4tQAXr pt7w== X-Gm-Message-State: AD7BkJKvOXMGLxEUEAJIT1gZ7Wi2YUqeiBMhwYz265FhkSEjtzDNuwDG10/quhXp3EhHeg== X-Received: by 10.107.2.69 with SMTP id 66mr8472242ioc.8.1457663548284; Thu, 10 Mar 2016 18:32:28 -0800 (PST) Received: from [192.168.0.5] (d199-74-164-53.col.wideopenwest.com. [74.199.53.164]) by smtp.gmail.com with ESMTPSA id j10sm10107igx.15.2016.03.10.18.32.27 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 10 Mar 2016 18:32:27 -0800 (PST) From: Programmingkid Date: Thu, 10 Mar 2016 21:32:26 -0500 Message-Id: <8768A4C2-CEBF-411A-9B43-9F43EA755238@gmail.com> To: Peter Maydell , Gerd Hoffmann , Eric Blake Mime-Version: 1.0 (Apple Message framework v1084) X-Mailer: Apple Mail (2.1084) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:4001:c06::244 Cc: qemu-devel qemu-devel Subject: [Qemu-devel] [PATCH v4 4/4] hw/input/adb.c: implement QKeyCode support 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+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, UNPARSEABLE_RELAY, UPPERCASE_50_75 autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Remove the old pc_to_adb_keycode array and replace it with QKeyCode support. Signed-off-by: John Arbuckle --- Some of the keys do not translate as logically as we would think they would. For example the Q_KEY_CODE_CTRL_R does not work with ADB_KEY_RIGHT_CONTROL. The wrong key would show up in the guest. These problem keys are commmented out and replaced with the number that does work correctly. This patch can be easily tested with the Linux command xev or Mac OS's Key Caps. hw/input/adb.c | 223 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 177 insertions(+), 46 deletions(-) diff --git a/hw/input/adb.c b/hw/input/adb.c index f0ad0d4..d176d39 100644 --- a/hw/input/adb.c +++ b/hw/input/adb.c @@ -25,6 +25,9 @@ #include "hw/hw.h" #include "hw/input/adb.h" #include "ui/console.h" +#include "include/hw/input/adb-keys.h" +#include "ui/input.h" +#include "sysemu/sysemu.h" /* debug ADB */ //#define DEBUG_ADB @@ -59,6 +62,9 @@ do { printf("ADB: " fmt , ## __VA_ARGS__); } while (0) /* error codes */ #define ADB_RET_NOTPRESENT (-2) +/* The adb keyboard doesn't have every key imaginable */ +#define NO_KEY 0xff + static void adb_device_reset(ADBDevice *d) { qdev_reset_all(DEVICE(d)); @@ -187,23 +193,138 @@ typedef struct ADBKeyboardClass { DeviceRealize parent_realize; } ADBKeyboardClass; -static const uint8_t pc_to_adb_keycode[256] = { - 0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48, - 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1, - 2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9, - 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96, - 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83, - 84, 85, 82, 65, 0, 0, 10,103,111, 0, 0,110, 81, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,125, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 75, 0, 0,124, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,115, 62,116, 0, 59, 0, 60, 0,119, - 61,121,114,117, 0, 0, 0, 0, 0, 0, 0, 55,126, 0,127, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +int qcode_to_adb_keycode[] = { + [Q_KEY_CODE_SHIFT] = ADB_KEY_LEFT_SHIFT, + [Q_KEY_CODE_SHIFT_R] = 123, /* ADB_KEY_RIGHT_SHIFT, */ + [Q_KEY_CODE_ALT] = ADB_KEY_LEFT_OPTION, + [Q_KEY_CODE_ALT_R] = 124, /* ADB_KEY_RIGHT_OPTION,*/ + [Q_KEY_CODE_ALTGR] = ADB_KEY_RIGHT_OPTION, + [Q_KEY_CODE_CTRL] = 54, /* ADB_KEY_LEFT_CONTROL, */ + [Q_KEY_CODE_CTRL_R] = 125, /* ADB_KEY_RIGHT_CONTROL, */ + [Q_KEY_CODE_META_L] = ADB_KEY_LEFT_COMMAND, + + /* 126 works as right super in Linux */ + /* Use ADB_KEY_LEFT_COMMAND for Mac OS compatibility */ + [Q_KEY_CODE_META_R] = ADB_KEY_LEFT_COMMAND, + [Q_KEY_CODE_SPC] = ADB_KEY_SPACEBAR, + + [Q_KEY_CODE_ESC] = ADB_KEY_ESC, + [Q_KEY_CODE_1] = ADB_KEY_1, + [Q_KEY_CODE_2] = ADB_KEY_2, + [Q_KEY_CODE_3] = ADB_KEY_3, + [Q_KEY_CODE_4] = ADB_KEY_4, + [Q_KEY_CODE_5] = ADB_KEY_5, + [Q_KEY_CODE_6] = ADB_KEY_6, + [Q_KEY_CODE_7] = ADB_KEY_7, + [Q_KEY_CODE_8] = ADB_KEY_8, + [Q_KEY_CODE_9] = ADB_KEY_9, + [Q_KEY_CODE_0] = ADB_KEY_0, + [Q_KEY_CODE_MINUS] = ADB_KEY_MINUS, + [Q_KEY_CODE_EQUAL] = ADB_KEY_EQUAL, + [Q_KEY_CODE_BACKSPACE] = ADB_KEY_DELETE, + [Q_KEY_CODE_TAB] = ADB_KEY_TAB, + [Q_KEY_CODE_Q] = ADB_KEY_Q, + [Q_KEY_CODE_W] = ADB_KEY_W, + [Q_KEY_CODE_E] = ADB_KEY_E, + [Q_KEY_CODE_R] = ADB_KEY_R, + [Q_KEY_CODE_T] = ADB_KEY_T, + [Q_KEY_CODE_Y] = ADB_KEY_Y, + [Q_KEY_CODE_U] = ADB_KEY_U, + [Q_KEY_CODE_I] = ADB_KEY_I, + [Q_KEY_CODE_O] = ADB_KEY_O, + [Q_KEY_CODE_P] = ADB_KEY_P, + [Q_KEY_CODE_BRACKET_LEFT] = ADB_KEY_LEFT_BRACKET, + [Q_KEY_CODE_BRACKET_RIGHT] = ADB_KEY_RIGHT_BRACKET, + [Q_KEY_CODE_RET] = ADB_KEY_RETURN, + [Q_KEY_CODE_A] = ADB_KEY_A, + [Q_KEY_CODE_S] = ADB_KEY_S, + [Q_KEY_CODE_D] = ADB_KEY_D, + [Q_KEY_CODE_F] = ADB_KEY_F, + [Q_KEY_CODE_G] = ADB_KEY_G, + [Q_KEY_CODE_H] = ADB_KEY_H, + [Q_KEY_CODE_J] = ADB_KEY_J, + [Q_KEY_CODE_K] = ADB_KEY_K, + [Q_KEY_CODE_L] = ADB_KEY_L, + [Q_KEY_CODE_SEMICOLON] = ADB_KEY_SEMICOLON, + [Q_KEY_CODE_APOSTROPHE] = ADB_KEY_APOSTROPHE, + [Q_KEY_CODE_GRAVE_ACCENT] = ADB_KEY_GRAVE_ACCENT, + [Q_KEY_CODE_BACKSLASH] = ADB_KEY_BACKSLASH, + [Q_KEY_CODE_Z] = ADB_KEY_Z, + [Q_KEY_CODE_X] = ADB_KEY_X, + [Q_KEY_CODE_C] = ADB_KEY_C, + [Q_KEY_CODE_V] = ADB_KEY_V, + [Q_KEY_CODE_B] = ADB_KEY_B, + [Q_KEY_CODE_N] = ADB_KEY_N, + [Q_KEY_CODE_M] = ADB_KEY_M, + [Q_KEY_CODE_COMMA] = ADB_KEY_COMMA, + [Q_KEY_CODE_DOT] = ADB_KEY_PERIOD, + [Q_KEY_CODE_SLASH] = ADB_KEY_FORWARD_SLASH, + [Q_KEY_CODE_ASTERISK] = ADB_KEY_KP_MULTIPLY, + [Q_KEY_CODE_CAPS_LOCK] = ADB_KEY_CAPS_LOCK, + + [Q_KEY_CODE_F1] = ADB_KEY_F1, + [Q_KEY_CODE_F2] = ADB_KEY_F2, + [Q_KEY_CODE_F3] = ADB_KEY_F3, + [Q_KEY_CODE_F4] = ADB_KEY_F4, + [Q_KEY_CODE_F5] = ADB_KEY_F5, + [Q_KEY_CODE_F6] = ADB_KEY_F6, + [Q_KEY_CODE_F7] = ADB_KEY_F7, + [Q_KEY_CODE_F8] = ADB_KEY_F8, + [Q_KEY_CODE_F9] = ADB_KEY_F9, + [Q_KEY_CODE_F10] = ADB_KEY_F10, + [Q_KEY_CODE_F11] = ADB_KEY_F11, + [Q_KEY_CODE_F12] = ADB_KEY_F12, + [Q_KEY_CODE_PRINT] = ADB_KEY_F13, + [Q_KEY_CODE_SYSRQ] = ADB_KEY_F13, + [Q_KEY_CODE_SCROLL_LOCK] = ADB_KEY_F14, + [Q_KEY_CODE_PAUSE] = ADB_KEY_F15, + [Q_KEY_CODE_POWER] = ADB_KEY_POWER, + + [Q_KEY_CODE_NUM_LOCK] = ADB_KEY_KP_CLEAR, + [Q_KEY_CODE_KP_EQUALS] = ADB_KEY_KP_EQUAL, + [Q_KEY_CODE_KP_DIVIDE] = ADB_KEY_KP_DIVIDE, + [Q_KEY_CODE_KP_MULTIPLY] = ADB_KEY_KP_MULTIPLY, + [Q_KEY_CODE_KP_SUBTRACT] = ADB_KEY_KP_SUBTRACT, + [Q_KEY_CODE_KP_ADD] = ADB_KEY_KP_PLUS, + [Q_KEY_CODE_KP_ENTER] = ADB_KEY_KP_ENTER, + [Q_KEY_CODE_KP_DECIMAL] = ADB_KEY_KP_PERIOD, + [Q_KEY_CODE_KP_0] = ADB_KEY_KP_0, + [Q_KEY_CODE_KP_1] = ADB_KEY_KP_1, + [Q_KEY_CODE_KP_2] = ADB_KEY_KP_2, + [Q_KEY_CODE_KP_3] = ADB_KEY_KP_3, + [Q_KEY_CODE_KP_4] = ADB_KEY_KP_4, + [Q_KEY_CODE_KP_5] = ADB_KEY_KP_5, + [Q_KEY_CODE_KP_6] = ADB_KEY_KP_6, + [Q_KEY_CODE_KP_7] = ADB_KEY_KP_7, + [Q_KEY_CODE_KP_8] = ADB_KEY_KP_8, + [Q_KEY_CODE_KP_9] = ADB_KEY_KP_9, + + [Q_KEY_CODE_UP] = 62, /* ADB_KEY_UP, */ + [Q_KEY_CODE_DOWN] = 61, /* ADB_KEY_DOWN, */ + [Q_KEY_CODE_LEFT] = 59, /* ADB_KEY_LEFT, */ + [Q_KEY_CODE_RIGHT] = 60, /* ADB_KEY_RIGHT, */ + + [Q_KEY_CODE_HELP] = ADB_KEY_HELP, + [Q_KEY_CODE_INSERT] = ADB_KEY_HELP, + [Q_KEY_CODE_DELETE] = ADB_KEY_FORWARD_DELETE, + [Q_KEY_CODE_HOME] = ADB_KEY_HOME, + [Q_KEY_CODE_END] = ADB_KEY_END, + [Q_KEY_CODE_PGUP] = ADB_KEY_PAGE_UP, + [Q_KEY_CODE_PGDN] = ADB_KEY_PAGE_DOWN, + + [Q_KEY_CODE_LESS] = NO_KEY, + [Q_KEY_CODE_STOP] = NO_KEY, + [Q_KEY_CODE_AGAIN] = NO_KEY, + [Q_KEY_CODE_PROPS] = NO_KEY, + [Q_KEY_CODE_UNDO] = NO_KEY, + [Q_KEY_CODE_FRONT] = NO_KEY, + [Q_KEY_CODE_COPY] = NO_KEY, + [Q_KEY_CODE_OPEN] = NO_KEY, + [Q_KEY_CODE_PASTE] = NO_KEY, + [Q_KEY_CODE_FIND] = NO_KEY, + [Q_KEY_CODE_CUT] = NO_KEY, + [Q_KEY_CODE_LF] = NO_KEY, + [Q_KEY_CODE_COMPOSE] = NO_KEY, }; static void adb_kbd_put_keycode(void *opaque, int keycode) @@ -220,35 +341,25 @@ static void adb_kbd_put_keycode(void *opaque, int keycode) static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf) { - static int ext_keycode; KBDState *s = ADB_KEYBOARD(d); - int adb_keycode, keycode; + int keycode; int olen; olen = 0; - for(;;) { - if (s->count == 0) - break; - keycode = s->data[s->rptr]; - if (++s->rptr == sizeof(s->data)) - s->rptr = 0; - s->count--; - - if (keycode == 0xe0) { - ext_keycode = 1; - } else { - if (ext_keycode) - adb_keycode = pc_to_adb_keycode[keycode | 0x80]; - else - adb_keycode = pc_to_adb_keycode[keycode & 0x7f]; - obuf[0] = adb_keycode | (keycode & 0x80); - /* NOTE: could put a second keycode if needed */ - obuf[1] = 0xff; - olen = 2; - ext_keycode = 0; - break; - } + if (s->count <= 0) { + return olen; + } + keycode = s->data[s->rptr]; + if (++s->rptr == sizeof(s->data)) { + s->rptr = 0; } + s->count--; + + obuf[0] = keycode; + /* NOTE: could put a second keycode if needed */ + obuf[1] = 0xff; + olen = 2; + return olen; } @@ -313,6 +424,24 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf, return olen; } +/* The is where keyboard events enter this file */ +static void adb_keyboard_event(DeviceState *dev, QemuConsole *src, + InputEvent *evt) +{ + KBDState *s = (KBDState *)dev; + int qcode, keycode; + + qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER); + qcode = qemu_input_key_value_to_qcode(evt->u.key->key); + keycode = qcode_to_adb_keycode[qcode]; + + if (evt->u.key->down == false) { /* if key up event */ + keycode = keycode | 0x80; /* create keyboard break code */ + } + + adb_kbd_put_keycode(s, keycode); +} + static const VMStateDescription vmstate_adb_kbd = { .name = "adb_kbd", .version_id = 2, @@ -342,18 +471,20 @@ static void adb_kbd_reset(DeviceState *dev) static void adb_kbd_realizefn(DeviceState *dev, Error **errp) { - ADBDevice *d = ADB_DEVICE(dev); ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev); - akc->parent_realize(dev, errp); - - qemu_add_kbd_event_handler(adb_kbd_put_keycode, d); } +static QemuInputHandler adb_keyboard_handler = { + .name = "QEMU ADB Keyboard", + .mask = INPUT_EVENT_MASK_KEY, + .event = adb_keyboard_event, +}; + static void adb_kbd_initfn(Object *obj) { ADBDevice *d = ADB_DEVICE(obj); - + qemu_input_handler_register((DeviceState *)d, &adb_keyboard_handler); d->devaddr = ADB_DEVID_KEYBOARD; }