# HG changeset patch
# User Ryan C. Gordon <icculus@icculus.org>
# Date 1350788180 14400
# Node ID f67c6fa3c9dfa18180b204d4694cd96ddc798089
# Parent  c6402c811a40217bceefd461d7def0068aec5dd3
Added SDL_PreferredLocales() API.

diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -78,5 +78,6 @@
 test/testver
 test/testwm2
 test/torturethread
+test/testlocale
 test/*.exe
 test/*.dSYM
diff --git a/Makefile.in b/Makefile.in
--- a/Makefile.in
+++ b/Makefile.in
@@ -58,6 +58,7 @@
 	SDL_keyboard.h \
 	SDL_keycode.h \
 	SDL_loadso.h \
+	SDL_locale.h \
 	SDL_log.h \
 	SDL_main.h \
 	SDL_mouse.h \
diff --git a/configure.in b/configure.in
--- a/configure.in
+++ b/configure.in
@@ -304,6 +304,7 @@
 SOURCES="$SOURCES $srcdir/src/thread/*.c"
 SOURCES="$SOURCES $srcdir/src/timer/*.c"
 SOURCES="$SOURCES $srcdir/src/video/*.c"
+SOURCES="$SOURCES $srcdir/src/locale/*.c"
 
 dnl Enable/disable various subsystems of the SDL library
 
@@ -2159,6 +2160,8 @@
                   , enable_rpath=yes)
 }
 
+have_locale=no
+
 dnl Set up the configuration based on the host platform!
 case "$host" in
     *-*-linux*|*-*-uclinux*|*-*-gnu*|*-*-k*bsd*-gnu|*-*-bsdi*|*-*-freebsd*|*-*-dragonfly*|*-*-netbsd*|*-*-openbsd*|*-*-sysv5*|*-*-solaris*|*-*-hpux*|*-*-aix*|*-*-minix*)
@@ -2203,6 +2206,10 @@
         CheckClockGettime
         CheckLinuxVersion
         CheckRPATH
+
+        SOURCES="$SOURCES $srcdir/src/locale/unix/*.c"
+        have_locale=yes
+
         # Set up files for the audio library
         if test x$enable_audio = xyes; then
           case $ARCH in
@@ -2283,6 +2290,10 @@
         # Set up the core platform files
         SOURCES="$SOURCES $srcdir/src/core/windows/*.c"
 
+        # Use the Windows locale APIs.
+        SOURCES="$SOURCES $srcdir/src/locale/windows/*.c"
+        have_locale=yes
+
         # Set up files for the video library
         if test x$enable_video = xyes; then
             AC_DEFINE(SDL_VIDEO_DRIVER_WINDOWS, 1, [ ])
@@ -2373,6 +2384,11 @@
         CheckDummyAudio
         CheckBWINDOW
         CheckBeGL
+
+        # Set up files for the locale library
+        SOURCES="$SOURCES $srcdir/src/locale/unix/*.c"
+        have_locale=yes
+
         # Set up files for the audio library
         if test x$enable_audio = xyes; then
             AC_DEFINE(SDL_AUDIO_DRIVER_BEOSAUDIO, 1, [ ])
@@ -2428,6 +2444,9 @@
         CheckCOCOA
         CheckPTHREAD
 
+        # Set up files for the locale library
+        SOURCES="$SOURCES $srcdir/src/locale/macosx/*.m"
+        have_locale=yes
 
         # Set up files for the audio library
         if test x$enable_audio = xyes; then
@@ -2490,6 +2509,10 @@
         # Need this or things might misbuild on a G3.
         EXTRA_CFLAGS="$EXTRA_CFLAGS -force_cpusubtype_ALL"
 
+        # Set up files for the locale library
+        SOURCES="$SOURCES $srcdir/src/locale/macosx/*.m"
+        have_locale=yes
+
         # Set up files for the audio library
         if test x$enable_audio = xyes; then
             AC_DEFINE(SDL_AUDIO_DRIVER_COREAUDIO, 1, [ ])
@@ -2548,6 +2571,9 @@
 
 # Verify that we have all the platform specific files we need
 
+if test x$have_locale != xyes; then
+    SOURCES="$SOURCES $srcdir/src/locale/dummy/*.c"
+fi
 if test x$have_joystick != xyes; then
     if test x$enable_joystick = xyes; then
         AC_DEFINE(SDL_JOYSTICK_DISABLED, 1, [ ])
diff --git a/include/SDL.h b/include/SDL.h
--- a/include/SDL.h
+++ b/include/SDL.h
@@ -91,6 +91,7 @@
 #include "SDL_timer.h"
 #include "SDL_version.h"
 #include "SDL_video.h"
+#include "SDL_locale.h"
 
 #include "begin_code.h"
 /* Set up for C function definitions, even when using C++ */
diff --git a/include/SDL_locale.h b/include/SDL_locale.h
new file mode 100644
--- /dev/null
+++ b/include/SDL_locale.h
@@ -0,0 +1,83 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 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.
+*/
+
+/**
+ *  \file SDL_locale.h
+ *
+ *  Include file for SDL locale services
+ */
+
+#ifndef _SDL_locale_h
+#define _SDL_locale_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+
+#include "begin_code.h"
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+/**
+ *  Report the user's preferred locales.
+ *
+ *  This returns an array of null-terminated strings with a NULL pointer to
+ *  mark the end of the array. The memory allocated for this return value is
+ *  owned by SDL, and should not be freed by the application; the returned
+ *  pointers remain valid until SDL_Quit() is called.
+ *
+ *  Returned strings are in the format xx, where 'xx' is an ISO-639 language
+ *  specifier (such as "en" for English, "de" for German, etc), or the format
+ *  xx_YY, where "YY" is an ISO-3166 country code (such as "US" for the United
+ *  States, "CA" for Canada, etc). Please note that not all of these codes are
+ *  2 characters; some are three or more.
+ *
+ *  The returned list of strings are in the order of the user's preference.
+ *  For example, a German citizen that is fluent in US English and knows
+ *  enough Japanese to navigate around Tokyo might have a list like:
+ *  { "de", "en_US", "jp", NULL }. Someone from England might prefer British
+ *  English (where "color" is spelled "colour", etc), but will settle for
+ *  anything like it: { "en_GB", "en", NULL }.
+ *
+ *  Most OSes only supply a single result; some, like Mac OS X, offer users
+ *  a way to prioritize a list of languages.
+ *
+ *  This function returns NULL on error, including when the platform does not
+ *  supply this information at all.
+ *
+ *   \return array of languages, NULL on error.
+ */
+extern DECLSPEC const char ** SDLCALL SDL_PreferredLocales(void);
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+#include "close_code.h"
+
+#endif /* _SDL_locale_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/SDL.c b/src/SDL.c
--- a/src/SDL.c
+++ b/src/SDL.c
@@ -28,6 +28,7 @@
 #include "SDL_assert_c.h"
 #include "haptic/SDL_haptic_c.h"
 #include "joystick/SDL_joystick_c.h"
+#include "locale/SDL_locale_c.h"
 
 /* Initialization/Cleanup routines */
 #if !SDL_TIMERS_DISABLED
@@ -207,6 +208,8 @@
 void
 SDL_Quit(void)
 {
+    SDL_LocalesQuit();
+
     /* Quit all subsystems */
 #if defined(__WIN32__)
     SDL_HelperWindowDestroy();
diff --git a/src/locale/SDL_locale.c b/src/locale/SDL_locale.c
new file mode 100644
--- /dev/null
+++ b/src/locale/SDL_locale.c
@@ -0,0 +1,54 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 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_config.h"
+#include "SDL_locale_c.h"
+#include "SDL_syslocale.h"
+
+static const char **SDL_langs = NULL;
+static SDL_bool SDL_langs_detected = SDL_FALSE;
+
+const char **
+SDL_PreferredLocales(void)
+{
+    if (SDL_langs_detected == SDL_FALSE) {
+        SDL_langs_detected = SDL_TRUE;
+        SDL_langs = SDL_SYS_GetLocales();
+    }
+    return SDL_langs;
+}
+
+void
+SDL_LocalesQuit(void)
+{
+    if (SDL_langs != NULL) {
+        size_t i;
+        for (i = 0; SDL_langs[i] != NULL; i++) {
+            SDL_free((void *) SDL_langs[i]);
+        }
+        SDL_free(SDL_langs);
+        SDL_langs = NULL;
+    }
+    SDL_langs_detected = SDL_FALSE;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/src/locale/SDL_locale_c.h b/src/locale/SDL_locale_c.h
new file mode 100644
--- /dev/null
+++ b/src/locale/SDL_locale_c.h
@@ -0,0 +1,28 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 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_config.h"
+
+#include "SDL_locale.h"
+
+extern void SDL_LocalesQuit(void);
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/src/locale/SDL_syslocale.h b/src/locale/SDL_syslocale.h
new file mode 100644
--- /dev/null
+++ b/src/locale/SDL_syslocale.h
@@ -0,0 +1,29 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 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_config.h"
+
+/* This is the system specific header for the SDL locale API */
+
+#include "SDL_locale.h"
+
+extern const char **SDL_SYS_GetLocales(void);
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/locale/dummy/SDL_syslocale.c b/src/locale/dummy/SDL_syslocale.c
new file mode 100644
--- /dev/null
+++ b/src/locale/dummy/SDL_syslocale.c
@@ -0,0 +1,32 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 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_config.h"
+#include "../SDL_syslocale.h"
+
+const char **
+SDL_SYS_GetLocales(void)
+{
+    return NULL;  /* dummy implementation. */
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/src/locale/macosx/SDL_syslocale.m b/src/locale/macosx/SDL_syslocale.m
new file mode 100644
--- /dev/null
+++ b/src/locale/macosx/SDL_syslocale.m
@@ -0,0 +1,85 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 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_config.h"
+#include "../SDL_syslocale.h"
+
+#import <Cocoa/Cocoa.h>
+
+const char **
+SDL_SYS_GetLocales(void)
+{
+    const char **retval = NULL;
+    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+    NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
+    size_t numlangs = 0;
+    size_t i;
+
+    if (languages == nil) {
+        return NULL;  // maybe on an old version of Mac OS X?
+    }
+
+    numlangs = (size_t) [languages count];
+    retval = (const char **) SDL_malloc(sizeof (const char *) * (numlangs+1));
+    if (retval == NULL) {
+        return NULL;
+    }
+
+    for (i = 0; i < numlangs; i++) {
+        NSString *nsstr = [languages objectAtIndex:i];
+        SDL_bool has_country;
+        size_t buflen;
+        char *str;
+
+        if (nsstr == nil) {
+            break;
+        }
+
+        // "length" should be safe: these are only ever ASCII strings.
+        buflen = ((size_t) [nsstr length]) + 1;
+        str = (char *) SDL_malloc(buflen);
+        if (str == NULL) {
+            break;
+        }
+
+        [nsstr getCString:str maxLength:buflen encoding:NSASCIIStringEncoding];
+
+        retval[i] = str;
+
+        // convert '-' to '_'...
+        if ((str = strchr(str, '-')) != NULL) {
+            has_country = SDL_TRUE;
+            *str = '_';
+        }
+    }
+
+    if (i > 0) {
+        retval[i] = NULL;
+    } else {
+        SDL_free(retval);   // no languages available?!
+        retval = NULL;
+    }
+
+    return retval;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/src/locale/unix/SDL_syslocale.c b/src/locale/unix/SDL_syslocale.c
new file mode 100644
--- /dev/null
+++ b/src/locale/unix/SDL_syslocale.c
@@ -0,0 +1,66 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 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_config.h"
+#include "../SDL_syslocale.h"
+
+const char **
+SDL_SYS_GetLocales(void)
+{
+    const char *envr = SDL_getenv("LANG");
+    const char **retval = NULL;
+    if (envr != NULL)
+    {
+        char *ptr = NULL;
+        char *dupstr = NULL;
+
+        retval = (const char **) SDL_malloc(sizeof (const char *) * 2);
+        if (retval == NULL) {
+            SDL_OutOfMemory();
+            return NULL;
+        }
+
+        dupstr = SDL_strdup(envr);
+        if (dupstr == NULL) {
+            SDL_free(retval);
+            SDL_OutOfMemory();
+            return NULL;
+        }
+
+        ptr = SDL_strchr(dupstr, '.');  /* chop off encoding if specified. */
+        if (ptr != NULL) {
+            *ptr = '\0';
+        }
+
+        ptr = SDL_strchr(dupstr, '@');  /* chop off extra bits if specified. */
+        if (ptr != NULL) {
+            *ptr = '\0';
+        }
+
+        retval[0] = dupstr;
+        retval[1] = NULL;
+    }
+    
+    return retval;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/src/locale/windows/SDL_syslocale.c b/src/locale/windows/SDL_syslocale.c
new file mode 100644
--- /dev/null
+++ b/src/locale/windows/SDL_syslocale.c
@@ -0,0 +1,67 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 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_config.h"
+#include "../SDL_syslocale.h"
+
+const char **
+SDL_SYS_GetLocales(void)
+{
+    const char **retval = NULL;
+    char lang[16];
+    char country[16];
+
+	const int langrc = GetLocaleInfoA(LOCALE_USER_DEFAULT,
+                                      LOCALE_SISO639LANGNAME,
+                                      lang, sizeof (lang));
+
+	const int ctryrc =  GetLocaleInfoA(LOCALE_USER_DEFAULT,
+                                       LOCALE_SISO3166CTRYNAME,
+                                       country, sizeof (country));
+
+    /* Win95 systems will fail, because they don't have LOCALE_SISO*NAME ... */
+    if ((langrc != 0) && (ctryrc != 0)) {
+        char *dupstr = NULL;
+        size_t len = 0;
+
+        retval = (const char **) SDL_malloc(sizeof (const char *) * 2);
+        if (retval == NULL) {
+            SDL_OutOfMemory();
+            return NULL;
+        }
+
+        len = SDL_strlen(lang) + SDL_strlen(country) + 2;
+        dupstr = (char *) SDL_malloc(len);
+        if (dupstr == NULL) {
+            SDL_free(retval);
+            SDL_OutOfMemory();
+            return NULL;
+        }
+        SDL_snprintf(dupstr, len, "%s_%s", lang, country);
+        retval[0] = dupstr;
+        retval[1] = NULL;
+    }
+
+    return retval;
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
+
diff --git a/test/Makefile.in b/test/Makefile.in
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -47,6 +47,7 @@
 	testwm2$(EXE) \
 	torturethread$(EXE) \
 	testrendercopyex$(EXE) \
+	testlocale$(EXE) \
 
 all: Makefile $(TARGETS)
 
@@ -189,7 +190,10 @@
 
 testrendercopyex$(EXE): $(srcdir)/testrendercopyex.c $(srcdir)/common.c
 	$(CC) -o $@ $(srcdir)/testrendercopyex.c $(srcdir)/common.c $(CFLAGS) $(LIBS) @MATHLIB@
-	
+
+testlocale$(EXE): $(srcdir)/testlocale.c
+	$(CC) -o $@ $? $(CFLAGS) $(LIBS)
+
 clean:
 	rm -f $(TARGETS)
 
diff --git a/test/testlocale.c b/test/testlocale.c
new file mode 100644
--- /dev/null
+++ b/test/testlocale.c
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 1997-2012 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.
+*/
+#include <stdio.h>
+#include "SDL.h"
+
+int
+main(int argc, char **argv)
+{
+    /* Print available audio drivers */
+    if (SDL_Init(SDL_INIT_VIDEO) != -1) {
+        const char **locales = SDL_PreferredLocales();
+        if (locales == NULL) {
+            printf("Couldn't determine locales.\n");
+        } else {
+            printf("Locales, in order of preference:\n");
+            while (*locales) {
+                printf("  %s\n", *locales);
+                locales++;
+            }
+            printf("\n");
+        }
+        SDL_Quit();
+    }
+
+    return 0;
+}
+
