Added a hint system to allow configuration hints to be specified by the application.
authorSam Lantinga <slouken@libsdl.org>
Sat, 05 Feb 2011 10:02:39 -0800
changeset 5189 6f6a9340fb93
parent 5188 59e0688d766f
child 5190 82a48f4d65f6
Added a hint system to allow configuration hints to be specified by the application.
Makefile.in
include/SDL.h
include/SDL_hints.h
src/SDL.c
src/SDL_hints.c
--- a/Makefile.in	Sat Feb 05 01:03:51 2011 -0800
+++ b/Makefile.in	Sat Feb 05 10:02:39 2011 -0800
@@ -53,6 +53,7 @@
 	SDL_events.h \
 	SDL_gesture.h \
 	SDL_haptic.h \
+	SDL_hints.h \
 	SDL_input.h \
 	SDL_joystick.h \
 	SDL_keyboard.h \
--- a/include/SDL.h	Sat Feb 05 01:03:51 2011 -0800
+++ b/include/SDL.h	Sat Feb 05 10:02:39 2011 -0800
@@ -79,6 +79,7 @@
 #include "SDL_endian.h"
 #include "SDL_error.h"
 #include "SDL_events.h"
+#include "SDL_hints.h"
 #include "SDL_loadso.h"
 #include "SDL_mutex.h"
 #include "SDL_power.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/SDL_hints.h	Sat Feb 05 10:02:39 2011 -0800
@@ -0,0 +1,104 @@
+/*
+    SDL - Simple DihintsMedia Layer
+    Copyright (C) 1997-2010 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+/**
+ *  \file SDL_hints.h
+ *  
+ *  Official documentation for SDL configuration variables
+ *
+ *  This file contains functions to set and get configuration hints,
+ *  as well as listing each of them alphabetically.
+ *
+ *  The convention for naming hints is SDL_HINT_X, where "SDL_X" is
+ *  the environment variable that can be used to override the default.
+ *
+ *  In general these hints are just that - they may or may not be
+ *  supported or applicable on any given platform, but they provide
+ *  a way for an application or user to give the library a hint as
+ *  to how they would like the library to work.
+ */
+
+#ifndef _SDL_hints_h
+#define _SDL_hints_h
+
+#include "SDL_stdinc.h"
+
+#include "begin_code.h"
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+
+
+/**
+ *  \brief  An enumeration of hint priorities
+ */
+typedef enum
+{
+    SDL_HINT_DEFAULT,
+    SDL_HINT_NORMAL,
+    SDL_HINT_OVERRIDE
+} SDL_HintPriority;
+
+
+/**
+ *  \brief Set a hint
+ *
+ *  The priority controls the behavior when setting a hint that already
+ *  has a value.  Hints will replace existing hints of their priority and
+ *  lower.  Environment variables are considered to have override priority.
+ * 
+ *  \return SDL_TRUE if the hint was set, SDL_FALSE otherwise
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name,
+                                             const char *value,
+                                             SDL_HintPriority priority);
+
+/**
+ *  \brief Get a hint
+ *  
+ *  \return The string value of a hint variable.
+ */
+extern DECLSPEC const char * SDLCALL SDL_GetHint(const char *name);
+
+/**
+ *  \brief  Clear all hints
+ *
+ *  This function is called during SDL_Quit() to free stored hints.
+ */
+extern DECLSPEC void SDLCALL SDL_ClearHints();
+
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+#include "close_code.h"
+
+#endif /* _SDL_hints_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- a/src/SDL.c	Sat Feb 05 01:03:51 2011 -0800
+++ b/src/SDL.c	Sat Feb 05 10:02:39 2011 -0800
@@ -246,6 +246,7 @@
     /* Uninstall any parachute signal handlers */
     SDL_UninstallParachute();
 
+    SDL_ClearHints();
     SDL_AssertionsQuit();
 
 #ifdef DEBUG_BUILD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/SDL_hints.c	Sat Feb 05 10:02:39 2011 -0800
@@ -0,0 +1,115 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#include "SDL_hints.h"
+
+
+/* Assuming there aren't many hints set and they aren't being queried in
+   critical performance paths, we'll just use a linked list here.
+ */
+typedef struct SDL_Hint {
+    char *name;
+    char *value;
+    SDL_HintPriority priority;
+    struct SDL_Hint *next;
+} SDL_Hint;
+
+static SDL_Hint *SDL_hints;
+
+
+SDL_bool
+SDL_SetHint(const char *name, const char *value, SDL_HintPriority priority)
+{
+    const char *env;
+    SDL_Hint *prev, *hint;
+
+    if (!name || !value) {
+        return SDL_FALSE;
+    }
+
+    env = SDL_getenv(name);
+    if (env && priority < SDL_HINT_OVERRIDE) {
+        return SDL_FALSE;
+    }
+
+    prev = NULL;
+    for (hint = SDL_hints; hint; prev = hint, hint = hint->next) {
+        if (SDL_strcmp(name, hint->name) == 0) {
+            if (priority < hint->priority) {
+                return SDL_FALSE;
+            }
+            if (SDL_strcmp(hint->value, value) != 0) {
+                SDL_free(hint->value);
+                hint->value = SDL_strdup(value);
+            }
+            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 = SDL_strdup(value);
+    hint->priority = priority;
+    hint->next = SDL_hints;
+    SDL_hints = hint;
+    return SDL_TRUE;
+}
+
+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_ClearHints()
+{
+    SDL_Hint *hint;
+
+    while (SDL_hints) {
+        hint = SDL_hints;
+        SDL_hints = hint->next;
+
+        SDL_free(hint->name);
+        SDL_free(hint->value);
+        SDL_free(hint);
+    }
+}
+
+/* vi: set ts=4 sw=4 expandtab: */