src/locale/windows/SDL_syslocale.c
author Ryan C. Gordon <icculus@icculus.org>
Thu, 21 May 2020 04:01:37 -0400
changeset 13845 210fb62f0c96
parent 13843 cbd001bb0b89
permissions -rw-r--r--
locale: Removed unused variable.
icculus@13797
     1
/*
icculus@13797
     2
  Simple DirectMedia Layer
icculus@13797
     3
  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
icculus@13797
     4
icculus@13797
     5
  This software is provided 'as-is', without any express or implied
icculus@13797
     6
  warranty.  In no event will the authors be held liable for any damages
icculus@13797
     7
  arising from the use of this software.
icculus@13797
     8
icculus@13797
     9
  Permission is granted to anyone to use this software for any purpose,
icculus@13797
    10
  including commercial applications, and to alter it and redistribute it
icculus@13797
    11
  freely, subject to the following restrictions:
icculus@13797
    12
icculus@13797
    13
  1. The origin of this software must not be misrepresented; you must not
icculus@13797
    14
     claim that you wrote the original software. If you use this software
icculus@13797
    15
     in a product, an acknowledgment in the product documentation would be
icculus@13797
    16
     appreciated but is not required.
icculus@13797
    17
  2. Altered source versions must be plainly marked as such, and must not be
icculus@13797
    18
     misrepresented as being the original software.
icculus@13797
    19
  3. This notice may not be removed or altered from any source distribution.
icculus@13797
    20
*/
icculus@13797
    21
icculus@13797
    22
#include "../../SDL_internal.h"
icculus@13797
    23
#include "../../core/windows/SDL_windows.h"
icculus@13797
    24
#include "../SDL_syslocale.h"
icculus@13797
    25
#include "SDL_assert.h"
icculus@13797
    26
icculus@13797
    27
typedef BOOL (WINAPI *pfnGetUserPreferredUILanguages)(DWORD,PULONG,PZZWSTR,PULONG);
icculus@13797
    28
#ifndef MUI_LANGUAGE_NAME
icculus@13797
    29
#define MUI_LANGUAGE_NAME 0x8 
icculus@13797
    30
#endif
icculus@13797
    31
icculus@13797
    32
static pfnGetUserPreferredUILanguages pGetUserPreferredUILanguages = NULL;
icculus@13797
    33
static HMODULE kernel32 = 0;
icculus@13797
    34
icculus@13797
    35
icculus@13797
    36
/* this is the fallback for WinXP...one language, not a list. */
icculus@13797
    37
static void
icculus@13797
    38
SDL_SYS_GetPreferredLocales_winxp(char *buf, size_t buflen)
icculus@13797
    39
{
icculus@13797
    40
    char lang[16];
icculus@13797
    41
    char country[16];
icculus@13797
    42
icculus@13797
    43
	const int langrc = GetLocaleInfoA(LOCALE_USER_DEFAULT,
icculus@13797
    44
                                      LOCALE_SISO639LANGNAME,
icculus@13797
    45
                                      lang, sizeof (lang));
icculus@13797
    46
icculus@13797
    47
	const int ctryrc =  GetLocaleInfoA(LOCALE_USER_DEFAULT,
icculus@13797
    48
                                       LOCALE_SISO3166CTRYNAME,
icculus@13797
    49
                                       country, sizeof (country));
icculus@13797
    50
icculus@13797
    51
    /* Win95 systems will fail, because they don't have LOCALE_SISO*NAME ... */
icculus@13797
    52
    if (langrc == 0) {
icculus@13797
    53
        SDL_SetError("Couldn't obtain language info");
icculus@13797
    54
    } else {
icculus@13797
    55
        SDL_snprintf(buf, buflen, "%s%s%s", lang, ctryrc ? "_" : "", ctryrc ? country : "");
icculus@13797
    56
    }
icculus@13797
    57
}
icculus@13797
    58
icculus@13797
    59
/* this works on Windows Vista and later. */
icculus@13797
    60
static void
icculus@13797
    61
SDL_SYS_GetPreferredLocales_vista(char *buf, size_t buflen)
icculus@13797
    62
{
icculus@13797
    63
    ULONG numlangs = 0;
icculus@13797
    64
    WCHAR *wbuf = NULL;
icculus@13797
    65
    ULONG wbuflen = 0;
icculus@13797
    66
    SDL_bool isstack;
icculus@13797
    67
icculus@13797
    68
    SDL_assert(pGetUserPreferredUILanguages != NULL);
icculus@13797
    69
    pGetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numlangs, NULL, &wbuflen);
icculus@13797
    70
icculus@13797
    71
    wbuf = SDL_small_alloc(WCHAR, wbuflen, &isstack);
icculus@13797
    72
    if (!wbuf) {
icculus@13797
    73
        SDL_OutOfMemory();
icculus@13797
    74
        return;
icculus@13797
    75
    }
icculus@13797
    76
icculus@13797
    77
    if (!pGetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numlangs, wbuf, &wbuflen)) {
icculus@13797
    78
        SDL_SYS_GetPreferredLocales_winxp(buf, buflen);  /* oh well, try the fallback. */
icculus@13797
    79
    } else {
icculus@13843
    80
        const ULONG endidx = (ULONG) SDL_min(buflen, wbuflen - 1);
icculus@13797
    81
        ULONG str_start = 0;
icculus@13797
    82
        ULONG i;
icculus@13797
    83
        for (i = 0; i < endidx; i++) {
icculus@13797
    84
            const char ch = (char) wbuf[i];  /* these should all be low-ASCII, safe to cast */
icculus@13797
    85
            if (ch == '\0') {
icculus@13797
    86
                buf[i] = ',';  /* change null separators to commas */
icculus@13797
    87
                str_start = i;
icculus@13797
    88
            } else if (ch == '-') {
icculus@13797
    89
                buf[i] = '_';  /* change '-' to '_' */
icculus@13797
    90
            } else {
icculus@13797
    91
                buf[i] = ch;   /* copy through as-is. */
icculus@13797
    92
            }
icculus@13797
    93
        }
icculus@13797
    94
        buf[str_start] = '\0';  /* terminate string, chop off final ',' */
icculus@13797
    95
    }
icculus@13797
    96
icculus@13797
    97
    SDL_small_free(wbuf, isstack);
icculus@13797
    98
}
icculus@13797
    99
icculus@13797
   100
void
icculus@13797
   101
SDL_SYS_GetPreferredLocales(char *buf, size_t buflen)
icculus@13797
   102
{
icculus@13797
   103
    if (!kernel32) {
icculus@13797
   104
        kernel32 = LoadLibraryW(L"kernel32.dll");
icculus@13797
   105
        if (kernel32) {
icculus@13797
   106
            pGetUserPreferredUILanguages = (pfnGetUserPreferredUILanguages) GetProcAddress(kernel32, "GetUserPreferredUILanguages");
icculus@13797
   107
        }
icculus@13797
   108
    }
icculus@13797
   109
icculus@13797
   110
    if (pGetUserPreferredUILanguages == NULL) {
icculus@13797
   111
        SDL_SYS_GetPreferredLocales_winxp(buf, buflen);  /* this is always available */
icculus@13797
   112
    } else {
icculus@13797
   113
        SDL_SYS_GetPreferredLocales_vista(buf, buflen);  /* available on Vista and later. */
icculus@13797
   114
    }
icculus@13797
   115
}
icculus@13797
   116
icculus@13797
   117
/* vi: set ts=4 sw=4 expandtab: */
icculus@13797
   118