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(); | ||||
| #endif | ||||
|  | ||||
|     SDL_SetObjectsInvalid(); | ||||
|     SDL_ClearHints(); | ||||
|     SDL_AssertionsQuit(); | ||||
|  | ||||
| @@ -563,20 +564,6 @@ void SDL_Quit(void) | ||||
|     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 */ | ||||
| int SDL_GetVersion(void) | ||||
| { | ||||
|   | ||||
| @@ -83,6 +83,10 @@ SDL_bool SDL_InsertIntoHashTable(SDL_HashTable *table, const void *key, const vo | ||||
|     SDL_HashItem *item; | ||||
|     const Uint32 hash = calc_hash(table, key); | ||||
|  | ||||
|     if (!table) { | ||||
|         return SDL_FALSE; | ||||
|     } | ||||
|  | ||||
|     if ( (!table->stackable) && (SDL_FindInHashTable(table, key, NULL)) ) { | ||||
|         return SDL_FALSE; | ||||
|     } | ||||
| @@ -107,6 +111,10 @@ SDL_bool SDL_FindInHashTable(const SDL_HashTable *table, const void *key, const | ||||
|     void *data = table->data; | ||||
|     SDL_HashItem *i; | ||||
|  | ||||
|     if (!table) { | ||||
|         return SDL_FALSE; | ||||
|     } | ||||
|  | ||||
|     for (i = table->table[hash]; i; i = i->next) { | ||||
|         if (table->keymatch(key, i->key, data)) { | ||||
|             if (_value) { | ||||
| @@ -126,6 +134,10 @@ SDL_bool SDL_RemoveFromHashTable(SDL_HashTable *table, const void *key) | ||||
|     SDL_HashItem *prev = NULL; | ||||
|     void *data = table->data; | ||||
|  | ||||
|     if (!table) { | ||||
|         return SDL_FALSE; | ||||
|     } | ||||
|  | ||||
|     for (item = table->table[hash]; item; item = item->next) { | ||||
|         if (table->keymatch(key, item->key, data)) { | ||||
|             if (prev) { | ||||
| @@ -134,7 +146,9 @@ SDL_bool SDL_RemoveFromHashTable(SDL_HashTable *table, const void *key) | ||||
|                 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); | ||||
|             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)]; | ||||
|  | ||||
|     if (!table) { | ||||
|         return SDL_FALSE; | ||||
|     } | ||||
|  | ||||
|     while (item) { | ||||
|         if (table->keymatch(key, item->key, table->data)) { | ||||
|             *_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; | ||||
|     Uint32 idx = 0; | ||||
|  | ||||
|     if (!table) { | ||||
|         return SDL_FALSE; | ||||
|     } | ||||
|  | ||||
|     if (item) { | ||||
|         const SDL_HashItem *orig = item; | ||||
|         item = item->next; | ||||
| @@ -219,7 +241,9 @@ void SDL_DestroyHashTable(SDL_HashTable *table) | ||||
|             SDL_HashItem *item = table->table[i]; | ||||
|             while (item) { | ||||
|                 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); | ||||
|                 item = next; | ||||
|             } | ||||
|   | ||||
| @@ -279,6 +279,8 @@ | ||||
| #define SDL_MAIN_NOIMPL /* don't drag in header-only implementation of SDL_main */ | ||||
| #include <SDL3/SDL_main.h> | ||||
|  | ||||
| #include "SDL_utils_c.h" | ||||
|  | ||||
| /* 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. | ||||
| */ | ||||
| @@ -287,7 +289,6 @@ | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| extern Uint32 SDLCALL SDL_GetNextObjectID(void); | ||||
| extern int SDLCALL SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, 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); | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
| */ | ||||
| #include "SDL_internal.h" | ||||
|  | ||||
| #include "SDL_utils_c.h" | ||||
| #include "SDL_hashtable.h" | ||||
|  | ||||
| /* 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; | ||||
| } | ||||
|  | ||||
| /* 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); | ||||
|  | ||||
| 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_ */ | ||||
|   | ||||
| @@ -23,7 +23,6 @@ | ||||
| #include "SDL_audio_c.h" | ||||
| #include "SDL_sysaudio.h" | ||||
| #include "../thread/SDL_systhread.h" | ||||
| #include "../SDL_utils_c.h" | ||||
|  | ||||
| // Available audio drivers | ||||
| static const AudioBootStrap *const bootstrap[] = { | ||||
|   | ||||
| @@ -37,7 +37,6 @@ | ||||
| #include <sys/soundcard.h> | ||||
|  | ||||
| #include "../SDL_audiodev_c.h" | ||||
| #include "../../SDL_utils_c.h" | ||||
| #include "SDL_dspaudio.h" | ||||
|  | ||||
| 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; | ||||
|  | ||||
|     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"); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -25,10 +25,9 @@ | ||||
| #include "../joystick/SDL_joystick_c.h" /* For SDL_IsJoystickValid */ | ||||
|  | ||||
| static SDL_Haptic *SDL_haptics = NULL; | ||||
| static char SDL_haptic_magic; | ||||
|  | ||||
| #define CHECK_HAPTIC_MAGIC(haptic, retval)                  \ | ||||
|     if (!haptic || haptic->magic != &SDL_haptic_magic) {    \ | ||||
|     if (!SDL_ObjectValid(haptic, SDL_OBJECT_TYPE_HAPTIC)) { \ | ||||
|         SDL_InvalidParamError("haptic");                    \ | ||||
|         return retval;                                      \ | ||||
|     } | ||||
| @@ -135,7 +134,7 @@ SDL_Haptic *SDL_OpenHaptic(SDL_HapticID instance_id) | ||||
|     } | ||||
|  | ||||
|     /* Initialize the haptic device */ | ||||
|     haptic->magic = &SDL_haptic_magic; | ||||
|     SDL_SetObjectValid(haptic, SDL_OBJECT_TYPE_HAPTIC, SDL_TRUE); | ||||
|     haptic->instance_id = instance_id; | ||||
|     haptic->rumble_id = -1; | ||||
|     if (SDL_SYS_HapticOpen(haptic) < 0) { | ||||
| @@ -318,7 +317,7 @@ void SDL_CloseHaptic(SDL_Haptic *haptic) | ||||
|         } | ||||
|     } | ||||
|     SDL_SYS_HapticClose(haptic); | ||||
|     haptic->magic = NULL; | ||||
|     SDL_SetObjectValid(haptic, SDL_OBJECT_TYPE_HAPTIC, SDL_FALSE); | ||||
|  | ||||
|     /* Remove from the list */ | ||||
|     hapticlist = SDL_haptics; | ||||
|   | ||||
| @@ -40,8 +40,6 @@ struct haptic_effect | ||||
|  */ | ||||
| struct SDL_Haptic | ||||
| { | ||||
|     const void *magic; | ||||
|  | ||||
|     SDL_HapticID instance_id;       /* Device instance, monotonically increasing from 0 */ | ||||
|     char *name;                     /* Device name - system dependent */ | ||||
|  | ||||
|   | ||||
| @@ -1000,19 +1000,17 @@ static const struct hidapi_backend LIBUSB_Backend = { | ||||
|  | ||||
| struct SDL_hid_device | ||||
| { | ||||
|     const void *magic; | ||||
|     void *device; | ||||
|     const struct hidapi_backend *backend; | ||||
|     SDL_hid_device_info info; | ||||
| }; | ||||
| static char device_magic; | ||||
|  | ||||
| #if defined(HAVE_PLATFORM_BACKEND) || defined(HAVE_DRIVER_BACKEND) || defined(HAVE_LIBUSB) | ||||
|  | ||||
| static SDL_hid_device *CreateHIDDeviceWrapper(void *device, const struct hidapi_backend *backend) | ||||
| { | ||||
|     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->backend = backend; | ||||
|     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 */ | ||||
|  | ||||
| static void DeleteHIDDeviceWrapper(SDL_hid_device *device) | ||||
| static void DeleteHIDDeviceWrapper(SDL_hid_device *wrapper) | ||||
| { | ||||
|     device->magic = NULL; | ||||
|     SDL_free(device->info.path); | ||||
|     SDL_free(device->info.serial_number); | ||||
|     SDL_free(device->info.manufacturer_string); | ||||
|     SDL_free(device->info.product_string); | ||||
|     SDL_free(device); | ||||
|     SDL_SetObjectValid(wrapper, SDL_OBJECT_TYPE_HIDAPI_DEVICE, SDL_FALSE); | ||||
|     SDL_free(wrapper->info.path); | ||||
|     SDL_free(wrapper->info.serial_number); | ||||
|     SDL_free(wrapper->info.manufacturer_string); | ||||
|     SDL_free(wrapper->info.product_string); | ||||
|     SDL_free(wrapper); | ||||
| } | ||||
|  | ||||
| #define CHECK_DEVICE_MAGIC(device, retval)           \ | ||||
|     if (!device || device->magic != &device_magic) { \ | ||||
|         SDL_SetError("Invalid device");              \ | ||||
|         return retval;                               \ | ||||
| #define CHECK_DEVICE_MAGIC(device, retval)                          \ | ||||
|     if (!SDL_ObjectValid(device, SDL_OBJECT_TYPE_HIDAPI_DEVICE)) {  \ | ||||
|         SDL_SetError("Invalid device");                             \ | ||||
|         return retval;                                              \ | ||||
|     } | ||||
|  | ||||
| #define COPY_IF_EXISTS(var)                \ | ||||
|   | ||||
| @@ -22,7 +22,6 @@ | ||||
|  | ||||
| /* This is the gamepad API for Simple DirectMedia Layer */ | ||||
|  | ||||
| #include "../SDL_utils_c.h" | ||||
| #include "SDL_sysjoystick.h" | ||||
| #include "SDL_joystick_c.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_pXInputMapping 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) | ||||
|  | ||||
| /* The SDL gamepad structure */ | ||||
| struct SDL_Gamepad | ||||
| { | ||||
|     const void *magic _guarded; | ||||
|  | ||||
|     SDL_Joystick *joystick _guarded; /* underlying joystick device */ | ||||
|     int ref_count _guarded; | ||||
|  | ||||
| @@ -131,12 +127,12 @@ struct SDL_Gamepad | ||||
|  | ||||
| #undef _guarded | ||||
|  | ||||
| #define CHECK_GAMEPAD_MAGIC(gamepad, retval)                   \ | ||||
|     if (!gamepad || gamepad->magic != &gamepad_magic || \ | ||||
|         !SDL_IsJoystickValid(gamepad->joystick)) {               \ | ||||
|         SDL_InvalidParamError("gamepad");                             \ | ||||
|         SDL_UnlockJoysticks();                                               \ | ||||
|         return retval;                                                       \ | ||||
| #define CHECK_GAMEPAD_MAGIC(gamepad, retval)                    \ | ||||
|     if (!SDL_ObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD) ||   \ | ||||
|         !SDL_IsJoystickValid(gamepad->joystick)) {              \ | ||||
|         SDL_InvalidParamError("gamepad");                       \ | ||||
|         SDL_UnlockJoysticks();                                  \ | ||||
|         return retval;                                          \ | ||||
|     } | ||||
|  | ||||
| static SDL_vidpid_list SDL_allowed_gamepads = { | ||||
| @@ -2683,7 +2679,7 @@ SDL_Gamepad *SDL_OpenGamepad(SDL_JoystickID instance_id) | ||||
|         SDL_UnlockJoysticks(); | ||||
|         return NULL; | ||||
|     } | ||||
|     gamepad->magic = &gamepad_magic; | ||||
|     SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, SDL_TRUE); | ||||
|  | ||||
|     gamepad->joystick = SDL_OpenJoystick(instance_id); | ||||
|     if (!gamepad->joystick) { | ||||
| @@ -3612,7 +3608,7 @@ void SDL_CloseGamepad(SDL_Gamepad *gamepad) | ||||
|  | ||||
|     SDL_LockJoysticks(); | ||||
|  | ||||
|     if (!gamepad || gamepad->magic != &gamepad_magic) { | ||||
|     if (!SDL_ObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD)) { | ||||
|         SDL_UnlockJoysticks(); | ||||
|         return; | ||||
|     } | ||||
| @@ -3641,7 +3637,7 @@ void SDL_CloseGamepad(SDL_Gamepad *gamepad) | ||||
|         gamepadlist = gamepadlist->next; | ||||
|     } | ||||
|  | ||||
|     gamepad->magic = NULL; | ||||
|     SDL_SetObjectValid(gamepad, SDL_OBJECT_TYPE_GAMEPAD, SDL_FALSE); | ||||
|     SDL_free(gamepad->bindings); | ||||
|     SDL_free(gamepad->last_match_axis); | ||||
|     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 SDL_JoystickID *SDL_joystick_players SDL_GUARDED_BY(SDL_joystick_lock) = NULL; | ||||
| static SDL_bool SDL_joystick_allows_background_events = SDL_FALSE; | ||||
| char SDL_joystick_magic; | ||||
|  | ||||
| static Uint32 initial_arcadestick_devices[] = { | ||||
|     MAKE_VIDPID(0x0079, 0x181a), /* Venom Arcade Stick */ | ||||
| @@ -415,11 +414,11 @@ static SDL_vidpid_list zero_centered_devices = { | ||||
|     SDL_FALSE | ||||
| }; | ||||
|  | ||||
| #define CHECK_JOYSTICK_MAGIC(joystick, retval)             \ | ||||
|     if (!joystick || joystick->magic != &SDL_joystick_magic) { \ | ||||
|         SDL_InvalidParamError("joystick");                 \ | ||||
|         SDL_UnlockJoysticks();                             \ | ||||
|         return retval;                                     \ | ||||
| #define CHECK_JOYSTICK_MAGIC(joystick, retval)                  \ | ||||
|     if (!SDL_ObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK)) { \ | ||||
|         SDL_InvalidParamError("joystick");                      \ | ||||
|         SDL_UnlockJoysticks();                                  \ | ||||
|         return retval;                                          \ | ||||
|     } | ||||
|  | ||||
| SDL_bool SDL_JoysticksInitialized(void) | ||||
| @@ -1096,7 +1095,7 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id) | ||||
|         SDL_UnlockJoysticks(); | ||||
|         return NULL; | ||||
|     } | ||||
|     joystick->magic = &SDL_joystick_magic; | ||||
|     SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, SDL_TRUE); | ||||
|     joystick->driver = driver; | ||||
|     joystick->instance_id = instance_id; | ||||
|     joystick->attached = SDL_TRUE; | ||||
| @@ -1104,6 +1103,7 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id) | ||||
|     joystick->battery_percent = -1; | ||||
|  | ||||
|     if (driver->Open(joystick, device_index) < 0) { | ||||
|         SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, SDL_FALSE); | ||||
|         SDL_free(joystick); | ||||
|         SDL_UnlockJoysticks(); | ||||
|         return NULL; | ||||
| @@ -1346,7 +1346,7 @@ int SDL_SendJoystickVirtualSensorData(SDL_Joystick *joystick, SDL_SensorType typ | ||||
| SDL_bool SDL_IsJoystickValid(SDL_Joystick *joystick) | ||||
| { | ||||
|     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) | ||||
| @@ -1869,7 +1869,7 @@ void SDL_CloseJoystick(SDL_Joystick *joystick) | ||||
|  | ||||
|         joystick->driver->Close(joystick); | ||||
|         joystick->hwdata = NULL; | ||||
|         joystick->magic = NULL; | ||||
|         SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, SDL_FALSE); | ||||
|  | ||||
|         joysticklist = SDL_joysticks; | ||||
|         joysticklistprev = NULL; | ||||
|   | ||||
| @@ -33,7 +33,6 @@ extern "C" { | ||||
|  | ||||
| struct SDL_JoystickDriver; | ||||
| struct SDL_SteamVirtualGamepadInfo; | ||||
| extern char SDL_joystick_magic; | ||||
|  | ||||
| /* Initialization and shutdown functions */ | ||||
| extern int SDL_InitJoysticks(void); | ||||
|   | ||||
| @@ -76,8 +76,6 @@ typedef struct SDL_JoystickSensorInfo | ||||
|  | ||||
| struct SDL_Joystick | ||||
| { | ||||
|     const void *magic _guarded; | ||||
|  | ||||
|     SDL_JoystickID instance_id _guarded; /* Device instance, monotonically increasing from 0 */ | ||||
|     char *name _guarded;                 /* Joystick name - 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 Uint32 SDL_HIDAPI_change_count = 0; | ||||
| 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 SDL_bool SDL_HIDAPI_combine_joycons = SDL_TRUE; | ||||
| 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) { | ||||
|         return NULL; | ||||
|     } | ||||
|     device->magic = &SDL_HIDAPI_device_magic; | ||||
|     SDL_SetObjectValid(device, SDL_OBJECT_TYPE_HIDAPI_JOYSTICK, SDL_TRUE); | ||||
|     device->path = SDL_strdup(info->path); | ||||
|     if (!device->path) { | ||||
|         SDL_free(device); | ||||
| @@ -1049,7 +1048,7 @@ static void HIDAPI_DelDevice(SDL_HIDAPI_Device *device) | ||||
|                 device->children[i]->parent = NULL; | ||||
|             } | ||||
|  | ||||
|             device->magic = NULL; | ||||
|             SDL_SetObjectValid(device, SDL_OBJECT_TYPE_HIDAPI_JOYSTICK, SDL_FALSE); | ||||
|             SDL_DestroyMutex(device->dev_lock); | ||||
|             SDL_free(device->manufacturer_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) { | ||||
|         *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; | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -66,7 +66,6 @@ struct SDL_HIDAPI_DeviceDriver; | ||||
|  | ||||
| typedef struct SDL_HIDAPI_Device | ||||
| { | ||||
|     const void *magic; | ||||
|     char *name; | ||||
|     char *manufacturer_string; | ||||
|     char *product_string; | ||||
|   | ||||
| @@ -41,7 +41,6 @@ | ||||
| #include <dirent.h> | ||||
| #include <linux/joystick.h> | ||||
|  | ||||
| #include "../../SDL_utils_c.h" | ||||
| #include "../../events/SDL_events_c.h" | ||||
| #include "../../core/linux/SDL_evdev.h" | ||||
| #include "../SDL_sysjoystick.h" | ||||
| @@ -2330,6 +2329,7 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap | ||||
|         MAPPED_DPAD_ALL = 0xF, | ||||
|     }; | ||||
|     unsigned int mapped; | ||||
|     SDL_bool result = SDL_FALSE; | ||||
|  | ||||
|     SDL_AssertJoysticksLocked(); | ||||
|  | ||||
| @@ -2351,22 +2351,19 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap | ||||
|     if (!joystick) { | ||||
|         return SDL_FALSE; | ||||
|     } | ||||
|     joystick->magic = &SDL_joystick_magic; | ||||
|     SDL_memcpy(&joystick->guid, &item->guid, sizeof(item->guid)); | ||||
|  | ||||
|     joystick->hwdata = (struct joystick_hwdata *) | ||||
|         SDL_calloc(1, sizeof(*joystick->hwdata)); | ||||
|     joystick->hwdata = (struct joystick_hwdata *)SDL_calloc(1, sizeof(*joystick->hwdata)); | ||||
|     if (!joystick->hwdata) { | ||||
|         SDL_free(joystick); | ||||
|         return SDL_FALSE; | ||||
|     } | ||||
|     SDL_SetObjectValid(joystick, SDL_OBJECT_TYPE_JOYSTICK, SDL_TRUE); | ||||
|  | ||||
|     item->checked_mapping = SDL_TRUE; | ||||
|  | ||||
|     if (PrepareJoystickHwdata(joystick, item, NULL) == -1) { | ||||
|         SDL_free(joystick->hwdata); | ||||
|         SDL_free(joystick); | ||||
|         return SDL_FALSE; /* SDL_SetError will already have been called */ | ||||
|     if (PrepareJoystickHwdata(joystick, item, NULL) < 0) { | ||||
|         goto done; /* SDL_SetError will already have been called */ | ||||
|     } | ||||
|  | ||||
|     /* 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]) { | ||||
|         /* Not a gamepad according to the specs. */ | ||||
|         LINUX_JoystickClose(joystick); | ||||
|         SDL_free(joystick); | ||||
|         return SDL_FALSE; | ||||
|         goto done; | ||||
|     } | ||||
|  | ||||
|     /* 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 */ | ||||
|     item->mapping = (SDL_GamepadMapping *)SDL_malloc(sizeof(*item->mapping)); | ||||
|     if (item->mapping) { | ||||
| @@ -2784,8 +2776,14 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap | ||||
| #ifdef DEBUG_GAMEPAD_MAPPING | ||||
|     SDL_Log("Generated mapping for device %d", device_index); | ||||
| #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 = { | ||||
|   | ||||
| @@ -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_TEXTURE_PARENT_POINTER "SDL.internal.texture.parent" | ||||
|  | ||||
| #define CHECK_RENDERER_MAGIC_BUT_NOT_DESTROYED_FLAG(renderer, retval)                  \ | ||||
|     if (!(renderer) || (renderer)->magic != &SDL_renderer_magic) { \ | ||||
|         SDL_InvalidParamError("renderer");                      \ | ||||
|         return retval;                                          \ | ||||
| #define CHECK_RENDERER_MAGIC_BUT_NOT_DESTROYED_FLAG(renderer, retval)   \ | ||||
|     if (!SDL_ObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER)) {         \ | ||||
|         SDL_InvalidParamError("renderer");                              \ | ||||
|         return 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)                    \ | ||||
|     if (!(texture) || (texture)->magic != &SDL_texture_magic) { \ | ||||
|     if (!SDL_ObjectValid(texture, SDL_OBJECT_TYPE_TEXTURE)) {   \ | ||||
|         SDL_InvalidParamError("texture");                       \ | ||||
|         return retval;                                          \ | ||||
|     } | ||||
| @@ -133,9 +133,6 @@ static const SDL_RenderDriver *render_drivers[] = { | ||||
| }; | ||||
| #endif /* !SDL_RENDER_DISABLED */ | ||||
|  | ||||
| char SDL_renderer_magic; | ||||
| char SDL_texture_magic; | ||||
|  | ||||
|  | ||||
| int SDL_AddSupportedTextureFormat(SDL_Renderer *renderer, SDL_PixelFormatEnum format) | ||||
| { | ||||
| @@ -946,7 +943,7 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props) | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|     renderer->magic = &SDL_renderer_magic; | ||||
|     SDL_SetObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER, SDL_TRUE); | ||||
|  | ||||
| #ifdef SDL_PLATFORM_ANDROID | ||||
|     Android_ActivityMutex_Lock_Running(); | ||||
| @@ -1007,7 +1004,6 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props) | ||||
|                     break;  // Yay, we got one! | ||||
|                 } | ||||
|                 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); | ||||
|  | ||||
|     renderer->magic = &SDL_renderer_magic; | ||||
|     renderer->window = window; | ||||
|     renderer->target_mutex = SDL_CreateMutex(); | ||||
|     if (surface) { | ||||
| @@ -1114,6 +1109,8 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props) | ||||
|  | ||||
| error: | ||||
|  | ||||
|     SDL_SetObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER, SDL_FALSE); | ||||
|  | ||||
| #ifdef SDL_PLATFORM_ANDROID | ||||
|     Android_ActivityMutex_Unlock(); | ||||
| #endif | ||||
| @@ -1316,7 +1313,7 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert | ||||
|     if (!texture) { | ||||
|         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->format = format; | ||||
|     texture->access = access; | ||||
| @@ -4496,7 +4493,7 @@ static int SDL_DestroyTextureInternal(SDL_Texture *texture, SDL_bool is_destroyi | ||||
|         renderer->logical_target = NULL; | ||||
|     } | ||||
|  | ||||
|     texture->magic = NULL; | ||||
|     SDL_SetObjectValid(texture, SDL_OBJECT_TYPE_TEXTURE, SDL_FALSE); | ||||
|  | ||||
|     if (texture->next) { | ||||
|         texture->next->prev = texture->prev; | ||||
| @@ -4596,7 +4593,7 @@ void SDL_DestroyRenderer(SDL_Renderer *renderer) | ||||
|     // in either order. | ||||
|     if (!renderer->destroyed) { | ||||
|         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); | ||||
|   | ||||
| @@ -44,8 +44,6 @@ typedef struct SDL_DRect | ||||
| /* The SDL 2D rendering system */ | ||||
|  | ||||
| typedef struct SDL_RenderDriver SDL_RenderDriver; | ||||
| extern char SDL_renderer_magic; | ||||
| extern char SDL_texture_magic; | ||||
|  | ||||
| /* Rendering view state */ | ||||
| typedef struct SDL_RenderViewState | ||||
| @@ -62,7 +60,6 @@ typedef struct SDL_RenderViewState | ||||
| /* Define the SDL texture structure */ | ||||
| struct SDL_Texture | ||||
| { | ||||
|     const void *magic; | ||||
|     SDL_Colorspace colorspace;  /**< The colorspace of the texture */ | ||||
|     float SDR_white_point;      /**< The SDR white point for this content */ | ||||
|     float HDR_headroom;         /**< The HDR headroom needed by this content */ | ||||
| @@ -160,8 +157,6 @@ typedef enum | ||||
| /* Define the SDL renderer structure */ | ||||
| struct SDL_Renderer | ||||
| { | ||||
|     const void *magic; | ||||
|  | ||||
|     void (*WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event); | ||||
|     int (*GetOutputSize)(SDL_Renderer *renderer, int *w, int *h); | ||||
|     SDL_bool (*SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode); | ||||
|   | ||||
| @@ -26,7 +26,6 @@ | ||||
| #include "../SDL_sysrender.h" | ||||
| #include "SDL_shaders_gl.h" | ||||
| #include "../../video/SDL_pixels_c.h" | ||||
| #include "../../SDL_utils_c.h" | ||||
|  | ||||
| #ifdef SDL_PLATFORM_MACOS | ||||
| #include <OpenGL/OpenGL.h> | ||||
|   | ||||
| @@ -56,13 +56,12 @@ static SDL_AtomicInt SDL_sensor_lock_pending; | ||||
| static int SDL_sensors_locked; | ||||
| static SDL_bool SDL_sensors_initialized; | ||||
| static SDL_Sensor *SDL_sensors SDL_GUARDED_BY(SDL_sensor_lock) = NULL; | ||||
| static char SDL_sensor_magic; | ||||
|  | ||||
| #define CHECK_SENSOR_MAGIC(sensor, retval)              \ | ||||
|     if (!sensor || sensor->magic != &SDL_sensor_magic) { \ | ||||
|         SDL_InvalidParamError("sensor");                \ | ||||
|         SDL_UnlockSensors();                            \ | ||||
|         return retval;                                  \ | ||||
| #define CHECK_SENSOR_MAGIC(sensor, retval)                  \ | ||||
|     if (!SDL_ObjectValid(sensor, SDL_OBJECT_TYPE_SENSOR)) { \ | ||||
|         SDL_InvalidParamError("sensor");                    \ | ||||
|         SDL_UnlockSensors();                                \ | ||||
|         return retval;                                      \ | ||||
|     } | ||||
|  | ||||
| SDL_bool SDL_SensorsInitialized(void) | ||||
| @@ -327,13 +326,14 @@ SDL_Sensor *SDL_OpenSensor(SDL_SensorID instance_id) | ||||
|         SDL_UnlockSensors(); | ||||
|         return NULL; | ||||
|     } | ||||
|     sensor->magic = &SDL_sensor_magic; | ||||
|     SDL_SetObjectValid(sensor, SDL_OBJECT_TYPE_SENSOR, SDL_TRUE); | ||||
|     sensor->driver = driver; | ||||
|     sensor->instance_id = instance_id; | ||||
|     sensor->type = driver->GetDeviceType(device_index); | ||||
|     sensor->non_portable_type = driver->GetDeviceNonPortableType(device_index); | ||||
|  | ||||
|     if (driver->Open(sensor, device_index) < 0) { | ||||
|         SDL_SetObjectValid(sensor, SDL_OBJECT_TYPE_SENSOR, SDL_FALSE); | ||||
|         SDL_free(sensor); | ||||
|         SDL_UnlockSensors(); | ||||
|         return NULL; | ||||
| @@ -508,6 +508,7 @@ void SDL_CloseSensor(SDL_Sensor *sensor) | ||||
|  | ||||
|         sensor->driver->Close(sensor); | ||||
|         sensor->hwdata = NULL; | ||||
|         SDL_SetObjectValid(sensor, SDL_OBJECT_TYPE_SENSOR, SDL_FALSE); | ||||
|  | ||||
|         sensorlist = SDL_sensors; | ||||
|         sensorlistprev = NULL; | ||||
|   | ||||
| @@ -32,8 +32,6 @@ | ||||
| /* The SDL sensor structure */ | ||||
| struct SDL_Sensor | ||||
| { | ||||
|     const void *magic _guarded; | ||||
|  | ||||
|     SDL_SensorID instance_id _guarded;   /* Device instance, monotonically increasing from 0 */ | ||||
|     char *name _guarded;                 /* Sensor name - system dependent */ | ||||
|     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 */ | ||||
| struct SDL_Window | ||||
| { | ||||
|     const void *magic; | ||||
|     SDL_WindowID id; | ||||
|     char *title; | ||||
|     SDL_Surface *icon; | ||||
| @@ -371,7 +370,6 @@ struct SDL_VideoDevice | ||||
|     SDL_Rect desktop_bounds; | ||||
|     SDL_Window *windows; | ||||
|     SDL_Window *grabbed_window; | ||||
|     Uint8 window_magic; | ||||
|     Uint32 clipboard_sequence; | ||||
|     SDL_ClipboardDataCallback clipboard_callback; | ||||
|     SDL_ClipboardCleanupCallback clipboard_cleanup; | ||||
|   | ||||
| @@ -141,7 +141,7 @@ static VideoBootStrap *bootstrap[] = { | ||||
|         SDL_UninitializedVideo();                                       \ | ||||
|         return retval;                                                  \ | ||||
|     }                                                                   \ | ||||
|     if (!(window) || (window)->magic != &_this->window_magic) {         \ | ||||
|     if (!SDL_ObjectValid(window, SDL_OBJECT_TYPE_WINDOW)) {             \ | ||||
|         SDL_SetError("Invalid window");                                 \ | ||||
|         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"); | ||||
|         return NULL; | ||||
|     } | ||||
| @@ -2130,7 +2130,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props) | ||||
|         } | ||||
|  | ||||
|         /* 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"); | ||||
|             return NULL; | ||||
|         } | ||||
| @@ -2236,7 +2236,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props) | ||||
|     if (!window) { | ||||
|         return NULL; | ||||
|     } | ||||
|     window->magic = &_this->window_magic; | ||||
|     SDL_SetObjectValid(window, SDL_OBJECT_TYPE_WINDOW, SDL_TRUE); | ||||
|     window->id = SDL_GetNextObjectID(); | ||||
|     window->floating.x = window->windowed.x = window->x = x; | ||||
|     window->floating.y = window->windowed.y = window->y = y; | ||||
| @@ -3920,7 +3920,7 @@ void SDL_DestroyWindow(SDL_Window *window) | ||||
|     } | ||||
|  | ||||
|     /* Now invalidate magic */ | ||||
|     window->magic = NULL; | ||||
|     SDL_SetObjectValid(window, SDL_OBJECT_TYPE_WINDOW, SDL_FALSE); | ||||
|  | ||||
|     /* Free memory associated with the window */ | ||||
|     SDL_free(window->title); | ||||
|   | ||||
| @@ -1854,7 +1854,7 @@ static void Wayland_ReleasePopup(SDL_VideoDevice *_this, SDL_Window *popup) | ||||
|     SDL_WindowData *popupdata; | ||||
|  | ||||
|     /* 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; | ||||
|     } | ||||
|     popupdata = popup->driverdata; | ||||
|   | ||||
| @@ -39,7 +39,6 @@ | ||||
| #include "../../events/SDL_mouse_c.h" | ||||
| #include "../../events/SDL_touch_c.h" | ||||
| #include "../../core/linux/SDL_system_theme.h" | ||||
| #include "../../SDL_utils_c.h" | ||||
| #include "../SDL_sysvideo.h" | ||||
|  | ||||
| #include <stdio.h> | ||||
|   | ||||
| @@ -28,7 +28,6 @@ | ||||
| #include "../../events/SDL_mouse_c.h" | ||||
| #include "../../events/SDL_events_c.h" | ||||
| #include "../../core/unix/SDL_appid.h" | ||||
| #include "../../SDL_utils_c.h" | ||||
|  | ||||
| #include "SDL_x11video.h" | ||||
| #include "SDL_x11mouse.h" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Sam Lantinga
					Sam Lantinga