* [Qemu-devel] [RFC PATCH 1/5] kbd-state: add keyboard state tracker
2018-02-21 17:08 [Qemu-devel] [RFC PATCH 0/5] ui: add keyboard state and hotkey tracker Gerd Hoffmann
@ 2018-02-21 17:08 ` Gerd Hoffmann
2018-02-21 17:08 ` [Qemu-devel] [RFC PATCH 2/5] kbd-state: add hotkey registry Gerd Hoffmann
` (4 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Gerd Hoffmann @ 2018-02-21 17:08 UTC (permalink / raw)
To: qemu-devel; +Cc: programmingkidx, berrange, peter.maydell, Gerd Hoffmann
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 <kraxel@redhat.com>
---
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 = 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 = test_bit(qcode, kbd->keys);
+
+ if (state == 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 = 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 = g_new0(KbdState, 1);
+
+ kbd->con = 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 += vnc-ws.o
vnc-obj-y += vnc-jobs.o
common-obj-y += keymaps.o console.o cursor.o qemu-pixman.o
-common-obj-y += input.o input-keymap.o input-legacy.o
+common-obj-y += input.o input-keymap.o input-legacy.o kbd-state.o
common-obj-$(CONFIG_LINUX) += input-linux.o
common-obj-$(CONFIG_SPICE) += spice-core.o spice-input.o spice-display.o
common-obj-$(CONFIG_SDL) += sdl.mo
--
2.9.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [RFC PATCH 2/5] kbd-state: add hotkey registry
2018-02-21 17:08 [Qemu-devel] [RFC PATCH 0/5] ui: add keyboard state and hotkey tracker Gerd Hoffmann
2018-02-21 17:08 ` [Qemu-devel] [RFC PATCH 1/5] kbd-state: add keyboard state tracker Gerd Hoffmann
@ 2018-02-21 17:08 ` Gerd Hoffmann
2018-06-01 19:05 ` Programmingkid
2018-02-21 17:08 ` [Qemu-devel] [RFC PATCH 3/5] kbd-state: use state tracker for sdl2 Gerd Hoffmann
` (3 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Gerd Hoffmann @ 2018-02-21 17:08 UTC (permalink / raw)
To: qemu-devel; +Cc: programmingkidx, berrange, peter.maydell, Gerd Hoffmann
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 <kraxel@redhat.com>
---
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 = 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"
-typedef struct KbdHotkey KbdHotkey;
+typedef struct KbdHotkeyEntry KbdHotkeyEntry;
-struct KbdHotkey {
+struct KbdHotkeyEntry {
uint32_t id;
QKeyCode qcode;
DECLARE_BITMAP(mods, KBD_MOD__MAX);
- QTAILQ_ENTRY(KbdHotkey) next;
+ QTAILQ_ENTRY(KbdHotkeyEntry) next;
};
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;
};
static void kbd_state_modifier_update(KbdState *kbd,
@@ -117,3 +117,36 @@ KbdState *kbd_state_init(QemuConsole *con)
return kbd;
}
+
+void kbd_state_hotkey_register(KbdState *kbd, KbdHotkey id, QKeyCode qcode,
+ KbdModifier mod1, KbdModifier mod2,
+ KbdModifier mod3)
+{
+ KbdHotkeyEntry *hotkey = g_new0(KbdHotkeyEntry, 1);
+
+ hotkey->id = id;
+ hotkey->qcode = qcode;
+ if (mod1 != KBD_MOD_NONE) {
+ set_bit(mod1, hotkey->mods);
+ }
+ if (mod2 != KBD_MOD_NONE) {
+ set_bit(mod2, hotkey->mods);
+ }
+ if (mod3 != 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 == hotkey->qcode &&
+ bitmap_equal(kbd->mods, hotkey->mods, KBD_MOD__MAX)) {
+ return hotkey->id;
+ }
+ }
+ return KBD_HOTKEY_NONE;
+}
--
2.9.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [RFC PATCH 2/5] kbd-state: add hotkey registry
2018-02-21 17:08 ` [Qemu-devel] [RFC PATCH 2/5] kbd-state: add hotkey registry Gerd Hoffmann
@ 2018-06-01 19:05 ` Programmingkid
2018-06-05 10:20 ` Gerd Hoffmann
0 siblings, 1 reply; 10+ messages in thread
From: Programmingkid @ 2018-06-01 19:05 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel, berrange, peter.maydell
> On Feb 21, 2018, at 12:08 PM, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
> 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.
I have finally reviewed the patches you sent to me. Sorry it took so long. The patches you sent look good.
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
> 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 = 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"
>
> -typedef struct KbdHotkey KbdHotkey;
> +typedef struct KbdHotkeyEntry KbdHotkeyEntry;
>
> -struct KbdHotkey {
> +struct KbdHotkeyEntry {
> uint32_t id;
> QKeyCode qcode;
> DECLARE_BITMAP(mods, KBD_MOD__MAX);
> - QTAILQ_ENTRY(KbdHotkey) next;
> + QTAILQ_ENTRY(KbdHotkeyEntry) next;
> };
>
> 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;
> };
>
> static void kbd_state_modifier_update(KbdState *kbd,
> @@ -117,3 +117,36 @@ KbdState *kbd_state_init(QemuConsole *con)
>
> return kbd;
> }
> +
> +void kbd_state_hotkey_register(KbdState *kbd, KbdHotkey id, QKeyCode qcode,
> + KbdModifier mod1, KbdModifier mod2,
> + KbdModifier mod3)
> +{
> + KbdHotkeyEntry *hotkey = g_new0(KbdHotkeyEntry, 1);
> +
> + hotkey->id = id;
> + hotkey->qcode = qcode;
> + if (mod1 != KBD_MOD_NONE) {
> + set_bit(mod1, hotkey->mods);
> + }
> + if (mod2 != KBD_MOD_NONE) {
> + set_bit(mod2, hotkey->mods);
> + }
> + if (mod3 != KBD_MOD_NONE) {
> + set_bit(mod3, hotkey->mods);
> + }
> + QTAILQ_INSERT_TAIL(&kbd->hotkeys, hotkey, next);
> +}
You say the hotkey is a QKeyCode and a modifier key combined. But it looks like a single QKeyCode would be supported. I would prefer being able to use a single key like F16 to ungrab the mouse. Would that be possible here?
Kbd_state_hotkey_register(kbd, KBD_HOTKEY_GRAB, Q_KEY_CODE_F16, KBD_MOD_NONE, KBD_MOD_NONE, KBD_MOD_NONE);
> +
> +KbdHotkey kbd_state_hotkey_get(KbdState *kbd, QKeyCode qcode)
> +{
> + KbdHotkeyEntry *hotkey;
> +
> + QTAILQ_FOREACH(hotkey, &kbd->hotkeys, next) {
> + if (qcode == hotkey->qcode &&
> + bitmap_equal(kbd->mods, hotkey->mods, KBD_MOD__MAX)) {
> + return hotkey->id;
> + }
> + }
> + return KBD_HOTKEY_NONE;
> +}
> --
> 2.9.3
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [RFC PATCH 2/5] kbd-state: add hotkey registry
2018-06-01 19:05 ` Programmingkid
@ 2018-06-05 10:20 ` Gerd Hoffmann
2018-06-05 14:37 ` Programmingkid
0 siblings, 1 reply; 10+ messages in thread
From: Gerd Hoffmann @ 2018-06-05 10:20 UTC (permalink / raw)
To: Programmingkid; +Cc: qemu-devel, berrange, peter.maydell
Hi,
> You say the hotkey is a QKeyCode and a modifier key combined. But it looks like a single QKeyCode would be supported. I would prefer being able to use a single key like F16 to ungrab the mouse. Would that be possible here?
>
> Kbd_state_hotkey_register(kbd, KBD_HOTKEY_GRAB, Q_KEY_CODE_F16, KBD_MOD_NONE, KBD_MOD_NONE, KBD_MOD_NONE);
Yes, that should work. I'm working on the series now and then (when I
find some time), latest state is here:
https://git.kraxel.org/cgit/qemu/log/?h=sirius/kbd-state
cheers,
Gerd
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [RFC PATCH 2/5] kbd-state: add hotkey registry
2018-06-05 10:20 ` Gerd Hoffmann
@ 2018-06-05 14:37 ` Programmingkid
0 siblings, 0 replies; 10+ messages in thread
From: Programmingkid @ 2018-06-05 14:37 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: qemu-devel, berrange, peter.maydell
> On Jun 5, 2018, at 6:20 AM, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
> Hi,
>
>> You say the hotkey is a QKeyCode and a modifier key combined. But it looks like a single QKeyCode would be supported. I would prefer being able to use a single key like F16 to ungrab the mouse. Would that be possible here?
>>
>> Kbd_state_hotkey_register(kbd, KBD_HOTKEY_GRAB, Q_KEY_CODE_F16, KBD_MOD_NONE, KBD_MOD_NONE, KBD_MOD_NONE);
>
> Yes, that should work. I'm working on the series now and then (when I
> find some time), latest state is here:
>
> https://git.kraxel.org/cgit/qemu/log/?h=sirius/kbd-state
>
> cheers,
> Gerd
Great. I look forward to seeing the completed series. I think we should add the code for specifying the command-line option for setting custom keys to this series if possible.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Qemu-devel] [RFC PATCH 3/5] kbd-state: use state tracker for sdl2
2018-02-21 17:08 [Qemu-devel] [RFC PATCH 0/5] ui: add keyboard state and hotkey tracker Gerd Hoffmann
2018-02-21 17:08 ` [Qemu-devel] [RFC PATCH 1/5] kbd-state: add keyboard state tracker Gerd Hoffmann
2018-02-21 17:08 ` [Qemu-devel] [RFC PATCH 2/5] kbd-state: add hotkey registry Gerd Hoffmann
@ 2018-02-21 17:08 ` Gerd Hoffmann
2018-02-21 17:08 ` [Qemu-devel] [RFC PATCH 4/5] kbd-state: register sdl2 hotkeys Gerd Hoffmann
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Gerd Hoffmann @ 2018-02-21 17:08 UTC (permalink / raw)
To: qemu-devel; +Cc: programmingkidx, berrange, peter.maydell, Gerd Hoffmann
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 <kraxel@redhat.com>
---
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 <SDL.h>
#include <SDL_syswm.h>
+#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"
-static uint8_t modifiers_state[SDL_NUM_SCANCODES];
-
void sdl2_reset_keys(struct sdl2_console *scon)
{
- QemuConsole *con = scon ? scon->dcl.con : NULL;
- int i;
-
- for (i = 0 ;
- i < SDL_NUM_SCANCODES && i < qemu_input_map_usb_to_qcode_len ;
- i++) {
- if (modifiers_state[i]) {
- int qcode = qemu_input_map_usb_to_qcode[i];
- qemu_input_event_send_key_qcode(con, qcode, false);
- modifiers_state[i] = 0;
- }
- }
+ kbd_state_lift_all_keys(scon->kbd);
}
void sdl2_process_key(struct sdl2_console *scon,
@@ -77,31 +64,5 @@ void sdl2_process_key(struct sdl2_console *scon,
return;
}
- 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 == SDL_KEYUP) {
- modifiers_state[ev->keysym.scancode] = 0;
- } else {
- modifiers_state[ev->keysym.scancode] = 1;
- }
- /* fall though */
- default:
- qemu_input_event_send_key_qcode(con, qcode,
- ev->type == SDL_KEYDOWN);
- }
+ kbd_state_key_event(scon->kbd, qcode, ev->type == 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 events 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 = 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 = get_scon_from_window(ev->key.windowID);
+ int gui_keysym = 0;
gui_key_modifier_pressed = get_mod_state();
@@ -413,23 +413,10 @@ static void handle_keydown(SDL_Event *ev)
static void handle_keyup(SDL_Event *ev)
{
- int mod_state;
struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
scon->ignore_hotkeys = false;
-
- if (!alt_grab) {
- mod_state = (ev->key.keysym.mod & gui_grab_code);
- } else {
- mod_state = (ev->key.keysym.mod & (gui_grab_code | KMOD_LSHIFT));
- }
- if (!mod_state && gui_key_modifier_pressed) {
- gui_key_modifier_pressed = 0;
- gui_keysym = 0;
- }
- if (!gui_keysym) {
- sdl2_process_key(scon, &ev->key);
- }
+ sdl2_process_key(scon, &ev->key);
}
static void handle_textinput(SDL_Event *ev)
@@ -829,6 +816,7 @@ void sdl_display_init(DisplayState *ds, DisplayOptions *o)
sdl2_console[i].dcl.ops = &dcl_2d_ops;
#endif
sdl2_console[i].dcl.con = con;
+ sdl2_console[i].kbd = kbd_state_init(con);
register_displaychangelistener(&sdl2_console[i].dcl);
#if defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_X11)
--
2.9.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [RFC PATCH 4/5] kbd-state: register sdl2 hotkeys
2018-02-21 17:08 [Qemu-devel] [RFC PATCH 0/5] ui: add keyboard state and hotkey tracker Gerd Hoffmann
` (2 preceding siblings ...)
2018-02-21 17:08 ` [Qemu-devel] [RFC PATCH 3/5] kbd-state: use state tracker for sdl2 Gerd Hoffmann
@ 2018-02-21 17:08 ` Gerd Hoffmann
2018-02-21 17:08 ` [Qemu-devel] [RFC PATCH 5/5] sdl2: use only QKeyCode in sdl2_process_key() Gerd Hoffmann
2018-02-22 14:14 ` [Qemu-devel] [RFC PATCH 0/5] ui: add keyboard state and hotkey tracker no-reply
5 siblings, 0 replies; 10+ messages in thread
From: Gerd Hoffmann @ 2018-02-21 17:08 UTC (permalink / raw)
To: qemu-devel; +Cc: programmingkidx, berrange, peter.maydell, Gerd Hoffmann
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-<key> hotkey
combinations accept both ctrl keys now. Likewise the
Ctrl-Alt-Shift-<key> 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 <kraxel@redhat.com>
---
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;
}
kbd_state_key_event(scon->kbd, qcode, ev->type == 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 events are grabbed */
static int gui_saved_grab;
static int gui_fullscreen;
-static int gui_key_modifier_pressed;
-static int gui_grab_code = 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 *scon)
sdl2_redraw(scon);
}
-static int get_mod_state(void)
-{
- SDL_Keymod mod = SDL_GetModState();
-
- if (alt_grab) {
- return (mod & (gui_grab_code | KMOD_LSHIFT)) ==
- (gui_grab_code | KMOD_LSHIFT);
- } else if (ctrl_grab) {
- return (mod & KMOD_RCTRL) == KMOD_RCTRL;
- } else {
- return (mod & gui_grab_code) == gui_grab_code;
- }
-}
-
static void handle_keydown(SDL_Event *ev)
{
int win;
struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
- int gui_keysym = 0;
+ KbdHotkey hotkey;
+ QKeyCode qcode;
- gui_key_modifier_pressed = get_mod_state();
+ if (ev->key.keysym.scancode >= qemu_input_map_usb_to_qcode_len) {
+ return;
+ }
+ qcode = qemu_input_map_usb_to_qcode[ev->key.keysym.scancode];
- if (!scon->ignore_hotkeys && gui_key_modifier_pressed && !ev->key.repeat) {
- 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 = 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);
- win = ev->key.keysym.scancode - SDL_SCANCODE_1;
+ win = hotkey - KBD_HOTKEY_CONSOLE_1;
if (win < sdl2_num_outputs) {
sdl2_console[win].hidden = !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 = 1;
}
break;
- case SDL_SCANCODE_F:
+ case KBD_HOTKEY_FULLSCREEN:
toggle_full_screen(scon);
- gui_keysym = 1;
break;
- case SDL_SCANCODE_G:
- gui_keysym = 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 = 1;
break;
#if 0
case SDL_SCANCODE_KP_PLUS:
@@ -402,11 +388,14 @@ static void handle_keydown(SDL_Event *ev)
gui_keysym = 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 = get_mod_state();
+ scon->ignore_hotkeys = SDL_GetModState();
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
if (gui_grab && !gui_fullscreen) {
@@ -756,6 +745,36 @@ void sdl_display_early_init(DisplayOptions *o)
}
}
+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 = KBD_MOD_CTRL;
+ KbdModifier m2 = KBD_MOD_ALT;
+ KbdModifier m3 = KBD_MOD_NONE;
+ int i;
+
+ if (alt_grab) {
+ m3 = 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 = 0; i <= 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 = con;
sdl2_console[i].kbd = kbd_state_init(con);
+ sdl2_hotkey_init(sdl2_console[i].kbd);
register_displaychangelistener(&sdl2_console[i].dcl);
#if defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_X11)
--
2.9.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [Qemu-devel] [RFC PATCH 5/5] sdl2: use only QKeyCode in sdl2_process_key()
2018-02-21 17:08 [Qemu-devel] [RFC PATCH 0/5] ui: add keyboard state and hotkey tracker Gerd Hoffmann
` (3 preceding siblings ...)
2018-02-21 17:08 ` [Qemu-devel] [RFC PATCH 4/5] kbd-state: register sdl2 hotkeys Gerd Hoffmann
@ 2018-02-21 17:08 ` Gerd Hoffmann
2018-02-22 14:14 ` [Qemu-devel] [RFC PATCH 0/5] ui: add keyboard state and hotkey tracker no-reply
5 siblings, 0 replies; 10+ messages in thread
From: Gerd Hoffmann @ 2018-02-21 17:08 UTC (permalink / raw)
To: qemu-devel; +Cc: programmingkidx, berrange, peter.maydell, Gerd Hoffmann
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 == NULL.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
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 = scon ? scon->dcl.con : NULL;
+ QemuConsole *con = scon->dcl.con;
if (ev->keysym.scancode >= qemu_input_map_usb_to_qcode_len) {
return;
}
-
qcode = qemu_input_map_usb_to_qcode[ev->keysym.scancode];
if (!qemu_console_is_graphic(con)) {
if (ev->type == 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;
--
2.9.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [Qemu-devel] [RFC PATCH 0/5] ui: add keyboard state and hotkey tracker
2018-02-21 17:08 [Qemu-devel] [RFC PATCH 0/5] ui: add keyboard state and hotkey tracker Gerd Hoffmann
` (4 preceding siblings ...)
2018-02-21 17:08 ` [Qemu-devel] [RFC PATCH 5/5] sdl2: use only QKeyCode in sdl2_process_key() Gerd Hoffmann
@ 2018-02-22 14:14 ` no-reply
5 siblings, 0 replies; 10+ messages in thread
From: no-reply @ 2018-02-22 14:14 UTC (permalink / raw)
To: kraxel; +Cc: famz, qemu-devel, programmingkidx, peter.maydell
Hi,
This series seems to have some coding style problems. See output below for
more information:
Type: series
Message-id: 20180221170820.15365-1-kraxel@redhat.com
Subject: [Qemu-devel] [RFC PATCH 0/5] ui: add keyboard state and hotkey tracker
=== TEST SCRIPT BEGIN ===
#!/bin/bash
BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done
exit $failed
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
* [new tag] patchew/20180220225904.16129-1-bsd@redhat.com -> patchew/20180220225904.16129-1-bsd@redhat.com
* [new tag] patchew/cover.1519036465.git.balaton@eik.bme.hu -> patchew/cover.1519036465.git.balaton@eik.bme.hu
Switched to a new branch 'test'
9065fbc367 sdl2: use only QKeyCode in sdl2_process_key()
0c65c8c6bb kbd-state: register sdl2 hotkeys
67a2d8cd4a kbd-state: use state tracker for sdl2
a389e7e994 kbd-state: add hotkey registry
d14a0b4fd8 kbd-state: add keyboard state tracker
=== OUTPUT BEGIN ===
Checking PATCH 1/5: kbd-state: add keyboard state tracker...
ERROR: space required after that ',' (ctx:BxV)
#86: FILE: ui/kbd-state.c:22:
+ QTAILQ_HEAD(,KbdHotkey) hotkeys;
^
total: 1 errors, 0 warnings, 149 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 2/5: kbd-state: add hotkey registry...
Checking PATCH 3/5: kbd-state: use state tracker for sdl2...
Checking PATCH 4/5: kbd-state: register sdl2 hotkeys...
Checking PATCH 5/5: sdl2: use only QKeyCode in sdl2_process_key()...
=== OUTPUT END ===
Test command exited with code: 1
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org
^ permalink raw reply [flat|nested] 10+ messages in thread