|
@@ -37,10 +37,9 @@
|
|
|
|
|
|
#define KEYBOARD_SOURCE_MASK (KEYBOARD_HARDWARE | KEYBOARD_AUTORELEASE)
|
|
|
|
|
|
-#define KEYCODE_OPTION_APPLY_MODIFIERS 0x01
|
|
|
-#define KEYCODE_OPTION_FRENCH_NUMBERS 0x02
|
|
|
-#define KEYCODE_OPTION_LATIN_LETTERS 0x04
|
|
|
-#define DEFAULT_KEYCODE_OPTIONS (KEYCODE_OPTION_APPLY_MODIFIERS | KEYCODE_OPTION_FRENCH_NUMBERS)
|
|
|
+#define KEYCODE_OPTION_FRENCH_NUMBERS 0x01
|
|
|
+#define KEYCODE_OPTION_LATIN_LETTERS 0x02
|
|
|
+#define DEFAULT_KEYCODE_OPTIONS (KEYCODE_OPTION_FRENCH_NUMBERS)
|
|
|
|
|
|
typedef struct SDL_KeyboardInstance
|
|
|
{
|
|
@@ -61,6 +60,7 @@ typedef struct SDL_Keyboard
|
|
|
Uint32 keycode_options;
|
|
|
SDL_bool autorelease_pending;
|
|
|
Uint64 hardware_timestamp;
|
|
|
+ int next_reserved_scancode;
|
|
|
} SDL_Keyboard;
|
|
|
|
|
|
static SDL_Keyboard SDL_keyboard;
|
|
@@ -73,16 +73,13 @@ static void SDLCALL SDL_KeycodeOptionsChanged(void *userdata, const char *name,
|
|
|
|
|
|
if (hint && *hint) {
|
|
|
keyboard->keycode_options = 0;
|
|
|
- if (SDL_strstr(hint, "unmodified")) {
|
|
|
- keyboard->keycode_options &= ~KEYCODE_OPTION_APPLY_MODIFIERS;
|
|
|
- } else if (SDL_strstr(hint, "modified")) {
|
|
|
- keyboard->keycode_options |= KEYCODE_OPTION_APPLY_MODIFIERS;
|
|
|
- }
|
|
|
- if (SDL_strstr(hint, "french_numbers")) {
|
|
|
- keyboard->keycode_options |= KEYCODE_OPTION_FRENCH_NUMBERS;
|
|
|
- }
|
|
|
- if (SDL_strstr(hint, "latin_letters")) {
|
|
|
- keyboard->keycode_options |= KEYCODE_OPTION_LATIN_LETTERS;
|
|
|
+ if (!SDL_strstr(hint, "none")) {
|
|
|
+ if (SDL_strstr(hint, "french_numbers")) {
|
|
|
+ keyboard->keycode_options |= KEYCODE_OPTION_FRENCH_NUMBERS;
|
|
|
+ }
|
|
|
+ if (SDL_strstr(hint, "latin_letters")) {
|
|
|
+ keyboard->keycode_options |= KEYCODE_OPTION_LATIN_LETTERS;
|
|
|
+ }
|
|
|
}
|
|
|
} else {
|
|
|
keyboard->keycode_options = DEFAULT_KEYCODE_OPTIONS;
|
|
@@ -258,6 +255,32 @@ void SDL_SetKeymap(SDL_Keymap *keymap, SDL_bool send_event)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static SDL_Scancode GetNextReservedScancode(void)
|
|
|
+{
|
|
|
+ SDL_Keyboard *keyboard = &SDL_keyboard;
|
|
|
+ SDL_Scancode scancode;
|
|
|
+
|
|
|
+ if (keyboard->next_reserved_scancode && keyboard->next_reserved_scancode < SDL_SCANCODE_RESERVED + 100) {
|
|
|
+ scancode = (SDL_Scancode)keyboard->next_reserved_scancode;
|
|
|
+ } else {
|
|
|
+ scancode = SDL_SCANCODE_RESERVED;
|
|
|
+ }
|
|
|
+ keyboard->next_reserved_scancode = (int)scancode + 1;
|
|
|
+
|
|
|
+ return scancode;
|
|
|
+}
|
|
|
+
|
|
|
+static void SetKeymapEntry(SDL_Scancode scancode, SDL_Keymod modstate, SDL_Keycode keycode)
|
|
|
+{
|
|
|
+ SDL_Keyboard *keyboard = &SDL_keyboard;
|
|
|
+
|
|
|
+ if (!keyboard->keymap) {
|
|
|
+ keyboard->keymap = SDL_CreateKeymap();
|
|
|
+ }
|
|
|
+
|
|
|
+ SDL_SetKeymapEntry(keyboard->keymap, scancode, modstate, keycode);
|
|
|
+}
|
|
|
+
|
|
|
SDL_Window *SDL_GetKeyboardFocus(void)
|
|
|
{
|
|
|
SDL_Keyboard *keyboard = &SDL_keyboard;
|
|
@@ -309,23 +332,21 @@ int SDL_SetKeyboardFocus(SDL_Window *window)
|
|
|
|
|
|
static SDL_Keycode SDL_GetEventKeycode(SDL_Keyboard *keyboard, SDL_Scancode scancode, SDL_Keymod modstate)
|
|
|
{
|
|
|
- SDL_Keycode keycode;
|
|
|
+ SDL_bool shifted = (modstate & SDL_KMOD_SHIFT) != 0;
|
|
|
+
|
|
|
+ // We won't be applying any modifiers by default
|
|
|
+ modstate = SDL_KMOD_NONE;
|
|
|
|
|
|
if (scancode >= SDL_SCANCODE_A && scancode <= SDL_SCANCODE_Z) {
|
|
|
if (keyboard->non_latin_letters && (keyboard->keycode_options & KEYCODE_OPTION_LATIN_LETTERS)) {
|
|
|
- if (keyboard->keycode_options & KEYCODE_OPTION_APPLY_MODIFIERS) {
|
|
|
- keycode = SDL_GetDefaultKeyFromScancode(scancode, modstate);
|
|
|
- } else {
|
|
|
- keycode = SDL_GetDefaultKeyFromScancode(scancode, SDL_KMOD_NONE);
|
|
|
- }
|
|
|
- return keycode;
|
|
|
+ return SDL_GetDefaultKeyFromScancode(scancode, modstate);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (scancode >= SDL_SCANCODE_1 && scancode <= SDL_SCANCODE_0) {
|
|
|
if (keyboard->french_numbers && (keyboard->keycode_options & KEYCODE_OPTION_FRENCH_NUMBERS)) {
|
|
|
// Invert the shift state to generate the correct keycode
|
|
|
- if (modstate & SDL_KMOD_SHIFT) {
|
|
|
+ if (shifted) {
|
|
|
modstate &= ~SDL_KMOD_SHIFT;
|
|
|
} else {
|
|
|
modstate |= SDL_KMOD_SHIFT;
|
|
@@ -333,19 +354,14 @@ static SDL_Keycode SDL_GetEventKeycode(SDL_Keyboard *keyboard, SDL_Scancode scan
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (keyboard->keycode_options & KEYCODE_OPTION_APPLY_MODIFIERS) {
|
|
|
- keycode = SDL_GetKeyFromScancode(scancode, modstate);
|
|
|
- } else {
|
|
|
- keycode = SDL_GetKeyFromScancode(scancode, SDL_KMOD_NONE);
|
|
|
- }
|
|
|
- return keycode;
|
|
|
+ return SDL_GetKeyFromScancode(scancode, modstate);
|
|
|
}
|
|
|
|
|
|
-static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, SDL_Keycode keycode, Uint8 state)
|
|
|
+static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, Uint8 state)
|
|
|
{
|
|
|
SDL_Keyboard *keyboard = &SDL_keyboard;
|
|
|
int posted;
|
|
|
- SDL_Keymod modifier;
|
|
|
+ SDL_Keycode keycode = SDLK_UNKNOWN;
|
|
|
Uint32 type;
|
|
|
Uint8 repeat = SDL_FALSE;
|
|
|
const Uint8 source = flags & KEYBOARD_SOURCE_MASK;
|
|
@@ -368,7 +384,7 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_Keybo
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- if (scancode != SDL_SCANCODE_UNKNOWN && scancode < SDL_NUM_SCANCODES) {
|
|
|
+ if (scancode > SDL_SCANCODE_UNKNOWN && scancode < SDL_NUM_SCANCODES) {
|
|
|
/* Drop events that don't change state */
|
|
|
if (state) {
|
|
|
if (keyboard->keystate[scancode]) {
|
|
@@ -389,11 +405,9 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_Keybo
|
|
|
/* Update internal keyboard state */
|
|
|
keyboard->keystate[scancode] = state;
|
|
|
|
|
|
- if (keycode == SDLK_UNKNOWN) {
|
|
|
- keycode = SDL_GetEventKeycode(keyboard, scancode, keyboard->modstate);
|
|
|
- }
|
|
|
+ keycode = SDL_GetEventKeycode(keyboard, scancode, keyboard->modstate);
|
|
|
|
|
|
- } else if (keycode == SDLK_UNKNOWN && rawcode == 0) {
|
|
|
+ } else if (rawcode == 0) {
|
|
|
/* Nothing to do! */
|
|
|
return 0;
|
|
|
}
|
|
@@ -406,6 +420,8 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_Keybo
|
|
|
|
|
|
/* Update modifiers state if applicable */
|
|
|
if (!(flags & KEYBOARD_IGNOREMODIFIERS) && !repeat) {
|
|
|
+ SDL_Keymod modifier;
|
|
|
+
|
|
|
switch (keycode) {
|
|
|
case SDLK_LCTRL:
|
|
|
modifier = SDL_KMOD_LCTRL;
|
|
@@ -496,48 +512,53 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_Keybo
|
|
|
int SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch)
|
|
|
{
|
|
|
SDL_Keymod modstate = SDL_KMOD_NONE;
|
|
|
- SDL_Scancode scancode = SDL_GetDefaultScancodeFromKey(ch, &modstate);
|
|
|
+ SDL_Scancode scancode = SDL_GetScancodeFromKey(ch, &modstate);
|
|
|
|
|
|
+ // Make sure we have this keycode in our keymap
|
|
|
+ if (scancode == SDL_SCANCODE_UNKNOWN && ch < SDLK_SCANCODE_MASK) {
|
|
|
+ scancode = GetNextReservedScancode();
|
|
|
+ SetKeymapEntry(scancode, modstate, ch);
|
|
|
+ }
|
|
|
|
|
|
if (modstate & SDL_KMOD_SHIFT) {
|
|
|
/* If the character uses shift, press shift down */
|
|
|
- SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, SDL_SCANCODE_LSHIFT, SDLK_LSHIFT, SDL_PRESSED);
|
|
|
+ SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, SDL_SCANCODE_LSHIFT, SDL_PRESSED);
|
|
|
}
|
|
|
|
|
|
/* Send a keydown and keyup for the character */
|
|
|
- SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, ch, SDL_PRESSED);
|
|
|
- SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, ch, SDL_RELEASED);
|
|
|
+ SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, SDL_PRESSED);
|
|
|
+ SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, SDL_RELEASED);
|
|
|
|
|
|
if (modstate & SDL_KMOD_SHIFT) {
|
|
|
/* If the character uses shift, release shift */
|
|
|
- SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, SDL_SCANCODE_LSHIFT, SDLK_LSHIFT, SDL_RELEASED);
|
|
|
+ SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, SDL_SCANCODE_LSHIFT, SDL_RELEASED);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-int SDL_SendVirtualKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode)
|
|
|
-{
|
|
|
- return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, SDLK_UNKNOWN, state);
|
|
|
-}
|
|
|
-
|
|
|
int SDL_SendKeyboardKey(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, Uint8 state)
|
|
|
{
|
|
|
- return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, keyboardID, rawcode, scancode, SDLK_UNKNOWN, state);
|
|
|
+ return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, keyboardID, rawcode, scancode, state);
|
|
|
}
|
|
|
|
|
|
int SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, SDL_Keycode keycode, Uint8 state)
|
|
|
{
|
|
|
- return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, keyboardID, rawcode, scancode, keycode, state);
|
|
|
+ if (state == SDL_PRESSED) {
|
|
|
+ // Make sure we have this keycode in our keymap
|
|
|
+ SetKeymapEntry(scancode, SDL_GetModState(), keycode);
|
|
|
+ }
|
|
|
+
|
|
|
+ return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, keyboardID, rawcode, scancode, state);
|
|
|
}
|
|
|
|
|
|
-int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode)
|
|
|
+int SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, Uint8 state)
|
|
|
{
|
|
|
- return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_AUTORELEASE, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, SDLK_UNKNOWN, SDL_PRESSED);
|
|
|
+ return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE | KEYBOARD_IGNOREMODIFIERS, keyboardID, rawcode, scancode, state);
|
|
|
}
|
|
|
|
|
|
-int SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, Uint8 state)
|
|
|
+int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode)
|
|
|
{
|
|
|
- return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE | KEYBOARD_IGNOREMODIFIERS, keyboardID, rawcode, scancode, SDLK_UNKNOWN, state);
|
|
|
+ return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_AUTORELEASE, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, SDL_PRESSED);
|
|
|
}
|
|
|
|
|
|
void SDL_ReleaseAutoReleaseKeys(void)
|
|
@@ -548,7 +569,7 @@ void SDL_ReleaseAutoReleaseKeys(void)
|
|
|
if (keyboard->autorelease_pending) {
|
|
|
for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) {
|
|
|
if (keyboard->keysource[scancode] == KEYBOARD_AUTORELEASE) {
|
|
|
- SDL_SendKeyboardKeyInternal(0, KEYBOARD_AUTORELEASE, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, SDLK_UNKNOWN, SDL_RELEASED);
|
|
|
+ SDL_SendKeyboardKeyInternal(0, KEYBOARD_AUTORELEASE, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, SDL_RELEASED);
|
|
|
}
|
|
|
}
|
|
|
keyboard->autorelease_pending = SDL_FALSE;
|