From nobody Wed Dec 17 04:16:54 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 151923325104448.1029191360783; Wed, 21 Feb 2018 09:14:11 -0800 (PST) Received: from localhost ([::1]:33859 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoXy6-00059v-0h for importer@patchew.org; Wed, 21 Feb 2018 12:14:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39781) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoXsY-0000Th-Gt for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoXsW-0005dC-CY for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:26 -0500 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:40734 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eoXsW-0005cQ-6p for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:24 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DA9AEEAEAB; Wed, 21 Feb 2018 17:08:23 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-147.ams2.redhat.com [10.36.116.147]) by smtp.corp.redhat.com (Postfix) with ESMTP id 916FF10A971A; Wed, 21 Feb 2018 17:08:21 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id CB74917514; Wed, 21 Feb 2018 18:08:20 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Wed, 21 Feb 2018 18:08:16 +0100 Message-Id: <20180221170820.15365-2-kraxel@redhat.com> In-Reply-To: <20180221170820.15365-1-kraxel@redhat.com> References: <20180221170820.15365-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Wed, 21 Feb 2018 17:08:23 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Wed, 21 Feb 2018 17:08:23 +0000 (UTC) for IP:'10.11.54.3' DOMAIN:'int-mx03.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kraxel@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 1/5] kbd-state: add keyboard state tracker X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: programmingkidx@gmail.com, Gerd Hoffmann , peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Now that most user interfaces are using QKeyCodes it is easier to have common keyboard code useable by all user interfaces. This patch adds helper code to track the state of all keyboard keys, using a bitmap indexed by QKeyCode. Modifier state is tracked too, as separate bitmap. That makes checking modifier state easier. Likewise we can easily apply special handling for capslock & numlock (toggles on keypress) and ctrl + shift (we have two keys for that). Signed-off-by: Gerd Hoffmann --- include/ui/kbd-state.h | 22 +++++++++ ui/kbd-state.c | 119 +++++++++++++++++++++++++++++++++++++++++++++= ++++ ui/Makefile.objs | 2 +- 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 include/ui/kbd-state.h create mode 100644 ui/kbd-state.c diff --git a/include/ui/kbd-state.h b/include/ui/kbd-state.h new file mode 100644 index 0000000000..c961da45b2 --- /dev/null +++ b/include/ui/kbd-state.h @@ -0,0 +1,22 @@ +typedef enum KbdModifier KbdModifier; + +enum KbdModifier { + KBD_MOD_NONE =3D 0, + + KBD_MOD_SHIFT, + KBD_MOD_CTRL, + KBD_MOD_ALT, + + KBD_MOD_NUMLOCK, + KBD_MOD_CAPSLOCK, + + KBD_MOD__MAX +}; + +typedef struct KbdState KbdState; + +bool kbd_state_modifier_get(KbdState *kbd, KbdModifier mod); +bool kbd_state_key_get(KbdState *kbd, QKeyCode qcode); +void kbd_state_key_event(KbdState *kbd, QKeyCode qcode, bool down); +void kbd_state_lift_all_keys(KbdState *kbd); +KbdState *kbd_state_init(QemuConsole *con); diff --git a/ui/kbd-state.c b/ui/kbd-state.c new file mode 100644 index 0000000000..7a9fe268c2 --- /dev/null +++ b/ui/kbd-state.c @@ -0,0 +1,119 @@ +#include "qemu/osdep.h" +#include "qemu/bitmap.h" +#include "qemu/queue.h" +#include "qapi-types.h" +#include "ui/console.h" +#include "ui/input.h" +#include "ui/kbd-state.h" + +typedef struct KbdHotkey KbdHotkey; + +struct KbdHotkey { + uint32_t id; + QKeyCode qcode; + DECLARE_BITMAP(mods, KBD_MOD__MAX); + QTAILQ_ENTRY(KbdHotkey) next; +}; + +struct KbdState { + QemuConsole *con; + DECLARE_BITMAP(keys, Q_KEY_CODE__MAX); + DECLARE_BITMAP(mods, KBD_MOD__MAX); + QTAILQ_HEAD(,KbdHotkey) hotkeys; +}; + +static void kbd_state_modifier_update(KbdState *kbd, + QKeyCode qcode1, QKeyCode qcode2, + KbdModifier mod) +{ + if (test_bit(qcode1, kbd->keys) || test_bit(qcode2, kbd->keys)) { + set_bit(mod, kbd->mods); + } else { + clear_bit(mod, kbd->mods); + } +} + +bool kbd_state_modifier_get(KbdState *kbd, KbdModifier mod) +{ + return test_bit(mod, kbd->mods); +} + +bool kbd_state_key_get(KbdState *kbd, QKeyCode qcode) +{ + return test_bit(qcode, kbd->keys); +} + +void kbd_state_key_event(KbdState *kbd, QKeyCode qcode, bool down) +{ + bool state =3D test_bit(qcode, kbd->keys); + + if (state =3D=3D down) { + /* + * Filter out events which don't change the keyboard state. + * + * Most notably this allows to simply send along all key-up + * events, and this function will filter out everything where + * the corresponding key-down event wasn't send to the guest, + * for example due to being a host hotkey. + */ + return; + } + + /* update key and modifier state */ + change_bit(qcode, kbd->keys); + switch (qcode) { + case Q_KEY_CODE_SHIFT: + case Q_KEY_CODE_SHIFT_R: + kbd_state_modifier_update(kbd, Q_KEY_CODE_SHIFT, Q_KEY_CODE_SHIFT_= R, + KBD_MOD_SHIFT); + break; + case Q_KEY_CODE_CTRL: + case Q_KEY_CODE_CTRL_R: + kbd_state_modifier_update(kbd, Q_KEY_CODE_CTRL, Q_KEY_CODE_CTRL_R, + KBD_MOD_CTRL); + break; + case Q_KEY_CODE_ALT: + kbd_state_modifier_update(kbd, Q_KEY_CODE_ALT, Q_KEY_CODE_ALT, + KBD_MOD_ALT); + break; + case Q_KEY_CODE_CAPS_LOCK: + if (down) { + change_bit(KBD_MOD_CAPSLOCK, kbd->mods); + } + break; + case Q_KEY_CODE_NUM_LOCK: + if (down) { + change_bit(KBD_MOD_NUMLOCK, kbd->mods); + } + break; + default: + /* keep gcc happy */ + break; + } + + /* send to guest */ + if (qemu_console_is_graphic(kbd->con)) { + qemu_input_event_send_key_qcode(kbd->con, qcode, down); + } +} + +void kbd_state_lift_all_keys(KbdState *kbd) +{ + int qcode; + + for (qcode =3D 0; qcode < Q_KEY_CODE__MAX; qcode++) { + if (test_bit(qcode, kbd->keys)) { + kbd_state_key_event(kbd, qcode, false); + } + } +} + +KbdState *kbd_state_init(QemuConsole *con) +{ + KbdState *kbd =3D g_new0(KbdState, 1); + + kbd->con =3D con; + QTAILQ_INIT(&kbd->hotkeys); + + return kbd; +} diff --git a/ui/Makefile.objs b/ui/Makefile.objs index ced7d91a63..aa81ce4c47 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -8,7 +8,7 @@ vnc-obj-y +=3D vnc-ws.o vnc-obj-y +=3D vnc-jobs.o =20 common-obj-y +=3D keymaps.o console.o cursor.o qemu-pixman.o -common-obj-y +=3D input.o input-keymap.o input-legacy.o +common-obj-y +=3D input.o input-keymap.o input-legacy.o kbd-state.o common-obj-$(CONFIG_LINUX) +=3D input-linux.o common-obj-$(CONFIG_SPICE) +=3D spice-core.o spice-input.o spice-display.o common-obj-$(CONFIG_SDL) +=3D sdl.mo --=20 2.9.3 From nobody Wed Dec 17 04:16:54 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1519233183427995.0631147454966; Wed, 21 Feb 2018 09:13:03 -0800 (PST) Received: from localhost ([::1]:33854 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoXws-0004Ep-1Z for importer@patchew.org; Wed, 21 Feb 2018 12:12:54 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39773) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoXsY-0000TY-En for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoXsU-0005b5-BE for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:26 -0500 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:32920 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eoXsU-0005an-5v for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:22 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D83AD4022905; Wed, 21 Feb 2018 17:08:21 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-147.ams2.redhat.com [10.36.116.147]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8B8D52024CA8; Wed, 21 Feb 2018 17:08:21 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id D52FE17515; Wed, 21 Feb 2018 18:08:20 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Wed, 21 Feb 2018 18:08:17 +0100 Message-Id: <20180221170820.15365-3-kraxel@redhat.com> In-Reply-To: <20180221170820.15365-1-kraxel@redhat.com> References: <20180221170820.15365-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Wed, 21 Feb 2018 17:08:21 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Wed, 21 Feb 2018 17:08:21 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kraxel@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 2/5] kbd-state: add hotkey registry X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: programmingkidx@gmail.com, Gerd Hoffmann , peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add support to register hotkeys and to check whenever a given QKeyCode combined with the current modifier state is a hotkey. A hotkey can be any key combined with up to three modifier keys. Signed-off-by: Gerd Hoffmann --- include/ui/kbd-state.h | 27 +++++++++++++++++++++++++++ ui/kbd-state.c | 41 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/include/ui/kbd-state.h b/include/ui/kbd-state.h index c961da45b2..3f13649b63 100644 --- a/include/ui/kbd-state.h +++ b/include/ui/kbd-state.h @@ -20,3 +20,30 @@ bool kbd_state_key_get(KbdState *kbd, QKeyCode qcode); void kbd_state_key_event(KbdState *kbd, QKeyCode qcode, bool down); void kbd_state_lift_all_keys(KbdState *kbd); KbdState *kbd_state_init(QemuConsole *con); + +/* ------------------------------------------------------------------ */ + +typedef enum KbdHotkey KbdHotkey; + +enum KbdHotkey { + KBD_HOTKEY_NONE =3D 0, + + KBD_HOTKEY_GRAB, + KBD_HOTKEY_FULLSCREEN, + KBD_HOTKEY_REDRAW, + + KBD_HOTKEY_CONSOLE_1, + KBD_HOTKEY_CONSOLE_2, + KBD_HOTKEY_CONSOLE_3, + KBD_HOTKEY_CONSOLE_4, + KBD_HOTKEY_CONSOLE_5, + KBD_HOTKEY_CONSOLE_6, + KBD_HOTKEY_CONSOLE_7, + KBD_HOTKEY_CONSOLE_8, + KBD_HOTKEY_CONSOLE_9, +}; + +void kbd_state_hotkey_register(KbdState *kbd, KbdHotkey, QKeyCode qcode, + KbdModifier mod1, KbdModifier mod2, + KbdModifier mod3); +KbdHotkey kbd_state_hotkey_get(KbdState *kbd, QKeyCode qcode); diff --git a/ui/kbd-state.c b/ui/kbd-state.c index 7a9fe268c2..812cb368e3 100644 --- a/ui/kbd-state.c +++ b/ui/kbd-state.c @@ -6,20 +6,20 @@ #include "ui/input.h" #include "ui/kbd-state.h" =20 -typedef struct KbdHotkey KbdHotkey; +typedef struct KbdHotkeyEntry KbdHotkeyEntry; =20 -struct KbdHotkey { +struct KbdHotkeyEntry { uint32_t id; QKeyCode qcode; DECLARE_BITMAP(mods, KBD_MOD__MAX); - QTAILQ_ENTRY(KbdHotkey) next; + QTAILQ_ENTRY(KbdHotkeyEntry) next; }; =20 struct KbdState { QemuConsole *con; DECLARE_BITMAP(keys, Q_KEY_CODE__MAX); DECLARE_BITMAP(mods, KBD_MOD__MAX); - QTAILQ_HEAD(,KbdHotkey) hotkeys; + QTAILQ_HEAD(, KbdHotkeyEntry) hotkeys; }; =20 static void kbd_state_modifier_update(KbdState *kbd, @@ -117,3 +117,36 @@ KbdState *kbd_state_init(QemuConsole *con) =20 return kbd; } + +void kbd_state_hotkey_register(KbdState *kbd, KbdHotkey id, QKeyCode qcode, + KbdModifier mod1, KbdModifier mod2, + KbdModifier mod3) +{ + KbdHotkeyEntry *hotkey =3D g_new0(KbdHotkeyEntry, 1); + + hotkey->id =3D id; + hotkey->qcode =3D qcode; + if (mod1 !=3D KBD_MOD_NONE) { + set_bit(mod1, hotkey->mods); + } + if (mod2 !=3D KBD_MOD_NONE) { + set_bit(mod2, hotkey->mods); + } + if (mod3 !=3D KBD_MOD_NONE) { + set_bit(mod3, hotkey->mods); + } + QTAILQ_INSERT_TAIL(&kbd->hotkeys, hotkey, next); +} + +KbdHotkey kbd_state_hotkey_get(KbdState *kbd, QKeyCode qcode) +{ + KbdHotkeyEntry *hotkey; + + QTAILQ_FOREACH(hotkey, &kbd->hotkeys, next) { + if (qcode =3D=3D hotkey->qcode && + bitmap_equal(kbd->mods, hotkey->mods, KBD_MOD__MAX)) { + return hotkey->id; + } + } + return KBD_HOTKEY_NONE; +} --=20 2.9.3 From nobody Wed Dec 17 04:16:54 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1519233028581657.7209878335472; Wed, 21 Feb 2018 09:10:28 -0800 (PST) Received: from localhost ([::1]:33831 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoXuQ-0001l8-K8 for importer@patchew.org; Wed, 21 Feb 2018 12:10:22 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39780) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoXsY-0000Tg-GH for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoXsV-0005bz-FF for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:26 -0500 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:36574 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eoXsV-0005be-90 for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:23 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E8E028185324; Wed, 21 Feb 2018 17:08:22 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-147.ams2.redhat.com [10.36.116.147]) by smtp.corp.redhat.com (Postfix) with ESMTP id 928132026E0E; Wed, 21 Feb 2018 17:08:21 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id DFE831751D; Wed, 21 Feb 2018 18:08:20 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Wed, 21 Feb 2018 18:08:18 +0100 Message-Id: <20180221170820.15365-4-kraxel@redhat.com> In-Reply-To: <20180221170820.15365-1-kraxel@redhat.com> References: <20180221170820.15365-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Wed, 21 Feb 2018 17:08:22 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Wed, 21 Feb 2018 17:08:22 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kraxel@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 3/5] kbd-state: use state tracker for sdl2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: programmingkidx@gmail.com, Gerd Hoffmann , peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Use the new keyboard state tracked for sdl2. We can drop the modifier state tracking from sdl2. Also keyup code is simpler, the state tracker will take care to not send suspious keyup events to the guest. Signed-off-by: Gerd Hoffmann --- include/ui/sdl2.h | 2 ++ ui/sdl2-input.c | 43 ++----------------------------------------- ui/sdl2.c | 18 +++--------------- 3 files changed, 7 insertions(+), 56 deletions(-) diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h index 51084e6320..c316e42706 100644 --- a/include/ui/sdl2.h +++ b/include/ui/sdl2.h @@ -7,6 +7,7 @@ #include #include =20 +#include "ui/kbd-state.h" #ifdef CONFIG_OPENGL # include "ui/egl-helpers.h" #endif @@ -26,6 +27,7 @@ struct sdl2_console { int idle_counter; int ignore_hotkeys; SDL_GLContext winctx; + KbdState *kbd; #ifdef CONFIG_OPENGL QemuGLShader *gls; egl_fb guest_fb; diff --git a/ui/sdl2-input.c b/ui/sdl2-input.c index 605d781971..d970655616 100644 --- a/ui/sdl2-input.c +++ b/ui/sdl2-input.c @@ -30,22 +30,9 @@ #include "ui/sdl2.h" #include "sysemu/sysemu.h" =20 -static uint8_t modifiers_state[SDL_NUM_SCANCODES]; - void sdl2_reset_keys(struct sdl2_console *scon) { - QemuConsole *con =3D scon ? scon->dcl.con : NULL; - int i; - - for (i =3D 0 ; - i < SDL_NUM_SCANCODES && i < qemu_input_map_usb_to_qcode_len ; - i++) { - if (modifiers_state[i]) { - int qcode =3D qemu_input_map_usb_to_qcode[i]; - qemu_input_event_send_key_qcode(con, qcode, false); - modifiers_state[i] =3D 0; - } - } + kbd_state_lift_all_keys(scon->kbd); } =20 void sdl2_process_key(struct sdl2_console *scon, @@ -77,31 +64,5 @@ void sdl2_process_key(struct sdl2_console *scon, return; } =20 - switch (ev->keysym.scancode) { -#if 0 - case SDL_SCANCODE_NUMLOCKCLEAR: - case SDL_SCANCODE_CAPSLOCK: - /* SDL does not send the key up event, so we generate it */ - qemu_input_event_send_key_qcode(con, qcode, true); - qemu_input_event_send_key_qcode(con, qcode, false); - return; -#endif - case SDL_SCANCODE_LCTRL: - case SDL_SCANCODE_LSHIFT: - case SDL_SCANCODE_LALT: - case SDL_SCANCODE_LGUI: - case SDL_SCANCODE_RCTRL: - case SDL_SCANCODE_RSHIFT: - case SDL_SCANCODE_RALT: - case SDL_SCANCODE_RGUI: - if (ev->type =3D=3D SDL_KEYUP) { - modifiers_state[ev->keysym.scancode] =3D 0; - } else { - modifiers_state[ev->keysym.scancode] =3D 1; - } - /* fall though */ - default: - qemu_input_event_send_key_qcode(con, qcode, - ev->type =3D=3D SDL_KEYDOWN); - } + kbd_state_key_event(scon->kbd, qcode, ev->type =3D=3D SDL_KEYDOWN); } diff --git a/ui/sdl2.c b/ui/sdl2.c index 6e96a4a24c..50f5fca0f6 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -40,7 +40,6 @@ static int gui_grab; /* if true, all keyboard/mouse event= s are grabbed */ static int gui_saved_grab; static int gui_fullscreen; static int gui_key_modifier_pressed; -static int gui_keysym; static int gui_grab_code =3D KMOD_LALT | KMOD_LCTRL; static SDL_Cursor *sdl_cursor_normal; static SDL_Cursor *sdl_cursor_hidden; @@ -331,6 +330,7 @@ static void handle_keydown(SDL_Event *ev) { int win; struct sdl2_console *scon =3D get_scon_from_window(ev->key.windowID); + int gui_keysym =3D 0; =20 gui_key_modifier_pressed =3D get_mod_state(); =20 @@ -413,23 +413,10 @@ static void handle_keydown(SDL_Event *ev) =20 static void handle_keyup(SDL_Event *ev) { - int mod_state; struct sdl2_console *scon =3D get_scon_from_window(ev->key.windowID); =20 scon->ignore_hotkeys =3D false; - - if (!alt_grab) { - mod_state =3D (ev->key.keysym.mod & gui_grab_code); - } else { - mod_state =3D (ev->key.keysym.mod & (gui_grab_code | KMOD_LSHIFT)); - } - if (!mod_state && gui_key_modifier_pressed) { - gui_key_modifier_pressed =3D 0; - gui_keysym =3D 0; - } - if (!gui_keysym) { - sdl2_process_key(scon, &ev->key); - } + sdl2_process_key(scon, &ev->key); } =20 static void handle_textinput(SDL_Event *ev) @@ -829,6 +816,7 @@ void sdl_display_init(DisplayState *ds, DisplayOptions = *o) sdl2_console[i].dcl.ops =3D &dcl_2d_ops; #endif sdl2_console[i].dcl.con =3D con; + sdl2_console[i].kbd =3D kbd_state_init(con); register_displaychangelistener(&sdl2_console[i].dcl); =20 #if defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_X11) --=20 2.9.3 From nobody Wed Dec 17 04:16:54 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1519233029517938.7064998724122; Wed, 21 Feb 2018 09:10:29 -0800 (PST) Received: from localhost ([::1]:33832 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoXuR-0001lv-Jg for importer@patchew.org; Wed, 21 Feb 2018 12:10:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39779) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoXsY-0000Tf-GD for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoXsW-0005dX-IE for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:26 -0500 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:32926 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eoXsW-0005cZ-Bh for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:24 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 04B174022905; Wed, 21 Feb 2018 17:08:24 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-147.ams2.redhat.com [10.36.116.147]) by smtp.corp.redhat.com (Postfix) with ESMTP id 951D3B07B9; Wed, 21 Feb 2018 17:08:21 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id E97801751E; Wed, 21 Feb 2018 18:08:20 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Wed, 21 Feb 2018 18:08:19 +0100 Message-Id: <20180221170820.15365-5-kraxel@redhat.com> In-Reply-To: <20180221170820.15365-1-kraxel@redhat.com> References: <20180221170820.15365-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Wed, 21 Feb 2018 17:08:24 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Wed, 21 Feb 2018 17:08:24 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kraxel@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 4/5] kbd-state: register sdl2 hotkeys X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: programmingkidx@gmail.com, Gerd Hoffmann , peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Register SDL2 hotkeys in keyboard state tracker, use it to check for hotkeys. Drop even more modifier code. This also changes behavior a bit. The Ctrl-Alt- hotkey combinations accept both ctrl keys now. Likewise the Ctrl-Alt-Shift- mode you can enable with -alt-grab accepts both ctrl and shift keys. The -ctrl-grab mode (use right ctrl key) is not supported. Signed-off-by: Gerd Hoffmann --- ui/sdl2-input.c | 1 - ui/sdl2.c | 98 ++++++++++++++++++++++++++++++++++-------------------= ---- 2 files changed, 59 insertions(+), 40 deletions(-) diff --git a/ui/sdl2-input.c b/ui/sdl2-input.c index d970655616..82ec375ea2 100644 --- a/ui/sdl2-input.c +++ b/ui/sdl2-input.c @@ -61,7 +61,6 @@ void sdl2_process_key(struct sdl2_console *scon, break; } } - return; } =20 kbd_state_key_event(scon->kbd, qcode, ev->type =3D=3D SDL_KEYDOWN); diff --git a/ui/sdl2.c b/ui/sdl2.c index 50f5fca0f6..0f48f5a546 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -39,8 +39,6 @@ static int gui_grab; /* if true, all keyboard/mouse event= s are grabbed */ =20 static int gui_saved_grab; static int gui_fullscreen; -static int gui_key_modifier_pressed; -static int gui_grab_code =3D KMOD_LALT | KMOD_LCTRL; static SDL_Cursor *sdl_cursor_normal; static SDL_Cursor *sdl_cursor_hidden; static int absolute_enabled; @@ -312,43 +310,35 @@ static void toggle_full_screen(struct sdl2_console *s= con) sdl2_redraw(scon); } =20 -static int get_mod_state(void) -{ - SDL_Keymod mod =3D SDL_GetModState(); - - if (alt_grab) { - return (mod & (gui_grab_code | KMOD_LSHIFT)) =3D=3D - (gui_grab_code | KMOD_LSHIFT); - } else if (ctrl_grab) { - return (mod & KMOD_RCTRL) =3D=3D KMOD_RCTRL; - } else { - return (mod & gui_grab_code) =3D=3D gui_grab_code; - } -} - static void handle_keydown(SDL_Event *ev) { int win; struct sdl2_console *scon =3D get_scon_from_window(ev->key.windowID); - int gui_keysym =3D 0; + KbdHotkey hotkey; + QKeyCode qcode; =20 - gui_key_modifier_pressed =3D get_mod_state(); + if (ev->key.keysym.scancode >=3D qemu_input_map_usb_to_qcode_len) { + return; + } + qcode =3D qemu_input_map_usb_to_qcode[ev->key.keysym.scancode]; =20 - if (!scon->ignore_hotkeys && gui_key_modifier_pressed && !ev->key.repe= at) { - switch (ev->key.keysym.scancode) { - case SDL_SCANCODE_2: - case SDL_SCANCODE_3: - case SDL_SCANCODE_4: - case SDL_SCANCODE_5: - case SDL_SCANCODE_6: - case SDL_SCANCODE_7: - case SDL_SCANCODE_8: - case SDL_SCANCODE_9: + if (!scon->ignore_hotkeys && !ev->key.repeat) { + hotkey =3D kbd_state_hotkey_get(scon->kbd, qcode); + switch (hotkey) { + case KBD_HOTKEY_CONSOLE_2: + case KBD_HOTKEY_CONSOLE_3: + case KBD_HOTKEY_CONSOLE_4: + case KBD_HOTKEY_CONSOLE_5: + case KBD_HOTKEY_CONSOLE_6: + case KBD_HOTKEY_CONSOLE_7: + case KBD_HOTKEY_CONSOLE_8: + case KBD_HOTKEY_CONSOLE_9: if (gui_grab) { sdl_grab_end(scon); } + sdl2_reset_keys(scon); =20 - win =3D ev->key.keysym.scancode - SDL_SCANCODE_1; + win =3D hotkey - KBD_HOTKEY_CONSOLE_1; if (win < sdl2_num_outputs) { sdl2_console[win].hidden =3D !sdl2_console[win].hidden; if (sdl2_console[win].real_window) { @@ -358,29 +348,25 @@ static void handle_keydown(SDL_Event *ev) SDL_ShowWindow(sdl2_console[win].real_window); } } - gui_keysym =3D 1; } break; - case SDL_SCANCODE_F: + case KBD_HOTKEY_FULLSCREEN: toggle_full_screen(scon); - gui_keysym =3D 1; break; - case SDL_SCANCODE_G: - gui_keysym =3D 1; + case KBD_HOTKEY_GRAB: if (!gui_grab) { sdl_grab_start(scon); } else if (!gui_fullscreen) { sdl_grab_end(scon); } break; - case SDL_SCANCODE_U: + case KBD_HOTKEY_REDRAW: sdl2_window_destroy(scon); sdl2_window_create(scon); if (!scon->opengl) { /* re-create scon->texture */ sdl2_2d_switch(&scon->dcl, scon->surface); } - gui_keysym =3D 1; break; #if 0 case SDL_SCANCODE_KP_PLUS: @@ -402,11 +388,14 @@ static void handle_keydown(SDL_Event *ev) gui_keysym =3D 1; } #endif + case KBD_HOTKEY_NONE: + sdl2_process_key(scon, &ev->key); + break; default: + /* keep gcc happy */ break; } - } - if (!gui_keysym) { + } else { sdl2_process_key(scon, &ev->key); } } @@ -546,7 +535,7 @@ static void handle_windowevent(SDL_Event *ev) * Work around this by ignoring further hotkey events until a * key is released. */ - scon->ignore_hotkeys =3D get_mod_state(); + scon->ignore_hotkeys =3D SDL_GetModState(); break; case SDL_WINDOWEVENT_FOCUS_LOST: if (gui_grab && !gui_fullscreen) { @@ -756,6 +745,36 @@ void sdl_display_early_init(DisplayOptions *o) } } =20 +static void sdl2_hotkey_init(KbdState *kbd) +{ + /* + * Register traditional SDL hotkeys for now. + * + * Making this configurable is left as an + * excercise for another day ... + */ + KbdModifier m1 =3D KBD_MOD_CTRL; + KbdModifier m2 =3D KBD_MOD_ALT; + KbdModifier m3 =3D KBD_MOD_NONE; + int i; + + if (alt_grab) { + m3 =3D KBD_MOD_SHIFT; + } + + kbd_state_hotkey_register(kbd, KBD_HOTKEY_FULLSCREEN, + Q_KEY_CODE_F, m1, m2, m3); + kbd_state_hotkey_register(kbd, KBD_HOTKEY_GRAB, + Q_KEY_CODE_G, m1, m2, m3); + kbd_state_hotkey_register(kbd, KBD_HOTKEY_REDRAW, + Q_KEY_CODE_U, m1, m2, m3); + for (i =3D 0; i <=3D 7; i++) { + /* keys 2 ... 9 */ + kbd_state_hotkey_register(kbd, KBD_HOTKEY_CONSOLE_2 + i, + Q_KEY_CODE_2 + i, m1, m2, m3); + } +} + void sdl_display_init(DisplayState *ds, DisplayOptions *o) { int flags; @@ -817,6 +836,7 @@ void sdl_display_init(DisplayState *ds, DisplayOptions = *o) #endif sdl2_console[i].dcl.con =3D con; sdl2_console[i].kbd =3D kbd_state_init(con); + sdl2_hotkey_init(sdl2_console[i].kbd); register_displaychangelistener(&sdl2_console[i].dcl); =20 #if defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_X11) --=20 2.9.3 From nobody Wed Dec 17 04:16:54 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1519233074582373.52522037519543; Wed, 21 Feb 2018 09:11:14 -0800 (PST) Received: from localhost ([::1]:33839 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoXvD-0002b9-P7 for importer@patchew.org; Wed, 21 Feb 2018 12:11:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39776) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eoXsY-0000Tb-Fv for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eoXsW-0005dI-Cl for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:26 -0500 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:35284 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eoXsW-0005cS-7v for qemu-devel@nongnu.org; Wed, 21 Feb 2018 12:08:24 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E531340744C6; Wed, 21 Feb 2018 17:08:23 +0000 (UTC) Received: from sirius.home.kraxel.org (ovpn-116-147.ams2.redhat.com [10.36.116.147]) by smtp.corp.redhat.com (Postfix) with ESMTP id A7EB6213AEE4; Wed, 21 Feb 2018 17:08:23 +0000 (UTC) Received: by sirius.home.kraxel.org (Postfix, from userid 1000) id F1AE717528; Wed, 21 Feb 2018 18:08:20 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Wed, 21 Feb 2018 18:08:20 +0100 Message-Id: <20180221170820.15365-6-kraxel@redhat.com> In-Reply-To: <20180221170820.15365-1-kraxel@redhat.com> References: <20180221170820.15365-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Wed, 21 Feb 2018 17:08:23 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Wed, 21 Feb 2018 17:08:23 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'kraxel@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 5/5] sdl2: use only QKeyCode in sdl2_process_key() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: programmingkidx@gmail.com, Gerd Hoffmann , peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Small cleanup. Also drop the special backspace handling, kbd_put_qcode_console() learned to handle that meanwhile. And sdl2_process_key is never called with scon =3D=3D NULL. Signed-off-by: Gerd Hoffmann --- ui/sdl2-input.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/ui/sdl2-input.c b/ui/sdl2-input.c index 82ec375ea2..f0847dd745 100644 --- a/ui/sdl2-input.c +++ b/ui/sdl2-input.c @@ -39,23 +39,19 @@ void sdl2_process_key(struct sdl2_console *scon, SDL_KeyboardEvent *ev) { int qcode; - QemuConsole *con =3D scon ? scon->dcl.con : NULL; + QemuConsole *con =3D scon->dcl.con; =20 if (ev->keysym.scancode >=3D qemu_input_map_usb_to_qcode_len) { return; } - qcode =3D qemu_input_map_usb_to_qcode[ev->keysym.scancode]; =20 if (!qemu_console_is_graphic(con)) { if (ev->type =3D=3D SDL_KEYDOWN) { - switch (ev->keysym.scancode) { - case SDL_SCANCODE_RETURN: + switch (qcode) { + case Q_KEY_CODE_RET: kbd_put_keysym_console(con, '\n'); break; - case SDL_SCANCODE_BACKSPACE: - kbd_put_keysym_console(con, QEMU_KEY_BACKSPACE); - break; default: kbd_put_qcode_console(con, qcode); break; --=20 2.9.3