diff options
| author | 3gg <3gg@shellblade.net> | 2025-12-27 12:03:39 -0800 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2025-12-27 12:03:39 -0800 |
| commit | 5a079a2d114f96d4847d1ee305d5b7c16eeec50e (patch) | |
| tree | 8926ab44f168acf787d8e19608857b3af0f82758 /contrib/SDL-3.2.8/src/events | |
Initial commit
Diffstat (limited to 'contrib/SDL-3.2.8/src/events')
39 files changed, 11735 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/events/SDL_categories.c b/contrib/SDL-3.2.8/src/events/SDL_categories.c new file mode 100644 index 0000000..cb41f6f --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_categories.c | |||
| @@ -0,0 +1,249 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | // SDL event categories | ||
| 24 | |||
| 25 | #include "SDL_events_c.h" | ||
| 26 | #include "SDL_categories_c.h" | ||
| 27 | |||
| 28 | SDL_EventCategory SDL_GetEventCategory(Uint32 type) | ||
| 29 | { | ||
| 30 | if (type >= SDL_EVENT_USER && type <= SDL_EVENT_LAST) { | ||
| 31 | return SDL_EVENTCATEGORY_USER; | ||
| 32 | } | ||
| 33 | else if (type >= SDL_EVENT_DISPLAY_FIRST && type <= SDL_EVENT_DISPLAY_LAST) { | ||
| 34 | return SDL_EVENTCATEGORY_DISPLAY; | ||
| 35 | } | ||
| 36 | else if (type >= SDL_EVENT_WINDOW_FIRST && type <= SDL_EVENT_WINDOW_LAST) { | ||
| 37 | return SDL_EVENTCATEGORY_WINDOW; | ||
| 38 | } | ||
| 39 | switch (type) { | ||
| 40 | default: | ||
| 41 | SDL_SetError("Unknown event type"); | ||
| 42 | return SDL_EVENTCATEGORY_UNKNOWN; | ||
| 43 | |||
| 44 | case SDL_EVENT_KEYMAP_CHANGED: | ||
| 45 | case SDL_EVENT_TERMINATING: | ||
| 46 | case SDL_EVENT_LOW_MEMORY: | ||
| 47 | case SDL_EVENT_WILL_ENTER_BACKGROUND: | ||
| 48 | case SDL_EVENT_DID_ENTER_BACKGROUND: | ||
| 49 | case SDL_EVENT_WILL_ENTER_FOREGROUND: | ||
| 50 | case SDL_EVENT_DID_ENTER_FOREGROUND: | ||
| 51 | case SDL_EVENT_LOCALE_CHANGED: | ||
| 52 | case SDL_EVENT_SYSTEM_THEME_CHANGED: | ||
| 53 | return SDL_EVENTCATEGORY_SYSTEM; | ||
| 54 | |||
| 55 | case SDL_EVENT_RENDER_TARGETS_RESET: | ||
| 56 | case SDL_EVENT_RENDER_DEVICE_RESET: | ||
| 57 | case SDL_EVENT_RENDER_DEVICE_LOST: | ||
| 58 | return SDL_EVENTCATEGORY_RENDER; | ||
| 59 | |||
| 60 | case SDL_EVENT_QUIT: | ||
| 61 | return SDL_EVENTCATEGORY_QUIT; | ||
| 62 | |||
| 63 | case SDL_EVENT_KEY_DOWN: | ||
| 64 | case SDL_EVENT_KEY_UP: | ||
| 65 | return SDL_EVENTCATEGORY_KEY; | ||
| 66 | |||
| 67 | case SDL_EVENT_TEXT_EDITING: | ||
| 68 | return SDL_EVENTCATEGORY_EDIT; | ||
| 69 | |||
| 70 | case SDL_EVENT_TEXT_INPUT: | ||
| 71 | return SDL_EVENTCATEGORY_TEXT; | ||
| 72 | |||
| 73 | case SDL_EVENT_KEYBOARD_ADDED: | ||
| 74 | case SDL_EVENT_KEYBOARD_REMOVED: | ||
| 75 | return SDL_EVENTCATEGORY_KDEVICE; | ||
| 76 | |||
| 77 | case SDL_EVENT_TEXT_EDITING_CANDIDATES: | ||
| 78 | return SDL_EVENTCATEGORY_EDIT_CANDIDATES; | ||
| 79 | |||
| 80 | case SDL_EVENT_MOUSE_MOTION: | ||
| 81 | return SDL_EVENTCATEGORY_MOTION; | ||
| 82 | |||
| 83 | case SDL_EVENT_MOUSE_BUTTON_DOWN: | ||
| 84 | case SDL_EVENT_MOUSE_BUTTON_UP: | ||
| 85 | return SDL_EVENTCATEGORY_BUTTON; | ||
| 86 | |||
| 87 | case SDL_EVENT_MOUSE_WHEEL: | ||
| 88 | return SDL_EVENTCATEGORY_WHEEL; | ||
| 89 | |||
| 90 | case SDL_EVENT_MOUSE_ADDED: | ||
| 91 | case SDL_EVENT_MOUSE_REMOVED: | ||
| 92 | return SDL_EVENTCATEGORY_MDEVICE; | ||
| 93 | |||
| 94 | case SDL_EVENT_JOYSTICK_AXIS_MOTION: | ||
| 95 | return SDL_EVENTCATEGORY_JAXIS; | ||
| 96 | |||
| 97 | case SDL_EVENT_JOYSTICK_BALL_MOTION: | ||
| 98 | return SDL_EVENTCATEGORY_JBALL; | ||
| 99 | |||
| 100 | case SDL_EVENT_JOYSTICK_HAT_MOTION: | ||
| 101 | return SDL_EVENTCATEGORY_JHAT; | ||
| 102 | |||
| 103 | case SDL_EVENT_JOYSTICK_BUTTON_DOWN: | ||
| 104 | case SDL_EVENT_JOYSTICK_BUTTON_UP: | ||
| 105 | return SDL_EVENTCATEGORY_JBUTTON; | ||
| 106 | |||
| 107 | case SDL_EVENT_JOYSTICK_ADDED: | ||
| 108 | case SDL_EVENT_JOYSTICK_REMOVED: | ||
| 109 | case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE: | ||
| 110 | return SDL_EVENTCATEGORY_JDEVICE; | ||
| 111 | |||
| 112 | case SDL_EVENT_JOYSTICK_BATTERY_UPDATED: | ||
| 113 | return SDL_EVENTCATEGORY_JBATTERY; | ||
| 114 | |||
| 115 | case SDL_EVENT_GAMEPAD_AXIS_MOTION: | ||
| 116 | return SDL_EVENTCATEGORY_GAXIS; | ||
| 117 | |||
| 118 | case SDL_EVENT_GAMEPAD_BUTTON_DOWN: | ||
| 119 | case SDL_EVENT_GAMEPAD_BUTTON_UP: | ||
| 120 | return SDL_EVENTCATEGORY_GBUTTON; | ||
| 121 | |||
| 122 | case SDL_EVENT_GAMEPAD_ADDED: | ||
| 123 | case SDL_EVENT_GAMEPAD_REMOVED: | ||
| 124 | case SDL_EVENT_GAMEPAD_REMAPPED: | ||
| 125 | case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE: | ||
| 126 | case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED: | ||
| 127 | return SDL_EVENTCATEGORY_GDEVICE; | ||
| 128 | |||
| 129 | case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN: | ||
| 130 | case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION: | ||
| 131 | case SDL_EVENT_GAMEPAD_TOUCHPAD_UP: | ||
| 132 | return SDL_EVENTCATEGORY_GTOUCHPAD; | ||
| 133 | |||
| 134 | case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: | ||
| 135 | return SDL_EVENTCATEGORY_GSENSOR; | ||
| 136 | |||
| 137 | case SDL_EVENT_FINGER_DOWN: | ||
| 138 | case SDL_EVENT_FINGER_UP: | ||
| 139 | case SDL_EVENT_FINGER_CANCELED: | ||
| 140 | case SDL_EVENT_FINGER_MOTION: | ||
| 141 | return SDL_EVENTCATEGORY_TFINGER; | ||
| 142 | |||
| 143 | case SDL_EVENT_CLIPBOARD_UPDATE: | ||
| 144 | return SDL_EVENTCATEGORY_CLIPBOARD; | ||
| 145 | |||
| 146 | case SDL_EVENT_DROP_FILE: | ||
| 147 | case SDL_EVENT_DROP_TEXT: | ||
| 148 | case SDL_EVENT_DROP_BEGIN: | ||
| 149 | case SDL_EVENT_DROP_COMPLETE: | ||
| 150 | case SDL_EVENT_DROP_POSITION: | ||
| 151 | return SDL_EVENTCATEGORY_DROP; | ||
| 152 | |||
| 153 | case SDL_EVENT_AUDIO_DEVICE_ADDED: | ||
| 154 | case SDL_EVENT_AUDIO_DEVICE_REMOVED: | ||
| 155 | case SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED: | ||
| 156 | return SDL_EVENTCATEGORY_ADEVICE; | ||
| 157 | |||
| 158 | case SDL_EVENT_SENSOR_UPDATE: | ||
| 159 | return SDL_EVENTCATEGORY_SENSOR; | ||
| 160 | |||
| 161 | case SDL_EVENT_PEN_PROXIMITY_IN: | ||
| 162 | case SDL_EVENT_PEN_PROXIMITY_OUT: | ||
| 163 | return SDL_EVENTCATEGORY_PPROXIMITY; | ||
| 164 | |||
| 165 | case SDL_EVENT_PEN_DOWN: | ||
| 166 | case SDL_EVENT_PEN_UP: | ||
| 167 | return SDL_EVENTCATEGORY_PTOUCH; | ||
| 168 | |||
| 169 | case SDL_EVENT_PEN_BUTTON_DOWN: | ||
| 170 | case SDL_EVENT_PEN_BUTTON_UP: | ||
| 171 | return SDL_EVENTCATEGORY_PBUTTON; | ||
| 172 | |||
| 173 | case SDL_EVENT_PEN_MOTION: | ||
| 174 | return SDL_EVENTCATEGORY_PMOTION; | ||
| 175 | |||
| 176 | case SDL_EVENT_PEN_AXIS: | ||
| 177 | return SDL_EVENTCATEGORY_PAXIS; | ||
| 178 | |||
| 179 | case SDL_EVENT_CAMERA_DEVICE_ADDED: | ||
| 180 | case SDL_EVENT_CAMERA_DEVICE_REMOVED: | ||
| 181 | case SDL_EVENT_CAMERA_DEVICE_APPROVED: | ||
| 182 | case SDL_EVENT_CAMERA_DEVICE_DENIED: | ||
| 183 | return SDL_EVENTCATEGORY_CDEVICE; | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | SDL_Window *SDL_GetWindowFromEvent(const SDL_Event *event) | ||
| 188 | { | ||
| 189 | SDL_WindowID windowID; | ||
| 190 | |||
| 191 | switch (SDL_GetEventCategory(event->type)) { | ||
| 192 | case SDL_EVENTCATEGORY_USER: | ||
| 193 | windowID = event->user.windowID; | ||
| 194 | break; | ||
| 195 | case SDL_EVENTCATEGORY_WINDOW: | ||
| 196 | windowID = event->window.windowID; | ||
| 197 | break; | ||
| 198 | case SDL_EVENTCATEGORY_KEY: | ||
| 199 | windowID = event->key.windowID; | ||
| 200 | break; | ||
| 201 | case SDL_EVENTCATEGORY_EDIT: | ||
| 202 | windowID = event->edit.windowID; | ||
| 203 | break; | ||
| 204 | case SDL_EVENTCATEGORY_TEXT: | ||
| 205 | windowID = event->text.windowID; | ||
| 206 | break; | ||
| 207 | case SDL_EVENTCATEGORY_EDIT_CANDIDATES: | ||
| 208 | windowID = event->edit_candidates.windowID; | ||
| 209 | break; | ||
| 210 | case SDL_EVENTCATEGORY_MOTION: | ||
| 211 | windowID = event->motion.windowID; | ||
| 212 | break; | ||
| 213 | case SDL_EVENTCATEGORY_BUTTON: | ||
| 214 | windowID = event->button.windowID; | ||
| 215 | break; | ||
| 216 | case SDL_EVENTCATEGORY_WHEEL: | ||
| 217 | windowID = event->wheel.windowID; | ||
| 218 | break; | ||
| 219 | case SDL_EVENTCATEGORY_TFINGER: | ||
| 220 | windowID = event->tfinger.windowID; | ||
| 221 | break; | ||
| 222 | case SDL_EVENTCATEGORY_PPROXIMITY: | ||
| 223 | windowID = event->pproximity.windowID; | ||
| 224 | break; | ||
| 225 | case SDL_EVENTCATEGORY_PTOUCH: | ||
| 226 | windowID = event->ptouch.windowID; | ||
| 227 | break; | ||
| 228 | case SDL_EVENTCATEGORY_PBUTTON: | ||
| 229 | windowID = event->pbutton.windowID; | ||
| 230 | break; | ||
| 231 | case SDL_EVENTCATEGORY_PMOTION: | ||
| 232 | windowID = event->pmotion.windowID; | ||
| 233 | break; | ||
| 234 | case SDL_EVENTCATEGORY_PAXIS: | ||
| 235 | windowID = event->paxis.windowID; | ||
| 236 | break; | ||
| 237 | case SDL_EVENTCATEGORY_DROP: | ||
| 238 | windowID = event->drop.windowID; | ||
| 239 | break; | ||
| 240 | case SDL_EVENTCATEGORY_RENDER: | ||
| 241 | windowID = event->render.windowID; | ||
| 242 | break; | ||
| 243 | default: | ||
| 244 | // < 0 -> invalid event type (error is set by SDL_GetEventCategory) | ||
| 245 | // else -> event has no associated window (not an error) | ||
| 246 | return NULL; | ||
| 247 | } | ||
| 248 | return SDL_GetWindowFromID(windowID); | ||
| 249 | } | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_categories_c.h b/contrib/SDL-3.2.8/src/events/SDL_categories_c.h new file mode 100644 index 0000000..31d926a --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_categories_c.h | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #ifndef SDL_categories_c_h_ | ||
| 24 | #define SDL_categories_c_h_ | ||
| 25 | |||
| 26 | typedef enum SDL_EventCategory | ||
| 27 | { | ||
| 28 | SDL_EVENTCATEGORY_UNKNOWN, | ||
| 29 | SDL_EVENTCATEGORY_SYSTEM, | ||
| 30 | SDL_EVENTCATEGORY_DISPLAY, | ||
| 31 | SDL_EVENTCATEGORY_WINDOW, | ||
| 32 | SDL_EVENTCATEGORY_KDEVICE, | ||
| 33 | SDL_EVENTCATEGORY_KEY, | ||
| 34 | SDL_EVENTCATEGORY_EDIT, | ||
| 35 | SDL_EVENTCATEGORY_EDIT_CANDIDATES, | ||
| 36 | SDL_EVENTCATEGORY_TEXT, | ||
| 37 | SDL_EVENTCATEGORY_MDEVICE, | ||
| 38 | SDL_EVENTCATEGORY_MOTION, | ||
| 39 | SDL_EVENTCATEGORY_BUTTON, | ||
| 40 | SDL_EVENTCATEGORY_WHEEL, | ||
| 41 | SDL_EVENTCATEGORY_JDEVICE, | ||
| 42 | SDL_EVENTCATEGORY_JAXIS, | ||
| 43 | SDL_EVENTCATEGORY_JBALL, | ||
| 44 | SDL_EVENTCATEGORY_JHAT, | ||
| 45 | SDL_EVENTCATEGORY_JBUTTON, | ||
| 46 | SDL_EVENTCATEGORY_JBATTERY, | ||
| 47 | SDL_EVENTCATEGORY_GDEVICE, | ||
| 48 | SDL_EVENTCATEGORY_GAXIS, | ||
| 49 | SDL_EVENTCATEGORY_GBUTTON, | ||
| 50 | SDL_EVENTCATEGORY_GTOUCHPAD, | ||
| 51 | SDL_EVENTCATEGORY_GSENSOR, | ||
| 52 | SDL_EVENTCATEGORY_ADEVICE, | ||
| 53 | SDL_EVENTCATEGORY_CDEVICE, | ||
| 54 | SDL_EVENTCATEGORY_SENSOR, | ||
| 55 | SDL_EVENTCATEGORY_QUIT, | ||
| 56 | SDL_EVENTCATEGORY_USER, | ||
| 57 | SDL_EVENTCATEGORY_TFINGER, | ||
| 58 | SDL_EVENTCATEGORY_PPROXIMITY, | ||
| 59 | SDL_EVENTCATEGORY_PTOUCH, | ||
| 60 | SDL_EVENTCATEGORY_PMOTION, | ||
| 61 | SDL_EVENTCATEGORY_PBUTTON, | ||
| 62 | SDL_EVENTCATEGORY_PAXIS, | ||
| 63 | SDL_EVENTCATEGORY_DROP, | ||
| 64 | SDL_EVENTCATEGORY_CLIPBOARD, | ||
| 65 | SDL_EVENTCATEGORY_RENDER, | ||
| 66 | } SDL_EventCategory; | ||
| 67 | |||
| 68 | extern SDL_EventCategory SDL_GetEventCategory(Uint32 type); | ||
| 69 | |||
| 70 | #endif // SDL_categories_c_h_ | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_clipboardevents.c b/contrib/SDL-3.2.8/src/events/SDL_clipboardevents.c new file mode 100644 index 0000000..d5cf8ad --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_clipboardevents.c | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | // Clipboard event handling code for SDL | ||
| 24 | |||
| 25 | #include "SDL_events_c.h" | ||
| 26 | #include "SDL_clipboardevents_c.h" | ||
| 27 | #include "../video/SDL_clipboard_c.h" | ||
| 28 | |||
| 29 | void SDL_SendClipboardUpdate(bool owner, char **mime_types, size_t num_mime_types) | ||
| 30 | { | ||
| 31 | if (!owner) { | ||
| 32 | /* Clear our internal clipboard contents when external clipboard is set. | ||
| 33 | * | ||
| 34 | * Wayland recursively sends a data offer to the client from which the clipboard data originated, | ||
| 35 | * and as the client can't determine the origin of the offer, the clipboard must not be cleared, | ||
| 36 | * or the original data may be destroyed. Cleanup will be done in the backend when an offer | ||
| 37 | * cancellation event arrives. | ||
| 38 | */ | ||
| 39 | if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") != 0) { | ||
| 40 | SDL_CancelClipboardData(0); | ||
| 41 | } | ||
| 42 | |||
| 43 | SDL_SaveClipboardMimeTypes((const char **)mime_types, num_mime_types); | ||
| 44 | } | ||
| 45 | |||
| 46 | if (SDL_EventEnabled(SDL_EVENT_CLIPBOARD_UPDATE)) { | ||
| 47 | SDL_Event event; | ||
| 48 | event.type = SDL_EVENT_CLIPBOARD_UPDATE; | ||
| 49 | |||
| 50 | SDL_ClipboardEvent *cevent = &event.clipboard; | ||
| 51 | cevent->timestamp = 0; | ||
| 52 | cevent->owner = owner; | ||
| 53 | cevent->mime_types = (const char **)mime_types; | ||
| 54 | cevent->num_mime_types = (Uint32)num_mime_types; | ||
| 55 | SDL_PushEvent(&event); | ||
| 56 | } | ||
| 57 | } | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_clipboardevents_c.h b/contrib/SDL-3.2.8/src/events/SDL_clipboardevents_c.h new file mode 100644 index 0000000..0b0f628 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_clipboardevents_c.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #ifndef SDL_clipboardevents_c_h_ | ||
| 24 | #define SDL_clipboardevents_c_h_ | ||
| 25 | |||
| 26 | extern void SDL_SendClipboardUpdate(bool owner, char **mime_types, size_t num_mime_types); | ||
| 27 | |||
| 28 | #endif // SDL_clipboardevents_c_h_ | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_displayevents.c b/contrib/SDL-3.2.8/src/events/SDL_displayevents.c new file mode 100644 index 0000000..e41f75c --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_displayevents.c | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | // Display event handling code for SDL | ||
| 24 | |||
| 25 | #include "SDL_events_c.h" | ||
| 26 | |||
| 27 | void SDL_SendDisplayEvent(SDL_VideoDisplay *display, SDL_EventType displayevent, int data1, int data2) | ||
| 28 | { | ||
| 29 | if (!display || display->id == 0) { | ||
| 30 | return; | ||
| 31 | } | ||
| 32 | switch (displayevent) { | ||
| 33 | case SDL_EVENT_DISPLAY_ORIENTATION: | ||
| 34 | if (data1 == SDL_ORIENTATION_UNKNOWN || data1 == display->current_orientation) { | ||
| 35 | return; | ||
| 36 | } | ||
| 37 | display->current_orientation = (SDL_DisplayOrientation)data1; | ||
| 38 | break; | ||
| 39 | default: | ||
| 40 | break; | ||
| 41 | } | ||
| 42 | |||
| 43 | // Post the event, if desired | ||
| 44 | if (SDL_EventEnabled(displayevent)) { | ||
| 45 | SDL_Event event; | ||
| 46 | event.type = displayevent; | ||
| 47 | event.common.timestamp = 0; | ||
| 48 | event.display.displayID = display->id; | ||
| 49 | event.display.data1 = data1; | ||
| 50 | event.display.data2 = data2; | ||
| 51 | SDL_PushEvent(&event); | ||
| 52 | } | ||
| 53 | |||
| 54 | switch (displayevent) { | ||
| 55 | case SDL_EVENT_DISPLAY_ADDED: | ||
| 56 | SDL_OnDisplayAdded(display); | ||
| 57 | break; | ||
| 58 | case SDL_EVENT_DISPLAY_MOVED: | ||
| 59 | SDL_OnDisplayMoved(display); | ||
| 60 | break; | ||
| 61 | default: | ||
| 62 | break; | ||
| 63 | } | ||
| 64 | } | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_displayevents_c.h b/contrib/SDL-3.2.8/src/events/SDL_displayevents_c.h new file mode 100644 index 0000000..ae0730c --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_displayevents_c.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #ifndef SDL_displayevents_c_h_ | ||
| 24 | #define SDL_displayevents_c_h_ | ||
| 25 | |||
| 26 | extern void SDL_SendDisplayEvent(SDL_VideoDisplay *display, SDL_EventType displayevent, int data1, int data2); | ||
| 27 | |||
| 28 | #endif // SDL_displayevents_c_h_ | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_dropevents.c b/contrib/SDL-3.2.8/src/events/SDL_dropevents.c new file mode 100644 index 0000000..661f4f3 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_dropevents.c | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | // Drag and drop event handling code for SDL | ||
| 24 | |||
| 25 | #include "SDL_events_c.h" | ||
| 26 | #include "SDL_dropevents_c.h" | ||
| 27 | |||
| 28 | #include "../video/SDL_sysvideo.h" // for SDL_Window internals. | ||
| 29 | |||
| 30 | static bool SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *source, const char *data, float x, float y) | ||
| 31 | { | ||
| 32 | static bool app_is_dropping = false; | ||
| 33 | static float last_drop_x = 0; | ||
| 34 | static float last_drop_y = 0; | ||
| 35 | bool posted = false; | ||
| 36 | |||
| 37 | // Post the event, if desired | ||
| 38 | if (SDL_EventEnabled(evtype)) { | ||
| 39 | const bool need_begin = window ? !window->is_dropping : !app_is_dropping; | ||
| 40 | SDL_Event event; | ||
| 41 | |||
| 42 | if (need_begin) { | ||
| 43 | SDL_zero(event); | ||
| 44 | event.type = SDL_EVENT_DROP_BEGIN; | ||
| 45 | event.common.timestamp = 0; | ||
| 46 | event.drop.windowID = window ? window->id : 0; | ||
| 47 | posted = SDL_PushEvent(&event); | ||
| 48 | if (!posted) { | ||
| 49 | return false; | ||
| 50 | } | ||
| 51 | if (window) { | ||
| 52 | window->is_dropping = true; | ||
| 53 | } else { | ||
| 54 | app_is_dropping = true; | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | SDL_zero(event); | ||
| 59 | event.type = evtype; | ||
| 60 | event.common.timestamp = 0; | ||
| 61 | if (source) { | ||
| 62 | event.drop.source = SDL_CreateTemporaryString(source); | ||
| 63 | if (!event.drop.source) { | ||
| 64 | return false; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | if (data) { | ||
| 68 | event.drop.data = SDL_CreateTemporaryString(data); | ||
| 69 | if (!event.drop.data) { | ||
| 70 | return false; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | event.drop.windowID = window ? window->id : 0; | ||
| 74 | |||
| 75 | if (evtype == SDL_EVENT_DROP_POSITION) { | ||
| 76 | last_drop_x = x; | ||
| 77 | last_drop_y = y; | ||
| 78 | } | ||
| 79 | event.drop.x = last_drop_x; | ||
| 80 | event.drop.y = last_drop_y; | ||
| 81 | posted = SDL_PushEvent(&event); | ||
| 82 | |||
| 83 | if (posted && (evtype == SDL_EVENT_DROP_COMPLETE)) { | ||
| 84 | if (window) { | ||
| 85 | window->is_dropping = false; | ||
| 86 | } else { | ||
| 87 | app_is_dropping = false; | ||
| 88 | } | ||
| 89 | |||
| 90 | last_drop_x = 0; | ||
| 91 | last_drop_y = 0; | ||
| 92 | } | ||
| 93 | } | ||
| 94 | return posted; | ||
| 95 | } | ||
| 96 | |||
| 97 | bool SDL_SendDropFile(SDL_Window *window, const char *source, const char *file) | ||
| 98 | { | ||
| 99 | return SDL_SendDrop(window, SDL_EVENT_DROP_FILE, source, file, 0, 0); | ||
| 100 | } | ||
| 101 | |||
| 102 | bool SDL_SendDropPosition(SDL_Window *window, float x, float y) | ||
| 103 | { | ||
| 104 | return SDL_SendDrop(window, SDL_EVENT_DROP_POSITION, NULL, NULL, x, y); | ||
| 105 | } | ||
| 106 | |||
| 107 | bool SDL_SendDropText(SDL_Window *window, const char *text) | ||
| 108 | { | ||
| 109 | return SDL_SendDrop(window, SDL_EVENT_DROP_TEXT, NULL, text, 0, 0); | ||
| 110 | } | ||
| 111 | |||
| 112 | bool SDL_SendDropComplete(SDL_Window *window) | ||
| 113 | { | ||
| 114 | return SDL_SendDrop(window, SDL_EVENT_DROP_COMPLETE, NULL, NULL, 0, 0); | ||
| 115 | } | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_dropevents_c.h b/contrib/SDL-3.2.8/src/events/SDL_dropevents_c.h new file mode 100644 index 0000000..efce0ac --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_dropevents_c.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #ifndef SDL_dropevents_c_h_ | ||
| 24 | #define SDL_dropevents_c_h_ | ||
| 25 | |||
| 26 | extern bool SDL_SendDropFile(SDL_Window *window, const char *source, const char *file); | ||
| 27 | extern bool SDL_SendDropPosition(SDL_Window *window, float x, float y); | ||
| 28 | extern bool SDL_SendDropText(SDL_Window *window, const char *text); | ||
| 29 | extern bool SDL_SendDropComplete(SDL_Window *window); | ||
| 30 | |||
| 31 | #endif // SDL_dropevents_c_h_ | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_events.c b/contrib/SDL-3.2.8/src/events/SDL_events.c new file mode 100644 index 0000000..349d575 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_events.c | |||
| @@ -0,0 +1,1987 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | // General event handling code for SDL | ||
| 24 | |||
| 25 | #include "SDL_events_c.h" | ||
| 26 | #include "SDL_eventwatch_c.h" | ||
| 27 | #include "SDL_windowevents_c.h" | ||
| 28 | #include "../SDL_hints_c.h" | ||
| 29 | #include "../audio/SDL_audio_c.h" | ||
| 30 | #include "../camera/SDL_camera_c.h" | ||
| 31 | #include "../timer/SDL_timer_c.h" | ||
| 32 | #ifndef SDL_JOYSTICK_DISABLED | ||
| 33 | #include "../joystick/SDL_joystick_c.h" | ||
| 34 | #endif | ||
| 35 | #ifndef SDL_SENSOR_DISABLED | ||
| 36 | #include "../sensor/SDL_sensor_c.h" | ||
| 37 | #endif | ||
| 38 | #include "../video/SDL_sysvideo.h" | ||
| 39 | |||
| 40 | #ifdef SDL_PLATFORM_ANDROID | ||
| 41 | #include "../core/android/SDL_android.h" | ||
| 42 | #include "../video/android/SDL_androidevents.h" | ||
| 43 | #endif | ||
| 44 | |||
| 45 | // An arbitrary limit so we don't have unbounded growth | ||
| 46 | #define SDL_MAX_QUEUED_EVENTS 65535 | ||
| 47 | |||
| 48 | // Determines how often we pump events if joystick or sensor subsystems are active | ||
| 49 | #define ENUMERATION_POLL_INTERVAL_NS (3 * SDL_NS_PER_SECOND) | ||
| 50 | |||
| 51 | // Determines how often to pump events if joysticks or sensors are actively being read | ||
| 52 | #define EVENT_POLL_INTERVAL_NS SDL_MS_TO_NS(1) | ||
| 53 | |||
| 54 | // Make sure the type in the SDL_Event aligns properly across the union | ||
| 55 | SDL_COMPILE_TIME_ASSERT(SDL_Event_type, sizeof(Uint32) == sizeof(SDL_EventType)); | ||
| 56 | |||
| 57 | #define SDL2_SYSWMEVENT 0x201 | ||
| 58 | |||
| 59 | #ifdef SDL_VIDEO_DRIVER_WINDOWS | ||
| 60 | #include "../core/windows/SDL_windows.h" | ||
| 61 | #endif | ||
| 62 | |||
| 63 | #ifdef SDL_VIDEO_DRIVER_X11 | ||
| 64 | #include <X11/Xlib.h> | ||
| 65 | #endif | ||
| 66 | |||
| 67 | typedef struct SDL2_version | ||
| 68 | { | ||
| 69 | Uint8 major; | ||
| 70 | Uint8 minor; | ||
| 71 | Uint8 patch; | ||
| 72 | } SDL2_version; | ||
| 73 | |||
| 74 | typedef enum | ||
| 75 | { | ||
| 76 | SDL2_SYSWM_UNKNOWN | ||
| 77 | } SDL2_SYSWM_TYPE; | ||
| 78 | |||
| 79 | typedef struct SDL2_SysWMmsg | ||
| 80 | { | ||
| 81 | SDL2_version version; | ||
| 82 | SDL2_SYSWM_TYPE subsystem; | ||
| 83 | union | ||
| 84 | { | ||
| 85 | #ifdef SDL_VIDEO_DRIVER_WINDOWS | ||
| 86 | struct { | ||
| 87 | HWND hwnd; /**< The window for the message */ | ||
| 88 | UINT msg; /**< The type of message */ | ||
| 89 | WPARAM wParam; /**< WORD message parameter */ | ||
| 90 | LPARAM lParam; /**< LONG message parameter */ | ||
| 91 | } win; | ||
| 92 | #endif | ||
| 93 | #ifdef SDL_VIDEO_DRIVER_X11 | ||
| 94 | struct { | ||
| 95 | XEvent event; | ||
| 96 | } x11; | ||
| 97 | #endif | ||
| 98 | /* Can't have an empty union */ | ||
| 99 | int dummy; | ||
| 100 | } msg; | ||
| 101 | } SDL2_SysWMmsg; | ||
| 102 | |||
| 103 | static SDL_EventWatchList SDL_event_watchers; | ||
| 104 | static SDL_AtomicInt SDL_sentinel_pending; | ||
| 105 | static Uint32 SDL_last_event_id = 0; | ||
| 106 | |||
| 107 | typedef struct | ||
| 108 | { | ||
| 109 | Uint32 bits[8]; | ||
| 110 | } SDL_DisabledEventBlock; | ||
| 111 | |||
| 112 | static SDL_DisabledEventBlock *SDL_disabled_events[256]; | ||
| 113 | static SDL_AtomicInt SDL_userevents; | ||
| 114 | |||
| 115 | typedef struct SDL_TemporaryMemory | ||
| 116 | { | ||
| 117 | void *memory; | ||
| 118 | struct SDL_TemporaryMemory *prev; | ||
| 119 | struct SDL_TemporaryMemory *next; | ||
| 120 | } SDL_TemporaryMemory; | ||
| 121 | |||
| 122 | typedef struct SDL_TemporaryMemoryState | ||
| 123 | { | ||
| 124 | SDL_TemporaryMemory *head; | ||
| 125 | SDL_TemporaryMemory *tail; | ||
| 126 | } SDL_TemporaryMemoryState; | ||
| 127 | |||
| 128 | static SDL_TLSID SDL_temporary_memory; | ||
| 129 | |||
| 130 | typedef struct SDL_EventEntry | ||
| 131 | { | ||
| 132 | SDL_Event event; | ||
| 133 | SDL_TemporaryMemory *memory; | ||
| 134 | struct SDL_EventEntry *prev; | ||
| 135 | struct SDL_EventEntry *next; | ||
| 136 | } SDL_EventEntry; | ||
| 137 | |||
| 138 | static struct | ||
| 139 | { | ||
| 140 | SDL_Mutex *lock; | ||
| 141 | bool active; | ||
| 142 | SDL_AtomicInt count; | ||
| 143 | int max_events_seen; | ||
| 144 | SDL_EventEntry *head; | ||
| 145 | SDL_EventEntry *tail; | ||
| 146 | SDL_EventEntry *free; | ||
| 147 | } SDL_EventQ = { NULL, false, { 0 }, 0, NULL, NULL, NULL }; | ||
| 148 | |||
| 149 | |||
| 150 | static void SDL_CleanupTemporaryMemory(void *data) | ||
| 151 | { | ||
| 152 | SDL_TemporaryMemoryState *state = (SDL_TemporaryMemoryState *)data; | ||
| 153 | |||
| 154 | SDL_FreeTemporaryMemory(); | ||
| 155 | SDL_free(state); | ||
| 156 | } | ||
| 157 | |||
| 158 | static SDL_TemporaryMemoryState *SDL_GetTemporaryMemoryState(bool create) | ||
| 159 | { | ||
| 160 | SDL_TemporaryMemoryState *state; | ||
| 161 | |||
| 162 | state = (SDL_TemporaryMemoryState *)SDL_GetTLS(&SDL_temporary_memory); | ||
| 163 | if (!state) { | ||
| 164 | if (!create) { | ||
| 165 | return NULL; | ||
| 166 | } | ||
| 167 | |||
| 168 | state = (SDL_TemporaryMemoryState *)SDL_calloc(1, sizeof(*state)); | ||
| 169 | if (!state) { | ||
| 170 | return NULL; | ||
| 171 | } | ||
| 172 | |||
| 173 | if (!SDL_SetTLS(&SDL_temporary_memory, state, SDL_CleanupTemporaryMemory)) { | ||
| 174 | SDL_free(state); | ||
| 175 | return NULL; | ||
| 176 | } | ||
| 177 | } | ||
| 178 | return state; | ||
| 179 | } | ||
| 180 | |||
| 181 | static SDL_TemporaryMemory *SDL_GetTemporaryMemoryEntry(SDL_TemporaryMemoryState *state, const void *mem) | ||
| 182 | { | ||
| 183 | SDL_TemporaryMemory *entry; | ||
| 184 | |||
| 185 | // Start from the end, it's likely to have been recently allocated | ||
| 186 | for (entry = state->tail; entry; entry = entry->prev) { | ||
| 187 | if (mem == entry->memory) { | ||
| 188 | return entry; | ||
| 189 | } | ||
| 190 | } | ||
| 191 | return NULL; | ||
| 192 | } | ||
| 193 | |||
| 194 | static void SDL_LinkTemporaryMemoryEntry(SDL_TemporaryMemoryState *state, SDL_TemporaryMemory *entry) | ||
| 195 | { | ||
| 196 | entry->prev = state->tail; | ||
| 197 | entry->next = NULL; | ||
| 198 | |||
| 199 | if (state->tail) { | ||
| 200 | state->tail->next = entry; | ||
| 201 | } else { | ||
| 202 | state->head = entry; | ||
| 203 | } | ||
| 204 | state->tail = entry; | ||
| 205 | } | ||
| 206 | |||
| 207 | static void SDL_UnlinkTemporaryMemoryEntry(SDL_TemporaryMemoryState *state, SDL_TemporaryMemory *entry) | ||
| 208 | { | ||
| 209 | if (state->head == entry) { | ||
| 210 | state->head = entry->next; | ||
| 211 | } | ||
| 212 | if (state->tail == entry) { | ||
| 213 | state->tail = entry->prev; | ||
| 214 | } | ||
| 215 | |||
| 216 | if (entry->prev) { | ||
| 217 | entry->prev->next = entry->next; | ||
| 218 | } | ||
| 219 | if (entry->next) { | ||
| 220 | entry->next->prev = entry->prev; | ||
| 221 | } | ||
| 222 | |||
| 223 | entry->prev = NULL; | ||
| 224 | entry->next = NULL; | ||
| 225 | } | ||
| 226 | |||
| 227 | static void SDL_FreeTemporaryMemoryEntry(SDL_TemporaryMemoryState *state, SDL_TemporaryMemory *entry, bool free_data) | ||
| 228 | { | ||
| 229 | if (free_data) { | ||
| 230 | SDL_free(entry->memory); | ||
| 231 | } | ||
| 232 | SDL_free(entry); | ||
| 233 | } | ||
| 234 | |||
| 235 | static void SDL_LinkTemporaryMemoryToEvent(SDL_EventEntry *event, const void *mem) | ||
| 236 | { | ||
| 237 | SDL_TemporaryMemoryState *state; | ||
| 238 | SDL_TemporaryMemory *entry; | ||
| 239 | |||
| 240 | state = SDL_GetTemporaryMemoryState(false); | ||
| 241 | if (!state) { | ||
| 242 | return; | ||
| 243 | } | ||
| 244 | |||
| 245 | entry = SDL_GetTemporaryMemoryEntry(state, mem); | ||
| 246 | if (entry) { | ||
| 247 | SDL_UnlinkTemporaryMemoryEntry(state, entry); | ||
| 248 | entry->next = event->memory; | ||
| 249 | event->memory = entry; | ||
| 250 | } | ||
| 251 | } | ||
| 252 | |||
| 253 | static void SDL_TransferSysWMMemoryToEvent(SDL_EventEntry *event) | ||
| 254 | { | ||
| 255 | SDL2_SysWMmsg **wmmsg = (SDL2_SysWMmsg **)((&event->event.common)+1); | ||
| 256 | SDL2_SysWMmsg *mem = SDL_AllocateTemporaryMemory(sizeof(*mem)); | ||
| 257 | if (mem) { | ||
| 258 | SDL_copyp(mem, *wmmsg); | ||
| 259 | *wmmsg = mem; | ||
| 260 | SDL_LinkTemporaryMemoryToEvent(event, mem); | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | // Transfer the event memory from the thread-local event memory list to the event | ||
| 265 | static void SDL_TransferTemporaryMemoryToEvent(SDL_EventEntry *event) | ||
| 266 | { | ||
| 267 | switch (event->event.type) { | ||
| 268 | case SDL_EVENT_TEXT_EDITING: | ||
| 269 | SDL_LinkTemporaryMemoryToEvent(event, event->event.edit.text); | ||
| 270 | break; | ||
| 271 | case SDL_EVENT_TEXT_EDITING_CANDIDATES: | ||
| 272 | SDL_LinkTemporaryMemoryToEvent(event, event->event.edit_candidates.candidates); | ||
| 273 | break; | ||
| 274 | case SDL_EVENT_TEXT_INPUT: | ||
| 275 | SDL_LinkTemporaryMemoryToEvent(event, event->event.text.text); | ||
| 276 | break; | ||
| 277 | case SDL_EVENT_DROP_BEGIN: | ||
| 278 | case SDL_EVENT_DROP_FILE: | ||
| 279 | case SDL_EVENT_DROP_TEXT: | ||
| 280 | case SDL_EVENT_DROP_COMPLETE: | ||
| 281 | case SDL_EVENT_DROP_POSITION: | ||
| 282 | SDL_LinkTemporaryMemoryToEvent(event, event->event.drop.source); | ||
| 283 | SDL_LinkTemporaryMemoryToEvent(event, event->event.drop.data); | ||
| 284 | break; | ||
| 285 | case SDL_EVENT_CLIPBOARD_UPDATE: | ||
| 286 | SDL_LinkTemporaryMemoryToEvent(event, event->event.clipboard.mime_types); | ||
| 287 | break; | ||
| 288 | case SDL2_SYSWMEVENT: | ||
| 289 | // We need to copy the stack pointer into temporary memory | ||
| 290 | SDL_TransferSysWMMemoryToEvent(event); | ||
| 291 | break; | ||
| 292 | default: | ||
| 293 | break; | ||
| 294 | } | ||
| 295 | } | ||
| 296 | |||
| 297 | // Transfer the event memory from the event to the thread-local event memory list | ||
| 298 | static void SDL_TransferTemporaryMemoryFromEvent(SDL_EventEntry *event) | ||
| 299 | { | ||
| 300 | SDL_TemporaryMemoryState *state; | ||
| 301 | SDL_TemporaryMemory *entry, *next; | ||
| 302 | |||
| 303 | if (!event->memory) { | ||
| 304 | return; | ||
| 305 | } | ||
| 306 | |||
| 307 | state = SDL_GetTemporaryMemoryState(true); | ||
| 308 | if (!state) { | ||
| 309 | return; // this is now a leak, but you probably have bigger problems if malloc failed. | ||
| 310 | } | ||
| 311 | |||
| 312 | for (entry = event->memory; entry; entry = next) { | ||
| 313 | next = entry->next; | ||
| 314 | SDL_LinkTemporaryMemoryEntry(state, entry); | ||
| 315 | } | ||
| 316 | event->memory = NULL; | ||
| 317 | } | ||
| 318 | |||
| 319 | static void *SDL_FreeLater(void *memory) | ||
| 320 | { | ||
| 321 | SDL_TemporaryMemoryState *state; | ||
| 322 | |||
| 323 | if (memory == NULL) { | ||
| 324 | return NULL; | ||
| 325 | } | ||
| 326 | |||
| 327 | // Make sure we're not adding this to the list twice | ||
| 328 | //SDL_assert(!SDL_ClaimTemporaryMemory(memory)); | ||
| 329 | |||
| 330 | state = SDL_GetTemporaryMemoryState(true); | ||
| 331 | if (!state) { | ||
| 332 | return memory; // this is now a leak, but you probably have bigger problems if malloc failed. | ||
| 333 | } | ||
| 334 | |||
| 335 | SDL_TemporaryMemory *entry = (SDL_TemporaryMemory *)SDL_malloc(sizeof(*entry)); | ||
| 336 | if (!entry) { | ||
| 337 | return memory; // this is now a leak, but you probably have bigger problems if malloc failed. We could probably pool up and reuse entries, though. | ||
| 338 | } | ||
| 339 | |||
| 340 | entry->memory = memory; | ||
| 341 | |||
| 342 | SDL_LinkTemporaryMemoryEntry(state, entry); | ||
| 343 | |||
| 344 | return memory; | ||
| 345 | } | ||
| 346 | |||
| 347 | void *SDL_AllocateTemporaryMemory(size_t size) | ||
| 348 | { | ||
| 349 | return SDL_FreeLater(SDL_malloc(size)); | ||
| 350 | } | ||
| 351 | |||
| 352 | const char *SDL_CreateTemporaryString(const char *string) | ||
| 353 | { | ||
| 354 | if (string) { | ||
| 355 | return (const char *)SDL_FreeLater(SDL_strdup(string)); | ||
| 356 | } | ||
| 357 | return NULL; | ||
| 358 | } | ||
| 359 | |||
| 360 | void *SDL_ClaimTemporaryMemory(const void *mem) | ||
| 361 | { | ||
| 362 | SDL_TemporaryMemoryState *state; | ||
| 363 | |||
| 364 | state = SDL_GetTemporaryMemoryState(false); | ||
| 365 | if (state && mem) { | ||
| 366 | SDL_TemporaryMemory *entry = SDL_GetTemporaryMemoryEntry(state, mem); | ||
| 367 | if (entry) { | ||
| 368 | SDL_UnlinkTemporaryMemoryEntry(state, entry); | ||
| 369 | SDL_FreeTemporaryMemoryEntry(state, entry, false); | ||
| 370 | return (void *)mem; | ||
| 371 | } | ||
| 372 | } | ||
| 373 | return NULL; | ||
| 374 | } | ||
| 375 | |||
| 376 | void SDL_FreeTemporaryMemory(void) | ||
| 377 | { | ||
| 378 | SDL_TemporaryMemoryState *state; | ||
| 379 | |||
| 380 | state = SDL_GetTemporaryMemoryState(false); | ||
| 381 | if (!state) { | ||
| 382 | return; | ||
| 383 | } | ||
| 384 | |||
| 385 | while (state->head) { | ||
| 386 | SDL_TemporaryMemory *entry = state->head; | ||
| 387 | |||
| 388 | SDL_UnlinkTemporaryMemoryEntry(state, entry); | ||
| 389 | SDL_FreeTemporaryMemoryEntry(state, entry, true); | ||
| 390 | } | ||
| 391 | } | ||
| 392 | |||
| 393 | #ifndef SDL_JOYSTICK_DISABLED | ||
| 394 | |||
| 395 | static bool SDL_update_joysticks = true; | ||
| 396 | |||
| 397 | static void SDLCALL SDL_AutoUpdateJoysticksChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 398 | { | ||
| 399 | SDL_update_joysticks = SDL_GetStringBoolean(hint, true); | ||
| 400 | } | ||
| 401 | |||
| 402 | #endif // !SDL_JOYSTICK_DISABLED | ||
| 403 | |||
| 404 | #ifndef SDL_SENSOR_DISABLED | ||
| 405 | |||
| 406 | static bool SDL_update_sensors = true; | ||
| 407 | |||
| 408 | static void SDLCALL SDL_AutoUpdateSensorsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 409 | { | ||
| 410 | SDL_update_sensors = SDL_GetStringBoolean(hint, true); | ||
| 411 | } | ||
| 412 | |||
| 413 | #endif // !SDL_SENSOR_DISABLED | ||
| 414 | |||
| 415 | static void SDLCALL SDL_PollSentinelChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 416 | { | ||
| 417 | SDL_SetEventEnabled(SDL_EVENT_POLL_SENTINEL, SDL_GetStringBoolean(hint, true)); | ||
| 418 | } | ||
| 419 | |||
| 420 | /** | ||
| 421 | * Verbosity of logged events as defined in SDL_HINT_EVENT_LOGGING: | ||
| 422 | * - 0: (default) no logging | ||
| 423 | * - 1: logging of most events | ||
| 424 | * - 2: as above, plus mouse, pen, and finger motion | ||
| 425 | */ | ||
| 426 | static int SDL_EventLoggingVerbosity = 0; | ||
| 427 | |||
| 428 | static void SDLCALL SDL_EventLoggingChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 429 | { | ||
| 430 | SDL_EventLoggingVerbosity = (hint && *hint) ? SDL_clamp(SDL_atoi(hint), 0, 3) : 0; | ||
| 431 | } | ||
| 432 | |||
| 433 | static void SDL_LogEvent(const SDL_Event *event) | ||
| 434 | { | ||
| 435 | static const char *pen_axisnames[] = { "PRESSURE", "XTILT", "YTILT", "DISTANCE", "ROTATION", "SLIDER", "TANGENTIAL_PRESSURE" }; | ||
| 436 | SDL_COMPILE_TIME_ASSERT(pen_axisnames_array_matches, SDL_arraysize(pen_axisnames) == SDL_PEN_AXIS_COUNT); | ||
| 437 | |||
| 438 | char name[64]; | ||
| 439 | char details[128]; | ||
| 440 | |||
| 441 | // sensor/mouse/pen/finger motion are spammy, ignore these if they aren't demanded. | ||
| 442 | if ((SDL_EventLoggingVerbosity < 2) && | ||
| 443 | ((event->type == SDL_EVENT_MOUSE_MOTION) || | ||
| 444 | (event->type == SDL_EVENT_FINGER_MOTION) || | ||
| 445 | (event->type == SDL_EVENT_PEN_AXIS) || | ||
| 446 | (event->type == SDL_EVENT_PEN_MOTION) || | ||
| 447 | (event->type == SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION) || | ||
| 448 | (event->type == SDL_EVENT_GAMEPAD_SENSOR_UPDATE) || | ||
| 449 | (event->type == SDL_EVENT_SENSOR_UPDATE))) { | ||
| 450 | return; | ||
| 451 | } | ||
| 452 | |||
| 453 | // this is to make (void)SDL_snprintf() calls cleaner. | ||
| 454 | #define uint unsigned int | ||
| 455 | |||
| 456 | name[0] = '\0'; | ||
| 457 | details[0] = '\0'; | ||
| 458 | |||
| 459 | // !!! FIXME: This code is kinda ugly, sorry. | ||
| 460 | |||
| 461 | if ((event->type >= SDL_EVENT_USER) && (event->type <= SDL_EVENT_LAST)) { | ||
| 462 | char plusstr[16]; | ||
| 463 | SDL_strlcpy(name, "SDL_EVENT_USER", sizeof(name)); | ||
| 464 | if (event->type > SDL_EVENT_USER) { | ||
| 465 | (void)SDL_snprintf(plusstr, sizeof(plusstr), "+%u", ((uint)event->type) - SDL_EVENT_USER); | ||
| 466 | } else { | ||
| 467 | plusstr[0] = '\0'; | ||
| 468 | } | ||
| 469 | (void)SDL_snprintf(details, sizeof(details), "%s (timestamp=%u windowid=%u code=%d data1=%p data2=%p)", | ||
| 470 | plusstr, (uint)event->user.timestamp, (uint)event->user.windowID, | ||
| 471 | (int)event->user.code, event->user.data1, event->user.data2); | ||
| 472 | } | ||
| 473 | |||
| 474 | switch (event->type) { | ||
| 475 | #define SDL_EVENT_CASE(x) \ | ||
| 476 | case x: \ | ||
| 477 | SDL_strlcpy(name, #x, sizeof(name)); | ||
| 478 | SDL_EVENT_CASE(SDL_EVENT_FIRST) | ||
| 479 | SDL_strlcpy(details, " (THIS IS PROBABLY A BUG!)", sizeof(details)); | ||
| 480 | break; | ||
| 481 | SDL_EVENT_CASE(SDL_EVENT_QUIT) | ||
| 482 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u)", (uint)event->quit.timestamp); | ||
| 483 | break; | ||
| 484 | SDL_EVENT_CASE(SDL_EVENT_TERMINATING) | ||
| 485 | break; | ||
| 486 | SDL_EVENT_CASE(SDL_EVENT_LOW_MEMORY) | ||
| 487 | break; | ||
| 488 | SDL_EVENT_CASE(SDL_EVENT_WILL_ENTER_BACKGROUND) | ||
| 489 | break; | ||
| 490 | SDL_EVENT_CASE(SDL_EVENT_DID_ENTER_BACKGROUND) | ||
| 491 | break; | ||
| 492 | SDL_EVENT_CASE(SDL_EVENT_WILL_ENTER_FOREGROUND) | ||
| 493 | break; | ||
| 494 | SDL_EVENT_CASE(SDL_EVENT_DID_ENTER_FOREGROUND) | ||
| 495 | break; | ||
| 496 | SDL_EVENT_CASE(SDL_EVENT_LOCALE_CHANGED) | ||
| 497 | break; | ||
| 498 | SDL_EVENT_CASE(SDL_EVENT_SYSTEM_THEME_CHANGED) | ||
| 499 | break; | ||
| 500 | SDL_EVENT_CASE(SDL_EVENT_KEYMAP_CHANGED) | ||
| 501 | break; | ||
| 502 | SDL_EVENT_CASE(SDL_EVENT_CLIPBOARD_UPDATE) | ||
| 503 | break; | ||
| 504 | |||
| 505 | #define SDL_RENDEREVENT_CASE(x) \ | ||
| 506 | case x: \ | ||
| 507 | SDL_strlcpy(name, #x, sizeof(name)); \ | ||
| 508 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u event=%s windowid=%u)", \ | ||
| 509 | (uint)event->display.timestamp, name, (uint)event->render.windowID); \ | ||
| 510 | break | ||
| 511 | SDL_RENDEREVENT_CASE(SDL_EVENT_RENDER_TARGETS_RESET); | ||
| 512 | SDL_RENDEREVENT_CASE(SDL_EVENT_RENDER_DEVICE_RESET); | ||
| 513 | SDL_RENDEREVENT_CASE(SDL_EVENT_RENDER_DEVICE_LOST); | ||
| 514 | |||
| 515 | #define SDL_DISPLAYEVENT_CASE(x) \ | ||
| 516 | case x: \ | ||
| 517 | SDL_strlcpy(name, #x, sizeof(name)); \ | ||
| 518 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u display=%u event=%s data1=%d, data2=%d)", \ | ||
| 519 | (uint)event->display.timestamp, (uint)event->display.displayID, name, (int)event->display.data1, (int)event->display.data2); \ | ||
| 520 | break | ||
| 521 | SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_ORIENTATION); | ||
| 522 | SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_ADDED); | ||
| 523 | SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_REMOVED); | ||
| 524 | SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_MOVED); | ||
| 525 | SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED); | ||
| 526 | SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED); | ||
| 527 | SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED); | ||
| 528 | #undef SDL_DISPLAYEVENT_CASE | ||
| 529 | |||
| 530 | #define SDL_WINDOWEVENT_CASE(x) \ | ||
| 531 | case x: \ | ||
| 532 | SDL_strlcpy(name, #x, sizeof(name)); \ | ||
| 533 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u event=%s data1=%d data2=%d)", \ | ||
| 534 | (uint)event->window.timestamp, (uint)event->window.windowID, name, (int)event->window.data1, (int)event->window.data2); \ | ||
| 535 | break | ||
| 536 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_SHOWN); | ||
| 537 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_HIDDEN); | ||
| 538 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_EXPOSED); | ||
| 539 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_MOVED); | ||
| 540 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_RESIZED); | ||
| 541 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED); | ||
| 542 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_METAL_VIEW_RESIZED); | ||
| 543 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_SAFE_AREA_CHANGED); | ||
| 544 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_MINIMIZED); | ||
| 545 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_MAXIMIZED); | ||
| 546 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_RESTORED); | ||
| 547 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_MOUSE_ENTER); | ||
| 548 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_MOUSE_LEAVE); | ||
| 549 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_FOCUS_GAINED); | ||
| 550 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_FOCUS_LOST); | ||
| 551 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_CLOSE_REQUESTED); | ||
| 552 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_HIT_TEST); | ||
| 553 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_ICCPROF_CHANGED); | ||
| 554 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_DISPLAY_CHANGED); | ||
| 555 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED); | ||
| 556 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_OCCLUDED); | ||
| 557 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_ENTER_FULLSCREEN); | ||
| 558 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_LEAVE_FULLSCREEN); | ||
| 559 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_DESTROYED); | ||
| 560 | SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_HDR_STATE_CHANGED); | ||
| 561 | #undef SDL_WINDOWEVENT_CASE | ||
| 562 | |||
| 563 | #define PRINT_KEYDEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u)", (uint)event->kdevice.timestamp, (uint)event->kdevice.which) | ||
| 564 | SDL_EVENT_CASE(SDL_EVENT_KEYBOARD_ADDED) | ||
| 565 | PRINT_KEYDEV_EVENT(event); | ||
| 566 | break; | ||
| 567 | SDL_EVENT_CASE(SDL_EVENT_KEYBOARD_REMOVED) | ||
| 568 | PRINT_KEYDEV_EVENT(event); | ||
| 569 | break; | ||
| 570 | #undef PRINT_KEYDEV_EVENT | ||
| 571 | |||
| 572 | #define PRINT_KEY_EVENT(event) \ | ||
| 573 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u state=%s repeat=%s scancode=%u keycode=%u mod=0x%x)", \ | ||
| 574 | (uint)event->key.timestamp, (uint)event->key.windowID, (uint)event->key.which, \ | ||
| 575 | event->key.down ? "pressed" : "released", \ | ||
| 576 | event->key.repeat ? "true" : "false", \ | ||
| 577 | (uint)event->key.scancode, \ | ||
| 578 | (uint)event->key.key, \ | ||
| 579 | (uint)event->key.mod) | ||
| 580 | SDL_EVENT_CASE(SDL_EVENT_KEY_DOWN) | ||
| 581 | PRINT_KEY_EVENT(event); | ||
| 582 | break; | ||
| 583 | SDL_EVENT_CASE(SDL_EVENT_KEY_UP) | ||
| 584 | PRINT_KEY_EVENT(event); | ||
| 585 | break; | ||
| 586 | #undef PRINT_KEY_EVENT | ||
| 587 | |||
| 588 | SDL_EVENT_CASE(SDL_EVENT_TEXT_EDITING) | ||
| 589 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u text='%s' start=%d length=%d)", | ||
| 590 | (uint)event->edit.timestamp, (uint)event->edit.windowID, | ||
| 591 | event->edit.text, (int)event->edit.start, (int)event->edit.length); | ||
| 592 | break; | ||
| 593 | |||
| 594 | SDL_EVENT_CASE(SDL_EVENT_TEXT_EDITING_CANDIDATES) | ||
| 595 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u num_candidates=%d selected_candidate=%d)", | ||
| 596 | (uint)event->edit_candidates.timestamp, (uint)event->edit_candidates.windowID, | ||
| 597 | (int)event->edit_candidates.num_candidates, (int)event->edit_candidates.selected_candidate); | ||
| 598 | break; | ||
| 599 | |||
| 600 | SDL_EVENT_CASE(SDL_EVENT_TEXT_INPUT) | ||
| 601 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u text='%s')", (uint)event->text.timestamp, (uint)event->text.windowID, event->text.text); | ||
| 602 | break; | ||
| 603 | |||
| 604 | #define PRINT_MOUSEDEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u)", (uint)event->mdevice.timestamp, (uint)event->mdevice.which) | ||
| 605 | SDL_EVENT_CASE(SDL_EVENT_MOUSE_ADDED) | ||
| 606 | PRINT_MOUSEDEV_EVENT(event); | ||
| 607 | break; | ||
| 608 | SDL_EVENT_CASE(SDL_EVENT_MOUSE_REMOVED) | ||
| 609 | PRINT_MOUSEDEV_EVENT(event); | ||
| 610 | break; | ||
| 611 | #undef PRINT_MOUSEDEV_EVENT | ||
| 612 | |||
| 613 | SDL_EVENT_CASE(SDL_EVENT_MOUSE_MOTION) | ||
| 614 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u state=%u x=%g y=%g xrel=%g yrel=%g)", | ||
| 615 | (uint)event->motion.timestamp, (uint)event->motion.windowID, | ||
| 616 | (uint)event->motion.which, (uint)event->motion.state, | ||
| 617 | event->motion.x, event->motion.y, | ||
| 618 | event->motion.xrel, event->motion.yrel); | ||
| 619 | break; | ||
| 620 | |||
| 621 | #define PRINT_MBUTTON_EVENT(event) \ | ||
| 622 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u button=%u state=%s clicks=%u x=%g y=%g)", \ | ||
| 623 | (uint)event->button.timestamp, (uint)event->button.windowID, \ | ||
| 624 | (uint)event->button.which, (uint)event->button.button, \ | ||
| 625 | event->button.down ? "pressed" : "released", \ | ||
| 626 | (uint)event->button.clicks, event->button.x, event->button.y) | ||
| 627 | SDL_EVENT_CASE(SDL_EVENT_MOUSE_BUTTON_DOWN) | ||
| 628 | PRINT_MBUTTON_EVENT(event); | ||
| 629 | break; | ||
| 630 | SDL_EVENT_CASE(SDL_EVENT_MOUSE_BUTTON_UP) | ||
| 631 | PRINT_MBUTTON_EVENT(event); | ||
| 632 | break; | ||
| 633 | #undef PRINT_MBUTTON_EVENT | ||
| 634 | |||
| 635 | SDL_EVENT_CASE(SDL_EVENT_MOUSE_WHEEL) | ||
| 636 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u x=%g y=%g direction=%s)", | ||
| 637 | (uint)event->wheel.timestamp, (uint)event->wheel.windowID, | ||
| 638 | (uint)event->wheel.which, event->wheel.x, event->wheel.y, | ||
| 639 | event->wheel.direction == SDL_MOUSEWHEEL_NORMAL ? "normal" : "flipped"); | ||
| 640 | break; | ||
| 641 | |||
| 642 | SDL_EVENT_CASE(SDL_EVENT_JOYSTICK_AXIS_MOTION) | ||
| 643 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d axis=%u value=%d)", | ||
| 644 | (uint)event->jaxis.timestamp, (int)event->jaxis.which, | ||
| 645 | (uint)event->jaxis.axis, (int)event->jaxis.value); | ||
| 646 | break; | ||
| 647 | |||
| 648 | SDL_EVENT_CASE(SDL_EVENT_JOYSTICK_BALL_MOTION) | ||
| 649 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d ball=%u xrel=%d yrel=%d)", | ||
| 650 | (uint)event->jball.timestamp, (int)event->jball.which, | ||
| 651 | (uint)event->jball.ball, (int)event->jball.xrel, (int)event->jball.yrel); | ||
| 652 | break; | ||
| 653 | |||
| 654 | SDL_EVENT_CASE(SDL_EVENT_JOYSTICK_HAT_MOTION) | ||
| 655 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d hat=%u value=%u)", | ||
| 656 | (uint)event->jhat.timestamp, (int)event->jhat.which, | ||
| 657 | (uint)event->jhat.hat, (uint)event->jhat.value); | ||
| 658 | break; | ||
| 659 | |||
| 660 | #define PRINT_JBUTTON_EVENT(event) \ | ||
| 661 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d button=%u state=%s)", \ | ||
| 662 | (uint)event->jbutton.timestamp, (int)event->jbutton.which, \ | ||
| 663 | (uint)event->jbutton.button, event->jbutton.down ? "pressed" : "released") | ||
| 664 | SDL_EVENT_CASE(SDL_EVENT_JOYSTICK_BUTTON_DOWN) | ||
| 665 | PRINT_JBUTTON_EVENT(event); | ||
| 666 | break; | ||
| 667 | SDL_EVENT_CASE(SDL_EVENT_JOYSTICK_BUTTON_UP) | ||
| 668 | PRINT_JBUTTON_EVENT(event); | ||
| 669 | break; | ||
| 670 | #undef PRINT_JBUTTON_EVENT | ||
| 671 | |||
| 672 | SDL_EVENT_CASE(SDL_EVENT_JOYSTICK_BATTERY_UPDATED) | ||
| 673 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d state=%u percent=%d)", | ||
| 674 | (uint)event->jbattery.timestamp, (int)event->jbattery.which, | ||
| 675 | event->jbattery.state, event->jbattery.percent); | ||
| 676 | break; | ||
| 677 | |||
| 678 | #define PRINT_JOYDEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d)", (uint)event->jdevice.timestamp, (int)event->jdevice.which) | ||
| 679 | SDL_EVENT_CASE(SDL_EVENT_JOYSTICK_ADDED) | ||
| 680 | PRINT_JOYDEV_EVENT(event); | ||
| 681 | break; | ||
| 682 | SDL_EVENT_CASE(SDL_EVENT_JOYSTICK_REMOVED) | ||
| 683 | PRINT_JOYDEV_EVENT(event); | ||
| 684 | break; | ||
| 685 | SDL_EVENT_CASE(SDL_EVENT_JOYSTICK_UPDATE_COMPLETE) | ||
| 686 | PRINT_JOYDEV_EVENT(event); | ||
| 687 | break; | ||
| 688 | #undef PRINT_JOYDEV_EVENT | ||
| 689 | |||
| 690 | SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_AXIS_MOTION) | ||
| 691 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d axis=%u value=%d)", | ||
| 692 | (uint)event->gaxis.timestamp, (int)event->gaxis.which, | ||
| 693 | (uint)event->gaxis.axis, (int)event->gaxis.value); | ||
| 694 | break; | ||
| 695 | |||
| 696 | #define PRINT_CBUTTON_EVENT(event) \ | ||
| 697 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d button=%u state=%s)", \ | ||
| 698 | (uint)event->gbutton.timestamp, (int)event->gbutton.which, \ | ||
| 699 | (uint)event->gbutton.button, event->gbutton.down ? "pressed" : "released") | ||
| 700 | SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_BUTTON_DOWN) | ||
| 701 | PRINT_CBUTTON_EVENT(event); | ||
| 702 | break; | ||
| 703 | SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_BUTTON_UP) | ||
| 704 | PRINT_CBUTTON_EVENT(event); | ||
| 705 | break; | ||
| 706 | #undef PRINT_CBUTTON_EVENT | ||
| 707 | |||
| 708 | #define PRINT_GAMEPADDEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d)", (uint)event->gdevice.timestamp, (int)event->gdevice.which) | ||
| 709 | SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_ADDED) | ||
| 710 | PRINT_GAMEPADDEV_EVENT(event); | ||
| 711 | break; | ||
| 712 | SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_REMOVED) | ||
| 713 | PRINT_GAMEPADDEV_EVENT(event); | ||
| 714 | break; | ||
| 715 | SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_REMAPPED) | ||
| 716 | PRINT_GAMEPADDEV_EVENT(event); | ||
| 717 | break; | ||
| 718 | SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_UPDATE_COMPLETE) | ||
| 719 | PRINT_GAMEPADDEV_EVENT(event); | ||
| 720 | break; | ||
| 721 | SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED) | ||
| 722 | PRINT_GAMEPADDEV_EVENT(event); | ||
| 723 | break; | ||
| 724 | #undef PRINT_GAMEPADDEV_EVENT | ||
| 725 | |||
| 726 | #define PRINT_CTOUCHPAD_EVENT(event) \ | ||
| 727 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d touchpad=%d finger=%d x=%f y=%f pressure=%f)", \ | ||
| 728 | (uint)event->gtouchpad.timestamp, (int)event->gtouchpad.which, \ | ||
| 729 | (int)event->gtouchpad.touchpad, (int)event->gtouchpad.finger, \ | ||
| 730 | event->gtouchpad.x, event->gtouchpad.y, event->gtouchpad.pressure) | ||
| 731 | SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN) | ||
| 732 | PRINT_CTOUCHPAD_EVENT(event); | ||
| 733 | break; | ||
| 734 | SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_TOUCHPAD_UP) | ||
| 735 | PRINT_CTOUCHPAD_EVENT(event); | ||
| 736 | break; | ||
| 737 | SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION) | ||
| 738 | PRINT_CTOUCHPAD_EVENT(event); | ||
| 739 | break; | ||
| 740 | #undef PRINT_CTOUCHPAD_EVENT | ||
| 741 | |||
| 742 | SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_SENSOR_UPDATE) | ||
| 743 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d sensor=%d data[0]=%f data[1]=%f data[2]=%f)", | ||
| 744 | (uint)event->gsensor.timestamp, (int)event->gsensor.which, (int)event->gsensor.sensor, | ||
| 745 | event->gsensor.data[0], event->gsensor.data[1], event->gsensor.data[2]); | ||
| 746 | break; | ||
| 747 | |||
| 748 | #define PRINT_FINGER_EVENT(event) \ | ||
| 749 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u touchid=%" SDL_PRIu64 " fingerid=%" SDL_PRIu64 " x=%f y=%f dx=%f dy=%f pressure=%f)", \ | ||
| 750 | (uint)event->tfinger.timestamp, event->tfinger.touchID, \ | ||
| 751 | event->tfinger.fingerID, event->tfinger.x, event->tfinger.y, \ | ||
| 752 | event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure) | ||
| 753 | SDL_EVENT_CASE(SDL_EVENT_FINGER_DOWN) | ||
| 754 | PRINT_FINGER_EVENT(event); | ||
| 755 | break; | ||
| 756 | SDL_EVENT_CASE(SDL_EVENT_FINGER_UP) | ||
| 757 | PRINT_FINGER_EVENT(event); | ||
| 758 | break; | ||
| 759 | SDL_EVENT_CASE(SDL_EVENT_FINGER_CANCELED) | ||
| 760 | PRINT_FINGER_EVENT(event); | ||
| 761 | break; | ||
| 762 | SDL_EVENT_CASE(SDL_EVENT_FINGER_MOTION) | ||
| 763 | PRINT_FINGER_EVENT(event); | ||
| 764 | break; | ||
| 765 | #undef PRINT_FINGER_EVENT | ||
| 766 | |||
| 767 | #define PRINT_PTOUCH_EVENT(event) \ | ||
| 768 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u pen_state=%u x=%g y=%g eraser=%s state=%s)", \ | ||
| 769 | (uint)event->ptouch.timestamp, (uint)event->ptouch.windowID, (uint)event->ptouch.which, (uint)event->ptouch.pen_state, event->ptouch.x, event->ptouch.y, \ | ||
| 770 | event->ptouch.eraser ? "yes" : "no", event->ptouch.down ? "down" : "up"); | ||
| 771 | SDL_EVENT_CASE(SDL_EVENT_PEN_DOWN) | ||
| 772 | PRINT_PTOUCH_EVENT(event); | ||
| 773 | break; | ||
| 774 | SDL_EVENT_CASE(SDL_EVENT_PEN_UP) | ||
| 775 | PRINT_PTOUCH_EVENT(event); | ||
| 776 | break; | ||
| 777 | #undef PRINT_PTOUCH_EVENT | ||
| 778 | |||
| 779 | #define PRINT_PPROXIMITY_EVENT(event) \ | ||
| 780 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u)", \ | ||
| 781 | (uint)event->pproximity.timestamp, (uint)event->pproximity.windowID, (uint)event->pproximity.which); | ||
| 782 | SDL_EVENT_CASE(SDL_EVENT_PEN_PROXIMITY_IN) | ||
| 783 | PRINT_PPROXIMITY_EVENT(event); | ||
| 784 | break; | ||
| 785 | SDL_EVENT_CASE(SDL_EVENT_PEN_PROXIMITY_OUT) | ||
| 786 | PRINT_PPROXIMITY_EVENT(event); | ||
| 787 | break; | ||
| 788 | #undef PRINT_PPROXIMITY_EVENT | ||
| 789 | |||
| 790 | SDL_EVENT_CASE(SDL_EVENT_PEN_AXIS) | ||
| 791 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u pen_state=%u x=%g y=%g axis=%s value=%g)", | ||
| 792 | (uint)event->paxis.timestamp, (uint)event->paxis.windowID, (uint)event->paxis.which, (uint)event->paxis.pen_state, event->paxis.x, event->paxis.y, | ||
| 793 | ((((int) event->paxis.axis) >= 0) && (event->paxis.axis < SDL_arraysize(pen_axisnames))) ? pen_axisnames[event->paxis.axis] : "[UNKNOWN]", event->paxis.value); | ||
| 794 | break; | ||
| 795 | |||
| 796 | SDL_EVENT_CASE(SDL_EVENT_PEN_MOTION) | ||
| 797 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u pen_state=%u x=%g y=%g)", | ||
| 798 | (uint)event->pmotion.timestamp, (uint)event->pmotion.windowID, (uint)event->pmotion.which, (uint)event->pmotion.pen_state, event->pmotion.x, event->pmotion.y); | ||
| 799 | break; | ||
| 800 | |||
| 801 | #define PRINT_PBUTTON_EVENT(event) \ | ||
| 802 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u pen_state=%u x=%g y=%g button=%u state=%s)", \ | ||
| 803 | (uint)event->pbutton.timestamp, (uint)event->pbutton.windowID, (uint)event->pbutton.which, (uint)event->pbutton.pen_state, event->pbutton.x, event->pbutton.y, \ | ||
| 804 | (uint)event->pbutton.button, event->pbutton.down ? "down" : "up"); | ||
| 805 | SDL_EVENT_CASE(SDL_EVENT_PEN_BUTTON_DOWN) | ||
| 806 | PRINT_PBUTTON_EVENT(event); | ||
| 807 | break; | ||
| 808 | SDL_EVENT_CASE(SDL_EVENT_PEN_BUTTON_UP) | ||
| 809 | PRINT_PBUTTON_EVENT(event); | ||
| 810 | break; | ||
| 811 | #undef PRINT_PBUTTON_EVENT | ||
| 812 | |||
| 813 | #define PRINT_DROP_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (data='%s' timestamp=%u windowid=%u x=%f y=%f)", event->drop.data, (uint)event->drop.timestamp, (uint)event->drop.windowID, event->drop.x, event->drop.y) | ||
| 814 | SDL_EVENT_CASE(SDL_EVENT_DROP_FILE) | ||
| 815 | PRINT_DROP_EVENT(event); | ||
| 816 | break; | ||
| 817 | SDL_EVENT_CASE(SDL_EVENT_DROP_TEXT) | ||
| 818 | PRINT_DROP_EVENT(event); | ||
| 819 | break; | ||
| 820 | SDL_EVENT_CASE(SDL_EVENT_DROP_BEGIN) | ||
| 821 | PRINT_DROP_EVENT(event); | ||
| 822 | break; | ||
| 823 | SDL_EVENT_CASE(SDL_EVENT_DROP_COMPLETE) | ||
| 824 | PRINT_DROP_EVENT(event); | ||
| 825 | break; | ||
| 826 | SDL_EVENT_CASE(SDL_EVENT_DROP_POSITION) | ||
| 827 | PRINT_DROP_EVENT(event); | ||
| 828 | break; | ||
| 829 | #undef PRINT_DROP_EVENT | ||
| 830 | |||
| 831 | #define PRINT_AUDIODEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u recording=%s)", (uint)event->adevice.timestamp, (uint)event->adevice.which, event->adevice.recording ? "true" : "false") | ||
| 832 | SDL_EVENT_CASE(SDL_EVENT_AUDIO_DEVICE_ADDED) | ||
| 833 | PRINT_AUDIODEV_EVENT(event); | ||
| 834 | break; | ||
| 835 | SDL_EVENT_CASE(SDL_EVENT_AUDIO_DEVICE_REMOVED) | ||
| 836 | PRINT_AUDIODEV_EVENT(event); | ||
| 837 | break; | ||
| 838 | SDL_EVENT_CASE(SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED) | ||
| 839 | PRINT_AUDIODEV_EVENT(event); | ||
| 840 | break; | ||
| 841 | #undef PRINT_AUDIODEV_EVENT | ||
| 842 | |||
| 843 | #define PRINT_CAMERADEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u)", (uint)event->cdevice.timestamp, (uint)event->cdevice.which) | ||
| 844 | SDL_EVENT_CASE(SDL_EVENT_CAMERA_DEVICE_ADDED) | ||
| 845 | PRINT_CAMERADEV_EVENT(event); | ||
| 846 | break; | ||
| 847 | SDL_EVENT_CASE(SDL_EVENT_CAMERA_DEVICE_REMOVED) | ||
| 848 | PRINT_CAMERADEV_EVENT(event); | ||
| 849 | break; | ||
| 850 | SDL_EVENT_CASE(SDL_EVENT_CAMERA_DEVICE_APPROVED) | ||
| 851 | PRINT_CAMERADEV_EVENT(event); | ||
| 852 | break; | ||
| 853 | SDL_EVENT_CASE(SDL_EVENT_CAMERA_DEVICE_DENIED) | ||
| 854 | PRINT_CAMERADEV_EVENT(event); | ||
| 855 | break; | ||
| 856 | #undef PRINT_CAMERADEV_EVENT | ||
| 857 | |||
| 858 | SDL_EVENT_CASE(SDL_EVENT_SENSOR_UPDATE) | ||
| 859 | (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d data[0]=%f data[1]=%f data[2]=%f data[3]=%f data[4]=%f data[5]=%f)", | ||
| 860 | (uint)event->sensor.timestamp, (int)event->sensor.which, | ||
| 861 | event->sensor.data[0], event->sensor.data[1], event->sensor.data[2], | ||
| 862 | event->sensor.data[3], event->sensor.data[4], event->sensor.data[5]); | ||
| 863 | break; | ||
| 864 | |||
| 865 | #undef SDL_EVENT_CASE | ||
| 866 | |||
| 867 | case SDL_EVENT_POLL_SENTINEL: | ||
| 868 | // No logging necessary for this one | ||
| 869 | break; | ||
| 870 | |||
| 871 | default: | ||
| 872 | if (!name[0]) { | ||
| 873 | if (event->type >= SDL_EVENT_USER) { | ||
| 874 | SDL_strlcpy(name, "USER", sizeof(name)); | ||
| 875 | } else { | ||
| 876 | SDL_strlcpy(name, "UNKNOWN", sizeof(name)); | ||
| 877 | } | ||
| 878 | (void)SDL_snprintf(details, sizeof(details), " 0x%x", (uint)event->type); | ||
| 879 | } | ||
| 880 | break; | ||
| 881 | } | ||
| 882 | |||
| 883 | if (name[0]) { | ||
| 884 | SDL_Log("SDL EVENT: %s%s", name, details); | ||
| 885 | } | ||
| 886 | |||
| 887 | #undef uint | ||
| 888 | } | ||
| 889 | |||
| 890 | void SDL_StopEventLoop(void) | ||
| 891 | { | ||
| 892 | const char *report = SDL_GetHint("SDL_EVENT_QUEUE_STATISTICS"); | ||
| 893 | int i; | ||
| 894 | SDL_EventEntry *entry; | ||
| 895 | |||
| 896 | SDL_LockMutex(SDL_EventQ.lock); | ||
| 897 | |||
| 898 | SDL_EventQ.active = false; | ||
| 899 | |||
| 900 | if (report && SDL_atoi(report)) { | ||
| 901 | SDL_Log("SDL EVENT QUEUE: Maximum events in-flight: %d", | ||
| 902 | SDL_EventQ.max_events_seen); | ||
| 903 | } | ||
| 904 | |||
| 905 | // Clean out EventQ | ||
| 906 | for (entry = SDL_EventQ.head; entry;) { | ||
| 907 | SDL_EventEntry *next = entry->next; | ||
| 908 | SDL_TransferTemporaryMemoryFromEvent(entry); | ||
| 909 | SDL_free(entry); | ||
| 910 | entry = next; | ||
| 911 | } | ||
| 912 | for (entry = SDL_EventQ.free; entry;) { | ||
| 913 | SDL_EventEntry *next = entry->next; | ||
| 914 | SDL_free(entry); | ||
| 915 | entry = next; | ||
| 916 | } | ||
| 917 | |||
| 918 | SDL_SetAtomicInt(&SDL_EventQ.count, 0); | ||
| 919 | SDL_EventQ.max_events_seen = 0; | ||
| 920 | SDL_EventQ.head = NULL; | ||
| 921 | SDL_EventQ.tail = NULL; | ||
| 922 | SDL_EventQ.free = NULL; | ||
| 923 | SDL_SetAtomicInt(&SDL_sentinel_pending, 0); | ||
| 924 | |||
| 925 | // Clear disabled event state | ||
| 926 | for (i = 0; i < SDL_arraysize(SDL_disabled_events); ++i) { | ||
| 927 | SDL_free(SDL_disabled_events[i]); | ||
| 928 | SDL_disabled_events[i] = NULL; | ||
| 929 | } | ||
| 930 | |||
| 931 | SDL_QuitEventWatchList(&SDL_event_watchers); | ||
| 932 | SDL_QuitWindowEventWatch(); | ||
| 933 | |||
| 934 | SDL_Mutex *lock = NULL; | ||
| 935 | if (SDL_EventQ.lock) { | ||
| 936 | lock = SDL_EventQ.lock; | ||
| 937 | SDL_EventQ.lock = NULL; | ||
| 938 | } | ||
| 939 | |||
| 940 | SDL_UnlockMutex(lock); | ||
| 941 | |||
| 942 | if (lock) { | ||
| 943 | SDL_DestroyMutex(lock); | ||
| 944 | } | ||
| 945 | } | ||
| 946 | |||
| 947 | // This function (and associated calls) may be called more than once | ||
| 948 | bool SDL_StartEventLoop(void) | ||
| 949 | { | ||
| 950 | /* We'll leave the event queue alone, since we might have gotten | ||
| 951 | some important events at launch (like SDL_EVENT_DROP_FILE) | ||
| 952 | |||
| 953 | FIXME: Does this introduce any other bugs with events at startup? | ||
| 954 | */ | ||
| 955 | |||
| 956 | // Create the lock and set ourselves active | ||
| 957 | #ifndef SDL_THREADS_DISABLED | ||
| 958 | if (!SDL_EventQ.lock) { | ||
| 959 | SDL_EventQ.lock = SDL_CreateMutex(); | ||
| 960 | if (SDL_EventQ.lock == NULL) { | ||
| 961 | return false; | ||
| 962 | } | ||
| 963 | } | ||
| 964 | SDL_LockMutex(SDL_EventQ.lock); | ||
| 965 | |||
| 966 | if (!SDL_InitEventWatchList(&SDL_event_watchers)) { | ||
| 967 | SDL_UnlockMutex(SDL_EventQ.lock); | ||
| 968 | return false; | ||
| 969 | } | ||
| 970 | #endif // !SDL_THREADS_DISABLED | ||
| 971 | |||
| 972 | SDL_InitWindowEventWatch(); | ||
| 973 | |||
| 974 | SDL_EventQ.active = true; | ||
| 975 | |||
| 976 | #ifndef SDL_THREADS_DISABLED | ||
| 977 | SDL_UnlockMutex(SDL_EventQ.lock); | ||
| 978 | #endif | ||
| 979 | return true; | ||
| 980 | } | ||
| 981 | |||
| 982 | // Add an event to the event queue -- called with the queue locked | ||
| 983 | static int SDL_AddEvent(SDL_Event *event) | ||
| 984 | { | ||
| 985 | SDL_EventEntry *entry; | ||
| 986 | const int initial_count = SDL_GetAtomicInt(&SDL_EventQ.count); | ||
| 987 | int final_count; | ||
| 988 | |||
| 989 | if (initial_count >= SDL_MAX_QUEUED_EVENTS) { | ||
| 990 | SDL_SetError("Event queue is full (%d events)", initial_count); | ||
| 991 | return 0; | ||
| 992 | } | ||
| 993 | |||
| 994 | if (SDL_EventQ.free == NULL) { | ||
| 995 | entry = (SDL_EventEntry *)SDL_malloc(sizeof(*entry)); | ||
| 996 | if (entry == NULL) { | ||
| 997 | return 0; | ||
| 998 | } | ||
| 999 | } else { | ||
| 1000 | entry = SDL_EventQ.free; | ||
| 1001 | SDL_EventQ.free = entry->next; | ||
| 1002 | } | ||
| 1003 | |||
| 1004 | if (SDL_EventLoggingVerbosity > 0) { | ||
| 1005 | SDL_LogEvent(event); | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | SDL_copyp(&entry->event, event); | ||
| 1009 | if (event->type == SDL_EVENT_POLL_SENTINEL) { | ||
| 1010 | SDL_AddAtomicInt(&SDL_sentinel_pending, 1); | ||
| 1011 | } | ||
| 1012 | entry->memory = NULL; | ||
| 1013 | SDL_TransferTemporaryMemoryToEvent(entry); | ||
| 1014 | |||
| 1015 | if (SDL_EventQ.tail) { | ||
| 1016 | SDL_EventQ.tail->next = entry; | ||
| 1017 | entry->prev = SDL_EventQ.tail; | ||
| 1018 | SDL_EventQ.tail = entry; | ||
| 1019 | entry->next = NULL; | ||
| 1020 | } else { | ||
| 1021 | SDL_assert(!SDL_EventQ.head); | ||
| 1022 | SDL_EventQ.head = entry; | ||
| 1023 | SDL_EventQ.tail = entry; | ||
| 1024 | entry->prev = NULL; | ||
| 1025 | entry->next = NULL; | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | final_count = SDL_AddAtomicInt(&SDL_EventQ.count, 1) + 1; | ||
| 1029 | if (final_count > SDL_EventQ.max_events_seen) { | ||
| 1030 | SDL_EventQ.max_events_seen = final_count; | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | ++SDL_last_event_id; | ||
| 1034 | |||
| 1035 | return 1; | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | // Remove an event from the queue -- called with the queue locked | ||
| 1039 | static void SDL_CutEvent(SDL_EventEntry *entry) | ||
| 1040 | { | ||
| 1041 | SDL_TransferTemporaryMemoryFromEvent(entry); | ||
| 1042 | |||
| 1043 | if (entry->prev) { | ||
| 1044 | entry->prev->next = entry->next; | ||
| 1045 | } | ||
| 1046 | if (entry->next) { | ||
| 1047 | entry->next->prev = entry->prev; | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | if (entry == SDL_EventQ.head) { | ||
| 1051 | SDL_assert(entry->prev == NULL); | ||
| 1052 | SDL_EventQ.head = entry->next; | ||
| 1053 | } | ||
| 1054 | if (entry == SDL_EventQ.tail) { | ||
| 1055 | SDL_assert(entry->next == NULL); | ||
| 1056 | SDL_EventQ.tail = entry->prev; | ||
| 1057 | } | ||
| 1058 | |||
| 1059 | if (entry->event.type == SDL_EVENT_POLL_SENTINEL) { | ||
| 1060 | SDL_AddAtomicInt(&SDL_sentinel_pending, -1); | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | entry->next = SDL_EventQ.free; | ||
| 1064 | SDL_EventQ.free = entry; | ||
| 1065 | SDL_assert(SDL_GetAtomicInt(&SDL_EventQ.count) > 0); | ||
| 1066 | SDL_AddAtomicInt(&SDL_EventQ.count, -1); | ||
| 1067 | } | ||
| 1068 | |||
| 1069 | static void SDL_SendWakeupEvent(void) | ||
| 1070 | { | ||
| 1071 | #ifdef SDL_PLATFORM_ANDROID | ||
| 1072 | Android_SendLifecycleEvent(SDL_ANDROID_LIFECYCLE_WAKE); | ||
| 1073 | #else | ||
| 1074 | SDL_VideoDevice *_this = SDL_GetVideoDevice(); | ||
| 1075 | if (_this == NULL || !_this->SendWakeupEvent) { | ||
| 1076 | return; | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | SDL_LockMutex(_this->wakeup_lock); | ||
| 1080 | { | ||
| 1081 | if (_this->wakeup_window) { | ||
| 1082 | _this->SendWakeupEvent(_this, _this->wakeup_window); | ||
| 1083 | |||
| 1084 | // No more wakeup events needed until we enter a new wait | ||
| 1085 | _this->wakeup_window = NULL; | ||
| 1086 | } | ||
| 1087 | } | ||
| 1088 | SDL_UnlockMutex(_this->wakeup_lock); | ||
| 1089 | #endif | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | // Lock the event queue, take a peep at it, and unlock it | ||
| 1093 | static int SDL_PeepEventsInternal(SDL_Event *events, int numevents, SDL_EventAction action, | ||
| 1094 | Uint32 minType, Uint32 maxType, bool include_sentinel) | ||
| 1095 | { | ||
| 1096 | int i, used, sentinels_expected = 0; | ||
| 1097 | |||
| 1098 | // Lock the event queue | ||
| 1099 | used = 0; | ||
| 1100 | |||
| 1101 | SDL_LockMutex(SDL_EventQ.lock); | ||
| 1102 | { | ||
| 1103 | // Don't look after we've quit | ||
| 1104 | if (!SDL_EventQ.active) { | ||
| 1105 | // We get a few spurious events at shutdown, so don't warn then | ||
| 1106 | if (action == SDL_GETEVENT) { | ||
| 1107 | SDL_SetError("The event system has been shut down"); | ||
| 1108 | } | ||
| 1109 | SDL_UnlockMutex(SDL_EventQ.lock); | ||
| 1110 | return -1; | ||
| 1111 | } | ||
| 1112 | if (action == SDL_ADDEVENT) { | ||
| 1113 | if (!events) { | ||
| 1114 | SDL_UnlockMutex(SDL_EventQ.lock); | ||
| 1115 | return SDL_InvalidParamError("events"); | ||
| 1116 | } | ||
| 1117 | for (i = 0; i < numevents; ++i) { | ||
| 1118 | used += SDL_AddEvent(&events[i]); | ||
| 1119 | } | ||
| 1120 | } else { | ||
| 1121 | SDL_EventEntry *entry, *next; | ||
| 1122 | Uint32 type; | ||
| 1123 | |||
| 1124 | for (entry = SDL_EventQ.head; entry && (events == NULL || used < numevents); entry = next) { | ||
| 1125 | next = entry->next; | ||
| 1126 | type = entry->event.type; | ||
| 1127 | if (minType <= type && type <= maxType) { | ||
| 1128 | if (events) { | ||
| 1129 | SDL_copyp(&events[used], &entry->event); | ||
| 1130 | |||
| 1131 | if (action == SDL_GETEVENT) { | ||
| 1132 | SDL_CutEvent(entry); | ||
| 1133 | } | ||
| 1134 | } | ||
| 1135 | if (type == SDL_EVENT_POLL_SENTINEL) { | ||
| 1136 | // Special handling for the sentinel event | ||
| 1137 | if (!include_sentinel) { | ||
| 1138 | // Skip it, we don't want to include it | ||
| 1139 | continue; | ||
| 1140 | } | ||
| 1141 | if (events == NULL || action != SDL_GETEVENT) { | ||
| 1142 | ++sentinels_expected; | ||
| 1143 | } | ||
| 1144 | if (SDL_GetAtomicInt(&SDL_sentinel_pending) > sentinels_expected) { | ||
| 1145 | // Skip it, there's another one pending | ||
| 1146 | continue; | ||
| 1147 | } | ||
| 1148 | } | ||
| 1149 | ++used; | ||
| 1150 | } | ||
| 1151 | } | ||
| 1152 | } | ||
| 1153 | } | ||
| 1154 | SDL_UnlockMutex(SDL_EventQ.lock); | ||
| 1155 | |||
| 1156 | if (used > 0 && action == SDL_ADDEVENT) { | ||
| 1157 | SDL_SendWakeupEvent(); | ||
| 1158 | } | ||
| 1159 | |||
| 1160 | return used; | ||
| 1161 | } | ||
| 1162 | int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_EventAction action, | ||
| 1163 | Uint32 minType, Uint32 maxType) | ||
| 1164 | { | ||
| 1165 | return SDL_PeepEventsInternal(events, numevents, action, minType, maxType, false); | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | bool SDL_HasEvent(Uint32 type) | ||
| 1169 | { | ||
| 1170 | return SDL_HasEvents(type, type); | ||
| 1171 | } | ||
| 1172 | |||
| 1173 | bool SDL_HasEvents(Uint32 minType, Uint32 maxType) | ||
| 1174 | { | ||
| 1175 | bool found = false; | ||
| 1176 | |||
| 1177 | SDL_LockMutex(SDL_EventQ.lock); | ||
| 1178 | { | ||
| 1179 | if (SDL_EventQ.active) { | ||
| 1180 | for (SDL_EventEntry *entry = SDL_EventQ.head; entry; entry = entry->next) { | ||
| 1181 | const Uint32 type = entry->event.type; | ||
| 1182 | if (minType <= type && type <= maxType) { | ||
| 1183 | found = true; | ||
| 1184 | break; | ||
| 1185 | } | ||
| 1186 | } | ||
| 1187 | } | ||
| 1188 | } | ||
| 1189 | SDL_UnlockMutex(SDL_EventQ.lock); | ||
| 1190 | |||
| 1191 | return found; | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | void SDL_FlushEvent(Uint32 type) | ||
| 1195 | { | ||
| 1196 | SDL_FlushEvents(type, type); | ||
| 1197 | } | ||
| 1198 | |||
| 1199 | void SDL_FlushEvents(Uint32 minType, Uint32 maxType) | ||
| 1200 | { | ||
| 1201 | SDL_EventEntry *entry, *next; | ||
| 1202 | Uint32 type; | ||
| 1203 | |||
| 1204 | // Make sure the events are current | ||
| 1205 | #if 0 | ||
| 1206 | /* Actually, we can't do this since we might be flushing while processing | ||
| 1207 | a resize event, and calling this might trigger further resize events. | ||
| 1208 | */ | ||
| 1209 | SDL_PumpEvents(); | ||
| 1210 | #endif | ||
| 1211 | |||
| 1212 | // Lock the event queue | ||
| 1213 | SDL_LockMutex(SDL_EventQ.lock); | ||
| 1214 | { | ||
| 1215 | // Don't look after we've quit | ||
| 1216 | if (!SDL_EventQ.active) { | ||
| 1217 | SDL_UnlockMutex(SDL_EventQ.lock); | ||
| 1218 | return; | ||
| 1219 | } | ||
| 1220 | for (entry = SDL_EventQ.head; entry; entry = next) { | ||
| 1221 | next = entry->next; | ||
| 1222 | type = entry->event.type; | ||
| 1223 | if (minType <= type && type <= maxType) { | ||
| 1224 | SDL_CutEvent(entry); | ||
| 1225 | } | ||
| 1226 | } | ||
| 1227 | } | ||
| 1228 | SDL_UnlockMutex(SDL_EventQ.lock); | ||
| 1229 | } | ||
| 1230 | |||
| 1231 | typedef enum | ||
| 1232 | { | ||
| 1233 | SDL_MAIN_CALLBACK_WAITING, | ||
| 1234 | SDL_MAIN_CALLBACK_COMPLETE, | ||
| 1235 | SDL_MAIN_CALLBACK_CANCELED, | ||
| 1236 | } SDL_MainThreadCallbackState; | ||
| 1237 | |||
| 1238 | typedef struct SDL_MainThreadCallbackEntry | ||
| 1239 | { | ||
| 1240 | SDL_MainThreadCallback callback; | ||
| 1241 | void *userdata; | ||
| 1242 | SDL_AtomicInt state; | ||
| 1243 | SDL_Semaphore *semaphore; | ||
| 1244 | struct SDL_MainThreadCallbackEntry *next; | ||
| 1245 | } SDL_MainThreadCallbackEntry; | ||
| 1246 | |||
| 1247 | static SDL_Mutex *SDL_main_callbacks_lock; | ||
| 1248 | static SDL_MainThreadCallbackEntry *SDL_main_callbacks_head; | ||
| 1249 | static SDL_MainThreadCallbackEntry *SDL_main_callbacks_tail; | ||
| 1250 | |||
| 1251 | static SDL_MainThreadCallbackEntry *SDL_CreateMainThreadCallback(SDL_MainThreadCallback callback, void *userdata, bool wait_complete) | ||
| 1252 | { | ||
| 1253 | SDL_MainThreadCallbackEntry *entry = (SDL_MainThreadCallbackEntry *)SDL_malloc(sizeof(*entry)); | ||
| 1254 | if (!entry) { | ||
| 1255 | return NULL; | ||
| 1256 | } | ||
| 1257 | |||
| 1258 | entry->callback = callback; | ||
| 1259 | entry->userdata = userdata; | ||
| 1260 | SDL_SetAtomicInt(&entry->state, SDL_MAIN_CALLBACK_WAITING); | ||
| 1261 | if (wait_complete) { | ||
| 1262 | entry->semaphore = SDL_CreateSemaphore(0); | ||
| 1263 | if (!entry->semaphore) { | ||
| 1264 | SDL_free(entry); | ||
| 1265 | return NULL; | ||
| 1266 | } | ||
| 1267 | } else { | ||
| 1268 | entry->semaphore = NULL; | ||
| 1269 | } | ||
| 1270 | entry->next = NULL; | ||
| 1271 | |||
| 1272 | return entry; | ||
| 1273 | } | ||
| 1274 | |||
| 1275 | static void SDL_DestroyMainThreadCallback(SDL_MainThreadCallbackEntry *entry) | ||
| 1276 | { | ||
| 1277 | if (entry->semaphore) { | ||
| 1278 | SDL_DestroySemaphore(entry->semaphore); | ||
| 1279 | } | ||
| 1280 | SDL_free(entry); | ||
| 1281 | } | ||
| 1282 | |||
| 1283 | static void SDL_InitMainThreadCallbacks(void) | ||
| 1284 | { | ||
| 1285 | SDL_main_callbacks_lock = SDL_CreateMutex(); | ||
| 1286 | SDL_assert(SDL_main_callbacks_head == NULL && | ||
| 1287 | SDL_main_callbacks_tail == NULL); | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | static void SDL_QuitMainThreadCallbacks(void) | ||
| 1291 | { | ||
| 1292 | SDL_MainThreadCallbackEntry *entry; | ||
| 1293 | |||
| 1294 | SDL_LockMutex(SDL_main_callbacks_lock); | ||
| 1295 | { | ||
| 1296 | entry = SDL_main_callbacks_head; | ||
| 1297 | SDL_main_callbacks_head = NULL; | ||
| 1298 | SDL_main_callbacks_tail = NULL; | ||
| 1299 | } | ||
| 1300 | SDL_UnlockMutex(SDL_main_callbacks_lock); | ||
| 1301 | |||
| 1302 | while (entry) { | ||
| 1303 | SDL_MainThreadCallbackEntry *next = entry->next; | ||
| 1304 | |||
| 1305 | if (entry->semaphore) { | ||
| 1306 | // Let the waiting thread know this is canceled | ||
| 1307 | SDL_SetAtomicInt(&entry->state, SDL_MAIN_CALLBACK_CANCELED); | ||
| 1308 | SDL_SignalSemaphore(entry->semaphore); | ||
| 1309 | } else { | ||
| 1310 | // Nobody's waiting for this, clean it up | ||
| 1311 | SDL_DestroyMainThreadCallback(entry); | ||
| 1312 | } | ||
| 1313 | entry = next; | ||
| 1314 | } | ||
| 1315 | |||
| 1316 | SDL_DestroyMutex(SDL_main_callbacks_lock); | ||
| 1317 | SDL_main_callbacks_lock = NULL; | ||
| 1318 | } | ||
| 1319 | |||
| 1320 | static void SDL_RunMainThreadCallbacks(void) | ||
| 1321 | { | ||
| 1322 | SDL_MainThreadCallbackEntry *entry; | ||
| 1323 | |||
| 1324 | SDL_LockMutex(SDL_main_callbacks_lock); | ||
| 1325 | { | ||
| 1326 | entry = SDL_main_callbacks_head; | ||
| 1327 | SDL_main_callbacks_head = NULL; | ||
| 1328 | SDL_main_callbacks_tail = NULL; | ||
| 1329 | } | ||
| 1330 | SDL_UnlockMutex(SDL_main_callbacks_lock); | ||
| 1331 | |||
| 1332 | while (entry) { | ||
| 1333 | SDL_MainThreadCallbackEntry *next = entry->next; | ||
| 1334 | |||
| 1335 | entry->callback(entry->userdata); | ||
| 1336 | |||
| 1337 | if (entry->semaphore) { | ||
| 1338 | // Let the waiting thread know this is done | ||
| 1339 | SDL_SetAtomicInt(&entry->state, SDL_MAIN_CALLBACK_COMPLETE); | ||
| 1340 | SDL_SignalSemaphore(entry->semaphore); | ||
| 1341 | } else { | ||
| 1342 | // Nobody's waiting for this, clean it up | ||
| 1343 | SDL_DestroyMainThreadCallback(entry); | ||
| 1344 | } | ||
| 1345 | entry = next; | ||
| 1346 | } | ||
| 1347 | } | ||
| 1348 | |||
| 1349 | bool SDL_RunOnMainThread(SDL_MainThreadCallback callback, void *userdata, bool wait_complete) | ||
| 1350 | { | ||
| 1351 | if (SDL_IsMainThread() || !SDL_WasInit(SDL_INIT_EVENTS)) { | ||
| 1352 | // No need to queue the callback | ||
| 1353 | callback(userdata); | ||
| 1354 | return true; | ||
| 1355 | } | ||
| 1356 | |||
| 1357 | SDL_MainThreadCallbackEntry *entry = SDL_CreateMainThreadCallback(callback, userdata, wait_complete); | ||
| 1358 | if (!entry) { | ||
| 1359 | return false; | ||
| 1360 | } | ||
| 1361 | |||
| 1362 | SDL_LockMutex(SDL_main_callbacks_lock); | ||
| 1363 | { | ||
| 1364 | if (SDL_main_callbacks_tail) { | ||
| 1365 | SDL_main_callbacks_tail->next = entry; | ||
| 1366 | SDL_main_callbacks_tail = entry; | ||
| 1367 | } else { | ||
| 1368 | SDL_main_callbacks_head = entry; | ||
| 1369 | SDL_main_callbacks_tail = entry; | ||
| 1370 | } | ||
| 1371 | } | ||
| 1372 | SDL_UnlockMutex(SDL_main_callbacks_lock); | ||
| 1373 | |||
| 1374 | // If the main thread is waiting for events, wake it up | ||
| 1375 | SDL_SendWakeupEvent(); | ||
| 1376 | |||
| 1377 | if (!wait_complete) { | ||
| 1378 | // Queued for execution, wait not requested | ||
| 1379 | return true; | ||
| 1380 | } | ||
| 1381 | |||
| 1382 | // Maximum wait of 30 seconds to prevent deadlocking forever | ||
| 1383 | const Sint32 MAX_CALLBACK_WAIT = 30 * 1000; | ||
| 1384 | SDL_WaitSemaphoreTimeout(entry->semaphore, MAX_CALLBACK_WAIT); | ||
| 1385 | |||
| 1386 | switch (SDL_GetAtomicInt(&entry->state)) { | ||
| 1387 | case SDL_MAIN_CALLBACK_COMPLETE: | ||
| 1388 | // Execution complete! | ||
| 1389 | SDL_DestroyMainThreadCallback(entry); | ||
| 1390 | return true; | ||
| 1391 | |||
| 1392 | case SDL_MAIN_CALLBACK_CANCELED: | ||
| 1393 | // The callback was canceled on the main thread | ||
| 1394 | SDL_DestroyMainThreadCallback(entry); | ||
| 1395 | return SDL_SetError("Callback canceled"); | ||
| 1396 | |||
| 1397 | default: | ||
| 1398 | // Probably hit a deadlock in the callback | ||
| 1399 | // We can't destroy the entry as the semaphore will be signaled | ||
| 1400 | // if it ever comes back, just leak it here. | ||
| 1401 | return SDL_SetError("Callback timed out"); | ||
| 1402 | } | ||
| 1403 | } | ||
| 1404 | |||
| 1405 | void SDL_PumpEventMaintenance(void) | ||
| 1406 | { | ||
| 1407 | #ifndef SDL_AUDIO_DISABLED | ||
| 1408 | SDL_UpdateAudio(); | ||
| 1409 | #endif | ||
| 1410 | |||
| 1411 | #ifndef SDL_CAMERA_DISABLED | ||
| 1412 | SDL_UpdateCamera(); | ||
| 1413 | #endif | ||
| 1414 | |||
| 1415 | #ifndef SDL_SENSOR_DISABLED | ||
| 1416 | // Check for sensor state change | ||
| 1417 | if (SDL_update_sensors) { | ||
| 1418 | SDL_UpdateSensors(); | ||
| 1419 | } | ||
| 1420 | #endif | ||
| 1421 | |||
| 1422 | #ifndef SDL_JOYSTICK_DISABLED | ||
| 1423 | // Check for joystick state change | ||
| 1424 | if (SDL_update_joysticks) { | ||
| 1425 | SDL_UpdateJoysticks(); | ||
| 1426 | } | ||
| 1427 | #endif | ||
| 1428 | |||
| 1429 | SDL_UpdateTrays(); | ||
| 1430 | |||
| 1431 | SDL_SendPendingSignalEvents(); // in case we had a signal handler fire, etc. | ||
| 1432 | } | ||
| 1433 | |||
| 1434 | // Run the system dependent event loops | ||
| 1435 | static void SDL_PumpEventsInternal(bool push_sentinel) | ||
| 1436 | { | ||
| 1437 | // Free any temporary memory from old events | ||
| 1438 | SDL_FreeTemporaryMemory(); | ||
| 1439 | |||
| 1440 | // Release any keys held down from last frame | ||
| 1441 | SDL_ReleaseAutoReleaseKeys(); | ||
| 1442 | |||
| 1443 | // Run any pending main thread callbacks | ||
| 1444 | SDL_RunMainThreadCallbacks(); | ||
| 1445 | |||
| 1446 | #ifdef SDL_PLATFORM_ANDROID | ||
| 1447 | // Android event processing is independent of the video subsystem | ||
| 1448 | Android_PumpEvents(0); | ||
| 1449 | #else | ||
| 1450 | // Get events from the video subsystem | ||
| 1451 | SDL_VideoDevice *_this = SDL_GetVideoDevice(); | ||
| 1452 | if (_this) { | ||
| 1453 | _this->PumpEvents(_this); | ||
| 1454 | } | ||
| 1455 | #endif | ||
| 1456 | |||
| 1457 | SDL_PumpEventMaintenance(); | ||
| 1458 | |||
| 1459 | if (push_sentinel && SDL_EventEnabled(SDL_EVENT_POLL_SENTINEL)) { | ||
| 1460 | SDL_Event sentinel; | ||
| 1461 | |||
| 1462 | // Make sure we don't already have a sentinel in the queue, and add one to the end | ||
| 1463 | if (SDL_GetAtomicInt(&SDL_sentinel_pending) > 0) { | ||
| 1464 | SDL_PeepEventsInternal(&sentinel, 1, SDL_GETEVENT, SDL_EVENT_POLL_SENTINEL, SDL_EVENT_POLL_SENTINEL, true); | ||
| 1465 | } | ||
| 1466 | |||
| 1467 | sentinel.type = SDL_EVENT_POLL_SENTINEL; | ||
| 1468 | sentinel.common.timestamp = 0; | ||
| 1469 | SDL_PushEvent(&sentinel); | ||
| 1470 | } | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | void SDL_PumpEvents(void) | ||
| 1474 | { | ||
| 1475 | SDL_PumpEventsInternal(false); | ||
| 1476 | } | ||
| 1477 | |||
| 1478 | // Public functions | ||
| 1479 | |||
| 1480 | bool SDL_PollEvent(SDL_Event *event) | ||
| 1481 | { | ||
| 1482 | return SDL_WaitEventTimeoutNS(event, 0); | ||
| 1483 | } | ||
| 1484 | |||
| 1485 | #ifndef SDL_PLATFORM_ANDROID | ||
| 1486 | |||
| 1487 | static Sint64 SDL_events_get_polling_interval(void) | ||
| 1488 | { | ||
| 1489 | Sint64 poll_intervalNS = SDL_MAX_SINT64; | ||
| 1490 | |||
| 1491 | #ifndef SDL_JOYSTICK_DISABLED | ||
| 1492 | if (SDL_WasInit(SDL_INIT_JOYSTICK) && SDL_update_joysticks) { | ||
| 1493 | if (SDL_JoysticksOpened()) { | ||
| 1494 | // If we have joysticks open, we need to poll rapidly for events | ||
| 1495 | poll_intervalNS = SDL_min(poll_intervalNS, EVENT_POLL_INTERVAL_NS); | ||
| 1496 | } else { | ||
| 1497 | // If not, just poll every few seconds to enumerate new joysticks | ||
| 1498 | poll_intervalNS = SDL_min(poll_intervalNS, ENUMERATION_POLL_INTERVAL_NS); | ||
| 1499 | } | ||
| 1500 | } | ||
| 1501 | #endif | ||
| 1502 | |||
| 1503 | #ifndef SDL_SENSOR_DISABLED | ||
| 1504 | if (SDL_WasInit(SDL_INIT_SENSOR) && SDL_update_sensors && SDL_SensorsOpened()) { | ||
| 1505 | // If we have sensors open, we need to poll rapidly for events | ||
| 1506 | poll_intervalNS = SDL_min(poll_intervalNS, EVENT_POLL_INTERVAL_NS); | ||
| 1507 | } | ||
| 1508 | #endif | ||
| 1509 | |||
| 1510 | return poll_intervalNS; | ||
| 1511 | } | ||
| 1512 | |||
| 1513 | static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeup_window, SDL_Event *event, Uint64 start, Sint64 timeoutNS) | ||
| 1514 | { | ||
| 1515 | Sint64 loop_timeoutNS = timeoutNS; | ||
| 1516 | Sint64 poll_intervalNS = SDL_events_get_polling_interval(); | ||
| 1517 | |||
| 1518 | for (;;) { | ||
| 1519 | int status; | ||
| 1520 | /* Pump events on entry and each time we wake to ensure: | ||
| 1521 | a) All pending events are batch processed after waking up from a wait | ||
| 1522 | b) Waiting can be completely skipped if events are already available to be pumped | ||
| 1523 | c) Periodic processing that takes place in some platform PumpEvents() functions happens | ||
| 1524 | d) Signals received in WaitEventTimeout() are turned into SDL events | ||
| 1525 | */ | ||
| 1526 | SDL_PumpEventsInternal(true); | ||
| 1527 | |||
| 1528 | SDL_LockMutex(_this->wakeup_lock); | ||
| 1529 | { | ||
| 1530 | status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST); | ||
| 1531 | // If status == 0 we are going to block so wakeup will be needed. | ||
| 1532 | if (status == 0) { | ||
| 1533 | _this->wakeup_window = wakeup_window; | ||
| 1534 | } else { | ||
| 1535 | _this->wakeup_window = NULL; | ||
| 1536 | } | ||
| 1537 | } | ||
| 1538 | SDL_UnlockMutex(_this->wakeup_lock); | ||
| 1539 | |||
| 1540 | if (status < 0) { | ||
| 1541 | // Got an error: return | ||
| 1542 | break; | ||
| 1543 | } | ||
| 1544 | if (status > 0) { | ||
| 1545 | // There is an event, we can return. | ||
| 1546 | return 1; | ||
| 1547 | } | ||
| 1548 | // No events found in the queue, call WaitEventTimeout to wait for an event. | ||
| 1549 | if (timeoutNS > 0) { | ||
| 1550 | Sint64 elapsed = SDL_GetTicksNS() - start; | ||
| 1551 | if (elapsed >= timeoutNS) { | ||
| 1552 | // Set wakeup_window to NULL without holding the lock. | ||
| 1553 | _this->wakeup_window = NULL; | ||
| 1554 | return 0; | ||
| 1555 | } | ||
| 1556 | loop_timeoutNS = (timeoutNS - elapsed); | ||
| 1557 | } | ||
| 1558 | // Adjust the timeout for any polling requirements we currently have. | ||
| 1559 | if (poll_intervalNS != SDL_MAX_SINT64) { | ||
| 1560 | if (loop_timeoutNS >= 0) { | ||
| 1561 | loop_timeoutNS = SDL_min(loop_timeoutNS, poll_intervalNS); | ||
| 1562 | } else { | ||
| 1563 | loop_timeoutNS = poll_intervalNS; | ||
| 1564 | } | ||
| 1565 | } | ||
| 1566 | status = _this->WaitEventTimeout(_this, loop_timeoutNS); | ||
| 1567 | // Set wakeup_window to NULL without holding the lock. | ||
| 1568 | _this->wakeup_window = NULL; | ||
| 1569 | if (status == 0 && poll_intervalNS != SDL_MAX_SINT64 && loop_timeoutNS == poll_intervalNS) { | ||
| 1570 | // We may have woken up to poll. Try again | ||
| 1571 | continue; | ||
| 1572 | } else if (status <= 0) { | ||
| 1573 | // There is either an error or the timeout is elapsed: return | ||
| 1574 | return status; | ||
| 1575 | } | ||
| 1576 | /* An event was found and pumped into the SDL events queue. Continue the loop | ||
| 1577 | to let SDL_PeepEvents pick it up .*/ | ||
| 1578 | } | ||
| 1579 | return 0; | ||
| 1580 | } | ||
| 1581 | |||
| 1582 | static SDL_Window *SDL_find_active_window(SDL_VideoDevice *_this) | ||
| 1583 | { | ||
| 1584 | SDL_Window *window; | ||
| 1585 | for (window = _this->windows; window; window = window->next) { | ||
| 1586 | if (!window->is_destroying) { | ||
| 1587 | return window; | ||
| 1588 | } | ||
| 1589 | } | ||
| 1590 | return NULL; | ||
| 1591 | } | ||
| 1592 | |||
| 1593 | #endif // !SDL_PLATFORM_ANDROID | ||
| 1594 | |||
| 1595 | bool SDL_WaitEvent(SDL_Event *event) | ||
| 1596 | { | ||
| 1597 | return SDL_WaitEventTimeoutNS(event, -1); | ||
| 1598 | } | ||
| 1599 | |||
| 1600 | bool SDL_WaitEventTimeout(SDL_Event *event, Sint32 timeoutMS) | ||
| 1601 | { | ||
| 1602 | Sint64 timeoutNS; | ||
| 1603 | |||
| 1604 | if (timeoutMS > 0) { | ||
| 1605 | timeoutNS = SDL_MS_TO_NS(timeoutMS); | ||
| 1606 | } else { | ||
| 1607 | timeoutNS = timeoutMS; | ||
| 1608 | } | ||
| 1609 | return SDL_WaitEventTimeoutNS(event, timeoutNS); | ||
| 1610 | } | ||
| 1611 | |||
| 1612 | bool SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS) | ||
| 1613 | { | ||
| 1614 | Uint64 start, expiration; | ||
| 1615 | bool include_sentinel = (timeoutNS == 0); | ||
| 1616 | int result; | ||
| 1617 | |||
| 1618 | if (timeoutNS > 0) { | ||
| 1619 | start = SDL_GetTicksNS(); | ||
| 1620 | expiration = start + timeoutNS; | ||
| 1621 | } else { | ||
| 1622 | start = 0; | ||
| 1623 | expiration = 0; | ||
| 1624 | } | ||
| 1625 | |||
| 1626 | // If there isn't a poll sentinel event pending, pump events and add one | ||
| 1627 | if (SDL_GetAtomicInt(&SDL_sentinel_pending) == 0) { | ||
| 1628 | SDL_PumpEventsInternal(true); | ||
| 1629 | } | ||
| 1630 | |||
| 1631 | // First check for existing events | ||
| 1632 | result = SDL_PeepEventsInternal(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST, include_sentinel); | ||
| 1633 | if (result < 0) { | ||
| 1634 | return false; | ||
| 1635 | } | ||
| 1636 | if (include_sentinel) { | ||
| 1637 | if (event) { | ||
| 1638 | if (event->type == SDL_EVENT_POLL_SENTINEL) { | ||
| 1639 | // Reached the end of a poll cycle, and not willing to wait | ||
| 1640 | return false; | ||
| 1641 | } | ||
| 1642 | } else { | ||
| 1643 | // Need to peek the next event to check for sentinel | ||
| 1644 | SDL_Event dummy; | ||
| 1645 | |||
| 1646 | if (SDL_PeepEventsInternal(&dummy, 1, SDL_PEEKEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST, true) && | ||
| 1647 | dummy.type == SDL_EVENT_POLL_SENTINEL) { | ||
| 1648 | SDL_PeepEventsInternal(&dummy, 1, SDL_GETEVENT, SDL_EVENT_POLL_SENTINEL, SDL_EVENT_POLL_SENTINEL, true); | ||
| 1649 | // Reached the end of a poll cycle, and not willing to wait | ||
| 1650 | return false; | ||
| 1651 | } | ||
| 1652 | } | ||
| 1653 | } | ||
| 1654 | if (result == 0) { | ||
| 1655 | if (timeoutNS == 0) { | ||
| 1656 | // No events available, and not willing to wait | ||
| 1657 | return false; | ||
| 1658 | } | ||
| 1659 | } else { | ||
| 1660 | // Has existing events | ||
| 1661 | return true; | ||
| 1662 | } | ||
| 1663 | // We should have completely handled timeoutNS == 0 above | ||
| 1664 | SDL_assert(timeoutNS != 0); | ||
| 1665 | |||
| 1666 | #ifdef SDL_PLATFORM_ANDROID | ||
| 1667 | for (;;) { | ||
| 1668 | if (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST) > 0) { | ||
| 1669 | return true; | ||
| 1670 | } | ||
| 1671 | |||
| 1672 | Uint64 delay = -1; | ||
| 1673 | if (timeoutNS > 0) { | ||
| 1674 | Uint64 now = SDL_GetTicksNS(); | ||
| 1675 | if (now >= expiration) { | ||
| 1676 | // Timeout expired and no events | ||
| 1677 | return false; | ||
| 1678 | } | ||
| 1679 | delay = (expiration - now); | ||
| 1680 | } | ||
| 1681 | Android_PumpEvents(delay); | ||
| 1682 | } | ||
| 1683 | #else | ||
| 1684 | SDL_VideoDevice *_this = SDL_GetVideoDevice(); | ||
| 1685 | if (_this && _this->WaitEventTimeout && _this->SendWakeupEvent) { | ||
| 1686 | // Look if a shown window is available to send the wakeup event. | ||
| 1687 | SDL_Window *wakeup_window = SDL_find_active_window(_this); | ||
| 1688 | if (wakeup_window) { | ||
| 1689 | result = SDL_WaitEventTimeout_Device(_this, wakeup_window, event, start, timeoutNS); | ||
| 1690 | if (result > 0) { | ||
| 1691 | return true; | ||
| 1692 | } else if (result == 0) { | ||
| 1693 | return false; | ||
| 1694 | } else { | ||
| 1695 | /* There may be implementation-defined conditions where the backend cannot | ||
| 1696 | * reliably wait for the next event. If that happens, fall back to polling. | ||
| 1697 | */ | ||
| 1698 | } | ||
| 1699 | } | ||
| 1700 | } | ||
| 1701 | |||
| 1702 | for (;;) { | ||
| 1703 | SDL_PumpEventsInternal(true); | ||
| 1704 | |||
| 1705 | if (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST) > 0) { | ||
| 1706 | return true; | ||
| 1707 | } | ||
| 1708 | |||
| 1709 | Uint64 delay = EVENT_POLL_INTERVAL_NS; | ||
| 1710 | if (timeoutNS > 0) { | ||
| 1711 | Uint64 now = SDL_GetTicksNS(); | ||
| 1712 | if (now >= expiration) { | ||
| 1713 | // Timeout expired and no events | ||
| 1714 | return false; | ||
| 1715 | } | ||
| 1716 | delay = SDL_min((expiration - now), delay); | ||
| 1717 | } | ||
| 1718 | SDL_DelayNS(delay); | ||
| 1719 | } | ||
| 1720 | #endif // SDL_PLATFORM_ANDROID | ||
| 1721 | } | ||
| 1722 | |||
| 1723 | static bool SDL_CallEventWatchers(SDL_Event *event) | ||
| 1724 | { | ||
| 1725 | if (event->common.type == SDL_EVENT_POLL_SENTINEL) { | ||
| 1726 | return true; | ||
| 1727 | } | ||
| 1728 | |||
| 1729 | return SDL_DispatchEventWatchList(&SDL_event_watchers, event); | ||
| 1730 | } | ||
| 1731 | |||
| 1732 | bool SDL_PushEvent(SDL_Event *event) | ||
| 1733 | { | ||
| 1734 | if (!event->common.timestamp) { | ||
| 1735 | event->common.timestamp = SDL_GetTicksNS(); | ||
| 1736 | } | ||
| 1737 | |||
| 1738 | if (!SDL_CallEventWatchers(event)) { | ||
| 1739 | SDL_ClearError(); | ||
| 1740 | return false; | ||
| 1741 | } | ||
| 1742 | |||
| 1743 | if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) { | ||
| 1744 | return false; | ||
| 1745 | } | ||
| 1746 | |||
| 1747 | return true; | ||
| 1748 | } | ||
| 1749 | |||
| 1750 | void SDL_SetEventFilter(SDL_EventFilter filter, void *userdata) | ||
| 1751 | { | ||
| 1752 | SDL_EventEntry *event, *next; | ||
| 1753 | SDL_LockMutex(SDL_event_watchers.lock); | ||
| 1754 | { | ||
| 1755 | // Set filter and discard pending events | ||
| 1756 | SDL_event_watchers.filter.callback = filter; | ||
| 1757 | SDL_event_watchers.filter.userdata = userdata; | ||
| 1758 | if (filter) { | ||
| 1759 | // Cut all events not accepted by the filter | ||
| 1760 | SDL_LockMutex(SDL_EventQ.lock); | ||
| 1761 | { | ||
| 1762 | for (event = SDL_EventQ.head; event; event = next) { | ||
| 1763 | next = event->next; | ||
| 1764 | if (!filter(userdata, &event->event)) { | ||
| 1765 | SDL_CutEvent(event); | ||
| 1766 | } | ||
| 1767 | } | ||
| 1768 | } | ||
| 1769 | SDL_UnlockMutex(SDL_EventQ.lock); | ||
| 1770 | } | ||
| 1771 | } | ||
| 1772 | SDL_UnlockMutex(SDL_event_watchers.lock); | ||
| 1773 | } | ||
| 1774 | |||
| 1775 | bool SDL_GetEventFilter(SDL_EventFilter *filter, void **userdata) | ||
| 1776 | { | ||
| 1777 | SDL_EventWatcher event_ok; | ||
| 1778 | |||
| 1779 | SDL_LockMutex(SDL_event_watchers.lock); | ||
| 1780 | { | ||
| 1781 | event_ok = SDL_event_watchers.filter; | ||
| 1782 | } | ||
| 1783 | SDL_UnlockMutex(SDL_event_watchers.lock); | ||
| 1784 | |||
| 1785 | if (filter) { | ||
| 1786 | *filter = event_ok.callback; | ||
| 1787 | } | ||
| 1788 | if (userdata) { | ||
| 1789 | *userdata = event_ok.userdata; | ||
| 1790 | } | ||
| 1791 | return event_ok.callback ? true : false; | ||
| 1792 | } | ||
| 1793 | |||
| 1794 | bool SDL_AddEventWatch(SDL_EventFilter filter, void *userdata) | ||
| 1795 | { | ||
| 1796 | return SDL_AddEventWatchList(&SDL_event_watchers, filter, userdata); | ||
| 1797 | } | ||
| 1798 | |||
| 1799 | void SDL_RemoveEventWatch(SDL_EventFilter filter, void *userdata) | ||
| 1800 | { | ||
| 1801 | SDL_RemoveEventWatchList(&SDL_event_watchers, filter, userdata); | ||
| 1802 | } | ||
| 1803 | |||
| 1804 | void SDL_FilterEvents(SDL_EventFilter filter, void *userdata) | ||
| 1805 | { | ||
| 1806 | SDL_LockMutex(SDL_EventQ.lock); | ||
| 1807 | { | ||
| 1808 | SDL_EventEntry *entry, *next; | ||
| 1809 | for (entry = SDL_EventQ.head; entry; entry = next) { | ||
| 1810 | next = entry->next; | ||
| 1811 | if (!filter(userdata, &entry->event)) { | ||
| 1812 | SDL_CutEvent(entry); | ||
| 1813 | } | ||
| 1814 | } | ||
| 1815 | } | ||
| 1816 | SDL_UnlockMutex(SDL_EventQ.lock); | ||
| 1817 | } | ||
| 1818 | |||
| 1819 | void SDL_SetEventEnabled(Uint32 type, bool enabled) | ||
| 1820 | { | ||
| 1821 | bool current_state; | ||
| 1822 | Uint8 hi = ((type >> 8) & 0xff); | ||
| 1823 | Uint8 lo = (type & 0xff); | ||
| 1824 | |||
| 1825 | if (SDL_disabled_events[hi] && | ||
| 1826 | (SDL_disabled_events[hi]->bits[lo / 32] & (1 << (lo & 31)))) { | ||
| 1827 | current_state = false; | ||
| 1828 | } else { | ||
| 1829 | current_state = true; | ||
| 1830 | } | ||
| 1831 | |||
| 1832 | if ((enabled != false) != current_state) { | ||
| 1833 | if (enabled) { | ||
| 1834 | SDL_assert(SDL_disabled_events[hi] != NULL); | ||
| 1835 | SDL_disabled_events[hi]->bits[lo / 32] &= ~(1 << (lo & 31)); | ||
| 1836 | |||
| 1837 | // Gamepad events depend on joystick events | ||
| 1838 | switch (type) { | ||
| 1839 | case SDL_EVENT_GAMEPAD_ADDED: | ||
| 1840 | SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_ADDED, true); | ||
| 1841 | break; | ||
| 1842 | case SDL_EVENT_GAMEPAD_REMOVED: | ||
| 1843 | SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_REMOVED, true); | ||
| 1844 | break; | ||
| 1845 | case SDL_EVENT_GAMEPAD_AXIS_MOTION: | ||
| 1846 | case SDL_EVENT_GAMEPAD_BUTTON_DOWN: | ||
| 1847 | case SDL_EVENT_GAMEPAD_BUTTON_UP: | ||
| 1848 | SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_AXIS_MOTION, true); | ||
| 1849 | SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_HAT_MOTION, true); | ||
| 1850 | SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_BUTTON_DOWN, true); | ||
| 1851 | SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_BUTTON_UP, true); | ||
| 1852 | break; | ||
| 1853 | case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE: | ||
| 1854 | SDL_SetEventEnabled(SDL_EVENT_JOYSTICK_UPDATE_COMPLETE, true); | ||
| 1855 | break; | ||
| 1856 | default: | ||
| 1857 | break; | ||
| 1858 | } | ||
| 1859 | } else { | ||
| 1860 | // Disable this event type and discard pending events | ||
| 1861 | if (!SDL_disabled_events[hi]) { | ||
| 1862 | SDL_disabled_events[hi] = (SDL_DisabledEventBlock *)SDL_calloc(1, sizeof(SDL_DisabledEventBlock)); | ||
| 1863 | } | ||
| 1864 | // Out of memory, nothing we can do... | ||
| 1865 | if (SDL_disabled_events[hi]) { | ||
| 1866 | SDL_disabled_events[hi]->bits[lo / 32] |= (1 << (lo & 31)); | ||
| 1867 | SDL_FlushEvent(type); | ||
| 1868 | } | ||
| 1869 | } | ||
| 1870 | |||
| 1871 | /* turn off drag'n'drop support if we've disabled the events. | ||
| 1872 | This might change some UI details at the OS level. */ | ||
| 1873 | if (type == SDL_EVENT_DROP_FILE || type == SDL_EVENT_DROP_TEXT) { | ||
| 1874 | SDL_ToggleDragAndDropSupport(); | ||
| 1875 | } | ||
| 1876 | } | ||
| 1877 | } | ||
| 1878 | |||
| 1879 | bool SDL_EventEnabled(Uint32 type) | ||
| 1880 | { | ||
| 1881 | Uint8 hi = ((type >> 8) & 0xff); | ||
| 1882 | Uint8 lo = (type & 0xff); | ||
| 1883 | |||
| 1884 | if (SDL_disabled_events[hi] && | ||
| 1885 | (SDL_disabled_events[hi]->bits[lo / 32] & (1 << (lo & 31)))) { | ||
| 1886 | return false; | ||
| 1887 | } else { | ||
| 1888 | return true; | ||
| 1889 | } | ||
| 1890 | } | ||
| 1891 | |||
| 1892 | Uint32 SDL_RegisterEvents(int numevents) | ||
| 1893 | { | ||
| 1894 | Uint32 event_base = 0; | ||
| 1895 | |||
| 1896 | if (numevents > 0) { | ||
| 1897 | int value = SDL_AddAtomicInt(&SDL_userevents, numevents); | ||
| 1898 | if (value >= 0 && value <= (SDL_EVENT_LAST - SDL_EVENT_USER)) { | ||
| 1899 | event_base = (Uint32)(SDL_EVENT_USER + value); | ||
| 1900 | } | ||
| 1901 | } | ||
| 1902 | return event_base; | ||
| 1903 | } | ||
| 1904 | |||
| 1905 | void SDL_SendAppEvent(SDL_EventType eventType) | ||
| 1906 | { | ||
| 1907 | if (SDL_EventEnabled(eventType)) { | ||
| 1908 | SDL_Event event; | ||
| 1909 | event.type = eventType; | ||
| 1910 | event.common.timestamp = 0; | ||
| 1911 | |||
| 1912 | switch (eventType) { | ||
| 1913 | case SDL_EVENT_TERMINATING: | ||
| 1914 | case SDL_EVENT_LOW_MEMORY: | ||
| 1915 | case SDL_EVENT_WILL_ENTER_BACKGROUND: | ||
| 1916 | case SDL_EVENT_DID_ENTER_BACKGROUND: | ||
| 1917 | case SDL_EVENT_WILL_ENTER_FOREGROUND: | ||
| 1918 | case SDL_EVENT_DID_ENTER_FOREGROUND: | ||
| 1919 | // We won't actually queue this event, it needs to be handled in this call stack by an event watcher | ||
| 1920 | if (SDL_EventLoggingVerbosity > 0) { | ||
| 1921 | SDL_LogEvent(&event); | ||
| 1922 | } | ||
| 1923 | SDL_CallEventWatchers(&event); | ||
| 1924 | break; | ||
| 1925 | default: | ||
| 1926 | SDL_PushEvent(&event); | ||
| 1927 | break; | ||
| 1928 | } | ||
| 1929 | } | ||
| 1930 | } | ||
| 1931 | |||
| 1932 | void SDL_SendKeymapChangedEvent(void) | ||
| 1933 | { | ||
| 1934 | SDL_SendAppEvent(SDL_EVENT_KEYMAP_CHANGED); | ||
| 1935 | } | ||
| 1936 | |||
| 1937 | void SDL_SendLocaleChangedEvent(void) | ||
| 1938 | { | ||
| 1939 | SDL_SendAppEvent(SDL_EVENT_LOCALE_CHANGED); | ||
| 1940 | } | ||
| 1941 | |||
| 1942 | void SDL_SendSystemThemeChangedEvent(void) | ||
| 1943 | { | ||
| 1944 | SDL_SendAppEvent(SDL_EVENT_SYSTEM_THEME_CHANGED); | ||
| 1945 | } | ||
| 1946 | |||
| 1947 | bool SDL_InitEvents(void) | ||
| 1948 | { | ||
| 1949 | #ifdef SDL_PLATFORM_ANDROID | ||
| 1950 | Android_InitEvents(); | ||
| 1951 | #endif | ||
| 1952 | #ifndef SDL_JOYSTICK_DISABLED | ||
| 1953 | SDL_AddHintCallback(SDL_HINT_AUTO_UPDATE_JOYSTICKS, SDL_AutoUpdateJoysticksChanged, NULL); | ||
| 1954 | #endif | ||
| 1955 | #ifndef SDL_SENSOR_DISABLED | ||
| 1956 | SDL_AddHintCallback(SDL_HINT_AUTO_UPDATE_SENSORS, SDL_AutoUpdateSensorsChanged, NULL); | ||
| 1957 | #endif | ||
| 1958 | SDL_AddHintCallback(SDL_HINT_EVENT_LOGGING, SDL_EventLoggingChanged, NULL); | ||
| 1959 | SDL_AddHintCallback(SDL_HINT_POLL_SENTINEL, SDL_PollSentinelChanged, NULL); | ||
| 1960 | SDL_InitMainThreadCallbacks(); | ||
| 1961 | if (!SDL_StartEventLoop()) { | ||
| 1962 | SDL_RemoveHintCallback(SDL_HINT_EVENT_LOGGING, SDL_EventLoggingChanged, NULL); | ||
| 1963 | return false; | ||
| 1964 | } | ||
| 1965 | |||
| 1966 | SDL_InitQuit(); | ||
| 1967 | |||
| 1968 | return true; | ||
| 1969 | } | ||
| 1970 | |||
| 1971 | void SDL_QuitEvents(void) | ||
| 1972 | { | ||
| 1973 | SDL_QuitQuit(); | ||
| 1974 | SDL_StopEventLoop(); | ||
| 1975 | SDL_QuitMainThreadCallbacks(); | ||
| 1976 | SDL_RemoveHintCallback(SDL_HINT_POLL_SENTINEL, SDL_PollSentinelChanged, NULL); | ||
| 1977 | SDL_RemoveHintCallback(SDL_HINT_EVENT_LOGGING, SDL_EventLoggingChanged, NULL); | ||
| 1978 | #ifndef SDL_JOYSTICK_DISABLED | ||
| 1979 | SDL_RemoveHintCallback(SDL_HINT_AUTO_UPDATE_JOYSTICKS, SDL_AutoUpdateJoysticksChanged, NULL); | ||
| 1980 | #endif | ||
| 1981 | #ifndef SDL_SENSOR_DISABLED | ||
| 1982 | SDL_RemoveHintCallback(SDL_HINT_AUTO_UPDATE_SENSORS, SDL_AutoUpdateSensorsChanged, NULL); | ||
| 1983 | #endif | ||
| 1984 | #ifdef SDL_PLATFORM_ANDROID | ||
| 1985 | Android_QuitEvents(); | ||
| 1986 | #endif | ||
| 1987 | } | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_events_c.h b/contrib/SDL-3.2.8/src/events/SDL_events_c.h new file mode 100644 index 0000000..e56ac47 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_events_c.h | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #ifndef SDL_events_c_h_ | ||
| 23 | #define SDL_events_c_h_ | ||
| 24 | |||
| 25 | #include "SDL_internal.h" | ||
| 26 | |||
| 27 | // Useful functions and variables from SDL_events.c | ||
| 28 | #include "../video/SDL_sysvideo.h" | ||
| 29 | |||
| 30 | #include "SDL_clipboardevents_c.h" | ||
| 31 | #include "SDL_displayevents_c.h" | ||
| 32 | #include "SDL_dropevents_c.h" | ||
| 33 | #include "SDL_keyboard_c.h" | ||
| 34 | #include "SDL_mouse_c.h" | ||
| 35 | #include "SDL_touch_c.h" | ||
| 36 | #include "SDL_pen_c.h" | ||
| 37 | #include "SDL_windowevents_c.h" | ||
| 38 | |||
| 39 | // Start and stop the event processing loop | ||
| 40 | extern bool SDL_StartEventLoop(void); | ||
| 41 | extern void SDL_StopEventLoop(void); | ||
| 42 | extern void SDL_QuitInterrupt(void); | ||
| 43 | |||
| 44 | extern void SDL_SendAppEvent(SDL_EventType eventType); | ||
| 45 | extern void SDL_SendKeymapChangedEvent(void); | ||
| 46 | extern void SDL_SendLocaleChangedEvent(void); | ||
| 47 | extern void SDL_SendSystemThemeChangedEvent(void); | ||
| 48 | |||
| 49 | extern void *SDL_AllocateTemporaryMemory(size_t size); | ||
| 50 | extern const char *SDL_CreateTemporaryString(const char *string); | ||
| 51 | extern void *SDL_ClaimTemporaryMemory(const void *mem); | ||
| 52 | extern void SDL_FreeTemporaryMemory(void); | ||
| 53 | |||
| 54 | extern void SDL_PumpEventMaintenance(void); | ||
| 55 | |||
| 56 | extern void SDL_SendQuit(void); | ||
| 57 | |||
| 58 | extern bool SDL_InitEvents(void); | ||
| 59 | extern void SDL_QuitEvents(void); | ||
| 60 | |||
| 61 | extern void SDL_SendPendingSignalEvents(void); | ||
| 62 | |||
| 63 | extern bool SDL_InitQuit(void); | ||
| 64 | extern void SDL_QuitQuit(void); | ||
| 65 | |||
| 66 | #endif // SDL_events_c_h_ | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_eventwatch.c b/contrib/SDL-3.2.8/src/events/SDL_eventwatch.c new file mode 100644 index 0000000..08e7248 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_eventwatch.c | |||
| @@ -0,0 +1,143 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #include "SDL_eventwatch_c.h" | ||
| 24 | |||
| 25 | |||
| 26 | bool SDL_InitEventWatchList(SDL_EventWatchList *list) | ||
| 27 | { | ||
| 28 | if (list->lock == NULL) { | ||
| 29 | list->lock = SDL_CreateMutex(); | ||
| 30 | if (list->lock == NULL) { | ||
| 31 | return false; | ||
| 32 | } | ||
| 33 | } | ||
| 34 | return true; | ||
| 35 | } | ||
| 36 | |||
| 37 | void SDL_QuitEventWatchList(SDL_EventWatchList *list) | ||
| 38 | { | ||
| 39 | if (list->lock) { | ||
| 40 | SDL_DestroyMutex(list->lock); | ||
| 41 | list->lock = NULL; | ||
| 42 | } | ||
| 43 | if (list->watchers) { | ||
| 44 | SDL_free(list->watchers); | ||
| 45 | list->watchers = NULL; | ||
| 46 | list->count = 0; | ||
| 47 | } | ||
| 48 | SDL_zero(list->filter); | ||
| 49 | } | ||
| 50 | |||
| 51 | bool SDL_DispatchEventWatchList(SDL_EventWatchList *list, SDL_Event *event) | ||
| 52 | { | ||
| 53 | SDL_EventWatcher *filter = &list->filter; | ||
| 54 | |||
| 55 | if (!filter->callback && list->count == 0) { | ||
| 56 | return true; | ||
| 57 | } | ||
| 58 | |||
| 59 | SDL_LockMutex(list->lock); | ||
| 60 | { | ||
| 61 | // Make sure we only dispatch the current watcher list | ||
| 62 | int i, count = list->count; | ||
| 63 | |||
| 64 | if (filter->callback && !filter->callback(filter->userdata, event)) { | ||
| 65 | SDL_UnlockMutex(list->lock); | ||
| 66 | return false; | ||
| 67 | } | ||
| 68 | |||
| 69 | list->dispatching = true; | ||
| 70 | for (i = 0; i < count; ++i) { | ||
| 71 | if (!list->watchers[i].removed) { | ||
| 72 | list->watchers[i].callback(list->watchers[i].userdata, event); | ||
| 73 | } | ||
| 74 | } | ||
| 75 | list->dispatching = false; | ||
| 76 | |||
| 77 | if (list->removed) { | ||
| 78 | for (i = list->count; i--;) { | ||
| 79 | if (list->watchers[i].removed) { | ||
| 80 | --list->count; | ||
| 81 | if (i < list->count) { | ||
| 82 | SDL_memmove(&list->watchers[i], &list->watchers[i + 1], (list->count - i) * sizeof(list->watchers[i])); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | } | ||
| 86 | list->removed = false; | ||
| 87 | } | ||
| 88 | } | ||
| 89 | SDL_UnlockMutex(list->lock); | ||
| 90 | |||
| 91 | return true; | ||
| 92 | } | ||
| 93 | |||
| 94 | bool SDL_AddEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, void *userdata) | ||
| 95 | { | ||
| 96 | bool result = true; | ||
| 97 | |||
| 98 | SDL_LockMutex(list->lock); | ||
| 99 | { | ||
| 100 | SDL_EventWatcher *watchers; | ||
| 101 | |||
| 102 | watchers = (SDL_EventWatcher *)SDL_realloc(list->watchers, (list->count + 1) * sizeof(*watchers)); | ||
| 103 | if (watchers) { | ||
| 104 | SDL_EventWatcher *watcher; | ||
| 105 | |||
| 106 | list->watchers = watchers; | ||
| 107 | watcher = &list->watchers[list->count]; | ||
| 108 | watcher->callback = filter; | ||
| 109 | watcher->userdata = userdata; | ||
| 110 | watcher->removed = false; | ||
| 111 | ++list->count; | ||
| 112 | } else { | ||
| 113 | result = false; | ||
| 114 | } | ||
| 115 | } | ||
| 116 | SDL_UnlockMutex(list->lock); | ||
| 117 | |||
| 118 | return result; | ||
| 119 | } | ||
| 120 | |||
| 121 | void SDL_RemoveEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, void *userdata) | ||
| 122 | { | ||
| 123 | SDL_LockMutex(list->lock); | ||
| 124 | { | ||
| 125 | int i; | ||
| 126 | |||
| 127 | for (i = 0; i < list->count; ++i) { | ||
| 128 | if (list->watchers[i].callback == filter && list->watchers[i].userdata == userdata) { | ||
| 129 | if (list->dispatching) { | ||
| 130 | list->watchers[i].removed = true; | ||
| 131 | list->removed = true; | ||
| 132 | } else { | ||
| 133 | --list->count; | ||
| 134 | if (i < list->count) { | ||
| 135 | SDL_memmove(&list->watchers[i], &list->watchers[i + 1], (list->count - i) * sizeof(list->watchers[i])); | ||
| 136 | } | ||
| 137 | } | ||
| 138 | break; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | } | ||
| 142 | SDL_UnlockMutex(list->lock); | ||
| 143 | } | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_eventwatch_c.h b/contrib/SDL-3.2.8/src/events/SDL_eventwatch_c.h new file mode 100644 index 0000000..c9aea38 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_eventwatch_c.h | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | typedef struct SDL_EventWatcher | ||
| 24 | { | ||
| 25 | SDL_EventFilter callback; | ||
| 26 | void *userdata; | ||
| 27 | bool removed; | ||
| 28 | } SDL_EventWatcher; | ||
| 29 | |||
| 30 | typedef struct SDL_EventWatchList | ||
| 31 | { | ||
| 32 | SDL_Mutex *lock; | ||
| 33 | SDL_EventWatcher filter; | ||
| 34 | SDL_EventWatcher *watchers; | ||
| 35 | int count; | ||
| 36 | bool dispatching; | ||
| 37 | bool removed; | ||
| 38 | } SDL_EventWatchList; | ||
| 39 | |||
| 40 | |||
| 41 | extern bool SDL_InitEventWatchList(SDL_EventWatchList *list); | ||
| 42 | extern void SDL_QuitEventWatchList(SDL_EventWatchList *list); | ||
| 43 | extern bool SDL_DispatchEventWatchList(SDL_EventWatchList *list, SDL_Event *event); | ||
| 44 | extern bool SDL_AddEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, void *userdata); | ||
| 45 | extern void SDL_RemoveEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, void *userdata); | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_keyboard.c b/contrib/SDL-3.2.8/src/events/SDL_keyboard.c new file mode 100644 index 0000000..066c6e6 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_keyboard.c | |||
| @@ -0,0 +1,922 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | // General keyboard handling code for SDL | ||
| 24 | |||
| 25 | #include "SDL_events_c.h" | ||
| 26 | #include "SDL_keymap_c.h" | ||
| 27 | #include "../video/SDL_sysvideo.h" | ||
| 28 | |||
| 29 | #if 0 | ||
| 30 | #define DEBUG_KEYBOARD | ||
| 31 | #endif | ||
| 32 | |||
| 33 | // Global keyboard information | ||
| 34 | |||
| 35 | #define KEYBOARD_HARDWARE 0x01 | ||
| 36 | #define KEYBOARD_VIRTUAL 0x02 | ||
| 37 | #define KEYBOARD_AUTORELEASE 0x04 | ||
| 38 | #define KEYBOARD_IGNOREMODIFIERS 0x08 | ||
| 39 | |||
| 40 | #define KEYBOARD_SOURCE_MASK (KEYBOARD_HARDWARE | KEYBOARD_AUTORELEASE) | ||
| 41 | |||
| 42 | #define KEYCODE_OPTION_HIDE_NUMPAD 0x01 | ||
| 43 | #define KEYCODE_OPTION_FRENCH_NUMBERS 0x02 | ||
| 44 | #define KEYCODE_OPTION_LATIN_LETTERS 0x04 | ||
| 45 | #define DEFAULT_KEYCODE_OPTIONS (KEYCODE_OPTION_FRENCH_NUMBERS | KEYCODE_OPTION_LATIN_LETTERS) | ||
| 46 | |||
| 47 | typedef struct SDL_KeyboardInstance | ||
| 48 | { | ||
| 49 | SDL_KeyboardID instance_id; | ||
| 50 | char *name; | ||
| 51 | } SDL_KeyboardInstance; | ||
| 52 | |||
| 53 | typedef struct SDL_Keyboard | ||
| 54 | { | ||
| 55 | // Data common to all keyboards | ||
| 56 | SDL_Window *focus; | ||
| 57 | SDL_Keymod modstate; | ||
| 58 | Uint8 keysource[SDL_SCANCODE_COUNT]; | ||
| 59 | bool keystate[SDL_SCANCODE_COUNT]; | ||
| 60 | SDL_Keymap *keymap; | ||
| 61 | bool french_numbers; | ||
| 62 | bool latin_letters; | ||
| 63 | bool thai_keyboard; | ||
| 64 | Uint32 keycode_options; | ||
| 65 | bool autorelease_pending; | ||
| 66 | Uint64 hardware_timestamp; | ||
| 67 | int next_reserved_scancode; | ||
| 68 | } SDL_Keyboard; | ||
| 69 | |||
| 70 | static SDL_Keyboard SDL_keyboard; | ||
| 71 | static int SDL_keyboard_count; | ||
| 72 | static SDL_KeyboardInstance *SDL_keyboards; | ||
| 73 | |||
| 74 | static void SDLCALL SDL_KeycodeOptionsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 75 | { | ||
| 76 | SDL_Keyboard *keyboard = (SDL_Keyboard *)userdata; | ||
| 77 | |||
| 78 | if (hint && *hint) { | ||
| 79 | keyboard->keycode_options = 0; | ||
| 80 | if (!SDL_strstr(hint, "none")) { | ||
| 81 | if (SDL_strstr(hint, "hide_numpad")) { | ||
| 82 | keyboard->keycode_options |= KEYCODE_OPTION_HIDE_NUMPAD; | ||
| 83 | } | ||
| 84 | if (SDL_strstr(hint, "french_numbers")) { | ||
| 85 | keyboard->keycode_options |= KEYCODE_OPTION_FRENCH_NUMBERS; | ||
| 86 | } | ||
| 87 | if (SDL_strstr(hint, "latin_letters")) { | ||
| 88 | keyboard->keycode_options |= KEYCODE_OPTION_LATIN_LETTERS; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | } else { | ||
| 92 | keyboard->keycode_options = DEFAULT_KEYCODE_OPTIONS; | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | // Public functions | ||
| 97 | bool SDL_InitKeyboard(void) | ||
| 98 | { | ||
| 99 | SDL_AddHintCallback(SDL_HINT_KEYCODE_OPTIONS, | ||
| 100 | SDL_KeycodeOptionsChanged, &SDL_keyboard); | ||
| 101 | return true; | ||
| 102 | } | ||
| 103 | |||
| 104 | bool SDL_IsKeyboard(Uint16 vendor, Uint16 product, int num_keys) | ||
| 105 | { | ||
| 106 | const int REAL_KEYBOARD_KEY_COUNT = 50; | ||
| 107 | if (num_keys > 0 && num_keys < REAL_KEYBOARD_KEY_COUNT) { | ||
| 108 | return false; | ||
| 109 | } | ||
| 110 | |||
| 111 | // Eventually we'll have a blacklist of devices that enumerate as keyboards but aren't really | ||
| 112 | return true; | ||
| 113 | } | ||
| 114 | |||
| 115 | static int SDL_GetKeyboardIndex(SDL_KeyboardID keyboardID) | ||
| 116 | { | ||
| 117 | for (int i = 0; i < SDL_keyboard_count; ++i) { | ||
| 118 | if (keyboardID == SDL_keyboards[i].instance_id) { | ||
| 119 | return i; | ||
| 120 | } | ||
| 121 | } | ||
| 122 | return -1; | ||
| 123 | } | ||
| 124 | |||
| 125 | void SDL_AddKeyboard(SDL_KeyboardID keyboardID, const char *name, bool send_event) | ||
| 126 | { | ||
| 127 | int keyboard_index = SDL_GetKeyboardIndex(keyboardID); | ||
| 128 | if (keyboard_index >= 0) { | ||
| 129 | // We already know about this keyboard | ||
| 130 | return; | ||
| 131 | } | ||
| 132 | |||
| 133 | SDL_assert(keyboardID != 0); | ||
| 134 | |||
| 135 | SDL_KeyboardInstance *keyboards = (SDL_KeyboardInstance *)SDL_realloc(SDL_keyboards, (SDL_keyboard_count + 1) * sizeof(*keyboards)); | ||
| 136 | if (!keyboards) { | ||
| 137 | return; | ||
| 138 | } | ||
| 139 | SDL_KeyboardInstance *instance = &keyboards[SDL_keyboard_count]; | ||
| 140 | instance->instance_id = keyboardID; | ||
| 141 | instance->name = SDL_strdup(name ? name : ""); | ||
| 142 | SDL_keyboards = keyboards; | ||
| 143 | ++SDL_keyboard_count; | ||
| 144 | |||
| 145 | if (send_event) { | ||
| 146 | SDL_Event event; | ||
| 147 | SDL_zero(event); | ||
| 148 | event.type = SDL_EVENT_KEYBOARD_ADDED; | ||
| 149 | event.kdevice.which = keyboardID; | ||
| 150 | SDL_PushEvent(&event); | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 154 | void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID, bool send_event) | ||
| 155 | { | ||
| 156 | int keyboard_index = SDL_GetKeyboardIndex(keyboardID); | ||
| 157 | if (keyboard_index < 0) { | ||
| 158 | // We don't know about this keyboard | ||
| 159 | return; | ||
| 160 | } | ||
| 161 | |||
| 162 | SDL_free(SDL_keyboards[keyboard_index].name); | ||
| 163 | |||
| 164 | if (keyboard_index != SDL_keyboard_count - 1) { | ||
| 165 | SDL_memmove(&SDL_keyboards[keyboard_index], &SDL_keyboards[keyboard_index + 1], (SDL_keyboard_count - keyboard_index - 1) * sizeof(SDL_keyboards[keyboard_index])); | ||
| 166 | } | ||
| 167 | --SDL_keyboard_count; | ||
| 168 | |||
| 169 | if (send_event) { | ||
| 170 | SDL_Event event; | ||
| 171 | SDL_zero(event); | ||
| 172 | event.type = SDL_EVENT_KEYBOARD_REMOVED; | ||
| 173 | event.kdevice.which = keyboardID; | ||
| 174 | SDL_PushEvent(&event); | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | bool SDL_HasKeyboard(void) | ||
| 179 | { | ||
| 180 | return (SDL_keyboard_count > 0); | ||
| 181 | } | ||
| 182 | |||
| 183 | SDL_KeyboardID *SDL_GetKeyboards(int *count) | ||
| 184 | { | ||
| 185 | int i; | ||
| 186 | SDL_KeyboardID *keyboards; | ||
| 187 | |||
| 188 | keyboards = (SDL_JoystickID *)SDL_malloc((SDL_keyboard_count + 1) * sizeof(*keyboards)); | ||
| 189 | if (keyboards) { | ||
| 190 | if (count) { | ||
| 191 | *count = SDL_keyboard_count; | ||
| 192 | } | ||
| 193 | |||
| 194 | for (i = 0; i < SDL_keyboard_count; ++i) { | ||
| 195 | keyboards[i] = SDL_keyboards[i].instance_id; | ||
| 196 | } | ||
| 197 | keyboards[i] = 0; | ||
| 198 | } else { | ||
| 199 | if (count) { | ||
| 200 | *count = 0; | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | return keyboards; | ||
| 205 | } | ||
| 206 | |||
| 207 | const char *SDL_GetKeyboardNameForID(SDL_KeyboardID instance_id) | ||
| 208 | { | ||
| 209 | int keyboard_index = SDL_GetKeyboardIndex(instance_id); | ||
| 210 | if (keyboard_index < 0) { | ||
| 211 | SDL_SetError("Keyboard %" SDL_PRIu32 " not found", instance_id); | ||
| 212 | return NULL; | ||
| 213 | } | ||
| 214 | return SDL_GetPersistentString(SDL_keyboards[keyboard_index].name); | ||
| 215 | } | ||
| 216 | |||
| 217 | void SDL_ResetKeyboard(void) | ||
| 218 | { | ||
| 219 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 220 | int scancode; | ||
| 221 | |||
| 222 | #ifdef DEBUG_KEYBOARD | ||
| 223 | SDL_Log("Resetting keyboard"); | ||
| 224 | #endif | ||
| 225 | for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_SCANCODE_COUNT; ++scancode) { | ||
| 226 | if (keyboard->keystate[scancode]) { | ||
| 227 | SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, 0, (SDL_Scancode)scancode, false); | ||
| 228 | } | ||
| 229 | } | ||
| 230 | } | ||
| 231 | |||
| 232 | SDL_Keymap *SDL_GetCurrentKeymap(void) | ||
| 233 | { | ||
| 234 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 235 | |||
| 236 | if (keyboard->thai_keyboard) { | ||
| 237 | // Thai keyboards are QWERTY plus Thai characters, use the default QWERTY keymap | ||
| 238 | return NULL; | ||
| 239 | } | ||
| 240 | |||
| 241 | if ((keyboard->keycode_options & KEYCODE_OPTION_LATIN_LETTERS) && | ||
| 242 | !keyboard->latin_letters) { | ||
| 243 | // We'll use the default QWERTY keymap | ||
| 244 | return NULL; | ||
| 245 | } | ||
| 246 | |||
| 247 | return keyboard->keymap; | ||
| 248 | } | ||
| 249 | |||
| 250 | void SDL_SetKeymap(SDL_Keymap *keymap, bool send_event) | ||
| 251 | { | ||
| 252 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 253 | |||
| 254 | if (keyboard->keymap) { | ||
| 255 | SDL_DestroyKeymap(keyboard->keymap); | ||
| 256 | } | ||
| 257 | |||
| 258 | keyboard->keymap = keymap; | ||
| 259 | |||
| 260 | // Detect French number row (all symbols) | ||
| 261 | keyboard->french_numbers = true; | ||
| 262 | for (int i = SDL_SCANCODE_1; i <= SDL_SCANCODE_0; ++i) { | ||
| 263 | if (SDL_isdigit(SDL_GetKeymapKeycode(keymap, (SDL_Scancode)i, SDL_KMOD_NONE)) || | ||
| 264 | !SDL_isdigit(SDL_GetKeymapKeycode(keymap, (SDL_Scancode)i, SDL_KMOD_SHIFT))) { | ||
| 265 | keyboard->french_numbers = false; | ||
| 266 | break; | ||
| 267 | } | ||
| 268 | } | ||
| 269 | |||
| 270 | // Detect non-Latin keymap | ||
| 271 | keyboard->thai_keyboard = false; | ||
| 272 | keyboard->latin_letters = false; | ||
| 273 | for (int i = SDL_SCANCODE_A; i <= SDL_SCANCODE_D; ++i) { | ||
| 274 | SDL_Keycode key = SDL_GetKeymapKeycode(keymap, (SDL_Scancode)i, SDL_KMOD_NONE); | ||
| 275 | if (key <= 0xFF) { | ||
| 276 | keyboard->latin_letters = true; | ||
| 277 | break; | ||
| 278 | } | ||
| 279 | |||
| 280 | if (key >= 0x0E00 && key <= 0x0E7F) { | ||
| 281 | keyboard->thai_keyboard = true; | ||
| 282 | break; | ||
| 283 | } | ||
| 284 | } | ||
| 285 | |||
| 286 | if (send_event) { | ||
| 287 | SDL_SendKeymapChangedEvent(); | ||
| 288 | } | ||
| 289 | } | ||
| 290 | |||
| 291 | static SDL_Scancode GetNextReservedScancode(void) | ||
| 292 | { | ||
| 293 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 294 | SDL_Scancode scancode; | ||
| 295 | |||
| 296 | if (keyboard->next_reserved_scancode && keyboard->next_reserved_scancode < SDL_SCANCODE_RESERVED + 100) { | ||
| 297 | scancode = (SDL_Scancode)keyboard->next_reserved_scancode; | ||
| 298 | } else { | ||
| 299 | scancode = SDL_SCANCODE_RESERVED; | ||
| 300 | } | ||
| 301 | keyboard->next_reserved_scancode = (int)scancode + 1; | ||
| 302 | |||
| 303 | return scancode; | ||
| 304 | } | ||
| 305 | |||
| 306 | static void SetKeymapEntry(SDL_Scancode scancode, SDL_Keymod modstate, SDL_Keycode keycode) | ||
| 307 | { | ||
| 308 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 309 | |||
| 310 | if (!keyboard->keymap) { | ||
| 311 | keyboard->keymap = SDL_CreateKeymap(); | ||
| 312 | } | ||
| 313 | |||
| 314 | SDL_SetKeymapEntry(keyboard->keymap, scancode, modstate, keycode); | ||
| 315 | } | ||
| 316 | |||
| 317 | SDL_Window *SDL_GetKeyboardFocus(void) | ||
| 318 | { | ||
| 319 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 320 | |||
| 321 | return keyboard->focus; | ||
| 322 | } | ||
| 323 | |||
| 324 | bool SDL_SetKeyboardFocus(SDL_Window *window) | ||
| 325 | { | ||
| 326 | SDL_VideoDevice *video = SDL_GetVideoDevice(); | ||
| 327 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 328 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 329 | |||
| 330 | if (window) { | ||
| 331 | if (!SDL_ObjectValid(window, SDL_OBJECT_TYPE_WINDOW) || window->is_destroying) { | ||
| 332 | return SDL_SetError("Invalid window"); | ||
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | if (keyboard->focus && !window) { | ||
| 337 | // We won't get anymore keyboard messages, so reset keyboard state | ||
| 338 | SDL_ResetKeyboard(); | ||
| 339 | |||
| 340 | // Also leave mouse relative mode | ||
| 341 | if (mouse->relative_mode) { | ||
| 342 | SDL_SetRelativeMouseMode(false); | ||
| 343 | |||
| 344 | SDL_Window *focus = keyboard->focus; | ||
| 345 | if ((focus->flags & SDL_WINDOW_MINIMIZED) != 0) { | ||
| 346 | // We can't warp the mouse within minimized windows, so manually restore the position | ||
| 347 | float x = focus->x + mouse->x; | ||
| 348 | float y = focus->y + mouse->y; | ||
| 349 | SDL_WarpMouseGlobal(x, y); | ||
| 350 | } | ||
| 351 | } | ||
| 352 | } | ||
| 353 | |||
| 354 | // See if the current window has lost focus | ||
| 355 | if (keyboard->focus && keyboard->focus != window) { | ||
| 356 | SDL_SendWindowEvent(keyboard->focus, SDL_EVENT_WINDOW_FOCUS_LOST, 0, 0); | ||
| 357 | |||
| 358 | // Ensures IME compositions are committed | ||
| 359 | if (SDL_TextInputActive(keyboard->focus)) { | ||
| 360 | if (video && video->StopTextInput) { | ||
| 361 | video->StopTextInput(video, keyboard->focus); | ||
| 362 | } | ||
| 363 | } | ||
| 364 | } | ||
| 365 | |||
| 366 | keyboard->focus = window; | ||
| 367 | |||
| 368 | if (keyboard->focus) { | ||
| 369 | SDL_SendWindowEvent(keyboard->focus, SDL_EVENT_WINDOW_FOCUS_GAINED, 0, 0); | ||
| 370 | |||
| 371 | if (SDL_TextInputActive(keyboard->focus)) { | ||
| 372 | if (video && video->StartTextInput) { | ||
| 373 | video->StartTextInput(video, keyboard->focus, keyboard->focus->text_input_props); | ||
| 374 | } | ||
| 375 | } | ||
| 376 | } | ||
| 377 | |||
| 378 | SDL_UpdateRelativeMouseMode(); | ||
| 379 | |||
| 380 | return true; | ||
| 381 | } | ||
| 382 | |||
| 383 | static SDL_Keycode SDL_ConvertNumpadKeycode(SDL_Keycode keycode, bool numlock) | ||
| 384 | { | ||
| 385 | switch (keycode) { | ||
| 386 | case SDLK_KP_DIVIDE: | ||
| 387 | return SDLK_SLASH; | ||
| 388 | case SDLK_KP_MULTIPLY: | ||
| 389 | return SDLK_ASTERISK; | ||
| 390 | case SDLK_KP_MINUS: | ||
| 391 | return SDLK_MINUS; | ||
| 392 | case SDLK_KP_PLUS: | ||
| 393 | return SDLK_PLUS; | ||
| 394 | case SDLK_KP_ENTER: | ||
| 395 | return SDLK_RETURN; | ||
| 396 | case SDLK_KP_1: | ||
| 397 | return numlock ? SDLK_1 : SDLK_END; | ||
| 398 | case SDLK_KP_2: | ||
| 399 | return numlock ? SDLK_2 : SDLK_DOWN; | ||
| 400 | case SDLK_KP_3: | ||
| 401 | return numlock ? SDLK_3 : SDLK_PAGEDOWN; | ||
| 402 | case SDLK_KP_4: | ||
| 403 | return numlock ? SDLK_4 : SDLK_LEFT; | ||
| 404 | case SDLK_KP_5: | ||
| 405 | return numlock ? SDLK_5 : SDLK_CLEAR; | ||
| 406 | case SDLK_KP_6: | ||
| 407 | return numlock ? SDLK_6 : SDLK_RIGHT; | ||
| 408 | case SDLK_KP_7: | ||
| 409 | return numlock ? SDLK_7 : SDLK_HOME; | ||
| 410 | case SDLK_KP_8: | ||
| 411 | return numlock ? SDLK_8 : SDLK_UP; | ||
| 412 | case SDLK_KP_9: | ||
| 413 | return numlock ? SDLK_9 : SDLK_PAGEUP; | ||
| 414 | case SDLK_KP_0: | ||
| 415 | return numlock ? SDLK_0 : SDLK_INSERT; | ||
| 416 | case SDLK_KP_PERIOD: | ||
| 417 | return numlock ? SDLK_PERIOD : SDLK_DELETE; | ||
| 418 | case SDLK_KP_EQUALS: | ||
| 419 | return SDLK_EQUALS; | ||
| 420 | case SDLK_KP_COMMA: | ||
| 421 | return SDLK_COMMA; | ||
| 422 | case SDLK_KP_EQUALSAS400: | ||
| 423 | return SDLK_EQUALS; | ||
| 424 | case SDLK_KP_LEFTPAREN: | ||
| 425 | return SDLK_LEFTPAREN; | ||
| 426 | case SDLK_KP_RIGHTPAREN: | ||
| 427 | return SDLK_RIGHTPAREN; | ||
| 428 | case SDLK_KP_LEFTBRACE: | ||
| 429 | return SDLK_LEFTBRACE; | ||
| 430 | case SDLK_KP_RIGHTBRACE: | ||
| 431 | return SDLK_RIGHTBRACE; | ||
| 432 | case SDLK_KP_TAB: | ||
| 433 | return SDLK_TAB; | ||
| 434 | case SDLK_KP_BACKSPACE: | ||
| 435 | return SDLK_BACKSPACE; | ||
| 436 | case SDLK_KP_A: | ||
| 437 | return SDLK_A; | ||
| 438 | case SDLK_KP_B: | ||
| 439 | return SDLK_B; | ||
| 440 | case SDLK_KP_C: | ||
| 441 | return SDLK_C; | ||
| 442 | case SDLK_KP_D: | ||
| 443 | return SDLK_D; | ||
| 444 | case SDLK_KP_E: | ||
| 445 | return SDLK_E; | ||
| 446 | case SDLK_KP_F: | ||
| 447 | return SDLK_F; | ||
| 448 | case SDLK_KP_PERCENT: | ||
| 449 | return SDLK_PERCENT; | ||
| 450 | case SDLK_KP_LESS: | ||
| 451 | return SDLK_LESS; | ||
| 452 | case SDLK_KP_GREATER: | ||
| 453 | return SDLK_GREATER; | ||
| 454 | case SDLK_KP_AMPERSAND: | ||
| 455 | return SDLK_AMPERSAND; | ||
| 456 | case SDLK_KP_COLON: | ||
| 457 | return SDLK_COLON; | ||
| 458 | case SDLK_KP_HASH: | ||
| 459 | return SDLK_HASH; | ||
| 460 | case SDLK_KP_SPACE: | ||
| 461 | return SDLK_SPACE; | ||
| 462 | case SDLK_KP_AT: | ||
| 463 | return SDLK_AT; | ||
| 464 | case SDLK_KP_EXCLAM: | ||
| 465 | return SDLK_EXCLAIM; | ||
| 466 | case SDLK_KP_PLUSMINUS: | ||
| 467 | return SDLK_PLUSMINUS; | ||
| 468 | default: | ||
| 469 | return keycode; | ||
| 470 | } | ||
| 471 | } | ||
| 472 | |||
| 473 | SDL_Keycode SDL_GetKeyFromScancode(SDL_Scancode scancode, SDL_Keymod modstate, bool key_event) | ||
| 474 | { | ||
| 475 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 476 | |||
| 477 | if (key_event) { | ||
| 478 | SDL_Keymap *keymap = SDL_GetCurrentKeymap(); | ||
| 479 | bool numlock = (modstate & SDL_KMOD_NUM) != 0; | ||
| 480 | SDL_Keycode keycode; | ||
| 481 | |||
| 482 | // We won't be applying any modifiers by default | ||
| 483 | modstate = SDL_KMOD_NONE; | ||
| 484 | |||
| 485 | if ((keyboard->keycode_options & KEYCODE_OPTION_FRENCH_NUMBERS) && | ||
| 486 | keyboard->french_numbers && | ||
| 487 | (scancode >= SDL_SCANCODE_1 && scancode <= SDL_SCANCODE_0)) { | ||
| 488 | // Add the shift state to generate a numeric keycode | ||
| 489 | modstate |= SDL_KMOD_SHIFT; | ||
| 490 | } | ||
| 491 | |||
| 492 | keycode = SDL_GetKeymapKeycode(keymap, scancode, modstate); | ||
| 493 | |||
| 494 | if (keyboard->keycode_options & KEYCODE_OPTION_HIDE_NUMPAD) { | ||
| 495 | keycode = SDL_ConvertNumpadKeycode(keycode, numlock); | ||
| 496 | } | ||
| 497 | return keycode; | ||
| 498 | } | ||
| 499 | |||
| 500 | return SDL_GetKeymapKeycode(keyboard->keymap, scancode, modstate); | ||
| 501 | } | ||
| 502 | |||
| 503 | SDL_Scancode SDL_GetScancodeFromKey(SDL_Keycode key, SDL_Keymod *modstate) | ||
| 504 | { | ||
| 505 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 506 | |||
| 507 | return SDL_GetKeymapScancode(keyboard->keymap, key, modstate); | ||
| 508 | } | ||
| 509 | |||
| 510 | static bool SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, bool down) | ||
| 511 | { | ||
| 512 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 513 | bool posted = false; | ||
| 514 | SDL_Keycode keycode = SDLK_UNKNOWN; | ||
| 515 | Uint32 type; | ||
| 516 | bool repeat = false; | ||
| 517 | const Uint8 source = flags & KEYBOARD_SOURCE_MASK; | ||
| 518 | |||
| 519 | #ifdef DEBUG_KEYBOARD | ||
| 520 | SDL_Log("The '%s' key has been %s", SDL_GetScancodeName(scancode), down ? "pressed" : "released"); | ||
| 521 | #endif | ||
| 522 | |||
| 523 | // Figure out what type of event this is | ||
| 524 | if (down) { | ||
| 525 | type = SDL_EVENT_KEY_DOWN; | ||
| 526 | } else { | ||
| 527 | type = SDL_EVENT_KEY_UP; | ||
| 528 | } | ||
| 529 | |||
| 530 | if (scancode > SDL_SCANCODE_UNKNOWN && scancode < SDL_SCANCODE_COUNT) { | ||
| 531 | // Drop events that don't change state | ||
| 532 | if (down) { | ||
| 533 | if (keyboard->keystate[scancode]) { | ||
| 534 | if (!(keyboard->keysource[scancode] & source)) { | ||
| 535 | keyboard->keysource[scancode] |= source; | ||
| 536 | return false; | ||
| 537 | } | ||
| 538 | repeat = true; | ||
| 539 | } | ||
| 540 | keyboard->keysource[scancode] |= source; | ||
| 541 | } else { | ||
| 542 | if (!keyboard->keystate[scancode]) { | ||
| 543 | return false; | ||
| 544 | } | ||
| 545 | keyboard->keysource[scancode] = 0; | ||
| 546 | } | ||
| 547 | |||
| 548 | // Update internal keyboard state | ||
| 549 | keyboard->keystate[scancode] = down; | ||
| 550 | |||
| 551 | keycode = SDL_GetKeyFromScancode(scancode, keyboard->modstate, true); | ||
| 552 | |||
| 553 | } else if (rawcode == 0) { | ||
| 554 | // Nothing to do! | ||
| 555 | return false; | ||
| 556 | } | ||
| 557 | |||
| 558 | if (source == KEYBOARD_HARDWARE) { | ||
| 559 | keyboard->hardware_timestamp = SDL_GetTicks(); | ||
| 560 | } else if (source == KEYBOARD_AUTORELEASE) { | ||
| 561 | keyboard->autorelease_pending = true; | ||
| 562 | } | ||
| 563 | |||
| 564 | // Update modifiers state if applicable | ||
| 565 | if (!(flags & KEYBOARD_IGNOREMODIFIERS) && !repeat) { | ||
| 566 | SDL_Keymod modifier; | ||
| 567 | |||
| 568 | switch (keycode) { | ||
| 569 | case SDLK_LCTRL: | ||
| 570 | modifier = SDL_KMOD_LCTRL; | ||
| 571 | break; | ||
| 572 | case SDLK_RCTRL: | ||
| 573 | modifier = SDL_KMOD_RCTRL; | ||
| 574 | break; | ||
| 575 | case SDLK_LSHIFT: | ||
| 576 | modifier = SDL_KMOD_LSHIFT; | ||
| 577 | break; | ||
| 578 | case SDLK_RSHIFT: | ||
| 579 | modifier = SDL_KMOD_RSHIFT; | ||
| 580 | break; | ||
| 581 | case SDLK_LALT: | ||
| 582 | modifier = SDL_KMOD_LALT; | ||
| 583 | break; | ||
| 584 | case SDLK_RALT: | ||
| 585 | modifier = SDL_KMOD_RALT; | ||
| 586 | break; | ||
| 587 | case SDLK_LGUI: | ||
| 588 | modifier = SDL_KMOD_LGUI; | ||
| 589 | break; | ||
| 590 | case SDLK_RGUI: | ||
| 591 | modifier = SDL_KMOD_RGUI; | ||
| 592 | break; | ||
| 593 | case SDLK_MODE: | ||
| 594 | modifier = SDL_KMOD_MODE; | ||
| 595 | break; | ||
| 596 | default: | ||
| 597 | modifier = SDL_KMOD_NONE; | ||
| 598 | break; | ||
| 599 | } | ||
| 600 | if (SDL_EVENT_KEY_DOWN == type) { | ||
| 601 | switch (keycode) { | ||
| 602 | case SDLK_NUMLOCKCLEAR: | ||
| 603 | keyboard->modstate ^= SDL_KMOD_NUM; | ||
| 604 | break; | ||
| 605 | case SDLK_CAPSLOCK: | ||
| 606 | keyboard->modstate ^= SDL_KMOD_CAPS; | ||
| 607 | break; | ||
| 608 | case SDLK_SCROLLLOCK: | ||
| 609 | keyboard->modstate ^= SDL_KMOD_SCROLL; | ||
| 610 | break; | ||
| 611 | default: | ||
| 612 | keyboard->modstate |= modifier; | ||
| 613 | break; | ||
| 614 | } | ||
| 615 | } else { | ||
| 616 | keyboard->modstate &= ~modifier; | ||
| 617 | } | ||
| 618 | } | ||
| 619 | |||
| 620 | // Post the event, if desired | ||
| 621 | if (SDL_EventEnabled(type)) { | ||
| 622 | SDL_Event event; | ||
| 623 | event.type = type; | ||
| 624 | event.common.timestamp = timestamp; | ||
| 625 | event.key.scancode = scancode; | ||
| 626 | event.key.key = keycode; | ||
| 627 | event.key.mod = keyboard->modstate; | ||
| 628 | event.key.raw = (Uint16)rawcode; | ||
| 629 | event.key.down = down; | ||
| 630 | event.key.repeat = repeat; | ||
| 631 | event.key.windowID = keyboard->focus ? keyboard->focus->id : 0; | ||
| 632 | event.key.which = keyboardID; | ||
| 633 | posted = SDL_PushEvent(&event); | ||
| 634 | } | ||
| 635 | |||
| 636 | /* If the keyboard is grabbed and the grabbed window is in full-screen, | ||
| 637 | minimize the window when we receive Alt+Tab, unless the application | ||
| 638 | has explicitly opted out of this behavior. */ | ||
| 639 | if (keycode == SDLK_TAB && down && | ||
| 640 | (keyboard->modstate & SDL_KMOD_ALT) && | ||
| 641 | keyboard->focus && | ||
| 642 | (keyboard->focus->flags & SDL_WINDOW_KEYBOARD_GRABBED) && | ||
| 643 | (keyboard->focus->flags & SDL_WINDOW_FULLSCREEN) && | ||
| 644 | SDL_GetHintBoolean(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, true)) { | ||
| 645 | /* We will temporarily forfeit our grab by minimizing our window, | ||
| 646 | allowing the user to escape the application */ | ||
| 647 | SDL_MinimizeWindow(keyboard->focus); | ||
| 648 | } | ||
| 649 | |||
| 650 | return posted; | ||
| 651 | } | ||
| 652 | |||
| 653 | void SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch) | ||
| 654 | { | ||
| 655 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 656 | SDL_Keymod modstate = SDL_KMOD_NONE; | ||
| 657 | SDL_Scancode scancode; | ||
| 658 | |||
| 659 | if (ch == '\n') { | ||
| 660 | ch = SDLK_RETURN; | ||
| 661 | } | ||
| 662 | scancode = SDL_GetKeymapScancode(keyboard->keymap, ch, &modstate); | ||
| 663 | |||
| 664 | // Make sure we have this keycode in our keymap | ||
| 665 | if (scancode == SDL_SCANCODE_UNKNOWN && ch < SDLK_SCANCODE_MASK) { | ||
| 666 | scancode = GetNextReservedScancode(); | ||
| 667 | SetKeymapEntry(scancode, modstate, ch); | ||
| 668 | } | ||
| 669 | |||
| 670 | if (modstate & SDL_KMOD_SHIFT) { | ||
| 671 | // If the character uses shift, press shift down | ||
| 672 | SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, SDL_SCANCODE_LSHIFT, true); | ||
| 673 | } | ||
| 674 | |||
| 675 | // Send a keydown and keyup for the character | ||
| 676 | SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, true); | ||
| 677 | SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, false); | ||
| 678 | |||
| 679 | if (modstate & SDL_KMOD_SHIFT) { | ||
| 680 | // If the character uses shift, release shift | ||
| 681 | SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, SDL_SCANCODE_LSHIFT, false); | ||
| 682 | } | ||
| 683 | } | ||
| 684 | |||
| 685 | bool SDL_SendKeyboardKey(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, bool down) | ||
| 686 | { | ||
| 687 | return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, keyboardID, rawcode, scancode, down); | ||
| 688 | } | ||
| 689 | |||
| 690 | bool SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, SDL_Keycode keycode, bool down) | ||
| 691 | { | ||
| 692 | if (down) { | ||
| 693 | // Make sure we have this keycode in our keymap | ||
| 694 | SetKeymapEntry(scancode, SDL_GetModState(), keycode); | ||
| 695 | } | ||
| 696 | |||
| 697 | return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, keyboardID, rawcode, scancode, down); | ||
| 698 | } | ||
| 699 | |||
| 700 | bool SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, bool down) | ||
| 701 | { | ||
| 702 | return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE | KEYBOARD_IGNOREMODIFIERS, keyboardID, rawcode, scancode, down); | ||
| 703 | } | ||
| 704 | |||
| 705 | bool SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode) | ||
| 706 | { | ||
| 707 | return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_AUTORELEASE, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, true); | ||
| 708 | } | ||
| 709 | |||
| 710 | void SDL_ReleaseAutoReleaseKeys(void) | ||
| 711 | { | ||
| 712 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 713 | int scancode; | ||
| 714 | |||
| 715 | if (keyboard->autorelease_pending) { | ||
| 716 | for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_SCANCODE_COUNT; ++scancode) { | ||
| 717 | if (keyboard->keysource[scancode] == KEYBOARD_AUTORELEASE) { | ||
| 718 | SDL_SendKeyboardKeyInternal(0, KEYBOARD_AUTORELEASE, SDL_GLOBAL_KEYBOARD_ID, 0, (SDL_Scancode)scancode, false); | ||
| 719 | } | ||
| 720 | } | ||
| 721 | keyboard->autorelease_pending = false; | ||
| 722 | } | ||
| 723 | |||
| 724 | if (keyboard->hardware_timestamp) { | ||
| 725 | // Keep hardware keyboard "active" for 250 ms | ||
| 726 | if (SDL_GetTicks() >= keyboard->hardware_timestamp + 250) { | ||
| 727 | keyboard->hardware_timestamp = 0; | ||
| 728 | } | ||
| 729 | } | ||
| 730 | } | ||
| 731 | |||
| 732 | bool SDL_HardwareKeyboardKeyPressed(void) | ||
| 733 | { | ||
| 734 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 735 | int scancode; | ||
| 736 | |||
| 737 | for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_SCANCODE_COUNT; ++scancode) { | ||
| 738 | if (keyboard->keysource[scancode] & KEYBOARD_HARDWARE) { | ||
| 739 | return true; | ||
| 740 | } | ||
| 741 | } | ||
| 742 | |||
| 743 | return keyboard->hardware_timestamp ? true : false; | ||
| 744 | } | ||
| 745 | |||
| 746 | void SDL_SendKeyboardText(const char *text) | ||
| 747 | { | ||
| 748 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 749 | |||
| 750 | if (!SDL_TextInputActive(keyboard->focus)) { | ||
| 751 | return; | ||
| 752 | } | ||
| 753 | |||
| 754 | if (!text || !*text) { | ||
| 755 | return; | ||
| 756 | } | ||
| 757 | |||
| 758 | // Don't post text events for unprintable characters | ||
| 759 | if (SDL_iscntrl((unsigned char)*text)) { | ||
| 760 | return; | ||
| 761 | } | ||
| 762 | |||
| 763 | // Post the event, if desired | ||
| 764 | if (SDL_EventEnabled(SDL_EVENT_TEXT_INPUT)) { | ||
| 765 | SDL_Event event; | ||
| 766 | event.type = SDL_EVENT_TEXT_INPUT; | ||
| 767 | event.common.timestamp = 0; | ||
| 768 | event.text.windowID = keyboard->focus ? keyboard->focus->id : 0; | ||
| 769 | event.text.text = SDL_CreateTemporaryString(text); | ||
| 770 | if (!event.text.text) { | ||
| 771 | return; | ||
| 772 | } | ||
| 773 | SDL_PushEvent(&event); | ||
| 774 | } | ||
| 775 | } | ||
| 776 | |||
| 777 | void SDL_SendEditingText(const char *text, int start, int length) | ||
| 778 | { | ||
| 779 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 780 | |||
| 781 | if (!SDL_TextInputActive(keyboard->focus)) { | ||
| 782 | return; | ||
| 783 | } | ||
| 784 | |||
| 785 | if (!text) { | ||
| 786 | return; | ||
| 787 | } | ||
| 788 | |||
| 789 | // Post the event, if desired | ||
| 790 | if (SDL_EventEnabled(SDL_EVENT_TEXT_EDITING)) { | ||
| 791 | SDL_Event event; | ||
| 792 | |||
| 793 | event.type = SDL_EVENT_TEXT_EDITING; | ||
| 794 | event.common.timestamp = 0; | ||
| 795 | event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0; | ||
| 796 | event.edit.start = start; | ||
| 797 | event.edit.length = length; | ||
| 798 | event.edit.text = SDL_CreateTemporaryString(text); | ||
| 799 | if (!event.edit.text) { | ||
| 800 | return; | ||
| 801 | } | ||
| 802 | SDL_PushEvent(&event); | ||
| 803 | } | ||
| 804 | } | ||
| 805 | |||
| 806 | static const char * const *CreateCandidatesForEvent(char **candidates, int num_candidates) | ||
| 807 | { | ||
| 808 | const char **event_candidates; | ||
| 809 | int i; | ||
| 810 | char *ptr; | ||
| 811 | size_t total_length = (num_candidates + 1) * sizeof(*event_candidates); | ||
| 812 | |||
| 813 | for (i = 0; i < num_candidates; ++i) { | ||
| 814 | size_t length = SDL_strlen(candidates[i]) + 1; | ||
| 815 | |||
| 816 | total_length += length; | ||
| 817 | } | ||
| 818 | |||
| 819 | event_candidates = (const char **)SDL_AllocateTemporaryMemory(total_length); | ||
| 820 | if (!event_candidates) { | ||
| 821 | return NULL; | ||
| 822 | } | ||
| 823 | ptr = (char *)(event_candidates + (num_candidates + 1)); | ||
| 824 | |||
| 825 | for (i = 0; i < num_candidates; ++i) { | ||
| 826 | size_t length = SDL_strlen(candidates[i]) + 1; | ||
| 827 | |||
| 828 | event_candidates[i] = ptr; | ||
| 829 | SDL_memcpy(ptr, candidates[i], length); | ||
| 830 | ptr += length; | ||
| 831 | } | ||
| 832 | event_candidates[i] = NULL; | ||
| 833 | |||
| 834 | return event_candidates; | ||
| 835 | } | ||
| 836 | |||
| 837 | void SDL_SendEditingTextCandidates(char **candidates, int num_candidates, int selected_candidate, bool horizontal) | ||
| 838 | { | ||
| 839 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 840 | |||
| 841 | if (!SDL_TextInputActive(keyboard->focus)) { | ||
| 842 | return; | ||
| 843 | } | ||
| 844 | |||
| 845 | // Post the event, if desired | ||
| 846 | if (SDL_EventEnabled(SDL_EVENT_TEXT_EDITING_CANDIDATES)) { | ||
| 847 | SDL_Event event; | ||
| 848 | |||
| 849 | event.type = SDL_EVENT_TEXT_EDITING_CANDIDATES; | ||
| 850 | event.common.timestamp = 0; | ||
| 851 | event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0; | ||
| 852 | if (num_candidates > 0) { | ||
| 853 | const char * const *event_candidates = CreateCandidatesForEvent(candidates, num_candidates); | ||
| 854 | if (!event_candidates) { | ||
| 855 | return; | ||
| 856 | } | ||
| 857 | event.edit_candidates.candidates = event_candidates; | ||
| 858 | event.edit_candidates.num_candidates = num_candidates; | ||
| 859 | event.edit_candidates.selected_candidate = selected_candidate; | ||
| 860 | event.edit_candidates.horizontal = horizontal; | ||
| 861 | } else { | ||
| 862 | event.edit_candidates.candidates = NULL; | ||
| 863 | event.edit_candidates.num_candidates = 0; | ||
| 864 | event.edit_candidates.selected_candidate = -1; | ||
| 865 | event.edit_candidates.horizontal = false; | ||
| 866 | } | ||
| 867 | SDL_PushEvent(&event); | ||
| 868 | } | ||
| 869 | } | ||
| 870 | |||
| 871 | void SDL_QuitKeyboard(void) | ||
| 872 | { | ||
| 873 | for (int i = SDL_keyboard_count; i--;) { | ||
| 874 | SDL_RemoveKeyboard(SDL_keyboards[i].instance_id, false); | ||
| 875 | } | ||
| 876 | SDL_free(SDL_keyboards); | ||
| 877 | SDL_keyboards = NULL; | ||
| 878 | |||
| 879 | if (SDL_keyboard.keymap) { | ||
| 880 | SDL_DestroyKeymap(SDL_keyboard.keymap); | ||
| 881 | SDL_keyboard.keymap = NULL; | ||
| 882 | } | ||
| 883 | |||
| 884 | SDL_RemoveHintCallback(SDL_HINT_KEYCODE_OPTIONS, | ||
| 885 | SDL_KeycodeOptionsChanged, &SDL_keyboard); | ||
| 886 | } | ||
| 887 | |||
| 888 | const bool *SDL_GetKeyboardState(int *numkeys) | ||
| 889 | { | ||
| 890 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 891 | |||
| 892 | if (numkeys != (int *)0) { | ||
| 893 | *numkeys = SDL_SCANCODE_COUNT; | ||
| 894 | } | ||
| 895 | return keyboard->keystate; | ||
| 896 | } | ||
| 897 | |||
| 898 | SDL_Keymod SDL_GetModState(void) | ||
| 899 | { | ||
| 900 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 901 | |||
| 902 | return keyboard->modstate; | ||
| 903 | } | ||
| 904 | |||
| 905 | void SDL_SetModState(SDL_Keymod modstate) | ||
| 906 | { | ||
| 907 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 908 | |||
| 909 | keyboard->modstate = modstate; | ||
| 910 | } | ||
| 911 | |||
| 912 | // Note that SDL_ToggleModState() is not a public API. SDL_SetModState() is. | ||
| 913 | void SDL_ToggleModState(SDL_Keymod modstate, bool toggle) | ||
| 914 | { | ||
| 915 | SDL_Keyboard *keyboard = &SDL_keyboard; | ||
| 916 | if (toggle) { | ||
| 917 | keyboard->modstate |= modstate; | ||
| 918 | } else { | ||
| 919 | keyboard->modstate &= ~modstate; | ||
| 920 | } | ||
| 921 | } | ||
| 922 | |||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_keyboard_c.h b/contrib/SDL-3.2.8/src/events/SDL_keyboard_c.h new file mode 100644 index 0000000..ddfb5c5 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_keyboard_c.h | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #ifndef SDL_keyboard_c_h_ | ||
| 24 | #define SDL_keyboard_c_h_ | ||
| 25 | |||
| 26 | #include "SDL_keymap_c.h" | ||
| 27 | |||
| 28 | // Keyboard events not associated with a specific input device | ||
| 29 | #define SDL_GLOBAL_KEYBOARD_ID 0 | ||
| 30 | |||
| 31 | // The default keyboard input device, for platforms that don't have multiple keyboards | ||
| 32 | #define SDL_DEFAULT_KEYBOARD_ID 1 | ||
| 33 | |||
| 34 | // Initialize the keyboard subsystem | ||
| 35 | extern bool SDL_InitKeyboard(void); | ||
| 36 | |||
| 37 | // Return whether a device is actually a keyboard | ||
| 38 | extern bool SDL_IsKeyboard(Uint16 vendor, Uint16 product, int num_keys); | ||
| 39 | |||
| 40 | // A keyboard has been added to the system | ||
| 41 | extern void SDL_AddKeyboard(SDL_KeyboardID keyboardID, const char *name, bool send_event); | ||
| 42 | |||
| 43 | // A keyboard has been removed from the system | ||
| 44 | extern void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID, bool send_event); | ||
| 45 | |||
| 46 | // Set the mapping of scancode to key codes | ||
| 47 | extern void SDL_SetKeymap(SDL_Keymap *keymap, bool send_event); | ||
| 48 | |||
| 49 | // Set the keyboard focus window | ||
| 50 | extern bool SDL_SetKeyboardFocus(SDL_Window *window); | ||
| 51 | |||
| 52 | /* Send a character from an on-screen keyboard as scancode and modifier key events, | ||
| 53 | currently assuming ASCII characters on a US keyboard layout | ||
| 54 | */ | ||
| 55 | extern void SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch); | ||
| 56 | |||
| 57 | // Send a keyboard key event | ||
| 58 | extern bool SDL_SendKeyboardKey(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, bool down); | ||
| 59 | extern bool SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, bool down); | ||
| 60 | extern bool SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode); | ||
| 61 | |||
| 62 | /* This is for platforms that don't know the keymap but can report scancode and keycode directly. | ||
| 63 | Most platforms should prefer to optionally call SDL_SetKeymap and then use SDL_SendKeyboardKey. */ | ||
| 64 | extern bool SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, SDL_Keycode keycode, bool down); | ||
| 65 | |||
| 66 | // Release all the autorelease keys | ||
| 67 | extern void SDL_ReleaseAutoReleaseKeys(void); | ||
| 68 | |||
| 69 | // Return true if any hardware key is pressed | ||
| 70 | extern bool SDL_HardwareKeyboardKeyPressed(void); | ||
| 71 | |||
| 72 | // Send keyboard text input | ||
| 73 | extern void SDL_SendKeyboardText(const char *text); | ||
| 74 | |||
| 75 | // Send editing text for selected range from start to end | ||
| 76 | extern void SDL_SendEditingText(const char *text, int start, int length); | ||
| 77 | |||
| 78 | // Send editing text candidates, which will be copied into the event | ||
| 79 | extern void SDL_SendEditingTextCandidates(char **candidates, int num_candidates, int selected_candidate, bool horizontal); | ||
| 80 | |||
| 81 | // Shutdown the keyboard subsystem | ||
| 82 | extern void SDL_QuitKeyboard(void); | ||
| 83 | |||
| 84 | // Toggle on or off pieces of the keyboard mod state. | ||
| 85 | extern void SDL_ToggleModState(SDL_Keymod modstate, bool toggle); | ||
| 86 | |||
| 87 | #endif // SDL_keyboard_c_h_ | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_keymap.c b/contrib/SDL-3.2.8/src/events/SDL_keymap.c new file mode 100644 index 0000000..bd08786 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_keymap.c | |||
| @@ -0,0 +1,1153 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #include "SDL_keymap_c.h" | ||
| 24 | #include "SDL_keyboard_c.h" | ||
| 25 | |||
| 26 | struct SDL_Keymap | ||
| 27 | { | ||
| 28 | SDL_HashTable *scancode_to_keycode; | ||
| 29 | SDL_HashTable *keycode_to_scancode; | ||
| 30 | }; | ||
| 31 | |||
| 32 | static SDL_Keycode SDL_GetDefaultKeyFromScancode(SDL_Scancode scancode, SDL_Keymod modstate); | ||
| 33 | static SDL_Scancode SDL_GetDefaultScancodeFromKey(SDL_Keycode key, SDL_Keymod *modstate); | ||
| 34 | |||
| 35 | SDL_Keymap *SDL_CreateKeymap(void) | ||
| 36 | { | ||
| 37 | SDL_Keymap *keymap = (SDL_Keymap *)SDL_malloc(sizeof(*keymap)); | ||
| 38 | if (!keymap) { | ||
| 39 | return NULL; | ||
| 40 | } | ||
| 41 | |||
| 42 | keymap->scancode_to_keycode = SDL_CreateHashTable(256, false, SDL_HashID, SDL_KeyMatchID, NULL, NULL); | ||
| 43 | keymap->keycode_to_scancode = SDL_CreateHashTable(256, false, SDL_HashID, SDL_KeyMatchID, NULL, NULL); | ||
| 44 | if (!keymap->scancode_to_keycode || !keymap->keycode_to_scancode) { | ||
| 45 | SDL_DestroyKeymap(keymap); | ||
| 46 | return NULL; | ||
| 47 | } | ||
| 48 | return keymap; | ||
| 49 | } | ||
| 50 | |||
| 51 | static SDL_Keymod NormalizeModifierStateForKeymap(SDL_Keymod modstate) | ||
| 52 | { | ||
| 53 | // The modifiers that affect the keymap are: SHIFT, CAPS, ALT, MODE, and LEVEL5 | ||
| 54 | modstate &= (SDL_KMOD_SHIFT | SDL_KMOD_CAPS | SDL_KMOD_ALT | SDL_KMOD_MODE | SDL_KMOD_LEVEL5); | ||
| 55 | |||
| 56 | // If either right or left Shift are set, set both in the output | ||
| 57 | if (modstate & SDL_KMOD_SHIFT) { | ||
| 58 | modstate |= SDL_KMOD_SHIFT; | ||
| 59 | } | ||
| 60 | |||
| 61 | // If either right or left Alt are set, set both in the output | ||
| 62 | if (modstate & SDL_KMOD_ALT) { | ||
| 63 | modstate |= SDL_KMOD_ALT; | ||
| 64 | } | ||
| 65 | |||
| 66 | return modstate; | ||
| 67 | } | ||
| 68 | |||
| 69 | void SDL_SetKeymapEntry(SDL_Keymap *keymap, SDL_Scancode scancode, SDL_Keymod modstate, SDL_Keycode keycode) | ||
| 70 | { | ||
| 71 | if (!keymap) { | ||
| 72 | return; | ||
| 73 | } | ||
| 74 | |||
| 75 | modstate = NormalizeModifierStateForKeymap(modstate); | ||
| 76 | Uint32 key = ((Uint32)modstate << 16) | scancode; | ||
| 77 | const void *value; | ||
| 78 | if (SDL_FindInHashTable(keymap->scancode_to_keycode, (void *)(uintptr_t)key, &value)) { | ||
| 79 | const SDL_Keycode existing_keycode = (SDL_Keycode)(uintptr_t)value; | ||
| 80 | if (existing_keycode == keycode) { | ||
| 81 | // We already have this mapping | ||
| 82 | return; | ||
| 83 | } | ||
| 84 | // InsertIntoHashTable will replace the existing entry in the keymap atomically. | ||
| 85 | } | ||
| 86 | SDL_InsertIntoHashTable(keymap->scancode_to_keycode, (void *)(uintptr_t)key, (void *)(uintptr_t)keycode, true); | ||
| 87 | |||
| 88 | bool update_keycode = true; | ||
| 89 | if (SDL_FindInHashTable(keymap->keycode_to_scancode, (void *)(uintptr_t)keycode, &value)) { | ||
| 90 | const Uint32 existing_value = (Uint32)(uintptr_t)value; | ||
| 91 | const SDL_Keymod existing_modstate = (SDL_Keymod)(existing_value >> 16); | ||
| 92 | |||
| 93 | // Keep the simplest combination of scancode and modifiers to generate this keycode | ||
| 94 | if (existing_modstate <= modstate) { | ||
| 95 | update_keycode = false; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | if (update_keycode) { | ||
| 99 | SDL_InsertIntoHashTable(keymap->keycode_to_scancode, (void *)(uintptr_t)keycode, (void *)(uintptr_t)key, true); | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | SDL_Keycode SDL_GetKeymapKeycode(SDL_Keymap *keymap, SDL_Scancode scancode, SDL_Keymod modstate) | ||
| 104 | { | ||
| 105 | SDL_Keycode keycode; | ||
| 106 | |||
| 107 | const Uint32 key = ((Uint32)NormalizeModifierStateForKeymap(modstate) << 16) | scancode; | ||
| 108 | const void *value; | ||
| 109 | if (keymap && SDL_FindInHashTable(keymap->scancode_to_keycode, (void *)(uintptr_t)key, &value)) { | ||
| 110 | keycode = (SDL_Keycode)(uintptr_t)value; | ||
| 111 | } else { | ||
| 112 | keycode = SDL_GetDefaultKeyFromScancode(scancode, modstate); | ||
| 113 | } | ||
| 114 | return keycode; | ||
| 115 | } | ||
| 116 | |||
| 117 | SDL_Scancode SDL_GetKeymapScancode(SDL_Keymap *keymap, SDL_Keycode keycode, SDL_Keymod *modstate) | ||
| 118 | { | ||
| 119 | SDL_Scancode scancode; | ||
| 120 | |||
| 121 | const void *value; | ||
| 122 | if (keymap && SDL_FindInHashTable(keymap->keycode_to_scancode, (void *)(uintptr_t)keycode, &value)) { | ||
| 123 | scancode = (SDL_Scancode)((uintptr_t)value & 0xFFFF); | ||
| 124 | if (modstate) { | ||
| 125 | *modstate = (SDL_Keymod)((uintptr_t)value >> 16); | ||
| 126 | } | ||
| 127 | } else { | ||
| 128 | scancode = SDL_GetDefaultScancodeFromKey(keycode, modstate); | ||
| 129 | } | ||
| 130 | return scancode; | ||
| 131 | } | ||
| 132 | |||
| 133 | void SDL_DestroyKeymap(SDL_Keymap *keymap) | ||
| 134 | { | ||
| 135 | if (!keymap) { | ||
| 136 | return; | ||
| 137 | } | ||
| 138 | |||
| 139 | SDL_DestroyHashTable(keymap->scancode_to_keycode); | ||
| 140 | SDL_DestroyHashTable(keymap->keycode_to_scancode); | ||
| 141 | SDL_free(keymap); | ||
| 142 | } | ||
| 143 | |||
| 144 | static const SDL_Keycode normal_default_symbols[] = { | ||
| 145 | SDLK_1, | ||
| 146 | SDLK_2, | ||
| 147 | SDLK_3, | ||
| 148 | SDLK_4, | ||
| 149 | SDLK_5, | ||
| 150 | SDLK_6, | ||
| 151 | SDLK_7, | ||
| 152 | SDLK_8, | ||
| 153 | SDLK_9, | ||
| 154 | SDLK_0, | ||
| 155 | SDLK_RETURN, | ||
| 156 | SDLK_ESCAPE, | ||
| 157 | SDLK_BACKSPACE, | ||
| 158 | SDLK_TAB, | ||
| 159 | SDLK_SPACE, | ||
| 160 | SDLK_MINUS, | ||
| 161 | SDLK_EQUALS, | ||
| 162 | SDLK_LEFTBRACKET, | ||
| 163 | SDLK_RIGHTBRACKET, | ||
| 164 | SDLK_BACKSLASH, | ||
| 165 | SDLK_HASH, | ||
| 166 | SDLK_SEMICOLON, | ||
| 167 | SDLK_APOSTROPHE, | ||
| 168 | SDLK_GRAVE, | ||
| 169 | SDLK_COMMA, | ||
| 170 | SDLK_PERIOD, | ||
| 171 | SDLK_SLASH, | ||
| 172 | }; | ||
| 173 | |||
| 174 | static const SDL_Keycode shifted_default_symbols[] = { | ||
| 175 | SDLK_EXCLAIM, | ||
| 176 | SDLK_AT, | ||
| 177 | SDLK_HASH, | ||
| 178 | SDLK_DOLLAR, | ||
| 179 | SDLK_PERCENT, | ||
| 180 | SDLK_CARET, | ||
| 181 | SDLK_AMPERSAND, | ||
| 182 | SDLK_ASTERISK, | ||
| 183 | SDLK_LEFTPAREN, | ||
| 184 | SDLK_RIGHTPAREN, | ||
| 185 | SDLK_RETURN, | ||
| 186 | SDLK_ESCAPE, | ||
| 187 | SDLK_BACKSPACE, | ||
| 188 | SDLK_TAB, | ||
| 189 | SDLK_SPACE, | ||
| 190 | SDLK_UNDERSCORE, | ||
| 191 | SDLK_PLUS, | ||
| 192 | SDLK_LEFTBRACE, | ||
| 193 | SDLK_RIGHTBRACE, | ||
| 194 | SDLK_PIPE, | ||
| 195 | SDLK_HASH, | ||
| 196 | SDLK_COLON, | ||
| 197 | SDLK_DBLAPOSTROPHE, | ||
| 198 | SDLK_TILDE, | ||
| 199 | SDLK_LESS, | ||
| 200 | SDLK_GREATER, | ||
| 201 | SDLK_QUESTION | ||
| 202 | }; | ||
| 203 | |||
| 204 | static const struct | ||
| 205 | { | ||
| 206 | SDL_Keycode keycode; | ||
| 207 | SDL_Scancode scancode; | ||
| 208 | } extended_default_symbols[] = { | ||
| 209 | { SDLK_LEFT_TAB, SDL_SCANCODE_TAB }, | ||
| 210 | { SDLK_MULTI_KEY_COMPOSE, SDL_SCANCODE_APPLICATION }, // Sun keyboards | ||
| 211 | { SDLK_LMETA, SDL_SCANCODE_LGUI }, | ||
| 212 | { SDLK_RMETA, SDL_SCANCODE_RGUI }, | ||
| 213 | { SDLK_RHYPER, SDL_SCANCODE_APPLICATION } | ||
| 214 | }; | ||
| 215 | |||
| 216 | static SDL_Keycode SDL_GetDefaultKeyFromScancode(SDL_Scancode scancode, SDL_Keymod modstate) | ||
| 217 | { | ||
| 218 | if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_SCANCODE_COUNT) { | ||
| 219 | SDL_InvalidParamError("scancode"); | ||
| 220 | return SDLK_UNKNOWN; | ||
| 221 | } | ||
| 222 | |||
| 223 | if (scancode < SDL_SCANCODE_A) { | ||
| 224 | return SDLK_UNKNOWN; | ||
| 225 | } | ||
| 226 | |||
| 227 | if (scancode < SDL_SCANCODE_1) { | ||
| 228 | bool shifted = (modstate & SDL_KMOD_SHIFT) ? true : false; | ||
| 229 | #ifdef SDL_PLATFORM_APPLE | ||
| 230 | // Apple maps to upper case for either shift or capslock inclusive | ||
| 231 | if (modstate & SDL_KMOD_CAPS) { | ||
| 232 | shifted = true; | ||
| 233 | } | ||
| 234 | #else | ||
| 235 | if (modstate & SDL_KMOD_CAPS) { | ||
| 236 | shifted = !shifted; | ||
| 237 | } | ||
| 238 | #endif | ||
| 239 | if (modstate & SDL_KMOD_MODE) { | ||
| 240 | return SDLK_UNKNOWN; | ||
| 241 | } | ||
| 242 | if (!shifted) { | ||
| 243 | return (SDL_Keycode)('a' + scancode - SDL_SCANCODE_A); | ||
| 244 | } else { | ||
| 245 | return (SDL_Keycode)('A' + scancode - SDL_SCANCODE_A); | ||
| 246 | } | ||
| 247 | } | ||
| 248 | |||
| 249 | if (scancode < SDL_SCANCODE_CAPSLOCK) { | ||
| 250 | bool shifted = (modstate & SDL_KMOD_SHIFT) ? true : false; | ||
| 251 | |||
| 252 | if (modstate & SDL_KMOD_MODE) { | ||
| 253 | return SDLK_UNKNOWN; | ||
| 254 | } | ||
| 255 | if (!shifted) { | ||
| 256 | return normal_default_symbols[scancode - SDL_SCANCODE_1]; | ||
| 257 | } else { | ||
| 258 | return shifted_default_symbols[scancode - SDL_SCANCODE_1]; | ||
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 262 | // These scancodes are not mapped to printable keycodes | ||
| 263 | switch (scancode) { | ||
| 264 | case SDL_SCANCODE_DELETE: | ||
| 265 | return SDLK_DELETE; | ||
| 266 | case SDL_SCANCODE_CAPSLOCK: | ||
| 267 | return SDLK_CAPSLOCK; | ||
| 268 | case SDL_SCANCODE_F1: | ||
| 269 | return SDLK_F1; | ||
| 270 | case SDL_SCANCODE_F2: | ||
| 271 | return SDLK_F2; | ||
| 272 | case SDL_SCANCODE_F3: | ||
| 273 | return SDLK_F3; | ||
| 274 | case SDL_SCANCODE_F4: | ||
| 275 | return SDLK_F4; | ||
| 276 | case SDL_SCANCODE_F5: | ||
| 277 | return SDLK_F5; | ||
| 278 | case SDL_SCANCODE_F6: | ||
| 279 | return SDLK_F6; | ||
| 280 | case SDL_SCANCODE_F7: | ||
| 281 | return SDLK_F7; | ||
| 282 | case SDL_SCANCODE_F8: | ||
| 283 | return SDLK_F8; | ||
| 284 | case SDL_SCANCODE_F9: | ||
| 285 | return SDLK_F9; | ||
| 286 | case SDL_SCANCODE_F10: | ||
| 287 | return SDLK_F10; | ||
| 288 | case SDL_SCANCODE_F11: | ||
| 289 | return SDLK_F11; | ||
| 290 | case SDL_SCANCODE_F12: | ||
| 291 | return SDLK_F12; | ||
| 292 | case SDL_SCANCODE_PRINTSCREEN: | ||
| 293 | return SDLK_PRINTSCREEN; | ||
| 294 | case SDL_SCANCODE_SCROLLLOCK: | ||
| 295 | return SDLK_SCROLLLOCK; | ||
| 296 | case SDL_SCANCODE_PAUSE: | ||
| 297 | return SDLK_PAUSE; | ||
| 298 | case SDL_SCANCODE_INSERT: | ||
| 299 | return SDLK_INSERT; | ||
| 300 | case SDL_SCANCODE_HOME: | ||
| 301 | return SDLK_HOME; | ||
| 302 | case SDL_SCANCODE_PAGEUP: | ||
| 303 | return SDLK_PAGEUP; | ||
| 304 | case SDL_SCANCODE_END: | ||
| 305 | return SDLK_END; | ||
| 306 | case SDL_SCANCODE_PAGEDOWN: | ||
| 307 | return SDLK_PAGEDOWN; | ||
| 308 | case SDL_SCANCODE_RIGHT: | ||
| 309 | return SDLK_RIGHT; | ||
| 310 | case SDL_SCANCODE_LEFT: | ||
| 311 | return SDLK_LEFT; | ||
| 312 | case SDL_SCANCODE_DOWN: | ||
| 313 | return SDLK_DOWN; | ||
| 314 | case SDL_SCANCODE_UP: | ||
| 315 | return SDLK_UP; | ||
| 316 | case SDL_SCANCODE_NUMLOCKCLEAR: | ||
| 317 | return SDLK_NUMLOCKCLEAR; | ||
| 318 | case SDL_SCANCODE_KP_DIVIDE: | ||
| 319 | return SDLK_KP_DIVIDE; | ||
| 320 | case SDL_SCANCODE_KP_MULTIPLY: | ||
| 321 | return SDLK_KP_MULTIPLY; | ||
| 322 | case SDL_SCANCODE_KP_MINUS: | ||
| 323 | return SDLK_KP_MINUS; | ||
| 324 | case SDL_SCANCODE_KP_PLUS: | ||
| 325 | return SDLK_KP_PLUS; | ||
| 326 | case SDL_SCANCODE_KP_ENTER: | ||
| 327 | return SDLK_KP_ENTER; | ||
| 328 | case SDL_SCANCODE_KP_1: | ||
| 329 | return SDLK_KP_1; | ||
| 330 | case SDL_SCANCODE_KP_2: | ||
| 331 | return SDLK_KP_2; | ||
| 332 | case SDL_SCANCODE_KP_3: | ||
| 333 | return SDLK_KP_3; | ||
| 334 | case SDL_SCANCODE_KP_4: | ||
| 335 | return SDLK_KP_4; | ||
| 336 | case SDL_SCANCODE_KP_5: | ||
| 337 | return SDLK_KP_5; | ||
| 338 | case SDL_SCANCODE_KP_6: | ||
| 339 | return SDLK_KP_6; | ||
| 340 | case SDL_SCANCODE_KP_7: | ||
| 341 | return SDLK_KP_7; | ||
| 342 | case SDL_SCANCODE_KP_8: | ||
| 343 | return SDLK_KP_8; | ||
| 344 | case SDL_SCANCODE_KP_9: | ||
| 345 | return SDLK_KP_9; | ||
| 346 | case SDL_SCANCODE_KP_0: | ||
| 347 | return SDLK_KP_0; | ||
| 348 | case SDL_SCANCODE_KP_PERIOD: | ||
| 349 | return SDLK_KP_PERIOD; | ||
| 350 | case SDL_SCANCODE_APPLICATION: | ||
| 351 | return SDLK_APPLICATION; | ||
| 352 | case SDL_SCANCODE_POWER: | ||
| 353 | return SDLK_POWER; | ||
| 354 | case SDL_SCANCODE_KP_EQUALS: | ||
| 355 | return SDLK_KP_EQUALS; | ||
| 356 | case SDL_SCANCODE_F13: | ||
| 357 | return SDLK_F13; | ||
| 358 | case SDL_SCANCODE_F14: | ||
| 359 | return SDLK_F14; | ||
| 360 | case SDL_SCANCODE_F15: | ||
| 361 | return SDLK_F15; | ||
| 362 | case SDL_SCANCODE_F16: | ||
| 363 | return SDLK_F16; | ||
| 364 | case SDL_SCANCODE_F17: | ||
| 365 | return SDLK_F17; | ||
| 366 | case SDL_SCANCODE_F18: | ||
| 367 | return SDLK_F18; | ||
| 368 | case SDL_SCANCODE_F19: | ||
| 369 | return SDLK_F19; | ||
| 370 | case SDL_SCANCODE_F20: | ||
| 371 | return SDLK_F20; | ||
| 372 | case SDL_SCANCODE_F21: | ||
| 373 | return SDLK_F21; | ||
| 374 | case SDL_SCANCODE_F22: | ||
| 375 | return SDLK_F22; | ||
| 376 | case SDL_SCANCODE_F23: | ||
| 377 | return SDLK_F23; | ||
| 378 | case SDL_SCANCODE_F24: | ||
| 379 | return SDLK_F24; | ||
| 380 | case SDL_SCANCODE_EXECUTE: | ||
| 381 | return SDLK_EXECUTE; | ||
| 382 | case SDL_SCANCODE_HELP: | ||
| 383 | return SDLK_HELP; | ||
| 384 | case SDL_SCANCODE_MENU: | ||
| 385 | return SDLK_MENU; | ||
| 386 | case SDL_SCANCODE_SELECT: | ||
| 387 | return SDLK_SELECT; | ||
| 388 | case SDL_SCANCODE_STOP: | ||
| 389 | return SDLK_STOP; | ||
| 390 | case SDL_SCANCODE_AGAIN: | ||
| 391 | return SDLK_AGAIN; | ||
| 392 | case SDL_SCANCODE_UNDO: | ||
| 393 | return SDLK_UNDO; | ||
| 394 | case SDL_SCANCODE_CUT: | ||
| 395 | return SDLK_CUT; | ||
| 396 | case SDL_SCANCODE_COPY: | ||
| 397 | return SDLK_COPY; | ||
| 398 | case SDL_SCANCODE_PASTE: | ||
| 399 | return SDLK_PASTE; | ||
| 400 | case SDL_SCANCODE_FIND: | ||
| 401 | return SDLK_FIND; | ||
| 402 | case SDL_SCANCODE_MUTE: | ||
| 403 | return SDLK_MUTE; | ||
| 404 | case SDL_SCANCODE_VOLUMEUP: | ||
| 405 | return SDLK_VOLUMEUP; | ||
| 406 | case SDL_SCANCODE_VOLUMEDOWN: | ||
| 407 | return SDLK_VOLUMEDOWN; | ||
| 408 | case SDL_SCANCODE_KP_COMMA: | ||
| 409 | return SDLK_KP_COMMA; | ||
| 410 | case SDL_SCANCODE_KP_EQUALSAS400: | ||
| 411 | return SDLK_KP_EQUALSAS400; | ||
| 412 | case SDL_SCANCODE_ALTERASE: | ||
| 413 | return SDLK_ALTERASE; | ||
| 414 | case SDL_SCANCODE_SYSREQ: | ||
| 415 | return SDLK_SYSREQ; | ||
| 416 | case SDL_SCANCODE_CANCEL: | ||
| 417 | return SDLK_CANCEL; | ||
| 418 | case SDL_SCANCODE_CLEAR: | ||
| 419 | return SDLK_CLEAR; | ||
| 420 | case SDL_SCANCODE_PRIOR: | ||
| 421 | return SDLK_PRIOR; | ||
| 422 | case SDL_SCANCODE_RETURN2: | ||
| 423 | return SDLK_RETURN2; | ||
| 424 | case SDL_SCANCODE_SEPARATOR: | ||
| 425 | return SDLK_SEPARATOR; | ||
| 426 | case SDL_SCANCODE_OUT: | ||
| 427 | return SDLK_OUT; | ||
| 428 | case SDL_SCANCODE_OPER: | ||
| 429 | return SDLK_OPER; | ||
| 430 | case SDL_SCANCODE_CLEARAGAIN: | ||
| 431 | return SDLK_CLEARAGAIN; | ||
| 432 | case SDL_SCANCODE_CRSEL: | ||
| 433 | return SDLK_CRSEL; | ||
| 434 | case SDL_SCANCODE_EXSEL: | ||
| 435 | return SDLK_EXSEL; | ||
| 436 | case SDL_SCANCODE_KP_00: | ||
| 437 | return SDLK_KP_00; | ||
| 438 | case SDL_SCANCODE_KP_000: | ||
| 439 | return SDLK_KP_000; | ||
| 440 | case SDL_SCANCODE_THOUSANDSSEPARATOR: | ||
| 441 | return SDLK_THOUSANDSSEPARATOR; | ||
| 442 | case SDL_SCANCODE_DECIMALSEPARATOR: | ||
| 443 | return SDLK_DECIMALSEPARATOR; | ||
| 444 | case SDL_SCANCODE_CURRENCYUNIT: | ||
| 445 | return SDLK_CURRENCYUNIT; | ||
| 446 | case SDL_SCANCODE_CURRENCYSUBUNIT: | ||
| 447 | return SDLK_CURRENCYSUBUNIT; | ||
| 448 | case SDL_SCANCODE_KP_LEFTPAREN: | ||
| 449 | return SDLK_KP_LEFTPAREN; | ||
| 450 | case SDL_SCANCODE_KP_RIGHTPAREN: | ||
| 451 | return SDLK_KP_RIGHTPAREN; | ||
| 452 | case SDL_SCANCODE_KP_LEFTBRACE: | ||
| 453 | return SDLK_KP_LEFTBRACE; | ||
| 454 | case SDL_SCANCODE_KP_RIGHTBRACE: | ||
| 455 | return SDLK_KP_RIGHTBRACE; | ||
| 456 | case SDL_SCANCODE_KP_TAB: | ||
| 457 | return SDLK_KP_TAB; | ||
| 458 | case SDL_SCANCODE_KP_BACKSPACE: | ||
| 459 | return SDLK_KP_BACKSPACE; | ||
| 460 | case SDL_SCANCODE_KP_A: | ||
| 461 | return SDLK_KP_A; | ||
| 462 | case SDL_SCANCODE_KP_B: | ||
| 463 | return SDLK_KP_B; | ||
| 464 | case SDL_SCANCODE_KP_C: | ||
| 465 | return SDLK_KP_C; | ||
| 466 | case SDL_SCANCODE_KP_D: | ||
| 467 | return SDLK_KP_D; | ||
| 468 | case SDL_SCANCODE_KP_E: | ||
| 469 | return SDLK_KP_E; | ||
| 470 | case SDL_SCANCODE_KP_F: | ||
| 471 | return SDLK_KP_F; | ||
| 472 | case SDL_SCANCODE_KP_XOR: | ||
| 473 | return SDLK_KP_XOR; | ||
| 474 | case SDL_SCANCODE_KP_POWER: | ||
| 475 | return SDLK_KP_POWER; | ||
| 476 | case SDL_SCANCODE_KP_PERCENT: | ||
| 477 | return SDLK_KP_PERCENT; | ||
| 478 | case SDL_SCANCODE_KP_LESS: | ||
| 479 | return SDLK_KP_LESS; | ||
| 480 | case SDL_SCANCODE_KP_GREATER: | ||
| 481 | return SDLK_KP_GREATER; | ||
| 482 | case SDL_SCANCODE_KP_AMPERSAND: | ||
| 483 | return SDLK_KP_AMPERSAND; | ||
| 484 | case SDL_SCANCODE_KP_DBLAMPERSAND: | ||
| 485 | return SDLK_KP_DBLAMPERSAND; | ||
| 486 | case SDL_SCANCODE_KP_VERTICALBAR: | ||
| 487 | return SDLK_KP_VERTICALBAR; | ||
| 488 | case SDL_SCANCODE_KP_DBLVERTICALBAR: | ||
| 489 | return SDLK_KP_DBLVERTICALBAR; | ||
| 490 | case SDL_SCANCODE_KP_COLON: | ||
| 491 | return SDLK_KP_COLON; | ||
| 492 | case SDL_SCANCODE_KP_HASH: | ||
| 493 | return SDLK_KP_HASH; | ||
| 494 | case SDL_SCANCODE_KP_SPACE: | ||
| 495 | return SDLK_KP_SPACE; | ||
| 496 | case SDL_SCANCODE_KP_AT: | ||
| 497 | return SDLK_KP_AT; | ||
| 498 | case SDL_SCANCODE_KP_EXCLAM: | ||
| 499 | return SDLK_KP_EXCLAM; | ||
| 500 | case SDL_SCANCODE_KP_MEMSTORE: | ||
| 501 | return SDLK_KP_MEMSTORE; | ||
| 502 | case SDL_SCANCODE_KP_MEMRECALL: | ||
| 503 | return SDLK_KP_MEMRECALL; | ||
| 504 | case SDL_SCANCODE_KP_MEMCLEAR: | ||
| 505 | return SDLK_KP_MEMCLEAR; | ||
| 506 | case SDL_SCANCODE_KP_MEMADD: | ||
| 507 | return SDLK_KP_MEMADD; | ||
| 508 | case SDL_SCANCODE_KP_MEMSUBTRACT: | ||
| 509 | return SDLK_KP_MEMSUBTRACT; | ||
| 510 | case SDL_SCANCODE_KP_MEMMULTIPLY: | ||
| 511 | return SDLK_KP_MEMMULTIPLY; | ||
| 512 | case SDL_SCANCODE_KP_MEMDIVIDE: | ||
| 513 | return SDLK_KP_MEMDIVIDE; | ||
| 514 | case SDL_SCANCODE_KP_PLUSMINUS: | ||
| 515 | return SDLK_KP_PLUSMINUS; | ||
| 516 | case SDL_SCANCODE_KP_CLEAR: | ||
| 517 | return SDLK_KP_CLEAR; | ||
| 518 | case SDL_SCANCODE_KP_CLEARENTRY: | ||
| 519 | return SDLK_KP_CLEARENTRY; | ||
| 520 | case SDL_SCANCODE_KP_BINARY: | ||
| 521 | return SDLK_KP_BINARY; | ||
| 522 | case SDL_SCANCODE_KP_OCTAL: | ||
| 523 | return SDLK_KP_OCTAL; | ||
| 524 | case SDL_SCANCODE_KP_DECIMAL: | ||
| 525 | return SDLK_KP_DECIMAL; | ||
| 526 | case SDL_SCANCODE_KP_HEXADECIMAL: | ||
| 527 | return SDLK_KP_HEXADECIMAL; | ||
| 528 | case SDL_SCANCODE_LCTRL: | ||
| 529 | return SDLK_LCTRL; | ||
| 530 | case SDL_SCANCODE_LSHIFT: | ||
| 531 | return SDLK_LSHIFT; | ||
| 532 | case SDL_SCANCODE_LALT: | ||
| 533 | return SDLK_LALT; | ||
| 534 | case SDL_SCANCODE_LGUI: | ||
| 535 | return SDLK_LGUI; | ||
| 536 | case SDL_SCANCODE_RCTRL: | ||
| 537 | return SDLK_RCTRL; | ||
| 538 | case SDL_SCANCODE_RSHIFT: | ||
| 539 | return SDLK_RSHIFT; | ||
| 540 | case SDL_SCANCODE_RALT: | ||
| 541 | return SDLK_RALT; | ||
| 542 | case SDL_SCANCODE_RGUI: | ||
| 543 | return SDLK_RGUI; | ||
| 544 | case SDL_SCANCODE_MODE: | ||
| 545 | return SDLK_MODE; | ||
| 546 | case SDL_SCANCODE_SLEEP: | ||
| 547 | return SDLK_SLEEP; | ||
| 548 | case SDL_SCANCODE_WAKE: | ||
| 549 | return SDLK_WAKE; | ||
| 550 | case SDL_SCANCODE_CHANNEL_INCREMENT: | ||
| 551 | return SDLK_CHANNEL_INCREMENT; | ||
| 552 | case SDL_SCANCODE_CHANNEL_DECREMENT: | ||
| 553 | return SDLK_CHANNEL_DECREMENT; | ||
| 554 | case SDL_SCANCODE_MEDIA_PLAY: | ||
| 555 | return SDLK_MEDIA_PLAY; | ||
| 556 | case SDL_SCANCODE_MEDIA_PAUSE: | ||
| 557 | return SDLK_MEDIA_PAUSE; | ||
| 558 | case SDL_SCANCODE_MEDIA_RECORD: | ||
| 559 | return SDLK_MEDIA_RECORD; | ||
| 560 | case SDL_SCANCODE_MEDIA_FAST_FORWARD: | ||
| 561 | return SDLK_MEDIA_FAST_FORWARD; | ||
| 562 | case SDL_SCANCODE_MEDIA_REWIND: | ||
| 563 | return SDLK_MEDIA_REWIND; | ||
| 564 | case SDL_SCANCODE_MEDIA_NEXT_TRACK: | ||
| 565 | return SDLK_MEDIA_NEXT_TRACK; | ||
| 566 | case SDL_SCANCODE_MEDIA_PREVIOUS_TRACK: | ||
| 567 | return SDLK_MEDIA_PREVIOUS_TRACK; | ||
| 568 | case SDL_SCANCODE_MEDIA_STOP: | ||
| 569 | return SDLK_MEDIA_STOP; | ||
| 570 | case SDL_SCANCODE_MEDIA_EJECT: | ||
| 571 | return SDLK_MEDIA_EJECT; | ||
| 572 | case SDL_SCANCODE_MEDIA_PLAY_PAUSE: | ||
| 573 | return SDLK_MEDIA_PLAY_PAUSE; | ||
| 574 | case SDL_SCANCODE_MEDIA_SELECT: | ||
| 575 | return SDLK_MEDIA_SELECT; | ||
| 576 | case SDL_SCANCODE_AC_NEW: | ||
| 577 | return SDLK_AC_NEW; | ||
| 578 | case SDL_SCANCODE_AC_OPEN: | ||
| 579 | return SDLK_AC_OPEN; | ||
| 580 | case SDL_SCANCODE_AC_CLOSE: | ||
| 581 | return SDLK_AC_CLOSE; | ||
| 582 | case SDL_SCANCODE_AC_EXIT: | ||
| 583 | return SDLK_AC_EXIT; | ||
| 584 | case SDL_SCANCODE_AC_SAVE: | ||
| 585 | return SDLK_AC_SAVE; | ||
| 586 | case SDL_SCANCODE_AC_PRINT: | ||
| 587 | return SDLK_AC_PRINT; | ||
| 588 | case SDL_SCANCODE_AC_PROPERTIES: | ||
| 589 | return SDLK_AC_PROPERTIES; | ||
| 590 | case SDL_SCANCODE_AC_SEARCH: | ||
| 591 | return SDLK_AC_SEARCH; | ||
| 592 | case SDL_SCANCODE_AC_HOME: | ||
| 593 | return SDLK_AC_HOME; | ||
| 594 | case SDL_SCANCODE_AC_BACK: | ||
| 595 | return SDLK_AC_BACK; | ||
| 596 | case SDL_SCANCODE_AC_FORWARD: | ||
| 597 | return SDLK_AC_FORWARD; | ||
| 598 | case SDL_SCANCODE_AC_STOP: | ||
| 599 | return SDLK_AC_STOP; | ||
| 600 | case SDL_SCANCODE_AC_REFRESH: | ||
| 601 | return SDLK_AC_REFRESH; | ||
| 602 | case SDL_SCANCODE_AC_BOOKMARKS: | ||
| 603 | return SDLK_AC_BOOKMARKS; | ||
| 604 | case SDL_SCANCODE_SOFTLEFT: | ||
| 605 | return SDLK_SOFTLEFT; | ||
| 606 | case SDL_SCANCODE_SOFTRIGHT: | ||
| 607 | return SDLK_SOFTRIGHT; | ||
| 608 | case SDL_SCANCODE_CALL: | ||
| 609 | return SDLK_CALL; | ||
| 610 | case SDL_SCANCODE_ENDCALL: | ||
| 611 | return SDLK_ENDCALL; | ||
| 612 | default: | ||
| 613 | return SDLK_UNKNOWN; | ||
| 614 | } | ||
| 615 | } | ||
| 616 | |||
| 617 | static SDL_Scancode SDL_GetDefaultScancodeFromKey(SDL_Keycode key, SDL_Keymod *modstate) | ||
| 618 | { | ||
| 619 | if (modstate) { | ||
| 620 | *modstate = SDL_KMOD_NONE; | ||
| 621 | } | ||
| 622 | |||
| 623 | if (key == SDLK_UNKNOWN) { | ||
| 624 | return SDL_SCANCODE_UNKNOWN; | ||
| 625 | } | ||
| 626 | |||
| 627 | if (key & SDLK_EXTENDED_MASK) { | ||
| 628 | for (int i = 0; i < SDL_arraysize(extended_default_symbols); ++i) { | ||
| 629 | if (extended_default_symbols[i].keycode == key) { | ||
| 630 | return extended_default_symbols[i].scancode; | ||
| 631 | } | ||
| 632 | } | ||
| 633 | |||
| 634 | return SDL_SCANCODE_UNKNOWN; | ||
| 635 | } | ||
| 636 | |||
| 637 | if (key & SDLK_SCANCODE_MASK) { | ||
| 638 | return (SDL_Scancode)(key & ~SDLK_SCANCODE_MASK); | ||
| 639 | } | ||
| 640 | |||
| 641 | if (key >= SDLK_A && key <= SDLK_Z) { | ||
| 642 | return (SDL_Scancode)(SDL_SCANCODE_A + key - SDLK_A); | ||
| 643 | } | ||
| 644 | |||
| 645 | if (key >= 'A' && key <= 'Z') { | ||
| 646 | if (modstate) { | ||
| 647 | *modstate = SDL_KMOD_SHIFT; | ||
| 648 | } | ||
| 649 | return (SDL_Scancode)(SDL_SCANCODE_A + key - 'A'); | ||
| 650 | } | ||
| 651 | |||
| 652 | for (int i = 0; i < SDL_arraysize(normal_default_symbols); ++i) { | ||
| 653 | if (key == normal_default_symbols[i]) { | ||
| 654 | return(SDL_Scancode)(SDL_SCANCODE_1 + i); | ||
| 655 | } | ||
| 656 | } | ||
| 657 | |||
| 658 | for (int i = 0; i < SDL_arraysize(shifted_default_symbols); ++i) { | ||
| 659 | if (key == shifted_default_symbols[i]) { | ||
| 660 | if (modstate) { | ||
| 661 | *modstate = SDL_KMOD_SHIFT; | ||
| 662 | } | ||
| 663 | return(SDL_Scancode)(SDL_SCANCODE_1 + i); | ||
| 664 | } | ||
| 665 | } | ||
| 666 | |||
| 667 | if (key == SDLK_DELETE) { | ||
| 668 | return SDL_SCANCODE_DELETE; | ||
| 669 | } | ||
| 670 | |||
| 671 | return SDL_SCANCODE_UNKNOWN; | ||
| 672 | } | ||
| 673 | |||
| 674 | static const char *SDL_scancode_names[SDL_SCANCODE_COUNT] = | ||
| 675 | { | ||
| 676 | /* 0 */ NULL, | ||
| 677 | /* 1 */ NULL, | ||
| 678 | /* 2 */ NULL, | ||
| 679 | /* 3 */ NULL, | ||
| 680 | /* 4 */ "A", | ||
| 681 | /* 5 */ "B", | ||
| 682 | /* 6 */ "C", | ||
| 683 | /* 7 */ "D", | ||
| 684 | /* 8 */ "E", | ||
| 685 | /* 9 */ "F", | ||
| 686 | /* 10 */ "G", | ||
| 687 | /* 11 */ "H", | ||
| 688 | /* 12 */ "I", | ||
| 689 | /* 13 */ "J", | ||
| 690 | /* 14 */ "K", | ||
| 691 | /* 15 */ "L", | ||
| 692 | /* 16 */ "M", | ||
| 693 | /* 17 */ "N", | ||
| 694 | /* 18 */ "O", | ||
| 695 | /* 19 */ "P", | ||
| 696 | /* 20 */ "Q", | ||
| 697 | /* 21 */ "R", | ||
| 698 | /* 22 */ "S", | ||
| 699 | /* 23 */ "T", | ||
| 700 | /* 24 */ "U", | ||
| 701 | /* 25 */ "V", | ||
| 702 | /* 26 */ "W", | ||
| 703 | /* 27 */ "X", | ||
| 704 | /* 28 */ "Y", | ||
| 705 | /* 29 */ "Z", | ||
| 706 | /* 30 */ "1", | ||
| 707 | /* 31 */ "2", | ||
| 708 | /* 32 */ "3", | ||
| 709 | /* 33 */ "4", | ||
| 710 | /* 34 */ "5", | ||
| 711 | /* 35 */ "6", | ||
| 712 | /* 36 */ "7", | ||
| 713 | /* 37 */ "8", | ||
| 714 | /* 38 */ "9", | ||
| 715 | /* 39 */ "0", | ||
| 716 | /* 40 */ "Return", | ||
| 717 | /* 41 */ "Escape", | ||
| 718 | /* 42 */ "Backspace", | ||
| 719 | /* 43 */ "Tab", | ||
| 720 | /* 44 */ "Space", | ||
| 721 | /* 45 */ "-", | ||
| 722 | /* 46 */ "=", | ||
| 723 | /* 47 */ "[", | ||
| 724 | /* 48 */ "]", | ||
| 725 | /* 49 */ "\\", | ||
| 726 | /* 50 */ "#", | ||
| 727 | /* 51 */ ";", | ||
| 728 | /* 52 */ "'", | ||
| 729 | /* 53 */ "`", | ||
| 730 | /* 54 */ ",", | ||
| 731 | /* 55 */ ".", | ||
| 732 | /* 56 */ "/", | ||
| 733 | /* 57 */ "CapsLock", | ||
| 734 | /* 58 */ "F1", | ||
| 735 | /* 59 */ "F2", | ||
| 736 | /* 60 */ "F3", | ||
| 737 | /* 61 */ "F4", | ||
| 738 | /* 62 */ "F5", | ||
| 739 | /* 63 */ "F6", | ||
| 740 | /* 64 */ "F7", | ||
| 741 | /* 65 */ "F8", | ||
| 742 | /* 66 */ "F9", | ||
| 743 | /* 67 */ "F10", | ||
| 744 | /* 68 */ "F11", | ||
| 745 | /* 69 */ "F12", | ||
| 746 | /* 70 */ "PrintScreen", | ||
| 747 | /* 71 */ "ScrollLock", | ||
| 748 | /* 72 */ "Pause", | ||
| 749 | /* 73 */ "Insert", | ||
| 750 | /* 74 */ "Home", | ||
| 751 | /* 75 */ "PageUp", | ||
| 752 | /* 76 */ "Delete", | ||
| 753 | /* 77 */ "End", | ||
| 754 | /* 78 */ "PageDown", | ||
| 755 | /* 79 */ "Right", | ||
| 756 | /* 80 */ "Left", | ||
| 757 | /* 81 */ "Down", | ||
| 758 | /* 82 */ "Up", | ||
| 759 | /* 83 */ "Numlock", | ||
| 760 | /* 84 */ "Keypad /", | ||
| 761 | /* 85 */ "Keypad *", | ||
| 762 | /* 86 */ "Keypad -", | ||
| 763 | /* 87 */ "Keypad +", | ||
| 764 | /* 88 */ "Keypad Enter", | ||
| 765 | /* 89 */ "Keypad 1", | ||
| 766 | /* 90 */ "Keypad 2", | ||
| 767 | /* 91 */ "Keypad 3", | ||
| 768 | /* 92 */ "Keypad 4", | ||
| 769 | /* 93 */ "Keypad 5", | ||
| 770 | /* 94 */ "Keypad 6", | ||
| 771 | /* 95 */ "Keypad 7", | ||
| 772 | /* 96 */ "Keypad 8", | ||
| 773 | /* 97 */ "Keypad 9", | ||
| 774 | /* 98 */ "Keypad 0", | ||
| 775 | /* 99 */ "Keypad .", | ||
| 776 | /* 100 */ "NonUSBackslash", | ||
| 777 | /* 101 */ "Application", | ||
| 778 | /* 102 */ "Power", | ||
| 779 | /* 103 */ "Keypad =", | ||
| 780 | /* 104 */ "F13", | ||
| 781 | /* 105 */ "F14", | ||
| 782 | /* 106 */ "F15", | ||
| 783 | /* 107 */ "F16", | ||
| 784 | /* 108 */ "F17", | ||
| 785 | /* 109 */ "F18", | ||
| 786 | /* 110 */ "F19", | ||
| 787 | /* 111 */ "F20", | ||
| 788 | /* 112 */ "F21", | ||
| 789 | /* 113 */ "F22", | ||
| 790 | /* 114 */ "F23", | ||
| 791 | /* 115 */ "F24", | ||
| 792 | /* 116 */ "Execute", | ||
| 793 | /* 117 */ "Help", | ||
| 794 | /* 118 */ "Menu", | ||
| 795 | /* 119 */ "Select", | ||
| 796 | /* 120 */ "Stop", | ||
| 797 | /* 121 */ "Again", | ||
| 798 | /* 122 */ "Undo", | ||
| 799 | /* 123 */ "Cut", | ||
| 800 | /* 124 */ "Copy", | ||
| 801 | /* 125 */ "Paste", | ||
| 802 | /* 126 */ "Find", | ||
| 803 | /* 127 */ "Mute", | ||
| 804 | /* 128 */ "VolumeUp", | ||
| 805 | /* 129 */ "VolumeDown", | ||
| 806 | /* 130 */ NULL, | ||
| 807 | /* 131 */ NULL, | ||
| 808 | /* 132 */ NULL, | ||
| 809 | /* 133 */ "Keypad ,", | ||
| 810 | /* 134 */ "Keypad = (AS400)", | ||
| 811 | /* 135 */ "International 1", | ||
| 812 | /* 136 */ "International 2", | ||
| 813 | /* 137 */ "International 3", | ||
| 814 | /* 138 */ "International 4", | ||
| 815 | /* 139 */ "International 5", | ||
| 816 | /* 140 */ "International 6", | ||
| 817 | /* 141 */ "International 7", | ||
| 818 | /* 142 */ "International 8", | ||
| 819 | /* 143 */ "International 9", | ||
| 820 | /* 144 */ "Language 1", | ||
| 821 | /* 145 */ "Language 2", | ||
| 822 | /* 146 */ "Language 3", | ||
| 823 | /* 147 */ "Language 4", | ||
| 824 | /* 148 */ "Language 5", | ||
| 825 | /* 149 */ "Language 6", | ||
| 826 | /* 150 */ "Language 7", | ||
| 827 | /* 151 */ "Language 8", | ||
| 828 | /* 152 */ "Language 9", | ||
| 829 | /* 153 */ "AltErase", | ||
| 830 | /* 154 */ "SysReq", | ||
| 831 | /* 155 */ "Cancel", | ||
| 832 | /* 156 */ "Clear", | ||
| 833 | /* 157 */ "Prior", | ||
| 834 | /* 158 */ "Return", | ||
| 835 | /* 159 */ "Separator", | ||
| 836 | /* 160 */ "Out", | ||
| 837 | /* 161 */ "Oper", | ||
| 838 | /* 162 */ "Clear / Again", | ||
| 839 | /* 163 */ "CrSel", | ||
| 840 | /* 164 */ "ExSel", | ||
| 841 | /* 165 */ NULL, | ||
| 842 | /* 166 */ NULL, | ||
| 843 | /* 167 */ NULL, | ||
| 844 | /* 168 */ NULL, | ||
| 845 | /* 169 */ NULL, | ||
| 846 | /* 170 */ NULL, | ||
| 847 | /* 171 */ NULL, | ||
| 848 | /* 172 */ NULL, | ||
| 849 | /* 173 */ NULL, | ||
| 850 | /* 174 */ NULL, | ||
| 851 | /* 175 */ NULL, | ||
| 852 | /* 176 */ "Keypad 00", | ||
| 853 | /* 177 */ "Keypad 000", | ||
| 854 | /* 178 */ "ThousandsSeparator", | ||
| 855 | /* 179 */ "DecimalSeparator", | ||
| 856 | /* 180 */ "CurrencyUnit", | ||
| 857 | /* 181 */ "CurrencySubUnit", | ||
| 858 | /* 182 */ "Keypad (", | ||
| 859 | /* 183 */ "Keypad )", | ||
| 860 | /* 184 */ "Keypad {", | ||
| 861 | /* 185 */ "Keypad }", | ||
| 862 | /* 186 */ "Keypad Tab", | ||
| 863 | /* 187 */ "Keypad Backspace", | ||
| 864 | /* 188 */ "Keypad A", | ||
| 865 | /* 189 */ "Keypad B", | ||
| 866 | /* 190 */ "Keypad C", | ||
| 867 | /* 191 */ "Keypad D", | ||
| 868 | /* 192 */ "Keypad E", | ||
| 869 | /* 193 */ "Keypad F", | ||
| 870 | /* 194 */ "Keypad XOR", | ||
| 871 | /* 195 */ "Keypad ^", | ||
| 872 | /* 196 */ "Keypad %", | ||
| 873 | /* 197 */ "Keypad <", | ||
| 874 | /* 198 */ "Keypad >", | ||
| 875 | /* 199 */ "Keypad &", | ||
| 876 | /* 200 */ "Keypad &&", | ||
| 877 | /* 201 */ "Keypad |", | ||
| 878 | /* 202 */ "Keypad ||", | ||
| 879 | /* 203 */ "Keypad :", | ||
| 880 | /* 204 */ "Keypad #", | ||
| 881 | /* 205 */ "Keypad Space", | ||
| 882 | /* 206 */ "Keypad @", | ||
| 883 | /* 207 */ "Keypad !", | ||
| 884 | /* 208 */ "Keypad MemStore", | ||
| 885 | /* 209 */ "Keypad MemRecall", | ||
| 886 | /* 210 */ "Keypad MemClear", | ||
| 887 | /* 211 */ "Keypad MemAdd", | ||
| 888 | /* 212 */ "Keypad MemSubtract", | ||
| 889 | /* 213 */ "Keypad MemMultiply", | ||
| 890 | /* 214 */ "Keypad MemDivide", | ||
| 891 | /* 215 */ "Keypad +/-", | ||
| 892 | /* 216 */ "Keypad Clear", | ||
| 893 | /* 217 */ "Keypad ClearEntry", | ||
| 894 | /* 218 */ "Keypad Binary", | ||
| 895 | /* 219 */ "Keypad Octal", | ||
| 896 | /* 220 */ "Keypad Decimal", | ||
| 897 | /* 221 */ "Keypad Hexadecimal", | ||
| 898 | /* 222 */ NULL, | ||
| 899 | /* 223 */ NULL, | ||
| 900 | /* 224 */ "Left Ctrl", | ||
| 901 | /* 225 */ "Left Shift", | ||
| 902 | /* 226 */ "Left Alt", | ||
| 903 | /* 227 */ "Left GUI", | ||
| 904 | /* 228 */ "Right Ctrl", | ||
| 905 | /* 229 */ "Right Shift", | ||
| 906 | /* 230 */ "Right Alt", | ||
| 907 | /* 231 */ "Right GUI", | ||
| 908 | /* 232 */ NULL, | ||
| 909 | /* 233 */ NULL, | ||
| 910 | /* 234 */ NULL, | ||
| 911 | /* 235 */ NULL, | ||
| 912 | /* 236 */ NULL, | ||
| 913 | /* 237 */ NULL, | ||
| 914 | /* 238 */ NULL, | ||
| 915 | /* 239 */ NULL, | ||
| 916 | /* 240 */ NULL, | ||
| 917 | /* 241 */ NULL, | ||
| 918 | /* 242 */ NULL, | ||
| 919 | /* 243 */ NULL, | ||
| 920 | /* 244 */ NULL, | ||
| 921 | /* 245 */ NULL, | ||
| 922 | /* 246 */ NULL, | ||
| 923 | /* 247 */ NULL, | ||
| 924 | /* 248 */ NULL, | ||
| 925 | /* 249 */ NULL, | ||
| 926 | /* 250 */ NULL, | ||
| 927 | /* 251 */ NULL, | ||
| 928 | /* 252 */ NULL, | ||
| 929 | /* 253 */ NULL, | ||
| 930 | /* 254 */ NULL, | ||
| 931 | /* 255 */ NULL, | ||
| 932 | /* 256 */ NULL, | ||
| 933 | /* 257 */ "ModeSwitch", | ||
| 934 | /* 258 */ "Sleep", | ||
| 935 | /* 259 */ "Wake", | ||
| 936 | /* 260 */ "ChannelUp", | ||
| 937 | /* 261 */ "ChannelDown", | ||
| 938 | /* 262 */ "MediaPlay", | ||
| 939 | /* 263 */ "MediaPause", | ||
| 940 | /* 264 */ "MediaRecord", | ||
| 941 | /* 265 */ "MediaFastForward", | ||
| 942 | /* 266 */ "MediaRewind", | ||
| 943 | /* 267 */ "MediaTrackNext", | ||
| 944 | /* 268 */ "MediaTrackPrevious", | ||
| 945 | /* 269 */ "MediaStop", | ||
| 946 | /* 270 */ "Eject", | ||
| 947 | /* 271 */ "MediaPlayPause", | ||
| 948 | /* 272 */ "MediaSelect", | ||
| 949 | /* 273 */ "AC New", | ||
| 950 | /* 274 */ "AC Open", | ||
| 951 | /* 275 */ "AC Close", | ||
| 952 | /* 276 */ "AC Exit", | ||
| 953 | /* 277 */ "AC Save", | ||
| 954 | /* 278 */ "AC Print", | ||
| 955 | /* 279 */ "AC Properties", | ||
| 956 | /* 280 */ "AC Search", | ||
| 957 | /* 281 */ "AC Home", | ||
| 958 | /* 282 */ "AC Back", | ||
| 959 | /* 283 */ "AC Forward", | ||
| 960 | /* 284 */ "AC Stop", | ||
| 961 | /* 285 */ "AC Refresh", | ||
| 962 | /* 286 */ "AC Bookmarks", | ||
| 963 | /* 287 */ "SoftLeft", | ||
| 964 | /* 288 */ "SoftRight", | ||
| 965 | /* 289 */ "Call", | ||
| 966 | /* 290 */ "EndCall", | ||
| 967 | }; | ||
| 968 | |||
| 969 | static const char *SDL_extended_key_names[] = { | ||
| 970 | "LeftTab", /* 0x01 SDLK_LEFT_TAB */ | ||
| 971 | "Level5Shift", /* 0x02 SDLK_LEVEL5_SHIFT */ | ||
| 972 | "MultiKeyCompose", /* 0x03 SDLK_MULTI_KEY_COMPOSE */ | ||
| 973 | "Left Meta", /* 0x04 SDLK_LMETA */ | ||
| 974 | "Right Meta", /* 0x05 SDLK_RMETA */ | ||
| 975 | "Left Hyper", /* 0x06 SDLK_LHYPER */ | ||
| 976 | "Right Hyper" /* 0x07 SDLK_RHYPER */ | ||
| 977 | }; | ||
| 978 | |||
| 979 | bool SDL_SetScancodeName(SDL_Scancode scancode, const char *name) | ||
| 980 | { | ||
| 981 | if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_SCANCODE_COUNT) { | ||
| 982 | return SDL_InvalidParamError("scancode"); | ||
| 983 | } | ||
| 984 | |||
| 985 | SDL_scancode_names[scancode] = name; | ||
| 986 | return true; | ||
| 987 | } | ||
| 988 | |||
| 989 | const char *SDL_GetScancodeName(SDL_Scancode scancode) | ||
| 990 | { | ||
| 991 | const char *name; | ||
| 992 | if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_SCANCODE_COUNT) { | ||
| 993 | SDL_InvalidParamError("scancode"); | ||
| 994 | return ""; | ||
| 995 | } | ||
| 996 | |||
| 997 | name = SDL_scancode_names[scancode]; | ||
| 998 | if (!name) { | ||
| 999 | name = ""; | ||
| 1000 | } | ||
| 1001 | // This is pointing to static memory or application managed memory | ||
| 1002 | return name; | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | SDL_Scancode SDL_GetScancodeFromName(const char *name) | ||
| 1006 | { | ||
| 1007 | int i; | ||
| 1008 | |||
| 1009 | if (!name || !*name) { | ||
| 1010 | SDL_InvalidParamError("name"); | ||
| 1011 | return SDL_SCANCODE_UNKNOWN; | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | for (i = 0; i < SDL_arraysize(SDL_scancode_names); ++i) { | ||
| 1015 | if (!SDL_scancode_names[i]) { | ||
| 1016 | continue; | ||
| 1017 | } | ||
| 1018 | if (SDL_strcasecmp(name, SDL_scancode_names[i]) == 0) { | ||
| 1019 | return (SDL_Scancode)i; | ||
| 1020 | } | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | SDL_InvalidParamError("name"); | ||
| 1024 | return SDL_SCANCODE_UNKNOWN; | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | const char *SDL_GetKeyName(SDL_Keycode key) | ||
| 1028 | { | ||
| 1029 | const bool uppercase = true; | ||
| 1030 | char name[8]; | ||
| 1031 | char *end; | ||
| 1032 | |||
| 1033 | if (key & SDLK_SCANCODE_MASK) { | ||
| 1034 | return SDL_GetScancodeName((SDL_Scancode)(key & ~SDLK_SCANCODE_MASK)); | ||
| 1035 | } | ||
| 1036 | |||
| 1037 | if (key & SDLK_EXTENDED_MASK) { | ||
| 1038 | const SDL_Keycode idx = (key & ~SDLK_EXTENDED_MASK); | ||
| 1039 | if (idx > 0 && (idx - 1) < SDL_arraysize(SDL_extended_key_names)) { | ||
| 1040 | return SDL_extended_key_names[idx - 1]; | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | // Key out of name index bounds. | ||
| 1044 | SDL_InvalidParamError("key"); | ||
| 1045 | return ""; | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | switch (key) { | ||
| 1049 | case SDLK_RETURN: | ||
| 1050 | return SDL_GetScancodeName(SDL_SCANCODE_RETURN); | ||
| 1051 | case SDLK_ESCAPE: | ||
| 1052 | return SDL_GetScancodeName(SDL_SCANCODE_ESCAPE); | ||
| 1053 | case SDLK_BACKSPACE: | ||
| 1054 | return SDL_GetScancodeName(SDL_SCANCODE_BACKSPACE); | ||
| 1055 | case SDLK_TAB: | ||
| 1056 | return SDL_GetScancodeName(SDL_SCANCODE_TAB); | ||
| 1057 | case SDLK_SPACE: | ||
| 1058 | return SDL_GetScancodeName(SDL_SCANCODE_SPACE); | ||
| 1059 | case SDLK_DELETE: | ||
| 1060 | return SDL_GetScancodeName(SDL_SCANCODE_DELETE); | ||
| 1061 | default: | ||
| 1062 | if (uppercase) { | ||
| 1063 | // SDL_Keycode is defined as the unshifted key on the keyboard, | ||
| 1064 | // but the key name is defined as the letter printed on that key, | ||
| 1065 | // which is usually the shifted capital letter. | ||
| 1066 | if (key > 0x7F || (key >= 'a' && key <= 'z')) { | ||
| 1067 | SDL_Keymap *keymap = SDL_GetCurrentKeymap(); | ||
| 1068 | SDL_Keymod modstate; | ||
| 1069 | SDL_Scancode scancode = SDL_GetKeymapScancode(keymap, key, &modstate); | ||
| 1070 | if (scancode != SDL_SCANCODE_UNKNOWN && !(modstate & SDL_KMOD_SHIFT)) { | ||
| 1071 | SDL_Keycode capital = SDL_GetKeymapKeycode(keymap, scancode, SDL_KMOD_SHIFT); | ||
| 1072 | if (capital > 0x7F || (capital >= 'A' && capital <= 'Z')) { | ||
| 1073 | key = capital; | ||
| 1074 | } | ||
| 1075 | } | ||
| 1076 | } | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | end = SDL_UCS4ToUTF8(key, name); | ||
| 1080 | *end = '\0'; | ||
| 1081 | return SDL_GetPersistentString(name); | ||
| 1082 | } | ||
| 1083 | } | ||
| 1084 | |||
| 1085 | SDL_Keycode SDL_GetKeyFromName(const char *name) | ||
| 1086 | { | ||
| 1087 | const bool uppercase = true; | ||
| 1088 | SDL_Keycode key; | ||
| 1089 | |||
| 1090 | // Check input | ||
| 1091 | if (!name) { | ||
| 1092 | return SDLK_UNKNOWN; | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | // If it's a single UTF-8 character, then that's the keycode itself | ||
| 1096 | key = *(const unsigned char *)name; | ||
| 1097 | if (key >= 0xF0) { | ||
| 1098 | if (SDL_strlen(name) == 4) { | ||
| 1099 | int i = 0; | ||
| 1100 | key = (Uint16)(name[i] & 0x07) << 18; | ||
| 1101 | key |= (Uint16)(name[++i] & 0x3F) << 12; | ||
| 1102 | key |= (Uint16)(name[++i] & 0x3F) << 6; | ||
| 1103 | key |= (Uint16)(name[++i] & 0x3F); | ||
| 1104 | } else { | ||
| 1105 | key = SDLK_UNKNOWN; | ||
| 1106 | } | ||
| 1107 | } else if (key >= 0xE0) { | ||
| 1108 | if (SDL_strlen(name) == 3) { | ||
| 1109 | int i = 0; | ||
| 1110 | key = (Uint16)(name[i] & 0x0F) << 12; | ||
| 1111 | key |= (Uint16)(name[++i] & 0x3F) << 6; | ||
| 1112 | key |= (Uint16)(name[++i] & 0x3F); | ||
| 1113 | } else { | ||
| 1114 | key = SDLK_UNKNOWN; | ||
| 1115 | } | ||
| 1116 | } else if (key >= 0xC0) { | ||
| 1117 | if (SDL_strlen(name) == 2) { | ||
| 1118 | int i = 0; | ||
| 1119 | key = (Uint16)(name[i] & 0x1F) << 6; | ||
| 1120 | key |= (Uint16)(name[++i] & 0x3F); | ||
| 1121 | } else { | ||
| 1122 | key = SDLK_UNKNOWN; | ||
| 1123 | } | ||
| 1124 | } else { | ||
| 1125 | if (SDL_strlen(name) != 1) { | ||
| 1126 | key = SDLK_UNKNOWN; | ||
| 1127 | } | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | if (key != SDLK_UNKNOWN) { | ||
| 1131 | if (uppercase) { | ||
| 1132 | // SDL_Keycode is defined as the unshifted key on the keyboard, | ||
| 1133 | // but the key name is defined as the letter printed on that key, | ||
| 1134 | // which is usually the shifted capital letter. | ||
| 1135 | SDL_Keymap *keymap = SDL_GetCurrentKeymap(); | ||
| 1136 | SDL_Keymod modstate; | ||
| 1137 | SDL_Scancode scancode = SDL_GetKeymapScancode(keymap, key, &modstate); | ||
| 1138 | if (scancode != SDL_SCANCODE_UNKNOWN && (modstate & (SDL_KMOD_SHIFT | SDL_KMOD_CAPS))) { | ||
| 1139 | key = SDL_GetKeymapKeycode(keymap, scancode, SDL_KMOD_NONE); | ||
| 1140 | } | ||
| 1141 | } | ||
| 1142 | return key; | ||
| 1143 | } | ||
| 1144 | |||
| 1145 | // Check the extended key names | ||
| 1146 | for (SDL_Keycode i = 0; i < SDL_arraysize(SDL_extended_key_names); ++i) { | ||
| 1147 | if (SDL_strcasecmp(name, SDL_extended_key_names[i]) == 0) { | ||
| 1148 | return (i + 1) | SDLK_EXTENDED_MASK; | ||
| 1149 | } | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | return SDL_GetKeyFromScancode(SDL_GetScancodeFromName(name), SDL_KMOD_NONE, false); | ||
| 1153 | } | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_keymap_c.h b/contrib/SDL-3.2.8/src/events/SDL_keymap_c.h new file mode 100644 index 0000000..9c80397 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_keymap_c.h | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #ifndef SDL_keymap_c_h_ | ||
| 24 | #define SDL_keymap_c_h_ | ||
| 25 | |||
| 26 | typedef struct SDL_Keymap SDL_Keymap; | ||
| 27 | |||
| 28 | SDL_Keymap *SDL_GetCurrentKeymap(void); | ||
| 29 | SDL_Keymap *SDL_CreateKeymap(void); | ||
| 30 | void SDL_SetKeymapEntry(SDL_Keymap *keymap, SDL_Scancode scancode, SDL_Keymod modstate, SDL_Keycode keycode); | ||
| 31 | SDL_Keycode SDL_GetKeymapKeycode(SDL_Keymap *keymap, SDL_Scancode scancode, SDL_Keymod modstate); | ||
| 32 | SDL_Scancode SDL_GetKeymapScancode(SDL_Keymap *keymap, SDL_Keycode keycode, SDL_Keymod *modstate); | ||
| 33 | void SDL_DestroyKeymap(SDL_Keymap *keymap); | ||
| 34 | |||
| 35 | #endif // SDL_keymap_c_h_ | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_keysym_to_keycode.c b/contrib/SDL-3.2.8/src/events/SDL_keysym_to_keycode.c new file mode 100644 index 0000000..7cbfcb6 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_keysym_to_keycode.c | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #if defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_X11) | ||
| 24 | |||
| 25 | #include "SDL_keyboard_c.h" | ||
| 26 | #include "SDL_keysym_to_scancode_c.h" | ||
| 27 | #include "imKStoUCS.h" | ||
| 28 | |||
| 29 | |||
| 30 | // Extended key code mappings | ||
| 31 | static const struct | ||
| 32 | { | ||
| 33 | Uint32 keysym; | ||
| 34 | SDL_Keycode keycode; | ||
| 35 | } keysym_to_keycode_table[] = { | ||
| 36 | { 0xfe03, SDLK_MODE }, // XK_ISO_Level3_Shift | ||
| 37 | { 0xfe11, SDLK_LEVEL5_SHIFT }, // XK_ISO_Level5_Shift | ||
| 38 | { 0xfe20, SDLK_LEFT_TAB }, // XK_ISO_Left_Tab | ||
| 39 | { 0xff20, SDLK_MULTI_KEY_COMPOSE }, // XK_Multi_key | ||
| 40 | { 0xffe7, SDLK_LMETA }, // XK_Meta_L | ||
| 41 | { 0xffe8, SDLK_RMETA }, // XK_Meta_R | ||
| 42 | { 0xffed, SDLK_LHYPER }, // XK_Hyper_L | ||
| 43 | { 0xffee, SDLK_RHYPER }, // XK_Hyper_R | ||
| 44 | }; | ||
| 45 | |||
| 46 | SDL_Keycode SDL_GetKeyCodeFromKeySym(Uint32 keysym, Uint32 keycode, SDL_Keymod modifiers) | ||
| 47 | { | ||
| 48 | SDL_Keycode sdl_keycode = SDL_KeySymToUcs4(keysym); | ||
| 49 | |||
| 50 | if (!sdl_keycode) { | ||
| 51 | for (int i = 0; i < SDL_arraysize(keysym_to_keycode_table); ++i) { | ||
| 52 | if (keysym == keysym_to_keycode_table[i].keysym) { | ||
| 53 | return keysym_to_keycode_table[i].keycode; | ||
| 54 | } | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | if (!sdl_keycode) { | ||
| 59 | const SDL_Scancode scancode = SDL_GetScancodeFromKeySym(keysym, keycode); | ||
| 60 | if (scancode != SDL_SCANCODE_UNKNOWN) { | ||
| 61 | sdl_keycode = SDL_GetKeymapKeycode(NULL, scancode, modifiers); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | return sdl_keycode; | ||
| 66 | } | ||
| 67 | |||
| 68 | #endif // SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_X11 | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_keysym_to_keycode_c.h b/contrib/SDL-3.2.8/src/events/SDL_keysym_to_keycode_c.h new file mode 100644 index 0000000..2321d20 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_keysym_to_keycode_c.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #ifndef SDL_keysym_to_keycode_c_h_ | ||
| 23 | #define SDL_keysym_to_keycode_c_h_ | ||
| 24 | |||
| 25 | // Convert a keysym to an SDL key code | ||
| 26 | extern SDL_Keycode SDL_GetKeyCodeFromKeySym(Uint32 keysym, Uint32 keycode, SDL_Keymod modifiers); | ||
| 27 | |||
| 28 | #endif // SDL_keysym_to_scancode_c_h_ | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_keysym_to_scancode.c b/contrib/SDL-3.2.8/src/events/SDL_keysym_to_scancode.c new file mode 100644 index 0000000..8d43ca3 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_keysym_to_scancode.c | |||
| @@ -0,0 +1,439 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #if defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_X11) | ||
| 24 | |||
| 25 | #include "SDL_keyboard_c.h" | ||
| 26 | #include "SDL_scancode_tables_c.h" | ||
| 27 | #include "SDL_keysym_to_scancode_c.h" | ||
| 28 | |||
| 29 | /* *INDENT-OFF* */ // clang-format off | ||
| 30 | static const struct { | ||
| 31 | Uint32 keysym; | ||
| 32 | SDL_Scancode scancode; | ||
| 33 | } KeySymToSDLScancode[] = { | ||
| 34 | { 0xFF9C, SDL_SCANCODE_KP_1 }, // XK_KP_End | ||
| 35 | { 0xFF99, SDL_SCANCODE_KP_2 }, // XK_KP_Down | ||
| 36 | { 0xFF9B, SDL_SCANCODE_KP_3 }, // XK_KP_Next | ||
| 37 | { 0xFF96, SDL_SCANCODE_KP_4 }, // XK_KP_Left | ||
| 38 | { 0xFF9D, SDL_SCANCODE_KP_5 }, // XK_KP_Begin | ||
| 39 | { 0xFF98, SDL_SCANCODE_KP_6 }, // XK_KP_Right | ||
| 40 | { 0xFF95, SDL_SCANCODE_KP_7 }, // XK_KP_Home | ||
| 41 | { 0xFF97, SDL_SCANCODE_KP_8 }, // XK_KP_Up | ||
| 42 | { 0xFF9A, SDL_SCANCODE_KP_9 }, // XK_KP_Prior | ||
| 43 | { 0xFF9E, SDL_SCANCODE_KP_0 }, // XK_KP_Insert | ||
| 44 | { 0xFF9F, SDL_SCANCODE_KP_PERIOD }, // XK_KP_Delete | ||
| 45 | { 0xFF62, SDL_SCANCODE_EXECUTE }, // XK_Execute | ||
| 46 | { 0xFFEE, SDL_SCANCODE_APPLICATION }, // XK_Hyper_R | ||
| 47 | { 0xFE03, SDL_SCANCODE_RALT }, // XK_ISO_Level3_Shift | ||
| 48 | { 0xFE20, SDL_SCANCODE_TAB }, // XK_ISO_Left_Tab | ||
| 49 | { 0xFFEB, SDL_SCANCODE_LGUI }, // XK_Super_L | ||
| 50 | { 0xFFEC, SDL_SCANCODE_RGUI }, // XK_Super_R | ||
| 51 | { 0xFF7E, SDL_SCANCODE_MODE }, // XK_Mode_switch | ||
| 52 | { 0x1008FF65, SDL_SCANCODE_MENU }, // XF86MenuKB | ||
| 53 | { 0x1008FF81, SDL_SCANCODE_F13 }, // XF86Tools | ||
| 54 | { 0x1008FF45, SDL_SCANCODE_F14 }, // XF86Launch5 | ||
| 55 | { 0x1008FF46, SDL_SCANCODE_F15 }, // XF86Launch6 | ||
| 56 | { 0x1008FF47, SDL_SCANCODE_F16 }, // XF86Launch7 | ||
| 57 | { 0x1008FF48, SDL_SCANCODE_F17 }, // XF86Launch8 | ||
| 58 | { 0x1008FF49, SDL_SCANCODE_F18 }, // XF86Launch9 | ||
| 59 | }; | ||
| 60 | |||
| 61 | // This is a mapping from X keysym to Linux keycode | ||
| 62 | static const Uint32 LinuxKeycodeKeysyms[] = { | ||
| 63 | /* 0, 0x000 */ 0x0, // NoSymbol | ||
| 64 | /* 1, 0x001 */ 0xFF1B, // Escape | ||
| 65 | /* 2, 0x002 */ 0x31, // 1 | ||
| 66 | /* 3, 0x003 */ 0x32, // 2 | ||
| 67 | /* 4, 0x004 */ 0x33, // 3 | ||
| 68 | /* 5, 0x005 */ 0x34, // 4 | ||
| 69 | /* 6, 0x006 */ 0x35, // 5 | ||
| 70 | /* 7, 0x007 */ 0x36, // 6 | ||
| 71 | /* 8, 0x008 */ 0x37, // 7 | ||
| 72 | /* 9, 0x009 */ 0x38, // 8 | ||
| 73 | /* 10, 0x00a */ 0x39, // 9 | ||
| 74 | /* 11, 0x00b */ 0x30, // 0 | ||
| 75 | /* 12, 0x00c */ 0x2D, // minus | ||
| 76 | /* 13, 0x00d */ 0x3D, // equal | ||
| 77 | /* 14, 0x00e */ 0xFF08, // BackSpace | ||
| 78 | /* 15, 0x00f */ 0xFF09, // Tab | ||
| 79 | /* 16, 0x010 */ 0x71, // q | ||
| 80 | /* 17, 0x011 */ 0x77, // w | ||
| 81 | /* 18, 0x012 */ 0x65, // e | ||
| 82 | /* 19, 0x013 */ 0x72, // r | ||
| 83 | /* 20, 0x014 */ 0x74, // t | ||
| 84 | /* 21, 0x015 */ 0x79, // y | ||
| 85 | /* 22, 0x016 */ 0x75, // u | ||
| 86 | /* 23, 0x017 */ 0x69, // i | ||
| 87 | /* 24, 0x018 */ 0x6F, // o | ||
| 88 | /* 25, 0x019 */ 0x70, // p | ||
| 89 | /* 26, 0x01a */ 0x5B, // bracketleft | ||
| 90 | /* 27, 0x01b */ 0x5D, // bracketright | ||
| 91 | /* 28, 0x01c */ 0xFF0D, // Return | ||
| 92 | /* 29, 0x01d */ 0xFFE3, // Control_L | ||
| 93 | /* 30, 0x01e */ 0x61, // a | ||
| 94 | /* 31, 0x01f */ 0x73, // s | ||
| 95 | /* 32, 0x020 */ 0x64, // d | ||
| 96 | /* 33, 0x021 */ 0x66, // f | ||
| 97 | /* 34, 0x022 */ 0x67, // g | ||
| 98 | /* 35, 0x023 */ 0x68, // h | ||
| 99 | /* 36, 0x024 */ 0x6A, // j | ||
| 100 | /* 37, 0x025 */ 0x6B, // k | ||
| 101 | /* 38, 0x026 */ 0x6C, // l | ||
| 102 | /* 39, 0x027 */ 0x3B, // semicolon | ||
| 103 | /* 40, 0x028 */ 0x27, // apostrophe | ||
| 104 | /* 41, 0x029 */ 0x60, // grave | ||
| 105 | /* 42, 0x02a */ 0xFFE1, // Shift_L | ||
| 106 | /* 43, 0x02b */ 0x5C, // backslash | ||
| 107 | /* 44, 0x02c */ 0x7A, // z | ||
| 108 | /* 45, 0x02d */ 0x78, // x | ||
| 109 | /* 46, 0x02e */ 0x63, // c | ||
| 110 | /* 47, 0x02f */ 0x76, // v | ||
| 111 | /* 48, 0x030 */ 0x62, // b | ||
| 112 | /* 49, 0x031 */ 0x6E, // n | ||
| 113 | /* 50, 0x032 */ 0x6D, // m | ||
| 114 | /* 51, 0x033 */ 0x2C, // comma | ||
| 115 | /* 52, 0x034 */ 0x2E, // period | ||
| 116 | /* 53, 0x035 */ 0x2F, // slash | ||
| 117 | /* 54, 0x036 */ 0xFFE2, // Shift_R | ||
| 118 | /* 55, 0x037 */ 0xFFAA, // KP_Multiply | ||
| 119 | /* 56, 0x038 */ 0xFFE9, // Alt_L | ||
| 120 | /* 57, 0x039 */ 0x20, // space | ||
| 121 | /* 58, 0x03a */ 0xFFE5, // Caps_Lock | ||
| 122 | /* 59, 0x03b */ 0xFFBE, // F1 | ||
| 123 | /* 60, 0x03c */ 0xFFBF, // F2 | ||
| 124 | /* 61, 0x03d */ 0xFFC0, // F3 | ||
| 125 | /* 62, 0x03e */ 0xFFC1, // F4 | ||
| 126 | /* 63, 0x03f */ 0xFFC2, // F5 | ||
| 127 | /* 64, 0x040 */ 0xFFC3, // F6 | ||
| 128 | /* 65, 0x041 */ 0xFFC4, // F7 | ||
| 129 | /* 66, 0x042 */ 0xFFC5, // F8 | ||
| 130 | /* 67, 0x043 */ 0xFFC6, // F9 | ||
| 131 | /* 68, 0x044 */ 0xFFC7, // F10 | ||
| 132 | /* 69, 0x045 */ 0xFF7F, // Num_Lock | ||
| 133 | /* 70, 0x046 */ 0xFF14, // Scroll_Lock | ||
| 134 | /* 71, 0x047 */ 0xFFB7, // KP_7 | ||
| 135 | /* 72, 0x048 */ 0XFFB8, // KP_8 | ||
| 136 | /* 73, 0x049 */ 0XFFB9, // KP_9 | ||
| 137 | /* 74, 0x04a */ 0xFFAD, // KP_Subtract | ||
| 138 | /* 75, 0x04b */ 0xFFB4, // KP_4 | ||
| 139 | /* 76, 0x04c */ 0xFFB5, // KP_5 | ||
| 140 | /* 77, 0x04d */ 0xFFB6, // KP_6 | ||
| 141 | /* 78, 0x04e */ 0xFFAB, // KP_Add | ||
| 142 | /* 79, 0x04f */ 0xFFB1, // KP_1 | ||
| 143 | /* 80, 0x050 */ 0xFFB2, // KP_2 | ||
| 144 | /* 81, 0x051 */ 0xFFB3, // KP_3 | ||
| 145 | /* 82, 0x052 */ 0xFFB0, // KP_0 | ||
| 146 | /* 83, 0x053 */ 0xFFAE, // KP_Decimal | ||
| 147 | /* 84, 0x054 */ 0x0, // NoSymbol | ||
| 148 | /* 85, 0x055 */ 0x0, // NoSymbol | ||
| 149 | /* 86, 0x056 */ 0x3C, // less | ||
| 150 | /* 87, 0x057 */ 0xFFC8, // F11 | ||
| 151 | /* 88, 0x058 */ 0xFFC9, // F12 | ||
| 152 | /* 89, 0x059 */ 0x0, // NoSymbol | ||
| 153 | /* 90, 0x05a */ 0xFF26, // Katakana | ||
| 154 | /* 91, 0x05b */ 0xFF25, // Hiragana | ||
| 155 | /* 92, 0x05c */ 0xFF23, // Henkan_Mode | ||
| 156 | /* 93, 0x05d */ 0xFF27, // Hiragana_Katakana | ||
| 157 | /* 94, 0x05e */ 0xFF22, // Muhenkan | ||
| 158 | /* 95, 0x05f */ 0x0, // NoSymbol | ||
| 159 | /* 96, 0x060 */ 0xFF8D, // KP_Enter | ||
| 160 | /* 97, 0x061 */ 0xFFE4, // Control_R | ||
| 161 | /* 98, 0x062 */ 0xFFAF, // KP_Divide | ||
| 162 | /* 99, 0x063 */ 0xFF15, // Sys_Req | ||
| 163 | /* 100, 0x064 */ 0xFFEA, // Alt_R | ||
| 164 | /* 101, 0x065 */ 0xFF0A, // Linefeed | ||
| 165 | /* 102, 0x066 */ 0xFF50, // Home | ||
| 166 | /* 103, 0x067 */ 0xFF52, // Up | ||
| 167 | /* 104, 0x068 */ 0xFF55, // Prior | ||
| 168 | /* 105, 0x069 */ 0xFF51, // Left | ||
| 169 | /* 106, 0x06a */ 0xFF53, // Right | ||
| 170 | /* 107, 0x06b */ 0xFF57, // End | ||
| 171 | /* 108, 0x06c */ 0xFF54, // Down | ||
| 172 | /* 109, 0x06d */ 0xFF56, // Next | ||
| 173 | /* 110, 0x06e */ 0xFF63, // Insert | ||
| 174 | /* 111, 0x06f */ 0xFFFF, // Delete | ||
| 175 | /* 112, 0x070 */ 0x0, // NoSymbol | ||
| 176 | /* 113, 0x071 */ 0x1008FF12, // XF86AudioMute | ||
| 177 | /* 114, 0x072 */ 0x1008FF11, // XF86AudioLowerVolume | ||
| 178 | /* 115, 0x073 */ 0x1008FF13, // XF86AudioRaiseVolume | ||
| 179 | /* 116, 0x074 */ 0x1008FF2A, // XF86PowerOff | ||
| 180 | /* 117, 0x075 */ 0xFFBD, // KP_Equal | ||
| 181 | /* 118, 0x076 */ 0xB1, // plusminus | ||
| 182 | /* 119, 0x077 */ 0xFF13, // Pause | ||
| 183 | /* 120, 0x078 */ 0x1008FF4A, // XF86LaunchA | ||
| 184 | /* 121, 0x079 */ 0xFFAC, // KP_Separator | ||
| 185 | /* 122, 0x07a */ 0xFF31, // Hangul | ||
| 186 | /* 123, 0x07b */ 0xFF34, // Hangul_Hanja | ||
| 187 | /* 124, 0x07c */ 0x0, // NoSymbol | ||
| 188 | /* 125, 0x07d */ 0xFFE7, // Meta_L | ||
| 189 | /* 126, 0x07e */ 0xFFE8, // Meta_R | ||
| 190 | /* 127, 0x07f */ 0xFF67, // Menu | ||
| 191 | /* 128, 0x080 */ 0x00, // NoSymbol | ||
| 192 | /* 129, 0x081 */ 0xFF66, // Redo | ||
| 193 | /* 130, 0x082 */ 0x1005FF70, // SunProps | ||
| 194 | /* 131, 0x083 */ 0xFF65, // Undo | ||
| 195 | /* 132, 0x084 */ 0x1005FF71, // SunFront | ||
| 196 | /* 133, 0x085 */ 0x1008FF57, // XF86Copy | ||
| 197 | /* 134, 0x086 */ 0x1008FF6B, // XF86Open | ||
| 198 | /* 135, 0x087 */ 0x1008FF6D, // XF86Paste | ||
| 199 | /* 136, 0x088 */ 0xFF68, // Find | ||
| 200 | /* 137, 0x089 */ 0x1008FF58, // XF86Cut | ||
| 201 | /* 138, 0x08a */ 0xFF6A, // Help | ||
| 202 | /* 139, 0x08b */ 0xFF67, // Menu | ||
| 203 | /* 140, 0x08c */ 0x1008FF1D, // XF86Calculator | ||
| 204 | /* 141, 0x08d */ 0x0, // NoSymbol | ||
| 205 | /* 142, 0x08e */ 0x1008FF2F, // XF86Sleep | ||
| 206 | /* 143, 0x08f */ 0x1008FF2B, // XF86WakeUp | ||
| 207 | /* 144, 0x090 */ 0x1008FF5D, // XF86Explorer | ||
| 208 | /* 145, 0x091 */ 0x1008FF7B, // XF86Send | ||
| 209 | /* 146, 0x092 */ 0x0, // NoSymbol | ||
| 210 | /* 147, 0x093 */ 0x1008FF8A, // XF86Xfer | ||
| 211 | /* 148, 0x094 */ 0x1008FF41, // XF86Launch1 | ||
| 212 | /* 149, 0x095 */ 0x1008FF42, // XF86Launch2 | ||
| 213 | /* 150, 0x096 */ 0x1008FF2E, // XF86WWW | ||
| 214 | /* 151, 0x097 */ 0x1008FF5A, // XF86DOS | ||
| 215 | /* 152, 0x098 */ 0x1008FF2D, // XF86ScreenSaver | ||
| 216 | /* 153, 0x099 */ 0x1008FF74, // XF86RotateWindows | ||
| 217 | /* 154, 0x09a */ 0x1008FF7F, // XF86TaskPane | ||
| 218 | /* 155, 0x09b */ 0x1008FF19, // XF86Mail | ||
| 219 | /* 156, 0x09c */ 0x1008FF30, // XF86Favorites | ||
| 220 | /* 157, 0x09d */ 0x1008FF33, // XF86MyComputer | ||
| 221 | /* 158, 0x09e */ 0x1008FF26, // XF86Back | ||
| 222 | /* 159, 0x09f */ 0x1008FF27, // XF86Forward | ||
| 223 | /* 160, 0x0a0 */ 0x0, // NoSymbol | ||
| 224 | /* 161, 0x0a1 */ 0x1008FF2C, // XF86Eject | ||
| 225 | /* 162, 0x0a2 */ 0x1008FF2C, // XF86Eject | ||
| 226 | /* 163, 0x0a3 */ 0x1008FF17, // XF86AudioNext | ||
| 227 | /* 164, 0x0a4 */ 0x1008FF14, // XF86AudioPlay | ||
| 228 | /* 165, 0x0a5 */ 0x1008FF16, // XF86AudioPrev | ||
| 229 | /* 166, 0x0a6 */ 0x1008FF15, // XF86AudioStop | ||
| 230 | /* 167, 0x0a7 */ 0x1008FF1C, // XF86AudioRecord | ||
| 231 | /* 168, 0x0a8 */ 0x1008FF3E, // XF86AudioRewind | ||
| 232 | /* 169, 0x0a9 */ 0x1008FF6E, // XF86Phone | ||
| 233 | /* 170, 0x0aa */ 0x0, // NoSymbol | ||
| 234 | /* 171, 0x0ab */ 0x1008FF81, // XF86Tools | ||
| 235 | /* 172, 0x0ac */ 0x1008FF18, // XF86HomePage | ||
| 236 | /* 173, 0x0ad */ 0x1008FF73, // XF86Reload | ||
| 237 | /* 174, 0x0ae */ 0x1008FF56, // XF86Close | ||
| 238 | /* 175, 0x0af */ 0x0, // NoSymbol | ||
| 239 | /* 176, 0x0b0 */ 0x0, // NoSymbol | ||
| 240 | /* 177, 0x0b1 */ 0x1008FF78, // XF86ScrollUp | ||
| 241 | /* 178, 0x0b2 */ 0x1008FF79, // XF86ScrollDown | ||
| 242 | /* 179, 0x0b3 */ 0x0, // NoSymbol | ||
| 243 | /* 180, 0x0b4 */ 0x0, // NoSymbol | ||
| 244 | /* 181, 0x0b5 */ 0x1008FF68, // XF86New | ||
| 245 | /* 182, 0x0b6 */ 0xFF66, // Redo | ||
| 246 | /* 183, 0x0b7 */ 0xFFCA, // F13 | ||
| 247 | /* 184, 0x0b8 */ 0xFFCB, // F14 | ||
| 248 | /* 185, 0x0b9 */ 0xFFCC, // F15 | ||
| 249 | /* 186, 0x0ba */ 0xFFCD, // F16 | ||
| 250 | /* 187, 0x0bb */ 0xFFCE, // F17 | ||
| 251 | /* 188, 0x0bc */ 0xFFCF, // F18 | ||
| 252 | /* 189, 0x0bd */ 0xFFD0, // F19 | ||
| 253 | /* 190, 0x0be */ 0xFFD1, // F20 | ||
| 254 | /* 191, 0x0bf */ 0xFFD2, // F21 | ||
| 255 | /* 192, 0x0c0 */ 0xFFD3, // F22 | ||
| 256 | /* 193, 0x0c1 */ 0xFFD4, // F23 | ||
| 257 | /* 194, 0x0c2 */ 0xFFD5, // F24 | ||
| 258 | /* 195, 0x0c3 */ 0x0, // NoSymbol | ||
| 259 | /* 196, 0x0c4 */ 0x0, // NoSymbol | ||
| 260 | /* 197, 0x0c5 */ 0x0, // NoSymbol | ||
| 261 | /* 198, 0x0c6 */ 0x0, // NoSymbol | ||
| 262 | /* 199, 0x0c7 */ 0x0, // NoSymbol | ||
| 263 | /* 200, 0x0c8 */ 0x1008FF14, // XF86AudioPlay | ||
| 264 | /* 201, 0x0c9 */ 0x1008FF31, // XF86AudioPause | ||
| 265 | /* 202, 0x0ca */ 0x1008FF43, // XF86Launch3 | ||
| 266 | /* 203, 0x0cb */ 0x1008FF44, // XF86Launch4 | ||
| 267 | /* 204, 0x0cc */ 0x1008FF4B, // XF86LaunchB | ||
| 268 | /* 205, 0x0cd */ 0x1008FFA7, // XF86Suspend | ||
| 269 | /* 206, 0x0ce */ 0x1008FF56, // XF86Close | ||
| 270 | /* 207, 0x0cf */ 0x1008FF14, // XF86AudioPlay | ||
| 271 | /* 208, 0x0d0 */ 0x1008FF97, // XF86AudioForward | ||
| 272 | /* 209, 0x0d1 */ 0x0, // NoSymbol | ||
| 273 | /* 210, 0x0d2 */ 0xFF61, // Print | ||
| 274 | /* 211, 0x0d3 */ 0x0, // NoSymbol | ||
| 275 | /* 212, 0x0d4 */ 0x1008FF8F, // XF86WebCam | ||
| 276 | /* 213, 0x0d5 */ 0x1008FFB6, // XF86AudioPreset | ||
| 277 | /* 214, 0x0d6 */ 0x0, // NoSymbol | ||
| 278 | /* 215, 0x0d7 */ 0x1008FF19, // XF86Mail | ||
| 279 | /* 216, 0x0d8 */ 0x1008FF8E, // XF86Messenger | ||
| 280 | /* 217, 0x0d9 */ 0x1008FF1B, // XF86Search | ||
| 281 | /* 218, 0x0da */ 0x1008FF5F, // XF86Go | ||
| 282 | /* 219, 0x0db */ 0x1008FF3C, // XF86Finance | ||
| 283 | /* 220, 0x0dc */ 0x1008FF5E, // XF86Game | ||
| 284 | /* 221, 0x0dd */ 0x1008FF36, // XF86Shop | ||
| 285 | /* 222, 0x0de */ 0x0, // NoSymbol | ||
| 286 | /* 223, 0x0df */ 0xFF69, // Cancel | ||
| 287 | /* 224, 0x0e0 */ 0x1008FF03, // XF86MonBrightnessDown | ||
| 288 | /* 225, 0x0e1 */ 0x1008FF02, // XF86MonBrightnessUp | ||
| 289 | /* 226, 0x0e2 */ 0x1008FF32, // XF86AudioMedia | ||
| 290 | /* 227, 0x0e3 */ 0x1008FF59, // XF86Display | ||
| 291 | /* 228, 0x0e4 */ 0x1008FF04, // XF86KbdLightOnOff | ||
| 292 | /* 229, 0x0e5 */ 0x1008FF06, // XF86KbdBrightnessDown | ||
| 293 | /* 230, 0x0e6 */ 0x1008FF05, // XF86KbdBrightnessUp | ||
| 294 | /* 231, 0x0e7 */ 0x1008FF7B, // XF86Send | ||
| 295 | /* 232, 0x0e8 */ 0x1008FF72, // XF86Reply | ||
| 296 | /* 233, 0x0e9 */ 0x1008FF90, // XF86MailForward | ||
| 297 | /* 234, 0x0ea */ 0x1008FF77, // XF86Save | ||
| 298 | /* 235, 0x0eb */ 0x1008FF5B, // XF86Documents | ||
| 299 | /* 236, 0x0ec */ 0x1008FF93, // XF86Battery | ||
| 300 | /* 237, 0x0ed */ 0x1008FF94, // XF86Bluetooth | ||
| 301 | /* 238, 0x0ee */ 0x1008FF95, // XF86WLAN | ||
| 302 | /* 239, 0x0ef */ 0x1008FF96, // XF86UWB | ||
| 303 | /* 240, 0x0f0 */ 0x0, // NoSymbol | ||
| 304 | /* 241, 0x0f1 */ 0x1008FE22, // XF86Next_VMode | ||
| 305 | /* 242, 0x0f2 */ 0x1008FE23, // XF86Prev_VMode | ||
| 306 | /* 243, 0x0f3 */ 0x1008FF07, // XF86MonBrightnessCycle | ||
| 307 | /* 244, 0x0f4 */ 0x100810F4, // XF86BrightnessAuto | ||
| 308 | /* 245, 0x0f5 */ 0x100810F5, // XF86DisplayOff | ||
| 309 | /* 246, 0x0f6 */ 0x1008FFB4, // XF86WWAN | ||
| 310 | /* 247, 0x0f7 */ 0x1008FFB5, // XF86RFKill | ||
| 311 | }; | ||
| 312 | |||
| 313 | #if 0 // Here is a script to generate the ExtendedLinuxKeycodeKeysyms table | ||
| 314 | #!/bin/bash | ||
| 315 | |||
| 316 | function process_line | ||
| 317 | { | ||
| 318 | sym=$(echo "$1" | awk '{print $3}') | ||
| 319 | code=$(echo "$1" | sed 's,.*_EVDEVK(\(0x[0-9A-Fa-f]*\)).*,\1,') | ||
| 320 | value=$(grep -E "#define ${sym}\s" -R /usr/include/X11 | awk '{print $3}') | ||
| 321 | printf " { 0x%.8X, 0x%.3x }, /* $sym */\n" $value $code | ||
| 322 | } | ||
| 323 | |||
| 324 | grep -F "/* Use: " /usr/include/xkbcommon/xkbcommon-keysyms.h | grep -F _EVDEVK | while read line; do | ||
| 325 | process_line "$line" | ||
| 326 | done | ||
| 327 | #endif | ||
| 328 | |||
| 329 | static const struct { | ||
| 330 | Uint32 keysym; | ||
| 331 | int linux_keycode; | ||
| 332 | } ExtendedLinuxKeycodeKeysyms[] = { | ||
| 333 | { 0x1008FF2C, 0x0a2 }, // XF86XK_Eject | ||
| 334 | { 0x1008FF68, 0x0b5 }, // XF86XK_New | ||
| 335 | { 0x0000FF66, 0x0b6 }, // XK_Redo | ||
| 336 | { 0x1008FF4B, 0x0cc }, // XF86XK_LaunchB | ||
| 337 | { 0x1008FF59, 0x0e3 }, // XF86XK_Display | ||
| 338 | { 0x1008FF04, 0x0e4 }, // XF86XK_KbdLightOnOff | ||
| 339 | { 0x1008FF06, 0x0e5 }, // XF86XK_KbdBrightnessDown | ||
| 340 | { 0x1008FF05, 0x0e6 }, // XF86XK_KbdBrightnessUp | ||
| 341 | { 0x1008FF7B, 0x0e7 }, // XF86XK_Send | ||
| 342 | { 0x1008FF72, 0x0e8 }, // XF86XK_Reply | ||
| 343 | { 0x1008FF90, 0x0e9 }, // XF86XK_MailForward | ||
| 344 | { 0x1008FF77, 0x0ea }, // XF86XK_Save | ||
| 345 | { 0x1008FF5B, 0x0eb }, // XF86XK_Documents | ||
| 346 | { 0x1008FF93, 0x0ec }, // XF86XK_Battery | ||
| 347 | { 0x1008FF94, 0x0ed }, // XF86XK_Bluetooth | ||
| 348 | { 0x1008FF95, 0x0ee }, // XF86XK_WLAN | ||
| 349 | { 0x1008FF96, 0x0ef }, // XF86XK_UWB | ||
| 350 | { 0x1008FE22, 0x0f1 }, // XF86XK_Next_VMode | ||
| 351 | { 0x1008FE23, 0x0f2 }, // XF86XK_Prev_VMode | ||
| 352 | { 0x1008FF07, 0x0f3 }, // XF86XK_MonBrightnessCycle | ||
| 353 | { 0x1008FFB4, 0x0f6 }, // XF86XK_WWAN | ||
| 354 | { 0x1008FFB5, 0x0f7 }, // XF86XK_RFKill | ||
| 355 | { 0x1008FFB2, 0x0f8 }, // XF86XK_AudioMicMute | ||
| 356 | { 0x1008FF9C, 0x173 }, // XF86XK_CycleAngle | ||
| 357 | { 0x1008FFB8, 0x174 }, // XF86XK_FullScreen | ||
| 358 | { 0x1008FF87, 0x189 }, // XF86XK_Video | ||
| 359 | { 0x1008FF20, 0x18d }, // XF86XK_Calendar | ||
| 360 | { 0x1008FF99, 0x19a }, // XF86XK_AudioRandomPlay | ||
| 361 | { 0x1008FF5E, 0x1a1 }, // XF86XK_Game | ||
| 362 | { 0x1008FF8B, 0x1a2 }, // XF86XK_ZoomIn | ||
| 363 | { 0x1008FF8C, 0x1a3 }, // XF86XK_ZoomOut | ||
| 364 | { 0x1008FF89, 0x1a5 }, // XF86XK_Word | ||
| 365 | { 0x1008FF5C, 0x1a7 }, // XF86XK_Excel | ||
| 366 | { 0x1008FF69, 0x1ab }, // XF86XK_News | ||
| 367 | { 0x1008FF8E, 0x1ae }, // XF86XK_Messenger | ||
| 368 | { 0x1008FF61, 0x1b1 }, // XF86XK_LogOff | ||
| 369 | { 0x00000024, 0x1b2 }, // XK_dollar | ||
| 370 | { 0x000020AC, 0x1b3 }, // XK_EuroSign | ||
| 371 | { 0x1008FF9D, 0x1b4 }, // XF86XK_FrameBack | ||
| 372 | { 0x1008FF9E, 0x1b5 }, // XF86XK_FrameForward | ||
| 373 | { 0x0000FFF1, 0x1f1 }, // XK_braille_dot_1 | ||
| 374 | { 0x0000FFF2, 0x1f2 }, // XK_braille_dot_2 | ||
| 375 | { 0x0000FFF3, 0x1f3 }, // XK_braille_dot_3 | ||
| 376 | { 0x0000FFF4, 0x1f4 }, // XK_braille_dot_4 | ||
| 377 | { 0x0000FFF5, 0x1f5 }, // XK_braille_dot_5 | ||
| 378 | { 0x0000FFF6, 0x1f6 }, // XK_braille_dot_6 | ||
| 379 | { 0x0000FFF7, 0x1f7 }, // XK_braille_dot_7 | ||
| 380 | { 0x0000FFF8, 0x1f8 }, // XK_braille_dot_8 | ||
| 381 | { 0x0000FFF9, 0x1f9 }, // XK_braille_dot_9 | ||
| 382 | { 0x0000FFF1, 0x1fa }, // XK_braille_dot_1 | ||
| 383 | { 0x1008FFA9, 0x212 }, // XF86XK_TouchpadToggle | ||
| 384 | { 0x1008FFB0, 0x213 }, // XF86XK_TouchpadOn | ||
| 385 | { 0x1008FFB1, 0x214 }, // XF86XK_TouchpadOff | ||
| 386 | { 0x1008FFB7, 0x231 }, // XF86XK_RotationLockToggle | ||
| 387 | { 0x0000FE08, 0x248 }, // XK_ISO_Next_Group | ||
| 388 | }; | ||
| 389 | /* *INDENT-ON* */ // clang-format on | ||
| 390 | |||
| 391 | SDL_Scancode SDL_GetScancodeFromKeySym(Uint32 keysym, Uint32 keycode) | ||
| 392 | { | ||
| 393 | int i; | ||
| 394 | Uint32 linux_keycode = 0; | ||
| 395 | |||
| 396 | // First check our custom list | ||
| 397 | for (i = 0; i < SDL_arraysize(KeySymToSDLScancode); ++i) { | ||
| 398 | if (keysym == KeySymToSDLScancode[i].keysym) { | ||
| 399 | return KeySymToSDLScancode[i].scancode; | ||
| 400 | } | ||
| 401 | } | ||
| 402 | |||
| 403 | if (keysym >= 0x41 && keysym <= 0x5a) { | ||
| 404 | // Normalize alphabetic keysyms to the lowercase form | ||
| 405 | keysym += 0x20; | ||
| 406 | } else if (keysym >= 0x10081000 && keysym <= 0x10081FFF) { | ||
| 407 | /* The rest of the keysyms map to Linux keycodes, so use that mapping | ||
| 408 | * Per xkbcommon-keysyms.h, this is actually a linux keycode. | ||
| 409 | */ | ||
| 410 | linux_keycode = (keysym - 0x10081000); | ||
| 411 | } | ||
| 412 | if (!linux_keycode) { | ||
| 413 | // See if this keysym is an exact match in our table | ||
| 414 | i = (keycode - 8); | ||
| 415 | if (i >= 0 && i < SDL_arraysize(LinuxKeycodeKeysyms) && keysym == LinuxKeycodeKeysyms[i]) { | ||
| 416 | linux_keycode = i; | ||
| 417 | } else { | ||
| 418 | // Scan the table for this keysym | ||
| 419 | for (i = 0; i < SDL_arraysize(LinuxKeycodeKeysyms); ++i) { | ||
| 420 | if (keysym == LinuxKeycodeKeysyms[i]) { | ||
| 421 | linux_keycode = i; | ||
| 422 | break; | ||
| 423 | } | ||
| 424 | } | ||
| 425 | } | ||
| 426 | } | ||
| 427 | if (!linux_keycode) { | ||
| 428 | // Scan the extended table for this keysym | ||
| 429 | for (i = 0; i < SDL_arraysize(ExtendedLinuxKeycodeKeysyms); ++i) { | ||
| 430 | if (keysym == ExtendedLinuxKeycodeKeysyms[i].keysym) { | ||
| 431 | linux_keycode = ExtendedLinuxKeycodeKeysyms[i].linux_keycode; | ||
| 432 | break; | ||
| 433 | } | ||
| 434 | } | ||
| 435 | } | ||
| 436 | return SDL_GetScancodeFromTable(SDL_SCANCODE_TABLE_LINUX, linux_keycode); | ||
| 437 | } | ||
| 438 | |||
| 439 | #endif // SDL_VIDEO_DRIVER_WAYLAND | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_keysym_to_scancode_c.h b/contrib/SDL-3.2.8/src/events/SDL_keysym_to_scancode_c.h new file mode 100644 index 0000000..8d0e214 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_keysym_to_scancode_c.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #ifndef SDL_keysym_to_scancode_c_h_ | ||
| 23 | #define SDL_keysym_to_scancode_c_h_ | ||
| 24 | |||
| 25 | // This function only correctly maps letters and numbers for keyboards in US QWERTY layout | ||
| 26 | extern SDL_Scancode SDL_GetScancodeFromKeySym(Uint32 keysym, Uint32 keycode); | ||
| 27 | |||
| 28 | #endif // SDL_keysym_to_scancode_c_h_ | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_mouse.c b/contrib/SDL-3.2.8/src/events/SDL_mouse.c new file mode 100644 index 0000000..2ea5995 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_mouse.c | |||
| @@ -0,0 +1,1673 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | // General mouse handling code for SDL | ||
| 24 | |||
| 25 | #include "../SDL_hints_c.h" | ||
| 26 | #include "../video/SDL_sysvideo.h" | ||
| 27 | #include "SDL_events_c.h" | ||
| 28 | #include "SDL_mouse_c.h" | ||
| 29 | #if defined(SDL_PLATFORM_WINDOWS) | ||
| 30 | #include "../core/windows/SDL_windows.h" // For GetDoubleClickTime() | ||
| 31 | #endif | ||
| 32 | |||
| 33 | // #define DEBUG_MOUSE | ||
| 34 | |||
| 35 | #define WARP_EMULATION_THRESHOLD_NS SDL_MS_TO_NS(30) | ||
| 36 | |||
| 37 | typedef struct SDL_MouseInstance | ||
| 38 | { | ||
| 39 | SDL_MouseID instance_id; | ||
| 40 | char *name; | ||
| 41 | } SDL_MouseInstance; | ||
| 42 | |||
| 43 | // The mouse state | ||
| 44 | static SDL_Mouse SDL_mouse; | ||
| 45 | static int SDL_mouse_count; | ||
| 46 | static SDL_MouseInstance *SDL_mice; | ||
| 47 | |||
| 48 | // for mapping mouse events to touch | ||
| 49 | static bool track_mouse_down = false; | ||
| 50 | |||
| 51 | static void SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, bool relative, float x, float y); | ||
| 52 | |||
| 53 | static void SDLCALL SDL_MouseDoubleClickTimeChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 54 | { | ||
| 55 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 56 | |||
| 57 | if (hint && *hint) { | ||
| 58 | mouse->double_click_time = SDL_atoi(hint); | ||
| 59 | } else { | ||
| 60 | #if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK) | ||
| 61 | mouse->double_click_time = GetDoubleClickTime(); | ||
| 62 | #else | ||
| 63 | mouse->double_click_time = 500; | ||
| 64 | #endif | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | static void SDLCALL SDL_MouseDoubleClickRadiusChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 69 | { | ||
| 70 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 71 | |||
| 72 | if (hint && *hint) { | ||
| 73 | mouse->double_click_radius = SDL_atoi(hint); | ||
| 74 | } else { | ||
| 75 | mouse->double_click_radius = 32; // 32 pixels seems about right for touch interfaces | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | static void SDLCALL SDL_MouseNormalSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 80 | { | ||
| 81 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 82 | |||
| 83 | if (hint && *hint) { | ||
| 84 | mouse->enable_normal_speed_scale = true; | ||
| 85 | mouse->normal_speed_scale = (float)SDL_atof(hint); | ||
| 86 | } else { | ||
| 87 | mouse->enable_normal_speed_scale = false; | ||
| 88 | mouse->normal_speed_scale = 1.0f; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | static void SDLCALL SDL_MouseRelativeSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 93 | { | ||
| 94 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 95 | |||
| 96 | if (hint && *hint) { | ||
| 97 | mouse->enable_relative_speed_scale = true; | ||
| 98 | mouse->relative_speed_scale = (float)SDL_atof(hint); | ||
| 99 | } else { | ||
| 100 | mouse->enable_relative_speed_scale = false; | ||
| 101 | mouse->relative_speed_scale = 1.0f; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | static void SDLCALL SDL_MouseRelativeModeCenterChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 106 | { | ||
| 107 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 108 | |||
| 109 | mouse->relative_mode_center = SDL_GetStringBoolean(hint, true); | ||
| 110 | } | ||
| 111 | |||
| 112 | static void SDLCALL SDL_MouseRelativeSystemScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 113 | { | ||
| 114 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 115 | |||
| 116 | mouse->enable_relative_system_scale = SDL_GetStringBoolean(hint, false); | ||
| 117 | } | ||
| 118 | |||
| 119 | static void SDLCALL SDL_MouseWarpEmulationChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 120 | { | ||
| 121 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 122 | |||
| 123 | mouse->warp_emulation_hint = SDL_GetStringBoolean(hint, true); | ||
| 124 | |||
| 125 | if (!mouse->warp_emulation_hint && mouse->warp_emulation_active) { | ||
| 126 | SDL_SetRelativeMouseMode(false); | ||
| 127 | mouse->warp_emulation_active = false; | ||
| 128 | } | ||
| 129 | } | ||
| 130 | |||
| 131 | static void SDLCALL SDL_TouchMouseEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 132 | { | ||
| 133 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 134 | |||
| 135 | mouse->touch_mouse_events = SDL_GetStringBoolean(hint, true); | ||
| 136 | } | ||
| 137 | |||
| 138 | #ifdef SDL_PLATFORM_VITA | ||
| 139 | static void SDLCALL SDL_VitaTouchMouseDeviceChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 140 | { | ||
| 141 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 142 | if (hint) { | ||
| 143 | switch (*hint) { | ||
| 144 | default: | ||
| 145 | case '0': | ||
| 146 | mouse->vita_touch_mouse_device = 1; | ||
| 147 | break; | ||
| 148 | case '1': | ||
| 149 | mouse->vita_touch_mouse_device = 2; | ||
| 150 | break; | ||
| 151 | case '2': | ||
| 152 | mouse->vita_touch_mouse_device = 3; | ||
| 153 | break; | ||
| 154 | } | ||
| 155 | } | ||
| 156 | } | ||
| 157 | #endif | ||
| 158 | |||
| 159 | static void SDLCALL SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 160 | { | ||
| 161 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 162 | bool default_value; | ||
| 163 | |||
| 164 | #if defined(SDL_PLATFORM_ANDROID) || (defined(SDL_PLATFORM_IOS) && !defined(SDL_PLATFORM_TVOS)) | ||
| 165 | default_value = true; | ||
| 166 | #else | ||
| 167 | default_value = false; | ||
| 168 | #endif | ||
| 169 | mouse->mouse_touch_events = SDL_GetStringBoolean(hint, default_value); | ||
| 170 | |||
| 171 | if (mouse->mouse_touch_events) { | ||
| 172 | if (!mouse->added_mouse_touch_device) { | ||
| 173 | SDL_AddTouch(SDL_MOUSE_TOUCHID, SDL_TOUCH_DEVICE_DIRECT, "mouse_input"); | ||
| 174 | mouse->added_mouse_touch_device = true; | ||
| 175 | } | ||
| 176 | } else { | ||
| 177 | if (mouse->added_mouse_touch_device) { | ||
| 178 | SDL_DelTouch(SDL_MOUSE_TOUCHID); | ||
| 179 | mouse->added_mouse_touch_device = false; | ||
| 180 | } | ||
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 184 | static void SDLCALL SDL_PenMouseEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 185 | { | ||
| 186 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 187 | |||
| 188 | mouse->pen_mouse_events = SDL_GetStringBoolean(hint, true); | ||
| 189 | } | ||
| 190 | |||
| 191 | static void SDLCALL SDL_PenTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 192 | { | ||
| 193 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 194 | |||
| 195 | mouse->pen_touch_events = SDL_GetStringBoolean(hint, true); | ||
| 196 | |||
| 197 | if (mouse->pen_touch_events) { | ||
| 198 | if (!mouse->added_pen_touch_device) { | ||
| 199 | SDL_AddTouch(SDL_PEN_TOUCHID, SDL_TOUCH_DEVICE_DIRECT, "pen_input"); | ||
| 200 | mouse->added_pen_touch_device = true; | ||
| 201 | } | ||
| 202 | } else { | ||
| 203 | if (mouse->added_pen_touch_device) { | ||
| 204 | SDL_DelTouch(SDL_PEN_TOUCHID); | ||
| 205 | mouse->added_pen_touch_device = false; | ||
| 206 | } | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | static void SDLCALL SDL_MouseAutoCaptureChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 211 | { | ||
| 212 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 213 | bool auto_capture = SDL_GetStringBoolean(hint, true); | ||
| 214 | |||
| 215 | if (auto_capture != mouse->auto_capture) { | ||
| 216 | mouse->auto_capture = auto_capture; | ||
| 217 | SDL_UpdateMouseCapture(false); | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | static void SDLCALL SDL_MouseRelativeWarpMotionChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 222 | { | ||
| 223 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 224 | |||
| 225 | mouse->relative_mode_warp_motion = SDL_GetStringBoolean(hint, false); | ||
| 226 | } | ||
| 227 | |||
| 228 | static void SDLCALL SDL_MouseRelativeCursorVisibleChanged(void *userdata, const char *name, const char *oldValue, const char *hint) | ||
| 229 | { | ||
| 230 | SDL_Mouse *mouse = (SDL_Mouse *)userdata; | ||
| 231 | |||
| 232 | mouse->relative_mode_cursor_visible = SDL_GetStringBoolean(hint, false); | ||
| 233 | |||
| 234 | SDL_SetCursor(NULL); // Update cursor visibility | ||
| 235 | } | ||
| 236 | |||
| 237 | // Public functions | ||
| 238 | bool SDL_PreInitMouse(void) | ||
| 239 | { | ||
| 240 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 241 | |||
| 242 | SDL_zerop(mouse); | ||
| 243 | |||
| 244 | SDL_AddHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_TIME, | ||
| 245 | SDL_MouseDoubleClickTimeChanged, mouse); | ||
| 246 | |||
| 247 | SDL_AddHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS, | ||
| 248 | SDL_MouseDoubleClickRadiusChanged, mouse); | ||
| 249 | |||
| 250 | SDL_AddHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE, | ||
| 251 | SDL_MouseNormalSpeedScaleChanged, mouse); | ||
| 252 | |||
| 253 | SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE, | ||
| 254 | SDL_MouseRelativeSpeedScaleChanged, mouse); | ||
| 255 | |||
| 256 | SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE, | ||
| 257 | SDL_MouseRelativeSystemScaleChanged, mouse); | ||
| 258 | |||
| 259 | SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, | ||
| 260 | SDL_MouseRelativeModeCenterChanged, mouse); | ||
| 261 | |||
| 262 | SDL_AddHintCallback(SDL_HINT_MOUSE_EMULATE_WARP_WITH_RELATIVE, | ||
| 263 | SDL_MouseWarpEmulationChanged, mouse); | ||
| 264 | |||
| 265 | SDL_AddHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS, | ||
| 266 | SDL_TouchMouseEventsChanged, mouse); | ||
| 267 | |||
| 268 | #ifdef SDL_PLATFORM_VITA | ||
| 269 | SDL_AddHintCallback(SDL_HINT_VITA_TOUCH_MOUSE_DEVICE, | ||
| 270 | SDL_VitaTouchMouseDeviceChanged, mouse); | ||
| 271 | #endif | ||
| 272 | |||
| 273 | SDL_AddHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS, | ||
| 274 | SDL_MouseTouchEventsChanged, mouse); | ||
| 275 | |||
| 276 | SDL_AddHintCallback(SDL_HINT_PEN_MOUSE_EVENTS, | ||
| 277 | SDL_PenMouseEventsChanged, mouse); | ||
| 278 | |||
| 279 | SDL_AddHintCallback(SDL_HINT_PEN_TOUCH_EVENTS, | ||
| 280 | SDL_PenTouchEventsChanged, mouse); | ||
| 281 | |||
| 282 | SDL_AddHintCallback(SDL_HINT_MOUSE_AUTO_CAPTURE, | ||
| 283 | SDL_MouseAutoCaptureChanged, mouse); | ||
| 284 | |||
| 285 | SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, | ||
| 286 | SDL_MouseRelativeWarpMotionChanged, mouse); | ||
| 287 | |||
| 288 | SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, | ||
| 289 | SDL_MouseRelativeCursorVisibleChanged, mouse); | ||
| 290 | |||
| 291 | mouse->was_touch_mouse_events = false; // no touch to mouse movement event pending | ||
| 292 | |||
| 293 | mouse->cursor_shown = true; | ||
| 294 | |||
| 295 | return true; | ||
| 296 | } | ||
| 297 | |||
| 298 | void SDL_PostInitMouse(void) | ||
| 299 | { | ||
| 300 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 301 | |||
| 302 | /* Create a dummy mouse cursor for video backends that don't support true cursors, | ||
| 303 | * so that mouse grab and focus functionality will work. | ||
| 304 | */ | ||
| 305 | if (!mouse->def_cursor) { | ||
| 306 | SDL_Surface *surface = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_ARGB8888); | ||
| 307 | if (surface) { | ||
| 308 | SDL_memset(surface->pixels, 0, (size_t)surface->h * surface->pitch); | ||
| 309 | SDL_SetDefaultCursor(SDL_CreateColorCursor(surface, 0, 0)); | ||
| 310 | SDL_DestroySurface(surface); | ||
| 311 | } | ||
| 312 | } | ||
| 313 | } | ||
| 314 | |||
| 315 | bool SDL_IsMouse(Uint16 vendor, Uint16 product) | ||
| 316 | { | ||
| 317 | // Eventually we'll have a blacklist of devices that enumerate as mice but aren't really | ||
| 318 | return true; | ||
| 319 | } | ||
| 320 | |||
| 321 | static int SDL_GetMouseIndex(SDL_MouseID mouseID) | ||
| 322 | { | ||
| 323 | for (int i = 0; i < SDL_mouse_count; ++i) { | ||
| 324 | if (mouseID == SDL_mice[i].instance_id) { | ||
| 325 | return i; | ||
| 326 | } | ||
| 327 | } | ||
| 328 | return -1; | ||
| 329 | } | ||
| 330 | |||
| 331 | void SDL_AddMouse(SDL_MouseID mouseID, const char *name, bool send_event) | ||
| 332 | { | ||
| 333 | int mouse_index = SDL_GetMouseIndex(mouseID); | ||
| 334 | if (mouse_index >= 0) { | ||
| 335 | // We already know about this mouse | ||
| 336 | return; | ||
| 337 | } | ||
| 338 | |||
| 339 | SDL_assert(mouseID != 0); | ||
| 340 | |||
| 341 | SDL_MouseInstance *mice = (SDL_MouseInstance *)SDL_realloc(SDL_mice, (SDL_mouse_count + 1) * sizeof(*mice)); | ||
| 342 | if (!mice) { | ||
| 343 | return; | ||
| 344 | } | ||
| 345 | SDL_MouseInstance *instance = &mice[SDL_mouse_count]; | ||
| 346 | instance->instance_id = mouseID; | ||
| 347 | instance->name = SDL_strdup(name ? name : ""); | ||
| 348 | SDL_mice = mice; | ||
| 349 | ++SDL_mouse_count; | ||
| 350 | |||
| 351 | if (send_event) { | ||
| 352 | SDL_Event event; | ||
| 353 | SDL_zero(event); | ||
| 354 | event.type = SDL_EVENT_MOUSE_ADDED; | ||
| 355 | event.mdevice.which = mouseID; | ||
| 356 | SDL_PushEvent(&event); | ||
| 357 | } | ||
| 358 | } | ||
| 359 | |||
| 360 | void SDL_RemoveMouse(SDL_MouseID mouseID, bool send_event) | ||
| 361 | { | ||
| 362 | int mouse_index = SDL_GetMouseIndex(mouseID); | ||
| 363 | if (mouse_index < 0) { | ||
| 364 | // We don't know about this mouse | ||
| 365 | return; | ||
| 366 | } | ||
| 367 | |||
| 368 | SDL_free(SDL_mice[mouse_index].name); | ||
| 369 | |||
| 370 | if (mouse_index != SDL_mouse_count - 1) { | ||
| 371 | SDL_memmove(&SDL_mice[mouse_index], &SDL_mice[mouse_index + 1], (SDL_mouse_count - mouse_index - 1) * sizeof(SDL_mice[mouse_index])); | ||
| 372 | } | ||
| 373 | --SDL_mouse_count; | ||
| 374 | |||
| 375 | // Remove any mouse input sources for this mouseID | ||
| 376 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 377 | for (int i = 0; i < mouse->num_sources; ++i) { | ||
| 378 | SDL_MouseInputSource *source = &mouse->sources[i]; | ||
| 379 | if (source->mouseID == mouseID) { | ||
| 380 | SDL_free(source->clickstate); | ||
| 381 | if (i != mouse->num_sources - 1) { | ||
| 382 | SDL_memmove(&mouse->sources[i], &mouse->sources[i + 1], (mouse->num_sources - i - 1) * sizeof(mouse->sources[i])); | ||
| 383 | } | ||
| 384 | --mouse->num_sources; | ||
| 385 | break; | ||
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | if (send_event) { | ||
| 390 | SDL_Event event; | ||
| 391 | SDL_zero(event); | ||
| 392 | event.type = SDL_EVENT_MOUSE_REMOVED; | ||
| 393 | event.mdevice.which = mouseID; | ||
| 394 | SDL_PushEvent(&event); | ||
| 395 | } | ||
| 396 | } | ||
| 397 | |||
| 398 | bool SDL_HasMouse(void) | ||
| 399 | { | ||
| 400 | return (SDL_mouse_count > 0); | ||
| 401 | } | ||
| 402 | |||
| 403 | SDL_MouseID *SDL_GetMice(int *count) | ||
| 404 | { | ||
| 405 | int i; | ||
| 406 | SDL_MouseID *mice; | ||
| 407 | |||
| 408 | mice = (SDL_JoystickID *)SDL_malloc((SDL_mouse_count + 1) * sizeof(*mice)); | ||
| 409 | if (mice) { | ||
| 410 | if (count) { | ||
| 411 | *count = SDL_mouse_count; | ||
| 412 | } | ||
| 413 | |||
| 414 | for (i = 0; i < SDL_mouse_count; ++i) { | ||
| 415 | mice[i] = SDL_mice[i].instance_id; | ||
| 416 | } | ||
| 417 | mice[i] = 0; | ||
| 418 | } else { | ||
| 419 | if (count) { | ||
| 420 | *count = 0; | ||
| 421 | } | ||
| 422 | } | ||
| 423 | |||
| 424 | return mice; | ||
| 425 | } | ||
| 426 | |||
| 427 | const char *SDL_GetMouseNameForID(SDL_MouseID instance_id) | ||
| 428 | { | ||
| 429 | int mouse_index = SDL_GetMouseIndex(instance_id); | ||
| 430 | if (mouse_index < 0) { | ||
| 431 | SDL_SetError("Mouse %" SDL_PRIu32 " not found", instance_id); | ||
| 432 | return NULL; | ||
| 433 | } | ||
| 434 | return SDL_GetPersistentString(SDL_mice[mouse_index].name); | ||
| 435 | } | ||
| 436 | |||
| 437 | void SDL_SetDefaultCursor(SDL_Cursor *cursor) | ||
| 438 | { | ||
| 439 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 440 | |||
| 441 | if (cursor == mouse->def_cursor) { | ||
| 442 | return; | ||
| 443 | } | ||
| 444 | |||
| 445 | if (mouse->def_cursor) { | ||
| 446 | SDL_Cursor *default_cursor = mouse->def_cursor; | ||
| 447 | SDL_Cursor *prev, *curr; | ||
| 448 | |||
| 449 | if (mouse->cur_cursor == mouse->def_cursor) { | ||
| 450 | mouse->cur_cursor = NULL; | ||
| 451 | } | ||
| 452 | mouse->def_cursor = NULL; | ||
| 453 | |||
| 454 | for (prev = NULL, curr = mouse->cursors; curr; | ||
| 455 | prev = curr, curr = curr->next) { | ||
| 456 | if (curr == default_cursor) { | ||
| 457 | if (prev) { | ||
| 458 | prev->next = curr->next; | ||
| 459 | } else { | ||
| 460 | mouse->cursors = curr->next; | ||
| 461 | } | ||
| 462 | |||
| 463 | break; | ||
| 464 | } | ||
| 465 | } | ||
| 466 | |||
| 467 | if (mouse->FreeCursor && default_cursor->internal) { | ||
| 468 | mouse->FreeCursor(default_cursor); | ||
| 469 | } else { | ||
| 470 | SDL_free(default_cursor); | ||
| 471 | } | ||
| 472 | } | ||
| 473 | |||
| 474 | mouse->def_cursor = cursor; | ||
| 475 | |||
| 476 | if (!mouse->cur_cursor) { | ||
| 477 | SDL_SetCursor(cursor); | ||
| 478 | } | ||
| 479 | } | ||
| 480 | |||
| 481 | SDL_SystemCursor SDL_GetDefaultSystemCursor(void) | ||
| 482 | { | ||
| 483 | SDL_SystemCursor id = SDL_SYSTEM_CURSOR_DEFAULT; | ||
| 484 | const char *value = SDL_GetHint(SDL_HINT_MOUSE_DEFAULT_SYSTEM_CURSOR); | ||
| 485 | if (value) { | ||
| 486 | int index = SDL_atoi(value); | ||
| 487 | if (0 <= index && index < SDL_SYSTEM_CURSOR_COUNT) { | ||
| 488 | id = (SDL_SystemCursor)index; | ||
| 489 | } | ||
| 490 | } | ||
| 491 | return id; | ||
| 492 | } | ||
| 493 | |||
| 494 | SDL_Mouse *SDL_GetMouse(void) | ||
| 495 | { | ||
| 496 | return &SDL_mouse; | ||
| 497 | } | ||
| 498 | |||
| 499 | static SDL_MouseButtonFlags SDL_GetMouseButtonState(SDL_Mouse *mouse, SDL_MouseID mouseID, bool include_touch) | ||
| 500 | { | ||
| 501 | int i; | ||
| 502 | SDL_MouseButtonFlags buttonstate = 0; | ||
| 503 | |||
| 504 | for (i = 0; i < mouse->num_sources; ++i) { | ||
| 505 | if (mouseID == SDL_GLOBAL_MOUSE_ID || mouseID == SDL_TOUCH_MOUSEID) { | ||
| 506 | if (include_touch || mouse->sources[i].mouseID != SDL_TOUCH_MOUSEID) { | ||
| 507 | buttonstate |= mouse->sources[i].buttonstate; | ||
| 508 | } | ||
| 509 | } else { | ||
| 510 | if (mouseID == mouse->sources[i].mouseID) { | ||
| 511 | buttonstate |= mouse->sources[i].buttonstate; | ||
| 512 | break; | ||
| 513 | } | ||
| 514 | } | ||
| 515 | } | ||
| 516 | return buttonstate; | ||
| 517 | } | ||
| 518 | |||
| 519 | SDL_Window *SDL_GetMouseFocus(void) | ||
| 520 | { | ||
| 521 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 522 | |||
| 523 | return mouse->focus; | ||
| 524 | } | ||
| 525 | |||
| 526 | /* TODO RECONNECT: Hello from the Wayland video driver! | ||
| 527 | * This was once removed from SDL, but it's been added back in comment form | ||
| 528 | * because we will need it when Wayland adds compositor reconnect support. | ||
| 529 | * If you need this before we do, great! Otherwise, leave this alone, we'll | ||
| 530 | * uncomment it at the right time. | ||
| 531 | * -flibit | ||
| 532 | */ | ||
| 533 | #if 0 | ||
| 534 | void SDL_ResetMouse(void) | ||
| 535 | { | ||
| 536 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 537 | Uint32 buttonState = SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, false); | ||
| 538 | int i; | ||
| 539 | |||
| 540 | for (i = 1; i <= sizeof(buttonState)*8; ++i) { | ||
| 541 | if (buttonState & SDL_BUTTON_MASK(i)) { | ||
| 542 | SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, i, false); | ||
| 543 | } | ||
| 544 | } | ||
| 545 | SDL_assert(SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, false) == 0); | ||
| 546 | } | ||
| 547 | #endif // 0 | ||
| 548 | |||
| 549 | void SDL_SetMouseFocus(SDL_Window *window) | ||
| 550 | { | ||
| 551 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 552 | |||
| 553 | if (mouse->focus == window) { | ||
| 554 | return; | ||
| 555 | } | ||
| 556 | |||
| 557 | /* Actually, this ends up being a bad idea, because most operating | ||
| 558 | systems have an implicit grab when you press the mouse button down | ||
| 559 | so you can drag things out of the window and then get the mouse up | ||
| 560 | when it happens. So, #if 0... | ||
| 561 | */ | ||
| 562 | #if 0 | ||
| 563 | if (mouse->focus && !window) { | ||
| 564 | // We won't get anymore mouse messages, so reset mouse state | ||
| 565 | SDL_ResetMouse(); | ||
| 566 | } | ||
| 567 | #endif | ||
| 568 | |||
| 569 | // See if the current window has lost focus | ||
| 570 | if (mouse->focus) { | ||
| 571 | SDL_SendWindowEvent(mouse->focus, SDL_EVENT_WINDOW_MOUSE_LEAVE, 0, 0); | ||
| 572 | } | ||
| 573 | |||
| 574 | mouse->focus = window; | ||
| 575 | mouse->has_position = false; | ||
| 576 | |||
| 577 | if (mouse->focus) { | ||
| 578 | SDL_SendWindowEvent(mouse->focus, SDL_EVENT_WINDOW_MOUSE_ENTER, 0, 0); | ||
| 579 | } | ||
| 580 | |||
| 581 | // Update cursor visibility | ||
| 582 | SDL_SetCursor(NULL); | ||
| 583 | } | ||
| 584 | |||
| 585 | bool SDL_MousePositionInWindow(SDL_Window *window, float x, float y) | ||
| 586 | { | ||
| 587 | if (!window) { | ||
| 588 | return false; | ||
| 589 | } | ||
| 590 | |||
| 591 | if (window && !(window->flags & SDL_WINDOW_MOUSE_CAPTURE)) { | ||
| 592 | if (x < 0.0f || y < 0.0f || x >= (float)window->w || y >= (float)window->h) { | ||
| 593 | return false; | ||
| 594 | } | ||
| 595 | } | ||
| 596 | return true; | ||
| 597 | } | ||
| 598 | |||
| 599 | // Check to see if we need to synthesize focus events | ||
| 600 | static bool SDL_UpdateMouseFocus(SDL_Window *window, float x, float y, Uint32 buttonstate, bool send_mouse_motion) | ||
| 601 | { | ||
| 602 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 603 | bool inWindow = SDL_MousePositionInWindow(window, x, y); | ||
| 604 | |||
| 605 | if (!inWindow) { | ||
| 606 | if (window == mouse->focus) { | ||
| 607 | #ifdef DEBUG_MOUSE | ||
| 608 | SDL_Log("Mouse left window, synthesizing move & focus lost event"); | ||
| 609 | #endif | ||
| 610 | if (send_mouse_motion) { | ||
| 611 | SDL_PrivateSendMouseMotion(0, window, SDL_GLOBAL_MOUSE_ID, false, x, y); | ||
| 612 | } | ||
| 613 | SDL_SetMouseFocus(NULL); | ||
| 614 | } | ||
| 615 | return false; | ||
| 616 | } | ||
| 617 | |||
| 618 | if (window != mouse->focus) { | ||
| 619 | #ifdef DEBUG_MOUSE | ||
| 620 | SDL_Log("Mouse entered window, synthesizing focus gain & move event"); | ||
| 621 | #endif | ||
| 622 | SDL_SetMouseFocus(window); | ||
| 623 | if (send_mouse_motion) { | ||
| 624 | SDL_PrivateSendMouseMotion(0, window, SDL_GLOBAL_MOUSE_ID, false, x, y); | ||
| 625 | } | ||
| 626 | } | ||
| 627 | return true; | ||
| 628 | } | ||
| 629 | |||
| 630 | void SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, bool relative, float x, float y) | ||
| 631 | { | ||
| 632 | if (window && !relative) { | ||
| 633 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 634 | if (!SDL_UpdateMouseFocus(window, x, y, SDL_GetMouseButtonState(mouse, mouseID, true), (mouseID != SDL_TOUCH_MOUSEID && mouseID != SDL_PEN_MOUSEID))) { | ||
| 635 | return; | ||
| 636 | } | ||
| 637 | } | ||
| 638 | |||
| 639 | SDL_PrivateSendMouseMotion(timestamp, window, mouseID, relative, x, y); | ||
| 640 | } | ||
| 641 | |||
| 642 | static void ConstrainMousePosition(SDL_Mouse *mouse, SDL_Window *window, float *x, float *y) | ||
| 643 | { | ||
| 644 | /* make sure that the pointers find themselves inside the windows, | ||
| 645 | unless we have the mouse captured. */ | ||
| 646 | if (window && !(window->flags & SDL_WINDOW_MOUSE_CAPTURE)) { | ||
| 647 | int x_min = 0, x_max = window->w - 1; | ||
| 648 | int y_min = 0, y_max = window->h - 1; | ||
| 649 | const SDL_Rect *confine = SDL_GetWindowMouseRect(window); | ||
| 650 | |||
| 651 | if (confine) { | ||
| 652 | SDL_Rect window_rect; | ||
| 653 | SDL_Rect mouse_rect; | ||
| 654 | |||
| 655 | window_rect.x = 0; | ||
| 656 | window_rect.y = 0; | ||
| 657 | window_rect.w = x_max + 1; | ||
| 658 | window_rect.h = y_max + 1; | ||
| 659 | if (SDL_GetRectIntersection(confine, &window_rect, &mouse_rect)) { | ||
| 660 | x_min = mouse_rect.x; | ||
| 661 | y_min = mouse_rect.y; | ||
| 662 | x_max = x_min + mouse_rect.w - 1; | ||
| 663 | y_max = y_min + mouse_rect.h - 1; | ||
| 664 | } | ||
| 665 | } | ||
| 666 | |||
| 667 | if (*x >= (float)(x_max + 1)) { | ||
| 668 | *x = SDL_max((float)x_max, mouse->last_x); | ||
| 669 | } | ||
| 670 | if (*x < (float)x_min) { | ||
| 671 | *x = (float)x_min; | ||
| 672 | } | ||
| 673 | |||
| 674 | if (*y >= (float)(y_max + 1)) { | ||
| 675 | *y = SDL_max((float)y_max, mouse->last_y); | ||
| 676 | } | ||
| 677 | if (*y < (float)y_min) { | ||
| 678 | *y = (float)y_min; | ||
| 679 | } | ||
| 680 | } | ||
| 681 | } | ||
| 682 | |||
| 683 | static void SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, bool relative, float x, float y) | ||
| 684 | { | ||
| 685 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 686 | float xrel = 0.0f; | ||
| 687 | float yrel = 0.0f; | ||
| 688 | bool window_is_relative = mouse->focus && (mouse->focus->flags & SDL_WINDOW_MOUSE_RELATIVE_MODE); | ||
| 689 | |||
| 690 | // SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events | ||
| 691 | if (mouse->mouse_touch_events) { | ||
| 692 | if (mouseID != SDL_TOUCH_MOUSEID && mouseID != SDL_PEN_MOUSEID && !relative && track_mouse_down) { | ||
| 693 | if (window) { | ||
| 694 | float normalized_x = x / (float)window->w; | ||
| 695 | float normalized_y = y / (float)window->h; | ||
| 696 | SDL_SendTouchMotion(timestamp, SDL_MOUSE_TOUCHID, SDL_BUTTON_LEFT, window, normalized_x, normalized_y, 1.0f); | ||
| 697 | } | ||
| 698 | } | ||
| 699 | } | ||
| 700 | |||
| 701 | // SDL_HINT_TOUCH_MOUSE_EVENTS: if not set, discard synthetic mouse events coming from platform layer | ||
| 702 | if (!mouse->touch_mouse_events && mouseID == SDL_TOUCH_MOUSEID) { | ||
| 703 | return; | ||
| 704 | } | ||
| 705 | |||
| 706 | if (relative) { | ||
| 707 | if (mouse->relative_mode) { | ||
| 708 | if (mouse->enable_relative_system_scale) { | ||
| 709 | if (mouse->ApplySystemScale) { | ||
| 710 | mouse->ApplySystemScale(mouse->system_scale_data, timestamp, window, mouseID, &x, &y); | ||
| 711 | } | ||
| 712 | } | ||
| 713 | if (mouse->enable_relative_speed_scale) { | ||
| 714 | x *= mouse->relative_speed_scale; | ||
| 715 | y *= mouse->relative_speed_scale; | ||
| 716 | } | ||
| 717 | } else { | ||
| 718 | if (mouse->enable_normal_speed_scale) { | ||
| 719 | x *= mouse->normal_speed_scale; | ||
| 720 | y *= mouse->normal_speed_scale; | ||
| 721 | } | ||
| 722 | } | ||
| 723 | xrel = x; | ||
| 724 | yrel = y; | ||
| 725 | x = (mouse->last_x + xrel); | ||
| 726 | y = (mouse->last_y + yrel); | ||
| 727 | ConstrainMousePosition(mouse, window, &x, &y); | ||
| 728 | } else { | ||
| 729 | ConstrainMousePosition(mouse, window, &x, &y); | ||
| 730 | if (mouse->has_position) { | ||
| 731 | xrel = x - mouse->last_x; | ||
| 732 | yrel = y - mouse->last_y; | ||
| 733 | } | ||
| 734 | } | ||
| 735 | |||
| 736 | if (mouse->has_position && xrel == 0.0f && yrel == 0.0f) { // Drop events that don't change state | ||
| 737 | #ifdef DEBUG_MOUSE | ||
| 738 | SDL_Log("Mouse event didn't change state - dropped!"); | ||
| 739 | #endif | ||
| 740 | return; | ||
| 741 | } | ||
| 742 | |||
| 743 | // Ignore relative motion positioning the first touch | ||
| 744 | if (mouseID == SDL_TOUCH_MOUSEID && !SDL_GetMouseButtonState(mouse, mouseID, true)) { | ||
| 745 | xrel = 0.0f; | ||
| 746 | yrel = 0.0f; | ||
| 747 | } | ||
| 748 | |||
| 749 | // modify internal state | ||
| 750 | { | ||
| 751 | mouse->x_accu += xrel; | ||
| 752 | mouse->y_accu += yrel; | ||
| 753 | |||
| 754 | if (relative && mouse->has_position) { | ||
| 755 | mouse->x += xrel; | ||
| 756 | mouse->y += yrel; | ||
| 757 | ConstrainMousePosition(mouse, window, &mouse->x, &mouse->y); | ||
| 758 | } else { | ||
| 759 | mouse->x = x; | ||
| 760 | mouse->y = y; | ||
| 761 | } | ||
| 762 | mouse->has_position = true; | ||
| 763 | |||
| 764 | // Use unclamped values if we're getting events outside the window | ||
| 765 | mouse->last_x = relative ? mouse->x : x; | ||
| 766 | mouse->last_y = relative ? mouse->y : y; | ||
| 767 | |||
| 768 | mouse->click_motion_x += xrel; | ||
| 769 | mouse->click_motion_y += yrel; | ||
| 770 | } | ||
| 771 | |||
| 772 | // Move the mouse cursor, if needed | ||
| 773 | if (mouse->cursor_shown && !mouse->relative_mode && | ||
| 774 | mouse->MoveCursor && mouse->cur_cursor) { | ||
| 775 | mouse->MoveCursor(mouse->cur_cursor); | ||
| 776 | } | ||
| 777 | |||
| 778 | // Post the event, if desired | ||
| 779 | if (SDL_EventEnabled(SDL_EVENT_MOUSE_MOTION)) { | ||
| 780 | if ((!mouse->relative_mode || mouse->warp_emulation_active) && mouseID != SDL_TOUCH_MOUSEID && mouseID != SDL_PEN_MOUSEID) { | ||
| 781 | // We're not in relative mode, so all mouse events are global mouse events | ||
| 782 | mouseID = SDL_GLOBAL_MOUSE_ID; | ||
| 783 | } | ||
| 784 | |||
| 785 | if (!relative && window_is_relative) { | ||
| 786 | if (!mouse->relative_mode_warp_motion) { | ||
| 787 | return; | ||
| 788 | } | ||
| 789 | xrel = 0.0f; | ||
| 790 | yrel = 0.0f; | ||
| 791 | } | ||
| 792 | |||
| 793 | SDL_Event event; | ||
| 794 | event.type = SDL_EVENT_MOUSE_MOTION; | ||
| 795 | event.common.timestamp = timestamp; | ||
| 796 | event.motion.windowID = mouse->focus ? mouse->focus->id : 0; | ||
| 797 | event.motion.which = mouseID; | ||
| 798 | // Set us pending (or clear during a normal mouse movement event) as having triggered | ||
| 799 | mouse->was_touch_mouse_events = (mouseID == SDL_TOUCH_MOUSEID); | ||
| 800 | event.motion.state = SDL_GetMouseButtonState(mouse, mouseID, true); | ||
| 801 | event.motion.x = mouse->x; | ||
| 802 | event.motion.y = mouse->y; | ||
| 803 | event.motion.xrel = xrel; | ||
| 804 | event.motion.yrel = yrel; | ||
| 805 | SDL_PushEvent(&event); | ||
| 806 | } | ||
| 807 | } | ||
| 808 | |||
| 809 | static SDL_MouseInputSource *GetMouseInputSource(SDL_Mouse *mouse, SDL_MouseID mouseID, bool down, Uint8 button) | ||
| 810 | { | ||
| 811 | SDL_MouseInputSource *source, *match = NULL, *sources; | ||
| 812 | int i; | ||
| 813 | |||
| 814 | for (i = 0; i < mouse->num_sources; ++i) { | ||
| 815 | source = &mouse->sources[i]; | ||
| 816 | if (source->mouseID == mouseID) { | ||
| 817 | match = source; | ||
| 818 | break; | ||
| 819 | } | ||
| 820 | } | ||
| 821 | |||
| 822 | if (!down && (!match || !(match->buttonstate & SDL_BUTTON_MASK(button)))) { | ||
| 823 | /* This might be a button release from a transition between mouse messages and raw input. | ||
| 824 | * See if there's another mouse source that already has that button down and use that. | ||
| 825 | */ | ||
| 826 | for (i = 0; i < mouse->num_sources; ++i) { | ||
| 827 | source = &mouse->sources[i]; | ||
| 828 | if ((source->buttonstate & SDL_BUTTON_MASK(button))) { | ||
| 829 | match = source; | ||
| 830 | break; | ||
| 831 | } | ||
| 832 | } | ||
| 833 | } | ||
| 834 | if (match) { | ||
| 835 | return match; | ||
| 836 | } | ||
| 837 | |||
| 838 | sources = (SDL_MouseInputSource *)SDL_realloc(mouse->sources, (mouse->num_sources + 1) * sizeof(*mouse->sources)); | ||
| 839 | if (sources) { | ||
| 840 | mouse->sources = sources; | ||
| 841 | ++mouse->num_sources; | ||
| 842 | source = &sources[mouse->num_sources - 1]; | ||
| 843 | SDL_zerop(source); | ||
| 844 | source->mouseID = mouseID; | ||
| 845 | return source; | ||
| 846 | } | ||
| 847 | return NULL; | ||
| 848 | } | ||
| 849 | |||
| 850 | static SDL_MouseClickState *GetMouseClickState(SDL_MouseInputSource *source, Uint8 button) | ||
| 851 | { | ||
| 852 | if (button >= source->num_clickstates) { | ||
| 853 | int i, count = button + 1; | ||
| 854 | SDL_MouseClickState *clickstate = (SDL_MouseClickState *)SDL_realloc(source->clickstate, count * sizeof(*source->clickstate)); | ||
| 855 | if (!clickstate) { | ||
| 856 | return NULL; | ||
| 857 | } | ||
| 858 | source->clickstate = clickstate; | ||
| 859 | |||
| 860 | for (i = source->num_clickstates; i < count; ++i) { | ||
| 861 | SDL_zero(source->clickstate[i]); | ||
| 862 | } | ||
| 863 | source->num_clickstates = count; | ||
| 864 | } | ||
| 865 | return &source->clickstate[button]; | ||
| 866 | } | ||
| 867 | |||
| 868 | static void SDL_PrivateSendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 button, bool down, int clicks) | ||
| 869 | { | ||
| 870 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 871 | SDL_EventType type; | ||
| 872 | Uint32 buttonstate; | ||
| 873 | SDL_MouseInputSource *source; | ||
| 874 | |||
| 875 | source = GetMouseInputSource(mouse, mouseID, down, button); | ||
| 876 | if (!source) { | ||
| 877 | return; | ||
| 878 | } | ||
| 879 | buttonstate = source->buttonstate; | ||
| 880 | |||
| 881 | // SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events | ||
| 882 | if (mouse->mouse_touch_events) { | ||
| 883 | if (mouseID != SDL_TOUCH_MOUSEID && mouseID != SDL_PEN_MOUSEID && button == SDL_BUTTON_LEFT) { | ||
| 884 | if (down) { | ||
| 885 | track_mouse_down = true; | ||
| 886 | } else { | ||
| 887 | track_mouse_down = false; | ||
| 888 | } | ||
| 889 | if (window) { | ||
| 890 | type = track_mouse_down ? SDL_EVENT_FINGER_DOWN : SDL_EVENT_FINGER_UP; | ||
| 891 | float normalized_x = mouse->x / (float)window->w; | ||
| 892 | float normalized_y = mouse->y / (float)window->h; | ||
| 893 | SDL_SendTouch(timestamp, SDL_MOUSE_TOUCHID, SDL_BUTTON_LEFT, window, type, normalized_x, normalized_y, 1.0f); | ||
| 894 | } | ||
| 895 | } | ||
| 896 | } | ||
| 897 | |||
| 898 | // SDL_HINT_TOUCH_MOUSE_EVENTS: if not set, discard synthetic mouse events coming from platform layer | ||
| 899 | if (mouse->touch_mouse_events == 0) { | ||
| 900 | if (mouseID == SDL_TOUCH_MOUSEID) { | ||
| 901 | return; | ||
| 902 | } | ||
| 903 | } | ||
| 904 | |||
| 905 | // Figure out which event to perform | ||
| 906 | if (down) { | ||
| 907 | type = SDL_EVENT_MOUSE_BUTTON_DOWN; | ||
| 908 | buttonstate |= SDL_BUTTON_MASK(button); | ||
| 909 | } else { | ||
| 910 | type = SDL_EVENT_MOUSE_BUTTON_UP; | ||
| 911 | buttonstate &= ~SDL_BUTTON_MASK(button); | ||
| 912 | } | ||
| 913 | |||
| 914 | // We do this after calculating buttonstate so button presses gain focus | ||
| 915 | if (window && down) { | ||
| 916 | SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate, true); | ||
| 917 | } | ||
| 918 | |||
| 919 | if (buttonstate == source->buttonstate) { | ||
| 920 | // Ignore this event, no state change | ||
| 921 | return; | ||
| 922 | } | ||
| 923 | source->buttonstate = buttonstate; | ||
| 924 | |||
| 925 | if (clicks < 0) { | ||
| 926 | SDL_MouseClickState *clickstate = GetMouseClickState(source, button); | ||
| 927 | if (clickstate) { | ||
| 928 | if (down) { | ||
| 929 | Uint64 now = SDL_GetTicks(); | ||
| 930 | |||
| 931 | if (now >= (clickstate->last_timestamp + mouse->double_click_time) || | ||
| 932 | SDL_fabs(mouse->click_motion_x - clickstate->click_motion_x) > mouse->double_click_radius || | ||
| 933 | SDL_fabs(mouse->click_motion_y - clickstate->click_motion_y) > mouse->double_click_radius) { | ||
| 934 | clickstate->click_count = 0; | ||
| 935 | } | ||
| 936 | clickstate->last_timestamp = now; | ||
| 937 | clickstate->click_motion_x = mouse->click_motion_x; | ||
| 938 | clickstate->click_motion_y = mouse->click_motion_y; | ||
| 939 | if (clickstate->click_count < 255) { | ||
| 940 | ++clickstate->click_count; | ||
| 941 | } | ||
| 942 | } | ||
| 943 | clicks = clickstate->click_count; | ||
| 944 | } else { | ||
| 945 | clicks = 1; | ||
| 946 | } | ||
| 947 | } | ||
| 948 | |||
| 949 | // Post the event, if desired | ||
| 950 | if (SDL_EventEnabled(type)) { | ||
| 951 | if ((!mouse->relative_mode || mouse->warp_emulation_active) && mouseID != SDL_TOUCH_MOUSEID && mouseID != SDL_PEN_MOUSEID) { | ||
| 952 | // We're not in relative mode, so all mouse events are global mouse events | ||
| 953 | mouseID = SDL_GLOBAL_MOUSE_ID; | ||
| 954 | } else { | ||
| 955 | mouseID = source->mouseID; | ||
| 956 | } | ||
| 957 | |||
| 958 | SDL_Event event; | ||
| 959 | event.type = type; | ||
| 960 | event.common.timestamp = timestamp; | ||
| 961 | event.button.windowID = mouse->focus ? mouse->focus->id : 0; | ||
| 962 | event.button.which = mouseID; | ||
| 963 | event.button.down = down; | ||
| 964 | event.button.button = button; | ||
| 965 | event.button.clicks = (Uint8)SDL_min(clicks, 255); | ||
| 966 | event.button.x = mouse->x; | ||
| 967 | event.button.y = mouse->y; | ||
| 968 | SDL_PushEvent(&event); | ||
| 969 | } | ||
| 970 | |||
| 971 | // We do this after dispatching event so button releases can lose focus | ||
| 972 | if (window && !down) { | ||
| 973 | SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate, true); | ||
| 974 | } | ||
| 975 | |||
| 976 | // Automatically capture the mouse while buttons are pressed | ||
| 977 | if (mouse->auto_capture) { | ||
| 978 | SDL_UpdateMouseCapture(false); | ||
| 979 | } | ||
| 980 | } | ||
| 981 | |||
| 982 | void SDL_SendMouseButtonClicks(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 button, bool down, int clicks) | ||
| 983 | { | ||
| 984 | clicks = SDL_max(clicks, 0); | ||
| 985 | SDL_PrivateSendMouseButton(timestamp, window, mouseID, button, down, clicks); | ||
| 986 | } | ||
| 987 | |||
| 988 | void SDL_SendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 button, bool down) | ||
| 989 | { | ||
| 990 | SDL_PrivateSendMouseButton(timestamp, window, mouseID, button, down, -1); | ||
| 991 | } | ||
| 992 | |||
| 993 | void SDL_SendMouseWheel(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction) | ||
| 994 | { | ||
| 995 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 996 | |||
| 997 | if (window) { | ||
| 998 | SDL_SetMouseFocus(window); | ||
| 999 | } | ||
| 1000 | |||
| 1001 | if (x == 0.0f && y == 0.0f) { | ||
| 1002 | return; | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | // Post the event, if desired | ||
| 1006 | if (SDL_EventEnabled(SDL_EVENT_MOUSE_WHEEL)) { | ||
| 1007 | if (!mouse->relative_mode || mouse->warp_emulation_active) { | ||
| 1008 | // We're not in relative mode, so all mouse events are global mouse events | ||
| 1009 | mouseID = SDL_GLOBAL_MOUSE_ID; | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | SDL_Event event; | ||
| 1013 | event.type = SDL_EVENT_MOUSE_WHEEL; | ||
| 1014 | event.common.timestamp = timestamp; | ||
| 1015 | event.wheel.windowID = mouse->focus ? mouse->focus->id : 0; | ||
| 1016 | event.wheel.which = mouseID; | ||
| 1017 | event.wheel.x = x; | ||
| 1018 | event.wheel.y = y; | ||
| 1019 | event.wheel.direction = direction; | ||
| 1020 | event.wheel.mouse_x = mouse->x; | ||
| 1021 | event.wheel.mouse_y = mouse->y; | ||
| 1022 | SDL_PushEvent(&event); | ||
| 1023 | } | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | void SDL_QuitMouse(void) | ||
| 1027 | { | ||
| 1028 | SDL_Cursor *cursor, *next; | ||
| 1029 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1030 | |||
| 1031 | if (mouse->added_mouse_touch_device) { | ||
| 1032 | SDL_DelTouch(SDL_MOUSE_TOUCHID); | ||
| 1033 | } | ||
| 1034 | |||
| 1035 | if (mouse->added_pen_touch_device) { | ||
| 1036 | SDL_DelTouch(SDL_PEN_TOUCHID); | ||
| 1037 | } | ||
| 1038 | |||
| 1039 | if (mouse->CaptureMouse) { | ||
| 1040 | SDL_CaptureMouse(false); | ||
| 1041 | SDL_UpdateMouseCapture(true); | ||
| 1042 | } | ||
| 1043 | SDL_SetRelativeMouseMode(false); | ||
| 1044 | SDL_ShowCursor(); | ||
| 1045 | |||
| 1046 | if (mouse->def_cursor) { | ||
| 1047 | SDL_SetDefaultCursor(NULL); | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | cursor = mouse->cursors; | ||
| 1051 | while (cursor) { | ||
| 1052 | next = cursor->next; | ||
| 1053 | SDL_DestroyCursor(cursor); | ||
| 1054 | cursor = next; | ||
| 1055 | } | ||
| 1056 | mouse->cursors = NULL; | ||
| 1057 | mouse->cur_cursor = NULL; | ||
| 1058 | |||
| 1059 | if (mouse->sources) { | ||
| 1060 | for (int i = 0; i < mouse->num_sources; ++i) { | ||
| 1061 | SDL_MouseInputSource *source = &mouse->sources[i]; | ||
| 1062 | SDL_free(source->clickstate); | ||
| 1063 | } | ||
| 1064 | SDL_free(mouse->sources); | ||
| 1065 | mouse->sources = NULL; | ||
| 1066 | } | ||
| 1067 | mouse->num_sources = 0; | ||
| 1068 | |||
| 1069 | SDL_RemoveHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_TIME, | ||
| 1070 | SDL_MouseDoubleClickTimeChanged, mouse); | ||
| 1071 | |||
| 1072 | SDL_RemoveHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS, | ||
| 1073 | SDL_MouseDoubleClickRadiusChanged, mouse); | ||
| 1074 | |||
| 1075 | SDL_RemoveHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE, | ||
| 1076 | SDL_MouseNormalSpeedScaleChanged, mouse); | ||
| 1077 | |||
| 1078 | SDL_RemoveHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE, | ||
| 1079 | SDL_MouseRelativeSpeedScaleChanged, mouse); | ||
| 1080 | |||
| 1081 | SDL_RemoveHintCallback(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE, | ||
| 1082 | SDL_MouseRelativeSystemScaleChanged, mouse); | ||
| 1083 | |||
| 1084 | SDL_RemoveHintCallback(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, | ||
| 1085 | SDL_MouseRelativeModeCenterChanged, mouse); | ||
| 1086 | |||
| 1087 | SDL_RemoveHintCallback(SDL_HINT_MOUSE_EMULATE_WARP_WITH_RELATIVE, | ||
| 1088 | SDL_MouseWarpEmulationChanged, mouse); | ||
| 1089 | |||
| 1090 | SDL_RemoveHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS, | ||
| 1091 | SDL_TouchMouseEventsChanged, mouse); | ||
| 1092 | |||
| 1093 | SDL_RemoveHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS, | ||
| 1094 | SDL_MouseTouchEventsChanged, mouse); | ||
| 1095 | |||
| 1096 | SDL_RemoveHintCallback(SDL_HINT_PEN_MOUSE_EVENTS, | ||
| 1097 | SDL_PenMouseEventsChanged, mouse); | ||
| 1098 | |||
| 1099 | SDL_RemoveHintCallback(SDL_HINT_PEN_TOUCH_EVENTS, | ||
| 1100 | SDL_PenTouchEventsChanged, mouse); | ||
| 1101 | |||
| 1102 | SDL_RemoveHintCallback(SDL_HINT_MOUSE_AUTO_CAPTURE, | ||
| 1103 | SDL_MouseAutoCaptureChanged, mouse); | ||
| 1104 | |||
| 1105 | SDL_RemoveHintCallback(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, | ||
| 1106 | SDL_MouseRelativeWarpMotionChanged, mouse); | ||
| 1107 | |||
| 1108 | SDL_RemoveHintCallback(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, | ||
| 1109 | SDL_MouseRelativeCursorVisibleChanged, mouse); | ||
| 1110 | |||
| 1111 | for (int i = SDL_mouse_count; i--; ) { | ||
| 1112 | SDL_RemoveMouse(SDL_mice[i].instance_id, false); | ||
| 1113 | } | ||
| 1114 | SDL_free(SDL_mice); | ||
| 1115 | SDL_mice = NULL; | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | SDL_MouseButtonFlags SDL_GetMouseState(float *x, float *y) | ||
| 1119 | { | ||
| 1120 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1121 | |||
| 1122 | if (x) { | ||
| 1123 | *x = mouse->x; | ||
| 1124 | } | ||
| 1125 | if (y) { | ||
| 1126 | *y = mouse->y; | ||
| 1127 | } | ||
| 1128 | return SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, true); | ||
| 1129 | } | ||
| 1130 | |||
| 1131 | SDL_MouseButtonFlags SDL_GetRelativeMouseState(float *x, float *y) | ||
| 1132 | { | ||
| 1133 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1134 | |||
| 1135 | if (x) { | ||
| 1136 | *x = mouse->x_accu; | ||
| 1137 | } | ||
| 1138 | if (y) { | ||
| 1139 | *y = mouse->y_accu; | ||
| 1140 | } | ||
| 1141 | mouse->x_accu = 0.0f; | ||
| 1142 | mouse->y_accu = 0.0f; | ||
| 1143 | return SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, true); | ||
| 1144 | } | ||
| 1145 | |||
| 1146 | SDL_MouseButtonFlags SDL_GetGlobalMouseState(float *x, float *y) | ||
| 1147 | { | ||
| 1148 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1149 | |||
| 1150 | if (mouse->GetGlobalMouseState) { | ||
| 1151 | float tmpx, tmpy; | ||
| 1152 | |||
| 1153 | // make sure these are never NULL for the backend implementations... | ||
| 1154 | if (!x) { | ||
| 1155 | x = &tmpx; | ||
| 1156 | } | ||
| 1157 | if (!y) { | ||
| 1158 | y = &tmpy; | ||
| 1159 | } | ||
| 1160 | |||
| 1161 | *x = *y = 0.0f; | ||
| 1162 | |||
| 1163 | return mouse->GetGlobalMouseState(x, y); | ||
| 1164 | } else { | ||
| 1165 | return SDL_GetMouseState(x, y); | ||
| 1166 | } | ||
| 1167 | } | ||
| 1168 | |||
| 1169 | void SDL_PerformWarpMouseInWindow(SDL_Window *window, float x, float y, bool ignore_relative_mode) | ||
| 1170 | { | ||
| 1171 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1172 | |||
| 1173 | if (!window) { | ||
| 1174 | window = mouse->focus; | ||
| 1175 | } | ||
| 1176 | |||
| 1177 | if (!window) { | ||
| 1178 | return; | ||
| 1179 | } | ||
| 1180 | |||
| 1181 | if ((window->flags & SDL_WINDOW_MINIMIZED) == SDL_WINDOW_MINIMIZED) { | ||
| 1182 | return; | ||
| 1183 | } | ||
| 1184 | |||
| 1185 | // Ignore the previous position when we warp | ||
| 1186 | mouse->last_x = x; | ||
| 1187 | mouse->last_y = y; | ||
| 1188 | mouse->has_position = false; | ||
| 1189 | |||
| 1190 | if (mouse->relative_mode && !ignore_relative_mode) { | ||
| 1191 | /* 2.0.22 made warping in relative mode actually functional, which | ||
| 1192 | * surprised many applications that weren't expecting the additional | ||
| 1193 | * mouse motion. | ||
| 1194 | * | ||
| 1195 | * So for now, warping in relative mode adjusts the absolution position | ||
| 1196 | * but doesn't generate motion events, unless SDL_HINT_MOUSE_RELATIVE_WARP_MOTION is set. | ||
| 1197 | */ | ||
| 1198 | if (!mouse->relative_mode_warp_motion) { | ||
| 1199 | mouse->x = x; | ||
| 1200 | mouse->y = y; | ||
| 1201 | mouse->has_position = true; | ||
| 1202 | return; | ||
| 1203 | } | ||
| 1204 | } | ||
| 1205 | |||
| 1206 | if (mouse->WarpMouse && !mouse->relative_mode) { | ||
| 1207 | mouse->WarpMouse(window, x, y); | ||
| 1208 | } else { | ||
| 1209 | SDL_PrivateSendMouseMotion(0, window, SDL_GLOBAL_MOUSE_ID, false, x, y); | ||
| 1210 | } | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | void SDL_DisableMouseWarpEmulation(void) | ||
| 1214 | { | ||
| 1215 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1216 | |||
| 1217 | if (mouse->warp_emulation_active) { | ||
| 1218 | SDL_SetRelativeMouseMode(false); | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | mouse->warp_emulation_prohibited = true; | ||
| 1222 | } | ||
| 1223 | |||
| 1224 | static void SDL_MaybeEnableWarpEmulation(SDL_Window *window, float x, float y) | ||
| 1225 | { | ||
| 1226 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1227 | |||
| 1228 | if (!mouse->warp_emulation_prohibited && mouse->warp_emulation_hint && !mouse->cursor_shown && !mouse->warp_emulation_active) { | ||
| 1229 | if (!window) { | ||
| 1230 | window = mouse->focus; | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | if (window) { | ||
| 1234 | const float cx = window->w / 2.f; | ||
| 1235 | const float cy = window->h / 2.f; | ||
| 1236 | if (x >= SDL_floorf(cx) && x <= SDL_ceilf(cx) && | ||
| 1237 | y >= SDL_floorf(cy) && y <= SDL_ceilf(cy)) { | ||
| 1238 | |||
| 1239 | // Require two consecutive warps to the center within a certain timespan to enter warp emulation mode. | ||
| 1240 | const Uint64 now = SDL_GetTicksNS(); | ||
| 1241 | if (now - mouse->last_center_warp_time_ns < WARP_EMULATION_THRESHOLD_NS) { | ||
| 1242 | if (SDL_SetRelativeMouseMode(true)) { | ||
| 1243 | mouse->warp_emulation_active = true; | ||
| 1244 | } | ||
| 1245 | } | ||
| 1246 | |||
| 1247 | mouse->last_center_warp_time_ns = now; | ||
| 1248 | return; | ||
| 1249 | } | ||
| 1250 | } | ||
| 1251 | |||
| 1252 | mouse->last_center_warp_time_ns = 0; | ||
| 1253 | } | ||
| 1254 | } | ||
| 1255 | |||
| 1256 | void SDL_WarpMouseInWindow(SDL_Window *window, float x, float y) | ||
| 1257 | { | ||
| 1258 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1259 | SDL_MaybeEnableWarpEmulation(window, x, y); | ||
| 1260 | |||
| 1261 | SDL_PerformWarpMouseInWindow(window, x, y, mouse->warp_emulation_active); | ||
| 1262 | } | ||
| 1263 | |||
| 1264 | bool SDL_WarpMouseGlobal(float x, float y) | ||
| 1265 | { | ||
| 1266 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1267 | |||
| 1268 | if (mouse->WarpMouseGlobal) { | ||
| 1269 | return mouse->WarpMouseGlobal(x, y); | ||
| 1270 | } | ||
| 1271 | |||
| 1272 | return SDL_Unsupported(); | ||
| 1273 | } | ||
| 1274 | |||
| 1275 | bool SDL_SetRelativeMouseMode(bool enabled) | ||
| 1276 | { | ||
| 1277 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1278 | SDL_Window *focusWindow = SDL_GetKeyboardFocus(); | ||
| 1279 | |||
| 1280 | if (!enabled) { | ||
| 1281 | // If warps were being emulated, reset the flag. | ||
| 1282 | mouse->warp_emulation_active = false; | ||
| 1283 | } | ||
| 1284 | |||
| 1285 | if (enabled == mouse->relative_mode) { | ||
| 1286 | return true; | ||
| 1287 | } | ||
| 1288 | |||
| 1289 | // Set the relative mode | ||
| 1290 | if (!mouse->SetRelativeMouseMode || !mouse->SetRelativeMouseMode(enabled)) { | ||
| 1291 | if (enabled) { | ||
| 1292 | return SDL_SetError("No relative mode implementation available"); | ||
| 1293 | } | ||
| 1294 | } | ||
| 1295 | mouse->relative_mode = enabled; | ||
| 1296 | |||
| 1297 | if (enabled) { | ||
| 1298 | // Update cursor visibility before we potentially warp the mouse | ||
| 1299 | SDL_SetCursor(NULL); | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | if (enabled && focusWindow) { | ||
| 1303 | SDL_SetMouseFocus(focusWindow); | ||
| 1304 | } | ||
| 1305 | |||
| 1306 | if (focusWindow) { | ||
| 1307 | SDL_UpdateWindowGrab(focusWindow); | ||
| 1308 | |||
| 1309 | // Put the cursor back to where the application expects it | ||
| 1310 | if (!enabled) { | ||
| 1311 | SDL_PerformWarpMouseInWindow(focusWindow, mouse->x, mouse->y, true); | ||
| 1312 | } | ||
| 1313 | |||
| 1314 | SDL_UpdateMouseCapture(false); | ||
| 1315 | } | ||
| 1316 | |||
| 1317 | if (!enabled) { | ||
| 1318 | // Update cursor visibility after we restore the mouse position | ||
| 1319 | SDL_SetCursor(NULL); | ||
| 1320 | } | ||
| 1321 | |||
| 1322 | // Flush pending mouse motion - ideally we would pump events, but that's not always safe | ||
| 1323 | SDL_FlushEvent(SDL_EVENT_MOUSE_MOTION); | ||
| 1324 | |||
| 1325 | return true; | ||
| 1326 | } | ||
| 1327 | |||
| 1328 | bool SDL_GetRelativeMouseMode(void) | ||
| 1329 | { | ||
| 1330 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1331 | |||
| 1332 | return mouse->relative_mode; | ||
| 1333 | } | ||
| 1334 | |||
| 1335 | void SDL_UpdateRelativeMouseMode(void) | ||
| 1336 | { | ||
| 1337 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1338 | SDL_Window *focus = SDL_GetKeyboardFocus(); | ||
| 1339 | bool relative_mode = (focus && (focus->flags & SDL_WINDOW_MOUSE_RELATIVE_MODE)); | ||
| 1340 | |||
| 1341 | if (relative_mode != mouse->relative_mode) { | ||
| 1342 | SDL_SetRelativeMouseMode(relative_mode); | ||
| 1343 | } | ||
| 1344 | } | ||
| 1345 | |||
| 1346 | bool SDL_UpdateMouseCapture(bool force_release) | ||
| 1347 | { | ||
| 1348 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1349 | SDL_Window *capture_window = NULL; | ||
| 1350 | |||
| 1351 | if (!mouse->CaptureMouse) { | ||
| 1352 | return true; | ||
| 1353 | } | ||
| 1354 | |||
| 1355 | if (!force_release) { | ||
| 1356 | if (SDL_GetMessageBoxCount() == 0 && | ||
| 1357 | (mouse->capture_desired || (mouse->auto_capture && SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, false) != 0))) { | ||
| 1358 | if (!mouse->relative_mode) { | ||
| 1359 | capture_window = mouse->focus; | ||
| 1360 | } | ||
| 1361 | } | ||
| 1362 | } | ||
| 1363 | |||
| 1364 | if (capture_window != mouse->capture_window) { | ||
| 1365 | /* We can get here recursively on Windows, so make sure we complete | ||
| 1366 | * all of the window state operations before we change the capture state | ||
| 1367 | * (e.g. https://github.com/libsdl-org/SDL/pull/5608) | ||
| 1368 | */ | ||
| 1369 | SDL_Window *previous_capture = mouse->capture_window; | ||
| 1370 | |||
| 1371 | if (previous_capture) { | ||
| 1372 | previous_capture->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; | ||
| 1373 | } | ||
| 1374 | |||
| 1375 | if (capture_window) { | ||
| 1376 | capture_window->flags |= SDL_WINDOW_MOUSE_CAPTURE; | ||
| 1377 | } | ||
| 1378 | |||
| 1379 | mouse->capture_window = capture_window; | ||
| 1380 | |||
| 1381 | if (!mouse->CaptureMouse(capture_window)) { | ||
| 1382 | // CaptureMouse() will have set an error, just restore the state | ||
| 1383 | if (previous_capture) { | ||
| 1384 | previous_capture->flags |= SDL_WINDOW_MOUSE_CAPTURE; | ||
| 1385 | } | ||
| 1386 | if (capture_window) { | ||
| 1387 | capture_window->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; | ||
| 1388 | } | ||
| 1389 | mouse->capture_window = previous_capture; | ||
| 1390 | |||
| 1391 | return false; | ||
| 1392 | } | ||
| 1393 | } | ||
| 1394 | return true; | ||
| 1395 | } | ||
| 1396 | |||
| 1397 | bool SDL_CaptureMouse(bool enabled) | ||
| 1398 | { | ||
| 1399 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1400 | |||
| 1401 | if (!mouse->CaptureMouse) { | ||
| 1402 | return SDL_Unsupported(); | ||
| 1403 | } | ||
| 1404 | |||
| 1405 | #if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK) | ||
| 1406 | /* Windows mouse capture is tied to the current thread, and must be called | ||
| 1407 | * from the thread that created the window being captured. Since we update | ||
| 1408 | * the mouse capture state from the event processing, any application state | ||
| 1409 | * changes must be processed on that thread as well. | ||
| 1410 | */ | ||
| 1411 | if (!SDL_OnVideoThread()) { | ||
| 1412 | return SDL_SetError("SDL_CaptureMouse() must be called on the main thread"); | ||
| 1413 | } | ||
| 1414 | #endif // defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK) | ||
| 1415 | |||
| 1416 | if (enabled && SDL_GetKeyboardFocus() == NULL) { | ||
| 1417 | return SDL_SetError("No window has focus"); | ||
| 1418 | } | ||
| 1419 | mouse->capture_desired = enabled; | ||
| 1420 | |||
| 1421 | return SDL_UpdateMouseCapture(false); | ||
| 1422 | } | ||
| 1423 | |||
| 1424 | SDL_Cursor *SDL_CreateCursor(const Uint8 *data, const Uint8 *mask, int w, int h, int hot_x, int hot_y) | ||
| 1425 | { | ||
| 1426 | SDL_Surface *surface; | ||
| 1427 | SDL_Cursor *cursor; | ||
| 1428 | int x, y; | ||
| 1429 | Uint32 *pixel; | ||
| 1430 | Uint8 datab = 0, maskb = 0; | ||
| 1431 | const Uint32 black = 0xFF000000; | ||
| 1432 | const Uint32 white = 0xFFFFFFFF; | ||
| 1433 | const Uint32 transparent = 0x00000000; | ||
| 1434 | #if defined(SDL_PLATFORM_WIN32) | ||
| 1435 | // Only Windows backend supports inverted pixels in mono cursors. | ||
| 1436 | const Uint32 inverted = 0x00FFFFFF; | ||
| 1437 | #else | ||
| 1438 | const Uint32 inverted = 0xFF000000; | ||
| 1439 | #endif // defined(SDL_PLATFORM_WIN32) | ||
| 1440 | |||
| 1441 | // Make sure the width is a multiple of 8 | ||
| 1442 | w = ((w + 7) & ~7); | ||
| 1443 | |||
| 1444 | // Create the surface from a bitmap | ||
| 1445 | surface = SDL_CreateSurface(w, h, SDL_PIXELFORMAT_ARGB8888); | ||
| 1446 | if (!surface) { | ||
| 1447 | return NULL; | ||
| 1448 | } | ||
| 1449 | for (y = 0; y < h; ++y) { | ||
| 1450 | pixel = (Uint32 *)((Uint8 *)surface->pixels + y * surface->pitch); | ||
| 1451 | for (x = 0; x < w; ++x) { | ||
| 1452 | if ((x % 8) == 0) { | ||
| 1453 | datab = *data++; | ||
| 1454 | maskb = *mask++; | ||
| 1455 | } | ||
| 1456 | if (maskb & 0x80) { | ||
| 1457 | *pixel++ = (datab & 0x80) ? black : white; | ||
| 1458 | } else { | ||
| 1459 | *pixel++ = (datab & 0x80) ? inverted : transparent; | ||
| 1460 | } | ||
| 1461 | datab <<= 1; | ||
| 1462 | maskb <<= 1; | ||
| 1463 | } | ||
| 1464 | } | ||
| 1465 | |||
| 1466 | cursor = SDL_CreateColorCursor(surface, hot_x, hot_y); | ||
| 1467 | |||
| 1468 | SDL_DestroySurface(surface); | ||
| 1469 | |||
| 1470 | return cursor; | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | SDL_Cursor *SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y) | ||
| 1474 | { | ||
| 1475 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1476 | SDL_Surface *temp = NULL; | ||
| 1477 | SDL_Cursor *cursor; | ||
| 1478 | |||
| 1479 | if (!surface) { | ||
| 1480 | SDL_InvalidParamError("surface"); | ||
| 1481 | return NULL; | ||
| 1482 | } | ||
| 1483 | |||
| 1484 | // Allow specifying the hot spot via properties on the surface | ||
| 1485 | SDL_PropertiesID props = SDL_GetSurfaceProperties(surface); | ||
| 1486 | hot_x = (int)SDL_GetNumberProperty(props, SDL_PROP_SURFACE_HOTSPOT_X_NUMBER, hot_x); | ||
| 1487 | hot_y = (int)SDL_GetNumberProperty(props, SDL_PROP_SURFACE_HOTSPOT_Y_NUMBER, hot_y); | ||
| 1488 | |||
| 1489 | // Sanity check the hot spot | ||
| 1490 | if ((hot_x < 0) || (hot_y < 0) || | ||
| 1491 | (hot_x >= surface->w) || (hot_y >= surface->h)) { | ||
| 1492 | SDL_SetError("Cursor hot spot doesn't lie within cursor"); | ||
| 1493 | return NULL; | ||
| 1494 | } | ||
| 1495 | |||
| 1496 | if (surface->format != SDL_PIXELFORMAT_ARGB8888) { | ||
| 1497 | temp = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_ARGB8888); | ||
| 1498 | if (!temp) { | ||
| 1499 | return NULL; | ||
| 1500 | } | ||
| 1501 | surface = temp; | ||
| 1502 | } | ||
| 1503 | |||
| 1504 | if (mouse->CreateCursor) { | ||
| 1505 | cursor = mouse->CreateCursor(surface, hot_x, hot_y); | ||
| 1506 | } else { | ||
| 1507 | cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor)); | ||
| 1508 | } | ||
| 1509 | if (cursor) { | ||
| 1510 | cursor->next = mouse->cursors; | ||
| 1511 | mouse->cursors = cursor; | ||
| 1512 | } | ||
| 1513 | |||
| 1514 | SDL_DestroySurface(temp); | ||
| 1515 | |||
| 1516 | return cursor; | ||
| 1517 | } | ||
| 1518 | |||
| 1519 | SDL_Cursor *SDL_CreateSystemCursor(SDL_SystemCursor id) | ||
| 1520 | { | ||
| 1521 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1522 | SDL_Cursor *cursor; | ||
| 1523 | |||
| 1524 | if (!mouse->CreateSystemCursor) { | ||
| 1525 | SDL_SetError("CreateSystemCursor is not currently supported"); | ||
| 1526 | return NULL; | ||
| 1527 | } | ||
| 1528 | |||
| 1529 | cursor = mouse->CreateSystemCursor(id); | ||
| 1530 | if (cursor) { | ||
| 1531 | cursor->next = mouse->cursors; | ||
| 1532 | mouse->cursors = cursor; | ||
| 1533 | } | ||
| 1534 | |||
| 1535 | return cursor; | ||
| 1536 | } | ||
| 1537 | |||
| 1538 | /* SDL_SetCursor(NULL) can be used to force the cursor redraw, | ||
| 1539 | if this is desired for any reason. This is used when setting | ||
| 1540 | the video mode and when the SDL window gains the mouse focus. | ||
| 1541 | */ | ||
| 1542 | bool SDL_SetCursor(SDL_Cursor *cursor) | ||
| 1543 | { | ||
| 1544 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1545 | |||
| 1546 | // Return immediately if setting the cursor to the currently set one (fixes #7151) | ||
| 1547 | if (cursor == mouse->cur_cursor) { | ||
| 1548 | return true; | ||
| 1549 | } | ||
| 1550 | |||
| 1551 | // Set the new cursor | ||
| 1552 | if (cursor) { | ||
| 1553 | // Make sure the cursor is still valid for this mouse | ||
| 1554 | if (cursor != mouse->def_cursor) { | ||
| 1555 | SDL_Cursor *found; | ||
| 1556 | for (found = mouse->cursors; found; found = found->next) { | ||
| 1557 | if (found == cursor) { | ||
| 1558 | break; | ||
| 1559 | } | ||
| 1560 | } | ||
| 1561 | if (!found) { | ||
| 1562 | return SDL_SetError("Cursor not associated with the current mouse"); | ||
| 1563 | } | ||
| 1564 | } | ||
| 1565 | mouse->cur_cursor = cursor; | ||
| 1566 | } else { | ||
| 1567 | if (mouse->focus) { | ||
| 1568 | cursor = mouse->cur_cursor; | ||
| 1569 | } else { | ||
| 1570 | cursor = mouse->def_cursor; | ||
| 1571 | } | ||
| 1572 | } | ||
| 1573 | |||
| 1574 | if (cursor && (!mouse->focus || (mouse->cursor_shown && (!mouse->relative_mode || mouse->relative_mode_cursor_visible)))) { | ||
| 1575 | if (mouse->ShowCursor) { | ||
| 1576 | mouse->ShowCursor(cursor); | ||
| 1577 | } | ||
| 1578 | } else { | ||
| 1579 | if (mouse->ShowCursor) { | ||
| 1580 | mouse->ShowCursor(NULL); | ||
| 1581 | } | ||
| 1582 | } | ||
| 1583 | return true; | ||
| 1584 | } | ||
| 1585 | |||
| 1586 | SDL_Cursor *SDL_GetCursor(void) | ||
| 1587 | { | ||
| 1588 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1589 | |||
| 1590 | if (!mouse) { | ||
| 1591 | return NULL; | ||
| 1592 | } | ||
| 1593 | return mouse->cur_cursor; | ||
| 1594 | } | ||
| 1595 | |||
| 1596 | SDL_Cursor *SDL_GetDefaultCursor(void) | ||
| 1597 | { | ||
| 1598 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1599 | |||
| 1600 | if (!mouse) { | ||
| 1601 | return NULL; | ||
| 1602 | } | ||
| 1603 | return mouse->def_cursor; | ||
| 1604 | } | ||
| 1605 | |||
| 1606 | void SDL_DestroyCursor(SDL_Cursor *cursor) | ||
| 1607 | { | ||
| 1608 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1609 | SDL_Cursor *curr, *prev; | ||
| 1610 | |||
| 1611 | if (!cursor) { | ||
| 1612 | return; | ||
| 1613 | } | ||
| 1614 | |||
| 1615 | if (cursor == mouse->def_cursor) { | ||
| 1616 | return; | ||
| 1617 | } | ||
| 1618 | if (cursor == mouse->cur_cursor) { | ||
| 1619 | SDL_SetCursor(mouse->def_cursor); | ||
| 1620 | } | ||
| 1621 | |||
| 1622 | for (prev = NULL, curr = mouse->cursors; curr; | ||
| 1623 | prev = curr, curr = curr->next) { | ||
| 1624 | if (curr == cursor) { | ||
| 1625 | if (prev) { | ||
| 1626 | prev->next = curr->next; | ||
| 1627 | } else { | ||
| 1628 | mouse->cursors = curr->next; | ||
| 1629 | } | ||
| 1630 | |||
| 1631 | if (mouse->FreeCursor && curr->internal) { | ||
| 1632 | mouse->FreeCursor(curr); | ||
| 1633 | } else { | ||
| 1634 | SDL_free(curr); | ||
| 1635 | } | ||
| 1636 | return; | ||
| 1637 | } | ||
| 1638 | } | ||
| 1639 | } | ||
| 1640 | |||
| 1641 | bool SDL_ShowCursor(void) | ||
| 1642 | { | ||
| 1643 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1644 | |||
| 1645 | if (mouse->warp_emulation_active) { | ||
| 1646 | SDL_SetRelativeMouseMode(false); | ||
| 1647 | mouse->warp_emulation_active = false; | ||
| 1648 | } | ||
| 1649 | |||
| 1650 | if (!mouse->cursor_shown) { | ||
| 1651 | mouse->cursor_shown = true; | ||
| 1652 | SDL_SetCursor(NULL); | ||
| 1653 | } | ||
| 1654 | return true; | ||
| 1655 | } | ||
| 1656 | |||
| 1657 | bool SDL_HideCursor(void) | ||
| 1658 | { | ||
| 1659 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1660 | |||
| 1661 | if (mouse->cursor_shown) { | ||
| 1662 | mouse->cursor_shown = false; | ||
| 1663 | SDL_SetCursor(NULL); | ||
| 1664 | } | ||
| 1665 | return true; | ||
| 1666 | } | ||
| 1667 | |||
| 1668 | bool SDL_CursorVisible(void) | ||
| 1669 | { | ||
| 1670 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 1671 | |||
| 1672 | return mouse->cursor_shown; | ||
| 1673 | } | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_mouse_c.h b/contrib/SDL-3.2.8/src/events/SDL_mouse_c.h new file mode 100644 index 0000000..43cc520 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_mouse_c.h | |||
| @@ -0,0 +1,208 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #ifndef SDL_mouse_c_h_ | ||
| 24 | #define SDL_mouse_c_h_ | ||
| 25 | |||
| 26 | // Mouse events not associated with a specific input device | ||
| 27 | #define SDL_GLOBAL_MOUSE_ID 0 | ||
| 28 | |||
| 29 | // The default mouse input device, for platforms that don't have multiple mice | ||
| 30 | #define SDL_DEFAULT_MOUSE_ID 1 | ||
| 31 | |||
| 32 | typedef struct SDL_CursorData SDL_CursorData; | ||
| 33 | |||
| 34 | struct SDL_Cursor | ||
| 35 | { | ||
| 36 | struct SDL_Cursor *next; | ||
| 37 | SDL_CursorData *internal; | ||
| 38 | }; | ||
| 39 | |||
| 40 | typedef struct | ||
| 41 | { | ||
| 42 | Uint64 last_timestamp; | ||
| 43 | double click_motion_x; | ||
| 44 | double click_motion_y; | ||
| 45 | Uint8 click_count; | ||
| 46 | } SDL_MouseClickState; | ||
| 47 | |||
| 48 | typedef struct | ||
| 49 | { | ||
| 50 | SDL_MouseID mouseID; | ||
| 51 | Uint32 buttonstate; | ||
| 52 | |||
| 53 | // Data for double-click tracking | ||
| 54 | int num_clickstates; | ||
| 55 | SDL_MouseClickState *clickstate; | ||
| 56 | } SDL_MouseInputSource; | ||
| 57 | |||
| 58 | typedef struct | ||
| 59 | { | ||
| 60 | // Create a cursor from a surface | ||
| 61 | SDL_Cursor *(*CreateCursor)(SDL_Surface *surface, int hot_x, int hot_y); | ||
| 62 | |||
| 63 | // Create a system cursor | ||
| 64 | SDL_Cursor *(*CreateSystemCursor)(SDL_SystemCursor id); | ||
| 65 | |||
| 66 | // Show the specified cursor, or hide if cursor is NULL | ||
| 67 | bool (*ShowCursor)(SDL_Cursor *cursor); | ||
| 68 | |||
| 69 | // This is called when a mouse motion event occurs | ||
| 70 | bool (*MoveCursor)(SDL_Cursor *cursor); | ||
| 71 | |||
| 72 | // Free a window manager cursor | ||
| 73 | void (*FreeCursor)(SDL_Cursor *cursor); | ||
| 74 | |||
| 75 | // Warp the mouse to (x,y) within a window | ||
| 76 | bool (*WarpMouse)(SDL_Window *window, float x, float y); | ||
| 77 | |||
| 78 | // Warp the mouse to (x,y) in screen space | ||
| 79 | bool (*WarpMouseGlobal)(float x, float y); | ||
| 80 | |||
| 81 | // Set relative mode | ||
| 82 | bool (*SetRelativeMouseMode)(bool enabled); | ||
| 83 | |||
| 84 | // Set mouse capture | ||
| 85 | bool (*CaptureMouse)(SDL_Window *window); | ||
| 86 | |||
| 87 | // Get absolute mouse coordinates. (x) and (y) are never NULL and set to zero before call. | ||
| 88 | SDL_MouseButtonFlags (*GetGlobalMouseState)(float *x, float *y); | ||
| 89 | |||
| 90 | // Platform-specific system mouse transform | ||
| 91 | void (*ApplySystemScale)(void *internal, Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float *x, float *y); | ||
| 92 | void *system_scale_data; | ||
| 93 | |||
| 94 | // Data common to all mice | ||
| 95 | SDL_Window *focus; | ||
| 96 | float x; | ||
| 97 | float y; | ||
| 98 | float x_accu; | ||
| 99 | float y_accu; | ||
| 100 | float last_x, last_y; // the last reported x and y coordinates | ||
| 101 | double click_motion_x; | ||
| 102 | double click_motion_y; | ||
| 103 | bool has_position; | ||
| 104 | bool relative_mode; | ||
| 105 | bool relative_mode_warp_motion; | ||
| 106 | bool relative_mode_cursor_visible; | ||
| 107 | bool relative_mode_center; | ||
| 108 | bool warp_emulation_hint; | ||
| 109 | bool warp_emulation_active; | ||
| 110 | bool warp_emulation_prohibited; | ||
| 111 | Uint64 last_center_warp_time_ns; | ||
| 112 | bool enable_normal_speed_scale; | ||
| 113 | float normal_speed_scale; | ||
| 114 | bool enable_relative_speed_scale; | ||
| 115 | float relative_speed_scale; | ||
| 116 | bool enable_relative_system_scale; | ||
| 117 | Uint32 double_click_time; | ||
| 118 | int double_click_radius; | ||
| 119 | bool touch_mouse_events; | ||
| 120 | bool mouse_touch_events; | ||
| 121 | bool pen_mouse_events; | ||
| 122 | bool pen_touch_events; | ||
| 123 | bool was_touch_mouse_events; // Was a touch-mouse event pending? | ||
| 124 | bool added_mouse_touch_device; // did we SDL_AddTouch() a virtual touch device for the mouse? | ||
| 125 | bool added_pen_touch_device; // did we SDL_AddTouch() a virtual touch device for pens? | ||
| 126 | #ifdef SDL_PLATFORM_VITA | ||
| 127 | Uint8 vita_touch_mouse_device; | ||
| 128 | #endif | ||
| 129 | bool auto_capture; | ||
| 130 | bool capture_desired; | ||
| 131 | SDL_Window *capture_window; | ||
| 132 | |||
| 133 | // Data for input source state | ||
| 134 | int num_sources; | ||
| 135 | SDL_MouseInputSource *sources; | ||
| 136 | |||
| 137 | SDL_Cursor *cursors; | ||
| 138 | SDL_Cursor *def_cursor; | ||
| 139 | SDL_Cursor *cur_cursor; | ||
| 140 | bool cursor_shown; | ||
| 141 | |||
| 142 | // Driver-dependent data. | ||
| 143 | void *internal; | ||
| 144 | } SDL_Mouse; | ||
| 145 | |||
| 146 | // Initialize the mouse subsystem, called before the main video driver is initialized | ||
| 147 | extern bool SDL_PreInitMouse(void); | ||
| 148 | |||
| 149 | // Finish initializing the mouse subsystem, called after the main video driver was initialized | ||
| 150 | extern void SDL_PostInitMouse(void); | ||
| 151 | |||
| 152 | // Return whether a device is actually a mouse | ||
| 153 | extern bool SDL_IsMouse(Uint16 vendor, Uint16 product); | ||
| 154 | |||
| 155 | // A mouse has been added to the system | ||
| 156 | extern void SDL_AddMouse(SDL_MouseID mouseID, const char *name, bool send_event); | ||
| 157 | |||
| 158 | // A mouse has been removed from the system | ||
| 159 | extern void SDL_RemoveMouse(SDL_MouseID mouseID, bool send_event); | ||
| 160 | |||
| 161 | // Get the mouse state structure | ||
| 162 | extern SDL_Mouse *SDL_GetMouse(void); | ||
| 163 | |||
| 164 | // Set the default mouse cursor | ||
| 165 | extern void SDL_SetDefaultCursor(SDL_Cursor *cursor); | ||
| 166 | |||
| 167 | // Get the preferred default system cursor | ||
| 168 | extern SDL_SystemCursor SDL_GetDefaultSystemCursor(void); | ||
| 169 | |||
| 170 | // Set the mouse focus window | ||
| 171 | extern void SDL_SetMouseFocus(SDL_Window *window); | ||
| 172 | |||
| 173 | // Update the mouse capture window | ||
| 174 | extern bool SDL_UpdateMouseCapture(bool force_release); | ||
| 175 | |||
| 176 | // Send a mouse motion event | ||
| 177 | extern void SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, bool relative, float x, float y); | ||
| 178 | |||
| 179 | // Send a mouse button event | ||
| 180 | extern void SDL_SendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 button, bool down); | ||
| 181 | |||
| 182 | // Send a mouse button event with a click count | ||
| 183 | extern void SDL_SendMouseButtonClicks(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 button, bool down, int clicks); | ||
| 184 | |||
| 185 | // Send a mouse wheel event | ||
| 186 | extern void SDL_SendMouseWheel(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction); | ||
| 187 | |||
| 188 | // Warp the mouse within the window, potentially overriding relative mode | ||
| 189 | extern void SDL_PerformWarpMouseInWindow(SDL_Window *window, float x, float y, bool ignore_relative_mode); | ||
| 190 | |||
| 191 | // Relative mouse mode | ||
| 192 | extern bool SDL_SetRelativeMouseMode(bool enabled); | ||
| 193 | extern bool SDL_GetRelativeMouseMode(void); | ||
| 194 | extern void SDL_UpdateRelativeMouseMode(void); | ||
| 195 | extern void SDL_DisableMouseWarpEmulation(void); | ||
| 196 | |||
| 197 | // TODO RECONNECT: Set mouse state to "zero" | ||
| 198 | #if 0 | ||
| 199 | extern void SDL_ResetMouse(void); | ||
| 200 | #endif // 0 | ||
| 201 | |||
| 202 | // Check if mouse position is within window or captured by window | ||
| 203 | extern bool SDL_MousePositionInWindow(SDL_Window *window, float x, float y); | ||
| 204 | |||
| 205 | // Shutdown the mouse subsystem | ||
| 206 | extern void SDL_QuitMouse(void); | ||
| 207 | |||
| 208 | #endif // SDL_mouse_c_h_ | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_pen.c b/contrib/SDL-3.2.8/src/events/SDL_pen.c new file mode 100644 index 0000000..1ef7062 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_pen.c | |||
| @@ -0,0 +1,577 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | // Pressure-sensitive pen handling code for SDL | ||
| 24 | |||
| 25 | #include "../SDL_hints_c.h" | ||
| 26 | #include "SDL_events_c.h" | ||
| 27 | #include "SDL_pen_c.h" | ||
| 28 | |||
| 29 | static SDL_PenID pen_touching = 0; // used for synthetic mouse/touch events. | ||
| 30 | |||
| 31 | typedef struct SDL_Pen | ||
| 32 | { | ||
| 33 | SDL_PenID instance_id; | ||
| 34 | char *name; | ||
| 35 | SDL_PenInfo info; | ||
| 36 | float axes[SDL_PEN_AXIS_COUNT]; | ||
| 37 | float x; | ||
| 38 | float y; | ||
| 39 | SDL_PenInputFlags input_state; | ||
| 40 | void *driverdata; | ||
| 41 | } SDL_Pen; | ||
| 42 | |||
| 43 | // we assume there's usually 0-1 pens in most cases and this list doesn't | ||
| 44 | // usually change after startup, so a simple array with a RWlock is fine for now. | ||
| 45 | static SDL_RWLock *pen_device_rwlock = NULL; | ||
| 46 | static SDL_Pen *pen_devices SDL_GUARDED_BY(pen_device_rwlock) = NULL; | ||
| 47 | static int pen_device_count SDL_GUARDED_BY(pen_device_rwlock) = 0; | ||
| 48 | |||
| 49 | // You must hold pen_device_rwlock before calling this, and result is only safe while lock is held! | ||
| 50 | // If SDL isn't initialized, grabbing the NULL lock is a no-op and there will be zero devices, so | ||
| 51 | // locking and calling this in that case will do the right thing. | ||
| 52 | static SDL_Pen *FindPenByInstanceId(SDL_PenID instance_id) SDL_REQUIRES_SHARED(pen_device_rwlock) | ||
| 53 | { | ||
| 54 | if (instance_id) { | ||
| 55 | for (int i = 0; i < pen_device_count; i++) { | ||
| 56 | if (pen_devices[i].instance_id == instance_id) { | ||
| 57 | return &pen_devices[i]; | ||
| 58 | } | ||
| 59 | } | ||
| 60 | } | ||
| 61 | SDL_SetError("Invalid pen instance ID"); | ||
| 62 | return NULL; | ||
| 63 | } | ||
| 64 | |||
| 65 | SDL_PenID SDL_FindPenByHandle(void *handle) | ||
| 66 | { | ||
| 67 | SDL_PenID result = 0; | ||
| 68 | SDL_LockRWLockForReading(pen_device_rwlock); | ||
| 69 | for (int i = 0; i < pen_device_count; i++) { | ||
| 70 | if (pen_devices[i].driverdata == handle) { | ||
| 71 | result = pen_devices[i].instance_id; | ||
| 72 | break; | ||
| 73 | } | ||
| 74 | } | ||
| 75 | SDL_UnlockRWLock(pen_device_rwlock); | ||
| 76 | return result; | ||
| 77 | } | ||
| 78 | |||
| 79 | SDL_PenID SDL_FindPenByCallback(bool (*callback)(void *handle, void *userdata), void *userdata) | ||
| 80 | { | ||
| 81 | SDL_PenID result = 0; | ||
| 82 | SDL_LockRWLockForReading(pen_device_rwlock); | ||
| 83 | for (int i = 0; i < pen_device_count; i++) { | ||
| 84 | if (callback(pen_devices[i].driverdata, userdata)) { | ||
| 85 | result = pen_devices[i].instance_id; | ||
| 86 | break; | ||
| 87 | } | ||
| 88 | } | ||
| 89 | SDL_UnlockRWLock(pen_device_rwlock); | ||
| 90 | return result; | ||
| 91 | } | ||
| 92 | |||
| 93 | |||
| 94 | |||
| 95 | // public API ... | ||
| 96 | |||
| 97 | bool SDL_InitPen(void) | ||
| 98 | { | ||
| 99 | SDL_assert(pen_device_rwlock == NULL); | ||
| 100 | SDL_assert(pen_devices == NULL); | ||
| 101 | SDL_assert(pen_device_count == 0); | ||
| 102 | pen_device_rwlock = SDL_CreateRWLock(); | ||
| 103 | if (!pen_device_rwlock) { | ||
| 104 | return false; | ||
| 105 | } | ||
| 106 | return true; | ||
| 107 | } | ||
| 108 | |||
| 109 | void SDL_QuitPen(void) | ||
| 110 | { | ||
| 111 | SDL_DestroyRWLock(pen_device_rwlock); | ||
| 112 | pen_device_rwlock = NULL; | ||
| 113 | if (pen_devices) { | ||
| 114 | for (int i = pen_device_count; i--; ) { | ||
| 115 | SDL_free(pen_devices[i].name); | ||
| 116 | } | ||
| 117 | SDL_free(pen_devices); | ||
| 118 | pen_devices = NULL; | ||
| 119 | } | ||
| 120 | pen_device_count = 0; | ||
| 121 | pen_touching = 0; | ||
| 122 | } | ||
| 123 | |||
| 124 | #if 0 // not a public API at the moment. | ||
| 125 | SDL_PenID *SDL_GetPens(int *count) | ||
| 126 | { | ||
| 127 | SDL_LockRWLockForReading(pen_device_rwlock); | ||
| 128 | const int num_devices = pen_device_count; | ||
| 129 | SDL_PenID *result = (SDL_PenID *) SDL_malloc((num_devices + 1) * sizeof (SDL_PenID)); | ||
| 130 | if (result) { | ||
| 131 | for (int i = 0; i < num_devices; i++) { | ||
| 132 | result[i] = pen_devices[i].instance_id; | ||
| 133 | } | ||
| 134 | result[num_devices] = 0; // null-terminated. | ||
| 135 | } | ||
| 136 | SDL_UnlockRWLock(pen_device_rwlock); | ||
| 137 | |||
| 138 | if (count) { | ||
| 139 | *count = result ? num_devices : 0; | ||
| 140 | } | ||
| 141 | return result; | ||
| 142 | } | ||
| 143 | |||
| 144 | const char *SDL_GetPenName(SDL_PenID instance_id) | ||
| 145 | { | ||
| 146 | SDL_LockRWLockForReading(pen_device_rwlock); | ||
| 147 | const SDL_Pen *pen = FindPenByInstanceId(instance_id); | ||
| 148 | const char *result = pen ? SDL_GetPersistentString(pen->name) : NULL; | ||
| 149 | SDL_UnlockRWLock(pen_device_rwlock); | ||
| 150 | return result; | ||
| 151 | } | ||
| 152 | |||
| 153 | bool SDL_GetPenInfo(SDL_PenID instance_id, SDL_PenInfo *info) | ||
| 154 | { | ||
| 155 | SDL_LockRWLockForReading(pen_device_rwlock); | ||
| 156 | const SDL_Pen *pen = FindPenByInstanceId(instance_id); | ||
| 157 | const bool result = pen ? true : false; | ||
| 158 | if (info) { | ||
| 159 | if (result) { | ||
| 160 | SDL_copyp(info, &pen->info); | ||
| 161 | } else { | ||
| 162 | SDL_zerop(info); | ||
| 163 | } | ||
| 164 | } | ||
| 165 | SDL_UnlockRWLock(pen_device_rwlock); | ||
| 166 | return result; | ||
| 167 | } | ||
| 168 | |||
| 169 | bool SDL_PenConnected(SDL_PenID instance_id) | ||
| 170 | { | ||
| 171 | SDL_LockRWLockForReading(pen_device_rwlock); | ||
| 172 | const SDL_Pen *pen = FindPenByInstanceId(instance_id); | ||
| 173 | const bool result = (pen != NULL); | ||
| 174 | SDL_UnlockRWLock(pen_device_rwlock); | ||
| 175 | return result; | ||
| 176 | } | ||
| 177 | #endif | ||
| 178 | |||
| 179 | SDL_PenInputFlags SDL_GetPenStatus(SDL_PenID instance_id, float *axes, int num_axes) | ||
| 180 | { | ||
| 181 | if (num_axes < 0) { | ||
| 182 | num_axes = 0; | ||
| 183 | } | ||
| 184 | |||
| 185 | SDL_LockRWLockForReading(pen_device_rwlock); | ||
| 186 | const SDL_Pen *pen = FindPenByInstanceId(instance_id); | ||
| 187 | SDL_PenInputFlags result = 0; | ||
| 188 | if (pen) { | ||
| 189 | result = pen->input_state; | ||
| 190 | if (axes && num_axes) { | ||
| 191 | SDL_memcpy(axes, pen->axes, SDL_min(num_axes, SDL_PEN_AXIS_COUNT) * sizeof (*axes)); | ||
| 192 | // zero out axes we don't know about, in case the caller built with newer SDL headers that support more of them. | ||
| 193 | if (num_axes > SDL_PEN_AXIS_COUNT) { | ||
| 194 | SDL_memset(&axes[SDL_PEN_AXIS_COUNT], '\0', (num_axes - SDL_PEN_AXIS_COUNT) * sizeof (*axes)); | ||
| 195 | } | ||
| 196 | } | ||
| 197 | } | ||
| 198 | SDL_UnlockRWLock(pen_device_rwlock); | ||
| 199 | return result; | ||
| 200 | } | ||
| 201 | |||
| 202 | SDL_PenCapabilityFlags SDL_GetPenCapabilityFromAxis(SDL_PenAxis axis) | ||
| 203 | { | ||
| 204 | // the initial capability bits happen to match up, but as | ||
| 205 | // more features show up later, the bits may no longer be contiguous! | ||
| 206 | if ((axis >= SDL_PEN_AXIS_PRESSURE) && (axis <= SDL_PEN_AXIS_SLIDER)) { | ||
| 207 | return ((SDL_PenCapabilityFlags) 1u) << ((SDL_PenCapabilityFlags) axis); | ||
| 208 | } | ||
| 209 | return 0; // oh well. | ||
| 210 | } | ||
| 211 | |||
| 212 | SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, const SDL_PenInfo *info, void *handle) | ||
| 213 | { | ||
| 214 | SDL_assert(handle != NULL); // just allocate a Uint8 so you have a unique pointer if not needed! | ||
| 215 | SDL_assert(SDL_FindPenByHandle(handle) == 0); // Backends shouldn't double-add pens! | ||
| 216 | SDL_assert(pen_device_rwlock != NULL); // subsystem should be initialized by now! | ||
| 217 | |||
| 218 | char *namecpy = SDL_strdup(name ? name : "Unnamed pen"); | ||
| 219 | if (!namecpy) { | ||
| 220 | return 0; | ||
| 221 | } | ||
| 222 | |||
| 223 | SDL_PenID result = 0; | ||
| 224 | |||
| 225 | SDL_LockRWLockForWriting(pen_device_rwlock); | ||
| 226 | |||
| 227 | SDL_Pen *pen = NULL; | ||
| 228 | void *ptr = SDL_realloc(pen_devices, (pen_device_count + 1) * sizeof (*pen)); | ||
| 229 | if (ptr) { | ||
| 230 | result = (SDL_PenID) SDL_GetNextObjectID(); | ||
| 231 | pen_devices = (SDL_Pen *) ptr; | ||
| 232 | pen = &pen_devices[pen_device_count]; | ||
| 233 | pen_device_count++; | ||
| 234 | |||
| 235 | SDL_zerop(pen); | ||
| 236 | pen->instance_id = result; | ||
| 237 | pen->name = namecpy; | ||
| 238 | if (info) { | ||
| 239 | SDL_copyp(&pen->info, info); | ||
| 240 | } | ||
| 241 | pen->driverdata = handle; | ||
| 242 | // axes and input state defaults to zero. | ||
| 243 | } | ||
| 244 | SDL_UnlockRWLock(pen_device_rwlock); | ||
| 245 | |||
| 246 | if (!pen) { | ||
| 247 | SDL_free(namecpy); | ||
| 248 | } | ||
| 249 | |||
| 250 | if (result && SDL_EventEnabled(SDL_EVENT_PEN_PROXIMITY_IN)) { | ||
| 251 | SDL_Event event; | ||
| 252 | SDL_zero(event); | ||
| 253 | event.pproximity.type = SDL_EVENT_PEN_PROXIMITY_IN; | ||
| 254 | event.pproximity.timestamp = timestamp; | ||
| 255 | event.pproximity.which = result; | ||
| 256 | SDL_PushEvent(&event); | ||
| 257 | } | ||
| 258 | |||
| 259 | return result; | ||
| 260 | } | ||
| 261 | |||
| 262 | void SDL_RemovePenDevice(Uint64 timestamp, SDL_PenID instance_id) | ||
| 263 | { | ||
| 264 | if (!instance_id) { | ||
| 265 | return; | ||
| 266 | } | ||
| 267 | |||
| 268 | SDL_LockRWLockForWriting(pen_device_rwlock); | ||
| 269 | SDL_Pen *pen = FindPenByInstanceId(instance_id); | ||
| 270 | if (pen) { | ||
| 271 | SDL_free(pen->name); | ||
| 272 | // we don't free `pen`, it's just part of simple array. Shuffle it out. | ||
| 273 | const int idx = ((int) (pen - pen_devices)); | ||
| 274 | SDL_assert((idx >= 0) && (idx < pen_device_count)); | ||
| 275 | if ( idx < (pen_device_count - 1) ) { | ||
| 276 | SDL_memmove(&pen_devices[idx], &pen_devices[idx + 1], sizeof (*pen) * ((pen_device_count - idx) - 1)); | ||
| 277 | } | ||
| 278 | |||
| 279 | SDL_assert(pen_device_count > 0); | ||
| 280 | pen_device_count--; | ||
| 281 | |||
| 282 | if (pen_device_count) { | ||
| 283 | void *ptr = SDL_realloc(pen_devices, sizeof (*pen) * pen_device_count); // shrink it down. | ||
| 284 | if (ptr) { | ||
| 285 | pen_devices = (SDL_Pen *) ptr; | ||
| 286 | } | ||
| 287 | } else { | ||
| 288 | SDL_free(pen_devices); | ||
| 289 | pen_devices = NULL; | ||
| 290 | } | ||
| 291 | } | ||
| 292 | SDL_UnlockRWLock(pen_device_rwlock); | ||
| 293 | |||
| 294 | if (pen && SDL_EventEnabled(SDL_EVENT_PEN_PROXIMITY_OUT)) { | ||
| 295 | SDL_Event event; | ||
| 296 | SDL_zero(event); | ||
| 297 | event.pproximity.type = SDL_EVENT_PEN_PROXIMITY_OUT; | ||
| 298 | event.pproximity.timestamp = timestamp; | ||
| 299 | event.pproximity.which = instance_id; | ||
| 300 | SDL_PushEvent(&event); | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 304 | // This presumably is happening during video quit, so we don't send PROXIMITY_OUT events here. | ||
| 305 | void SDL_RemoveAllPenDevices(void (*callback)(SDL_PenID instance_id, void *handle, void *userdata), void *userdata) | ||
| 306 | { | ||
| 307 | SDL_LockRWLockForWriting(pen_device_rwlock); | ||
| 308 | if (pen_device_count > 0) { | ||
| 309 | SDL_assert(pen_devices != NULL); | ||
| 310 | for (int i = 0; i < pen_device_count; i++) { | ||
| 311 | callback(pen_devices[i].instance_id, pen_devices[i].driverdata, userdata); | ||
| 312 | SDL_free(pen_devices[i].name); | ||
| 313 | } | ||
| 314 | } | ||
| 315 | SDL_free(pen_devices); | ||
| 316 | pen_devices = NULL; | ||
| 317 | SDL_UnlockRWLock(pen_device_rwlock); | ||
| 318 | } | ||
| 319 | |||
| 320 | void SDL_SendPenTouch(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, bool eraser, bool down) | ||
| 321 | { | ||
| 322 | bool send_event = false; | ||
| 323 | SDL_PenInputFlags input_state = 0; | ||
| 324 | float x = 0.0f; | ||
| 325 | float y = 0.0f; | ||
| 326 | |||
| 327 | // note that this locks for _reading_ because the lock protects the | ||
| 328 | // pen_devices array from being reallocated from under us, not the data in it; | ||
| 329 | // we assume only one thread (in the backend) is modifying an individual pen at | ||
| 330 | // a time, so it can update input state cleanly here. | ||
| 331 | SDL_LockRWLockForReading(pen_device_rwlock); | ||
| 332 | SDL_Pen *pen = FindPenByInstanceId(instance_id); | ||
| 333 | if (pen) { | ||
| 334 | input_state = pen->input_state; | ||
| 335 | x = pen->x; | ||
| 336 | y = pen->y; | ||
| 337 | |||
| 338 | if (down && ((input_state & SDL_PEN_INPUT_DOWN) == 0)) { | ||
| 339 | input_state |= SDL_PEN_INPUT_DOWN; | ||
| 340 | send_event = true; | ||
| 341 | } else if (!down && (input_state & SDL_PEN_INPUT_DOWN)) { | ||
| 342 | input_state &= ~SDL_PEN_INPUT_DOWN; | ||
| 343 | send_event = true; | ||
| 344 | } | ||
| 345 | |||
| 346 | if (eraser && ((input_state & SDL_PEN_INPUT_ERASER_TIP) == 0)) { | ||
| 347 | input_state |= SDL_PEN_INPUT_ERASER_TIP; | ||
| 348 | send_event = true; | ||
| 349 | } else if (!eraser && (input_state & SDL_PEN_INPUT_ERASER_TIP)) { | ||
| 350 | input_state &= ~SDL_PEN_INPUT_ERASER_TIP; | ||
| 351 | send_event = true; | ||
| 352 | } | ||
| 353 | |||
| 354 | pen->input_state = input_state; // we could do an SDL_SetAtomicInt here if we run into trouble... | ||
| 355 | } | ||
| 356 | SDL_UnlockRWLock(pen_device_rwlock); | ||
| 357 | |||
| 358 | if (send_event) { | ||
| 359 | const SDL_EventType evtype = down ? SDL_EVENT_PEN_DOWN : SDL_EVENT_PEN_UP; | ||
| 360 | if (SDL_EventEnabled(evtype)) { | ||
| 361 | SDL_Event event; | ||
| 362 | SDL_zero(event); | ||
| 363 | event.ptouch.type = evtype; | ||
| 364 | event.ptouch.timestamp = timestamp; | ||
| 365 | event.ptouch.windowID = window ? window->id : 0; | ||
| 366 | event.ptouch.which = instance_id; | ||
| 367 | event.ptouch.pen_state = input_state; | ||
| 368 | event.ptouch.x = x; | ||
| 369 | event.ptouch.y = y; | ||
| 370 | event.ptouch.eraser = eraser; | ||
| 371 | event.ptouch.down = down; | ||
| 372 | SDL_PushEvent(&event); | ||
| 373 | } | ||
| 374 | |||
| 375 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 376 | if (mouse && window) { | ||
| 377 | if (mouse->pen_mouse_events) { | ||
| 378 | if (down) { | ||
| 379 | if (!pen_touching) { | ||
| 380 | SDL_SendMouseMotion(timestamp, window, SDL_PEN_MOUSEID, false, x, y); | ||
| 381 | SDL_SendMouseButton(timestamp, window, SDL_PEN_MOUSEID, SDL_BUTTON_LEFT, true); | ||
| 382 | } | ||
| 383 | } else { | ||
| 384 | if (pen_touching == instance_id) { | ||
| 385 | SDL_SendMouseButton(timestamp, window, SDL_PEN_MOUSEID, SDL_BUTTON_LEFT, false); | ||
| 386 | } | ||
| 387 | } | ||
| 388 | } | ||
| 389 | |||
| 390 | if (mouse->pen_touch_events) { | ||
| 391 | const SDL_EventType touchtype = down ? SDL_EVENT_FINGER_DOWN : SDL_EVENT_FINGER_UP; | ||
| 392 | const float normalized_x = x / (float)window->w; | ||
| 393 | const float normalized_y = y / (float)window->h; | ||
| 394 | if (!pen_touching || (pen_touching == instance_id)) { | ||
| 395 | SDL_SendTouch(timestamp, SDL_PEN_TOUCHID, SDL_BUTTON_LEFT, window, touchtype, normalized_x, normalized_y, pen->axes[SDL_PEN_AXIS_PRESSURE]); | ||
| 396 | } | ||
| 397 | } | ||
| 398 | } | ||
| 399 | |||
| 400 | if (down) { | ||
| 401 | if (!pen_touching) { | ||
| 402 | pen_touching = instance_id; | ||
| 403 | } | ||
| 404 | } else { | ||
| 405 | if (pen_touching == instance_id) { | ||
| 406 | pen_touching = 0; | ||
| 407 | } | ||
| 408 | } | ||
| 409 | } | ||
| 410 | } | ||
| 411 | |||
| 412 | void SDL_SendPenAxis(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, SDL_PenAxis axis, float value) | ||
| 413 | { | ||
| 414 | SDL_assert((axis >= 0) && (axis < SDL_PEN_AXIS_COUNT)); // fix the backend if this triggers. | ||
| 415 | |||
| 416 | bool send_event = false; | ||
| 417 | SDL_PenInputFlags input_state = 0; | ||
| 418 | float x = 0.0f; | ||
| 419 | float y = 0.0f; | ||
| 420 | |||
| 421 | // note that this locks for _reading_ because the lock protects the | ||
| 422 | // pen_devices array from being reallocated from under us, not the data in it; | ||
| 423 | // we assume only one thread (in the backend) is modifying an individual pen at | ||
| 424 | // a time, so it can update input state cleanly here. | ||
| 425 | SDL_LockRWLockForReading(pen_device_rwlock); | ||
| 426 | SDL_Pen *pen = FindPenByInstanceId(instance_id); | ||
| 427 | if (pen) { | ||
| 428 | if (pen->axes[axis] != value) { | ||
| 429 | pen->axes[axis] = value; // we could do an SDL_SetAtomicInt here if we run into trouble... | ||
| 430 | input_state = pen->input_state; | ||
| 431 | x = pen->x; | ||
| 432 | y = pen->y; | ||
| 433 | send_event = true; | ||
| 434 | } | ||
| 435 | } | ||
| 436 | SDL_UnlockRWLock(pen_device_rwlock); | ||
| 437 | |||
| 438 | if (send_event && SDL_EventEnabled(SDL_EVENT_PEN_AXIS)) { | ||
| 439 | SDL_Event event; | ||
| 440 | SDL_zero(event); | ||
| 441 | event.paxis.type = SDL_EVENT_PEN_AXIS; | ||
| 442 | event.paxis.timestamp = timestamp; | ||
| 443 | event.paxis.windowID = window ? window->id : 0; | ||
| 444 | event.paxis.which = instance_id; | ||
| 445 | event.paxis.pen_state = input_state; | ||
| 446 | event.paxis.x = x; | ||
| 447 | event.paxis.y = y; | ||
| 448 | event.paxis.axis = axis; | ||
| 449 | event.paxis.value = value; | ||
| 450 | SDL_PushEvent(&event); | ||
| 451 | |||
| 452 | if (window && (axis == SDL_PEN_AXIS_PRESSURE) && (pen_touching == instance_id)) { | ||
| 453 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 454 | if (mouse && mouse->pen_touch_events) { | ||
| 455 | const float normalized_x = x / (float)window->w; | ||
| 456 | const float normalized_y = y / (float)window->h; | ||
| 457 | SDL_SendTouchMotion(timestamp, SDL_PEN_TOUCHID, SDL_BUTTON_LEFT, window, normalized_x, normalized_y, value); | ||
| 458 | } | ||
| 459 | } | ||
| 460 | } | ||
| 461 | } | ||
| 462 | |||
| 463 | void SDL_SendPenMotion(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, float x, float y) | ||
| 464 | { | ||
| 465 | bool send_event = false; | ||
| 466 | SDL_PenInputFlags input_state = 0; | ||
| 467 | |||
| 468 | // note that this locks for _reading_ because the lock protects the | ||
| 469 | // pen_devices array from being reallocated from under us, not the data in it; | ||
| 470 | // we assume only one thread (in the backend) is modifying an individual pen at | ||
| 471 | // a time, so it can update input state cleanly here. | ||
| 472 | SDL_LockRWLockForReading(pen_device_rwlock); | ||
| 473 | SDL_Pen *pen = FindPenByInstanceId(instance_id); | ||
| 474 | if (pen) { | ||
| 475 | if ((pen->x != x) || (pen->y != y)) { | ||
| 476 | pen->x = x; // we could do an SDL_SetAtomicInt here if we run into trouble... | ||
| 477 | pen->y = y; // we could do an SDL_SetAtomicInt here if we run into trouble... | ||
| 478 | input_state = pen->input_state; | ||
| 479 | send_event = true; | ||
| 480 | } | ||
| 481 | } | ||
| 482 | SDL_UnlockRWLock(pen_device_rwlock); | ||
| 483 | |||
| 484 | if (send_event && SDL_EventEnabled(SDL_EVENT_PEN_MOTION)) { | ||
| 485 | SDL_Event event; | ||
| 486 | SDL_zero(event); | ||
| 487 | event.pmotion.type = SDL_EVENT_PEN_MOTION; | ||
| 488 | event.pmotion.timestamp = timestamp; | ||
| 489 | event.pmotion.windowID = window ? window->id : 0; | ||
| 490 | event.pmotion.which = instance_id; | ||
| 491 | event.pmotion.pen_state = input_state; | ||
| 492 | event.pmotion.x = x; | ||
| 493 | event.pmotion.y = y; | ||
| 494 | SDL_PushEvent(&event); | ||
| 495 | |||
| 496 | if (window) { | ||
| 497 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 498 | if (mouse) { | ||
| 499 | if (pen_touching == instance_id) { | ||
| 500 | if (mouse->pen_mouse_events) { | ||
| 501 | SDL_SendMouseMotion(timestamp, window, SDL_PEN_MOUSEID, false, x, y); | ||
| 502 | } | ||
| 503 | |||
| 504 | if (mouse->pen_touch_events) { | ||
| 505 | const float normalized_x = x / (float)window->w; | ||
| 506 | const float normalized_y = y / (float)window->h; | ||
| 507 | SDL_SendTouchMotion(timestamp, SDL_PEN_TOUCHID, SDL_BUTTON_LEFT, window, normalized_x, normalized_y, pen->axes[SDL_PEN_AXIS_PRESSURE]); | ||
| 508 | } | ||
| 509 | } else if (pen_touching == 0) { // send mouse motion (without a pressed button) for pens that aren't touching. | ||
| 510 | // this might cause a little chaos if you have multiple pens hovering at the same time, but this seems unlikely in the real world, and also something you did to yourself. :) | ||
| 511 | SDL_SendMouseMotion(timestamp, window, SDL_PEN_MOUSEID, false, x, y); | ||
| 512 | } | ||
| 513 | } | ||
| 514 | } | ||
| 515 | } | ||
| 516 | } | ||
| 517 | |||
| 518 | void SDL_SendPenButton(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, Uint8 button, bool down) | ||
| 519 | { | ||
| 520 | bool send_event = false; | ||
| 521 | SDL_PenInputFlags input_state = 0; | ||
| 522 | float x = 0.0f; | ||
| 523 | float y = 0.0f; | ||
| 524 | |||
| 525 | if ((button < 1) || (button > 5)) { | ||
| 526 | return; // clamp for now. | ||
| 527 | } | ||
| 528 | |||
| 529 | // note that this locks for _reading_ because the lock protects the | ||
| 530 | // pen_devices array from being reallocated from under us, not the data in it; | ||
| 531 | // we assume only one thread (in the backend) is modifying an individual pen at | ||
| 532 | // a time, so it can update input state cleanly here. | ||
| 533 | SDL_LockRWLockForReading(pen_device_rwlock); | ||
| 534 | SDL_Pen *pen = FindPenByInstanceId(instance_id); | ||
| 535 | if (pen) { | ||
| 536 | input_state = pen->input_state; | ||
| 537 | const Uint32 flag = (Uint32) (1u << button); | ||
| 538 | const bool current = ((input_state & flag) != 0); | ||
| 539 | x = pen->x; | ||
| 540 | y = pen->y; | ||
| 541 | if (down && !current) { | ||
| 542 | input_state |= flag; | ||
| 543 | send_event = true; | ||
| 544 | } else if (!down && current) { | ||
| 545 | input_state &= ~flag; | ||
| 546 | send_event = true; | ||
| 547 | } | ||
| 548 | pen->input_state = input_state; // we could do an SDL_SetAtomicInt here if we run into trouble... | ||
| 549 | } | ||
| 550 | SDL_UnlockRWLock(pen_device_rwlock); | ||
| 551 | |||
| 552 | if (send_event) { | ||
| 553 | const SDL_EventType evtype = down ? SDL_EVENT_PEN_BUTTON_DOWN : SDL_EVENT_PEN_BUTTON_UP; | ||
| 554 | if (SDL_EventEnabled(evtype)) { | ||
| 555 | SDL_Event event; | ||
| 556 | SDL_zero(event); | ||
| 557 | event.pbutton.type = evtype; | ||
| 558 | event.pbutton.timestamp = timestamp; | ||
| 559 | event.pbutton.windowID = window ? window->id : 0; | ||
| 560 | event.pbutton.which = instance_id; | ||
| 561 | event.pbutton.pen_state = input_state; | ||
| 562 | event.pbutton.x = x; | ||
| 563 | event.pbutton.y = y; | ||
| 564 | event.pbutton.button = button; | ||
| 565 | event.pbutton.down = down; | ||
| 566 | SDL_PushEvent(&event); | ||
| 567 | |||
| 568 | if (window && (pen_touching == instance_id)) { | ||
| 569 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 570 | if (mouse && mouse->pen_mouse_events) { | ||
| 571 | SDL_SendMouseButton(timestamp, window, SDL_PEN_MOUSEID, button + 1, down); | ||
| 572 | } | ||
| 573 | } | ||
| 574 | } | ||
| 575 | } | ||
| 576 | } | ||
| 577 | |||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_pen_c.h b/contrib/SDL-3.2.8/src/events/SDL_pen_c.h new file mode 100644 index 0000000..1eff47f --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_pen_c.h | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include "../SDL_internal.h" | ||
| 23 | |||
| 24 | #ifndef SDL_pen_c_h_ | ||
| 25 | #define SDL_pen_c_h_ | ||
| 26 | |||
| 27 | #include "SDL_mouse_c.h" | ||
| 28 | |||
| 29 | typedef Uint32 SDL_PenCapabilityFlags; | ||
| 30 | #define SDL_PEN_CAPABILITY_PRESSURE (1u << 0) /**< Provides pressure information on SDL_PEN_AXIS_PRESSURE. */ | ||
| 31 | #define SDL_PEN_CAPABILITY_XTILT (1u << 1) /**< Provides horizontal tilt information on SDL_PEN_AXIS_XTILT. */ | ||
| 32 | #define SDL_PEN_CAPABILITY_YTILT (1u << 2) /**< Provides vertical tilt information on SDL_PEN_AXIS_YTILT. */ | ||
| 33 | #define SDL_PEN_CAPABILITY_DISTANCE (1u << 3) /**< Provides distance to drawing tablet on SDL_PEN_AXIS_DISTANCE. */ | ||
| 34 | #define SDL_PEN_CAPABILITY_ROTATION (1u << 4) /**< Provides barrel rotation info on SDL_PEN_AXIS_ROTATION. */ | ||
| 35 | #define SDL_PEN_CAPABILITY_SLIDER (1u << 5) /**< Provides slider/finger wheel/etc on SDL_PEN_AXIS_SLIDER. */ | ||
| 36 | #define SDL_PEN_CAPABILITY_TANGENTIAL_PRESSURE (1u << 6) /**< Provides barrel pressure on SDL_PEN_AXIS_TANGENTIAL_PRESSURE. */ | ||
| 37 | #define SDL_PEN_CAPABILITY_ERASER (1u << 7) /**< Pen also has an eraser tip. */ | ||
| 38 | |||
| 39 | typedef enum SDL_PenSubtype | ||
| 40 | { | ||
| 41 | SDL_PEN_TYPE_UNKNOWN, /**< Unknown pen device */ | ||
| 42 | SDL_PEN_TYPE_ERASER, /**< Eraser */ | ||
| 43 | SDL_PEN_TYPE_PEN, /**< Generic pen; this is the default. */ | ||
| 44 | SDL_PEN_TYPE_PENCIL, /**< Pencil */ | ||
| 45 | SDL_PEN_TYPE_BRUSH, /**< Brush-like device */ | ||
| 46 | SDL_PEN_TYPE_AIRBRUSH /**< Airbrush device that "sprays" ink */ | ||
| 47 | } SDL_PenSubtype; | ||
| 48 | |||
| 49 | typedef struct SDL_PenInfo | ||
| 50 | { | ||
| 51 | SDL_PenCapabilityFlags capabilities; /**< bitflags of device capabilities */ | ||
| 52 | float max_tilt; /**< Physical maximum tilt angle, for XTILT and YTILT, or -1.0f if unknown. Pens cannot typically tilt all the way to 90 degrees, so this value is usually less than 90.0. */ | ||
| 53 | Uint32 wacom_id; /**< For Wacom devices: wacom tool type ID, otherwise 0 (useful e.g. with libwacom) */ | ||
| 54 | int num_buttons; /**< Number of pen buttons (not counting the pen tip), or -1 if unknown. */ | ||
| 55 | SDL_PenSubtype subtype; /**< type of pen device */ | ||
| 56 | } SDL_PenInfo; | ||
| 57 | |||
| 58 | // Backend calls this when a new pen device is hotplugged, plus once for each pen already connected at startup. | ||
| 59 | // Note that name and info are copied but currently unused; this is placeholder for a potentially more robust API later. | ||
| 60 | // Both are allowed to be NULL. | ||
| 61 | extern SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, const SDL_PenInfo *info, void *handle); | ||
| 62 | |||
| 63 | // Backend calls this when an existing pen device is disconnected during runtime. They must free their own stuff separately. | ||
| 64 | extern void SDL_RemovePenDevice(Uint64 timestamp, SDL_PenID instance_id); | ||
| 65 | |||
| 66 | // Backend can call this to remove all pens, probably during shutdown, with a callback to let them free their own handle. | ||
| 67 | extern void SDL_RemoveAllPenDevices(void (*callback)(SDL_PenID instance_id, void *handle, void *userdata), void *userdata); | ||
| 68 | |||
| 69 | // Backend calls this when a pen's button changes, to generate events and update state. | ||
| 70 | extern void SDL_SendPenTouch(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, bool eraser, bool down); | ||
| 71 | |||
| 72 | // Backend calls this when a pen moves on the tablet, to generate events and update state. | ||
| 73 | extern void SDL_SendPenMotion(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, float x, float y); | ||
| 74 | |||
| 75 | // Backend calls this when a pen's axis changes, to generate events and update state. | ||
| 76 | extern void SDL_SendPenAxis(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, SDL_PenAxis axis, float value); | ||
| 77 | |||
| 78 | // Backend calls this when a pen's button changes, to generate events and update state. | ||
| 79 | extern void SDL_SendPenButton(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, Uint8 button, bool down); | ||
| 80 | |||
| 81 | // Backend can optionally use this to find the SDL_PenID for the `handle` that was passed to SDL_AddPenDevice. | ||
| 82 | extern SDL_PenID SDL_FindPenByHandle(void *handle); | ||
| 83 | |||
| 84 | // Backend can optionally use this to find a SDL_PenID, selected by a callback examining all devices. Zero if not found. | ||
| 85 | extern SDL_PenID SDL_FindPenByCallback(bool (*callback)(void *handle, void *userdata), void *userdata); | ||
| 86 | |||
| 87 | // Backend can use this to query current pen status. | ||
| 88 | SDL_PenInputFlags SDL_GetPenStatus(SDL_PenID instance_id, float *axes, int num_axes); | ||
| 89 | |||
| 90 | // Backend can use this to map an axis to a capability bit. | ||
| 91 | SDL_PenCapabilityFlags SDL_GetPenCapabilityFromAxis(SDL_PenAxis axis); | ||
| 92 | |||
| 93 | // Higher-level SDL video subsystem code calls this when starting up. Backends shouldn't. | ||
| 94 | extern bool SDL_InitPen(void); | ||
| 95 | |||
| 96 | // Higher-level SDL video subsystem code calls this when shutting down. Backends shouldn't. | ||
| 97 | extern void SDL_QuitPen(void); | ||
| 98 | |||
| 99 | #endif // SDL_pen_c_h_ | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_quit.c b/contrib/SDL-3.2.8/src/events/SDL_quit.c new file mode 100644 index 0000000..5456203 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_quit.c | |||
| @@ -0,0 +1,194 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | // General quit handling code for SDL | ||
| 24 | |||
| 25 | #ifdef HAVE_SIGNAL_H | ||
| 26 | #include <signal.h> | ||
| 27 | #endif | ||
| 28 | |||
| 29 | #include "SDL_events_c.h" | ||
| 30 | |||
| 31 | #if defined(HAVE_SIGNAL_H) || defined(HAVE_SIGACTION) | ||
| 32 | #define HAVE_SIGNAL_SUPPORT 1 | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #ifdef HAVE_SIGNAL_SUPPORT | ||
| 36 | static bool disable_signals = false; | ||
| 37 | static bool send_quit_pending = false; | ||
| 38 | |||
| 39 | #ifdef SDL_BACKGROUNDING_SIGNAL | ||
| 40 | static bool send_backgrounding_pending = false; | ||
| 41 | #endif | ||
| 42 | |||
| 43 | #ifdef SDL_FOREGROUNDING_SIGNAL | ||
| 44 | static bool send_foregrounding_pending = false; | ||
| 45 | #endif | ||
| 46 | |||
| 47 | static void SDL_HandleSIG(int sig) | ||
| 48 | { | ||
| 49 | // Reset the signal handler | ||
| 50 | (void)signal(sig, SDL_HandleSIG); | ||
| 51 | |||
| 52 | // Send a quit event next time the event loop pumps. | ||
| 53 | // We can't send it in signal handler; SDL_malloc() might be interrupted! | ||
| 54 | if ((sig == SIGINT) || (sig == SIGTERM)) { | ||
| 55 | send_quit_pending = true; | ||
| 56 | } | ||
| 57 | |||
| 58 | #ifdef SDL_BACKGROUNDING_SIGNAL | ||
| 59 | else if (sig == SDL_BACKGROUNDING_SIGNAL) { | ||
| 60 | send_backgrounding_pending = true; | ||
| 61 | } | ||
| 62 | #endif | ||
| 63 | |||
| 64 | #ifdef SDL_FOREGROUNDING_SIGNAL | ||
| 65 | else if (sig == SDL_FOREGROUNDING_SIGNAL) { | ||
| 66 | send_foregrounding_pending = true; | ||
| 67 | } | ||
| 68 | #endif | ||
| 69 | } | ||
| 70 | |||
| 71 | static void SDL_EventSignal_Init(const int sig) | ||
| 72 | { | ||
| 73 | #ifdef HAVE_SIGACTION | ||
| 74 | struct sigaction action; | ||
| 75 | |||
| 76 | sigaction(sig, NULL, &action); | ||
| 77 | #ifdef HAVE_SA_SIGACTION | ||
| 78 | if (action.sa_handler == SIG_DFL && (void (*)(int))action.sa_sigaction == SIG_DFL) { | ||
| 79 | #else | ||
| 80 | if (action.sa_handler == SIG_DFL) { | ||
| 81 | #endif | ||
| 82 | action.sa_handler = SDL_HandleSIG; | ||
| 83 | sigaction(sig, &action, NULL); | ||
| 84 | } | ||
| 85 | #elif defined(HAVE_SIGNAL_H) | ||
| 86 | void (*ohandler)(int) = signal(sig, SDL_HandleSIG); | ||
| 87 | if (ohandler != SIG_DFL) { | ||
| 88 | signal(sig, ohandler); | ||
| 89 | } | ||
| 90 | #endif | ||
| 91 | } | ||
| 92 | |||
| 93 | static void SDL_EventSignal_Quit(const int sig) | ||
| 94 | { | ||
| 95 | #ifdef HAVE_SIGACTION | ||
| 96 | struct sigaction action; | ||
| 97 | sigaction(sig, NULL, &action); | ||
| 98 | if (action.sa_handler == SDL_HandleSIG) { | ||
| 99 | action.sa_handler = SIG_DFL; | ||
| 100 | sigaction(sig, &action, NULL); | ||
| 101 | } | ||
| 102 | #elif defined(HAVE_SIGNAL_H) | ||
| 103 | void (*ohandler)(int) = signal(sig, SIG_DFL); | ||
| 104 | if (ohandler != SDL_HandleSIG) { | ||
| 105 | signal(sig, ohandler); | ||
| 106 | } | ||
| 107 | #endif // HAVE_SIGNAL_H | ||
| 108 | } | ||
| 109 | |||
| 110 | // Public functions | ||
| 111 | static bool SDL_QuitInit_Internal(void) | ||
| 112 | { | ||
| 113 | // Both SIGINT and SIGTERM are translated into quit interrupts | ||
| 114 | // and SDL can be built to simulate iOS/Android semantics with arbitrary signals. | ||
| 115 | SDL_EventSignal_Init(SIGINT); | ||
| 116 | SDL_EventSignal_Init(SIGTERM); | ||
| 117 | |||
| 118 | #ifdef SDL_BACKGROUNDING_SIGNAL | ||
| 119 | SDL_EventSignal_Init(SDL_BACKGROUNDING_SIGNAL); | ||
| 120 | #endif | ||
| 121 | |||
| 122 | #ifdef SDL_FOREGROUNDING_SIGNAL | ||
| 123 | SDL_EventSignal_Init(SDL_FOREGROUNDING_SIGNAL); | ||
| 124 | #endif | ||
| 125 | |||
| 126 | // That's it! | ||
| 127 | return true; | ||
| 128 | } | ||
| 129 | |||
| 130 | static void SDL_QuitQuit_Internal(void) | ||
| 131 | { | ||
| 132 | SDL_EventSignal_Quit(SIGINT); | ||
| 133 | SDL_EventSignal_Quit(SIGTERM); | ||
| 134 | |||
| 135 | #ifdef SDL_BACKGROUNDING_SIGNAL | ||
| 136 | SDL_EventSignal_Quit(SDL_BACKGROUNDING_SIGNAL); | ||
| 137 | #endif | ||
| 138 | |||
| 139 | #ifdef SDL_FOREGROUNDING_SIGNAL | ||
| 140 | SDL_EventSignal_Quit(SDL_FOREGROUNDING_SIGNAL); | ||
| 141 | #endif | ||
| 142 | } | ||
| 143 | #endif | ||
| 144 | |||
| 145 | bool SDL_InitQuit(void) | ||
| 146 | { | ||
| 147 | #ifdef HAVE_SIGNAL_SUPPORT | ||
| 148 | if (!SDL_GetHintBoolean(SDL_HINT_NO_SIGNAL_HANDLERS, false)) { | ||
| 149 | return SDL_QuitInit_Internal(); | ||
| 150 | } | ||
| 151 | #endif | ||
| 152 | return true; | ||
| 153 | } | ||
| 154 | |||
| 155 | void SDL_QuitQuit(void) | ||
| 156 | { | ||
| 157 | #ifdef HAVE_SIGNAL_SUPPORT | ||
| 158 | if (!disable_signals) { | ||
| 159 | SDL_QuitQuit_Internal(); | ||
| 160 | } | ||
| 161 | #endif | ||
| 162 | } | ||
| 163 | |||
| 164 | void SDL_SendPendingSignalEvents(void) | ||
| 165 | { | ||
| 166 | #ifdef HAVE_SIGNAL_SUPPORT | ||
| 167 | if (send_quit_pending) { | ||
| 168 | SDL_SendQuit(); | ||
| 169 | SDL_assert(!send_quit_pending); | ||
| 170 | } | ||
| 171 | |||
| 172 | #ifdef SDL_BACKGROUNDING_SIGNAL | ||
| 173 | if (send_backgrounding_pending) { | ||
| 174 | send_backgrounding_pending = false; | ||
| 175 | SDL_OnApplicationWillEnterBackground(); | ||
| 176 | } | ||
| 177 | #endif | ||
| 178 | |||
| 179 | #ifdef SDL_FOREGROUNDING_SIGNAL | ||
| 180 | if (send_foregrounding_pending) { | ||
| 181 | send_foregrounding_pending = false; | ||
| 182 | SDL_OnApplicationDidEnterForeground(); | ||
| 183 | } | ||
| 184 | #endif | ||
| 185 | #endif | ||
| 186 | } | ||
| 187 | |||
| 188 | void SDL_SendQuit(void) | ||
| 189 | { | ||
| 190 | #ifdef HAVE_SIGNAL_SUPPORT | ||
| 191 | send_quit_pending = false; | ||
| 192 | #endif | ||
| 193 | SDL_SendAppEvent(SDL_EVENT_QUIT); | ||
| 194 | } | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_scancode_tables.c b/contrib/SDL-3.2.8/src/events/SDL_scancode_tables.c new file mode 100644 index 0000000..a780f13 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_scancode_tables.c | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #if defined(SDL_INPUT_LINUXEV) || defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_X11) | ||
| 24 | |||
| 25 | #include "SDL_scancode_tables_c.h" | ||
| 26 | |||
| 27 | #include "scancodes_darwin.h" | ||
| 28 | #include "scancodes_linux.h" | ||
| 29 | #include "scancodes_xfree86.h" | ||
| 30 | |||
| 31 | static const struct | ||
| 32 | { | ||
| 33 | SDL_ScancodeTable table; | ||
| 34 | SDL_Scancode const *scancodes; | ||
| 35 | int num_entries; | ||
| 36 | } SDL_scancode_tables[] = { | ||
| 37 | { SDL_SCANCODE_TABLE_DARWIN, darwin_scancode_table, SDL_arraysize(darwin_scancode_table) }, | ||
| 38 | { SDL_SCANCODE_TABLE_LINUX, linux_scancode_table, SDL_arraysize(linux_scancode_table) }, | ||
| 39 | { SDL_SCANCODE_TABLE_XFREE86_1, xfree86_scancode_table, SDL_arraysize(xfree86_scancode_table) }, | ||
| 40 | { SDL_SCANCODE_TABLE_XFREE86_2, xfree86_scancode_table2, SDL_arraysize(xfree86_scancode_table2) }, | ||
| 41 | { SDL_SCANCODE_TABLE_XVNC, xvnc_scancode_table, SDL_arraysize(xvnc_scancode_table) }, | ||
| 42 | }; | ||
| 43 | |||
| 44 | const SDL_Scancode *SDL_GetScancodeTable(SDL_ScancodeTable table, int *num_entries) | ||
| 45 | { | ||
| 46 | int i; | ||
| 47 | |||
| 48 | for (i = 0; i < SDL_arraysize(SDL_scancode_tables); ++i) { | ||
| 49 | if (table == SDL_scancode_tables[i].table) { | ||
| 50 | *num_entries = SDL_scancode_tables[i].num_entries; | ||
| 51 | return SDL_scancode_tables[i].scancodes; | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | *num_entries = 0; | ||
| 56 | return NULL; | ||
| 57 | } | ||
| 58 | |||
| 59 | SDL_Scancode SDL_GetScancodeFromTable(SDL_ScancodeTable table, int keycode) | ||
| 60 | { | ||
| 61 | SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; | ||
| 62 | int num_entries; | ||
| 63 | const SDL_Scancode *scancodes = SDL_GetScancodeTable(table, &num_entries); | ||
| 64 | |||
| 65 | if (keycode >= 0 && keycode < num_entries) { | ||
| 66 | scancode = scancodes[keycode]; | ||
| 67 | } | ||
| 68 | return scancode; | ||
| 69 | } | ||
| 70 | |||
| 71 | #endif // SDL_INPUT_LINUXEV || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_X11 | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_scancode_tables_c.h b/contrib/SDL-3.2.8/src/events/SDL_scancode_tables_c.h new file mode 100644 index 0000000..c8ad5fc --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_scancode_tables_c.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | typedef enum | ||
| 24 | { | ||
| 25 | SDL_SCANCODE_TABLE_DARWIN, | ||
| 26 | SDL_SCANCODE_TABLE_LINUX, | ||
| 27 | SDL_SCANCODE_TABLE_XFREE86_1, | ||
| 28 | SDL_SCANCODE_TABLE_XFREE86_2, | ||
| 29 | SDL_SCANCODE_TABLE_XVNC, | ||
| 30 | } SDL_ScancodeTable; | ||
| 31 | |||
| 32 | extern const SDL_Scancode *SDL_GetScancodeTable(SDL_ScancodeTable table, int *num_entries); | ||
| 33 | extern SDL_Scancode SDL_GetScancodeFromTable(SDL_ScancodeTable table, int keycode); | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_touch.c b/contrib/SDL-3.2.8/src/events/SDL_touch.c new file mode 100644 index 0000000..ec4acb1 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_touch.c | |||
| @@ -0,0 +1,500 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | // General touch handling code for SDL | ||
| 24 | |||
| 25 | #include "SDL_events_c.h" | ||
| 26 | #include "../video/SDL_sysvideo.h" | ||
| 27 | |||
| 28 | static int SDL_num_touch = 0; | ||
| 29 | static SDL_Touch **SDL_touchDevices = NULL; | ||
| 30 | |||
| 31 | // for mapping touch events to mice | ||
| 32 | static bool finger_touching = false; | ||
| 33 | static SDL_FingerID track_fingerid; | ||
| 34 | static SDL_TouchID track_touchid; | ||
| 35 | |||
| 36 | // Public functions | ||
| 37 | bool SDL_InitTouch(void) | ||
| 38 | { | ||
| 39 | return true; | ||
| 40 | } | ||
| 41 | |||
| 42 | bool SDL_TouchDevicesAvailable(void) | ||
| 43 | { | ||
| 44 | return SDL_num_touch > 0; | ||
| 45 | } | ||
| 46 | |||
| 47 | SDL_TouchID *SDL_GetTouchDevices(int *count) | ||
| 48 | { | ||
| 49 | if (count) { | ||
| 50 | *count = 0; | ||
| 51 | } | ||
| 52 | |||
| 53 | const int total = SDL_num_touch; | ||
| 54 | SDL_TouchID *result = (SDL_TouchID *) SDL_malloc(sizeof (SDL_TouchID) * (total + 1)); | ||
| 55 | if (result) { | ||
| 56 | for (int i = 0; i < total; i++) { | ||
| 57 | result[i] = SDL_touchDevices[i]->id; | ||
| 58 | } | ||
| 59 | result[total] = 0; | ||
| 60 | if (count) { | ||
| 61 | *count = SDL_num_touch; | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | return result; | ||
| 66 | } | ||
| 67 | |||
| 68 | static int SDL_GetTouchIndex(SDL_TouchID id) | ||
| 69 | { | ||
| 70 | int index; | ||
| 71 | SDL_Touch *touch; | ||
| 72 | |||
| 73 | for (index = 0; index < SDL_num_touch; ++index) { | ||
| 74 | touch = SDL_touchDevices[index]; | ||
| 75 | if (touch->id == id) { | ||
| 76 | return index; | ||
| 77 | } | ||
| 78 | } | ||
| 79 | return -1; | ||
| 80 | } | ||
| 81 | |||
| 82 | SDL_Touch *SDL_GetTouch(SDL_TouchID id) | ||
| 83 | { | ||
| 84 | int index = SDL_GetTouchIndex(id); | ||
| 85 | if (index < 0 || index >= SDL_num_touch) { | ||
| 86 | if (SDL_GetVideoDevice()->ResetTouch != NULL) { | ||
| 87 | SDL_SetError("Unknown touch id %d, resetting", (int)id); | ||
| 88 | (SDL_GetVideoDevice()->ResetTouch)(SDL_GetVideoDevice()); | ||
| 89 | } else { | ||
| 90 | SDL_SetError("Unknown touch device id %d, cannot reset", (int)id); | ||
| 91 | } | ||
| 92 | return NULL; | ||
| 93 | } | ||
| 94 | return SDL_touchDevices[index]; | ||
| 95 | } | ||
| 96 | |||
| 97 | const char *SDL_GetTouchDeviceName(SDL_TouchID id) | ||
| 98 | { | ||
| 99 | SDL_Touch *touch = SDL_GetTouch(id); | ||
| 100 | if (!touch) { | ||
| 101 | return NULL; | ||
| 102 | } | ||
| 103 | return SDL_GetPersistentString(touch->name); | ||
| 104 | } | ||
| 105 | |||
| 106 | SDL_TouchDeviceType SDL_GetTouchDeviceType(SDL_TouchID id) | ||
| 107 | { | ||
| 108 | SDL_Touch *touch = SDL_GetTouch(id); | ||
| 109 | return touch ? touch->type : SDL_TOUCH_DEVICE_INVALID; | ||
| 110 | } | ||
| 111 | |||
| 112 | static int SDL_GetFingerIndex(const SDL_Touch *touch, SDL_FingerID fingerid) | ||
| 113 | { | ||
| 114 | int index; | ||
| 115 | for (index = 0; index < touch->num_fingers; ++index) { | ||
| 116 | if (touch->fingers[index]->id == fingerid) { | ||
| 117 | return index; | ||
| 118 | } | ||
| 119 | } | ||
| 120 | return -1; | ||
| 121 | } | ||
| 122 | |||
| 123 | static SDL_Finger *SDL_GetFinger(const SDL_Touch *touch, SDL_FingerID id) | ||
| 124 | { | ||
| 125 | int index = SDL_GetFingerIndex(touch, id); | ||
| 126 | if (index < 0 || index >= touch->num_fingers) { | ||
| 127 | return NULL; | ||
| 128 | } | ||
| 129 | return touch->fingers[index]; | ||
| 130 | } | ||
| 131 | |||
| 132 | SDL_Finger **SDL_GetTouchFingers(SDL_TouchID touchID, int *count) | ||
| 133 | { | ||
| 134 | SDL_Finger **fingers; | ||
| 135 | SDL_Finger *finger_data; | ||
| 136 | |||
| 137 | if (count) { | ||
| 138 | *count = 0; | ||
| 139 | } | ||
| 140 | |||
| 141 | SDL_Touch *touch = SDL_GetTouch(touchID); | ||
| 142 | if (!touch) { | ||
| 143 | return NULL; | ||
| 144 | } | ||
| 145 | |||
| 146 | // Create a snapshot of the current finger state | ||
| 147 | fingers = (SDL_Finger **)SDL_malloc((touch->num_fingers + 1) * sizeof(*fingers) + touch->num_fingers * sizeof(**fingers)); | ||
| 148 | if (!fingers) { | ||
| 149 | return NULL; | ||
| 150 | } | ||
| 151 | finger_data = (SDL_Finger *)(fingers + (touch->num_fingers + 1)); | ||
| 152 | |||
| 153 | for (int i = 0; i < touch->num_fingers; ++i) { | ||
| 154 | fingers[i] = &finger_data[i]; | ||
| 155 | SDL_copyp(fingers[i], touch->fingers[i]); | ||
| 156 | } | ||
| 157 | fingers[touch->num_fingers] = NULL; | ||
| 158 | |||
| 159 | if (count) { | ||
| 160 | *count = touch->num_fingers; | ||
| 161 | } | ||
| 162 | return fingers; | ||
| 163 | } | ||
| 164 | |||
| 165 | int SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name) | ||
| 166 | { | ||
| 167 | SDL_Touch **touchDevices; | ||
| 168 | int index; | ||
| 169 | |||
| 170 | SDL_assert(touchID != 0); | ||
| 171 | |||
| 172 | index = SDL_GetTouchIndex(touchID); | ||
| 173 | if (index >= 0) { | ||
| 174 | return index; | ||
| 175 | } | ||
| 176 | |||
| 177 | // Add the touch to the list of touch | ||
| 178 | touchDevices = (SDL_Touch **)SDL_realloc(SDL_touchDevices, | ||
| 179 | (SDL_num_touch + 1) * sizeof(*touchDevices)); | ||
| 180 | if (!touchDevices) { | ||
| 181 | return -1; | ||
| 182 | } | ||
| 183 | |||
| 184 | SDL_touchDevices = touchDevices; | ||
| 185 | index = SDL_num_touch; | ||
| 186 | |||
| 187 | SDL_touchDevices[index] = (SDL_Touch *)SDL_malloc(sizeof(*SDL_touchDevices[index])); | ||
| 188 | if (!SDL_touchDevices[index]) { | ||
| 189 | return -1; | ||
| 190 | } | ||
| 191 | |||
| 192 | // Added touch to list | ||
| 193 | ++SDL_num_touch; | ||
| 194 | |||
| 195 | // we're setting the touch properties | ||
| 196 | SDL_touchDevices[index]->id = touchID; | ||
| 197 | SDL_touchDevices[index]->type = type; | ||
| 198 | SDL_touchDevices[index]->num_fingers = 0; | ||
| 199 | SDL_touchDevices[index]->max_fingers = 0; | ||
| 200 | SDL_touchDevices[index]->fingers = NULL; | ||
| 201 | SDL_touchDevices[index]->name = SDL_strdup(name ? name : ""); | ||
| 202 | |||
| 203 | return index; | ||
| 204 | } | ||
| 205 | |||
| 206 | static bool SDL_AddFinger(SDL_Touch *touch, SDL_FingerID fingerid, float x, float y, float pressure) | ||
| 207 | { | ||
| 208 | SDL_Finger *finger; | ||
| 209 | |||
| 210 | SDL_assert(fingerid != 0); | ||
| 211 | |||
| 212 | if (touch->num_fingers == touch->max_fingers) { | ||
| 213 | SDL_Finger **new_fingers; | ||
| 214 | new_fingers = (SDL_Finger **)SDL_realloc(touch->fingers, (touch->max_fingers + 1) * sizeof(*touch->fingers)); | ||
| 215 | if (!new_fingers) { | ||
| 216 | return false; | ||
| 217 | } | ||
| 218 | touch->fingers = new_fingers; | ||
| 219 | touch->fingers[touch->max_fingers] = (SDL_Finger *)SDL_malloc(sizeof(*finger)); | ||
| 220 | if (!touch->fingers[touch->max_fingers]) { | ||
| 221 | return false; | ||
| 222 | } | ||
| 223 | touch->max_fingers++; | ||
| 224 | } | ||
| 225 | |||
| 226 | finger = touch->fingers[touch->num_fingers++]; | ||
| 227 | finger->id = fingerid; | ||
| 228 | finger->x = x; | ||
| 229 | finger->y = y; | ||
| 230 | finger->pressure = pressure; | ||
| 231 | return true; | ||
| 232 | } | ||
| 233 | |||
| 234 | static void SDL_DelFinger(SDL_Touch *touch, SDL_FingerID fingerid) | ||
| 235 | { | ||
| 236 | int index = SDL_GetFingerIndex(touch, fingerid); | ||
| 237 | if (index < 0) { | ||
| 238 | return; | ||
| 239 | } | ||
| 240 | |||
| 241 | --touch->num_fingers; | ||
| 242 | if (index < (touch->num_fingers)) { | ||
| 243 | // Move the deleted finger to just past the end of the active fingers array and shift the active fingers by one. | ||
| 244 | // This ensures that the descriptor for the now-deleted finger is located at `touch->fingers[touch->num_fingers]` | ||
| 245 | // and is ready for use in SDL_AddFinger. | ||
| 246 | SDL_Finger *deleted_finger = touch->fingers[index]; | ||
| 247 | SDL_memmove(&touch->fingers[index], &touch->fingers[index + 1], (touch->num_fingers - index) * sizeof(touch->fingers[index])); | ||
| 248 | touch->fingers[touch->num_fingers] = deleted_finger; | ||
| 249 | } | ||
| 250 | } | ||
| 251 | |||
| 252 | void SDL_SendTouch(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, SDL_EventType type, float x, float y, float pressure) | ||
| 253 | { | ||
| 254 | SDL_Finger *finger; | ||
| 255 | bool down = (type == SDL_EVENT_FINGER_DOWN); | ||
| 256 | |||
| 257 | SDL_Touch *touch = SDL_GetTouch(id); | ||
| 258 | if (!touch) { | ||
| 259 | return; | ||
| 260 | } | ||
| 261 | |||
| 262 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 263 | |||
| 264 | // SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events | ||
| 265 | // SDL_HINT_VITA_TOUCH_MOUSE_DEVICE: controlling which touchpad should generate synthetic mouse events, PSVita-only | ||
| 266 | { | ||
| 267 | // FIXME: maybe we should only restrict to a few SDL_TouchDeviceType | ||
| 268 | if ((id != SDL_MOUSE_TOUCHID) && (id != SDL_PEN_TOUCHID)) { | ||
| 269 | #ifdef SDL_PLATFORM_VITA | ||
| 270 | if (mouse->touch_mouse_events && ((mouse->vita_touch_mouse_device == id) || (mouse->vita_touch_mouse_device == 3))) { | ||
| 271 | #else | ||
| 272 | if (mouse->touch_mouse_events) { | ||
| 273 | #endif | ||
| 274 | if (window) { | ||
| 275 | if (down) { | ||
| 276 | if (finger_touching == false) { | ||
| 277 | float pos_x = (x * (float)window->w); | ||
| 278 | float pos_y = (y * (float)window->h); | ||
| 279 | if (pos_x < 0) { | ||
| 280 | pos_x = 0; | ||
| 281 | } | ||
| 282 | if (pos_x > (float)(window->w - 1)) { | ||
| 283 | pos_x = (float)(window->w - 1); | ||
| 284 | } | ||
| 285 | if (pos_y < 0.0f) { | ||
| 286 | pos_y = 0.0f; | ||
| 287 | } | ||
| 288 | if (pos_y > (float)(window->h - 1)) { | ||
| 289 | pos_y = (float)(window->h - 1); | ||
| 290 | } | ||
| 291 | SDL_SendMouseMotion(timestamp, window, SDL_TOUCH_MOUSEID, false, pos_x, pos_y); | ||
| 292 | SDL_SendMouseButton(timestamp, window, SDL_TOUCH_MOUSEID, SDL_BUTTON_LEFT, true); | ||
| 293 | } | ||
| 294 | } else { | ||
| 295 | if (finger_touching == true && track_touchid == id && track_fingerid == fingerid) { | ||
| 296 | SDL_SendMouseButton(timestamp, window, SDL_TOUCH_MOUSEID, SDL_BUTTON_LEFT, false); | ||
| 297 | } | ||
| 298 | } | ||
| 299 | } | ||
| 300 | if (down) { | ||
| 301 | if (finger_touching == false) { | ||
| 302 | finger_touching = true; | ||
| 303 | track_touchid = id; | ||
| 304 | track_fingerid = fingerid; | ||
| 305 | } | ||
| 306 | } else { | ||
| 307 | if (finger_touching == true && track_touchid == id && track_fingerid == fingerid) { | ||
| 308 | finger_touching = false; | ||
| 309 | } | ||
| 310 | } | ||
| 311 | } | ||
| 312 | } | ||
| 313 | } | ||
| 314 | |||
| 315 | // SDL_HINT_MOUSE_TOUCH_EVENTS: if not set, discard synthetic touch events coming from platform layer | ||
| 316 | if (!mouse->mouse_touch_events && (id == SDL_MOUSE_TOUCHID)) { | ||
| 317 | return; | ||
| 318 | } else if (!mouse->pen_touch_events && (id == SDL_PEN_TOUCHID)) { | ||
| 319 | return; | ||
| 320 | } | ||
| 321 | |||
| 322 | finger = SDL_GetFinger(touch, fingerid); | ||
| 323 | if (down) { | ||
| 324 | if (finger) { | ||
| 325 | /* This finger is already down. | ||
| 326 | Assume the finger-up for the previous touch was lost, and send it. */ | ||
| 327 | SDL_SendTouch(timestamp, id, fingerid, window, SDL_EVENT_FINGER_CANCELED, x, y, pressure); | ||
| 328 | } | ||
| 329 | |||
| 330 | if (!SDL_AddFinger(touch, fingerid, x, y, pressure)) { | ||
| 331 | return; | ||
| 332 | } | ||
| 333 | |||
| 334 | if (SDL_EventEnabled(type)) { | ||
| 335 | SDL_Event event; | ||
| 336 | event.type = type; | ||
| 337 | event.common.timestamp = timestamp; | ||
| 338 | event.tfinger.touchID = id; | ||
| 339 | event.tfinger.fingerID = fingerid; | ||
| 340 | event.tfinger.x = x; | ||
| 341 | event.tfinger.y = y; | ||
| 342 | event.tfinger.dx = 0; | ||
| 343 | event.tfinger.dy = 0; | ||
| 344 | event.tfinger.pressure = pressure; | ||
| 345 | event.tfinger.windowID = window ? SDL_GetWindowID(window) : 0; | ||
| 346 | SDL_PushEvent(&event); | ||
| 347 | } | ||
| 348 | } else { | ||
| 349 | if (!finger) { | ||
| 350 | // This finger is already up | ||
| 351 | return; | ||
| 352 | } | ||
| 353 | |||
| 354 | if (SDL_EventEnabled(type)) { | ||
| 355 | SDL_Event event; | ||
| 356 | event.type = type; | ||
| 357 | event.common.timestamp = timestamp; | ||
| 358 | event.tfinger.touchID = id; | ||
| 359 | event.tfinger.fingerID = fingerid; | ||
| 360 | // I don't trust the coordinates passed on fingerUp | ||
| 361 | event.tfinger.x = finger->x; | ||
| 362 | event.tfinger.y = finger->y; | ||
| 363 | event.tfinger.dx = 0; | ||
| 364 | event.tfinger.dy = 0; | ||
| 365 | event.tfinger.pressure = pressure; | ||
| 366 | event.tfinger.windowID = window ? SDL_GetWindowID(window) : 0; | ||
| 367 | SDL_PushEvent(&event); | ||
| 368 | } | ||
| 369 | |||
| 370 | SDL_DelFinger(touch, fingerid); | ||
| 371 | } | ||
| 372 | } | ||
| 373 | |||
| 374 | void SDL_SendTouchMotion(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, | ||
| 375 | float x, float y, float pressure) | ||
| 376 | { | ||
| 377 | SDL_Touch *touch; | ||
| 378 | SDL_Finger *finger; | ||
| 379 | float xrel, yrel, prel; | ||
| 380 | |||
| 381 | touch = SDL_GetTouch(id); | ||
| 382 | if (!touch) { | ||
| 383 | return; | ||
| 384 | } | ||
| 385 | |||
| 386 | SDL_Mouse *mouse = SDL_GetMouse(); | ||
| 387 | |||
| 388 | // SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events | ||
| 389 | { | ||
| 390 | if ((id != SDL_MOUSE_TOUCHID) && (id != SDL_PEN_TOUCHID)) { | ||
| 391 | if (mouse->touch_mouse_events) { | ||
| 392 | if (window) { | ||
| 393 | if (finger_touching == true && track_touchid == id && track_fingerid == fingerid) { | ||
| 394 | float pos_x = (x * (float)window->w); | ||
| 395 | float pos_y = (y * (float)window->h); | ||
| 396 | if (pos_x < 0.0f) { | ||
| 397 | pos_x = 0.0f; | ||
| 398 | } | ||
| 399 | if (pos_x > (float)(window->w - 1)) { | ||
| 400 | pos_x = (float)(window->w - 1); | ||
| 401 | } | ||
| 402 | if (pos_y < 0.0f) { | ||
| 403 | pos_y = 0.0f; | ||
| 404 | } | ||
| 405 | if (pos_y > (float)(window->h - 1)) { | ||
| 406 | pos_y = (float)(window->h - 1); | ||
| 407 | } | ||
| 408 | SDL_SendMouseMotion(timestamp, window, SDL_TOUCH_MOUSEID, false, pos_x, pos_y); | ||
| 409 | } | ||
| 410 | } | ||
| 411 | } | ||
| 412 | } | ||
| 413 | } | ||
| 414 | |||
| 415 | // SDL_HINT_MOUSE_TOUCH_EVENTS: if not set, discard synthetic touch events coming from platform layer | ||
| 416 | if (mouse->mouse_touch_events == 0) { | ||
| 417 | if (id == SDL_MOUSE_TOUCHID) { | ||
| 418 | return; | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 422 | finger = SDL_GetFinger(touch, fingerid); | ||
| 423 | if (!finger) { | ||
| 424 | SDL_SendTouch(timestamp, id, fingerid, window, SDL_EVENT_FINGER_DOWN, x, y, pressure); | ||
| 425 | return; | ||
| 426 | } | ||
| 427 | |||
| 428 | xrel = x - finger->x; | ||
| 429 | yrel = y - finger->y; | ||
| 430 | prel = pressure - finger->pressure; | ||
| 431 | |||
| 432 | // Drop events that don't change state | ||
| 433 | if (xrel == 0.0f && yrel == 0.0f && prel == 0.0f) { | ||
| 434 | #if 0 | ||
| 435 | printf("Touch event didn't change state - dropped!\n"); | ||
| 436 | #endif | ||
| 437 | return; | ||
| 438 | } | ||
| 439 | |||
| 440 | // Update internal touch coordinates | ||
| 441 | finger->x = x; | ||
| 442 | finger->y = y; | ||
| 443 | finger->pressure = pressure; | ||
| 444 | |||
| 445 | // Post the event, if desired | ||
| 446 | if (SDL_EventEnabled(SDL_EVENT_FINGER_MOTION)) { | ||
| 447 | SDL_Event event; | ||
| 448 | event.type = SDL_EVENT_FINGER_MOTION; | ||
| 449 | event.common.timestamp = timestamp; | ||
| 450 | event.tfinger.touchID = id; | ||
| 451 | event.tfinger.fingerID = fingerid; | ||
| 452 | event.tfinger.x = x; | ||
| 453 | event.tfinger.y = y; | ||
| 454 | event.tfinger.dx = xrel; | ||
| 455 | event.tfinger.dy = yrel; | ||
| 456 | event.tfinger.pressure = pressure; | ||
| 457 | event.tfinger.windowID = window ? SDL_GetWindowID(window) : 0; | ||
| 458 | SDL_PushEvent(&event); | ||
| 459 | } | ||
| 460 | } | ||
| 461 | |||
| 462 | void SDL_DelTouch(SDL_TouchID id) | ||
| 463 | { | ||
| 464 | int i, index; | ||
| 465 | SDL_Touch *touch; | ||
| 466 | |||
| 467 | if (SDL_num_touch == 0) { | ||
| 468 | // We've already cleaned up, we won't find this device | ||
| 469 | return; | ||
| 470 | } | ||
| 471 | |||
| 472 | index = SDL_GetTouchIndex(id); | ||
| 473 | touch = SDL_GetTouch(id); | ||
| 474 | if (!touch) { | ||
| 475 | return; | ||
| 476 | } | ||
| 477 | |||
| 478 | for (i = 0; i < touch->max_fingers; ++i) { | ||
| 479 | SDL_free(touch->fingers[i]); | ||
| 480 | } | ||
| 481 | SDL_free(touch->fingers); | ||
| 482 | SDL_free(touch->name); | ||
| 483 | SDL_free(touch); | ||
| 484 | |||
| 485 | SDL_num_touch--; | ||
| 486 | SDL_touchDevices[index] = SDL_touchDevices[SDL_num_touch]; | ||
| 487 | } | ||
| 488 | |||
| 489 | void SDL_QuitTouch(void) | ||
| 490 | { | ||
| 491 | int i; | ||
| 492 | |||
| 493 | for (i = SDL_num_touch; i--;) { | ||
| 494 | SDL_DelTouch(SDL_touchDevices[i]->id); | ||
| 495 | } | ||
| 496 | SDL_assert(SDL_num_touch == 0); | ||
| 497 | |||
| 498 | SDL_free(SDL_touchDevices); | ||
| 499 | SDL_touchDevices = NULL; | ||
| 500 | } | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_touch_c.h b/contrib/SDL-3.2.8/src/events/SDL_touch_c.h new file mode 100644 index 0000000..db2d64b --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_touch_c.h | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #ifndef SDL_touch_c_h_ | ||
| 24 | #define SDL_touch_c_h_ | ||
| 25 | |||
| 26 | typedef struct SDL_Touch | ||
| 27 | { | ||
| 28 | SDL_TouchID id; | ||
| 29 | SDL_TouchDeviceType type; | ||
| 30 | int num_fingers; | ||
| 31 | int max_fingers; | ||
| 32 | SDL_Finger **fingers; | ||
| 33 | char *name; | ||
| 34 | } SDL_Touch; | ||
| 35 | |||
| 36 | // Initialize the touch subsystem | ||
| 37 | extern bool SDL_InitTouch(void); | ||
| 38 | |||
| 39 | // Returns true if _any_ connected touch devices are known to SDL | ||
| 40 | extern bool SDL_TouchDevicesAvailable(void); | ||
| 41 | |||
| 42 | // Add a touch, returning the index of the touch, or -1 if there was an error. | ||
| 43 | extern int SDL_AddTouch(SDL_TouchID id, SDL_TouchDeviceType type, const char *name); | ||
| 44 | |||
| 45 | // Get the touch with a given id | ||
| 46 | extern SDL_Touch *SDL_GetTouch(SDL_TouchID id); | ||
| 47 | |||
| 48 | // Send a touch down/up event for a touch | ||
| 49 | extern void SDL_SendTouch(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, SDL_EventType type, float x, float y, float pressure); | ||
| 50 | |||
| 51 | // Send a touch motion event for a touch | ||
| 52 | extern void SDL_SendTouchMotion(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, float x, float y, float pressure); | ||
| 53 | |||
| 54 | // Remove a touch | ||
| 55 | extern void SDL_DelTouch(SDL_TouchID id); | ||
| 56 | |||
| 57 | // Shutdown the touch subsystem | ||
| 58 | extern void SDL_QuitTouch(void); | ||
| 59 | |||
| 60 | #endif // SDL_touch_c_h_ | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_windowevents.c b/contrib/SDL-3.2.8/src/events/SDL_windowevents.c new file mode 100644 index 0000000..e20cd3a --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_windowevents.c | |||
| @@ -0,0 +1,300 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | // Window event handling code for SDL | ||
| 24 | |||
| 25 | #include "SDL_events_c.h" | ||
| 26 | #include "SDL_eventwatch_c.h" | ||
| 27 | #include "SDL_mouse_c.h" | ||
| 28 | #include "../tray/SDL_tray_utils.h" | ||
| 29 | |||
| 30 | |||
| 31 | #define NUM_WINDOW_EVENT_WATCH_PRIORITIES (SDL_WINDOW_EVENT_WATCH_NORMAL + 1) | ||
| 32 | |||
| 33 | static SDL_EventWatchList SDL_window_event_watchers[NUM_WINDOW_EVENT_WATCH_PRIORITIES]; | ||
| 34 | |||
| 35 | void SDL_InitWindowEventWatch(void) | ||
| 36 | { | ||
| 37 | for (int i = 0; i < SDL_arraysize(SDL_window_event_watchers); ++i) { | ||
| 38 | SDL_InitEventWatchList(&SDL_window_event_watchers[i]); | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | void SDL_QuitWindowEventWatch(void) | ||
| 43 | { | ||
| 44 | for (int i = 0; i < SDL_arraysize(SDL_window_event_watchers); ++i) { | ||
| 45 | SDL_QuitEventWatchList(&SDL_window_event_watchers[i]); | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | void SDL_AddWindowEventWatch(SDL_WindowEventWatchPriority priority, SDL_EventFilter filter, void *userdata) | ||
| 50 | { | ||
| 51 | SDL_AddEventWatchList(&SDL_window_event_watchers[priority], filter, userdata); | ||
| 52 | } | ||
| 53 | |||
| 54 | void SDL_RemoveWindowEventWatch(SDL_WindowEventWatchPriority priority, SDL_EventFilter filter, void *userdata) | ||
| 55 | { | ||
| 56 | SDL_RemoveEventWatchList(&SDL_window_event_watchers[priority], filter, userdata); | ||
| 57 | } | ||
| 58 | |||
| 59 | static bool SDLCALL RemoveSupercededWindowEvents(void *userdata, SDL_Event *event) | ||
| 60 | { | ||
| 61 | SDL_Event *new_event = (SDL_Event *)userdata; | ||
| 62 | |||
| 63 | if (event->type == new_event->type && | ||
| 64 | event->window.windowID == new_event->window.windowID) { | ||
| 65 | // We're about to post a new move event, drop the old one | ||
| 66 | return false; | ||
| 67 | } | ||
| 68 | return true; | ||
| 69 | } | ||
| 70 | |||
| 71 | bool SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent, int data1, int data2) | ||
| 72 | { | ||
| 73 | bool posted = false; | ||
| 74 | |||
| 75 | if (!window) { | ||
| 76 | return false; | ||
| 77 | } | ||
| 78 | SDL_assert(SDL_ObjectValid(window, SDL_OBJECT_TYPE_WINDOW)); | ||
| 79 | |||
| 80 | if (window->is_destroying && windowevent != SDL_EVENT_WINDOW_DESTROYED) { | ||
| 81 | return false; | ||
| 82 | } | ||
| 83 | switch (windowevent) { | ||
| 84 | case SDL_EVENT_WINDOW_SHOWN: | ||
| 85 | if (!(window->flags & SDL_WINDOW_HIDDEN)) { | ||
| 86 | return false; | ||
| 87 | } | ||
| 88 | window->flags &= ~(SDL_WINDOW_HIDDEN | SDL_WINDOW_MINIMIZED); | ||
| 89 | break; | ||
| 90 | case SDL_EVENT_WINDOW_HIDDEN: | ||
| 91 | if (window->flags & SDL_WINDOW_HIDDEN) { | ||
| 92 | return false; | ||
| 93 | } | ||
| 94 | window->flags |= SDL_WINDOW_HIDDEN; | ||
| 95 | break; | ||
| 96 | case SDL_EVENT_WINDOW_EXPOSED: | ||
| 97 | window->flags &= ~SDL_WINDOW_OCCLUDED; | ||
| 98 | break; | ||
| 99 | case SDL_EVENT_WINDOW_MOVED: | ||
| 100 | window->undefined_x = false; | ||
| 101 | window->undefined_y = false; | ||
| 102 | window->last_position_pending = false; | ||
| 103 | if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { | ||
| 104 | window->windowed.x = data1; | ||
| 105 | window->windowed.y = data2; | ||
| 106 | |||
| 107 | if (!(window->flags & SDL_WINDOW_MAXIMIZED) && !window->tiled) { | ||
| 108 | window->floating.x = data1; | ||
| 109 | window->floating.y = data2; | ||
| 110 | } | ||
| 111 | } | ||
| 112 | if (data1 == window->x && data2 == window->y) { | ||
| 113 | return false; | ||
| 114 | } | ||
| 115 | window->x = data1; | ||
| 116 | window->y = data2; | ||
| 117 | break; | ||
| 118 | case SDL_EVENT_WINDOW_RESIZED: | ||
| 119 | window->last_size_pending = false; | ||
| 120 | if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { | ||
| 121 | window->windowed.w = data1; | ||
| 122 | window->windowed.h = data2; | ||
| 123 | |||
| 124 | if (!(window->flags & SDL_WINDOW_MAXIMIZED) && !window->tiled) { | ||
| 125 | window->floating.w = data1; | ||
| 126 | window->floating.h = data2; | ||
| 127 | } | ||
| 128 | } | ||
| 129 | if (data1 == window->w && data2 == window->h) { | ||
| 130 | SDL_CheckWindowPixelSizeChanged(window); | ||
| 131 | return false; | ||
| 132 | } | ||
| 133 | window->w = data1; | ||
| 134 | window->h = data2; | ||
| 135 | break; | ||
| 136 | case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: | ||
| 137 | if (data1 == window->last_pixel_w && data2 == window->last_pixel_h) { | ||
| 138 | return false; | ||
| 139 | } | ||
| 140 | window->last_pixel_w = data1; | ||
| 141 | window->last_pixel_h = data2; | ||
| 142 | break; | ||
| 143 | case SDL_EVENT_WINDOW_MINIMIZED: | ||
| 144 | if (window->flags & SDL_WINDOW_MINIMIZED) { | ||
| 145 | return false; | ||
| 146 | } | ||
| 147 | window->flags &= ~SDL_WINDOW_MAXIMIZED; | ||
| 148 | window->flags |= SDL_WINDOW_MINIMIZED; | ||
| 149 | break; | ||
| 150 | case SDL_EVENT_WINDOW_MAXIMIZED: | ||
| 151 | if (window->flags & SDL_WINDOW_MAXIMIZED) { | ||
| 152 | return false; | ||
| 153 | } | ||
| 154 | window->flags &= ~SDL_WINDOW_MINIMIZED; | ||
| 155 | window->flags |= SDL_WINDOW_MAXIMIZED; | ||
| 156 | break; | ||
| 157 | case SDL_EVENT_WINDOW_RESTORED: | ||
| 158 | if (!(window->flags & (SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED))) { | ||
| 159 | return false; | ||
| 160 | } | ||
| 161 | window->flags &= ~(SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED); | ||
| 162 | break; | ||
| 163 | case SDL_EVENT_WINDOW_MOUSE_ENTER: | ||
| 164 | if (window->flags & SDL_WINDOW_MOUSE_FOCUS) { | ||
| 165 | return false; | ||
| 166 | } | ||
| 167 | window->flags |= SDL_WINDOW_MOUSE_FOCUS; | ||
| 168 | break; | ||
| 169 | case SDL_EVENT_WINDOW_MOUSE_LEAVE: | ||
| 170 | if (!(window->flags & SDL_WINDOW_MOUSE_FOCUS)) { | ||
| 171 | return false; | ||
| 172 | } | ||
| 173 | window->flags &= ~SDL_WINDOW_MOUSE_FOCUS; | ||
| 174 | break; | ||
| 175 | case SDL_EVENT_WINDOW_FOCUS_GAINED: | ||
| 176 | if (window->flags & SDL_WINDOW_INPUT_FOCUS) { | ||
| 177 | return false; | ||
| 178 | } | ||
| 179 | window->flags |= SDL_WINDOW_INPUT_FOCUS; | ||
| 180 | break; | ||
| 181 | case SDL_EVENT_WINDOW_FOCUS_LOST: | ||
| 182 | if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) { | ||
| 183 | return false; | ||
| 184 | } | ||
| 185 | window->flags &= ~SDL_WINDOW_INPUT_FOCUS; | ||
| 186 | break; | ||
| 187 | case SDL_EVENT_WINDOW_DISPLAY_CHANGED: | ||
| 188 | if (data1 == 0 || (SDL_DisplayID)data1 == window->last_displayID) { | ||
| 189 | return false; | ||
| 190 | } | ||
| 191 | window->last_displayID = (SDL_DisplayID)data1; | ||
| 192 | break; | ||
| 193 | case SDL_EVENT_WINDOW_OCCLUDED: | ||
| 194 | if (window->flags & SDL_WINDOW_OCCLUDED) { | ||
| 195 | return false; | ||
| 196 | } | ||
| 197 | window->flags |= SDL_WINDOW_OCCLUDED; | ||
| 198 | break; | ||
| 199 | case SDL_EVENT_WINDOW_ENTER_FULLSCREEN: | ||
| 200 | if (window->flags & SDL_WINDOW_FULLSCREEN) { | ||
| 201 | return false; | ||
| 202 | } | ||
| 203 | window->flags |= SDL_WINDOW_FULLSCREEN; | ||
| 204 | break; | ||
| 205 | case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN: | ||
| 206 | if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { | ||
| 207 | return false; | ||
| 208 | } | ||
| 209 | window->flags &= ~SDL_WINDOW_FULLSCREEN; | ||
| 210 | break; | ||
| 211 | default: | ||
| 212 | break; | ||
| 213 | } | ||
| 214 | |||
| 215 | // Post the event, if desired | ||
| 216 | SDL_Event event; | ||
| 217 | event.type = windowevent; | ||
| 218 | event.common.timestamp = 0; | ||
| 219 | event.window.data1 = data1; | ||
| 220 | event.window.data2 = data2; | ||
| 221 | event.window.windowID = window->id; | ||
| 222 | |||
| 223 | SDL_DispatchEventWatchList(&SDL_window_event_watchers[SDL_WINDOW_EVENT_WATCH_EARLY], &event); | ||
| 224 | SDL_DispatchEventWatchList(&SDL_window_event_watchers[SDL_WINDOW_EVENT_WATCH_NORMAL], &event); | ||
| 225 | |||
| 226 | if (SDL_EventEnabled(windowevent)) { | ||
| 227 | // Fixes queue overflow with move/resize events that aren't processed | ||
| 228 | if (windowevent == SDL_EVENT_WINDOW_MOVED || | ||
| 229 | windowevent == SDL_EVENT_WINDOW_RESIZED || | ||
| 230 | windowevent == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED || | ||
| 231 | windowevent == SDL_EVENT_WINDOW_SAFE_AREA_CHANGED || | ||
| 232 | windowevent == SDL_EVENT_WINDOW_EXPOSED || | ||
| 233 | windowevent == SDL_EVENT_WINDOW_OCCLUDED) { | ||
| 234 | SDL_FilterEvents(RemoveSupercededWindowEvents, &event); | ||
| 235 | } | ||
| 236 | posted = SDL_PushEvent(&event); | ||
| 237 | } | ||
| 238 | |||
| 239 | switch (windowevent) { | ||
| 240 | case SDL_EVENT_WINDOW_SHOWN: | ||
| 241 | SDL_OnWindowShown(window); | ||
| 242 | break; | ||
| 243 | case SDL_EVENT_WINDOW_HIDDEN: | ||
| 244 | SDL_OnWindowHidden(window); | ||
| 245 | break; | ||
| 246 | case SDL_EVENT_WINDOW_MOVED: | ||
| 247 | SDL_OnWindowMoved(window); | ||
| 248 | break; | ||
| 249 | case SDL_EVENT_WINDOW_RESIZED: | ||
| 250 | SDL_OnWindowResized(window); | ||
| 251 | break; | ||
| 252 | case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: | ||
| 253 | SDL_OnWindowPixelSizeChanged(window); | ||
| 254 | break; | ||
| 255 | case SDL_EVENT_WINDOW_MINIMIZED: | ||
| 256 | SDL_OnWindowMinimized(window); | ||
| 257 | break; | ||
| 258 | case SDL_EVENT_WINDOW_MAXIMIZED: | ||
| 259 | SDL_OnWindowMaximized(window); | ||
| 260 | break; | ||
| 261 | case SDL_EVENT_WINDOW_RESTORED: | ||
| 262 | SDL_OnWindowRestored(window); | ||
| 263 | break; | ||
| 264 | case SDL_EVENT_WINDOW_MOUSE_ENTER: | ||
| 265 | SDL_OnWindowEnter(window); | ||
| 266 | break; | ||
| 267 | case SDL_EVENT_WINDOW_MOUSE_LEAVE: | ||
| 268 | SDL_OnWindowLeave(window); | ||
| 269 | break; | ||
| 270 | case SDL_EVENT_WINDOW_FOCUS_GAINED: | ||
| 271 | SDL_OnWindowFocusGained(window); | ||
| 272 | break; | ||
| 273 | case SDL_EVENT_WINDOW_FOCUS_LOST: | ||
| 274 | SDL_OnWindowFocusLost(window); | ||
| 275 | break; | ||
| 276 | case SDL_EVENT_WINDOW_DISPLAY_CHANGED: | ||
| 277 | SDL_OnWindowDisplayChanged(window); | ||
| 278 | break; | ||
| 279 | default: | ||
| 280 | break; | ||
| 281 | } | ||
| 282 | |||
| 283 | if (windowevent == SDL_EVENT_WINDOW_CLOSE_REQUESTED && !window->parent && !SDL_HasActiveTrays()) { | ||
| 284 | int toplevel_count = 0; | ||
| 285 | SDL_Window *n; | ||
| 286 | for (n = SDL_GetVideoDevice()->windows; n; n = n->next) { | ||
| 287 | if (!n->parent && !(n->flags & SDL_WINDOW_HIDDEN)) { | ||
| 288 | ++toplevel_count; | ||
| 289 | } | ||
| 290 | } | ||
| 291 | |||
| 292 | if (toplevel_count <= 1) { | ||
| 293 | if (SDL_GetHintBoolean(SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE, true)) { | ||
| 294 | SDL_SendQuit(); // This is the last toplevel window in the list so send the SDL_EVENT_QUIT event | ||
| 295 | } | ||
| 296 | } | ||
| 297 | } | ||
| 298 | |||
| 299 | return posted; | ||
| 300 | } | ||
diff --git a/contrib/SDL-3.2.8/src/events/SDL_windowevents_c.h b/contrib/SDL-3.2.8/src/events/SDL_windowevents_c.h new file mode 100644 index 0000000..7204305 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/SDL_windowevents_c.h | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #ifndef SDL_windowevents_c_h_ | ||
| 24 | #define SDL_windowevents_c_h_ | ||
| 25 | |||
| 26 | typedef enum | ||
| 27 | { | ||
| 28 | SDL_WINDOW_EVENT_WATCH_EARLY, | ||
| 29 | SDL_WINDOW_EVENT_WATCH_NORMAL | ||
| 30 | } SDL_WindowEventWatchPriority; | ||
| 31 | |||
| 32 | extern void SDL_InitWindowEventWatch(void); | ||
| 33 | extern void SDL_QuitWindowEventWatch(void); | ||
| 34 | extern void SDL_AddWindowEventWatch(SDL_WindowEventWatchPriority priority, SDL_EventFilter filter, void *userdata); | ||
| 35 | extern void SDL_RemoveWindowEventWatch(SDL_WindowEventWatchPriority priority, SDL_EventFilter filter, void *userdata); | ||
| 36 | |||
| 37 | extern bool SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent, int data1, int data2); | ||
| 38 | |||
| 39 | #endif // SDL_windowevents_c_h_ | ||
diff --git a/contrib/SDL-3.2.8/src/events/blank_cursor.h b/contrib/SDL-3.2.8/src/events/blank_cursor.h new file mode 100644 index 0000000..d8d9b4d --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/blank_cursor.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | |||
| 22 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | ||
| 23 | * A default blank 8x8 cursor */ | ||
| 24 | |||
| 25 | #define BLANK_CWIDTH 8 | ||
| 26 | #define BLANK_CHEIGHT 8 | ||
| 27 | #define BLANK_CHOTX 0 | ||
| 28 | #define BLANK_CHOTY 0 | ||
| 29 | |||
| 30 | static const unsigned char blank_cdata[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | ||
| 31 | static const unsigned char blank_cmask[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | ||
diff --git a/contrib/SDL-3.2.8/src/events/default_cursor.h b/contrib/SDL-3.2.8/src/events/default_cursor.h new file mode 100644 index 0000000..9a76f94 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/default_cursor.h | |||
| @@ -0,0 +1,113 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | |||
| 22 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | ||
| 23 | * Default cursor - it happens to be the Mac cursor, but could be anything */ | ||
| 24 | |||
| 25 | #define DEFAULT_CWIDTH 16 | ||
| 26 | #define DEFAULT_CHEIGHT 16 | ||
| 27 | #define DEFAULT_CHOTX 0 | ||
| 28 | #define DEFAULT_CHOTY 0 | ||
| 29 | |||
| 30 | // Added a real MacOS cursor, at the request of Luc-Olivier de Charrière | ||
| 31 | #define USE_MACOS_CURSOR | ||
| 32 | |||
| 33 | #ifdef USE_MACOS_CURSOR | ||
| 34 | |||
| 35 | static const unsigned char default_cdata[] = { | ||
| 36 | 0x00, 0x00, | ||
| 37 | 0x40, 0x00, | ||
| 38 | 0x60, 0x00, | ||
| 39 | 0x70, 0x00, | ||
| 40 | 0x78, 0x00, | ||
| 41 | 0x7C, 0x00, | ||
| 42 | 0x7E, 0x00, | ||
| 43 | 0x7F, 0x00, | ||
| 44 | 0x7F, 0x80, | ||
| 45 | 0x7C, 0x00, | ||
| 46 | 0x6C, 0x00, | ||
| 47 | 0x46, 0x00, | ||
| 48 | 0x06, 0x00, | ||
| 49 | 0x03, 0x00, | ||
| 50 | 0x03, 0x00, | ||
| 51 | 0x00, 0x00 | ||
| 52 | }; | ||
| 53 | |||
| 54 | static const unsigned char default_cmask[] = { | ||
| 55 | 0xC0, 0x00, | ||
| 56 | 0xE0, 0x00, | ||
| 57 | 0xF0, 0x00, | ||
| 58 | 0xF8, 0x00, | ||
| 59 | 0xFC, 0x00, | ||
| 60 | 0xFE, 0x00, | ||
| 61 | 0xFF, 0x00, | ||
| 62 | 0xFF, 0x80, | ||
| 63 | 0xFF, 0xC0, | ||
| 64 | 0xFF, 0xE0, | ||
| 65 | 0xFE, 0x00, | ||
| 66 | 0xEF, 0x00, | ||
| 67 | 0xCF, 0x00, | ||
| 68 | 0x87, 0x80, | ||
| 69 | 0x07, 0x80, | ||
| 70 | 0x03, 0x00 | ||
| 71 | }; | ||
| 72 | |||
| 73 | #else | ||
| 74 | |||
| 75 | static const unsigned char default_cdata[] = { | ||
| 76 | 0x00, 0x00, | ||
| 77 | 0x40, 0x00, | ||
| 78 | 0x60, 0x00, | ||
| 79 | 0x70, 0x00, | ||
| 80 | 0x78, 0x00, | ||
| 81 | 0x7C, 0x00, | ||
| 82 | 0x7E, 0x00, | ||
| 83 | 0x7F, 0x00, | ||
| 84 | 0x7F, 0x80, | ||
| 85 | 0x7C, 0x00, | ||
| 86 | 0x6C, 0x00, | ||
| 87 | 0x46, 0x00, | ||
| 88 | 0x06, 0x00, | ||
| 89 | 0x03, 0x00, | ||
| 90 | 0x03, 0x00, | ||
| 91 | 0x00, 0x00 | ||
| 92 | }; | ||
| 93 | |||
| 94 | static const unsigned char default_cmask[] = { | ||
| 95 | 0x40, 0x00, | ||
| 96 | 0xE0, 0x00, | ||
| 97 | 0xF0, 0x00, | ||
| 98 | 0xF8, 0x00, | ||
| 99 | 0xFC, 0x00, | ||
| 100 | 0xFE, 0x00, | ||
| 101 | 0xFF, 0x00, | ||
| 102 | 0xFF, 0x80, | ||
| 103 | 0xFF, 0xC0, | ||
| 104 | 0xFF, 0x80, | ||
| 105 | 0xFE, 0x00, | ||
| 106 | 0xEF, 0x00, | ||
| 107 | 0x4F, 0x00, | ||
| 108 | 0x07, 0x80, | ||
| 109 | 0x07, 0x80, | ||
| 110 | 0x03, 0x00 | ||
| 111 | }; | ||
| 112 | |||
| 113 | #endif // USE_MACOS_CURSOR | ||
diff --git a/contrib/SDL-3.2.8/src/events/imKStoUCS.c b/contrib/SDL-3.2.8/src/events/imKStoUCS.c new file mode 100644 index 0000000..503abb0 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/imKStoUCS.c | |||
| @@ -0,0 +1,349 @@ | |||
| 1 | /* | ||
| 2 | Copyright (C) 2003-2006,2008 Jamey Sharp, Josh Triplett | ||
| 3 | Copyright © 2009 Red Hat, Inc. | ||
| 4 | Copyright 1990-1992,1999,2000,2004,2009,2010 Oracle and/or its affiliates. | ||
| 5 | All rights reserved. | ||
| 6 | |||
| 7 | Permission is hereby granted, free of charge, to any person obtaining a | ||
| 8 | copy of this software and associated documentation files (the "Software"), | ||
| 9 | to deal in the Software without restriction, including without limitation | ||
| 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 11 | and/or sell copies of the Software, and to permit persons to whom the | ||
| 12 | Software is furnished to do so, subject to the following conditions: | ||
| 13 | |||
| 14 | The above copyright notice and this permission notice (including the next | ||
| 15 | paragraph) shall be included in all copies or substantial portions of the | ||
| 16 | Software. | ||
| 17 | |||
| 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| 24 | DEALINGS IN THE SOFTWARE. | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include "SDL_internal.h" | ||
| 28 | |||
| 29 | #if defined(SDL_VIDEO_DRIVER_X11) || defined(SDL_VIDEO_DRIVER_WAYLAND) | ||
| 30 | #include "imKStoUCS.h" | ||
| 31 | |||
| 32 | static unsigned short const keysym_to_unicode_1a1_1ff[] = { | ||
| 33 | 0x0104, 0x02d8, 0x0141, 0x0000, 0x013d, 0x015a, 0x0000, /* 0x01a0-0x01a7 */ | ||
| 34 | 0x0000, 0x0160, 0x015e, 0x0164, 0x0179, 0x0000, 0x017d, 0x017b, /* 0x01a8-0x01af */ | ||
| 35 | 0x0000, 0x0105, 0x02db, 0x0142, 0x0000, 0x013e, 0x015b, 0x02c7, /* 0x01b0-0x01b7 */ | ||
| 36 | 0x0000, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, /* 0x01b8-0x01bf */ | ||
| 37 | 0x0154, 0x0000, 0x0000, 0x0102, 0x0000, 0x0139, 0x0106, 0x0000, /* 0x01c0-0x01c7 */ | ||
| 38 | 0x010c, 0x0000, 0x0118, 0x0000, 0x011a, 0x0000, 0x0000, 0x010e, /* 0x01c8-0x01cf */ | ||
| 39 | 0x0110, 0x0143, 0x0147, 0x0000, 0x0000, 0x0150, 0x0000, 0x0000, /* 0x01d0-0x01d7 */ | ||
| 40 | 0x0158, 0x016e, 0x0000, 0x0170, 0x0000, 0x0000, 0x0162, 0x0000, /* 0x01d8-0x01df */ | ||
| 41 | 0x0155, 0x0000, 0x0000, 0x0103, 0x0000, 0x013a, 0x0107, 0x0000, /* 0x01e0-0x01e7 */ | ||
| 42 | 0x010d, 0x0000, 0x0119, 0x0000, 0x011b, 0x0000, 0x0000, 0x010f, /* 0x01e8-0x01ef */ | ||
| 43 | 0x0111, 0x0144, 0x0148, 0x0000, 0x0000, 0x0151, 0x0000, 0x0000, /* 0x01f0-0x01f7 */ | ||
| 44 | 0x0159, 0x016f, 0x0000, 0x0171, 0x0000, 0x0000, 0x0163, 0x02d9 /* 0x01f8-0x01ff */ | ||
| 45 | }; | ||
| 46 | |||
| 47 | static unsigned short const keysym_to_unicode_2a1_2fe[] = { | ||
| 48 | 0x0126, 0x0000, 0x0000, 0x0000, 0x0000, 0x0124, 0x0000, /* 0x02a0-0x02a7 */ | ||
| 49 | 0x0000, 0x0130, 0x0000, 0x011e, 0x0134, 0x0000, 0x0000, 0x0000, /* 0x02a8-0x02af */ | ||
| 50 | 0x0000, 0x0127, 0x0000, 0x0000, 0x0000, 0x0000, 0x0125, 0x0000, /* 0x02b0-0x02b7 */ | ||
| 51 | 0x0000, 0x0131, 0x0000, 0x011f, 0x0135, 0x0000, 0x0000, 0x0000, /* 0x02b8-0x02bf */ | ||
| 52 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010a, 0x0108, 0x0000, /* 0x02c0-0x02c7 */ | ||
| 53 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02c8-0x02cf */ | ||
| 54 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0120, 0x0000, 0x0000, /* 0x02d0-0x02d7 */ | ||
| 55 | 0x011c, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x015c, 0x0000, /* 0x02d8-0x02df */ | ||
| 56 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010b, 0x0109, 0x0000, /* 0x02e0-0x02e7 */ | ||
| 57 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02e8-0x02ef */ | ||
| 58 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0121, 0x0000, 0x0000, /* 0x02f0-0x02f7 */ | ||
| 59 | 0x011d, 0x0000, 0x0000, 0x0000, 0x0000, 0x016d, 0x015d /* 0x02f8-0x02ff */ | ||
| 60 | }; | ||
| 61 | |||
| 62 | static unsigned short const keysym_to_unicode_3a2_3fe[] = { | ||
| 63 | 0x0138, 0x0156, 0x0000, 0x0128, 0x013b, 0x0000, /* 0x03a0-0x03a7 */ | ||
| 64 | 0x0000, 0x0000, 0x0112, 0x0122, 0x0166, 0x0000, 0x0000, 0x0000, /* 0x03a8-0x03af */ | ||
| 65 | 0x0000, 0x0000, 0x0000, 0x0157, 0x0000, 0x0129, 0x013c, 0x0000, /* 0x03b0-0x03b7 */ | ||
| 66 | 0x0000, 0x0000, 0x0113, 0x0123, 0x0167, 0x014a, 0x0000, 0x014b, /* 0x03b8-0x03bf */ | ||
| 67 | 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012e, /* 0x03c0-0x03c7 */ | ||
| 68 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0116, 0x0000, 0x0000, 0x012a, /* 0x03c8-0x03cf */ | ||
| 69 | 0x0000, 0x0145, 0x014c, 0x0136, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03d0-0x03d7 */ | ||
| 70 | 0x0000, 0x0172, 0x0000, 0x0000, 0x0000, 0x0168, 0x016a, 0x0000, /* 0x03d8-0x03df */ | ||
| 71 | 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012f, /* 0x03e0-0x03e7 */ | ||
| 72 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0117, 0x0000, 0x0000, 0x012b, /* 0x03e8-0x03ef */ | ||
| 73 | 0x0000, 0x0146, 0x014d, 0x0137, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03f0-0x03f7 */ | ||
| 74 | 0x0000, 0x0173, 0x0000, 0x0000, 0x0000, 0x0169, 0x016b /* 0x03f8-0x03ff */ | ||
| 75 | }; | ||
| 76 | |||
| 77 | static unsigned short const keysym_to_unicode_4a1_4df[] = { | ||
| 78 | 0x3002, 0x3008, 0x3009, 0x3001, 0x30fb, 0x30f2, 0x30a1, /* 0x04a0-0x04a7 */ | ||
| 79 | 0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3, /* 0x04a8-0x04af */ | ||
| 80 | 0x30fc, 0x30a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, 0x30ab, 0x30ad, /* 0x04b0-0x04b7 */ | ||
| 81 | 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, 0x30bd, /* 0x04b8-0x04bf */ | ||
| 82 | 0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc, /* 0x04c0-0x04c7 */ | ||
| 83 | 0x30cd, 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, /* 0x04c8-0x04cf */ | ||
| 84 | 0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, /* 0x04d0-0x04d7 */ | ||
| 85 | 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f3, 0x309b, 0x309c /* 0x04d8-0x04df */ | ||
| 86 | }; | ||
| 87 | |||
| 88 | static unsigned short const keysym_to_unicode_590_5fe[] = { | ||
| 89 | 0x06f0, 0x06f1, 0x06f2, 0x06f3, 0x06f4, 0x06f5, 0x06f6, 0x06f7, /* 0x0590-0x0597 */ | ||
| 90 | 0x06f8, 0x06f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x0598-0x059f */ | ||
| 91 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x066a, 0x0670, 0x0679, /* 0x05a0-0x05a7 */ | ||
| 92 | |||
| 93 | 0x067e, 0x0686, 0x0688, 0x0691, 0x060c, 0x0000, 0x06d4, 0x0000, /* 0x05ac-0x05af */ | ||
| 94 | 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, /* 0x05b0-0x05b7 */ | ||
| 95 | 0x0668, 0x0669, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f, /* 0x05b8-0x05bf */ | ||
| 96 | 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, /* 0x05c0-0x05c7 */ | ||
| 97 | 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, /* 0x05c8-0x05cf */ | ||
| 98 | 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, /* 0x05d0-0x05d7 */ | ||
| 99 | 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x05d8-0x05df */ | ||
| 100 | 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, /* 0x05e0-0x05e7 */ | ||
| 101 | 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, /* 0x05e8-0x05ef */ | ||
| 102 | 0x0650, 0x0651, 0x0652, 0x0653, 0x0654, 0x0655, 0x0698, 0x06a4, /* 0x05f0-0x05f7 */ | ||
| 103 | 0x06a9, 0x06af, 0x06ba, 0x06be, 0x06cc, 0x06d2, 0x06c1 /* 0x05f8-0x05fe */ | ||
| 104 | }; | ||
| 105 | |||
| 106 | static unsigned short keysym_to_unicode_680_6ff[] = { | ||
| 107 | 0x0492, 0x0496, 0x049a, 0x049c, 0x04a2, 0x04ae, 0x04b0, 0x04b2, /* 0x0680-0x0687 */ | ||
| 108 | 0x04b6, 0x04b8, 0x04ba, 0x0000, 0x04d8, 0x04e2, 0x04e8, 0x04ee, /* 0x0688-0x068f */ | ||
| 109 | 0x0493, 0x0497, 0x049b, 0x049d, 0x04a3, 0x04af, 0x04b1, 0x04b3, /* 0x0690-0x0697 */ | ||
| 110 | 0x04b7, 0x04b9, 0x04bb, 0x0000, 0x04d9, 0x04e3, 0x04e9, 0x04ef, /* 0x0698-0x069f */ | ||
| 111 | 0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, /* 0x06a0-0x06a7 */ | ||
| 112 | 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0491, 0x045e, 0x045f, /* 0x06a8-0x06af */ | ||
| 113 | 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, /* 0x06b0-0x06b7 */ | ||
| 114 | 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0490, 0x040e, 0x040f, /* 0x06b8-0x06bf */ | ||
| 115 | 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, /* 0x06c0-0x06c7 */ | ||
| 116 | 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, /* 0x06c8-0x06cf */ | ||
| 117 | 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, /* 0x06d0-0x06d7 */ | ||
| 118 | 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, /* 0x06d8-0x06df */ | ||
| 119 | 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, /* 0x06e0-0x06e7 */ | ||
| 120 | 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, /* 0x06e8-0x06ef */ | ||
| 121 | 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, /* 0x06f0-0x06f7 */ | ||
| 122 | 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a /* 0x06f8-0x06ff */ | ||
| 123 | }; | ||
| 124 | |||
| 125 | static unsigned short const keysym_to_unicode_7a1_7f9[] = { | ||
| 126 | 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c, /* 0x07a0-0x07a7 */ | ||
| 127 | 0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015, /* 0x07a8-0x07af */ | ||
| 128 | 0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc, /* 0x07b0-0x07b7 */ | ||
| 129 | 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07b8-0x07bf */ | ||
| 130 | 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, /* 0x07c0-0x07c7 */ | ||
| 131 | 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, /* 0x07c8-0x07cf */ | ||
| 132 | 0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7, /* 0x07d0-0x07d7 */ | ||
| 133 | 0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07d8-0x07df */ | ||
| 134 | 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, /* 0x07e0-0x07e7 */ | ||
| 135 | 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, /* 0x07e8-0x07ef */ | ||
| 136 | 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7, /* 0x07f0-0x07f7 */ | ||
| 137 | 0x03c8, 0x03c9 /* 0x07f8-0x07ff */ | ||
| 138 | }; | ||
| 139 | |||
| 140 | static unsigned short const keysym_to_unicode_8a4_8fe[] = { | ||
| 141 | 0x2320, 0x2321, 0x0000, 0x231c, /* 0x08a0-0x08a7 */ | ||
| 142 | 0x231d, 0x231e, 0x231f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08a8-0x08af */ | ||
| 143 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08b0-0x08b7 */ | ||
| 144 | 0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222b, /* 0x08b8-0x08bf */ | ||
| 145 | 0x2234, 0x0000, 0x221e, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000, /* 0x08c0-0x08c7 */ | ||
| 146 | 0x2245, 0x2246, 0x0000, 0x0000, 0x0000, 0x0000, 0x21d2, 0x0000, /* 0x08c8-0x08cf */ | ||
| 147 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221a, 0x0000, /* 0x08d0-0x08d7 */ | ||
| 148 | 0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222a, 0x2227, 0x2228, /* 0x08d8-0x08df */ | ||
| 149 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e0-0x08e7 */ | ||
| 150 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2202, /* 0x08e8-0x08ef */ | ||
| 151 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000, /* 0x08f0-0x08f7 */ | ||
| 152 | 0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193 /* 0x08f8-0x08ff */ | ||
| 153 | }; | ||
| 154 | |||
| 155 | static unsigned short const keysym_to_unicode_9df_9f8[] = { | ||
| 156 | 0x2422, /* 0x09d8-0x09df */ | ||
| 157 | 0x2666, 0x25a6, 0x2409, 0x240c, 0x240d, 0x240a, 0x0000, 0x0000, /* 0x09e0-0x09e7 */ | ||
| 158 | 0x240a, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x2500, /* 0x09e8-0x09ef */ | ||
| 159 | 0x0000, 0x0000, 0x0000, 0x0000, 0x251c, 0x2524, 0x2534, 0x252c, /* 0x09f0-0x09f7 */ | ||
| 160 | 0x2502 /* 0x09f8-0x09ff */ | ||
| 161 | }; | ||
| 162 | |||
| 163 | static unsigned short const keysym_to_unicode_aa1_afe[] = { | ||
| 164 | 0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009, /* 0x0aa0-0x0aa7 */ | ||
| 165 | 0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025, /* 0x0aa8-0x0aaf */ | ||
| 166 | 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, /* 0x0ab0-0x0ab7 */ | ||
| 167 | 0x2105, 0x0000, 0x0000, 0x2012, 0x2039, 0x2024, 0x203a, 0x0000, /* 0x0ab8-0x0abf */ | ||
| 168 | 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000, /* 0x0ac0-0x0ac7 */ | ||
| 169 | 0x0000, 0x2122, 0x2120, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25ad, /* 0x0ac8-0x0acf */ | ||
| 170 | 0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x2030, 0x2032, 0x2033, /* 0x0ad0-0x0ad7 */ | ||
| 171 | 0x0000, 0x271d, 0x0000, 0x220e, 0x25c2, 0x2023, 0x25cf, 0x25ac, /* 0x0ad8-0x0adf */ | ||
| 172 | 0x25e6, 0x25ab, 0x25ae, 0x25b5, 0x25bf, 0x2606, 0x2022, 0x25aa, /* 0x0ae0-0x0ae7 */ | ||
| 173 | 0x25b4, 0x25be, 0x261a, 0x261b, 0x2663, 0x2666, 0x2665, 0x0000, /* 0x0ae8-0x0aef */ | ||
| 174 | 0x2720, 0x2020, 0x2021, 0x2713, 0x2612, 0x266f, 0x266d, 0x2642, /* 0x0af0-0x0af7 */ | ||
| 175 | 0x2640, 0x2121, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e /* 0x0af8-0x0aff */ | ||
| 176 | }; | ||
| 177 | |||
| 178 | /* none of the APL keysyms match the Unicode characters */ | ||
| 179 | |||
| 180 | static unsigned short const keysym_to_unicode_cdf_cfa[] = { | ||
| 181 | 0x2017, /* 0x0cd8-0x0cdf */ | ||
| 182 | 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, /* 0x0ce0-0x0ce7 */ | ||
| 183 | 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, /* 0x0ce8-0x0cef */ | ||
| 184 | 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, /* 0x0cf0-0x0cf7 */ | ||
| 185 | 0x05e8, 0x05e9, 0x05ea /* 0x0cf8-0x0cff */ | ||
| 186 | }; | ||
| 187 | |||
| 188 | static unsigned short const keysym_to_unicode_da1_df9[] = { | ||
| 189 | 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, /* 0x0da0-0x0da7 */ | ||
| 190 | 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, /* 0x0da8-0x0daf */ | ||
| 191 | 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, /* 0x0db0-0x0db7 */ | ||
| 192 | 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, /* 0x0db8-0x0dbf */ | ||
| 193 | 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, /* 0x0dc0-0x0dc7 */ | ||
| 194 | 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, /* 0x0dc8-0x0dcf */ | ||
| 195 | 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, /* 0x0dd0-0x0dd7 */ | ||
| 196 | 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0e3e, 0x0e3f, /* 0x0dd8-0x0ddf */ | ||
| 197 | 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, /* 0x0de0-0x0de7 */ | ||
| 198 | 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0000, 0x0000, /* 0x0de8-0x0def */ | ||
| 199 | 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, /* 0x0df0-0x0df7 */ | ||
| 200 | 0x0e58, 0x0e59 /* 0x0df8-0x0dff */ | ||
| 201 | }; | ||
| 202 | |||
| 203 | static unsigned short const keysym_to_unicode_ea0_eff[] = { | ||
| 204 | 0x0000, 0x1101, 0x1101, 0x11aa, 0x1102, 0x11ac, 0x11ad, 0x1103, /* 0x0ea0-0x0ea7 */ | ||
| 205 | 0x1104, 0x1105, 0x11b0, 0x11b1, 0x11b2, 0x11b3, 0x11b4, 0x11b5, /* 0x0ea8-0x0eaf */ | ||
| 206 | 0x11b6, 0x1106, 0x1107, 0x1108, 0x11b9, 0x1109, 0x110a, 0x110b, /* 0x0eb0-0x0eb7 */ | ||
| 207 | 0x110c, 0x110d, 0x110e, 0x110f, 0x1110, 0x1111, 0x1112, 0x1161, /* 0x0eb8-0x0ebf */ | ||
| 208 | 0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167, 0x1168, 0x1169, /* 0x0ec0-0x0ec7 */ | ||
| 209 | 0x116a, 0x116b, 0x116c, 0x116d, 0x116e, 0x116f, 0x1170, 0x1171, /* 0x0ec8-0x0ecf */ | ||
| 210 | 0x1172, 0x1173, 0x1174, 0x1175, 0x11a8, 0x11a9, 0x11aa, 0x11ab, /* 0x0ed0-0x0ed7 */ | ||
| 211 | 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3, /* 0x0ed8-0x0edf */ | ||
| 212 | 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb, /* 0x0ee0-0x0ee7 */ | ||
| 213 | 0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x0000, /* 0x0ee8-0x0eef */ | ||
| 214 | 0x0000, 0x0000, 0x1140, 0x0000, 0x0000, 0x1159, 0x119e, 0x0000, /* 0x0ef0-0x0ef7 */ | ||
| 215 | 0x11eb, 0x0000, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9, /* 0x0ef8-0x0eff */ | ||
| 216 | }; | ||
| 217 | |||
| 218 | static unsigned short keysym_to_unicode_12a1_12fe[] = { | ||
| 219 | 0x1e02, 0x1e03, 0x0000, 0x0000, 0x0000, 0x1e0a, 0x0000, /* 0x12a0-0x12a7 */ | ||
| 220 | 0x1e80, 0x0000, 0x1e82, 0x1e0b, 0x1ef2, 0x0000, 0x0000, 0x0000, /* 0x12a8-0x12af */ | ||
| 221 | 0x1e1e, 0x1e1f, 0x0000, 0x0000, 0x1e40, 0x1e41, 0x0000, 0x1e56, /* 0x12b0-0x12b7 */ | ||
| 222 | 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61, /* 0x12b8-0x12bf */ | ||
| 223 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c0-0x12c7 */ | ||
| 224 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c8-0x12cf */ | ||
| 225 | 0x0174, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6a, /* 0x12d0-0x12d7 */ | ||
| 226 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0176, 0x0000, /* 0x12d8-0x12df */ | ||
| 227 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e0-0x12e7 */ | ||
| 228 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e8-0x12ef */ | ||
| 229 | 0x0175, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6b, /* 0x12f0-0x12f7 */ | ||
| 230 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0177 /* 0x12f0-0x12ff */ | ||
| 231 | }; | ||
| 232 | |||
| 233 | static unsigned short const keysym_to_unicode_13bc_13be[] = { | ||
| 234 | 0x0152, 0x0153, 0x0178 /* 0x13b8-0x13bf */ | ||
| 235 | }; | ||
| 236 | |||
| 237 | static unsigned short keysym_to_unicode_14a1_14ff[] = { | ||
| 238 | 0x2741, 0x00a7, 0x0589, 0x0029, 0x0028, 0x00bb, 0x00ab, /* 0x14a0-0x14a7 */ | ||
| 239 | 0x2014, 0x002e, 0x055d, 0x002c, 0x2013, 0x058a, 0x2026, 0x055c, /* 0x14a8-0x14af */ | ||
| 240 | 0x055b, 0x055e, 0x0531, 0x0561, 0x0532, 0x0562, 0x0533, 0x0563, /* 0x14b0-0x14b7 */ | ||
| 241 | 0x0534, 0x0564, 0x0535, 0x0565, 0x0536, 0x0566, 0x0537, 0x0567, /* 0x14b8-0x14bf */ | ||
| 242 | 0x0538, 0x0568, 0x0539, 0x0569, 0x053a, 0x056a, 0x053b, 0x056b, /* 0x14c0-0x14c7 */ | ||
| 243 | 0x053c, 0x056c, 0x053d, 0x056d, 0x053e, 0x056e, 0x053f, 0x056f, /* 0x14c8-0x14cf */ | ||
| 244 | 0x0540, 0x0570, 0x0541, 0x0571, 0x0542, 0x0572, 0x0543, 0x0573, /* 0x14d0-0x14d7 */ | ||
| 245 | 0x0544, 0x0574, 0x0545, 0x0575, 0x0546, 0x0576, 0x0547, 0x0577, /* 0x14d8-0x14df */ | ||
| 246 | 0x0548, 0x0578, 0x0549, 0x0579, 0x054a, 0x057a, 0x054b, 0x057b, /* 0x14e0-0x14e7 */ | ||
| 247 | 0x054c, 0x057c, 0x054d, 0x057d, 0x054e, 0x057e, 0x054f, 0x057f, /* 0x14e8-0x14ef */ | ||
| 248 | 0x0550, 0x0580, 0x0551, 0x0581, 0x0552, 0x0582, 0x0553, 0x0583, /* 0x14f0-0x14f7 */ | ||
| 249 | 0x0554, 0x0584, 0x0555, 0x0585, 0x0556, 0x0586, 0x2019, 0x0027, /* 0x14f8-0x14ff */ | ||
| 250 | }; | ||
| 251 | |||
| 252 | static unsigned short keysym_to_unicode_15d0_15f6[] = { | ||
| 253 | 0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7, /* 0x15d0-0x15d7 */ | ||
| 254 | 0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df, /* 0x15d8-0x15df */ | ||
| 255 | 0x10e0, 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7, /* 0x15e0-0x15e7 */ | ||
| 256 | 0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef, /* 0x15e8-0x15ef */ | ||
| 257 | 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6 /* 0x15f0-0x15f7 */ | ||
| 258 | }; | ||
| 259 | |||
| 260 | static unsigned short keysym_to_unicode_16a0_16f6[] = { | ||
| 261 | 0x0000, 0x0000, 0xf0a2, 0x1e8a, 0x0000, 0xf0a5, 0x012c, 0xf0a7, /* 0x16a0-0x16a7 */ | ||
| 262 | 0xf0a8, 0x01b5, 0x01e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x019f, /* 0x16a8-0x16af */ | ||
| 263 | 0x0000, 0x0000, 0xf0b2, 0x1e8b, 0x01d1, 0xf0b5, 0x012d, 0xf0b7, /* 0x16b0-0x16b7 */ | ||
| 264 | 0xf0b8, 0x01b6, 0x01e7, 0x0000, 0x0000, 0x01d2, 0x0000, 0x0275, /* 0x16b8-0x16bf */ | ||
| 265 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x018f, 0x0000, /* 0x16c0-0x16c7 */ | ||
| 266 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16c8-0x16cf */ | ||
| 267 | 0x0000, 0x1e36, 0xf0d2, 0xf0d3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d0-0x16d7 */ | ||
| 268 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d8-0x16df */ | ||
| 269 | 0x0000, 0x1e37, 0xf0e2, 0xf0e3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e0-0x16e7 */ | ||
| 270 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e8-0x16ef */ | ||
| 271 | 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0259 /* 0x16f0-0x16f6 */ | ||
| 272 | }; | ||
| 273 | |||
| 274 | static unsigned short const keysym_to_unicode_1e9f_1eff[] = { | ||
| 275 | 0x0303, | ||
| 276 | 0x1ea0, 0x1ea1, 0x1ea2, 0x1ea3, 0x1ea4, 0x1ea5, 0x1ea6, 0x1ea7, /* 0x1ea0-0x1ea7 */ | ||
| 277 | 0x1ea8, 0x1ea9, 0x1eaa, 0x1eab, 0x1eac, 0x1ead, 0x1eae, 0x1eaf, /* 0x1ea8-0x1eaf */ | ||
| 278 | 0x1eb0, 0x1eb1, 0x1eb2, 0x1eb3, 0x1eb4, 0x1eb5, 0x1eb6, 0x1eb7, /* 0x1eb0-0x1eb7 */ | ||
| 279 | 0x1eb8, 0x1eb9, 0x1eba, 0x1ebb, 0x1ebc, 0x1ebd, 0x1ebe, 0x1ebf, /* 0x1eb8-0x1ebf */ | ||
| 280 | 0x1ec0, 0x1ec1, 0x1ec2, 0x1ec3, 0x1ec4, 0x1ec5, 0x1ec6, 0x1ec7, /* 0x1ec0-0x1ec7 */ | ||
| 281 | 0x1ec8, 0x1ec9, 0x1eca, 0x1ecb, 0x1ecc, 0x1ecd, 0x1ece, 0x1ecf, /* 0x1ec8-0x1ecf */ | ||
| 282 | 0x1ed0, 0x1ed1, 0x1ed2, 0x1ed3, 0x1ed4, 0x1ed5, 0x1ed6, 0x1ed7, /* 0x1ed0-0x1ed7 */ | ||
| 283 | 0x1ed8, 0x1ed9, 0x1eda, 0x1edb, 0x1edc, 0x1edd, 0x1ede, 0x1edf, /* 0x1ed8-0x1edf */ | ||
| 284 | 0x1ee0, 0x1ee1, 0x1ee2, 0x1ee3, 0x1ee4, 0x1ee5, 0x1ee6, 0x1ee7, /* 0x1ee0-0x1ee7 */ | ||
| 285 | 0x1ee8, 0x1ee9, 0x1eea, 0x1eeb, 0x1eec, 0x1eed, 0x1eee, 0x1eef, /* 0x1ee8-0x1eef */ | ||
| 286 | 0x1ef0, 0x1ef1, 0x0300, 0x0301, 0x1ef4, 0x1ef5, 0x1ef6, 0x1ef7, /* 0x1ef0-0x1ef7 */ | ||
| 287 | 0x1ef8, 0x1ef9, 0x01a0, 0x01a1, 0x01af, 0x01b0, 0x0309, 0x0323 /* 0x1ef8-0x1eff */ | ||
| 288 | }; | ||
| 289 | |||
| 290 | static unsigned short const keysym_to_unicode_20a0_20ac[] = { | ||
| 291 | 0x20a0, 0x20a1, 0x20a2, 0x20a3, 0x20a4, 0x20a5, 0x20a6, 0x20a7, /* 0x20a0-0x20a7 */ | ||
| 292 | 0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac /* 0x20a8-0x20af */ | ||
| 293 | }; | ||
| 294 | |||
| 295 | unsigned int | ||
| 296 | SDL_KeySymToUcs4(Uint32 keysym) | ||
| 297 | { | ||
| 298 | /* 'Unicode keysym' */ | ||
| 299 | if ((keysym & 0xff000000) == 0x01000000) | ||
| 300 | return (keysym & 0x00ffffff); | ||
| 301 | |||
| 302 | if (keysym > 0 && keysym < 0x100) | ||
| 303 | return keysym; | ||
| 304 | else if (keysym > 0x1a0 && keysym < 0x200) | ||
| 305 | return keysym_to_unicode_1a1_1ff[keysym - 0x1a1]; | ||
| 306 | else if (keysym > 0x2a0 && keysym < 0x2ff) | ||
| 307 | return keysym_to_unicode_2a1_2fe[keysym - 0x2a1]; | ||
| 308 | else if (keysym > 0x3a1 && keysym < 0x3ff) | ||
| 309 | return keysym_to_unicode_3a2_3fe[keysym - 0x3a2]; | ||
| 310 | else if (keysym > 0x4a0 && keysym < 0x4e0) | ||
| 311 | return keysym_to_unicode_4a1_4df[keysym - 0x4a1]; | ||
| 312 | else if (keysym > 0x589 && keysym < 0x5ff) | ||
| 313 | return keysym_to_unicode_590_5fe[keysym - 0x590]; | ||
| 314 | else if (keysym > 0x67f && keysym < 0x700) | ||
| 315 | return keysym_to_unicode_680_6ff[keysym - 0x680]; | ||
| 316 | else if (keysym > 0x7a0 && keysym < 0x7fa) | ||
| 317 | return keysym_to_unicode_7a1_7f9[keysym - 0x7a1]; | ||
| 318 | else if (keysym > 0x8a3 && keysym < 0x8ff) | ||
| 319 | return keysym_to_unicode_8a4_8fe[keysym - 0x8a4]; | ||
| 320 | else if (keysym > 0x9de && keysym < 0x9f9) | ||
| 321 | return keysym_to_unicode_9df_9f8[keysym - 0x9df]; | ||
| 322 | else if (keysym > 0xaa0 && keysym < 0xaff) | ||
| 323 | return keysym_to_unicode_aa1_afe[keysym - 0xaa1]; | ||
| 324 | else if (keysym > 0xcde && keysym < 0xcfb) | ||
| 325 | return keysym_to_unicode_cdf_cfa[keysym - 0xcdf]; | ||
| 326 | else if (keysym > 0xda0 && keysym < 0xdfa) | ||
| 327 | return keysym_to_unicode_da1_df9[keysym - 0xda1]; | ||
| 328 | else if (keysym > 0xe9f && keysym < 0xf00) | ||
| 329 | return keysym_to_unicode_ea0_eff[keysym - 0xea0]; | ||
| 330 | else if (keysym > 0x12a0 && keysym < 0x12ff) | ||
| 331 | return keysym_to_unicode_12a1_12fe[keysym - 0x12a1]; | ||
| 332 | else if (keysym > 0x13bb && keysym < 0x13bf) | ||
| 333 | return keysym_to_unicode_13bc_13be[keysym - 0x13bc]; | ||
| 334 | else if (keysym > 0x14a0 && keysym < 0x1500) | ||
| 335 | return keysym_to_unicode_14a1_14ff[keysym - 0x14a1]; | ||
| 336 | else if (keysym > 0x15cf && keysym < 0x15f7) | ||
| 337 | return keysym_to_unicode_15d0_15f6[keysym - 0x15d0]; | ||
| 338 | else if (keysym > 0x169f && keysym < 0x16f7) | ||
| 339 | return keysym_to_unicode_16a0_16f6[keysym - 0x16a0]; | ||
| 340 | else if (keysym > 0x1e9e && keysym < 0x1f00) | ||
| 341 | return keysym_to_unicode_1e9f_1eff[keysym - 0x1e9f]; | ||
| 342 | else if (keysym > 0x209f && keysym < 0x20ad) | ||
| 343 | return keysym_to_unicode_20a0_20ac[keysym - 0x20a0]; | ||
| 344 | else | ||
| 345 | return 0; | ||
| 346 | } | ||
| 347 | |||
| 348 | #endif /* SDL_VIDEO_DRIVER_X11 */ | ||
| 349 | |||
diff --git a/contrib/SDL-3.2.8/src/events/imKStoUCS.h b/contrib/SDL-3.2.8/src/events/imKStoUCS.h new file mode 100644 index 0000000..4182c1b --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/imKStoUCS.h | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | #ifndef _imKStoUCS_h | ||
| 2 | #define _imKStoUCS_h | ||
| 3 | |||
| 4 | /* | ||
| 5 | Copyright (C) 2003-2006,2008 Jamey Sharp, Josh Triplett | ||
| 6 | Copyright © 2009 Red Hat, Inc. | ||
| 7 | Copyright 1990-1992,1999,2000,2004,2009,2010 Oracle and/or its affiliates. | ||
| 8 | All rights reserved. | ||
| 9 | |||
| 10 | Permission is hereby granted, free of charge, to any person obtaining a | ||
| 11 | copy of this software and associated documentation files (the "Software"), | ||
| 12 | to deal in the Software without restriction, including without limitation | ||
| 13 | the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 14 | and/or sell copies of the Software, and to permit persons to whom the | ||
| 15 | Software is furnished to do so, subject to the following conditions: | ||
| 16 | |||
| 17 | The above copyright notice and this permission notice (including the next | ||
| 18 | paragraph) shall be included in all copies or substantial portions of the | ||
| 19 | Software. | ||
| 20 | |||
| 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 22 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 23 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 24 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 25 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| 26 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| 27 | DEALINGS IN THE SOFTWARE. | ||
| 28 | */ | ||
| 29 | |||
| 30 | extern unsigned int SDL_KeySymToUcs4(Uint32 keysym); | ||
| 31 | |||
| 32 | #endif /* _imKStoUCS_h */ | ||
diff --git a/contrib/SDL-3.2.8/src/events/scancodes_darwin.h b/contrib/SDL-3.2.8/src/events/scancodes_darwin.h new file mode 100644 index 0000000..c3a2d4c --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/scancodes_darwin.h | |||
| @@ -0,0 +1,159 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | |||
| 22 | /* Mac virtual key code to SDL scancode mapping table | ||
| 23 | Sources: | ||
| 24 | - Inside Macintosh: Text <http://developer.apple.com/documentation/mac/Text/Text-571.html> | ||
| 25 | - Apple USB keyboard driver source <http://darwinsource.opendarwin.org/10.4.6.ppc/IOHIDFamily-172.8/IOHIDFamily/Cosmo_USB2ADB.c> | ||
| 26 | - experimentation on various ADB and USB ISO keyboards and one ADB ANSI keyboard | ||
| 27 | */ | ||
| 28 | /* *INDENT-OFF* */ // clang-format off | ||
| 29 | static const SDL_Scancode darwin_scancode_table[] = { | ||
| 30 | /* 0 */ SDL_SCANCODE_A, | ||
| 31 | /* 1 */ SDL_SCANCODE_S, | ||
| 32 | /* 2 */ SDL_SCANCODE_D, | ||
| 33 | /* 3 */ SDL_SCANCODE_F, | ||
| 34 | /* 4 */ SDL_SCANCODE_H, | ||
| 35 | /* 5 */ SDL_SCANCODE_G, | ||
| 36 | /* 6 */ SDL_SCANCODE_Z, | ||
| 37 | /* 7 */ SDL_SCANCODE_X, | ||
| 38 | /* 8 */ SDL_SCANCODE_C, | ||
| 39 | /* 9 */ SDL_SCANCODE_V, | ||
| 40 | /* 10 */ SDL_SCANCODE_NONUSBACKSLASH, // SDL_SCANCODE_NONUSBACKSLASH on ANSI and JIS keyboards (if this key would exist there), SDL_SCANCODE_GRAVE on ISO. (The USB keyboard driver actually translates these usage codes to different virtual key codes depending on whether the keyboard is ISO/ANSI/JIS. That's why you have to help it identify the keyboard type when you plug in a PC USB keyboard. It's a historical thing - ADB keyboards are wired this way.) | ||
| 41 | /* 11 */ SDL_SCANCODE_B, | ||
| 42 | /* 12 */ SDL_SCANCODE_Q, | ||
| 43 | /* 13 */ SDL_SCANCODE_W, | ||
| 44 | /* 14 */ SDL_SCANCODE_E, | ||
| 45 | /* 15 */ SDL_SCANCODE_R, | ||
| 46 | /* 16 */ SDL_SCANCODE_Y, | ||
| 47 | /* 17 */ SDL_SCANCODE_T, | ||
| 48 | /* 18 */ SDL_SCANCODE_1, | ||
| 49 | /* 19 */ SDL_SCANCODE_2, | ||
| 50 | /* 20 */ SDL_SCANCODE_3, | ||
| 51 | /* 21 */ SDL_SCANCODE_4, | ||
| 52 | /* 22 */ SDL_SCANCODE_6, | ||
| 53 | /* 23 */ SDL_SCANCODE_5, | ||
| 54 | /* 24 */ SDL_SCANCODE_EQUALS, | ||
| 55 | /* 25 */ SDL_SCANCODE_9, | ||
| 56 | /* 26 */ SDL_SCANCODE_7, | ||
| 57 | /* 27 */ SDL_SCANCODE_MINUS, | ||
| 58 | /* 28 */ SDL_SCANCODE_8, | ||
| 59 | /* 29 */ SDL_SCANCODE_0, | ||
| 60 | /* 30 */ SDL_SCANCODE_RIGHTBRACKET, | ||
| 61 | /* 31 */ SDL_SCANCODE_O, | ||
| 62 | /* 32 */ SDL_SCANCODE_U, | ||
| 63 | /* 33 */ SDL_SCANCODE_LEFTBRACKET, | ||
| 64 | /* 34 */ SDL_SCANCODE_I, | ||
| 65 | /* 35 */ SDL_SCANCODE_P, | ||
| 66 | /* 36 */ SDL_SCANCODE_RETURN, | ||
| 67 | /* 37 */ SDL_SCANCODE_L, | ||
| 68 | /* 38 */ SDL_SCANCODE_J, | ||
| 69 | /* 39 */ SDL_SCANCODE_APOSTROPHE, | ||
| 70 | /* 40 */ SDL_SCANCODE_K, | ||
| 71 | /* 41 */ SDL_SCANCODE_SEMICOLON, | ||
| 72 | /* 42 */ SDL_SCANCODE_BACKSLASH, | ||
| 73 | /* 43 */ SDL_SCANCODE_COMMA, | ||
| 74 | /* 44 */ SDL_SCANCODE_SLASH, | ||
| 75 | /* 45 */ SDL_SCANCODE_N, | ||
| 76 | /* 46 */ SDL_SCANCODE_M, | ||
| 77 | /* 47 */ SDL_SCANCODE_PERIOD, | ||
| 78 | /* 48 */ SDL_SCANCODE_TAB, | ||
| 79 | /* 49 */ SDL_SCANCODE_SPACE, | ||
| 80 | /* 50 */ SDL_SCANCODE_GRAVE, // SDL_SCANCODE_GRAVE on ANSI and JIS keyboards, SDL_SCANCODE_NONUSBACKSLASH on ISO (see comment about virtual key code 10 above) | ||
| 81 | /* 51 */ SDL_SCANCODE_BACKSPACE, | ||
| 82 | /* 52 */ SDL_SCANCODE_KP_ENTER, // keyboard enter on portables | ||
| 83 | /* 53 */ SDL_SCANCODE_ESCAPE, | ||
| 84 | /* 54 */ SDL_SCANCODE_RGUI, | ||
| 85 | /* 55 */ SDL_SCANCODE_LGUI, | ||
| 86 | /* 56 */ SDL_SCANCODE_LSHIFT, | ||
| 87 | /* 57 */ SDL_SCANCODE_CAPSLOCK, | ||
| 88 | /* 58 */ SDL_SCANCODE_LALT, | ||
| 89 | /* 59 */ SDL_SCANCODE_LCTRL, | ||
| 90 | /* 60 */ SDL_SCANCODE_RSHIFT, | ||
| 91 | /* 61 */ SDL_SCANCODE_RALT, | ||
| 92 | /* 62 */ SDL_SCANCODE_RCTRL, | ||
| 93 | /* 63 */ SDL_SCANCODE_RGUI, // fn on portables, acts as a hardware-level modifier already, so we don't generate events for it, also XK_Meta_R | ||
| 94 | /* 64 */ SDL_SCANCODE_F17, | ||
| 95 | /* 65 */ SDL_SCANCODE_KP_PERIOD, | ||
| 96 | /* 66 */ SDL_SCANCODE_UNKNOWN, // unknown (unused?) | ||
| 97 | /* 67 */ SDL_SCANCODE_KP_MULTIPLY, | ||
| 98 | /* 68 */ SDL_SCANCODE_UNKNOWN, // unknown (unused?) | ||
| 99 | /* 69 */ SDL_SCANCODE_KP_PLUS, | ||
| 100 | /* 70 */ SDL_SCANCODE_UNKNOWN, // unknown (unused?) | ||
| 101 | /* 71 */ SDL_SCANCODE_NUMLOCKCLEAR, | ||
| 102 | /* 72 */ SDL_SCANCODE_VOLUMEUP, | ||
| 103 | /* 73 */ SDL_SCANCODE_VOLUMEDOWN, | ||
| 104 | /* 74 */ SDL_SCANCODE_MUTE, | ||
| 105 | /* 75 */ SDL_SCANCODE_KP_DIVIDE, | ||
| 106 | /* 76 */ SDL_SCANCODE_KP_ENTER, // keypad enter on external keyboards, fn-return on portables | ||
| 107 | /* 77 */ SDL_SCANCODE_UNKNOWN, // unknown (unused?) | ||
| 108 | /* 78 */ SDL_SCANCODE_KP_MINUS, | ||
| 109 | /* 79 */ SDL_SCANCODE_F18, | ||
| 110 | /* 80 */ SDL_SCANCODE_F19, | ||
| 111 | /* 81 */ SDL_SCANCODE_KP_EQUALS, | ||
| 112 | /* 82 */ SDL_SCANCODE_KP_0, | ||
| 113 | /* 83 */ SDL_SCANCODE_KP_1, | ||
| 114 | /* 84 */ SDL_SCANCODE_KP_2, | ||
| 115 | /* 85 */ SDL_SCANCODE_KP_3, | ||
| 116 | /* 86 */ SDL_SCANCODE_KP_4, | ||
| 117 | /* 87 */ SDL_SCANCODE_KP_5, | ||
| 118 | /* 88 */ SDL_SCANCODE_KP_6, | ||
| 119 | /* 89 */ SDL_SCANCODE_KP_7, | ||
| 120 | /* 90 */ SDL_SCANCODE_UNKNOWN, // unknown (unused?) | ||
| 121 | /* 91 */ SDL_SCANCODE_KP_8, | ||
| 122 | /* 92 */ SDL_SCANCODE_KP_9, | ||
| 123 | /* 93 */ SDL_SCANCODE_INTERNATIONAL3, // Cosmo_USB2ADB.c says "Yen (JIS)" | ||
| 124 | /* 94 */ SDL_SCANCODE_INTERNATIONAL1, // Cosmo_USB2ADB.c says "Ro (JIS)" | ||
| 125 | /* 95 */ SDL_SCANCODE_KP_COMMA, // Cosmo_USB2ADB.c says ", JIS only" | ||
| 126 | /* 96 */ SDL_SCANCODE_F5, | ||
| 127 | /* 97 */ SDL_SCANCODE_F6, | ||
| 128 | /* 98 */ SDL_SCANCODE_F7, | ||
| 129 | /* 99 */ SDL_SCANCODE_F3, | ||
| 130 | /* 100 */ SDL_SCANCODE_F8, | ||
| 131 | /* 101 */ SDL_SCANCODE_F9, | ||
| 132 | /* 102 */ SDL_SCANCODE_LANG2, // Cosmo_USB2ADB.c says "Eisu" | ||
| 133 | /* 103 */ SDL_SCANCODE_F11, | ||
| 134 | /* 104 */ SDL_SCANCODE_LANG1, // Cosmo_USB2ADB.c says "Kana" | ||
| 135 | /* 105 */ SDL_SCANCODE_PRINTSCREEN, // On ADB keyboards, this key is labeled "F13/print screen". Problem: USB has different usage codes for these two functions. On Apple USB keyboards, the key is labeled "F13" and sends the F13 usage code (SDL_SCANCODE_F13). I decided to use SDL_SCANCODE_PRINTSCREEN here nevertheless since SDL applications are more likely to assume the presence of a print screen key than an F13 key. | ||
| 136 | /* 106 */ SDL_SCANCODE_F16, | ||
| 137 | /* 107 */ SDL_SCANCODE_SCROLLLOCK, // F14/scroll lock, see comment about F13/print screen above | ||
| 138 | /* 108 */ SDL_SCANCODE_UNKNOWN, // unknown (unused?) | ||
| 139 | /* 109 */ SDL_SCANCODE_F10, | ||
| 140 | /* 110 */ SDL_SCANCODE_APPLICATION, // windows contextual menu key, fn-enter on portables | ||
| 141 | /* 111 */ SDL_SCANCODE_F12, | ||
| 142 | /* 112 */ SDL_SCANCODE_UNKNOWN, // unknown (unused?) | ||
| 143 | /* 113 */ SDL_SCANCODE_PAUSE, // F15/pause, see comment about F13/print screen above | ||
| 144 | /* 114 */ SDL_SCANCODE_INSERT, // the key is actually labeled "help" on Apple keyboards, and works as such in Mac OS, but it sends the "insert" usage code even on Apple USB keyboards | ||
| 145 | /* 115 */ SDL_SCANCODE_HOME, | ||
| 146 | /* 116 */ SDL_SCANCODE_PAGEUP, | ||
| 147 | /* 117 */ SDL_SCANCODE_DELETE, | ||
| 148 | /* 118 */ SDL_SCANCODE_F4, | ||
| 149 | /* 119 */ SDL_SCANCODE_END, | ||
| 150 | /* 120 */ SDL_SCANCODE_F2, | ||
| 151 | /* 121 */ SDL_SCANCODE_PAGEDOWN, | ||
| 152 | /* 122 */ SDL_SCANCODE_F1, | ||
| 153 | /* 123 */ SDL_SCANCODE_LEFT, | ||
| 154 | /* 124 */ SDL_SCANCODE_RIGHT, | ||
| 155 | /* 125 */ SDL_SCANCODE_DOWN, | ||
| 156 | /* 126 */ SDL_SCANCODE_UP, | ||
| 157 | /* 127 */ SDL_SCANCODE_POWER | ||
| 158 | }; | ||
| 159 | /* *INDENT-ON* */ // clang-format on | ||
diff --git a/contrib/SDL-3.2.8/src/events/scancodes_linux.h b/contrib/SDL-3.2.8/src/events/scancodes_linux.h new file mode 100644 index 0000000..2deeb9a --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/scancodes_linux.h | |||
| @@ -0,0 +1,848 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | /* Linux virtual key code to SDL_Keycode mapping table | ||
| 24 | Sources: | ||
| 25 | - Linux kernel source input.h | ||
| 26 | */ | ||
| 27 | /* *INDENT-OFF* */ // clang-format off | ||
| 28 | static SDL_Scancode const linux_scancode_table[] = { | ||
| 29 | /* 0, 0x000 */ SDL_SCANCODE_UNKNOWN, // KEY_RESERVED | ||
| 30 | /* 1, 0x001 */ SDL_SCANCODE_ESCAPE, // KEY_ESC | ||
| 31 | /* 2, 0x002 */ SDL_SCANCODE_1, // KEY_1 | ||
| 32 | /* 3, 0x003 */ SDL_SCANCODE_2, // KEY_2 | ||
| 33 | /* 4, 0x004 */ SDL_SCANCODE_3, // KEY_3 | ||
| 34 | /* 5, 0x005 */ SDL_SCANCODE_4, // KEY_4 | ||
| 35 | /* 6, 0x006 */ SDL_SCANCODE_5, // KEY_5 | ||
| 36 | /* 7, 0x007 */ SDL_SCANCODE_6, // KEY_6 | ||
| 37 | /* 8, 0x008 */ SDL_SCANCODE_7, // KEY_7 | ||
| 38 | /* 9, 0x009 */ SDL_SCANCODE_8, // KEY_8 | ||
| 39 | /* 10, 0x00a */ SDL_SCANCODE_9, // KEY_9 | ||
| 40 | /* 11, 0x00b */ SDL_SCANCODE_0, // KEY_0 | ||
| 41 | /* 12, 0x00c */ SDL_SCANCODE_MINUS, // KEY_MINUS | ||
| 42 | /* 13, 0x00d */ SDL_SCANCODE_EQUALS, // KEY_EQUAL | ||
| 43 | /* 14, 0x00e */ SDL_SCANCODE_BACKSPACE, // KEY_BACKSPACE | ||
| 44 | /* 15, 0x00f */ SDL_SCANCODE_TAB, // KEY_TAB | ||
| 45 | /* 16, 0x010 */ SDL_SCANCODE_Q, // KEY_Q | ||
| 46 | /* 17, 0x011 */ SDL_SCANCODE_W, // KEY_W | ||
| 47 | /* 18, 0x012 */ SDL_SCANCODE_E, // KEY_E | ||
| 48 | /* 19, 0x013 */ SDL_SCANCODE_R, // KEY_R | ||
| 49 | /* 20, 0x014 */ SDL_SCANCODE_T, // KEY_T | ||
| 50 | /* 21, 0x015 */ SDL_SCANCODE_Y, // KEY_Y | ||
| 51 | /* 22, 0x016 */ SDL_SCANCODE_U, // KEY_U | ||
| 52 | /* 23, 0x017 */ SDL_SCANCODE_I, // KEY_I | ||
| 53 | /* 24, 0x018 */ SDL_SCANCODE_O, // KEY_O | ||
| 54 | /* 25, 0x019 */ SDL_SCANCODE_P, // KEY_P | ||
| 55 | /* 26, 0x01a */ SDL_SCANCODE_LEFTBRACKET, // KEY_LEFTBRACE | ||
| 56 | /* 27, 0x01b */ SDL_SCANCODE_RIGHTBRACKET, // KEY_RIGHTBRACE | ||
| 57 | /* 28, 0x01c */ SDL_SCANCODE_RETURN, // KEY_ENTER | ||
| 58 | /* 29, 0x01d */ SDL_SCANCODE_LCTRL, // KEY_LEFTCTRL | ||
| 59 | /* 30, 0x01e */ SDL_SCANCODE_A, // KEY_A | ||
| 60 | /* 31, 0x01f */ SDL_SCANCODE_S, // KEY_S | ||
| 61 | /* 32, 0x020 */ SDL_SCANCODE_D, // KEY_D | ||
| 62 | /* 33, 0x021 */ SDL_SCANCODE_F, // KEY_F | ||
| 63 | /* 34, 0x022 */ SDL_SCANCODE_G, // KEY_G | ||
| 64 | /* 35, 0x023 */ SDL_SCANCODE_H, // KEY_H | ||
| 65 | /* 36, 0x024 */ SDL_SCANCODE_J, // KEY_J | ||
| 66 | /* 37, 0x025 */ SDL_SCANCODE_K, // KEY_K | ||
| 67 | /* 38, 0x026 */ SDL_SCANCODE_L, // KEY_L | ||
| 68 | /* 39, 0x027 */ SDL_SCANCODE_SEMICOLON, // KEY_SEMICOLON | ||
| 69 | /* 40, 0x028 */ SDL_SCANCODE_APOSTROPHE, // KEY_APOSTROPHE | ||
| 70 | /* 41, 0x029 */ SDL_SCANCODE_GRAVE, // KEY_GRAVE | ||
| 71 | /* 42, 0x02a */ SDL_SCANCODE_LSHIFT, // KEY_LEFTSHIFT | ||
| 72 | /* 43, 0x02b */ SDL_SCANCODE_BACKSLASH, // KEY_BACKSLASH | ||
| 73 | /* 44, 0x02c */ SDL_SCANCODE_Z, // KEY_Z | ||
| 74 | /* 45, 0x02d */ SDL_SCANCODE_X, // KEY_X | ||
| 75 | /* 46, 0x02e */ SDL_SCANCODE_C, // KEY_C | ||
| 76 | /* 47, 0x02f */ SDL_SCANCODE_V, // KEY_V | ||
| 77 | /* 48, 0x030 */ SDL_SCANCODE_B, // KEY_B | ||
| 78 | /* 49, 0x031 */ SDL_SCANCODE_N, // KEY_N | ||
| 79 | /* 50, 0x032 */ SDL_SCANCODE_M, // KEY_M | ||
| 80 | /* 51, 0x033 */ SDL_SCANCODE_COMMA, // KEY_COMMA | ||
| 81 | /* 52, 0x034 */ SDL_SCANCODE_PERIOD, // KEY_DOT | ||
| 82 | /* 53, 0x035 */ SDL_SCANCODE_SLASH, // KEY_SLASH | ||
| 83 | /* 54, 0x036 */ SDL_SCANCODE_RSHIFT, // KEY_RIGHTSHIFT | ||
| 84 | /* 55, 0x037 */ SDL_SCANCODE_KP_MULTIPLY, // KEY_KPASTERISK | ||
| 85 | /* 56, 0x038 */ SDL_SCANCODE_LALT, // KEY_LEFTALT | ||
| 86 | /* 57, 0x039 */ SDL_SCANCODE_SPACE, // KEY_SPACE | ||
| 87 | /* 58, 0x03a */ SDL_SCANCODE_CAPSLOCK, // KEY_CAPSLOCK | ||
| 88 | /* 59, 0x03b */ SDL_SCANCODE_F1, // KEY_F1 | ||
| 89 | /* 60, 0x03c */ SDL_SCANCODE_F2, // KEY_F2 | ||
| 90 | /* 61, 0x03d */ SDL_SCANCODE_F3, // KEY_F3 | ||
| 91 | /* 62, 0x03e */ SDL_SCANCODE_F4, // KEY_F4 | ||
| 92 | /* 63, 0x03f */ SDL_SCANCODE_F5, // KEY_F5 | ||
| 93 | /* 64, 0x040 */ SDL_SCANCODE_F6, // KEY_F6 | ||
| 94 | /* 65, 0x041 */ SDL_SCANCODE_F7, // KEY_F7 | ||
| 95 | /* 66, 0x042 */ SDL_SCANCODE_F8, // KEY_F8 | ||
| 96 | /* 67, 0x043 */ SDL_SCANCODE_F9, // KEY_F9 | ||
| 97 | /* 68, 0x044 */ SDL_SCANCODE_F10, // KEY_F10 | ||
| 98 | /* 69, 0x045 */ SDL_SCANCODE_NUMLOCKCLEAR, // KEY_NUMLOCK | ||
| 99 | /* 70, 0x046 */ SDL_SCANCODE_SCROLLLOCK, // KEY_SCROLLLOCK | ||
| 100 | /* 71, 0x047 */ SDL_SCANCODE_KP_7, // KEY_KP7 | ||
| 101 | /* 72, 0x048 */ SDL_SCANCODE_KP_8, // KEY_KP8 | ||
| 102 | /* 73, 0x049 */ SDL_SCANCODE_KP_9, // KEY_KP9 | ||
| 103 | /* 74, 0x04a */ SDL_SCANCODE_KP_MINUS, // KEY_KPMINUS | ||
| 104 | /* 75, 0x04b */ SDL_SCANCODE_KP_4, // KEY_KP4 | ||
| 105 | /* 76, 0x04c */ SDL_SCANCODE_KP_5, // KEY_KP5 | ||
| 106 | /* 77, 0x04d */ SDL_SCANCODE_KP_6, // KEY_KP6 | ||
| 107 | /* 78, 0x04e */ SDL_SCANCODE_KP_PLUS, // KEY_KPPLUS | ||
| 108 | /* 79, 0x04f */ SDL_SCANCODE_KP_1, // KEY_KP1 | ||
| 109 | /* 80, 0x050 */ SDL_SCANCODE_KP_2, // KEY_KP2 | ||
| 110 | /* 81, 0x051 */ SDL_SCANCODE_KP_3, // KEY_KP3 | ||
| 111 | /* 82, 0x052 */ SDL_SCANCODE_KP_0, // KEY_KP0 | ||
| 112 | /* 83, 0x053 */ SDL_SCANCODE_KP_PERIOD, // KEY_KPDOT | ||
| 113 | /* 84, 0x054 */ SDL_SCANCODE_UNKNOWN, | ||
| 114 | /* 85, 0x055 */ SDL_SCANCODE_LANG5, // KEY_ZENKAKUHANKAKU | ||
| 115 | /* 86, 0x056 */ SDL_SCANCODE_NONUSBACKSLASH, // KEY_102ND | ||
| 116 | /* 87, 0x057 */ SDL_SCANCODE_F11, // KEY_F11 | ||
| 117 | /* 88, 0x058 */ SDL_SCANCODE_F12, // KEY_F12 | ||
| 118 | /* 89, 0x059 */ SDL_SCANCODE_INTERNATIONAL1, // KEY_RO | ||
| 119 | /* 90, 0x05a */ SDL_SCANCODE_LANG3, // KEY_KATAKANA | ||
| 120 | /* 91, 0x05b */ SDL_SCANCODE_LANG4, // KEY_HIRAGANA | ||
| 121 | /* 92, 0x05c */ SDL_SCANCODE_INTERNATIONAL4, // KEY_HENKAN | ||
| 122 | /* 93, 0x05d */ SDL_SCANCODE_INTERNATIONAL2, // KEY_KATAKANAHIRAGANA | ||
| 123 | /* 94, 0x05e */ SDL_SCANCODE_INTERNATIONAL5, // KEY_MUHENKAN | ||
| 124 | /* 95, 0x05f */ SDL_SCANCODE_INTERNATIONAL5, // KEY_KPJPCOMMA | ||
| 125 | /* 96, 0x060 */ SDL_SCANCODE_KP_ENTER, // KEY_KPENTER | ||
| 126 | /* 97, 0x061 */ SDL_SCANCODE_RCTRL, // KEY_RIGHTCTRL | ||
| 127 | /* 98, 0x062 */ SDL_SCANCODE_KP_DIVIDE, // KEY_KPSLASH | ||
| 128 | /* 99, 0x063 */ SDL_SCANCODE_SYSREQ, // KEY_SYSRQ | ||
| 129 | /* 100, 0x064 */ SDL_SCANCODE_RALT, // KEY_RIGHTALT | ||
| 130 | /* 101, 0x065 */ SDL_SCANCODE_UNKNOWN, // KEY_LINEFEED | ||
| 131 | /* 102, 0x066 */ SDL_SCANCODE_HOME, // KEY_HOME | ||
| 132 | /* 103, 0x067 */ SDL_SCANCODE_UP, // KEY_UP | ||
| 133 | /* 104, 0x068 */ SDL_SCANCODE_PAGEUP, // KEY_PAGEUP | ||
| 134 | /* 105, 0x069 */ SDL_SCANCODE_LEFT, // KEY_LEFT | ||
| 135 | /* 106, 0x06a */ SDL_SCANCODE_RIGHT, // KEY_RIGHT | ||
| 136 | /* 107, 0x06b */ SDL_SCANCODE_END, // KEY_END | ||
| 137 | /* 108, 0x06c */ SDL_SCANCODE_DOWN, // KEY_DOWN | ||
| 138 | /* 109, 0x06d */ SDL_SCANCODE_PAGEDOWN, // KEY_PAGEDOWN | ||
| 139 | /* 110, 0x06e */ SDL_SCANCODE_INSERT, // KEY_INSERT | ||
| 140 | /* 111, 0x06f */ SDL_SCANCODE_DELETE, // KEY_DELETE | ||
| 141 | /* 112, 0x070 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO | ||
| 142 | /* 113, 0x071 */ SDL_SCANCODE_MUTE, // KEY_MUTE | ||
| 143 | /* 114, 0x072 */ SDL_SCANCODE_VOLUMEDOWN, // KEY_VOLUMEDOWN | ||
| 144 | /* 115, 0x073 */ SDL_SCANCODE_VOLUMEUP, // KEY_VOLUMEUP | ||
| 145 | /* 116, 0x074 */ SDL_SCANCODE_POWER, // KEY_POWER | ||
| 146 | /* 117, 0x075 */ SDL_SCANCODE_KP_EQUALS, // KEY_KPEQUAL | ||
| 147 | /* 118, 0x076 */ SDL_SCANCODE_KP_PLUSMINUS, // KEY_KPPLUSMINUS | ||
| 148 | /* 119, 0x077 */ SDL_SCANCODE_PAUSE, // KEY_PAUSE | ||
| 149 | /* 120, 0x078 */ SDL_SCANCODE_UNKNOWN, // KEY_SCALE | ||
| 150 | /* 121, 0x079 */ SDL_SCANCODE_KP_COMMA, // KEY_KPCOMMA | ||
| 151 | /* 122, 0x07a */ SDL_SCANCODE_LANG1, // KEY_HANGEUL | ||
| 152 | /* 123, 0x07b */ SDL_SCANCODE_LANG2, // KEY_HANJA | ||
| 153 | /* 124, 0x07c */ SDL_SCANCODE_INTERNATIONAL3, // KEY_YEN | ||
| 154 | /* 125, 0x07d */ SDL_SCANCODE_LGUI, // KEY_LEFTMETA | ||
| 155 | /* 126, 0x07e */ SDL_SCANCODE_RGUI, // KEY_RIGHTMETA | ||
| 156 | /* 127, 0x07f */ SDL_SCANCODE_APPLICATION, // KEY_COMPOSE | ||
| 157 | /* 128, 0x080 */ SDL_SCANCODE_STOP, // KEY_STOP | ||
| 158 | /* 129, 0x081 */ SDL_SCANCODE_AGAIN, // KEY_AGAIN | ||
| 159 | /* 130, 0x082 */ SDL_SCANCODE_AC_PROPERTIES, // KEY_PROPS | ||
| 160 | /* 131, 0x083 */ SDL_SCANCODE_UNDO, // KEY_UNDO | ||
| 161 | /* 132, 0x084 */ SDL_SCANCODE_UNKNOWN, // KEY_FRONT | ||
| 162 | /* 133, 0x085 */ SDL_SCANCODE_COPY, // KEY_COPY | ||
| 163 | /* 134, 0x086 */ SDL_SCANCODE_AC_OPEN, // KEY_OPEN | ||
| 164 | /* 135, 0x087 */ SDL_SCANCODE_PASTE, // KEY_PASTE | ||
| 165 | /* 136, 0x088 */ SDL_SCANCODE_FIND, // KEY_FIND | ||
| 166 | /* 137, 0x089 */ SDL_SCANCODE_CUT, // KEY_CUT | ||
| 167 | /* 138, 0x08a */ SDL_SCANCODE_HELP, // KEY_HELP | ||
| 168 | /* 139, 0x08b */ SDL_SCANCODE_MENU, // KEY_MENU | ||
| 169 | /* 140, 0x08c */ SDL_SCANCODE_UNKNOWN, // KEY_CALC | ||
| 170 | /* 141, 0x08d */ SDL_SCANCODE_UNKNOWN, // KEY_SETUP | ||
| 171 | /* 142, 0x08e */ SDL_SCANCODE_SLEEP, // KEY_SLEEP | ||
| 172 | /* 143, 0x08f */ SDL_SCANCODE_WAKE, // KEY_WAKEUP | ||
| 173 | /* 144, 0x090 */ SDL_SCANCODE_UNKNOWN, // KEY_FILE | ||
| 174 | /* 145, 0x091 */ SDL_SCANCODE_UNKNOWN, // KEY_SENDFILE | ||
| 175 | /* 146, 0x092 */ SDL_SCANCODE_UNKNOWN, // KEY_DELETEFILE | ||
| 176 | /* 147, 0x093 */ SDL_SCANCODE_UNKNOWN, // KEY_XFER | ||
| 177 | /* 148, 0x094 */ SDL_SCANCODE_UNKNOWN, // KEY_PROG1 | ||
| 178 | /* 149, 0x095 */ SDL_SCANCODE_UNKNOWN, // KEY_PROG2 | ||
| 179 | /* 150, 0x096 */ SDL_SCANCODE_UNKNOWN, // KEY_WWW | ||
| 180 | /* 151, 0x097 */ SDL_SCANCODE_UNKNOWN, // KEY_MSDOS | ||
| 181 | /* 152, 0x098 */ SDL_SCANCODE_UNKNOWN, // KEY_COFFEE | ||
| 182 | /* 153, 0x099 */ SDL_SCANCODE_UNKNOWN, // KEY_ROTATE_DISPLAY | ||
| 183 | /* 154, 0x09a */ SDL_SCANCODE_UNKNOWN, // KEY_CYCLEWINDOWS | ||
| 184 | /* 155, 0x09b */ SDL_SCANCODE_UNKNOWN, // KEY_MAIL | ||
| 185 | /* 156, 0x09c */ SDL_SCANCODE_AC_BOOKMARKS, // KEY_BOOKMARKS | ||
| 186 | /* 157, 0x09d */ SDL_SCANCODE_UNKNOWN, // KEY_COMPUTER | ||
| 187 | /* 158, 0x09e */ SDL_SCANCODE_AC_BACK, // KEY_BACK | ||
| 188 | /* 159, 0x09f */ SDL_SCANCODE_AC_FORWARD, // KEY_FORWARD | ||
| 189 | /* 160, 0x0a0 */ SDL_SCANCODE_UNKNOWN, // KEY_CLOSECD | ||
| 190 | /* 161, 0x0a1 */ SDL_SCANCODE_MEDIA_EJECT, // KEY_EJECTCD | ||
| 191 | /* 162, 0x0a2 */ SDL_SCANCODE_MEDIA_EJECT, // KEY_EJECTCLOSECD | ||
| 192 | /* 163, 0x0a3 */ SDL_SCANCODE_MEDIA_NEXT_TRACK, // KEY_NEXTSONG | ||
| 193 | /* 164, 0x0a4 */ SDL_SCANCODE_MEDIA_PLAY_PAUSE, // KEY_PLAYPAUSE | ||
| 194 | /* 165, 0x0a5 */ SDL_SCANCODE_MEDIA_PREVIOUS_TRACK, // KEY_PREVIOUSSONG | ||
| 195 | /* 166, 0x0a6 */ SDL_SCANCODE_MEDIA_STOP, // KEY_STOPCD | ||
| 196 | /* 167, 0x0a7 */ SDL_SCANCODE_MEDIA_RECORD, // KEY_RECORD | ||
| 197 | /* 168, 0x0a8 */ SDL_SCANCODE_MEDIA_REWIND, // KEY_REWIND | ||
| 198 | /* 169, 0x0a9 */ SDL_SCANCODE_UNKNOWN, // KEY_PHONE | ||
| 199 | /* 170, 0x0aa */ SDL_SCANCODE_UNKNOWN, // KEY_ISO | ||
| 200 | /* 171, 0x0ab */ SDL_SCANCODE_UNKNOWN, // KEY_CONFIG | ||
| 201 | /* 172, 0x0ac */ SDL_SCANCODE_AC_HOME, // KEY_HOMEPAGE | ||
| 202 | /* 173, 0x0ad */ SDL_SCANCODE_AC_REFRESH, // KEY_REFRESH | ||
| 203 | /* 174, 0x0ae */ SDL_SCANCODE_AC_EXIT, // KEY_EXIT | ||
| 204 | /* 175, 0x0af */ SDL_SCANCODE_UNKNOWN, // KEY_MOVE | ||
| 205 | /* 176, 0x0b0 */ SDL_SCANCODE_UNKNOWN, // KEY_EDIT | ||
| 206 | /* 177, 0x0b1 */ SDL_SCANCODE_UNKNOWN, // KEY_SCROLLUP | ||
| 207 | /* 178, 0x0b2 */ SDL_SCANCODE_UNKNOWN, // KEY_SCROLLDOWN | ||
| 208 | /* 179, 0x0b3 */ SDL_SCANCODE_KP_LEFTPAREN, // KEY_KPLEFTPAREN | ||
| 209 | /* 180, 0x0b4 */ SDL_SCANCODE_KP_RIGHTPAREN, // KEY_KPRIGHTPAREN | ||
| 210 | /* 181, 0x0b5 */ SDL_SCANCODE_AC_NEW, // KEY_NEW | ||
| 211 | /* 182, 0x0b6 */ SDL_SCANCODE_AGAIN, // KEY_REDO | ||
| 212 | /* 183, 0x0b7 */ SDL_SCANCODE_F13, // KEY_F13 | ||
| 213 | /* 184, 0x0b8 */ SDL_SCANCODE_F14, // KEY_F14 | ||
| 214 | /* 185, 0x0b9 */ SDL_SCANCODE_F15, // KEY_F15 | ||
| 215 | /* 186, 0x0ba */ SDL_SCANCODE_F16, // KEY_F16 | ||
| 216 | /* 187, 0x0bb */ SDL_SCANCODE_F17, // KEY_F17 | ||
| 217 | /* 188, 0x0bc */ SDL_SCANCODE_F18, // KEY_F18 | ||
| 218 | /* 189, 0x0bd */ SDL_SCANCODE_F19, // KEY_F19 | ||
| 219 | /* 190, 0x0be */ SDL_SCANCODE_F20, // KEY_F20 | ||
| 220 | /* 191, 0x0bf */ SDL_SCANCODE_F21, // KEY_F21 | ||
| 221 | /* 192, 0x0c0 */ SDL_SCANCODE_F22, // KEY_F22 | ||
| 222 | /* 193, 0x0c1 */ SDL_SCANCODE_F23, // KEY_F23 | ||
| 223 | /* 194, 0x0c2 */ SDL_SCANCODE_F24, // KEY_F24 | ||
| 224 | /* 195, 0x0c3 */ SDL_SCANCODE_UNKNOWN, | ||
| 225 | /* 196, 0x0c4 */ SDL_SCANCODE_UNKNOWN, | ||
| 226 | /* 197, 0x0c5 */ SDL_SCANCODE_UNKNOWN, | ||
| 227 | /* 198, 0x0c6 */ SDL_SCANCODE_UNKNOWN, | ||
| 228 | /* 199, 0x0c7 */ SDL_SCANCODE_UNKNOWN, | ||
| 229 | /* 200, 0x0c8 */ SDL_SCANCODE_MEDIA_PLAY, // KEY_PLAYCD | ||
| 230 | /* 201, 0x0c9 */ SDL_SCANCODE_MEDIA_PAUSE, // KEY_PAUSECD | ||
| 231 | /* 202, 0x0ca */ SDL_SCANCODE_UNKNOWN, // KEY_PROG3 | ||
| 232 | /* 203, 0x0cb */ SDL_SCANCODE_UNKNOWN, // KEY_PROG4 | ||
| 233 | /* 204, 0x0cc */ SDL_SCANCODE_UNKNOWN, // KEY_ALL_APPLICATIONS | ||
| 234 | /* 205, 0x0cd */ SDL_SCANCODE_UNKNOWN, // KEY_SUSPEND | ||
| 235 | /* 206, 0x0ce */ SDL_SCANCODE_AC_CLOSE, // KEY_CLOSE | ||
| 236 | /* 207, 0x0cf */ SDL_SCANCODE_MEDIA_PLAY, // KEY_PLAY | ||
| 237 | /* 208, 0x0d0 */ SDL_SCANCODE_MEDIA_FAST_FORWARD, // KEY_FASTFORWARD | ||
| 238 | /* 209, 0x0d1 */ SDL_SCANCODE_UNKNOWN, // KEY_BASSBOOST | ||
| 239 | /* 210, 0x0d2 */ SDL_SCANCODE_PRINTSCREEN, // KEY_PRINT | ||
| 240 | /* 211, 0x0d3 */ SDL_SCANCODE_UNKNOWN, // KEY_HP | ||
| 241 | /* 212, 0x0d4 */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA | ||
| 242 | /* 213, 0x0d5 */ SDL_SCANCODE_UNKNOWN, // KEY_SOUND | ||
| 243 | /* 214, 0x0d6 */ SDL_SCANCODE_UNKNOWN, // KEY_QUESTION | ||
| 244 | /* 215, 0x0d7 */ SDL_SCANCODE_UNKNOWN, // KEY_EMAIL | ||
| 245 | /* 216, 0x0d8 */ SDL_SCANCODE_UNKNOWN, // KEY_CHAT | ||
| 246 | /* 217, 0x0d9 */ SDL_SCANCODE_AC_SEARCH, // KEY_SEARCH | ||
| 247 | /* 218, 0x0da */ SDL_SCANCODE_UNKNOWN, // KEY_CONNECT | ||
| 248 | /* 219, 0x0db */ SDL_SCANCODE_UNKNOWN, // KEY_FINANCE | ||
| 249 | /* 220, 0x0dc */ SDL_SCANCODE_UNKNOWN, // KEY_SPORT | ||
| 250 | /* 221, 0x0dd */ SDL_SCANCODE_UNKNOWN, // KEY_SHOP | ||
| 251 | /* 222, 0x0de */ SDL_SCANCODE_ALTERASE, // KEY_ALTERASE | ||
| 252 | /* 223, 0x0df */ SDL_SCANCODE_CANCEL, // KEY_CANCEL | ||
| 253 | /* 224, 0x0e0 */ SDL_SCANCODE_UNKNOWN, // KEY_BRIGHTNESSDOWN | ||
| 254 | /* 225, 0x0e1 */ SDL_SCANCODE_UNKNOWN, // KEY_BRIGHTNESSUP | ||
| 255 | /* 226, 0x0e2 */ SDL_SCANCODE_MEDIA_SELECT, // KEY_MEDIA | ||
| 256 | /* 227, 0x0e3 */ SDL_SCANCODE_UNKNOWN, // KEY_SWITCHVIDEOMODE | ||
| 257 | /* 228, 0x0e4 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDILLUMTOGGLE | ||
| 258 | /* 229, 0x0e5 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDILLUMDOWN | ||
| 259 | /* 230, 0x0e6 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDILLUMUP | ||
| 260 | /* 231, 0x0e7 */ SDL_SCANCODE_UNKNOWN, // KEY_SEND | ||
| 261 | /* 232, 0x0e8 */ SDL_SCANCODE_UNKNOWN, // KEY_REPLY | ||
| 262 | /* 233, 0x0e9 */ SDL_SCANCODE_UNKNOWN, // KEY_FORWARDMAIL | ||
| 263 | /* 234, 0x0ea */ SDL_SCANCODE_AC_SAVE, // KEY_SAVE | ||
| 264 | /* 235, 0x0eb */ SDL_SCANCODE_UNKNOWN, // KEY_DOCUMENTS | ||
| 265 | /* 236, 0x0ec */ SDL_SCANCODE_UNKNOWN, // KEY_BATTERY | ||
| 266 | /* 237, 0x0ed */ SDL_SCANCODE_UNKNOWN, // KEY_BLUETOOTH | ||
| 267 | /* 238, 0x0ee */ SDL_SCANCODE_UNKNOWN, // KEY_WLAN | ||
| 268 | /* 239, 0x0ef */ SDL_SCANCODE_UNKNOWN, // KEY_UWB | ||
| 269 | /* 240, 0x0f0 */ SDL_SCANCODE_UNKNOWN, // KEY_UNKNOWN | ||
| 270 | /* 241, 0x0f1 */ SDL_SCANCODE_UNKNOWN, // KEY_VIDEO_NEXT | ||
| 271 | /* 242, 0x0f2 */ SDL_SCANCODE_UNKNOWN, // KEY_VIDEO_PREV | ||
| 272 | /* 243, 0x0f3 */ SDL_SCANCODE_UNKNOWN, // KEY_BRIGHTNESS_CYCLE | ||
| 273 | /* 244, 0x0f4 */ SDL_SCANCODE_UNKNOWN, // KEY_BRIGHTNESS_AUTO | ||
| 274 | /* 245, 0x0f5 */ SDL_SCANCODE_UNKNOWN, // KEY_DISPLAY_OFF | ||
| 275 | /* 246, 0x0f6 */ SDL_SCANCODE_UNKNOWN, // KEY_WWAN | ||
| 276 | /* 247, 0x0f7 */ SDL_SCANCODE_UNKNOWN, // KEY_RFKILL | ||
| 277 | /* 248, 0x0f8 */ SDL_SCANCODE_UNKNOWN, // KEY_MICMUTE | ||
| 278 | /* 249, 0x0f9 */ SDL_SCANCODE_UNKNOWN, | ||
| 279 | /* 250, 0x0fa */ SDL_SCANCODE_UNKNOWN, | ||
| 280 | /* 251, 0x0fb */ SDL_SCANCODE_UNKNOWN, | ||
| 281 | /* 252, 0x0fc */ SDL_SCANCODE_UNKNOWN, | ||
| 282 | /* 253, 0x0fd */ SDL_SCANCODE_UNKNOWN, | ||
| 283 | /* 254, 0x0fe */ SDL_SCANCODE_UNKNOWN, | ||
| 284 | /* 255, 0x0ff */ SDL_SCANCODE_UNKNOWN, | ||
| 285 | /* 256, 0x100 */ SDL_SCANCODE_UNKNOWN, | ||
| 286 | /* 257, 0x101 */ SDL_SCANCODE_UNKNOWN, | ||
| 287 | /* 258, 0x102 */ SDL_SCANCODE_UNKNOWN, | ||
| 288 | /* 259, 0x103 */ SDL_SCANCODE_UNKNOWN, | ||
| 289 | /* 260, 0x104 */ SDL_SCANCODE_UNKNOWN, | ||
| 290 | /* 261, 0x105 */ SDL_SCANCODE_UNKNOWN, | ||
| 291 | /* 262, 0x106 */ SDL_SCANCODE_UNKNOWN, | ||
| 292 | /* 263, 0x107 */ SDL_SCANCODE_UNKNOWN, | ||
| 293 | /* 264, 0x108 */ SDL_SCANCODE_UNKNOWN, | ||
| 294 | /* 265, 0x109 */ SDL_SCANCODE_UNKNOWN, | ||
| 295 | /* 266, 0x10a */ SDL_SCANCODE_UNKNOWN, | ||
| 296 | /* 267, 0x10b */ SDL_SCANCODE_UNKNOWN, | ||
| 297 | /* 268, 0x10c */ SDL_SCANCODE_UNKNOWN, | ||
| 298 | /* 269, 0x10d */ SDL_SCANCODE_UNKNOWN, | ||
| 299 | /* 270, 0x10e */ SDL_SCANCODE_UNKNOWN, | ||
| 300 | /* 271, 0x10f */ SDL_SCANCODE_UNKNOWN, | ||
| 301 | /* 272, 0x110 */ SDL_SCANCODE_UNKNOWN, | ||
| 302 | /* 273, 0x111 */ SDL_SCANCODE_UNKNOWN, | ||
| 303 | /* 274, 0x112 */ SDL_SCANCODE_UNKNOWN, | ||
| 304 | /* 275, 0x113 */ SDL_SCANCODE_UNKNOWN, | ||
| 305 | /* 276, 0x114 */ SDL_SCANCODE_UNKNOWN, | ||
| 306 | /* 277, 0x115 */ SDL_SCANCODE_UNKNOWN, | ||
| 307 | /* 278, 0x116 */ SDL_SCANCODE_UNKNOWN, | ||
| 308 | /* 279, 0x117 */ SDL_SCANCODE_UNKNOWN, | ||
| 309 | /* 280, 0x118 */ SDL_SCANCODE_UNKNOWN, | ||
| 310 | /* 281, 0x119 */ SDL_SCANCODE_UNKNOWN, | ||
| 311 | /* 282, 0x11a */ SDL_SCANCODE_UNKNOWN, | ||
| 312 | /* 283, 0x11b */ SDL_SCANCODE_UNKNOWN, | ||
| 313 | /* 284, 0x11c */ SDL_SCANCODE_UNKNOWN, | ||
| 314 | /* 285, 0x11d */ SDL_SCANCODE_UNKNOWN, | ||
| 315 | /* 286, 0x11e */ SDL_SCANCODE_UNKNOWN, | ||
| 316 | /* 287, 0x11f */ SDL_SCANCODE_UNKNOWN, | ||
| 317 | /* 288, 0x120 */ SDL_SCANCODE_UNKNOWN, | ||
| 318 | /* 289, 0x121 */ SDL_SCANCODE_UNKNOWN, | ||
| 319 | /* 290, 0x122 */ SDL_SCANCODE_UNKNOWN, | ||
| 320 | /* 291, 0x123 */ SDL_SCANCODE_UNKNOWN, | ||
| 321 | /* 292, 0x124 */ SDL_SCANCODE_UNKNOWN, | ||
| 322 | /* 293, 0x125 */ SDL_SCANCODE_UNKNOWN, | ||
| 323 | /* 294, 0x126 */ SDL_SCANCODE_UNKNOWN, | ||
| 324 | /* 295, 0x127 */ SDL_SCANCODE_UNKNOWN, | ||
| 325 | /* 296, 0x128 */ SDL_SCANCODE_UNKNOWN, | ||
| 326 | /* 297, 0x129 */ SDL_SCANCODE_UNKNOWN, | ||
| 327 | /* 298, 0x12a */ SDL_SCANCODE_UNKNOWN, | ||
| 328 | /* 299, 0x12b */ SDL_SCANCODE_UNKNOWN, | ||
| 329 | /* 300, 0x12c */ SDL_SCANCODE_UNKNOWN, | ||
| 330 | /* 301, 0x12d */ SDL_SCANCODE_UNKNOWN, | ||
| 331 | /* 302, 0x12e */ SDL_SCANCODE_UNKNOWN, | ||
| 332 | /* 303, 0x12f */ SDL_SCANCODE_UNKNOWN, | ||
| 333 | /* 304, 0x130 */ SDL_SCANCODE_UNKNOWN, | ||
| 334 | /* 305, 0x131 */ SDL_SCANCODE_UNKNOWN, | ||
| 335 | /* 306, 0x132 */ SDL_SCANCODE_UNKNOWN, | ||
| 336 | /* 307, 0x133 */ SDL_SCANCODE_UNKNOWN, | ||
| 337 | /* 308, 0x134 */ SDL_SCANCODE_UNKNOWN, | ||
| 338 | /* 309, 0x135 */ SDL_SCANCODE_UNKNOWN, | ||
| 339 | /* 310, 0x136 */ SDL_SCANCODE_UNKNOWN, | ||
| 340 | /* 311, 0x137 */ SDL_SCANCODE_UNKNOWN, | ||
| 341 | /* 312, 0x138 */ SDL_SCANCODE_UNKNOWN, | ||
| 342 | /* 313, 0x139 */ SDL_SCANCODE_UNKNOWN, | ||
| 343 | /* 314, 0x13a */ SDL_SCANCODE_UNKNOWN, | ||
| 344 | /* 315, 0x13b */ SDL_SCANCODE_UNKNOWN, | ||
| 345 | /* 316, 0x13c */ SDL_SCANCODE_UNKNOWN, | ||
| 346 | /* 317, 0x13d */ SDL_SCANCODE_UNKNOWN, | ||
| 347 | /* 318, 0x13e */ SDL_SCANCODE_UNKNOWN, | ||
| 348 | /* 319, 0x13f */ SDL_SCANCODE_UNKNOWN, | ||
| 349 | /* 320, 0x140 */ SDL_SCANCODE_UNKNOWN, | ||
| 350 | /* 321, 0x141 */ SDL_SCANCODE_UNKNOWN, | ||
| 351 | /* 322, 0x142 */ SDL_SCANCODE_UNKNOWN, | ||
| 352 | /* 323, 0x143 */ SDL_SCANCODE_UNKNOWN, | ||
| 353 | /* 324, 0x144 */ SDL_SCANCODE_UNKNOWN, | ||
| 354 | /* 325, 0x145 */ SDL_SCANCODE_UNKNOWN, | ||
| 355 | /* 326, 0x146 */ SDL_SCANCODE_UNKNOWN, | ||
| 356 | /* 327, 0x147 */ SDL_SCANCODE_UNKNOWN, | ||
| 357 | /* 328, 0x148 */ SDL_SCANCODE_UNKNOWN, | ||
| 358 | /* 329, 0x149 */ SDL_SCANCODE_UNKNOWN, | ||
| 359 | /* 330, 0x14a */ SDL_SCANCODE_UNKNOWN, | ||
| 360 | /* 331, 0x14b */ SDL_SCANCODE_UNKNOWN, | ||
| 361 | /* 332, 0x14c */ SDL_SCANCODE_UNKNOWN, | ||
| 362 | /* 333, 0x14d */ SDL_SCANCODE_UNKNOWN, | ||
| 363 | /* 334, 0x14e */ SDL_SCANCODE_UNKNOWN, | ||
| 364 | /* 335, 0x14f */ SDL_SCANCODE_UNKNOWN, | ||
| 365 | /* 336, 0x150 */ SDL_SCANCODE_UNKNOWN, | ||
| 366 | /* 337, 0x151 */ SDL_SCANCODE_UNKNOWN, | ||
| 367 | /* 338, 0x152 */ SDL_SCANCODE_UNKNOWN, | ||
| 368 | /* 339, 0x153 */ SDL_SCANCODE_UNKNOWN, | ||
| 369 | /* 340, 0x154 */ SDL_SCANCODE_UNKNOWN, | ||
| 370 | /* 341, 0x155 */ SDL_SCANCODE_UNKNOWN, | ||
| 371 | /* 342, 0x156 */ SDL_SCANCODE_UNKNOWN, | ||
| 372 | /* 343, 0x157 */ SDL_SCANCODE_UNKNOWN, | ||
| 373 | /* 344, 0x158 */ SDL_SCANCODE_UNKNOWN, | ||
| 374 | /* 345, 0x159 */ SDL_SCANCODE_UNKNOWN, | ||
| 375 | /* 346, 0x15a */ SDL_SCANCODE_UNKNOWN, | ||
| 376 | /* 347, 0x15b */ SDL_SCANCODE_UNKNOWN, | ||
| 377 | /* 348, 0x15c */ SDL_SCANCODE_UNKNOWN, | ||
| 378 | /* 349, 0x15d */ SDL_SCANCODE_UNKNOWN, | ||
| 379 | /* 350, 0x15e */ SDL_SCANCODE_UNKNOWN, | ||
| 380 | /* 351, 0x15f */ SDL_SCANCODE_UNKNOWN, | ||
| 381 | /* 352, 0x160 */ SDL_SCANCODE_UNKNOWN, // KEY_OK | ||
| 382 | /* 353, 0x161 */ SDL_SCANCODE_SELECT, // KEY_SELECT | ||
| 383 | /* 354, 0x162 */ SDL_SCANCODE_UNKNOWN, // KEY_GOTO | ||
| 384 | /* 355, 0x163 */ SDL_SCANCODE_CLEAR, // KEY_CLEAR | ||
| 385 | /* 356, 0x164 */ SDL_SCANCODE_UNKNOWN, // KEY_POWER2 | ||
| 386 | /* 357, 0x165 */ SDL_SCANCODE_UNKNOWN, // KEY_OPTION | ||
| 387 | /* 358, 0x166 */ SDL_SCANCODE_UNKNOWN, // KEY_INFO | ||
| 388 | /* 359, 0x167 */ SDL_SCANCODE_UNKNOWN, // KEY_TIME | ||
| 389 | /* 360, 0x168 */ SDL_SCANCODE_UNKNOWN, // KEY_VENDOR | ||
| 390 | /* 361, 0x169 */ SDL_SCANCODE_UNKNOWN, // KEY_ARCHIVE | ||
| 391 | /* 362, 0x16a */ SDL_SCANCODE_UNKNOWN, // KEY_PROGRAM | ||
| 392 | /* 363, 0x16b */ SDL_SCANCODE_UNKNOWN, // KEY_CHANNEL | ||
| 393 | /* 364, 0x16c */ SDL_SCANCODE_UNKNOWN, // KEY_FAVORITES | ||
| 394 | /* 365, 0x16d */ SDL_SCANCODE_UNKNOWN, // KEY_EPG | ||
| 395 | /* 366, 0x16e */ SDL_SCANCODE_UNKNOWN, // KEY_PVR | ||
| 396 | /* 367, 0x16f */ SDL_SCANCODE_UNKNOWN, // KEY_MHP | ||
| 397 | /* 368, 0x170 */ SDL_SCANCODE_UNKNOWN, // KEY_LANGUAGE | ||
| 398 | /* 369, 0x171 */ SDL_SCANCODE_UNKNOWN, // KEY_TITLE | ||
| 399 | /* 370, 0x172 */ SDL_SCANCODE_UNKNOWN, // KEY_SUBTITLE | ||
| 400 | /* 371, 0x173 */ SDL_SCANCODE_UNKNOWN, // KEY_ANGLE | ||
| 401 | /* 372, 0x174 */ SDL_SCANCODE_UNKNOWN, // KEY_FULL_SCREEN | ||
| 402 | /* 373, 0x175 */ SDL_SCANCODE_MODE, // KEY_MODE | ||
| 403 | /* 374, 0x176 */ SDL_SCANCODE_UNKNOWN, // KEY_KEYBOARD | ||
| 404 | /* 375, 0x177 */ SDL_SCANCODE_UNKNOWN, // KEY_ASPECT_RATIO | ||
| 405 | /* 376, 0x178 */ SDL_SCANCODE_UNKNOWN, // KEY_PC | ||
| 406 | /* 377, 0x179 */ SDL_SCANCODE_UNKNOWN, // KEY_TV | ||
| 407 | /* 378, 0x17a */ SDL_SCANCODE_UNKNOWN, // KEY_TV2 | ||
| 408 | /* 379, 0x17b */ SDL_SCANCODE_UNKNOWN, // KEY_VCR | ||
| 409 | /* 380, 0x17c */ SDL_SCANCODE_UNKNOWN, // KEY_VCR2 | ||
| 410 | /* 381, 0x17d */ SDL_SCANCODE_UNKNOWN, // KEY_SAT | ||
| 411 | /* 382, 0x17e */ SDL_SCANCODE_UNKNOWN, // KEY_SAT2 | ||
| 412 | /* 383, 0x17f */ SDL_SCANCODE_UNKNOWN, // KEY_CD | ||
| 413 | /* 384, 0x180 */ SDL_SCANCODE_UNKNOWN, // KEY_TAPE | ||
| 414 | /* 385, 0x181 */ SDL_SCANCODE_UNKNOWN, // KEY_RADIO | ||
| 415 | /* 386, 0x182 */ SDL_SCANCODE_UNKNOWN, // KEY_TUNER | ||
| 416 | /* 387, 0x183 */ SDL_SCANCODE_UNKNOWN, // KEY_PLAYER | ||
| 417 | /* 388, 0x184 */ SDL_SCANCODE_UNKNOWN, // KEY_TEXT | ||
| 418 | /* 389, 0x185 */ SDL_SCANCODE_UNKNOWN, // KEY_DVD | ||
| 419 | /* 390, 0x186 */ SDL_SCANCODE_UNKNOWN, // KEY_AUX | ||
| 420 | /* 391, 0x187 */ SDL_SCANCODE_UNKNOWN, // KEY_MP3 | ||
| 421 | /* 392, 0x188 */ SDL_SCANCODE_UNKNOWN, // KEY_AUDIO | ||
| 422 | /* 393, 0x189 */ SDL_SCANCODE_UNKNOWN, // KEY_VIDEO | ||
| 423 | /* 394, 0x18a */ SDL_SCANCODE_UNKNOWN, // KEY_DIRECTORY | ||
| 424 | /* 395, 0x18b */ SDL_SCANCODE_UNKNOWN, // KEY_LIST | ||
| 425 | /* 396, 0x18c */ SDL_SCANCODE_UNKNOWN, // KEY_MEMO | ||
| 426 | /* 397, 0x18d */ SDL_SCANCODE_UNKNOWN, // KEY_CALENDAR | ||
| 427 | /* 398, 0x18e */ SDL_SCANCODE_UNKNOWN, // KEY_RED | ||
| 428 | /* 399, 0x18f */ SDL_SCANCODE_UNKNOWN, // KEY_GREEN | ||
| 429 | /* 400, 0x190 */ SDL_SCANCODE_UNKNOWN, // KEY_YELLOW | ||
| 430 | /* 401, 0x191 */ SDL_SCANCODE_UNKNOWN, // KEY_BLUE | ||
| 431 | /* 402, 0x192 */ SDL_SCANCODE_CHANNEL_INCREMENT, // KEY_CHANNELUP | ||
| 432 | /* 403, 0x193 */ SDL_SCANCODE_CHANNEL_DECREMENT, // KEY_CHANNELDOWN | ||
| 433 | #if 0 // We don't have any mapped scancodes after this point (yet) | ||
| 434 | /* 404, 0x194 */ SDL_SCANCODE_UNKNOWN, // KEY_FIRST | ||
| 435 | /* 405, 0x195 */ SDL_SCANCODE_UNKNOWN, // KEY_LAST | ||
| 436 | /* 406, 0x196 */ SDL_SCANCODE_UNKNOWN, // KEY_AB | ||
| 437 | /* 407, 0x197 */ SDL_SCANCODE_UNKNOWN, // KEY_NEXT | ||
| 438 | /* 408, 0x198 */ SDL_SCANCODE_UNKNOWN, // KEY_RESTART | ||
| 439 | /* 409, 0x199 */ SDL_SCANCODE_UNKNOWN, // KEY_SLOW | ||
| 440 | /* 410, 0x19a */ SDL_SCANCODE_UNKNOWN, // KEY_SHUFFLE | ||
| 441 | /* 411, 0x19b */ SDL_SCANCODE_UNKNOWN, // KEY_BREAK | ||
| 442 | /* 412, 0x19c */ SDL_SCANCODE_UNKNOWN, // KEY_PREVIOUS | ||
| 443 | /* 413, 0x19d */ SDL_SCANCODE_UNKNOWN, // KEY_DIGITS | ||
| 444 | /* 414, 0x19e */ SDL_SCANCODE_UNKNOWN, // KEY_TEEN | ||
| 445 | /* 415, 0x19f */ SDL_SCANCODE_UNKNOWN, // KEY_TWEN | ||
| 446 | /* 416, 0x1a0 */ SDL_SCANCODE_UNKNOWN, // KEY_VIDEOPHONE | ||
| 447 | /* 417, 0x1a1 */ SDL_SCANCODE_UNKNOWN, // KEY_GAMES | ||
| 448 | /* 418, 0x1a2 */ SDL_SCANCODE_UNKNOWN, // KEY_ZOOMIN | ||
| 449 | /* 419, 0x1a3 */ SDL_SCANCODE_UNKNOWN, // KEY_ZOOMOUT | ||
| 450 | /* 420, 0x1a4 */ SDL_SCANCODE_UNKNOWN, // KEY_ZOOMRESET | ||
| 451 | /* 421, 0x1a5 */ SDL_SCANCODE_UNKNOWN, // KEY_WORDPROCESSOR | ||
| 452 | /* 422, 0x1a6 */ SDL_SCANCODE_UNKNOWN, // KEY_EDITOR | ||
| 453 | /* 423, 0x1a7 */ SDL_SCANCODE_UNKNOWN, // KEY_SPREADSHEET | ||
| 454 | /* 424, 0x1a8 */ SDL_SCANCODE_UNKNOWN, // KEY_GRAPHICSEDITOR | ||
| 455 | /* 425, 0x1a9 */ SDL_SCANCODE_UNKNOWN, // KEY_PRESENTATION | ||
| 456 | /* 426, 0x1aa */ SDL_SCANCODE_UNKNOWN, // KEY_DATABASE | ||
| 457 | /* 427, 0x1ab */ SDL_SCANCODE_UNKNOWN, // KEY_NEWS | ||
| 458 | /* 428, 0x1ac */ SDL_SCANCODE_UNKNOWN, // KEY_VOICEMAIL | ||
| 459 | /* 429, 0x1ad */ SDL_SCANCODE_UNKNOWN, // KEY_ADDRESSBOOK | ||
| 460 | /* 430, 0x1ae */ SDL_SCANCODE_UNKNOWN, // KEY_MESSENGER | ||
| 461 | /* 431, 0x1af */ SDL_SCANCODE_UNKNOWN, // KEY_DISPLAYTOGGLE | ||
| 462 | /* 432, 0x1b0 */ SDL_SCANCODE_UNKNOWN, // KEY_SPELLCHECK | ||
| 463 | /* 433, 0x1b1 */ SDL_SCANCODE_UNKNOWN, // KEY_LOGOFF | ||
| 464 | /* 434, 0x1b2 */ SDL_SCANCODE_UNKNOWN, // KEY_DOLLAR | ||
| 465 | /* 435, 0x1b3 */ SDL_SCANCODE_UNKNOWN, // KEY_EURO | ||
| 466 | /* 436, 0x1b4 */ SDL_SCANCODE_UNKNOWN, // KEY_FRAMEBACK | ||
| 467 | /* 437, 0x1b5 */ SDL_SCANCODE_UNKNOWN, // KEY_FRAMEFORWARD | ||
| 468 | /* 438, 0x1b6 */ SDL_SCANCODE_UNKNOWN, // KEY_CONTEXT_MENU | ||
| 469 | /* 439, 0x1b7 */ SDL_SCANCODE_UNKNOWN, // KEY_MEDIA_REPEAT | ||
| 470 | /* 440, 0x1b8 */ SDL_SCANCODE_UNKNOWN, // KEY_10CHANNELSUP | ||
| 471 | /* 441, 0x1b9 */ SDL_SCANCODE_UNKNOWN, // KEY_10CHANNELSDOWN | ||
| 472 | /* 442, 0x1ba */ SDL_SCANCODE_UNKNOWN, // KEY_IMAGES | ||
| 473 | /* 443, 0x1bb */ SDL_SCANCODE_UNKNOWN, | ||
| 474 | /* 444, 0x1bc */ SDL_SCANCODE_UNKNOWN, // KEY_NOTIFICATION_CENTER | ||
| 475 | /* 445, 0x1bd */ SDL_SCANCODE_UNKNOWN, // KEY_PICKUP_PHONE | ||
| 476 | /* 446, 0x1be */ SDL_SCANCODE_UNKNOWN, // KEY_HANGUP_PHONE | ||
| 477 | /* 447, 0x1bf */ SDL_SCANCODE_UNKNOWN, | ||
| 478 | /* 448, 0x1c0 */ SDL_SCANCODE_UNKNOWN, // KEY_DEL_EOL | ||
| 479 | /* 449, 0x1c1 */ SDL_SCANCODE_UNKNOWN, // KEY_DEL_EOS | ||
| 480 | /* 450, 0x1c2 */ SDL_SCANCODE_UNKNOWN, // KEY_INS_LINE | ||
| 481 | /* 451, 0x1c3 */ SDL_SCANCODE_UNKNOWN, // KEY_DEL_LINE | ||
| 482 | /* 452, 0x1c4 */ SDL_SCANCODE_UNKNOWN, | ||
| 483 | /* 453, 0x1c5 */ SDL_SCANCODE_UNKNOWN, | ||
| 484 | /* 454, 0x1c6 */ SDL_SCANCODE_UNKNOWN, | ||
| 485 | /* 455, 0x1c7 */ SDL_SCANCODE_UNKNOWN, | ||
| 486 | /* 456, 0x1c8 */ SDL_SCANCODE_UNKNOWN, | ||
| 487 | /* 457, 0x1c9 */ SDL_SCANCODE_UNKNOWN, | ||
| 488 | /* 458, 0x1ca */ SDL_SCANCODE_UNKNOWN, | ||
| 489 | /* 459, 0x1cb */ SDL_SCANCODE_UNKNOWN, | ||
| 490 | /* 460, 0x1cc */ SDL_SCANCODE_UNKNOWN, | ||
| 491 | /* 461, 0x1cd */ SDL_SCANCODE_UNKNOWN, | ||
| 492 | /* 462, 0x1ce */ SDL_SCANCODE_UNKNOWN, | ||
| 493 | /* 463, 0x1cf */ SDL_SCANCODE_UNKNOWN, | ||
| 494 | /* 464, 0x1d0 */ SDL_SCANCODE_UNKNOWN, // KEY_FN | ||
| 495 | /* 465, 0x1d1 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_ESC | ||
| 496 | /* 466, 0x1d2 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F1 | ||
| 497 | /* 467, 0x1d3 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F2 | ||
| 498 | /* 468, 0x1d4 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F3 | ||
| 499 | /* 469, 0x1d5 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F4 | ||
| 500 | /* 470, 0x1d6 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F5 | ||
| 501 | /* 471, 0x1d7 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F6 | ||
| 502 | /* 472, 0x1d8 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F7 | ||
| 503 | /* 473, 0x1d9 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F8 | ||
| 504 | /* 474, 0x1da */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F9 | ||
| 505 | /* 475, 0x1db */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F10 | ||
| 506 | /* 476, 0x1dc */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F11 | ||
| 507 | /* 477, 0x1dd */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F12 | ||
| 508 | /* 478, 0x1de */ SDL_SCANCODE_UNKNOWN, // KEY_FN_1 | ||
| 509 | /* 479, 0x1df */ SDL_SCANCODE_UNKNOWN, // KEY_FN_2 | ||
| 510 | /* 480, 0x1e0 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_D | ||
| 511 | /* 481, 0x1e1 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_E | ||
| 512 | /* 482, 0x1e2 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F | ||
| 513 | /* 483, 0x1e3 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_S | ||
| 514 | /* 484, 0x1e4 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_B | ||
| 515 | /* 485, 0x1e5 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_RIGHT_SHIFT | ||
| 516 | /* 486, 0x1e6 */ SDL_SCANCODE_UNKNOWN, | ||
| 517 | /* 487, 0x1e7 */ SDL_SCANCODE_UNKNOWN, | ||
| 518 | /* 488, 0x1e8 */ SDL_SCANCODE_UNKNOWN, | ||
| 519 | /* 489, 0x1e9 */ SDL_SCANCODE_UNKNOWN, | ||
| 520 | /* 490, 0x1ea */ SDL_SCANCODE_UNKNOWN, | ||
| 521 | /* 491, 0x1eb */ SDL_SCANCODE_UNKNOWN, | ||
| 522 | /* 492, 0x1ec */ SDL_SCANCODE_UNKNOWN, | ||
| 523 | /* 493, 0x1ed */ SDL_SCANCODE_UNKNOWN, | ||
| 524 | /* 494, 0x1ee */ SDL_SCANCODE_UNKNOWN, | ||
| 525 | /* 495, 0x1ef */ SDL_SCANCODE_UNKNOWN, | ||
| 526 | /* 496, 0x1f0 */ SDL_SCANCODE_UNKNOWN, | ||
| 527 | /* 497, 0x1f1 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT1 | ||
| 528 | /* 498, 0x1f2 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT2 | ||
| 529 | /* 499, 0x1f3 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT3 | ||
| 530 | /* 500, 0x1f4 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT4 | ||
| 531 | /* 501, 0x1f5 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT5 | ||
| 532 | /* 502, 0x1f6 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT6 | ||
| 533 | /* 503, 0x1f7 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT7 | ||
| 534 | /* 504, 0x1f8 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT8 | ||
| 535 | /* 505, 0x1f9 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT9 | ||
| 536 | /* 506, 0x1fa */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT10 | ||
| 537 | /* 507, 0x1fb */ SDL_SCANCODE_UNKNOWN, | ||
| 538 | /* 508, 0x1fc */ SDL_SCANCODE_UNKNOWN, | ||
| 539 | /* 509, 0x1fd */ SDL_SCANCODE_UNKNOWN, | ||
| 540 | /* 510, 0x1fe */ SDL_SCANCODE_UNKNOWN, | ||
| 541 | /* 511, 0x1ff */ SDL_SCANCODE_UNKNOWN, | ||
| 542 | /* 512, 0x200 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_0 | ||
| 543 | /* 513, 0x201 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_1 | ||
| 544 | /* 514, 0x202 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_2 | ||
| 545 | /* 515, 0x203 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_3 | ||
| 546 | /* 516, 0x204 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_4 | ||
| 547 | /* 517, 0x205 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_5 | ||
| 548 | /* 518, 0x206 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_6 | ||
| 549 | /* 519, 0x207 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_7 | ||
| 550 | /* 520, 0x208 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_8 | ||
| 551 | /* 521, 0x209 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_9 | ||
| 552 | /* 522, 0x20a */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_STAR | ||
| 553 | /* 523, 0x20b */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_POUND | ||
| 554 | /* 524, 0x20c */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_A | ||
| 555 | /* 525, 0x20d */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_B | ||
| 556 | /* 526, 0x20e */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_C | ||
| 557 | /* 527, 0x20f */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_D | ||
| 558 | /* 528, 0x210 */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA_FOCUS | ||
| 559 | /* 529, 0x211 */ SDL_SCANCODE_UNKNOWN, // KEY_WPS_BUTTON | ||
| 560 | /* 530, 0x212 */ SDL_SCANCODE_UNKNOWN, // KEY_TOUCHPAD_TOGGLE | ||
| 561 | /* 531, 0x213 */ SDL_SCANCODE_UNKNOWN, // KEY_TOUCHPAD_ON | ||
| 562 | /* 532, 0x214 */ SDL_SCANCODE_UNKNOWN, // KEY_TOUCHPAD_OFF | ||
| 563 | /* 533, 0x215 */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA_ZOOMIN | ||
| 564 | /* 534, 0x216 */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA_ZOOMOUT | ||
| 565 | /* 535, 0x217 */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA_UP | ||
| 566 | /* 536, 0x218 */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA_DOWN | ||
| 567 | /* 537, 0x219 */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA_LEFT | ||
| 568 | /* 538, 0x21a */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA_RIGHT | ||
| 569 | /* 539, 0x21b */ SDL_SCANCODE_UNKNOWN, // KEY_ATTENDANT_ON | ||
| 570 | /* 540, 0x21c */ SDL_SCANCODE_UNKNOWN, // KEY_ATTENDANT_OFF | ||
| 571 | /* 541, 0x21d */ SDL_SCANCODE_UNKNOWN, // KEY_ATTENDANT_TOGGLE | ||
| 572 | /* 542, 0x21e */ SDL_SCANCODE_UNKNOWN, // KEY_LIGHTS_TOGGLE | ||
| 573 | /* 543, 0x21f */ SDL_SCANCODE_UNKNOWN, | ||
| 574 | /* 544, 0x220 */ SDL_SCANCODE_UNKNOWN, | ||
| 575 | /* 545, 0x221 */ SDL_SCANCODE_UNKNOWN, | ||
| 576 | /* 546, 0x222 */ SDL_SCANCODE_UNKNOWN, | ||
| 577 | /* 547, 0x223 */ SDL_SCANCODE_UNKNOWN, | ||
| 578 | /* 548, 0x224 */ SDL_SCANCODE_UNKNOWN, | ||
| 579 | /* 549, 0x225 */ SDL_SCANCODE_UNKNOWN, | ||
| 580 | /* 550, 0x226 */ SDL_SCANCODE_UNKNOWN, | ||
| 581 | /* 551, 0x227 */ SDL_SCANCODE_UNKNOWN, | ||
| 582 | /* 552, 0x228 */ SDL_SCANCODE_UNKNOWN, | ||
| 583 | /* 553, 0x229 */ SDL_SCANCODE_UNKNOWN, | ||
| 584 | /* 554, 0x22a */ SDL_SCANCODE_UNKNOWN, | ||
| 585 | /* 555, 0x22b */ SDL_SCANCODE_UNKNOWN, | ||
| 586 | /* 556, 0x22c */ SDL_SCANCODE_UNKNOWN, | ||
| 587 | /* 557, 0x22d */ SDL_SCANCODE_UNKNOWN, | ||
| 588 | /* 558, 0x22e */ SDL_SCANCODE_UNKNOWN, | ||
| 589 | /* 559, 0x22f */ SDL_SCANCODE_UNKNOWN, | ||
| 590 | /* 560, 0x230 */ SDL_SCANCODE_UNKNOWN, // KEY_ALS_TOGGLE | ||
| 591 | /* 561, 0x231 */ SDL_SCANCODE_UNKNOWN, // KEY_ROTATE_LOCK_TOGGLE | ||
| 592 | /* 562, 0x232 */ SDL_SCANCODE_UNKNOWN, | ||
| 593 | /* 563, 0x233 */ SDL_SCANCODE_UNKNOWN, | ||
| 594 | /* 564, 0x234 */ SDL_SCANCODE_UNKNOWN, | ||
| 595 | /* 565, 0x235 */ SDL_SCANCODE_UNKNOWN, | ||
| 596 | /* 566, 0x236 */ SDL_SCANCODE_UNKNOWN, | ||
| 597 | /* 567, 0x237 */ SDL_SCANCODE_UNKNOWN, | ||
| 598 | /* 568, 0x238 */ SDL_SCANCODE_UNKNOWN, | ||
| 599 | /* 569, 0x239 */ SDL_SCANCODE_UNKNOWN, | ||
| 600 | /* 570, 0x23a */ SDL_SCANCODE_UNKNOWN, | ||
| 601 | /* 571, 0x23b */ SDL_SCANCODE_UNKNOWN, | ||
| 602 | /* 572, 0x23c */ SDL_SCANCODE_UNKNOWN, | ||
| 603 | /* 573, 0x23d */ SDL_SCANCODE_UNKNOWN, | ||
| 604 | /* 574, 0x23e */ SDL_SCANCODE_UNKNOWN, | ||
| 605 | /* 575, 0x23f */ SDL_SCANCODE_UNKNOWN, | ||
| 606 | /* 576, 0x240 */ SDL_SCANCODE_UNKNOWN, // KEY_BUTTONCONFIG | ||
| 607 | /* 577, 0x241 */ SDL_SCANCODE_UNKNOWN, // KEY_TASKMANAGER | ||
| 608 | /* 578, 0x242 */ SDL_SCANCODE_UNKNOWN, // KEY_JOURNAL | ||
| 609 | /* 579, 0x243 */ SDL_SCANCODE_UNKNOWN, // KEY_CONTROLPANEL | ||
| 610 | /* 580, 0x244 */ SDL_SCANCODE_UNKNOWN, // KEY_APPSELECT | ||
| 611 | /* 581, 0x245 */ SDL_SCANCODE_UNKNOWN, // KEY_SCREENSAVER | ||
| 612 | /* 582, 0x246 */ SDL_SCANCODE_UNKNOWN, // KEY_VOICECOMMAND | ||
| 613 | /* 583, 0x247 */ SDL_SCANCODE_UNKNOWN, // KEY_ASSISTANT | ||
| 614 | /* 584, 0x248 */ SDL_SCANCODE_UNKNOWN, // KEY_KBD_LAYOUT_NEXT | ||
| 615 | /* 585, 0x249 */ SDL_SCANCODE_UNKNOWN, // KEY_EMOJI_PICKER | ||
| 616 | /* 586, 0x24a */ SDL_SCANCODE_UNKNOWN, // KEY_DICTATE | ||
| 617 | /* 587, 0x24b */ SDL_SCANCODE_UNKNOWN, | ||
| 618 | /* 588, 0x24c */ SDL_SCANCODE_UNKNOWN, | ||
| 619 | /* 589, 0x24d */ SDL_SCANCODE_UNKNOWN, | ||
| 620 | /* 590, 0x24e */ SDL_SCANCODE_UNKNOWN, | ||
| 621 | /* 591, 0x24f */ SDL_SCANCODE_UNKNOWN, | ||
| 622 | /* 592, 0x250 */ SDL_SCANCODE_UNKNOWN, // KEY_BRIGHTNESS_MIN | ||
| 623 | /* 593, 0x251 */ SDL_SCANCODE_UNKNOWN, // KEY_BRIGHTNESS_MAX | ||
| 624 | /* 594, 0x252 */ SDL_SCANCODE_UNKNOWN, | ||
| 625 | /* 595, 0x253 */ SDL_SCANCODE_UNKNOWN, | ||
| 626 | /* 596, 0x254 */ SDL_SCANCODE_UNKNOWN, | ||
| 627 | /* 597, 0x255 */ SDL_SCANCODE_UNKNOWN, | ||
| 628 | /* 598, 0x256 */ SDL_SCANCODE_UNKNOWN, | ||
| 629 | /* 599, 0x257 */ SDL_SCANCODE_UNKNOWN, | ||
| 630 | /* 600, 0x258 */ SDL_SCANCODE_UNKNOWN, | ||
| 631 | /* 601, 0x259 */ SDL_SCANCODE_UNKNOWN, | ||
| 632 | /* 602, 0x25a */ SDL_SCANCODE_UNKNOWN, | ||
| 633 | /* 603, 0x25b */ SDL_SCANCODE_UNKNOWN, | ||
| 634 | /* 604, 0x25c */ SDL_SCANCODE_UNKNOWN, | ||
| 635 | /* 605, 0x25d */ SDL_SCANCODE_UNKNOWN, | ||
| 636 | /* 606, 0x25e */ SDL_SCANCODE_UNKNOWN, | ||
| 637 | /* 607, 0x25f */ SDL_SCANCODE_UNKNOWN, | ||
| 638 | /* 608, 0x260 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDINPUTASSIST_PREV | ||
| 639 | /* 609, 0x261 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDINPUTASSIST_NEXT | ||
| 640 | /* 610, 0x262 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDINPUTASSIST_PREVGROUP | ||
| 641 | /* 611, 0x263 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDINPUTASSIST_NEXTGROUP | ||
| 642 | /* 612, 0x264 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDINPUTASSIST_ACCEPT | ||
| 643 | /* 613, 0x265 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDINPUTASSIST_CANCEL | ||
| 644 | /* 614, 0x266 */ SDL_SCANCODE_UNKNOWN, // KEY_RIGHT_UP | ||
| 645 | /* 615, 0x267 */ SDL_SCANCODE_UNKNOWN, // KEY_RIGHT_DOWN | ||
| 646 | /* 616, 0x268 */ SDL_SCANCODE_UNKNOWN, // KEY_LEFT_UP | ||
| 647 | /* 617, 0x269 */ SDL_SCANCODE_UNKNOWN, // KEY_LEFT_DOWN | ||
| 648 | /* 618, 0x26a */ SDL_SCANCODE_UNKNOWN, // KEY_ROOT_MENU | ||
| 649 | /* 619, 0x26b */ SDL_SCANCODE_UNKNOWN, // KEY_MEDIA_TOP_MENU | ||
| 650 | /* 620, 0x26c */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_11 | ||
| 651 | /* 621, 0x26d */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_12 | ||
| 652 | /* 622, 0x26e */ SDL_SCANCODE_UNKNOWN, // KEY_AUDIO_DESC | ||
| 653 | /* 623, 0x26f */ SDL_SCANCODE_UNKNOWN, // KEY_3D_MODE | ||
| 654 | /* 624, 0x270 */ SDL_SCANCODE_UNKNOWN, // KEY_NEXT_FAVORITE | ||
| 655 | /* 625, 0x271 */ SDL_SCANCODE_UNKNOWN, // KEY_STOP_RECORD | ||
| 656 | /* 626, 0x272 */ SDL_SCANCODE_UNKNOWN, // KEY_PAUSE_RECORD | ||
| 657 | /* 627, 0x273 */ SDL_SCANCODE_UNKNOWN, // KEY_VOD | ||
| 658 | /* 628, 0x274 */ SDL_SCANCODE_UNKNOWN, // KEY_UNMUTE | ||
| 659 | /* 629, 0x275 */ SDL_SCANCODE_UNKNOWN, // KEY_FASTREVERSE | ||
| 660 | /* 630, 0x276 */ SDL_SCANCODE_UNKNOWN, // KEY_SLOWREVERSE | ||
| 661 | /* 631, 0x277 */ SDL_SCANCODE_UNKNOWN, // KEY_DATA | ||
| 662 | /* 632, 0x278 */ SDL_SCANCODE_UNKNOWN, // KEY_ONSCREEN_KEYBOARD | ||
| 663 | /* 633, 0x279 */ SDL_SCANCODE_UNKNOWN, // KEY_PRIVACY_SCREEN_TOGGLE | ||
| 664 | /* 634, 0x27a */ SDL_SCANCODE_UNKNOWN, // KEY_SELECTIVE_SCREENSHOT | ||
| 665 | /* 635, 0x27b */ SDL_SCANCODE_UNKNOWN, | ||
| 666 | /* 636, 0x27c */ SDL_SCANCODE_UNKNOWN, | ||
| 667 | /* 637, 0x27d */ SDL_SCANCODE_UNKNOWN, | ||
| 668 | /* 638, 0x27e */ SDL_SCANCODE_UNKNOWN, | ||
| 669 | /* 639, 0x27f */ SDL_SCANCODE_UNKNOWN, | ||
| 670 | /* 640, 0x280 */ SDL_SCANCODE_UNKNOWN, | ||
| 671 | /* 641, 0x281 */ SDL_SCANCODE_UNKNOWN, | ||
| 672 | /* 642, 0x282 */ SDL_SCANCODE_UNKNOWN, | ||
| 673 | /* 643, 0x283 */ SDL_SCANCODE_UNKNOWN, | ||
| 674 | /* 644, 0x284 */ SDL_SCANCODE_UNKNOWN, | ||
| 675 | /* 645, 0x285 */ SDL_SCANCODE_UNKNOWN, | ||
| 676 | /* 646, 0x286 */ SDL_SCANCODE_UNKNOWN, | ||
| 677 | /* 647, 0x287 */ SDL_SCANCODE_UNKNOWN, | ||
| 678 | /* 648, 0x288 */ SDL_SCANCODE_UNKNOWN, | ||
| 679 | /* 649, 0x289 */ SDL_SCANCODE_UNKNOWN, | ||
| 680 | /* 650, 0x28a */ SDL_SCANCODE_UNKNOWN, | ||
| 681 | /* 651, 0x28b */ SDL_SCANCODE_UNKNOWN, | ||
| 682 | /* 652, 0x28c */ SDL_SCANCODE_UNKNOWN, | ||
| 683 | /* 653, 0x28d */ SDL_SCANCODE_UNKNOWN, | ||
| 684 | /* 654, 0x28e */ SDL_SCANCODE_UNKNOWN, | ||
| 685 | /* 655, 0x28f */ SDL_SCANCODE_UNKNOWN, | ||
| 686 | /* 656, 0x290 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO1 | ||
| 687 | /* 657, 0x291 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO2 | ||
| 688 | /* 658, 0x292 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO3 | ||
| 689 | /* 659, 0x293 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO4 | ||
| 690 | /* 660, 0x294 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO5 | ||
| 691 | /* 661, 0x295 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO6 | ||
| 692 | /* 662, 0x296 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO7 | ||
| 693 | /* 663, 0x297 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO8 | ||
| 694 | /* 664, 0x298 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO9 | ||
| 695 | /* 665, 0x299 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO10 | ||
| 696 | /* 666, 0x29a */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO11 | ||
| 697 | /* 667, 0x29b */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO12 | ||
| 698 | /* 668, 0x29c */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO13 | ||
| 699 | /* 669, 0x29d */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO14 | ||
| 700 | /* 670, 0x29e */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO15 | ||
| 701 | /* 671, 0x29f */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO16 | ||
| 702 | /* 672, 0x2a0 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO17 | ||
| 703 | /* 673, 0x2a1 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO18 | ||
| 704 | /* 674, 0x2a2 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO19 | ||
| 705 | /* 675, 0x2a3 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO20 | ||
| 706 | /* 676, 0x2a4 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO21 | ||
| 707 | /* 677, 0x2a5 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO22 | ||
| 708 | /* 678, 0x2a6 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO23 | ||
| 709 | /* 679, 0x2a7 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO24 | ||
| 710 | /* 680, 0x2a8 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO25 | ||
| 711 | /* 681, 0x2a9 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO26 | ||
| 712 | /* 682, 0x2aa */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO27 | ||
| 713 | /* 683, 0x2ab */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO28 | ||
| 714 | /* 684, 0x2ac */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO29 | ||
| 715 | /* 685, 0x2ad */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO30 | ||
| 716 | /* 686, 0x2ae */ SDL_SCANCODE_UNKNOWN, | ||
| 717 | /* 687, 0x2af */ SDL_SCANCODE_UNKNOWN, | ||
| 718 | /* 688, 0x2b0 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO_RECORD_START | ||
| 719 | /* 689, 0x2b1 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO_RECORD_STOP | ||
| 720 | /* 690, 0x2b2 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO_PRESET_CYCLE | ||
| 721 | /* 691, 0x2b3 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO_PRESET1 | ||
| 722 | /* 692, 0x2b4 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO_PRESET2 | ||
| 723 | /* 693, 0x2b5 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO_PRESET3 | ||
| 724 | /* 694, 0x2b6 */ SDL_SCANCODE_UNKNOWN, | ||
| 725 | /* 695, 0x2b7 */ SDL_SCANCODE_UNKNOWN, | ||
| 726 | /* 696, 0x2b8 */ SDL_SCANCODE_UNKNOWN, // KEY_KBD_LCD_MENU1 | ||
| 727 | /* 697, 0x2b9 */ SDL_SCANCODE_UNKNOWN, // KEY_KBD_LCD_MENU2 | ||
| 728 | /* 698, 0x2ba */ SDL_SCANCODE_UNKNOWN, // KEY_KBD_LCD_MENU3 | ||
| 729 | /* 699, 0x2bb */ SDL_SCANCODE_UNKNOWN, // KEY_KBD_LCD_MENU4 | ||
| 730 | /* 700, 0x2bc */ SDL_SCANCODE_UNKNOWN, // KEY_KBD_LCD_MENU5 | ||
| 731 | /* 701, 0x2bd */ SDL_SCANCODE_UNKNOWN, | ||
| 732 | /* 702, 0x2be */ SDL_SCANCODE_UNKNOWN, | ||
| 733 | /* 703, 0x2bf */ SDL_SCANCODE_UNKNOWN, | ||
| 734 | /* 704, 0x2c0 */ SDL_SCANCODE_UNKNOWN, | ||
| 735 | /* 705, 0x2c1 */ SDL_SCANCODE_UNKNOWN, | ||
| 736 | /* 706, 0x2c2 */ SDL_SCANCODE_UNKNOWN, | ||
| 737 | /* 707, 0x2c3 */ SDL_SCANCODE_UNKNOWN, | ||
| 738 | /* 708, 0x2c4 */ SDL_SCANCODE_UNKNOWN, | ||
| 739 | /* 709, 0x2c5 */ SDL_SCANCODE_UNKNOWN, | ||
| 740 | /* 710, 0x2c6 */ SDL_SCANCODE_UNKNOWN, | ||
| 741 | /* 711, 0x2c7 */ SDL_SCANCODE_UNKNOWN, | ||
| 742 | /* 712, 0x2c8 */ SDL_SCANCODE_UNKNOWN, | ||
| 743 | /* 713, 0x2c9 */ SDL_SCANCODE_UNKNOWN, | ||
| 744 | /* 714, 0x2ca */ SDL_SCANCODE_UNKNOWN, | ||
| 745 | /* 715, 0x2cb */ SDL_SCANCODE_UNKNOWN, | ||
| 746 | /* 716, 0x2cc */ SDL_SCANCODE_UNKNOWN, | ||
| 747 | /* 717, 0x2cd */ SDL_SCANCODE_UNKNOWN, | ||
| 748 | /* 718, 0x2ce */ SDL_SCANCODE_UNKNOWN, | ||
| 749 | /* 719, 0x2cf */ SDL_SCANCODE_UNKNOWN, | ||
| 750 | /* 720, 0x2d0 */ SDL_SCANCODE_UNKNOWN, | ||
| 751 | /* 721, 0x2d1 */ SDL_SCANCODE_UNKNOWN, | ||
| 752 | /* 722, 0x2d2 */ SDL_SCANCODE_UNKNOWN, | ||
| 753 | /* 723, 0x2d3 */ SDL_SCANCODE_UNKNOWN, | ||
| 754 | /* 724, 0x2d4 */ SDL_SCANCODE_UNKNOWN, | ||
| 755 | /* 725, 0x2d5 */ SDL_SCANCODE_UNKNOWN, | ||
| 756 | /* 726, 0x2d6 */ SDL_SCANCODE_UNKNOWN, | ||
| 757 | /* 727, 0x2d7 */ SDL_SCANCODE_UNKNOWN, | ||
| 758 | /* 728, 0x2d8 */ SDL_SCANCODE_UNKNOWN, | ||
| 759 | /* 729, 0x2d9 */ SDL_SCANCODE_UNKNOWN, | ||
| 760 | /* 730, 0x2da */ SDL_SCANCODE_UNKNOWN, | ||
| 761 | /* 731, 0x2db */ SDL_SCANCODE_UNKNOWN, | ||
| 762 | /* 732, 0x2dc */ SDL_SCANCODE_UNKNOWN, | ||
| 763 | /* 733, 0x2dd */ SDL_SCANCODE_UNKNOWN, | ||
| 764 | /* 734, 0x2de */ SDL_SCANCODE_UNKNOWN, | ||
| 765 | /* 735, 0x2df */ SDL_SCANCODE_UNKNOWN, | ||
| 766 | /* 736, 0x2e0 */ SDL_SCANCODE_UNKNOWN, | ||
| 767 | /* 737, 0x2e1 */ SDL_SCANCODE_UNKNOWN, | ||
| 768 | /* 738, 0x2e2 */ SDL_SCANCODE_UNKNOWN, | ||
| 769 | /* 739, 0x2e3 */ SDL_SCANCODE_UNKNOWN, | ||
| 770 | /* 740, 0x2e4 */ SDL_SCANCODE_UNKNOWN, | ||
| 771 | /* 741, 0x2e5 */ SDL_SCANCODE_UNKNOWN, | ||
| 772 | /* 742, 0x2e6 */ SDL_SCANCODE_UNKNOWN, | ||
| 773 | /* 743, 0x2e7 */ SDL_SCANCODE_UNKNOWN, | ||
| 774 | /* 744, 0x2e8 */ SDL_SCANCODE_UNKNOWN, | ||
| 775 | /* 745, 0x2e9 */ SDL_SCANCODE_UNKNOWN, | ||
| 776 | /* 746, 0x2ea */ SDL_SCANCODE_UNKNOWN, | ||
| 777 | /* 747, 0x2eb */ SDL_SCANCODE_UNKNOWN, | ||
| 778 | /* 748, 0x2ec */ SDL_SCANCODE_UNKNOWN, | ||
| 779 | /* 749, 0x2ed */ SDL_SCANCODE_UNKNOWN, | ||
| 780 | /* 750, 0x2ee */ SDL_SCANCODE_UNKNOWN, | ||
| 781 | /* 751, 0x2ef */ SDL_SCANCODE_UNKNOWN, | ||
| 782 | /* 752, 0x2f0 */ SDL_SCANCODE_UNKNOWN, | ||
| 783 | /* 753, 0x2f1 */ SDL_SCANCODE_UNKNOWN, | ||
| 784 | /* 754, 0x2f2 */ SDL_SCANCODE_UNKNOWN, | ||
| 785 | /* 755, 0x2f3 */ SDL_SCANCODE_UNKNOWN, | ||
| 786 | /* 756, 0x2f4 */ SDL_SCANCODE_UNKNOWN, | ||
| 787 | /* 757, 0x2f5 */ SDL_SCANCODE_UNKNOWN, | ||
| 788 | /* 758, 0x2f6 */ SDL_SCANCODE_UNKNOWN, | ||
| 789 | /* 759, 0x2f7 */ SDL_SCANCODE_UNKNOWN, | ||
| 790 | /* 760, 0x2f8 */ SDL_SCANCODE_UNKNOWN, | ||
| 791 | /* 761, 0x2f9 */ SDL_SCANCODE_UNKNOWN, | ||
| 792 | /* 762, 0x2fa */ SDL_SCANCODE_UNKNOWN, | ||
| 793 | /* 763, 0x2fb */ SDL_SCANCODE_UNKNOWN, | ||
| 794 | /* 764, 0x2fc */ SDL_SCANCODE_UNKNOWN, | ||
| 795 | /* 765, 0x2fd */ SDL_SCANCODE_UNKNOWN, | ||
| 796 | /* 766, 0x2fe */ SDL_SCANCODE_UNKNOWN, | ||
| 797 | /* 767, 0x2ff */ SDL_SCANCODE_UNKNOWN, // KEY_MAX | ||
| 798 | #endif // 0 | ||
| 799 | }; | ||
| 800 | |||
| 801 | #if 0 // A shell script to update the Linux key names in this file | ||
| 802 | #!/bin/bash | ||
| 803 | |||
| 804 | function get_keyname | ||
| 805 | { | ||
| 806 | value=$(echo "$1" | awk '{print $3}') | ||
| 807 | grep -F KEY_ /usr/include/linux/input-event-codes.h | while read line; do | ||
| 808 | read -ra fields <<<"$line" | ||
| 809 | if [ "${fields[2]}" = "$value" ]; then | ||
| 810 | echo "${fields[1]}" | ||
| 811 | return | ||
| 812 | fi | ||
| 813 | done | ||
| 814 | } | ||
| 815 | |||
| 816 | grep -F SDL_SCANCODE scancodes_linux.h | while read line; do | ||
| 817 | if [ $(echo "$line" | awk '{print NF}') -eq 5 ]; then | ||
| 818 | name=$(get_keyname "$line") | ||
| 819 | if [ "$name" != "" ]; then | ||
| 820 | echo " $line /* $name */" | ||
| 821 | continue | ||
| 822 | fi | ||
| 823 | fi | ||
| 824 | echo " $line" | ||
| 825 | done | ||
| 826 | #endif // end script | ||
| 827 | |||
| 828 | #if 0 // A shell script to get comments from the Linux header for these keys | ||
| 829 | #!/bin/bash | ||
| 830 | |||
| 831 | function get_comment | ||
| 832 | { | ||
| 833 | name=$(echo "$1" | awk '{print $7}') | ||
| 834 | if [ "$name" != "" ]; then | ||
| 835 | grep -E "$name\s" /usr/include/linux/input-event-codes.h | grep -F "/*" | sed 's,[^/]*/,/,' | ||
| 836 | fi | ||
| 837 | } | ||
| 838 | |||
| 839 | grep -F SDL_SCANCODE scancodes_linux.h | while read line; do | ||
| 840 | comment=$(get_comment "$line") | ||
| 841 | if [ "$comment" != "" ]; then | ||
| 842 | echo " $line $comment" | ||
| 843 | fi | ||
| 844 | done | ||
| 845 | #endif // end script | ||
| 846 | |||
| 847 | |||
| 848 | /* *INDENT-ON* */ // clang-format on | ||
diff --git a/contrib/SDL-3.2.8/src/events/scancodes_windows.h b/contrib/SDL-3.2.8/src/events/scancodes_windows.h new file mode 100644 index 0000000..6f35114 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/scancodes_windows.h | |||
| @@ -0,0 +1,286 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Windows scancode to SDL scancode mapping table | ||
| 25 | * https://learn.microsoft.com/windows/win32/inputdev/about-keyboard-input#scan-codes */ | ||
| 26 | |||
| 27 | /* *INDENT-OFF* */ // clang-format off | ||
| 28 | static const SDL_Scancode windows_scancode_table[] = { | ||
| 29 | /*0x00*/ SDL_SCANCODE_UNKNOWN, | ||
| 30 | /*0x01*/ SDL_SCANCODE_ESCAPE, | ||
| 31 | /*0x02*/ SDL_SCANCODE_1, | ||
| 32 | /*0x03*/ SDL_SCANCODE_2, | ||
| 33 | /*0x04*/ SDL_SCANCODE_3, | ||
| 34 | /*0x05*/ SDL_SCANCODE_4, | ||
| 35 | /*0x06*/ SDL_SCANCODE_5, | ||
| 36 | /*0x07*/ SDL_SCANCODE_6, | ||
| 37 | /*0x08*/ SDL_SCANCODE_7, | ||
| 38 | /*0x09*/ SDL_SCANCODE_8, | ||
| 39 | /*0x0a*/ SDL_SCANCODE_9, | ||
| 40 | /*0x0b*/ SDL_SCANCODE_0, | ||
| 41 | /*0x0c*/ SDL_SCANCODE_MINUS, | ||
| 42 | /*0x0d*/ SDL_SCANCODE_EQUALS, | ||
| 43 | /*0x0e*/ SDL_SCANCODE_BACKSPACE, | ||
| 44 | /*0x0f*/ SDL_SCANCODE_TAB, | ||
| 45 | /*0x10*/ SDL_SCANCODE_Q, | ||
| 46 | /*0x11*/ SDL_SCANCODE_W, | ||
| 47 | /*0x12*/ SDL_SCANCODE_E, | ||
| 48 | /*0x13*/ SDL_SCANCODE_R, | ||
| 49 | /*0x14*/ SDL_SCANCODE_T, | ||
| 50 | /*0x15*/ SDL_SCANCODE_Y, | ||
| 51 | /*0x16*/ SDL_SCANCODE_U, | ||
| 52 | /*0x17*/ SDL_SCANCODE_I, | ||
| 53 | /*0x18*/ SDL_SCANCODE_O, | ||
| 54 | /*0x19*/ SDL_SCANCODE_P, | ||
| 55 | /*0x1a*/ SDL_SCANCODE_LEFTBRACKET, | ||
| 56 | /*0x1b*/ SDL_SCANCODE_RIGHTBRACKET, | ||
| 57 | /*0x1c*/ SDL_SCANCODE_RETURN, | ||
| 58 | /*0x1d*/ SDL_SCANCODE_LCTRL, | ||
| 59 | /*0x1e*/ SDL_SCANCODE_A, | ||
| 60 | /*0x1f*/ SDL_SCANCODE_S, | ||
| 61 | /*0x20*/ SDL_SCANCODE_D, | ||
| 62 | /*0x21*/ SDL_SCANCODE_F, | ||
| 63 | /*0x22*/ SDL_SCANCODE_G, | ||
| 64 | /*0x23*/ SDL_SCANCODE_H, | ||
| 65 | /*0x24*/ SDL_SCANCODE_J, | ||
| 66 | /*0x25*/ SDL_SCANCODE_K, | ||
| 67 | /*0x26*/ SDL_SCANCODE_L, | ||
| 68 | /*0x27*/ SDL_SCANCODE_SEMICOLON, | ||
| 69 | /*0x28*/ SDL_SCANCODE_APOSTROPHE, | ||
| 70 | /*0x29*/ SDL_SCANCODE_GRAVE, | ||
| 71 | /*0x2a*/ SDL_SCANCODE_LSHIFT, | ||
| 72 | /*0x2b*/ SDL_SCANCODE_BACKSLASH, | ||
| 73 | /*0x2c*/ SDL_SCANCODE_Z, | ||
| 74 | /*0x2d*/ SDL_SCANCODE_X, | ||
| 75 | /*0x2e*/ SDL_SCANCODE_C, | ||
| 76 | /*0x2f*/ SDL_SCANCODE_V, | ||
| 77 | /*0x30*/ SDL_SCANCODE_B, | ||
| 78 | /*0x31*/ SDL_SCANCODE_N, | ||
| 79 | /*0x32*/ SDL_SCANCODE_M, | ||
| 80 | /*0x33*/ SDL_SCANCODE_COMMA, | ||
| 81 | /*0x34*/ SDL_SCANCODE_PERIOD, | ||
| 82 | /*0x35*/ SDL_SCANCODE_SLASH, | ||
| 83 | /*0x36*/ SDL_SCANCODE_RSHIFT, | ||
| 84 | /*0x37*/ SDL_SCANCODE_KP_MULTIPLY, | ||
| 85 | /*0x38*/ SDL_SCANCODE_LALT, | ||
| 86 | /*0x39*/ SDL_SCANCODE_SPACE, | ||
| 87 | /*0x3a*/ SDL_SCANCODE_CAPSLOCK, | ||
| 88 | /*0x3b*/ SDL_SCANCODE_F1, | ||
| 89 | /*0x3c*/ SDL_SCANCODE_F2, | ||
| 90 | /*0x3d*/ SDL_SCANCODE_F3, | ||
| 91 | /*0x3e*/ SDL_SCANCODE_F4, | ||
| 92 | /*0x3f*/ SDL_SCANCODE_F5, | ||
| 93 | /*0x40*/ SDL_SCANCODE_F6, | ||
| 94 | /*0x41*/ SDL_SCANCODE_F7, | ||
| 95 | /*0x42*/ SDL_SCANCODE_F8, | ||
| 96 | /*0x43*/ SDL_SCANCODE_F9, | ||
| 97 | /*0x44*/ SDL_SCANCODE_F10, | ||
| 98 | /*0x45*/ SDL_SCANCODE_NUMLOCKCLEAR, | ||
| 99 | /*0x46*/ SDL_SCANCODE_SCROLLLOCK, | ||
| 100 | /*0x47*/ SDL_SCANCODE_KP_7, | ||
| 101 | /*0x48*/ SDL_SCANCODE_KP_8, | ||
| 102 | /*0x49*/ SDL_SCANCODE_KP_9, | ||
| 103 | /*0x4a*/ SDL_SCANCODE_KP_MINUS, | ||
| 104 | /*0x4b*/ SDL_SCANCODE_KP_4, | ||
| 105 | /*0x4c*/ SDL_SCANCODE_KP_5, | ||
| 106 | /*0x4d*/ SDL_SCANCODE_KP_6, | ||
| 107 | /*0x4e*/ SDL_SCANCODE_KP_PLUS, | ||
| 108 | /*0x4f*/ SDL_SCANCODE_KP_1, | ||
| 109 | /*0x50*/ SDL_SCANCODE_KP_2, | ||
| 110 | /*0x51*/ SDL_SCANCODE_KP_3, | ||
| 111 | /*0x52*/ SDL_SCANCODE_KP_0, | ||
| 112 | /*0x53*/ SDL_SCANCODE_KP_PERIOD, | ||
| 113 | /*0x54*/ SDL_SCANCODE_UNKNOWN, | ||
| 114 | /*0x55*/ SDL_SCANCODE_UNKNOWN, | ||
| 115 | /*0x56*/ SDL_SCANCODE_NONUSBACKSLASH, | ||
| 116 | /*0x57*/ SDL_SCANCODE_F11, | ||
| 117 | /*0x58*/ SDL_SCANCODE_F12, | ||
| 118 | /*0x59*/ SDL_SCANCODE_KP_EQUALS, | ||
| 119 | /*0x5a*/ SDL_SCANCODE_UNKNOWN, | ||
| 120 | /*0x5b*/ SDL_SCANCODE_UNKNOWN, | ||
| 121 | /*0x5c*/ SDL_SCANCODE_INTERNATIONAL6, | ||
| 122 | /*0x5d*/ SDL_SCANCODE_UNKNOWN, | ||
| 123 | /*0x5e*/ SDL_SCANCODE_UNKNOWN, | ||
| 124 | /*0x5f*/ SDL_SCANCODE_UNKNOWN, | ||
| 125 | /*0x60*/ SDL_SCANCODE_UNKNOWN, | ||
| 126 | /*0x61*/ SDL_SCANCODE_UNKNOWN, | ||
| 127 | /*0x62*/ SDL_SCANCODE_UNKNOWN, | ||
| 128 | /*0x63*/ SDL_SCANCODE_UNKNOWN, | ||
| 129 | /*0x64*/ SDL_SCANCODE_F13, | ||
| 130 | /*0x65*/ SDL_SCANCODE_F14, | ||
| 131 | /*0x66*/ SDL_SCANCODE_F15, | ||
| 132 | /*0x67*/ SDL_SCANCODE_F16, | ||
| 133 | /*0x68*/ SDL_SCANCODE_F17, | ||
| 134 | /*0x69*/ SDL_SCANCODE_F18, | ||
| 135 | /*0x6a*/ SDL_SCANCODE_F19, | ||
| 136 | /*0x6b*/ SDL_SCANCODE_F20, | ||
| 137 | /*0x6c*/ SDL_SCANCODE_F21, | ||
| 138 | /*0x6d*/ SDL_SCANCODE_F22, | ||
| 139 | /*0x6e*/ SDL_SCANCODE_F23, | ||
| 140 | /*0x6f*/ SDL_SCANCODE_UNKNOWN, | ||
| 141 | /*0x70*/ SDL_SCANCODE_INTERNATIONAL2, | ||
| 142 | /*0x71*/ SDL_SCANCODE_LANG2, | ||
| 143 | /*0x72*/ SDL_SCANCODE_LANG1, | ||
| 144 | /*0x73*/ SDL_SCANCODE_INTERNATIONAL1, | ||
| 145 | /*0x74*/ SDL_SCANCODE_UNKNOWN, | ||
| 146 | /*0x75*/ SDL_SCANCODE_UNKNOWN, | ||
| 147 | /*0x76*/ SDL_SCANCODE_F24, | ||
| 148 | /*0x77*/ SDL_SCANCODE_LANG4, | ||
| 149 | /*0x78*/ SDL_SCANCODE_LANG3, | ||
| 150 | /*0x79*/ SDL_SCANCODE_INTERNATIONAL4, | ||
| 151 | /*0x7a*/ SDL_SCANCODE_UNKNOWN, | ||
| 152 | /*0x7b*/ SDL_SCANCODE_INTERNATIONAL5, | ||
| 153 | /*0x7c*/ SDL_SCANCODE_UNKNOWN, | ||
| 154 | /*0x7d*/ SDL_SCANCODE_INTERNATIONAL3, | ||
| 155 | /*0x7e*/ SDL_SCANCODE_KP_COMMA, | ||
| 156 | /*0x7f*/ SDL_SCANCODE_UNKNOWN, | ||
| 157 | /*0xe000*/ SDL_SCANCODE_UNKNOWN, | ||
| 158 | /*0xe001*/ SDL_SCANCODE_UNKNOWN, | ||
| 159 | /*0xe002*/ SDL_SCANCODE_UNKNOWN, | ||
| 160 | /*0xe003*/ SDL_SCANCODE_UNKNOWN, | ||
| 161 | /*0xe004*/ SDL_SCANCODE_UNKNOWN, | ||
| 162 | /*0xe005*/ SDL_SCANCODE_UNKNOWN, | ||
| 163 | /*0xe006*/ SDL_SCANCODE_UNKNOWN, | ||
| 164 | /*0xe007*/ SDL_SCANCODE_UNKNOWN, | ||
| 165 | /*0xe008*/ SDL_SCANCODE_UNKNOWN, | ||
| 166 | /*0xe009*/ SDL_SCANCODE_UNKNOWN, | ||
| 167 | /*0xe00a*/ SDL_SCANCODE_PASTE, | ||
| 168 | /*0xe00b*/ SDL_SCANCODE_UNKNOWN, | ||
| 169 | /*0xe00c*/ SDL_SCANCODE_UNKNOWN, | ||
| 170 | /*0xe00d*/ SDL_SCANCODE_UNKNOWN, | ||
| 171 | /*0xe00e*/ SDL_SCANCODE_UNKNOWN, | ||
| 172 | /*0xe00f*/ SDL_SCANCODE_UNKNOWN, | ||
| 173 | /*0xe010*/ SDL_SCANCODE_MEDIA_PREVIOUS_TRACK, | ||
| 174 | /*0xe011*/ SDL_SCANCODE_UNKNOWN, | ||
| 175 | /*0xe012*/ SDL_SCANCODE_UNKNOWN, | ||
| 176 | /*0xe013*/ SDL_SCANCODE_UNKNOWN, | ||
| 177 | /*0xe014*/ SDL_SCANCODE_UNKNOWN, | ||
| 178 | /*0xe015*/ SDL_SCANCODE_UNKNOWN, | ||
| 179 | /*0xe016*/ SDL_SCANCODE_UNKNOWN, | ||
| 180 | /*0xe017*/ SDL_SCANCODE_CUT, | ||
| 181 | /*0xe018*/ SDL_SCANCODE_COPY, | ||
| 182 | /*0xe019*/ SDL_SCANCODE_MEDIA_NEXT_TRACK, | ||
| 183 | /*0xe01a*/ SDL_SCANCODE_UNKNOWN, | ||
| 184 | /*0xe01b*/ SDL_SCANCODE_UNKNOWN, | ||
| 185 | /*0xe01c*/ SDL_SCANCODE_KP_ENTER, | ||
| 186 | /*0xe01d*/ SDL_SCANCODE_RCTRL, | ||
| 187 | /*0xe01e*/ SDL_SCANCODE_UNKNOWN, | ||
| 188 | /*0xe01f*/ SDL_SCANCODE_UNKNOWN, | ||
| 189 | /*0xe020*/ SDL_SCANCODE_MUTE, | ||
| 190 | /*0xe021*/ SDL_SCANCODE_UNKNOWN, // LaunchApp2 | ||
| 191 | /*0xe022*/ SDL_SCANCODE_MEDIA_PLAY_PAUSE, | ||
| 192 | /*0xe023*/ SDL_SCANCODE_UNKNOWN, | ||
| 193 | /*0xe024*/ SDL_SCANCODE_MEDIA_STOP, | ||
| 194 | /*0xe025*/ SDL_SCANCODE_UNKNOWN, | ||
| 195 | /*0xe026*/ SDL_SCANCODE_UNKNOWN, | ||
| 196 | /*0xe027*/ SDL_SCANCODE_UNKNOWN, | ||
| 197 | /*0xe028*/ SDL_SCANCODE_UNKNOWN, | ||
| 198 | /*0xe029*/ SDL_SCANCODE_UNKNOWN, | ||
| 199 | /*0xe02a*/ SDL_SCANCODE_UNKNOWN, | ||
| 200 | /*0xe02b*/ SDL_SCANCODE_UNKNOWN, | ||
| 201 | /*0xe02c*/ SDL_SCANCODE_MEDIA_EJECT, | ||
| 202 | /*0xe02d*/ SDL_SCANCODE_UNKNOWN, | ||
| 203 | /*0xe02e*/ SDL_SCANCODE_VOLUMEDOWN, | ||
| 204 | /*0xe02f*/ SDL_SCANCODE_UNKNOWN, | ||
| 205 | /*0xe030*/ SDL_SCANCODE_VOLUMEUP, | ||
| 206 | /*0xe031*/ SDL_SCANCODE_UNKNOWN, | ||
| 207 | /*0xe032*/ SDL_SCANCODE_AC_HOME, | ||
| 208 | /*0xe033*/ SDL_SCANCODE_UNKNOWN, | ||
| 209 | /*0xe034*/ SDL_SCANCODE_UNKNOWN, | ||
| 210 | /*0xe035*/ SDL_SCANCODE_KP_DIVIDE, | ||
| 211 | /*0xe036*/ SDL_SCANCODE_UNKNOWN, | ||
| 212 | /*0xe037*/ SDL_SCANCODE_PRINTSCREEN, | ||
| 213 | /*0xe038*/ SDL_SCANCODE_RALT, | ||
| 214 | /*0xe039*/ SDL_SCANCODE_UNKNOWN, | ||
| 215 | /*0xe03a*/ SDL_SCANCODE_UNKNOWN, | ||
| 216 | /*0xe03b*/ SDL_SCANCODE_HELP, | ||
| 217 | /*0xe03c*/ SDL_SCANCODE_UNKNOWN, | ||
| 218 | /*0xe03d*/ SDL_SCANCODE_UNKNOWN, | ||
| 219 | /*0xe03e*/ SDL_SCANCODE_UNKNOWN, | ||
| 220 | /*0xe03f*/ SDL_SCANCODE_UNKNOWN, | ||
| 221 | /*0xe040*/ SDL_SCANCODE_UNKNOWN, | ||
| 222 | /*0xe041*/ SDL_SCANCODE_UNKNOWN, | ||
| 223 | /*0xe042*/ SDL_SCANCODE_UNKNOWN, | ||
| 224 | /*0xe043*/ SDL_SCANCODE_UNKNOWN, | ||
| 225 | /*0xe044*/ SDL_SCANCODE_UNKNOWN, | ||
| 226 | /*0xe045*/ SDL_SCANCODE_NUMLOCKCLEAR, | ||
| 227 | /*0xe046*/ SDL_SCANCODE_PAUSE, | ||
| 228 | /*0xe047*/ SDL_SCANCODE_HOME, | ||
| 229 | /*0xe048*/ SDL_SCANCODE_UP, | ||
| 230 | /*0xe049*/ SDL_SCANCODE_PAGEUP, | ||
| 231 | /*0xe04a*/ SDL_SCANCODE_UNKNOWN, | ||
| 232 | /*0xe04b*/ SDL_SCANCODE_LEFT, | ||
| 233 | /*0xe04c*/ SDL_SCANCODE_UNKNOWN, | ||
| 234 | /*0xe04d*/ SDL_SCANCODE_RIGHT, | ||
| 235 | /*0xe04e*/ SDL_SCANCODE_UNKNOWN, | ||
| 236 | /*0xe04f*/ SDL_SCANCODE_END, | ||
| 237 | /*0xe050*/ SDL_SCANCODE_DOWN, | ||
| 238 | /*0xe051*/ SDL_SCANCODE_PAGEDOWN, | ||
| 239 | /*0xe052*/ SDL_SCANCODE_INSERT, | ||
| 240 | /*0xe053*/ SDL_SCANCODE_DELETE, | ||
| 241 | /*0xe054*/ SDL_SCANCODE_UNKNOWN, | ||
| 242 | /*0xe055*/ SDL_SCANCODE_UNKNOWN, | ||
| 243 | /*0xe056*/ SDL_SCANCODE_UNKNOWN, | ||
| 244 | /*0xe057*/ SDL_SCANCODE_UNKNOWN, | ||
| 245 | /*0xe058*/ SDL_SCANCODE_UNKNOWN, | ||
| 246 | /*0xe059*/ SDL_SCANCODE_UNKNOWN, | ||
| 247 | /*0xe05a*/ SDL_SCANCODE_UNKNOWN, | ||
| 248 | /*0xe05b*/ SDL_SCANCODE_LGUI, | ||
| 249 | /*0xe05c*/ SDL_SCANCODE_RGUI, | ||
| 250 | /*0xe05d*/ SDL_SCANCODE_APPLICATION, | ||
| 251 | /*0xe05e*/ SDL_SCANCODE_POWER, | ||
| 252 | /*0xe05f*/ SDL_SCANCODE_SLEEP, | ||
| 253 | /*0xe060*/ SDL_SCANCODE_UNKNOWN, | ||
| 254 | /*0xe061*/ SDL_SCANCODE_UNKNOWN, | ||
| 255 | /*0xe062*/ SDL_SCANCODE_UNKNOWN, | ||
| 256 | /*0xe063*/ SDL_SCANCODE_UNKNOWN, | ||
| 257 | /*0xe064*/ SDL_SCANCODE_UNKNOWN, | ||
| 258 | /*0xe065*/ SDL_SCANCODE_AC_SEARCH, | ||
| 259 | /*0xe066*/ SDL_SCANCODE_AC_BOOKMARKS, | ||
| 260 | /*0xe067*/ SDL_SCANCODE_AC_REFRESH, | ||
| 261 | /*0xe068*/ SDL_SCANCODE_AC_STOP, | ||
| 262 | /*0xe069*/ SDL_SCANCODE_AC_FORWARD, | ||
| 263 | /*0xe06a*/ SDL_SCANCODE_AC_BACK, | ||
| 264 | /*0xe06b*/ SDL_SCANCODE_UNKNOWN, // LaunchApp1 | ||
| 265 | /*0xe06c*/ SDL_SCANCODE_UNKNOWN, // LaunchMail | ||
| 266 | /*0xe06d*/ SDL_SCANCODE_MEDIA_SELECT, | ||
| 267 | /*0xe06e*/ SDL_SCANCODE_UNKNOWN, | ||
| 268 | /*0xe06f*/ SDL_SCANCODE_UNKNOWN, | ||
| 269 | /*0xe070*/ SDL_SCANCODE_UNKNOWN, | ||
| 270 | /*0xe071*/ SDL_SCANCODE_UNKNOWN, | ||
| 271 | /*0xe072*/ SDL_SCANCODE_UNKNOWN, | ||
| 272 | /*0xe073*/ SDL_SCANCODE_UNKNOWN, | ||
| 273 | /*0xe074*/ SDL_SCANCODE_UNKNOWN, | ||
| 274 | /*0xe075*/ SDL_SCANCODE_UNKNOWN, | ||
| 275 | /*0xe076*/ SDL_SCANCODE_UNKNOWN, | ||
| 276 | /*0xe077*/ SDL_SCANCODE_UNKNOWN, | ||
| 277 | /*0xe078*/ SDL_SCANCODE_UNKNOWN, | ||
| 278 | /*0xe079*/ SDL_SCANCODE_UNKNOWN, | ||
| 279 | /*0xe07a*/ SDL_SCANCODE_UNKNOWN, | ||
| 280 | /*0xe07b*/ SDL_SCANCODE_UNKNOWN, | ||
| 281 | /*0xe07c*/ SDL_SCANCODE_UNKNOWN, | ||
| 282 | /*0xe07d*/ SDL_SCANCODE_UNKNOWN, | ||
| 283 | /*0xe07e*/ SDL_SCANCODE_UNKNOWN, | ||
| 284 | /*0xe07f*/ SDL_SCANCODE_UNKNOWN | ||
| 285 | }; | ||
| 286 | /* *INDENT-ON* */ // clang-format on | ||
diff --git a/contrib/SDL-3.2.8/src/events/scancodes_xfree86.h b/contrib/SDL-3.2.8/src/events/scancodes_xfree86.h new file mode 100644 index 0000000..5e51bb1 --- /dev/null +++ b/contrib/SDL-3.2.8/src/events/scancodes_xfree86.h | |||
| @@ -0,0 +1,520 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #ifndef scancodes_xfree86_h_ | ||
| 24 | #define scancodes_xfree86_h_ | ||
| 25 | |||
| 26 | /* XFree86 key code to SDL scancode mapping table | ||
| 27 | Sources: | ||
| 28 | - atKeyNames.h from XFree86 source code | ||
| 29 | */ | ||
| 30 | /* *INDENT-OFF* */ // clang-format off | ||
| 31 | static const SDL_Scancode xfree86_scancode_table[] = { | ||
| 32 | /* 0 */ SDL_SCANCODE_UNKNOWN, | ||
| 33 | /* 1 */ SDL_SCANCODE_ESCAPE, | ||
| 34 | /* 2 */ SDL_SCANCODE_1, | ||
| 35 | /* 3 */ SDL_SCANCODE_2, | ||
| 36 | /* 4 */ SDL_SCANCODE_3, | ||
| 37 | /* 5 */ SDL_SCANCODE_4, | ||
| 38 | /* 6 */ SDL_SCANCODE_5, | ||
| 39 | /* 7 */ SDL_SCANCODE_6, | ||
| 40 | /* 8 */ SDL_SCANCODE_7, | ||
| 41 | /* 9 */ SDL_SCANCODE_8, | ||
| 42 | /* 10 */ SDL_SCANCODE_9, | ||
| 43 | /* 11 */ SDL_SCANCODE_0, | ||
| 44 | /* 12 */ SDL_SCANCODE_MINUS, | ||
| 45 | /* 13 */ SDL_SCANCODE_EQUALS, | ||
| 46 | /* 14 */ SDL_SCANCODE_BACKSPACE, | ||
| 47 | /* 15 */ SDL_SCANCODE_TAB, | ||
| 48 | /* 16 */ SDL_SCANCODE_Q, | ||
| 49 | /* 17 */ SDL_SCANCODE_W, | ||
| 50 | /* 18 */ SDL_SCANCODE_E, | ||
| 51 | /* 19 */ SDL_SCANCODE_R, | ||
| 52 | /* 20 */ SDL_SCANCODE_T, | ||
| 53 | /* 21 */ SDL_SCANCODE_Y, | ||
| 54 | /* 22 */ SDL_SCANCODE_U, | ||
| 55 | /* 23 */ SDL_SCANCODE_I, | ||
| 56 | /* 24 */ SDL_SCANCODE_O, | ||
| 57 | /* 25 */ SDL_SCANCODE_P, | ||
| 58 | /* 26 */ SDL_SCANCODE_LEFTBRACKET, | ||
| 59 | /* 27 */ SDL_SCANCODE_RIGHTBRACKET, | ||
| 60 | /* 28 */ SDL_SCANCODE_RETURN, | ||
| 61 | /* 29 */ SDL_SCANCODE_LCTRL, | ||
| 62 | /* 30 */ SDL_SCANCODE_A, | ||
| 63 | /* 31 */ SDL_SCANCODE_S, | ||
| 64 | /* 32 */ SDL_SCANCODE_D, | ||
| 65 | /* 33 */ SDL_SCANCODE_F, | ||
| 66 | /* 34 */ SDL_SCANCODE_G, | ||
| 67 | /* 35 */ SDL_SCANCODE_H, | ||
| 68 | /* 36 */ SDL_SCANCODE_J, | ||
| 69 | /* 37 */ SDL_SCANCODE_K, | ||
| 70 | /* 38 */ SDL_SCANCODE_L, | ||
| 71 | /* 39 */ SDL_SCANCODE_SEMICOLON, | ||
| 72 | /* 40 */ SDL_SCANCODE_APOSTROPHE, | ||
| 73 | /* 41 */ SDL_SCANCODE_GRAVE, | ||
| 74 | /* 42 */ SDL_SCANCODE_LSHIFT, | ||
| 75 | /* 43 */ SDL_SCANCODE_BACKSLASH, | ||
| 76 | /* 44 */ SDL_SCANCODE_Z, | ||
| 77 | /* 45 */ SDL_SCANCODE_X, | ||
| 78 | /* 46 */ SDL_SCANCODE_C, | ||
| 79 | /* 47 */ SDL_SCANCODE_V, | ||
| 80 | /* 48 */ SDL_SCANCODE_B, | ||
| 81 | /* 49 */ SDL_SCANCODE_N, | ||
| 82 | /* 50 */ SDL_SCANCODE_M, | ||
| 83 | /* 51 */ SDL_SCANCODE_COMMA, | ||
| 84 | /* 52 */ SDL_SCANCODE_PERIOD, | ||
| 85 | /* 53 */ SDL_SCANCODE_SLASH, | ||
| 86 | /* 54 */ SDL_SCANCODE_RSHIFT, | ||
| 87 | /* 55 */ SDL_SCANCODE_KP_MULTIPLY, | ||
| 88 | /* 56 */ SDL_SCANCODE_LALT, | ||
| 89 | /* 57 */ SDL_SCANCODE_SPACE, | ||
| 90 | /* 58 */ SDL_SCANCODE_CAPSLOCK, | ||
| 91 | /* 59 */ SDL_SCANCODE_F1, | ||
| 92 | /* 60 */ SDL_SCANCODE_F2, | ||
| 93 | /* 61 */ SDL_SCANCODE_F3, | ||
| 94 | /* 62 */ SDL_SCANCODE_F4, | ||
| 95 | /* 63 */ SDL_SCANCODE_F5, | ||
| 96 | /* 64 */ SDL_SCANCODE_F6, | ||
| 97 | /* 65 */ SDL_SCANCODE_F7, | ||
| 98 | /* 66 */ SDL_SCANCODE_F8, | ||
| 99 | /* 67 */ SDL_SCANCODE_F9, | ||
| 100 | /* 68 */ SDL_SCANCODE_F10, | ||
| 101 | /* 69 */ SDL_SCANCODE_NUMLOCKCLEAR, | ||
| 102 | /* 70 */ SDL_SCANCODE_SCROLLLOCK, | ||
| 103 | /* 71 */ SDL_SCANCODE_KP_7, | ||
| 104 | /* 72 */ SDL_SCANCODE_KP_8, | ||
| 105 | /* 73 */ SDL_SCANCODE_KP_9, | ||
| 106 | /* 74 */ SDL_SCANCODE_KP_MINUS, | ||
| 107 | /* 75 */ SDL_SCANCODE_KP_4, | ||
| 108 | /* 76 */ SDL_SCANCODE_KP_5, | ||
| 109 | /* 77 */ SDL_SCANCODE_KP_6, | ||
| 110 | /* 78 */ SDL_SCANCODE_KP_PLUS, | ||
| 111 | /* 79 */ SDL_SCANCODE_KP_1, | ||
| 112 | /* 80 */ SDL_SCANCODE_KP_2, | ||
| 113 | /* 81 */ SDL_SCANCODE_KP_3, | ||
| 114 | /* 82 */ SDL_SCANCODE_KP_0, | ||
| 115 | /* 83 */ SDL_SCANCODE_KP_PERIOD, | ||
| 116 | /* 84 */ SDL_SCANCODE_SYSREQ, | ||
| 117 | /* 85 */ SDL_SCANCODE_MODE, | ||
| 118 | /* 86 */ SDL_SCANCODE_NONUSBACKSLASH, | ||
| 119 | /* 87 */ SDL_SCANCODE_F11, | ||
| 120 | /* 88 */ SDL_SCANCODE_F12, | ||
| 121 | /* 89 */ SDL_SCANCODE_HOME, | ||
| 122 | /* 90 */ SDL_SCANCODE_UP, | ||
| 123 | /* 91 */ SDL_SCANCODE_PAGEUP, | ||
| 124 | /* 92 */ SDL_SCANCODE_LEFT, | ||
| 125 | /* 93 */ SDL_SCANCODE_UNKNOWN, // on PowerBook G4 / KEY_Begin | ||
| 126 | /* 94 */ SDL_SCANCODE_RIGHT, | ||
| 127 | /* 95 */ SDL_SCANCODE_END, | ||
| 128 | /* 96 */ SDL_SCANCODE_DOWN, | ||
| 129 | /* 97 */ SDL_SCANCODE_PAGEDOWN, | ||
| 130 | /* 98 */ SDL_SCANCODE_INSERT, | ||
| 131 | /* 99 */ SDL_SCANCODE_DELETE, | ||
| 132 | /* 100 */ SDL_SCANCODE_KP_ENTER, | ||
| 133 | /* 101 */ SDL_SCANCODE_RCTRL, | ||
| 134 | /* 102 */ SDL_SCANCODE_PAUSE, | ||
| 135 | /* 103 */ SDL_SCANCODE_PRINTSCREEN, | ||
| 136 | /* 104 */ SDL_SCANCODE_KP_DIVIDE, | ||
| 137 | /* 105 */ SDL_SCANCODE_RALT, | ||
| 138 | /* 106 */ SDL_SCANCODE_UNKNOWN, // BREAK | ||
| 139 | /* 107 */ SDL_SCANCODE_LGUI, | ||
| 140 | /* 108 */ SDL_SCANCODE_RGUI, | ||
| 141 | /* 109 */ SDL_SCANCODE_APPLICATION, | ||
| 142 | /* 110 */ SDL_SCANCODE_F13, | ||
| 143 | /* 111 */ SDL_SCANCODE_F14, | ||
| 144 | /* 112 */ SDL_SCANCODE_F15, | ||
| 145 | /* 113 */ SDL_SCANCODE_F16, | ||
| 146 | /* 114 */ SDL_SCANCODE_F17, | ||
| 147 | /* 115 */ SDL_SCANCODE_INTERNATIONAL1, // \_ | ||
| 148 | /* 116 */ SDL_SCANCODE_UNKNOWN, /* is translated to XK_ISO_Level3_Shift by my X server, but I have no keyboard that generates this code, so I don't know what the correct SDL_SCANCODE_* for it is */ | ||
| 149 | /* 117 */ SDL_SCANCODE_UNKNOWN, | ||
| 150 | /* 118 */ SDL_SCANCODE_KP_EQUALS, | ||
| 151 | /* 119 */ SDL_SCANCODE_UNKNOWN, | ||
| 152 | /* 120 */ SDL_SCANCODE_UNKNOWN, | ||
| 153 | /* 121 */ SDL_SCANCODE_INTERNATIONAL4, // Henkan_Mode | ||
| 154 | /* 122 */ SDL_SCANCODE_UNKNOWN, | ||
| 155 | /* 123 */ SDL_SCANCODE_INTERNATIONAL5, // Muhenkan | ||
| 156 | /* 124 */ SDL_SCANCODE_UNKNOWN, | ||
| 157 | /* 125 */ SDL_SCANCODE_INTERNATIONAL3, // Yen | ||
| 158 | /* 126 */ SDL_SCANCODE_UNKNOWN, | ||
| 159 | /* 127 */ SDL_SCANCODE_UNKNOWN, | ||
| 160 | /* 128 */ SDL_SCANCODE_UNKNOWN, | ||
| 161 | /* 129 */ SDL_SCANCODE_UNKNOWN, | ||
| 162 | /* 130 */ SDL_SCANCODE_UNKNOWN, | ||
| 163 | /* 131 */ SDL_SCANCODE_UNKNOWN, | ||
| 164 | /* 132 */ SDL_SCANCODE_POWER, | ||
| 165 | /* 133 */ SDL_SCANCODE_MUTE, | ||
| 166 | /* 134 */ SDL_SCANCODE_VOLUMEDOWN, | ||
| 167 | /* 135 */ SDL_SCANCODE_VOLUMEUP, | ||
| 168 | /* 136 */ SDL_SCANCODE_HELP, | ||
| 169 | /* 137 */ SDL_SCANCODE_STOP, | ||
| 170 | /* 138 */ SDL_SCANCODE_AGAIN, | ||
| 171 | /* 139 */ SDL_SCANCODE_UNKNOWN, // PROPS | ||
| 172 | /* 140 */ SDL_SCANCODE_UNDO, | ||
| 173 | /* 141 */ SDL_SCANCODE_UNKNOWN, // FRONT | ||
| 174 | /* 142 */ SDL_SCANCODE_COPY, | ||
| 175 | /* 143 */ SDL_SCANCODE_UNKNOWN, // OPEN | ||
| 176 | /* 144 */ SDL_SCANCODE_PASTE, | ||
| 177 | /* 145 */ SDL_SCANCODE_FIND, | ||
| 178 | /* 146 */ SDL_SCANCODE_CUT, | ||
| 179 | }; | ||
| 180 | |||
| 181 | // This is largely identical to the Linux keycode mapping | ||
| 182 | static const SDL_Scancode xfree86_scancode_table2[] = { | ||
| 183 | /* 0, 0x000 */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 184 | /* 1, 0x001 */ SDL_SCANCODE_ESCAPE, // Escape | ||
| 185 | /* 2, 0x002 */ SDL_SCANCODE_1, // 1 | ||
| 186 | /* 3, 0x003 */ SDL_SCANCODE_2, // 2 | ||
| 187 | /* 4, 0x004 */ SDL_SCANCODE_3, // 3 | ||
| 188 | /* 5, 0x005 */ SDL_SCANCODE_4, // 4 | ||
| 189 | /* 6, 0x006 */ SDL_SCANCODE_5, // 5 | ||
| 190 | /* 7, 0x007 */ SDL_SCANCODE_6, // 6 | ||
| 191 | /* 8, 0x008 */ SDL_SCANCODE_7, // 7 | ||
| 192 | /* 9, 0x009 */ SDL_SCANCODE_8, // 8 | ||
| 193 | /* 10, 0x00a */ SDL_SCANCODE_9, // 9 | ||
| 194 | /* 11, 0x00b */ SDL_SCANCODE_0, // 0 | ||
| 195 | /* 12, 0x00c */ SDL_SCANCODE_MINUS, // minus | ||
| 196 | /* 13, 0x00d */ SDL_SCANCODE_EQUALS, // equal | ||
| 197 | /* 14, 0x00e */ SDL_SCANCODE_BACKSPACE, // BackSpace | ||
| 198 | /* 15, 0x00f */ SDL_SCANCODE_TAB, // Tab | ||
| 199 | /* 16, 0x010 */ SDL_SCANCODE_Q, // q | ||
| 200 | /* 17, 0x011 */ SDL_SCANCODE_W, // w | ||
| 201 | /* 18, 0x012 */ SDL_SCANCODE_E, // e | ||
| 202 | /* 19, 0x013 */ SDL_SCANCODE_R, // r | ||
| 203 | /* 20, 0x014 */ SDL_SCANCODE_T, // t | ||
| 204 | /* 21, 0x015 */ SDL_SCANCODE_Y, // y | ||
| 205 | /* 22, 0x016 */ SDL_SCANCODE_U, // u | ||
| 206 | /* 23, 0x017 */ SDL_SCANCODE_I, // i | ||
| 207 | /* 24, 0x018 */ SDL_SCANCODE_O, // o | ||
| 208 | /* 25, 0x019 */ SDL_SCANCODE_P, // p | ||
| 209 | /* 26, 0x01a */ SDL_SCANCODE_LEFTBRACKET, // bracketleft | ||
| 210 | /* 27, 0x01b */ SDL_SCANCODE_RIGHTBRACKET, // bracketright | ||
| 211 | /* 28, 0x01c */ SDL_SCANCODE_RETURN, // Return | ||
| 212 | /* 29, 0x01d */ SDL_SCANCODE_LCTRL, // Control_L | ||
| 213 | /* 30, 0x01e */ SDL_SCANCODE_A, // a | ||
| 214 | /* 31, 0x01f */ SDL_SCANCODE_S, // s | ||
| 215 | /* 32, 0x020 */ SDL_SCANCODE_D, // d | ||
| 216 | /* 33, 0x021 */ SDL_SCANCODE_F, // f | ||
| 217 | /* 34, 0x022 */ SDL_SCANCODE_G, // g | ||
| 218 | /* 35, 0x023 */ SDL_SCANCODE_H, // h | ||
| 219 | /* 36, 0x024 */ SDL_SCANCODE_J, // j | ||
| 220 | /* 37, 0x025 */ SDL_SCANCODE_K, // k | ||
| 221 | /* 38, 0x026 */ SDL_SCANCODE_L, // l | ||
| 222 | /* 39, 0x027 */ SDL_SCANCODE_SEMICOLON, // semicolon | ||
| 223 | /* 40, 0x028 */ SDL_SCANCODE_APOSTROPHE, // apostrophe | ||
| 224 | /* 41, 0x029 */ SDL_SCANCODE_GRAVE, // grave | ||
| 225 | /* 42, 0x02a */ SDL_SCANCODE_LSHIFT, // Shift_L | ||
| 226 | /* 43, 0x02b */ SDL_SCANCODE_BACKSLASH, // backslash | ||
| 227 | /* 44, 0x02c */ SDL_SCANCODE_Z, // z | ||
| 228 | /* 45, 0x02d */ SDL_SCANCODE_X, // x | ||
| 229 | /* 46, 0x02e */ SDL_SCANCODE_C, // c | ||
| 230 | /* 47, 0x02f */ SDL_SCANCODE_V, // v | ||
| 231 | /* 48, 0x030 */ SDL_SCANCODE_B, // b | ||
| 232 | /* 49, 0x031 */ SDL_SCANCODE_N, // n | ||
| 233 | /* 50, 0x032 */ SDL_SCANCODE_M, // m | ||
| 234 | /* 51, 0x033 */ SDL_SCANCODE_COMMA, // comma | ||
| 235 | /* 52, 0x034 */ SDL_SCANCODE_PERIOD, // period | ||
| 236 | /* 53, 0x035 */ SDL_SCANCODE_SLASH, // slash | ||
| 237 | /* 54, 0x036 */ SDL_SCANCODE_RSHIFT, // Shift_R | ||
| 238 | /* 55, 0x037 */ SDL_SCANCODE_KP_MULTIPLY, // KP_Multiply | ||
| 239 | /* 56, 0x038 */ SDL_SCANCODE_LALT, // Alt_L | ||
| 240 | /* 57, 0x039 */ SDL_SCANCODE_SPACE, // space | ||
| 241 | /* 58, 0x03a */ SDL_SCANCODE_CAPSLOCK, // Caps_Lock | ||
| 242 | /* 59, 0x03b */ SDL_SCANCODE_F1, // F1 | ||
| 243 | /* 60, 0x03c */ SDL_SCANCODE_F2, // F2 | ||
| 244 | /* 61, 0x03d */ SDL_SCANCODE_F3, // F3 | ||
| 245 | /* 62, 0x03e */ SDL_SCANCODE_F4, // F4 | ||
| 246 | /* 63, 0x03f */ SDL_SCANCODE_F5, // F5 | ||
| 247 | /* 64, 0x040 */ SDL_SCANCODE_F6, // F6 | ||
| 248 | /* 65, 0x041 */ SDL_SCANCODE_F7, // F7 | ||
| 249 | /* 66, 0x042 */ SDL_SCANCODE_F8, // F8 | ||
| 250 | /* 67, 0x043 */ SDL_SCANCODE_F9, // F9 | ||
| 251 | /* 68, 0x044 */ SDL_SCANCODE_F10, // F10 | ||
| 252 | /* 69, 0x045 */ SDL_SCANCODE_NUMLOCKCLEAR, // Num_Lock | ||
| 253 | /* 70, 0x046 */ SDL_SCANCODE_SCROLLLOCK, // Scroll_Lock | ||
| 254 | /* 71, 0x047 */ SDL_SCANCODE_KP_7, // KP_Home | ||
| 255 | /* 72, 0x048 */ SDL_SCANCODE_KP_8, // KP_Up | ||
| 256 | /* 73, 0x049 */ SDL_SCANCODE_KP_9, // KP_Prior | ||
| 257 | /* 74, 0x04a */ SDL_SCANCODE_KP_MINUS, // KP_Subtract | ||
| 258 | /* 75, 0x04b */ SDL_SCANCODE_KP_4, // KP_Left | ||
| 259 | /* 76, 0x04c */ SDL_SCANCODE_KP_5, // KP_Begin | ||
| 260 | /* 77, 0x04d */ SDL_SCANCODE_KP_6, // KP_Right | ||
| 261 | /* 78, 0x04e */ SDL_SCANCODE_KP_PLUS, // KP_Add | ||
| 262 | /* 79, 0x04f */ SDL_SCANCODE_KP_1, // KP_End | ||
| 263 | /* 80, 0x050 */ SDL_SCANCODE_KP_2, // KP_Down | ||
| 264 | /* 81, 0x051 */ SDL_SCANCODE_KP_3, // KP_Next | ||
| 265 | /* 82, 0x052 */ SDL_SCANCODE_KP_0, // KP_Insert | ||
| 266 | /* 83, 0x053 */ SDL_SCANCODE_KP_PERIOD, // KP_Delete | ||
| 267 | /* 84, 0x054 */ SDL_SCANCODE_RALT, // ISO_Level3_Shift | ||
| 268 | /* 85, 0x055 */ SDL_SCANCODE_MODE, // ???? | ||
| 269 | /* 86, 0x056 */ SDL_SCANCODE_NONUSBACKSLASH, // less | ||
| 270 | /* 87, 0x057 */ SDL_SCANCODE_F11, // F11 | ||
| 271 | /* 88, 0x058 */ SDL_SCANCODE_F12, // F12 | ||
| 272 | /* 89, 0x059 */ SDL_SCANCODE_INTERNATIONAL1, // \_ | ||
| 273 | /* 90, 0x05a */ SDL_SCANCODE_LANG3, // Katakana | ||
| 274 | /* 91, 0x05b */ SDL_SCANCODE_LANG4, // Hiragana | ||
| 275 | /* 92, 0x05c */ SDL_SCANCODE_INTERNATIONAL4, // Henkan_Mode | ||
| 276 | /* 93, 0x05d */ SDL_SCANCODE_INTERNATIONAL2, // Hiragana_Katakana | ||
| 277 | /* 94, 0x05e */ SDL_SCANCODE_INTERNATIONAL5, // Muhenkan | ||
| 278 | /* 95, 0x05f */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 279 | /* 96, 0x060 */ SDL_SCANCODE_KP_ENTER, // KP_Enter | ||
| 280 | /* 97, 0x061 */ SDL_SCANCODE_RCTRL, // Control_R | ||
| 281 | /* 98, 0x062 */ SDL_SCANCODE_KP_DIVIDE, // KP_Divide | ||
| 282 | /* 99, 0x063 */ SDL_SCANCODE_PRINTSCREEN, // Print | ||
| 283 | /* 100, 0x064 */ SDL_SCANCODE_RALT, // ISO_Level3_Shift, ALTGR, RALT | ||
| 284 | /* 101, 0x065 */ SDL_SCANCODE_UNKNOWN, // Linefeed | ||
| 285 | /* 102, 0x066 */ SDL_SCANCODE_HOME, // Home | ||
| 286 | /* 103, 0x067 */ SDL_SCANCODE_UP, // Up | ||
| 287 | /* 104, 0x068 */ SDL_SCANCODE_PAGEUP, // Prior | ||
| 288 | /* 105, 0x069 */ SDL_SCANCODE_LEFT, // Left | ||
| 289 | /* 106, 0x06a */ SDL_SCANCODE_RIGHT, // Right | ||
| 290 | /* 107, 0x06b */ SDL_SCANCODE_END, // End | ||
| 291 | /* 108, 0x06c */ SDL_SCANCODE_DOWN, // Down | ||
| 292 | /* 109, 0x06d */ SDL_SCANCODE_PAGEDOWN, // Next | ||
| 293 | /* 110, 0x06e */ SDL_SCANCODE_INSERT, // Insert | ||
| 294 | /* 111, 0x06f */ SDL_SCANCODE_DELETE, // Delete | ||
| 295 | /* 112, 0x070 */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 296 | /* 113, 0x071 */ SDL_SCANCODE_MUTE, // XF86AudioMute | ||
| 297 | /* 114, 0x072 */ SDL_SCANCODE_VOLUMEDOWN, // XF86AudioLowerVolume | ||
| 298 | /* 115, 0x073 */ SDL_SCANCODE_VOLUMEUP, // XF86AudioRaiseVolume | ||
| 299 | /* 116, 0x074 */ SDL_SCANCODE_POWER, // XF86PowerOff | ||
| 300 | /* 117, 0x075 */ SDL_SCANCODE_KP_EQUALS, // KP_Equal | ||
| 301 | /* 118, 0x076 */ SDL_SCANCODE_KP_PLUSMINUS, // plusminus | ||
| 302 | /* 119, 0x077 */ SDL_SCANCODE_PAUSE, // Pause | ||
| 303 | /* 120, 0x078 */ SDL_SCANCODE_UNKNOWN, // XF86LaunchA | ||
| 304 | /* 121, 0x079 */ SDL_SCANCODE_KP_PERIOD, // KP_Decimal | ||
| 305 | /* 122, 0x07a */ SDL_SCANCODE_LANG1, // Hangul | ||
| 306 | /* 123, 0x07b */ SDL_SCANCODE_LANG2, // Hangul_Hanja | ||
| 307 | /* 124, 0x07c */ SDL_SCANCODE_INTERNATIONAL3, // Yen | ||
| 308 | /* 125, 0x07d */ SDL_SCANCODE_LGUI, // Super_L | ||
| 309 | /* 126, 0x07e */ SDL_SCANCODE_RGUI, // Super_R | ||
| 310 | /* 127, 0x07f */ SDL_SCANCODE_APPLICATION, // Menu | ||
| 311 | /* 128, 0x080 */ SDL_SCANCODE_CANCEL, // Cancel | ||
| 312 | /* 129, 0x081 */ SDL_SCANCODE_AGAIN, // Redo | ||
| 313 | /* 130, 0x082 */ SDL_SCANCODE_UNKNOWN, // SunProps | ||
| 314 | /* 131, 0x083 */ SDL_SCANCODE_UNDO, // Undo | ||
| 315 | /* 132, 0x084 */ SDL_SCANCODE_UNKNOWN, // SunFront | ||
| 316 | /* 133, 0x085 */ SDL_SCANCODE_COPY, // XF86Copy | ||
| 317 | /* 134, 0x086 */ SDL_SCANCODE_UNKNOWN, // SunOpen, XF86Open | ||
| 318 | /* 135, 0x087 */ SDL_SCANCODE_PASTE, // XF86Paste | ||
| 319 | /* 136, 0x088 */ SDL_SCANCODE_FIND, // Find | ||
| 320 | /* 137, 0x089 */ SDL_SCANCODE_CUT, // XF86Cut | ||
| 321 | /* 138, 0x08a */ SDL_SCANCODE_HELP, // Help | ||
| 322 | /* 139, 0x08b */ SDL_SCANCODE_MENU, // XF86MenuKB | ||
| 323 | /* 140, 0x08c */ SDL_SCANCODE_UNKNOWN, // XF86Calculator | ||
| 324 | /* 141, 0x08d */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 325 | /* 142, 0x08e */ SDL_SCANCODE_SLEEP, // XF86Sleep | ||
| 326 | /* 143, 0x08f */ SDL_SCANCODE_UNKNOWN, // XF86WakeUp | ||
| 327 | /* 144, 0x090 */ SDL_SCANCODE_UNKNOWN, // XF86Explorer | ||
| 328 | /* 145, 0x091 */ SDL_SCANCODE_UNKNOWN, // XF86Send | ||
| 329 | /* 146, 0x092 */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 330 | /* 147, 0x093 */ SDL_SCANCODE_UNKNOWN, // XF86Xfer | ||
| 331 | /* 148, 0x094 */ SDL_SCANCODE_UNKNOWN, // XF86Launch1 | ||
| 332 | /* 149, 0x095 */ SDL_SCANCODE_UNKNOWN, // XF86Launch2 | ||
| 333 | /* 150, 0x096 */ SDL_SCANCODE_UNKNOWN, // XF86WWW | ||
| 334 | /* 151, 0x097 */ SDL_SCANCODE_UNKNOWN, // XF86DOS | ||
| 335 | /* 152, 0x098 */ SDL_SCANCODE_UNKNOWN, // XF86ScreenSaver | ||
| 336 | /* 153, 0x099 */ SDL_SCANCODE_UNKNOWN, // XF86RotateWindows | ||
| 337 | /* 154, 0x09a */ SDL_SCANCODE_UNKNOWN, // XF86TaskPane | ||
| 338 | /* 155, 0x09b */ SDL_SCANCODE_UNKNOWN, // XF86Mail | ||
| 339 | /* 156, 0x09c */ SDL_SCANCODE_AC_BOOKMARKS, // XF86Favorites | ||
| 340 | /* 157, 0x09d */ SDL_SCANCODE_UNKNOWN, // XF86MyComputer | ||
| 341 | /* 158, 0x09e */ SDL_SCANCODE_AC_BACK, // XF86Back | ||
| 342 | /* 159, 0x09f */ SDL_SCANCODE_AC_FORWARD, // XF86Forward | ||
| 343 | /* 160, 0x0a0 */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 344 | /* 161, 0x0a1 */ SDL_SCANCODE_MEDIA_EJECT, // XF86Eject | ||
| 345 | /* 162, 0x0a2 */ SDL_SCANCODE_MEDIA_EJECT, // XF86Eject | ||
| 346 | /* 163, 0x0a3 */ SDL_SCANCODE_MEDIA_NEXT_TRACK, // XF86AudioNext | ||
| 347 | /* 164, 0x0a4 */ SDL_SCANCODE_MEDIA_PLAY_PAUSE, // XF86AudioPlay | ||
| 348 | /* 165, 0x0a5 */ SDL_SCANCODE_MEDIA_PREVIOUS_TRACK, // XF86AudioPrev | ||
| 349 | /* 166, 0x0a6 */ SDL_SCANCODE_MEDIA_STOP, // XF86AudioStop | ||
| 350 | /* 167, 0x0a7 */ SDL_SCANCODE_MEDIA_RECORD, // XF86AudioRecord | ||
| 351 | /* 168, 0x0a8 */ SDL_SCANCODE_MEDIA_REWIND, // XF86AudioRewind | ||
| 352 | /* 169, 0x0a9 */ SDL_SCANCODE_UNKNOWN, // XF86Phone | ||
| 353 | /* 170, 0x0aa */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 354 | /* 171, 0x0ab */ SDL_SCANCODE_F13, // XF86Tools | ||
| 355 | /* 172, 0x0ac */ SDL_SCANCODE_AC_HOME, // XF86HomePage | ||
| 356 | /* 173, 0x0ad */ SDL_SCANCODE_AC_REFRESH, // XF86Reload | ||
| 357 | /* 174, 0x0ae */ SDL_SCANCODE_UNKNOWN, // XF86Close | ||
| 358 | /* 175, 0x0af */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 359 | /* 176, 0x0b0 */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 360 | /* 177, 0x0b1 */ SDL_SCANCODE_UNKNOWN, // XF86ScrollUp | ||
| 361 | /* 178, 0x0b2 */ SDL_SCANCODE_UNKNOWN, // XF86ScrollDown | ||
| 362 | /* 179, 0x0b3 */ SDL_SCANCODE_KP_LEFTPAREN, // parenleft | ||
| 363 | /* 180, 0x0b4 */ SDL_SCANCODE_KP_RIGHTPAREN, // parenright | ||
| 364 | /* 181, 0x0b5 */ SDL_SCANCODE_AC_NEW, // XF86New | ||
| 365 | /* 182, 0x0b6 */ SDL_SCANCODE_AGAIN, // Redo | ||
| 366 | /* 183, 0x0b7 */ SDL_SCANCODE_F13, // XF86Tools | ||
| 367 | /* 184, 0x0b8 */ SDL_SCANCODE_F14, // XF86Launch5 | ||
| 368 | /* 185, 0x0b9 */ SDL_SCANCODE_F15, // XF86Launch6 | ||
| 369 | /* 186, 0x0ba */ SDL_SCANCODE_F16, // XF86Launch7 | ||
| 370 | /* 187, 0x0bb */ SDL_SCANCODE_F17, // XF86Launch8 | ||
| 371 | /* 188, 0x0bc */ SDL_SCANCODE_F18, // XF86Launch9 | ||
| 372 | /* 189, 0x0bd */ SDL_SCANCODE_F19, // NoSymbol | ||
| 373 | /* 190, 0x0be */ SDL_SCANCODE_F20, // XF86AudioMicMute | ||
| 374 | /* 191, 0x0bf */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadToggle | ||
| 375 | /* 192, 0x0c0 */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadOn | ||
| 376 | /* 193, 0x0c1 */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadOff | ||
| 377 | /* 194, 0x0c2 */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 378 | /* 195, 0x0c3 */ SDL_SCANCODE_MODE, // Mode_switch | ||
| 379 | /* 196, 0x0c4 */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 380 | /* 197, 0x0c5 */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 381 | /* 198, 0x0c6 */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 382 | /* 199, 0x0c7 */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 383 | /* 200, 0x0c8 */ SDL_SCANCODE_MEDIA_PLAY, // XF86AudioPlay | ||
| 384 | /* 201, 0x0c9 */ SDL_SCANCODE_MEDIA_PAUSE, // XF86AudioPause | ||
| 385 | /* 202, 0x0ca */ SDL_SCANCODE_UNKNOWN, // XF86Launch3 | ||
| 386 | /* 203, 0x0cb */ SDL_SCANCODE_UNKNOWN, // XF86Launch4 | ||
| 387 | /* 204, 0x0cc */ SDL_SCANCODE_UNKNOWN, // XF86LaunchB | ||
| 388 | /* 205, 0x0cd */ SDL_SCANCODE_UNKNOWN, // XF86Suspend | ||
| 389 | /* 206, 0x0ce */ SDL_SCANCODE_AC_CLOSE, // XF86Close | ||
| 390 | /* 207, 0x0cf */ SDL_SCANCODE_MEDIA_PLAY, // XF86AudioPlay | ||
| 391 | /* 208, 0x0d0 */ SDL_SCANCODE_MEDIA_FAST_FORWARD, // XF86AudioForward | ||
| 392 | /* 209, 0x0d1 */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 393 | /* 210, 0x0d2 */ SDL_SCANCODE_PRINTSCREEN, // Print | ||
| 394 | /* 211, 0x0d3 */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 395 | /* 212, 0x0d4 */ SDL_SCANCODE_UNKNOWN, // XF86WebCam | ||
| 396 | /* 213, 0x0d5 */ SDL_SCANCODE_UNKNOWN, // XF86AudioPreset | ||
| 397 | /* 214, 0x0d6 */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 398 | /* 215, 0x0d7 */ SDL_SCANCODE_UNKNOWN, // XF86Mail | ||
| 399 | /* 216, 0x0d8 */ SDL_SCANCODE_UNKNOWN, // XF86Messenger | ||
| 400 | /* 217, 0x0d9 */ SDL_SCANCODE_AC_SEARCH, // XF86Search | ||
| 401 | /* 218, 0x0da */ SDL_SCANCODE_UNKNOWN, // XF86Go | ||
| 402 | /* 219, 0x0db */ SDL_SCANCODE_UNKNOWN, // XF86Finance | ||
| 403 | /* 220, 0x0dc */ SDL_SCANCODE_UNKNOWN, // XF86Game | ||
| 404 | /* 221, 0x0dd */ SDL_SCANCODE_UNKNOWN, // XF86Shop | ||
| 405 | /* 222, 0x0de */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 406 | /* 223, 0x0df */ SDL_SCANCODE_CANCEL, // Cancel | ||
| 407 | /* 224, 0x0e0 */ SDL_SCANCODE_UNKNOWN, // XF86MonBrightnessDown | ||
| 408 | /* 225, 0x0e1 */ SDL_SCANCODE_UNKNOWN, // XF86MonBrightnessUp | ||
| 409 | /* 226, 0x0e2 */ SDL_SCANCODE_MEDIA_SELECT, // XF86AudioMedia | ||
| 410 | /* 227, 0x0e3 */ SDL_SCANCODE_UNKNOWN, // XF86Display | ||
| 411 | /* 228, 0x0e4 */ SDL_SCANCODE_UNKNOWN, // XF86KbdLightOnOff | ||
| 412 | /* 229, 0x0e5 */ SDL_SCANCODE_UNKNOWN, // XF86KbdBrightnessDown | ||
| 413 | /* 230, 0x0e6 */ SDL_SCANCODE_UNKNOWN, // XF86KbdBrightnessUp | ||
| 414 | /* 231, 0x0e7 */ SDL_SCANCODE_UNKNOWN, // XF86Send | ||
| 415 | /* 232, 0x0e8 */ SDL_SCANCODE_UNKNOWN, // XF86Reply | ||
| 416 | /* 233, 0x0e9 */ SDL_SCANCODE_UNKNOWN, // XF86MailForward | ||
| 417 | /* 234, 0x0ea */ SDL_SCANCODE_UNKNOWN, // XF86Save | ||
| 418 | /* 235, 0x0eb */ SDL_SCANCODE_UNKNOWN, // XF86Documents | ||
| 419 | /* 236, 0x0ec */ SDL_SCANCODE_UNKNOWN, // XF86Battery | ||
| 420 | /* 237, 0x0ed */ SDL_SCANCODE_UNKNOWN, // XF86Bluetooth | ||
| 421 | /* 238, 0x0ee */ SDL_SCANCODE_UNKNOWN, // XF86WLAN | ||
| 422 | /* 239, 0x0ef */ SDL_SCANCODE_UNKNOWN, // XF86UWB | ||
| 423 | /* 240, 0x0f0 */ SDL_SCANCODE_UNKNOWN, // NoSymbol | ||
| 424 | /* 241, 0x0f1 */ SDL_SCANCODE_UNKNOWN, // XF86Next_VMode | ||
| 425 | /* 242, 0x0f2 */ SDL_SCANCODE_UNKNOWN, // XF86Prev_VMode | ||
| 426 | /* 243, 0x0f3 */ SDL_SCANCODE_UNKNOWN, // XF86MonBrightnessCycle | ||
| 427 | /* 244, 0x0f4 */ SDL_SCANCODE_UNKNOWN, // XF86BrightnessAuto | ||
| 428 | /* 245, 0x0f5 */ SDL_SCANCODE_UNKNOWN, // XF86DisplayOff | ||
| 429 | /* 246, 0x0f6 */ SDL_SCANCODE_UNKNOWN, // XF86WWAN | ||
| 430 | /* 247, 0x0f7 */ SDL_SCANCODE_UNKNOWN, // XF86RFKill | ||
| 431 | }; | ||
| 432 | |||
| 433 | // Xvnc / Xtightvnc scancodes from xmodmap -pk | ||
| 434 | static const SDL_Scancode xvnc_scancode_table[] = { | ||
| 435 | /* 0 */ SDL_SCANCODE_LCTRL, | ||
| 436 | /* 1 */ SDL_SCANCODE_RCTRL, | ||
| 437 | /* 2 */ SDL_SCANCODE_LSHIFT, | ||
| 438 | /* 3 */ SDL_SCANCODE_RSHIFT, | ||
| 439 | /* 4 */ SDL_SCANCODE_UNKNOWN, // Meta_L | ||
| 440 | /* 5 */ SDL_SCANCODE_UNKNOWN, // Meta_R | ||
| 441 | /* 6 */ SDL_SCANCODE_LALT, | ||
| 442 | /* 7 */ SDL_SCANCODE_RALT, | ||
| 443 | /* 8 */ SDL_SCANCODE_SPACE, | ||
| 444 | /* 9 */ SDL_SCANCODE_0, | ||
| 445 | /* 10 */ SDL_SCANCODE_1, | ||
| 446 | /* 11 */ SDL_SCANCODE_2, | ||
| 447 | /* 12 */ SDL_SCANCODE_3, | ||
| 448 | /* 13 */ SDL_SCANCODE_4, | ||
| 449 | /* 14 */ SDL_SCANCODE_5, | ||
| 450 | /* 15 */ SDL_SCANCODE_6, | ||
| 451 | /* 16 */ SDL_SCANCODE_7, | ||
| 452 | /* 17 */ SDL_SCANCODE_8, | ||
| 453 | /* 18 */ SDL_SCANCODE_9, | ||
| 454 | /* 19 */ SDL_SCANCODE_MINUS, | ||
| 455 | /* 20 */ SDL_SCANCODE_EQUALS, | ||
| 456 | /* 21 */ SDL_SCANCODE_LEFTBRACKET, | ||
| 457 | /* 22 */ SDL_SCANCODE_RIGHTBRACKET, | ||
| 458 | /* 23 */ SDL_SCANCODE_SEMICOLON, | ||
| 459 | /* 24 */ SDL_SCANCODE_APOSTROPHE, | ||
| 460 | /* 25 */ SDL_SCANCODE_GRAVE, | ||
| 461 | /* 26 */ SDL_SCANCODE_COMMA, | ||
| 462 | /* 27 */ SDL_SCANCODE_PERIOD, | ||
| 463 | /* 28 */ SDL_SCANCODE_SLASH, | ||
| 464 | /* 29 */ SDL_SCANCODE_BACKSLASH, | ||
| 465 | /* 30 */ SDL_SCANCODE_A, | ||
| 466 | /* 31 */ SDL_SCANCODE_B, | ||
| 467 | /* 32 */ SDL_SCANCODE_C, | ||
| 468 | /* 33 */ SDL_SCANCODE_D, | ||
| 469 | /* 34 */ SDL_SCANCODE_E, | ||
| 470 | /* 35 */ SDL_SCANCODE_F, | ||
| 471 | /* 36 */ SDL_SCANCODE_G, | ||
| 472 | /* 37 */ SDL_SCANCODE_H, | ||
| 473 | /* 38 */ SDL_SCANCODE_I, | ||
| 474 | /* 39 */ SDL_SCANCODE_J, | ||
| 475 | /* 40 */ SDL_SCANCODE_K, | ||
| 476 | /* 41 */ SDL_SCANCODE_L, | ||
| 477 | /* 42 */ SDL_SCANCODE_M, | ||
| 478 | /* 43 */ SDL_SCANCODE_N, | ||
| 479 | /* 44 */ SDL_SCANCODE_O, | ||
| 480 | /* 45 */ SDL_SCANCODE_P, | ||
| 481 | /* 46 */ SDL_SCANCODE_Q, | ||
| 482 | /* 47 */ SDL_SCANCODE_R, | ||
| 483 | /* 48 */ SDL_SCANCODE_S, | ||
| 484 | /* 49 */ SDL_SCANCODE_T, | ||
| 485 | /* 50 */ SDL_SCANCODE_U, | ||
| 486 | /* 51 */ SDL_SCANCODE_V, | ||
| 487 | /* 52 */ SDL_SCANCODE_W, | ||
| 488 | /* 53 */ SDL_SCANCODE_X, | ||
| 489 | /* 54 */ SDL_SCANCODE_Y, | ||
| 490 | /* 55 */ SDL_SCANCODE_Z, | ||
| 491 | /* 56 */ SDL_SCANCODE_BACKSPACE, | ||
| 492 | /* 57 */ SDL_SCANCODE_RETURN, | ||
| 493 | /* 58 */ SDL_SCANCODE_TAB, | ||
| 494 | /* 59 */ SDL_SCANCODE_ESCAPE, | ||
| 495 | /* 60 */ SDL_SCANCODE_DELETE, | ||
| 496 | /* 61 */ SDL_SCANCODE_HOME, | ||
| 497 | /* 62 */ SDL_SCANCODE_END, | ||
| 498 | /* 63 */ SDL_SCANCODE_PAGEUP, | ||
| 499 | /* 64 */ SDL_SCANCODE_PAGEDOWN, | ||
| 500 | /* 65 */ SDL_SCANCODE_UP, | ||
| 501 | /* 66 */ SDL_SCANCODE_DOWN, | ||
| 502 | /* 67 */ SDL_SCANCODE_LEFT, | ||
| 503 | /* 68 */ SDL_SCANCODE_RIGHT, | ||
| 504 | /* 69 */ SDL_SCANCODE_F1, | ||
| 505 | /* 70 */ SDL_SCANCODE_F2, | ||
| 506 | /* 71 */ SDL_SCANCODE_F3, | ||
| 507 | /* 72 */ SDL_SCANCODE_F4, | ||
| 508 | /* 73 */ SDL_SCANCODE_F5, | ||
| 509 | /* 74 */ SDL_SCANCODE_F6, | ||
| 510 | /* 75 */ SDL_SCANCODE_F7, | ||
| 511 | /* 76 */ SDL_SCANCODE_F8, | ||
| 512 | /* 77 */ SDL_SCANCODE_F9, | ||
| 513 | /* 78 */ SDL_SCANCODE_F10, | ||
| 514 | /* 79 */ SDL_SCANCODE_F11, | ||
| 515 | /* 80 */ SDL_SCANCODE_F12, | ||
| 516 | }; | ||
| 517 | |||
| 518 | #endif // scancodes_xfree86_h_ | ||
| 519 | |||
| 520 | /* *INDENT-ON* */ // clang-format on | ||
