mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-05-16 17:58:27 +00:00
Prevent crashes if freed objects are passed to SDL API functions
Instead of using the magic tag in the object, we'll actually keep track of valid objects Fixes https://github.com/libsdl-org/SDL/issues/9869 Fixes https://github.com/libsdl-org/SDL/issues/9235
This commit is contained in:
parent
57a15933cd
commit
b0e93e4e63
28 changed files with 191 additions and 126 deletions
15
src/SDL.c
15
src/SDL.c
|
@ -543,6 +543,7 @@ void SDL_Quit(void)
|
||||||
SDL_DBus_Quit();
|
SDL_DBus_Quit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
SDL_SetObjectsInvalid();
|
||||||
SDL_ClearHints();
|
SDL_ClearHints();
|
||||||
SDL_AssertionsQuit();
|
SDL_AssertionsQuit();
|
||||||
|
|
||||||
|
@ -563,20 +564,6 @@ void SDL_Quit(void)
|
||||||
SDL_bInMainQuit = SDL_FALSE;
|
SDL_bInMainQuit = SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assume we can wrap SDL_AtomicInt values and cast to Uint32 */
|
|
||||||
SDL_COMPILE_TIME_ASSERT(sizeof_object_id, sizeof(int) == sizeof(Uint32));
|
|
||||||
|
|
||||||
Uint32 SDL_GetNextObjectID(void)
|
|
||||||
{
|
|
||||||
static SDL_AtomicInt last_id;
|
|
||||||
|
|
||||||
Uint32 id = (Uint32)SDL_AtomicIncRef(&last_id) + 1;
|
|
||||||
if (id == 0) {
|
|
||||||
id = (Uint32)SDL_AtomicIncRef(&last_id) + 1;
|
|
||||||
}
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the library version number */
|
/* Get the library version number */
|
||||||
int SDL_GetVersion(void)
|
int SDL_GetVersion(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -83,6 +83,10 @@ SDL_bool SDL_InsertIntoHashTable(SDL_HashTable *table, const void *key, const vo
|
||||||
SDL_HashItem *item;
|
SDL_HashItem *item;
|
||||||
const Uint32 hash = calc_hash(table, key);
|
const Uint32 hash = calc_hash(table, key);
|
||||||
|
|
||||||
|
if (!table) {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if ( (!table->stackable) && (SDL_FindInHashTable(table, key, NULL)) ) {
|
if ( (!table->stackable) && (SDL_FindInHashTable(table, key, NULL)) ) {
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -107,6 +111,10 @@ SDL_bool SDL_FindInHashTable(const SDL_HashTable *table, const void *key, const
|
||||||
void *data = table->data;
|
void *data = table->data;
|
||||||
SDL_HashItem *i;
|
SDL_HashItem *i;
|
||||||
|
|
||||||
|
if (!table) {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = table->table[hash]; i; i = i->next) {
|
for (i = table->table[hash]; i; i = i->next) {
|
||||||
if (table->keymatch(key, i->key, data)) {
|
if (table->keymatch(key, i->key, data)) {
|
||||||
if (_value) {
|
if (_value) {
|
||||||
|
@ -126,6 +134,10 @@ SDL_bool SDL_RemoveFromHashTable(SDL_HashTable *table, const void *key)
|
||||||
SDL_HashItem *prev = NULL;
|
SDL_HashItem *prev = NULL;
|
||||||
void *data = table->data;
|
void *data = table->data;
|
||||||
|
|
||||||
|
if (!table) {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
for (item = table->table[hash]; item; item = item->next) {
|
for (item = table->table[hash]; item; item = item->next) {
|
||||||
if (table->keymatch(key, item->key, data)) {
|
if (table->keymatch(key, item->key, data)) {
|
||||||
if (prev) {
|
if (prev) {
|
||||||
|
@ -134,7 +146,9 @@ SDL_bool SDL_RemoveFromHashTable(SDL_HashTable *table, const void *key)
|
||||||
table->table[hash] = item->next;
|
table->table[hash] = item->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
table->nuke(item->key, item->value, data);
|
if (table->nuke) {
|
||||||
|
table->nuke(item->key, item->value, data);
|
||||||
|
}
|
||||||
SDL_free(item);
|
SDL_free(item);
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -149,6 +163,10 @@ SDL_bool SDL_IterateHashTableKey(const SDL_HashTable *table, const void *key, co
|
||||||
{
|
{
|
||||||
SDL_HashItem *item = *iter ? ((SDL_HashItem *) *iter)->next : table->table[calc_hash(table, key)];
|
SDL_HashItem *item = *iter ? ((SDL_HashItem *) *iter)->next : table->table[calc_hash(table, key)];
|
||||||
|
|
||||||
|
if (!table) {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
while (item) {
|
while (item) {
|
||||||
if (table->keymatch(key, item->key, table->data)) {
|
if (table->keymatch(key, item->key, table->data)) {
|
||||||
*_value = item->value;
|
*_value = item->value;
|
||||||
|
@ -169,6 +187,10 @@ SDL_bool SDL_IterateHashTable(const SDL_HashTable *table, const void **_key, con
|
||||||
SDL_HashItem *item = (SDL_HashItem *) *iter;
|
SDL_HashItem *item = (SDL_HashItem *) *iter;
|
||||||
Uint32 idx = 0;
|
Uint32 idx = 0;
|
||||||
|
|
||||||
|
if (!table) {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (item) {
|
if (item) {
|
||||||
const SDL_HashItem *orig = item;
|
const SDL_HashItem *orig = item;
|
||||||
item = item->next;
|
item = item->next;
|
||||||
|
@ -219,7 +241,9 @@ void SDL_DestroyHashTable(SDL_HashTable *table)
|
||||||
SDL_HashItem *item = table->table[i];
|
SDL_HashItem *item = table->table[i];
|
||||||
while (item) {
|
while (item) {
|
||||||
SDL_HashItem *next = item->next;
|
SDL_HashItem *next = item->next;
|
||||||
table->nuke(item->key, item->value, data);
|
if (table->nuke) {
|
||||||
|
table->nuke(item->key, item->value, data);
|
||||||
|
}
|
||||||
SDL_free(item);
|
SDL_free(item);
|
||||||
item = next;
|
item = next;
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,6 +279,8 @@
|
||||||
#define SDL_MAIN_NOIMPL /* don't drag in header-only implementation of SDL_main */
|
#define SDL_MAIN_NOIMPL /* don't drag in header-only implementation of SDL_main */
|
||||||
#include <SDL3/SDL_main.h>
|
#include <SDL3/SDL_main.h>
|
||||||
|
|
||||||
|
#include "SDL_utils_c.h"
|
||||||
|
|
||||||
/* The internal implementations of these functions have up to nanosecond precision.
|
/* The internal implementations of these functions have up to nanosecond precision.
|
||||||
We can expose these functions as part of the API if we want to later.
|
We can expose these functions as part of the API if we want to later.
|
||||||
*/
|
*/
|
||||||
|
@ -287,7 +289,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern Uint32 SDLCALL SDL_GetNextObjectID(void);
|
|
||||||
extern int SDLCALL SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS);
|
extern int SDLCALL SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeoutNS);
|
||||||
extern int SDLCALL SDL_WaitConditionTimeoutNS(SDL_Condition *cond, SDL_Mutex *mutex, Sint64 timeoutNS);
|
extern int SDLCALL SDL_WaitConditionTimeoutNS(SDL_Condition *cond, SDL_Mutex *mutex, Sint64 timeoutNS);
|
||||||
extern SDL_bool SDLCALL SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS);
|
extern SDL_bool SDLCALL SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS);
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
#include "SDL_internal.h"
|
#include "SDL_internal.h"
|
||||||
|
|
||||||
#include "SDL_utils_c.h"
|
#include "SDL_hashtable.h"
|
||||||
|
|
||||||
/* Common utility functions that aren't in the public API */
|
/* Common utility functions that aren't in the public API */
|
||||||
|
|
||||||
|
@ -100,3 +100,68 @@ SDL_bool SDL_endswith(const char *string, const char *suffix)
|
||||||
}
|
}
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Assume we can wrap SDL_AtomicInt values and cast to Uint32 */
|
||||||
|
SDL_COMPILE_TIME_ASSERT(sizeof_object_id, sizeof(int) == sizeof(Uint32));
|
||||||
|
|
||||||
|
Uint32 SDL_GetNextObjectID(void)
|
||||||
|
{
|
||||||
|
static SDL_AtomicInt last_id;
|
||||||
|
|
||||||
|
Uint32 id = (Uint32)SDL_AtomicIncRef(&last_id) + 1;
|
||||||
|
if (id == 0) {
|
||||||
|
id = (Uint32)SDL_AtomicIncRef(&last_id) + 1;
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SDL_HashTable *SDL_objects;
|
||||||
|
|
||||||
|
static Uint32 SDL_HashObject(const void *key, void *unused)
|
||||||
|
{
|
||||||
|
return (Uint32)(uintptr_t)key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SDL_bool SDL_KeyMatchObject(const void *a, const void *b, void *unused)
|
||||||
|
{
|
||||||
|
return (a == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDL_SetObjectValid(void *object, SDL_ObjectType type, SDL_bool valid)
|
||||||
|
{
|
||||||
|
SDL_assert(object != NULL);
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
if (!SDL_objects) {
|
||||||
|
SDL_objects = SDL_CreateHashTable(NULL, 32, SDL_HashObject, SDL_KeyMatchObject, NULL, SDL_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_InsertIntoHashTable(SDL_objects, object, (void *)(uintptr_t)type);
|
||||||
|
} else {
|
||||||
|
if (SDL_objects) {
|
||||||
|
SDL_RemoveFromHashTable(SDL_objects, object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_bool SDL_ObjectValid(void *object, SDL_ObjectType type)
|
||||||
|
{
|
||||||
|
if (!object) {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const void *object_type;
|
||||||
|
if (!SDL_FindInHashTable(SDL_objects, object, &object_type)) {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (((SDL_ObjectType)(uintptr_t)object_type) == type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SDL_SetObjectsInvalid(void)
|
||||||
|
{
|
||||||
|
if (SDL_objects) {
|
||||||
|
SDL_DestroyHashTable(SDL_objects);
|
||||||
|
SDL_objects = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -32,4 +32,24 @@ extern void SDL_CalculateFraction(float x, int *numerator, int *denominator);
|
||||||
|
|
||||||
extern SDL_bool SDL_endswith(const char *string, const char *suffix);
|
extern SDL_bool SDL_endswith(const char *string, const char *suffix);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
SDL_OBJECT_TYPE_UNKNOWN,
|
||||||
|
SDL_OBJECT_TYPE_WINDOW,
|
||||||
|
SDL_OBJECT_TYPE_RENDERER,
|
||||||
|
SDL_OBJECT_TYPE_TEXTURE,
|
||||||
|
SDL_OBJECT_TYPE_JOYSTICK,
|
||||||
|
SDL_OBJECT_TYPE_GAMEPAD,
|
||||||
|
SDL_OBJECT_TYPE_HAPTIC,
|
||||||
|
SDL_OBJECT_TYPE_SENSOR,
|
||||||
|
SDL_OBJECT_TYPE_HIDAPI_DEVICE,
|
||||||
|
SDL_OBJECT_TYPE_HIDAPI_JOYSTICK,
|
||||||
|
|
||||||
|
} SDL_ObjectType;
|
||||||
|
|
||||||
|
extern Uint32 SDL_GetNextObjectID(void);
|
||||||
|
extern void SDL_SetObjectValid(void *object, SDL_ObjectType type, SDL_bool valid);
|
||||||
|
extern SDL_bool SDL_ObjectValid(void *object, SDL_ObjectType type);
|
||||||
|
extern void SDL_SetObjectsInvalid(void);
|
||||||
|
|
||||||
#endif /* SDL_utils_h_ */
|
#endif /* SDL_utils_h_ */
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include "SDL_audio_c.h"
|
#include "SDL_audio_c.h"
|
||||||
#include "SDL_sysaudio.h"
|
#include "SDL_sysaudio.h"
|
||||||
#include "../thread/SDL_systhread.h"
|
#include "../thread/SDL_systhread.h"
|
||||||
#include "../SDL_utils_c.h"
|
|
||||||
|
|
||||||
// Available audio drivers
|
// Available audio drivers
|
||||||
static const AudioBootStrap *const bootstrap[] = {
|
static const AudioBootStrap *const bootstrap[] = {
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include <sys/soundcard.h>
|
#include <sys/soundcard.h>
|
||||||
|
|
||||||
#include "../SDL_audiodev_c.h"
|
#include "../SDL_audiodev_c.h"
|
||||||
#include "../../SDL_utils_c.h"
|
|
||||||
#include "SDL_dspaudio.h"
|
#include "SDL_dspaudio.h"
|
||||||
|
|
||||||
static void DSP_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture)
|
static void DSP_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevice **default_capture)
|
||||||
|
|
|
@ -891,7 +891,7 @@ int SDL_SetKeyboardFocus(SDL_Window *window)
|
||||||
SDL_Keyboard *keyboard = &SDL_keyboard;
|
SDL_Keyboard *keyboard = &SDL_keyboard;
|
||||||
|
|
||||||
if (window) {
|
if (window) {
|
||||||
if (!video || window->magic != &video->window_magic || window->is_destroying) {
|
if (!SDL_ObjectValid(window, SDL_OBJECT_TYPE_WINDOW) || window->is_destroying) {
|
||||||
return SDL_SetError("Invalid window");
|
return SDL_SetError("Invalid window");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,9 @@
|
||||||
#include "../joystick/SDL_joystick_c.h" /* For SDL_IsJoystickValid */
|
#include "../joystick/SDL_joystick_c.h" /* For SDL_IsJoystickValid */
|
||||||
|
|
||||||
static SDL_Haptic *SDL_haptics = NULL;
|
static SDL_Haptic *SDL_haptics = NULL;
|
||||||
static char SDL_haptic_magic;
|
|
||||||
|
|
||||||
#define CHECK_HAPTIC_MAGIC(haptic, retval) \
|
#define CHECK_HAPTIC_MAGIC(haptic, retval) \
|
||||||
if (!haptic || haptic->magic != &SDL_haptic_magic) { \
|
if (!SDL_ObjectValid(haptic, SDL_OBJECT_TYPE_HAPTIC)) { \
|
||||||
SDL_InvalidParamError("haptic"); \
|
SDL_InvalidParamError("haptic"); \
|
||||||
return retval; \
|
return retval; \
|
||||||
}
|
}
|
||||||
|
@ -135,7 +134,7 @@ SDL_Haptic *SDL_OpenHaptic(SDL_HapticID instance_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the haptic device */
|
/* Initialize the haptic device */
|
||||||
haptic->magic = &SDL_haptic_magic;
|
SDL_SetObjectValid(haptic, SDL_OBJECT_TYPE_HAPTIC, SDL_TRUE);
|
||||||
haptic->instance_id = instance_id;
|
haptic->instance_id = instance_id;
|
||||||
haptic->rumble_id = -1;
|
haptic->rumble_id = -1;
|
||||||
if (SDL_SYS_HapticOpen(haptic) < 0) {
|
if (SDL_SYS_HapticOpen(haptic) < 0) {
|
||||||
|
@ -318,7 +317,7 @@ void SDL_CloseHaptic(SDL_Haptic *haptic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SDL_SYS_HapticClose(haptic);
|
SDL_SYS_HapticClose(haptic);
|
||||||
haptic->magic = NULL;
|
SDL_SetObjectValid(haptic, SDL_OBJECT_TYPE_HAPTIC, SDL_FALSE);
|
||||||
|
|
||||||
/* Remove from the list */
|
/* Remove from the list */
|
||||||
hapticlist = SDL_haptics;
|
hapticlist = SDL_haptics;
|
||||||
|
|
|
@ -40,8 +40,6 @@ struct haptic_effect
|
||||||
*/
|
*/
|
||||||
struct SDL_Haptic
|
struct SDL_Haptic
|
||||||
{
|
{
|
||||||
const void *magic;
|
|
||||||
|
|
||||||
SDL_HapticID instance_id; /* Device instance, monotonically increasing from 0 */
|
SDL_HapticID instance_id; /* Device instance, monotonically increasing from 0 */
|
||||||
char *name; /* Device name - system dependent */
|
char *name; /* Device name - system dependent */
|
||||||
|
|
||||||
|
|
|
@ -1000,19 +1000,17 @@ static const struct hidapi_backend LIBUSB_Backend = {
|
||||||
|
|
||||||
struct SDL_hid_device
|
struct SDL_hid_device
|
||||||
{
|
{
|
||||||
const void *magic;
|
|
||||||
void *device;
|
void *device;
|
||||||
const struct hidapi_backend *backend;
|
const struct hidapi_backend *backend;
|
||||||
SDL_hid_device_info info;
|
SDL_hid_device_info info;
|
||||||
};
|
};
|
||||||
static char device_magic;
|
|
||||||
|
|
||||||
#if defined(HAVE_PLATFORM_BACKEND) || defined(HAVE_DRIVER_BACKEND) || defined(HAVE_LIBUSB)
|
#if defined(HAVE_PLATFORM_BACKEND) || defined(HAVE_DRIVER_BACKEND) || defined(HAVE_LIBUSB)
|
||||||
|
|
||||||
static SDL_hid_device *CreateHIDDeviceWrapper(void *device, const struct hidapi_backend *backend)
|
static SDL_hid_device *CreateHIDDeviceWrapper(void *device, const struct hidapi_backend *backend)
|
||||||
{
|
{
|
||||||
SDL_hid_device *wrapper = (SDL_hid_device *)SDL_malloc(sizeof(*wrapper));
|
SDL_hid_device *wrapper = (SDL_hid_device *)SDL_malloc(sizeof(*wrapper));
|
||||||
wrapper->magic = &device_magic;
|
SDL_SetObjectValid(wrapper, SDL_OBJECT_TYPE_HIDAPI_DEVICE, SDL_TRUE);
|
||||||
wrapper->device = device;
|
wrapper->device = device;
|
||||||
wrapper->backend = backend;
|
wrapper->backend = backend;
|
||||||
SDL_zero(wrapper->info);
|
SDL_zero(wrapper->info);
|
||||||
|
@ -1021,20 +1019,20 @@ static SDL_hid_device *CreateHIDDeviceWrapper(void *device, const struct hidapi_
|
||||||
|
|
||||||
#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB */
|
#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB */
|
||||||
|
|
||||||
static void DeleteHIDDeviceWrapper(SDL_hid_device *device)
|
static void DeleteHIDDeviceWrapper(SDL_hid_device *wrapper)
|
||||||
{
|
{
|
||||||
device->magic = NULL;
|
SDL_SetObjectValid(wrapper, SDL_OBJECT_TYPE_HIDAPI_DEVICE, SDL_FALSE);
|
||||||
SDL_free(device->info.path);
|
SDL_free(wrapper->info.path);
|
||||||
SDL_free(device->info.serial_number);
|
SDL_free(wrapper->info.serial_number);
|
||||||
SDL_free(device->info.manufacturer_string);
|
SDL_free(wrapper->info.manufacturer_string);
|
||||||
SDL_free(device->info.product_string);
|
SDL_free(wrapper->info.product_string);
|
||||||
SDL_free(device);
|
SDL_free(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_DEVICE_MAGIC(device, retval) \
|
#define CHECK_DEVICE_MAGIC(device, retval) \
|
||||||
if (!device || device->magic != &device_magic) { \
|
if (!SDL_ObjectValid(device, SDL_OBJECT_TYPE_HIDAPI_DEVICE)) { \
|
||||||
SDL_SetError("Invalid device"); \
|
SDL_SetError("Invalid device"); \
|
||||||
return retval; \
|
return retval; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define COPY_IF_EXISTS(var) \
|
#define COPY_IF_EXISTS(var) \
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
/* This is the gamepad API for Simple DirectMedia Layer */
|
/* This is the gamepad API for Simple DirectMedia Layer */
|
||||||
|
|
||||||
#include "../SDL_utils_c.h"
|
|
||||||
#include "SDL_sysjoystick.h"
|
#include "SDL_sysjoystick.h"
|
||||||
#include "SDL_joystick_c.h"
|
#include "SDL_joystick_c.h"
|
||||||
#include "SDL_steam_virtual_gamepad.h"
|
#include "SDL_steam_virtual_gamepad.h"
|
||||||
|
@ -104,15 +103,12 @@ static GamepadMapping_t *s_pSupportedGamepads SDL_GUARDED_BY(SDL_joystick_lock)
|
||||||
static GamepadMapping_t *s_pDefaultMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
static GamepadMapping_t *s_pDefaultMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
static GamepadMapping_t *s_pXInputMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
static GamepadMapping_t *s_pXInputMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
static MappingChangeTracker *s_mappingChangeTracker SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
static MappingChangeTracker *s_mappingChangeTracker SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
static char gamepad_magic;
|
|
||||||
|
|
||||||
#define _guarded SDL_GUARDED_BY(SDL_joystick_lock)
|
#define _guarded SDL_GUARDED_BY(SDL_joystick_lock)
|
||||||
|
|
||||||
/* The SDL gamepad structure */
|
/* The SDL gamepad structure */
|
||||||
struct SDL_Gamepad
|
struct SDL_Gamepad
|
||||||
{
|
{
|
||||||
const void *magic _guarded;
|
|
||||||
|
|
||||||
SDL_Joystick *joystick _guarded; /* underlying joystick device */
|
SDL_Joystick *joystick _guarded; /* underlying joystick device */
|
||||||
int ref_count _guarded;
|
int ref_count _guarded;
|
||||||
|
|
||||||
|
@ -131,12 +127,12 @@ struct SDL_Gamepad
|
||||||
|
|
||||||
#undef _guarded
|
#undef _guarded
|
||||||
|
|
||||||
#define CHECK_GAMEPAD_MAGIC(gamepad, retval) \
|
#define CHECK_GAMEPAD_MAGIC(gamepad, retval) \
|
||||||
if (!gamepad || gamepad->magic != &gamepad_magic || \
|
if (!SDL_ObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD) || \
|
||||||
!SDL_IsJoystickValid(gamepad->joystick)) { \
|
!SDL_IsJoystickValid(gamepad->joystick)) { \
|
||||||
SDL_InvalidParamError("gamepad"); \
|
SDL_InvalidParamError("gamepad"); \
|
||||||
SDL_UnlockJoysticks(); \
|
SDL_UnlockJoysticks(); \
|
||||||
return retval; \
|
return retval; \
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_vidpid_list SDL_allowed_gamepads = {
|
static SDL_vidpid_list SDL_allowed_gamepads = {
|
||||||
|
@ -2683,7 +2679,7 @@ SDL_Gamepad *SDL_OpenGamepad(SDL_JoystickID instance_id)
|
||||||
SDL_UnlockJoysticks();
|
SDL_UnlockJoysticks();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
gamepad->magic = &gamepad_magic;
|
SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, SDL_TRUE);
|
||||||
|
|
||||||
gamepad->joystick = SDL_OpenJoystick(instance_id);
|
gamepad->joystick = SDL_OpenJoystick(instance_id);
|
||||||
if (!gamepad->joystick) {
|
if (!gamepad->joystick) {
|
||||||
|
@ -3612,7 +3608,7 @@ void SDL_CloseGamepad(SDL_Gamepad *gamepad)
|
||||||
|
|
||||||
SDL_LockJoysticks();
|
SDL_LockJoysticks();
|
||||||
|
|
||||||
if (!gamepad || gamepad->magic != &gamepad_magic) {
|
if (!SDL_ObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD)) {
|
||||||
SDL_UnlockJoysticks();
|
SDL_UnlockJoysticks();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3641,7 +3637,7 @@ void SDL_CloseGamepad(SDL_Gamepad *gamepad)
|
||||||
gamepadlist = gamepadlist->next;
|
gamepadlist = gamepadlist->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
gamepad->magic = NULL;
|
SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, SDL_FALSE);
|
||||||
SDL_free(gamepad->bindings);
|
SDL_free(gamepad->bindings);
|
||||||
SDL_free(gamepad->last_match_axis);
|
SDL_free(gamepad->last_match_axis);
|
||||||
SDL_free(gamepad->last_hat_mask);
|
SDL_free(gamepad->last_hat_mask);
|
||||||
|
|
|
@ -121,7 +121,6 @@ static SDL_Joystick *SDL_joysticks SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
static int SDL_joystick_player_count SDL_GUARDED_BY(SDL_joystick_lock) = 0;
|
static int SDL_joystick_player_count SDL_GUARDED_BY(SDL_joystick_lock) = 0;
|
||||||
static SDL_JoystickID *SDL_joystick_players SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
static SDL_JoystickID *SDL_joystick_players SDL_GUARDED_BY(SDL_joystick_lock) = NULL;
|
||||||
static SDL_bool SDL_joystick_allows_background_events = SDL_FALSE;
|
static SDL_bool SDL_joystick_allows_background_events = SDL_FALSE;
|
||||||
char SDL_joystick_magic;
|
|
||||||
|
|
||||||
static Uint32 initial_arcadestick_devices[] = {
|
static Uint32 initial_arcadestick_devices[] = {
|
||||||
MAKE_VIDPID(0x0079, 0x181a), /* Venom Arcade Stick */
|
MAKE_VIDPID(0x0079, 0x181a), /* Venom Arcade Stick */
|
||||||
|
@ -415,11 +414,11 @@ static SDL_vidpid_list zero_centered_devices = {
|
||||||
SDL_FALSE
|
SDL_FALSE
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CHECK_JOYSTICK_MAGIC(joystick, retval) \
|
#define CHECK_JOYSTICK_MAGIC(joystick, retval) \
|
||||||
if (!joystick || joystick->magic != &SDL_joystick_magic) { \
|
if (!SDL_ObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK)) { \
|
||||||
SDL_InvalidParamError("joystick"); \
|
SDL_InvalidParamError("joystick"); \
|
||||||
SDL_UnlockJoysticks(); \
|
SDL_UnlockJoysticks(); \
|
||||||
return retval; \
|
return retval; \
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool SDL_JoysticksInitialized(void)
|
SDL_bool SDL_JoysticksInitialized(void)
|
||||||
|
@ -1096,7 +1095,7 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id)
|
||||||
SDL_UnlockJoysticks();
|
SDL_UnlockJoysticks();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
joystick->magic = &SDL_joystick_magic;
|
SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, SDL_TRUE);
|
||||||
joystick->driver = driver;
|
joystick->driver = driver;
|
||||||
joystick->instance_id = instance_id;
|
joystick->instance_id = instance_id;
|
||||||
joystick->attached = SDL_TRUE;
|
joystick->attached = SDL_TRUE;
|
||||||
|
@ -1104,6 +1103,7 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id)
|
||||||
joystick->battery_percent = -1;
|
joystick->battery_percent = -1;
|
||||||
|
|
||||||
if (driver->Open(joystick, device_index) < 0) {
|
if (driver->Open(joystick, device_index) < 0) {
|
||||||
|
SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, SDL_FALSE);
|
||||||
SDL_free(joystick);
|
SDL_free(joystick);
|
||||||
SDL_UnlockJoysticks();
|
SDL_UnlockJoysticks();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1346,7 +1346,7 @@ int SDL_SendJoystickVirtualSensorData(SDL_Joystick *joystick, SDL_SensorType typ
|
||||||
SDL_bool SDL_IsJoystickValid(SDL_Joystick *joystick)
|
SDL_bool SDL_IsJoystickValid(SDL_Joystick *joystick)
|
||||||
{
|
{
|
||||||
SDL_AssertJoysticksLocked();
|
SDL_AssertJoysticksLocked();
|
||||||
return (joystick && joystick->magic == &SDL_joystick_magic);
|
return SDL_ObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool SDL_PrivateJoystickGetAutoGamepadMapping(SDL_JoystickID instance_id, SDL_GamepadMapping *out)
|
SDL_bool SDL_PrivateJoystickGetAutoGamepadMapping(SDL_JoystickID instance_id, SDL_GamepadMapping *out)
|
||||||
|
@ -1869,7 +1869,7 @@ void SDL_CloseJoystick(SDL_Joystick *joystick)
|
||||||
|
|
||||||
joystick->driver->Close(joystick);
|
joystick->driver->Close(joystick);
|
||||||
joystick->hwdata = NULL;
|
joystick->hwdata = NULL;
|
||||||
joystick->magic = NULL;
|
SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, SDL_FALSE);
|
||||||
|
|
||||||
joysticklist = SDL_joysticks;
|
joysticklist = SDL_joysticks;
|
||||||
joysticklistprev = NULL;
|
joysticklistprev = NULL;
|
||||||
|
|
|
@ -33,7 +33,6 @@ extern "C" {
|
||||||
|
|
||||||
struct SDL_JoystickDriver;
|
struct SDL_JoystickDriver;
|
||||||
struct SDL_SteamVirtualGamepadInfo;
|
struct SDL_SteamVirtualGamepadInfo;
|
||||||
extern char SDL_joystick_magic;
|
|
||||||
|
|
||||||
/* Initialization and shutdown functions */
|
/* Initialization and shutdown functions */
|
||||||
extern int SDL_InitJoysticks(void);
|
extern int SDL_InitJoysticks(void);
|
||||||
|
|
|
@ -76,8 +76,6 @@ typedef struct SDL_JoystickSensorInfo
|
||||||
|
|
||||||
struct SDL_Joystick
|
struct SDL_Joystick
|
||||||
{
|
{
|
||||||
const void *magic _guarded;
|
|
||||||
|
|
||||||
SDL_JoystickID instance_id _guarded; /* Device instance, monotonically increasing from 0 */
|
SDL_JoystickID instance_id _guarded; /* Device instance, monotonically increasing from 0 */
|
||||||
char *name _guarded; /* Joystick name - system dependent */
|
char *name _guarded; /* Joystick name - system dependent */
|
||||||
char *path _guarded; /* Joystick path - system dependent */
|
char *path _guarded; /* Joystick path - system dependent */
|
||||||
|
|
|
@ -91,7 +91,6 @@ static SDL_SpinLock SDL_HIDAPI_spinlock;
|
||||||
static SDL_bool SDL_HIDAPI_hints_changed = SDL_FALSE;
|
static SDL_bool SDL_HIDAPI_hints_changed = SDL_FALSE;
|
||||||
static Uint32 SDL_HIDAPI_change_count = 0;
|
static Uint32 SDL_HIDAPI_change_count = 0;
|
||||||
static SDL_HIDAPI_Device *SDL_HIDAPI_devices SDL_GUARDED_BY(SDL_joystick_lock);
|
static SDL_HIDAPI_Device *SDL_HIDAPI_devices SDL_GUARDED_BY(SDL_joystick_lock);
|
||||||
static char SDL_HIDAPI_device_magic;
|
|
||||||
static int SDL_HIDAPI_numjoysticks = 0;
|
static int SDL_HIDAPI_numjoysticks = 0;
|
||||||
static SDL_bool SDL_HIDAPI_combine_joycons = SDL_TRUE;
|
static SDL_bool SDL_HIDAPI_combine_joycons = SDL_TRUE;
|
||||||
static SDL_bool initialized = SDL_FALSE;
|
static SDL_bool initialized = SDL_FALSE;
|
||||||
|
@ -933,7 +932,7 @@ static SDL_HIDAPI_Device *HIDAPI_AddDevice(const struct SDL_hid_device_info *inf
|
||||||
if (!device) {
|
if (!device) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
device->magic = &SDL_HIDAPI_device_magic;
|
SDL_SetObjectValid(device, SDL_OBJECT_TYPE_HIDAPI_JOYSTICK, SDL_TRUE);
|
||||||
device->path = SDL_strdup(info->path);
|
device->path = SDL_strdup(info->path);
|
||||||
if (!device->path) {
|
if (!device->path) {
|
||||||
SDL_free(device);
|
SDL_free(device);
|
||||||
|
@ -1049,7 +1048,7 @@ static void HIDAPI_DelDevice(SDL_HIDAPI_Device *device)
|
||||||
device->children[i]->parent = NULL;
|
device->children[i]->parent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
device->magic = NULL;
|
SDL_SetObjectValid(device, SDL_OBJECT_TYPE_HIDAPI_JOYSTICK, SDL_FALSE);
|
||||||
SDL_DestroyMutex(device->dev_lock);
|
SDL_DestroyMutex(device->dev_lock);
|
||||||
SDL_free(device->manufacturer_string);
|
SDL_free(device->manufacturer_string);
|
||||||
SDL_free(device->product_string);
|
SDL_free(device->product_string);
|
||||||
|
@ -1547,7 +1546,7 @@ static SDL_bool HIDAPI_GetJoystickDevice(SDL_Joystick *joystick, SDL_HIDAPI_Devi
|
||||||
|
|
||||||
if (joystick && joystick->hwdata) {
|
if (joystick && joystick->hwdata) {
|
||||||
*device = joystick->hwdata->device;
|
*device = joystick->hwdata->device;
|
||||||
if (*device && (*device)->magic == &SDL_HIDAPI_device_magic && (*device)->driver != NULL) {
|
if (SDL_ObjectValid(*device, SDL_OBJECT_TYPE_HIDAPI_JOYSTICK) && (*device)->driver != NULL) {
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,6 @@ struct SDL_HIDAPI_DeviceDriver;
|
||||||
|
|
||||||
typedef struct SDL_HIDAPI_Device
|
typedef struct SDL_HIDAPI_Device
|
||||||
{
|
{
|
||||||
const void *magic;
|
|
||||||
char *name;
|
char *name;
|
||||||
char *manufacturer_string;
|
char *manufacturer_string;
|
||||||
char *product_string;
|
char *product_string;
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <linux/joystick.h>
|
#include <linux/joystick.h>
|
||||||
|
|
||||||
#include "../../SDL_utils_c.h"
|
|
||||||
#include "../../events/SDL_events_c.h"
|
#include "../../events/SDL_events_c.h"
|
||||||
#include "../../core/linux/SDL_evdev.h"
|
#include "../../core/linux/SDL_evdev.h"
|
||||||
#include "../SDL_sysjoystick.h"
|
#include "../SDL_sysjoystick.h"
|
||||||
|
@ -2330,6 +2329,7 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
|
||||||
MAPPED_DPAD_ALL = 0xF,
|
MAPPED_DPAD_ALL = 0xF,
|
||||||
};
|
};
|
||||||
unsigned int mapped;
|
unsigned int mapped;
|
||||||
|
SDL_bool result = SDL_FALSE;
|
||||||
|
|
||||||
SDL_AssertJoysticksLocked();
|
SDL_AssertJoysticksLocked();
|
||||||
|
|
||||||
|
@ -2351,22 +2351,19 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
|
||||||
if (!joystick) {
|
if (!joystick) {
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
joystick->magic = &SDL_joystick_magic;
|
|
||||||
SDL_memcpy(&joystick->guid, &item->guid, sizeof(item->guid));
|
SDL_memcpy(&joystick->guid, &item->guid, sizeof(item->guid));
|
||||||
|
|
||||||
joystick->hwdata = (struct joystick_hwdata *)
|
joystick->hwdata = (struct joystick_hwdata *)SDL_calloc(1, sizeof(*joystick->hwdata));
|
||||||
SDL_calloc(1, sizeof(*joystick->hwdata));
|
|
||||||
if (!joystick->hwdata) {
|
if (!joystick->hwdata) {
|
||||||
SDL_free(joystick);
|
SDL_free(joystick);
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, SDL_TRUE);
|
||||||
|
|
||||||
item->checked_mapping = SDL_TRUE;
|
item->checked_mapping = SDL_TRUE;
|
||||||
|
|
||||||
if (PrepareJoystickHwdata(joystick, item, NULL) == -1) {
|
if (PrepareJoystickHwdata(joystick, item, NULL) < 0) {
|
||||||
SDL_free(joystick->hwdata);
|
goto done; /* SDL_SetError will already have been called */
|
||||||
SDL_free(joystick);
|
|
||||||
return SDL_FALSE; /* SDL_SetError will already have been called */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* don't assign `item->hwdata` so it's not in any global state. */
|
/* don't assign `item->hwdata` so it's not in any global state. */
|
||||||
|
@ -2375,9 +2372,7 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
|
||||||
|
|
||||||
if (!joystick->hwdata->has_key[BTN_GAMEPAD]) {
|
if (!joystick->hwdata->has_key[BTN_GAMEPAD]) {
|
||||||
/* Not a gamepad according to the specs. */
|
/* Not a gamepad according to the specs. */
|
||||||
LINUX_JoystickClose(joystick);
|
goto done;
|
||||||
SDL_free(joystick);
|
|
||||||
return SDL_FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have a gamepad, start filling out the mappings */
|
/* We have a gamepad, start filling out the mappings */
|
||||||
|
@ -2773,9 +2768,6 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LINUX_JoystickClose(joystick);
|
|
||||||
SDL_free(joystick);
|
|
||||||
|
|
||||||
/* Cache the mapping for later */
|
/* Cache the mapping for later */
|
||||||
item->mapping = (SDL_GamepadMapping *)SDL_malloc(sizeof(*item->mapping));
|
item->mapping = (SDL_GamepadMapping *)SDL_malloc(sizeof(*item->mapping));
|
||||||
if (item->mapping) {
|
if (item->mapping) {
|
||||||
|
@ -2784,8 +2776,14 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
|
||||||
#ifdef DEBUG_GAMEPAD_MAPPING
|
#ifdef DEBUG_GAMEPAD_MAPPING
|
||||||
SDL_Log("Generated mapping for device %d", device_index);
|
SDL_Log("Generated mapping for device %d", device_index);
|
||||||
#endif
|
#endif
|
||||||
|
result = SDL_TRUE;
|
||||||
|
|
||||||
return SDL_TRUE;
|
done:
|
||||||
|
LINUX_JoystickClose(joystick);
|
||||||
|
SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, SDL_FALSE);
|
||||||
|
SDL_free(joystick);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_JoystickDriver SDL_LINUX_JoystickDriver = {
|
SDL_JoystickDriver SDL_LINUX_JoystickDriver = {
|
||||||
|
|
|
@ -46,10 +46,10 @@ this should probably be removed at some point in the future. --ryan. */
|
||||||
#define SDL_PROP_WINDOW_RENDERER_POINTER "SDL.internal.window.renderer"
|
#define SDL_PROP_WINDOW_RENDERER_POINTER "SDL.internal.window.renderer"
|
||||||
#define SDL_PROP_TEXTURE_PARENT_POINTER "SDL.internal.texture.parent"
|
#define SDL_PROP_TEXTURE_PARENT_POINTER "SDL.internal.texture.parent"
|
||||||
|
|
||||||
#define CHECK_RENDERER_MAGIC_BUT_NOT_DESTROYED_FLAG(renderer, retval) \
|
#define CHECK_RENDERER_MAGIC_BUT_NOT_DESTROYED_FLAG(renderer, retval) \
|
||||||
if (!(renderer) || (renderer)->magic != &SDL_renderer_magic) { \
|
if (!SDL_ObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER)) { \
|
||||||
SDL_InvalidParamError("renderer"); \
|
SDL_InvalidParamError("renderer"); \
|
||||||
return retval; \
|
return retval; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_RENDERER_MAGIC(renderer, retval) \
|
#define CHECK_RENDERER_MAGIC(renderer, retval) \
|
||||||
|
@ -60,7 +60,7 @@ this should probably be removed at some point in the future. --ryan. */
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_TEXTURE_MAGIC(texture, retval) \
|
#define CHECK_TEXTURE_MAGIC(texture, retval) \
|
||||||
if (!(texture) || (texture)->magic != &SDL_texture_magic) { \
|
if (!SDL_ObjectValid(texture, SDL_OBJECT_TYPE_TEXTURE)) { \
|
||||||
SDL_InvalidParamError("texture"); \
|
SDL_InvalidParamError("texture"); \
|
||||||
return retval; \
|
return retval; \
|
||||||
}
|
}
|
||||||
|
@ -133,9 +133,6 @@ static const SDL_RenderDriver *render_drivers[] = {
|
||||||
};
|
};
|
||||||
#endif /* !SDL_RENDER_DISABLED */
|
#endif /* !SDL_RENDER_DISABLED */
|
||||||
|
|
||||||
char SDL_renderer_magic;
|
|
||||||
char SDL_texture_magic;
|
|
||||||
|
|
||||||
|
|
||||||
int SDL_AddSupportedTextureFormat(SDL_Renderer *renderer, SDL_PixelFormatEnum format)
|
int SDL_AddSupportedTextureFormat(SDL_Renderer *renderer, SDL_PixelFormatEnum format)
|
||||||
{
|
{
|
||||||
|
@ -946,7 +943,7 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->magic = &SDL_renderer_magic;
|
SDL_SetObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER, SDL_TRUE);
|
||||||
|
|
||||||
#ifdef SDL_PLATFORM_ANDROID
|
#ifdef SDL_PLATFORM_ANDROID
|
||||||
Android_ActivityMutex_Lock_Running();
|
Android_ActivityMutex_Lock_Running();
|
||||||
|
@ -1007,7 +1004,6 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
|
||||||
break; // Yay, we got one!
|
break; // Yay, we got one!
|
||||||
}
|
}
|
||||||
SDL_zerop(renderer); // make sure we don't leave function pointers from a previous CreateRenderer() in this struct.
|
SDL_zerop(renderer); // make sure we don't leave function pointers from a previous CreateRenderer() in this struct.
|
||||||
renderer->magic = &SDL_renderer_magic;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1021,7 +1017,6 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
|
||||||
|
|
||||||
VerifyDrawQueueFunctions(renderer);
|
VerifyDrawQueueFunctions(renderer);
|
||||||
|
|
||||||
renderer->magic = &SDL_renderer_magic;
|
|
||||||
renderer->window = window;
|
renderer->window = window;
|
||||||
renderer->target_mutex = SDL_CreateMutex();
|
renderer->target_mutex = SDL_CreateMutex();
|
||||||
if (surface) {
|
if (surface) {
|
||||||
|
@ -1114,6 +1109,8 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
||||||
|
SDL_SetObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER, SDL_FALSE);
|
||||||
|
|
||||||
#ifdef SDL_PLATFORM_ANDROID
|
#ifdef SDL_PLATFORM_ANDROID
|
||||||
Android_ActivityMutex_Unlock();
|
Android_ActivityMutex_Unlock();
|
||||||
#endif
|
#endif
|
||||||
|
@ -1316,7 +1313,7 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
texture->magic = &SDL_texture_magic;
|
SDL_SetObjectValid(texture, SDL_OBJECT_TYPE_TEXTURE, SDL_TRUE);
|
||||||
texture->colorspace = (SDL_Colorspace)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, default_colorspace);
|
texture->colorspace = (SDL_Colorspace)SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, default_colorspace);
|
||||||
texture->format = format;
|
texture->format = format;
|
||||||
texture->access = access;
|
texture->access = access;
|
||||||
|
@ -4496,7 +4493,7 @@ static int SDL_DestroyTextureInternal(SDL_Texture *texture, SDL_bool is_destroyi
|
||||||
renderer->logical_target = NULL;
|
renderer->logical_target = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
texture->magic = NULL;
|
SDL_SetObjectValid(texture, SDL_OBJECT_TYPE_TEXTURE, SDL_FALSE);
|
||||||
|
|
||||||
if (texture->next) {
|
if (texture->next) {
|
||||||
texture->next->prev = texture->prev;
|
texture->next->prev = texture->prev;
|
||||||
|
@ -4596,7 +4593,7 @@ void SDL_DestroyRenderer(SDL_Renderer *renderer)
|
||||||
// in either order.
|
// in either order.
|
||||||
if (!renderer->destroyed) {
|
if (!renderer->destroyed) {
|
||||||
SDL_DestroyRendererWithoutFreeing(renderer);
|
SDL_DestroyRendererWithoutFreeing(renderer);
|
||||||
renderer->magic = NULL; // It's no longer magical...
|
SDL_SetObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER, SDL_FALSE); // It's no longer magical...
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_free((void *)renderer->info.texture_formats);
|
SDL_free((void *)renderer->info.texture_formats);
|
||||||
|
|
|
@ -44,8 +44,6 @@ typedef struct SDL_DRect
|
||||||
/* The SDL 2D rendering system */
|
/* The SDL 2D rendering system */
|
||||||
|
|
||||||
typedef struct SDL_RenderDriver SDL_RenderDriver;
|
typedef struct SDL_RenderDriver SDL_RenderDriver;
|
||||||
extern char SDL_renderer_magic;
|
|
||||||
extern char SDL_texture_magic;
|
|
||||||
|
|
||||||
/* Rendering view state */
|
/* Rendering view state */
|
||||||
typedef struct SDL_RenderViewState
|
typedef struct SDL_RenderViewState
|
||||||
|
@ -62,7 +60,6 @@ typedef struct SDL_RenderViewState
|
||||||
/* Define the SDL texture structure */
|
/* Define the SDL texture structure */
|
||||||
struct SDL_Texture
|
struct SDL_Texture
|
||||||
{
|
{
|
||||||
const void *magic;
|
|
||||||
SDL_Colorspace colorspace; /**< The colorspace of the texture */
|
SDL_Colorspace colorspace; /**< The colorspace of the texture */
|
||||||
float SDR_white_point; /**< The SDR white point for this content */
|
float SDR_white_point; /**< The SDR white point for this content */
|
||||||
float HDR_headroom; /**< The HDR headroom needed by this content */
|
float HDR_headroom; /**< The HDR headroom needed by this content */
|
||||||
|
@ -160,8 +157,6 @@ typedef enum
|
||||||
/* Define the SDL renderer structure */
|
/* Define the SDL renderer structure */
|
||||||
struct SDL_Renderer
|
struct SDL_Renderer
|
||||||
{
|
{
|
||||||
const void *magic;
|
|
||||||
|
|
||||||
void (*WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event);
|
void (*WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event);
|
||||||
int (*GetOutputSize)(SDL_Renderer *renderer, int *w, int *h);
|
int (*GetOutputSize)(SDL_Renderer *renderer, int *w, int *h);
|
||||||
SDL_bool (*SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode);
|
SDL_bool (*SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode);
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "../SDL_sysrender.h"
|
#include "../SDL_sysrender.h"
|
||||||
#include "SDL_shaders_gl.h"
|
#include "SDL_shaders_gl.h"
|
||||||
#include "../../video/SDL_pixels_c.h"
|
#include "../../video/SDL_pixels_c.h"
|
||||||
#include "../../SDL_utils_c.h"
|
|
||||||
|
|
||||||
#ifdef SDL_PLATFORM_MACOS
|
#ifdef SDL_PLATFORM_MACOS
|
||||||
#include <OpenGL/OpenGL.h>
|
#include <OpenGL/OpenGL.h>
|
||||||
|
|
|
@ -56,13 +56,12 @@ static SDL_AtomicInt SDL_sensor_lock_pending;
|
||||||
static int SDL_sensors_locked;
|
static int SDL_sensors_locked;
|
||||||
static SDL_bool SDL_sensors_initialized;
|
static SDL_bool SDL_sensors_initialized;
|
||||||
static SDL_Sensor *SDL_sensors SDL_GUARDED_BY(SDL_sensor_lock) = NULL;
|
static SDL_Sensor *SDL_sensors SDL_GUARDED_BY(SDL_sensor_lock) = NULL;
|
||||||
static char SDL_sensor_magic;
|
|
||||||
|
|
||||||
#define CHECK_SENSOR_MAGIC(sensor, retval) \
|
#define CHECK_SENSOR_MAGIC(sensor, retval) \
|
||||||
if (!sensor || sensor->magic != &SDL_sensor_magic) { \
|
if (!SDL_ObjectValid(sensor, SDL_OBJECT_TYPE_SENSOR)) { \
|
||||||
SDL_InvalidParamError("sensor"); \
|
SDL_InvalidParamError("sensor"); \
|
||||||
SDL_UnlockSensors(); \
|
SDL_UnlockSensors(); \
|
||||||
return retval; \
|
return retval; \
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool SDL_SensorsInitialized(void)
|
SDL_bool SDL_SensorsInitialized(void)
|
||||||
|
@ -327,13 +326,14 @@ SDL_Sensor *SDL_OpenSensor(SDL_SensorID instance_id)
|
||||||
SDL_UnlockSensors();
|
SDL_UnlockSensors();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sensor->magic = &SDL_sensor_magic;
|
SDL_SetObjectValid(sensor, SDL_OBJECT_TYPE_SENSOR, SDL_TRUE);
|
||||||
sensor->driver = driver;
|
sensor->driver = driver;
|
||||||
sensor->instance_id = instance_id;
|
sensor->instance_id = instance_id;
|
||||||
sensor->type = driver->GetDeviceType(device_index);
|
sensor->type = driver->GetDeviceType(device_index);
|
||||||
sensor->non_portable_type = driver->GetDeviceNonPortableType(device_index);
|
sensor->non_portable_type = driver->GetDeviceNonPortableType(device_index);
|
||||||
|
|
||||||
if (driver->Open(sensor, device_index) < 0) {
|
if (driver->Open(sensor, device_index) < 0) {
|
||||||
|
SDL_SetObjectValid(sensor, SDL_OBJECT_TYPE_SENSOR, SDL_FALSE);
|
||||||
SDL_free(sensor);
|
SDL_free(sensor);
|
||||||
SDL_UnlockSensors();
|
SDL_UnlockSensors();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -508,6 +508,7 @@ void SDL_CloseSensor(SDL_Sensor *sensor)
|
||||||
|
|
||||||
sensor->driver->Close(sensor);
|
sensor->driver->Close(sensor);
|
||||||
sensor->hwdata = NULL;
|
sensor->hwdata = NULL;
|
||||||
|
SDL_SetObjectValid(sensor, SDL_OBJECT_TYPE_SENSOR, SDL_FALSE);
|
||||||
|
|
||||||
sensorlist = SDL_sensors;
|
sensorlist = SDL_sensors;
|
||||||
sensorlistprev = NULL;
|
sensorlistprev = NULL;
|
||||||
|
|
|
@ -32,8 +32,6 @@
|
||||||
/* The SDL sensor structure */
|
/* The SDL sensor structure */
|
||||||
struct SDL_Sensor
|
struct SDL_Sensor
|
||||||
{
|
{
|
||||||
const void *magic _guarded;
|
|
||||||
|
|
||||||
SDL_SensorID instance_id _guarded; /* Device instance, monotonically increasing from 0 */
|
SDL_SensorID instance_id _guarded; /* Device instance, monotonically increasing from 0 */
|
||||||
char *name _guarded; /* Sensor name - system dependent */
|
char *name _guarded; /* Sensor name - system dependent */
|
||||||
SDL_SensorType type _guarded; /* Type of the sensor */
|
SDL_SensorType type _guarded; /* Type of the sensor */
|
||||||
|
|
|
@ -37,7 +37,6 @@ typedef struct SDL_WindowData SDL_WindowData;
|
||||||
/* Define the SDL window structure, corresponding to toplevel windows */
|
/* Define the SDL window structure, corresponding to toplevel windows */
|
||||||
struct SDL_Window
|
struct SDL_Window
|
||||||
{
|
{
|
||||||
const void *magic;
|
|
||||||
SDL_WindowID id;
|
SDL_WindowID id;
|
||||||
char *title;
|
char *title;
|
||||||
SDL_Surface *icon;
|
SDL_Surface *icon;
|
||||||
|
@ -371,7 +370,6 @@ struct SDL_VideoDevice
|
||||||
SDL_Rect desktop_bounds;
|
SDL_Rect desktop_bounds;
|
||||||
SDL_Window *windows;
|
SDL_Window *windows;
|
||||||
SDL_Window *grabbed_window;
|
SDL_Window *grabbed_window;
|
||||||
Uint8 window_magic;
|
|
||||||
Uint32 clipboard_sequence;
|
Uint32 clipboard_sequence;
|
||||||
SDL_ClipboardDataCallback clipboard_callback;
|
SDL_ClipboardDataCallback clipboard_callback;
|
||||||
SDL_ClipboardCleanupCallback clipboard_cleanup;
|
SDL_ClipboardCleanupCallback clipboard_cleanup;
|
||||||
|
|
|
@ -141,7 +141,7 @@ static VideoBootStrap *bootstrap[] = {
|
||||||
SDL_UninitializedVideo(); \
|
SDL_UninitializedVideo(); \
|
||||||
return retval; \
|
return retval; \
|
||||||
} \
|
} \
|
||||||
if (!(window) || (window)->magic != &_this->window_magic) { \
|
if (!SDL_ObjectValid(window, SDL_OBJECT_TYPE_WINDOW)) { \
|
||||||
SDL_SetError("Invalid window"); \
|
SDL_SetError("Invalid window"); \
|
||||||
return retval; \
|
return retval; \
|
||||||
}
|
}
|
||||||
|
@ -2118,7 +2118,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & SDL_WINDOW_MODAL) && (!parent || parent->magic != &_this->window_magic)) {
|
if ((flags & SDL_WINDOW_MODAL) && !SDL_ObjectValid(parent, SDL_OBJECT_TYPE_WINDOW)) {
|
||||||
SDL_SetError("Modal windows must specify a parent window");
|
SDL_SetError("Modal windows must specify a parent window");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2130,7 +2130,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tooltip and popup menu window must specify a parent window */
|
/* Tooltip and popup menu window must specify a parent window */
|
||||||
if (!parent || parent->magic != &_this->window_magic) {
|
if (!SDL_ObjectValid(parent, SDL_OBJECT_TYPE_WINDOW)) {
|
||||||
SDL_SetError("Tooltip and popup menu windows must specify a parent window");
|
SDL_SetError("Tooltip and popup menu windows must specify a parent window");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2236,7 +2236,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
|
||||||
if (!window) {
|
if (!window) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
window->magic = &_this->window_magic;
|
SDL_SetObjectValid(window, SDL_OBJECT_TYPE_WINDOW, SDL_TRUE);
|
||||||
window->id = SDL_GetNextObjectID();
|
window->id = SDL_GetNextObjectID();
|
||||||
window->floating.x = window->windowed.x = window->x = x;
|
window->floating.x = window->windowed.x = window->x = x;
|
||||||
window->floating.y = window->windowed.y = window->y = y;
|
window->floating.y = window->windowed.y = window->y = y;
|
||||||
|
@ -3920,7 +3920,7 @@ void SDL_DestroyWindow(SDL_Window *window)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now invalidate magic */
|
/* Now invalidate magic */
|
||||||
window->magic = NULL;
|
SDL_SetObjectValid(window, SDL_OBJECT_TYPE_WINDOW, SDL_FALSE);
|
||||||
|
|
||||||
/* Free memory associated with the window */
|
/* Free memory associated with the window */
|
||||||
SDL_free(window->title);
|
SDL_free(window->title);
|
||||||
|
|
|
@ -1252,7 +1252,7 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
|
||||||
} else if (window->max_aspect && aspect > window->max_aspect) {
|
} else if (window->max_aspect && aspect > window->max_aspect) {
|
||||||
wind->requested.pixel_width = SDL_roundf((float)wind->requested.pixel_height * window->max_aspect);
|
wind->requested.pixel_width = SDL_roundf((float)wind->requested.pixel_height * window->max_aspect);
|
||||||
}
|
}
|
||||||
|
|
||||||
wind->requested.logical_width = PixelToPoint(window, wind->requested.pixel_width);
|
wind->requested.logical_width = PixelToPoint(window, wind->requested.pixel_width);
|
||||||
wind->requested.logical_height = PixelToPoint(window, wind->requested.pixel_height);
|
wind->requested.logical_height = PixelToPoint(window, wind->requested.pixel_height);
|
||||||
}
|
}
|
||||||
|
@ -1854,7 +1854,7 @@ static void Wayland_ReleasePopup(SDL_VideoDevice *_this, SDL_Window *popup)
|
||||||
SDL_WindowData *popupdata;
|
SDL_WindowData *popupdata;
|
||||||
|
|
||||||
/* Basic sanity checks to weed out the weird popup closures */
|
/* Basic sanity checks to weed out the weird popup closures */
|
||||||
if (!popup || popup->magic != &_this->window_magic) {
|
if (!SDL_ObjectValid(popup, SDL_OBJECT_TYPE_WINDOW)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
popupdata = popup->driverdata;
|
popupdata = popup->driverdata;
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
#include "../../events/SDL_mouse_c.h"
|
#include "../../events/SDL_mouse_c.h"
|
||||||
#include "../../events/SDL_touch_c.h"
|
#include "../../events/SDL_touch_c.h"
|
||||||
#include "../../core/linux/SDL_system_theme.h"
|
#include "../../core/linux/SDL_system_theme.h"
|
||||||
#include "../../SDL_utils_c.h"
|
|
||||||
#include "../SDL_sysvideo.h"
|
#include "../SDL_sysvideo.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#include "../../events/SDL_mouse_c.h"
|
#include "../../events/SDL_mouse_c.h"
|
||||||
#include "../../events/SDL_events_c.h"
|
#include "../../events/SDL_events_c.h"
|
||||||
#include "../../core/unix/SDL_appid.h"
|
#include "../../core/unix/SDL_appid.h"
|
||||||
#include "../../SDL_utils_c.h"
|
|
||||||
|
|
||||||
#include "SDL_x11video.h"
|
#include "SDL_x11video.h"
|
||||||
#include "SDL_x11mouse.h"
|
#include "SDL_x11mouse.h"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue