From 30f41c02aec763d32e62351452da9ef582bc3472 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Fri, 6 Mar 2026 13:30:59 -0800 Subject: Move contrib libraries to contrib repo --- contrib/SDL-3.2.8/src/events/SDL_keyboard.c | 922 ---------------------------- 1 file changed, 922 deletions(-) delete mode 100644 contrib/SDL-3.2.8/src/events/SDL_keyboard.c (limited to 'contrib/SDL-3.2.8/src/events/SDL_keyboard.c') diff --git a/contrib/SDL-3.2.8/src/events/SDL_keyboard.c b/contrib/SDL-3.2.8/src/events/SDL_keyboard.c deleted file mode 100644 index 066c6e6..0000000 --- a/contrib/SDL-3.2.8/src/events/SDL_keyboard.c +++ /dev/null @@ -1,922 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "SDL_internal.h" - -// General keyboard handling code for SDL - -#include "SDL_events_c.h" -#include "SDL_keymap_c.h" -#include "../video/SDL_sysvideo.h" - -#if 0 -#define DEBUG_KEYBOARD -#endif - -// Global keyboard information - -#define KEYBOARD_HARDWARE 0x01 -#define KEYBOARD_VIRTUAL 0x02 -#define KEYBOARD_AUTORELEASE 0x04 -#define KEYBOARD_IGNOREMODIFIERS 0x08 - -#define KEYBOARD_SOURCE_MASK (KEYBOARD_HARDWARE | KEYBOARD_AUTORELEASE) - -#define KEYCODE_OPTION_HIDE_NUMPAD 0x01 -#define KEYCODE_OPTION_FRENCH_NUMBERS 0x02 -#define KEYCODE_OPTION_LATIN_LETTERS 0x04 -#define DEFAULT_KEYCODE_OPTIONS (KEYCODE_OPTION_FRENCH_NUMBERS | KEYCODE_OPTION_LATIN_LETTERS) - -typedef struct SDL_KeyboardInstance -{ - SDL_KeyboardID instance_id; - char *name; -} SDL_KeyboardInstance; - -typedef struct SDL_Keyboard -{ - // Data common to all keyboards - SDL_Window *focus; - SDL_Keymod modstate; - Uint8 keysource[SDL_SCANCODE_COUNT]; - bool keystate[SDL_SCANCODE_COUNT]; - SDL_Keymap *keymap; - bool french_numbers; - bool latin_letters; - bool thai_keyboard; - Uint32 keycode_options; - bool autorelease_pending; - Uint64 hardware_timestamp; - int next_reserved_scancode; -} SDL_Keyboard; - -static SDL_Keyboard SDL_keyboard; -static int SDL_keyboard_count; -static SDL_KeyboardInstance *SDL_keyboards; - -static void SDLCALL SDL_KeycodeOptionsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) -{ - SDL_Keyboard *keyboard = (SDL_Keyboard *)userdata; - - if (hint && *hint) { - keyboard->keycode_options = 0; - if (!SDL_strstr(hint, "none")) { - if (SDL_strstr(hint, "hide_numpad")) { - keyboard->keycode_options |= KEYCODE_OPTION_HIDE_NUMPAD; - } - 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; - } -} - -// Public functions -bool SDL_InitKeyboard(void) -{ - SDL_AddHintCallback(SDL_HINT_KEYCODE_OPTIONS, - SDL_KeycodeOptionsChanged, &SDL_keyboard); - return true; -} - -bool SDL_IsKeyboard(Uint16 vendor, Uint16 product, int num_keys) -{ - const int REAL_KEYBOARD_KEY_COUNT = 50; - if (num_keys > 0 && num_keys < REAL_KEYBOARD_KEY_COUNT) { - return false; - } - - // Eventually we'll have a blacklist of devices that enumerate as keyboards but aren't really - return true; -} - -static int SDL_GetKeyboardIndex(SDL_KeyboardID keyboardID) -{ - for (int i = 0; i < SDL_keyboard_count; ++i) { - if (keyboardID == SDL_keyboards[i].instance_id) { - return i; - } - } - return -1; -} - -void SDL_AddKeyboard(SDL_KeyboardID keyboardID, const char *name, bool send_event) -{ - int keyboard_index = SDL_GetKeyboardIndex(keyboardID); - if (keyboard_index >= 0) { - // We already know about this keyboard - return; - } - - SDL_assert(keyboardID != 0); - - SDL_KeyboardInstance *keyboards = (SDL_KeyboardInstance *)SDL_realloc(SDL_keyboards, (SDL_keyboard_count + 1) * sizeof(*keyboards)); - if (!keyboards) { - return; - } - SDL_KeyboardInstance *instance = &keyboards[SDL_keyboard_count]; - instance->instance_id = keyboardID; - instance->name = SDL_strdup(name ? name : ""); - SDL_keyboards = keyboards; - ++SDL_keyboard_count; - - if (send_event) { - SDL_Event event; - SDL_zero(event); - event.type = SDL_EVENT_KEYBOARD_ADDED; - event.kdevice.which = keyboardID; - SDL_PushEvent(&event); - } -} - -void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID, bool send_event) -{ - int keyboard_index = SDL_GetKeyboardIndex(keyboardID); - if (keyboard_index < 0) { - // We don't know about this keyboard - return; - } - - SDL_free(SDL_keyboards[keyboard_index].name); - - if (keyboard_index != SDL_keyboard_count - 1) { - SDL_memmove(&SDL_keyboards[keyboard_index], &SDL_keyboards[keyboard_index + 1], (SDL_keyboard_count - keyboard_index - 1) * sizeof(SDL_keyboards[keyboard_index])); - } - --SDL_keyboard_count; - - if (send_event) { - SDL_Event event; - SDL_zero(event); - event.type = SDL_EVENT_KEYBOARD_REMOVED; - event.kdevice.which = keyboardID; - SDL_PushEvent(&event); - } -} - -bool SDL_HasKeyboard(void) -{ - return (SDL_keyboard_count > 0); -} - -SDL_KeyboardID *SDL_GetKeyboards(int *count) -{ - int i; - SDL_KeyboardID *keyboards; - - keyboards = (SDL_JoystickID *)SDL_malloc((SDL_keyboard_count + 1) * sizeof(*keyboards)); - if (keyboards) { - if (count) { - *count = SDL_keyboard_count; - } - - for (i = 0; i < SDL_keyboard_count; ++i) { - keyboards[i] = SDL_keyboards[i].instance_id; - } - keyboards[i] = 0; - } else { - if (count) { - *count = 0; - } - } - - return keyboards; -} - -const char *SDL_GetKeyboardNameForID(SDL_KeyboardID instance_id) -{ - int keyboard_index = SDL_GetKeyboardIndex(instance_id); - if (keyboard_index < 0) { - SDL_SetError("Keyboard %" SDL_PRIu32 " not found", instance_id); - return NULL; - } - return SDL_GetPersistentString(SDL_keyboards[keyboard_index].name); -} - -void SDL_ResetKeyboard(void) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - int scancode; - -#ifdef DEBUG_KEYBOARD - SDL_Log("Resetting keyboard"); -#endif - for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_SCANCODE_COUNT; ++scancode) { - if (keyboard->keystate[scancode]) { - SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, 0, (SDL_Scancode)scancode, false); - } - } -} - -SDL_Keymap *SDL_GetCurrentKeymap(void) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - - if (keyboard->thai_keyboard) { - // Thai keyboards are QWERTY plus Thai characters, use the default QWERTY keymap - return NULL; - } - - if ((keyboard->keycode_options & KEYCODE_OPTION_LATIN_LETTERS) && - !keyboard->latin_letters) { - // We'll use the default QWERTY keymap - return NULL; - } - - return keyboard->keymap; -} - -void SDL_SetKeymap(SDL_Keymap *keymap, bool send_event) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - - if (keyboard->keymap) { - SDL_DestroyKeymap(keyboard->keymap); - } - - keyboard->keymap = keymap; - - // Detect French number row (all symbols) - keyboard->french_numbers = true; - for (int i = SDL_SCANCODE_1; i <= SDL_SCANCODE_0; ++i) { - if (SDL_isdigit(SDL_GetKeymapKeycode(keymap, (SDL_Scancode)i, SDL_KMOD_NONE)) || - !SDL_isdigit(SDL_GetKeymapKeycode(keymap, (SDL_Scancode)i, SDL_KMOD_SHIFT))) { - keyboard->french_numbers = false; - break; - } - } - - // Detect non-Latin keymap - keyboard->thai_keyboard = false; - keyboard->latin_letters = false; - for (int i = SDL_SCANCODE_A; i <= SDL_SCANCODE_D; ++i) { - SDL_Keycode key = SDL_GetKeymapKeycode(keymap, (SDL_Scancode)i, SDL_KMOD_NONE); - if (key <= 0xFF) { - keyboard->latin_letters = true; - break; - } - - if (key >= 0x0E00 && key <= 0x0E7F) { - keyboard->thai_keyboard = true; - break; - } - } - - if (send_event) { - SDL_SendKeymapChangedEvent(); - } -} - -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; - - return keyboard->focus; -} - -bool SDL_SetKeyboardFocus(SDL_Window *window) -{ - SDL_VideoDevice *video = SDL_GetVideoDevice(); - SDL_Keyboard *keyboard = &SDL_keyboard; - SDL_Mouse *mouse = SDL_GetMouse(); - - if (window) { - if (!SDL_ObjectValid(window, SDL_OBJECT_TYPE_WINDOW) || window->is_destroying) { - return SDL_SetError("Invalid window"); - } - } - - if (keyboard->focus && !window) { - // We won't get anymore keyboard messages, so reset keyboard state - SDL_ResetKeyboard(); - - // Also leave mouse relative mode - if (mouse->relative_mode) { - SDL_SetRelativeMouseMode(false); - - SDL_Window *focus = keyboard->focus; - if ((focus->flags & SDL_WINDOW_MINIMIZED) != 0) { - // We can't warp the mouse within minimized windows, so manually restore the position - float x = focus->x + mouse->x; - float y = focus->y + mouse->y; - SDL_WarpMouseGlobal(x, y); - } - } - } - - // See if the current window has lost focus - if (keyboard->focus && keyboard->focus != window) { - SDL_SendWindowEvent(keyboard->focus, SDL_EVENT_WINDOW_FOCUS_LOST, 0, 0); - - // Ensures IME compositions are committed - if (SDL_TextInputActive(keyboard->focus)) { - if (video && video->StopTextInput) { - video->StopTextInput(video, keyboard->focus); - } - } - } - - keyboard->focus = window; - - if (keyboard->focus) { - SDL_SendWindowEvent(keyboard->focus, SDL_EVENT_WINDOW_FOCUS_GAINED, 0, 0); - - if (SDL_TextInputActive(keyboard->focus)) { - if (video && video->StartTextInput) { - video->StartTextInput(video, keyboard->focus, keyboard->focus->text_input_props); - } - } - } - - SDL_UpdateRelativeMouseMode(); - - return true; -} - -static SDL_Keycode SDL_ConvertNumpadKeycode(SDL_Keycode keycode, bool numlock) -{ - switch (keycode) { - case SDLK_KP_DIVIDE: - return SDLK_SLASH; - case SDLK_KP_MULTIPLY: - return SDLK_ASTERISK; - case SDLK_KP_MINUS: - return SDLK_MINUS; - case SDLK_KP_PLUS: - return SDLK_PLUS; - case SDLK_KP_ENTER: - return SDLK_RETURN; - case SDLK_KP_1: - return numlock ? SDLK_1 : SDLK_END; - case SDLK_KP_2: - return numlock ? SDLK_2 : SDLK_DOWN; - case SDLK_KP_3: - return numlock ? SDLK_3 : SDLK_PAGEDOWN; - case SDLK_KP_4: - return numlock ? SDLK_4 : SDLK_LEFT; - case SDLK_KP_5: - return numlock ? SDLK_5 : SDLK_CLEAR; - case SDLK_KP_6: - return numlock ? SDLK_6 : SDLK_RIGHT; - case SDLK_KP_7: - return numlock ? SDLK_7 : SDLK_HOME; - case SDLK_KP_8: - return numlock ? SDLK_8 : SDLK_UP; - case SDLK_KP_9: - return numlock ? SDLK_9 : SDLK_PAGEUP; - case SDLK_KP_0: - return numlock ? SDLK_0 : SDLK_INSERT; - case SDLK_KP_PERIOD: - return numlock ? SDLK_PERIOD : SDLK_DELETE; - case SDLK_KP_EQUALS: - return SDLK_EQUALS; - case SDLK_KP_COMMA: - return SDLK_COMMA; - case SDLK_KP_EQUALSAS400: - return SDLK_EQUALS; - case SDLK_KP_LEFTPAREN: - return SDLK_LEFTPAREN; - case SDLK_KP_RIGHTPAREN: - return SDLK_RIGHTPAREN; - case SDLK_KP_LEFTBRACE: - return SDLK_LEFTBRACE; - case SDLK_KP_RIGHTBRACE: - return SDLK_RIGHTBRACE; - case SDLK_KP_TAB: - return SDLK_TAB; - case SDLK_KP_BACKSPACE: - return SDLK_BACKSPACE; - case SDLK_KP_A: - return SDLK_A; - case SDLK_KP_B: - return SDLK_B; - case SDLK_KP_C: - return SDLK_C; - case SDLK_KP_D: - return SDLK_D; - case SDLK_KP_E: - return SDLK_E; - case SDLK_KP_F: - return SDLK_F; - case SDLK_KP_PERCENT: - return SDLK_PERCENT; - case SDLK_KP_LESS: - return SDLK_LESS; - case SDLK_KP_GREATER: - return SDLK_GREATER; - case SDLK_KP_AMPERSAND: - return SDLK_AMPERSAND; - case SDLK_KP_COLON: - return SDLK_COLON; - case SDLK_KP_HASH: - return SDLK_HASH; - case SDLK_KP_SPACE: - return SDLK_SPACE; - case SDLK_KP_AT: - return SDLK_AT; - case SDLK_KP_EXCLAM: - return SDLK_EXCLAIM; - case SDLK_KP_PLUSMINUS: - return SDLK_PLUSMINUS; - default: - return keycode; - } -} - -SDL_Keycode SDL_GetKeyFromScancode(SDL_Scancode scancode, SDL_Keymod modstate, bool key_event) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - - if (key_event) { - SDL_Keymap *keymap = SDL_GetCurrentKeymap(); - bool numlock = (modstate & SDL_KMOD_NUM) != 0; - SDL_Keycode keycode; - - // We won't be applying any modifiers by default - modstate = SDL_KMOD_NONE; - - if ((keyboard->keycode_options & KEYCODE_OPTION_FRENCH_NUMBERS) && - keyboard->french_numbers && - (scancode >= SDL_SCANCODE_1 && scancode <= SDL_SCANCODE_0)) { - // Add the shift state to generate a numeric keycode - modstate |= SDL_KMOD_SHIFT; - } - - keycode = SDL_GetKeymapKeycode(keymap, scancode, modstate); - - if (keyboard->keycode_options & KEYCODE_OPTION_HIDE_NUMPAD) { - keycode = SDL_ConvertNumpadKeycode(keycode, numlock); - } - return keycode; - } - - return SDL_GetKeymapKeycode(keyboard->keymap, scancode, modstate); -} - -SDL_Scancode SDL_GetScancodeFromKey(SDL_Keycode key, SDL_Keymod *modstate) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - - return SDL_GetKeymapScancode(keyboard->keymap, key, modstate); -} - -static bool SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, bool down) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - bool posted = false; - SDL_Keycode keycode = SDLK_UNKNOWN; - Uint32 type; - bool repeat = false; - const Uint8 source = flags & KEYBOARD_SOURCE_MASK; - -#ifdef DEBUG_KEYBOARD - SDL_Log("The '%s' key has been %s", SDL_GetScancodeName(scancode), down ? "pressed" : "released"); -#endif - - // Figure out what type of event this is - if (down) { - type = SDL_EVENT_KEY_DOWN; - } else { - type = SDL_EVENT_KEY_UP; - } - - if (scancode > SDL_SCANCODE_UNKNOWN && scancode < SDL_SCANCODE_COUNT) { - // Drop events that don't change state - if (down) { - if (keyboard->keystate[scancode]) { - if (!(keyboard->keysource[scancode] & source)) { - keyboard->keysource[scancode] |= source; - return false; - } - repeat = true; - } - keyboard->keysource[scancode] |= source; - } else { - if (!keyboard->keystate[scancode]) { - return false; - } - keyboard->keysource[scancode] = 0; - } - - // Update internal keyboard state - keyboard->keystate[scancode] = down; - - keycode = SDL_GetKeyFromScancode(scancode, keyboard->modstate, true); - - } else if (rawcode == 0) { - // Nothing to do! - return false; - } - - if (source == KEYBOARD_HARDWARE) { - keyboard->hardware_timestamp = SDL_GetTicks(); - } else if (source == KEYBOARD_AUTORELEASE) { - keyboard->autorelease_pending = true; - } - - // Update modifiers state if applicable - if (!(flags & KEYBOARD_IGNOREMODIFIERS) && !repeat) { - SDL_Keymod modifier; - - 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_EVENT_KEY_DOWN == 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 - if (SDL_EventEnabled(type)) { - SDL_Event event; - event.type = type; - event.common.timestamp = timestamp; - event.key.scancode = scancode; - event.key.key = keycode; - event.key.mod = keyboard->modstate; - event.key.raw = (Uint16)rawcode; - event.key.down = down; - event.key.repeat = repeat; - event.key.windowID = keyboard->focus ? keyboard->focus->id : 0; - event.key.which = keyboardID; - posted = SDL_PushEvent(&event); - } - - /* If the keyboard is grabbed and the grabbed window is in full-screen, - minimize the window when we receive Alt+Tab, unless the application - has explicitly opted out of this behavior. */ - if (keycode == SDLK_TAB && down && - (keyboard->modstate & SDL_KMOD_ALT) && - keyboard->focus && - (keyboard->focus->flags & SDL_WINDOW_KEYBOARD_GRABBED) && - (keyboard->focus->flags & SDL_WINDOW_FULLSCREEN) && - SDL_GetHintBoolean(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, true)) { - /* We will temporarily forfeit our grab by minimizing our window, - allowing the user to escape the application */ - SDL_MinimizeWindow(keyboard->focus); - } - - return posted; -} - -void SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - SDL_Keymod modstate = SDL_KMOD_NONE; - SDL_Scancode scancode; - - if (ch == '\n') { - ch = SDLK_RETURN; - } - scancode = SDL_GetKeymapScancode(keyboard->keymap, 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, true); - } - - // Send a keydown and keyup for the character - SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, true); - SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, false); - - 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, false); - } -} - -bool SDL_SendKeyboardKey(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, bool down) -{ - return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, keyboardID, rawcode, scancode, down); -} - -bool SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, SDL_Keycode keycode, bool down) -{ - if (down) { - // Make sure we have this keycode in our keymap - SetKeymapEntry(scancode, SDL_GetModState(), keycode); - } - - return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, keyboardID, rawcode, scancode, down); -} - -bool SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, bool down) -{ - return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE | KEYBOARD_IGNOREMODIFIERS, keyboardID, rawcode, scancode, down); -} - -bool SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode) -{ - return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_AUTORELEASE, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, true); -} - -void SDL_ReleaseAutoReleaseKeys(void) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - int scancode; - - if (keyboard->autorelease_pending) { - for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_SCANCODE_COUNT; ++scancode) { - if (keyboard->keysource[scancode] == KEYBOARD_AUTORELEASE) { - SDL_SendKeyboardKeyInternal(0, KEYBOARD_AUTORELEASE, SDL_GLOBAL_KEYBOARD_ID, 0, (SDL_Scancode)scancode, false); - } - } - keyboard->autorelease_pending = false; - } - - if (keyboard->hardware_timestamp) { - // Keep hardware keyboard "active" for 250 ms - if (SDL_GetTicks() >= keyboard->hardware_timestamp + 250) { - keyboard->hardware_timestamp = 0; - } - } -} - -bool SDL_HardwareKeyboardKeyPressed(void) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - int scancode; - - for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_SCANCODE_COUNT; ++scancode) { - if (keyboard->keysource[scancode] & KEYBOARD_HARDWARE) { - return true; - } - } - - return keyboard->hardware_timestamp ? true : false; -} - -void SDL_SendKeyboardText(const char *text) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - - if (!SDL_TextInputActive(keyboard->focus)) { - return; - } - - if (!text || !*text) { - return; - } - - // Don't post text events for unprintable characters - if (SDL_iscntrl((unsigned char)*text)) { - return; - } - - // Post the event, if desired - if (SDL_EventEnabled(SDL_EVENT_TEXT_INPUT)) { - SDL_Event event; - event.type = SDL_EVENT_TEXT_INPUT; - event.common.timestamp = 0; - event.text.windowID = keyboard->focus ? keyboard->focus->id : 0; - event.text.text = SDL_CreateTemporaryString(text); - if (!event.text.text) { - return; - } - SDL_PushEvent(&event); - } -} - -void SDL_SendEditingText(const char *text, int start, int length) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - - if (!SDL_TextInputActive(keyboard->focus)) { - return; - } - - if (!text) { - return; - } - - // Post the event, if desired - if (SDL_EventEnabled(SDL_EVENT_TEXT_EDITING)) { - SDL_Event event; - - event.type = SDL_EVENT_TEXT_EDITING; - event.common.timestamp = 0; - event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0; - event.edit.start = start; - event.edit.length = length; - event.edit.text = SDL_CreateTemporaryString(text); - if (!event.edit.text) { - return; - } - SDL_PushEvent(&event); - } -} - -static const char * const *CreateCandidatesForEvent(char **candidates, int num_candidates) -{ - const char **event_candidates; - int i; - char *ptr; - size_t total_length = (num_candidates + 1) * sizeof(*event_candidates); - - for (i = 0; i < num_candidates; ++i) { - size_t length = SDL_strlen(candidates[i]) + 1; - - total_length += length; - } - - event_candidates = (const char **)SDL_AllocateTemporaryMemory(total_length); - if (!event_candidates) { - return NULL; - } - ptr = (char *)(event_candidates + (num_candidates + 1)); - - for (i = 0; i < num_candidates; ++i) { - size_t length = SDL_strlen(candidates[i]) + 1; - - event_candidates[i] = ptr; - SDL_memcpy(ptr, candidates[i], length); - ptr += length; - } - event_candidates[i] = NULL; - - return event_candidates; -} - -void SDL_SendEditingTextCandidates(char **candidates, int num_candidates, int selected_candidate, bool horizontal) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - - if (!SDL_TextInputActive(keyboard->focus)) { - return; - } - - // Post the event, if desired - if (SDL_EventEnabled(SDL_EVENT_TEXT_EDITING_CANDIDATES)) { - SDL_Event event; - - event.type = SDL_EVENT_TEXT_EDITING_CANDIDATES; - event.common.timestamp = 0; - event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0; - if (num_candidates > 0) { - const char * const *event_candidates = CreateCandidatesForEvent(candidates, num_candidates); - if (!event_candidates) { - return; - } - event.edit_candidates.candidates = event_candidates; - event.edit_candidates.num_candidates = num_candidates; - event.edit_candidates.selected_candidate = selected_candidate; - event.edit_candidates.horizontal = horizontal; - } else { - event.edit_candidates.candidates = NULL; - event.edit_candidates.num_candidates = 0; - event.edit_candidates.selected_candidate = -1; - event.edit_candidates.horizontal = false; - } - SDL_PushEvent(&event); - } -} - -void SDL_QuitKeyboard(void) -{ - for (int i = SDL_keyboard_count; i--;) { - SDL_RemoveKeyboard(SDL_keyboards[i].instance_id, false); - } - SDL_free(SDL_keyboards); - SDL_keyboards = NULL; - - if (SDL_keyboard.keymap) { - SDL_DestroyKeymap(SDL_keyboard.keymap); - SDL_keyboard.keymap = NULL; - } - - SDL_RemoveHintCallback(SDL_HINT_KEYCODE_OPTIONS, - SDL_KeycodeOptionsChanged, &SDL_keyboard); -} - -const bool *SDL_GetKeyboardState(int *numkeys) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - - if (numkeys != (int *)0) { - *numkeys = SDL_SCANCODE_COUNT; - } - return keyboard->keystate; -} - -SDL_Keymod SDL_GetModState(void) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - - return keyboard->modstate; -} - -void SDL_SetModState(SDL_Keymod modstate) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - - keyboard->modstate = modstate; -} - -// Note that SDL_ToggleModState() is not a public API. SDL_SetModState() is. -void SDL_ToggleModState(SDL_Keymod modstate, bool toggle) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - if (toggle) { - keyboard->modstate |= modstate; - } else { - keyboard->modstate &= ~modstate; - } -} - -- cgit v1.2.3