Added SDL_ResetHint() to reset a hint to the default value Resolves question of how to clear an override hint raised by @pionere in https://github.com/libsdl-org/SDL/pull/5309
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
diff --git a/WhatsNew.txt b/WhatsNew.txt
index feb4aac..8997d0b 100644
--- a/WhatsNew.txt
+++ b/WhatsNew.txt
@@ -20,6 +20,7 @@ General:
the SDL 2.24.0 stable release.
* Added SDL_bsearch() and SDL_utf8strnlen() to the stdlib routines
* Added SDL_size_mul_overflow() and SDL_size_add_overflow() for better size overflow protection
+* Added SDL_ResetHint() to reset a hint to the default value
* The hint SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS now defaults on
* Added support for mini-gamepad mode for Nintendo Joy-Con controllers using the HIDAPI driver
* Added the hint SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS to control whether Joy-Con controllers are automatically merged into a unified gamepad when using the HIDAPI driver. This hint defaults on.
diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index 02d5fc5..2c7a33a 100644
--- a/include/SDL_hints.h
+++ b/include/SDL_hints.h
@@ -2287,6 +2287,23 @@ extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name,
const char *value);
/**
+ * Reset a hint to the default value.
+ *
+ * This will reset a hint to the value of the environment variable, or NULL
+ * if the environment isn't set. Callbacks will be called normally with
+ * this change.
+ *
+ * \param name the hint to set
+ * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 2.24.0.
+ *
+ * \sa SDL_GetHint
+ * \sa SDL_SetHint
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_ResetHint(const char *name);
+
+/**
* Get the value of a hint.
*
* \param name the hint to query
diff --git a/src/SDL_hints.c b/src/SDL_hints.c
index 423851a..93bcc47 100644
--- a/src/SDL_hints.c
+++ b/src/SDL_hints.c
@@ -97,6 +97,43 @@ SDL_SetHintWithPriority(const char *name, const char *value,
}
SDL_bool
+SDL_ResetHint(const char *name)
+{
+ const char *env;
+ SDL_Hint *hint, *prev;
+ SDL_HintWatch *entry;
+
+ if (!name) {
+ return SDL_FALSE;
+ }
+
+ env = SDL_getenv(name);
+ for (prev = NULL, hint = SDL_hints; hint; prev = hint, hint = hint->next) {
+ if (SDL_strcmp(name, hint->name) == 0) {
+ if ((env == NULL && hint->value != NULL) ||
+ (env != NULL && hint->value == NULL) ||
+ (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;
+ }
+ }
+ if (prev) {
+ prev->next = hint->next;
+ } else {
+ SDL_hints = hint->next;
+ }
+ SDL_free(hint->value);
+ SDL_free(hint);
+ return SDL_TRUE;
+ }
+ }
+ return SDL_FALSE;
+}
+
+SDL_bool
SDL_SetHint(const char *name, const char *value)
{
return SDL_SetHintWithPriority(name, value, SDL_HINT_NORMAL);
diff --git a/src/dynapi/SDL2.exports b/src/dynapi/SDL2.exports
index 80d15ee..c790e25 100644
--- a/src/dynapi/SDL2.exports
+++ b/src/dynapi/SDL2.exports
@@ -856,3 +856,4 @@
++'_SDL_GetDefaultAudioInfo'.'SDL2.dll'.'SDL_GetDefaultAudioInfo'
++'_SDL_GetPointDisplayIndex'.'SDL2.dll'.'SDL_GetPointDisplayIndex'
++'_SDL_GetRectDisplayIndex'.'SDL2.dll'.'SDL_GetRectDisplayIndex'
+++'_SDL_ResetHint'.'SDL2.dll'.'SDL_ResetHint'
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index 91f13c3..48c599b 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -882,3 +882,4 @@
#define SDL_GetDefaultAudioInfo SDL_GetDefaultAudioInfo_REAL
#define SDL_GetPointDisplayIndex SDL_GetPointDisplayIndex_REAL
#define SDL_GetRectDisplayIndex SDL_GetRectDisplayIndex_REAL
+#define SDL_ResetHint SDL_ResetHint_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index f23cdf7..1d2cbfe 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -965,3 +965,4 @@ SDL_DYNAPI_PROC(void,SDL_ResetKeyboard,(void),(),)
SDL_DYNAPI_PROC(int,SDL_GetDefaultAudioInfo,(char **a, SDL_AudioSpec *b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_GetPointDisplayIndex,(const SDL_Point *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GetRectDisplayIndex,(const SDL_Rect *a),(a),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_ResetHint,(const char *a),(a),return)
diff --git a/test/testautomation_hints.c b/test/testautomation_hints.c
index 91b8c02..bbcc9fd 100644
--- a/test/testautomation_hints.c
+++ b/test/testautomation_hints.c
@@ -98,8 +98,9 @@ hints_getHint(void *arg)
int
hints_setHint(void *arg)
{
+ const char *testHint = "SDL_AUTOMATED_TEST_HINT";
const char *originalValue;
- const char *value;
+ char *value;
const char *testValue;
SDL_bool result;
int i, j;
@@ -142,7 +143,54 @@ hints_setHint(void *arg)
SDL_free((void *)originalValue);
}
- SDL_free((void *)value);
+ SDL_free(value);
+
+ /* Set default value in environment */
+ SDL_setenv(testHint, "original", 1);
+
+ SDLTest_AssertPass("Call to SDL_GetHint() after saving and restoring hint");
+ originalValue = SDL_GetHint(testHint);
+ value = (originalValue == NULL) ? NULL : SDL_strdup(originalValue);
+ SDL_SetHint(testHint, "temp");
+ SDL_SetHint(testHint, value);
+ SDL_free(value);
+ testValue = SDL_GetHint(testHint);
+ SDLTest_AssertCheck(
+ testValue && SDL_strcmp(testValue, "original") == 0,
+ "testValue = %s, expected \"original\"",
+ testValue);
+
+ SDLTest_AssertPass("Call to SDL_SetHintWithPriority(NULL, SDL_HINT_DEFAULT)");
+ SDL_SetHintWithPriority(testHint, NULL, SDL_HINT_DEFAULT);
+ testValue = SDL_GetHint(testHint);
+ SDLTest_AssertCheck(
+ testValue && SDL_strcmp(testValue, "original") == 0,
+ "testValue = %s, expected \"original\"",
+ testValue);
+
+ SDLTest_AssertPass("Call to SDL_SetHintWithPriority(\"temp\", SDL_HINT_OVERRIDE)");
+ SDL_SetHintWithPriority(testHint, "temp", SDL_HINT_OVERRIDE);
+ testValue = SDL_GetHint(testHint);
+ SDLTest_AssertCheck(
+ testValue && SDL_strcmp(testValue, "temp") == 0,
+ "testValue = %s, expected \"temp\"",
+ testValue);
+
+ SDLTest_AssertPass("Call to SDL_SetHintWithPriority(NULL, SDL_HINT_OVERRIDE)");
+ SDL_SetHintWithPriority(testHint, NULL, SDL_HINT_OVERRIDE);
+ testValue = SDL_GetHint(testHint);
+ SDLTest_AssertCheck(
+ testValue == NULL,
+ "testValue = %s, expected NULL",
+ testValue);
+
+ SDLTest_AssertPass("Call to SDL_ResetHint()");
+ SDL_ResetHint(testHint);
+ testValue = SDL_GetHint(testHint);
+ SDLTest_AssertCheck(
+ testValue && SDL_strcmp(testValue, "original") == 0,
+ "testValue = %s, expected \"original\"",
+ testValue);
return TEST_COMPLETED;
}