mirror of
				https://github.com/libsdl-org/SDL.git
				synced 2025-11-04 01:34:38 +00:00 
			
		
		
		
	hints: Change hints to be backed by Properties, add documentation. (#9892)
This makes the subsystem thread-safe, more performant, and cleans up the code a little. Also removed SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS, since setting this hint programmatically initializes properties, which creates a lock, so we can't check hints while creating locks. The slim reader-writer locks have been the default for ages and are solid, so we'll just use those when available.
This commit is contained in:
		@@ -755,6 +755,8 @@ SDL_AddHintCallback() now returns a standard int result instead of void, returni
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Calling SDL_GetHint() with the name of the hint being changed from within a hint callback will now return the new value rather than the old value. The old value is still passed as a parameter to the hint callback.
 | 
					Calling SDL_GetHint() with the name of the hint being changed from within a hint callback will now return the new value rather than the old value. The old value is still passed as a parameter to the hint callback.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SDL_SetHint, SDL_SetHintWithPriority, and SDL_ResetHint now return int (-1 on error, 0 on success) instead of SDL_bool (SDL_FALSE on error, SDL_TRUE on success).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The environment variables SDL_VIDEODRIVER and SDL_AUDIODRIVER have been renamed to SDL_VIDEO_DRIVER and SDL_AUDIO_DRIVER.
 | 
					The environment variables SDL_VIDEODRIVER and SDL_AUDIODRIVER have been renamed to SDL_VIDEO_DRIVER and SDL_AUDIO_DRIVER.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The environment variables SDL_VIDEO_X11_WMCLASS and SDL_VIDEO_WAYLAND_WMCLASS have been removed and replaced by either using the appindentifier param to SDL_SetAppMetadata() or setting SDL_PROP_APP_METADATA_IDENTIFIER_STRING with SDL_SetAppMetadataProperty()
 | 
					The environment variables SDL_VIDEO_X11_WMCLASS and SDL_VIDEO_WAYLAND_WMCLASS have been removed and replaced by either using the appindentifier param to SDL_SetAppMetadata() or setting SDL_PROP_APP_METADATA_IDENTIFIER_STRING with SDL_SetAppMetadataProperty()
 | 
				
			||||||
@@ -799,6 +801,7 @@ The following hints have been removed:
 | 
				
			|||||||
* SDL_HINT_VIDEO_X11_XINERAMA - Xinerama no longer supported by the X11 backend
 | 
					* SDL_HINT_VIDEO_X11_XINERAMA - Xinerama no longer supported by the X11 backend
 | 
				
			||||||
* SDL_HINT_VIDEO_X11_XVIDMODE - Xvidmode no longer supported by the X11 backend
 | 
					* SDL_HINT_VIDEO_X11_XVIDMODE - Xvidmode no longer supported by the X11 backend
 | 
				
			||||||
* SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING - SDL now properly handles the 0x406D1388 Exception if no debugger intercepts it, preventing its propagation.
 | 
					* SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING - SDL now properly handles the 0x406D1388 Exception if no debugger intercepts it, preventing its propagation.
 | 
				
			||||||
 | 
					* SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS - Slim Reader/Writer Locks are always used if available
 | 
				
			||||||
* SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 - replaced with SDL_HINT_WINDOWS_CLOSE_ON_ALT_F4, defaulting to SDL_TRUE
 | 
					* SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 - replaced with SDL_HINT_WINDOWS_CLOSE_ON_ALT_F4, defaulting to SDL_TRUE
 | 
				
			||||||
* SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING
 | 
					* SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING
 | 
				
			||||||
* SDL_HINT_AUDIO_DEVICE_APP_NAME - replaced by either using the appname param to SDL_SetAppMetadata() or setting SDL_PROP_APP_METADATA_NAME_STRING with SDL_SetAppMetadataProperty()
 | 
					* SDL_HINT_AUDIO_DEVICE_APP_NAME - replaced by either using the appname param to SDL_SetAppMetadata() or setting SDL_PROP_APP_METADATA_NAME_STRING with SDL_SetAppMetadataProperty()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3837,27 +3837,6 @@ extern "C" {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
#define SDL_HINT_WINDOWS_RAW_KEYBOARD   "SDL_WINDOWS_RAW_KEYBOARD"
 | 
					#define SDL_HINT_WINDOWS_RAW_KEYBOARD   "SDL_WINDOWS_RAW_KEYBOARD"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * A variable controlling whether SDL uses Critical Sections for mutexes on
 | 
					 | 
				
			||||||
 * Windows.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * On Windows 7 and newer, Slim Reader/Writer Locks are available. They offer
 | 
					 | 
				
			||||||
 * better performance, allocate no kernel resources and use less memory. SDL
 | 
					 | 
				
			||||||
 * will fall back to Critical Sections on older OS versions or if forced to by
 | 
					 | 
				
			||||||
 * this hint.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * The variable can be set to the following values:
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * - "0": Use SRW Locks when available, otherwise fall back to Critical
 | 
					 | 
				
			||||||
 *   Sections. (default)
 | 
					 | 
				
			||||||
 * - "1": Force the use of Critical Sections in all cases.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This hint should be set before SDL is initialized.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * \since This hint is available since SDL 3.0.0.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS "SDL_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A variable controlling whether SDL uses Kernel Semaphores on Windows.
 | 
					 * A variable controlling whether SDL uses Kernel Semaphores on Windows.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -4133,7 +4112,10 @@ typedef enum SDL_HintPriority
 | 
				
			|||||||
 * \param name the hint to set.
 | 
					 * \param name the hint to set.
 | 
				
			||||||
 * \param value the value of the hint variable.
 | 
					 * \param value the value of the hint variable.
 | 
				
			||||||
 * \param priority the SDL_HintPriority level for the hint.
 | 
					 * \param priority the SDL_HintPriority level for the hint.
 | 
				
			||||||
 * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise.
 | 
					 * \returns 0 on success or a negative error code on failure; call
 | 
				
			||||||
 | 
					 *          SDL_GetError() for more information.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \threadsafety It is safe to call this function from any thread.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \since This function is available since SDL 3.0.0.
 | 
					 * \since This function is available since SDL 3.0.0.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -4141,9 +4123,9 @@ typedef enum SDL_HintPriority
 | 
				
			|||||||
 * \sa SDL_ResetHint
 | 
					 * \sa SDL_ResetHint
 | 
				
			||||||
 * \sa SDL_SetHint
 | 
					 * \sa SDL_SetHint
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
extern SDL_DECLSPEC SDL_bool SDLCALL SDL_SetHintWithPriority(const char *name,
 | 
					extern SDL_DECLSPEC int SDLCALL SDL_SetHintWithPriority(const char *name,
 | 
				
			||||||
                                                         const char *value,
 | 
					                                                        const char *value,
 | 
				
			||||||
                                                         SDL_HintPriority priority);
 | 
					                                                        SDL_HintPriority priority);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Set a hint with normal priority.
 | 
					 * Set a hint with normal priority.
 | 
				
			||||||
@@ -4154,7 +4136,10 @@ extern SDL_DECLSPEC SDL_bool SDLCALL SDL_SetHintWithPriority(const char *name,
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * \param name the hint to set.
 | 
					 * \param name the hint to set.
 | 
				
			||||||
 * \param value the value of the hint variable.
 | 
					 * \param value the value of the hint variable.
 | 
				
			||||||
 * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise.
 | 
					 * \returns 0 on success or a negative error code on failure; call
 | 
				
			||||||
 | 
					 *          SDL_GetError() for more information.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \threadsafety It is safe to call this function from any thread.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \since This function is available since SDL 3.0.0.
 | 
					 * \since This function is available since SDL 3.0.0.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@@ -4162,8 +4147,7 @@ extern SDL_DECLSPEC SDL_bool SDLCALL SDL_SetHintWithPriority(const char *name,
 | 
				
			|||||||
 * \sa SDL_ResetHint
 | 
					 * \sa SDL_ResetHint
 | 
				
			||||||
 * \sa SDL_SetHintWithPriority
 | 
					 * \sa SDL_SetHintWithPriority
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
extern SDL_DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name,
 | 
					extern SDL_DECLSPEC int SDLCALL SDL_SetHint(const char *name, const char *value);
 | 
				
			||||||
                                             const char *value);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Reset a hint to the default value.
 | 
					 * Reset a hint to the default value.
 | 
				
			||||||
@@ -4173,14 +4157,17 @@ extern SDL_DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name,
 | 
				
			|||||||
 * change.
 | 
					 * change.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \param name the hint to set.
 | 
					 * \param name the hint to set.
 | 
				
			||||||
 * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise.
 | 
					 * \returns 0 on success or a negative error code on failure; call
 | 
				
			||||||
 | 
					 *          SDL_GetError() for more information.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \threadsafety It is safe to call this function from any thread.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \since This function is available since SDL 3.0.0.
 | 
					 * \since This function is available since SDL 3.0.0.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \sa SDL_SetHint
 | 
					 * \sa SDL_SetHint
 | 
				
			||||||
 * \sa SDL_ResetHints
 | 
					 * \sa SDL_ResetHints
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
extern SDL_DECLSPEC SDL_bool SDLCALL SDL_ResetHint(const char *name);
 | 
					extern SDL_DECLSPEC int SDLCALL SDL_ResetHint(const char *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Reset all hints to the default values.
 | 
					 * Reset all hints to the default values.
 | 
				
			||||||
@@ -4189,6 +4176,8 @@ extern SDL_DECLSPEC SDL_bool SDLCALL SDL_ResetHint(const char *name);
 | 
				
			|||||||
 * variable, or NULL if the environment isn't set. Callbacks will be called
 | 
					 * variable, or NULL if the environment isn't set. Callbacks will be called
 | 
				
			||||||
 * normally with this change.
 | 
					 * normally with this change.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * \threadsafety It is safe to call this function from any thread.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * \since This function is available since SDL 3.0.0.
 | 
					 * \since This function is available since SDL 3.0.0.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \sa SDL_ResetHint
 | 
					 * \sa SDL_ResetHint
 | 
				
			||||||
@@ -4201,6 +4190,13 @@ extern SDL_DECLSPEC void SDLCALL SDL_ResetHints(void);
 | 
				
			|||||||
 * \param name the hint to query.
 | 
					 * \param name the hint to query.
 | 
				
			||||||
 * \returns the string value of a hint or NULL if the hint isn't set.
 | 
					 * \returns the string value of a hint or NULL if the hint isn't set.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * \threadsafety It is safe to call this function from any thread, however
 | 
				
			||||||
 | 
					 *               the return value only remains valid until the hint is
 | 
				
			||||||
 | 
					 *               changed; if another thread might do so, the app should
 | 
				
			||||||
 | 
					 *               supply locks and/or make a copy of the string. Note that
 | 
				
			||||||
 | 
					 *               using a hint callback instead is always thread-safe, as SDL
 | 
				
			||||||
 | 
					 *               holds a lock on the thread subsystem during the callback.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * \since This function is available since SDL 3.0.0.
 | 
					 * \since This function is available since SDL 3.0.0.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \sa SDL_SetHint
 | 
					 * \sa SDL_SetHint
 | 
				
			||||||
@@ -4216,6 +4212,8 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetHint(const char *name);
 | 
				
			|||||||
 * \returns the boolean value of a hint or the provided default value if the
 | 
					 * \returns the boolean value of a hint or the provided default value if the
 | 
				
			||||||
 *          hint does not exist.
 | 
					 *          hint does not exist.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * \threadsafety It is safe to call this function from any thread.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * \since This function is available since SDL 3.0.0.
 | 
					 * \since This function is available since SDL 3.0.0.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \sa SDL_GetHint
 | 
					 * \sa SDL_GetHint
 | 
				
			||||||
@@ -4224,37 +4222,48 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetHint(const char *name);
 | 
				
			|||||||
extern SDL_DECLSPEC SDL_bool SDLCALL SDL_GetHintBoolean(const char *name, SDL_bool default_value);
 | 
					extern SDL_DECLSPEC SDL_bool SDLCALL SDL_GetHintBoolean(const char *name, SDL_bool default_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Type definition of the hint callback function.
 | 
					 * A callback used to send notifications of hint value changes.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This is called an initial time during SDL_AddHintCallback with the hint's
 | 
				
			||||||
 | 
					 * current value, and then again each time the hint's value changes.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \param userdata what was passed as `userdata` to SDL_AddHintCallback().
 | 
					 * \param userdata what was passed as `userdata` to SDL_AddHintCallback().
 | 
				
			||||||
 * \param name what was passed as `name` to SDL_AddHintCallback().
 | 
					 * \param name what was passed as `name` to SDL_AddHintCallback().
 | 
				
			||||||
 * \param oldValue the previous hint value.
 | 
					 * \param oldValue the previous hint value.
 | 
				
			||||||
 * \param newValue the new value hint is to be set to.
 | 
					 * \param newValue the new value hint is to be set to.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * \threadsafety This callback is fired from whatever thread is setting a
 | 
				
			||||||
 | 
					 *               new hint value. SDL holds a lock on the hint subsystem when
 | 
				
			||||||
 | 
					 *               calling this callback.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * \since This datatype is available since SDL 3.0.0.
 | 
					 * \since This datatype is available since SDL 3.0.0.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * \sa SDL_AddHintCallback
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
typedef void (SDLCALL *SDL_HintCallback)(void *userdata, const char *name, const char *oldValue, const char *newValue);
 | 
					typedef void (SDLCALL *SDL_HintCallback)(void *userdata, const char *name, const char *oldValue, const char *newValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Add a function to watch a particular hint.
 | 
					 * Add a function to watch a particular hint.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * The callback function is called _during_ this function, to provide it an
 | 
				
			||||||
 | 
					 * initial value, and again each time the hint's value changes.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * \param name the hint to watch.
 | 
					 * \param name the hint to watch.
 | 
				
			||||||
 * \param callback an SDL_HintCallback function that will be called when the
 | 
					 * \param callback An SDL_HintCallback function that will be called when the
 | 
				
			||||||
 *                 hint value changes.
 | 
					 *                 hint value changes.
 | 
				
			||||||
 * \param userdata a pointer to pass to the callback function.
 | 
					 * \param userdata a pointer to pass to the callback function.
 | 
				
			||||||
 * \returns 0 on success or a negative error code on failure; call
 | 
					 * \returns 0 on success or a negative error code on failure; call
 | 
				
			||||||
 *          SDL_GetError() for more information.
 | 
					 *          SDL_GetError() for more information.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \threadsafety It is **NOT** safe to call this function from two threads at
 | 
					 * \threadsafety It is safe to call this function from any thread.
 | 
				
			||||||
 *               once.
 | 
					 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \since This function is available since SDL 3.0.0.
 | 
					 * \since This function is available since SDL 3.0.0.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \sa SDL_DelHintCallback
 | 
					 * \sa SDL_DelHintCallback
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
extern SDL_DECLSPEC int SDLCALL SDL_AddHintCallback(const char *name,
 | 
					extern SDL_DECLSPEC int SDLCALL SDL_AddHintCallback(const char *name,
 | 
				
			||||||
                                                SDL_HintCallback callback,
 | 
					                                                    SDL_HintCallback callback,
 | 
				
			||||||
                                                void *userdata);
 | 
					                                                    void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Remove a function watching a particular hint.
 | 
					 * Remove a function watching a particular hint.
 | 
				
			||||||
@@ -4264,13 +4273,15 @@ extern SDL_DECLSPEC int SDLCALL SDL_AddHintCallback(const char *name,
 | 
				
			|||||||
 *                 hint value changes.
 | 
					 *                 hint value changes.
 | 
				
			||||||
 * \param userdata a pointer being passed to the callback function.
 | 
					 * \param userdata a pointer being passed to the callback function.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * \threadsafety It is safe to call this function from any thread.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * \since This function is available since SDL 3.0.0.
 | 
					 * \since This function is available since SDL 3.0.0.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * \sa SDL_AddHintCallback
 | 
					 * \sa SDL_AddHintCallback
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
extern SDL_DECLSPEC void SDLCALL SDL_DelHintCallback(const char *name,
 | 
					extern SDL_DECLSPEC void SDLCALL SDL_DelHintCallback(const char *name,
 | 
				
			||||||
                                                 SDL_HintCallback callback,
 | 
					                                                     SDL_HintCallback callback,
 | 
				
			||||||
                                                 void *userdata);
 | 
					                                                     void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Ends C function definitions when using C++ */
 | 
					/* Ends C function definitions when using C++ */
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -255,10 +255,12 @@ void SDL_InitMainThread(void)
 | 
				
			|||||||
    SDL_InitLog();
 | 
					    SDL_InitLog();
 | 
				
			||||||
    SDL_InitProperties();
 | 
					    SDL_InitProperties();
 | 
				
			||||||
    SDL_GetGlobalProperties();
 | 
					    SDL_GetGlobalProperties();
 | 
				
			||||||
 | 
					    SDL_InitHints();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void SDL_QuitMainThread(void)
 | 
					static void SDL_QuitMainThread(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    SDL_QuitHints();
 | 
				
			||||||
    SDL_QuitProperties();
 | 
					    SDL_QuitProperties();
 | 
				
			||||||
    SDL_QuitLog();
 | 
					    SDL_QuitLog();
 | 
				
			||||||
    SDL_QuitFilesystem();
 | 
					    SDL_QuitFilesystem();
 | 
				
			||||||
@@ -623,7 +625,6 @@ void SDL_Quit(void)
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SDL_SetObjectsInvalid();
 | 
					    SDL_SetObjectsInvalid();
 | 
				
			||||||
    SDL_ClearHints();
 | 
					 | 
				
			||||||
    SDL_AssertionsQuit();
 | 
					    SDL_AssertionsQuit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SDL_QuitPixelFormatDetails();
 | 
					    SDL_QuitPixelFormatDetails();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										336
									
								
								src/SDL_hints.c
									
									
									
									
									
								
							
							
						
						
									
										336
									
								
								src/SDL_hints.c
									
									
									
									
									
								
							@@ -22,9 +22,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "SDL_hints_c.h"
 | 
					#include "SDL_hints_c.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Assuming there aren't many hints set and they aren't being queried in
 | 
					 | 
				
			||||||
   critical performance paths, we'll just use linked lists here.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
typedef struct SDL_HintWatch
 | 
					typedef struct SDL_HintWatch
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SDL_HintCallback callback;
 | 
					    SDL_HintCallback callback;
 | 
				
			||||||
@@ -34,42 +31,71 @@ typedef struct SDL_HintWatch
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct SDL_Hint
 | 
					typedef struct SDL_Hint
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char *name;
 | 
					 | 
				
			||||||
    char *value;
 | 
					    char *value;
 | 
				
			||||||
    SDL_HintPriority priority;
 | 
					    SDL_HintPriority priority;
 | 
				
			||||||
    SDL_HintWatch *callbacks;
 | 
					    SDL_HintWatch *callbacks;
 | 
				
			||||||
    struct SDL_Hint *next;
 | 
					 | 
				
			||||||
} SDL_Hint;
 | 
					} SDL_Hint;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static SDL_Hint *SDL_hints;
 | 
					static SDL_PropertiesID SDL_hint_props = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SDL_bool SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPriority priority)
 | 
					static SDL_PropertiesID GetHintProperties(SDL_bool create)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const char *env;
 | 
					    if (!SDL_hint_props && create) {
 | 
				
			||||||
    SDL_Hint *hint;
 | 
					        SDL_hint_props = SDL_CreateProperties();
 | 
				
			||||||
    SDL_HintWatch *entry;
 | 
					    }
 | 
				
			||||||
 | 
					    return SDL_hint_props;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!name) {
 | 
					void SDL_InitHints(void)
 | 
				
			||||||
        return SDL_FALSE;
 | 
					{
 | 
				
			||||||
 | 
					    // Just make sure the hint properties are created on the main thread
 | 
				
			||||||
 | 
					    (void)GetHintProperties(SDL_TRUE);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void SDLCALL CleanupHintProperty(void *userdata, void *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SDL_Hint *hint = (SDL_Hint *) value;
 | 
				
			||||||
 | 
					    SDL_free(hint->value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SDL_HintWatch *entry = hint->callbacks;
 | 
				
			||||||
 | 
					    while (entry) {
 | 
				
			||||||
 | 
					        SDL_HintWatch *freeable = entry;
 | 
				
			||||||
 | 
					        entry = entry->next;
 | 
				
			||||||
 | 
					        SDL_free(freeable);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    SDL_free(hint);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPriority priority)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!name || !*name) {
 | 
				
			||||||
 | 
					        return SDL_InvalidParamError("name");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    env = SDL_getenv(name);
 | 
					    const char *env = SDL_getenv(name);
 | 
				
			||||||
    if (env && priority < SDL_HINT_OVERRIDE) {
 | 
					    if (env && (priority < SDL_HINT_OVERRIDE)) {
 | 
				
			||||||
        return SDL_FALSE;
 | 
					        return SDL_SetError("An environment variable is taking priority");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (hint = SDL_hints; hint; hint = hint->next) {
 | 
					    const SDL_PropertiesID hints = GetHintProperties(SDL_TRUE);
 | 
				
			||||||
        if (SDL_strcmp(name, hint->name) == 0) {
 | 
					    if (!hints) {
 | 
				
			||||||
            if (priority < hint->priority) {
 | 
					        return -1;
 | 
				
			||||||
                return SDL_FALSE;
 | 
					    }
 | 
				
			||||||
            }
 | 
					
 | 
				
			||||||
            if (hint->value != value &&
 | 
					    int retval = -1;
 | 
				
			||||||
                (!value || !hint->value || SDL_strcmp(hint->value, value) != 0)) {
 | 
					
 | 
				
			||||||
 | 
					    SDL_LockProperties(hints);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SDL_Hint *hint = SDL_GetPointerProperty(hints, name, NULL);
 | 
				
			||||||
 | 
					    if (hint) {
 | 
				
			||||||
 | 
					        if (priority >= hint->priority) {
 | 
				
			||||||
 | 
					            if (hint->value != value && (!value || !hint->value || SDL_strcmp(hint->value, value) != 0)) {
 | 
				
			||||||
                char *old_value = hint->value;
 | 
					                char *old_value = hint->value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                hint->value = value ? SDL_strdup(value) : NULL;
 | 
					                hint->value = value ? SDL_strdup(value) : NULL;
 | 
				
			||||||
                for (entry = hint->callbacks; entry;) {
 | 
					                SDL_HintWatch *entry = hint->callbacks;
 | 
				
			||||||
                    /* Save the next entry in case this one is deleted */
 | 
					                while (entry) {
 | 
				
			||||||
 | 
					                    // Save the next entry in case this one is deleted
 | 
				
			||||||
                    SDL_HintWatch *next = entry->next;
 | 
					                    SDL_HintWatch *next = entry->next;
 | 
				
			||||||
                    entry->callback(entry->userdata, name, old_value, value);
 | 
					                    entry->callback(entry->userdata, name, old_value, value);
 | 
				
			||||||
                    entry = next;
 | 
					                    entry = next;
 | 
				
			||||||
@@ -77,104 +103,118 @@ SDL_bool SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPr
 | 
				
			|||||||
                SDL_free(old_value);
 | 
					                SDL_free(old_value);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            hint->priority = priority;
 | 
					            hint->priority = priority;
 | 
				
			||||||
            return SDL_TRUE;
 | 
					            retval = 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else {  // Couldn't find the hint? Add a new one.
 | 
				
			||||||
 | 
					        hint = (SDL_Hint *)SDL_malloc(sizeof(*hint));
 | 
				
			||||||
 | 
					        if (hint) {
 | 
				
			||||||
 | 
					            hint->value = value ? SDL_strdup(value) : NULL;
 | 
				
			||||||
 | 
					            hint->priority = priority;
 | 
				
			||||||
 | 
					            hint->callbacks = NULL;
 | 
				
			||||||
 | 
					            retval = (SDL_SetPointerPropertyWithCleanup(hints, name, hint, CleanupHintProperty, NULL) != -1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Couldn't find the hint, add a new one */
 | 
					    SDL_UnlockProperties(hints);
 | 
				
			||||||
    hint = (SDL_Hint *)SDL_malloc(sizeof(*hint));
 | 
					
 | 
				
			||||||
    if (!hint) {
 | 
					    return retval;
 | 
				
			||||||
        return SDL_FALSE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    hint->name = SDL_strdup(name);
 | 
					 | 
				
			||||||
    hint->value = value ? SDL_strdup(value) : NULL;
 | 
					 | 
				
			||||||
    hint->priority = priority;
 | 
					 | 
				
			||||||
    hint->callbacks = NULL;
 | 
					 | 
				
			||||||
    hint->next = SDL_hints;
 | 
					 | 
				
			||||||
    SDL_hints = hint;
 | 
					 | 
				
			||||||
    return SDL_TRUE;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SDL_bool SDL_ResetHint(const char *name)
 | 
					int SDL_ResetHint(const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const char *env;
 | 
					    if (!name || !*name) {
 | 
				
			||||||
    SDL_Hint *hint;
 | 
					        return SDL_InvalidParamError("name");
 | 
				
			||||||
    SDL_HintWatch *entry;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!name) {
 | 
					 | 
				
			||||||
        return SDL_FALSE;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    env = SDL_getenv(name);
 | 
					    const char *env = SDL_getenv(name);
 | 
				
			||||||
    for (hint = SDL_hints; hint; hint = hint->next) {
 | 
					
 | 
				
			||||||
        if (SDL_strcmp(name, hint->name) == 0) {
 | 
					    const SDL_PropertiesID hints = GetHintProperties(SDL_FALSE);
 | 
				
			||||||
            if ((!env && hint->value) ||
 | 
					    if (!hints) {
 | 
				
			||||||
                (env && !hint->value) ||
 | 
					        return -1;
 | 
				
			||||||
                (env && SDL_strcmp(env, hint->value) != 0)) {
 | 
					 | 
				
			||||||
                for (entry = hint->callbacks; entry;) {
 | 
					 | 
				
			||||||
                    /* Save the next entry in case this one is deleted */
 | 
					 | 
				
			||||||
                    SDL_HintWatch *next = entry->next;
 | 
					 | 
				
			||||||
                    entry->callback(entry->userdata, name, hint->value, env);
 | 
					 | 
				
			||||||
                    entry = next;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            SDL_free(hint->value);
 | 
					 | 
				
			||||||
            hint->value = NULL;
 | 
					 | 
				
			||||||
            hint->priority = SDL_HINT_DEFAULT;
 | 
					 | 
				
			||||||
            return SDL_TRUE;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return SDL_FALSE;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SDL_ResetHints(void)
 | 
					    int retval = -1;
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    const char *env;
 | 
					 | 
				
			||||||
    SDL_Hint *hint;
 | 
					 | 
				
			||||||
    SDL_HintWatch *entry;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (hint = SDL_hints; hint; hint = hint->next) {
 | 
					    SDL_LockProperties(hints);
 | 
				
			||||||
        env = SDL_getenv(hint->name);
 | 
					
 | 
				
			||||||
        if ((!env && hint->value) ||
 | 
					    SDL_Hint *hint = SDL_GetPointerProperty(hints, name, NULL);
 | 
				
			||||||
            (env && !hint->value) ||
 | 
					    if (hint) {
 | 
				
			||||||
            (env && SDL_strcmp(env, hint->value) != 0)) {
 | 
					        if ((!env && hint->value) || (env && !hint->value) || (env && SDL_strcmp(env, hint->value) != 0)) {
 | 
				
			||||||
            for (entry = hint->callbacks; entry;) {
 | 
					            for (SDL_HintWatch *entry = hint->callbacks; entry;) {
 | 
				
			||||||
                /* Save the next entry in case this one is deleted */
 | 
					                // Save the next entry in case this one is deleted
 | 
				
			||||||
                SDL_HintWatch *next = entry->next;
 | 
					                SDL_HintWatch *next = entry->next;
 | 
				
			||||||
                entry->callback(entry->userdata, hint->name, hint->value, env);
 | 
					                entry->callback(entry->userdata, name, hint->value, env);
 | 
				
			||||||
                entry = next;
 | 
					                entry = next;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        SDL_free(hint->value);
 | 
					        SDL_free(hint->value);
 | 
				
			||||||
        hint->value = NULL;
 | 
					        hint->value = NULL;
 | 
				
			||||||
        hint->priority = SDL_HINT_DEFAULT;
 | 
					        hint->priority = SDL_HINT_DEFAULT;
 | 
				
			||||||
 | 
					        retval = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SDL_UnlockProperties(hints);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return retval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SDL_bool SDL_SetHint(const char *name, const char *value)
 | 
					static void SDLCALL ResetHintsCallback(void *userdata, SDL_PropertiesID hints, const char *name)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SDL_Hint *hint = SDL_GetPointerProperty(hints, name, NULL);
 | 
				
			||||||
 | 
					    if (!hint) {
 | 
				
			||||||
 | 
					        return;  // uh...okay.
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const char *env = SDL_getenv(name);
 | 
				
			||||||
 | 
					    if ((!env && hint->value) || (env && !hint->value) || (env && SDL_strcmp(env, hint->value) != 0)) {
 | 
				
			||||||
 | 
					        SDL_HintWatch *entry = hint->callbacks;
 | 
				
			||||||
 | 
					        while (entry) {
 | 
				
			||||||
 | 
					            // Save the next entry in case this one is deleted
 | 
				
			||||||
 | 
					            SDL_HintWatch *next = entry->next;
 | 
				
			||||||
 | 
					            entry->callback(entry->userdata, name, hint->value, env);
 | 
				
			||||||
 | 
					            entry = next;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    SDL_free(hint->value);
 | 
				
			||||||
 | 
					    hint->value = NULL;
 | 
				
			||||||
 | 
					    hint->priority = SDL_HINT_DEFAULT;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SDL_ResetHints(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SDL_EnumerateProperties(GetHintProperties(SDL_FALSE), ResetHintsCallback, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SDL_SetHint(const char *name, const char *value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return SDL_SetHintWithPriority(name, value, SDL_HINT_NORMAL);
 | 
					    return SDL_SetHintWithPriority(name, value, SDL_HINT_NORMAL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char *SDL_GetHint(const char *name)
 | 
					const char *SDL_GetHint(const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    const char *env;
 | 
					 | 
				
			||||||
    SDL_Hint *hint;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!name) {
 | 
					    if (!name) {
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    env = SDL_getenv(name);
 | 
					    const SDL_PropertiesID hints = GetHintProperties(SDL_FALSE);
 | 
				
			||||||
    for (hint = SDL_hints; hint; hint = hint->next) {
 | 
					    if (!hints) {
 | 
				
			||||||
        if (SDL_strcmp(name, hint->name) == 0) {
 | 
					        return NULL;
 | 
				
			||||||
            if (!env || hint->priority == SDL_HINT_OVERRIDE) {
 | 
					    }
 | 
				
			||||||
                return SDL_GetPersistentString(hint->value);
 | 
					
 | 
				
			||||||
            }
 | 
					    const char *retval = SDL_getenv(name);
 | 
				
			||||||
            break;
 | 
					
 | 
				
			||||||
 | 
					    SDL_LockProperties(hints);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SDL_Hint *hint = SDL_GetPointerProperty(hints, name, NULL);
 | 
				
			||||||
 | 
					    if (hint) {
 | 
				
			||||||
 | 
					        if (!retval || hint->priority == SDL_HINT_OVERRIDE) {
 | 
				
			||||||
 | 
					            retval = SDL_GetPersistentString(hint->value);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return env;
 | 
					
 | 
				
			||||||
 | 
					    SDL_UnlockProperties(hints);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return retval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int SDL_GetStringInteger(const char *value, int default_value)
 | 
					int SDL_GetStringInteger(const char *value, int default_value)
 | 
				
			||||||
@@ -213,102 +253,92 @@ SDL_bool SDL_GetHintBoolean(const char *name, SDL_bool default_value)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
 | 
					int SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SDL_Hint *hint;
 | 
					 | 
				
			||||||
    SDL_HintWatch *entry;
 | 
					 | 
				
			||||||
    const char *value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!name || !*name) {
 | 
					    if (!name || !*name) {
 | 
				
			||||||
        return SDL_InvalidParamError("name");
 | 
					        return SDL_InvalidParamError("name");
 | 
				
			||||||
    }
 | 
					    } else if (!callback) {
 | 
				
			||||||
    if (!callback) {
 | 
					 | 
				
			||||||
        return SDL_InvalidParamError("callback");
 | 
					        return SDL_InvalidParamError("callback");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SDL_DelHintCallback(name, callback, userdata);
 | 
					    const SDL_PropertiesID hints = GetHintProperties(SDL_TRUE);
 | 
				
			||||||
 | 
					    if (!hints) {
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    entry = (SDL_HintWatch *)SDL_malloc(sizeof(*entry));
 | 
					    SDL_HintWatch *entry = (SDL_HintWatch *)SDL_malloc(sizeof(*entry));
 | 
				
			||||||
    if (!entry) {
 | 
					    if (!entry) {
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    entry->callback = callback;
 | 
					    entry->callback = callback;
 | 
				
			||||||
    entry->userdata = userdata;
 | 
					    entry->userdata = userdata;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (hint = SDL_hints; hint; hint = hint->next) {
 | 
					    int retval = -1;
 | 
				
			||||||
        if (SDL_strcmp(name, hint->name) == 0) {
 | 
					
 | 
				
			||||||
            break;
 | 
					    SDL_LockProperties(hints);
 | 
				
			||||||
        }
 | 
					
 | 
				
			||||||
    }
 | 
					    SDL_DelHintCallback(name, callback, userdata);
 | 
				
			||||||
    if (!hint) {
 | 
					
 | 
				
			||||||
        /* Need to add a hint entry for this watcher */
 | 
					    SDL_Hint *hint = SDL_GetPointerProperty(hints, name, NULL);
 | 
				
			||||||
 | 
					    if (hint) {
 | 
				
			||||||
 | 
					        retval = 0;
 | 
				
			||||||
 | 
					    } else {  // Need to add a hint entry for this watcher
 | 
				
			||||||
        hint = (SDL_Hint *)SDL_malloc(sizeof(*hint));
 | 
					        hint = (SDL_Hint *)SDL_malloc(sizeof(*hint));
 | 
				
			||||||
        if (!hint) {
 | 
					        if (!hint) {
 | 
				
			||||||
            SDL_free(entry);
 | 
					            SDL_free(entry);
 | 
				
			||||||
            return -1;
 | 
					        } else {
 | 
				
			||||||
 | 
					            hint->value = NULL;
 | 
				
			||||||
 | 
					            hint->priority = SDL_HINT_DEFAULT;
 | 
				
			||||||
 | 
					            hint->callbacks = NULL;
 | 
				
			||||||
 | 
					            retval = SDL_SetPointerPropertyWithCleanup(hints, name, hint, CleanupHintProperty, NULL);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        hint->name = SDL_strdup(name);
 | 
					 | 
				
			||||||
        if (!hint->name) {
 | 
					 | 
				
			||||||
            SDL_free(entry);
 | 
					 | 
				
			||||||
            SDL_free(hint);
 | 
					 | 
				
			||||||
            return -1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        hint->value = NULL;
 | 
					 | 
				
			||||||
        hint->priority = SDL_HINT_DEFAULT;
 | 
					 | 
				
			||||||
        hint->callbacks = NULL;
 | 
					 | 
				
			||||||
        hint->next = SDL_hints;
 | 
					 | 
				
			||||||
        SDL_hints = hint;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Add it to the callbacks for this hint */
 | 
					    // Add it to the callbacks for this hint
 | 
				
			||||||
    entry->next = hint->callbacks;
 | 
					    entry->next = hint->callbacks;
 | 
				
			||||||
    hint->callbacks = entry;
 | 
					    hint->callbacks = entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Now call it with the current value */
 | 
					    // Now call it with the current value
 | 
				
			||||||
    value = SDL_GetHint(name);
 | 
					    const char *value = SDL_GetHint(name);
 | 
				
			||||||
    callback(userdata, name, value, value);
 | 
					    callback(userdata, name, value, value);
 | 
				
			||||||
    return 0;
 | 
					
 | 
				
			||||||
 | 
					    SDL_UnlockProperties(hints);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return retval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SDL_DelHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
 | 
					void SDL_DelHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SDL_Hint *hint;
 | 
					    if (!name || !*name) {
 | 
				
			||||||
    SDL_HintWatch *entry, *prev;
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (hint = SDL_hints; hint; hint = hint->next) {
 | 
					    const SDL_PropertiesID hints = GetHintProperties(SDL_FALSE);
 | 
				
			||||||
        if (SDL_strcmp(name, hint->name) == 0) {
 | 
					    if (!hints) {
 | 
				
			||||||
            prev = NULL;
 | 
					        return;
 | 
				
			||||||
            for (entry = hint->callbacks; entry; entry = entry->next) {
 | 
					    }
 | 
				
			||||||
                if (callback == entry->callback && userdata == entry->userdata) {
 | 
					
 | 
				
			||||||
                    if (prev) {
 | 
					    SDL_LockProperties(hints);
 | 
				
			||||||
                        prev->next = entry->next;
 | 
					    SDL_Hint *hint = SDL_GetPointerProperty(hints, name, NULL);
 | 
				
			||||||
                    } else {
 | 
					    if (hint) {
 | 
				
			||||||
                        hint->callbacks = entry->next;
 | 
					        SDL_HintWatch *prev = NULL;
 | 
				
			||||||
                    }
 | 
					        for (SDL_HintWatch *entry = hint->callbacks; entry; entry = entry->next) {
 | 
				
			||||||
                    SDL_free(entry);
 | 
					            if ((callback == entry->callback) && (userdata == entry->userdata)) {
 | 
				
			||||||
                    break;
 | 
					                if (prev) {
 | 
				
			||||||
 | 
					                    prev->next = entry->next;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    hint->callbacks = entry->next;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                prev = entry;
 | 
					                SDL_free(entry);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return;
 | 
					            prev = entry;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    SDL_UnlockProperties(hints);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SDL_ClearHints(void)
 | 
					void SDL_QuitHints(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SDL_Hint *hint;
 | 
					    SDL_DestroyProperties(SDL_hint_props);
 | 
				
			||||||
    SDL_HintWatch *entry;
 | 
					    SDL_hint_props = 0;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    while (SDL_hints) {
 | 
					 | 
				
			||||||
        hint = SDL_hints;
 | 
					 | 
				
			||||||
        SDL_hints = hint->next;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SDL_free(hint->name);
 | 
					 | 
				
			||||||
        SDL_free(hint->value);
 | 
					 | 
				
			||||||
        for (entry = hint->callbacks; entry;) {
 | 
					 | 
				
			||||||
            SDL_HintWatch *freeable = entry;
 | 
					 | 
				
			||||||
            entry = entry->next;
 | 
					 | 
				
			||||||
            SDL_free(freeable);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        SDL_free(hint);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,8 +25,9 @@
 | 
				
			|||||||
#ifndef SDL_hints_c_h_
 | 
					#ifndef SDL_hints_c_h_
 | 
				
			||||||
#define SDL_hints_c_h_
 | 
					#define SDL_hints_c_h_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern void SDL_InitHints(void);
 | 
				
			||||||
extern SDL_bool SDL_GetStringBoolean(const char *value, SDL_bool default_value);
 | 
					extern SDL_bool SDL_GetStringBoolean(const char *value, SDL_bool default_value);
 | 
				
			||||||
extern int SDL_GetStringInteger(const char *value, int default_value);
 | 
					extern int SDL_GetStringInteger(const char *value, int default_value);
 | 
				
			||||||
extern void SDL_ClearHints(void);
 | 
					extern void SDL_QuitHints(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* SDL_hints_c_h_ */
 | 
					#endif /* SDL_hints_c_h_ */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -711,7 +711,7 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_RenderViewportSet,(SDL_Renderer *a),(a),return)
 | 
				
			|||||||
SDL_DYNAPI_PROC(SDL_AssertState,SDL_ReportAssertion,(SDL_AssertData *a, const char *b, const char *c, int d),(a,b,c,d),return)
 | 
					SDL_DYNAPI_PROC(SDL_AssertState,SDL_ReportAssertion,(SDL_AssertData *a, const char *b, const char *c, int d),(a,b,c,d),return)
 | 
				
			||||||
SDL_DYNAPI_PROC(int,SDL_RequestAndroidPermission,(const char *a, SDL_RequestAndroidPermissionCallback b, void *c),(a,b,c),return)
 | 
					SDL_DYNAPI_PROC(int,SDL_RequestAndroidPermission,(const char *a, SDL_RequestAndroidPermissionCallback b, void *c),(a,b,c),return)
 | 
				
			||||||
SDL_DYNAPI_PROC(void,SDL_ResetAssertionReport,(void),(),)
 | 
					SDL_DYNAPI_PROC(void,SDL_ResetAssertionReport,(void),(),)
 | 
				
			||||||
SDL_DYNAPI_PROC(SDL_bool,SDL_ResetHint,(const char *a),(a),return)
 | 
					SDL_DYNAPI_PROC(int,SDL_ResetHint,(const char *a),(a),return)
 | 
				
			||||||
SDL_DYNAPI_PROC(void,SDL_ResetHints,(void),(),)
 | 
					SDL_DYNAPI_PROC(void,SDL_ResetHints,(void),(),)
 | 
				
			||||||
SDL_DYNAPI_PROC(void,SDL_ResetKeyboard,(void),(),)
 | 
					SDL_DYNAPI_PROC(void,SDL_ResetKeyboard,(void),(),)
 | 
				
			||||||
SDL_DYNAPI_PROC(void,SDL_ResetLogPriorities,(void),(),)
 | 
					SDL_DYNAPI_PROC(void,SDL_ResetLogPriorities,(void),(),)
 | 
				
			||||||
@@ -762,8 +762,8 @@ SDL_DYNAPI_PROC(int,SDL_SetGamepadPlayerIndex,(SDL_Gamepad *a, int b),(a,b),retu
 | 
				
			|||||||
SDL_DYNAPI_PROC(int,SDL_SetGamepadSensorEnabled,(SDL_Gamepad *a, SDL_SensorType b, SDL_bool c),(a,b,c),return)
 | 
					SDL_DYNAPI_PROC(int,SDL_SetGamepadSensorEnabled,(SDL_Gamepad *a, SDL_SensorType b, SDL_bool c),(a,b,c),return)
 | 
				
			||||||
SDL_DYNAPI_PROC(int,SDL_SetHapticAutocenter,(SDL_Haptic *a, int b),(a,b),return)
 | 
					SDL_DYNAPI_PROC(int,SDL_SetHapticAutocenter,(SDL_Haptic *a, int b),(a,b),return)
 | 
				
			||||||
SDL_DYNAPI_PROC(int,SDL_SetHapticGain,(SDL_Haptic *a, int b),(a,b),return)
 | 
					SDL_DYNAPI_PROC(int,SDL_SetHapticGain,(SDL_Haptic *a, int b),(a,b),return)
 | 
				
			||||||
SDL_DYNAPI_PROC(SDL_bool,SDL_SetHint,(const char *a, const char *b),(a,b),return)
 | 
					SDL_DYNAPI_PROC(int,SDL_SetHint,(const char *a, const char *b),(a,b),return)
 | 
				
			||||||
SDL_DYNAPI_PROC(SDL_bool,SDL_SetHintWithPriority,(const char *a, const char *b, SDL_HintPriority c),(a,b,c),return)
 | 
					SDL_DYNAPI_PROC(int,SDL_SetHintWithPriority,(const char *a, const char *b, SDL_HintPriority c),(a,b,c),return)
 | 
				
			||||||
SDL_DYNAPI_PROC(void,SDL_SetJoystickEventsEnabled,(SDL_bool a),(a),)
 | 
					SDL_DYNAPI_PROC(void,SDL_SetJoystickEventsEnabled,(SDL_bool a),(a),)
 | 
				
			||||||
SDL_DYNAPI_PROC(int,SDL_SetJoystickLED,(SDL_Joystick *a, Uint8 b, Uint8 c, Uint8 d),(a,b,c,d),return)
 | 
					SDL_DYNAPI_PROC(int,SDL_SetJoystickLED,(SDL_Joystick *a, Uint8 b, Uint8 c, Uint8 d),(a,b,c,d),return)
 | 
				
			||||||
SDL_DYNAPI_PROC(int,SDL_SetJoystickPlayerIndex,(SDL_Joystick *a, int b),(a,b),return)
 | 
					SDL_DYNAPI_PROC(int,SDL_SetJoystickPlayerIndex,(SDL_Joystick *a, int b),(a,b),return)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -194,29 +194,25 @@ static const SDL_mutex_impl_t SDL_mutex_impl_cs = {
 | 
				
			|||||||
SDL_Mutex *SDL_CreateMutex(void)
 | 
					SDL_Mutex *SDL_CreateMutex(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (!SDL_mutex_impl_active.Create) {
 | 
					    if (!SDL_mutex_impl_active.Create) {
 | 
				
			||||||
        // Default to fallback implementation
 | 
					#ifdef SDL_PLATFORM_WINRT
 | 
				
			||||||
 | 
					        const SDL_mutex_impl_t *impl = &SDL_mutex_impl_srw;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
        const SDL_mutex_impl_t *impl = &SDL_mutex_impl_cs;
 | 
					        const SDL_mutex_impl_t *impl = &SDL_mutex_impl_cs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!SDL_GetHintBoolean(SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS, SDL_FALSE)) {
 | 
					        // Try faster implementation for Windows 7 and newer
 | 
				
			||||||
#ifdef SDL_PLATFORM_WINRT
 | 
					        HMODULE kernel32 = GetModuleHandle(TEXT("kernel32.dll"));
 | 
				
			||||||
            // Link statically on this platform
 | 
					        if (kernel32) {
 | 
				
			||||||
            impl = &SDL_mutex_impl_srw;
 | 
					            // Requires Vista:
 | 
				
			||||||
#else
 | 
					            pInitializeSRWLock = (pfnInitializeSRWLock)GetProcAddress(kernel32, "InitializeSRWLock");
 | 
				
			||||||
            // Try faster implementation for Windows 7 and newer
 | 
					            pReleaseSRWLockExclusive = (pfnReleaseSRWLockExclusive)GetProcAddress(kernel32, "ReleaseSRWLockExclusive");
 | 
				
			||||||
            HMODULE kernel32 = GetModuleHandle(TEXT("kernel32.dll"));
 | 
					            pAcquireSRWLockExclusive = (pfnAcquireSRWLockExclusive)GetProcAddress(kernel32, "AcquireSRWLockExclusive");
 | 
				
			||||||
            if (kernel32) {
 | 
					            // Requires 7:
 | 
				
			||||||
                // Requires Vista:
 | 
					            pTryAcquireSRWLockExclusive = (pfnTryAcquireSRWLockExclusive)GetProcAddress(kernel32, "TryAcquireSRWLockExclusive");
 | 
				
			||||||
                pInitializeSRWLock = (pfnInitializeSRWLock)GetProcAddress(kernel32, "InitializeSRWLock");
 | 
					            if (pInitializeSRWLock && pReleaseSRWLockExclusive && pAcquireSRWLockExclusive && pTryAcquireSRWLockExclusive) {
 | 
				
			||||||
                pReleaseSRWLockExclusive = (pfnReleaseSRWLockExclusive)GetProcAddress(kernel32, "ReleaseSRWLockExclusive");
 | 
					                impl = &SDL_mutex_impl_srw;
 | 
				
			||||||
                pAcquireSRWLockExclusive = (pfnAcquireSRWLockExclusive)GetProcAddress(kernel32, "AcquireSRWLockExclusive");
 | 
					 | 
				
			||||||
                // Requires 7:
 | 
					 | 
				
			||||||
                pTryAcquireSRWLockExclusive = (pfnTryAcquireSRWLockExclusive)GetProcAddress(kernel32, "TryAcquireSRWLockExclusive");
 | 
					 | 
				
			||||||
                if (pInitializeSRWLock && pReleaseSRWLockExclusive && pAcquireSRWLockExclusive && pTryAcquireSRWLockExclusive) {
 | 
					 | 
				
			||||||
                    impl = &SDL_mutex_impl_srw;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					#endif // SDL_PLATFORM_WINRT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Copy instead of using pointer to save one level of indirection
 | 
					        // Copy instead of using pointer to save one level of indirection
 | 
				
			||||||
        SDL_copyp(&SDL_mutex_impl_active, impl);
 | 
					        SDL_copyp(&SDL_mutex_impl_active, impl);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user