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.
This commit is contained in:
Frank Praznik 2022-12-30 10:06:00 -05:00 committed by Sam Lantinga
parent 59ad6793b9
commit d2917918c0
2 changed files with 60 additions and 45 deletions

View file

@ -30,8 +30,14 @@
/* Global keyboard information */ /* Global keyboard information */
#define KEYBOARD_HARDWARE 0x01 typedef enum
#define KEYBOARD_AUTORELEASE 0x02 {
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; 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; SDL_Keyboard *keyboard = &SDL_keyboard;
int posted; int posted;
SDL_Keymod modifier; SDL_Keymod modifier;
Uint32 type; Uint32 type;
Uint8 repeat = SDL_FALSE; Uint8 repeat = SDL_FALSE;
const Uint8 source = flags & KEYBOARD_SOURCE_MASK;
if (scancode == SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { if (scancode == SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
return 0; return 0;
@ -848,55 +855,57 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint8 source, Uint8 sta
} }
/* Update modifiers state if applicable */ /* Update modifiers state if applicable */
switch (keycode) { if (!(flags & KEYBOARD_IGNOREMODIFIERS)) {
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) {
switch (keycode) { switch (keycode) {
case SDLK_NUMLOCKCLEAR: case SDLK_LCTRL:
keyboard->modstate ^= SDL_KMOD_NUM; modifier = SDL_KMOD_LCTRL;
break; break;
case SDLK_CAPSLOCK: case SDLK_RCTRL:
keyboard->modstate ^= SDL_KMOD_CAPS; modifier = SDL_KMOD_RCTRL;
break; break;
case SDLK_SCROLLLOCK: case SDLK_LSHIFT:
keyboard->modstate ^= SDL_KMOD_SCROLL; 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; break;
default: default:
keyboard->modstate |= modifier; modifier = SDL_KMOD_NONE;
break; break;
} }
} else { if (SDL_KEYDOWN == type) {
keyboard->modstate &= ~modifier; 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 */ /* 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); 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) void SDL_ReleaseAutoReleaseKeys(void)
{ {
SDL_Keyboard *keyboard = &SDL_keyboard; SDL_Keyboard *keyboard = &SDL_keyboard;

View file

@ -52,6 +52,7 @@ extern int SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch);
/* Send a keyboard key event */ /* Send a keyboard key event */
extern int SDL_SendKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode); extern int SDL_SendKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode);
extern int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, 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. /* 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. */ Most platforms should prefer to optionally call SDL_SetKeymap and then use SDL_SendKeyboardKey. */