chore(build): use SDL3

This commit is contained in:
phaneron 2025-04-12 04:38:19 -04:00
parent 9d04a35d87
commit b3c0734a9e
3286 changed files with 866354 additions and 554996 deletions

View file

@ -0,0 +1,249 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
// SDL event categories
#include "SDL_events_c.h"
#include "SDL_categories_c.h"
SDL_EventCategory SDL_GetEventCategory(Uint32 type)
{
if (type >= SDL_EVENT_USER && type <= SDL_EVENT_LAST) {
return SDL_EVENTCATEGORY_USER;
}
else if (type >= SDL_EVENT_DISPLAY_FIRST && type <= SDL_EVENT_DISPLAY_LAST) {
return SDL_EVENTCATEGORY_DISPLAY;
}
else if (type >= SDL_EVENT_WINDOW_FIRST && type <= SDL_EVENT_WINDOW_LAST) {
return SDL_EVENTCATEGORY_WINDOW;
}
switch (type) {
default:
SDL_SetError("Unknown event type");
return SDL_EVENTCATEGORY_UNKNOWN;
case SDL_EVENT_KEYMAP_CHANGED:
case SDL_EVENT_TERMINATING:
case SDL_EVENT_LOW_MEMORY:
case SDL_EVENT_WILL_ENTER_BACKGROUND:
case SDL_EVENT_DID_ENTER_BACKGROUND:
case SDL_EVENT_WILL_ENTER_FOREGROUND:
case SDL_EVENT_DID_ENTER_FOREGROUND:
case SDL_EVENT_LOCALE_CHANGED:
case SDL_EVENT_SYSTEM_THEME_CHANGED:
return SDL_EVENTCATEGORY_SYSTEM;
case SDL_EVENT_RENDER_TARGETS_RESET:
case SDL_EVENT_RENDER_DEVICE_RESET:
case SDL_EVENT_RENDER_DEVICE_LOST:
return SDL_EVENTCATEGORY_RENDER;
case SDL_EVENT_QUIT:
return SDL_EVENTCATEGORY_QUIT;
case SDL_EVENT_KEY_DOWN:
case SDL_EVENT_KEY_UP:
return SDL_EVENTCATEGORY_KEY;
case SDL_EVENT_TEXT_EDITING:
return SDL_EVENTCATEGORY_EDIT;
case SDL_EVENT_TEXT_INPUT:
return SDL_EVENTCATEGORY_TEXT;
case SDL_EVENT_KEYBOARD_ADDED:
case SDL_EVENT_KEYBOARD_REMOVED:
return SDL_EVENTCATEGORY_KDEVICE;
case SDL_EVENT_TEXT_EDITING_CANDIDATES:
return SDL_EVENTCATEGORY_EDIT_CANDIDATES;
case SDL_EVENT_MOUSE_MOTION:
return SDL_EVENTCATEGORY_MOTION;
case SDL_EVENT_MOUSE_BUTTON_DOWN:
case SDL_EVENT_MOUSE_BUTTON_UP:
return SDL_EVENTCATEGORY_BUTTON;
case SDL_EVENT_MOUSE_WHEEL:
return SDL_EVENTCATEGORY_WHEEL;
case SDL_EVENT_MOUSE_ADDED:
case SDL_EVENT_MOUSE_REMOVED:
return SDL_EVENTCATEGORY_MDEVICE;
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
return SDL_EVENTCATEGORY_JAXIS;
case SDL_EVENT_JOYSTICK_BALL_MOTION:
return SDL_EVENTCATEGORY_JBALL;
case SDL_EVENT_JOYSTICK_HAT_MOTION:
return SDL_EVENTCATEGORY_JHAT;
case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
case SDL_EVENT_JOYSTICK_BUTTON_UP:
return SDL_EVENTCATEGORY_JBUTTON;
case SDL_EVENT_JOYSTICK_ADDED:
case SDL_EVENT_JOYSTICK_REMOVED:
case SDL_EVENT_JOYSTICK_UPDATE_COMPLETE:
return SDL_EVENTCATEGORY_JDEVICE;
case SDL_EVENT_JOYSTICK_BATTERY_UPDATED:
return SDL_EVENTCATEGORY_JBATTERY;
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
return SDL_EVENTCATEGORY_GAXIS;
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
case SDL_EVENT_GAMEPAD_BUTTON_UP:
return SDL_EVENTCATEGORY_GBUTTON;
case SDL_EVENT_GAMEPAD_ADDED:
case SDL_EVENT_GAMEPAD_REMOVED:
case SDL_EVENT_GAMEPAD_REMAPPED:
case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE:
case SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED:
return SDL_EVENTCATEGORY_GDEVICE;
case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN:
case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION:
case SDL_EVENT_GAMEPAD_TOUCHPAD_UP:
return SDL_EVENTCATEGORY_GTOUCHPAD;
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE:
return SDL_EVENTCATEGORY_GSENSOR;
case SDL_EVENT_FINGER_DOWN:
case SDL_EVENT_FINGER_UP:
case SDL_EVENT_FINGER_CANCELED:
case SDL_EVENT_FINGER_MOTION:
return SDL_EVENTCATEGORY_TFINGER;
case SDL_EVENT_CLIPBOARD_UPDATE:
return SDL_EVENTCATEGORY_CLIPBOARD;
case SDL_EVENT_DROP_FILE:
case SDL_EVENT_DROP_TEXT:
case SDL_EVENT_DROP_BEGIN:
case SDL_EVENT_DROP_COMPLETE:
case SDL_EVENT_DROP_POSITION:
return SDL_EVENTCATEGORY_DROP;
case SDL_EVENT_AUDIO_DEVICE_ADDED:
case SDL_EVENT_AUDIO_DEVICE_REMOVED:
case SDL_EVENT_AUDIO_DEVICE_FORMAT_CHANGED:
return SDL_EVENTCATEGORY_ADEVICE;
case SDL_EVENT_SENSOR_UPDATE:
return SDL_EVENTCATEGORY_SENSOR;
case SDL_EVENT_PEN_PROXIMITY_IN:
case SDL_EVENT_PEN_PROXIMITY_OUT:
return SDL_EVENTCATEGORY_PPROXIMITY;
case SDL_EVENT_PEN_DOWN:
case SDL_EVENT_PEN_UP:
return SDL_EVENTCATEGORY_PTOUCH;
case SDL_EVENT_PEN_BUTTON_DOWN:
case SDL_EVENT_PEN_BUTTON_UP:
return SDL_EVENTCATEGORY_PBUTTON;
case SDL_EVENT_PEN_MOTION:
return SDL_EVENTCATEGORY_PMOTION;
case SDL_EVENT_PEN_AXIS:
return SDL_EVENTCATEGORY_PAXIS;
case SDL_EVENT_CAMERA_DEVICE_ADDED:
case SDL_EVENT_CAMERA_DEVICE_REMOVED:
case SDL_EVENT_CAMERA_DEVICE_APPROVED:
case SDL_EVENT_CAMERA_DEVICE_DENIED:
return SDL_EVENTCATEGORY_CDEVICE;
}
}
SDL_Window *SDL_GetWindowFromEvent(const SDL_Event *event)
{
SDL_WindowID windowID;
switch (SDL_GetEventCategory(event->type)) {
case SDL_EVENTCATEGORY_USER:
windowID = event->user.windowID;
break;
case SDL_EVENTCATEGORY_WINDOW:
windowID = event->window.windowID;
break;
case SDL_EVENTCATEGORY_KEY:
windowID = event->key.windowID;
break;
case SDL_EVENTCATEGORY_EDIT:
windowID = event->edit.windowID;
break;
case SDL_EVENTCATEGORY_TEXT:
windowID = event->text.windowID;
break;
case SDL_EVENTCATEGORY_EDIT_CANDIDATES:
windowID = event->edit_candidates.windowID;
break;
case SDL_EVENTCATEGORY_MOTION:
windowID = event->motion.windowID;
break;
case SDL_EVENTCATEGORY_BUTTON:
windowID = event->button.windowID;
break;
case SDL_EVENTCATEGORY_WHEEL:
windowID = event->wheel.windowID;
break;
case SDL_EVENTCATEGORY_TFINGER:
windowID = event->tfinger.windowID;
break;
case SDL_EVENTCATEGORY_PPROXIMITY:
windowID = event->pproximity.windowID;
break;
case SDL_EVENTCATEGORY_PTOUCH:
windowID = event->ptouch.windowID;
break;
case SDL_EVENTCATEGORY_PBUTTON:
windowID = event->pbutton.windowID;
break;
case SDL_EVENTCATEGORY_PMOTION:
windowID = event->pmotion.windowID;
break;
case SDL_EVENTCATEGORY_PAXIS:
windowID = event->paxis.windowID;
break;
case SDL_EVENTCATEGORY_DROP:
windowID = event->drop.windowID;
break;
case SDL_EVENTCATEGORY_RENDER:
windowID = event->render.windowID;
break;
default:
// < 0 -> invalid event type (error is set by SDL_GetEventCategory)
// else -> event has no associated window (not an error)
return NULL;
}
return SDL_GetWindowFromID(windowID);
}

View file

@ -0,0 +1,70 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_categories_c_h_
#define SDL_categories_c_h_
typedef enum SDL_EventCategory
{
SDL_EVENTCATEGORY_UNKNOWN,
SDL_EVENTCATEGORY_SYSTEM,
SDL_EVENTCATEGORY_DISPLAY,
SDL_EVENTCATEGORY_WINDOW,
SDL_EVENTCATEGORY_KDEVICE,
SDL_EVENTCATEGORY_KEY,
SDL_EVENTCATEGORY_EDIT,
SDL_EVENTCATEGORY_EDIT_CANDIDATES,
SDL_EVENTCATEGORY_TEXT,
SDL_EVENTCATEGORY_MDEVICE,
SDL_EVENTCATEGORY_MOTION,
SDL_EVENTCATEGORY_BUTTON,
SDL_EVENTCATEGORY_WHEEL,
SDL_EVENTCATEGORY_JDEVICE,
SDL_EVENTCATEGORY_JAXIS,
SDL_EVENTCATEGORY_JBALL,
SDL_EVENTCATEGORY_JHAT,
SDL_EVENTCATEGORY_JBUTTON,
SDL_EVENTCATEGORY_JBATTERY,
SDL_EVENTCATEGORY_GDEVICE,
SDL_EVENTCATEGORY_GAXIS,
SDL_EVENTCATEGORY_GBUTTON,
SDL_EVENTCATEGORY_GTOUCHPAD,
SDL_EVENTCATEGORY_GSENSOR,
SDL_EVENTCATEGORY_ADEVICE,
SDL_EVENTCATEGORY_CDEVICE,
SDL_EVENTCATEGORY_SENSOR,
SDL_EVENTCATEGORY_QUIT,
SDL_EVENTCATEGORY_USER,
SDL_EVENTCATEGORY_TFINGER,
SDL_EVENTCATEGORY_PPROXIMITY,
SDL_EVENTCATEGORY_PTOUCH,
SDL_EVENTCATEGORY_PMOTION,
SDL_EVENTCATEGORY_PBUTTON,
SDL_EVENTCATEGORY_PAXIS,
SDL_EVENTCATEGORY_DROP,
SDL_EVENTCATEGORY_CLIPBOARD,
SDL_EVENTCATEGORY_RENDER,
} SDL_EventCategory;
extern SDL_EventCategory SDL_GetEventCategory(Uint32 type);
#endif // SDL_categories_c_h_

View file

@ -0,0 +1,57 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
// Clipboard event handling code for SDL
#include "SDL_events_c.h"
#include "SDL_clipboardevents_c.h"
#include "../video/SDL_clipboard_c.h"
void SDL_SendClipboardUpdate(bool owner, char **mime_types, size_t num_mime_types)
{
if (!owner) {
/* Clear our internal clipboard contents when external clipboard is set.
*
* Wayland recursively sends a data offer to the client from which the clipboard data originated,
* and as the client can't determine the origin of the offer, the clipboard must not be cleared,
* or the original data may be destroyed. Cleanup will be done in the backend when an offer
* cancellation event arrives.
*/
if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") != 0) {
SDL_CancelClipboardData(0);
}
SDL_SaveClipboardMimeTypes((const char **)mime_types, num_mime_types);
}
if (SDL_EventEnabled(SDL_EVENT_CLIPBOARD_UPDATE)) {
SDL_Event event;
event.type = SDL_EVENT_CLIPBOARD_UPDATE;
SDL_ClipboardEvent *cevent = &event.clipboard;
cevent->timestamp = 0;
cevent->owner = owner;
cevent->mime_types = (const char **)mime_types;
cevent->num_mime_types = (Uint32)num_mime_types;
SDL_PushEvent(&event);
}
}

View file

@ -0,0 +1,28 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_clipboardevents_c_h_
#define SDL_clipboardevents_c_h_
extern void SDL_SendClipboardUpdate(bool owner, char **mime_types, size_t num_mime_types);
#endif // SDL_clipboardevents_c_h_

View file

@ -0,0 +1,64 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
// Display event handling code for SDL
#include "SDL_events_c.h"
void SDL_SendDisplayEvent(SDL_VideoDisplay *display, SDL_EventType displayevent, int data1, int data2)
{
if (!display || display->id == 0) {
return;
}
switch (displayevent) {
case SDL_EVENT_DISPLAY_ORIENTATION:
if (data1 == SDL_ORIENTATION_UNKNOWN || data1 == display->current_orientation) {
return;
}
display->current_orientation = (SDL_DisplayOrientation)data1;
break;
default:
break;
}
// Post the event, if desired
if (SDL_EventEnabled(displayevent)) {
SDL_Event event;
event.type = displayevent;
event.common.timestamp = 0;
event.display.displayID = display->id;
event.display.data1 = data1;
event.display.data2 = data2;
SDL_PushEvent(&event);
}
switch (displayevent) {
case SDL_EVENT_DISPLAY_ADDED:
SDL_OnDisplayAdded(display);
break;
case SDL_EVENT_DISPLAY_MOVED:
SDL_OnDisplayMoved(display);
break;
default:
break;
}
}

View file

@ -0,0 +1,28 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_displayevents_c_h_
#define SDL_displayevents_c_h_
extern void SDL_SendDisplayEvent(SDL_VideoDisplay *display, SDL_EventType displayevent, int data1, int data2);
#endif // SDL_displayevents_c_h_

View file

@ -0,0 +1,115 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
// Drag and drop event handling code for SDL
#include "SDL_events_c.h"
#include "SDL_dropevents_c.h"
#include "../video/SDL_sysvideo.h" // for SDL_Window internals.
static bool SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *source, const char *data, float x, float y)
{
static bool app_is_dropping = false;
static float last_drop_x = 0;
static float last_drop_y = 0;
bool posted = false;
// Post the event, if desired
if (SDL_EventEnabled(evtype)) {
const bool need_begin = window ? !window->is_dropping : !app_is_dropping;
SDL_Event event;
if (need_begin) {
SDL_zero(event);
event.type = SDL_EVENT_DROP_BEGIN;
event.common.timestamp = 0;
event.drop.windowID = window ? window->id : 0;
posted = SDL_PushEvent(&event);
if (!posted) {
return false;
}
if (window) {
window->is_dropping = true;
} else {
app_is_dropping = true;
}
}
SDL_zero(event);
event.type = evtype;
event.common.timestamp = 0;
if (source) {
event.drop.source = SDL_CreateTemporaryString(source);
if (!event.drop.source) {
return false;
}
}
if (data) {
event.drop.data = SDL_CreateTemporaryString(data);
if (!event.drop.data) {
return false;
}
}
event.drop.windowID = window ? window->id : 0;
if (evtype == SDL_EVENT_DROP_POSITION) {
last_drop_x = x;
last_drop_y = y;
}
event.drop.x = last_drop_x;
event.drop.y = last_drop_y;
posted = SDL_PushEvent(&event);
if (posted && (evtype == SDL_EVENT_DROP_COMPLETE)) {
if (window) {
window->is_dropping = false;
} else {
app_is_dropping = false;
}
last_drop_x = 0;
last_drop_y = 0;
}
}
return posted;
}
bool SDL_SendDropFile(SDL_Window *window, const char *source, const char *file)
{
return SDL_SendDrop(window, SDL_EVENT_DROP_FILE, source, file, 0, 0);
}
bool SDL_SendDropPosition(SDL_Window *window, float x, float y)
{
return SDL_SendDrop(window, SDL_EVENT_DROP_POSITION, NULL, NULL, x, y);
}
bool SDL_SendDropText(SDL_Window *window, const char *text)
{
return SDL_SendDrop(window, SDL_EVENT_DROP_TEXT, NULL, text, 0, 0);
}
bool SDL_SendDropComplete(SDL_Window *window)
{
return SDL_SendDrop(window, SDL_EVENT_DROP_COMPLETE, NULL, NULL, 0, 0);
}

View file

@ -0,0 +1,31 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_dropevents_c_h_
#define SDL_dropevents_c_h_
extern bool SDL_SendDropFile(SDL_Window *window, const char *source, const char *file);
extern bool SDL_SendDropPosition(SDL_Window *window, float x, float y);
extern bool SDL_SendDropText(SDL_Window *window, const char *text);
extern bool SDL_SendDropComplete(SDL_Window *window);
#endif // SDL_dropevents_c_h_

1987
vendor/sdl-3.2.10/src/events/SDL_events.c vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,66 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_events_c_h_
#define SDL_events_c_h_
#include "SDL_internal.h"
// Useful functions and variables from SDL_events.c
#include "../video/SDL_sysvideo.h"
#include "SDL_clipboardevents_c.h"
#include "SDL_displayevents_c.h"
#include "SDL_dropevents_c.h"
#include "SDL_keyboard_c.h"
#include "SDL_mouse_c.h"
#include "SDL_touch_c.h"
#include "SDL_pen_c.h"
#include "SDL_windowevents_c.h"
// Start and stop the event processing loop
extern bool SDL_StartEventLoop(void);
extern void SDL_StopEventLoop(void);
extern void SDL_QuitInterrupt(void);
extern void SDL_SendAppEvent(SDL_EventType eventType);
extern void SDL_SendKeymapChangedEvent(void);
extern void SDL_SendLocaleChangedEvent(void);
extern void SDL_SendSystemThemeChangedEvent(void);
extern void *SDL_AllocateTemporaryMemory(size_t size);
extern const char *SDL_CreateTemporaryString(const char *string);
extern void *SDL_ClaimTemporaryMemory(const void *mem);
extern void SDL_FreeTemporaryMemory(void);
extern void SDL_PumpEventMaintenance(void);
extern void SDL_SendQuit(void);
extern bool SDL_InitEvents(void);
extern void SDL_QuitEvents(void);
extern void SDL_SendPendingSignalEvents(void);
extern bool SDL_InitQuit(void);
extern void SDL_QuitQuit(void);
#endif // SDL_events_c_h_

View file

@ -0,0 +1,143 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#include "SDL_eventwatch_c.h"
bool SDL_InitEventWatchList(SDL_EventWatchList *list)
{
if (list->lock == NULL) {
list->lock = SDL_CreateMutex();
if (list->lock == NULL) {
return false;
}
}
return true;
}
void SDL_QuitEventWatchList(SDL_EventWatchList *list)
{
if (list->lock) {
SDL_DestroyMutex(list->lock);
list->lock = NULL;
}
if (list->watchers) {
SDL_free(list->watchers);
list->watchers = NULL;
list->count = 0;
}
SDL_zero(list->filter);
}
bool SDL_DispatchEventWatchList(SDL_EventWatchList *list, SDL_Event *event)
{
SDL_EventWatcher *filter = &list->filter;
if (!filter->callback && list->count == 0) {
return true;
}
SDL_LockMutex(list->lock);
{
// Make sure we only dispatch the current watcher list
int i, count = list->count;
if (filter->callback && !filter->callback(filter->userdata, event)) {
SDL_UnlockMutex(list->lock);
return false;
}
list->dispatching = true;
for (i = 0; i < count; ++i) {
if (!list->watchers[i].removed) {
list->watchers[i].callback(list->watchers[i].userdata, event);
}
}
list->dispatching = false;
if (list->removed) {
for (i = list->count; i--;) {
if (list->watchers[i].removed) {
--list->count;
if (i < list->count) {
SDL_memmove(&list->watchers[i], &list->watchers[i + 1], (list->count - i) * sizeof(list->watchers[i]));
}
}
}
list->removed = false;
}
}
SDL_UnlockMutex(list->lock);
return true;
}
bool SDL_AddEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, void *userdata)
{
bool result = true;
SDL_LockMutex(list->lock);
{
SDL_EventWatcher *watchers;
watchers = (SDL_EventWatcher *)SDL_realloc(list->watchers, (list->count + 1) * sizeof(*watchers));
if (watchers) {
SDL_EventWatcher *watcher;
list->watchers = watchers;
watcher = &list->watchers[list->count];
watcher->callback = filter;
watcher->userdata = userdata;
watcher->removed = false;
++list->count;
} else {
result = false;
}
}
SDL_UnlockMutex(list->lock);
return result;
}
void SDL_RemoveEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, void *userdata)
{
SDL_LockMutex(list->lock);
{
int i;
for (i = 0; i < list->count; ++i) {
if (list->watchers[i].callback == filter && list->watchers[i].userdata == userdata) {
if (list->dispatching) {
list->watchers[i].removed = true;
list->removed = true;
} else {
--list->count;
if (i < list->count) {
SDL_memmove(&list->watchers[i], &list->watchers[i + 1], (list->count - i) * sizeof(list->watchers[i]));
}
}
break;
}
}
}
SDL_UnlockMutex(list->lock);
}

View file

@ -0,0 +1,45 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
typedef struct SDL_EventWatcher
{
SDL_EventFilter callback;
void *userdata;
bool removed;
} SDL_EventWatcher;
typedef struct SDL_EventWatchList
{
SDL_Mutex *lock;
SDL_EventWatcher filter;
SDL_EventWatcher *watchers;
int count;
bool dispatching;
bool removed;
} SDL_EventWatchList;
extern bool SDL_InitEventWatchList(SDL_EventWatchList *list);
extern void SDL_QuitEventWatchList(SDL_EventWatchList *list);
extern bool SDL_DispatchEventWatchList(SDL_EventWatchList *list, SDL_Event *event);
extern bool SDL_AddEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, void *userdata);
extern void SDL_RemoveEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, void *userdata);

View file

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

View file

@ -0,0 +1,87 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_keyboard_c_h_
#define SDL_keyboard_c_h_
#include "SDL_keymap_c.h"
// Keyboard events not associated with a specific input device
#define SDL_GLOBAL_KEYBOARD_ID 0
// The default keyboard input device, for platforms that don't have multiple keyboards
#define SDL_DEFAULT_KEYBOARD_ID 1
// Initialize the keyboard subsystem
extern bool SDL_InitKeyboard(void);
// Return whether a device is actually a keyboard
extern bool SDL_IsKeyboard(Uint16 vendor, Uint16 product, int num_keys);
// A keyboard has been added to the system
extern void SDL_AddKeyboard(SDL_KeyboardID keyboardID, const char *name, bool send_event);
// A keyboard has been removed from the system
extern void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID, bool send_event);
// Set the mapping of scancode to key codes
extern void SDL_SetKeymap(SDL_Keymap *keymap, bool send_event);
// Set the keyboard focus window
extern bool SDL_SetKeyboardFocus(SDL_Window *window);
/* Send a character from an on-screen keyboard as scancode and modifier key events,
currently assuming ASCII characters on a US keyboard layout
*/
extern void SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch);
// Send a keyboard key event
extern bool SDL_SendKeyboardKey(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, bool down);
extern bool SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, bool down);
extern bool SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode);
/* This is for platforms that don't know the keymap but can report scancode and keycode directly.
Most platforms should prefer to optionally call SDL_SetKeymap and then use SDL_SendKeyboardKey. */
extern bool SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, SDL_KeyboardID keyboardID, int rawcode, SDL_Scancode scancode, SDL_Keycode keycode, bool down);
// Release all the autorelease keys
extern void SDL_ReleaseAutoReleaseKeys(void);
// Return true if any hardware key is pressed
extern bool SDL_HardwareKeyboardKeyPressed(void);
// Send keyboard text input
extern void SDL_SendKeyboardText(const char *text);
// Send editing text for selected range from start to end
extern void SDL_SendEditingText(const char *text, int start, int length);
// Send editing text candidates, which will be copied into the event
extern void SDL_SendEditingTextCandidates(char **candidates, int num_candidates, int selected_candidate, bool horizontal);
// Shutdown the keyboard subsystem
extern void SDL_QuitKeyboard(void);
// Toggle on or off pieces of the keyboard mod state.
extern void SDL_ToggleModState(SDL_Keymod modstate, bool toggle);
#endif // SDL_keyboard_c_h_

1153
vendor/sdl-3.2.10/src/events/SDL_keymap.c vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,35 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_keymap_c_h_
#define SDL_keymap_c_h_
typedef struct SDL_Keymap SDL_Keymap;
SDL_Keymap *SDL_GetCurrentKeymap(void);
SDL_Keymap *SDL_CreateKeymap(void);
void SDL_SetKeymapEntry(SDL_Keymap *keymap, SDL_Scancode scancode, SDL_Keymod modstate, SDL_Keycode keycode);
SDL_Keycode SDL_GetKeymapKeycode(SDL_Keymap *keymap, SDL_Scancode scancode, SDL_Keymod modstate);
SDL_Scancode SDL_GetKeymapScancode(SDL_Keymap *keymap, SDL_Keycode keycode, SDL_Keymod *modstate);
void SDL_DestroyKeymap(SDL_Keymap *keymap);
#endif // SDL_keymap_c_h_

View file

@ -0,0 +1,68 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_X11)
#include "SDL_keyboard_c.h"
#include "SDL_keysym_to_scancode_c.h"
#include "imKStoUCS.h"
// Extended key code mappings
static const struct
{
Uint32 keysym;
SDL_Keycode keycode;
} keysym_to_keycode_table[] = {
{ 0xfe03, SDLK_MODE }, // XK_ISO_Level3_Shift
{ 0xfe11, SDLK_LEVEL5_SHIFT }, // XK_ISO_Level5_Shift
{ 0xfe20, SDLK_LEFT_TAB }, // XK_ISO_Left_Tab
{ 0xff20, SDLK_MULTI_KEY_COMPOSE }, // XK_Multi_key
{ 0xffe7, SDLK_LMETA }, // XK_Meta_L
{ 0xffe8, SDLK_RMETA }, // XK_Meta_R
{ 0xffed, SDLK_LHYPER }, // XK_Hyper_L
{ 0xffee, SDLK_RHYPER }, // XK_Hyper_R
};
SDL_Keycode SDL_GetKeyCodeFromKeySym(Uint32 keysym, Uint32 keycode, SDL_Keymod modifiers)
{
SDL_Keycode sdl_keycode = SDL_KeySymToUcs4(keysym);
if (!sdl_keycode) {
for (int i = 0; i < SDL_arraysize(keysym_to_keycode_table); ++i) {
if (keysym == keysym_to_keycode_table[i].keysym) {
return keysym_to_keycode_table[i].keycode;
}
}
}
if (!sdl_keycode) {
const SDL_Scancode scancode = SDL_GetScancodeFromKeySym(keysym, keycode);
if (scancode != SDL_SCANCODE_UNKNOWN) {
sdl_keycode = SDL_GetKeymapKeycode(NULL, scancode, modifiers);
}
}
return sdl_keycode;
}
#endif // SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_X11

View file

@ -0,0 +1,28 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_keysym_to_keycode_c_h_
#define SDL_keysym_to_keycode_c_h_
// Convert a keysym to an SDL key code
extern SDL_Keycode SDL_GetKeyCodeFromKeySym(Uint32 keysym, Uint32 keycode, SDL_Keymod modifiers);
#endif // SDL_keysym_to_scancode_c_h_

View file

@ -0,0 +1,439 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_X11)
#include "SDL_keyboard_c.h"
#include "SDL_scancode_tables_c.h"
#include "SDL_keysym_to_scancode_c.h"
/* *INDENT-OFF* */ // clang-format off
static const struct {
Uint32 keysym;
SDL_Scancode scancode;
} KeySymToSDLScancode[] = {
{ 0xFF9C, SDL_SCANCODE_KP_1 }, // XK_KP_End
{ 0xFF99, SDL_SCANCODE_KP_2 }, // XK_KP_Down
{ 0xFF9B, SDL_SCANCODE_KP_3 }, // XK_KP_Next
{ 0xFF96, SDL_SCANCODE_KP_4 }, // XK_KP_Left
{ 0xFF9D, SDL_SCANCODE_KP_5 }, // XK_KP_Begin
{ 0xFF98, SDL_SCANCODE_KP_6 }, // XK_KP_Right
{ 0xFF95, SDL_SCANCODE_KP_7 }, // XK_KP_Home
{ 0xFF97, SDL_SCANCODE_KP_8 }, // XK_KP_Up
{ 0xFF9A, SDL_SCANCODE_KP_9 }, // XK_KP_Prior
{ 0xFF9E, SDL_SCANCODE_KP_0 }, // XK_KP_Insert
{ 0xFF9F, SDL_SCANCODE_KP_PERIOD }, // XK_KP_Delete
{ 0xFF62, SDL_SCANCODE_EXECUTE }, // XK_Execute
{ 0xFFEE, SDL_SCANCODE_APPLICATION }, // XK_Hyper_R
{ 0xFE03, SDL_SCANCODE_RALT }, // XK_ISO_Level3_Shift
{ 0xFE20, SDL_SCANCODE_TAB }, // XK_ISO_Left_Tab
{ 0xFFEB, SDL_SCANCODE_LGUI }, // XK_Super_L
{ 0xFFEC, SDL_SCANCODE_RGUI }, // XK_Super_R
{ 0xFF7E, SDL_SCANCODE_MODE }, // XK_Mode_switch
{ 0x1008FF65, SDL_SCANCODE_MENU }, // XF86MenuKB
{ 0x1008FF81, SDL_SCANCODE_F13 }, // XF86Tools
{ 0x1008FF45, SDL_SCANCODE_F14 }, // XF86Launch5
{ 0x1008FF46, SDL_SCANCODE_F15 }, // XF86Launch6
{ 0x1008FF47, SDL_SCANCODE_F16 }, // XF86Launch7
{ 0x1008FF48, SDL_SCANCODE_F17 }, // XF86Launch8
{ 0x1008FF49, SDL_SCANCODE_F18 }, // XF86Launch9
};
// This is a mapping from X keysym to Linux keycode
static const Uint32 LinuxKeycodeKeysyms[] = {
/* 0, 0x000 */ 0x0, // NoSymbol
/* 1, 0x001 */ 0xFF1B, // Escape
/* 2, 0x002 */ 0x31, // 1
/* 3, 0x003 */ 0x32, // 2
/* 4, 0x004 */ 0x33, // 3
/* 5, 0x005 */ 0x34, // 4
/* 6, 0x006 */ 0x35, // 5
/* 7, 0x007 */ 0x36, // 6
/* 8, 0x008 */ 0x37, // 7
/* 9, 0x009 */ 0x38, // 8
/* 10, 0x00a */ 0x39, // 9
/* 11, 0x00b */ 0x30, // 0
/* 12, 0x00c */ 0x2D, // minus
/* 13, 0x00d */ 0x3D, // equal
/* 14, 0x00e */ 0xFF08, // BackSpace
/* 15, 0x00f */ 0xFF09, // Tab
/* 16, 0x010 */ 0x71, // q
/* 17, 0x011 */ 0x77, // w
/* 18, 0x012 */ 0x65, // e
/* 19, 0x013 */ 0x72, // r
/* 20, 0x014 */ 0x74, // t
/* 21, 0x015 */ 0x79, // y
/* 22, 0x016 */ 0x75, // u
/* 23, 0x017 */ 0x69, // i
/* 24, 0x018 */ 0x6F, // o
/* 25, 0x019 */ 0x70, // p
/* 26, 0x01a */ 0x5B, // bracketleft
/* 27, 0x01b */ 0x5D, // bracketright
/* 28, 0x01c */ 0xFF0D, // Return
/* 29, 0x01d */ 0xFFE3, // Control_L
/* 30, 0x01e */ 0x61, // a
/* 31, 0x01f */ 0x73, // s
/* 32, 0x020 */ 0x64, // d
/* 33, 0x021 */ 0x66, // f
/* 34, 0x022 */ 0x67, // g
/* 35, 0x023 */ 0x68, // h
/* 36, 0x024 */ 0x6A, // j
/* 37, 0x025 */ 0x6B, // k
/* 38, 0x026 */ 0x6C, // l
/* 39, 0x027 */ 0x3B, // semicolon
/* 40, 0x028 */ 0x27, // apostrophe
/* 41, 0x029 */ 0x60, // grave
/* 42, 0x02a */ 0xFFE1, // Shift_L
/* 43, 0x02b */ 0x5C, // backslash
/* 44, 0x02c */ 0x7A, // z
/* 45, 0x02d */ 0x78, // x
/* 46, 0x02e */ 0x63, // c
/* 47, 0x02f */ 0x76, // v
/* 48, 0x030 */ 0x62, // b
/* 49, 0x031 */ 0x6E, // n
/* 50, 0x032 */ 0x6D, // m
/* 51, 0x033 */ 0x2C, // comma
/* 52, 0x034 */ 0x2E, // period
/* 53, 0x035 */ 0x2F, // slash
/* 54, 0x036 */ 0xFFE2, // Shift_R
/* 55, 0x037 */ 0xFFAA, // KP_Multiply
/* 56, 0x038 */ 0xFFE9, // Alt_L
/* 57, 0x039 */ 0x20, // space
/* 58, 0x03a */ 0xFFE5, // Caps_Lock
/* 59, 0x03b */ 0xFFBE, // F1
/* 60, 0x03c */ 0xFFBF, // F2
/* 61, 0x03d */ 0xFFC0, // F3
/* 62, 0x03e */ 0xFFC1, // F4
/* 63, 0x03f */ 0xFFC2, // F5
/* 64, 0x040 */ 0xFFC3, // F6
/* 65, 0x041 */ 0xFFC4, // F7
/* 66, 0x042 */ 0xFFC5, // F8
/* 67, 0x043 */ 0xFFC6, // F9
/* 68, 0x044 */ 0xFFC7, // F10
/* 69, 0x045 */ 0xFF7F, // Num_Lock
/* 70, 0x046 */ 0xFF14, // Scroll_Lock
/* 71, 0x047 */ 0xFFB7, // KP_7
/* 72, 0x048 */ 0XFFB8, // KP_8
/* 73, 0x049 */ 0XFFB9, // KP_9
/* 74, 0x04a */ 0xFFAD, // KP_Subtract
/* 75, 0x04b */ 0xFFB4, // KP_4
/* 76, 0x04c */ 0xFFB5, // KP_5
/* 77, 0x04d */ 0xFFB6, // KP_6
/* 78, 0x04e */ 0xFFAB, // KP_Add
/* 79, 0x04f */ 0xFFB1, // KP_1
/* 80, 0x050 */ 0xFFB2, // KP_2
/* 81, 0x051 */ 0xFFB3, // KP_3
/* 82, 0x052 */ 0xFFB0, // KP_0
/* 83, 0x053 */ 0xFFAE, // KP_Decimal
/* 84, 0x054 */ 0x0, // NoSymbol
/* 85, 0x055 */ 0x0, // NoSymbol
/* 86, 0x056 */ 0x3C, // less
/* 87, 0x057 */ 0xFFC8, // F11
/* 88, 0x058 */ 0xFFC9, // F12
/* 89, 0x059 */ 0x0, // NoSymbol
/* 90, 0x05a */ 0xFF26, // Katakana
/* 91, 0x05b */ 0xFF25, // Hiragana
/* 92, 0x05c */ 0xFF23, // Henkan_Mode
/* 93, 0x05d */ 0xFF27, // Hiragana_Katakana
/* 94, 0x05e */ 0xFF22, // Muhenkan
/* 95, 0x05f */ 0x0, // NoSymbol
/* 96, 0x060 */ 0xFF8D, // KP_Enter
/* 97, 0x061 */ 0xFFE4, // Control_R
/* 98, 0x062 */ 0xFFAF, // KP_Divide
/* 99, 0x063 */ 0xFF15, // Sys_Req
/* 100, 0x064 */ 0xFFEA, // Alt_R
/* 101, 0x065 */ 0xFF0A, // Linefeed
/* 102, 0x066 */ 0xFF50, // Home
/* 103, 0x067 */ 0xFF52, // Up
/* 104, 0x068 */ 0xFF55, // Prior
/* 105, 0x069 */ 0xFF51, // Left
/* 106, 0x06a */ 0xFF53, // Right
/* 107, 0x06b */ 0xFF57, // End
/* 108, 0x06c */ 0xFF54, // Down
/* 109, 0x06d */ 0xFF56, // Next
/* 110, 0x06e */ 0xFF63, // Insert
/* 111, 0x06f */ 0xFFFF, // Delete
/* 112, 0x070 */ 0x0, // NoSymbol
/* 113, 0x071 */ 0x1008FF12, // XF86AudioMute
/* 114, 0x072 */ 0x1008FF11, // XF86AudioLowerVolume
/* 115, 0x073 */ 0x1008FF13, // XF86AudioRaiseVolume
/* 116, 0x074 */ 0x1008FF2A, // XF86PowerOff
/* 117, 0x075 */ 0xFFBD, // KP_Equal
/* 118, 0x076 */ 0xB1, // plusminus
/* 119, 0x077 */ 0xFF13, // Pause
/* 120, 0x078 */ 0x1008FF4A, // XF86LaunchA
/* 121, 0x079 */ 0xFFAC, // KP_Separator
/* 122, 0x07a */ 0xFF31, // Hangul
/* 123, 0x07b */ 0xFF34, // Hangul_Hanja
/* 124, 0x07c */ 0x0, // NoSymbol
/* 125, 0x07d */ 0xFFE7, // Meta_L
/* 126, 0x07e */ 0xFFE8, // Meta_R
/* 127, 0x07f */ 0xFF67, // Menu
/* 128, 0x080 */ 0x00, // NoSymbol
/* 129, 0x081 */ 0xFF66, // Redo
/* 130, 0x082 */ 0x1005FF70, // SunProps
/* 131, 0x083 */ 0xFF65, // Undo
/* 132, 0x084 */ 0x1005FF71, // SunFront
/* 133, 0x085 */ 0x1008FF57, // XF86Copy
/* 134, 0x086 */ 0x1008FF6B, // XF86Open
/* 135, 0x087 */ 0x1008FF6D, // XF86Paste
/* 136, 0x088 */ 0xFF68, // Find
/* 137, 0x089 */ 0x1008FF58, // XF86Cut
/* 138, 0x08a */ 0xFF6A, // Help
/* 139, 0x08b */ 0xFF67, // Menu
/* 140, 0x08c */ 0x1008FF1D, // XF86Calculator
/* 141, 0x08d */ 0x0, // NoSymbol
/* 142, 0x08e */ 0x1008FF2F, // XF86Sleep
/* 143, 0x08f */ 0x1008FF2B, // XF86WakeUp
/* 144, 0x090 */ 0x1008FF5D, // XF86Explorer
/* 145, 0x091 */ 0x1008FF7B, // XF86Send
/* 146, 0x092 */ 0x0, // NoSymbol
/* 147, 0x093 */ 0x1008FF8A, // XF86Xfer
/* 148, 0x094 */ 0x1008FF41, // XF86Launch1
/* 149, 0x095 */ 0x1008FF42, // XF86Launch2
/* 150, 0x096 */ 0x1008FF2E, // XF86WWW
/* 151, 0x097 */ 0x1008FF5A, // XF86DOS
/* 152, 0x098 */ 0x1008FF2D, // XF86ScreenSaver
/* 153, 0x099 */ 0x1008FF74, // XF86RotateWindows
/* 154, 0x09a */ 0x1008FF7F, // XF86TaskPane
/* 155, 0x09b */ 0x1008FF19, // XF86Mail
/* 156, 0x09c */ 0x1008FF30, // XF86Favorites
/* 157, 0x09d */ 0x1008FF33, // XF86MyComputer
/* 158, 0x09e */ 0x1008FF26, // XF86Back
/* 159, 0x09f */ 0x1008FF27, // XF86Forward
/* 160, 0x0a0 */ 0x0, // NoSymbol
/* 161, 0x0a1 */ 0x1008FF2C, // XF86Eject
/* 162, 0x0a2 */ 0x1008FF2C, // XF86Eject
/* 163, 0x0a3 */ 0x1008FF17, // XF86AudioNext
/* 164, 0x0a4 */ 0x1008FF14, // XF86AudioPlay
/* 165, 0x0a5 */ 0x1008FF16, // XF86AudioPrev
/* 166, 0x0a6 */ 0x1008FF15, // XF86AudioStop
/* 167, 0x0a7 */ 0x1008FF1C, // XF86AudioRecord
/* 168, 0x0a8 */ 0x1008FF3E, // XF86AudioRewind
/* 169, 0x0a9 */ 0x1008FF6E, // XF86Phone
/* 170, 0x0aa */ 0x0, // NoSymbol
/* 171, 0x0ab */ 0x1008FF81, // XF86Tools
/* 172, 0x0ac */ 0x1008FF18, // XF86HomePage
/* 173, 0x0ad */ 0x1008FF73, // XF86Reload
/* 174, 0x0ae */ 0x1008FF56, // XF86Close
/* 175, 0x0af */ 0x0, // NoSymbol
/* 176, 0x0b0 */ 0x0, // NoSymbol
/* 177, 0x0b1 */ 0x1008FF78, // XF86ScrollUp
/* 178, 0x0b2 */ 0x1008FF79, // XF86ScrollDown
/* 179, 0x0b3 */ 0x0, // NoSymbol
/* 180, 0x0b4 */ 0x0, // NoSymbol
/* 181, 0x0b5 */ 0x1008FF68, // XF86New
/* 182, 0x0b6 */ 0xFF66, // Redo
/* 183, 0x0b7 */ 0xFFCA, // F13
/* 184, 0x0b8 */ 0xFFCB, // F14
/* 185, 0x0b9 */ 0xFFCC, // F15
/* 186, 0x0ba */ 0xFFCD, // F16
/* 187, 0x0bb */ 0xFFCE, // F17
/* 188, 0x0bc */ 0xFFCF, // F18
/* 189, 0x0bd */ 0xFFD0, // F19
/* 190, 0x0be */ 0xFFD1, // F20
/* 191, 0x0bf */ 0xFFD2, // F21
/* 192, 0x0c0 */ 0xFFD3, // F22
/* 193, 0x0c1 */ 0xFFD4, // F23
/* 194, 0x0c2 */ 0xFFD5, // F24
/* 195, 0x0c3 */ 0x0, // NoSymbol
/* 196, 0x0c4 */ 0x0, // NoSymbol
/* 197, 0x0c5 */ 0x0, // NoSymbol
/* 198, 0x0c6 */ 0x0, // NoSymbol
/* 199, 0x0c7 */ 0x0, // NoSymbol
/* 200, 0x0c8 */ 0x1008FF14, // XF86AudioPlay
/* 201, 0x0c9 */ 0x1008FF31, // XF86AudioPause
/* 202, 0x0ca */ 0x1008FF43, // XF86Launch3
/* 203, 0x0cb */ 0x1008FF44, // XF86Launch4
/* 204, 0x0cc */ 0x1008FF4B, // XF86LaunchB
/* 205, 0x0cd */ 0x1008FFA7, // XF86Suspend
/* 206, 0x0ce */ 0x1008FF56, // XF86Close
/* 207, 0x0cf */ 0x1008FF14, // XF86AudioPlay
/* 208, 0x0d0 */ 0x1008FF97, // XF86AudioForward
/* 209, 0x0d1 */ 0x0, // NoSymbol
/* 210, 0x0d2 */ 0xFF61, // Print
/* 211, 0x0d3 */ 0x0, // NoSymbol
/* 212, 0x0d4 */ 0x1008FF8F, // XF86WebCam
/* 213, 0x0d5 */ 0x1008FFB6, // XF86AudioPreset
/* 214, 0x0d6 */ 0x0, // NoSymbol
/* 215, 0x0d7 */ 0x1008FF19, // XF86Mail
/* 216, 0x0d8 */ 0x1008FF8E, // XF86Messenger
/* 217, 0x0d9 */ 0x1008FF1B, // XF86Search
/* 218, 0x0da */ 0x1008FF5F, // XF86Go
/* 219, 0x0db */ 0x1008FF3C, // XF86Finance
/* 220, 0x0dc */ 0x1008FF5E, // XF86Game
/* 221, 0x0dd */ 0x1008FF36, // XF86Shop
/* 222, 0x0de */ 0x0, // NoSymbol
/* 223, 0x0df */ 0xFF69, // Cancel
/* 224, 0x0e0 */ 0x1008FF03, // XF86MonBrightnessDown
/* 225, 0x0e1 */ 0x1008FF02, // XF86MonBrightnessUp
/* 226, 0x0e2 */ 0x1008FF32, // XF86AudioMedia
/* 227, 0x0e3 */ 0x1008FF59, // XF86Display
/* 228, 0x0e4 */ 0x1008FF04, // XF86KbdLightOnOff
/* 229, 0x0e5 */ 0x1008FF06, // XF86KbdBrightnessDown
/* 230, 0x0e6 */ 0x1008FF05, // XF86KbdBrightnessUp
/* 231, 0x0e7 */ 0x1008FF7B, // XF86Send
/* 232, 0x0e8 */ 0x1008FF72, // XF86Reply
/* 233, 0x0e9 */ 0x1008FF90, // XF86MailForward
/* 234, 0x0ea */ 0x1008FF77, // XF86Save
/* 235, 0x0eb */ 0x1008FF5B, // XF86Documents
/* 236, 0x0ec */ 0x1008FF93, // XF86Battery
/* 237, 0x0ed */ 0x1008FF94, // XF86Bluetooth
/* 238, 0x0ee */ 0x1008FF95, // XF86WLAN
/* 239, 0x0ef */ 0x1008FF96, // XF86UWB
/* 240, 0x0f0 */ 0x0, // NoSymbol
/* 241, 0x0f1 */ 0x1008FE22, // XF86Next_VMode
/* 242, 0x0f2 */ 0x1008FE23, // XF86Prev_VMode
/* 243, 0x0f3 */ 0x1008FF07, // XF86MonBrightnessCycle
/* 244, 0x0f4 */ 0x100810F4, // XF86BrightnessAuto
/* 245, 0x0f5 */ 0x100810F5, // XF86DisplayOff
/* 246, 0x0f6 */ 0x1008FFB4, // XF86WWAN
/* 247, 0x0f7 */ 0x1008FFB5, // XF86RFKill
};
#if 0 // Here is a script to generate the ExtendedLinuxKeycodeKeysyms table
#!/bin/bash
function process_line
{
sym=$(echo "$1" | awk '{print $3}')
code=$(echo "$1" | sed 's,.*_EVDEVK(\(0x[0-9A-Fa-f]*\)).*,\1,')
value=$(grep -E "#define ${sym}\s" -R /usr/include/X11 | awk '{print $3}')
printf " { 0x%.8X, 0x%.3x }, /* $sym */\n" $value $code
}
grep -F "/* Use: " /usr/include/xkbcommon/xkbcommon-keysyms.h | grep -F _EVDEVK | while read line; do
process_line "$line"
done
#endif
static const struct {
Uint32 keysym;
int linux_keycode;
} ExtendedLinuxKeycodeKeysyms[] = {
{ 0x1008FF2C, 0x0a2 }, // XF86XK_Eject
{ 0x1008FF68, 0x0b5 }, // XF86XK_New
{ 0x0000FF66, 0x0b6 }, // XK_Redo
{ 0x1008FF4B, 0x0cc }, // XF86XK_LaunchB
{ 0x1008FF59, 0x0e3 }, // XF86XK_Display
{ 0x1008FF04, 0x0e4 }, // XF86XK_KbdLightOnOff
{ 0x1008FF06, 0x0e5 }, // XF86XK_KbdBrightnessDown
{ 0x1008FF05, 0x0e6 }, // XF86XK_KbdBrightnessUp
{ 0x1008FF7B, 0x0e7 }, // XF86XK_Send
{ 0x1008FF72, 0x0e8 }, // XF86XK_Reply
{ 0x1008FF90, 0x0e9 }, // XF86XK_MailForward
{ 0x1008FF77, 0x0ea }, // XF86XK_Save
{ 0x1008FF5B, 0x0eb }, // XF86XK_Documents
{ 0x1008FF93, 0x0ec }, // XF86XK_Battery
{ 0x1008FF94, 0x0ed }, // XF86XK_Bluetooth
{ 0x1008FF95, 0x0ee }, // XF86XK_WLAN
{ 0x1008FF96, 0x0ef }, // XF86XK_UWB
{ 0x1008FE22, 0x0f1 }, // XF86XK_Next_VMode
{ 0x1008FE23, 0x0f2 }, // XF86XK_Prev_VMode
{ 0x1008FF07, 0x0f3 }, // XF86XK_MonBrightnessCycle
{ 0x1008FFB4, 0x0f6 }, // XF86XK_WWAN
{ 0x1008FFB5, 0x0f7 }, // XF86XK_RFKill
{ 0x1008FFB2, 0x0f8 }, // XF86XK_AudioMicMute
{ 0x1008FF9C, 0x173 }, // XF86XK_CycleAngle
{ 0x1008FFB8, 0x174 }, // XF86XK_FullScreen
{ 0x1008FF87, 0x189 }, // XF86XK_Video
{ 0x1008FF20, 0x18d }, // XF86XK_Calendar
{ 0x1008FF99, 0x19a }, // XF86XK_AudioRandomPlay
{ 0x1008FF5E, 0x1a1 }, // XF86XK_Game
{ 0x1008FF8B, 0x1a2 }, // XF86XK_ZoomIn
{ 0x1008FF8C, 0x1a3 }, // XF86XK_ZoomOut
{ 0x1008FF89, 0x1a5 }, // XF86XK_Word
{ 0x1008FF5C, 0x1a7 }, // XF86XK_Excel
{ 0x1008FF69, 0x1ab }, // XF86XK_News
{ 0x1008FF8E, 0x1ae }, // XF86XK_Messenger
{ 0x1008FF61, 0x1b1 }, // XF86XK_LogOff
{ 0x00000024, 0x1b2 }, // XK_dollar
{ 0x000020AC, 0x1b3 }, // XK_EuroSign
{ 0x1008FF9D, 0x1b4 }, // XF86XK_FrameBack
{ 0x1008FF9E, 0x1b5 }, // XF86XK_FrameForward
{ 0x0000FFF1, 0x1f1 }, // XK_braille_dot_1
{ 0x0000FFF2, 0x1f2 }, // XK_braille_dot_2
{ 0x0000FFF3, 0x1f3 }, // XK_braille_dot_3
{ 0x0000FFF4, 0x1f4 }, // XK_braille_dot_4
{ 0x0000FFF5, 0x1f5 }, // XK_braille_dot_5
{ 0x0000FFF6, 0x1f6 }, // XK_braille_dot_6
{ 0x0000FFF7, 0x1f7 }, // XK_braille_dot_7
{ 0x0000FFF8, 0x1f8 }, // XK_braille_dot_8
{ 0x0000FFF9, 0x1f9 }, // XK_braille_dot_9
{ 0x0000FFF1, 0x1fa }, // XK_braille_dot_1
{ 0x1008FFA9, 0x212 }, // XF86XK_TouchpadToggle
{ 0x1008FFB0, 0x213 }, // XF86XK_TouchpadOn
{ 0x1008FFB1, 0x214 }, // XF86XK_TouchpadOff
{ 0x1008FFB7, 0x231 }, // XF86XK_RotationLockToggle
{ 0x0000FE08, 0x248 }, // XK_ISO_Next_Group
};
/* *INDENT-ON* */ // clang-format on
SDL_Scancode SDL_GetScancodeFromKeySym(Uint32 keysym, Uint32 keycode)
{
int i;
Uint32 linux_keycode = 0;
// First check our custom list
for (i = 0; i < SDL_arraysize(KeySymToSDLScancode); ++i) {
if (keysym == KeySymToSDLScancode[i].keysym) {
return KeySymToSDLScancode[i].scancode;
}
}
if (keysym >= 0x41 && keysym <= 0x5a) {
// Normalize alphabetic keysyms to the lowercase form
keysym += 0x20;
} else if (keysym >= 0x10081000 && keysym <= 0x10081FFF) {
/* The rest of the keysyms map to Linux keycodes, so use that mapping
* Per xkbcommon-keysyms.h, this is actually a linux keycode.
*/
linux_keycode = (keysym - 0x10081000);
}
if (!linux_keycode) {
// See if this keysym is an exact match in our table
i = (keycode - 8);
if (i >= 0 && i < SDL_arraysize(LinuxKeycodeKeysyms) && keysym == LinuxKeycodeKeysyms[i]) {
linux_keycode = i;
} else {
// Scan the table for this keysym
for (i = 0; i < SDL_arraysize(LinuxKeycodeKeysyms); ++i) {
if (keysym == LinuxKeycodeKeysyms[i]) {
linux_keycode = i;
break;
}
}
}
}
if (!linux_keycode) {
// Scan the extended table for this keysym
for (i = 0; i < SDL_arraysize(ExtendedLinuxKeycodeKeysyms); ++i) {
if (keysym == ExtendedLinuxKeycodeKeysyms[i].keysym) {
linux_keycode = ExtendedLinuxKeycodeKeysyms[i].linux_keycode;
break;
}
}
}
return SDL_GetScancodeFromTable(SDL_SCANCODE_TABLE_LINUX, linux_keycode);
}
#endif // SDL_VIDEO_DRIVER_WAYLAND

View file

@ -0,0 +1,28 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_keysym_to_scancode_c_h_
#define SDL_keysym_to_scancode_c_h_
// This function only correctly maps letters and numbers for keyboards in US QWERTY layout
extern SDL_Scancode SDL_GetScancodeFromKeySym(Uint32 keysym, Uint32 keycode);
#endif // SDL_keysym_to_scancode_c_h_

1706
vendor/sdl-3.2.10/src/events/SDL_mouse.c vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,215 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_mouse_c_h_
#define SDL_mouse_c_h_
// Mouse events not associated with a specific input device
#define SDL_GLOBAL_MOUSE_ID 0
// The default mouse input device, for platforms that don't have multiple mice
#define SDL_DEFAULT_MOUSE_ID 1
typedef struct SDL_CursorData SDL_CursorData;
struct SDL_Cursor
{
struct SDL_Cursor *next;
SDL_CursorData *internal;
};
typedef struct
{
Uint64 last_timestamp;
double click_motion_x;
double click_motion_y;
Uint8 click_count;
} SDL_MouseClickState;
typedef struct
{
SDL_MouseID mouseID;
Uint32 buttonstate;
// Data for double-click tracking
int num_clickstates;
SDL_MouseClickState *clickstate;
} SDL_MouseInputSource;
typedef struct
{
// Create a cursor from a surface
SDL_Cursor *(*CreateCursor)(SDL_Surface *surface, int hot_x, int hot_y);
// Create a system cursor
SDL_Cursor *(*CreateSystemCursor)(SDL_SystemCursor id);
// Show the specified cursor, or hide if cursor is NULL
bool (*ShowCursor)(SDL_Cursor *cursor);
// This is called when a mouse motion event occurs
bool (*MoveCursor)(SDL_Cursor *cursor);
// Free a window manager cursor
void (*FreeCursor)(SDL_Cursor *cursor);
// Warp the mouse to (x,y) within a window
bool (*WarpMouse)(SDL_Window *window, float x, float y);
// Warp the mouse to (x,y) in screen space
bool (*WarpMouseGlobal)(float x, float y);
// Set relative mode
bool (*SetRelativeMouseMode)(bool enabled);
// Set mouse capture
bool (*CaptureMouse)(SDL_Window *window);
// Get absolute mouse coordinates. (x) and (y) are never NULL and set to zero before call.
SDL_MouseButtonFlags (*GetGlobalMouseState)(float *x, float *y);
// Platform-specific system mouse transform
void (*ApplySystemScale)(void *internal, Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float *x, float *y);
void *system_scale_data;
// integer mode data
Uint8 integer_mode_flags; // 1 to enable mouse quantization, 2 to enable wheel quantization
float integer_mode_residual_motion_x;
float integer_mode_residual_motion_y;
float integer_mode_residual_scroll_x;
float integer_mode_residual_scroll_y;
// Data common to all mice
SDL_Window *focus;
float x;
float y;
float x_accu;
float y_accu;
float last_x, last_y; // the last reported x and y coordinates
double click_motion_x;
double click_motion_y;
bool has_position;
bool relative_mode;
bool relative_mode_warp_motion;
bool relative_mode_cursor_visible;
bool relative_mode_center;
bool warp_emulation_hint;
bool warp_emulation_active;
bool warp_emulation_prohibited;
Uint64 last_center_warp_time_ns;
bool enable_normal_speed_scale;
float normal_speed_scale;
bool enable_relative_speed_scale;
float relative_speed_scale;
bool enable_relative_system_scale;
Uint32 double_click_time;
int double_click_radius;
bool touch_mouse_events;
bool mouse_touch_events;
bool pen_mouse_events;
bool pen_touch_events;
bool was_touch_mouse_events; // Was a touch-mouse event pending?
bool added_mouse_touch_device; // did we SDL_AddTouch() a virtual touch device for the mouse?
bool added_pen_touch_device; // did we SDL_AddTouch() a virtual touch device for pens?
#ifdef SDL_PLATFORM_VITA
Uint8 vita_touch_mouse_device;
#endif
bool auto_capture;
bool capture_desired;
SDL_Window *capture_window;
// Data for input source state
int num_sources;
SDL_MouseInputSource *sources;
SDL_Cursor *cursors;
SDL_Cursor *def_cursor;
SDL_Cursor *cur_cursor;
bool cursor_shown;
// Driver-dependent data.
void *internal;
} SDL_Mouse;
// Initialize the mouse subsystem, called before the main video driver is initialized
extern bool SDL_PreInitMouse(void);
// Finish initializing the mouse subsystem, called after the main video driver was initialized
extern void SDL_PostInitMouse(void);
// Return whether a device is actually a mouse
extern bool SDL_IsMouse(Uint16 vendor, Uint16 product);
// A mouse has been added to the system
extern void SDL_AddMouse(SDL_MouseID mouseID, const char *name, bool send_event);
// A mouse has been removed from the system
extern void SDL_RemoveMouse(SDL_MouseID mouseID, bool send_event);
// Get the mouse state structure
extern SDL_Mouse *SDL_GetMouse(void);
// Set the default mouse cursor
extern void SDL_SetDefaultCursor(SDL_Cursor *cursor);
// Get the preferred default system cursor
extern SDL_SystemCursor SDL_GetDefaultSystemCursor(void);
// Set the mouse focus window
extern void SDL_SetMouseFocus(SDL_Window *window);
// Update the mouse capture window
extern bool SDL_UpdateMouseCapture(bool force_release);
// Send a mouse motion event
extern void SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, bool relative, float x, float y);
// Send a mouse button event
extern void SDL_SendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 button, bool down);
// Send a mouse button event with a click count
extern void SDL_SendMouseButtonClicks(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 button, bool down, int clicks);
// Send a mouse wheel event
extern void SDL_SendMouseWheel(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction);
// Warp the mouse within the window, potentially overriding relative mode
extern void SDL_PerformWarpMouseInWindow(SDL_Window *window, float x, float y, bool ignore_relative_mode);
// Relative mouse mode
extern bool SDL_SetRelativeMouseMode(bool enabled);
extern bool SDL_GetRelativeMouseMode(void);
extern void SDL_UpdateRelativeMouseMode(void);
extern void SDL_DisableMouseWarpEmulation(void);
// TODO RECONNECT: Set mouse state to "zero"
#if 0
extern void SDL_ResetMouse(void);
#endif // 0
// Check if mouse position is within window or captured by window
extern bool SDL_MousePositionInWindow(SDL_Window *window, float x, float y);
// Shutdown the mouse subsystem
extern void SDL_QuitMouse(void);
#endif // SDL_mouse_c_h_

577
vendor/sdl-3.2.10/src/events/SDL_pen.c vendored Normal file
View file

@ -0,0 +1,577 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
// Pressure-sensitive pen handling code for SDL
#include "../SDL_hints_c.h"
#include "SDL_events_c.h"
#include "SDL_pen_c.h"
static SDL_PenID pen_touching = 0; // used for synthetic mouse/touch events.
typedef struct SDL_Pen
{
SDL_PenID instance_id;
char *name;
SDL_PenInfo info;
float axes[SDL_PEN_AXIS_COUNT];
float x;
float y;
SDL_PenInputFlags input_state;
void *driverdata;
} SDL_Pen;
// we assume there's usually 0-1 pens in most cases and this list doesn't
// usually change after startup, so a simple array with a RWlock is fine for now.
static SDL_RWLock *pen_device_rwlock = NULL;
static SDL_Pen *pen_devices SDL_GUARDED_BY(pen_device_rwlock) = NULL;
static int pen_device_count SDL_GUARDED_BY(pen_device_rwlock) = 0;
// You must hold pen_device_rwlock before calling this, and result is only safe while lock is held!
// If SDL isn't initialized, grabbing the NULL lock is a no-op and there will be zero devices, so
// locking and calling this in that case will do the right thing.
static SDL_Pen *FindPenByInstanceId(SDL_PenID instance_id) SDL_REQUIRES_SHARED(pen_device_rwlock)
{
if (instance_id) {
for (int i = 0; i < pen_device_count; i++) {
if (pen_devices[i].instance_id == instance_id) {
return &pen_devices[i];
}
}
}
SDL_SetError("Invalid pen instance ID");
return NULL;
}
SDL_PenID SDL_FindPenByHandle(void *handle)
{
SDL_PenID result = 0;
SDL_LockRWLockForReading(pen_device_rwlock);
for (int i = 0; i < pen_device_count; i++) {
if (pen_devices[i].driverdata == handle) {
result = pen_devices[i].instance_id;
break;
}
}
SDL_UnlockRWLock(pen_device_rwlock);
return result;
}
SDL_PenID SDL_FindPenByCallback(bool (*callback)(void *handle, void *userdata), void *userdata)
{
SDL_PenID result = 0;
SDL_LockRWLockForReading(pen_device_rwlock);
for (int i = 0; i < pen_device_count; i++) {
if (callback(pen_devices[i].driverdata, userdata)) {
result = pen_devices[i].instance_id;
break;
}
}
SDL_UnlockRWLock(pen_device_rwlock);
return result;
}
// public API ...
bool SDL_InitPen(void)
{
SDL_assert(pen_device_rwlock == NULL);
SDL_assert(pen_devices == NULL);
SDL_assert(pen_device_count == 0);
pen_device_rwlock = SDL_CreateRWLock();
if (!pen_device_rwlock) {
return false;
}
return true;
}
void SDL_QuitPen(void)
{
SDL_DestroyRWLock(pen_device_rwlock);
pen_device_rwlock = NULL;
if (pen_devices) {
for (int i = pen_device_count; i--; ) {
SDL_free(pen_devices[i].name);
}
SDL_free(pen_devices);
pen_devices = NULL;
}
pen_device_count = 0;
pen_touching = 0;
}
#if 0 // not a public API at the moment.
SDL_PenID *SDL_GetPens(int *count)
{
SDL_LockRWLockForReading(pen_device_rwlock);
const int num_devices = pen_device_count;
SDL_PenID *result = (SDL_PenID *) SDL_malloc((num_devices + 1) * sizeof (SDL_PenID));
if (result) {
for (int i = 0; i < num_devices; i++) {
result[i] = pen_devices[i].instance_id;
}
result[num_devices] = 0; // null-terminated.
}
SDL_UnlockRWLock(pen_device_rwlock);
if (count) {
*count = result ? num_devices : 0;
}
return result;
}
const char *SDL_GetPenName(SDL_PenID instance_id)
{
SDL_LockRWLockForReading(pen_device_rwlock);
const SDL_Pen *pen = FindPenByInstanceId(instance_id);
const char *result = pen ? SDL_GetPersistentString(pen->name) : NULL;
SDL_UnlockRWLock(pen_device_rwlock);
return result;
}
bool SDL_GetPenInfo(SDL_PenID instance_id, SDL_PenInfo *info)
{
SDL_LockRWLockForReading(pen_device_rwlock);
const SDL_Pen *pen = FindPenByInstanceId(instance_id);
const bool result = pen ? true : false;
if (info) {
if (result) {
SDL_copyp(info, &pen->info);
} else {
SDL_zerop(info);
}
}
SDL_UnlockRWLock(pen_device_rwlock);
return result;
}
bool SDL_PenConnected(SDL_PenID instance_id)
{
SDL_LockRWLockForReading(pen_device_rwlock);
const SDL_Pen *pen = FindPenByInstanceId(instance_id);
const bool result = (pen != NULL);
SDL_UnlockRWLock(pen_device_rwlock);
return result;
}
#endif
SDL_PenInputFlags SDL_GetPenStatus(SDL_PenID instance_id, float *axes, int num_axes)
{
if (num_axes < 0) {
num_axes = 0;
}
SDL_LockRWLockForReading(pen_device_rwlock);
const SDL_Pen *pen = FindPenByInstanceId(instance_id);
SDL_PenInputFlags result = 0;
if (pen) {
result = pen->input_state;
if (axes && num_axes) {
SDL_memcpy(axes, pen->axes, SDL_min(num_axes, SDL_PEN_AXIS_COUNT) * sizeof (*axes));
// zero out axes we don't know about, in case the caller built with newer SDL headers that support more of them.
if (num_axes > SDL_PEN_AXIS_COUNT) {
SDL_memset(&axes[SDL_PEN_AXIS_COUNT], '\0', (num_axes - SDL_PEN_AXIS_COUNT) * sizeof (*axes));
}
}
}
SDL_UnlockRWLock(pen_device_rwlock);
return result;
}
SDL_PenCapabilityFlags SDL_GetPenCapabilityFromAxis(SDL_PenAxis axis)
{
// the initial capability bits happen to match up, but as
// more features show up later, the bits may no longer be contiguous!
if ((axis >= SDL_PEN_AXIS_PRESSURE) && (axis <= SDL_PEN_AXIS_SLIDER)) {
return ((SDL_PenCapabilityFlags) 1u) << ((SDL_PenCapabilityFlags) axis);
}
return 0; // oh well.
}
SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, const SDL_PenInfo *info, void *handle)
{
SDL_assert(handle != NULL); // just allocate a Uint8 so you have a unique pointer if not needed!
SDL_assert(SDL_FindPenByHandle(handle) == 0); // Backends shouldn't double-add pens!
SDL_assert(pen_device_rwlock != NULL); // subsystem should be initialized by now!
char *namecpy = SDL_strdup(name ? name : "Unnamed pen");
if (!namecpy) {
return 0;
}
SDL_PenID result = 0;
SDL_LockRWLockForWriting(pen_device_rwlock);
SDL_Pen *pen = NULL;
void *ptr = SDL_realloc(pen_devices, (pen_device_count + 1) * sizeof (*pen));
if (ptr) {
result = (SDL_PenID) SDL_GetNextObjectID();
pen_devices = (SDL_Pen *) ptr;
pen = &pen_devices[pen_device_count];
pen_device_count++;
SDL_zerop(pen);
pen->instance_id = result;
pen->name = namecpy;
if (info) {
SDL_copyp(&pen->info, info);
}
pen->driverdata = handle;
// axes and input state defaults to zero.
}
SDL_UnlockRWLock(pen_device_rwlock);
if (!pen) {
SDL_free(namecpy);
}
if (result && SDL_EventEnabled(SDL_EVENT_PEN_PROXIMITY_IN)) {
SDL_Event event;
SDL_zero(event);
event.pproximity.type = SDL_EVENT_PEN_PROXIMITY_IN;
event.pproximity.timestamp = timestamp;
event.pproximity.which = result;
SDL_PushEvent(&event);
}
return result;
}
void SDL_RemovePenDevice(Uint64 timestamp, SDL_PenID instance_id)
{
if (!instance_id) {
return;
}
SDL_LockRWLockForWriting(pen_device_rwlock);
SDL_Pen *pen = FindPenByInstanceId(instance_id);
if (pen) {
SDL_free(pen->name);
// we don't free `pen`, it's just part of simple array. Shuffle it out.
const int idx = ((int) (pen - pen_devices));
SDL_assert((idx >= 0) && (idx < pen_device_count));
if ( idx < (pen_device_count - 1) ) {
SDL_memmove(&pen_devices[idx], &pen_devices[idx + 1], sizeof (*pen) * ((pen_device_count - idx) - 1));
}
SDL_assert(pen_device_count > 0);
pen_device_count--;
if (pen_device_count) {
void *ptr = SDL_realloc(pen_devices, sizeof (*pen) * pen_device_count); // shrink it down.
if (ptr) {
pen_devices = (SDL_Pen *) ptr;
}
} else {
SDL_free(pen_devices);
pen_devices = NULL;
}
}
SDL_UnlockRWLock(pen_device_rwlock);
if (pen && SDL_EventEnabled(SDL_EVENT_PEN_PROXIMITY_OUT)) {
SDL_Event event;
SDL_zero(event);
event.pproximity.type = SDL_EVENT_PEN_PROXIMITY_OUT;
event.pproximity.timestamp = timestamp;
event.pproximity.which = instance_id;
SDL_PushEvent(&event);
}
}
// This presumably is happening during video quit, so we don't send PROXIMITY_OUT events here.
void SDL_RemoveAllPenDevices(void (*callback)(SDL_PenID instance_id, void *handle, void *userdata), void *userdata)
{
SDL_LockRWLockForWriting(pen_device_rwlock);
if (pen_device_count > 0) {
SDL_assert(pen_devices != NULL);
for (int i = 0; i < pen_device_count; i++) {
callback(pen_devices[i].instance_id, pen_devices[i].driverdata, userdata);
SDL_free(pen_devices[i].name);
}
}
SDL_free(pen_devices);
pen_devices = NULL;
SDL_UnlockRWLock(pen_device_rwlock);
}
void SDL_SendPenTouch(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, bool eraser, bool down)
{
bool send_event = false;
SDL_PenInputFlags input_state = 0;
float x = 0.0f;
float y = 0.0f;
// note that this locks for _reading_ because the lock protects the
// pen_devices array from being reallocated from under us, not the data in it;
// we assume only one thread (in the backend) is modifying an individual pen at
// a time, so it can update input state cleanly here.
SDL_LockRWLockForReading(pen_device_rwlock);
SDL_Pen *pen = FindPenByInstanceId(instance_id);
if (pen) {
input_state = pen->input_state;
x = pen->x;
y = pen->y;
if (down && ((input_state & SDL_PEN_INPUT_DOWN) == 0)) {
input_state |= SDL_PEN_INPUT_DOWN;
send_event = true;
} else if (!down && (input_state & SDL_PEN_INPUT_DOWN)) {
input_state &= ~SDL_PEN_INPUT_DOWN;
send_event = true;
}
if (eraser && ((input_state & SDL_PEN_INPUT_ERASER_TIP) == 0)) {
input_state |= SDL_PEN_INPUT_ERASER_TIP;
send_event = true;
} else if (!eraser && (input_state & SDL_PEN_INPUT_ERASER_TIP)) {
input_state &= ~SDL_PEN_INPUT_ERASER_TIP;
send_event = true;
}
pen->input_state = input_state; // we could do an SDL_SetAtomicInt here if we run into trouble...
}
SDL_UnlockRWLock(pen_device_rwlock);
if (send_event) {
const SDL_EventType evtype = down ? SDL_EVENT_PEN_DOWN : SDL_EVENT_PEN_UP;
if (SDL_EventEnabled(evtype)) {
SDL_Event event;
SDL_zero(event);
event.ptouch.type = evtype;
event.ptouch.timestamp = timestamp;
event.ptouch.windowID = window ? window->id : 0;
event.ptouch.which = instance_id;
event.ptouch.pen_state = input_state;
event.ptouch.x = x;
event.ptouch.y = y;
event.ptouch.eraser = eraser;
event.ptouch.down = down;
SDL_PushEvent(&event);
}
SDL_Mouse *mouse = SDL_GetMouse();
if (mouse && window) {
if (mouse->pen_mouse_events) {
if (down) {
if (!pen_touching) {
SDL_SendMouseMotion(timestamp, window, SDL_PEN_MOUSEID, false, x, y);
SDL_SendMouseButton(timestamp, window, SDL_PEN_MOUSEID, SDL_BUTTON_LEFT, true);
}
} else {
if (pen_touching == instance_id) {
SDL_SendMouseButton(timestamp, window, SDL_PEN_MOUSEID, SDL_BUTTON_LEFT, false);
}
}
}
if (mouse->pen_touch_events) {
const SDL_EventType touchtype = down ? SDL_EVENT_FINGER_DOWN : SDL_EVENT_FINGER_UP;
const float normalized_x = x / (float)window->w;
const float normalized_y = y / (float)window->h;
if (!pen_touching || (pen_touching == instance_id)) {
SDL_SendTouch(timestamp, SDL_PEN_TOUCHID, SDL_BUTTON_LEFT, window, touchtype, normalized_x, normalized_y, pen->axes[SDL_PEN_AXIS_PRESSURE]);
}
}
}
if (down) {
if (!pen_touching) {
pen_touching = instance_id;
}
} else {
if (pen_touching == instance_id) {
pen_touching = 0;
}
}
}
}
void SDL_SendPenAxis(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, SDL_PenAxis axis, float value)
{
SDL_assert((axis >= 0) && (axis < SDL_PEN_AXIS_COUNT)); // fix the backend if this triggers.
bool send_event = false;
SDL_PenInputFlags input_state = 0;
float x = 0.0f;
float y = 0.0f;
// note that this locks for _reading_ because the lock protects the
// pen_devices array from being reallocated from under us, not the data in it;
// we assume only one thread (in the backend) is modifying an individual pen at
// a time, so it can update input state cleanly here.
SDL_LockRWLockForReading(pen_device_rwlock);
SDL_Pen *pen = FindPenByInstanceId(instance_id);
if (pen) {
if (pen->axes[axis] != value) {
pen->axes[axis] = value; // we could do an SDL_SetAtomicInt here if we run into trouble...
input_state = pen->input_state;
x = pen->x;
y = pen->y;
send_event = true;
}
}
SDL_UnlockRWLock(pen_device_rwlock);
if (send_event && SDL_EventEnabled(SDL_EVENT_PEN_AXIS)) {
SDL_Event event;
SDL_zero(event);
event.paxis.type = SDL_EVENT_PEN_AXIS;
event.paxis.timestamp = timestamp;
event.paxis.windowID = window ? window->id : 0;
event.paxis.which = instance_id;
event.paxis.pen_state = input_state;
event.paxis.x = x;
event.paxis.y = y;
event.paxis.axis = axis;
event.paxis.value = value;
SDL_PushEvent(&event);
if (window && (axis == SDL_PEN_AXIS_PRESSURE) && (pen_touching == instance_id)) {
SDL_Mouse *mouse = SDL_GetMouse();
if (mouse && mouse->pen_touch_events) {
const float normalized_x = x / (float)window->w;
const float normalized_y = y / (float)window->h;
SDL_SendTouchMotion(timestamp, SDL_PEN_TOUCHID, SDL_BUTTON_LEFT, window, normalized_x, normalized_y, value);
}
}
}
}
void SDL_SendPenMotion(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, float x, float y)
{
bool send_event = false;
SDL_PenInputFlags input_state = 0;
// note that this locks for _reading_ because the lock protects the
// pen_devices array from being reallocated from under us, not the data in it;
// we assume only one thread (in the backend) is modifying an individual pen at
// a time, so it can update input state cleanly here.
SDL_LockRWLockForReading(pen_device_rwlock);
SDL_Pen *pen = FindPenByInstanceId(instance_id);
if (pen) {
if ((pen->x != x) || (pen->y != y)) {
pen->x = x; // we could do an SDL_SetAtomicInt here if we run into trouble...
pen->y = y; // we could do an SDL_SetAtomicInt here if we run into trouble...
input_state = pen->input_state;
send_event = true;
}
}
SDL_UnlockRWLock(pen_device_rwlock);
if (send_event && SDL_EventEnabled(SDL_EVENT_PEN_MOTION)) {
SDL_Event event;
SDL_zero(event);
event.pmotion.type = SDL_EVENT_PEN_MOTION;
event.pmotion.timestamp = timestamp;
event.pmotion.windowID = window ? window->id : 0;
event.pmotion.which = instance_id;
event.pmotion.pen_state = input_state;
event.pmotion.x = x;
event.pmotion.y = y;
SDL_PushEvent(&event);
if (window) {
SDL_Mouse *mouse = SDL_GetMouse();
if (mouse) {
if (pen_touching == instance_id) {
if (mouse->pen_mouse_events) {
SDL_SendMouseMotion(timestamp, window, SDL_PEN_MOUSEID, false, x, y);
}
if (mouse->pen_touch_events) {
const float normalized_x = x / (float)window->w;
const float normalized_y = y / (float)window->h;
SDL_SendTouchMotion(timestamp, SDL_PEN_TOUCHID, SDL_BUTTON_LEFT, window, normalized_x, normalized_y, pen->axes[SDL_PEN_AXIS_PRESSURE]);
}
} else if (pen_touching == 0) { // send mouse motion (without a pressed button) for pens that aren't touching.
// 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. :)
SDL_SendMouseMotion(timestamp, window, SDL_PEN_MOUSEID, false, x, y);
}
}
}
}
}
void SDL_SendPenButton(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, Uint8 button, bool down)
{
bool send_event = false;
SDL_PenInputFlags input_state = 0;
float x = 0.0f;
float y = 0.0f;
if ((button < 1) || (button > 5)) {
return; // clamp for now.
}
// note that this locks for _reading_ because the lock protects the
// pen_devices array from being reallocated from under us, not the data in it;
// we assume only one thread (in the backend) is modifying an individual pen at
// a time, so it can update input state cleanly here.
SDL_LockRWLockForReading(pen_device_rwlock);
SDL_Pen *pen = FindPenByInstanceId(instance_id);
if (pen) {
input_state = pen->input_state;
const Uint32 flag = (Uint32) (1u << button);
const bool current = ((input_state & flag) != 0);
x = pen->x;
y = pen->y;
if (down && !current) {
input_state |= flag;
send_event = true;
} else if (!down && current) {
input_state &= ~flag;
send_event = true;
}
pen->input_state = input_state; // we could do an SDL_SetAtomicInt here if we run into trouble...
}
SDL_UnlockRWLock(pen_device_rwlock);
if (send_event) {
const SDL_EventType evtype = down ? SDL_EVENT_PEN_BUTTON_DOWN : SDL_EVENT_PEN_BUTTON_UP;
if (SDL_EventEnabled(evtype)) {
SDL_Event event;
SDL_zero(event);
event.pbutton.type = evtype;
event.pbutton.timestamp = timestamp;
event.pbutton.windowID = window ? window->id : 0;
event.pbutton.which = instance_id;
event.pbutton.pen_state = input_state;
event.pbutton.x = x;
event.pbutton.y = y;
event.pbutton.button = button;
event.pbutton.down = down;
SDL_PushEvent(&event);
if (window && (pen_touching == instance_id)) {
SDL_Mouse *mouse = SDL_GetMouse();
if (mouse && mouse->pen_mouse_events) {
SDL_SendMouseButton(timestamp, window, SDL_PEN_MOUSEID, button + 1, down);
}
}
}
}
}

View file

@ -0,0 +1,99 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"
#ifndef SDL_pen_c_h_
#define SDL_pen_c_h_
#include "SDL_mouse_c.h"
typedef Uint32 SDL_PenCapabilityFlags;
#define SDL_PEN_CAPABILITY_PRESSURE (1u << 0) /**< Provides pressure information on SDL_PEN_AXIS_PRESSURE. */
#define SDL_PEN_CAPABILITY_XTILT (1u << 1) /**< Provides horizontal tilt information on SDL_PEN_AXIS_XTILT. */
#define SDL_PEN_CAPABILITY_YTILT (1u << 2) /**< Provides vertical tilt information on SDL_PEN_AXIS_YTILT. */
#define SDL_PEN_CAPABILITY_DISTANCE (1u << 3) /**< Provides distance to drawing tablet on SDL_PEN_AXIS_DISTANCE. */
#define SDL_PEN_CAPABILITY_ROTATION (1u << 4) /**< Provides barrel rotation info on SDL_PEN_AXIS_ROTATION. */
#define SDL_PEN_CAPABILITY_SLIDER (1u << 5) /**< Provides slider/finger wheel/etc on SDL_PEN_AXIS_SLIDER. */
#define SDL_PEN_CAPABILITY_TANGENTIAL_PRESSURE (1u << 6) /**< Provides barrel pressure on SDL_PEN_AXIS_TANGENTIAL_PRESSURE. */
#define SDL_PEN_CAPABILITY_ERASER (1u << 7) /**< Pen also has an eraser tip. */
typedef enum SDL_PenSubtype
{
SDL_PEN_TYPE_UNKNOWN, /**< Unknown pen device */
SDL_PEN_TYPE_ERASER, /**< Eraser */
SDL_PEN_TYPE_PEN, /**< Generic pen; this is the default. */
SDL_PEN_TYPE_PENCIL, /**< Pencil */
SDL_PEN_TYPE_BRUSH, /**< Brush-like device */
SDL_PEN_TYPE_AIRBRUSH /**< Airbrush device that "sprays" ink */
} SDL_PenSubtype;
typedef struct SDL_PenInfo
{
SDL_PenCapabilityFlags capabilities; /**< bitflags of device capabilities */
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. */
Uint32 wacom_id; /**< For Wacom devices: wacom tool type ID, otherwise 0 (useful e.g. with libwacom) */
int num_buttons; /**< Number of pen buttons (not counting the pen tip), or -1 if unknown. */
SDL_PenSubtype subtype; /**< type of pen device */
} SDL_PenInfo;
// Backend calls this when a new pen device is hotplugged, plus once for each pen already connected at startup.
// Note that name and info are copied but currently unused; this is placeholder for a potentially more robust API later.
// Both are allowed to be NULL.
extern SDL_PenID SDL_AddPenDevice(Uint64 timestamp, const char *name, const SDL_PenInfo *info, void *handle);
// Backend calls this when an existing pen device is disconnected during runtime. They must free their own stuff separately.
extern void SDL_RemovePenDevice(Uint64 timestamp, SDL_PenID instance_id);
// Backend can call this to remove all pens, probably during shutdown, with a callback to let them free their own handle.
extern void SDL_RemoveAllPenDevices(void (*callback)(SDL_PenID instance_id, void *handle, void *userdata), void *userdata);
// Backend calls this when a pen's button changes, to generate events and update state.
extern void SDL_SendPenTouch(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, bool eraser, bool down);
// Backend calls this when a pen moves on the tablet, to generate events and update state.
extern void SDL_SendPenMotion(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, float x, float y);
// Backend calls this when a pen's axis changes, to generate events and update state.
extern void SDL_SendPenAxis(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, SDL_PenAxis axis, float value);
// Backend calls this when a pen's button changes, to generate events and update state.
extern void SDL_SendPenButton(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *window, Uint8 button, bool down);
// Backend can optionally use this to find the SDL_PenID for the `handle` that was passed to SDL_AddPenDevice.
extern SDL_PenID SDL_FindPenByHandle(void *handle);
// Backend can optionally use this to find a SDL_PenID, selected by a callback examining all devices. Zero if not found.
extern SDL_PenID SDL_FindPenByCallback(bool (*callback)(void *handle, void *userdata), void *userdata);
// Backend can use this to query current pen status.
SDL_PenInputFlags SDL_GetPenStatus(SDL_PenID instance_id, float *axes, int num_axes);
// Backend can use this to map an axis to a capability bit.
SDL_PenCapabilityFlags SDL_GetPenCapabilityFromAxis(SDL_PenAxis axis);
// Higher-level SDL video subsystem code calls this when starting up. Backends shouldn't.
extern bool SDL_InitPen(void);
// Higher-level SDL video subsystem code calls this when shutting down. Backends shouldn't.
extern void SDL_QuitPen(void);
#endif // SDL_pen_c_h_

194
vendor/sdl-3.2.10/src/events/SDL_quit.c vendored Normal file
View file

@ -0,0 +1,194 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
// General quit handling code for SDL
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
#include "SDL_events_c.h"
#if defined(HAVE_SIGNAL_H) || defined(HAVE_SIGACTION)
#define HAVE_SIGNAL_SUPPORT 1
#endif
#ifdef HAVE_SIGNAL_SUPPORT
static bool disable_signals = false;
static bool send_quit_pending = false;
#ifdef SDL_BACKGROUNDING_SIGNAL
static bool send_backgrounding_pending = false;
#endif
#ifdef SDL_FOREGROUNDING_SIGNAL
static bool send_foregrounding_pending = false;
#endif
static void SDL_HandleSIG(int sig)
{
// Reset the signal handler
(void)signal(sig, SDL_HandleSIG);
// Send a quit event next time the event loop pumps.
// We can't send it in signal handler; SDL_malloc() might be interrupted!
if ((sig == SIGINT) || (sig == SIGTERM)) {
send_quit_pending = true;
}
#ifdef SDL_BACKGROUNDING_SIGNAL
else if (sig == SDL_BACKGROUNDING_SIGNAL) {
send_backgrounding_pending = true;
}
#endif
#ifdef SDL_FOREGROUNDING_SIGNAL
else if (sig == SDL_FOREGROUNDING_SIGNAL) {
send_foregrounding_pending = true;
}
#endif
}
static void SDL_EventSignal_Init(const int sig)
{
#ifdef HAVE_SIGACTION
struct sigaction action;
sigaction(sig, NULL, &action);
#ifdef HAVE_SA_SIGACTION
if (action.sa_handler == SIG_DFL && (void (*)(int))action.sa_sigaction == SIG_DFL) {
#else
if (action.sa_handler == SIG_DFL) {
#endif
action.sa_handler = SDL_HandleSIG;
sigaction(sig, &action, NULL);
}
#elif defined(HAVE_SIGNAL_H)
void (*ohandler)(int) = signal(sig, SDL_HandleSIG);
if (ohandler != SIG_DFL) {
signal(sig, ohandler);
}
#endif
}
static void SDL_EventSignal_Quit(const int sig)
{
#ifdef HAVE_SIGACTION
struct sigaction action;
sigaction(sig, NULL, &action);
if (action.sa_handler == SDL_HandleSIG) {
action.sa_handler = SIG_DFL;
sigaction(sig, &action, NULL);
}
#elif defined(HAVE_SIGNAL_H)
void (*ohandler)(int) = signal(sig, SIG_DFL);
if (ohandler != SDL_HandleSIG) {
signal(sig, ohandler);
}
#endif // HAVE_SIGNAL_H
}
// Public functions
static bool SDL_QuitInit_Internal(void)
{
// Both SIGINT and SIGTERM are translated into quit interrupts
// and SDL can be built to simulate iOS/Android semantics with arbitrary signals.
SDL_EventSignal_Init(SIGINT);
SDL_EventSignal_Init(SIGTERM);
#ifdef SDL_BACKGROUNDING_SIGNAL
SDL_EventSignal_Init(SDL_BACKGROUNDING_SIGNAL);
#endif
#ifdef SDL_FOREGROUNDING_SIGNAL
SDL_EventSignal_Init(SDL_FOREGROUNDING_SIGNAL);
#endif
// That's it!
return true;
}
static void SDL_QuitQuit_Internal(void)
{
SDL_EventSignal_Quit(SIGINT);
SDL_EventSignal_Quit(SIGTERM);
#ifdef SDL_BACKGROUNDING_SIGNAL
SDL_EventSignal_Quit(SDL_BACKGROUNDING_SIGNAL);
#endif
#ifdef SDL_FOREGROUNDING_SIGNAL
SDL_EventSignal_Quit(SDL_FOREGROUNDING_SIGNAL);
#endif
}
#endif
bool SDL_InitQuit(void)
{
#ifdef HAVE_SIGNAL_SUPPORT
if (!SDL_GetHintBoolean(SDL_HINT_NO_SIGNAL_HANDLERS, false)) {
return SDL_QuitInit_Internal();
}
#endif
return true;
}
void SDL_QuitQuit(void)
{
#ifdef HAVE_SIGNAL_SUPPORT
if (!disable_signals) {
SDL_QuitQuit_Internal();
}
#endif
}
void SDL_SendPendingSignalEvents(void)
{
#ifdef HAVE_SIGNAL_SUPPORT
if (send_quit_pending) {
SDL_SendQuit();
SDL_assert(!send_quit_pending);
}
#ifdef SDL_BACKGROUNDING_SIGNAL
if (send_backgrounding_pending) {
send_backgrounding_pending = false;
SDL_OnApplicationWillEnterBackground();
}
#endif
#ifdef SDL_FOREGROUNDING_SIGNAL
if (send_foregrounding_pending) {
send_foregrounding_pending = false;
SDL_OnApplicationDidEnterForeground();
}
#endif
#endif
}
void SDL_SendQuit(void)
{
#ifdef HAVE_SIGNAL_SUPPORT
send_quit_pending = false;
#endif
SDL_SendAppEvent(SDL_EVENT_QUIT);
}

View file

@ -0,0 +1,71 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if defined(SDL_INPUT_LINUXEV) || defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_X11)
#include "SDL_scancode_tables_c.h"
#include "scancodes_darwin.h"
#include "scancodes_linux.h"
#include "scancodes_xfree86.h"
static const struct
{
SDL_ScancodeTable table;
SDL_Scancode const *scancodes;
int num_entries;
} SDL_scancode_tables[] = {
{ SDL_SCANCODE_TABLE_DARWIN, darwin_scancode_table, SDL_arraysize(darwin_scancode_table) },
{ SDL_SCANCODE_TABLE_LINUX, linux_scancode_table, SDL_arraysize(linux_scancode_table) },
{ SDL_SCANCODE_TABLE_XFREE86_1, xfree86_scancode_table, SDL_arraysize(xfree86_scancode_table) },
{ SDL_SCANCODE_TABLE_XFREE86_2, xfree86_scancode_table2, SDL_arraysize(xfree86_scancode_table2) },
{ SDL_SCANCODE_TABLE_XVNC, xvnc_scancode_table, SDL_arraysize(xvnc_scancode_table) },
};
const SDL_Scancode *SDL_GetScancodeTable(SDL_ScancodeTable table, int *num_entries)
{
int i;
for (i = 0; i < SDL_arraysize(SDL_scancode_tables); ++i) {
if (table == SDL_scancode_tables[i].table) {
*num_entries = SDL_scancode_tables[i].num_entries;
return SDL_scancode_tables[i].scancodes;
}
}
*num_entries = 0;
return NULL;
}
SDL_Scancode SDL_GetScancodeFromTable(SDL_ScancodeTable table, int keycode)
{
SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
int num_entries;
const SDL_Scancode *scancodes = SDL_GetScancodeTable(table, &num_entries);
if (keycode >= 0 && keycode < num_entries) {
scancode = scancodes[keycode];
}
return scancode;
}
#endif // SDL_INPUT_LINUXEV || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_X11

View file

@ -0,0 +1,33 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
typedef enum
{
SDL_SCANCODE_TABLE_DARWIN,
SDL_SCANCODE_TABLE_LINUX,
SDL_SCANCODE_TABLE_XFREE86_1,
SDL_SCANCODE_TABLE_XFREE86_2,
SDL_SCANCODE_TABLE_XVNC,
} SDL_ScancodeTable;
extern const SDL_Scancode *SDL_GetScancodeTable(SDL_ScancodeTable table, int *num_entries);
extern SDL_Scancode SDL_GetScancodeFromTable(SDL_ScancodeTable table, int keycode);

500
vendor/sdl-3.2.10/src/events/SDL_touch.c vendored Normal file
View file

@ -0,0 +1,500 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
// General touch handling code for SDL
#include "SDL_events_c.h"
#include "../video/SDL_sysvideo.h"
static int SDL_num_touch = 0;
static SDL_Touch **SDL_touchDevices = NULL;
// for mapping touch events to mice
static bool finger_touching = false;
static SDL_FingerID track_fingerid;
static SDL_TouchID track_touchid;
// Public functions
bool SDL_InitTouch(void)
{
return true;
}
bool SDL_TouchDevicesAvailable(void)
{
return SDL_num_touch > 0;
}
SDL_TouchID *SDL_GetTouchDevices(int *count)
{
if (count) {
*count = 0;
}
const int total = SDL_num_touch;
SDL_TouchID *result = (SDL_TouchID *) SDL_malloc(sizeof (SDL_TouchID) * (total + 1));
if (result) {
for (int i = 0; i < total; i++) {
result[i] = SDL_touchDevices[i]->id;
}
result[total] = 0;
if (count) {
*count = SDL_num_touch;
}
}
return result;
}
static int SDL_GetTouchIndex(SDL_TouchID id)
{
int index;
SDL_Touch *touch;
for (index = 0; index < SDL_num_touch; ++index) {
touch = SDL_touchDevices[index];
if (touch->id == id) {
return index;
}
}
return -1;
}
SDL_Touch *SDL_GetTouch(SDL_TouchID id)
{
int index = SDL_GetTouchIndex(id);
if (index < 0 || index >= SDL_num_touch) {
if (SDL_GetVideoDevice()->ResetTouch != NULL) {
SDL_SetError("Unknown touch id %d, resetting", (int)id);
(SDL_GetVideoDevice()->ResetTouch)(SDL_GetVideoDevice());
} else {
SDL_SetError("Unknown touch device id %d, cannot reset", (int)id);
}
return NULL;
}
return SDL_touchDevices[index];
}
const char *SDL_GetTouchDeviceName(SDL_TouchID id)
{
SDL_Touch *touch = SDL_GetTouch(id);
if (!touch) {
return NULL;
}
return SDL_GetPersistentString(touch->name);
}
SDL_TouchDeviceType SDL_GetTouchDeviceType(SDL_TouchID id)
{
SDL_Touch *touch = SDL_GetTouch(id);
return touch ? touch->type : SDL_TOUCH_DEVICE_INVALID;
}
static int SDL_GetFingerIndex(const SDL_Touch *touch, SDL_FingerID fingerid)
{
int index;
for (index = 0; index < touch->num_fingers; ++index) {
if (touch->fingers[index]->id == fingerid) {
return index;
}
}
return -1;
}
static SDL_Finger *SDL_GetFinger(const SDL_Touch *touch, SDL_FingerID id)
{
int index = SDL_GetFingerIndex(touch, id);
if (index < 0 || index >= touch->num_fingers) {
return NULL;
}
return touch->fingers[index];
}
SDL_Finger **SDL_GetTouchFingers(SDL_TouchID touchID, int *count)
{
SDL_Finger **fingers;
SDL_Finger *finger_data;
if (count) {
*count = 0;
}
SDL_Touch *touch = SDL_GetTouch(touchID);
if (!touch) {
return NULL;
}
// Create a snapshot of the current finger state
fingers = (SDL_Finger **)SDL_malloc((touch->num_fingers + 1) * sizeof(*fingers) + touch->num_fingers * sizeof(**fingers));
if (!fingers) {
return NULL;
}
finger_data = (SDL_Finger *)(fingers + (touch->num_fingers + 1));
for (int i = 0; i < touch->num_fingers; ++i) {
fingers[i] = &finger_data[i];
SDL_copyp(fingers[i], touch->fingers[i]);
}
fingers[touch->num_fingers] = NULL;
if (count) {
*count = touch->num_fingers;
}
return fingers;
}
int SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name)
{
SDL_Touch **touchDevices;
int index;
SDL_assert(touchID != 0);
index = SDL_GetTouchIndex(touchID);
if (index >= 0) {
return index;
}
// Add the touch to the list of touch
touchDevices = (SDL_Touch **)SDL_realloc(SDL_touchDevices,
(SDL_num_touch + 1) * sizeof(*touchDevices));
if (!touchDevices) {
return -1;
}
SDL_touchDevices = touchDevices;
index = SDL_num_touch;
SDL_touchDevices[index] = (SDL_Touch *)SDL_malloc(sizeof(*SDL_touchDevices[index]));
if (!SDL_touchDevices[index]) {
return -1;
}
// Added touch to list
++SDL_num_touch;
// we're setting the touch properties
SDL_touchDevices[index]->id = touchID;
SDL_touchDevices[index]->type = type;
SDL_touchDevices[index]->num_fingers = 0;
SDL_touchDevices[index]->max_fingers = 0;
SDL_touchDevices[index]->fingers = NULL;
SDL_touchDevices[index]->name = SDL_strdup(name ? name : "");
return index;
}
static bool SDL_AddFinger(SDL_Touch *touch, SDL_FingerID fingerid, float x, float y, float pressure)
{
SDL_Finger *finger;
SDL_assert(fingerid != 0);
if (touch->num_fingers == touch->max_fingers) {
SDL_Finger **new_fingers;
new_fingers = (SDL_Finger **)SDL_realloc(touch->fingers, (touch->max_fingers + 1) * sizeof(*touch->fingers));
if (!new_fingers) {
return false;
}
touch->fingers = new_fingers;
touch->fingers[touch->max_fingers] = (SDL_Finger *)SDL_malloc(sizeof(*finger));
if (!touch->fingers[touch->max_fingers]) {
return false;
}
touch->max_fingers++;
}
finger = touch->fingers[touch->num_fingers++];
finger->id = fingerid;
finger->x = x;
finger->y = y;
finger->pressure = pressure;
return true;
}
static void SDL_DelFinger(SDL_Touch *touch, SDL_FingerID fingerid)
{
int index = SDL_GetFingerIndex(touch, fingerid);
if (index < 0) {
return;
}
--touch->num_fingers;
if (index < (touch->num_fingers)) {
// Move the deleted finger to just past the end of the active fingers array and shift the active fingers by one.
// This ensures that the descriptor for the now-deleted finger is located at `touch->fingers[touch->num_fingers]`
// and is ready for use in SDL_AddFinger.
SDL_Finger *deleted_finger = touch->fingers[index];
SDL_memmove(&touch->fingers[index], &touch->fingers[index + 1], (touch->num_fingers - index) * sizeof(touch->fingers[index]));
touch->fingers[touch->num_fingers] = deleted_finger;
}
}
void SDL_SendTouch(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, SDL_EventType type, float x, float y, float pressure)
{
SDL_Finger *finger;
bool down = (type == SDL_EVENT_FINGER_DOWN);
SDL_Touch *touch = SDL_GetTouch(id);
if (!touch) {
return;
}
SDL_Mouse *mouse = SDL_GetMouse();
// SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events
// SDL_HINT_VITA_TOUCH_MOUSE_DEVICE: controlling which touchpad should generate synthetic mouse events, PSVita-only
{
// FIXME: maybe we should only restrict to a few SDL_TouchDeviceType
if ((id != SDL_MOUSE_TOUCHID) && (id != SDL_PEN_TOUCHID)) {
#ifdef SDL_PLATFORM_VITA
if (mouse->touch_mouse_events && ((mouse->vita_touch_mouse_device == id) || (mouse->vita_touch_mouse_device == 3))) {
#else
if (mouse->touch_mouse_events) {
#endif
if (window) {
if (down) {
if (finger_touching == false) {
float pos_x = (x * (float)window->w);
float pos_y = (y * (float)window->h);
if (pos_x < 0) {
pos_x = 0;
}
if (pos_x > (float)(window->w - 1)) {
pos_x = (float)(window->w - 1);
}
if (pos_y < 0.0f) {
pos_y = 0.0f;
}
if (pos_y > (float)(window->h - 1)) {
pos_y = (float)(window->h - 1);
}
SDL_SendMouseMotion(timestamp, window, SDL_TOUCH_MOUSEID, false, pos_x, pos_y);
SDL_SendMouseButton(timestamp, window, SDL_TOUCH_MOUSEID, SDL_BUTTON_LEFT, true);
}
} else {
if (finger_touching == true && track_touchid == id && track_fingerid == fingerid) {
SDL_SendMouseButton(timestamp, window, SDL_TOUCH_MOUSEID, SDL_BUTTON_LEFT, false);
}
}
}
if (down) {
if (finger_touching == false) {
finger_touching = true;
track_touchid = id;
track_fingerid = fingerid;
}
} else {
if (finger_touching == true && track_touchid == id && track_fingerid == fingerid) {
finger_touching = false;
}
}
}
}
}
// SDL_HINT_MOUSE_TOUCH_EVENTS: if not set, discard synthetic touch events coming from platform layer
if (!mouse->mouse_touch_events && (id == SDL_MOUSE_TOUCHID)) {
return;
} else if (!mouse->pen_touch_events && (id == SDL_PEN_TOUCHID)) {
return;
}
finger = SDL_GetFinger(touch, fingerid);
if (down) {
if (finger) {
/* This finger is already down.
Assume the finger-up for the previous touch was lost, and send it. */
SDL_SendTouch(timestamp, id, fingerid, window, SDL_EVENT_FINGER_CANCELED, x, y, pressure);
}
if (!SDL_AddFinger(touch, fingerid, x, y, pressure)) {
return;
}
if (SDL_EventEnabled(type)) {
SDL_Event event;
event.type = type;
event.common.timestamp = timestamp;
event.tfinger.touchID = id;
event.tfinger.fingerID = fingerid;
event.tfinger.x = x;
event.tfinger.y = y;
event.tfinger.dx = 0;
event.tfinger.dy = 0;
event.tfinger.pressure = pressure;
event.tfinger.windowID = window ? SDL_GetWindowID(window) : 0;
SDL_PushEvent(&event);
}
} else {
if (!finger) {
// This finger is already up
return;
}
if (SDL_EventEnabled(type)) {
SDL_Event event;
event.type = type;
event.common.timestamp = timestamp;
event.tfinger.touchID = id;
event.tfinger.fingerID = fingerid;
// I don't trust the coordinates passed on fingerUp
event.tfinger.x = finger->x;
event.tfinger.y = finger->y;
event.tfinger.dx = 0;
event.tfinger.dy = 0;
event.tfinger.pressure = pressure;
event.tfinger.windowID = window ? SDL_GetWindowID(window) : 0;
SDL_PushEvent(&event);
}
SDL_DelFinger(touch, fingerid);
}
}
void SDL_SendTouchMotion(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window,
float x, float y, float pressure)
{
SDL_Touch *touch;
SDL_Finger *finger;
float xrel, yrel, prel;
touch = SDL_GetTouch(id);
if (!touch) {
return;
}
SDL_Mouse *mouse = SDL_GetMouse();
// SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events
{
if ((id != SDL_MOUSE_TOUCHID) && (id != SDL_PEN_TOUCHID)) {
if (mouse->touch_mouse_events) {
if (window) {
if (finger_touching == true && track_touchid == id && track_fingerid == fingerid) {
float pos_x = (x * (float)window->w);
float pos_y = (y * (float)window->h);
if (pos_x < 0.0f) {
pos_x = 0.0f;
}
if (pos_x > (float)(window->w - 1)) {
pos_x = (float)(window->w - 1);
}
if (pos_y < 0.0f) {
pos_y = 0.0f;
}
if (pos_y > (float)(window->h - 1)) {
pos_y = (float)(window->h - 1);
}
SDL_SendMouseMotion(timestamp, window, SDL_TOUCH_MOUSEID, false, pos_x, pos_y);
}
}
}
}
}
// SDL_HINT_MOUSE_TOUCH_EVENTS: if not set, discard synthetic touch events coming from platform layer
if (mouse->mouse_touch_events == 0) {
if (id == SDL_MOUSE_TOUCHID) {
return;
}
}
finger = SDL_GetFinger(touch, fingerid);
if (!finger) {
SDL_SendTouch(timestamp, id, fingerid, window, SDL_EVENT_FINGER_DOWN, x, y, pressure);
return;
}
xrel = x - finger->x;
yrel = y - finger->y;
prel = pressure - finger->pressure;
// Drop events that don't change state
if (xrel == 0.0f && yrel == 0.0f && prel == 0.0f) {
#if 0
printf("Touch event didn't change state - dropped!\n");
#endif
return;
}
// Update internal touch coordinates
finger->x = x;
finger->y = y;
finger->pressure = pressure;
// Post the event, if desired
if (SDL_EventEnabled(SDL_EVENT_FINGER_MOTION)) {
SDL_Event event;
event.type = SDL_EVENT_FINGER_MOTION;
event.common.timestamp = timestamp;
event.tfinger.touchID = id;
event.tfinger.fingerID = fingerid;
event.tfinger.x = x;
event.tfinger.y = y;
event.tfinger.dx = xrel;
event.tfinger.dy = yrel;
event.tfinger.pressure = pressure;
event.tfinger.windowID = window ? SDL_GetWindowID(window) : 0;
SDL_PushEvent(&event);
}
}
void SDL_DelTouch(SDL_TouchID id)
{
int i, index;
SDL_Touch *touch;
if (SDL_num_touch == 0) {
// We've already cleaned up, we won't find this device
return;
}
index = SDL_GetTouchIndex(id);
touch = SDL_GetTouch(id);
if (!touch) {
return;
}
for (i = 0; i < touch->max_fingers; ++i) {
SDL_free(touch->fingers[i]);
}
SDL_free(touch->fingers);
SDL_free(touch->name);
SDL_free(touch);
SDL_num_touch--;
SDL_touchDevices[index] = SDL_touchDevices[SDL_num_touch];
}
void SDL_QuitTouch(void)
{
int i;
for (i = SDL_num_touch; i--;) {
SDL_DelTouch(SDL_touchDevices[i]->id);
}
SDL_assert(SDL_num_touch == 0);
SDL_free(SDL_touchDevices);
SDL_touchDevices = NULL;
}

View file

@ -0,0 +1,60 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_touch_c_h_
#define SDL_touch_c_h_
typedef struct SDL_Touch
{
SDL_TouchID id;
SDL_TouchDeviceType type;
int num_fingers;
int max_fingers;
SDL_Finger **fingers;
char *name;
} SDL_Touch;
// Initialize the touch subsystem
extern bool SDL_InitTouch(void);
// Returns true if _any_ connected touch devices are known to SDL
extern bool SDL_TouchDevicesAvailable(void);
// Add a touch, returning the index of the touch, or -1 if there was an error.
extern int SDL_AddTouch(SDL_TouchID id, SDL_TouchDeviceType type, const char *name);
// Get the touch with a given id
extern SDL_Touch *SDL_GetTouch(SDL_TouchID id);
// Send a touch down/up event for a touch
extern void SDL_SendTouch(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, SDL_EventType type, float x, float y, float pressure);
// Send a touch motion event for a touch
extern void SDL_SendTouchMotion(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, float x, float y, float pressure);
// Remove a touch
extern void SDL_DelTouch(SDL_TouchID id);
// Shutdown the touch subsystem
extern void SDL_QuitTouch(void);
#endif // SDL_touch_c_h_

View file

@ -0,0 +1,300 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
// Window event handling code for SDL
#include "SDL_events_c.h"
#include "SDL_eventwatch_c.h"
#include "SDL_mouse_c.h"
#include "../tray/SDL_tray_utils.h"
#define NUM_WINDOW_EVENT_WATCH_PRIORITIES (SDL_WINDOW_EVENT_WATCH_NORMAL + 1)
static SDL_EventWatchList SDL_window_event_watchers[NUM_WINDOW_EVENT_WATCH_PRIORITIES];
void SDL_InitWindowEventWatch(void)
{
for (int i = 0; i < SDL_arraysize(SDL_window_event_watchers); ++i) {
SDL_InitEventWatchList(&SDL_window_event_watchers[i]);
}
}
void SDL_QuitWindowEventWatch(void)
{
for (int i = 0; i < SDL_arraysize(SDL_window_event_watchers); ++i) {
SDL_QuitEventWatchList(&SDL_window_event_watchers[i]);
}
}
void SDL_AddWindowEventWatch(SDL_WindowEventWatchPriority priority, SDL_EventFilter filter, void *userdata)
{
SDL_AddEventWatchList(&SDL_window_event_watchers[priority], filter, userdata);
}
void SDL_RemoveWindowEventWatch(SDL_WindowEventWatchPriority priority, SDL_EventFilter filter, void *userdata)
{
SDL_RemoveEventWatchList(&SDL_window_event_watchers[priority], filter, userdata);
}
static bool SDLCALL RemoveSupercededWindowEvents(void *userdata, SDL_Event *event)
{
SDL_Event *new_event = (SDL_Event *)userdata;
if (event->type == new_event->type &&
event->window.windowID == new_event->window.windowID) {
// We're about to post a new move event, drop the old one
return false;
}
return true;
}
bool SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent, int data1, int data2)
{
bool posted = false;
if (!window) {
return false;
}
SDL_assert(SDL_ObjectValid(window, SDL_OBJECT_TYPE_WINDOW));
if (window->is_destroying && windowevent != SDL_EVENT_WINDOW_DESTROYED) {
return false;
}
switch (windowevent) {
case SDL_EVENT_WINDOW_SHOWN:
if (!(window->flags & SDL_WINDOW_HIDDEN)) {
return false;
}
window->flags &= ~(SDL_WINDOW_HIDDEN | SDL_WINDOW_MINIMIZED);
break;
case SDL_EVENT_WINDOW_HIDDEN:
if (window->flags & SDL_WINDOW_HIDDEN) {
return false;
}
window->flags |= SDL_WINDOW_HIDDEN;
break;
case SDL_EVENT_WINDOW_EXPOSED:
window->flags &= ~SDL_WINDOW_OCCLUDED;
break;
case SDL_EVENT_WINDOW_MOVED:
window->undefined_x = false;
window->undefined_y = false;
window->last_position_pending = false;
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
window->windowed.x = data1;
window->windowed.y = data2;
if (!(window->flags & SDL_WINDOW_MAXIMIZED) && !window->tiled) {
window->floating.x = data1;
window->floating.y = data2;
}
}
if (data1 == window->x && data2 == window->y) {
return false;
}
window->x = data1;
window->y = data2;
break;
case SDL_EVENT_WINDOW_RESIZED:
window->last_size_pending = false;
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
window->windowed.w = data1;
window->windowed.h = data2;
if (!(window->flags & SDL_WINDOW_MAXIMIZED) && !window->tiled) {
window->floating.w = data1;
window->floating.h = data2;
}
}
if (data1 == window->w && data2 == window->h) {
SDL_CheckWindowPixelSizeChanged(window);
return false;
}
window->w = data1;
window->h = data2;
break;
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
if (data1 == window->last_pixel_w && data2 == window->last_pixel_h) {
return false;
}
window->last_pixel_w = data1;
window->last_pixel_h = data2;
break;
case SDL_EVENT_WINDOW_MINIMIZED:
if (window->flags & SDL_WINDOW_MINIMIZED) {
return false;
}
window->flags &= ~SDL_WINDOW_MAXIMIZED;
window->flags |= SDL_WINDOW_MINIMIZED;
break;
case SDL_EVENT_WINDOW_MAXIMIZED:
if (window->flags & SDL_WINDOW_MAXIMIZED) {
return false;
}
window->flags &= ~SDL_WINDOW_MINIMIZED;
window->flags |= SDL_WINDOW_MAXIMIZED;
break;
case SDL_EVENT_WINDOW_RESTORED:
if (!(window->flags & (SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED))) {
return false;
}
window->flags &= ~(SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED);
break;
case SDL_EVENT_WINDOW_MOUSE_ENTER:
if (window->flags & SDL_WINDOW_MOUSE_FOCUS) {
return false;
}
window->flags |= SDL_WINDOW_MOUSE_FOCUS;
break;
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
if (!(window->flags & SDL_WINDOW_MOUSE_FOCUS)) {
return false;
}
window->flags &= ~SDL_WINDOW_MOUSE_FOCUS;
break;
case SDL_EVENT_WINDOW_FOCUS_GAINED:
if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
return false;
}
window->flags |= SDL_WINDOW_INPUT_FOCUS;
break;
case SDL_EVENT_WINDOW_FOCUS_LOST:
if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
return false;
}
window->flags &= ~SDL_WINDOW_INPUT_FOCUS;
break;
case SDL_EVENT_WINDOW_DISPLAY_CHANGED:
if (data1 == 0 || (SDL_DisplayID)data1 == window->last_displayID) {
return false;
}
window->last_displayID = (SDL_DisplayID)data1;
break;
case SDL_EVENT_WINDOW_OCCLUDED:
if (window->flags & SDL_WINDOW_OCCLUDED) {
return false;
}
window->flags |= SDL_WINDOW_OCCLUDED;
break;
case SDL_EVENT_WINDOW_ENTER_FULLSCREEN:
if (window->flags & SDL_WINDOW_FULLSCREEN) {
return false;
}
window->flags |= SDL_WINDOW_FULLSCREEN;
break;
case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN:
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
return false;
}
window->flags &= ~SDL_WINDOW_FULLSCREEN;
break;
default:
break;
}
// Post the event, if desired
SDL_Event event;
event.type = windowevent;
event.common.timestamp = 0;
event.window.data1 = data1;
event.window.data2 = data2;
event.window.windowID = window->id;
SDL_DispatchEventWatchList(&SDL_window_event_watchers[SDL_WINDOW_EVENT_WATCH_EARLY], &event);
SDL_DispatchEventWatchList(&SDL_window_event_watchers[SDL_WINDOW_EVENT_WATCH_NORMAL], &event);
if (SDL_EventEnabled(windowevent)) {
// Fixes queue overflow with move/resize events that aren't processed
if (windowevent == SDL_EVENT_WINDOW_MOVED ||
windowevent == SDL_EVENT_WINDOW_RESIZED ||
windowevent == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED ||
windowevent == SDL_EVENT_WINDOW_SAFE_AREA_CHANGED ||
windowevent == SDL_EVENT_WINDOW_EXPOSED ||
windowevent == SDL_EVENT_WINDOW_OCCLUDED) {
SDL_FilterEvents(RemoveSupercededWindowEvents, &event);
}
posted = SDL_PushEvent(&event);
}
switch (windowevent) {
case SDL_EVENT_WINDOW_SHOWN:
SDL_OnWindowShown(window);
break;
case SDL_EVENT_WINDOW_HIDDEN:
SDL_OnWindowHidden(window);
break;
case SDL_EVENT_WINDOW_MOVED:
SDL_OnWindowMoved(window);
break;
case SDL_EVENT_WINDOW_RESIZED:
SDL_OnWindowResized(window);
break;
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
SDL_OnWindowPixelSizeChanged(window);
break;
case SDL_EVENT_WINDOW_MINIMIZED:
SDL_OnWindowMinimized(window);
break;
case SDL_EVENT_WINDOW_MAXIMIZED:
SDL_OnWindowMaximized(window);
break;
case SDL_EVENT_WINDOW_RESTORED:
SDL_OnWindowRestored(window);
break;
case SDL_EVENT_WINDOW_MOUSE_ENTER:
SDL_OnWindowEnter(window);
break;
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
SDL_OnWindowLeave(window);
break;
case SDL_EVENT_WINDOW_FOCUS_GAINED:
SDL_OnWindowFocusGained(window);
break;
case SDL_EVENT_WINDOW_FOCUS_LOST:
SDL_OnWindowFocusLost(window);
break;
case SDL_EVENT_WINDOW_DISPLAY_CHANGED:
SDL_OnWindowDisplayChanged(window);
break;
default:
break;
}
if (windowevent == SDL_EVENT_WINDOW_CLOSE_REQUESTED && !window->parent && !SDL_HasActiveTrays()) {
int toplevel_count = 0;
SDL_Window *n;
for (n = SDL_GetVideoDevice()->windows; n; n = n->next) {
if (!n->parent && !(n->flags & SDL_WINDOW_HIDDEN)) {
++toplevel_count;
}
}
if (toplevel_count <= 1) {
if (SDL_GetHintBoolean(SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE, true)) {
SDL_SendQuit(); // This is the last toplevel window in the list so send the SDL_EVENT_QUIT event
}
}
}
return posted;
}

View file

@ -0,0 +1,39 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_windowevents_c_h_
#define SDL_windowevents_c_h_
typedef enum
{
SDL_WINDOW_EVENT_WATCH_EARLY,
SDL_WINDOW_EVENT_WATCH_NORMAL
} SDL_WindowEventWatchPriority;
extern void SDL_InitWindowEventWatch(void);
extern void SDL_QuitWindowEventWatch(void);
extern void SDL_AddWindowEventWatch(SDL_WindowEventWatchPriority priority, SDL_EventFilter filter, void *userdata);
extern void SDL_RemoveWindowEventWatch(SDL_WindowEventWatchPriority priority, SDL_EventFilter filter, void *userdata);
extern bool SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent, int data1, int data2);
#endif // SDL_windowevents_c_h_

View file

@ -0,0 +1,31 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* A default blank 8x8 cursor */
#define BLANK_CWIDTH 8
#define BLANK_CHEIGHT 8
#define BLANK_CHOTX 0
#define BLANK_CHOTY 0
static const unsigned char blank_cdata[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
static const unsigned char blank_cmask[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };

View file

@ -0,0 +1,113 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Default cursor - it happens to be the Mac cursor, but could be anything */
#define DEFAULT_CWIDTH 16
#define DEFAULT_CHEIGHT 16
#define DEFAULT_CHOTX 0
#define DEFAULT_CHOTY 0
// Added a real MacOS cursor, at the request of Luc-Olivier de Charrière
#define USE_MACOS_CURSOR
#ifdef USE_MACOS_CURSOR
static const unsigned char default_cdata[] = {
0x00, 0x00,
0x40, 0x00,
0x60, 0x00,
0x70, 0x00,
0x78, 0x00,
0x7C, 0x00,
0x7E, 0x00,
0x7F, 0x00,
0x7F, 0x80,
0x7C, 0x00,
0x6C, 0x00,
0x46, 0x00,
0x06, 0x00,
0x03, 0x00,
0x03, 0x00,
0x00, 0x00
};
static const unsigned char default_cmask[] = {
0xC0, 0x00,
0xE0, 0x00,
0xF0, 0x00,
0xF8, 0x00,
0xFC, 0x00,
0xFE, 0x00,
0xFF, 0x00,
0xFF, 0x80,
0xFF, 0xC0,
0xFF, 0xE0,
0xFE, 0x00,
0xEF, 0x00,
0xCF, 0x00,
0x87, 0x80,
0x07, 0x80,
0x03, 0x00
};
#else
static const unsigned char default_cdata[] = {
0x00, 0x00,
0x40, 0x00,
0x60, 0x00,
0x70, 0x00,
0x78, 0x00,
0x7C, 0x00,
0x7E, 0x00,
0x7F, 0x00,
0x7F, 0x80,
0x7C, 0x00,
0x6C, 0x00,
0x46, 0x00,
0x06, 0x00,
0x03, 0x00,
0x03, 0x00,
0x00, 0x00
};
static const unsigned char default_cmask[] = {
0x40, 0x00,
0xE0, 0x00,
0xF0, 0x00,
0xF8, 0x00,
0xFC, 0x00,
0xFE, 0x00,
0xFF, 0x00,
0xFF, 0x80,
0xFF, 0xC0,
0xFF, 0x80,
0xFE, 0x00,
0xEF, 0x00,
0x4F, 0x00,
0x07, 0x80,
0x07, 0x80,
0x03, 0x00
};
#endif // USE_MACOS_CURSOR

349
vendor/sdl-3.2.10/src/events/imKStoUCS.c vendored Normal file
View file

@ -0,0 +1,349 @@
/*
Copyright (C) 2003-2006,2008 Jamey Sharp, Josh Triplett
Copyright © 2009 Red Hat, Inc.
Copyright 1990-1992,1999,2000,2004,2009,2010 Oracle and/or its affiliates.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_DRIVER_X11) || defined(SDL_VIDEO_DRIVER_WAYLAND)
#include "imKStoUCS.h"
static unsigned short const keysym_to_unicode_1a1_1ff[] = {
0x0104, 0x02d8, 0x0141, 0x0000, 0x013d, 0x015a, 0x0000, /* 0x01a0-0x01a7 */
0x0000, 0x0160, 0x015e, 0x0164, 0x0179, 0x0000, 0x017d, 0x017b, /* 0x01a8-0x01af */
0x0000, 0x0105, 0x02db, 0x0142, 0x0000, 0x013e, 0x015b, 0x02c7, /* 0x01b0-0x01b7 */
0x0000, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, /* 0x01b8-0x01bf */
0x0154, 0x0000, 0x0000, 0x0102, 0x0000, 0x0139, 0x0106, 0x0000, /* 0x01c0-0x01c7 */
0x010c, 0x0000, 0x0118, 0x0000, 0x011a, 0x0000, 0x0000, 0x010e, /* 0x01c8-0x01cf */
0x0110, 0x0143, 0x0147, 0x0000, 0x0000, 0x0150, 0x0000, 0x0000, /* 0x01d0-0x01d7 */
0x0158, 0x016e, 0x0000, 0x0170, 0x0000, 0x0000, 0x0162, 0x0000, /* 0x01d8-0x01df */
0x0155, 0x0000, 0x0000, 0x0103, 0x0000, 0x013a, 0x0107, 0x0000, /* 0x01e0-0x01e7 */
0x010d, 0x0000, 0x0119, 0x0000, 0x011b, 0x0000, 0x0000, 0x010f, /* 0x01e8-0x01ef */
0x0111, 0x0144, 0x0148, 0x0000, 0x0000, 0x0151, 0x0000, 0x0000, /* 0x01f0-0x01f7 */
0x0159, 0x016f, 0x0000, 0x0171, 0x0000, 0x0000, 0x0163, 0x02d9 /* 0x01f8-0x01ff */
};
static unsigned short const keysym_to_unicode_2a1_2fe[] = {
0x0126, 0x0000, 0x0000, 0x0000, 0x0000, 0x0124, 0x0000, /* 0x02a0-0x02a7 */
0x0000, 0x0130, 0x0000, 0x011e, 0x0134, 0x0000, 0x0000, 0x0000, /* 0x02a8-0x02af */
0x0000, 0x0127, 0x0000, 0x0000, 0x0000, 0x0000, 0x0125, 0x0000, /* 0x02b0-0x02b7 */
0x0000, 0x0131, 0x0000, 0x011f, 0x0135, 0x0000, 0x0000, 0x0000, /* 0x02b8-0x02bf */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010a, 0x0108, 0x0000, /* 0x02c0-0x02c7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02c8-0x02cf */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0120, 0x0000, 0x0000, /* 0x02d0-0x02d7 */
0x011c, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x015c, 0x0000, /* 0x02d8-0x02df */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010b, 0x0109, 0x0000, /* 0x02e0-0x02e7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02e8-0x02ef */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0121, 0x0000, 0x0000, /* 0x02f0-0x02f7 */
0x011d, 0x0000, 0x0000, 0x0000, 0x0000, 0x016d, 0x015d /* 0x02f8-0x02ff */
};
static unsigned short const keysym_to_unicode_3a2_3fe[] = {
0x0138, 0x0156, 0x0000, 0x0128, 0x013b, 0x0000, /* 0x03a0-0x03a7 */
0x0000, 0x0000, 0x0112, 0x0122, 0x0166, 0x0000, 0x0000, 0x0000, /* 0x03a8-0x03af */
0x0000, 0x0000, 0x0000, 0x0157, 0x0000, 0x0129, 0x013c, 0x0000, /* 0x03b0-0x03b7 */
0x0000, 0x0000, 0x0113, 0x0123, 0x0167, 0x014a, 0x0000, 0x014b, /* 0x03b8-0x03bf */
0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012e, /* 0x03c0-0x03c7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0116, 0x0000, 0x0000, 0x012a, /* 0x03c8-0x03cf */
0x0000, 0x0145, 0x014c, 0x0136, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03d0-0x03d7 */
0x0000, 0x0172, 0x0000, 0x0000, 0x0000, 0x0168, 0x016a, 0x0000, /* 0x03d8-0x03df */
0x0101, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012f, /* 0x03e0-0x03e7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0117, 0x0000, 0x0000, 0x012b, /* 0x03e8-0x03ef */
0x0000, 0x0146, 0x014d, 0x0137, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03f0-0x03f7 */
0x0000, 0x0173, 0x0000, 0x0000, 0x0000, 0x0169, 0x016b /* 0x03f8-0x03ff */
};
static unsigned short const keysym_to_unicode_4a1_4df[] = {
0x3002, 0x3008, 0x3009, 0x3001, 0x30fb, 0x30f2, 0x30a1, /* 0x04a0-0x04a7 */
0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3, /* 0x04a8-0x04af */
0x30fc, 0x30a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, 0x30ab, 0x30ad, /* 0x04b0-0x04b7 */
0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, 0x30bd, /* 0x04b8-0x04bf */
0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc, /* 0x04c0-0x04c7 */
0x30cd, 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, /* 0x04c8-0x04cf */
0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, /* 0x04d0-0x04d7 */
0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f3, 0x309b, 0x309c /* 0x04d8-0x04df */
};
static unsigned short const keysym_to_unicode_590_5fe[] = {
0x06f0, 0x06f1, 0x06f2, 0x06f3, 0x06f4, 0x06f5, 0x06f6, 0x06f7, /* 0x0590-0x0597 */
0x06f8, 0x06f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x0598-0x059f */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x066a, 0x0670, 0x0679, /* 0x05a0-0x05a7 */
0x067e, 0x0686, 0x0688, 0x0691, 0x060c, 0x0000, 0x06d4, 0x0000, /* 0x05ac-0x05af */
0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, /* 0x05b0-0x05b7 */
0x0668, 0x0669, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f, /* 0x05b8-0x05bf */
0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, /* 0x05c0-0x05c7 */
0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, /* 0x05c8-0x05cf */
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, /* 0x05d0-0x05d7 */
0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x05d8-0x05df */
0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, /* 0x05e0-0x05e7 */
0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, /* 0x05e8-0x05ef */
0x0650, 0x0651, 0x0652, 0x0653, 0x0654, 0x0655, 0x0698, 0x06a4, /* 0x05f0-0x05f7 */
0x06a9, 0x06af, 0x06ba, 0x06be, 0x06cc, 0x06d2, 0x06c1 /* 0x05f8-0x05fe */
};
static unsigned short keysym_to_unicode_680_6ff[] = {
0x0492, 0x0496, 0x049a, 0x049c, 0x04a2, 0x04ae, 0x04b0, 0x04b2, /* 0x0680-0x0687 */
0x04b6, 0x04b8, 0x04ba, 0x0000, 0x04d8, 0x04e2, 0x04e8, 0x04ee, /* 0x0688-0x068f */
0x0493, 0x0497, 0x049b, 0x049d, 0x04a3, 0x04af, 0x04b1, 0x04b3, /* 0x0690-0x0697 */
0x04b7, 0x04b9, 0x04bb, 0x0000, 0x04d9, 0x04e3, 0x04e9, 0x04ef, /* 0x0698-0x069f */
0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, /* 0x06a0-0x06a7 */
0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0491, 0x045e, 0x045f, /* 0x06a8-0x06af */
0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, /* 0x06b0-0x06b7 */
0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0490, 0x040e, 0x040f, /* 0x06b8-0x06bf */
0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, /* 0x06c0-0x06c7 */
0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, /* 0x06c8-0x06cf */
0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, /* 0x06d0-0x06d7 */
0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, /* 0x06d8-0x06df */
0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, /* 0x06e0-0x06e7 */
0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, /* 0x06e8-0x06ef */
0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, /* 0x06f0-0x06f7 */
0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a /* 0x06f8-0x06ff */
};
static unsigned short const keysym_to_unicode_7a1_7f9[] = {
0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c, /* 0x07a0-0x07a7 */
0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015, /* 0x07a8-0x07af */
0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc, /* 0x07b0-0x07b7 */
0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07b8-0x07bf */
0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, /* 0x07c0-0x07c7 */
0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, /* 0x07c8-0x07cf */
0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7, /* 0x07d0-0x07d7 */
0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07d8-0x07df */
0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, /* 0x07e0-0x07e7 */
0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, /* 0x07e8-0x07ef */
0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7, /* 0x07f0-0x07f7 */
0x03c8, 0x03c9 /* 0x07f8-0x07ff */
};
static unsigned short const keysym_to_unicode_8a4_8fe[] = {
0x2320, 0x2321, 0x0000, 0x231c, /* 0x08a0-0x08a7 */
0x231d, 0x231e, 0x231f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08a8-0x08af */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08b0-0x08b7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222b, /* 0x08b8-0x08bf */
0x2234, 0x0000, 0x221e, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000, /* 0x08c0-0x08c7 */
0x2245, 0x2246, 0x0000, 0x0000, 0x0000, 0x0000, 0x21d2, 0x0000, /* 0x08c8-0x08cf */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221a, 0x0000, /* 0x08d0-0x08d7 */
0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222a, 0x2227, 0x2228, /* 0x08d8-0x08df */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e0-0x08e7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2202, /* 0x08e8-0x08ef */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000, /* 0x08f0-0x08f7 */
0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193 /* 0x08f8-0x08ff */
};
static unsigned short const keysym_to_unicode_9df_9f8[] = {
0x2422, /* 0x09d8-0x09df */
0x2666, 0x25a6, 0x2409, 0x240c, 0x240d, 0x240a, 0x0000, 0x0000, /* 0x09e0-0x09e7 */
0x240a, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x2500, /* 0x09e8-0x09ef */
0x0000, 0x0000, 0x0000, 0x0000, 0x251c, 0x2524, 0x2534, 0x252c, /* 0x09f0-0x09f7 */
0x2502 /* 0x09f8-0x09ff */
};
static unsigned short const keysym_to_unicode_aa1_afe[] = {
0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009, /* 0x0aa0-0x0aa7 */
0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025, /* 0x0aa8-0x0aaf */
0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, /* 0x0ab0-0x0ab7 */
0x2105, 0x0000, 0x0000, 0x2012, 0x2039, 0x2024, 0x203a, 0x0000, /* 0x0ab8-0x0abf */
0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000, /* 0x0ac0-0x0ac7 */
0x0000, 0x2122, 0x2120, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25ad, /* 0x0ac8-0x0acf */
0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x2030, 0x2032, 0x2033, /* 0x0ad0-0x0ad7 */
0x0000, 0x271d, 0x0000, 0x220e, 0x25c2, 0x2023, 0x25cf, 0x25ac, /* 0x0ad8-0x0adf */
0x25e6, 0x25ab, 0x25ae, 0x25b5, 0x25bf, 0x2606, 0x2022, 0x25aa, /* 0x0ae0-0x0ae7 */
0x25b4, 0x25be, 0x261a, 0x261b, 0x2663, 0x2666, 0x2665, 0x0000, /* 0x0ae8-0x0aef */
0x2720, 0x2020, 0x2021, 0x2713, 0x2612, 0x266f, 0x266d, 0x2642, /* 0x0af0-0x0af7 */
0x2640, 0x2121, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e /* 0x0af8-0x0aff */
};
/* none of the APL keysyms match the Unicode characters */
static unsigned short const keysym_to_unicode_cdf_cfa[] = {
0x2017, /* 0x0cd8-0x0cdf */
0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, /* 0x0ce0-0x0ce7 */
0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, /* 0x0ce8-0x0cef */
0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, /* 0x0cf0-0x0cf7 */
0x05e8, 0x05e9, 0x05ea /* 0x0cf8-0x0cff */
};
static unsigned short const keysym_to_unicode_da1_df9[] = {
0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, /* 0x0da0-0x0da7 */
0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, /* 0x0da8-0x0daf */
0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, /* 0x0db0-0x0db7 */
0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, /* 0x0db8-0x0dbf */
0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, /* 0x0dc0-0x0dc7 */
0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, /* 0x0dc8-0x0dcf */
0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, /* 0x0dd0-0x0dd7 */
0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0e3e, 0x0e3f, /* 0x0dd8-0x0ddf */
0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, /* 0x0de0-0x0de7 */
0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0000, 0x0000, /* 0x0de8-0x0def */
0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, /* 0x0df0-0x0df7 */
0x0e58, 0x0e59 /* 0x0df8-0x0dff */
};
static unsigned short const keysym_to_unicode_ea0_eff[] = {
0x0000, 0x1101, 0x1101, 0x11aa, 0x1102, 0x11ac, 0x11ad, 0x1103, /* 0x0ea0-0x0ea7 */
0x1104, 0x1105, 0x11b0, 0x11b1, 0x11b2, 0x11b3, 0x11b4, 0x11b5, /* 0x0ea8-0x0eaf */
0x11b6, 0x1106, 0x1107, 0x1108, 0x11b9, 0x1109, 0x110a, 0x110b, /* 0x0eb0-0x0eb7 */
0x110c, 0x110d, 0x110e, 0x110f, 0x1110, 0x1111, 0x1112, 0x1161, /* 0x0eb8-0x0ebf */
0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167, 0x1168, 0x1169, /* 0x0ec0-0x0ec7 */
0x116a, 0x116b, 0x116c, 0x116d, 0x116e, 0x116f, 0x1170, 0x1171, /* 0x0ec8-0x0ecf */
0x1172, 0x1173, 0x1174, 0x1175, 0x11a8, 0x11a9, 0x11aa, 0x11ab, /* 0x0ed0-0x0ed7 */
0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3, /* 0x0ed8-0x0edf */
0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb, /* 0x0ee0-0x0ee7 */
0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x0000, /* 0x0ee8-0x0eef */
0x0000, 0x0000, 0x1140, 0x0000, 0x0000, 0x1159, 0x119e, 0x0000, /* 0x0ef0-0x0ef7 */
0x11eb, 0x0000, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9, /* 0x0ef8-0x0eff */
};
static unsigned short keysym_to_unicode_12a1_12fe[] = {
0x1e02, 0x1e03, 0x0000, 0x0000, 0x0000, 0x1e0a, 0x0000, /* 0x12a0-0x12a7 */
0x1e80, 0x0000, 0x1e82, 0x1e0b, 0x1ef2, 0x0000, 0x0000, 0x0000, /* 0x12a8-0x12af */
0x1e1e, 0x1e1f, 0x0000, 0x0000, 0x1e40, 0x1e41, 0x0000, 0x1e56, /* 0x12b0-0x12b7 */
0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61, /* 0x12b8-0x12bf */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c0-0x12c7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c8-0x12cf */
0x0174, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6a, /* 0x12d0-0x12d7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0176, 0x0000, /* 0x12d8-0x12df */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e0-0x12e7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e8-0x12ef */
0x0175, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6b, /* 0x12f0-0x12f7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0177 /* 0x12f0-0x12ff */
};
static unsigned short const keysym_to_unicode_13bc_13be[] = {
0x0152, 0x0153, 0x0178 /* 0x13b8-0x13bf */
};
static unsigned short keysym_to_unicode_14a1_14ff[] = {
0x2741, 0x00a7, 0x0589, 0x0029, 0x0028, 0x00bb, 0x00ab, /* 0x14a0-0x14a7 */
0x2014, 0x002e, 0x055d, 0x002c, 0x2013, 0x058a, 0x2026, 0x055c, /* 0x14a8-0x14af */
0x055b, 0x055e, 0x0531, 0x0561, 0x0532, 0x0562, 0x0533, 0x0563, /* 0x14b0-0x14b7 */
0x0534, 0x0564, 0x0535, 0x0565, 0x0536, 0x0566, 0x0537, 0x0567, /* 0x14b8-0x14bf */
0x0538, 0x0568, 0x0539, 0x0569, 0x053a, 0x056a, 0x053b, 0x056b, /* 0x14c0-0x14c7 */
0x053c, 0x056c, 0x053d, 0x056d, 0x053e, 0x056e, 0x053f, 0x056f, /* 0x14c8-0x14cf */
0x0540, 0x0570, 0x0541, 0x0571, 0x0542, 0x0572, 0x0543, 0x0573, /* 0x14d0-0x14d7 */
0x0544, 0x0574, 0x0545, 0x0575, 0x0546, 0x0576, 0x0547, 0x0577, /* 0x14d8-0x14df */
0x0548, 0x0578, 0x0549, 0x0579, 0x054a, 0x057a, 0x054b, 0x057b, /* 0x14e0-0x14e7 */
0x054c, 0x057c, 0x054d, 0x057d, 0x054e, 0x057e, 0x054f, 0x057f, /* 0x14e8-0x14ef */
0x0550, 0x0580, 0x0551, 0x0581, 0x0552, 0x0582, 0x0553, 0x0583, /* 0x14f0-0x14f7 */
0x0554, 0x0584, 0x0555, 0x0585, 0x0556, 0x0586, 0x2019, 0x0027, /* 0x14f8-0x14ff */
};
static unsigned short keysym_to_unicode_15d0_15f6[] = {
0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7, /* 0x15d0-0x15d7 */
0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df, /* 0x15d8-0x15df */
0x10e0, 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7, /* 0x15e0-0x15e7 */
0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef, /* 0x15e8-0x15ef */
0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6 /* 0x15f0-0x15f7 */
};
static unsigned short keysym_to_unicode_16a0_16f6[] = {
0x0000, 0x0000, 0xf0a2, 0x1e8a, 0x0000, 0xf0a5, 0x012c, 0xf0a7, /* 0x16a0-0x16a7 */
0xf0a8, 0x01b5, 0x01e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x019f, /* 0x16a8-0x16af */
0x0000, 0x0000, 0xf0b2, 0x1e8b, 0x01d1, 0xf0b5, 0x012d, 0xf0b7, /* 0x16b0-0x16b7 */
0xf0b8, 0x01b6, 0x01e7, 0x0000, 0x0000, 0x01d2, 0x0000, 0x0275, /* 0x16b8-0x16bf */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x018f, 0x0000, /* 0x16c0-0x16c7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16c8-0x16cf */
0x0000, 0x1e36, 0xf0d2, 0xf0d3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d0-0x16d7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d8-0x16df */
0x0000, 0x1e37, 0xf0e2, 0xf0e3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e0-0x16e7 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e8-0x16ef */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0259 /* 0x16f0-0x16f6 */
};
static unsigned short const keysym_to_unicode_1e9f_1eff[] = {
0x0303,
0x1ea0, 0x1ea1, 0x1ea2, 0x1ea3, 0x1ea4, 0x1ea5, 0x1ea6, 0x1ea7, /* 0x1ea0-0x1ea7 */
0x1ea8, 0x1ea9, 0x1eaa, 0x1eab, 0x1eac, 0x1ead, 0x1eae, 0x1eaf, /* 0x1ea8-0x1eaf */
0x1eb0, 0x1eb1, 0x1eb2, 0x1eb3, 0x1eb4, 0x1eb5, 0x1eb6, 0x1eb7, /* 0x1eb0-0x1eb7 */
0x1eb8, 0x1eb9, 0x1eba, 0x1ebb, 0x1ebc, 0x1ebd, 0x1ebe, 0x1ebf, /* 0x1eb8-0x1ebf */
0x1ec0, 0x1ec1, 0x1ec2, 0x1ec3, 0x1ec4, 0x1ec5, 0x1ec6, 0x1ec7, /* 0x1ec0-0x1ec7 */
0x1ec8, 0x1ec9, 0x1eca, 0x1ecb, 0x1ecc, 0x1ecd, 0x1ece, 0x1ecf, /* 0x1ec8-0x1ecf */
0x1ed0, 0x1ed1, 0x1ed2, 0x1ed3, 0x1ed4, 0x1ed5, 0x1ed6, 0x1ed7, /* 0x1ed0-0x1ed7 */
0x1ed8, 0x1ed9, 0x1eda, 0x1edb, 0x1edc, 0x1edd, 0x1ede, 0x1edf, /* 0x1ed8-0x1edf */
0x1ee0, 0x1ee1, 0x1ee2, 0x1ee3, 0x1ee4, 0x1ee5, 0x1ee6, 0x1ee7, /* 0x1ee0-0x1ee7 */
0x1ee8, 0x1ee9, 0x1eea, 0x1eeb, 0x1eec, 0x1eed, 0x1eee, 0x1eef, /* 0x1ee8-0x1eef */
0x1ef0, 0x1ef1, 0x0300, 0x0301, 0x1ef4, 0x1ef5, 0x1ef6, 0x1ef7, /* 0x1ef0-0x1ef7 */
0x1ef8, 0x1ef9, 0x01a0, 0x01a1, 0x01af, 0x01b0, 0x0309, 0x0323 /* 0x1ef8-0x1eff */
};
static unsigned short const keysym_to_unicode_20a0_20ac[] = {
0x20a0, 0x20a1, 0x20a2, 0x20a3, 0x20a4, 0x20a5, 0x20a6, 0x20a7, /* 0x20a0-0x20a7 */
0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac /* 0x20a8-0x20af */
};
unsigned int
SDL_KeySymToUcs4(Uint32 keysym)
{
/* 'Unicode keysym' */
if ((keysym & 0xff000000) == 0x01000000)
return (keysym & 0x00ffffff);
if (keysym > 0 && keysym < 0x100)
return keysym;
else if (keysym > 0x1a0 && keysym < 0x200)
return keysym_to_unicode_1a1_1ff[keysym - 0x1a1];
else if (keysym > 0x2a0 && keysym < 0x2ff)
return keysym_to_unicode_2a1_2fe[keysym - 0x2a1];
else if (keysym > 0x3a1 && keysym < 0x3ff)
return keysym_to_unicode_3a2_3fe[keysym - 0x3a2];
else if (keysym > 0x4a0 && keysym < 0x4e0)
return keysym_to_unicode_4a1_4df[keysym - 0x4a1];
else if (keysym > 0x589 && keysym < 0x5ff)
return keysym_to_unicode_590_5fe[keysym - 0x590];
else if (keysym > 0x67f && keysym < 0x700)
return keysym_to_unicode_680_6ff[keysym - 0x680];
else if (keysym > 0x7a0 && keysym < 0x7fa)
return keysym_to_unicode_7a1_7f9[keysym - 0x7a1];
else if (keysym > 0x8a3 && keysym < 0x8ff)
return keysym_to_unicode_8a4_8fe[keysym - 0x8a4];
else if (keysym > 0x9de && keysym < 0x9f9)
return keysym_to_unicode_9df_9f8[keysym - 0x9df];
else if (keysym > 0xaa0 && keysym < 0xaff)
return keysym_to_unicode_aa1_afe[keysym - 0xaa1];
else if (keysym > 0xcde && keysym < 0xcfb)
return keysym_to_unicode_cdf_cfa[keysym - 0xcdf];
else if (keysym > 0xda0 && keysym < 0xdfa)
return keysym_to_unicode_da1_df9[keysym - 0xda1];
else if (keysym > 0xe9f && keysym < 0xf00)
return keysym_to_unicode_ea0_eff[keysym - 0xea0];
else if (keysym > 0x12a0 && keysym < 0x12ff)
return keysym_to_unicode_12a1_12fe[keysym - 0x12a1];
else if (keysym > 0x13bb && keysym < 0x13bf)
return keysym_to_unicode_13bc_13be[keysym - 0x13bc];
else if (keysym > 0x14a0 && keysym < 0x1500)
return keysym_to_unicode_14a1_14ff[keysym - 0x14a1];
else if (keysym > 0x15cf && keysym < 0x15f7)
return keysym_to_unicode_15d0_15f6[keysym - 0x15d0];
else if (keysym > 0x169f && keysym < 0x16f7)
return keysym_to_unicode_16a0_16f6[keysym - 0x16a0];
else if (keysym > 0x1e9e && keysym < 0x1f00)
return keysym_to_unicode_1e9f_1eff[keysym - 0x1e9f];
else if (keysym > 0x209f && keysym < 0x20ad)
return keysym_to_unicode_20a0_20ac[keysym - 0x20a0];
else
return 0;
}
#endif /* SDL_VIDEO_DRIVER_X11 */

View file

@ -0,0 +1,32 @@
#ifndef _imKStoUCS_h
#define _imKStoUCS_h
/*
Copyright (C) 2003-2006,2008 Jamey Sharp, Josh Triplett
Copyright © 2009 Red Hat, Inc.
Copyright 1990-1992,1999,2000,2004,2009,2010 Oracle and/or its affiliates.
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
extern unsigned int SDL_KeySymToUcs4(Uint32 keysym);
#endif /* _imKStoUCS_h */

View file

@ -0,0 +1,159 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* Mac virtual key code to SDL scancode mapping table
Sources:
- Inside Macintosh: Text <http://developer.apple.com/documentation/mac/Text/Text-571.html>
- Apple USB keyboard driver source <http://darwinsource.opendarwin.org/10.4.6.ppc/IOHIDFamily-172.8/IOHIDFamily/Cosmo_USB2ADB.c>
- experimentation on various ADB and USB ISO keyboards and one ADB ANSI keyboard
*/
/* *INDENT-OFF* */ // clang-format off
static const SDL_Scancode darwin_scancode_table[] = {
/* 0 */ SDL_SCANCODE_A,
/* 1 */ SDL_SCANCODE_S,
/* 2 */ SDL_SCANCODE_D,
/* 3 */ SDL_SCANCODE_F,
/* 4 */ SDL_SCANCODE_H,
/* 5 */ SDL_SCANCODE_G,
/* 6 */ SDL_SCANCODE_Z,
/* 7 */ SDL_SCANCODE_X,
/* 8 */ SDL_SCANCODE_C,
/* 9 */ SDL_SCANCODE_V,
/* 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.)
/* 11 */ SDL_SCANCODE_B,
/* 12 */ SDL_SCANCODE_Q,
/* 13 */ SDL_SCANCODE_W,
/* 14 */ SDL_SCANCODE_E,
/* 15 */ SDL_SCANCODE_R,
/* 16 */ SDL_SCANCODE_Y,
/* 17 */ SDL_SCANCODE_T,
/* 18 */ SDL_SCANCODE_1,
/* 19 */ SDL_SCANCODE_2,
/* 20 */ SDL_SCANCODE_3,
/* 21 */ SDL_SCANCODE_4,
/* 22 */ SDL_SCANCODE_6,
/* 23 */ SDL_SCANCODE_5,
/* 24 */ SDL_SCANCODE_EQUALS,
/* 25 */ SDL_SCANCODE_9,
/* 26 */ SDL_SCANCODE_7,
/* 27 */ SDL_SCANCODE_MINUS,
/* 28 */ SDL_SCANCODE_8,
/* 29 */ SDL_SCANCODE_0,
/* 30 */ SDL_SCANCODE_RIGHTBRACKET,
/* 31 */ SDL_SCANCODE_O,
/* 32 */ SDL_SCANCODE_U,
/* 33 */ SDL_SCANCODE_LEFTBRACKET,
/* 34 */ SDL_SCANCODE_I,
/* 35 */ SDL_SCANCODE_P,
/* 36 */ SDL_SCANCODE_RETURN,
/* 37 */ SDL_SCANCODE_L,
/* 38 */ SDL_SCANCODE_J,
/* 39 */ SDL_SCANCODE_APOSTROPHE,
/* 40 */ SDL_SCANCODE_K,
/* 41 */ SDL_SCANCODE_SEMICOLON,
/* 42 */ SDL_SCANCODE_BACKSLASH,
/* 43 */ SDL_SCANCODE_COMMA,
/* 44 */ SDL_SCANCODE_SLASH,
/* 45 */ SDL_SCANCODE_N,
/* 46 */ SDL_SCANCODE_M,
/* 47 */ SDL_SCANCODE_PERIOD,
/* 48 */ SDL_SCANCODE_TAB,
/* 49 */ SDL_SCANCODE_SPACE,
/* 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)
/* 51 */ SDL_SCANCODE_BACKSPACE,
/* 52 */ SDL_SCANCODE_KP_ENTER, // keyboard enter on portables
/* 53 */ SDL_SCANCODE_ESCAPE,
/* 54 */ SDL_SCANCODE_RGUI,
/* 55 */ SDL_SCANCODE_LGUI,
/* 56 */ SDL_SCANCODE_LSHIFT,
/* 57 */ SDL_SCANCODE_CAPSLOCK,
/* 58 */ SDL_SCANCODE_LALT,
/* 59 */ SDL_SCANCODE_LCTRL,
/* 60 */ SDL_SCANCODE_RSHIFT,
/* 61 */ SDL_SCANCODE_RALT,
/* 62 */ SDL_SCANCODE_RCTRL,
/* 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
/* 64 */ SDL_SCANCODE_F17,
/* 65 */ SDL_SCANCODE_KP_PERIOD,
/* 66 */ SDL_SCANCODE_UNKNOWN, // unknown (unused?)
/* 67 */ SDL_SCANCODE_KP_MULTIPLY,
/* 68 */ SDL_SCANCODE_UNKNOWN, // unknown (unused?)
/* 69 */ SDL_SCANCODE_KP_PLUS,
/* 70 */ SDL_SCANCODE_UNKNOWN, // unknown (unused?)
/* 71 */ SDL_SCANCODE_NUMLOCKCLEAR,
/* 72 */ SDL_SCANCODE_VOLUMEUP,
/* 73 */ SDL_SCANCODE_VOLUMEDOWN,
/* 74 */ SDL_SCANCODE_MUTE,
/* 75 */ SDL_SCANCODE_KP_DIVIDE,
/* 76 */ SDL_SCANCODE_KP_ENTER, // keypad enter on external keyboards, fn-return on portables
/* 77 */ SDL_SCANCODE_UNKNOWN, // unknown (unused?)
/* 78 */ SDL_SCANCODE_KP_MINUS,
/* 79 */ SDL_SCANCODE_F18,
/* 80 */ SDL_SCANCODE_F19,
/* 81 */ SDL_SCANCODE_KP_EQUALS,
/* 82 */ SDL_SCANCODE_KP_0,
/* 83 */ SDL_SCANCODE_KP_1,
/* 84 */ SDL_SCANCODE_KP_2,
/* 85 */ SDL_SCANCODE_KP_3,
/* 86 */ SDL_SCANCODE_KP_4,
/* 87 */ SDL_SCANCODE_KP_5,
/* 88 */ SDL_SCANCODE_KP_6,
/* 89 */ SDL_SCANCODE_KP_7,
/* 90 */ SDL_SCANCODE_UNKNOWN, // unknown (unused?)
/* 91 */ SDL_SCANCODE_KP_8,
/* 92 */ SDL_SCANCODE_KP_9,
/* 93 */ SDL_SCANCODE_INTERNATIONAL3, // Cosmo_USB2ADB.c says "Yen (JIS)"
/* 94 */ SDL_SCANCODE_INTERNATIONAL1, // Cosmo_USB2ADB.c says "Ro (JIS)"
/* 95 */ SDL_SCANCODE_KP_COMMA, // Cosmo_USB2ADB.c says ", JIS only"
/* 96 */ SDL_SCANCODE_F5,
/* 97 */ SDL_SCANCODE_F6,
/* 98 */ SDL_SCANCODE_F7,
/* 99 */ SDL_SCANCODE_F3,
/* 100 */ SDL_SCANCODE_F8,
/* 101 */ SDL_SCANCODE_F9,
/* 102 */ SDL_SCANCODE_LANG2, // Cosmo_USB2ADB.c says "Eisu"
/* 103 */ SDL_SCANCODE_F11,
/* 104 */ SDL_SCANCODE_LANG1, // Cosmo_USB2ADB.c says "Kana"
/* 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.
/* 106 */ SDL_SCANCODE_F16,
/* 107 */ SDL_SCANCODE_SCROLLLOCK, // F14/scroll lock, see comment about F13/print screen above
/* 108 */ SDL_SCANCODE_UNKNOWN, // unknown (unused?)
/* 109 */ SDL_SCANCODE_F10,
/* 110 */ SDL_SCANCODE_APPLICATION, // windows contextual menu key, fn-enter on portables
/* 111 */ SDL_SCANCODE_F12,
/* 112 */ SDL_SCANCODE_UNKNOWN, // unknown (unused?)
/* 113 */ SDL_SCANCODE_PAUSE, // F15/pause, see comment about F13/print screen above
/* 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
/* 115 */ SDL_SCANCODE_HOME,
/* 116 */ SDL_SCANCODE_PAGEUP,
/* 117 */ SDL_SCANCODE_DELETE,
/* 118 */ SDL_SCANCODE_F4,
/* 119 */ SDL_SCANCODE_END,
/* 120 */ SDL_SCANCODE_F2,
/* 121 */ SDL_SCANCODE_PAGEDOWN,
/* 122 */ SDL_SCANCODE_F1,
/* 123 */ SDL_SCANCODE_LEFT,
/* 124 */ SDL_SCANCODE_RIGHT,
/* 125 */ SDL_SCANCODE_DOWN,
/* 126 */ SDL_SCANCODE_UP,
/* 127 */ SDL_SCANCODE_POWER
};
/* *INDENT-ON* */ // clang-format on

View file

@ -0,0 +1,848 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
/* Linux virtual key code to SDL_Keycode mapping table
Sources:
- Linux kernel source input.h
*/
/* *INDENT-OFF* */ // clang-format off
static SDL_Scancode const linux_scancode_table[] = {
/* 0, 0x000 */ SDL_SCANCODE_UNKNOWN, // KEY_RESERVED
/* 1, 0x001 */ SDL_SCANCODE_ESCAPE, // KEY_ESC
/* 2, 0x002 */ SDL_SCANCODE_1, // KEY_1
/* 3, 0x003 */ SDL_SCANCODE_2, // KEY_2
/* 4, 0x004 */ SDL_SCANCODE_3, // KEY_3
/* 5, 0x005 */ SDL_SCANCODE_4, // KEY_4
/* 6, 0x006 */ SDL_SCANCODE_5, // KEY_5
/* 7, 0x007 */ SDL_SCANCODE_6, // KEY_6
/* 8, 0x008 */ SDL_SCANCODE_7, // KEY_7
/* 9, 0x009 */ SDL_SCANCODE_8, // KEY_8
/* 10, 0x00a */ SDL_SCANCODE_9, // KEY_9
/* 11, 0x00b */ SDL_SCANCODE_0, // KEY_0
/* 12, 0x00c */ SDL_SCANCODE_MINUS, // KEY_MINUS
/* 13, 0x00d */ SDL_SCANCODE_EQUALS, // KEY_EQUAL
/* 14, 0x00e */ SDL_SCANCODE_BACKSPACE, // KEY_BACKSPACE
/* 15, 0x00f */ SDL_SCANCODE_TAB, // KEY_TAB
/* 16, 0x010 */ SDL_SCANCODE_Q, // KEY_Q
/* 17, 0x011 */ SDL_SCANCODE_W, // KEY_W
/* 18, 0x012 */ SDL_SCANCODE_E, // KEY_E
/* 19, 0x013 */ SDL_SCANCODE_R, // KEY_R
/* 20, 0x014 */ SDL_SCANCODE_T, // KEY_T
/* 21, 0x015 */ SDL_SCANCODE_Y, // KEY_Y
/* 22, 0x016 */ SDL_SCANCODE_U, // KEY_U
/* 23, 0x017 */ SDL_SCANCODE_I, // KEY_I
/* 24, 0x018 */ SDL_SCANCODE_O, // KEY_O
/* 25, 0x019 */ SDL_SCANCODE_P, // KEY_P
/* 26, 0x01a */ SDL_SCANCODE_LEFTBRACKET, // KEY_LEFTBRACE
/* 27, 0x01b */ SDL_SCANCODE_RIGHTBRACKET, // KEY_RIGHTBRACE
/* 28, 0x01c */ SDL_SCANCODE_RETURN, // KEY_ENTER
/* 29, 0x01d */ SDL_SCANCODE_LCTRL, // KEY_LEFTCTRL
/* 30, 0x01e */ SDL_SCANCODE_A, // KEY_A
/* 31, 0x01f */ SDL_SCANCODE_S, // KEY_S
/* 32, 0x020 */ SDL_SCANCODE_D, // KEY_D
/* 33, 0x021 */ SDL_SCANCODE_F, // KEY_F
/* 34, 0x022 */ SDL_SCANCODE_G, // KEY_G
/* 35, 0x023 */ SDL_SCANCODE_H, // KEY_H
/* 36, 0x024 */ SDL_SCANCODE_J, // KEY_J
/* 37, 0x025 */ SDL_SCANCODE_K, // KEY_K
/* 38, 0x026 */ SDL_SCANCODE_L, // KEY_L
/* 39, 0x027 */ SDL_SCANCODE_SEMICOLON, // KEY_SEMICOLON
/* 40, 0x028 */ SDL_SCANCODE_APOSTROPHE, // KEY_APOSTROPHE
/* 41, 0x029 */ SDL_SCANCODE_GRAVE, // KEY_GRAVE
/* 42, 0x02a */ SDL_SCANCODE_LSHIFT, // KEY_LEFTSHIFT
/* 43, 0x02b */ SDL_SCANCODE_BACKSLASH, // KEY_BACKSLASH
/* 44, 0x02c */ SDL_SCANCODE_Z, // KEY_Z
/* 45, 0x02d */ SDL_SCANCODE_X, // KEY_X
/* 46, 0x02e */ SDL_SCANCODE_C, // KEY_C
/* 47, 0x02f */ SDL_SCANCODE_V, // KEY_V
/* 48, 0x030 */ SDL_SCANCODE_B, // KEY_B
/* 49, 0x031 */ SDL_SCANCODE_N, // KEY_N
/* 50, 0x032 */ SDL_SCANCODE_M, // KEY_M
/* 51, 0x033 */ SDL_SCANCODE_COMMA, // KEY_COMMA
/* 52, 0x034 */ SDL_SCANCODE_PERIOD, // KEY_DOT
/* 53, 0x035 */ SDL_SCANCODE_SLASH, // KEY_SLASH
/* 54, 0x036 */ SDL_SCANCODE_RSHIFT, // KEY_RIGHTSHIFT
/* 55, 0x037 */ SDL_SCANCODE_KP_MULTIPLY, // KEY_KPASTERISK
/* 56, 0x038 */ SDL_SCANCODE_LALT, // KEY_LEFTALT
/* 57, 0x039 */ SDL_SCANCODE_SPACE, // KEY_SPACE
/* 58, 0x03a */ SDL_SCANCODE_CAPSLOCK, // KEY_CAPSLOCK
/* 59, 0x03b */ SDL_SCANCODE_F1, // KEY_F1
/* 60, 0x03c */ SDL_SCANCODE_F2, // KEY_F2
/* 61, 0x03d */ SDL_SCANCODE_F3, // KEY_F3
/* 62, 0x03e */ SDL_SCANCODE_F4, // KEY_F4
/* 63, 0x03f */ SDL_SCANCODE_F5, // KEY_F5
/* 64, 0x040 */ SDL_SCANCODE_F6, // KEY_F6
/* 65, 0x041 */ SDL_SCANCODE_F7, // KEY_F7
/* 66, 0x042 */ SDL_SCANCODE_F8, // KEY_F8
/* 67, 0x043 */ SDL_SCANCODE_F9, // KEY_F9
/* 68, 0x044 */ SDL_SCANCODE_F10, // KEY_F10
/* 69, 0x045 */ SDL_SCANCODE_NUMLOCKCLEAR, // KEY_NUMLOCK
/* 70, 0x046 */ SDL_SCANCODE_SCROLLLOCK, // KEY_SCROLLLOCK
/* 71, 0x047 */ SDL_SCANCODE_KP_7, // KEY_KP7
/* 72, 0x048 */ SDL_SCANCODE_KP_8, // KEY_KP8
/* 73, 0x049 */ SDL_SCANCODE_KP_9, // KEY_KP9
/* 74, 0x04a */ SDL_SCANCODE_KP_MINUS, // KEY_KPMINUS
/* 75, 0x04b */ SDL_SCANCODE_KP_4, // KEY_KP4
/* 76, 0x04c */ SDL_SCANCODE_KP_5, // KEY_KP5
/* 77, 0x04d */ SDL_SCANCODE_KP_6, // KEY_KP6
/* 78, 0x04e */ SDL_SCANCODE_KP_PLUS, // KEY_KPPLUS
/* 79, 0x04f */ SDL_SCANCODE_KP_1, // KEY_KP1
/* 80, 0x050 */ SDL_SCANCODE_KP_2, // KEY_KP2
/* 81, 0x051 */ SDL_SCANCODE_KP_3, // KEY_KP3
/* 82, 0x052 */ SDL_SCANCODE_KP_0, // KEY_KP0
/* 83, 0x053 */ SDL_SCANCODE_KP_PERIOD, // KEY_KPDOT
/* 84, 0x054 */ SDL_SCANCODE_UNKNOWN,
/* 85, 0x055 */ SDL_SCANCODE_LANG5, // KEY_ZENKAKUHANKAKU
/* 86, 0x056 */ SDL_SCANCODE_NONUSBACKSLASH, // KEY_102ND
/* 87, 0x057 */ SDL_SCANCODE_F11, // KEY_F11
/* 88, 0x058 */ SDL_SCANCODE_F12, // KEY_F12
/* 89, 0x059 */ SDL_SCANCODE_INTERNATIONAL1, // KEY_RO
/* 90, 0x05a */ SDL_SCANCODE_LANG3, // KEY_KATAKANA
/* 91, 0x05b */ SDL_SCANCODE_LANG4, // KEY_HIRAGANA
/* 92, 0x05c */ SDL_SCANCODE_INTERNATIONAL4, // KEY_HENKAN
/* 93, 0x05d */ SDL_SCANCODE_INTERNATIONAL2, // KEY_KATAKANAHIRAGANA
/* 94, 0x05e */ SDL_SCANCODE_INTERNATIONAL5, // KEY_MUHENKAN
/* 95, 0x05f */ SDL_SCANCODE_INTERNATIONAL5, // KEY_KPJPCOMMA
/* 96, 0x060 */ SDL_SCANCODE_KP_ENTER, // KEY_KPENTER
/* 97, 0x061 */ SDL_SCANCODE_RCTRL, // KEY_RIGHTCTRL
/* 98, 0x062 */ SDL_SCANCODE_KP_DIVIDE, // KEY_KPSLASH
/* 99, 0x063 */ SDL_SCANCODE_SYSREQ, // KEY_SYSRQ
/* 100, 0x064 */ SDL_SCANCODE_RALT, // KEY_RIGHTALT
/* 101, 0x065 */ SDL_SCANCODE_UNKNOWN, // KEY_LINEFEED
/* 102, 0x066 */ SDL_SCANCODE_HOME, // KEY_HOME
/* 103, 0x067 */ SDL_SCANCODE_UP, // KEY_UP
/* 104, 0x068 */ SDL_SCANCODE_PAGEUP, // KEY_PAGEUP
/* 105, 0x069 */ SDL_SCANCODE_LEFT, // KEY_LEFT
/* 106, 0x06a */ SDL_SCANCODE_RIGHT, // KEY_RIGHT
/* 107, 0x06b */ SDL_SCANCODE_END, // KEY_END
/* 108, 0x06c */ SDL_SCANCODE_DOWN, // KEY_DOWN
/* 109, 0x06d */ SDL_SCANCODE_PAGEDOWN, // KEY_PAGEDOWN
/* 110, 0x06e */ SDL_SCANCODE_INSERT, // KEY_INSERT
/* 111, 0x06f */ SDL_SCANCODE_DELETE, // KEY_DELETE
/* 112, 0x070 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO
/* 113, 0x071 */ SDL_SCANCODE_MUTE, // KEY_MUTE
/* 114, 0x072 */ SDL_SCANCODE_VOLUMEDOWN, // KEY_VOLUMEDOWN
/* 115, 0x073 */ SDL_SCANCODE_VOLUMEUP, // KEY_VOLUMEUP
/* 116, 0x074 */ SDL_SCANCODE_POWER, // KEY_POWER
/* 117, 0x075 */ SDL_SCANCODE_KP_EQUALS, // KEY_KPEQUAL
/* 118, 0x076 */ SDL_SCANCODE_KP_PLUSMINUS, // KEY_KPPLUSMINUS
/* 119, 0x077 */ SDL_SCANCODE_PAUSE, // KEY_PAUSE
/* 120, 0x078 */ SDL_SCANCODE_UNKNOWN, // KEY_SCALE
/* 121, 0x079 */ SDL_SCANCODE_KP_COMMA, // KEY_KPCOMMA
/* 122, 0x07a */ SDL_SCANCODE_LANG1, // KEY_HANGEUL
/* 123, 0x07b */ SDL_SCANCODE_LANG2, // KEY_HANJA
/* 124, 0x07c */ SDL_SCANCODE_INTERNATIONAL3, // KEY_YEN
/* 125, 0x07d */ SDL_SCANCODE_LGUI, // KEY_LEFTMETA
/* 126, 0x07e */ SDL_SCANCODE_RGUI, // KEY_RIGHTMETA
/* 127, 0x07f */ SDL_SCANCODE_APPLICATION, // KEY_COMPOSE
/* 128, 0x080 */ SDL_SCANCODE_STOP, // KEY_STOP
/* 129, 0x081 */ SDL_SCANCODE_AGAIN, // KEY_AGAIN
/* 130, 0x082 */ SDL_SCANCODE_AC_PROPERTIES, // KEY_PROPS
/* 131, 0x083 */ SDL_SCANCODE_UNDO, // KEY_UNDO
/* 132, 0x084 */ SDL_SCANCODE_UNKNOWN, // KEY_FRONT
/* 133, 0x085 */ SDL_SCANCODE_COPY, // KEY_COPY
/* 134, 0x086 */ SDL_SCANCODE_AC_OPEN, // KEY_OPEN
/* 135, 0x087 */ SDL_SCANCODE_PASTE, // KEY_PASTE
/* 136, 0x088 */ SDL_SCANCODE_FIND, // KEY_FIND
/* 137, 0x089 */ SDL_SCANCODE_CUT, // KEY_CUT
/* 138, 0x08a */ SDL_SCANCODE_HELP, // KEY_HELP
/* 139, 0x08b */ SDL_SCANCODE_MENU, // KEY_MENU
/* 140, 0x08c */ SDL_SCANCODE_UNKNOWN, // KEY_CALC
/* 141, 0x08d */ SDL_SCANCODE_UNKNOWN, // KEY_SETUP
/* 142, 0x08e */ SDL_SCANCODE_SLEEP, // KEY_SLEEP
/* 143, 0x08f */ SDL_SCANCODE_WAKE, // KEY_WAKEUP
/* 144, 0x090 */ SDL_SCANCODE_UNKNOWN, // KEY_FILE
/* 145, 0x091 */ SDL_SCANCODE_UNKNOWN, // KEY_SENDFILE
/* 146, 0x092 */ SDL_SCANCODE_UNKNOWN, // KEY_DELETEFILE
/* 147, 0x093 */ SDL_SCANCODE_UNKNOWN, // KEY_XFER
/* 148, 0x094 */ SDL_SCANCODE_UNKNOWN, // KEY_PROG1
/* 149, 0x095 */ SDL_SCANCODE_UNKNOWN, // KEY_PROG2
/* 150, 0x096 */ SDL_SCANCODE_UNKNOWN, // KEY_WWW
/* 151, 0x097 */ SDL_SCANCODE_UNKNOWN, // KEY_MSDOS
/* 152, 0x098 */ SDL_SCANCODE_UNKNOWN, // KEY_COFFEE
/* 153, 0x099 */ SDL_SCANCODE_UNKNOWN, // KEY_ROTATE_DISPLAY
/* 154, 0x09a */ SDL_SCANCODE_UNKNOWN, // KEY_CYCLEWINDOWS
/* 155, 0x09b */ SDL_SCANCODE_UNKNOWN, // KEY_MAIL
/* 156, 0x09c */ SDL_SCANCODE_AC_BOOKMARKS, // KEY_BOOKMARKS
/* 157, 0x09d */ SDL_SCANCODE_UNKNOWN, // KEY_COMPUTER
/* 158, 0x09e */ SDL_SCANCODE_AC_BACK, // KEY_BACK
/* 159, 0x09f */ SDL_SCANCODE_AC_FORWARD, // KEY_FORWARD
/* 160, 0x0a0 */ SDL_SCANCODE_UNKNOWN, // KEY_CLOSECD
/* 161, 0x0a1 */ SDL_SCANCODE_MEDIA_EJECT, // KEY_EJECTCD
/* 162, 0x0a2 */ SDL_SCANCODE_MEDIA_EJECT, // KEY_EJECTCLOSECD
/* 163, 0x0a3 */ SDL_SCANCODE_MEDIA_NEXT_TRACK, // KEY_NEXTSONG
/* 164, 0x0a4 */ SDL_SCANCODE_MEDIA_PLAY_PAUSE, // KEY_PLAYPAUSE
/* 165, 0x0a5 */ SDL_SCANCODE_MEDIA_PREVIOUS_TRACK, // KEY_PREVIOUSSONG
/* 166, 0x0a6 */ SDL_SCANCODE_MEDIA_STOP, // KEY_STOPCD
/* 167, 0x0a7 */ SDL_SCANCODE_MEDIA_RECORD, // KEY_RECORD
/* 168, 0x0a8 */ SDL_SCANCODE_MEDIA_REWIND, // KEY_REWIND
/* 169, 0x0a9 */ SDL_SCANCODE_UNKNOWN, // KEY_PHONE
/* 170, 0x0aa */ SDL_SCANCODE_UNKNOWN, // KEY_ISO
/* 171, 0x0ab */ SDL_SCANCODE_UNKNOWN, // KEY_CONFIG
/* 172, 0x0ac */ SDL_SCANCODE_AC_HOME, // KEY_HOMEPAGE
/* 173, 0x0ad */ SDL_SCANCODE_AC_REFRESH, // KEY_REFRESH
/* 174, 0x0ae */ SDL_SCANCODE_AC_EXIT, // KEY_EXIT
/* 175, 0x0af */ SDL_SCANCODE_UNKNOWN, // KEY_MOVE
/* 176, 0x0b0 */ SDL_SCANCODE_UNKNOWN, // KEY_EDIT
/* 177, 0x0b1 */ SDL_SCANCODE_UNKNOWN, // KEY_SCROLLUP
/* 178, 0x0b2 */ SDL_SCANCODE_UNKNOWN, // KEY_SCROLLDOWN
/* 179, 0x0b3 */ SDL_SCANCODE_KP_LEFTPAREN, // KEY_KPLEFTPAREN
/* 180, 0x0b4 */ SDL_SCANCODE_KP_RIGHTPAREN, // KEY_KPRIGHTPAREN
/* 181, 0x0b5 */ SDL_SCANCODE_AC_NEW, // KEY_NEW
/* 182, 0x0b6 */ SDL_SCANCODE_AGAIN, // KEY_REDO
/* 183, 0x0b7 */ SDL_SCANCODE_F13, // KEY_F13
/* 184, 0x0b8 */ SDL_SCANCODE_F14, // KEY_F14
/* 185, 0x0b9 */ SDL_SCANCODE_F15, // KEY_F15
/* 186, 0x0ba */ SDL_SCANCODE_F16, // KEY_F16
/* 187, 0x0bb */ SDL_SCANCODE_F17, // KEY_F17
/* 188, 0x0bc */ SDL_SCANCODE_F18, // KEY_F18
/* 189, 0x0bd */ SDL_SCANCODE_F19, // KEY_F19
/* 190, 0x0be */ SDL_SCANCODE_F20, // KEY_F20
/* 191, 0x0bf */ SDL_SCANCODE_F21, // KEY_F21
/* 192, 0x0c0 */ SDL_SCANCODE_F22, // KEY_F22
/* 193, 0x0c1 */ SDL_SCANCODE_F23, // KEY_F23
/* 194, 0x0c2 */ SDL_SCANCODE_F24, // KEY_F24
/* 195, 0x0c3 */ SDL_SCANCODE_UNKNOWN,
/* 196, 0x0c4 */ SDL_SCANCODE_UNKNOWN,
/* 197, 0x0c5 */ SDL_SCANCODE_UNKNOWN,
/* 198, 0x0c6 */ SDL_SCANCODE_UNKNOWN,
/* 199, 0x0c7 */ SDL_SCANCODE_UNKNOWN,
/* 200, 0x0c8 */ SDL_SCANCODE_MEDIA_PLAY, // KEY_PLAYCD
/* 201, 0x0c9 */ SDL_SCANCODE_MEDIA_PAUSE, // KEY_PAUSECD
/* 202, 0x0ca */ SDL_SCANCODE_UNKNOWN, // KEY_PROG3
/* 203, 0x0cb */ SDL_SCANCODE_UNKNOWN, // KEY_PROG4
/* 204, 0x0cc */ SDL_SCANCODE_UNKNOWN, // KEY_ALL_APPLICATIONS
/* 205, 0x0cd */ SDL_SCANCODE_UNKNOWN, // KEY_SUSPEND
/* 206, 0x0ce */ SDL_SCANCODE_AC_CLOSE, // KEY_CLOSE
/* 207, 0x0cf */ SDL_SCANCODE_MEDIA_PLAY, // KEY_PLAY
/* 208, 0x0d0 */ SDL_SCANCODE_MEDIA_FAST_FORWARD, // KEY_FASTFORWARD
/* 209, 0x0d1 */ SDL_SCANCODE_UNKNOWN, // KEY_BASSBOOST
/* 210, 0x0d2 */ SDL_SCANCODE_PRINTSCREEN, // KEY_PRINT
/* 211, 0x0d3 */ SDL_SCANCODE_UNKNOWN, // KEY_HP
/* 212, 0x0d4 */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA
/* 213, 0x0d5 */ SDL_SCANCODE_UNKNOWN, // KEY_SOUND
/* 214, 0x0d6 */ SDL_SCANCODE_UNKNOWN, // KEY_QUESTION
/* 215, 0x0d7 */ SDL_SCANCODE_UNKNOWN, // KEY_EMAIL
/* 216, 0x0d8 */ SDL_SCANCODE_UNKNOWN, // KEY_CHAT
/* 217, 0x0d9 */ SDL_SCANCODE_AC_SEARCH, // KEY_SEARCH
/* 218, 0x0da */ SDL_SCANCODE_UNKNOWN, // KEY_CONNECT
/* 219, 0x0db */ SDL_SCANCODE_UNKNOWN, // KEY_FINANCE
/* 220, 0x0dc */ SDL_SCANCODE_UNKNOWN, // KEY_SPORT
/* 221, 0x0dd */ SDL_SCANCODE_UNKNOWN, // KEY_SHOP
/* 222, 0x0de */ SDL_SCANCODE_ALTERASE, // KEY_ALTERASE
/* 223, 0x0df */ SDL_SCANCODE_CANCEL, // KEY_CANCEL
/* 224, 0x0e0 */ SDL_SCANCODE_UNKNOWN, // KEY_BRIGHTNESSDOWN
/* 225, 0x0e1 */ SDL_SCANCODE_UNKNOWN, // KEY_BRIGHTNESSUP
/* 226, 0x0e2 */ SDL_SCANCODE_MEDIA_SELECT, // KEY_MEDIA
/* 227, 0x0e3 */ SDL_SCANCODE_UNKNOWN, // KEY_SWITCHVIDEOMODE
/* 228, 0x0e4 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDILLUMTOGGLE
/* 229, 0x0e5 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDILLUMDOWN
/* 230, 0x0e6 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDILLUMUP
/* 231, 0x0e7 */ SDL_SCANCODE_UNKNOWN, // KEY_SEND
/* 232, 0x0e8 */ SDL_SCANCODE_UNKNOWN, // KEY_REPLY
/* 233, 0x0e9 */ SDL_SCANCODE_UNKNOWN, // KEY_FORWARDMAIL
/* 234, 0x0ea */ SDL_SCANCODE_AC_SAVE, // KEY_SAVE
/* 235, 0x0eb */ SDL_SCANCODE_UNKNOWN, // KEY_DOCUMENTS
/* 236, 0x0ec */ SDL_SCANCODE_UNKNOWN, // KEY_BATTERY
/* 237, 0x0ed */ SDL_SCANCODE_UNKNOWN, // KEY_BLUETOOTH
/* 238, 0x0ee */ SDL_SCANCODE_UNKNOWN, // KEY_WLAN
/* 239, 0x0ef */ SDL_SCANCODE_UNKNOWN, // KEY_UWB
/* 240, 0x0f0 */ SDL_SCANCODE_UNKNOWN, // KEY_UNKNOWN
/* 241, 0x0f1 */ SDL_SCANCODE_UNKNOWN, // KEY_VIDEO_NEXT
/* 242, 0x0f2 */ SDL_SCANCODE_UNKNOWN, // KEY_VIDEO_PREV
/* 243, 0x0f3 */ SDL_SCANCODE_UNKNOWN, // KEY_BRIGHTNESS_CYCLE
/* 244, 0x0f4 */ SDL_SCANCODE_UNKNOWN, // KEY_BRIGHTNESS_AUTO
/* 245, 0x0f5 */ SDL_SCANCODE_UNKNOWN, // KEY_DISPLAY_OFF
/* 246, 0x0f6 */ SDL_SCANCODE_UNKNOWN, // KEY_WWAN
/* 247, 0x0f7 */ SDL_SCANCODE_UNKNOWN, // KEY_RFKILL
/* 248, 0x0f8 */ SDL_SCANCODE_UNKNOWN, // KEY_MICMUTE
/* 249, 0x0f9 */ SDL_SCANCODE_UNKNOWN,
/* 250, 0x0fa */ SDL_SCANCODE_UNKNOWN,
/* 251, 0x0fb */ SDL_SCANCODE_UNKNOWN,
/* 252, 0x0fc */ SDL_SCANCODE_UNKNOWN,
/* 253, 0x0fd */ SDL_SCANCODE_UNKNOWN,
/* 254, 0x0fe */ SDL_SCANCODE_UNKNOWN,
/* 255, 0x0ff */ SDL_SCANCODE_UNKNOWN,
/* 256, 0x100 */ SDL_SCANCODE_UNKNOWN,
/* 257, 0x101 */ SDL_SCANCODE_UNKNOWN,
/* 258, 0x102 */ SDL_SCANCODE_UNKNOWN,
/* 259, 0x103 */ SDL_SCANCODE_UNKNOWN,
/* 260, 0x104 */ SDL_SCANCODE_UNKNOWN,
/* 261, 0x105 */ SDL_SCANCODE_UNKNOWN,
/* 262, 0x106 */ SDL_SCANCODE_UNKNOWN,
/* 263, 0x107 */ SDL_SCANCODE_UNKNOWN,
/* 264, 0x108 */ SDL_SCANCODE_UNKNOWN,
/* 265, 0x109 */ SDL_SCANCODE_UNKNOWN,
/* 266, 0x10a */ SDL_SCANCODE_UNKNOWN,
/* 267, 0x10b */ SDL_SCANCODE_UNKNOWN,
/* 268, 0x10c */ SDL_SCANCODE_UNKNOWN,
/* 269, 0x10d */ SDL_SCANCODE_UNKNOWN,
/* 270, 0x10e */ SDL_SCANCODE_UNKNOWN,
/* 271, 0x10f */ SDL_SCANCODE_UNKNOWN,
/* 272, 0x110 */ SDL_SCANCODE_UNKNOWN,
/* 273, 0x111 */ SDL_SCANCODE_UNKNOWN,
/* 274, 0x112 */ SDL_SCANCODE_UNKNOWN,
/* 275, 0x113 */ SDL_SCANCODE_UNKNOWN,
/* 276, 0x114 */ SDL_SCANCODE_UNKNOWN,
/* 277, 0x115 */ SDL_SCANCODE_UNKNOWN,
/* 278, 0x116 */ SDL_SCANCODE_UNKNOWN,
/* 279, 0x117 */ SDL_SCANCODE_UNKNOWN,
/* 280, 0x118 */ SDL_SCANCODE_UNKNOWN,
/* 281, 0x119 */ SDL_SCANCODE_UNKNOWN,
/* 282, 0x11a */ SDL_SCANCODE_UNKNOWN,
/* 283, 0x11b */ SDL_SCANCODE_UNKNOWN,
/* 284, 0x11c */ SDL_SCANCODE_UNKNOWN,
/* 285, 0x11d */ SDL_SCANCODE_UNKNOWN,
/* 286, 0x11e */ SDL_SCANCODE_UNKNOWN,
/* 287, 0x11f */ SDL_SCANCODE_UNKNOWN,
/* 288, 0x120 */ SDL_SCANCODE_UNKNOWN,
/* 289, 0x121 */ SDL_SCANCODE_UNKNOWN,
/* 290, 0x122 */ SDL_SCANCODE_UNKNOWN,
/* 291, 0x123 */ SDL_SCANCODE_UNKNOWN,
/* 292, 0x124 */ SDL_SCANCODE_UNKNOWN,
/* 293, 0x125 */ SDL_SCANCODE_UNKNOWN,
/* 294, 0x126 */ SDL_SCANCODE_UNKNOWN,
/* 295, 0x127 */ SDL_SCANCODE_UNKNOWN,
/* 296, 0x128 */ SDL_SCANCODE_UNKNOWN,
/* 297, 0x129 */ SDL_SCANCODE_UNKNOWN,
/* 298, 0x12a */ SDL_SCANCODE_UNKNOWN,
/* 299, 0x12b */ SDL_SCANCODE_UNKNOWN,
/* 300, 0x12c */ SDL_SCANCODE_UNKNOWN,
/* 301, 0x12d */ SDL_SCANCODE_UNKNOWN,
/* 302, 0x12e */ SDL_SCANCODE_UNKNOWN,
/* 303, 0x12f */ SDL_SCANCODE_UNKNOWN,
/* 304, 0x130 */ SDL_SCANCODE_UNKNOWN,
/* 305, 0x131 */ SDL_SCANCODE_UNKNOWN,
/* 306, 0x132 */ SDL_SCANCODE_UNKNOWN,
/* 307, 0x133 */ SDL_SCANCODE_UNKNOWN,
/* 308, 0x134 */ SDL_SCANCODE_UNKNOWN,
/* 309, 0x135 */ SDL_SCANCODE_UNKNOWN,
/* 310, 0x136 */ SDL_SCANCODE_UNKNOWN,
/* 311, 0x137 */ SDL_SCANCODE_UNKNOWN,
/* 312, 0x138 */ SDL_SCANCODE_UNKNOWN,
/* 313, 0x139 */ SDL_SCANCODE_UNKNOWN,
/* 314, 0x13a */ SDL_SCANCODE_UNKNOWN,
/* 315, 0x13b */ SDL_SCANCODE_UNKNOWN,
/* 316, 0x13c */ SDL_SCANCODE_UNKNOWN,
/* 317, 0x13d */ SDL_SCANCODE_UNKNOWN,
/* 318, 0x13e */ SDL_SCANCODE_UNKNOWN,
/* 319, 0x13f */ SDL_SCANCODE_UNKNOWN,
/* 320, 0x140 */ SDL_SCANCODE_UNKNOWN,
/* 321, 0x141 */ SDL_SCANCODE_UNKNOWN,
/* 322, 0x142 */ SDL_SCANCODE_UNKNOWN,
/* 323, 0x143 */ SDL_SCANCODE_UNKNOWN,
/* 324, 0x144 */ SDL_SCANCODE_UNKNOWN,
/* 325, 0x145 */ SDL_SCANCODE_UNKNOWN,
/* 326, 0x146 */ SDL_SCANCODE_UNKNOWN,
/* 327, 0x147 */ SDL_SCANCODE_UNKNOWN,
/* 328, 0x148 */ SDL_SCANCODE_UNKNOWN,
/* 329, 0x149 */ SDL_SCANCODE_UNKNOWN,
/* 330, 0x14a */ SDL_SCANCODE_UNKNOWN,
/* 331, 0x14b */ SDL_SCANCODE_UNKNOWN,
/* 332, 0x14c */ SDL_SCANCODE_UNKNOWN,
/* 333, 0x14d */ SDL_SCANCODE_UNKNOWN,
/* 334, 0x14e */ SDL_SCANCODE_UNKNOWN,
/* 335, 0x14f */ SDL_SCANCODE_UNKNOWN,
/* 336, 0x150 */ SDL_SCANCODE_UNKNOWN,
/* 337, 0x151 */ SDL_SCANCODE_UNKNOWN,
/* 338, 0x152 */ SDL_SCANCODE_UNKNOWN,
/* 339, 0x153 */ SDL_SCANCODE_UNKNOWN,
/* 340, 0x154 */ SDL_SCANCODE_UNKNOWN,
/* 341, 0x155 */ SDL_SCANCODE_UNKNOWN,
/* 342, 0x156 */ SDL_SCANCODE_UNKNOWN,
/* 343, 0x157 */ SDL_SCANCODE_UNKNOWN,
/* 344, 0x158 */ SDL_SCANCODE_UNKNOWN,
/* 345, 0x159 */ SDL_SCANCODE_UNKNOWN,
/* 346, 0x15a */ SDL_SCANCODE_UNKNOWN,
/* 347, 0x15b */ SDL_SCANCODE_UNKNOWN,
/* 348, 0x15c */ SDL_SCANCODE_UNKNOWN,
/* 349, 0x15d */ SDL_SCANCODE_UNKNOWN,
/* 350, 0x15e */ SDL_SCANCODE_UNKNOWN,
/* 351, 0x15f */ SDL_SCANCODE_UNKNOWN,
/* 352, 0x160 */ SDL_SCANCODE_UNKNOWN, // KEY_OK
/* 353, 0x161 */ SDL_SCANCODE_SELECT, // KEY_SELECT
/* 354, 0x162 */ SDL_SCANCODE_UNKNOWN, // KEY_GOTO
/* 355, 0x163 */ SDL_SCANCODE_CLEAR, // KEY_CLEAR
/* 356, 0x164 */ SDL_SCANCODE_UNKNOWN, // KEY_POWER2
/* 357, 0x165 */ SDL_SCANCODE_UNKNOWN, // KEY_OPTION
/* 358, 0x166 */ SDL_SCANCODE_UNKNOWN, // KEY_INFO
/* 359, 0x167 */ SDL_SCANCODE_UNKNOWN, // KEY_TIME
/* 360, 0x168 */ SDL_SCANCODE_UNKNOWN, // KEY_VENDOR
/* 361, 0x169 */ SDL_SCANCODE_UNKNOWN, // KEY_ARCHIVE
/* 362, 0x16a */ SDL_SCANCODE_UNKNOWN, // KEY_PROGRAM
/* 363, 0x16b */ SDL_SCANCODE_UNKNOWN, // KEY_CHANNEL
/* 364, 0x16c */ SDL_SCANCODE_UNKNOWN, // KEY_FAVORITES
/* 365, 0x16d */ SDL_SCANCODE_UNKNOWN, // KEY_EPG
/* 366, 0x16e */ SDL_SCANCODE_UNKNOWN, // KEY_PVR
/* 367, 0x16f */ SDL_SCANCODE_UNKNOWN, // KEY_MHP
/* 368, 0x170 */ SDL_SCANCODE_UNKNOWN, // KEY_LANGUAGE
/* 369, 0x171 */ SDL_SCANCODE_UNKNOWN, // KEY_TITLE
/* 370, 0x172 */ SDL_SCANCODE_UNKNOWN, // KEY_SUBTITLE
/* 371, 0x173 */ SDL_SCANCODE_UNKNOWN, // KEY_ANGLE
/* 372, 0x174 */ SDL_SCANCODE_UNKNOWN, // KEY_FULL_SCREEN
/* 373, 0x175 */ SDL_SCANCODE_MODE, // KEY_MODE
/* 374, 0x176 */ SDL_SCANCODE_UNKNOWN, // KEY_KEYBOARD
/* 375, 0x177 */ SDL_SCANCODE_UNKNOWN, // KEY_ASPECT_RATIO
/* 376, 0x178 */ SDL_SCANCODE_UNKNOWN, // KEY_PC
/* 377, 0x179 */ SDL_SCANCODE_UNKNOWN, // KEY_TV
/* 378, 0x17a */ SDL_SCANCODE_UNKNOWN, // KEY_TV2
/* 379, 0x17b */ SDL_SCANCODE_UNKNOWN, // KEY_VCR
/* 380, 0x17c */ SDL_SCANCODE_UNKNOWN, // KEY_VCR2
/* 381, 0x17d */ SDL_SCANCODE_UNKNOWN, // KEY_SAT
/* 382, 0x17e */ SDL_SCANCODE_UNKNOWN, // KEY_SAT2
/* 383, 0x17f */ SDL_SCANCODE_UNKNOWN, // KEY_CD
/* 384, 0x180 */ SDL_SCANCODE_UNKNOWN, // KEY_TAPE
/* 385, 0x181 */ SDL_SCANCODE_UNKNOWN, // KEY_RADIO
/* 386, 0x182 */ SDL_SCANCODE_UNKNOWN, // KEY_TUNER
/* 387, 0x183 */ SDL_SCANCODE_UNKNOWN, // KEY_PLAYER
/* 388, 0x184 */ SDL_SCANCODE_UNKNOWN, // KEY_TEXT
/* 389, 0x185 */ SDL_SCANCODE_UNKNOWN, // KEY_DVD
/* 390, 0x186 */ SDL_SCANCODE_UNKNOWN, // KEY_AUX
/* 391, 0x187 */ SDL_SCANCODE_UNKNOWN, // KEY_MP3
/* 392, 0x188 */ SDL_SCANCODE_UNKNOWN, // KEY_AUDIO
/* 393, 0x189 */ SDL_SCANCODE_UNKNOWN, // KEY_VIDEO
/* 394, 0x18a */ SDL_SCANCODE_UNKNOWN, // KEY_DIRECTORY
/* 395, 0x18b */ SDL_SCANCODE_UNKNOWN, // KEY_LIST
/* 396, 0x18c */ SDL_SCANCODE_UNKNOWN, // KEY_MEMO
/* 397, 0x18d */ SDL_SCANCODE_UNKNOWN, // KEY_CALENDAR
/* 398, 0x18e */ SDL_SCANCODE_UNKNOWN, // KEY_RED
/* 399, 0x18f */ SDL_SCANCODE_UNKNOWN, // KEY_GREEN
/* 400, 0x190 */ SDL_SCANCODE_UNKNOWN, // KEY_YELLOW
/* 401, 0x191 */ SDL_SCANCODE_UNKNOWN, // KEY_BLUE
/* 402, 0x192 */ SDL_SCANCODE_CHANNEL_INCREMENT, // KEY_CHANNELUP
/* 403, 0x193 */ SDL_SCANCODE_CHANNEL_DECREMENT, // KEY_CHANNELDOWN
#if 0 // We don't have any mapped scancodes after this point (yet)
/* 404, 0x194 */ SDL_SCANCODE_UNKNOWN, // KEY_FIRST
/* 405, 0x195 */ SDL_SCANCODE_UNKNOWN, // KEY_LAST
/* 406, 0x196 */ SDL_SCANCODE_UNKNOWN, // KEY_AB
/* 407, 0x197 */ SDL_SCANCODE_UNKNOWN, // KEY_NEXT
/* 408, 0x198 */ SDL_SCANCODE_UNKNOWN, // KEY_RESTART
/* 409, 0x199 */ SDL_SCANCODE_UNKNOWN, // KEY_SLOW
/* 410, 0x19a */ SDL_SCANCODE_UNKNOWN, // KEY_SHUFFLE
/* 411, 0x19b */ SDL_SCANCODE_UNKNOWN, // KEY_BREAK
/* 412, 0x19c */ SDL_SCANCODE_UNKNOWN, // KEY_PREVIOUS
/* 413, 0x19d */ SDL_SCANCODE_UNKNOWN, // KEY_DIGITS
/* 414, 0x19e */ SDL_SCANCODE_UNKNOWN, // KEY_TEEN
/* 415, 0x19f */ SDL_SCANCODE_UNKNOWN, // KEY_TWEN
/* 416, 0x1a0 */ SDL_SCANCODE_UNKNOWN, // KEY_VIDEOPHONE
/* 417, 0x1a1 */ SDL_SCANCODE_UNKNOWN, // KEY_GAMES
/* 418, 0x1a2 */ SDL_SCANCODE_UNKNOWN, // KEY_ZOOMIN
/* 419, 0x1a3 */ SDL_SCANCODE_UNKNOWN, // KEY_ZOOMOUT
/* 420, 0x1a4 */ SDL_SCANCODE_UNKNOWN, // KEY_ZOOMRESET
/* 421, 0x1a5 */ SDL_SCANCODE_UNKNOWN, // KEY_WORDPROCESSOR
/* 422, 0x1a6 */ SDL_SCANCODE_UNKNOWN, // KEY_EDITOR
/* 423, 0x1a7 */ SDL_SCANCODE_UNKNOWN, // KEY_SPREADSHEET
/* 424, 0x1a8 */ SDL_SCANCODE_UNKNOWN, // KEY_GRAPHICSEDITOR
/* 425, 0x1a9 */ SDL_SCANCODE_UNKNOWN, // KEY_PRESENTATION
/* 426, 0x1aa */ SDL_SCANCODE_UNKNOWN, // KEY_DATABASE
/* 427, 0x1ab */ SDL_SCANCODE_UNKNOWN, // KEY_NEWS
/* 428, 0x1ac */ SDL_SCANCODE_UNKNOWN, // KEY_VOICEMAIL
/* 429, 0x1ad */ SDL_SCANCODE_UNKNOWN, // KEY_ADDRESSBOOK
/* 430, 0x1ae */ SDL_SCANCODE_UNKNOWN, // KEY_MESSENGER
/* 431, 0x1af */ SDL_SCANCODE_UNKNOWN, // KEY_DISPLAYTOGGLE
/* 432, 0x1b0 */ SDL_SCANCODE_UNKNOWN, // KEY_SPELLCHECK
/* 433, 0x1b1 */ SDL_SCANCODE_UNKNOWN, // KEY_LOGOFF
/* 434, 0x1b2 */ SDL_SCANCODE_UNKNOWN, // KEY_DOLLAR
/* 435, 0x1b3 */ SDL_SCANCODE_UNKNOWN, // KEY_EURO
/* 436, 0x1b4 */ SDL_SCANCODE_UNKNOWN, // KEY_FRAMEBACK
/* 437, 0x1b5 */ SDL_SCANCODE_UNKNOWN, // KEY_FRAMEFORWARD
/* 438, 0x1b6 */ SDL_SCANCODE_UNKNOWN, // KEY_CONTEXT_MENU
/* 439, 0x1b7 */ SDL_SCANCODE_UNKNOWN, // KEY_MEDIA_REPEAT
/* 440, 0x1b8 */ SDL_SCANCODE_UNKNOWN, // KEY_10CHANNELSUP
/* 441, 0x1b9 */ SDL_SCANCODE_UNKNOWN, // KEY_10CHANNELSDOWN
/* 442, 0x1ba */ SDL_SCANCODE_UNKNOWN, // KEY_IMAGES
/* 443, 0x1bb */ SDL_SCANCODE_UNKNOWN,
/* 444, 0x1bc */ SDL_SCANCODE_UNKNOWN, // KEY_NOTIFICATION_CENTER
/* 445, 0x1bd */ SDL_SCANCODE_UNKNOWN, // KEY_PICKUP_PHONE
/* 446, 0x1be */ SDL_SCANCODE_UNKNOWN, // KEY_HANGUP_PHONE
/* 447, 0x1bf */ SDL_SCANCODE_UNKNOWN,
/* 448, 0x1c0 */ SDL_SCANCODE_UNKNOWN, // KEY_DEL_EOL
/* 449, 0x1c1 */ SDL_SCANCODE_UNKNOWN, // KEY_DEL_EOS
/* 450, 0x1c2 */ SDL_SCANCODE_UNKNOWN, // KEY_INS_LINE
/* 451, 0x1c3 */ SDL_SCANCODE_UNKNOWN, // KEY_DEL_LINE
/* 452, 0x1c4 */ SDL_SCANCODE_UNKNOWN,
/* 453, 0x1c5 */ SDL_SCANCODE_UNKNOWN,
/* 454, 0x1c6 */ SDL_SCANCODE_UNKNOWN,
/* 455, 0x1c7 */ SDL_SCANCODE_UNKNOWN,
/* 456, 0x1c8 */ SDL_SCANCODE_UNKNOWN,
/* 457, 0x1c9 */ SDL_SCANCODE_UNKNOWN,
/* 458, 0x1ca */ SDL_SCANCODE_UNKNOWN,
/* 459, 0x1cb */ SDL_SCANCODE_UNKNOWN,
/* 460, 0x1cc */ SDL_SCANCODE_UNKNOWN,
/* 461, 0x1cd */ SDL_SCANCODE_UNKNOWN,
/* 462, 0x1ce */ SDL_SCANCODE_UNKNOWN,
/* 463, 0x1cf */ SDL_SCANCODE_UNKNOWN,
/* 464, 0x1d0 */ SDL_SCANCODE_UNKNOWN, // KEY_FN
/* 465, 0x1d1 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_ESC
/* 466, 0x1d2 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F1
/* 467, 0x1d3 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F2
/* 468, 0x1d4 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F3
/* 469, 0x1d5 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F4
/* 470, 0x1d6 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F5
/* 471, 0x1d7 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F6
/* 472, 0x1d8 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F7
/* 473, 0x1d9 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F8
/* 474, 0x1da */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F9
/* 475, 0x1db */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F10
/* 476, 0x1dc */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F11
/* 477, 0x1dd */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F12
/* 478, 0x1de */ SDL_SCANCODE_UNKNOWN, // KEY_FN_1
/* 479, 0x1df */ SDL_SCANCODE_UNKNOWN, // KEY_FN_2
/* 480, 0x1e0 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_D
/* 481, 0x1e1 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_E
/* 482, 0x1e2 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_F
/* 483, 0x1e3 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_S
/* 484, 0x1e4 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_B
/* 485, 0x1e5 */ SDL_SCANCODE_UNKNOWN, // KEY_FN_RIGHT_SHIFT
/* 486, 0x1e6 */ SDL_SCANCODE_UNKNOWN,
/* 487, 0x1e7 */ SDL_SCANCODE_UNKNOWN,
/* 488, 0x1e8 */ SDL_SCANCODE_UNKNOWN,
/* 489, 0x1e9 */ SDL_SCANCODE_UNKNOWN,
/* 490, 0x1ea */ SDL_SCANCODE_UNKNOWN,
/* 491, 0x1eb */ SDL_SCANCODE_UNKNOWN,
/* 492, 0x1ec */ SDL_SCANCODE_UNKNOWN,
/* 493, 0x1ed */ SDL_SCANCODE_UNKNOWN,
/* 494, 0x1ee */ SDL_SCANCODE_UNKNOWN,
/* 495, 0x1ef */ SDL_SCANCODE_UNKNOWN,
/* 496, 0x1f0 */ SDL_SCANCODE_UNKNOWN,
/* 497, 0x1f1 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT1
/* 498, 0x1f2 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT2
/* 499, 0x1f3 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT3
/* 500, 0x1f4 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT4
/* 501, 0x1f5 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT5
/* 502, 0x1f6 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT6
/* 503, 0x1f7 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT7
/* 504, 0x1f8 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT8
/* 505, 0x1f9 */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT9
/* 506, 0x1fa */ SDL_SCANCODE_UNKNOWN, // KEY_BRL_DOT10
/* 507, 0x1fb */ SDL_SCANCODE_UNKNOWN,
/* 508, 0x1fc */ SDL_SCANCODE_UNKNOWN,
/* 509, 0x1fd */ SDL_SCANCODE_UNKNOWN,
/* 510, 0x1fe */ SDL_SCANCODE_UNKNOWN,
/* 511, 0x1ff */ SDL_SCANCODE_UNKNOWN,
/* 512, 0x200 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_0
/* 513, 0x201 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_1
/* 514, 0x202 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_2
/* 515, 0x203 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_3
/* 516, 0x204 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_4
/* 517, 0x205 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_5
/* 518, 0x206 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_6
/* 519, 0x207 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_7
/* 520, 0x208 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_8
/* 521, 0x209 */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_9
/* 522, 0x20a */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_STAR
/* 523, 0x20b */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_POUND
/* 524, 0x20c */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_A
/* 525, 0x20d */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_B
/* 526, 0x20e */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_C
/* 527, 0x20f */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_D
/* 528, 0x210 */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA_FOCUS
/* 529, 0x211 */ SDL_SCANCODE_UNKNOWN, // KEY_WPS_BUTTON
/* 530, 0x212 */ SDL_SCANCODE_UNKNOWN, // KEY_TOUCHPAD_TOGGLE
/* 531, 0x213 */ SDL_SCANCODE_UNKNOWN, // KEY_TOUCHPAD_ON
/* 532, 0x214 */ SDL_SCANCODE_UNKNOWN, // KEY_TOUCHPAD_OFF
/* 533, 0x215 */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA_ZOOMIN
/* 534, 0x216 */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA_ZOOMOUT
/* 535, 0x217 */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA_UP
/* 536, 0x218 */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA_DOWN
/* 537, 0x219 */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA_LEFT
/* 538, 0x21a */ SDL_SCANCODE_UNKNOWN, // KEY_CAMERA_RIGHT
/* 539, 0x21b */ SDL_SCANCODE_UNKNOWN, // KEY_ATTENDANT_ON
/* 540, 0x21c */ SDL_SCANCODE_UNKNOWN, // KEY_ATTENDANT_OFF
/* 541, 0x21d */ SDL_SCANCODE_UNKNOWN, // KEY_ATTENDANT_TOGGLE
/* 542, 0x21e */ SDL_SCANCODE_UNKNOWN, // KEY_LIGHTS_TOGGLE
/* 543, 0x21f */ SDL_SCANCODE_UNKNOWN,
/* 544, 0x220 */ SDL_SCANCODE_UNKNOWN,
/* 545, 0x221 */ SDL_SCANCODE_UNKNOWN,
/* 546, 0x222 */ SDL_SCANCODE_UNKNOWN,
/* 547, 0x223 */ SDL_SCANCODE_UNKNOWN,
/* 548, 0x224 */ SDL_SCANCODE_UNKNOWN,
/* 549, 0x225 */ SDL_SCANCODE_UNKNOWN,
/* 550, 0x226 */ SDL_SCANCODE_UNKNOWN,
/* 551, 0x227 */ SDL_SCANCODE_UNKNOWN,
/* 552, 0x228 */ SDL_SCANCODE_UNKNOWN,
/* 553, 0x229 */ SDL_SCANCODE_UNKNOWN,
/* 554, 0x22a */ SDL_SCANCODE_UNKNOWN,
/* 555, 0x22b */ SDL_SCANCODE_UNKNOWN,
/* 556, 0x22c */ SDL_SCANCODE_UNKNOWN,
/* 557, 0x22d */ SDL_SCANCODE_UNKNOWN,
/* 558, 0x22e */ SDL_SCANCODE_UNKNOWN,
/* 559, 0x22f */ SDL_SCANCODE_UNKNOWN,
/* 560, 0x230 */ SDL_SCANCODE_UNKNOWN, // KEY_ALS_TOGGLE
/* 561, 0x231 */ SDL_SCANCODE_UNKNOWN, // KEY_ROTATE_LOCK_TOGGLE
/* 562, 0x232 */ SDL_SCANCODE_UNKNOWN,
/* 563, 0x233 */ SDL_SCANCODE_UNKNOWN,
/* 564, 0x234 */ SDL_SCANCODE_UNKNOWN,
/* 565, 0x235 */ SDL_SCANCODE_UNKNOWN,
/* 566, 0x236 */ SDL_SCANCODE_UNKNOWN,
/* 567, 0x237 */ SDL_SCANCODE_UNKNOWN,
/* 568, 0x238 */ SDL_SCANCODE_UNKNOWN,
/* 569, 0x239 */ SDL_SCANCODE_UNKNOWN,
/* 570, 0x23a */ SDL_SCANCODE_UNKNOWN,
/* 571, 0x23b */ SDL_SCANCODE_UNKNOWN,
/* 572, 0x23c */ SDL_SCANCODE_UNKNOWN,
/* 573, 0x23d */ SDL_SCANCODE_UNKNOWN,
/* 574, 0x23e */ SDL_SCANCODE_UNKNOWN,
/* 575, 0x23f */ SDL_SCANCODE_UNKNOWN,
/* 576, 0x240 */ SDL_SCANCODE_UNKNOWN, // KEY_BUTTONCONFIG
/* 577, 0x241 */ SDL_SCANCODE_UNKNOWN, // KEY_TASKMANAGER
/* 578, 0x242 */ SDL_SCANCODE_UNKNOWN, // KEY_JOURNAL
/* 579, 0x243 */ SDL_SCANCODE_UNKNOWN, // KEY_CONTROLPANEL
/* 580, 0x244 */ SDL_SCANCODE_UNKNOWN, // KEY_APPSELECT
/* 581, 0x245 */ SDL_SCANCODE_UNKNOWN, // KEY_SCREENSAVER
/* 582, 0x246 */ SDL_SCANCODE_UNKNOWN, // KEY_VOICECOMMAND
/* 583, 0x247 */ SDL_SCANCODE_UNKNOWN, // KEY_ASSISTANT
/* 584, 0x248 */ SDL_SCANCODE_UNKNOWN, // KEY_KBD_LAYOUT_NEXT
/* 585, 0x249 */ SDL_SCANCODE_UNKNOWN, // KEY_EMOJI_PICKER
/* 586, 0x24a */ SDL_SCANCODE_UNKNOWN, // KEY_DICTATE
/* 587, 0x24b */ SDL_SCANCODE_UNKNOWN,
/* 588, 0x24c */ SDL_SCANCODE_UNKNOWN,
/* 589, 0x24d */ SDL_SCANCODE_UNKNOWN,
/* 590, 0x24e */ SDL_SCANCODE_UNKNOWN,
/* 591, 0x24f */ SDL_SCANCODE_UNKNOWN,
/* 592, 0x250 */ SDL_SCANCODE_UNKNOWN, // KEY_BRIGHTNESS_MIN
/* 593, 0x251 */ SDL_SCANCODE_UNKNOWN, // KEY_BRIGHTNESS_MAX
/* 594, 0x252 */ SDL_SCANCODE_UNKNOWN,
/* 595, 0x253 */ SDL_SCANCODE_UNKNOWN,
/* 596, 0x254 */ SDL_SCANCODE_UNKNOWN,
/* 597, 0x255 */ SDL_SCANCODE_UNKNOWN,
/* 598, 0x256 */ SDL_SCANCODE_UNKNOWN,
/* 599, 0x257 */ SDL_SCANCODE_UNKNOWN,
/* 600, 0x258 */ SDL_SCANCODE_UNKNOWN,
/* 601, 0x259 */ SDL_SCANCODE_UNKNOWN,
/* 602, 0x25a */ SDL_SCANCODE_UNKNOWN,
/* 603, 0x25b */ SDL_SCANCODE_UNKNOWN,
/* 604, 0x25c */ SDL_SCANCODE_UNKNOWN,
/* 605, 0x25d */ SDL_SCANCODE_UNKNOWN,
/* 606, 0x25e */ SDL_SCANCODE_UNKNOWN,
/* 607, 0x25f */ SDL_SCANCODE_UNKNOWN,
/* 608, 0x260 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDINPUTASSIST_PREV
/* 609, 0x261 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDINPUTASSIST_NEXT
/* 610, 0x262 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDINPUTASSIST_PREVGROUP
/* 611, 0x263 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDINPUTASSIST_NEXTGROUP
/* 612, 0x264 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDINPUTASSIST_ACCEPT
/* 613, 0x265 */ SDL_SCANCODE_UNKNOWN, // KEY_KBDINPUTASSIST_CANCEL
/* 614, 0x266 */ SDL_SCANCODE_UNKNOWN, // KEY_RIGHT_UP
/* 615, 0x267 */ SDL_SCANCODE_UNKNOWN, // KEY_RIGHT_DOWN
/* 616, 0x268 */ SDL_SCANCODE_UNKNOWN, // KEY_LEFT_UP
/* 617, 0x269 */ SDL_SCANCODE_UNKNOWN, // KEY_LEFT_DOWN
/* 618, 0x26a */ SDL_SCANCODE_UNKNOWN, // KEY_ROOT_MENU
/* 619, 0x26b */ SDL_SCANCODE_UNKNOWN, // KEY_MEDIA_TOP_MENU
/* 620, 0x26c */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_11
/* 621, 0x26d */ SDL_SCANCODE_UNKNOWN, // KEY_NUMERIC_12
/* 622, 0x26e */ SDL_SCANCODE_UNKNOWN, // KEY_AUDIO_DESC
/* 623, 0x26f */ SDL_SCANCODE_UNKNOWN, // KEY_3D_MODE
/* 624, 0x270 */ SDL_SCANCODE_UNKNOWN, // KEY_NEXT_FAVORITE
/* 625, 0x271 */ SDL_SCANCODE_UNKNOWN, // KEY_STOP_RECORD
/* 626, 0x272 */ SDL_SCANCODE_UNKNOWN, // KEY_PAUSE_RECORD
/* 627, 0x273 */ SDL_SCANCODE_UNKNOWN, // KEY_VOD
/* 628, 0x274 */ SDL_SCANCODE_UNKNOWN, // KEY_UNMUTE
/* 629, 0x275 */ SDL_SCANCODE_UNKNOWN, // KEY_FASTREVERSE
/* 630, 0x276 */ SDL_SCANCODE_UNKNOWN, // KEY_SLOWREVERSE
/* 631, 0x277 */ SDL_SCANCODE_UNKNOWN, // KEY_DATA
/* 632, 0x278 */ SDL_SCANCODE_UNKNOWN, // KEY_ONSCREEN_KEYBOARD
/* 633, 0x279 */ SDL_SCANCODE_UNKNOWN, // KEY_PRIVACY_SCREEN_TOGGLE
/* 634, 0x27a */ SDL_SCANCODE_UNKNOWN, // KEY_SELECTIVE_SCREENSHOT
/* 635, 0x27b */ SDL_SCANCODE_UNKNOWN,
/* 636, 0x27c */ SDL_SCANCODE_UNKNOWN,
/* 637, 0x27d */ SDL_SCANCODE_UNKNOWN,
/* 638, 0x27e */ SDL_SCANCODE_UNKNOWN,
/* 639, 0x27f */ SDL_SCANCODE_UNKNOWN,
/* 640, 0x280 */ SDL_SCANCODE_UNKNOWN,
/* 641, 0x281 */ SDL_SCANCODE_UNKNOWN,
/* 642, 0x282 */ SDL_SCANCODE_UNKNOWN,
/* 643, 0x283 */ SDL_SCANCODE_UNKNOWN,
/* 644, 0x284 */ SDL_SCANCODE_UNKNOWN,
/* 645, 0x285 */ SDL_SCANCODE_UNKNOWN,
/* 646, 0x286 */ SDL_SCANCODE_UNKNOWN,
/* 647, 0x287 */ SDL_SCANCODE_UNKNOWN,
/* 648, 0x288 */ SDL_SCANCODE_UNKNOWN,
/* 649, 0x289 */ SDL_SCANCODE_UNKNOWN,
/* 650, 0x28a */ SDL_SCANCODE_UNKNOWN,
/* 651, 0x28b */ SDL_SCANCODE_UNKNOWN,
/* 652, 0x28c */ SDL_SCANCODE_UNKNOWN,
/* 653, 0x28d */ SDL_SCANCODE_UNKNOWN,
/* 654, 0x28e */ SDL_SCANCODE_UNKNOWN,
/* 655, 0x28f */ SDL_SCANCODE_UNKNOWN,
/* 656, 0x290 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO1
/* 657, 0x291 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO2
/* 658, 0x292 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO3
/* 659, 0x293 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO4
/* 660, 0x294 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO5
/* 661, 0x295 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO6
/* 662, 0x296 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO7
/* 663, 0x297 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO8
/* 664, 0x298 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO9
/* 665, 0x299 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO10
/* 666, 0x29a */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO11
/* 667, 0x29b */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO12
/* 668, 0x29c */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO13
/* 669, 0x29d */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO14
/* 670, 0x29e */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO15
/* 671, 0x29f */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO16
/* 672, 0x2a0 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO17
/* 673, 0x2a1 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO18
/* 674, 0x2a2 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO19
/* 675, 0x2a3 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO20
/* 676, 0x2a4 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO21
/* 677, 0x2a5 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO22
/* 678, 0x2a6 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO23
/* 679, 0x2a7 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO24
/* 680, 0x2a8 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO25
/* 681, 0x2a9 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO26
/* 682, 0x2aa */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO27
/* 683, 0x2ab */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO28
/* 684, 0x2ac */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO29
/* 685, 0x2ad */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO30
/* 686, 0x2ae */ SDL_SCANCODE_UNKNOWN,
/* 687, 0x2af */ SDL_SCANCODE_UNKNOWN,
/* 688, 0x2b0 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO_RECORD_START
/* 689, 0x2b1 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO_RECORD_STOP
/* 690, 0x2b2 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO_PRESET_CYCLE
/* 691, 0x2b3 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO_PRESET1
/* 692, 0x2b4 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO_PRESET2
/* 693, 0x2b5 */ SDL_SCANCODE_UNKNOWN, // KEY_MACRO_PRESET3
/* 694, 0x2b6 */ SDL_SCANCODE_UNKNOWN,
/* 695, 0x2b7 */ SDL_SCANCODE_UNKNOWN,
/* 696, 0x2b8 */ SDL_SCANCODE_UNKNOWN, // KEY_KBD_LCD_MENU1
/* 697, 0x2b9 */ SDL_SCANCODE_UNKNOWN, // KEY_KBD_LCD_MENU2
/* 698, 0x2ba */ SDL_SCANCODE_UNKNOWN, // KEY_KBD_LCD_MENU3
/* 699, 0x2bb */ SDL_SCANCODE_UNKNOWN, // KEY_KBD_LCD_MENU4
/* 700, 0x2bc */ SDL_SCANCODE_UNKNOWN, // KEY_KBD_LCD_MENU5
/* 701, 0x2bd */ SDL_SCANCODE_UNKNOWN,
/* 702, 0x2be */ SDL_SCANCODE_UNKNOWN,
/* 703, 0x2bf */ SDL_SCANCODE_UNKNOWN,
/* 704, 0x2c0 */ SDL_SCANCODE_UNKNOWN,
/* 705, 0x2c1 */ SDL_SCANCODE_UNKNOWN,
/* 706, 0x2c2 */ SDL_SCANCODE_UNKNOWN,
/* 707, 0x2c3 */ SDL_SCANCODE_UNKNOWN,
/* 708, 0x2c4 */ SDL_SCANCODE_UNKNOWN,
/* 709, 0x2c5 */ SDL_SCANCODE_UNKNOWN,
/* 710, 0x2c6 */ SDL_SCANCODE_UNKNOWN,
/* 711, 0x2c7 */ SDL_SCANCODE_UNKNOWN,
/* 712, 0x2c8 */ SDL_SCANCODE_UNKNOWN,
/* 713, 0x2c9 */ SDL_SCANCODE_UNKNOWN,
/* 714, 0x2ca */ SDL_SCANCODE_UNKNOWN,
/* 715, 0x2cb */ SDL_SCANCODE_UNKNOWN,
/* 716, 0x2cc */ SDL_SCANCODE_UNKNOWN,
/* 717, 0x2cd */ SDL_SCANCODE_UNKNOWN,
/* 718, 0x2ce */ SDL_SCANCODE_UNKNOWN,
/* 719, 0x2cf */ SDL_SCANCODE_UNKNOWN,
/* 720, 0x2d0 */ SDL_SCANCODE_UNKNOWN,
/* 721, 0x2d1 */ SDL_SCANCODE_UNKNOWN,
/* 722, 0x2d2 */ SDL_SCANCODE_UNKNOWN,
/* 723, 0x2d3 */ SDL_SCANCODE_UNKNOWN,
/* 724, 0x2d4 */ SDL_SCANCODE_UNKNOWN,
/* 725, 0x2d5 */ SDL_SCANCODE_UNKNOWN,
/* 726, 0x2d6 */ SDL_SCANCODE_UNKNOWN,
/* 727, 0x2d7 */ SDL_SCANCODE_UNKNOWN,
/* 728, 0x2d8 */ SDL_SCANCODE_UNKNOWN,
/* 729, 0x2d9 */ SDL_SCANCODE_UNKNOWN,
/* 730, 0x2da */ SDL_SCANCODE_UNKNOWN,
/* 731, 0x2db */ SDL_SCANCODE_UNKNOWN,
/* 732, 0x2dc */ SDL_SCANCODE_UNKNOWN,
/* 733, 0x2dd */ SDL_SCANCODE_UNKNOWN,
/* 734, 0x2de */ SDL_SCANCODE_UNKNOWN,
/* 735, 0x2df */ SDL_SCANCODE_UNKNOWN,
/* 736, 0x2e0 */ SDL_SCANCODE_UNKNOWN,
/* 737, 0x2e1 */ SDL_SCANCODE_UNKNOWN,
/* 738, 0x2e2 */ SDL_SCANCODE_UNKNOWN,
/* 739, 0x2e3 */ SDL_SCANCODE_UNKNOWN,
/* 740, 0x2e4 */ SDL_SCANCODE_UNKNOWN,
/* 741, 0x2e5 */ SDL_SCANCODE_UNKNOWN,
/* 742, 0x2e6 */ SDL_SCANCODE_UNKNOWN,
/* 743, 0x2e7 */ SDL_SCANCODE_UNKNOWN,
/* 744, 0x2e8 */ SDL_SCANCODE_UNKNOWN,
/* 745, 0x2e9 */ SDL_SCANCODE_UNKNOWN,
/* 746, 0x2ea */ SDL_SCANCODE_UNKNOWN,
/* 747, 0x2eb */ SDL_SCANCODE_UNKNOWN,
/* 748, 0x2ec */ SDL_SCANCODE_UNKNOWN,
/* 749, 0x2ed */ SDL_SCANCODE_UNKNOWN,
/* 750, 0x2ee */ SDL_SCANCODE_UNKNOWN,
/* 751, 0x2ef */ SDL_SCANCODE_UNKNOWN,
/* 752, 0x2f0 */ SDL_SCANCODE_UNKNOWN,
/* 753, 0x2f1 */ SDL_SCANCODE_UNKNOWN,
/* 754, 0x2f2 */ SDL_SCANCODE_UNKNOWN,
/* 755, 0x2f3 */ SDL_SCANCODE_UNKNOWN,
/* 756, 0x2f4 */ SDL_SCANCODE_UNKNOWN,
/* 757, 0x2f5 */ SDL_SCANCODE_UNKNOWN,
/* 758, 0x2f6 */ SDL_SCANCODE_UNKNOWN,
/* 759, 0x2f7 */ SDL_SCANCODE_UNKNOWN,
/* 760, 0x2f8 */ SDL_SCANCODE_UNKNOWN,
/* 761, 0x2f9 */ SDL_SCANCODE_UNKNOWN,
/* 762, 0x2fa */ SDL_SCANCODE_UNKNOWN,
/* 763, 0x2fb */ SDL_SCANCODE_UNKNOWN,
/* 764, 0x2fc */ SDL_SCANCODE_UNKNOWN,
/* 765, 0x2fd */ SDL_SCANCODE_UNKNOWN,
/* 766, 0x2fe */ SDL_SCANCODE_UNKNOWN,
/* 767, 0x2ff */ SDL_SCANCODE_UNKNOWN, // KEY_MAX
#endif // 0
};
#if 0 // A shell script to update the Linux key names in this file
#!/bin/bash
function get_keyname
{
value=$(echo "$1" | awk '{print $3}')
grep -F KEY_ /usr/include/linux/input-event-codes.h | while read line; do
read -ra fields <<<"$line"
if [ "${fields[2]}" = "$value" ]; then
echo "${fields[1]}"
return
fi
done
}
grep -F SDL_SCANCODE scancodes_linux.h | while read line; do
if [ $(echo "$line" | awk '{print NF}') -eq 5 ]; then
name=$(get_keyname "$line")
if [ "$name" != "" ]; then
echo " $line /* $name */"
continue
fi
fi
echo " $line"
done
#endif // end script
#if 0 // A shell script to get comments from the Linux header for these keys
#!/bin/bash
function get_comment
{
name=$(echo "$1" | awk '{print $7}')
if [ "$name" != "" ]; then
grep -E "$name\s" /usr/include/linux/input-event-codes.h | grep -F "/*" | sed 's,[^/]*/,/,'
fi
}
grep -F SDL_SCANCODE scancodes_linux.h | while read line; do
comment=$(get_comment "$line")
if [ "$comment" != "" ]; then
echo " $line $comment"
fi
done
#endif // end script
/* *INDENT-ON* */ // clang-format on

View file

@ -0,0 +1,286 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
/*
* Windows scancode to SDL scancode mapping table
* https://learn.microsoft.com/windows/win32/inputdev/about-keyboard-input#scan-codes */
/* *INDENT-OFF* */ // clang-format off
static const SDL_Scancode windows_scancode_table[] = {
/*0x00*/ SDL_SCANCODE_UNKNOWN,
/*0x01*/ SDL_SCANCODE_ESCAPE,
/*0x02*/ SDL_SCANCODE_1,
/*0x03*/ SDL_SCANCODE_2,
/*0x04*/ SDL_SCANCODE_3,
/*0x05*/ SDL_SCANCODE_4,
/*0x06*/ SDL_SCANCODE_5,
/*0x07*/ SDL_SCANCODE_6,
/*0x08*/ SDL_SCANCODE_7,
/*0x09*/ SDL_SCANCODE_8,
/*0x0a*/ SDL_SCANCODE_9,
/*0x0b*/ SDL_SCANCODE_0,
/*0x0c*/ SDL_SCANCODE_MINUS,
/*0x0d*/ SDL_SCANCODE_EQUALS,
/*0x0e*/ SDL_SCANCODE_BACKSPACE,
/*0x0f*/ SDL_SCANCODE_TAB,
/*0x10*/ SDL_SCANCODE_Q,
/*0x11*/ SDL_SCANCODE_W,
/*0x12*/ SDL_SCANCODE_E,
/*0x13*/ SDL_SCANCODE_R,
/*0x14*/ SDL_SCANCODE_T,
/*0x15*/ SDL_SCANCODE_Y,
/*0x16*/ SDL_SCANCODE_U,
/*0x17*/ SDL_SCANCODE_I,
/*0x18*/ SDL_SCANCODE_O,
/*0x19*/ SDL_SCANCODE_P,
/*0x1a*/ SDL_SCANCODE_LEFTBRACKET,
/*0x1b*/ SDL_SCANCODE_RIGHTBRACKET,
/*0x1c*/ SDL_SCANCODE_RETURN,
/*0x1d*/ SDL_SCANCODE_LCTRL,
/*0x1e*/ SDL_SCANCODE_A,
/*0x1f*/ SDL_SCANCODE_S,
/*0x20*/ SDL_SCANCODE_D,
/*0x21*/ SDL_SCANCODE_F,
/*0x22*/ SDL_SCANCODE_G,
/*0x23*/ SDL_SCANCODE_H,
/*0x24*/ SDL_SCANCODE_J,
/*0x25*/ SDL_SCANCODE_K,
/*0x26*/ SDL_SCANCODE_L,
/*0x27*/ SDL_SCANCODE_SEMICOLON,
/*0x28*/ SDL_SCANCODE_APOSTROPHE,
/*0x29*/ SDL_SCANCODE_GRAVE,
/*0x2a*/ SDL_SCANCODE_LSHIFT,
/*0x2b*/ SDL_SCANCODE_BACKSLASH,
/*0x2c*/ SDL_SCANCODE_Z,
/*0x2d*/ SDL_SCANCODE_X,
/*0x2e*/ SDL_SCANCODE_C,
/*0x2f*/ SDL_SCANCODE_V,
/*0x30*/ SDL_SCANCODE_B,
/*0x31*/ SDL_SCANCODE_N,
/*0x32*/ SDL_SCANCODE_M,
/*0x33*/ SDL_SCANCODE_COMMA,
/*0x34*/ SDL_SCANCODE_PERIOD,
/*0x35*/ SDL_SCANCODE_SLASH,
/*0x36*/ SDL_SCANCODE_RSHIFT,
/*0x37*/ SDL_SCANCODE_KP_MULTIPLY,
/*0x38*/ SDL_SCANCODE_LALT,
/*0x39*/ SDL_SCANCODE_SPACE,
/*0x3a*/ SDL_SCANCODE_CAPSLOCK,
/*0x3b*/ SDL_SCANCODE_F1,
/*0x3c*/ SDL_SCANCODE_F2,
/*0x3d*/ SDL_SCANCODE_F3,
/*0x3e*/ SDL_SCANCODE_F4,
/*0x3f*/ SDL_SCANCODE_F5,
/*0x40*/ SDL_SCANCODE_F6,
/*0x41*/ SDL_SCANCODE_F7,
/*0x42*/ SDL_SCANCODE_F8,
/*0x43*/ SDL_SCANCODE_F9,
/*0x44*/ SDL_SCANCODE_F10,
/*0x45*/ SDL_SCANCODE_NUMLOCKCLEAR,
/*0x46*/ SDL_SCANCODE_SCROLLLOCK,
/*0x47*/ SDL_SCANCODE_KP_7,
/*0x48*/ SDL_SCANCODE_KP_8,
/*0x49*/ SDL_SCANCODE_KP_9,
/*0x4a*/ SDL_SCANCODE_KP_MINUS,
/*0x4b*/ SDL_SCANCODE_KP_4,
/*0x4c*/ SDL_SCANCODE_KP_5,
/*0x4d*/ SDL_SCANCODE_KP_6,
/*0x4e*/ SDL_SCANCODE_KP_PLUS,
/*0x4f*/ SDL_SCANCODE_KP_1,
/*0x50*/ SDL_SCANCODE_KP_2,
/*0x51*/ SDL_SCANCODE_KP_3,
/*0x52*/ SDL_SCANCODE_KP_0,
/*0x53*/ SDL_SCANCODE_KP_PERIOD,
/*0x54*/ SDL_SCANCODE_UNKNOWN,
/*0x55*/ SDL_SCANCODE_UNKNOWN,
/*0x56*/ SDL_SCANCODE_NONUSBACKSLASH,
/*0x57*/ SDL_SCANCODE_F11,
/*0x58*/ SDL_SCANCODE_F12,
/*0x59*/ SDL_SCANCODE_KP_EQUALS,
/*0x5a*/ SDL_SCANCODE_UNKNOWN,
/*0x5b*/ SDL_SCANCODE_UNKNOWN,
/*0x5c*/ SDL_SCANCODE_INTERNATIONAL6,
/*0x5d*/ SDL_SCANCODE_UNKNOWN,
/*0x5e*/ SDL_SCANCODE_UNKNOWN,
/*0x5f*/ SDL_SCANCODE_UNKNOWN,
/*0x60*/ SDL_SCANCODE_UNKNOWN,
/*0x61*/ SDL_SCANCODE_UNKNOWN,
/*0x62*/ SDL_SCANCODE_UNKNOWN,
/*0x63*/ SDL_SCANCODE_UNKNOWN,
/*0x64*/ SDL_SCANCODE_F13,
/*0x65*/ SDL_SCANCODE_F14,
/*0x66*/ SDL_SCANCODE_F15,
/*0x67*/ SDL_SCANCODE_F16,
/*0x68*/ SDL_SCANCODE_F17,
/*0x69*/ SDL_SCANCODE_F18,
/*0x6a*/ SDL_SCANCODE_F19,
/*0x6b*/ SDL_SCANCODE_F20,
/*0x6c*/ SDL_SCANCODE_F21,
/*0x6d*/ SDL_SCANCODE_F22,
/*0x6e*/ SDL_SCANCODE_F23,
/*0x6f*/ SDL_SCANCODE_UNKNOWN,
/*0x70*/ SDL_SCANCODE_INTERNATIONAL2,
/*0x71*/ SDL_SCANCODE_LANG2,
/*0x72*/ SDL_SCANCODE_LANG1,
/*0x73*/ SDL_SCANCODE_INTERNATIONAL1,
/*0x74*/ SDL_SCANCODE_UNKNOWN,
/*0x75*/ SDL_SCANCODE_UNKNOWN,
/*0x76*/ SDL_SCANCODE_F24,
/*0x77*/ SDL_SCANCODE_LANG4,
/*0x78*/ SDL_SCANCODE_LANG3,
/*0x79*/ SDL_SCANCODE_INTERNATIONAL4,
/*0x7a*/ SDL_SCANCODE_UNKNOWN,
/*0x7b*/ SDL_SCANCODE_INTERNATIONAL5,
/*0x7c*/ SDL_SCANCODE_UNKNOWN,
/*0x7d*/ SDL_SCANCODE_INTERNATIONAL3,
/*0x7e*/ SDL_SCANCODE_KP_COMMA,
/*0x7f*/ SDL_SCANCODE_UNKNOWN,
/*0xe000*/ SDL_SCANCODE_UNKNOWN,
/*0xe001*/ SDL_SCANCODE_UNKNOWN,
/*0xe002*/ SDL_SCANCODE_UNKNOWN,
/*0xe003*/ SDL_SCANCODE_UNKNOWN,
/*0xe004*/ SDL_SCANCODE_UNKNOWN,
/*0xe005*/ SDL_SCANCODE_UNKNOWN,
/*0xe006*/ SDL_SCANCODE_UNKNOWN,
/*0xe007*/ SDL_SCANCODE_UNKNOWN,
/*0xe008*/ SDL_SCANCODE_UNKNOWN,
/*0xe009*/ SDL_SCANCODE_UNKNOWN,
/*0xe00a*/ SDL_SCANCODE_PASTE,
/*0xe00b*/ SDL_SCANCODE_UNKNOWN,
/*0xe00c*/ SDL_SCANCODE_UNKNOWN,
/*0xe00d*/ SDL_SCANCODE_UNKNOWN,
/*0xe00e*/ SDL_SCANCODE_UNKNOWN,
/*0xe00f*/ SDL_SCANCODE_UNKNOWN,
/*0xe010*/ SDL_SCANCODE_MEDIA_PREVIOUS_TRACK,
/*0xe011*/ SDL_SCANCODE_UNKNOWN,
/*0xe012*/ SDL_SCANCODE_UNKNOWN,
/*0xe013*/ SDL_SCANCODE_UNKNOWN,
/*0xe014*/ SDL_SCANCODE_UNKNOWN,
/*0xe015*/ SDL_SCANCODE_UNKNOWN,
/*0xe016*/ SDL_SCANCODE_UNKNOWN,
/*0xe017*/ SDL_SCANCODE_CUT,
/*0xe018*/ SDL_SCANCODE_COPY,
/*0xe019*/ SDL_SCANCODE_MEDIA_NEXT_TRACK,
/*0xe01a*/ SDL_SCANCODE_UNKNOWN,
/*0xe01b*/ SDL_SCANCODE_UNKNOWN,
/*0xe01c*/ SDL_SCANCODE_KP_ENTER,
/*0xe01d*/ SDL_SCANCODE_RCTRL,
/*0xe01e*/ SDL_SCANCODE_UNKNOWN,
/*0xe01f*/ SDL_SCANCODE_UNKNOWN,
/*0xe020*/ SDL_SCANCODE_MUTE,
/*0xe021*/ SDL_SCANCODE_UNKNOWN, // LaunchApp2
/*0xe022*/ SDL_SCANCODE_MEDIA_PLAY_PAUSE,
/*0xe023*/ SDL_SCANCODE_UNKNOWN,
/*0xe024*/ SDL_SCANCODE_MEDIA_STOP,
/*0xe025*/ SDL_SCANCODE_UNKNOWN,
/*0xe026*/ SDL_SCANCODE_UNKNOWN,
/*0xe027*/ SDL_SCANCODE_UNKNOWN,
/*0xe028*/ SDL_SCANCODE_UNKNOWN,
/*0xe029*/ SDL_SCANCODE_UNKNOWN,
/*0xe02a*/ SDL_SCANCODE_UNKNOWN,
/*0xe02b*/ SDL_SCANCODE_UNKNOWN,
/*0xe02c*/ SDL_SCANCODE_MEDIA_EJECT,
/*0xe02d*/ SDL_SCANCODE_UNKNOWN,
/*0xe02e*/ SDL_SCANCODE_VOLUMEDOWN,
/*0xe02f*/ SDL_SCANCODE_UNKNOWN,
/*0xe030*/ SDL_SCANCODE_VOLUMEUP,
/*0xe031*/ SDL_SCANCODE_UNKNOWN,
/*0xe032*/ SDL_SCANCODE_AC_HOME,
/*0xe033*/ SDL_SCANCODE_UNKNOWN,
/*0xe034*/ SDL_SCANCODE_UNKNOWN,
/*0xe035*/ SDL_SCANCODE_KP_DIVIDE,
/*0xe036*/ SDL_SCANCODE_UNKNOWN,
/*0xe037*/ SDL_SCANCODE_PRINTSCREEN,
/*0xe038*/ SDL_SCANCODE_RALT,
/*0xe039*/ SDL_SCANCODE_UNKNOWN,
/*0xe03a*/ SDL_SCANCODE_UNKNOWN,
/*0xe03b*/ SDL_SCANCODE_HELP,
/*0xe03c*/ SDL_SCANCODE_UNKNOWN,
/*0xe03d*/ SDL_SCANCODE_UNKNOWN,
/*0xe03e*/ SDL_SCANCODE_UNKNOWN,
/*0xe03f*/ SDL_SCANCODE_UNKNOWN,
/*0xe040*/ SDL_SCANCODE_UNKNOWN,
/*0xe041*/ SDL_SCANCODE_UNKNOWN,
/*0xe042*/ SDL_SCANCODE_UNKNOWN,
/*0xe043*/ SDL_SCANCODE_UNKNOWN,
/*0xe044*/ SDL_SCANCODE_UNKNOWN,
/*0xe045*/ SDL_SCANCODE_NUMLOCKCLEAR,
/*0xe046*/ SDL_SCANCODE_PAUSE,
/*0xe047*/ SDL_SCANCODE_HOME,
/*0xe048*/ SDL_SCANCODE_UP,
/*0xe049*/ SDL_SCANCODE_PAGEUP,
/*0xe04a*/ SDL_SCANCODE_UNKNOWN,
/*0xe04b*/ SDL_SCANCODE_LEFT,
/*0xe04c*/ SDL_SCANCODE_UNKNOWN,
/*0xe04d*/ SDL_SCANCODE_RIGHT,
/*0xe04e*/ SDL_SCANCODE_UNKNOWN,
/*0xe04f*/ SDL_SCANCODE_END,
/*0xe050*/ SDL_SCANCODE_DOWN,
/*0xe051*/ SDL_SCANCODE_PAGEDOWN,
/*0xe052*/ SDL_SCANCODE_INSERT,
/*0xe053*/ SDL_SCANCODE_DELETE,
/*0xe054*/ SDL_SCANCODE_UNKNOWN,
/*0xe055*/ SDL_SCANCODE_UNKNOWN,
/*0xe056*/ SDL_SCANCODE_UNKNOWN,
/*0xe057*/ SDL_SCANCODE_UNKNOWN,
/*0xe058*/ SDL_SCANCODE_UNKNOWN,
/*0xe059*/ SDL_SCANCODE_UNKNOWN,
/*0xe05a*/ SDL_SCANCODE_UNKNOWN,
/*0xe05b*/ SDL_SCANCODE_LGUI,
/*0xe05c*/ SDL_SCANCODE_RGUI,
/*0xe05d*/ SDL_SCANCODE_APPLICATION,
/*0xe05e*/ SDL_SCANCODE_POWER,
/*0xe05f*/ SDL_SCANCODE_SLEEP,
/*0xe060*/ SDL_SCANCODE_UNKNOWN,
/*0xe061*/ SDL_SCANCODE_UNKNOWN,
/*0xe062*/ SDL_SCANCODE_UNKNOWN,
/*0xe063*/ SDL_SCANCODE_UNKNOWN,
/*0xe064*/ SDL_SCANCODE_UNKNOWN,
/*0xe065*/ SDL_SCANCODE_AC_SEARCH,
/*0xe066*/ SDL_SCANCODE_AC_BOOKMARKS,
/*0xe067*/ SDL_SCANCODE_AC_REFRESH,
/*0xe068*/ SDL_SCANCODE_AC_STOP,
/*0xe069*/ SDL_SCANCODE_AC_FORWARD,
/*0xe06a*/ SDL_SCANCODE_AC_BACK,
/*0xe06b*/ SDL_SCANCODE_UNKNOWN, // LaunchApp1
/*0xe06c*/ SDL_SCANCODE_UNKNOWN, // LaunchMail
/*0xe06d*/ SDL_SCANCODE_MEDIA_SELECT,
/*0xe06e*/ SDL_SCANCODE_UNKNOWN,
/*0xe06f*/ SDL_SCANCODE_UNKNOWN,
/*0xe070*/ SDL_SCANCODE_UNKNOWN,
/*0xe071*/ SDL_SCANCODE_UNKNOWN,
/*0xe072*/ SDL_SCANCODE_UNKNOWN,
/*0xe073*/ SDL_SCANCODE_UNKNOWN,
/*0xe074*/ SDL_SCANCODE_UNKNOWN,
/*0xe075*/ SDL_SCANCODE_UNKNOWN,
/*0xe076*/ SDL_SCANCODE_UNKNOWN,
/*0xe077*/ SDL_SCANCODE_UNKNOWN,
/*0xe078*/ SDL_SCANCODE_UNKNOWN,
/*0xe079*/ SDL_SCANCODE_UNKNOWN,
/*0xe07a*/ SDL_SCANCODE_UNKNOWN,
/*0xe07b*/ SDL_SCANCODE_UNKNOWN,
/*0xe07c*/ SDL_SCANCODE_UNKNOWN,
/*0xe07d*/ SDL_SCANCODE_UNKNOWN,
/*0xe07e*/ SDL_SCANCODE_UNKNOWN,
/*0xe07f*/ SDL_SCANCODE_UNKNOWN
};
/* *INDENT-ON* */ // clang-format on

View file

@ -0,0 +1,520 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef scancodes_xfree86_h_
#define scancodes_xfree86_h_
/* XFree86 key code to SDL scancode mapping table
Sources:
- atKeyNames.h from XFree86 source code
*/
/* *INDENT-OFF* */ // clang-format off
static const SDL_Scancode xfree86_scancode_table[] = {
/* 0 */ SDL_SCANCODE_UNKNOWN,
/* 1 */ SDL_SCANCODE_ESCAPE,
/* 2 */ SDL_SCANCODE_1,
/* 3 */ SDL_SCANCODE_2,
/* 4 */ SDL_SCANCODE_3,
/* 5 */ SDL_SCANCODE_4,
/* 6 */ SDL_SCANCODE_5,
/* 7 */ SDL_SCANCODE_6,
/* 8 */ SDL_SCANCODE_7,
/* 9 */ SDL_SCANCODE_8,
/* 10 */ SDL_SCANCODE_9,
/* 11 */ SDL_SCANCODE_0,
/* 12 */ SDL_SCANCODE_MINUS,
/* 13 */ SDL_SCANCODE_EQUALS,
/* 14 */ SDL_SCANCODE_BACKSPACE,
/* 15 */ SDL_SCANCODE_TAB,
/* 16 */ SDL_SCANCODE_Q,
/* 17 */ SDL_SCANCODE_W,
/* 18 */ SDL_SCANCODE_E,
/* 19 */ SDL_SCANCODE_R,
/* 20 */ SDL_SCANCODE_T,
/* 21 */ SDL_SCANCODE_Y,
/* 22 */ SDL_SCANCODE_U,
/* 23 */ SDL_SCANCODE_I,
/* 24 */ SDL_SCANCODE_O,
/* 25 */ SDL_SCANCODE_P,
/* 26 */ SDL_SCANCODE_LEFTBRACKET,
/* 27 */ SDL_SCANCODE_RIGHTBRACKET,
/* 28 */ SDL_SCANCODE_RETURN,
/* 29 */ SDL_SCANCODE_LCTRL,
/* 30 */ SDL_SCANCODE_A,
/* 31 */ SDL_SCANCODE_S,
/* 32 */ SDL_SCANCODE_D,
/* 33 */ SDL_SCANCODE_F,
/* 34 */ SDL_SCANCODE_G,
/* 35 */ SDL_SCANCODE_H,
/* 36 */ SDL_SCANCODE_J,
/* 37 */ SDL_SCANCODE_K,
/* 38 */ SDL_SCANCODE_L,
/* 39 */ SDL_SCANCODE_SEMICOLON,
/* 40 */ SDL_SCANCODE_APOSTROPHE,
/* 41 */ SDL_SCANCODE_GRAVE,
/* 42 */ SDL_SCANCODE_LSHIFT,
/* 43 */ SDL_SCANCODE_BACKSLASH,
/* 44 */ SDL_SCANCODE_Z,
/* 45 */ SDL_SCANCODE_X,
/* 46 */ SDL_SCANCODE_C,
/* 47 */ SDL_SCANCODE_V,
/* 48 */ SDL_SCANCODE_B,
/* 49 */ SDL_SCANCODE_N,
/* 50 */ SDL_SCANCODE_M,
/* 51 */ SDL_SCANCODE_COMMA,
/* 52 */ SDL_SCANCODE_PERIOD,
/* 53 */ SDL_SCANCODE_SLASH,
/* 54 */ SDL_SCANCODE_RSHIFT,
/* 55 */ SDL_SCANCODE_KP_MULTIPLY,
/* 56 */ SDL_SCANCODE_LALT,
/* 57 */ SDL_SCANCODE_SPACE,
/* 58 */ SDL_SCANCODE_CAPSLOCK,
/* 59 */ SDL_SCANCODE_F1,
/* 60 */ SDL_SCANCODE_F2,
/* 61 */ SDL_SCANCODE_F3,
/* 62 */ SDL_SCANCODE_F4,
/* 63 */ SDL_SCANCODE_F5,
/* 64 */ SDL_SCANCODE_F6,
/* 65 */ SDL_SCANCODE_F7,
/* 66 */ SDL_SCANCODE_F8,
/* 67 */ SDL_SCANCODE_F9,
/* 68 */ SDL_SCANCODE_F10,
/* 69 */ SDL_SCANCODE_NUMLOCKCLEAR,
/* 70 */ SDL_SCANCODE_SCROLLLOCK,
/* 71 */ SDL_SCANCODE_KP_7,
/* 72 */ SDL_SCANCODE_KP_8,
/* 73 */ SDL_SCANCODE_KP_9,
/* 74 */ SDL_SCANCODE_KP_MINUS,
/* 75 */ SDL_SCANCODE_KP_4,
/* 76 */ SDL_SCANCODE_KP_5,
/* 77 */ SDL_SCANCODE_KP_6,
/* 78 */ SDL_SCANCODE_KP_PLUS,
/* 79 */ SDL_SCANCODE_KP_1,
/* 80 */ SDL_SCANCODE_KP_2,
/* 81 */ SDL_SCANCODE_KP_3,
/* 82 */ SDL_SCANCODE_KP_0,
/* 83 */ SDL_SCANCODE_KP_PERIOD,
/* 84 */ SDL_SCANCODE_SYSREQ,
/* 85 */ SDL_SCANCODE_MODE,
/* 86 */ SDL_SCANCODE_NONUSBACKSLASH,
/* 87 */ SDL_SCANCODE_F11,
/* 88 */ SDL_SCANCODE_F12,
/* 89 */ SDL_SCANCODE_HOME,
/* 90 */ SDL_SCANCODE_UP,
/* 91 */ SDL_SCANCODE_PAGEUP,
/* 92 */ SDL_SCANCODE_LEFT,
/* 93 */ SDL_SCANCODE_UNKNOWN, // on PowerBook G4 / KEY_Begin
/* 94 */ SDL_SCANCODE_RIGHT,
/* 95 */ SDL_SCANCODE_END,
/* 96 */ SDL_SCANCODE_DOWN,
/* 97 */ SDL_SCANCODE_PAGEDOWN,
/* 98 */ SDL_SCANCODE_INSERT,
/* 99 */ SDL_SCANCODE_DELETE,
/* 100 */ SDL_SCANCODE_KP_ENTER,
/* 101 */ SDL_SCANCODE_RCTRL,
/* 102 */ SDL_SCANCODE_PAUSE,
/* 103 */ SDL_SCANCODE_PRINTSCREEN,
/* 104 */ SDL_SCANCODE_KP_DIVIDE,
/* 105 */ SDL_SCANCODE_RALT,
/* 106 */ SDL_SCANCODE_UNKNOWN, // BREAK
/* 107 */ SDL_SCANCODE_LGUI,
/* 108 */ SDL_SCANCODE_RGUI,
/* 109 */ SDL_SCANCODE_APPLICATION,
/* 110 */ SDL_SCANCODE_F13,
/* 111 */ SDL_SCANCODE_F14,
/* 112 */ SDL_SCANCODE_F15,
/* 113 */ SDL_SCANCODE_F16,
/* 114 */ SDL_SCANCODE_F17,
/* 115 */ SDL_SCANCODE_INTERNATIONAL1, // \_
/* 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 */
/* 117 */ SDL_SCANCODE_UNKNOWN,
/* 118 */ SDL_SCANCODE_KP_EQUALS,
/* 119 */ SDL_SCANCODE_UNKNOWN,
/* 120 */ SDL_SCANCODE_UNKNOWN,
/* 121 */ SDL_SCANCODE_INTERNATIONAL4, // Henkan_Mode
/* 122 */ SDL_SCANCODE_UNKNOWN,
/* 123 */ SDL_SCANCODE_INTERNATIONAL5, // Muhenkan
/* 124 */ SDL_SCANCODE_UNKNOWN,
/* 125 */ SDL_SCANCODE_INTERNATIONAL3, // Yen
/* 126 */ SDL_SCANCODE_UNKNOWN,
/* 127 */ SDL_SCANCODE_UNKNOWN,
/* 128 */ SDL_SCANCODE_UNKNOWN,
/* 129 */ SDL_SCANCODE_UNKNOWN,
/* 130 */ SDL_SCANCODE_UNKNOWN,
/* 131 */ SDL_SCANCODE_UNKNOWN,
/* 132 */ SDL_SCANCODE_POWER,
/* 133 */ SDL_SCANCODE_MUTE,
/* 134 */ SDL_SCANCODE_VOLUMEDOWN,
/* 135 */ SDL_SCANCODE_VOLUMEUP,
/* 136 */ SDL_SCANCODE_HELP,
/* 137 */ SDL_SCANCODE_STOP,
/* 138 */ SDL_SCANCODE_AGAIN,
/* 139 */ SDL_SCANCODE_UNKNOWN, // PROPS
/* 140 */ SDL_SCANCODE_UNDO,
/* 141 */ SDL_SCANCODE_UNKNOWN, // FRONT
/* 142 */ SDL_SCANCODE_COPY,
/* 143 */ SDL_SCANCODE_UNKNOWN, // OPEN
/* 144 */ SDL_SCANCODE_PASTE,
/* 145 */ SDL_SCANCODE_FIND,
/* 146 */ SDL_SCANCODE_CUT,
};
// This is largely identical to the Linux keycode mapping
static const SDL_Scancode xfree86_scancode_table2[] = {
/* 0, 0x000 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 1, 0x001 */ SDL_SCANCODE_ESCAPE, // Escape
/* 2, 0x002 */ SDL_SCANCODE_1, // 1
/* 3, 0x003 */ SDL_SCANCODE_2, // 2
/* 4, 0x004 */ SDL_SCANCODE_3, // 3
/* 5, 0x005 */ SDL_SCANCODE_4, // 4
/* 6, 0x006 */ SDL_SCANCODE_5, // 5
/* 7, 0x007 */ SDL_SCANCODE_6, // 6
/* 8, 0x008 */ SDL_SCANCODE_7, // 7
/* 9, 0x009 */ SDL_SCANCODE_8, // 8
/* 10, 0x00a */ SDL_SCANCODE_9, // 9
/* 11, 0x00b */ SDL_SCANCODE_0, // 0
/* 12, 0x00c */ SDL_SCANCODE_MINUS, // minus
/* 13, 0x00d */ SDL_SCANCODE_EQUALS, // equal
/* 14, 0x00e */ SDL_SCANCODE_BACKSPACE, // BackSpace
/* 15, 0x00f */ SDL_SCANCODE_TAB, // Tab
/* 16, 0x010 */ SDL_SCANCODE_Q, // q
/* 17, 0x011 */ SDL_SCANCODE_W, // w
/* 18, 0x012 */ SDL_SCANCODE_E, // e
/* 19, 0x013 */ SDL_SCANCODE_R, // r
/* 20, 0x014 */ SDL_SCANCODE_T, // t
/* 21, 0x015 */ SDL_SCANCODE_Y, // y
/* 22, 0x016 */ SDL_SCANCODE_U, // u
/* 23, 0x017 */ SDL_SCANCODE_I, // i
/* 24, 0x018 */ SDL_SCANCODE_O, // o
/* 25, 0x019 */ SDL_SCANCODE_P, // p
/* 26, 0x01a */ SDL_SCANCODE_LEFTBRACKET, // bracketleft
/* 27, 0x01b */ SDL_SCANCODE_RIGHTBRACKET, // bracketright
/* 28, 0x01c */ SDL_SCANCODE_RETURN, // Return
/* 29, 0x01d */ SDL_SCANCODE_LCTRL, // Control_L
/* 30, 0x01e */ SDL_SCANCODE_A, // a
/* 31, 0x01f */ SDL_SCANCODE_S, // s
/* 32, 0x020 */ SDL_SCANCODE_D, // d
/* 33, 0x021 */ SDL_SCANCODE_F, // f
/* 34, 0x022 */ SDL_SCANCODE_G, // g
/* 35, 0x023 */ SDL_SCANCODE_H, // h
/* 36, 0x024 */ SDL_SCANCODE_J, // j
/* 37, 0x025 */ SDL_SCANCODE_K, // k
/* 38, 0x026 */ SDL_SCANCODE_L, // l
/* 39, 0x027 */ SDL_SCANCODE_SEMICOLON, // semicolon
/* 40, 0x028 */ SDL_SCANCODE_APOSTROPHE, // apostrophe
/* 41, 0x029 */ SDL_SCANCODE_GRAVE, // grave
/* 42, 0x02a */ SDL_SCANCODE_LSHIFT, // Shift_L
/* 43, 0x02b */ SDL_SCANCODE_BACKSLASH, // backslash
/* 44, 0x02c */ SDL_SCANCODE_Z, // z
/* 45, 0x02d */ SDL_SCANCODE_X, // x
/* 46, 0x02e */ SDL_SCANCODE_C, // c
/* 47, 0x02f */ SDL_SCANCODE_V, // v
/* 48, 0x030 */ SDL_SCANCODE_B, // b
/* 49, 0x031 */ SDL_SCANCODE_N, // n
/* 50, 0x032 */ SDL_SCANCODE_M, // m
/* 51, 0x033 */ SDL_SCANCODE_COMMA, // comma
/* 52, 0x034 */ SDL_SCANCODE_PERIOD, // period
/* 53, 0x035 */ SDL_SCANCODE_SLASH, // slash
/* 54, 0x036 */ SDL_SCANCODE_RSHIFT, // Shift_R
/* 55, 0x037 */ SDL_SCANCODE_KP_MULTIPLY, // KP_Multiply
/* 56, 0x038 */ SDL_SCANCODE_LALT, // Alt_L
/* 57, 0x039 */ SDL_SCANCODE_SPACE, // space
/* 58, 0x03a */ SDL_SCANCODE_CAPSLOCK, // Caps_Lock
/* 59, 0x03b */ SDL_SCANCODE_F1, // F1
/* 60, 0x03c */ SDL_SCANCODE_F2, // F2
/* 61, 0x03d */ SDL_SCANCODE_F3, // F3
/* 62, 0x03e */ SDL_SCANCODE_F4, // F4
/* 63, 0x03f */ SDL_SCANCODE_F5, // F5
/* 64, 0x040 */ SDL_SCANCODE_F6, // F6
/* 65, 0x041 */ SDL_SCANCODE_F7, // F7
/* 66, 0x042 */ SDL_SCANCODE_F8, // F8
/* 67, 0x043 */ SDL_SCANCODE_F9, // F9
/* 68, 0x044 */ SDL_SCANCODE_F10, // F10
/* 69, 0x045 */ SDL_SCANCODE_NUMLOCKCLEAR, // Num_Lock
/* 70, 0x046 */ SDL_SCANCODE_SCROLLLOCK, // Scroll_Lock
/* 71, 0x047 */ SDL_SCANCODE_KP_7, // KP_Home
/* 72, 0x048 */ SDL_SCANCODE_KP_8, // KP_Up
/* 73, 0x049 */ SDL_SCANCODE_KP_9, // KP_Prior
/* 74, 0x04a */ SDL_SCANCODE_KP_MINUS, // KP_Subtract
/* 75, 0x04b */ SDL_SCANCODE_KP_4, // KP_Left
/* 76, 0x04c */ SDL_SCANCODE_KP_5, // KP_Begin
/* 77, 0x04d */ SDL_SCANCODE_KP_6, // KP_Right
/* 78, 0x04e */ SDL_SCANCODE_KP_PLUS, // KP_Add
/* 79, 0x04f */ SDL_SCANCODE_KP_1, // KP_End
/* 80, 0x050 */ SDL_SCANCODE_KP_2, // KP_Down
/* 81, 0x051 */ SDL_SCANCODE_KP_3, // KP_Next
/* 82, 0x052 */ SDL_SCANCODE_KP_0, // KP_Insert
/* 83, 0x053 */ SDL_SCANCODE_KP_PERIOD, // KP_Delete
/* 84, 0x054 */ SDL_SCANCODE_RALT, // ISO_Level3_Shift
/* 85, 0x055 */ SDL_SCANCODE_MODE, // ????
/* 86, 0x056 */ SDL_SCANCODE_NONUSBACKSLASH, // less
/* 87, 0x057 */ SDL_SCANCODE_F11, // F11
/* 88, 0x058 */ SDL_SCANCODE_F12, // F12
/* 89, 0x059 */ SDL_SCANCODE_INTERNATIONAL1, // \_
/* 90, 0x05a */ SDL_SCANCODE_LANG3, // Katakana
/* 91, 0x05b */ SDL_SCANCODE_LANG4, // Hiragana
/* 92, 0x05c */ SDL_SCANCODE_INTERNATIONAL4, // Henkan_Mode
/* 93, 0x05d */ SDL_SCANCODE_INTERNATIONAL2, // Hiragana_Katakana
/* 94, 0x05e */ SDL_SCANCODE_INTERNATIONAL5, // Muhenkan
/* 95, 0x05f */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 96, 0x060 */ SDL_SCANCODE_KP_ENTER, // KP_Enter
/* 97, 0x061 */ SDL_SCANCODE_RCTRL, // Control_R
/* 98, 0x062 */ SDL_SCANCODE_KP_DIVIDE, // KP_Divide
/* 99, 0x063 */ SDL_SCANCODE_PRINTSCREEN, // Print
/* 100, 0x064 */ SDL_SCANCODE_RALT, // ISO_Level3_Shift, ALTGR, RALT
/* 101, 0x065 */ SDL_SCANCODE_UNKNOWN, // Linefeed
/* 102, 0x066 */ SDL_SCANCODE_HOME, // Home
/* 103, 0x067 */ SDL_SCANCODE_UP, // Up
/* 104, 0x068 */ SDL_SCANCODE_PAGEUP, // Prior
/* 105, 0x069 */ SDL_SCANCODE_LEFT, // Left
/* 106, 0x06a */ SDL_SCANCODE_RIGHT, // Right
/* 107, 0x06b */ SDL_SCANCODE_END, // End
/* 108, 0x06c */ SDL_SCANCODE_DOWN, // Down
/* 109, 0x06d */ SDL_SCANCODE_PAGEDOWN, // Next
/* 110, 0x06e */ SDL_SCANCODE_INSERT, // Insert
/* 111, 0x06f */ SDL_SCANCODE_DELETE, // Delete
/* 112, 0x070 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 113, 0x071 */ SDL_SCANCODE_MUTE, // XF86AudioMute
/* 114, 0x072 */ SDL_SCANCODE_VOLUMEDOWN, // XF86AudioLowerVolume
/* 115, 0x073 */ SDL_SCANCODE_VOLUMEUP, // XF86AudioRaiseVolume
/* 116, 0x074 */ SDL_SCANCODE_POWER, // XF86PowerOff
/* 117, 0x075 */ SDL_SCANCODE_KP_EQUALS, // KP_Equal
/* 118, 0x076 */ SDL_SCANCODE_KP_PLUSMINUS, // plusminus
/* 119, 0x077 */ SDL_SCANCODE_PAUSE, // Pause
/* 120, 0x078 */ SDL_SCANCODE_UNKNOWN, // XF86LaunchA
/* 121, 0x079 */ SDL_SCANCODE_KP_PERIOD, // KP_Decimal
/* 122, 0x07a */ SDL_SCANCODE_LANG1, // Hangul
/* 123, 0x07b */ SDL_SCANCODE_LANG2, // Hangul_Hanja
/* 124, 0x07c */ SDL_SCANCODE_INTERNATIONAL3, // Yen
/* 125, 0x07d */ SDL_SCANCODE_LGUI, // Super_L
/* 126, 0x07e */ SDL_SCANCODE_RGUI, // Super_R
/* 127, 0x07f */ SDL_SCANCODE_APPLICATION, // Menu
/* 128, 0x080 */ SDL_SCANCODE_CANCEL, // Cancel
/* 129, 0x081 */ SDL_SCANCODE_AGAIN, // Redo
/* 130, 0x082 */ SDL_SCANCODE_UNKNOWN, // SunProps
/* 131, 0x083 */ SDL_SCANCODE_UNDO, // Undo
/* 132, 0x084 */ SDL_SCANCODE_UNKNOWN, // SunFront
/* 133, 0x085 */ SDL_SCANCODE_COPY, // XF86Copy
/* 134, 0x086 */ SDL_SCANCODE_UNKNOWN, // SunOpen, XF86Open
/* 135, 0x087 */ SDL_SCANCODE_PASTE, // XF86Paste
/* 136, 0x088 */ SDL_SCANCODE_FIND, // Find
/* 137, 0x089 */ SDL_SCANCODE_CUT, // XF86Cut
/* 138, 0x08a */ SDL_SCANCODE_HELP, // Help
/* 139, 0x08b */ SDL_SCANCODE_MENU, // XF86MenuKB
/* 140, 0x08c */ SDL_SCANCODE_UNKNOWN, // XF86Calculator
/* 141, 0x08d */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 142, 0x08e */ SDL_SCANCODE_SLEEP, // XF86Sleep
/* 143, 0x08f */ SDL_SCANCODE_UNKNOWN, // XF86WakeUp
/* 144, 0x090 */ SDL_SCANCODE_UNKNOWN, // XF86Explorer
/* 145, 0x091 */ SDL_SCANCODE_UNKNOWN, // XF86Send
/* 146, 0x092 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 147, 0x093 */ SDL_SCANCODE_UNKNOWN, // XF86Xfer
/* 148, 0x094 */ SDL_SCANCODE_UNKNOWN, // XF86Launch1
/* 149, 0x095 */ SDL_SCANCODE_UNKNOWN, // XF86Launch2
/* 150, 0x096 */ SDL_SCANCODE_UNKNOWN, // XF86WWW
/* 151, 0x097 */ SDL_SCANCODE_UNKNOWN, // XF86DOS
/* 152, 0x098 */ SDL_SCANCODE_UNKNOWN, // XF86ScreenSaver
/* 153, 0x099 */ SDL_SCANCODE_UNKNOWN, // XF86RotateWindows
/* 154, 0x09a */ SDL_SCANCODE_UNKNOWN, // XF86TaskPane
/* 155, 0x09b */ SDL_SCANCODE_UNKNOWN, // XF86Mail
/* 156, 0x09c */ SDL_SCANCODE_AC_BOOKMARKS, // XF86Favorites
/* 157, 0x09d */ SDL_SCANCODE_UNKNOWN, // XF86MyComputer
/* 158, 0x09e */ SDL_SCANCODE_AC_BACK, // XF86Back
/* 159, 0x09f */ SDL_SCANCODE_AC_FORWARD, // XF86Forward
/* 160, 0x0a0 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 161, 0x0a1 */ SDL_SCANCODE_MEDIA_EJECT, // XF86Eject
/* 162, 0x0a2 */ SDL_SCANCODE_MEDIA_EJECT, // XF86Eject
/* 163, 0x0a3 */ SDL_SCANCODE_MEDIA_NEXT_TRACK, // XF86AudioNext
/* 164, 0x0a4 */ SDL_SCANCODE_MEDIA_PLAY_PAUSE, // XF86AudioPlay
/* 165, 0x0a5 */ SDL_SCANCODE_MEDIA_PREVIOUS_TRACK, // XF86AudioPrev
/* 166, 0x0a6 */ SDL_SCANCODE_MEDIA_STOP, // XF86AudioStop
/* 167, 0x0a7 */ SDL_SCANCODE_MEDIA_RECORD, // XF86AudioRecord
/* 168, 0x0a8 */ SDL_SCANCODE_MEDIA_REWIND, // XF86AudioRewind
/* 169, 0x0a9 */ SDL_SCANCODE_UNKNOWN, // XF86Phone
/* 170, 0x0aa */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 171, 0x0ab */ SDL_SCANCODE_F13, // XF86Tools
/* 172, 0x0ac */ SDL_SCANCODE_AC_HOME, // XF86HomePage
/* 173, 0x0ad */ SDL_SCANCODE_AC_REFRESH, // XF86Reload
/* 174, 0x0ae */ SDL_SCANCODE_UNKNOWN, // XF86Close
/* 175, 0x0af */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 176, 0x0b0 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 177, 0x0b1 */ SDL_SCANCODE_UNKNOWN, // XF86ScrollUp
/* 178, 0x0b2 */ SDL_SCANCODE_UNKNOWN, // XF86ScrollDown
/* 179, 0x0b3 */ SDL_SCANCODE_KP_LEFTPAREN, // parenleft
/* 180, 0x0b4 */ SDL_SCANCODE_KP_RIGHTPAREN, // parenright
/* 181, 0x0b5 */ SDL_SCANCODE_AC_NEW, // XF86New
/* 182, 0x0b6 */ SDL_SCANCODE_AGAIN, // Redo
/* 183, 0x0b7 */ SDL_SCANCODE_F13, // XF86Tools
/* 184, 0x0b8 */ SDL_SCANCODE_F14, // XF86Launch5
/* 185, 0x0b9 */ SDL_SCANCODE_F15, // XF86Launch6
/* 186, 0x0ba */ SDL_SCANCODE_F16, // XF86Launch7
/* 187, 0x0bb */ SDL_SCANCODE_F17, // XF86Launch8
/* 188, 0x0bc */ SDL_SCANCODE_F18, // XF86Launch9
/* 189, 0x0bd */ SDL_SCANCODE_F19, // NoSymbol
/* 190, 0x0be */ SDL_SCANCODE_F20, // XF86AudioMicMute
/* 191, 0x0bf */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadToggle
/* 192, 0x0c0 */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadOn
/* 193, 0x0c1 */ SDL_SCANCODE_UNKNOWN, // XF86TouchpadOff
/* 194, 0x0c2 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 195, 0x0c3 */ SDL_SCANCODE_MODE, // Mode_switch
/* 196, 0x0c4 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 197, 0x0c5 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 198, 0x0c6 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 199, 0x0c7 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 200, 0x0c8 */ SDL_SCANCODE_MEDIA_PLAY, // XF86AudioPlay
/* 201, 0x0c9 */ SDL_SCANCODE_MEDIA_PAUSE, // XF86AudioPause
/* 202, 0x0ca */ SDL_SCANCODE_UNKNOWN, // XF86Launch3
/* 203, 0x0cb */ SDL_SCANCODE_UNKNOWN, // XF86Launch4
/* 204, 0x0cc */ SDL_SCANCODE_UNKNOWN, // XF86LaunchB
/* 205, 0x0cd */ SDL_SCANCODE_UNKNOWN, // XF86Suspend
/* 206, 0x0ce */ SDL_SCANCODE_AC_CLOSE, // XF86Close
/* 207, 0x0cf */ SDL_SCANCODE_MEDIA_PLAY, // XF86AudioPlay
/* 208, 0x0d0 */ SDL_SCANCODE_MEDIA_FAST_FORWARD, // XF86AudioForward
/* 209, 0x0d1 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 210, 0x0d2 */ SDL_SCANCODE_PRINTSCREEN, // Print
/* 211, 0x0d3 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 212, 0x0d4 */ SDL_SCANCODE_UNKNOWN, // XF86WebCam
/* 213, 0x0d5 */ SDL_SCANCODE_UNKNOWN, // XF86AudioPreset
/* 214, 0x0d6 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 215, 0x0d7 */ SDL_SCANCODE_UNKNOWN, // XF86Mail
/* 216, 0x0d8 */ SDL_SCANCODE_UNKNOWN, // XF86Messenger
/* 217, 0x0d9 */ SDL_SCANCODE_AC_SEARCH, // XF86Search
/* 218, 0x0da */ SDL_SCANCODE_UNKNOWN, // XF86Go
/* 219, 0x0db */ SDL_SCANCODE_UNKNOWN, // XF86Finance
/* 220, 0x0dc */ SDL_SCANCODE_UNKNOWN, // XF86Game
/* 221, 0x0dd */ SDL_SCANCODE_UNKNOWN, // XF86Shop
/* 222, 0x0de */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 223, 0x0df */ SDL_SCANCODE_CANCEL, // Cancel
/* 224, 0x0e0 */ SDL_SCANCODE_UNKNOWN, // XF86MonBrightnessDown
/* 225, 0x0e1 */ SDL_SCANCODE_UNKNOWN, // XF86MonBrightnessUp
/* 226, 0x0e2 */ SDL_SCANCODE_MEDIA_SELECT, // XF86AudioMedia
/* 227, 0x0e3 */ SDL_SCANCODE_UNKNOWN, // XF86Display
/* 228, 0x0e4 */ SDL_SCANCODE_UNKNOWN, // XF86KbdLightOnOff
/* 229, 0x0e5 */ SDL_SCANCODE_UNKNOWN, // XF86KbdBrightnessDown
/* 230, 0x0e6 */ SDL_SCANCODE_UNKNOWN, // XF86KbdBrightnessUp
/* 231, 0x0e7 */ SDL_SCANCODE_UNKNOWN, // XF86Send
/* 232, 0x0e8 */ SDL_SCANCODE_UNKNOWN, // XF86Reply
/* 233, 0x0e9 */ SDL_SCANCODE_UNKNOWN, // XF86MailForward
/* 234, 0x0ea */ SDL_SCANCODE_UNKNOWN, // XF86Save
/* 235, 0x0eb */ SDL_SCANCODE_UNKNOWN, // XF86Documents
/* 236, 0x0ec */ SDL_SCANCODE_UNKNOWN, // XF86Battery
/* 237, 0x0ed */ SDL_SCANCODE_UNKNOWN, // XF86Bluetooth
/* 238, 0x0ee */ SDL_SCANCODE_UNKNOWN, // XF86WLAN
/* 239, 0x0ef */ SDL_SCANCODE_UNKNOWN, // XF86UWB
/* 240, 0x0f0 */ SDL_SCANCODE_UNKNOWN, // NoSymbol
/* 241, 0x0f1 */ SDL_SCANCODE_UNKNOWN, // XF86Next_VMode
/* 242, 0x0f2 */ SDL_SCANCODE_UNKNOWN, // XF86Prev_VMode
/* 243, 0x0f3 */ SDL_SCANCODE_UNKNOWN, // XF86MonBrightnessCycle
/* 244, 0x0f4 */ SDL_SCANCODE_UNKNOWN, // XF86BrightnessAuto
/* 245, 0x0f5 */ SDL_SCANCODE_UNKNOWN, // XF86DisplayOff
/* 246, 0x0f6 */ SDL_SCANCODE_UNKNOWN, // XF86WWAN
/* 247, 0x0f7 */ SDL_SCANCODE_UNKNOWN, // XF86RFKill
};
// Xvnc / Xtightvnc scancodes from xmodmap -pk
static const SDL_Scancode xvnc_scancode_table[] = {
/* 0 */ SDL_SCANCODE_LCTRL,
/* 1 */ SDL_SCANCODE_RCTRL,
/* 2 */ SDL_SCANCODE_LSHIFT,
/* 3 */ SDL_SCANCODE_RSHIFT,
/* 4 */ SDL_SCANCODE_UNKNOWN, // Meta_L
/* 5 */ SDL_SCANCODE_UNKNOWN, // Meta_R
/* 6 */ SDL_SCANCODE_LALT,
/* 7 */ SDL_SCANCODE_RALT,
/* 8 */ SDL_SCANCODE_SPACE,
/* 9 */ SDL_SCANCODE_0,
/* 10 */ SDL_SCANCODE_1,
/* 11 */ SDL_SCANCODE_2,
/* 12 */ SDL_SCANCODE_3,
/* 13 */ SDL_SCANCODE_4,
/* 14 */ SDL_SCANCODE_5,
/* 15 */ SDL_SCANCODE_6,
/* 16 */ SDL_SCANCODE_7,
/* 17 */ SDL_SCANCODE_8,
/* 18 */ SDL_SCANCODE_9,
/* 19 */ SDL_SCANCODE_MINUS,
/* 20 */ SDL_SCANCODE_EQUALS,
/* 21 */ SDL_SCANCODE_LEFTBRACKET,
/* 22 */ SDL_SCANCODE_RIGHTBRACKET,
/* 23 */ SDL_SCANCODE_SEMICOLON,
/* 24 */ SDL_SCANCODE_APOSTROPHE,
/* 25 */ SDL_SCANCODE_GRAVE,
/* 26 */ SDL_SCANCODE_COMMA,
/* 27 */ SDL_SCANCODE_PERIOD,
/* 28 */ SDL_SCANCODE_SLASH,
/* 29 */ SDL_SCANCODE_BACKSLASH,
/* 30 */ SDL_SCANCODE_A,
/* 31 */ SDL_SCANCODE_B,
/* 32 */ SDL_SCANCODE_C,
/* 33 */ SDL_SCANCODE_D,
/* 34 */ SDL_SCANCODE_E,
/* 35 */ SDL_SCANCODE_F,
/* 36 */ SDL_SCANCODE_G,
/* 37 */ SDL_SCANCODE_H,
/* 38 */ SDL_SCANCODE_I,
/* 39 */ SDL_SCANCODE_J,
/* 40 */ SDL_SCANCODE_K,
/* 41 */ SDL_SCANCODE_L,
/* 42 */ SDL_SCANCODE_M,
/* 43 */ SDL_SCANCODE_N,
/* 44 */ SDL_SCANCODE_O,
/* 45 */ SDL_SCANCODE_P,
/* 46 */ SDL_SCANCODE_Q,
/* 47 */ SDL_SCANCODE_R,
/* 48 */ SDL_SCANCODE_S,
/* 49 */ SDL_SCANCODE_T,
/* 50 */ SDL_SCANCODE_U,
/* 51 */ SDL_SCANCODE_V,
/* 52 */ SDL_SCANCODE_W,
/* 53 */ SDL_SCANCODE_X,
/* 54 */ SDL_SCANCODE_Y,
/* 55 */ SDL_SCANCODE_Z,
/* 56 */ SDL_SCANCODE_BACKSPACE,
/* 57 */ SDL_SCANCODE_RETURN,
/* 58 */ SDL_SCANCODE_TAB,
/* 59 */ SDL_SCANCODE_ESCAPE,
/* 60 */ SDL_SCANCODE_DELETE,
/* 61 */ SDL_SCANCODE_HOME,
/* 62 */ SDL_SCANCODE_END,
/* 63 */ SDL_SCANCODE_PAGEUP,
/* 64 */ SDL_SCANCODE_PAGEDOWN,
/* 65 */ SDL_SCANCODE_UP,
/* 66 */ SDL_SCANCODE_DOWN,
/* 67 */ SDL_SCANCODE_LEFT,
/* 68 */ SDL_SCANCODE_RIGHT,
/* 69 */ SDL_SCANCODE_F1,
/* 70 */ SDL_SCANCODE_F2,
/* 71 */ SDL_SCANCODE_F3,
/* 72 */ SDL_SCANCODE_F4,
/* 73 */ SDL_SCANCODE_F5,
/* 74 */ SDL_SCANCODE_F6,
/* 75 */ SDL_SCANCODE_F7,
/* 76 */ SDL_SCANCODE_F8,
/* 77 */ SDL_SCANCODE_F9,
/* 78 */ SDL_SCANCODE_F10,
/* 79 */ SDL_SCANCODE_F11,
/* 80 */ SDL_SCANCODE_F12,
};
#endif // scancodes_xfree86_h_
/* *INDENT-ON* */ // clang-format on