src/locale/windows/SDL_syslocale.c
changeset 13797 55ec5ae4aa0b
child 13843 cbd001bb0b89
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/locale/windows/SDL_syslocale.c	Mon May 04 02:27:29 2020 -0400
     1.3 @@ -0,0 +1,119 @@
     1.4 +/*
     1.5 +  Simple DirectMedia Layer
     1.6 +  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
     1.7 +
     1.8 +  This software is provided 'as-is', without any express or implied
     1.9 +  warranty.  In no event will the authors be held liable for any damages
    1.10 +  arising from the use of this software.
    1.11 +
    1.12 +  Permission is granted to anyone to use this software for any purpose,
    1.13 +  including commercial applications, and to alter it and redistribute it
    1.14 +  freely, subject to the following restrictions:
    1.15 +
    1.16 +  1. The origin of this software must not be misrepresented; you must not
    1.17 +     claim that you wrote the original software. If you use this software
    1.18 +     in a product, an acknowledgment in the product documentation would be
    1.19 +     appreciated but is not required.
    1.20 +  2. Altered source versions must be plainly marked as such, and must not be
    1.21 +     misrepresented as being the original software.
    1.22 +  3. This notice may not be removed or altered from any source distribution.
    1.23 +*/
    1.24 +
    1.25 +#include "../../SDL_internal.h"
    1.26 +#include "../../core/windows/SDL_windows.h"
    1.27 +#include "../SDL_syslocale.h"
    1.28 +#include "SDL_assert.h"
    1.29 +
    1.30 +typedef BOOL (WINAPI *pfnGetUserPreferredUILanguages)(DWORD,PULONG,PZZWSTR,PULONG);
    1.31 +#ifndef MUI_LANGUAGE_NAME
    1.32 +#define MUI_LANGUAGE_NAME 0x8 
    1.33 +#endif
    1.34 +
    1.35 +static pfnGetUserPreferredUILanguages pGetUserPreferredUILanguages = NULL;
    1.36 +static HMODULE kernel32 = 0;
    1.37 +
    1.38 +
    1.39 +/* this is the fallback for WinXP...one language, not a list. */
    1.40 +static void
    1.41 +SDL_SYS_GetPreferredLocales_winxp(char *buf, size_t buflen)
    1.42 +{
    1.43 +    const char **retval = NULL;
    1.44 +    char lang[16];
    1.45 +    char country[16];
    1.46 +
    1.47 +	const int langrc = GetLocaleInfoA(LOCALE_USER_DEFAULT,
    1.48 +                                      LOCALE_SISO639LANGNAME,
    1.49 +                                      lang, sizeof (lang));
    1.50 +
    1.51 +	const int ctryrc =  GetLocaleInfoA(LOCALE_USER_DEFAULT,
    1.52 +                                       LOCALE_SISO3166CTRYNAME,
    1.53 +                                       country, sizeof (country));
    1.54 +
    1.55 +    /* Win95 systems will fail, because they don't have LOCALE_SISO*NAME ... */
    1.56 +    if (langrc == 0) {
    1.57 +        SDL_SetError("Couldn't obtain language info");
    1.58 +    } else {
    1.59 +        SDL_snprintf(buf, buflen, "%s%s%s", lang, ctryrc ? "_" : "", ctryrc ? country : "");
    1.60 +    }
    1.61 +}
    1.62 +
    1.63 +/* this works on Windows Vista and later. */
    1.64 +static void
    1.65 +SDL_SYS_GetPreferredLocales_vista(char *buf, size_t buflen)
    1.66 +{
    1.67 +    ULONG numlangs = 0;
    1.68 +    WCHAR *wbuf = NULL;
    1.69 +    ULONG wbuflen = 0;
    1.70 +    SDL_bool isstack;
    1.71 +
    1.72 +    SDL_assert(pGetUserPreferredUILanguages != NULL);
    1.73 +    pGetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numlangs, NULL, &wbuflen);
    1.74 +
    1.75 +    wbuf = SDL_small_alloc(WCHAR, wbuflen, &isstack);
    1.76 +    if (!wbuf) {
    1.77 +        SDL_OutOfMemory();
    1.78 +        return;
    1.79 +    }
    1.80 +
    1.81 +    if (!pGetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numlangs, wbuf, &wbuflen)) {
    1.82 +        SDL_SYS_GetPreferredLocales_winxp(buf, buflen);  /* oh well, try the fallback. */
    1.83 +    } else {
    1.84 +        const ULONG endidx = SDL_min(buflen, wbuflen - 1);
    1.85 +        ULONG str_start = 0;
    1.86 +        ULONG i;
    1.87 +        for (i = 0; i < endidx; i++) {
    1.88 +            const char ch = (char) wbuf[i];  /* these should all be low-ASCII, safe to cast */
    1.89 +            if (ch == '\0') {
    1.90 +                buf[i] = ',';  /* change null separators to commas */
    1.91 +                str_start = i;
    1.92 +            } else if (ch == '-') {
    1.93 +                buf[i] = '_';  /* change '-' to '_' */
    1.94 +            } else {
    1.95 +                buf[i] = ch;   /* copy through as-is. */
    1.96 +            }
    1.97 +        }
    1.98 +        buf[str_start] = '\0';  /* terminate string, chop off final ',' */
    1.99 +    }
   1.100 +
   1.101 +    SDL_small_free(wbuf, isstack);
   1.102 +}
   1.103 +
   1.104 +void
   1.105 +SDL_SYS_GetPreferredLocales(char *buf, size_t buflen)
   1.106 +{
   1.107 +    if (!kernel32) {
   1.108 +        kernel32 = LoadLibraryW(L"kernel32.dll");
   1.109 +        if (kernel32) {
   1.110 +            pGetUserPreferredUILanguages = (pfnGetUserPreferredUILanguages) GetProcAddress(kernel32, "GetUserPreferredUILanguages");
   1.111 +        }
   1.112 +    }
   1.113 +
   1.114 +    if (pGetUserPreferredUILanguages == NULL) {
   1.115 +        SDL_SYS_GetPreferredLocales_winxp(buf, buflen);  /* this is always available */
   1.116 +    } else {
   1.117 +        SDL_SYS_GetPreferredLocales_vista(buf, buflen);  /* available on Vista and later. */
   1.118 +    }
   1.119 +}
   1.120 +
   1.121 +/* vi: set ts=4 sw=4 expandtab: */
   1.122 +