diff --git a/Android.mk b/Android.mk --- a/Android.mk +++ b/Android.mk @@ -35,6 +35,8 @@ $(wildcard $(LOCAL_PATH)/src/joystick/hidapi/*.c) \ $(wildcard $(LOCAL_PATH)/src/joystick/virtual/*.c) \ $(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c) \ + $(wildcard $(LOCAL_PATH)/src/locale/*.c) \ + $(wildcard $(LOCAL_PATH)/src/locale/android/*.c) \ $(wildcard $(LOCAL_PATH)/src/power/*.c) \ $(wildcard $(LOCAL_PATH)/src/power/android/*.c) \ $(wildcard $(LOCAL_PATH)/src/filesystem/android/*.c) \ diff --git a/Makefile.in b/Makefile.in --- a/Makefile.in +++ b/Makefile.in @@ -82,6 +82,7 @@ SDL_keyboard.h \ SDL_keycode.h \ SDL_loadso.h \ + SDL_locale.h \ SDL_log.h \ SDL_main.h \ SDL_messagebox.h \ diff --git a/configure b/configure --- a/configure +++ b/configure @@ -770,6 +770,7 @@ docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -981,6 +982,7 @@ sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' @@ -1233,6 +1235,15 @@ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1370,7 +1381,7 @@ for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1523,6 +1534,7 @@ --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -17309,6 +17321,7 @@ SOURCES="$SOURCES $srcdir/src/timer/*.c" SOURCES="$SOURCES $srcdir/src/video/*.c" SOURCES="$SOURCES $srcdir/src/video/yuv2rgb/*.c" +SOURCES="$SOURCES $srcdir/src/locale/*.c" # Check whether --enable-atomic was given. @@ -24659,6 +24672,8 @@ CheckEventSignals +have_locale=no + case "$host" in *-*-linux*|*-*-uclinux*|*-*-gnu*|*-*-k*bsd*-gnu|*-*-bsdi*|*-*-freebsd*|*-*-dragonfly*|*-*-netbsd*|*-*-openbsd*|*-*-sysv5*|*-*-solaris*|*-*-hpux*|*-*-aix*|*-*-minix*|*-*-nto*) case "$host" in @@ -24746,6 +24761,9 @@ CheckRPATH CheckVivanteVideo + 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 @@ -24923,6 +24941,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 @@ -25216,6 +25238,10 @@ CheckVulkan 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 @@ -25337,6 +25363,10 @@ CheckPTHREAD CheckHIDAPI + # 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 @@ -25549,6 +25579,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 diff --git a/configure.ac b/configure.ac --- a/configure.ac +++ b/configure.ac @@ -413,6 +413,7 @@ SOURCES="$SOURCES $srcdir/src/timer/*.c" SOURCES="$SOURCES $srcdir/src/video/*.c" SOURCES="$SOURCES $srcdir/src/video/yuv2rgb/*.c" +SOURCES="$SOURCES $srcdir/src/locale/*.c" dnl Enable/disable various subsystems of the SDL library @@ -3439,6 +3440,8 @@ dnl Do this for every platform, but for some it doesn't mean anything, but better to catch it here anyhow. CheckEventSignals +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*|*-*-nto*) @@ -3527,6 +3530,9 @@ CheckRPATH CheckVivanteVideo + 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 @@ -3676,6 +3682,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, [ ]) @@ -3867,6 +3877,10 @@ CheckVulkan 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 AC_DEFINE(SDL_AUDIO_DRIVER_COREAUDIO, 1, [ ]) @@ -3966,6 +3980,10 @@ CheckPTHREAD CheckHIDAPI + # 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, [ ]) @@ -4141,6 +4159,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_DUMMY, 1, [ ]) diff --git a/include/SDL.h b/include/SDL.h --- a/include/SDL.h +++ b/include/SDL.h @@ -59,6 +59,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,144 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + 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); + + +/** + * \brief The Languages detected from the String Locales + */ +typedef enum { + SDL_LANG_EN = 0 , /**< English */ + SDL_LANG_JA = 1 , /**< Japanese */ + SDL_LANG_HE = 2 , /**< Hebrew */ + SDL_LANG_FR = 3 , /**< French */ + SDL_LANG_FI = 4 , /**< Finnish */ + SDL_LANG_CS = 5 , /**< Czech */ + SDL_LANG_HI = 6 , /**< Hindi */ + SDL_LANG_NO = 7 , /**< Norwegian */ + SDL_LANG_ES = 8 , /**< Spanish */ + SDL_LANG_RU = 9 , /**< Russian */ + SDL_LANG_DE = 10, /**< German */ + SDL_LANG_KO = 11, /**< Korean */ + SDL_LANG_IT = 12, /**< Italian */ + SDL_LANG_PT = 13, /**< Portuguese */ + SDL_LANG_HU = 14, /**< Hungarian */ + SDL_LANG_PL = 15, /**< Polish */ + SDL_LANG_SV = 16, /**< Swedish */ + SDL_LANG_NL = 17, /**< Dutch */ + SDL_LANG_DA = 18, /**< Danish */ + SDL_LANG_CHS = 19, /**< Chinese Simplified */ + SDL_LANG_CHT = 20, /**< Chinese Traditionnal */ + SDL_LANG_TH = 21, /**< Thai */ + SDL_LANG_AR = 22, /**< Arabic */ + SDL_LANG_SQ = 23, /**< Albanian */ + SDL_LANG_EL = 24, /**< Greek */ + SDL_LANG_MS = 25, /**< Malay */ + SDL_LANG_RO = 26, /**< Romanian */ + SDL_LANG_BG = 27, /**< Bulgarian */ + SDL_LANG_VI = 28, /**< Vietnamese */ + SDL_LANG_TR = 29, /**< Turkish */ + SDL_LANG_HR = 30, /**< Croatian */ + SDL_LANG_CA = 31, /**< Catalan */ + SDL_LANG_NB, /**< Don't use this one ! but SDL_LanguageGetNumber() instead */ + SDL_LANG_UNKNOWN = -1 +} SDL_Language; + +/** + * \brief Convert a locale (obtained by SDL_PreferredLocales) to a SDL_Language enum + */ +extern DECLSPEC SDL_Language SDL_LanguageFromLocale(const char *locale); + +/** + * \brief Number of language that can be detected + */ +extern DECLSPEC int SDL_LanguageGetNumber(); + +/** + * \brief Convert a SDL_Language enum to a readable english string + */ +extern DECLSPEC const char *SDL_LanguageToString(SDL_Language lang); + +/** + * \brief Convert an int to a SDL_Language enum + */ +extern DECLSPEC SDL_Language SDL_LanguageFromInt(int val); + +/* 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 @@ -41,6 +41,7 @@ #include "events/SDL_events_c.h" #include "haptic/SDL_haptic_c.h" #include "joystick/SDL_joystick_c.h" +#include "locale/SDL_locale_c.h" #include "sensor/SDL_sensor_c.h" /* Initialization/Cleanup routines */ @@ -411,6 +412,8 @@ { SDL_bInMainQuit = SDL_TRUE; + SDL_LocalesQuit(); + /* Quit all subsystems */ #if SDL_VIDEO_DRIVER_WINDOWS SDL_HelperWindowDestroy(); diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -44,6 +44,8 @@ #include "../../haptic/android/SDL_syshaptic_c.h" #include +#include +#include #include #include #include @@ -2796,6 +2798,80 @@ return bPermissionRequestResult; } +/* str_locale is 6 char max. */ +int Android_JNI_GetLocale(char *str_locale) +{ + struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); + JNIEnv* env = Android_JNI_GetEnv(); + int retval = -1; + + JNIEnv *mEnv = Android_JNI_GetEnv(); + if (!LocalReferenceHolder_Init(&refs, env)) { + LocalReferenceHolder_Cleanup(&refs); + return -1; + } + + jmethodID mid; + jobject context; + jobject assetManager; + + /* context = SDLActivity.getContext(); */ + mid = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "getContext","()Landroid/content/Context;"); + context = (*mEnv)->CallStaticObjectMethod(mEnv, mActivityClass, mid); + + /* assetManager = context.getAssets(); */ + mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, context), + "getAssets", "()Landroid/content/res/AssetManager;"); + assetManager = (*mEnv)->CallObjectMethod(mEnv, context, mid); + + + /* API from NDK: android/configuration.h */ + /* API from NDK: android/asset_manager_jni.h */ + AAssetManager* asset_mgr = AAssetManager_fromJava(env, assetManager); + AConfiguration *cfg = AConfiguration_new(); + + if (asset_mgr && cfg) + { + char language[2] = {}; + char country[2] = {}; + int id = 0; + + AConfiguration_fromAssetManager(cfg, asset_mgr); + AConfiguration_getLanguage(cfg, language); + AConfiguration_getCountry(cfg, country); + + retval = 0; + + /* copy language (not null terminated) */ + if (language[0]) { + str_locale[id++] = language[0]; + if (language[1]) { + str_locale[id++] = language[1]; + } + } + + str_locale[id++] = '_'; + + /* copy country (not null terminated) */ + if (country[0]) { + str_locale[id++] = country[0]; + if (country[1]) { + str_locale[id++] = country[1]; + } + } + + str_locale[id++] = '\0'; + } + + if (cfg) { + AConfiguration_delete(cfg); + } + + LocalReferenceHolder_Cleanup(&refs); + return retval; +} + #endif /* __ANDROID__ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h --- a/src/core/android/SDL_android.h +++ b/src/core/android/SDL_android.h @@ -104,6 +104,9 @@ JNIEnv *Android_JNI_GetEnv(void); int Android_JNI_SetupThread(void); +/* Locale */ +int Android_JNI_GetLocale(char *str_locale); + /* Generic messages */ int Android_JNI_SendMessage(int command, int param); diff --git a/src/events/SDL_gesture.c b/src/events/SDL_gesture.c --- a/src/events/SDL_gesture.c +++ b/src/events/SDL_gesture.c @@ -36,7 +36,7 @@ #define MAXPATHSIZE 1024 -#define ENABLE_DOLLAR +// PATCH slvn #define ENABLE_DOLLAR #define DOLLARNPOINTS 64 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,260 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + 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; +} + +int +SDL_LanguageGetNumber() +{ + return SDL_LANG_NB; +} + +const char * +SDL_LanguageToString(SDL_Language lang) +{ + switch (lang) + { + case SDL_LANG_EN: return "English"; + case SDL_LANG_JA: return "Japanese"; + case SDL_LANG_HE: return "Hebrew"; + case SDL_LANG_FR: return "French"; + case SDL_LANG_FI: return "Finnish"; + case SDL_LANG_CS: return "Czech"; + case SDL_LANG_HI: return "Hindi"; + case SDL_LANG_NO: return "Norwegian"; + case SDL_LANG_ES: return "Spanish"; + case SDL_LANG_RU: return "Russian"; + case SDL_LANG_DE: return "German"; + case SDL_LANG_KO: return "Korean"; + case SDL_LANG_IT: return "Italian"; + case SDL_LANG_PT: return "Portuguese"; + case SDL_LANG_HU: return "Hungarian"; + case SDL_LANG_PL: return "Polish"; + case SDL_LANG_SV: return "Swedish"; + case SDL_LANG_NL: return "Dutch"; + case SDL_LANG_DA: return "Danish"; + case SDL_LANG_CHS: return "Chinese Simplified"; + case SDL_LANG_CHT: return "Chinese Traditional"; + case SDL_LANG_TH: return "Thai"; + case SDL_LANG_AR: return "Arabic"; + case SDL_LANG_SQ: return "Albanian"; + case SDL_LANG_EL: return "Greek"; + case SDL_LANG_MS: return "Malay"; + case SDL_LANG_RO: return "Romanian"; + case SDL_LANG_BG: return "Bulgarian"; + case SDL_LANG_VI: return "Vietnamese"; + case SDL_LANG_TR: return "Turkish"; + case SDL_LANG_HR: return "Croatian"; + case SDL_LANG_CA: return "Catalan"; + + default: + return "Unknown"; + } + return "Unknown"; +} + +SDL_Language +SDL_LanguageFromInt(int val) +{ + switch (val) + { + case 0: return SDL_LANG_EN; // English + case 1: return SDL_LANG_JA; // Japanese + case 2: return SDL_LANG_HE; // Hebrew + case 3: return SDL_LANG_FR; // French + case 4: return SDL_LANG_FI; // Finnish + case 5: return SDL_LANG_CS; // Czech + case 6: return SDL_LANG_HI; // Hindi + case 7: return SDL_LANG_NO; // Norwegian + case 8: return SDL_LANG_ES; // Spanish + case 9: return SDL_LANG_RU; // Russian + case 10: return SDL_LANG_DE; // German + case 11: return SDL_LANG_KO; // Korean + case 12: return SDL_LANG_IT; // Italian + case 13: return SDL_LANG_PT; // Portuguese + case 14: return SDL_LANG_HU; // Hungarian + case 15: return SDL_LANG_PL; // Polish + case 16: return SDL_LANG_SV; // Swedish + case 17: return SDL_LANG_NL; // Dutch + case 18: return SDL_LANG_DA; // Danish + case 19: return SDL_LANG_CHS; // Chinese Simplified + case 20: return SDL_LANG_CHT; // Chinese Traditionnal + case 21: return SDL_LANG_TH; // Thai + case 22: return SDL_LANG_AR; // Arabic + case 23: return SDL_LANG_SQ; // Albanian + case 24: return SDL_LANG_EL; // Greek + case 25: return SDL_LANG_MS; // Malay + case 26: return SDL_LANG_RO; // Romanian + case 27: return SDL_LANG_BG; // Bulgarian + case 28: return SDL_LANG_VI; // Vietnamese + case 29: return SDL_LANG_TR; // Turkish + case 30: return SDL_LANG_HR; // Croatian + case 31: return SDL_LANG_CA; // Catalan + + default: + return SDL_LANG_UNKNOWN; + } + + return SDL_LANG_UNKNOWN; +} + + +#define CHECK_LANG(lang, c1, c2) \ + if (buf[0] == c1 && buf[1] == c2) \ + { \ + return lang; \ + } \ + + +SDL_Language +SDL_LanguageFromLocale(const char *str) +{ + if (str == NULL) + { + return SDL_LANG_UNKNOWN; + } + + int len = strlen(str); + + if (len < 2) + { + return SDL_LANG_UNKNOWN; + } + + if (len > 30) + { + len = 30; + } + char buf[32]; + memset(buf, 0, sizeof(buf)); + + /* Upper case */ + int i; + for (i = 0; i < len + 1; i++) + { + const char c = str[i]; + if (c >= 'a' && c <= 'z') + { + buf[i] = c - 'a' + 'A'; + } + else + { + buf[i] = c; + } + } + buf[len] = 0; + + CHECK_LANG(SDL_LANG_AR, 'A', 'R'); + CHECK_LANG(SDL_LANG_CS, 'C', 'S'); + CHECK_LANG(SDL_LANG_DA, 'D', 'A'); + CHECK_LANG(SDL_LANG_DE, 'D', 'E'); + CHECK_LANG(SDL_LANG_EL, 'E', 'L'); + CHECK_LANG(SDL_LANG_EN, 'E', 'N'); + CHECK_LANG(SDL_LANG_ES, 'E', 'S'); + CHECK_LANG(SDL_LANG_FI, 'F', 'I'); + CHECK_LANG(SDL_LANG_FR, 'F', 'R'); + CHECK_LANG(SDL_LANG_HE, 'H', 'E'); CHECK_LANG(SDL_LANG_HE, 'I', 'W'); /* Hebrew has two "language code" HE and IW */ + CHECK_LANG(SDL_LANG_HI, 'H', 'I'); + CHECK_LANG(SDL_LANG_HU, 'H', 'U'); + CHECK_LANG(SDL_LANG_IT, 'I', 'T'); + CHECK_LANG(SDL_LANG_JA, 'J', 'A'); + CHECK_LANG(SDL_LANG_KO, 'K', 'O'); + CHECK_LANG(SDL_LANG_MS, 'M', 'S'); + CHECK_LANG(SDL_LANG_NL, 'N', 'L'); + CHECK_LANG(SDL_LANG_NO, 'N', 'O'); + CHECK_LANG(SDL_LANG_PL, 'P', 'L'); + CHECK_LANG(SDL_LANG_PT, 'P', 'T'); + CHECK_LANG(SDL_LANG_RU, 'R', 'U'); + CHECK_LANG(SDL_LANG_SQ, 'S', 'Q'); + CHECK_LANG(SDL_LANG_SV, 'S', 'V'); + CHECK_LANG(SDL_LANG_TH, 'T', 'H'); + CHECK_LANG(SDL_LANG_RO, 'R', 'O'); + CHECK_LANG(SDL_LANG_BG, 'B', 'G'); + CHECK_LANG(SDL_LANG_VI, 'V', 'I'); + CHECK_LANG(SDL_LANG_TR, 'T', 'R'); + CHECK_LANG(SDL_LANG_HR, 'H', 'R'); + CHECK_LANG(SDL_LANG_CA, 'C', 'A'); + + /* Chinese */ + if (buf[0] == 'Z' && buf[1] == 'H') + { + /* Honk-hong, Taiwan, Macau => Traditionnal */ + if (len >=5) + { + if (buf[3] == 'H' && buf[4] == 'K') + { + return SDL_LANG_CHT; + } + if (buf[3] == 'T' && buf[4] == 'W') + { + return SDL_LANG_CHT; + } + if (buf[3] == 'M' && buf[4] == 'O') + { + return SDL_LANG_CHT; + } + } + + /* Traditionnal */ + if (len >= 6) + { + if (buf[3] == 'C' && buf[4] == 'H' && buf[5] == 'T') + { + return SDL_LANG_CHT; + } + } + return SDL_LANG_CHS; /* Default is Simplified */ + } + + return SDL_LANG_UNKNOWN; +} + +/* 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-2014 Sam Lantinga + + 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-2014 Sam Lantinga + + 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/android/SDL_syslocale.c b/src/locale/android/SDL_syslocale.c new file mode 100644 --- /dev/null +++ b/src/locale/android/SDL_syslocale.c @@ -0,0 +1,61 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + 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 envr[6]; /* expected, max 6 char : aa_AA\0 */ + + memset(envr, 0, sizeof (envr)); + + Android_JNI_GetLocale(envr); + + if (envr[0] != '\0') + { + 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; + } + + retval[0] = dupstr; + retval[1] = NULL; + } + + return retval; +} + +/* 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-2014 Sam Lantinga + + 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-2014 Sam Lantinga + + 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 + +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-2014 Sam Lantinga + + 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-2014 Sam Lantinga + + 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/src/locale/winrt/SDL_syslocale.c b/src/locale/winrt/SDL_syslocale.c new file mode 100644 --- /dev/null +++ b/src/locale/winrt/SDL_syslocale.c @@ -0,0 +1,77 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2014 Sam Lantinga + + 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" + +using namespace Windows::Graphics::Display; +# include + +const char ** +SDL_SYS_GetLocales(void) +{ + char buffer[128] = ""; + char buffer2[128] = ""; + int ret = 0; + +# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + ret = GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_SNAME, (LPWSTR)buffer, 32); +# else + ret = GetSystemDefaultLocaleName((LPWSTR)buffer, 32); +# endif + + if (ret > 0) + { + /* Need to conver LPWSTR to LPSTR, that is wide char to char. */ + memset(buffer2, 0, sizeof(buffer2)); + if (ret > 32) { + ret = 32; + } + for (int i = 0; i < ret; i++) { + buffer2[i] = buffer[2 * i]; + } + } + + if (buffer2[0] != '\0') { + char *dupstr = NULL; + size_t len = 0; + + retval = (const char **) SDL_malloc(sizeof (const char *) * 2); + if (retval == NULL) { + SDL_OutOfMemory(); + return NULL; + } + + dupstr = SDL_strdup(buffer2); + if (dupstr == NULL) { + SDL_free(retval); + SDL_OutOfMemory(); + return NULL; + } + 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 @@ -37,6 +37,7 @@ testjoystick$(EXE) \ testkeys$(EXE) \ testloadso$(EXE) \ + testlocale$(EXE) \ testlock$(EXE) \ testmessage$(EXE) \ testmultiaudio$(EXE) \ @@ -303,6 +304,10 @@ testvulkan$(EXE): $(srcdir)/testvulkan.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) +testlocale$(EXE): $(srcdir)/testlocale.c + $(CC) -o $@ $? $(CFLAGS) $(LIBS) + + clean: rm -f $(TARGETS) diff --git a/test/README b/test/README --- a/test/README +++ b/test/README @@ -12,6 +12,7 @@ testjoystick List joysticks and watch joystick events testkeys List the available keyboard keys testloadso Tests the loadable library layer + testlocale Test Locale API testlock Hacked up test of multi-threading and locking testmultiaudio Tests using several audio devices testoverlay2 Tests the overlay flickering/scaling during playback. diff --git a/test/configure b/test/configure --- a/test/configure +++ b/test/configure @@ -640,6 +640,7 @@ docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -720,6 +721,7 @@ sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' @@ -972,6 +974,15 @@ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1109,7 +1120,7 @@ for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1262,6 +1273,7 @@ --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] diff --git a/test/testlocale.c b/test/testlocale.c new file mode 100644 --- /dev/null +++ b/test/testlocale.c @@ -0,0 +1,52 @@ +/* + Copyright (C) 1997-2014 Sam Lantinga + + 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 +#include "SDL.h" + +int +main(int argc, char **argv) +{ + + /* Print locales and languages */ + 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) { + SDL_Language lang = SDL_LanguageFromLocale(*locales); + + printf(" %s - language = %s\n", *locales, SDL_LanguageToString(lang)); + locales++; + } + printf("\n"); + } + + { + int nb = SDL_LanguageGetNumber(); + int i; + printf("List of languages:\n"); + for (i = 0; i < nb; i++) + { + SDL_Language lang = SDL_LanguageFromInt(i); + printf(" %d - language = %s\n", i, SDL_LanguageToString(lang)); + } + printf(" %d - language = %s\n", -1, SDL_LanguageToString(-1)); + } + + SDL_Quit(); + } + + return 0; +} +