From fa23e3d00b461b707bdcf4693e231229d3ad863b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 4 May 2020 02:27:29 -0400 Subject: [PATCH] locale: Implemented SDL_GetPreferredLocales(). This was something I proposed a long time ago, Sylvain Becker did additional work on it, then back to me. Fixes Bugzilla #2131. --- Android.mk | 2 + CMakeLists.txt | 44 ++++++- Makefile.in | 1 + Makefile.os2 | 4 +- VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj | 4 + .../UWP_VS2015/SDL-UWP.vcxproj.filters | 12 ++ .../WinPhone81_VS2013/SDL-WinPhone81.vcxproj | 4 + .../SDL-WinPhone81.vcxproj.filters | 12 ++ .../WinRT81_VS2013/SDL-WinRT81.vcxproj | 4 + .../SDL-WinRT81.vcxproj.filters | 12 ++ VisualC/SDL/SDL.vcxproj | 4 + VisualC/SDL/SDL.vcxproj.filters | 6 + Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj | 57 +++++++++ Xcode/SDL/SDL.xcodeproj/project.pbxproj | 64 ++++++++++ configure | 43 ++++++- configure.ac | 29 +++++ include/SDL.h | 1 + include/SDL_events.h | 2 + include/SDL_hints.h | 15 +++ include/SDL_locale.h | 101 +++++++++++++++ src/core/android/SDL_android.c | 78 ++++++++++++ src/core/android/SDL_android.h | 3 + src/dynapi/SDL_dynapi_overrides.h | 1 + src/dynapi/SDL_dynapi_procs.h | 1 + src/events/SDL_events.c | 6 + src/events/SDL_events_c.h | 1 + src/locale/SDL_locale.c | 103 +++++++++++++++ src/locale/SDL_syslocale.h | 29 +++++ src/locale/android/SDL_syslocale.c | 32 +++++ src/locale/dummy/SDL_syslocale.c | 33 +++++ src/locale/emscripten/SDL_syslocale.c | 72 +++++++++++ src/locale/haiku/SDL_syslocale.cc | 75 +++++++++++ src/locale/macosx/SDL_syslocale.m | 76 +++++++++++ src/locale/unix/SDL_syslocale.c | 110 ++++++++++++++++ src/locale/windows/SDL_syslocale.c | 119 ++++++++++++++++++ src/locale/winrt/SDL_syslocale.c | 58 +++++++++ src/main/haiku/SDL_BApp.h | 5 + src/video/cocoa/SDL_cocoaevents.m | 12 ++ test/Makefile.in | 5 + test/README | 1 + test/configure | 14 ++- test/testlocale.c | 67 ++++++++++ 42 files changed, 1318 insertions(+), 4 deletions(-) create mode 100644 include/SDL_locale.h create mode 100644 src/locale/SDL_locale.c create mode 100644 src/locale/SDL_syslocale.h create mode 100644 src/locale/android/SDL_syslocale.c create mode 100644 src/locale/dummy/SDL_syslocale.c create mode 100644 src/locale/emscripten/SDL_syslocale.c create mode 100644 src/locale/haiku/SDL_syslocale.cc create mode 100644 src/locale/macosx/SDL_syslocale.m create mode 100644 src/locale/unix/SDL_syslocale.c create mode 100644 src/locale/windows/SDL_syslocale.c create mode 100644 src/locale/winrt/SDL_syslocale.c create mode 100644 test/testlocale.c diff --git a/Android.mk b/Android.mk index 264c03d8b0c67..6036a350249b4 100755 --- a/Android.mk +++ b/Android.mk @@ -35,6 +35,8 @@ LOCAL_SRC_FILES := \ $(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/CMakeLists.txt b/CMakeLists.txt index 6be75e2985732..0b63bf8a63a8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -307,7 +307,7 @@ endif() set(SDL_SUBSYSTEMS Atomic Audio Video Render Events Joystick Haptic Power Threads Timers - File Loadso CPUinfo Filesystem Dlopen Sensor) + File Loadso CPUinfo Filesystem Dlopen Sensor Locale) foreach(_SUB ${SDL_SUBSYSTEMS}) string(TOUPPER ${_SUB} _OPT) if (NOT DEFINED SDL_${_OPT}_ENABLED_BY_DEFAULT) @@ -404,6 +404,7 @@ file(GLOB SOURCE_FILES ${SDL2_SOURCE_DIR}/src/events/*.c ${SDL2_SOURCE_DIR}/src/file/*.c ${SDL2_SOURCE_DIR}/src/libm/*.c + ${SDL2_SOURCE_DIR}/src/locale/*.c ${SDL2_SOURCE_DIR}/src/render/*.c ${SDL2_SOURCE_DIR}/src/render/*/*.c ${SDL2_SOURCE_DIR}/src/stdlib/*.c @@ -885,6 +886,8 @@ if(SDL_POWER) file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${POWER_SOURCES}) endif() + + # TODO: in configure.ac, the test for LOADSO and SDL_DLOPEN is a bit weird: # if LOADSO is not wanted, SDL_LOADSO_DISABLED is set # If however on Unix or APPLE dlopen() is detected via CheckDLOPEN(), @@ -993,6 +996,11 @@ if(ANDROID) set(SOURCE_FILES ${SOURCE_FILES} ${ANDROID_POWER_SOURCES}) set(HAVE_SDL_POWER TRUE) endif() + if(SDL_LOCALE) + file(GLOB ANDROID_LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/android/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${ANDROID_LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() if(SDL_TIMERS) set(SDL_TIMER_UNIX 1) file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c) @@ -1083,6 +1091,11 @@ elseif(EMSCRIPTEN) set(SOURCE_FILES ${SOURCE_FILES} ${EM_POWER_SOURCES}) set(HAVE_SDL_POWER TRUE) endif() + if(SDL_LOCALE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/emscripten/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() if(SDL_TIMERS) set(SDL_TIMER_UNIX 1) file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c) @@ -1272,6 +1285,12 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS) endif() endif() + if(SDL_LOCALE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/unix/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() + if(SDL_FILESYSTEM) set(SDL_FILESYSTEM_UNIX 1) file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/unix/*.c) @@ -1438,6 +1457,12 @@ elseif(WINDOWS) set(HAVE_SDL_POWER TRUE) endif() + if(SDL_LOCALE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/windows/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() + if(SDL_FILESYSTEM) set(SDL_FILESYSTEM_WINDOWS 1) file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/windows/*.c) @@ -1629,6 +1654,12 @@ elseif(APPLE) set(HAVE_SDL_POWER TRUE) endif() + if(SDL_LOCALE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/macosx/*.m) + set(SOURCE_FILES ${SOURCE_FILES} ${LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() + if(SDL_TIMERS) set(SDL_TIMER_UNIX 1) file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c) @@ -1837,6 +1868,12 @@ elseif(HAIKU) set(HAVE_SDL_TIMERS TRUE) endif() + if(SDL_LOCALE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/haiku/*.cc) + set(SOURCE_FILES ${SOURCE_FILES} ${LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() + CheckPTHREAD() elseif(RISCOS) @@ -1899,6 +1936,11 @@ if(NOT HAVE_SDL_FILESYSTEM) file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/dummy/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${FILESYSTEM_SOURCES}) endif() +if(NOT HAVE_SDL_LOCALE) + set(SDL_LOCALE_DISABLED 1) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/dummy/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${LOCALE_SOURCES}) +endif() # We always need to have threads and timers around if(NOT HAVE_SDL_THREADS) diff --git a/Makefile.in b/Makefile.in index 7982fc34bd95b..2e7db2cdb3960 100644 --- a/Makefile.in +++ b/Makefile.in @@ -82,6 +82,7 @@ HDRS = \ SDL_keyboard.h \ SDL_keycode.h \ SDL_loadso.h \ + SDL_locale.h \ SDL_log.h \ SDL_main.h \ SDL_messagebox.h \ diff --git a/Makefile.os2 b/Makefile.os2 index 444ab329e0c03..9e9af64a55735 100644 --- a/Makefile.os2 +++ b/Makefile.os2 @@ -60,6 +60,8 @@ SRCS+= SDL_dummysensor.c SRCS+= SDL_dynapi.c +SRCS+= SDL_locale.c SDL_syslocale.c + OBJS = $(SRCS:.c=.obj) MOBJS= $(MSRCS:.c=.obj) @@ -68,7 +70,7 @@ MOBJS= $(MSRCS:.c=.obj) .c: ./src;./src/dynapi;./src/audio;./src/cpuinfo;./src/events;./src/file;./src/haptic;./src/joystick;./src/power;./src/render;./src/render/software;./src/sensor;./src/stdlib;./src/thread;./src/timer;./src/video;./src/video/yuv2rgb;./src/atomic;./src/audio/disk; .c: ./src/haptic/dummy;./src/joystick/dummy;./src/audio/dummy;./src/video/dummy;./src/sensor/dummy; -.c: ./src/loadso/dummy;./src/filesystem/dummy;./src/timer/dummy;./src/thread/generic; +.c: ./src/loadso/dummy;./src/filesystem/dummy;./src/timer/dummy;./src/thread/generic;./src/locale/unix all: $(DLLFILE) $(LIBFILE) .symbolic diff --git a/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj b/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj index 79857af269a96..07e82ecffbfbf 100644 --- a/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj +++ b/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj @@ -52,6 +52,7 @@ + @@ -118,6 +119,7 @@ + @@ -249,6 +251,8 @@ + + diff --git a/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters b/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters index cb13cee45c38e..14619dd03dc31 100644 --- a/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters +++ b/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters @@ -84,6 +84,9 @@ Header Files + + Header Files + Header Files @@ -321,6 +324,9 @@ Source Files + + Source Files + Source Files @@ -614,6 +620,12 @@ Source Files + + Source Files + + + Source Files + Source Files diff --git a/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj b/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj index 0e9047e11e6f7..cb4229cf99df4 100644 --- a/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj +++ b/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj @@ -44,6 +44,7 @@ + @@ -124,6 +125,7 @@ + @@ -245,6 +247,8 @@ + + diff --git a/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters b/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters index 5925b8bcd1183..8d6a824532f39 100644 --- a/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters +++ b/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters @@ -84,6 +84,9 @@ Header Files + + Header Files + Header Files @@ -306,6 +309,9 @@ Source Files + + Source Files + Source Files @@ -578,6 +584,12 @@ Source Files + + Source Files + + + Source Files + Source Files diff --git a/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj b/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj index 1346c6d437d9b..e0c933b11b22c 100644 --- a/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj +++ b/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj @@ -52,6 +52,7 @@ + @@ -139,6 +140,7 @@ + @@ -277,6 +279,8 @@ + + diff --git a/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters b/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters index f72a82deff775..1227e88924fd0 100644 --- a/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters +++ b/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters @@ -84,6 +84,9 @@ Header Files + + Header Files + Header Files @@ -306,6 +309,9 @@ Source Files + + Source Files + Source Files @@ -596,6 +602,12 @@ Source Files + + Source Files + + + Source Files + Source Files diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj index 701ad2b964b16..0a14b89c1f273 100644 --- a/VisualC/SDL/SDL.vcxproj +++ b/VisualC/SDL/SDL.vcxproj @@ -239,6 +239,7 @@ + @@ -331,6 +332,7 @@ + @@ -463,6 +465,8 @@ + + diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters index 9f68a1629bcdc..af4c6b28af18c 100644 --- a/VisualC/SDL/SDL.vcxproj.filters +++ b/VisualC/SDL/SDL.vcxproj.filters @@ -84,6 +84,9 @@ API Headers + + API Headers + API Headers @@ -269,6 +272,7 @@ + @@ -401,6 +405,8 @@ + + diff --git a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj index 988277a2f4d2b..18258d2f659c4 100755 --- a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj @@ -343,6 +343,22 @@ 55FFA91A2122302B00D7CBED /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = 55FFA9192122302B00D7CBED /* SDL_syspower.h */; }; 566726451DF72CF5001DD3DB /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = 566726431DF72CF5001DD3DB /* SDL_dataqueue.c */; }; 566726461DF72CF5001DD3DB /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 566726441DF72CF5001DD3DB /* SDL_dataqueue.h */; }; + 566E26EE2462770300718109 /* SDL_locale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26ED2462770300718109 /* SDL_locale.h */; }; + 566E26EF2462770300718109 /* SDL_locale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26ED2462770300718109 /* SDL_locale.h */; }; + 566E26F02462770300718109 /* SDL_locale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26ED2462770300718109 /* SDL_locale.h */; }; + 566E26F12462770300718109 /* SDL_locale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26ED2462770300718109 /* SDL_locale.h */; }; + 566E26F22462770300718109 /* SDL_locale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26ED2462770300718109 /* SDL_locale.h */; }; + 566E26F82462774E00718109 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26F42462774E00718109 /* SDL_syslocale.h */; }; + 566E26F92462774E00718109 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26F42462774E00718109 /* SDL_syslocale.h */; }; + 566E26FA2462774E00718109 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26F42462774E00718109 /* SDL_syslocale.h */; }; + 566E26FD2462774E00718109 /* SDL_syslocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 566E26F62462774E00718109 /* SDL_syslocale.m */; }; + 566E26FE2462774E00718109 /* SDL_syslocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 566E26F62462774E00718109 /* SDL_syslocale.m */; }; + 566E26FF2462774E00718109 /* SDL_syslocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 566E26F62462774E00718109 /* SDL_syslocale.m */; }; + 566E27002462774E00718109 /* SDL_syslocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 566E26F62462774E00718109 /* SDL_syslocale.m */; }; + 566E27032462774E00718109 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26F72462774E00718109 /* SDL_locale.c */; }; + 566E27042462774E00718109 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26F72462774E00718109 /* SDL_locale.c */; }; + 566E27052462774E00718109 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26F72462774E00718109 /* SDL_locale.c */; }; + 566E27062462774E00718109 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26F72462774E00718109 /* SDL_locale.c */; }; 56A6702E18565E450007D20F /* SDL_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 56A6702D18565E450007D20F /* SDL_internal.h */; }; 56A6703518565E760007D20F /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = 56A6703118565E760007D20F /* SDL_dynapi_overrides.h */; }; 56A6703618565E760007D20F /* SDL_dynapi_procs.h in Headers */ = {isa = PBXBuildFile; fileRef = 56A6703218565E760007D20F /* SDL_dynapi_procs.h */; }; @@ -982,6 +998,10 @@ 55FFA9192122302B00D7CBED /* SDL_syspower.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_syspower.h; sourceTree = ""; }; 566726431DF72CF5001DD3DB /* SDL_dataqueue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_dataqueue.c; sourceTree = ""; }; 566726441DF72CF5001DD3DB /* SDL_dataqueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dataqueue.h; sourceTree = ""; }; + 566E26ED2462770300718109 /* SDL_locale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_locale.h; sourceTree = ""; }; + 566E26F42462774E00718109 /* SDL_syslocale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_syslocale.h; path = locale/SDL_syslocale.h; sourceTree = ""; }; + 566E26F62462774E00718109 /* SDL_syslocale.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_syslocale.m; sourceTree = ""; }; + 566E26F72462774E00718109 /* SDL_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_locale.c; path = locale/SDL_locale.c; sourceTree = ""; }; 56A6702D18565E450007D20F /* SDL_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_internal.h; sourceTree = ""; }; 56A6703118565E760007D20F /* SDL_dynapi_overrides.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dynapi_overrides.h; sourceTree = ""; }; 56A6703218565E760007D20F /* SDL_dynapi_procs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dynapi_procs.h; sourceTree = ""; }; @@ -1384,6 +1404,25 @@ name = Frameworks; sourceTree = ""; }; + 566E26F32462773A00718109 /* locale */ = { + isa = PBXGroup; + children = ( + 566E26F52462774E00718109 /* macosx */, + 566E26F72462774E00718109 /* SDL_locale.c */, + 566E26F42462774E00718109 /* SDL_syslocale.h */, + ); + name = locale; + sourceTree = ""; + }; + 566E26F52462774E00718109 /* macosx */ = { + isa = PBXGroup; + children = ( + 566E26F62462774E00718109 /* SDL_syslocale.m */, + ); + name = macosx; + path = locale/macosx; + sourceTree = ""; + }; 56A6702F18565E4F0007D20F /* dynapi */ = { isa = PBXGroup; children = ( @@ -1656,6 +1695,7 @@ AA7558781595D55500BBD41B /* SDL_keyboard.h */, AA7558791595D55500BBD41B /* SDL_keycode.h */, AA75587A1595D55500BBD41B /* SDL_loadso.h */, + 566E26ED2462770300718109 /* SDL_locale.h */, AA75587B1595D55500BBD41B /* SDL_log.h */, AA75587C1595D55500BBD41B /* SDL_main.h */, AA9FF9501637C6E5000DF050 /* SDL_messagebox.h */, @@ -1708,6 +1748,7 @@ F35CEA6E20F51B7F003ECE98 /* hidapi */, FD5F9D080E0E08B3008E885B /* joystick */, FD8BD8150E27E25900B52CD5 /* loadso */, + 566E26F32462773A00718109 /* locale */, F3E3C65322406963007D243C /* main */, 56ED04DE118A8E9A00A56AA6 /* power */, 041B2CE312FA0F680087D585 /* render */, @@ -1968,9 +2009,11 @@ 52ED1DA2222889500061FCE0 /* SDL_audio.h in Headers */, 52ED1DA3222889500061FCE0 /* SDL_syspower.h in Headers */, 52ED1DA4222889500061FCE0 /* SDL_blendmode.h in Headers */, + 566E26F92462774E00718109 /* SDL_syslocale.h in Headers */, 52ED1DA5222889500061FCE0 /* SDL_sensor_c.h in Headers */, 52ED1DA6222889500061FCE0 /* SDL_clipboard.h in Headers */, 52ED1DA7222889500061FCE0 /* SDL_config_iphoneos.h in Headers */, + 566E26EF2462770300718109 /* SDL_locale.h in Headers */, 52ED1DA8222889500061FCE0 /* SDL_config.h in Headers */, 52ED1DA9222889500061FCE0 /* SDL_copying.h in Headers */, 52ED1DAA222889500061FCE0 /* SDL_egl_c.h in Headers */, @@ -2043,6 +2086,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 566E26F12462770300718109 /* SDL_locale.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2106,9 +2150,11 @@ F3E3C6902241389A007D243C /* SDL_audio.h in Headers */, F3E3C6912241389A007D243C /* SDL_syspower.h in Headers */, F3E3C6922241389A007D243C /* SDL_blendmode.h in Headers */, + 566E26FA2462774E00718109 /* SDL_syslocale.h in Headers */, F3E3C6932241389A007D243C /* SDL_sensor_c.h in Headers */, F3E3C6942241389A007D243C /* SDL_clipboard.h in Headers */, F3E3C6952241389A007D243C /* SDL_config_iphoneos.h in Headers */, + 566E26F02462770300718109 /* SDL_locale.h in Headers */, F3E3C6962241389A007D243C /* SDL_config.h in Headers */, F3E3C6972241389A007D243C /* SDL_copying.h in Headers */, F3E3C6982241389A007D243C /* SDL_egl_c.h in Headers */, @@ -2181,6 +2227,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 566E26F22462770300718109 /* SDL_locale.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2260,6 +2307,7 @@ AA7558A61595D55500BBD41B /* SDL_gesture.h in Headers */, AA7558A71595D55500BBD41B /* SDL_haptic.h in Headers */, AA7558A81595D55500BBD41B /* SDL_hints.h in Headers */, + 566E26F82462774E00718109 /* SDL_syslocale.h in Headers */, 566726461DF72CF5001DD3DB /* SDL_dataqueue.h in Headers */, F30D9C9F212CD0990047DF2E /* SDL_syssensor.h in Headers */, AA7558AA1595D55500BBD41B /* SDL_joystick.h in Headers */, @@ -2290,6 +2338,7 @@ AA7558BE1595D55500BBD41B /* SDL_scancode.h in Headers */, AA7558BF1595D55500BBD41B /* SDL_shape.h in Headers */, AA7558C01595D55500BBD41B /* SDL_stdinc.h in Headers */, + 566E26EE2462770300718109 /* SDL_locale.h in Headers */, FAD4F7021BA3C4E8008346CE /* SDL_sysjoystick_c.h in Headers */, AA7558C11595D55500BBD41B /* SDL_surface.h in Headers */, AA7558C21595D55500BBD41B /* SDL_system.h in Headers */, @@ -2539,6 +2588,7 @@ 52ED1DFC222889500061FCE0 /* SDL_rwops.c in Sources */, 52ED1DFD222889500061FCE0 /* hid.m in Sources */, 52ED1DFE222889500061FCE0 /* SDL_vulkan_utils.c in Sources */, + 566E27042462774E00718109 /* SDL_locale.c in Sources */, 52ED1DFF222889500061FCE0 /* SDL_error.c in Sources */, 52ED1E00222889500061FCE0 /* SDL.c in Sources */, 52ED1E01222889500061FCE0 /* SDL_syscond.c in Sources */, @@ -2550,6 +2600,7 @@ 52ED1E07222889500061FCE0 /* SDL_getenv.c in Sources */, 52ED1E08222889500061FCE0 /* SDL_iconv.c in Sources */, 52ED1E09222889500061FCE0 /* SDL_malloc.c in Sources */, + 566E26FE2462774E00718109 /* SDL_syslocale.m in Sources */, A7FF6B6323AC3BC6005876C6 /* SDL_hidapi_gamecube.c in Sources */, 52ED1E0A222889500061FCE0 /* SDL_hidapi_xbox360.c in Sources */, 52ED1E0B222889500061FCE0 /* SDL_qsort.c in Sources */, @@ -2673,6 +2724,7 @@ F3E3C6EA2241389A007D243C /* SDL_rwops.c in Sources */, F3E3C6EB2241389A007D243C /* hid.m in Sources */, F3E3C6EC2241389A007D243C /* SDL_vulkan_utils.c in Sources */, + 566E27062462774E00718109 /* SDL_locale.c in Sources */, F3E3C6ED2241389A007D243C /* SDL_error.c in Sources */, F3E3C6EE2241389A007D243C /* SDL.c in Sources */, F3E3C6EF2241389A007D243C /* SDL_syscond.c in Sources */, @@ -2684,6 +2736,7 @@ F3E3C6F52241389A007D243C /* SDL_getenv.c in Sources */, F3E3C6F62241389A007D243C /* SDL_iconv.c in Sources */, F3E3C6F72241389A007D243C /* SDL_malloc.c in Sources */, + 566E27002462774E00718109 /* SDL_syslocale.m in Sources */, A7FF6B6523AC3BC6005876C6 /* SDL_hidapi_gamecube.c in Sources */, F3E3C6F82241389A007D243C /* SDL_hidapi_xbox360.c in Sources */, F3E3C6F92241389A007D243C /* SDL_qsort.c in Sources */, @@ -2847,7 +2900,9 @@ FAB598731BB5C31600BE72C5 /* SDL_iconv.c in Sources */, FAB598741BB5C31600BE72C5 /* SDL_malloc.c in Sources */, FAB598751BB5C31600BE72C5 /* SDL_qsort.c in Sources */, + 566E27052462774E00718109 /* SDL_locale.c in Sources */, F36839CE214790950000F255 /* SDL_dummysensor.c in Sources */, + 566E26FF2462774E00718109 /* SDL_syslocale.m in Sources */, A7C19D2B212E552C00DF2152 /* SDL_displayevents.c in Sources */, FAB598761BB5C31600BE72C5 /* SDL_stdlib.c in Sources */, FAB598771BB5C31600BE72C5 /* SDL_string.c in Sources */, @@ -2931,6 +2986,7 @@ FD6526760DE8FCDD002AD96B /* SDL_rwops.c in Sources */, F30D9CC6212CE92C0047DF2E /* hid.m in Sources */, 4D7517201EE1D98200820EEA /* SDL_vulkan_utils.c in Sources */, + 566E27032462774E00718109 /* SDL_locale.c in Sources */, FD6526780DE8FCDD002AD96B /* SDL_error.c in Sources */, FD65267A0DE8FCDD002AD96B /* SDL.c in Sources */, FD65267B0DE8FCDD002AD96B /* SDL_syscond.c in Sources */, @@ -2942,6 +2998,7 @@ FD3F4A760DEA620800C5B771 /* SDL_getenv.c in Sources */, FD3F4A770DEA620800C5B771 /* SDL_iconv.c in Sources */, FD3F4A780DEA620800C5B771 /* SDL_malloc.c in Sources */, + 566E26FD2462774E00718109 /* SDL_syslocale.m in Sources */, A7FF6B6223AC3BC6005876C6 /* SDL_hidapi_gamecube.c in Sources */, F3BDD79220F51CB8004ECBF3 /* SDL_hidapi_xbox360.c in Sources */, FD3F4A790DEA620800C5B771 /* SDL_qsort.c in Sources */, diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj index ee5f06da5411c..cc1c883747c9c 100755 --- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -17,6 +17,10 @@ 564624381FF821DA0074AC87 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624371FF821CB0074AC87 /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 5646243B1FF822100074AC87 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624351FF821B80074AC87 /* QuartzCore.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 5646243C1FF822170074AC87 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624371FF821CB0074AC87 /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 566E267A2462701100718109 /* SDL_locale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26792462701100718109 /* SDL_locale.h */; }; + 566E26CF246274CC00718109 /* SDL_syslocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CC246274CB00718109 /* SDL_syslocale.m */; }; + 566E26D8246274CC00718109 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CD246274CB00718109 /* SDL_locale.c */; }; + 566E26E1246274CC00718109 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26CE246274CC00718109 /* SDL_syslocale.h */; }; 567E2F2117C44C35005F1892 /* SDL_filesystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 567E2F2017C44C35005F1892 /* SDL_filesystem.h */; settings = {ATTRIBUTES = (Public, ); }; }; 56C5237F1D8F4985001F2F30 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; }; 56C523811D8F498C001F2F30 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; }; @@ -3983,6 +3987,10 @@ 4D4820431F0F10B400EDC31C /* SDL_vulkan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_vulkan.h; sourceTree = ""; }; 564624351FF821B80074AC87 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 564624371FF821CB0074AC87 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; + 566E26792462701100718109 /* SDL_locale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_locale.h; sourceTree = ""; }; + 566E26CC246274CB00718109 /* SDL_syslocale.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDL_syslocale.m; path = locale/macosx/SDL_syslocale.m; sourceTree = ""; }; + 566E26CD246274CB00718109 /* SDL_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_locale.c; path = locale/SDL_locale.c; sourceTree = ""; }; + 566E26CE246274CC00718109 /* SDL_syslocale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_syslocale.h; path = locale/SDL_syslocale.h; sourceTree = ""; }; 567E2F2017C44C35005F1892 /* SDL_filesystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_filesystem.h; sourceTree = ""; }; 5C2EF7001FC9EF0F003F5197 /* SDL_egl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_egl.h; sourceTree = ""; }; 75E09158241EA924004729E1 /* SDL_virtualjoystick.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_virtualjoystick.c; sourceTree = ""; }; @@ -4662,6 +4670,7 @@ AA7557DA1595D4D800BBD41B /* SDL_keyboard.h */, AA7557DB1595D4D800BBD41B /* SDL_keycode.h */, AA7557DC1595D4D800BBD41B /* SDL_loadso.h */, + 566E26792462701100718109 /* SDL_locale.h */, AA7557DD1595D4D800BBD41B /* SDL_log.h */, AA7557DE1595D4D800BBD41B /* SDL_main.h */, AA9FF9591637CBF9000DF050 /* SDL_messagebox.h */, @@ -4760,6 +4769,7 @@ A7D8A79D23E2513E00DCD162 /* joystick */, A7D8A91123E2514000DCD162 /* libm */, A7D8A85D23E2513F00DCD162 /* loadso */, + 566E26CB246274AE00718109 /* locale */, A7D8A5AC23E2513D00DCD162 /* main */, A7D8A7DF23E2513F00DCD162 /* power */, A7D8A8DA23E2514000DCD162 /* render */, @@ -4826,6 +4836,24 @@ name = Frameworks; sourceTree = ""; }; + 566E26CB246274AE00718109 /* locale */ = { + isa = PBXGroup; + children = ( + 566E26EA246274E800718109 /* macosx */, + 566E26CD246274CB00718109 /* SDL_locale.c */, + 566E26CE246274CC00718109 /* SDL_syslocale.h */, + ); + name = locale; + sourceTree = ""; + }; + 566E26EA246274E800718109 /* macosx */ = { + isa = PBXGroup; + children = ( + 566E26CC246274CB00718109 /* SDL_syslocale.m */, + ); + name = macosx; + sourceTree = ""; + }; 75E09157241EA924004729E1 /* virtual */ = { isa = PBXGroup; children = ( @@ -5734,6 +5762,7 @@ A75FCD2323E25AB700529352 /* SDL_uikitmessagebox.h in Headers */, A75FCD2423E25AB700529352 /* SDL_x11messagebox.h in Headers */, A75FCD2523E25AB700529352 /* SDL_thread_c.h in Headers */, + 566E26812462701100718109 /* SDL_locale.h in Headers */, A75FCD2623E25AB700529352 /* SDL_cocoamessagebox.h in Headers */, A75FCD2723E25AB700529352 /* SDL_x11shape.h in Headers */, A75FCD2823E25AB700529352 /* SDL_cpuinfo.h in Headers */, @@ -5816,6 +5845,7 @@ A75FCD7323E25AB700529352 /* SDL_yuv_c.h in Headers */, A75FCD7423E25AB700529352 /* scancodes_xfree86.h in Headers */, A75FCD7523E25AB700529352 /* SDL_syspower.h in Headers */, + 566E26E8246274CC00718109 /* SDL_syslocale.h in Headers */, A75FDAFA23E35ED600529352 /* SDL_config_iphoneos.h in Headers */, A75FCD7623E25AB700529352 /* SDL_x11clipboard.h in Headers */, A75FCD7723E25AB700529352 /* SDL_name.h in Headers */, @@ -5975,6 +6005,7 @@ A75FCEDC23E25AC700529352 /* SDL_uikitmessagebox.h in Headers */, A75FCEDD23E25AC700529352 /* SDL_x11messagebox.h in Headers */, A75FCEDE23E25AC700529352 /* SDL_thread_c.h in Headers */, + 566E26822462701100718109 /* SDL_locale.h in Headers */, A75FCEDF23E25AC700529352 /* SDL_cocoamessagebox.h in Headers */, A75FCEE023E25AC700529352 /* SDL_x11shape.h in Headers */, A75FCEE123E25AC700529352 /* SDL_cpuinfo.h in Headers */, @@ -6057,6 +6088,7 @@ A75FCF2C23E25AC700529352 /* SDL_yuv_c.h in Headers */, A75FCF2D23E25AC700529352 /* scancodes_xfree86.h in Headers */, A75FCF2E23E25AC700529352 /* SDL_syspower.h in Headers */, + 566E26E9246274CC00718109 /* SDL_syslocale.h in Headers */, A75FDAFB23E35ED700529352 /* SDL_config_iphoneos.h in Headers */, A75FCF2F23E25AC700529352 /* SDL_x11clipboard.h in Headers */, A75FCF3023E25AC700529352 /* SDL_name.h in Headers */, @@ -6240,6 +6272,7 @@ A769B0AA23E259AE00872273 /* SDL_uikitmessagebox.h in Headers */, A769B0AB23E259AE00872273 /* SDL_x11messagebox.h in Headers */, A769B0AC23E259AE00872273 /* SDL_thread_c.h in Headers */, + 566E267F2462701100718109 /* SDL_locale.h in Headers */, A769B0AD23E259AE00872273 /* SDL_cocoamessagebox.h in Headers */, A769B0AE23E259AE00872273 /* SDL_x11shape.h in Headers */, A769B0AF23E259AE00872273 /* SDL_cpuinfo.h in Headers */, @@ -6322,6 +6355,7 @@ A769B0FB23E259AE00872273 /* SDL_yuv_c.h in Headers */, A769B0FC23E259AE00872273 /* scancodes_xfree86.h in Headers */, A769B0FD23E259AE00872273 /* SDL_syspower.h in Headers */, + 566E26E6246274CC00718109 /* SDL_syslocale.h in Headers */, A75FDAF923E35ED500529352 /* SDL_config_iphoneos.h in Headers */, A769B0FE23E259AE00872273 /* SDL_x11clipboard.h in Headers */, A769B0FF23E259AE00872273 /* SDL_name.h in Headers */, @@ -6638,10 +6672,12 @@ A7D8B39923E2514200DCD162 /* SDL_blit_copy.h in Headers */, A7D8B22B23E2514200DCD162 /* gl2.h in Headers */, A7D88A5023E2437C00DCD162 /* SDL_shape.h in Headers */, + 566E26E2246274CC00718109 /* SDL_syslocale.h in Headers */, A7D88A5123E2437C00DCD162 /* SDL_stdinc.h in Headers */, A7D8ACCA23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */, A7D8BBB823E254E400DCD162 /* SDL_sysjoystick_c.h in Headers */, A7D8B3B123E2514200DCD162 /* SDL_yuv_c.h in Headers */, + 566E267B2462701100718109 /* SDL_locale.h in Headers */, A7D8B1F523E2514200DCD162 /* SDL_x11dyn.h in Headers */, A7D8AC8823E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */, A7D8AC0A23E2514100DCD162 /* SDL_shape_internals.h in Headers */, @@ -6882,10 +6918,12 @@ A7D88C0823E24BED00DCD162 /* SDL_scancode.h in Headers */, A7D8B39A23E2514200DCD162 /* SDL_blit_copy.h in Headers */, A7D8B22C23E2514200DCD162 /* gl2.h in Headers */, + 566E26E3246274CC00718109 /* SDL_syslocale.h in Headers */, A7D88C0A23E24BED00DCD162 /* SDL_shape.h in Headers */, A7D88C0C23E24BED00DCD162 /* SDL_stdinc.h in Headers */, A7D8ACCB23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */, A7D8B3B223E2514200DCD162 /* SDL_yuv_c.h in Headers */, + 566E267C2462701100718109 /* SDL_locale.h in Headers */, A7D8B1F623E2514200DCD162 /* SDL_x11dyn.h in Headers */, A7D8AC8923E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */, A7D8AC0B23E2514100DCD162 /* SDL_shape_internals.h in Headers */, @@ -6969,6 +7007,7 @@ A7D8AC9723E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */, A7D8B15023E2514200DCD162 /* SDL_x11messagebox.h in Headers */, A7D8B3F023E2514300DCD162 /* SDL_thread_c.h in Headers */, + 566E267E2462701100718109 /* SDL_locale.h in Headers */, A7D8AF0A23E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, A7D8B16823E2514200DCD162 /* SDL_x11shape.h in Headers */, A7D88D2723E24D3B00DCD162 /* SDL_cpuinfo.h in Headers */, @@ -7051,6 +7090,7 @@ A7D8B3B423E2514200DCD162 /* SDL_yuv_c.h in Headers */, A7D8BBA323E2514500DCD162 /* scancodes_xfree86.h in Headers */, A7D8B5D923E2514300DCD162 /* SDL_syspower.h in Headers */, + 566E26E5246274CC00718109 /* SDL_syslocale.h in Headers */, A75FDAF823E35ED500529352 /* SDL_config_iphoneos.h in Headers */, A7D8B21023E2514200DCD162 /* SDL_x11clipboard.h in Headers */, A7D88D3923E24D3B00DCD162 /* SDL_name.h in Headers */, @@ -7185,6 +7225,7 @@ A7D8BBE023E2574800DCD162 /* SDL_uikitopenglview.h in Headers */, A7D8B4AC23E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */, A7D8B9EF23E2514400DCD162 /* SDL_drawpoint.h in Headers */, + 566E26E1246274CC00718109 /* SDL_syslocale.h in Headers */, A7D8B39E23E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, A7D8B44023E2514300DCD162 /* SDL_sysmutex_c.h in Headers */, A7D8BA4323E2514400DCD162 /* SDL_glesfuncs.h in Headers */, @@ -7321,6 +7362,7 @@ A7D8BB9F23E2514500DCD162 /* scancodes_xfree86.h in Headers */, A7D8BBE623E2574800DCD162 /* SDL_uikitviewcontroller.h in Headers */, A7D8AF1E23E2514100DCD162 /* SDL_cocoamouse.h in Headers */, + 566E267A2462701100718109 /* SDL_locale.h in Headers */, A7D8BBEA23E2574800DCD162 /* SDL_uikitwindow.h in Headers */, A7D8AE8E23E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, A7D8BA4F23E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, @@ -7484,6 +7526,7 @@ A7D8BA7623E2514400DCD162 /* SDL_shaders_gl.h in Headers */, A7D8B42B23E2514300DCD162 /* SDL_systhread_c.h in Headers */, AA7558231595D4D800BBD41B /* SDL_keycode.h in Headers */, + 566E26E4246274CC00718109 /* SDL_syslocale.h in Headers */, A7D8B20923E2514200DCD162 /* SDL_x11keyboard.h in Headers */, A7D8AE9123E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, A7D8B1F123E2514200DCD162 /* SDL_x11framebuffer.h in Headers */, @@ -7552,6 +7595,7 @@ A7D8BB6023E2514500DCD162 /* scancodes_linux.h in Headers */, A7D8B1F723E2514200DCD162 /* SDL_x11dyn.h in Headers */, A7D8BB6623E2514500DCD162 /* SDL_touch_c.h in Headers */, + 566E267D2462701100718109 /* SDL_locale.h in Headers */, A7D8B4AF23E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */, A7D8AEEB23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, A7D8B23323E2514200DCD162 /* gl2platform.h in Headers */, @@ -7724,6 +7768,7 @@ A7D8BBB023E2514500DCD162 /* SDL_windowevents_c.h in Headers */, DB313FD917554B71006C0E22 /* SDL_joystick.h in Headers */, A7D8AF0523E2514100DCD162 /* SDL_cocoavideo.h in Headers */, + 566E26E7246274CC00718109 /* SDL_syslocale.h in Headers */, DB313FDA17554B71006C0E22 /* SDL_keyboard.h in Headers */, A7D8ACC223E2514100DCD162 /* SDL_uikitevents.h in Headers */, A7D8BB3E23E2514500DCD162 /* SDL_gesture_c.h in Headers */, @@ -7792,6 +7837,7 @@ A7D8AC0223E2514100DCD162 /* SDL_nullevents_c.h in Headers */, A7D8B58623E2514300DCD162 /* SDL_sysjoystick.h in Headers */, A7D8BBCF23E2561600DCD162 /* SDL_steamcontroller.h in Headers */, + 566E26802462701100718109 /* SDL_locale.h in Headers */, A7D8BB6223E2514500DCD162 /* scancodes_linux.h in Headers */, A7D8B1F923E2514200DCD162 /* SDL_x11dyn.h in Headers */, A7D8BB6823E2514500DCD162 /* SDL_touch_c.h in Headers */, @@ -8393,6 +8439,7 @@ A75FCE2C23E25AB700529352 /* SDL_cocoakeyboard.m in Sources */, A75FCE2D23E25AB700529352 /* SDL_dynapi.c in Sources */, A75FCE2E23E25AB700529352 /* SDL_shaders_gl.c in Sources */, + 566E26DF246274CC00718109 /* SDL_locale.c in Sources */, A75FCE2F23E25AB700529352 /* e_log.c in Sources */, A75FCE3023E25AB700529352 /* SDL_cocoamessagebox.m in Sources */, A75FCE3123E25AB700529352 /* SDL_blendfillrect.c in Sources */, @@ -8465,6 +8512,7 @@ A75FCE7523E25AB700529352 /* SDL_rect.c in Sources */, A75FCE7623E25AB700529352 /* SDL_cocoaopengles.m in Sources */, A75FCE7723E25AB700529352 /* SDL_qsort.c in Sources */, + 566E26D6246274CC00718109 /* SDL_syslocale.m in Sources */, A75FCE7823E25AB700529352 /* SDL_hidapi_switch.c in Sources */, A75FCE7923E25AB700529352 /* SDL_strtokr.c in Sources */, A75FCE7A23E25AB700529352 /* SDL_clipboardevents.c in Sources */, @@ -8589,6 +8637,7 @@ A75FCFE523E25AC700529352 /* SDL_cocoakeyboard.m in Sources */, A75FCFE623E25AC700529352 /* SDL_dynapi.c in Sources */, A75FCFE723E25AC700529352 /* SDL_shaders_gl.c in Sources */, + 566E26E0246274CC00718109 /* SDL_locale.c in Sources */, A75FCFE823E25AC700529352 /* e_log.c in Sources */, A75FCFE923E25AC700529352 /* SDL_cocoamessagebox.m in Sources */, A75FCFEA23E25AC700529352 /* SDL_blendfillrect.c in Sources */, @@ -8661,6 +8710,7 @@ A75FD02E23E25AC700529352 /* SDL_rect.c in Sources */, A75FD02F23E25AC700529352 /* SDL_cocoaopengles.m in Sources */, A75FD03023E25AC700529352 /* SDL_qsort.c in Sources */, + 566E26D7246274CC00718109 /* SDL_syslocale.m in Sources */, A75FD03123E25AC700529352 /* SDL_hidapi_switch.c in Sources */, A75FD03223E25AC700529352 /* SDL_strtokr.c in Sources */, A75FD03323E25AC700529352 /* SDL_clipboardevents.c in Sources */, @@ -8879,12 +8929,14 @@ A769B1FD23E259AE00872273 /* SDL_blit_auto.c in Sources */, A769B1FE23E259AE00872273 /* SDL_x11keyboard.c in Sources */, A769B1FF23E259AE00872273 /* SDL_keyboard.c in Sources */, + 566E26DD246274CC00718109 /* SDL_locale.c in Sources */, A769B20123E259AE00872273 /* SDL_rect.c in Sources */, A769B20223E259AE00872273 /* SDL_cocoaopengles.m in Sources */, A769B20323E259AE00872273 /* SDL_qsort.c in Sources */, A75FDB5223E39D1700529352 /* hid.m in Sources */, A769B20423E259AE00872273 /* SDL_hidapi_switch.c in Sources */, A769B20523E259AE00872273 /* SDL_strtokr.c in Sources */, + 566E26D4246274CC00718109 /* SDL_syslocale.m in Sources */, A769B20623E259AE00872273 /* SDL_clipboardevents.c in Sources */, A769B20723E259AE00872273 /* SDL_x11framebuffer.c in Sources */, A769B20823E259AE00872273 /* k_cos.c in Sources */, @@ -9097,10 +9149,12 @@ A7D8AAB123E2514100DCD162 /* SDL_syshaptic.c in Sources */, A7D8B5CA23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, A7D8AC1023E2514100DCD162 /* SDL_video.c in Sources */, + 566E26D0246274CC00718109 /* SDL_syslocale.m in Sources */, A7D8AB5623E2514100DCD162 /* SDL_offscreenopengl.c in Sources */, A7D8ACC423E2514100DCD162 /* SDL_uikitmetalview.m in Sources */, A7D8BA5C23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, A7D8B14123E2514200DCD162 /* SDL_blit_1.c in Sources */, + 566E26D9246274CC00718109 /* SDL_locale.c in Sources */, A7D8B17D23E2514200DCD162 /* SDL_x11dyn.c in Sources */, A7D8BB1623E2514500DCD162 /* SDL_mouse.c in Sources */, A7D8BADA23E2514500DCD162 /* e_rem_pio2.c in Sources */, @@ -9292,10 +9346,12 @@ A7D8AAB223E2514100DCD162 /* SDL_syshaptic.c in Sources */, A7D8B5CB23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, A7D8AC1123E2514100DCD162 /* SDL_video.c in Sources */, + 566E26D1246274CC00718109 /* SDL_syslocale.m in Sources */, A7D8AB5723E2514100DCD162 /* SDL_offscreenopengl.c in Sources */, A7D8ACC523E2514100DCD162 /* SDL_uikitmetalview.m in Sources */, A7D8BA5D23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, A7D8B14223E2514200DCD162 /* SDL_blit_1.c in Sources */, + 566E26DA246274CC00718109 /* SDL_locale.c in Sources */, A7D8B17E23E2514200DCD162 /* SDL_x11dyn.c in Sources */, A7D8BB1723E2514500DCD162 /* SDL_mouse.c in Sources */, A7D8BADB23E2514500DCD162 /* e_rem_pio2.c in Sources */, @@ -9466,12 +9522,14 @@ A7D8AD2723E2514100DCD162 /* SDL_blit_auto.c in Sources */, A7D8B1AA23E2514200DCD162 /* SDL_x11keyboard.c in Sources */, A7D8BB6D23E2514500DCD162 /* SDL_keyboard.c in Sources */, + 566E26DC246274CC00718109 /* SDL_locale.c in Sources */, A7D8ACEB23E2514100DCD162 /* SDL_rect.c in Sources */, A7D8AE9E23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */, A7D8B96C23E2514400DCD162 /* SDL_qsort.c in Sources */, A75FDB5123E39D1700529352 /* hid.m in Sources */, A7D8B55523E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, A7D8B96623E2514400DCD162 /* SDL_strtokr.c in Sources */, + 566E26D3246274CC00718109 /* SDL_syslocale.m in Sources */, A7D8BB7923E2514500DCD162 /* SDL_clipboardevents.c in Sources */, A7D8B18623E2514200DCD162 /* SDL_x11framebuffer.c in Sources */, A7D8BAB923E2514400DCD162 /* k_cos.c in Sources */, @@ -9635,6 +9693,7 @@ A7D8BB0923E2514500DCD162 /* k_tan.c in Sources */, A7D8B15E23E2514200DCD162 /* SDL_x11vulkan.c in Sources */, A7D8B8A823E2514400DCD162 /* SDL_diskaudio.c in Sources */, + 566E26CF246274CC00718109 /* SDL_syslocale.m in Sources */, A7D8AFC023E2514200DCD162 /* SDL_egl.c in Sources */, A7D8AC3323E2514100DCD162 /* SDL_RLEaccel.c in Sources */, A7D8BBB123E2514500DCD162 /* SDL_assert.c in Sources */, @@ -9706,6 +9765,7 @@ A7D8B15823E2514200DCD162 /* SDL_x11opengl.c in Sources */, A7D8AEA023E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, A7D8AB6123E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, + 566E26D8246274CC00718109 /* SDL_locale.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -9805,6 +9865,7 @@ A7D8B5F623E2514300DCD162 /* SDL_syspower.c in Sources */, A7D8B1C723E2514200DCD162 /* SDL_x11touch.c in Sources */, A7D8B95323E2514400DCD162 /* SDL_iconv.c in Sources */, + 566E26DB246274CC00718109 /* SDL_locale.c in Sources */, A7D8BAA023E2514400DCD162 /* s_fabs.c in Sources */, A7D8B1E523E2514200DCD162 /* SDL_x11shape.c in Sources */, A7D8BC0423E2574800DCD162 /* SDL_uikitvulkan.m in Sources */, @@ -9880,6 +9941,7 @@ A7D8AC1223E2514100DCD162 /* SDL_video.c in Sources */, A7D8AB5823E2514100DCD162 /* SDL_offscreenopengl.c in Sources */, A7D8BA5E23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, + 566E26D2246274CC00718109 /* SDL_syslocale.m in Sources */, A7D8B14323E2514200DCD162 /* SDL_blit_1.c in Sources */, A7D8B17F23E2514200DCD162 /* SDL_x11dyn.c in Sources */, A7D8BB1823E2514500DCD162 /* SDL_mouse.c in Sources */, @@ -9999,6 +10061,7 @@ A7D8B76323E2514300DCD162 /* SDL_sysloadso.c in Sources */, A7D8B16F23E2514200DCD162 /* SDL_x11xinput2.c in Sources */, A7D8B5F823E2514300DCD162 /* SDL_syspower.c in Sources */, + 566E26DE246274CC00718109 /* SDL_locale.c in Sources */, A7D8B1C923E2514200DCD162 /* SDL_x11touch.c in Sources */, A7D8B95523E2514400DCD162 /* SDL_iconv.c in Sources */, A7D8BAA223E2514400DCD162 /* s_fabs.c in Sources */, @@ -10074,6 +10137,7 @@ A7D8ACC823E2514100DCD162 /* SDL_uikitmetalview.m in Sources */, A7D8BBBA23E2560600DCD162 /* SDL_steamcontroller.c in Sources */, A7D8BA6023E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, + 566E26D5246274CC00718109 /* SDL_syslocale.m in Sources */, A7D8B14523E2514200DCD162 /* SDL_blit_1.c in Sources */, A7D8B18123E2514200DCD162 /* SDL_x11dyn.c in Sources */, A7D8BB1A23E2514500DCD162 /* SDL_mouse.c in Sources */, diff --git a/configure b/configure index 7bfdfd81aff1c..0e48c383e2bb3 100755 --- a/configure +++ b/configure @@ -770,6 +770,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -981,6 +982,7 @@ datadir='${datarootdir}' 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 @@ do | -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 @@ fi 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 @@ Fine tuning of the installation directories: --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/thread/*.c" 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 @@ CheckNoStrictAliasing 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 @@ case "$host" in 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 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h # 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 @@ -25174,6 +25196,11 @@ $as_echo "#define SDL_FILESYSTEM_HAIKU 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/filesystem/haiku/*.cc" have_filesystem=yes fi + + # Set up files for the locale library + SOURCES="$SOURCES $srcdir/src/locale/haiku/*.cc" + have_locale=yes + # The Haiku platform requires special setup. SOURCES="$srcdir/src/main/haiku/*.cc $SOURCES" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lroot -lbe -lmedia -lgame -ldevice -ltextencoding" @@ -25216,6 +25243,10 @@ fi 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 +25368,10 @@ $as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h 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 @@ -25492,6 +25527,9 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/timer/unix/*.c" have_timers=yes fi + # Set up files for the locale library + SOURCES="$SOURCES $srcdir/src/locale/emscripten/*.c" + have_locale=yes ;; *-*-riscos*) ARCH=riscos @@ -25549,6 +25587,9 @@ INSTALL_SDL2_CONFIG=$enable_sdl2_config # 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 index 574d66f2920dd..fcc5c488a1abc 100644 --- a/configure.ac +++ b/configure.ac @@ -413,6 +413,7 @@ SOURCES="$SOURCES $srcdir/src/thread/*.c" 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 @@ CheckNoStrictAliasing 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 @@ case "$host" in 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 @@ case "$host" in # 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, [ ]) @@ -3847,6 +3857,11 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau SOURCES="$SOURCES $srcdir/src/filesystem/haiku/*.cc" have_filesystem=yes fi + + # Set up files for the locale library + SOURCES="$SOURCES $srcdir/src/locale/haiku/*.cc" + have_locale=yes + # The Haiku platform requires special setup. SOURCES="$srcdir/src/main/haiku/*.cc $SOURCES" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lroot -lbe -lmedia -lgame -ldevice -ltextencoding" @@ -3867,6 +3882,10 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau 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 +3985,10 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau 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, [ ]) @@ -4093,6 +4116,9 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau SOURCES="$SOURCES $srcdir/src/timer/unix/*.c" have_timers=yes fi + # Set up files for the locale library + SOURCES="$SOURCES $srcdir/src/locale/emscripten/*.c" + have_locale=yes ;; *-*-riscos*) ARCH=riscos @@ -4141,6 +4167,9 @@ AC_SUBST([INSTALL_SDL2_CONFIG], [$enable_sdl2_config]) # 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 index 634bf4b6d3f2a..9a8f580f1ccd6 100644 --- 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_events.h b/include/SDL_events.h index 32cfbe3272f79..74cbb4b59451b 100644 --- a/include/SDL_events.h +++ b/include/SDL_events.h @@ -85,6 +85,8 @@ typedef enum Called on Android in onResume() */ + SDL_LOCALECHANGED, /**< The user's locale preferences have changed. */ + /* Display events */ SDL_DISPLAYEVENT = 0x150, /**< Display state change */ diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 28cf544a75104..44e6fd4579b1d 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -1348,6 +1348,21 @@ extern "C" { #define SDL_HINT_AUDIO_DEVICE_STREAM_NAME "SDL_AUDIO_DEVICE_STREAM_NAME" +/** + * \brief Override for SDL_GetPreferredLocales() + * + * If set, this will be favored over anything the OS might report for the + * user's preferred locales. Changing this hint at runtime will not generate + * a SDL_LOCALECHANGED event (but if you can change the hint, you can push + * your own event, if you want). + * + * The format of this hint is a comma-separated list of language and locale, + * combined with an underscore, as is a common format: "en_GB". Locale is + * optional: "en". So you might have a list like this: "en_GB,jp,es_PT" + */ +#define SDL_HINT_PREFERRED_LOCALES "SDL_PREFERRED_LOCALES" + + /** * \brief An enumeration of hint priorities */ diff --git a/include/SDL_locale.h b/include/SDL_locale.h new file mode 100644 index 0000000000000..1f4b0c469ac9b --- /dev/null +++ b/include/SDL_locale.h @@ -0,0 +1,101 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 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 + + +typedef struct SDL_Locale +{ + const char *language; /**< A language name, like "en" for English. */ + const char *country; /**< A country, like "US" for America. Can be NULL. */ +} SDL_Locale; + +/** + * \brief Report the user's preferred locale. + * + * This returns an array of SDL_Locale structs, the final item zeroed out. + * When the caller is done with this array, it should call SDL_free() on + * the returned value; all the memory involved is allocated in a single + * block, so a single SDL_free() will suffice. + * + * Returned language strings are in the format xx, where 'xx' is an ISO-639 + * language specifier (such as "en" for English, "de" for German, etc). + * Country strings are in the format YY, where "YY" is an ISO-3166 country + * code (such as "US" for the United States, "CA" for Canada, etc). Country + * might be NULL if there's no specific guidance on them (so you might get + * { "en", "US" } for American English, but { "en", NULL } means "English + * language, generically"). Language strings are never NULL, except to + * terminate the array. + * + * Please note that not all of these strings are 2 characters; some are + * three or more. + * + * The returned list of locales 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 }. + * + * This function returns NULL on error, including when the platform does not + * supply this information at all. + * + * This might be a "slow" call that has to query the operating system. It's + * best to ask for this once and save the results. However, this list can + * change, usually because the user has changed a system preference outside + * of your program; SDL will send an SDL_LOCALECHANGED event in this case, + * if possible, and you can call this function again to get an updated copy + * of preferred locales. + * + * \return array of locales, terminated with a locale with a NULL language + * field. Will return NULL on error. + */ +extern DECLSPEC SDL_Locale * SDLCALL SDL_GetPreferredLocales(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/core/android/SDL_android.c b/src/core/android/SDL_android.c index 664608705a996..c7add21dabb88 100644 --- 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,82 @@ SDL_bool Android_JNI_RequestPermission(const char *permission) return bPermissionRequestResult; } +int Android_JNI_GetLocale(char *buf, size_t buflen) +{ + 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; + } + + SDL_assert(buflen > 6); + + 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] = {}; + size_t 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]) { + buf[id++] = language[0]; + if (language[1]) { + buf[id++] = language[1]; + } + } + + buf[id++] = '_'; + + /* copy country (not null terminated) */ + if (country[0]) { + buf[id++] = country[0]; + if (country[1]) { + buf[id++] = country[1]; + } + } + + buf[id++] = '\0'; + SDL_assert(id <= buflen); + } + + 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 index 9f3f3cc7fcc3b..153105199d3d8 100644 --- a/src/core/android/SDL_android.h +++ b/src/core/android/SDL_android.h @@ -104,6 +104,9 @@ void Android_JNI_InitTouch(void); JNIEnv *Android_JNI_GetEnv(void); int Android_JNI_SetupThread(void); +/* Locale */ +int Android_JNI_GetLocale(char *buf, size_t buflen); + /* Generic messages */ int Android_JNI_SendMessage(int command, int param); diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 4474a519c6dd1..cb596aaca170c 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -763,3 +763,4 @@ #define SDL_Metal_GetDrawableSize SDL_Metal_GetDrawableSize_REAL #define SDL_trunc SDL_trunc_REAL #define SDL_truncf SDL_truncf_REAL +#define SDL_GetPreferredLocales SDL_GetPreferredLocales_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index c4822a6c89a94..b501d6998009c 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -822,3 +822,4 @@ SDL_DYNAPI_PROC(void*,SDL_Metal_GetLayer,(SDL_MetalView a),(a),return) SDL_DYNAPI_PROC(void,SDL_Metal_GetDrawableSize,(SDL_Window *a, int *b, int *c),(a,b,c),) SDL_DYNAPI_PROC(double,SDL_trunc,(double a),(a),return) SDL_DYNAPI_PROC(float,SDL_truncf,(float a),(a),return) +SDL_DYNAPI_PROC(SDL_Locale *,SDL_GetPreferredLocales,(void),(),return) diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index a6f0d24515ca0..ec9a1817ecc46 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -1009,6 +1009,12 @@ SDL_SendKeymapChangedEvent(void) return SDL_SendAppEvent(SDL_KEYMAPCHANGED); } +int +SDL_SendLocaleChangedEvent(void) +{ + return SDL_SendAppEvent(SDL_LOCALECHANGED); +} + int SDL_EventsInit(void) { diff --git a/src/events/SDL_events_c.h b/src/events/SDL_events_c.h index 2d9680cb9db9f..3c067e7282a57 100644 --- a/src/events/SDL_events_c.h +++ b/src/events/SDL_events_c.h @@ -46,6 +46,7 @@ extern void SDL_QuitInterrupt(void); extern int SDL_SendAppEvent(SDL_EventType eventType); extern int SDL_SendSysWMEvent(SDL_SysWMmsg * message); extern int SDL_SendKeymapChangedEvent(void); +extern int SDL_SendLocaleChangedEvent(void); extern int SDL_SendQuit(void); diff --git a/src/locale/SDL_locale.c b/src/locale/SDL_locale.c new file mode 100644 index 0000000000000..c7e5b1011c948 --- /dev/null +++ b/src/locale/SDL_locale.c @@ -0,0 +1,103 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 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_internal.h" +#include "SDL_syslocale.h" +#include "SDL_hints.h" + +static SDL_Locale * +build_locales_from_csv_string(char *csv) +{ + size_t num_locales = 1; /* at least one */ + size_t slen; + size_t alloclen; + char *ptr; + SDL_Locale *loc; + SDL_Locale *retval; + + if (!csv || !csv[0]) { + return NULL; /* nothing to report */ + } + + for (ptr = csv; *ptr; ptr++) { + if (*ptr == ',') { + num_locales++; + } + } + + num_locales++; /* one more for terminator */ + + slen = ((size_t) (ptr - csv)) + 1; /* strlen(csv) + 1 */ + alloclen = slen + (num_locales * sizeof (SDL_Locale)); + + loc = retval = (SDL_Locale *) SDL_calloc(1, alloclen); + if (!retval) { + SDL_OutOfMemory(); + return NULL; /* oh well */ + } + ptr = (char *) (retval + num_locales); + SDL_strlcpy(ptr, csv, slen); + + while (SDL_TRUE) { /* parse out the string */ + while (*ptr == ' ') ptr++; /* skip whitespace. */ + if (*ptr == '\0') { + break; + } + loc->language = ptr++; + while (SDL_TRUE) { + const char ch = *ptr; + if (ch == '_') { + *(ptr++) = '\0'; + loc->country = ptr; + } else if (ch == ' ') { + *(ptr++) = '\0'; /* trim ending whitespace and keep going. */ + } else if (ch == ',') { + *(ptr++) = '\0'; + loc++; + break; + } else if (ch == '\0') { + loc++; + break; + } else { + ptr++; /* just keep going, still a valid string */ + } + } + } + + return retval; +} + +SDL_Locale * +SDL_GetPreferredLocales(void) +{ + char locbuf[128]; /* enough for 21 "xx_YY," language strings. */ + const char *hint = SDL_GetHint(SDL_HINT_PREFERRED_LOCALES); + if (hint) { + SDL_strlcpy(locbuf, hint, sizeof (locbuf)); + } else { + SDL_zeroa(locbuf); + SDL_SYS_GetPreferredLocales(locbuf, sizeof (locbuf)); + } + return build_locales_from_csv_string(locbuf); +} + +/* 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 index 0000000000000..b83a809ed5eb5 --- /dev/null +++ b/src/locale/SDL_syslocale.h @@ -0,0 +1,29 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 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 void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen); + +/* 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 index 0000000000000..eef9b1ba21785 --- /dev/null +++ b/src/locale/android/SDL_syslocale.c @@ -0,0 +1,32 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 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_internal.h" +#include "../SDL_syslocale.h" + +void +SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + Android_JNI_GetLocale(buf, buflen); +} + +/* 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 index 0000000000000..ad554daefd191 --- /dev/null +++ b/src/locale/dummy/SDL_syslocale.c @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 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_internal.h" +#include "../SDL_syslocale.h" + +void +SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + /* dummy implementation. Caller already zero'd out buffer. */ + SDL_Unsupported(); +} + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/locale/emscripten/SDL_syslocale.c b/src/locale/emscripten/SDL_syslocale.c new file mode 100644 index 0000000000000..7004258e0a42c --- /dev/null +++ b/src/locale/emscripten/SDL_syslocale.c @@ -0,0 +1,72 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 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 + +#include "../../SDL_internal.h" +#include "../SDL_syslocale.h" + +void +SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + EM_ASM({ + var buf = $0; + var buflen = $1; + var list = undefined; + + if (navigator.languages && navigator.languages.length) { + list = navigator.languages; + } else { + var oneOfThese = navigator.userLanguage || navigator.language || navigator.browserLanguage || navigator.systemLanguage; + if (oneOfThese !== undefined) { + list = [ oneOfThese ]; + } + } + + if (list === undefined) { + return; /* we've got nothing. */ + } + + var str = ""; /* Can't do list.join() because we need to fit in buflen. */ + for (var i = 0; i < list.length; i++) { + var item = list[i]; + if ((str.length + item.length + 1) > buflen) { + break; /* don't add, we're out of space. */ + } + if (str.length > 0) { + str += ","; + } + str += item; + } + + str = str.replace(/-/g, "_"); + if (buflen > str.length) { + buflen = str.length; /* clamp to size of string. */ + } + + for (var i = 0; i < buflen; i++) { + setValue(buf + i, str.charCodeAt(i), "i8"); /* fill in C array. */ + } + }, buf, buflen); +} + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/locale/haiku/SDL_syslocale.cc b/src/locale/haiku/SDL_syslocale.cc new file mode 100644 index 0000000000000..44cae7a556884 --- /dev/null +++ b/src/locale/haiku/SDL_syslocale.cc @@ -0,0 +1,75 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 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 + +#include "../../SDL_internal.h" +#include "../SDL_syslocale.h" + +void +SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + BLocaleRoster *roster = BLocaleRoster::Default(); + roster->Refresh(); + + BMessage msg; + if (roster->GetPreferredLanguages(&msg) != B_OK) { + SDL_SetError("BLocaleRoster couldn't get preferred languages"); + return; + } + + const char *key = "language"; + type_code typ = B_ANY_TYPE; + int32 numlangs = 0; + if ((msg.GetInfo(key, &typ, &numlangs) != B_OK) || (typ != B_STRING_TYPE)) { + SDL_SetError("BLocaleRoster message was wrong"); + return; + } + + for (int32 i = 0; i < numlangs; i++) { + const char *str = NULL; + if (msg.FindString(key, i, &str) != B_OK) { + continue; + } + + const size_t len = SDL_strlen(str); + if (buflen <= len) { + break; // can't fit it, we're done. + } + + SDL_strlcpy(buf, str, buflen); + buf += len; + buflen -= len; + + if (i < (numlangs - 1)) { + if (buflen <= 1) { + break; // out of room, stop looking. + } + buf[0] = ','; // add a comma between entries. + buf[1] = '\0'; + buf++; + buflen--; + } + } +} + +/* 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 index 0000000000000..5ffbecdde31ee --- /dev/null +++ b/src/locale/macosx/SDL_syslocale.m @@ -0,0 +1,76 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 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_internal.h" +#include "../SDL_syslocale.h" + +#import + +void +SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ @autoreleasepool { + NSArray *languages = NSLocale.preferredLanguages; + size_t numlangs = 0; + size_t i; + + numlangs = (size_t) [languages count]; + + for (i = 0; i < numlangs; i++) { + NSString *nsstr = [languages objectAtIndex:i]; + size_t len; + char *ptr; + + if (nsstr == nil) { + break; + } + + [nsstr getCString:buf maxLength:buflen encoding:NSASCIIStringEncoding]; + len = SDL_strlen(buf); + + // convert '-' to '_'... + // These are always full lang-COUNTRY, so we search from the back, + // so things like zh-Hant-CN find the right '-' to convert. + if ((ptr = SDL_strrchr(buf, '-')) != NULL) { + *ptr = '_'; + } + + if (buflen <= len) { + *buf = '\0'; // drop this one and stop, we can't fit anymore. + break; + } + + buf += len; + buflen -= len; + + if (i < (numlangs - 1)) { + if (buflen <= 1) { + break; // out of room, stop looking. + } + buf[0] = ','; // add a comma between entries. + buf[1] = '\0'; + buf++; + buflen--; + } + } +}} + +/* 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 index 0000000000000..b8a2b4975bf7b --- /dev/null +++ b/src/locale/unix/SDL_syslocale.c @@ -0,0 +1,110 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 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_internal.h" +#include "../SDL_syslocale.h" +#include "SDL_assert.h" + +static void +normalize_locale_str(char *dst, char *str, size_t buflen) +{ + char *ptr; + + ptr = SDL_strchr(str, '.'); /* chop off encoding if specified. */ + if (ptr != NULL) { + *ptr = '\0'; + } + + ptr = SDL_strchr(str, '@'); /* chop off extra bits if specified. */ + if (ptr != NULL) { + *ptr = '\0'; + } + + /* The "C" locale isn't useful for our needs, ignore it if you see it. */ + if ((str[0] == 'C') && (str[1] == '\0')) { + return; + } + + if (*str) { + if (*dst) { + SDL_strlcat(dst, ",", buflen); /* SDL has these split by commas */ + } + SDL_strlcat(dst, str, buflen); + } +} + +static void +normalize_locales(char *dst, char *src, size_t buflen) +{ + char *ptr; + + /* entries are separated by colons */ + while ((ptr = SDL_strchr(src, ':')) != NULL) { + *ptr = '\0'; + normalize_locale_str(dst, src, buflen); + src = ptr + 1; + } + normalize_locale_str(dst, src, buflen); +} + +void +SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + /* !!! FIXME: should we be using setlocale()? Or some D-Bus thing? */ + SDL_bool isstack; + const char *envr; + char *tmp; + + SDL_assert(buflen > 0); + tmp = SDL_small_alloc(char, buflen, &isstack); + if (!tmp) { + SDL_OutOfMemory(); + return; + } + + *tmp = '\0'; + + /* LANG is the primary locale (maybe) */ + envr = SDL_getenv("LANG"); + if (envr) { + SDL_strlcpy(tmp, envr, buflen); + } + + /* fallback languages */ + envr = SDL_getenv("LANGUAGE"); + if (envr) { + if (*tmp) { + SDL_strlcat(tmp, ":", buflen); + } + SDL_strlcat(tmp, envr, buflen); + } + + if (*tmp == '\0') { + SDL_SetError("LANG environment variable isn't set"); + } else { + normalize_locales(buf, tmp, buflen); + } + + SDL_small_free(tmp, isstack); +} + +/* 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 index 0000000000000..267b7955d8750 --- /dev/null +++ b/src/locale/windows/SDL_syslocale.c @@ -0,0 +1,119 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 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_internal.h" +#include "../../core/windows/SDL_windows.h" +#include "../SDL_syslocale.h" +#include "SDL_assert.h" + +typedef BOOL (WINAPI *pfnGetUserPreferredUILanguages)(DWORD,PULONG,PZZWSTR,PULONG); +#ifndef MUI_LANGUAGE_NAME +#define MUI_LANGUAGE_NAME 0x8 +#endif + +static pfnGetUserPreferredUILanguages pGetUserPreferredUILanguages = NULL; +static HMODULE kernel32 = 0; + + +/* this is the fallback for WinXP...one language, not a list. */ +static void +SDL_SYS_GetPreferredLocales_winxp(char *buf, size_t buflen) +{ + 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) { + SDL_SetError("Couldn't obtain language info"); + } else { + SDL_snprintf(buf, buflen, "%s%s%s", lang, ctryrc ? "_" : "", ctryrc ? country : ""); + } +} + +/* this works on Windows Vista and later. */ +static void +SDL_SYS_GetPreferredLocales_vista(char *buf, size_t buflen) +{ + ULONG numlangs = 0; + WCHAR *wbuf = NULL; + ULONG wbuflen = 0; + SDL_bool isstack; + + SDL_assert(pGetUserPreferredUILanguages != NULL); + pGetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numlangs, NULL, &wbuflen); + + wbuf = SDL_small_alloc(WCHAR, wbuflen, &isstack); + if (!wbuf) { + SDL_OutOfMemory(); + return; + } + + if (!pGetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numlangs, wbuf, &wbuflen)) { + SDL_SYS_GetPreferredLocales_winxp(buf, buflen); /* oh well, try the fallback. */ + } else { + const ULONG endidx = SDL_min(buflen, wbuflen - 1); + ULONG str_start = 0; + ULONG i; + for (i = 0; i < endidx; i++) { + const char ch = (char) wbuf[i]; /* these should all be low-ASCII, safe to cast */ + if (ch == '\0') { + buf[i] = ','; /* change null separators to commas */ + str_start = i; + } else if (ch == '-') { + buf[i] = '_'; /* change '-' to '_' */ + } else { + buf[i] = ch; /* copy through as-is. */ + } + } + buf[str_start] = '\0'; /* terminate string, chop off final ',' */ + } + + SDL_small_free(wbuf, isstack); +} + +void +SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + if (!kernel32) { + kernel32 = LoadLibraryW(L"kernel32.dll"); + if (kernel32) { + pGetUserPreferredUILanguages = (pfnGetUserPreferredUILanguages) GetProcAddress(kernel32, "GetUserPreferredUILanguages"); + } + } + + if (pGetUserPreferredUILanguages == NULL) { + SDL_SYS_GetPreferredLocales_winxp(buf, buflen); /* this is always available */ + } else { + SDL_SYS_GetPreferredLocales_vista(buf, buflen); /* available on Vista and later. */ + } +} + +/* 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 index 0000000000000..e7e8b50dd0345 --- /dev/null +++ b/src/locale/winrt/SDL_syslocale.c @@ -0,0 +1,58 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2020 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 + +#include "../../SDL_internal.h" +#include "../SDL_syslocale.h" + +/*using namespace Windows::Graphics::Display;*/ +#include + +void +SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + WCHAR wbuffer[128] = L""; + int ret = 0; + + /* !!! FIXME: do we not have GetUserPreferredUILanguages on WinPhone or UWP? */ +# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + ret = GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_SNAME, wbuffer, SDL_arraylen(wbuffer)); +# else + ret = GetSystemDefaultLocaleName(wbuffer, SDL_arraysize(wbuffer)); +# endif + + if (ret > 0) + { + /* Need to convert LPWSTR to LPSTR, that is wide char to char. */ + int i; + + if (ret >= (buflen - 1) ) { + ret = (int) (buflen - 1); + } + for (i = 0; i < ret; i++) { + buf[i] = (char) wbuffer[i]; /* assume this was ASCII anyhow. */ + } + } +} + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/main/haiku/SDL_BApp.h b/src/main/haiku/SDL_BApp.h index 93ae0c611c64c..ce1fc6812a39c 100644 --- a/src/main/haiku/SDL_BApp.h +++ b/src/main/haiku/SDL_BApp.h @@ -22,6 +22,7 @@ #define SDL_BAPP_H #include +#include #if SDL_VIDEO_OPENGL #include #endif @@ -153,6 +154,10 @@ class SDL_BApp : public BApplication { _HandleWindowResized(message); break; + case B_LOCALE_CHANGED: + SDL_SendLocaleChangedEvent(); + break; + case BAPP_SCREEN_CHANGED: /* TODO: Handle screen resize or workspace change */ break; diff --git a/src/video/cocoa/SDL_cocoaevents.m b/src/video/cocoa/SDL_cocoaevents.m index 1cc24b480b0a3..8aec00008a8b8 100644 --- a/src/video/cocoa/SDL_cocoaevents.m +++ b/src/video/cocoa/SDL_cocoaevents.m @@ -117,6 +117,7 @@ @interface SDLAppDelegate : NSObject { } - (id)init; +- (void)localeDidChange:(NSNotification *)notification; @end @implementation SDLAppDelegate : NSObject @@ -137,6 +138,11 @@ - (id)init selector:@selector(focusSomeWindow:) name:NSApplicationDidBecomeActiveNotification object:nil]; + + [center addObserver:self + selector:@selector(localeDidChange:) + name:NSCurrentLocaleDidChangeNotification + object:nil]; } return self; @@ -148,6 +154,7 @@ - (void)dealloc [center removeObserver:self name:NSWindowWillCloseNotification object:nil]; [center removeObserver:self name:NSApplicationDidBecomeActiveNotification object:nil]; + [center removeObserver:self name:NSCurrentLocaleDidChangeNotification object:nil]; [super dealloc]; } @@ -226,6 +233,11 @@ - (void)focusSomeWindow:(NSNotification *)aNotification } } +- (void)localeDidChange:(NSNotification *)notification; +{ + SDL_SendLocaleChangedEvent(); +} + - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename { return (BOOL)SDL_SendDropFile(NULL, [filename UTF8String]) && SDL_SendDropComplete(NULL); diff --git a/test/Makefile.in b/test/Makefile.in index 9a62156ecd349..c14692451a3aa 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -37,6 +37,7 @@ TARGETS = \ testjoystick$(EXE) \ testkeys$(EXE) \ testloadso$(EXE) \ + testlocale$(EXE) \ testlock$(EXE) \ testmessage$(EXE) \ testmultiaudio$(EXE) \ @@ -303,6 +304,10 @@ controllermap$(EXE): $(srcdir)/controllermap.c 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 index f6282be34df35..8329cb96f3048 100644 --- a/test/README +++ b/test/README @@ -12,6 +12,7 @@ These are test programs for the SDL library: 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 index 24d27f36f557d..b9e8df02664a2 100755 --- a/test/configure +++ b/test/configure @@ -640,6 +640,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -720,6 +721,7 @@ datadir='${datarootdir}' 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 @@ do | -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 @@ fi 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 @@ Fine tuning of the installation directories: --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 index 0000000000000..762e9c1bc1c7e --- /dev/null +++ b/test/testlocale.c @@ -0,0 +1,67 @@ +/* + Copyright (C) 1997-2020 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" + +/* !!! FIXME: move this to the test framework */ + +static void log_locales(void) +{ + SDL_Locale *locales = SDL_GetPreferredLocales(); + if (locales == NULL) { + SDL_Log("Couldn't determine locales: %s", SDL_GetError()); + } else { + SDL_Locale *l; + unsigned int total = 0; + SDL_Log("Locales, in order of preference:"); + for (l = locales; l->language; l++) { + const char *c = l->country; + SDL_Log(" - %s%s%s", l->language, c ? "_" : "", c ? c : ""); + total++; + } + SDL_Log("%u locales seen.", total); + SDL_free(locales); + } +} + +int main(int argc, char **argv) +{ + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + /* Print locales and languages */ + if (SDL_Init(SDL_INIT_VIDEO) != -1) { + log_locales(); + + if ((argc == 2) && (SDL_strcmp(argv[1], "--listen") == 0)) { + SDL_bool keep_going = SDL_TRUE; + while (keep_going) { + SDL_Event e; + while (SDL_PollEvent(&e)) { + if (e.type == SDL_QUIT) { + keep_going = SDL_FALSE; + } else if (e.type == SDL_LOCALECHANGED) { + SDL_Log("Saw SDL_LOCALECHANGED event!"); + log_locales(); + } + } + SDL_Delay(10); + } + } + + SDL_Quit(); + } + + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */