mirror of
				https://github.com/libsdl-org/SDL.git
				synced 2025-11-03 17:24:34 +00:00 
			
		
		
		
	Introduce formal policy for APIs that return strings.
This declares that any `const char *` returned from SDL is owned by SDL, and promises to be valid _at least_ until the next time the event queue runs, or SDL_Quit() is called, even if the thing that owns the string gets destroyed or changed before then. This is noted in the headers as "the SDL_GetStringRule", so this will both be greppable to find a detailed explaination in docs/README-strings.md and wikiheaders will automatically turn it into a link we can point at the appropriate documentation. Fixes #9902. (and several FIXMEs, both known and yet-undocumented.)
This commit is contained in:
		
							
								
								
									
										58
									
								
								docs/README-strings.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								docs/README-strings.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
# String policies in SDL3.
 | 
			
		||||
 | 
			
		||||
## Encoding.
 | 
			
		||||
 | 
			
		||||
Unless otherwise specified, all strings in SDL, across all platforms, are
 | 
			
		||||
UTF-8 encoded.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## The SDL Get String Rule.
 | 
			
		||||
 | 
			
		||||
Did you see 'SDL_GetStringRule' in the wiki or headers? Here are the details
 | 
			
		||||
that aren't worth copying across dozens of functions' documentation.
 | 
			
		||||
 | 
			
		||||
tl;dr: If an SDL function returns a `const char *` string, do not modify or
 | 
			
		||||
free it, and if you need to save it, make a copy right away.
 | 
			
		||||
 | 
			
		||||
In several cases, SDL wants to return a string to the app, and the question
 | 
			
		||||
in any library that does this is: _who owns this thing?_
 | 
			
		||||
 | 
			
		||||
The answer in almost all cases, is that SDL does, but not for long.
 | 
			
		||||
 | 
			
		||||
The pointer is only guaranteed to be valid until the next time the event
 | 
			
		||||
queue is updated, or SDL_Quit is called.
 | 
			
		||||
 | 
			
		||||
The reason for this is memory safety.
 | 
			
		||||
 | 
			
		||||
There are several strings that SDL provides that could be freed at
 | 
			
		||||
any moment. For example, an app calls SDL_GetAudioDeviceName(), which returns
 | 
			
		||||
a string that is part of the internal audio device structure. But, while this
 | 
			
		||||
function is returning, the user yanks the USB audio device out of the
 | 
			
		||||
computer, and SDL decides to deallocate the structure...and the string!
 | 
			
		||||
Now the app is holding a pointer that didn't live long enough to be useful,
 | 
			
		||||
and could crash if accessed.
 | 
			
		||||
 | 
			
		||||
To avoid this, instead of calling SDL_free on a string as soon as it's done
 | 
			
		||||
with it, SDL adds the pointer to a list. This list is freed at specific
 | 
			
		||||
points: when the event queue is run (for ongoing cleanup) and when SDL_Quit
 | 
			
		||||
is called (to catch things that are just hanging around). This allows the
 | 
			
		||||
app to use a string without worrying about it becoming bogus in the middle
 | 
			
		||||
of a printf() call. If the app needs it for longer, it should copy it.
 | 
			
		||||
 | 
			
		||||
When does "the event queue run"? There are several points:
 | 
			
		||||
 | 
			
		||||
- If the app calls SDL_PumpEvents() _from any thread_.
 | 
			
		||||
- SDL_PumpEvents is also called by several other APIs internally:
 | 
			
		||||
  SDL_PollEvent(), SDL_PeepEvents(), SDL_WaitEvent(),
 | 
			
		||||
  SDL_WaitEventTimeout(), and maybe others.
 | 
			
		||||
- If you are using [the main callbacks](README-main-functions), the
 | 
			
		||||
  event queue can run immediately after any of the callback functions return.
 | 
			
		||||
 | 
			
		||||
Note that these are just guaranteed minimum lifespans; any given string
 | 
			
		||||
might live much longer--some might even be static memory that is _never_
 | 
			
		||||
deallocated--but this rule promises that the app has a safe window.
 | 
			
		||||
 | 
			
		||||
Note that none of this applies if the return value is `char *` instead of
 | 
			
		||||
`const char *`. Please see the specific function's documentation for how
 | 
			
		||||
to handle those pointers.
 | 
			
		||||
 | 
			
		||||
@@ -374,9 +374,11 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetNumAudioDrivers(void);
 | 
			
		||||
 * first (as far as the SDL developers believe) are earlier in the list.
 | 
			
		||||
 *
 | 
			
		||||
 * The names of drivers are all simple, low-ASCII identifiers, like "alsa",
 | 
			
		||||
 * "coreaudio" or "xaudio2". These never have Unicode characters, and are not
 | 
			
		||||
 * "coreaudio" or "wasapi". These never have Unicode characters, and are not
 | 
			
		||||
 * meant to be proper names.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param index the index of the audio driver; the value ranges from 0 to
 | 
			
		||||
 *              SDL_GetNumAudioDrivers() - 1
 | 
			
		||||
 * \returns the name of the audio driver at the requested index, or NULL if an
 | 
			
		||||
@@ -394,11 +396,11 @@ extern SDL_DECLSPEC const char *SDLCALL SDL_GetAudioDriver(int index);
 | 
			
		||||
/**
 | 
			
		||||
 * Get the name of the current audio driver.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string points to internal static memory and thus never becomes
 | 
			
		||||
 * invalid, even if you quit the audio subsystem and initialize a new driver
 | 
			
		||||
 * (although such a case would return a different static string from another
 | 
			
		||||
 * call to this function, of course). As such, you should not modify or free
 | 
			
		||||
 * the returned string.
 | 
			
		||||
 * The names of drivers are all simple, low-ASCII identifiers, like "alsa",
 | 
			
		||||
 * "coreaudio" or "wasapi". These never have Unicode characters, and are not
 | 
			
		||||
 * meant to be proper names.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \returns the name of the current audio driver or NULL if no driver has been
 | 
			
		||||
 *          initialized.
 | 
			
		||||
@@ -470,8 +472,7 @@ extern SDL_DECLSPEC SDL_AudioDeviceID *SDLCALL SDL_GetAudioCaptureDevices(int *c
 | 
			
		||||
/**
 | 
			
		||||
 * Get the human-readable name of a specific audio device.
 | 
			
		||||
 *
 | 
			
		||||
 * The string returned by this function is UTF-8 encoded. The caller should
 | 
			
		||||
 * call SDL_free on the return value when done with it.
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param devid the instance ID of the device to query.
 | 
			
		||||
 * \returns the name of the audio device, or NULL on error.
 | 
			
		||||
@@ -484,7 +485,7 @@ extern SDL_DECLSPEC SDL_AudioDeviceID *SDLCALL SDL_GetAudioCaptureDevices(int *c
 | 
			
		||||
 * \sa SDL_GetAudioCaptureDevices
 | 
			
		||||
 * \sa SDL_GetDefaultAudioInfo
 | 
			
		||||
 */
 | 
			
		||||
extern SDL_DECLSPEC char *SDLCALL SDL_GetAudioDeviceName(SDL_AudioDeviceID devid);
 | 
			
		||||
extern SDL_DECLSPEC const char *SDLCALL SDL_GetAudioDeviceName(SDL_AudioDeviceID devid);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the current audio format of a specific audio device.
 | 
			
		||||
 
 | 
			
		||||
@@ -134,6 +134,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetNumCameraDrivers(void);
 | 
			
		||||
 * "coremedia" or "android". These never have Unicode characters, and are not
 | 
			
		||||
 * meant to be proper names.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param index the index of the camera driver; the value ranges from 0 to
 | 
			
		||||
 *              SDL_GetNumCameraDrivers() - 1
 | 
			
		||||
 * \returns the name of the camera driver at the requested index, or NULL if
 | 
			
		||||
@@ -150,11 +152,11 @@ extern SDL_DECLSPEC const char *SDLCALL SDL_GetCameraDriver(int index);
 | 
			
		||||
/**
 | 
			
		||||
 * Get the name of the current camera driver.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string points to internal static memory and thus never becomes
 | 
			
		||||
 * invalid, even if you quit the camera subsystem and initialize a new driver
 | 
			
		||||
 * (although such a case would return a different static string from another
 | 
			
		||||
 * call to this function, of course). As such, you should not modify or free
 | 
			
		||||
 * the returned string.
 | 
			
		||||
 * The names of drivers are all simple, low-ASCII identifiers, like "v4l2",
 | 
			
		||||
 * "coremedia" or "android". These never have Unicode characters, and are not
 | 
			
		||||
 * meant to be proper names.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \returns the name of the current camera driver or NULL if no driver has
 | 
			
		||||
 *          been initialized.
 | 
			
		||||
 
 | 
			
		||||
@@ -96,15 +96,14 @@ extern SDL_DECLSPEC int SDLCALL SDL_OutOfMemory(void);
 | 
			
		||||
 * Error strings are set per-thread, so an error set in a different thread
 | 
			
		||||
 * will not interfere with the current thread's operation.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string is internally allocated and must not be freed by the
 | 
			
		||||
 * application.
 | 
			
		||||
 * The returned string does **NOT** follow the SDL_GetStringRule! The
 | 
			
		||||
 * pointer is valid until the current thread's error string is changed, so
 | 
			
		||||
 * the caller should make a copy if the string is to be used after calling
 | 
			
		||||
 * into SDL again.
 | 
			
		||||
 *
 | 
			
		||||
 * \returns a message with information about the specific error that occurred,
 | 
			
		||||
 *          or an empty string if there hasn't been an error message set since
 | 
			
		||||
 *          the last call to SDL_ClearError(). The message is only applicable
 | 
			
		||||
 *          when an SDL function has signaled an error. You must check the
 | 
			
		||||
 *          return values of SDL function calls to determine when to
 | 
			
		||||
 *          appropriately call SDL_GetError().
 | 
			
		||||
 *          the last call to SDL_ClearError().
 | 
			
		||||
 *
 | 
			
		||||
 * \since This function is available since SDL 3.0.0.
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -500,6 +500,8 @@ extern SDL_DECLSPEC SDL_bool SDLCALL SDL_IsGamepad(SDL_JoystickID instance_id);
 | 
			
		||||
 *
 | 
			
		||||
 * This can be called before any gamepads are opened.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param instance_id the joystick instance ID
 | 
			
		||||
 * \returns the name of the selected gamepad. If no name can be found, this
 | 
			
		||||
 *          function returns NULL; call SDL_GetError() for more information.
 | 
			
		||||
@@ -516,6 +518,8 @@ extern SDL_DECLSPEC const char *SDLCALL SDL_GetGamepadInstanceName(SDL_JoystickI
 | 
			
		||||
 *
 | 
			
		||||
 * This can be called before any gamepads are opened.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param instance_id the joystick instance ID
 | 
			
		||||
 * \returns the path of the selected gamepad. If no path can be found, this
 | 
			
		||||
 *          function returns NULL; call SDL_GetError() for more information.
 | 
			
		||||
@@ -748,6 +752,8 @@ extern SDL_DECLSPEC SDL_JoystickID SDLCALL SDL_GetGamepadInstanceID(SDL_Gamepad
 | 
			
		||||
/**
 | 
			
		||||
 * Get the implementation-dependent name for an opened gamepad.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param gamepad a gamepad identifier previously returned by
 | 
			
		||||
 *                SDL_OpenGamepad()
 | 
			
		||||
 * \returns the implementation dependent name for the gamepad, or NULL if
 | 
			
		||||
@@ -762,6 +768,8 @@ extern SDL_DECLSPEC const char *SDLCALL SDL_GetGamepadName(SDL_Gamepad *gamepad)
 | 
			
		||||
/**
 | 
			
		||||
 * Get the implementation-dependent path for an opened gamepad.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param gamepad a gamepad identifier previously returned by
 | 
			
		||||
 *                SDL_OpenGamepad()
 | 
			
		||||
 * \returns the implementation dependent path for the gamepad, or NULL if
 | 
			
		||||
@@ -887,6 +895,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetGamepadFirmwareVersion(SDL_Gamepad *ga
 | 
			
		||||
 *
 | 
			
		||||
 * Returns the serial number of the gamepad, or NULL if it is not available.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param gamepad the gamepad object to query.
 | 
			
		||||
 * \returns the serial number, or NULL if unavailable.
 | 
			
		||||
 *
 | 
			
		||||
@@ -1045,7 +1055,7 @@ extern SDL_DECLSPEC SDL_GamepadType SDLCALL SDL_GetGamepadTypeFromString(const c
 | 
			
		||||
/**
 | 
			
		||||
 * Convert from an SDL_GamepadType enum to a string.
 | 
			
		||||
 *
 | 
			
		||||
 * The caller should not SDL_free() the returned string.
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param type an enum value for a given SDL_GamepadType
 | 
			
		||||
 * \returns a string for the given type, or NULL if an invalid type is
 | 
			
		||||
@@ -1083,7 +1093,7 @@ extern SDL_DECLSPEC SDL_GamepadAxis SDLCALL SDL_GetGamepadAxisFromString(const c
 | 
			
		||||
/**
 | 
			
		||||
 * Convert from an SDL_GamepadAxis enum to a string.
 | 
			
		||||
 *
 | 
			
		||||
 * The caller should not SDL_free() the returned string.
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param axis an enum value for a given SDL_GamepadAxis
 | 
			
		||||
 * \returns a string for the given axis, or NULL if an invalid axis is
 | 
			
		||||
@@ -1158,7 +1168,7 @@ extern SDL_DECLSPEC SDL_GamepadButton SDLCALL SDL_GetGamepadButtonFromString(con
 | 
			
		||||
/**
 | 
			
		||||
 * Convert from an SDL_GamepadButton enum to a string.
 | 
			
		||||
 *
 | 
			
		||||
 * The caller should not SDL_free() the returned string.
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param button an enum value for a given SDL_GamepadButton
 | 
			
		||||
 * \returns a string for the given button, or NULL if an invalid button is
 | 
			
		||||
@@ -1446,6 +1456,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_CloseGamepad(SDL_Gamepad *gamepad);
 | 
			
		||||
 * Return the sfSymbolsName for a given button on a gamepad on Apple
 | 
			
		||||
 * platforms.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param gamepad the gamepad to query
 | 
			
		||||
 * \param button a button on the gamepad
 | 
			
		||||
 * \returns the sfSymbolsName or NULL if the name can't be found
 | 
			
		||||
@@ -1459,6 +1471,8 @@ extern SDL_DECLSPEC const char* SDLCALL SDL_GetGamepadAppleSFSymbolsNameForButto
 | 
			
		||||
/**
 | 
			
		||||
 * Return the sfSymbolsName for a given axis on a gamepad on Apple platforms.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param gamepad the gamepad to query
 | 
			
		||||
 * \param axis an axis on the gamepad
 | 
			
		||||
 * \returns the sfSymbolsName or NULL if the name can't be found
 | 
			
		||||
 
 | 
			
		||||
@@ -948,6 +948,8 @@ extern SDL_DECLSPEC SDL_HapticID *SDLCALL SDL_GetHaptics(int *count);
 | 
			
		||||
 *
 | 
			
		||||
 * This can be called before any haptic devices are opened.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param instance_id the haptic device instance ID
 | 
			
		||||
 * \returns the name of the selected haptic device. If no name can be found,
 | 
			
		||||
 *          this function returns NULL; call SDL_GetError() for more
 | 
			
		||||
@@ -1011,6 +1013,8 @@ extern SDL_DECLSPEC SDL_HapticID SDLCALL SDL_GetHapticInstanceID(SDL_Haptic *hap
 | 
			
		||||
/**
 | 
			
		||||
 * Get the implementation dependent name of a haptic device.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param haptic the SDL_Haptic obtained from SDL_OpenJoystick()
 | 
			
		||||
 * \returns the name of the selected haptic device. If no name can be found,
 | 
			
		||||
 *          this function returns NULL; call SDL_GetError() for more
 | 
			
		||||
 
 | 
			
		||||
@@ -3806,6 +3806,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_ResetHints(void);
 | 
			
		||||
/**
 | 
			
		||||
 * Get the value of a hint.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param name the hint to query
 | 
			
		||||
 * \returns the string value of a hint or NULL if the hint isn't set.
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -231,6 +231,8 @@ extern SDL_DECLSPEC SDL_JoystickID *SDLCALL SDL_GetJoysticks(int *count);
 | 
			
		||||
 *
 | 
			
		||||
 * This can be called before any joysticks are opened.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param instance_id the joystick instance ID
 | 
			
		||||
 * \returns the name of the selected joystick. If no name can be found, this
 | 
			
		||||
 *          function returns NULL; call SDL_GetError() for more information.
 | 
			
		||||
@@ -247,6 +249,8 @@ extern SDL_DECLSPEC const char *SDLCALL SDL_GetJoystickInstanceName(SDL_Joystick
 | 
			
		||||
 *
 | 
			
		||||
 * This can be called before any joysticks are opened.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param instance_id the joystick instance ID
 | 
			
		||||
 * \returns the path of the selected joystick. If no path can be found, this
 | 
			
		||||
 *          function returns NULL; call SDL_GetError() for more information.
 | 
			
		||||
@@ -669,6 +673,8 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetJoystickProperties(SDL_Joyst
 | 
			
		||||
/**
 | 
			
		||||
 * Get the implementation dependent name of a joystick.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick()
 | 
			
		||||
 * \returns the name of the selected joystick. If no name can be found, this
 | 
			
		||||
 *          function returns NULL; call SDL_GetError() for more information.
 | 
			
		||||
@@ -682,6 +688,8 @@ extern SDL_DECLSPEC const char *SDLCALL SDL_GetJoystickName(SDL_Joystick *joysti
 | 
			
		||||
/**
 | 
			
		||||
 * Get the implementation dependent path of a joystick.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick()
 | 
			
		||||
 * \returns the path of the selected joystick. If no path can be found, this
 | 
			
		||||
 *          function returns NULL; call SDL_GetError() for more information.
 | 
			
		||||
@@ -799,6 +807,8 @@ extern SDL_DECLSPEC Uint16 SDLCALL SDL_GetJoystickFirmwareVersion(SDL_Joystick *
 | 
			
		||||
 *
 | 
			
		||||
 * Returns the serial number of the joystick, or NULL if it is not available.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param joystick the SDL_Joystick obtained from SDL_OpenJoystick()
 | 
			
		||||
 * \returns the serial number of the selected joystick, or NULL if
 | 
			
		||||
 *          unavailable.
 | 
			
		||||
 
 | 
			
		||||
@@ -109,6 +109,8 @@ extern SDL_DECLSPEC SDL_KeyboardID *SDLCALL SDL_GetKeyboards(int *count);
 | 
			
		||||
 *
 | 
			
		||||
 * This function returns "" if the keyboard doesn't have a name.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param instance_id the keyboard instance ID
 | 
			
		||||
 * \returns the name of the selected keyboard, or NULL on failure; call
 | 
			
		||||
 *          SDL_GetError() for more information.
 | 
			
		||||
@@ -255,6 +257,8 @@ extern SDL_DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromKey(SDL_Keycode key)
 | 
			
		||||
 *
 | 
			
		||||
 * See SDL_Scancode for details.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * **Warning**: The returned name is by design not stable across platforms,
 | 
			
		||||
 * e.g. the name for `SDL_SCANCODE_LGUI` is "Left GUI" under Linux but "Left
 | 
			
		||||
 * Windows" under Microsoft Windows, and some scancodes like
 | 
			
		||||
@@ -295,6 +299,8 @@ extern SDL_DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromName(const char *nam
 | 
			
		||||
 *
 | 
			
		||||
 * See SDL_Scancode and SDL_Keycode for details.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param key the desired SDL_Keycode to query
 | 
			
		||||
 * \returns a pointer to a UTF-8 string that stays valid at least until the
 | 
			
		||||
 *          next call to this function. If you need it around any longer, you
 | 
			
		||||
 
 | 
			
		||||
@@ -152,6 +152,8 @@ extern SDL_DECLSPEC SDL_MouseID *SDLCALL SDL_GetMice(int *count);
 | 
			
		||||
 *
 | 
			
		||||
 * This function returns "" if the mouse doesn't have a name.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param instance_id the mouse instance ID
 | 
			
		||||
 * \returns the name of the selected mouse, or NULL on failure; call
 | 
			
		||||
 *          SDL_GetError() for more information.
 | 
			
		||||
 
 | 
			
		||||
@@ -224,6 +224,8 @@ extern SDL_DECLSPEC SDL_bool SDLCALL SDL_PenConnected(SDL_PenID instance_id);
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieves a human-readable description for a SDL_PenID.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param instance_id The pen to query.
 | 
			
		||||
 * \returns A string that contains the name of the pen, intended for human
 | 
			
		||||
 *          consumption. The string might or might not be localised, depending
 | 
			
		||||
 
 | 
			
		||||
@@ -758,6 +758,8 @@ typedef struct SDL_PixelFormat
 | 
			
		||||
/**
 | 
			
		||||
 * Get the human readable name of a pixel format.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param format the pixel format to query
 | 
			
		||||
 * \returns the human readable name of the specified pixel format or
 | 
			
		||||
 *          `SDL_PIXELFORMAT_UNKNOWN` if the format isn't recognized.
 | 
			
		||||
 
 | 
			
		||||
@@ -48,12 +48,14 @@ extern "C" {
 | 
			
		||||
 * - "iOS"
 | 
			
		||||
 * - "Android"
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \returns the name of the platform. If the correct platform name is not
 | 
			
		||||
 *          available, returns a string beginning with the text "Unknown".
 | 
			
		||||
 *
 | 
			
		||||
 * \since This function is available since SDL 3.0.0.
 | 
			
		||||
 */
 | 
			
		||||
extern SDL_DECLSPEC const char * SDLCALL SDL_GetPlatform (void);
 | 
			
		||||
extern SDL_DECLSPEC const char * SDLCALL SDL_GetPlatform(void);
 | 
			
		||||
 | 
			
		||||
/* Ends C function definitions when using C++ */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 
 | 
			
		||||
@@ -360,6 +360,8 @@ extern SDL_DECLSPEC void *SDLCALL SDL_GetProperty(SDL_PropertiesID props, const
 | 
			
		||||
/**
 | 
			
		||||
 * Get a string property on a set of properties.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param props the properties to query
 | 
			
		||||
 * \param name the name of the property to query
 | 
			
		||||
 * \param default_value the default value of the property
 | 
			
		||||
 
 | 
			
		||||
@@ -166,8 +166,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetNumRenderDrivers(void);
 | 
			
		||||
 * "direct3d12" or "metal". These never have Unicode characters, and are not
 | 
			
		||||
 * meant to be proper names.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned value points to a static, read-only string; do not modify or
 | 
			
		||||
 * free it!
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param index the index of the rendering driver; the value ranges from 0 to
 | 
			
		||||
 *              SDL_GetNumRenderDrivers() - 1
 | 
			
		||||
 
 | 
			
		||||
@@ -158,6 +158,8 @@ extern SDL_DECLSPEC SDL_SensorID *SDLCALL SDL_GetSensors(int *count);
 | 
			
		||||
/**
 | 
			
		||||
 * Get the implementation dependent name of a sensor.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param instance_id the sensor instance ID
 | 
			
		||||
 * \returns the sensor name, or NULL if `instance_id` is not valid
 | 
			
		||||
 *
 | 
			
		||||
@@ -224,6 +226,8 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetSensorProperties(SDL_Sensor
 | 
			
		||||
/**
 | 
			
		||||
 * Get the implementation dependent name of a sensor.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param sensor The SDL_Sensor object
 | 
			
		||||
 * \returns the sensor name, or NULL if `sensor` is NULL.
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -385,6 +385,8 @@ extern SDL_DECLSPEC void SDLCALL SDL_AndroidBackButton(void);
 | 
			
		||||
 * Your internal storage path is typically:
 | 
			
		||||
 * `/data/data/your.app.package/files`.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \returns the path used for internal storage or NULL on failure; call
 | 
			
		||||
 *          SDL_GetError() for more information.
 | 
			
		||||
 *
 | 
			
		||||
@@ -392,7 +394,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_AndroidBackButton(void);
 | 
			
		||||
 *
 | 
			
		||||
 * \sa SDL_AndroidGetExternalStorageState
 | 
			
		||||
 */
 | 
			
		||||
extern SDL_DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath(void);
 | 
			
		||||
extern SDL_DECLSPEC const char *SDLCALL SDL_AndroidGetInternalStoragePath(void);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the current state of external storage.
 | 
			
		||||
@@ -422,6 +424,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState(Uint32 *state
 | 
			
		||||
 * Your external storage path is typically:
 | 
			
		||||
 * `/storage/sdcard0/Android/data/your.app.package/files`.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \returns the path used for external storage for this application on success
 | 
			
		||||
 *          or NULL on failure; call SDL_GetError() for more information.
 | 
			
		||||
 *
 | 
			
		||||
@@ -576,6 +580,8 @@ typedef enum SDL_WinRT_DeviceFamily
 | 
			
		||||
 *
 | 
			
		||||
 * https://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param pathType the type of path to retrieve, one of SDL_WinRT_Path
 | 
			
		||||
 * \returns a UTF-8 string (8-bit, multi-byte) containing the path, or NULL if
 | 
			
		||||
 *          the path is not available for any reason; call SDL_GetError() for
 | 
			
		||||
 
 | 
			
		||||
@@ -331,8 +331,7 @@ extern SDL_DECLSPEC SDL_Thread *SDLCALL SDL_CreateThreadWithPropertiesRuntime(SD
 | 
			
		||||
/**
 | 
			
		||||
 * Get the thread name as it was specified in SDL_CreateThread().
 | 
			
		||||
 *
 | 
			
		||||
 * This is internal memory, not to be freed by the caller, and remains valid
 | 
			
		||||
 * until the specified thread is cleaned up by SDL_WaitThread().
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param thread the thread to query
 | 
			
		||||
 * \returns a pointer to a UTF-8 string that names the specified thread, or
 | 
			
		||||
 
 | 
			
		||||
@@ -96,7 +96,7 @@ extern SDL_DECLSPEC SDL_TouchID *SDLCALL SDL_GetTouchDevices(int *count);
 | 
			
		||||
/**
 | 
			
		||||
 * Get the touch device name as reported from the driver.
 | 
			
		||||
 *
 | 
			
		||||
 * You do not own the returned string, do not modify or free it.
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param touchID the touch device instance ID.
 | 
			
		||||
 * \returns touch device name, or NULL on error; call SDL_GetError() for more
 | 
			
		||||
@@ -104,7 +104,7 @@ extern SDL_DECLSPEC SDL_TouchID *SDLCALL SDL_GetTouchDevices(int *count);
 | 
			
		||||
 *
 | 
			
		||||
 * \since This function is available since SDL 3.0.0.
 | 
			
		||||
 */
 | 
			
		||||
extern SDL_DECLSPEC const char* SDLCALL SDL_GetTouchDeviceName(SDL_TouchID touchID);
 | 
			
		||||
extern SDL_DECLSPEC const char *SDLCALL SDL_GetTouchDeviceName(SDL_TouchID touchID);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the type of the given touch device.
 | 
			
		||||
 
 | 
			
		||||
@@ -143,6 +143,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetVersion(void);
 | 
			
		||||
 * You shouldn't use this function for anything but logging it for debugging
 | 
			
		||||
 * purposes. The string is not intended to be reliable in any way.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \returns an arbitrary string, uniquely identifying the exact revision of
 | 
			
		||||
 *          the SDL library in use.
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -338,6 +338,12 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetNumVideoDrivers(void);
 | 
			
		||||
 * The video drivers are presented in the order in which they are normally
 | 
			
		||||
 * checked during initialization.
 | 
			
		||||
 *
 | 
			
		||||
 * The names of drivers are all simple, low-ASCII identifiers, like "cocoa",
 | 
			
		||||
 * "x11" or "windows". These never have Unicode characters, and are not
 | 
			
		||||
 * meant to be proper names.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param index the index of a video driver
 | 
			
		||||
 * \returns the name of the video driver with the given **index**.
 | 
			
		||||
 *
 | 
			
		||||
@@ -350,6 +356,12 @@ extern SDL_DECLSPEC const char *SDLCALL SDL_GetVideoDriver(int index);
 | 
			
		||||
/**
 | 
			
		||||
 * Get the name of the currently initialized video driver.
 | 
			
		||||
 *
 | 
			
		||||
 * The names of drivers are all simple, low-ASCII identifiers, like "cocoa",
 | 
			
		||||
 * "x11" or "windows". These never have Unicode characters, and are not
 | 
			
		||||
 * meant to be proper names.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \returns the name of the current video driver or NULL if no driver has been
 | 
			
		||||
 *          initialized.
 | 
			
		||||
 *
 | 
			
		||||
@@ -438,6 +450,8 @@ extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetDisplayProperties(SDL_Displa
 | 
			
		||||
/**
 | 
			
		||||
 * Get the name of a display in UTF-8 encoding.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param displayID the instance ID of the display to query
 | 
			
		||||
 * \returns the name of a display or NULL on failure; call SDL_GetError() for
 | 
			
		||||
 *          more information.
 | 
			
		||||
@@ -1260,6 +1274,8 @@ extern SDL_DECLSPEC int SDLCALL SDL_SetWindowTitle(SDL_Window *window, const cha
 | 
			
		||||
/**
 | 
			
		||||
 * Get the title of a window.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string follows the SDL_GetStringRule.
 | 
			
		||||
 *
 | 
			
		||||
 * \param window the window to query
 | 
			
		||||
 * \returns the title of the window in UTF-8 format or "" if there is no
 | 
			
		||||
 *          title.
 | 
			
		||||
 
 | 
			
		||||
@@ -573,10 +573,11 @@ int SDL_GetVersion(void)
 | 
			
		||||
/* Get the library source revision */
 | 
			
		||||
const char *SDL_GetRevision(void)
 | 
			
		||||
{
 | 
			
		||||
    return SDL_REVISION;
 | 
			
		||||
    return SDL_REVISION;  // a string literal, no need to SDL_FreeLater it.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Get the name of the platform */
 | 
			
		||||
// Get the name of the platform
 | 
			
		||||
// (a string literal, no need to SDL_FreeLater it.)
 | 
			
		||||
const char *SDL_GetPlatform(void)
 | 
			
		||||
{
 | 
			
		||||
#if defined(SDL_PLATFORM_AIX)
 | 
			
		||||
 
 | 
			
		||||
@@ -74,9 +74,7 @@ SDL_bool SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPr
 | 
			
		||||
                    entry->callback(entry->userdata, name, old_value, value);
 | 
			
		||||
                    entry = next;
 | 
			
		||||
                }
 | 
			
		||||
                if (old_value) {
 | 
			
		||||
                    SDL_free(old_value);
 | 
			
		||||
                }
 | 
			
		||||
                SDL_FreeLater(old_value);
 | 
			
		||||
            }
 | 
			
		||||
            hint->priority = priority;
 | 
			
		||||
            return SDL_TRUE;
 | 
			
		||||
@@ -120,7 +118,7 @@ SDL_bool SDL_ResetHint(const char *name)
 | 
			
		||||
                    entry = next;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            SDL_free(hint->value);
 | 
			
		||||
            SDL_FreeLater(hint->value);
 | 
			
		||||
            hint->value = NULL;
 | 
			
		||||
            hint->priority = SDL_HINT_DEFAULT;
 | 
			
		||||
            return SDL_TRUE;
 | 
			
		||||
@@ -147,7 +145,7 @@ void SDL_ResetHints(void)
 | 
			
		||||
                entry = next;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        SDL_free(hint->value);
 | 
			
		||||
        SDL_FreeLater(hint->value);
 | 
			
		||||
        hint->value = NULL;
 | 
			
		||||
        hint->priority = SDL_HINT_DEFAULT;
 | 
			
		||||
    }
 | 
			
		||||
@@ -305,7 +303,7 @@ void SDL_ClearHints(void)
 | 
			
		||||
        SDL_hints = hint->next;
 | 
			
		||||
 | 
			
		||||
        SDL_free(hint->name);
 | 
			
		||||
        SDL_free(hint->value);
 | 
			
		||||
        SDL_FreeLater(hint->value);
 | 
			
		||||
        for (entry = hint->callbacks; entry;) {
 | 
			
		||||
            SDL_HintWatch *freeable = entry;
 | 
			
		||||
            entry = entry->next;
 | 
			
		||||
 
 | 
			
		||||
@@ -293,6 +293,13 @@ extern int SDLCALL SDL_WaitSemaphoreTimeoutNS(SDL_Semaphore *sem, Sint64 timeout
 | 
			
		||||
extern int SDLCALL SDL_WaitConditionTimeoutNS(SDL_Condition *cond, SDL_Mutex *mutex, Sint64 timeoutNS);
 | 
			
		||||
extern SDL_bool SDLCALL SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS);
 | 
			
		||||
 | 
			
		||||
/* Queue `memory` to be passed to SDL_free once the event queue is emptied.
 | 
			
		||||
   this manages the list of pointers to SDL_AllocateEventMemory, but you
 | 
			
		||||
   can use it to queue pointers from other subsystems that can die at any
 | 
			
		||||
   moment but definitely need to live long enough for the app to copy them
 | 
			
		||||
   if they happened to query them in their last moments. */
 | 
			
		||||
extern void *SDL_FreeLater(void *memory);
 | 
			
		||||
 | 
			
		||||
/* Ends C function definitions when using C++ */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -65,14 +65,12 @@ static void SDL_FreePropertyWithCleanup(const void *key, const void *value, void
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case SDL_PROPERTY_TYPE_STRING:
 | 
			
		||||
            SDL_free(property->value.string_value);
 | 
			
		||||
            SDL_FreeLater(property->value.string_value);  // this pointer might be given to the app by SDL_GetStringProperty.
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        if (property->string_storage) {
 | 
			
		||||
            SDL_free(property->string_storage);
 | 
			
		||||
        }
 | 
			
		||||
        SDL_FreeLater(property->string_storage);  // this pointer might be given to the app by SDL_GetStringProperty.
 | 
			
		||||
    }
 | 
			
		||||
    SDL_free((void *)key);
 | 
			
		||||
    SDL_free((void *)value);
 | 
			
		||||
@@ -552,12 +550,6 @@ const char *SDL_GetStringProperty(SDL_PropertiesID props, const char *name, cons
 | 
			
		||||
        return value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Note that taking the lock here only guarantees that we won't read the
 | 
			
		||||
     * hashtable while it's being modified. The value itself can easily be
 | 
			
		||||
     * freed from another thread after it is returned here.
 | 
			
		||||
     *
 | 
			
		||||
     * FIXME: Should we SDL_strdup() the return value to avoid this?
 | 
			
		||||
     */
 | 
			
		||||
    SDL_LockMutex(properties->lock);
 | 
			
		||||
    {
 | 
			
		||||
        SDL_Property *property = NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -131,6 +131,7 @@ int SDL_GetNumAudioDrivers(void)
 | 
			
		||||
    return num_drivers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// this returns string literals, so there's no need to use SDL_FreeLater.
 | 
			
		||||
const char *SDL_GetAudioDriver(int index)
 | 
			
		||||
{
 | 
			
		||||
    if (index >= 0 && index < SDL_GetNumAudioDrivers()) {
 | 
			
		||||
@@ -139,6 +140,7 @@ const char *SDL_GetAudioDriver(int index)
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// this returns string literals, so there's no need to use SDL_FreeLater.
 | 
			
		||||
const char *SDL_GetCurrentAudioDriver(void)
 | 
			
		||||
{
 | 
			
		||||
    return current_audio.name;
 | 
			
		||||
@@ -521,7 +523,7 @@ static void DestroyPhysicalAudioDevice(SDL_AudioDevice *device)
 | 
			
		||||
    SDL_DestroyMutex(device->lock);
 | 
			
		||||
    SDL_DestroyCondition(device->close_cond);
 | 
			
		||||
    SDL_free(device->work_buffer);
 | 
			
		||||
    SDL_free(device->name);
 | 
			
		||||
    SDL_FreeLater(device->name);  // this pointer is handed to the app during SDL_GetAudioDeviceName
 | 
			
		||||
    SDL_free(device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1402,12 +1404,12 @@ SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByHandle(void *handle)
 | 
			
		||||
    return SDL_FindPhysicalAudioDeviceByCallback(TestDeviceHandleCallback, handle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
 | 
			
		||||
const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
 | 
			
		||||
{
 | 
			
		||||
    char *retval = NULL;
 | 
			
		||||
    const char *retval = NULL;
 | 
			
		||||
    SDL_AudioDevice *device = ObtainPhysicalAudioDevice(devid);
 | 
			
		||||
    if (device) {
 | 
			
		||||
        retval = SDL_strdup(device->name);
 | 
			
		||||
        retval = device->name;
 | 
			
		||||
    }
 | 
			
		||||
    ReleaseAudioDevice(device);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -63,6 +63,7 @@ int SDL_GetNumCameraDrivers(void)
 | 
			
		||||
    return SDL_arraysize(bootstrap) - 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// this returns string literals, so there's no need to use SDL_FreeLater.
 | 
			
		||||
const char *SDL_GetCameraDriver(int index)
 | 
			
		||||
{
 | 
			
		||||
    if (index >= 0 && index < SDL_GetNumCameraDrivers()) {
 | 
			
		||||
@@ -71,6 +72,7 @@ const char *SDL_GetCameraDriver(int index)
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// this returns string literals, so there's no need to use SDL_FreeLater.
 | 
			
		||||
const char *SDL_GetCurrentCameraDriver(void)
 | 
			
		||||
{
 | 
			
		||||
    return camera_driver.name;
 | 
			
		||||
 
 | 
			
		||||
@@ -141,7 +141,7 @@ int SDL_AndroidGetExternalStorageState(Uint32 *state)
 | 
			
		||||
    return SDL_Unsupported();
 | 
			
		||||
}
 | 
			
		||||
SDL_DECLSPEC const char *SDLCALL SDL_AndroidGetInternalStoragePath(void);
 | 
			
		||||
const char *SDL_AndroidGetInternalStoragePath()
 | 
			
		||||
const char *SDL_AndroidGetInternalStoragePath(void)
 | 
			
		||||
{
 | 
			
		||||
    SDL_Unsupported();
 | 
			
		||||
    return NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -2417,6 +2417,7 @@ void SDL_AndroidBackButton(void)
 | 
			
		||||
    (*env)->CallStaticVoidMethod(env, mActivityClass, midManualBackButton);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// this caches a string until the process ends, so there's no need to use SDL_FreeLater.
 | 
			
		||||
const char *SDL_AndroidGetInternalStoragePath(void)
 | 
			
		||||
{
 | 
			
		||||
    static char *s_AndroidInternalFilesPath = NULL;
 | 
			
		||||
@@ -2516,6 +2517,7 @@ int SDL_AndroidGetExternalStorageState(Uint32 *state)
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// this caches a string until the process ends, so there's no need to use SDL_FreeLater.
 | 
			
		||||
const char *SDL_AndroidGetExternalStoragePath(void)
 | 
			
		||||
{
 | 
			
		||||
    static char *s_AndroidExternalFilesPath = NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -213,7 +213,7 @@ SDL_DYNAPI_PROC(SDL_AssertionHandler,SDL_GetAssertionHandler,(void **a),(a),retu
 | 
			
		||||
SDL_DYNAPI_PROC(const SDL_AssertData*,SDL_GetAssertionReport,(void),(),return)
 | 
			
		||||
SDL_DYNAPI_PROC(SDL_AudioDeviceID*,SDL_GetAudioCaptureDevices,(int *a),(a),return)
 | 
			
		||||
SDL_DYNAPI_PROC(int,SDL_GetAudioDeviceFormat,(SDL_AudioDeviceID a, SDL_AudioSpec *b, int *c),(a,b,c),return)
 | 
			
		||||
SDL_DYNAPI_PROC(char*,SDL_GetAudioDeviceName,(SDL_AudioDeviceID a),(a),return)
 | 
			
		||||
SDL_DYNAPI_PROC(const char*,SDL_GetAudioDeviceName,(SDL_AudioDeviceID a),(a),return)
 | 
			
		||||
SDL_DYNAPI_PROC(const char*,SDL_GetAudioDriver,(int a),(a),return)
 | 
			
		||||
SDL_DYNAPI_PROC(SDL_AudioDeviceID*,SDL_GetAudioOutputDevices,(int *a),(a),return)
 | 
			
		||||
SDL_DYNAPI_PROC(int,SDL_GetAudioStreamAvailable,(SDL_AudioStream *a),(a),return)
 | 
			
		||||
 
 | 
			
		||||
@@ -108,37 +108,40 @@ static SDL_Mutex *SDL_event_memory_lock;
 | 
			
		||||
static SDL_EventMemory *SDL_event_memory_head;
 | 
			
		||||
static SDL_EventMemory *SDL_event_memory_tail;
 | 
			
		||||
 | 
			
		||||
void *SDL_AllocateEventMemory(size_t size)
 | 
			
		||||
void *SDL_FreeLater(void *memory)
 | 
			
		||||
{
 | 
			
		||||
    void *memory = SDL_malloc(size);
 | 
			
		||||
    if (!memory) {
 | 
			
		||||
    if (memory == NULL) {
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SDL_EventMemory *entry = (SDL_EventMemory *)SDL_malloc(sizeof(*entry));
 | 
			
		||||
    if (!entry) {
 | 
			
		||||
        return memory;  // this is now a leak, but you probably have bigger problems if malloc failed. We could probably pool up and reuse entries, though.
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SDL_LockMutex(SDL_event_memory_lock);
 | 
			
		||||
    {
 | 
			
		||||
        SDL_EventMemory *entry = (SDL_EventMemory *)SDL_malloc(sizeof(*entry));
 | 
			
		||||
        if (entry) {
 | 
			
		||||
            entry->eventID = SDL_last_event_id;
 | 
			
		||||
            entry->memory = memory;
 | 
			
		||||
            entry->next = NULL;
 | 
			
		||||
        entry->eventID = SDL_last_event_id;
 | 
			
		||||
        entry->memory = memory;
 | 
			
		||||
        entry->next = NULL;
 | 
			
		||||
 | 
			
		||||
            if (SDL_event_memory_tail) {
 | 
			
		||||
                SDL_event_memory_tail->next = entry;
 | 
			
		||||
            } else {
 | 
			
		||||
                SDL_event_memory_head = entry;
 | 
			
		||||
            }
 | 
			
		||||
            SDL_event_memory_tail = entry;
 | 
			
		||||
        if (SDL_event_memory_tail) {
 | 
			
		||||
            SDL_event_memory_tail->next = entry;
 | 
			
		||||
        } else {
 | 
			
		||||
            SDL_free(memory);
 | 
			
		||||
            memory = NULL;
 | 
			
		||||
            SDL_event_memory_head = entry;
 | 
			
		||||
        }
 | 
			
		||||
        SDL_event_memory_tail = entry;
 | 
			
		||||
    }
 | 
			
		||||
    SDL_UnlockMutex(SDL_event_memory_lock);
 | 
			
		||||
 | 
			
		||||
    return memory;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *SDL_AllocateEventMemory(size_t size)
 | 
			
		||||
{
 | 
			
		||||
    return SDL_FreeLater(SDL_malloc(size));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void SDL_FlushEventMemory(Uint32 eventID)
 | 
			
		||||
{
 | 
			
		||||
    SDL_LockMutex(SDL_event_memory_lock);
 | 
			
		||||
 
 | 
			
		||||
@@ -742,7 +742,7 @@ void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID, SDL_bool send_event)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SDL_free(SDL_keyboards[keyboard_index].name);
 | 
			
		||||
    SDL_FreeLater(SDL_keyboards[keyboard_index].name);
 | 
			
		||||
 | 
			
		||||
    if (keyboard_index != SDL_keyboard_count - 1) {
 | 
			
		||||
        SDL_memcpy(&SDL_keyboards[keyboard_index], &SDL_keyboards[keyboard_index + 1], (SDL_keyboard_count - keyboard_index - 1) * sizeof(SDL_keyboards[keyboard_index]));
 | 
			
		||||
@@ -1334,6 +1334,7 @@ SDL_Scancode SDL_GetScancodeFromKey(SDL_Keycode key)
 | 
			
		||||
    return SDL_SCANCODE_UNKNOWN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// these are static memory, so we don't use SDL_FreeLater on them.
 | 
			
		||||
const char *SDL_GetScancodeName(SDL_Scancode scancode)
 | 
			
		||||
{
 | 
			
		||||
    const char *name;
 | 
			
		||||
@@ -1374,7 +1375,7 @@ SDL_Scancode SDL_GetScancodeFromName(const char *name)
 | 
			
		||||
 | 
			
		||||
const char *SDL_GetKeyName(SDL_Keycode key)
 | 
			
		||||
{
 | 
			
		||||
    static char name[8];
 | 
			
		||||
    char name[8];
 | 
			
		||||
    char *end;
 | 
			
		||||
 | 
			
		||||
    if (key & SDLK_SCANCODE_MASK) {
 | 
			
		||||
@@ -1405,7 +1406,7 @@ const char *SDL_GetKeyName(SDL_Keycode key)
 | 
			
		||||
 | 
			
		||||
        end = SDL_UCS4ToUTF8((Uint32)key, name);
 | 
			
		||||
        *end = '\0';
 | 
			
		||||
        return name;
 | 
			
		||||
        return SDL_FreeLater(SDL_strdup(name));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -288,7 +288,7 @@ void SDL_RemoveMouse(SDL_MouseID mouseID, SDL_bool send_event)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SDL_free(SDL_mice[mouse_index].name);
 | 
			
		||||
    SDL_FreeLater(SDL_mice[mouse_index].name);  // SDL_GetMouseInstanceName returns this pointer.
 | 
			
		||||
 | 
			
		||||
    if (mouse_index != SDL_mouse_count - 1) {
 | 
			
		||||
        SDL_memcpy(&SDL_mice[mouse_index], &SDL_mice[mouse_index + 1], (SDL_mouse_count - mouse_index - 1) * sizeof(SDL_mice[mouse_index]));
 | 
			
		||||
 
 | 
			
		||||
@@ -493,7 +493,7 @@ void SDL_DelTouch(SDL_TouchID id)
 | 
			
		||||
        SDL_free(touch->fingers[i]);
 | 
			
		||||
    }
 | 
			
		||||
    SDL_free(touch->fingers);
 | 
			
		||||
    SDL_free(touch->name);
 | 
			
		||||
    SDL_FreeLater(touch->name);  // this pointer might be given to the app by SDL_GetTouchDeviceName.
 | 
			
		||||
    SDL_free(touch);
 | 
			
		||||
 | 
			
		||||
    SDL_num_touch--;
 | 
			
		||||
 
 | 
			
		||||
@@ -93,6 +93,7 @@ static const wchar_t *SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType)
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// this caches a string until the process ends, so there's no need to use SDL_FreeLater.
 | 
			
		||||
extern "C" const char *SDL_WinRTGetFSPath(SDL_WinRT_Path pathType)
 | 
			
		||||
{
 | 
			
		||||
    typedef unordered_map<SDL_WinRT_Path, string> UTF8PathMap;
 | 
			
		||||
 
 | 
			
		||||
@@ -100,7 +100,7 @@ const char *SDL_GetHapticInstanceName(SDL_HapticID instance_id)
 | 
			
		||||
    if (SDL_GetHapticIndex(instance_id, &device_index)) {
 | 
			
		||||
        name = SDL_SYS_HapticName(device_index);
 | 
			
		||||
    }
 | 
			
		||||
    return name;
 | 
			
		||||
    return name ? SDL_FreeLater(SDL_strdup(name)) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SDL_Haptic *SDL_OpenHaptic(SDL_HapticID instance_id)
 | 
			
		||||
@@ -338,7 +338,7 @@ void SDL_CloseHaptic(SDL_Haptic *haptic)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Free the data associated with this device */
 | 
			
		||||
    SDL_free(haptic->name);
 | 
			
		||||
    SDL_FreeLater(haptic->name);  // this pointer is handed to the app in SDL_GetHapticName()
 | 
			
		||||
    SDL_free(haptic);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1594,7 +1594,7 @@ static GamepadMapping_t *SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, co
 | 
			
		||||
        /* Only overwrite the mapping if the priority is the same or higher. */
 | 
			
		||||
        if (pGamepadMapping->priority <= priority) {
 | 
			
		||||
            /* Update existing mapping */
 | 
			
		||||
            SDL_free(pGamepadMapping->name);
 | 
			
		||||
            SDL_FreeLater(pGamepadMapping->name);  // this is returned in SDL_GetGamepadName.
 | 
			
		||||
            pGamepadMapping->name = pchName;
 | 
			
		||||
            SDL_free(pGamepadMapping->mapping);
 | 
			
		||||
            pGamepadMapping->mapping = pchMapping;
 | 
			
		||||
@@ -3413,7 +3413,8 @@ const char * SDL_GetGamepadSerial(SDL_Gamepad *gamepad)
 | 
			
		||||
    if (!joystick) {
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
    return SDL_GetJoystickSerial(joystick);
 | 
			
		||||
    return SDL_GetJoystickSerial(joystick);  // this already returns a SDL_FreeLater pointer.
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Uint64 SDL_GetGamepadSteamHandle(SDL_Gamepad *gamepad)
 | 
			
		||||
@@ -3680,7 +3681,7 @@ void SDL_QuitGamepadMappings(void)
 | 
			
		||||
    while (s_pSupportedGamepads) {
 | 
			
		||||
        pGamepadMap = s_pSupportedGamepads;
 | 
			
		||||
        s_pSupportedGamepads = s_pSupportedGamepads->next;
 | 
			
		||||
        SDL_free(pGamepadMap->name);
 | 
			
		||||
        SDL_FreeLater(pGamepadMap->name);  // this is returned in SDL_GetGamepadName.
 | 
			
		||||
        SDL_free(pGamepadMap->mapping);
 | 
			
		||||
        SDL_free(pGamepadMap);
 | 
			
		||||
    }
 | 
			
		||||
@@ -3826,8 +3827,8 @@ void SDL_GamepadHandleDelayedGuideButton(SDL_Joystick *joystick)
 | 
			
		||||
const char *SDL_GetGamepadAppleSFSymbolsNameForButton(SDL_Gamepad *gamepad, SDL_GamepadButton button)
 | 
			
		||||
{
 | 
			
		||||
#ifdef SDL_JOYSTICK_MFI
 | 
			
		||||
    const char *IOS_GetAppleSFSymbolsNameForButton(SDL_Gamepad *gamepad, SDL_GamepadButton button);
 | 
			
		||||
    const char *retval;
 | 
			
		||||
    char *IOS_GetAppleSFSymbolsNameForButton(SDL_Gamepad *gamepad, SDL_GamepadButton button);
 | 
			
		||||
    char *retval;
 | 
			
		||||
 | 
			
		||||
    SDL_LockJoysticks();
 | 
			
		||||
    {
 | 
			
		||||
@@ -3837,9 +3838,11 @@ const char *SDL_GetGamepadAppleSFSymbolsNameForButton(SDL_Gamepad *gamepad, SDL_
 | 
			
		||||
    }
 | 
			
		||||
    SDL_UnlockJoysticks();
 | 
			
		||||
 | 
			
		||||
    // retval was malloc'd by IOS_GetAppleSFSymbolsNameForButton
 | 
			
		||||
    if (retval && *retval) {
 | 
			
		||||
        return retval;
 | 
			
		||||
        return SDL_FreeLater(retval);
 | 
			
		||||
    }
 | 
			
		||||
    SDL_free(retval);
 | 
			
		||||
#endif
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
@@ -3847,8 +3850,8 @@ const char *SDL_GetGamepadAppleSFSymbolsNameForButton(SDL_Gamepad *gamepad, SDL_
 | 
			
		||||
const char *SDL_GetGamepadAppleSFSymbolsNameForAxis(SDL_Gamepad *gamepad, SDL_GamepadAxis axis)
 | 
			
		||||
{
 | 
			
		||||
#ifdef SDL_JOYSTICK_MFI
 | 
			
		||||
    const char *IOS_GetAppleSFSymbolsNameForAxis(SDL_Gamepad *gamepad, SDL_GamepadAxis axis);
 | 
			
		||||
    const char *retval;
 | 
			
		||||
    char *IOS_GetAppleSFSymbolsNameForAxis(SDL_Gamepad *gamepad, SDL_GamepadAxis axis);
 | 
			
		||||
    char *retval;
 | 
			
		||||
 | 
			
		||||
    SDL_LockJoysticks();
 | 
			
		||||
    {
 | 
			
		||||
@@ -3858,9 +3861,11 @@ const char *SDL_GetGamepadAppleSFSymbolsNameForAxis(SDL_Gamepad *gamepad, SDL_Ga
 | 
			
		||||
    }
 | 
			
		||||
    SDL_UnlockJoysticks();
 | 
			
		||||
 | 
			
		||||
    // retval was malloc'd by IOS_GetAppleSFSymbolsNameForAxis
 | 
			
		||||
    if (retval && *retval) {
 | 
			
		||||
        return retval;
 | 
			
		||||
        return SDL_FreeLater(retval);
 | 
			
		||||
    }
 | 
			
		||||
    SDL_free(retval);
 | 
			
		||||
#endif
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -785,8 +785,7 @@ const char *SDL_GetJoystickInstanceName(SDL_JoystickID instance_id)
 | 
			
		||||
    }
 | 
			
		||||
    SDL_UnlockJoysticks();
 | 
			
		||||
 | 
			
		||||
    /* FIXME: Really we should reference count this name so it doesn't go away after unlock */
 | 
			
		||||
    return name;
 | 
			
		||||
    return name ? SDL_FreeLater(SDL_strdup(name)) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -804,11 +803,10 @@ const char *SDL_GetJoystickInstancePath(SDL_JoystickID instance_id)
 | 
			
		||||
    }
 | 
			
		||||
    SDL_UnlockJoysticks();
 | 
			
		||||
 | 
			
		||||
    /* FIXME: Really we should reference count this path so it doesn't go away after unlock */
 | 
			
		||||
    if (!path) {
 | 
			
		||||
        SDL_Unsupported();
 | 
			
		||||
    }
 | 
			
		||||
    return path;
 | 
			
		||||
    return path ? SDL_FreeLater(SDL_strdup(path)) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -1663,7 +1661,6 @@ const char *SDL_GetJoystickName(SDL_Joystick *joystick)
 | 
			
		||||
    }
 | 
			
		||||
    SDL_UnlockJoysticks();
 | 
			
		||||
 | 
			
		||||
    /* FIXME: Really we should reference count this name so it doesn't go away after unlock */
 | 
			
		||||
    return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1888,9 +1885,9 @@ void SDL_CloseJoystick(SDL_Joystick *joystick)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Free the data associated with this joystick */
 | 
			
		||||
        SDL_free(joystick->name);
 | 
			
		||||
        SDL_free(joystick->path);
 | 
			
		||||
        SDL_free(joystick->serial);
 | 
			
		||||
        SDL_FreeLater(joystick->name);  // SDL_GetJoystickName returns this pointer.
 | 
			
		||||
        SDL_FreeLater(joystick->path);  // SDL_GetJoystickPath returns this pointer.
 | 
			
		||||
        SDL_FreeLater(joystick->serial);  // SDL_GetJoystickSerial returns this pointer.
 | 
			
		||||
        SDL_free(joystick->axes);
 | 
			
		||||
        SDL_free(joystick->balls);
 | 
			
		||||
        SDL_free(joystick->hats);
 | 
			
		||||
 
 | 
			
		||||
@@ -1916,11 +1916,11 @@ static GCControllerDirectionPad *GetDirectionalPadForController(GCController *co
 | 
			
		||||
}
 | 
			
		||||
#endif /* SDL_JOYSTICK_MFI && ENABLE_PHYSICAL_INPUT_PROFILE */
 | 
			
		||||
 | 
			
		||||
static char elementName[256];
 | 
			
		||||
 | 
			
		||||
const char *IOS_GetAppleSFSymbolsNameForButton(SDL_Gamepad *gamepad, SDL_GamepadButton button)
 | 
			
		||||
char *IOS_GetAppleSFSymbolsNameForButton(SDL_Gamepad *gamepad, SDL_GamepadButton button)
 | 
			
		||||
{
 | 
			
		||||
    char elementName[256];
 | 
			
		||||
    elementName[0] = '\0';
 | 
			
		||||
 | 
			
		||||
#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE)
 | 
			
		||||
    if (gamepad && SDL_GetGamepadJoystick(gamepad)->driver == &SDL_IOS_JoystickDriver) {
 | 
			
		||||
        if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
 | 
			
		||||
@@ -2030,12 +2030,15 @@ const char *IOS_GetAppleSFSymbolsNameForButton(SDL_Gamepad *gamepad, SDL_Gamepad
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    return elementName;
 | 
			
		||||
 | 
			
		||||
    return SDL_strdup(elementName);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *IOS_GetAppleSFSymbolsNameForAxis(SDL_Gamepad *gamepad, SDL_GamepadAxis axis)
 | 
			
		||||
char *IOS_GetAppleSFSymbolsNameForAxis(SDL_Gamepad *gamepad, SDL_GamepadAxis axis)
 | 
			
		||||
{
 | 
			
		||||
    char elementName[256];
 | 
			
		||||
    elementName[0] = '\0';
 | 
			
		||||
 | 
			
		||||
#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE)
 | 
			
		||||
    if (gamepad && SDL_GetGamepadJoystick(gamepad)->driver == &SDL_IOS_JoystickDriver) {
 | 
			
		||||
        if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) {
 | 
			
		||||
@@ -2068,7 +2071,7 @@ const char *IOS_GetAppleSFSymbolsNameForAxis(SDL_Gamepad *gamepad, SDL_GamepadAx
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    return *elementName ? elementName : NULL;
 | 
			
		||||
    return *elementName ? SDL_strdup(elementName) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SDL_JoystickDriver SDL_IOS_JoystickDriver = {
 | 
			
		||||
 
 | 
			
		||||
@@ -780,6 +780,7 @@ int SDL_GetNumRenderDrivers(void)
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// this returns string literals, so there's no need to use SDL_FreeLater.
 | 
			
		||||
const char *SDL_GetRenderDriver(int index)
 | 
			
		||||
{
 | 
			
		||||
#ifndef SDL_RENDER_DISABLED
 | 
			
		||||
 
 | 
			
		||||
@@ -250,8 +250,7 @@ const char *SDL_GetSensorInstanceName(SDL_SensorID instance_id)
 | 
			
		||||
    }
 | 
			
		||||
    SDL_UnlockSensors();
 | 
			
		||||
 | 
			
		||||
    /* FIXME: Really we should reference count this name so it doesn't go away after unlock */
 | 
			
		||||
    return name;
 | 
			
		||||
    return name ? SDL_FreeLater(SDL_strdup(name)) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SDL_SensorType SDL_GetSensorInstanceType(SDL_SensorID instance_id)
 | 
			
		||||
@@ -527,7 +526,7 @@ void SDL_CloseSensor(SDL_Sensor *sensor)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Free the data associated with this sensor */
 | 
			
		||||
        SDL_free(sensor->name);
 | 
			
		||||
        SDL_FreeLater(sensor->name);  // this pointer gets handed to the app by SDL_GetSensorName().
 | 
			
		||||
        SDL_free(sensor);
 | 
			
		||||
    }
 | 
			
		||||
    SDL_UnlockSensors();
 | 
			
		||||
 
 | 
			
		||||
@@ -299,9 +299,7 @@ void SDL_RunThread(SDL_Thread *thread)
 | 
			
		||||
    if (!SDL_AtomicCompareAndSwap(&thread->state, SDL_THREAD_STATE_ALIVE, SDL_THREAD_STATE_ZOMBIE)) {
 | 
			
		||||
        /* Clean up if something already detached us. */
 | 
			
		||||
        if (SDL_AtomicCompareAndSwap(&thread->state, SDL_THREAD_STATE_DETACHED, SDL_THREAD_STATE_CLEANED)) {
 | 
			
		||||
            if (thread->name) {
 | 
			
		||||
                SDL_free(thread->name);
 | 
			
		||||
            }
 | 
			
		||||
            SDL_FreeLater(thread->name);
 | 
			
		||||
            SDL_free(thread);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -421,9 +419,7 @@ void SDL_WaitThread(SDL_Thread *thread, int *status)
 | 
			
		||||
        if (status) {
 | 
			
		||||
            *status = thread->status;
 | 
			
		||||
        }
 | 
			
		||||
        if (thread->name) {
 | 
			
		||||
            SDL_free(thread->name);
 | 
			
		||||
        }
 | 
			
		||||
        SDL_FreeLater(thread->name);
 | 
			
		||||
        SDL_free(thread);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -85,6 +85,7 @@ Uint16 SDL_expand_byte10[] = {
 | 
			
		||||
 | 
			
		||||
/* Helper functions */
 | 
			
		||||
 | 
			
		||||
// This doesn't need SDL_FreeLater since it returns string literals.
 | 
			
		||||
#define CASE(X) \
 | 
			
		||||
    case X:     \
 | 
			
		||||
        return #X;
 | 
			
		||||
 
 | 
			
		||||
@@ -498,6 +498,7 @@ int SDL_GetNumVideoDrivers(void)
 | 
			
		||||
    return SDL_arraysize(bootstrap) - 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// this returns string literals, so there's no need to use SDL_FreeLater.
 | 
			
		||||
const char *SDL_GetVideoDriver(int index)
 | 
			
		||||
{
 | 
			
		||||
    if (index >= 0 && index < SDL_GetNumVideoDrivers()) {
 | 
			
		||||
@@ -642,6 +643,7 @@ pre_driver_error:
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// this returns string literals, so there's no need to use SDL_FreeLater.
 | 
			
		||||
const char *SDL_GetCurrentVideoDriver(void)
 | 
			
		||||
{
 | 
			
		||||
    if (!_this) {
 | 
			
		||||
 
 | 
			
		||||
@@ -973,7 +973,7 @@ static Thing *CreatePhysicalDeviceThing(const SDL_AudioDeviceID which, const SDL
 | 
			
		||||
    if (thing) {
 | 
			
		||||
        thing->data.physdev.devid = which;
 | 
			
		||||
        thing->data.physdev.iscapture = iscapture;
 | 
			
		||||
        thing->data.physdev.name = SDL_GetAudioDeviceName(which);
 | 
			
		||||
        thing->data.physdev.name = SDL_strdup(SDL_GetAudioDeviceName(which));
 | 
			
		||||
        thing->ondrag = DeviceThing_ondrag;
 | 
			
		||||
        thing->ondrop = PhysicalDeviceThing_ondrop;
 | 
			
		||||
        thing->ontick = PhysicalDeviceThing_ontick;
 | 
			
		||||
 
 | 
			
		||||
@@ -81,12 +81,11 @@ int SDL_AppInit(void **appstate, int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
    devices = SDL_GetAudioCaptureDevices(NULL);
 | 
			
		||||
    for (i = 0; devices[i] != 0; i++) {
 | 
			
		||||
        char *name = SDL_GetAudioDeviceName(devices[i]);
 | 
			
		||||
        const char *name = SDL_GetAudioDeviceName(devices[i]);
 | 
			
		||||
        SDL_Log(" Capture device #%d: '%s'\n", i, name);
 | 
			
		||||
        if (devname && (SDL_strcmp(devname, name) == 0)) {
 | 
			
		||||
            want_device = devices[i];
 | 
			
		||||
        }
 | 
			
		||||
        SDL_free(name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (devname && (want_device == SDL_AUDIO_DEVICE_DEFAULT_CAPTURE)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ static void iteration(void)
 | 
			
		||||
        } else if (e.type == SDL_EVENT_AUDIO_DEVICE_ADDED) {
 | 
			
		||||
            const SDL_AudioDeviceID which = (SDL_AudioDeviceID) e.adevice.which;
 | 
			
		||||
            const SDL_bool iscapture = e.adevice.iscapture ? SDL_TRUE : SDL_FALSE;
 | 
			
		||||
            char *name = SDL_GetAudioDeviceName(which);
 | 
			
		||||
            const char *name = SDL_GetAudioDeviceName(which);
 | 
			
		||||
            if (name) {
 | 
			
		||||
                SDL_Log("New %s audio device at id %u: %s", devtypestr(iscapture), (unsigned int)which, name);
 | 
			
		||||
            } else {
 | 
			
		||||
@@ -92,7 +92,6 @@ static void iteration(void)
 | 
			
		||||
                    /* !!! FIXME: this is leaking the stream for now. We'll wire it up to a dictionary or whatever later. */
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            SDL_free(name);
 | 
			
		||||
        } else if (e.type == SDL_EVENT_AUDIO_DEVICE_REMOVED) {
 | 
			
		||||
            dev = (SDL_AudioDeviceID)e.adevice.which;
 | 
			
		||||
            SDL_Log("%s device %u removed.\n", devtypestr(e.adevice.iscapture), (unsigned int)dev);
 | 
			
		||||
 
 | 
			
		||||
@@ -30,10 +30,9 @@ print_devices(SDL_bool iscapture)
 | 
			
		||||
        int i;
 | 
			
		||||
        SDL_Log("Found %d %s device%s:\n", n, typestr, n != 1 ? "s" : "");
 | 
			
		||||
        for (i = 0; i < n; i++) {
 | 
			
		||||
            char *name = SDL_GetAudioDeviceName(devices[i]);
 | 
			
		||||
            const char *name = SDL_GetAudioDeviceName(devices[i]);
 | 
			
		||||
            if (name) {
 | 
			
		||||
                SDL_Log("  %d: %s\n", i, name);
 | 
			
		||||
                SDL_free(name);
 | 
			
		||||
            } else {
 | 
			
		||||
                SDL_Log("  %d Error: %s\n", i, SDL_GetError());
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -365,7 +365,7 @@ static int audio_enumerateAndNameAudioDevices(void *arg)
 | 
			
		||||
{
 | 
			
		||||
    int t;
 | 
			
		||||
    int i, n;
 | 
			
		||||
    char *name;
 | 
			
		||||
    const char *name;
 | 
			
		||||
    SDL_AudioDeviceID *devices = NULL;
 | 
			
		||||
 | 
			
		||||
    /* Iterate over types: t=0 output device, t=1 input/capture device */
 | 
			
		||||
@@ -385,7 +385,6 @@ static int audio_enumerateAndNameAudioDevices(void *arg)
 | 
			
		||||
                SDLTest_AssertCheck(name != NULL, "Verify result from SDL_GetAudioDeviceName(%i) is not NULL", i);
 | 
			
		||||
                if (name != NULL) {
 | 
			
		||||
                    SDLTest_AssertCheck(name[0] != '\0', "verify result from SDL_GetAudioDeviceName(%i) is not empty, got: '%s'", i, name);
 | 
			
		||||
                    SDL_free(name);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,7 @@ test_multi_audio(SDL_AudioDeviceID *devices, int devcount)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < devcount; i++) {
 | 
			
		||||
        char *devname = SDL_GetAudioDeviceName(devices[i]);
 | 
			
		||||
        const char *devname = SDL_GetAudioDeviceName(devices[i]);
 | 
			
		||||
 | 
			
		||||
        SDL_Log("Playing on device #%d of %d: id=%u, name='%s'...", i, devcount, (unsigned int) devices[i], devname);
 | 
			
		||||
 | 
			
		||||
@@ -82,7 +82,6 @@ test_multi_audio(SDL_AudioDeviceID *devices, int devcount)
 | 
			
		||||
            SDL_Log("done.");
 | 
			
		||||
            SDL_DestroyAudioStream(stream);
 | 
			
		||||
        }
 | 
			
		||||
        SDL_free(devname);
 | 
			
		||||
        stream = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -191,12 +191,11 @@ int main(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < devcount; i++) {
 | 
			
		||||
        SDL_AudioStream *stream = NULL;
 | 
			
		||||
        char *devname = SDL_GetAudioDeviceName(devices[i]);
 | 
			
		||||
        const char *devname = SDL_GetAudioDeviceName(devices[i]);
 | 
			
		||||
        int j;
 | 
			
		||||
        SDL_AudioSpec spec;
 | 
			
		||||
 | 
			
		||||
        SDL_Log("Testing audio device: %s\n", devname);
 | 
			
		||||
        SDL_free(devname);
 | 
			
		||||
 | 
			
		||||
        if (SDL_GetAudioDeviceFormat(devices[i], &spec, NULL) != 0) {
 | 
			
		||||
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GetAudioDeviceFormat() failed: %s\n", SDL_GetError());
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user