mirror of
				https://github.com/libsdl-org/SDL.git
				synced 2025-10-26 12:27:44 +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:
		
							
								
								
									
										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" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Sam Lantinga
					Sam Lantinga