release 0.1.0

This commit is contained in:
InoriRus
2022-05-21 22:04:50 +10:00
parent bc02c0560e
commit a37a9ca253
1056 changed files with 222884 additions and 41332 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
+1 -3
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
@@ -31,8 +31,6 @@ SDL_SendDisplayEvent(SDL_VideoDisplay *display, Uint8 displayevent, int data1)
{
int posted;
printf("SDL_SendDisplayEvent\n");
if (!display) {
return 0;
}
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
+525 -99
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
@@ -26,6 +26,7 @@
#include "SDL_events.h"
#include "SDL_thread.h"
#include "SDL_events_c.h"
#include "../SDL_hints_c.h"
#include "../timer/SDL_timer_c.h"
#if !SDL_JOYSTICK_DISABLED
#include "../joystick/SDL_joystick_c.h"
@@ -33,11 +34,19 @@
#include "../video/SDL_sysvideo.h"
#include "SDL_syswm.h"
/*#define SDL_DEBUG_EVENTS 1*/
#undef SDL_PRIs64
#if defined(__WIN32__) && !defined(__CYGWIN__)
#define SDL_PRIs64 "I64d"
#else
#define SDL_PRIs64 "lld"
#endif
/* An arbitrary limit so we don't have unbounded growth */
#define SDL_MAX_QUEUED_EVENTS 65535
/* Determines how often we wake to call SDL_PumpEvents() in SDL_WaitEventTimeout_Device() */
#define PERIODIC_POLL_INTERVAL_MS 3000
typedef struct SDL_EventWatcher {
SDL_EventFilter callback;
void *userdata;
@@ -50,6 +59,7 @@ static SDL_EventWatcher *SDL_event_watchers = NULL;
static int SDL_event_watchers_count = 0;
static SDL_bool SDL_event_watchers_dispatching = SDL_FALSE;
static SDL_bool SDL_event_watchers_removed = SDL_FALSE;
static SDL_atomic_t SDL_sentinel_pending;
typedef struct {
Uint32 bits[8];
@@ -87,51 +97,142 @@ static struct
} SDL_EventQ = { NULL, { 1 }, { 0 }, 0, NULL, NULL, NULL, NULL, NULL };
#ifdef SDL_DEBUG_EVENTS
#if !SDL_JOYSTICK_DISABLED
/* this is to make printf() calls cleaner. */
#define uint unsigned int
static SDL_bool SDL_update_joysticks = SDL_TRUE;
static void
SDL_DebugPrintEvent(const SDL_Event *event)
SDL_CalculateShouldUpdateJoysticks()
{
/* !!! FIXME: This code is kinda ugly, sorry. */
printf("SDL EVENT: ");
if (SDL_GetHintBoolean(SDL_HINT_AUTO_UPDATE_JOYSTICKS, SDL_TRUE) &&
(!SDL_disabled_events[SDL_JOYAXISMOTION >> 8] || SDL_JoystickEventState(SDL_QUERY))) {
SDL_update_joysticks = SDL_TRUE;
} else {
SDL_update_joysticks = SDL_FALSE;
}
}
if ((event->type >= SDL_USEREVENT) && (event->type <= SDL_LASTEVENT)) {
printf("SDL_USEREVENT");
if (event->type > SDL_USEREVENT) {
printf("+%u", ((uint) event->type) - SDL_USEREVENT);
}
printf(" (timestamp=%u windowid=%u code=%d data1=%p data2=%p)",
(uint) event->user.timestamp, (uint) event->user.windowID,
(int) event->user.code, event->user.data1, event->user.data2);
static void SDLCALL
SDL_AutoUpdateJoysticksChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_CalculateShouldUpdateJoysticks();
}
#endif /* !SDL_JOYSTICK_DISABLED */
#if !SDL_SENSOR_DISABLED
static SDL_bool SDL_update_sensors = SDL_TRUE;
static void
SDL_CalculateShouldUpdateSensors()
{
if (SDL_GetHintBoolean(SDL_HINT_AUTO_UPDATE_SENSORS, SDL_TRUE) &&
!SDL_disabled_events[SDL_SENSORUPDATE >> 8]) {
SDL_update_sensors = SDL_TRUE;
} else {
SDL_update_sensors = SDL_FALSE;
}
}
static void SDLCALL
SDL_AutoUpdateSensorsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_CalculateShouldUpdateSensors();
}
#endif /* !SDL_SENSOR_DISABLED */
static void SDLCALL
SDL_PollSentinelChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_EventState(SDL_POLLSENTINEL, SDL_GetStringBoolean(hint, SDL_TRUE) ? SDL_ENABLE : SDL_DISABLE);
}
/* 0 (default) means no logging, 1 means logging, 2 means logging with mouse and finger motion */
static int SDL_DoEventLogging = 0;
static void SDLCALL
SDL_EventLoggingChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_DoEventLogging = (hint && *hint) ? SDL_clamp(SDL_atoi(hint), 0, 2) : 0;
}
static void
SDL_LogEvent(const SDL_Event *event)
{
char name[32];
char details[128];
/* sensor/mouse/finger motion are spammy, ignore these if they aren't demanded. */
if ( (SDL_DoEventLogging < 2) &&
( (event->type == SDL_MOUSEMOTION) ||
(event->type == SDL_FINGERMOTION) ||
(event->type == SDL_CONTROLLERTOUCHPADMOTION) ||
(event->type == SDL_CONTROLLERSENSORUPDATE) ||
(event->type == SDL_SENSORUPDATE) ) ) {
return;
}
/* this is to make SDL_snprintf() calls cleaner. */
#define uint unsigned int
name[0] = '\0';
details[0] = '\0';
/* !!! FIXME: This code is kinda ugly, sorry. */
if ((event->type >= SDL_USEREVENT) && (event->type <= SDL_LASTEVENT)) {
char plusstr[16];
SDL_strlcpy(name, "SDL_USEREVENT", sizeof (name));
if (event->type > SDL_USEREVENT) {
SDL_snprintf(plusstr, sizeof (plusstr), "+%u", ((uint) event->type) - SDL_USEREVENT);
} else {
plusstr[0] = '\0';
}
SDL_snprintf(details, sizeof (details), "%s (timestamp=%u windowid=%u code=%d data1=%p data2=%p)",
plusstr, (uint) event->user.timestamp, (uint) event->user.windowID,
(int) event->user.code, event->user.data1, event->user.data2);
}
switch (event->type) {
#define SDL_EVENT_CASE(x) case x: printf("%s", #x);
SDL_EVENT_CASE(SDL_FIRSTEVENT) printf("(THIS IS PROBABLY A BUG!)"); break;
SDL_EVENT_CASE(SDL_QUIT) printf("(timestamp=%u)", (uint) event->quit.timestamp); break;
#define SDL_EVENT_CASE(x) case x: SDL_strlcpy(name, #x, sizeof (name));
SDL_EVENT_CASE(SDL_FIRSTEVENT) SDL_strlcpy(details, " (THIS IS PROBABLY A BUG!)", sizeof (details)); break;
SDL_EVENT_CASE(SDL_QUIT) SDL_snprintf(details, sizeof (details), " (timestamp=%u)", (uint) event->quit.timestamp); break;
SDL_EVENT_CASE(SDL_APP_TERMINATING) break;
SDL_EVENT_CASE(SDL_APP_LOWMEMORY) break;
SDL_EVENT_CASE(SDL_APP_WILLENTERBACKGROUND) break;
SDL_EVENT_CASE(SDL_APP_DIDENTERBACKGROUND) break;
SDL_EVENT_CASE(SDL_APP_WILLENTERFOREGROUND) break;
SDL_EVENT_CASE(SDL_APP_DIDENTERFOREGROUND) break;
SDL_EVENT_CASE(SDL_LOCALECHANGED) break;
SDL_EVENT_CASE(SDL_KEYMAPCHANGED) break;
SDL_EVENT_CASE(SDL_CLIPBOARDUPDATE) break;
SDL_EVENT_CASE(SDL_RENDER_TARGETS_RESET) break;
SDL_EVENT_CASE(SDL_RENDER_DEVICE_RESET) break;
#undef SDL_EVENT_CASE
#define SDL_EVENT_CASE(x) case x: printf("%s ", #x);
SDL_EVENT_CASE(SDL_DISPLAYEVENT) {
char name2[64];
switch (event->display.event) {
case SDL_DISPLAYEVENT_NONE: SDL_strlcpy(name2, "SDL_DISPLAYEVENT_NONE (THIS IS PROBABLY A BUG!)", sizeof(name2)); break;
#define SDL_DISPLAYEVENT_CASE(x) case x: SDL_strlcpy(name2, #x, sizeof (name2)); break
SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_ORIENTATION);
SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_CONNECTED);
SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_DISCONNECTED);
#undef SDL_DISPLAYEVENT_CASE
default: SDL_strlcpy(name2, "UNKNOWN (bug? fixme?)", sizeof(name2)); break;
}
SDL_snprintf(details, sizeof (details), " (timestamp=%u display=%u event=%s data1=%d)",
(uint) event->display.timestamp, (uint) event->display.display, name2, (int) event->display.data1);
break;
}
SDL_EVENT_CASE(SDL_WINDOWEVENT)
printf("(timestamp=%u windowid=%u event=", (uint) event->window.timestamp, (uint) event->window.windowID);
SDL_EVENT_CASE(SDL_WINDOWEVENT) {
char name2[64];
switch(event->window.event) {
case SDL_WINDOWEVENT_NONE: printf("none(THIS IS PROBABLY A BUG!)"); break;
#define SDL_WINDOWEVENT_CASE(x) case x: printf("%s", #x); break
case SDL_WINDOWEVENT_NONE: SDL_strlcpy(name2, "SDL_WINDOWEVENT_NONE (THIS IS PROBABLY A BUG!)", sizeof (name2)); break;
#define SDL_WINDOWEVENT_CASE(x) case x: SDL_strlcpy(name2, #x, sizeof (name2)); break
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_SHOWN);
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_HIDDEN);
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_EXPOSED);
@@ -148,19 +249,23 @@ SDL_DebugPrintEvent(const SDL_Event *event)
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_CLOSE);
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_TAKE_FOCUS);
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_HIT_TEST);
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_ICCPROF_CHANGED);
SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_DISPLAY_CHANGED);
#undef SDL_WINDOWEVENT_CASE
default: printf("UNKNOWN(bug? fixme?)"); break;
default: SDL_strlcpy(name2, "UNKNOWN (bug? fixme?)", sizeof (name2)); break;
}
printf(" data1=%d data2=%d)", (int) event->window.data1, (int) event->window.data2);
SDL_snprintf(details, sizeof (details), " (timestamp=%u windowid=%u event=%s data1=%d data2=%d)",
(uint) event->window.timestamp, (uint) event->window.windowID, name2, (int) event->window.data1, (int) event->window.data2);
break;
}
SDL_EVENT_CASE(SDL_SYSWMEVENT)
printf("(timestamp=%u)", (uint) event->syswm.timestamp);
/* !!! FIXME: we don't delve further at the moment. */
SDL_snprintf(details, sizeof (details), " (timestamp=%u)", (uint) event->syswm.timestamp);
break;
#define PRINT_KEY_EVENT(event) \
printf("(timestamp=%u windowid=%u state=%s repeat=%s scancode=%u keycode=%u mod=%u)", \
SDL_snprintf(details, sizeof (details), " (timestamp=%u windowid=%u state=%s repeat=%s scancode=%u keycode=%u mod=%u)", \
(uint) event->key.timestamp, (uint) event->key.windowID, \
event->key.state == SDL_PRESSED ? "pressed" : "released", \
event->key.repeat ? "true" : "false", \
@@ -172,18 +277,18 @@ SDL_DebugPrintEvent(const SDL_Event *event)
#undef PRINT_KEY_EVENT
SDL_EVENT_CASE(SDL_TEXTEDITING)
printf("(timestamp=%u windowid=%u text='%s' start=%d length=%d)",
SDL_snprintf(details, sizeof (details), " (timestamp=%u windowid=%u text='%s' start=%d length=%d)",
(uint) event->edit.timestamp, (uint) event->edit.windowID,
event->edit.text, (int) event->edit.start, (int) event->edit.length);
break;
SDL_EVENT_CASE(SDL_TEXTINPUT)
printf("(timestamp=%u windowid=%u text='%s')", (uint) event->text.timestamp, (uint) event->text.windowID, event->text.text);
SDL_snprintf(details, sizeof (details), " (timestamp=%u windowid=%u text='%s')", (uint) event->text.timestamp, (uint) event->text.windowID, event->text.text);
break;
SDL_EVENT_CASE(SDL_MOUSEMOTION)
printf("(timestamp=%u windowid=%u which=%u state=%u x=%d y=%d xrel=%d yrel=%d)",
SDL_snprintf(details, sizeof (details), " (timestamp=%u windowid=%u which=%u state=%u x=%d y=%d xrel=%d yrel=%d)",
(uint) event->motion.timestamp, (uint) event->motion.windowID,
(uint) event->motion.which, (uint) event->motion.state,
(int) event->motion.x, (int) event->motion.y,
@@ -191,7 +296,7 @@ SDL_DebugPrintEvent(const SDL_Event *event)
break;
#define PRINT_MBUTTON_EVENT(event) \
printf("(timestamp=%u windowid=%u which=%u button=%u state=%s clicks=%u x=%d y=%d)", \
SDL_snprintf(details, sizeof (details), " (timestamp=%u windowid=%u which=%u button=%u state=%s clicks=%u x=%d y=%d)", \
(uint) event->button.timestamp, (uint) event->button.windowID, \
(uint) event->button.which, (uint) event->button.button, \
event->button.state == SDL_PRESSED ? "pressed" : "released", \
@@ -202,67 +307,84 @@ SDL_DebugPrintEvent(const SDL_Event *event)
SDL_EVENT_CASE(SDL_MOUSEWHEEL)
printf("(timestamp=%u windowid=%u which=%u x=%d y=%d direction=%s)",
SDL_snprintf(details, sizeof (details), " (timestamp=%u windowid=%u which=%u x=%d y=%d preciseX=%f preciseY=%f direction=%s)",
(uint) event->wheel.timestamp, (uint) event->wheel.windowID,
(uint) event->wheel.which, (int) event->wheel.x, (int) event->wheel.y,
event->wheel.preciseX, event->wheel.preciseY,
event->wheel.direction == SDL_MOUSEWHEEL_NORMAL ? "normal" : "flipped");
break;
SDL_EVENT_CASE(SDL_JOYAXISMOTION)
printf("(timestamp=%u which=%d axis=%u value=%d)",
SDL_snprintf(details, sizeof (details), " (timestamp=%u which=%d axis=%u value=%d)",
(uint) event->jaxis.timestamp, (int) event->jaxis.which,
(uint) event->jaxis.axis, (int) event->jaxis.value);
break;
SDL_EVENT_CASE(SDL_JOYBALLMOTION)
printf("(timestamp=%u which=%d ball=%u xrel=%d yrel=%d)",
SDL_snprintf(details, sizeof (details), " (timestamp=%u which=%d ball=%u xrel=%d yrel=%d)",
(uint) event->jball.timestamp, (int) event->jball.which,
(uint) event->jball.ball, (int) event->jball.xrel, (int) event->jball.yrel);
break;
SDL_EVENT_CASE(SDL_JOYHATMOTION)
printf("(timestamp=%u which=%d hat=%u value=%u)",
SDL_snprintf(details, sizeof (details), " (timestamp=%u which=%d hat=%u value=%u)",
(uint) event->jhat.timestamp, (int) event->jhat.which,
(uint) event->jhat.hat, (uint) event->jhat.value);
break;
#define PRINT_JBUTTON_EVENT(event) \
printf("(timestamp=%u which=%d button=%u state=%s)", \
SDL_snprintf(details, sizeof (details), " (timestamp=%u which=%d button=%u state=%s)", \
(uint) event->jbutton.timestamp, (int) event->jbutton.which, \
(uint) event->jbutton.button, event->jbutton.state == SDL_PRESSED ? "pressed" : "released")
SDL_EVENT_CASE(SDL_JOYBUTTONDOWN) PRINT_JBUTTON_EVENT(event); break;
SDL_EVENT_CASE(SDL_JOYBUTTONUP) PRINT_JBUTTON_EVENT(event); break;
#undef PRINT_JBUTTON_EVENT
#define PRINT_JOYDEV_EVENT(event) printf("(timestamp=%u which=%d)", (uint) event->jdevice.timestamp, (int) event->jdevice.which)
#define PRINT_JOYDEV_EVENT(event) SDL_snprintf(details, sizeof (details), " (timestamp=%u which=%d)", (uint) event->jdevice.timestamp, (int) event->jdevice.which)
SDL_EVENT_CASE(SDL_JOYDEVICEADDED) PRINT_JOYDEV_EVENT(event); break;
SDL_EVENT_CASE(SDL_JOYDEVICEREMOVED) PRINT_JOYDEV_EVENT(event); break;
#undef PRINT_JOYDEV_EVENT
SDL_EVENT_CASE(SDL_CONTROLLERAXISMOTION)
printf("(timestamp=%u which=%d axis=%u value=%d)",
SDL_snprintf(details, sizeof (details), " (timestamp=%u which=%d axis=%u value=%d)",
(uint) event->caxis.timestamp, (int) event->caxis.which,
(uint) event->caxis.axis, (int) event->caxis.value);
break;
#define PRINT_CBUTTON_EVENT(event) \
printf("(timestamp=%u which=%d button=%u state=%s)", \
SDL_snprintf(details, sizeof (details), " (timestamp=%u which=%d button=%u state=%s)", \
(uint) event->cbutton.timestamp, (int) event->cbutton.which, \
(uint) event->cbutton.button, event->cbutton.state == SDL_PRESSED ? "pressed" : "released")
SDL_EVENT_CASE(SDL_CONTROLLERBUTTONDOWN) PRINT_CBUTTON_EVENT(event); break;
SDL_EVENT_CASE(SDL_CONTROLLERBUTTONUP) PRINT_CBUTTON_EVENT(event); break;
#undef PRINT_CBUTTON_EVENT
#define PRINT_CONTROLLERDEV_EVENT(event) printf("(timestamp=%u which=%d)", (uint) event->cdevice.timestamp, (int) event->cdevice.which)
#define PRINT_CONTROLLERDEV_EVENT(event) SDL_snprintf(details, sizeof (details), " (timestamp=%u which=%d)", (uint) event->cdevice.timestamp, (int) event->cdevice.which)
SDL_EVENT_CASE(SDL_CONTROLLERDEVICEADDED) PRINT_CONTROLLERDEV_EVENT(event); break;
SDL_EVENT_CASE(SDL_CONTROLLERDEVICEREMOVED) PRINT_CONTROLLERDEV_EVENT(event); break;
SDL_EVENT_CASE(SDL_CONTROLLERDEVICEREMAPPED) PRINT_CONTROLLERDEV_EVENT(event); break;
#undef PRINT_CONTROLLERDEV_EVENT
#define PRINT_CTOUCHPAD_EVENT(event) \
SDL_snprintf(details, sizeof (details), " (timestamp=%u which=%d touchpad=%d finger=%d x=%f y=%f pressure=%f)", \
(uint) event->ctouchpad.timestamp, (int) event->ctouchpad.which, \
(int) event->ctouchpad.touchpad, (int) event->ctouchpad.finger, \
event->ctouchpad.x, event->ctouchpad.y, event->ctouchpad.pressure)
SDL_EVENT_CASE(SDL_CONTROLLERTOUCHPADDOWN) PRINT_CTOUCHPAD_EVENT(event); break;
SDL_EVENT_CASE(SDL_CONTROLLERTOUCHPADUP) PRINT_CTOUCHPAD_EVENT(event); break;
SDL_EVENT_CASE(SDL_CONTROLLERTOUCHPADMOTION) PRINT_CTOUCHPAD_EVENT(event); break;
#undef PRINT_CTOUCHPAD_EVENT
SDL_EVENT_CASE(SDL_CONTROLLERSENSORUPDATE)
SDL_snprintf(details, sizeof (details), " (timestamp=%u which=%d sensor=%d data[0]=%f data[1]=%f data[2]=%f)", \
(uint) event->csensor.timestamp, (int) event->csensor.which, (int) event->csensor.sensor, \
event->csensor.data[0], event->csensor.data[1], event->csensor.data[2]);
break;
#define PRINT_FINGER_EVENT(event) \
printf("(timestamp=%u touchid=%lld fingerid=%lld x=%f y=%f dx=%f dy=%f pressure=%f)", \
(uint) event->tfinger.timestamp, (long long) event->tfinger.touchId, \
(long long) event->tfinger.fingerId, event->tfinger.x, event->tfinger.y, \
SDL_snprintf(details, sizeof (details), " (timestamp=%u touchid=%"SDL_PRIs64" fingerid=%"SDL_PRIs64" x=%f y=%f dx=%f dy=%f pressure=%f)", \
(uint) event->tfinger.timestamp, (long long)event->tfinger.touchId, \
(long long)event->tfinger.fingerId, event->tfinger.x, event->tfinger.y, \
event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure)
SDL_EVENT_CASE(SDL_FINGERDOWN) PRINT_FINGER_EVENT(event); break;
SDL_EVENT_CASE(SDL_FINGERUP) PRINT_FINGER_EVENT(event); break;
@@ -270,44 +392,60 @@ SDL_DebugPrintEvent(const SDL_Event *event)
#undef PRINT_FINGER_EVENT
#define PRINT_DOLLAR_EVENT(event) \
printf("(timestamp=%u touchid=%lld gestureid=%lld numfingers=%u error=%f x=%f y=%f)", \
(uint) event->dgesture.timestamp, (long long) event->dgesture.touchId, \
(long long) event->dgesture.gestureId, (uint) event->dgesture.numFingers, \
SDL_snprintf(details, sizeof (details), " (timestamp=%u touchid=%"SDL_PRIs64" gestureid=%"SDL_PRIs64" numfingers=%u error=%f x=%f y=%f)", \
(uint) event->dgesture.timestamp, (long long)event->dgesture.touchId, \
(long long)event->dgesture.gestureId, (uint) event->dgesture.numFingers, \
event->dgesture.error, event->dgesture.x, event->dgesture.y);
SDL_EVENT_CASE(SDL_DOLLARGESTURE) PRINT_DOLLAR_EVENT(event); break;
SDL_EVENT_CASE(SDL_DOLLARRECORD) PRINT_DOLLAR_EVENT(event); break;
#undef PRINT_DOLLAR_EVENT
SDL_EVENT_CASE(SDL_MULTIGESTURE)
printf("(timestamp=%u touchid=%lld dtheta=%f ddist=%f x=%f y=%f numfingers=%u)",
(uint) event->mgesture.timestamp, (long long) event->mgesture.touchId,
SDL_snprintf(details, sizeof (details), " (timestamp=%u touchid=%"SDL_PRIs64" dtheta=%f ddist=%f x=%f y=%f numfingers=%u)",
(uint) event->mgesture.timestamp, (long long)event->mgesture.touchId,
event->mgesture.dTheta, event->mgesture.dDist,
event->mgesture.x, event->mgesture.y, (uint) event->mgesture.numFingers);
break;
#define PRINT_DROP_EVENT(event) printf("(file='%s' timestamp=%u windowid=%u)", event->drop.file, (uint) event->drop.timestamp, (uint) event->drop.windowID)
#define PRINT_DROP_EVENT(event) SDL_snprintf(details, sizeof (details), " (file='%s' timestamp=%u windowid=%u)", event->drop.file, (uint) event->drop.timestamp, (uint) event->drop.windowID)
SDL_EVENT_CASE(SDL_DROPFILE) PRINT_DROP_EVENT(event); break;
SDL_EVENT_CASE(SDL_DROPTEXT) PRINT_DROP_EVENT(event); break;
SDL_EVENT_CASE(SDL_DROPBEGIN) PRINT_DROP_EVENT(event); break;
SDL_EVENT_CASE(SDL_DROPCOMPLETE) PRINT_DROP_EVENT(event); break;
#undef PRINT_DROP_EVENT
#define PRINT_AUDIODEV_EVENT(event) printf("(timestamp=%u which=%u iscapture=%s)", (uint) event->adevice.timestamp, (uint) event->adevice.which, event->adevice.iscapture ? "true" : "false");
#define PRINT_AUDIODEV_EVENT(event) SDL_snprintf(details, sizeof (details), " (timestamp=%u which=%u iscapture=%s)", (uint) event->adevice.timestamp, (uint) event->adevice.which, event->adevice.iscapture ? "true" : "false");
SDL_EVENT_CASE(SDL_AUDIODEVICEADDED) PRINT_AUDIODEV_EVENT(event); break;
SDL_EVENT_CASE(SDL_AUDIODEVICEREMOVED) PRINT_AUDIODEV_EVENT(event); break;
#undef PRINT_AUDIODEV_EVENT
SDL_EVENT_CASE(SDL_SENSORUPDATE)
SDL_snprintf(details, sizeof (details), " (timestamp=%u which=%d data[0]=%f data[1]=%f data[2]=%f data[3]=%f data[4]=%f data[5]=%f)", \
(uint) event->sensor.timestamp, (int) event->sensor.which, \
event->sensor.data[0], event->sensor.data[1], event->sensor.data[2], \
event->sensor.data[3], event->sensor.data[4], event->sensor.data[5]);
break;
#undef SDL_EVENT_CASE
case SDL_POLLSENTINEL:
/* No logging necessary for this one */
break;
default:
printf("UNKNOWN SDL EVENT #%u! (Bug? FIXME?)", (uint) event->type);
if (!name[0]) {
SDL_strlcpy(name, "UNKNOWN", sizeof (name));
SDL_snprintf(details, sizeof (details), " #%u! (Bug? FIXME?)", (uint) event->type);
}
break;
}
printf("\n");
if (name[0]) {
SDL_Log("SDL EVENT: %s%s", name, details);
}
#undef uint
}
#undef uint
#endif
@@ -361,6 +499,7 @@ SDL_StopEventLoop(void)
SDL_EventQ.free = NULL;
SDL_EventQ.wmmsg_used = NULL;
SDL_EventQ.wmmsg_free = NULL;
SDL_AtomicSet(&SDL_sentinel_pending, 0);
/* Clear disabled event state */
for (i = 0; i < SDL_arraysize(SDL_disabled_events); ++i) {
@@ -451,12 +590,14 @@ SDL_AddEvent(SDL_Event * event)
SDL_EventQ.free = entry->next;
}
#ifdef SDL_DEBUG_EVENTS
SDL_DebugPrintEvent(event);
#endif
if (SDL_DoEventLogging) {
SDL_LogEvent(event);
}
entry->event = *event;
if (event->type == SDL_SYSWMEVENT) {
if (event->type == SDL_POLLSENTINEL) {
SDL_AtomicAdd(&SDL_sentinel_pending, 1);
} else if (event->type == SDL_SYSWMEVENT) {
entry->msg = *event->syswm.msg;
entry->event.syswm.msg = &entry->msg;
}
@@ -502,23 +643,48 @@ SDL_CutEvent(SDL_EventEntry *entry)
SDL_EventQ.tail = entry->prev;
}
if (entry->event.type == SDL_POLLSENTINEL) {
SDL_AtomicAdd(&SDL_sentinel_pending, -1);
}
entry->next = SDL_EventQ.free;
SDL_EventQ.free = entry;
SDL_assert(SDL_AtomicGet(&SDL_EventQ.count) > 0);
SDL_AtomicAdd(&SDL_EventQ.count, -1);
}
/* Lock the event queue, take a peep at it, and unlock it */
int
SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action,
Uint32 minType, Uint32 maxType)
static int
SDL_SendWakeupEvent()
{
int i, used;
SDL_VideoDevice *_this = SDL_GetVideoDevice();
if (!_this || !_this->SendWakeupEvent) {
return 0;
}
if (!_this->wakeup_lock || SDL_LockMutex(_this->wakeup_lock) == 0) {
if (_this->wakeup_window) {
_this->SendWakeupEvent(_this, _this->wakeup_window);
/* No more wakeup events needed until we enter a new wait */
_this->wakeup_window = NULL;
}
if (_this->wakeup_lock) {
SDL_UnlockMutex(_this->wakeup_lock);
}
}
return 0;
}
/* Lock the event queue, take a peep at it, and unlock it */
static int
SDL_PeepEventsInternal(SDL_Event * events, int numevents, SDL_eventaction action,
Uint32 minType, Uint32 maxType, SDL_bool include_sentinel)
{
int i, used, sentinels_expected = 0;
/* Don't look after we've quit */
if (!SDL_AtomicGet(&SDL_EventQ.active)) {
/* We get a few spurious events at shutdown, so don't warn then */
if (action != SDL_ADDEVENT) {
if (action == SDL_GETEVENT) {
SDL_SetError("The event system has been shut down");
}
return (-1);
@@ -574,6 +740,20 @@ SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action,
SDL_CutEvent(entry);
}
}
if (type == SDL_POLLSENTINEL) {
/* Special handling for the sentinel event */
if (!include_sentinel) {
/* Skip it, we don't want to include it */
continue;
}
if (!events || action != SDL_GETEVENT) {
++sentinels_expected;
}
if (SDL_AtomicGet(&SDL_sentinel_pending) > sentinels_expected) {
/* Skip it, there's another one pending */
continue;
}
}
++used;
}
}
@@ -584,8 +764,19 @@ SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action,
} else {
return SDL_SetError("Couldn't lock event queue");
}
if (used > 0 && action == SDL_ADDEVENT) {
SDL_SendWakeupEvent();
}
return (used);
}
int
SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action,
Uint32 minType, Uint32 maxType)
{
return SDL_PeepEventsInternal(events, numevents, action, minType, maxType, SDL_FALSE);
}
SDL_bool
SDL_HasEvent(Uint32 type)
@@ -643,30 +834,48 @@ SDL_FlushEvents(Uint32 minType, Uint32 maxType)
}
/* Run the system dependent event loops */
void
SDL_PumpEvents(void)
static void
SDL_PumpEventsInternal(SDL_bool push_sentinel)
{
SDL_VideoDevice *_this = SDL_GetVideoDevice();
/* Release any keys held down from last frame */
SDL_ReleaseAutoReleaseKeys();
/* Get events from the video subsystem */
if (_this) {
_this->PumpEvents(_this);
}
#if !SDL_JOYSTICK_DISABLED
/* Check for joystick state change */
if ((!SDL_disabled_events[SDL_JOYAXISMOTION >> 8] || SDL_JoystickEventState(SDL_QUERY))) {
if (SDL_update_joysticks) {
SDL_JoystickUpdate();
}
#endif
#if !SDL_SENSOR_DISABLED
/* Check for sensor state change */
if (!SDL_disabled_events[SDL_SENSORUPDATE >> 8]) {
if (SDL_update_sensors) {
SDL_SensorUpdate();
}
#endif
SDL_SendPendingQuit(); /* in case we had a signal handler fire, etc. */
SDL_SendPendingSignalEvents(); /* in case we had a signal handler fire, etc. */
if (push_sentinel && SDL_GetEventState(SDL_POLLSENTINEL) == SDL_ENABLE) {
SDL_Event sentinel;
SDL_zero(sentinel);
sentinel.type = SDL_POLLSENTINEL;
SDL_PushEvent(&sentinel);
}
}
void
SDL_PumpEvents()
{
SDL_PumpEventsInternal(SDL_FALSE);
}
/* Public functions */
@@ -677,6 +886,124 @@ SDL_PollEvent(SDL_Event * event)
return SDL_WaitEventTimeout(event, 0);
}
static SDL_bool
SDL_events_need_periodic_poll() {
SDL_bool need_periodic_poll = SDL_FALSE;
#if !SDL_JOYSTICK_DISABLED
need_periodic_poll =
SDL_WasInit(SDL_INIT_JOYSTICK) &&
(!SDL_disabled_events[SDL_JOYAXISMOTION >> 8] || SDL_JoystickEventState(SDL_QUERY));
#endif
#if !SDL_SENSOR_DISABLED
need_periodic_poll = need_periodic_poll ||
(SDL_WasInit(SDL_INIT_SENSOR) && !SDL_disabled_events[SDL_SENSORUPDATE >> 8]);
#endif
return need_periodic_poll;
}
static int
SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Event * event, Uint32 start, int timeout)
{
int loop_timeout = timeout;
SDL_bool need_periodic_poll = SDL_events_need_periodic_poll();
for (;;) {
/* Pump events on entry and each time we wake to ensure:
a) All pending events are batch processed after waking up from a wait
b) Waiting can be completely skipped if events are already available to be pumped
c) Periodic processing that takes place in some platform PumpEvents() functions happens
d) Signals received in WaitEventTimeout() are turned into SDL events
*/
/* We only want a single sentinel in the queue. We could get more than one if event is NULL,
* since the SDL_PeepEvents() call below won't remove it in that case.
*/
SDL_bool add_sentinel = (SDL_AtomicGet(&SDL_sentinel_pending) == 0) ? SDL_TRUE : SDL_FALSE;
SDL_PumpEventsInternal(add_sentinel);
if (!_this->wakeup_lock || SDL_LockMutex(_this->wakeup_lock) == 0) {
int status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
/* If status == 0 we are going to block so wakeup will be needed. */
if (status == 0) {
_this->wakeup_window = wakeup_window;
} else {
_this->wakeup_window = NULL;
}
if (_this->wakeup_lock) {
SDL_UnlockMutex(_this->wakeup_lock);
}
if (status < 0) {
/* Got an error: return */
break;
}
if (status > 0) {
/* There is an event, we can return. */
return 1;
}
/* No events found in the queue, call WaitEventTimeout to wait for an event. */
if (timeout > 0) {
Uint32 elapsed = SDL_GetTicks() - start;
if (elapsed >= (Uint32)timeout) {
/* Set wakeup_window to NULL without holding the lock. */
_this->wakeup_window = NULL;
return 0;
}
loop_timeout = (int)((Uint32)timeout - elapsed);
}
if (need_periodic_poll) {
if (loop_timeout >= 0) {
loop_timeout = SDL_min(loop_timeout, PERIODIC_POLL_INTERVAL_MS);
} else {
loop_timeout = PERIODIC_POLL_INTERVAL_MS;
}
}
status = _this->WaitEventTimeout(_this, loop_timeout);
/* Set wakeup_window to NULL without holding the lock. */
_this->wakeup_window = NULL;
if (status <= 0) {
/* There is either an error or the timeout is elapsed: return */
return status;
}
/* An event was found and pumped into the SDL events queue. Continue the loop
to let SDL_PeepEvents pick it up .*/
}
}
return 0;
}
static SDL_bool
SDL_events_need_polling() {
SDL_bool need_polling = SDL_FALSE;
#if !SDL_JOYSTICK_DISABLED
need_polling =
SDL_WasInit(SDL_INIT_JOYSTICK) &&
(!SDL_disabled_events[SDL_JOYAXISMOTION >> 8] || SDL_JoystickEventState(SDL_QUERY)) &&
(SDL_NumJoysticks() > 0);
#endif
#if !SDL_SENSOR_DISABLED
need_polling = need_polling ||
(SDL_WasInit(SDL_INIT_SENSOR) && !SDL_disabled_events[SDL_SENSORUPDATE >> 8] && (SDL_NumSensors() > 0));
#endif
return need_polling;
}
static SDL_Window *
SDL_find_active_window(SDL_VideoDevice * _this)
{
SDL_Window *window;
for (window = _this->windows; window; window = window->next) {
if (!window->is_destroying) {
return window;
}
}
return NULL;
}
int
SDL_WaitEvent(SDL_Event * event)
{
@@ -686,26 +1013,85 @@ SDL_WaitEvent(SDL_Event * event)
int
SDL_WaitEventTimeout(SDL_Event * event, int timeout)
{
Uint32 expiration = 0;
SDL_VideoDevice *_this = SDL_GetVideoDevice();
SDL_Window *wakeup_window;
Uint32 start, expiration;
SDL_bool include_sentinel = (timeout == 0) ? SDL_TRUE : SDL_FALSE;
int result;
if (timeout > 0)
expiration = SDL_GetTicks() + timeout;
/* If there isn't a poll sentinel event pending, pump events and add one */
if (SDL_AtomicGet(&SDL_sentinel_pending) == 0) {
SDL_PumpEventsInternal(SDL_TRUE);
}
/* First check for existing events */
result = SDL_PeepEventsInternal(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT, include_sentinel);
if (result < 0) {
return 0;
}
if (include_sentinel) {
if (event) {
if (event->type == SDL_POLLSENTINEL) {
/* Reached the end of a poll cycle, and not willing to wait */
return 0;
}
} else {
/* Need to peek the next event to check for sentinel */
SDL_Event dummy;
if (SDL_PeepEventsInternal(&dummy, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT, SDL_TRUE) &&
dummy.type == SDL_POLLSENTINEL) {
SDL_PeepEventsInternal(&dummy, 1, SDL_GETEVENT, SDL_POLLSENTINEL, SDL_POLLSENTINEL, SDL_TRUE);
/* Reached the end of a poll cycle, and not willing to wait */
return 0;
}
}
}
if (result == 0) {
if (timeout == 0) {
/* No events available, and not willing to wait */
return 0;
}
} else {
/* Has existing events */
return 1;
}
/* We should have completely handled timeout == 0 above */
SDL_assert(timeout != 0);
if (timeout > 0) {
start = SDL_GetTicks();
expiration = start + timeout;
} else {
start = 0;
expiration = 0;
}
if (_this && _this->WaitEventTimeout && _this->SendWakeupEvent && !SDL_events_need_polling()) {
/* Look if a shown window is available to send the wakeup event. */
wakeup_window = SDL_find_active_window(_this);
if (wakeup_window) {
int status = SDL_WaitEventTimeout_Device(_this, wakeup_window, event, start, timeout);
/* There may be implementation-defined conditions where the backend cannot
reliably wait for the next event. If that happens, fall back to polling. */
if (status >= 0) {
return status;
}
}
}
for (;;) {
SDL_PumpEvents();
SDL_PumpEventsInternal(SDL_TRUE);
switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
case -1:
return 0;
case 0:
if (timeout == 0) {
/* Polling and no events, just return */
return 0;
}
if (timeout > 0 && SDL_TICKS_PASSED(SDL_GetTicks(), expiration)) {
/* Timeout expired and no events */
return 0;
}
SDL_Delay(10);
SDL_Delay(1);
break;
default:
/* Has events */
@@ -878,8 +1264,7 @@ SDL_FilterEvents(SDL_EventFilter filter, void *userdata)
Uint8
SDL_EventState(Uint32 type, int state)
{
const SDL_bool isdnd = ((state == SDL_DISABLE) || (state == SDL_ENABLE)) &&
((type == SDL_DROPFILE) || (type == SDL_DROPTEXT));
const SDL_bool isde = (state == SDL_DISABLE) || (state == SDL_ENABLE);
Uint8 current_state;
Uint8 hi = ((type >> 8) & 0xff);
Uint8 lo = (type & 0xff);
@@ -891,33 +1276,32 @@ SDL_EventState(Uint32 type, int state)
current_state = SDL_ENABLE;
}
if (state != current_state)
{
switch (state) {
case SDL_DISABLE:
if (isde && state != current_state) {
if (state == SDL_DISABLE) {
/* Disable this event type and discard pending events */
if (!SDL_disabled_events[hi]) {
SDL_disabled_events[hi] = (SDL_DisabledEventBlock*) SDL_calloc(1, sizeof(SDL_DisabledEventBlock));
if (!SDL_disabled_events[hi]) {
/* Out of memory, nothing we can do... */
break;
}
}
SDL_disabled_events[hi]->bits[lo/32] |= (1 << (lo&31));
SDL_FlushEvent(type);
break;
case SDL_ENABLE:
/* Out of memory, nothing we can do... */
if (SDL_disabled_events[hi]) {
SDL_disabled_events[hi]->bits[lo/32] |= (1 << (lo&31));
SDL_FlushEvent(type);
}
} else { // state == SDL_ENABLE
SDL_disabled_events[hi]->bits[lo/32] &= ~(1 << (lo&31));
break;
default:
/* Querying state... */
break;
}
#if !SDL_JOYSTICK_DISABLED
SDL_CalculateShouldUpdateJoysticks();
#endif
#if !SDL_SENSOR_DISABLED
SDL_CalculateShouldUpdateSensors();
#endif
}
/* turn off drag'n'drop support if we've disabled the events.
This might change some UI details at the OS level. */
if (isdnd) {
if (isde && ((type == SDL_DROPFILE) || (type == SDL_DROPTEXT))) {
SDL_ToggleDragAndDropSupport();
}
@@ -975,4 +1359,46 @@ SDL_SendKeymapChangedEvent(void)
return SDL_SendAppEvent(SDL_KEYMAPCHANGED);
}
int
SDL_SendLocaleChangedEvent(void)
{
return SDL_SendAppEvent(SDL_LOCALECHANGED);
}
int
SDL_EventsInit(void)
{
#if !SDL_JOYSTICK_DISABLED
SDL_AddHintCallback(SDL_HINT_AUTO_UPDATE_JOYSTICKS, SDL_AutoUpdateJoysticksChanged, NULL);
#endif
#if !SDL_SENSOR_DISABLED
SDL_AddHintCallback(SDL_HINT_AUTO_UPDATE_SENSORS, SDL_AutoUpdateSensorsChanged, NULL);
#endif
SDL_AddHintCallback(SDL_HINT_EVENT_LOGGING, SDL_EventLoggingChanged, NULL);
SDL_AddHintCallback(SDL_HINT_POLL_SENTINEL, SDL_PollSentinelChanged, NULL);
if (SDL_StartEventLoop() < 0) {
SDL_DelHintCallback(SDL_HINT_EVENT_LOGGING, SDL_EventLoggingChanged, NULL);
return -1;
}
SDL_QuitInit();
return 0;
}
void
SDL_EventsQuit(void)
{
SDL_QuitQuit();
SDL_StopEventLoop();
SDL_DelHintCallback(SDL_HINT_POLL_SENTINEL, SDL_PollSentinelChanged, NULL);
SDL_DelHintCallback(SDL_HINT_EVENT_LOGGING, SDL_EventLoggingChanged, NULL);
#if !SDL_JOYSTICK_DISABLED
SDL_DelHintCallback(SDL_HINT_AUTO_UPDATE_JOYSTICKS, SDL_AutoUpdateJoysticksChanged, NULL);
#endif
#if !SDL_SENSOR_DISABLED
SDL_DelHintCallback(SDL_HINT_AUTO_UPDATE_SENSORS, SDL_AutoUpdateSensorsChanged, NULL);
#endif
}
/* vi: set ts=4 sw=4 expandtab: */
+9 -4
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
@@ -46,13 +46,18 @@ extern void SDL_QuitInterrupt(void);
extern int SDL_SendAppEvent(SDL_EventType eventType);
extern int SDL_SendSysWMEvent(SDL_SysWMmsg * message);
extern int SDL_SendKeymapChangedEvent(void);
extern int SDL_SendLocaleChangedEvent(void);
extern int SDL_SendQuit(void);
extern int SDL_EventsInit(void);
extern void SDL_EventsQuit(void);
extern void SDL_SendPendingSignalEvents(void);
extern int SDL_QuitInit(void);
extern int SDL_SendQuit(void);
extern void SDL_QuitQuit(void);
extern void SDL_SendPendingQuit(void);
#endif /* SDL_events_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */
+61 -42
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
@@ -32,16 +32,18 @@
#include <stdio.h>
*/
/* TODO: Replace with malloc */
/* TODO: Replace with SDL_malloc */
#define MAXPATHSIZE 1024
#define DOLLARNPOINTS 64
#define DOLLARSIZE 256
#define ENABLE_DOLLAR
#define PHI 0.618033989
#define DOLLARNPOINTS 64
#if defined(ENABLE_DOLLAR)
# define DOLLARSIZE 256
# define PHI 0.618033989
#endif
typedef struct {
float x,y;
@@ -279,6 +281,7 @@ int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src)
}
#if defined(ENABLE_DOLLAR)
static float dollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ,float ang)
{
/* SDL_FloatPoint p[DOLLARNPOINTS]; */
@@ -334,7 +337,7 @@ static float bestDollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ)
}
/* DollarPath contains raw points, plus (possibly) the calculated length */
static int dollarNormalize(const SDL_DollarPath *path,SDL_FloatPoint *points)
static int dollarNormalize(const SDL_DollarPath *path,SDL_FloatPoint *points, SDL_bool is_recording)
{
int i;
float interval;
@@ -380,7 +383,9 @@ static int dollarNormalize(const SDL_DollarPath *path,SDL_FloatPoint *points)
dist += d;
}
if (numPoints < DOLLARNPOINTS-1) {
SDL_SetError("ERROR: NumPoints = %i", numPoints);
if (is_recording) {
SDL_SetError("ERROR: NumPoints = %i", numPoints);
}
return 0;
}
/* copy the last point */
@@ -434,7 +439,7 @@ static float dollarRecognize(const SDL_DollarPath *path,int *bestTempl,SDL_Gestu
SDL_memset(points, 0, sizeof(points));
dollarNormalize(path,points);
dollarNormalize(path, points, SDL_FALSE);
/* PrintPath(points); */
*bestTempl = -1;
@@ -444,6 +449,7 @@ static float dollarRecognize(const SDL_DollarPath *path,int *bestTempl,SDL_Gestu
}
return bestDiff;
}
#endif
int SDL_GestureAddTouch(SDL_TouchID touchId)
{
@@ -481,7 +487,9 @@ int SDL_GestureDelTouch(SDL_TouchID touchId)
SDL_zero(SDL_gestureTouch[i]);
SDL_numGestureTouches--;
SDL_memcpy(&SDL_gestureTouch[i], &SDL_gestureTouch[SDL_numGestureTouches], sizeof(SDL_gestureTouch[i]));
if (i != SDL_numGestureTouches) {
SDL_memcpy(&SDL_gestureTouch[i], &SDL_gestureTouch[SDL_numGestureTouches], sizeof(SDL_gestureTouch[i]));
}
return 0;
}
@@ -496,51 +504,60 @@ static SDL_GestureTouch * SDL_GetGestureTouch(SDL_TouchID id)
return NULL;
}
static int SDL_SendGestureMulti(SDL_GestureTouch* touch,float dTheta,float dDist)
static void SDL_SendGestureMulti(SDL_GestureTouch* touch,float dTheta,float dDist)
{
SDL_Event event;
event.mgesture.type = SDL_MULTIGESTURE;
event.mgesture.touchId = touch->id;
event.mgesture.x = touch->centroid.x;
event.mgesture.y = touch->centroid.y;
event.mgesture.dTheta = dTheta;
event.mgesture.dDist = dDist;
event.mgesture.numFingers = touch->numDownFingers;
return SDL_PushEvent(&event) > 0;
if (SDL_GetEventState(SDL_MULTIGESTURE) == SDL_ENABLE) {
SDL_Event event;
event.mgesture.type = SDL_MULTIGESTURE;
event.mgesture.touchId = touch->id;
event.mgesture.x = touch->centroid.x;
event.mgesture.y = touch->centroid.y;
event.mgesture.dTheta = dTheta;
event.mgesture.dDist = dDist;
event.mgesture.numFingers = touch->numDownFingers;
SDL_PushEvent(&event);
}
}
static int SDL_SendGestureDollar(SDL_GestureTouch* touch,
#if defined(ENABLE_DOLLAR)
static void SDL_SendGestureDollar(SDL_GestureTouch* touch,
SDL_GestureID gestureId,float error)
{
SDL_Event event;
event.dgesture.type = SDL_DOLLARGESTURE;
event.dgesture.touchId = touch->id;
event.dgesture.x = touch->centroid.x;
event.dgesture.y = touch->centroid.y;
event.dgesture.gestureId = gestureId;
event.dgesture.error = error;
/* A finger came up to trigger this event. */
event.dgesture.numFingers = touch->numDownFingers + 1;
return SDL_PushEvent(&event) > 0;
if (SDL_GetEventState(SDL_DOLLARGESTURE) == SDL_ENABLE) {
SDL_Event event;
event.dgesture.type = SDL_DOLLARGESTURE;
event.dgesture.touchId = touch->id;
event.dgesture.x = touch->centroid.x;
event.dgesture.y = touch->centroid.y;
event.dgesture.gestureId = gestureId;
event.dgesture.error = error;
/* A finger came up to trigger this event. */
event.dgesture.numFingers = touch->numDownFingers + 1;
SDL_PushEvent(&event);
}
}
static int SDL_SendDollarRecord(SDL_GestureTouch* touch,SDL_GestureID gestureId)
static void SDL_SendDollarRecord(SDL_GestureTouch* touch,SDL_GestureID gestureId)
{
SDL_Event event;
event.dgesture.type = SDL_DOLLARRECORD;
event.dgesture.touchId = touch->id;
event.dgesture.gestureId = gestureId;
return SDL_PushEvent(&event) > 0;
if (SDL_GetEventState(SDL_DOLLARRECORD) == SDL_ENABLE) {
SDL_Event event;
event.dgesture.type = SDL_DOLLARRECORD;
event.dgesture.touchId = touch->id;
event.dgesture.gestureId = gestureId;
SDL_PushEvent(&event);
}
}
#endif
void SDL_GestureProcessEvent(SDL_Event* event)
{
float x,y;
#if defined(ENABLE_DOLLAR)
int index;
int i;
float pathDx, pathDy;
#endif
SDL_FloatPoint lastP;
SDL_FloatPoint lastCentroid;
float lDist;
@@ -561,14 +578,16 @@ void SDL_GestureProcessEvent(SDL_Event* event)
/* Finger Up */
if (event->type == SDL_FINGERUP) {
#if defined(ENABLE_DOLLAR)
SDL_FloatPoint path[DOLLARNPOINTS];
#endif
inTouch->numDownFingers--;
#ifdef ENABLE_DOLLAR
#if defined(ENABLE_DOLLAR)
if (inTouch->recording) {
inTouch->recording = SDL_FALSE;
dollarNormalize(&inTouch->dollarPath,path);
dollarNormalize(&inTouch->dollarPath, path, SDL_TRUE);
/* PrintPath(path); */
if (recordAll) {
index = SDL_AddDollarGesture(NULL,path);
@@ -610,7 +629,7 @@ void SDL_GestureProcessEvent(SDL_Event* event)
else if (event->type == SDL_FINGERMOTION) {
float dx = event->tfinger.dx;
float dy = event->tfinger.dy;
#ifdef ENABLE_DOLLAR
#if defined(ENABLE_DOLLAR)
SDL_DollarPath* path = &inTouch->dollarPath;
if (path->numPoints < MAXPATHSIZE) {
path->p[path->numPoints].x = inTouch->centroid.x;
@@ -687,7 +706,7 @@ void SDL_GestureProcessEvent(SDL_Event* event)
/* printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y,
inTouch->centroid.x,inTouch->centroid.y); */
#ifdef ENABLE_DOLLAR
#if defined(ENABLE_DOLLAR)
inTouch->dollarPath.length = 0;
inTouch->dollarPath.p[0].x = x;
inTouch->dollarPath.p[0].y = y;
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
+120 -32
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
@@ -22,10 +22,10 @@
/* General keyboard handling code for SDL */
#include "SDL_hints.h"
#include "SDL_timer.h"
#include "SDL_events.h"
#include "SDL_events_c.h"
#include "SDL_assert.h"
#include "../video/SDL_sysvideo.h"
@@ -33,6 +33,9 @@
/* Global keyboard information */
#define KEYBOARD_HARDWARE 0x01
#define KEYBOARD_AUTORELEASE 0x02
typedef struct SDL_Keyboard SDL_Keyboard;
struct SDL_Keyboard
@@ -40,8 +43,10 @@ struct SDL_Keyboard
/* Data common to all keyboards */
SDL_Window *focus;
Uint16 modstate;
Uint8 keysource[SDL_NUM_SCANCODES];
Uint8 keystate[SDL_NUM_SCANCODES];
SDL_Keycode keymap[SDL_NUM_SCANCODES];
SDL_bool autorelease_pending;
};
static SDL_Keyboard SDL_keyboard;
@@ -532,27 +537,12 @@ SDL_UCS4ToUTF8(Uint32 ch, char *dst)
p[1] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
p[2] = 0x80 | (Uint8) (ch & 0x3F);
dst += 3;
} else if (ch <= 0x1FFFFF) {
} else {
p[0] = 0xF0 | (Uint8) ((ch >> 18) & 0x07);
p[1] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
p[2] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
p[3] = 0x80 | (Uint8) (ch & 0x3F);
dst += 4;
} else if (ch <= 0x3FFFFFF) {
p[0] = 0xF8 | (Uint8) ((ch >> 24) & 0x03);
p[1] = 0x80 | (Uint8) ((ch >> 18) & 0x3F);
p[2] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
p[3] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
p[4] = 0x80 | (Uint8) (ch & 0x3F);
dst += 5;
} else {
p[0] = 0xFC | (Uint8) ((ch >> 30) & 0x01);
p[1] = 0x80 | (Uint8) ((ch >> 24) & 0x3F);
p[2] = 0x80 | (Uint8) ((ch >> 18) & 0x3F);
p[3] = 0x80 | (Uint8) ((ch >> 12) & 0x3F);
p[4] = 0x80 | (Uint8) ((ch >> 6) & 0x3F);
p[5] = 0x80 | (Uint8) (ch & 0x3F);
dst += 6;
}
return dst;
}
@@ -615,6 +605,9 @@ SDL_SetKeymap(int start, SDL_Keycode * keys, int length)
void
SDL_SetScancodeName(SDL_Scancode scancode, const char *name)
{
if (scancode >= SDL_NUM_SCANCODES) {
return;
}
SDL_scancode_names[scancode] = name;
}
@@ -645,6 +638,7 @@ SDL_SetKeyboardFocus(SDL_Window * window)
/* old window must lose an existing mouse capture. */
if (keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE) {
SDL_CaptureMouse(SDL_FALSE); /* drop the capture. */
SDL_UpdateMouseCapture(SDL_TRUE);
SDL_assert(!(keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE));
}
@@ -675,19 +669,20 @@ SDL_SetKeyboardFocus(SDL_Window * window)
}
}
int
SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
static int
SDL_SendKeyboardKeyInternal(Uint8 source, Uint8 state, SDL_Scancode scancode)
{
SDL_Keyboard *keyboard = &SDL_keyboard;
int posted;
SDL_Keymod modifier;
SDL_Keycode keycode;
Uint32 type;
Uint8 repeat;
Uint8 repeat = SDL_FALSE;
if (!scancode) {
if (scancode == SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
return 0;
}
#ifdef DEBUG_KEYBOARD
printf("The '%s' key has been %s\n", SDL_GetScancodeName(scancode),
state == SDL_PRESSED ? "pressed" : "released");
@@ -707,12 +702,20 @@ SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
}
/* Drop events that don't change state */
repeat = (state && keyboard->keystate[scancode]);
if (keyboard->keystate[scancode] == state && !repeat) {
#if 0
printf("Keyboard event didn't change state - dropped!\n");
#endif
return 0;
if (state) {
if (keyboard->keystate[scancode]) {
if (!(keyboard->keysource[scancode] & source)) {
keyboard->keysource[scancode] |= source;
return 0;
}
repeat = SDL_TRUE;
}
keyboard->keysource[scancode] |= source;
} else {
if (!keyboard->keystate[scancode]) {
return 0;
}
keyboard->keysource[scancode] = 0;
}
/* Update internal keyboard state */
@@ -720,6 +723,10 @@ SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
keycode = keyboard->keymap[scancode];
if (source == KEYBOARD_AUTORELEASE) {
keyboard->autorelease_pending = SDL_TRUE;
}
/* Update modifiers state if applicable */
switch (keycode) {
case SDLK_LCTRL:
@@ -761,6 +768,9 @@ SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
case SDLK_CAPSLOCK:
keyboard->modstate ^= KMOD_CAPS;
break;
case SDLK_SCROLLLOCK:
keyboard->modstate ^= KMOD_SCROLL;
break;
default:
keyboard->modstate |= modifier;
break;
@@ -782,9 +792,67 @@ SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
event.key.windowID = keyboard->focus ? keyboard->focus->id : 0;
posted = (SDL_PushEvent(&event) > 0);
}
/* 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 &&
state == SDL_PRESSED &&
(keyboard->modstate & 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, SDL_TRUE)) {
/* We will temporarily forfeit our grab by minimizing our window,
allowing the user to escape the application */
SDL_MinimizeWindow(keyboard->focus);
}
return (posted);
}
int
SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
{
return SDL_SendKeyboardKeyInternal(KEYBOARD_HARDWARE, state, scancode);
}
int
SDL_SendKeyboardKeyAutoRelease(SDL_Scancode scancode)
{
return SDL_SendKeyboardKeyInternal(KEYBOARD_AUTORELEASE, SDL_PRESSED, scancode);
}
void
SDL_ReleaseAutoReleaseKeys(void)
{
SDL_Keyboard *keyboard = &SDL_keyboard;
SDL_Scancode scancode;
if (keyboard->autorelease_pending) {
for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) {
if (keyboard->keysource[scancode] == KEYBOARD_AUTORELEASE) {
SDL_SendKeyboardKeyInternal(KEYBOARD_AUTORELEASE, SDL_RELEASED, scancode);
}
}
keyboard->autorelease_pending = SDL_FALSE;
}
}
SDL_bool
SDL_HardwareKeyboardKeyPressed(void)
{
SDL_Keyboard *keyboard = &SDL_keyboard;
SDL_Scancode scancode;
for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) {
if ((keyboard->keysource[scancode] & KEYBOARD_HARDWARE) != 0) {
return SDL_TRUE;
}
}
return SDL_FALSE;
}
int
SDL_SendKeyboardText(const char *text)
{
@@ -800,10 +868,14 @@ SDL_SendKeyboardText(const char *text)
posted = 0;
if (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) {
SDL_Event event;
size_t i = 0, length = SDL_strlen(text);
event.text.type = SDL_TEXTINPUT;
event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
SDL_utf8strlcpy(event.text.text, text, SDL_arraysize(event.text.text));
posted = (SDL_PushEvent(&event) > 0);
while (i < length) {
i += SDL_utf8strlcpy(event.text.text, text + i, SDL_arraysize(event.text.text));
posted |= (SDL_PushEvent(&event) > 0);
}
}
return (posted);
}
@@ -823,6 +895,22 @@ SDL_SendEditingText(const char *text, int start, int length)
event.edit.start = start;
event.edit.length = length;
SDL_utf8strlcpy(event.edit.text, text, SDL_arraysize(event.edit.text));
if (SDL_GetHintBoolean(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, SDL_FALSE) &&
SDL_strlen(text) > SDL_arraysize(event.text.text)) {
event.editExt.type = SDL_TEXTEDITING_EXT;
event.editExt.windowID = keyboard->focus ? keyboard->focus->id : 0;
event.editExt.text = text ? SDL_strdup(text) : NULL;
event.editExt.start = start;
event.editExt.length = length;
} else {
event.edit.type = SDL_TEXTEDITING;
event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0;
event.edit.start = start;
event.edit.length = length;
SDL_utf8strlcpy(event.edit.text, text, SDL_arraysize(event.edit.text));
}
posted = (SDL_PushEvent(&event) > 0);
}
return (posted);
@@ -878,7 +966,7 @@ SDL_GetKeyFromScancode(SDL_Scancode scancode)
{
SDL_Keyboard *keyboard = &SDL_keyboard;
if (((int)scancode) < ((int)SDL_SCANCODE_UNKNOWN) || scancode >= SDL_NUM_SCANCODES) {
if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
SDL_InvalidParamError("scancode");
return 0;
}
@@ -905,7 +993,7 @@ const char *
SDL_GetScancodeName(SDL_Scancode scancode)
{
const char *name;
if (((int)scancode) < ((int)SDL_SCANCODE_UNKNOWN) || scancode >= SDL_NUM_SCANCODES) {
if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
SDL_InvalidParamError("scancode");
return "";
}
+8 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
@@ -49,6 +49,13 @@ extern void SDL_SetKeyboardFocus(SDL_Window * window);
/* Send a keyboard key event */
extern int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode);
extern int SDL_SendKeyboardKeyAutoRelease(SDL_Scancode scancode);
/* Release all the autorelease keys */
extern void SDL_ReleaseAutoReleaseKeys(void);
/* Return true if any hardware key is pressed */
extern SDL_bool SDL_HardwareKeyboardKeyPressed(void);
/* Send keyboard text input */
extern int SDL_SendKeyboardText(const char *text);
+363 -142
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
@@ -22,21 +22,28 @@
/* General mouse handling code for SDL */
#include "SDL_assert.h"
#include "SDL_hints.h"
#include "SDL_timer.h"
#include "SDL_events.h"
#include "SDL_events_c.h"
#include "../SDL_hints_c.h"
#include "../video/SDL_sysvideo.h"
#ifdef __WIN32__
#include "../core/windows/SDL_windows.h" // For GetDoubleClickTime()
#endif
#if defined(__OS2__)
#define INCL_WIN
#include <os2.h>
#endif
/* #define DEBUG_MOUSE */
/* The mouse state */
static SDL_Mouse SDL_mouse;
/* for mapping mouse events to touch */
static SDL_bool track_mouse_down = SDL_FALSE;
static int
SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
@@ -50,6 +57,8 @@ SDL_MouseDoubleClickTimeChanged(void *userdata, const char *name, const char *ol
} else {
#ifdef __WIN32__
mouse->double_click_time = GetDoubleClickTime();
#elif defined(__OS2__)
mouse->double_click_time = WinQuerySysValue(HWND_DESKTOP, SV_DBLCLKTIME);
#else
mouse->double_click_time = 500;
#endif
@@ -97,10 +106,58 @@ SDL_TouchMouseEventsChanged(void *userdata, const char *name, const char *oldVal
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
if (hint && (*hint == '0' || SDL_strcasecmp(hint, "false") == 0)) {
mouse->touch_mouse_events = SDL_FALSE;
} else {
mouse->touch_mouse_events = SDL_TRUE;
mouse->touch_mouse_events = SDL_GetStringBoolean(hint, SDL_TRUE);
}
#if defined(__vita__)
static void SDLCALL
SDL_VitaTouchMouseDeviceChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
if (hint) {
switch(*hint) {
default:
case '0':
mouse->vita_touch_mouse_device = 0;
break;
case '1':
mouse->vita_touch_mouse_device = 1;
break;
case '2':
mouse->vita_touch_mouse_device = 2;
break;
}
}
}
#endif
static void SDLCALL
SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
SDL_bool default_value;
#if defined(__ANDROID__) || (defined(__IPHONEOS__) && !defined(__TVOS__))
default_value = SDL_TRUE;
#else
default_value = SDL_FALSE;
#endif
mouse->mouse_touch_events = SDL_GetStringBoolean(hint, default_value);
if (mouse->mouse_touch_events) {
SDL_AddTouch(SDL_MOUSE_TOUCHID, SDL_TOUCH_DEVICE_DIRECT, "mouse_input");
}
}
static void SDLCALL
SDL_MouseAutoCaptureChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
SDL_bool auto_capture = SDL_GetStringBoolean(hint, SDL_TRUE);
if (auto_capture != mouse->auto_capture) {
mouse->auto_capture = auto_capture;
SDL_UpdateMouseCapture(SDL_FALSE);
}
}
@@ -127,6 +184,19 @@ SDL_MouseInit(void)
SDL_AddHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS,
SDL_TouchMouseEventsChanged, mouse);
#if defined(__vita__)
SDL_AddHintCallback(SDL_HINT_VITA_TOUCH_MOUSE_DEVICE,
SDL_VitaTouchMouseDeviceChanged, mouse);
#endif
SDL_AddHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS,
SDL_MouseTouchEventsChanged, mouse);
SDL_AddHintCallback(SDL_HINT_MOUSE_AUTO_CAPTURE,
SDL_MouseAutoCaptureChanged, mouse);
mouse->was_touch_mouse_events = SDL_FALSE; /* no touch to mouse movement event pending */
mouse->cursor_shown = SDL_TRUE;
return (0);
@@ -149,6 +219,17 @@ SDL_GetMouse(void)
return &SDL_mouse;
}
static Uint32 GetButtonState(SDL_Mouse *mouse)
{
int i;
Uint32 buttonstate = 0;
for (i = 0; i < mouse->num_sources; ++i) {
buttonstate |= mouse->sources[i].buttonstate;
}
return buttonstate;
}
SDL_Window *
SDL_GetMouseFocus(void)
{
@@ -157,25 +238,6 @@ SDL_GetMouseFocus(void)
return mouse->focus;
}
#if 0
void
SDL_ResetMouse(void)
{
SDL_Mouse *mouse = SDL_GetMouse();
Uint8 i;
#ifdef DEBUG_MOUSE
printf("Resetting mouse\n");
#endif
for (i = 1; i <= sizeof(mouse->buttonstate)*8; ++i) {
if (mouse->buttonstate & SDL_BUTTON(i)) {
SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, i);
}
}
SDL_assert(mouse->buttonstate == 0);
}
#endif
void
SDL_SetMouseFocus(SDL_Window * window)
{
@@ -215,7 +277,7 @@ SDL_SetMouseFocus(SDL_Window * window)
/* Check to see if we need to synthesize focus events */
static SDL_bool
SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate)
SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate, SDL_bool send_mouse_motion)
{
SDL_Mouse *mouse = SDL_GetMouse();
SDL_bool inWindow = SDL_TRUE;
@@ -228,25 +290,14 @@ SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate)
}
}
/* Linux doesn't give you mouse events outside your window unless you grab
the pointer.
Windows doesn't give you mouse events outside your window unless you call
SetCapture().
Both of these are slightly scary changes, so for now we'll punt and if the
mouse leaves the window you'll lose mouse focus and reset button state.
*/
#ifdef SUPPORT_DRAG_OUTSIDE_WINDOW
if (!inWindow && !buttonstate) {
#else
if (!inWindow) {
#endif
if (window == mouse->focus) {
#ifdef DEBUG_MOUSE
printf("Mouse left window, synthesizing move & focus lost event\n");
SDL_Log("Mouse left window, synthesizing move & focus lost event\n");
#endif
SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
if (send_mouse_motion) {
SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
}
SDL_SetMouseFocus(NULL);
}
return SDL_FALSE;
@@ -254,10 +305,12 @@ SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate)
if (window != mouse->focus) {
#ifdef DEBUG_MOUSE
printf("Mouse entered window, synthesizing focus gain & move event\n");
SDL_Log("Mouse entered window, synthesizing focus gain & move event\n");
#endif
SDL_SetMouseFocus(window);
SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
if (send_mouse_motion) {
SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
}
}
return SDL_TRUE;
}
@@ -267,7 +320,7 @@ SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int
{
if (window && !relative) {
SDL_Mouse *mouse = SDL_GetMouse();
if (!SDL_UpdateMouseFocus(window, x, y, mouse->buttonstate)) {
if (!SDL_UpdateMouseFocus(window, x, y, GetButtonState(mouse), (mouseID == SDL_TOUCH_MOUSEID) ? SDL_FALSE : SDL_TRUE)) {
return 0;
}
}
@@ -298,8 +351,22 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
int xrel;
int yrel;
if (mouseID == SDL_TOUCH_MOUSEID && !mouse->touch_mouse_events) {
return 0;
/* SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events */
if (mouse->mouse_touch_events) {
if (mouseID != SDL_TOUCH_MOUSEID && !relative && track_mouse_down) {
if (window) {
float fx = (float)x / (float)window->w;
float fy = (float)y / (float)window->h;
SDL_SendTouchMotion(SDL_MOUSE_TOUCHID, 0, window, fx, fy, 1.0f);
}
}
}
/* SDL_HINT_TOUCH_MOUSE_EVENTS: if not set, discard synthetic mouse events coming from platform layer */
if (mouse->touch_mouse_events == 0) {
if (mouseID == SDL_TOUCH_MOUSEID) {
return 0;
}
}
if (mouseID != SDL_TOUCH_MOUSEID && mouse->relative_mode_warp) {
@@ -312,7 +379,13 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
mouse->last_y = center_y;
return 0;
}
SDL_WarpMouseInWindow(window, center_x, center_y);
if (window && (window->flags & SDL_WINDOW_INPUT_FOCUS) != 0) {
if (mouse->WarpMouse) {
mouse->WarpMouse(window, center_x, center_y);
} else {
SDL_PrivateSendMouseMotion(window, mouseID, 0, center_x, center_y);
}
}
}
if (relative) {
@@ -332,23 +405,20 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
yrel = y - mouse->last_y;
}
/* Drop events that don't change state */
if (!xrel && !yrel) {
/* Ignore relative motion when first positioning the mouse */
if (!mouse->has_position) {
mouse->x = x;
mouse->y = y;
mouse->has_position = SDL_TRUE;
} else if (!xrel && !yrel) { /* Drop events that don't change state */
#ifdef DEBUG_MOUSE
printf("Mouse event didn't change state - dropped!\n");
SDL_Log("Mouse event didn't change state - dropped!\n");
#endif
return 0;
}
/* Ignore relative motion when first positioning the mouse */
if (!mouse->has_position) {
xrel = 0;
yrel = 0;
mouse->has_position = SDL_TRUE;
}
/* Ignore relative motion positioning the first touch */
if (mouseID == SDL_TOUCH_MOUSEID && !mouse->buttonstate) {
if (mouseID == SDL_TOUCH_MOUSEID && !GetButtonState(mouse)) {
xrel = 0;
yrel = 0;
}
@@ -365,25 +435,42 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
/* make sure that the pointers find themselves inside the windows,
unless we have the mouse captured. */
if (window && ((window->flags & SDL_WINDOW_MOUSE_CAPTURE) == 0)) {
int x_max = 0, y_max = 0;
int x_min = 0, x_max = 0;
int y_min = 0, y_max = 0;
const SDL_Rect *confine = SDL_GetWindowMouseRect(window);
/* !!! FIXME: shouldn't this be (window) instead of (mouse->focus)? */
SDL_GetWindowSize(mouse->focus, &x_max, &y_max);
SDL_GetWindowSize(window, &x_max, &y_max);
--x_max;
--y_max;
if (confine) {
SDL_Rect window_rect;
SDL_Rect mouse_rect;
window_rect.x = 0;
window_rect.y = 0;
window_rect.w = x_max + 1;
window_rect.h = y_max + 1;
if (SDL_IntersectRect(confine, &window_rect, &mouse_rect)) {
x_min = mouse_rect.x;
y_min = mouse_rect.y;
x_max = x_min + mouse_rect.w - 1;
y_max = y_min + mouse_rect.h - 1;
}
}
if (mouse->x > x_max) {
mouse->x = x_max;
}
if (mouse->x < 0) {
mouse->x = 0;
if (mouse->x < x_min) {
mouse->x = x_min;
}
if (mouse->y > y_max) {
mouse->y = y_max;
}
if (mouse->y < 0) {
mouse->y = 0;
if (mouse->y < y_min) {
mouse->y = y_min;
}
}
@@ -403,7 +490,9 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
event.motion.type = SDL_MOUSEMOTION;
event.motion.windowID = mouse->focus ? mouse->focus->id : 0;
event.motion.which = mouseID;
event.motion.state = mouse->buttonstate;
/* Set us pending (or clear during a normal mouse movement event) as having triggered */
mouse->was_touch_mouse_events = (mouseID == SDL_TOUCH_MOUSEID)? SDL_TRUE : SDL_FALSE;
event.motion.state = GetButtonState(mouse);
event.motion.x = mouse->x;
event.motion.y = mouse->y;
event.motion.xrel = xrel;
@@ -421,6 +510,30 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
return posted;
}
static SDL_MouseInputSource *GetMouseInputSource(SDL_Mouse *mouse, SDL_MouseID mouseID)
{
SDL_MouseInputSource *source, *sources;
int i;
for (i = 0; i < mouse->num_sources; ++i) {
source = &mouse->sources[i];
if (source->mouseID == mouseID) {
return source;
}
}
sources = (SDL_MouseInputSource *)SDL_realloc(mouse->sources, (mouse->num_sources + 1)*sizeof(*mouse->sources));
if (sources) {
mouse->sources = sources;
++mouse->num_sources;
source = &sources[mouse->num_sources - 1];
source->mouseID = mouseID;
source->buttonstate = 0;
return source;
}
return NULL;
}
static SDL_MouseClickState *GetMouseClickState(SDL_Mouse *mouse, Uint8 button)
{
if (button >= mouse->num_clickstates) {
@@ -445,11 +558,37 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state
SDL_Mouse *mouse = SDL_GetMouse();
int posted;
Uint32 type;
Uint32 buttonstate = mouse->buttonstate;
Uint32 buttonstate;
SDL_MouseInputSource *source;
if (mouseID == SDL_TOUCH_MOUSEID && !mouse->touch_mouse_events) {
source = GetMouseInputSource(mouse, mouseID);
if (!source) {
return 0;
}
buttonstate = source->buttonstate;
/* SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events */
if (mouse->mouse_touch_events) {
if (mouseID != SDL_TOUCH_MOUSEID && button == SDL_BUTTON_LEFT) {
if (state == SDL_PRESSED) {
track_mouse_down = SDL_TRUE;
} else {
track_mouse_down = SDL_FALSE;
}
if (window) {
float fx = (float)mouse->x / (float)window->w;
float fy = (float)mouse->y / (float)window->h;
SDL_SendTouch(SDL_MOUSE_TOUCHID, 0, window, track_mouse_down, fx, fy, 1.0f);
}
}
}
/* SDL_HINT_TOUCH_MOUSE_EVENTS: if not set, discard synthetic mouse events coming from platform layer */
if (mouse->touch_mouse_events == 0) {
if (mouseID == SDL_TOUCH_MOUSEID) {
return 0;
}
}
/* Figure out which event to perform */
switch (state) {
@@ -468,14 +607,14 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state
/* We do this after calculating buttonstate so button presses gain focus */
if (window && state == SDL_PRESSED) {
SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate);
SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate, SDL_TRUE);
}
if (buttonstate == mouse->buttonstate) {
if (buttonstate == source->buttonstate) {
/* Ignore this event, no state change */
return 0;
}
mouse->buttonstate = buttonstate;
source->buttonstate = buttonstate;
if (clicks < 0) {
SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button);
@@ -518,9 +657,14 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state
/* We do this after dispatching event so button releases can lose focus */
if (window && state == SDL_RELEASED) {
SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate);
SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate, SDL_TRUE);
}
/* Automatically capture the mouse while buttons are pressed */
if (mouse->auto_capture) {
SDL_UpdateMouseCapture(SDL_FALSE);
}
return posted;
}
@@ -548,24 +692,42 @@ SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, float x, float y, S
SDL_SetMouseFocus(window);
}
if (!x && !y) {
if (x == 0.0f && y == 0.0f) {
return 0;
}
if (x > 0.0f) {
if (mouse->accumulated_wheel_x < 0.0f) {
mouse->accumulated_wheel_x = 0.0f;
}
} else if (x < 0.0f) {
if (mouse->accumulated_wheel_x > 0.0f) {
mouse->accumulated_wheel_x = 0.0f;
}
}
mouse->accumulated_wheel_x += x;
if (mouse->accumulated_wheel_x > 0) {
if (mouse->accumulated_wheel_x > 0.0f) {
integral_x = (int)SDL_floor(mouse->accumulated_wheel_x);
} else if (mouse->accumulated_wheel_x < 0) {
} else if (mouse->accumulated_wheel_x < 0.0f) {
integral_x = (int)SDL_ceil(mouse->accumulated_wheel_x);
} else {
integral_x = 0;
}
mouse->accumulated_wheel_x -= integral_x;
if (y > 0.0f) {
if (mouse->accumulated_wheel_y < 0.0f) {
mouse->accumulated_wheel_y = 0.0f;
}
} else if (y < 0.0f) {
if (mouse->accumulated_wheel_y > 0.0f) {
mouse->accumulated_wheel_y = 0.0f;
}
}
mouse->accumulated_wheel_y += y;
if (mouse->accumulated_wheel_y > 0) {
if (mouse->accumulated_wheel_y > 0.0f) {
integral_y = (int)SDL_floor(mouse->accumulated_wheel_y);
} else if (mouse->accumulated_wheel_y < 0) {
} else if (mouse->accumulated_wheel_y < 0.0f) {
integral_y = (int)SDL_ceil(mouse->accumulated_wheel_y);
} else {
integral_y = 0;
@@ -579,12 +741,10 @@ SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, float x, float y, S
event.type = SDL_MOUSEWHEEL;
event.wheel.windowID = mouse->focus ? mouse->focus->id : 0;
event.wheel.which = mouseID;
#if 0 /* Uncomment this when it goes in for SDL 2.1 */
event.wheel.preciseX = x;
event.wheel.preciseY = y;
#endif
event.wheel.x = integral_x;
event.wheel.y = integral_y;
event.wheel.preciseX = x;
event.wheel.preciseY = y;
event.wheel.direction = (Uint32)direction;
posted = (SDL_PushEvent(&event) > 0);
}
@@ -599,6 +759,7 @@ SDL_MouseQuit(void)
if (mouse->CaptureMouse) {
SDL_CaptureMouse(SDL_FALSE);
SDL_UpdateMouseCapture(SDL_TRUE);
}
SDL_SetRelativeMouseMode(SDL_FALSE);
SDL_ShowCursor(1);
@@ -610,22 +771,45 @@ SDL_MouseQuit(void)
cursor = next;
}
mouse->cursors = NULL;
mouse->cur_cursor = NULL;
if (mouse->def_cursor && mouse->FreeCursor) {
mouse->FreeCursor(mouse->def_cursor);
mouse->def_cursor = NULL;
}
if (mouse->sources) {
SDL_free(mouse->sources);
mouse->sources = NULL;
}
mouse->num_sources = 0;
if (mouse->clickstate) {
SDL_free(mouse->clickstate);
mouse->clickstate = NULL;
}
mouse->num_clickstates = 0;
SDL_DelHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_TIME,
SDL_MouseDoubleClickTimeChanged, mouse);
SDL_DelHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS,
SDL_MouseDoubleClickRadiusChanged, mouse);
SDL_DelHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE,
SDL_MouseNormalSpeedScaleChanged, mouse);
SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE,
SDL_MouseRelativeSpeedScaleChanged, mouse);
SDL_DelHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS,
SDL_TouchMouseEventsChanged, mouse);
SDL_DelHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS,
SDL_MouseTouchEventsChanged, mouse);
SDL_DelHintCallback(SDL_HINT_MOUSE_AUTO_CAPTURE,
SDL_MouseAutoCaptureChanged, mouse);
}
Uint32
@@ -639,7 +823,7 @@ SDL_GetMouseState(int *x, int *y)
if (y) {
*y = mouse->y;
}
return mouse->buttonstate;
return GetButtonState(mouse);
}
Uint32
@@ -655,30 +839,31 @@ SDL_GetRelativeMouseState(int *x, int *y)
}
mouse->xdelta = 0;
mouse->ydelta = 0;
return mouse->buttonstate;
return GetButtonState(mouse);
}
Uint32
SDL_GetGlobalMouseState(int *x, int *y)
{
SDL_Mouse *mouse = SDL_GetMouse();
int tmpx, tmpy;
/* make sure these are never NULL for the backend implementations... */
if (!x) {
x = &tmpx;
if (mouse->GetGlobalMouseState) {
int tmpx, tmpy;
/* make sure these are never NULL for the backend implementations... */
if (!x) {
x = &tmpx;
}
if (!y) {
y = &tmpy;
}
*x = *y = 0;
return mouse->GetGlobalMouseState(x, y);
} else {
return SDL_GetMouseState(x, y);
}
if (!y) {
y = &tmpy;
}
*x = *y = 0;
if (!mouse->GetGlobalMouseState) {
return 0;
}
return mouse->GetGlobalMouseState(x, y);
}
void
@@ -694,10 +879,18 @@ SDL_WarpMouseInWindow(SDL_Window * window, int x, int y)
return;
}
if (mouse->WarpMouse) {
if ((window->flags & SDL_WINDOW_MINIMIZED) == SDL_WINDOW_MINIMIZED) {
return;
}
/* Ignore the previous position when we warp */
mouse->has_position = SDL_FALSE;
if (mouse->WarpMouse &&
(!mouse->relative_mode || mouse->relative_mode_warp)) {
mouse->WarpMouse(window, x, y);
} else {
SDL_SendMouseMotion(window, mouse->mouseID, 0, x, y);
SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
}
}
@@ -716,9 +909,9 @@ SDL_WarpMouseGlobal(int x, int y)
static SDL_bool
ShouldUseRelativeModeWarp(SDL_Mouse *mouse)
{
if (!mouse->SetRelativeMouseMode) {
SDL_assert(mouse->WarpMouse); /* Need this functionality for relative mode warp implementation */
return SDL_TRUE;
if (!mouse->WarpMouse) {
/* Need this functionality for relative mode warp implementation */
return SDL_FALSE;
}
return SDL_GetHintBoolean(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, SDL_FALSE);
@@ -734,20 +927,12 @@ SDL_SetRelativeMouseMode(SDL_bool enabled)
return 0;
}
if (enabled && focusWindow) {
/* Center it in the focused window to prevent clicks from going through
* to background windows.
*/
SDL_SetMouseFocus(focusWindow);
SDL_WarpMouseInWindow(focusWindow, focusWindow->w/2, focusWindow->h/2);
}
/* Set the relative mode */
if (!enabled && mouse->relative_mode_warp) {
mouse->relative_mode_warp = SDL_FALSE;
} else if (enabled && ShouldUseRelativeModeWarp(mouse)) {
mouse->relative_mode_warp = SDL_TRUE;
} else if (mouse->SetRelativeMouseMode(enabled) < 0) {
} else if (!mouse->SetRelativeMouseMode || mouse->SetRelativeMouseMode(enabled) < 0) {
if (enabled) {
/* Fall back to warp mode if native relative mode failed */
if (!mouse->WarpMouse) {
@@ -760,21 +945,37 @@ SDL_SetRelativeMouseMode(SDL_bool enabled)
mouse->scale_accum_x = 0.0f;
mouse->scale_accum_y = 0.0f;
if (mouse->focus) {
SDL_UpdateWindowGrab(mouse->focus);
if (enabled) {
/* Update cursor visibility before we potentially warp the mouse */
SDL_SetCursor(NULL);
}
if (enabled && focusWindow) {
SDL_SetMouseFocus(focusWindow);
if (mouse->relative_mode_warp)
SDL_WarpMouseInWindow(focusWindow, focusWindow->w/2, focusWindow->h/2);
}
if (focusWindow) {
SDL_UpdateWindowGrab(focusWindow);
/* Put the cursor back to where the application expects it */
if (!enabled) {
SDL_WarpMouseInWindow(mouse->focus, mouse->x, mouse->y);
SDL_WarpMouseInWindow(focusWindow, mouse->x, mouse->y);
}
SDL_UpdateMouseCapture(SDL_FALSE);
}
if (!enabled) {
/* Update cursor visibility after we restore the mouse position */
SDL_SetCursor(NULL);
}
/* Flush pending mouse motion - ideally we would pump events, but that's not always safe */
SDL_FlushEvent(SDL_MOUSEMOTION);
/* Update cursor visibility */
SDL_SetCursor(NULL);
return 0;
}
@@ -786,39 +987,59 @@ SDL_GetRelativeMouseMode()
return mouse->relative_mode;
}
int
SDL_UpdateMouseCapture(SDL_bool force_release)
{
SDL_Mouse *mouse = SDL_GetMouse();
SDL_Window *capture_window = NULL;
if (!mouse->CaptureMouse) {
return 0;
}
if (!force_release) {
if (mouse->capture_desired || (mouse->auto_capture && SDL_GetMouseState(NULL, NULL) != 0)) {
if (!mouse->relative_mode) {
capture_window = SDL_GetKeyboardFocus();
}
}
}
if (capture_window != mouse->capture_window) {
if (mouse->capture_window) {
mouse->CaptureMouse(NULL);
mouse->capture_window->flags &= ~SDL_WINDOW_MOUSE_CAPTURE;
mouse->capture_window = NULL;
}
if (capture_window) {
if (mouse->CaptureMouse(capture_window) < 0) {
/* CaptureMouse() will have set an error */
return -1;
}
capture_window->flags |= SDL_WINDOW_MOUSE_CAPTURE;
}
mouse->capture_window = capture_window;
}
return 0;
}
int
SDL_CaptureMouse(SDL_bool enabled)
{
SDL_Mouse *mouse = SDL_GetMouse();
SDL_Window *focusWindow;
SDL_bool isCaptured;
if (!mouse->CaptureMouse) {
return SDL_Unsupported();
}
focusWindow = SDL_GetKeyboardFocus();
isCaptured = focusWindow && (focusWindow->flags & SDL_WINDOW_MOUSE_CAPTURE);
if (isCaptured == enabled) {
return 0; /* already done! */
if (enabled && SDL_GetKeyboardFocus() == NULL) {
return SDL_SetError("No window has focus");
}
mouse->capture_desired = enabled;
if (enabled) {
if (!focusWindow) {
return SDL_SetError("No window has focus");
} else if (mouse->CaptureMouse(focusWindow) == -1) {
return -1; /* CaptureMouse() should call SetError */
}
focusWindow->flags |= SDL_WINDOW_MOUSE_CAPTURE;
} else {
if (mouse->CaptureMouse(NULL) == -1) {
return -1; /* CaptureMouse() should call SetError */
}
focusWindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE;
}
return 0;
return SDL_UpdateMouseCapture(SDL_FALSE);
}
SDL_Cursor *
@@ -878,7 +1099,7 @@ SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y)
SDL_Cursor *cursor;
if (!surface) {
SDL_SetError("Passed NULL cursor surface");
SDL_InvalidParamError("surface");
return NULL;
}
+22 -2
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
@@ -33,6 +33,12 @@ struct SDL_Cursor
void *driverdata;
};
typedef struct
{
SDL_MouseID mouseID;
Uint32 buttonstate;
} SDL_MouseInputSource;
typedef struct
{
int last_x, last_y;
@@ -82,7 +88,6 @@ typedef struct
int last_x, last_y; /* the last reported x and y coordinates */
float accumulated_wheel_x;
float accumulated_wheel_y;
Uint32 buttonstate;
SDL_bool has_position;
SDL_bool relative_mode;
SDL_bool relative_mode_warp;
@@ -93,6 +98,18 @@ typedef struct
Uint32 double_click_time;
int double_click_radius;
SDL_bool touch_mouse_events;
SDL_bool mouse_touch_events;
SDL_bool was_touch_mouse_events; /* Was a touch-mouse event pending? */
#if defined(__vita__)
Uint8 vita_touch_mouse_device;
#endif
SDL_bool auto_capture;
SDL_bool capture_desired;
SDL_Window *capture_window;
/* Data for input source state */
int num_sources;
SDL_MouseInputSource *sources;
/* Data for double-click tracking */
int num_clickstates;
@@ -120,6 +137,9 @@ extern void SDL_SetDefaultCursor(SDL_Cursor * cursor);
/* Set the mouse focus window */
extern void SDL_SetMouseFocus(SDL_Window * window);
/* Update the mouse capture window */
extern int SDL_UpdateMouseCapture(SDL_bool force_release);
/* Send a mouse motion event */
extern int SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
+132 -75
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
@@ -19,8 +19,8 @@
3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"
#include "SDL_hints.h"
#include "SDL_assert.h"
/* General quit handling code for SDL */
@@ -31,10 +31,22 @@
#include "SDL_events.h"
#include "SDL_events_c.h"
#if defined(HAVE_SIGNAL_H) || defined(HAVE_SIGACTION)
#define HAVE_SIGNAL_SUPPORT 1
#endif
#ifdef HAVE_SIGNAL_SUPPORT
static SDL_bool disable_signals = SDL_FALSE;
static SDL_bool send_quit_pending = SDL_FALSE;
#ifdef HAVE_SIGNAL_H
#ifdef SDL_BACKGROUNDING_SIGNAL
static SDL_bool send_backgrounding_pending = SDL_FALSE;
#endif
#ifdef SDL_FOREGROUNDING_SIGNAL
static SDL_bool send_foregrounding_pending = SDL_FALSE;
#endif
static void
SDL_HandleSIG(int sig)
{
@@ -42,111 +54,156 @@ SDL_HandleSIG(int sig)
signal(sig, SDL_HandleSIG);
/* Send a quit event next time the event loop pumps. */
/* We can't send it in signal handler; malloc() might be interrupted! */
send_quit_pending = SDL_TRUE;
/* We can't send it in signal handler; SDL_malloc() might be interrupted! */
if ((sig == SIGINT) || (sig == SIGTERM)) {
send_quit_pending = SDL_TRUE;
}
#ifdef SDL_BACKGROUNDING_SIGNAL
else if (sig == SDL_BACKGROUNDING_SIGNAL) {
send_backgrounding_pending = SDL_TRUE;
}
#endif
#ifdef SDL_FOREGROUNDING_SIGNAL
else if (sig == SDL_FOREGROUNDING_SIGNAL) {
send_foregrounding_pending = SDL_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 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 HAVE_SIGNAL_H
void (*ohandler) (int) = signal(sig, SIG_DFL);
if (ohandler != SDL_HandleSIG) {
signal(sig, ohandler);
}
#endif /* HAVE_SIGNAL_H */
}
/* Public functions */
static int
SDL_QuitInit_Internal(void)
{
#ifdef HAVE_SIGACTION
struct sigaction action;
sigaction(SIGINT, 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(SIGINT, &action, NULL);
}
sigaction(SIGTERM, 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(SIGTERM, &action, NULL);
}
#elif HAVE_SIGNAL_H
void (*ohandler) (int);
/* Both SIGINT and SIGTERM are translated into quit interrupts */
ohandler = signal(SIGINT, SDL_HandleSIG);
if (ohandler != SIG_DFL)
signal(SIGINT, ohandler);
ohandler = signal(SIGTERM, SDL_HandleSIG);
if (ohandler != SIG_DFL)
signal(SIGTERM, ohandler);
#endif /* HAVE_SIGNAL_H */
/* 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 0;
}
int
SDL_QuitInit(void)
{
if (!SDL_GetHintBoolean(SDL_HINT_NO_SIGNAL_HANDLERS, SDL_FALSE)) {
return SDL_QuitInit_Internal();
}
return 0;
}
static void
SDL_QuitQuit_Internal(void)
{
#ifdef HAVE_SIGACTION
struct sigaction action;
sigaction(SIGINT, NULL, &action);
if ( action.sa_handler == SDL_HandleSIG ) {
action.sa_handler = SIG_DFL;
sigaction(SIGINT, &action, NULL);
}
sigaction(SIGTERM, NULL, &action);
if ( action.sa_handler == SDL_HandleSIG ) {
action.sa_handler = SIG_DFL;
sigaction(SIGTERM, &action, NULL);
}
#elif HAVE_SIGNAL_H
void (*ohandler) (int);
SDL_EventSignal_Quit(SIGINT);
SDL_EventSignal_Quit(SIGTERM);
ohandler = signal(SIGINT, SIG_DFL);
if (ohandler != SDL_HandleSIG)
signal(SIGINT, ohandler);
ohandler = signal(SIGTERM, SIG_DFL);
if (ohandler != SDL_HandleSIG)
signal(SIGTERM, ohandler);
#endif /* HAVE_SIGNAL_H */
#ifdef SDL_BACKGROUNDING_SIGNAL
SDL_EventSignal_Quit(SDL_BACKGROUNDING_SIGNAL);
#endif
#ifdef SDL_FOREGROUNDING_SIGNAL
SDL_EventSignal_Quit(SDL_FOREGROUNDING_SIGNAL);
#endif
}
#endif
int
SDL_QuitInit(void)
{
#ifdef HAVE_SIGNAL_SUPPORT
if (!SDL_GetHintBoolean(SDL_HINT_NO_SIGNAL_HANDLERS, SDL_FALSE)) {
return SDL_QuitInit_Internal();
}
#endif
return 0;
}
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 = SDL_FALSE;
SDL_OnApplicationWillResignActive();
}
#endif
#ifdef SDL_FOREGROUNDING_SIGNAL
if (send_foregrounding_pending) {
send_foregrounding_pending = SDL_FALSE;
SDL_OnApplicationDidBecomeActive();
}
#endif
#endif
}
/* This function returns 1 if it's okay to close the application window */
int
SDL_SendQuit(void)
{
#ifdef HAVE_SIGNAL_SUPPORT
send_quit_pending = SDL_FALSE;
#endif
return SDL_SendAppEvent(SDL_QUIT);
}
void
SDL_SendPendingQuit(void)
{
if (send_quit_pending) {
SDL_SendQuit();
SDL_assert(!send_quit_pending);
}
}
/* vi: set ts=4 sw=4 expandtab: */
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
+131 -10
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
@@ -22,7 +22,6 @@
/* General touch handling code for SDL */
#include "SDL_assert.h"
#include "SDL_events.h"
#include "SDL_events_c.h"
#include "../video/SDL_sysvideo.h"
@@ -31,6 +30,15 @@
static int SDL_num_touch = 0;
static SDL_Touch **SDL_touchDevices = NULL;
/* for mapping touch events to mice */
#define SYNTHESIZE_TOUCH_TO_MOUSE 1
#if SYNTHESIZE_TOUCH_TO_MOUSE
static SDL_bool finger_touching = SDL_FALSE;
static SDL_FingerID track_fingerid;
static SDL_TouchID track_touchid;
#endif
/* Public functions */
int
@@ -55,6 +63,16 @@ SDL_GetTouchDevice(int index)
return SDL_touchDevices[index]->id;
}
const char*
SDL_GetTouchName(int index)
{
if (index < 0 || index >= SDL_num_touch) {
SDL_SetError("Unknown touch device");
return NULL;
}
return SDL_touchDevices[index]->name;
}
static int
SDL_GetTouchIndex(SDL_TouchID id)
{
@@ -86,6 +104,16 @@ SDL_GetTouch(SDL_TouchID id)
return SDL_touchDevices[index];
}
SDL_TouchDeviceType
SDL_GetTouchDeviceType(SDL_TouchID id)
{
SDL_Touch *touch = SDL_GetTouch(id);
if (touch) {
return touch->type;
}
return SDL_TOUCH_DEVICE_INVALID;
}
static int
SDL_GetFingerIndex(const SDL_Touch * touch, SDL_FingerID fingerid)
{
@@ -133,7 +161,7 @@ SDL_GetTouchFinger(SDL_TouchID touchID, int index)
}
int
SDL_AddTouch(SDL_TouchID touchID, const char *name)
SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name)
{
SDL_Touch **touchDevices;
int index;
@@ -163,9 +191,11 @@ SDL_AddTouch(SDL_TouchID touchID, const char *name)
/* 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 : "");
/* Record this touch device for gestures */
/* We could do this on the fly in the gesture code if we wanted */
@@ -219,22 +249,78 @@ SDL_DelFinger(SDL_Touch* touch, SDL_FingerID fingerid)
}
int
SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid,
SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window,
SDL_bool down, float x, float y, float pressure)
{
int posted;
SDL_Finger *finger;
SDL_Mouse *mouse;
SDL_Touch* touch = SDL_GetTouch(id);
if (!touch) {
return -1;
}
mouse = SDL_GetMouse();
#if SYNTHESIZE_TOUCH_TO_MOUSE
/* 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 */
{
#if defined(__vita__)
if (mouse->touch_mouse_events && ((mouse->vita_touch_mouse_device == id) || (mouse->vita_touch_mouse_device == 2)) ) {
#else
if (mouse->touch_mouse_events) {
#endif
/* FIXME: maybe we should only restrict to a few SDL_TouchDeviceType */
if (id != SDL_MOUSE_TOUCHID) {
if (window) {
if (down) {
if (finger_touching == SDL_FALSE) {
int pos_x = (int)(x * (float)window->w);
int pos_y = (int)(y * (float)window->h);
if (pos_x < 0) pos_x = 0;
if (pos_x > window->w - 1) pos_x = window->w - 1;
if (pos_y < 0) pos_y = 0;
if (pos_y > window->h - 1) pos_y = window->h - 1;
SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
}
} else {
if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
}
}
}
if (down) {
if (finger_touching == SDL_FALSE) {
finger_touching = SDL_TRUE;
track_touchid = id;
track_fingerid = fingerid;
}
} else {
if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
finger_touching = SDL_FALSE;
}
}
}
}
}
#endif
/* 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 0;
}
}
finger = SDL_GetFinger(touch, fingerid);
if (down) {
if (finger) {
/* This finger is already down */
return 0;
/* This finger is already down.
Assume the finger-up for the previous touch was lost, and send it. */
SDL_SendTouch(id, fingerid, window, SDL_FALSE, x, y, pressure);
}
if (SDL_AddFinger(touch, fingerid, x, y, pressure) < 0) {
@@ -252,6 +338,7 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid,
event.tfinger.dx = 0;
event.tfinger.dy = 0;
event.tfinger.pressure = pressure;
event.tfinger.windowID = window ? SDL_GetWindowID(window) : 0;
posted = (SDL_PushEvent(&event) > 0);
}
} else {
@@ -264,7 +351,7 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid,
if (SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) {
SDL_Event event;
event.tfinger.type = SDL_FINGERUP;
event.tfinger.touchId = id;
event.tfinger.touchId = id;
event.tfinger.fingerId = fingerid;
/* I don't trust the coordinates passed on fingerUp */
event.tfinger.x = finger->x;
@@ -272,6 +359,7 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid,
event.tfinger.dx = 0;
event.tfinger.dy = 0;
event.tfinger.pressure = pressure;
event.tfinger.windowID = window ? SDL_GetWindowID(window) : 0;
posted = (SDL_PushEvent(&event) > 0);
}
@@ -281,11 +369,12 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid,
}
int
SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid,
SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window,
float x, float y, float pressure)
{
SDL_Touch *touch;
SDL_Finger *finger;
SDL_Mouse *mouse;
int posted;
float xrel, yrel, prel;
@@ -294,9 +383,39 @@ SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid,
return -1;
}
mouse = SDL_GetMouse();
#if SYNTHESIZE_TOUCH_TO_MOUSE
/* SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events */
{
if (mouse->touch_mouse_events) {
if (id != SDL_MOUSE_TOUCHID) {
if (window) {
if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
int pos_x = (int)(x * (float)window->w);
int pos_y = (int)(y * (float)window->h);
if (pos_x < 0) pos_x = 0;
if (pos_x > window->w - 1) pos_x = window->w - 1;
if (pos_y < 0) pos_y = 0;
if (pos_y > window->h - 1) pos_y = window->h - 1;
SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
}
}
}
}
}
#endif
/* 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 0;
}
}
finger = SDL_GetFinger(touch,fingerid);
if (!finger) {
return SDL_SendTouch(id, fingerid, SDL_TRUE, x, y, pressure);
return SDL_SendTouch(id, fingerid, window, SDL_TRUE, x, y, pressure);
}
xrel = x - finger->x;
@@ -304,7 +423,7 @@ SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid,
prel = pressure - finger->pressure;
/* Drop events that don't change state */
if (!xrel && !yrel && !prel) {
if (xrel == 0.0f && yrel == 0.0f && prel == 0.0f) {
#if 0
printf("Touch event didn't change state - dropped!\n");
#endif
@@ -328,6 +447,7 @@ SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid,
event.tfinger.dx = xrel;
event.tfinger.dy = yrel;
event.tfinger.pressure = pressure;
event.tfinger.windowID = window ? SDL_GetWindowID(window) : 0;
posted = (SDL_PushEvent(&event) > 0);
}
return posted;
@@ -348,6 +468,7 @@ SDL_DelTouch(SDL_TouchID id)
SDL_free(touch->fingers[i]);
}
SDL_free(touch->fingers);
SDL_free(touch->name);
SDL_free(touch);
SDL_num_touch--;
+6 -4
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
@@ -27,9 +27,11 @@
typedef struct SDL_Touch
{
SDL_TouchID id;
SDL_TouchDeviceType type;
int num_fingers;
int max_fingers;
SDL_Finger** fingers;
char *name;
} SDL_Touch;
@@ -37,17 +39,17 @@ typedef struct SDL_Touch
extern int SDL_TouchInit(void);
/* Add a touch, returning the index of the touch, or -1 if there was an error. */
extern int SDL_AddTouch(SDL_TouchID id, const char *name);
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 int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid,
extern int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window,
SDL_bool down, float x, float y, float pressure);
/* Send a touch motion event for a touch */
extern int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid,
extern int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window,
float x, float y, float pressure);
/* Remove a touch */
+7 -5
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
@@ -25,7 +25,7 @@
#include "SDL_events.h"
#include "SDL_events_c.h"
#include "SDL_mouse_c.h"
#include "SDL_hints.h"
static int SDLCALL
RemovePendingSizeChangedAndResizedEvents(void * userdata, SDL_Event *event)
@@ -84,7 +84,7 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
if (window->flags & SDL_WINDOW_SHOWN) {
return 0;
}
window->flags &= ~SDL_WINDOW_HIDDEN;
window->flags &= ~(SDL_WINDOW_HIDDEN | SDL_WINDOW_MINIMIZED);
window->flags |= SDL_WINDOW_SHOWN;
SDL_OnWindowShown(window);
break;
@@ -110,6 +110,7 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
}
window->x = data1;
window->y = data2;
SDL_OnWindowMoved(window);
break;
case SDL_WINDOWEVENT_RESIZED:
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
@@ -200,8 +201,9 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
if (windowevent == SDL_WINDOWEVENT_CLOSE) {
if ( !window->prev && !window->next ) {
/* This is the last window in the list so send the SDL_QUIT event */
SDL_SendQuit();
if (SDL_GetHintBoolean(SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE, SDL_TRUE)) {
SDL_SendQuit(); /* This is the last window in the list so send the SDL_QUIT event */
}
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
+2 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
@@ -111,4 +111,5 @@ static const unsigned char default_cmask[] = {
};
#endif /* USE_MACOS_CURSOR */
/* vi: set ts=4 sw=4 expandtab: */
+349
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 SDL_VIDEO_DRIVER_X11 || 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 */
+32
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 */
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
+10 -10
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2022 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
@@ -299,12 +299,12 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
/* 115 */ SDL_SCANCODE_VOLUMEUP,
/* 116 */ SDL_SCANCODE_POWER,
/* 117 */ SDL_SCANCODE_KP_EQUALS,
/* 118 */ SDL_SCANCODE_UNKNOWN, /* plusminus */
/* 118 */ SDL_SCANCODE_KP_PLUSMINUS, /* plusminus */
/* 119 */ SDL_SCANCODE_PAUSE,
/* 120 */ SDL_SCANCODE_UNKNOWN, /* XF86LaunchA */
/* 121 */ SDL_SCANCODE_UNKNOWN, /* KP_Decimal */
/* 122 */ SDL_SCANCODE_UNKNOWN, /* Hangul */
/* 123 */ SDL_SCANCODE_UNKNOWN, /* Hangul_Hanja */
/* 121 */ SDL_SCANCODE_KP_COMMA, /* KP_Decimal */
/* 122 */ SDL_SCANCODE_LANG1, /* Hangul */
/* 123 */ SDL_SCANCODE_LANG2, /* Hangul_Hanja */
/* 124 */ SDL_SCANCODE_INTERNATIONAL3, /* Yen */
/* 125 */ SDL_SCANCODE_LGUI,
/* 126 */ SDL_SCANCODE_RGUI,
@@ -320,7 +320,7 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
/* 136 */ SDL_SCANCODE_FIND,
/* 137 */ SDL_SCANCODE_CUT,
/* 138 */ SDL_SCANCODE_HELP,
/* 139 */ SDL_SCANCODE_UNKNOWN, /* XF86MenuKB */
/* 139 */ SDL_SCANCODE_MENU, /* XF86MenuKB */
/* 140 */ SDL_SCANCODE_CALCULATOR,
/* 141 */ SDL_SCANCODE_UNKNOWN,
/* 142 */ SDL_SCANCODE_SLEEP,
@@ -360,8 +360,8 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
/* 176 */ SDL_SCANCODE_UNKNOWN,
/* 177 */ SDL_SCANCODE_UNKNOWN, /* XF86ScrollUp */
/* 178 */ SDL_SCANCODE_UNKNOWN, /* XF86ScrollDown */
/* 179 */ SDL_SCANCODE_UNKNOWN, /* parenleft */
/* 180 */ SDL_SCANCODE_UNKNOWN, /* parenright */
/* 179 */ SDL_SCANCODE_KP_LEFTPAREN, /* parenleft */
/* 180 */ SDL_SCANCODE_KP_RIGHTPAREN, /* parenright */
/* 181 */ SDL_SCANCODE_UNKNOWN, /* XF86New */
/* 182 */ SDL_SCANCODE_AGAIN,
/* 183 */ SDL_SCANCODE_F13, /* XF86Tools */
@@ -371,7 +371,7 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
/* 187 */ SDL_SCANCODE_F17, /* XF86Launch8 */
/* 188 */ SDL_SCANCODE_F18, /* XF86Launch9 */
/* 189 */ SDL_SCANCODE_F19, /* null keysym */
/* 190 */ SDL_SCANCODE_UNKNOWN,
/* 190 */ SDL_SCANCODE_F20,
/* 191 */ SDL_SCANCODE_UNKNOWN,
/* 192 */ SDL_SCANCODE_UNKNOWN, /* XF86TouchpadToggle */
/* 193 */ SDL_SCANCODE_UNKNOWN,
@@ -389,7 +389,7 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
/* 205 */ SDL_SCANCODE_UNKNOWN, /* XF86Suspend */
/* 206 */ SDL_SCANCODE_UNKNOWN, /* XF86Close */
/* 207 */ SDL_SCANCODE_AUDIOPLAY,
/* 208 */ SDL_SCANCODE_AUDIONEXT,
/* 208 */ SDL_SCANCODE_AUDIOFASTFORWARD,
/* 209 */ SDL_SCANCODE_UNKNOWN,
/* 210 */ SDL_SCANCODE_PRINTSCREEN,
/* 211 */ SDL_SCANCODE_UNKNOWN,