diff --git a/Android.mk b/Android.mk
index 264c03d8b..6036a3502 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 6be75e298..0b63bf8a6 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 7982fc34b..2e7db2cdb 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 444ab329e..9e9af64a5 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 79857af26..07e82ecff 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 cb13cee45..14619dd03 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 0e9047e11..cb4229cf9 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 5925b8bcd..8d6a82453 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 1346c6d43..e0c933b11 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 f72a82def..1227e8892 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 701ad2b96..0a14b89c1 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 9f68a1629..af4c6b28a 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 988277a2f..18258d2f6 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 ee5f06da5..cc1c88374 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 7bfdfd81a..0e48c383e 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 574d66f29..fcc5c488a 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 634bf4b6d..9a8f580f1 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 32cfbe327..74cbb4b59 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 28cf544a7..44e6fd457 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 000000000..1f4b0c469
--- /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 664608705..c7add21da 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 9f3f3cc7f..153105199 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 4474a519c..cb596aaca 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 c4822a6c8..b501d6998 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 a6f0d2451..ec9a1817e 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 2d9680cb9..3c067e728 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 000000000..c7e5b1011
--- /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 000000000..b83a809ed
--- /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 000000000..eef9b1ba2
--- /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 000000000..ad554daef
--- /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 000000000..7004258e0
--- /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 000000000..44cae7a55
--- /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 000000000..5ffbecdde
--- /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 000000000..b8a2b4975
--- /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 000000000..267b7955d
--- /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 000000000..e7e8b50dd
--- /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 93ae0c611..ce1fc6812 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 @@ public:
_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 1cc24b480..8aec00008 100644
--- a/src/video/cocoa/SDL_cocoaevents.m
+++ b/src/video/cocoa/SDL_cocoaevents.m
@@ -117,6 +117,7 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
}
- (id)init;
+- (void)localeDidChange:(NSNotification *)notification;
@end
@implementation SDLAppDelegate : NSObject
@@ -137,6 +138,11 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
selector:@selector(focusSomeWindow:)
name:NSApplicationDidBecomeActiveNotification
object:nil];
+
+ [center addObserver:self
+ selector:@selector(localeDidChange:)
+ name:NSCurrentLocaleDidChangeNotification
+ object:nil];
}
return self;
@@ -148,6 +154,7 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
[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 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
}
}
+- (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 9a62156ec..c14692451 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 f6282be34..8329cb96f 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 24d27f36f..b9e8df026 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 000000000..762e9c1bc
--- /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: */