summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/SDL2/src/SDL_hints.c
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2016-02-27 16:28:05 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2016-02-27 16:53:49 +0100
commitcf6dc7d370407914020f3e623719f09c8668c692 (patch)
tree46b3416d091b4c09b50fba7ffcbd310aed032cc8 /3rdparty/SDL2/src/SDL_hints.c
parent64135e73f973d9b95beb0c60b65feb34fbfec64a (diff)
Placed SDL2 source since we need it on some platforms (nw)
Diffstat (limited to '3rdparty/SDL2/src/SDL_hints.c')
-rw-r--r--3rdparty/SDL2/src/SDL_hints.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/3rdparty/SDL2/src/SDL_hints.c b/3rdparty/SDL2/src/SDL_hints.c
new file mode 100644
index 00000000000..04523327ade
--- /dev/null
+++ b/3rdparty/SDL2/src/SDL_hints.c
@@ -0,0 +1,223 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "./SDL_internal.h"
+
+#include "SDL_hints.h"
+#include "SDL_error.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 {
+ SDL_HintCallback callback;
+ void *userdata;
+ struct SDL_HintWatch *next;
+} SDL_HintWatch;
+
+typedef struct SDL_Hint {
+ char *name;
+ char *value;
+ SDL_HintPriority priority;
+ SDL_HintWatch *callbacks;
+ struct SDL_Hint *next;
+} SDL_Hint;
+
+static SDL_Hint *SDL_hints;
+
+SDL_bool
+SDL_SetHintWithPriority(const char *name, const char *value,
+ SDL_HintPriority priority)
+{
+ const char *env;
+ SDL_Hint *hint;
+ SDL_HintWatch *entry;
+
+ if (!name || !value) {
+ return SDL_FALSE;
+ }
+
+ env = SDL_getenv(name);
+ if (env && priority < SDL_HINT_OVERRIDE) {
+ return SDL_FALSE;
+ }
+
+ for (hint = SDL_hints; hint; hint = hint->next) {
+ if (SDL_strcmp(name, hint->name) == 0) {
+ if (priority < hint->priority) {
+ return SDL_FALSE;
+ }
+ if (!hint->value || !value || SDL_strcmp(hint->value, 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, value);
+ entry = next;
+ }
+ SDL_free(hint->value);
+ hint->value = value ? SDL_strdup(value) : NULL;
+ }
+ hint->priority = priority;
+ return SDL_TRUE;
+ }
+ }
+
+ /* Couldn't find the hint, add a new one */
+ hint = (SDL_Hint *)SDL_malloc(sizeof(*hint));
+ if (!hint) {
+ 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_SetHint(const char *name, const char *value)
+{
+ return SDL_SetHintWithPriority(name, value, SDL_HINT_NORMAL);
+}
+
+const char *
+SDL_GetHint(const char *name)
+{
+ const char *env;
+ SDL_Hint *hint;
+
+ env = SDL_getenv(name);
+ for (hint = SDL_hints; hint; hint = hint->next) {
+ if (SDL_strcmp(name, hint->name) == 0) {
+ if (!env || hint->priority == SDL_HINT_OVERRIDE) {
+ return hint->value;
+ }
+ break;
+ }
+ }
+ return env;
+}
+
+void
+SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
+{
+ SDL_Hint *hint;
+ SDL_HintWatch *entry;
+ const char *value;
+
+ if (!name || !*name) {
+ SDL_InvalidParamError("name");
+ return;
+ }
+ if (!callback) {
+ SDL_InvalidParamError("callback");
+ return;
+ }
+
+ SDL_DelHintCallback(name, callback, userdata);
+
+ entry = (SDL_HintWatch *)SDL_malloc(sizeof(*entry));
+ if (!entry) {
+ SDL_OutOfMemory();
+ return;
+ }
+ entry->callback = callback;
+ entry->userdata = userdata;
+
+ for (hint = SDL_hints; hint; hint = hint->next) {
+ if (SDL_strcmp(name, hint->name) == 0) {
+ break;
+ }
+ }
+ if (!hint) {
+ /* Need to add a hint entry for this watcher */
+ hint = (SDL_Hint *)SDL_malloc(sizeof(*hint));
+ if (!hint) {
+ SDL_OutOfMemory();
+ SDL_free(entry);
+ return;
+ }
+ hint->name = SDL_strdup(name);
+ 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 */
+ entry->next = hint->callbacks;
+ hint->callbacks = entry;
+
+ /* Now call it with the current value */
+ value = SDL_GetHint(name);
+ callback(userdata, name, value, value);
+}
+
+void
+SDL_DelHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
+{
+ SDL_Hint *hint;
+ SDL_HintWatch *entry, *prev;
+
+ for (hint = SDL_hints; hint; hint = hint->next) {
+ if (SDL_strcmp(name, hint->name) == 0) {
+ prev = NULL;
+ for (entry = hint->callbacks; entry; entry = entry->next) {
+ if (callback == entry->callback && userdata == entry->userdata) {
+ if (prev) {
+ prev->next = entry->next;
+ } else {
+ hint->callbacks = entry->next;
+ }
+ SDL_free(entry);
+ break;
+ }
+ prev = entry;
+ }
+ return;
+ }
+ }
+}
+
+void SDL_ClearHints(void)
+{
+ SDL_Hint *hint;
+ SDL_HintWatch *entry;
+
+ 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);
+ }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */