From d2917918c099240e1610668f75b7c3d26f0b8819 Mon Sep 17 00:00:00 2001 From: Frank Praznik 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 09486250e6..26c83a3942 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_CAPSLOCK: - keyboard->modstate ^= SDL_KMOD_CAPS; + case SDLK_RCTRL: + modifier = SDL_KMOD_RCTRL; break; - case SDLK_SCROLLLOCK: - keyboard->modstate ^= SDL_KMOD_SCROLL; + 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: - 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 acf788be8e..fe9a8cbc1e 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. */