Atlas - SDL_hints.c

Home / ext / SDL2 / src Lines: 1 | Size: 6437 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "./SDL_internal.h" 22 23#include "SDL_hints.h" 24#include "SDL_error.h" 25 26 27/* Assuming there aren't many hints set and they aren't being queried in 28 critical performance paths, we'll just use linked lists here. 29 */ 30typedef struct SDL_HintWatch { 31 SDL_HintCallback callback; 32 void *userdata; 33 struct SDL_HintWatch *next; 34} SDL_HintWatch; 35 36typedef struct SDL_Hint { 37 char *name; 38 char *value; 39 SDL_HintPriority priority; 40 SDL_HintWatch *callbacks; 41 struct SDL_Hint *next; 42} SDL_Hint; 43 44static SDL_Hint *SDL_hints; 45 46SDL_bool 47SDL_SetHintWithPriority(const char *name, const char *value, 48 SDL_HintPriority priority) 49{ 50 const char *env; 51 SDL_Hint *hint; 52 SDL_HintWatch *entry; 53 54 if (!name || !value) { 55 return SDL_FALSE; 56 } 57 58 env = SDL_getenv(name); 59 if (env && priority < SDL_HINT_OVERRIDE) { 60 return SDL_FALSE; 61 } 62 63 for (hint = SDL_hints; hint; hint = hint->next) { 64 if (SDL_strcmp(name, hint->name) == 0) { 65 if (priority < hint->priority) { 66 return SDL_FALSE; 67 } 68 if (!hint->value || !value || SDL_strcmp(hint->value, value) != 0) { 69 for (entry = hint->callbacks; entry; ) { 70 /* Save the next entry in case this one is deleted */ 71 SDL_HintWatch *next = entry->next; 72 entry->callback(entry->userdata, name, hint->value, value); 73 entry = next; 74 } 75 SDL_free(hint->value); 76 hint->value = value ? SDL_strdup(value) : NULL; 77 } 78 hint->priority = priority; 79 return SDL_TRUE; 80 } 81 } 82 83 /* Couldn't find the hint, add a new one */ 84 hint = (SDL_Hint *)SDL_malloc(sizeof(*hint)); 85 if (!hint) { 86 return SDL_FALSE; 87 } 88 hint->name = SDL_strdup(name); 89 hint->value = value ? SDL_strdup(value) : NULL; 90 hint->priority = priority; 91 hint->callbacks = NULL; 92 hint->next = SDL_hints; 93 SDL_hints = hint; 94 return SDL_TRUE; 95} 96 97SDL_bool 98SDL_SetHint(const char *name, const char *value) 99{ 100 return SDL_SetHintWithPriority(name, value, SDL_HINT_NORMAL); 101} 102 103const char * 104SDL_GetHint(const char *name) 105{ 106 const char *env; 107 SDL_Hint *hint; 108 109 env = SDL_getenv(name); 110 for (hint = SDL_hints; hint; hint = hint->next) { 111 if (SDL_strcmp(name, hint->name) == 0) { 112 if (!env || hint->priority == SDL_HINT_OVERRIDE) { 113 return hint->value; 114 } 115 break; 116 } 117 } 118 return env; 119} 120 121SDL_bool 122SDL_GetHintBoolean(const char *name, SDL_bool default_value) 123{ 124 const char *hint = SDL_GetHint(name); 125 if (!hint || !*hint) { 126 return default_value; 127 } 128 if (*hint == '0' || SDL_strcasecmp(hint, "false") == 0) { 129 return SDL_FALSE; 130 } 131 return SDL_TRUE; 132} 133 134void 135SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata) 136{ 137 SDL_Hint *hint; 138 SDL_HintWatch *entry; 139 const char *value; 140 141 if (!name || !*name) { 142 SDL_InvalidParamError("name"); 143 return; 144 } 145 if (!callback) { 146 SDL_InvalidParamError("callback"); 147 return; 148 } 149 150 SDL_DelHintCallback(name, callback, userdata); 151 152 entry = (SDL_HintWatch *)SDL_malloc(sizeof(*entry)); 153 if (!entry) { 154 SDL_OutOfMemory(); 155 return; 156 } 157 entry->callback = callback; 158 entry->userdata = userdata; 159 160 for (hint = SDL_hints; hint; hint = hint->next) { 161 if (SDL_strcmp(name, hint->name) == 0) { 162 break; 163 } 164 } 165 if (!hint) { 166 /* Need to add a hint entry for this watcher */ 167 hint = (SDL_Hint *)SDL_malloc(sizeof(*hint)); 168 if (!hint) { 169 SDL_OutOfMemory(); 170 SDL_free(entry); 171 return; 172 } 173 hint->name = SDL_strdup(name); 174 hint->value = NULL; 175 hint->priority = SDL_HINT_DEFAULT; 176 hint->callbacks = NULL; 177 hint->next = SDL_hints; 178 SDL_hints = hint; 179 } 180 181 /* Add it to the callbacks for this hint */ 182 entry->next = hint->callbacks; 183 hint->callbacks = entry; 184 185 /* Now call it with the current value */ 186 value = SDL_GetHint(name); 187 callback(userdata, name, value, value); 188} 189 190void 191SDL_DelHintCallback(const char *name, SDL_HintCallback callback, void *userdata) 192{ 193 SDL_Hint *hint; 194 SDL_HintWatch *entry, *prev; 195 196 for (hint = SDL_hints; hint; hint = hint->next) { 197 if (SDL_strcmp(name, hint->name) == 0) { 198 prev = NULL; 199 for (entry = hint->callbacks; entry; entry = entry->next) { 200 if (callback == entry->callback && userdata == entry->userdata) { 201 if (prev) { 202 prev->next = entry->next; 203 } else { 204 hint->callbacks = entry->next; 205 } 206 SDL_free(entry); 207 break; 208 } 209 prev = entry; 210 } 211 return; 212 } 213 } 214} 215 216void SDL_ClearHints(void) 217{ 218 SDL_Hint *hint; 219 SDL_HintWatch *entry; 220 221 while (SDL_hints) { 222 hint = SDL_hints; 223 SDL_hints = hint->next; 224 225 SDL_free(hint->name); 226 SDL_free(hint->value); 227 for (entry = hint->callbacks; entry; ) { 228 SDL_HintWatch *freeable = entry; 229 entry = entry->next; 230 SDL_free(freeable); 231 } 232 SDL_free(hint); 233 } 234} 235 236/* vi: set ts=4 sw=4 expandtab: */ 237
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.