From d2917918c099240e1610668f75b7c3d26f0b8819 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Fri, 30 Dec 2022 10:06:00 -0500
Subject: [PATCH] events: Add function to send keystrokes and not update the
modifier state
Add SDL_SendKeyboardKeyIgnoreModifiers() function and repurpose the source parameter for the SDL_SendKeyboardKeyInternal() function to use as a generic set of keyboard flags.
---
src/events/SDL_keyboard.c | 104 ++++++++++++++++++++----------------
src/events/SDL_keyboard_c.h | 1 +
2 files changed, 60 insertions(+), 45 deletions(-)
diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c
index 09486250e6fb..26c83a39427b 100644
--- a/src/events/SDL_keyboard.c
+++ b/src/events/SDL_keyboard.c
@@ -30,8 +30,14 @@
/* Global keyboard information */
-#define KEYBOARD_HARDWARE 0x01
-#define KEYBOARD_AUTORELEASE 0x02
+typedef enum
+{
+ KEYBOARD_HARDWARE = 0x01,
+ KEYBOARD_AUTORELEASE = 0x02,
+ KEYBOARD_IGNOREMODIFIERS = 0x04
+} SDL_KeyboardFlags;
+
+#define KEYBOARD_SOURCE_MASK (KEYBOARD_HARDWARE | KEYBOARD_AUTORELEASE)
typedef struct SDL_Keyboard SDL_Keyboard;
@@ -789,13 +795,14 @@ void SDL_SetKeyboardFocus(SDL_Window *window)
}
}
-static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint8 source, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
+static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, SDL_KeyboardFlags flags, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
{
SDL_Keyboard *keyboard = &SDL_keyboard;
int posted;
SDL_Keymod modifier;
Uint32 type;
Uint8 repeat = SDL_FALSE;
+ const Uint8 source = flags & KEYBOARD_SOURCE_MASK;
if (scancode == SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
return 0;
@@ -848,55 +855,57 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint8 source, Uint8 sta
}
/* Update modifiers state if applicable */
- switch (keycode) {
- case SDLK_LCTRL:
- modifier = SDL_KMOD_LCTRL;
- break;
- case SDLK_RCTRL:
- modifier = SDL_KMOD_RCTRL;
- break;
- case SDLK_LSHIFT:
- modifier = SDL_KMOD_LSHIFT;
- break;
- case SDLK_RSHIFT:
- modifier = SDL_KMOD_RSHIFT;
- break;
- case SDLK_LALT:
- modifier = SDL_KMOD_LALT;
- break;
- case SDLK_RALT:
- modifier = SDL_KMOD_RALT;
- break;
- case SDLK_LGUI:
- modifier = SDL_KMOD_LGUI;
- break;
- case SDLK_RGUI:
- modifier = SDL_KMOD_RGUI;
- break;
- case SDLK_MODE:
- modifier = SDL_KMOD_MODE;
- break;
- default:
- modifier = SDL_KMOD_NONE;
- break;
- }
- if (SDL_KEYDOWN == type) {
+ if (!(flags & KEYBOARD_IGNOREMODIFIERS)) {
switch (keycode) {
- case SDLK_NUMLOCKCLEAR:
- keyboard->modstate ^= SDL_KMOD_NUM;
+ case SDLK_LCTRL:
+ modifier = SDL_KMOD_LCTRL;
+ break;
+ case SDLK_RCTRL:
+ modifier = SDL_KMOD_RCTRL;
+ break;
+ case SDLK_LSHIFT:
+ modifier = SDL_KMOD_LSHIFT;
break;
- case SDLK_CAPSLOCK:
- keyboard->modstate ^= SDL_KMOD_CAPS;
+ case SDLK_RSHIFT:
+ modifier = SDL_KMOD_RSHIFT;
break;
- case SDLK_SCROLLLOCK:
- keyboard->modstate ^= SDL_KMOD_SCROLL;
+ case SDLK_LALT:
+ modifier = SDL_KMOD_LALT;
+ break;
+ case SDLK_RALT:
+ modifier = SDL_KMOD_RALT;
+ break;
+ case SDLK_LGUI:
+ modifier = SDL_KMOD_LGUI;
+ break;
+ case SDLK_RGUI:
+ modifier = SDL_KMOD_RGUI;
+ break;
+ case SDLK_MODE:
+ modifier = SDL_KMOD_MODE;
break;
default:
- keyboard->modstate |= modifier;
+ modifier = SDL_KMOD_NONE;
break;
}
- } else {
- keyboard->modstate &= ~modifier;
+ if (SDL_KEYDOWN == type) {
+ switch (keycode) {
+ case SDLK_NUMLOCKCLEAR:
+ keyboard->modstate ^= SDL_KMOD_NUM;
+ break;
+ case SDLK_CAPSLOCK:
+ keyboard->modstate ^= SDL_KMOD_CAPS;
+ break;
+ case SDLK_SCROLLLOCK:
+ keyboard->modstate ^= SDL_KMOD_SCROLL;
+ break;
+ default:
+ keyboard->modstate |= modifier;
+ break;
+ }
+ } else {
+ keyboard->modstate &= ~modifier;
+ }
}
/* Post the event, if desired */
@@ -973,6 +982,11 @@ int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode)
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_AUTORELEASE, SDL_PRESSED, scancode, SDLK_UNKNOWN);
}
+int SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, Uint8 state, SDL_Scancode scancode)
+{
+ return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE | KEYBOARD_IGNOREMODIFIERS, state, scancode, SDLK_UNKNOWN);
+}
+
void SDL_ReleaseAutoReleaseKeys(void)
{
SDL_Keyboard *keyboard = &SDL_keyboard;
diff --git a/src/events/SDL_keyboard_c.h b/src/events/SDL_keyboard_c.h
index acf788be8e69..fe9a8cbc1eda 100644
--- a/src/events/SDL_keyboard_c.h
+++ b/src/events/SDL_keyboard_c.h
@@ -52,6 +52,7 @@ extern int SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch);
/* Send a keyboard key event */
extern int SDL_SendKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode);
extern int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode);
+extern int SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, Uint8 state, SDL_Scancode scancode);
/* This is for platforms that don't know the keymap but can report scancode and keycode directly.
Most platforms should prefer to optionally call SDL_SetKeymap and then use SDL_SendKeyboardKey. */