Browse Source

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.
Ryan C. Gordon 5 years ago
parent
commit
fa23e3d00b
42 changed files with 1318 additions and 4 deletions
  1. 2 0
      Android.mk
  2. 43 1
      CMakeLists.txt
  3. 1 0
      Makefile.in
  4. 3 1
      Makefile.os2
  5. 4 0
      VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj
  6. 12 0
      VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters
  7. 4 0
      VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj
  8. 12 0
      VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters
  9. 4 0
      VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj
  10. 12 0
      VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters
  11. 4 0
      VisualC/SDL/SDL.vcxproj
  12. 6 0
      VisualC/SDL/SDL.vcxproj.filters
  13. 57 0
      Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj
  14. 64 0
      Xcode/SDL/SDL.xcodeproj/project.pbxproj
  15. 42 1
      configure
  16. 29 0
      configure.ac
  17. 1 0
      include/SDL.h
  18. 2 0
      include/SDL_events.h
  19. 15 0
      include/SDL_hints.h
  20. 101 0
      include/SDL_locale.h
  21. 78 0
      src/core/android/SDL_android.c
  22. 3 0
      src/core/android/SDL_android.h
  23. 1 0
      src/dynapi/SDL_dynapi_overrides.h
  24. 1 0
      src/dynapi/SDL_dynapi_procs.h
  25. 6 0
      src/events/SDL_events.c
  26. 1 0
      src/events/SDL_events_c.h
  27. 103 0
      src/locale/SDL_locale.c
  28. 29 0
      src/locale/SDL_syslocale.h
  29. 32 0
      src/locale/android/SDL_syslocale.c
  30. 33 0
      src/locale/dummy/SDL_syslocale.c
  31. 72 0
      src/locale/emscripten/SDL_syslocale.c
  32. 75 0
      src/locale/haiku/SDL_syslocale.cc
  33. 76 0
      src/locale/macosx/SDL_syslocale.m
  34. 110 0
      src/locale/unix/SDL_syslocale.c
  35. 119 0
      src/locale/windows/SDL_syslocale.c
  36. 58 0
      src/locale/winrt/SDL_syslocale.c
  37. 5 0
      src/main/haiku/SDL_BApp.h
  38. 12 0
      src/video/cocoa/SDL_cocoaevents.m
  39. 5 0
      test/Makefile.in
  40. 1 0
      test/README
  41. 13 1
      test/configure
  42. 67 0
      test/testlocale.c

+ 2 - 0
Android.mk

@@ -35,6 +35,8 @@ LOCAL_SRC_FILES := \
 	$(wildcard $(LOCAL_PATH)/src/joystick/hidapi/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/joystick/hidapi/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/joystick/virtual/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/joystick/virtual/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.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/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/power/android/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/power/android/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/filesystem/android/*.c) \
 	$(wildcard $(LOCAL_PATH)/src/filesystem/android/*.c) \

+ 43 - 1
CMakeLists.txt

@@ -307,7 +307,7 @@ endif()
 
 
 set(SDL_SUBSYSTEMS
 set(SDL_SUBSYSTEMS
     Atomic Audio Video Render Events Joystick Haptic Power Threads Timers
     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})
 foreach(_SUB ${SDL_SUBSYSTEMS})
   string(TOUPPER ${_SUB} _OPT)
   string(TOUPPER ${_SUB} _OPT)
   if (NOT DEFINED SDL_${_OPT}_ENABLED_BY_DEFAULT)
   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/events/*.c
   ${SDL2_SOURCE_DIR}/src/file/*.c
   ${SDL2_SOURCE_DIR}/src/file/*.c
   ${SDL2_SOURCE_DIR}/src/libm/*.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/render/*/*.c
   ${SDL2_SOURCE_DIR}/src/render/*/*.c
   ${SDL2_SOURCE_DIR}/src/stdlib/*.c
   ${SDL2_SOURCE_DIR}/src/stdlib/*.c
@@ -885,6 +886,8 @@ if(SDL_POWER)
   file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/*.c)
   file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/*.c)
   set(SOURCE_FILES ${SOURCE_FILES} ${POWER_SOURCES})
   set(SOURCE_FILES ${SOURCE_FILES} ${POWER_SOURCES})
 endif()
 endif()
+
+
 # TODO: in configure.ac, the test for LOADSO and SDL_DLOPEN is a bit weird:
 # 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 LOADSO is not wanted, SDL_LOADSO_DISABLED is set
 # If however on Unix or APPLE dlopen() is detected via CheckDLOPEN(),
 # 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(SOURCE_FILES ${SOURCE_FILES} ${ANDROID_POWER_SOURCES})
     set(HAVE_SDL_POWER TRUE)
     set(HAVE_SDL_POWER TRUE)
   endif()
   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)
   if(SDL_TIMERS)
     set(SDL_TIMER_UNIX 1)
     set(SDL_TIMER_UNIX 1)
     file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c)
     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(SOURCE_FILES ${SOURCE_FILES} ${EM_POWER_SOURCES})
     set(HAVE_SDL_POWER TRUE)
     set(HAVE_SDL_POWER TRUE)
   endif()
   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)
   if(SDL_TIMERS)
     set(SDL_TIMER_UNIX 1)
     set(SDL_TIMER_UNIX 1)
     file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c)
     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()
   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)
   if(SDL_FILESYSTEM)
     set(SDL_FILESYSTEM_UNIX 1)
     set(SDL_FILESYSTEM_UNIX 1)
     file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/unix/*.c)
     file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/unix/*.c)
@@ -1438,6 +1457,12 @@ elseif(WINDOWS)
     set(HAVE_SDL_POWER TRUE)
     set(HAVE_SDL_POWER TRUE)
   endif()
   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)
   if(SDL_FILESYSTEM)
     set(SDL_FILESYSTEM_WINDOWS 1)
     set(SDL_FILESYSTEM_WINDOWS 1)
     file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/windows/*.c)
     file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/windows/*.c)
@@ -1629,6 +1654,12 @@ elseif(APPLE)
     set(HAVE_SDL_POWER TRUE)
     set(HAVE_SDL_POWER TRUE)
   endif()
   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)
   if(SDL_TIMERS)
     set(SDL_TIMER_UNIX 1)
     set(SDL_TIMER_UNIX 1)
     file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c)
     file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c)
@@ -1837,6 +1868,12 @@ elseif(HAIKU)
     set(HAVE_SDL_TIMERS TRUE)
     set(HAVE_SDL_TIMERS TRUE)
   endif()
   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()
   CheckPTHREAD()
 
 
 elseif(RISCOS)
 elseif(RISCOS)
@@ -1899,6 +1936,11 @@ if(NOT HAVE_SDL_FILESYSTEM)
   file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/dummy/*.c)
   file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/dummy/*.c)
   set(SOURCE_FILES ${SOURCE_FILES} ${FILESYSTEM_SOURCES})
   set(SOURCE_FILES ${SOURCE_FILES} ${FILESYSTEM_SOURCES})
 endif()
 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
 # We always need to have threads and timers around
 if(NOT HAVE_SDL_THREADS)
 if(NOT HAVE_SDL_THREADS)

+ 1 - 0
Makefile.in

@@ -82,6 +82,7 @@ HDRS = \
 	SDL_keyboard.h \
 	SDL_keyboard.h \
 	SDL_keycode.h \
 	SDL_keycode.h \
 	SDL_loadso.h \
 	SDL_loadso.h \
+	SDL_locale.h \
 	SDL_log.h \
 	SDL_log.h \
 	SDL_main.h \
 	SDL_main.h \
 	SDL_messagebox.h \
 	SDL_messagebox.h \

+ 3 - 1
Makefile.os2

@@ -60,6 +60,8 @@ SRCS+= SDL_dummysensor.c
 
 
 SRCS+= SDL_dynapi.c
 SRCS+= SDL_dynapi.c
 
 
+SRCS+= SDL_locale.c SDL_syslocale.c
+
 OBJS = $(SRCS:.c=.obj)
 OBJS = $(SRCS:.c=.obj)
 MOBJS= $(MSRCS:.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;./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/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
 all: $(DLLFILE) $(LIBFILE) .symbolic
 
 

+ 4 - 0
VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj

@@ -52,6 +52,7 @@
     <ClInclude Include="..\..\include\SDL_keyboard.h" />
     <ClInclude Include="..\..\include\SDL_keyboard.h" />
     <ClInclude Include="..\..\include\SDL_keycode.h" />
     <ClInclude Include="..\..\include\SDL_keycode.h" />
     <ClInclude Include="..\..\include\SDL_loadso.h" />
     <ClInclude Include="..\..\include\SDL_loadso.h" />
+    <ClInclude Include="..\..\include\SDL_locale.h" />
     <ClInclude Include="..\..\include\SDL_log.h" />
     <ClInclude Include="..\..\include\SDL_log.h" />
     <ClInclude Include="..\..\include\SDL_main.h" />
     <ClInclude Include="..\..\include\SDL_main.h" />
     <ClInclude Include="..\..\include\SDL_mouse.h" />
     <ClInclude Include="..\..\include\SDL_mouse.h" />
@@ -118,6 +119,7 @@
     <ClInclude Include="..\..\src\joystick\windows\SDL_dinputjoystick_c.h" />
     <ClInclude Include="..\..\src\joystick\windows\SDL_dinputjoystick_c.h" />
     <ClInclude Include="..\..\src\joystick\windows\SDL_windowsjoystick_c.h" />
     <ClInclude Include="..\..\src\joystick\windows\SDL_windowsjoystick_c.h" />
     <ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h" />
     <ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h" />
+    <ClInclude Include="..\..\src\locale\SDL_syslocale.h" />
     <ClInclude Include="..\..\src\render\direct3d11\SDL_render_winrt.h" />
     <ClInclude Include="..\..\src\render\direct3d11\SDL_render_winrt.h" />
     <ClInclude Include="..\..\src\render\direct3d11\SDL_shaders_d3d11.h" />
     <ClInclude Include="..\..\src\render\direct3d11\SDL_shaders_d3d11.h" />
     <ClInclude Include="..\..\src\render\opengles2\SDL_gles2funcs.h" />
     <ClInclude Include="..\..\src\render\opengles2\SDL_gles2funcs.h" />
@@ -249,6 +251,8 @@
     <ClCompile Include="..\..\src\joystick\windows\SDL_windowsjoystick.c" />
     <ClCompile Include="..\..\src\joystick\windows\SDL_windowsjoystick.c" />
     <ClCompile Include="..\..\src\joystick\windows\SDL_xinputjoystick.c" />
     <ClCompile Include="..\..\src\joystick\windows\SDL_xinputjoystick.c" />
     <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c" />
     <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c" />
+    <ClCompile Include="..\..\src\locale\SDL_locale.c" />
+    <ClCompile Include="..\..\src\locale\winrt\SDL_syslocale.c" />
     <ClCompile Include="..\..\src\power\SDL_power.c" />
     <ClCompile Include="..\..\src\power\SDL_power.c" />
     <ClCompile Include="..\..\src\power\winrt\SDL_syspower.cpp" />
     <ClCompile Include="..\..\src\power\winrt\SDL_syspower.cpp" />
     <ClCompile Include="..\..\src\render\direct3d11\SDL_render_d3d11.c" />
     <ClCompile Include="..\..\src\render\direct3d11\SDL_render_d3d11.c" />

+ 12 - 0
VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters

@@ -84,6 +84,9 @@
     <ClInclude Include="..\..\include\SDL_loadso.h">
     <ClInclude Include="..\..\include\SDL_loadso.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="..\..\include\SDL_locale.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\include\SDL_log.h">
     <ClInclude Include="..\..\include\SDL_log.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
@@ -321,6 +324,9 @@
     <ClInclude Include="..\..\src\SDL_internal.h">
     <ClInclude Include="..\..\src\SDL_internal.h">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="..\..\src\locale\SDL_syslocale.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\src\thread\SDL_systhread.h">
     <ClInclude Include="..\..\src\thread\SDL_systhread.h">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClInclude>
     </ClInclude>
@@ -614,6 +620,12 @@
     <ClCompile Include="..\..\src\SDL_log.c">
     <ClCompile Include="..\..\src\SDL_log.c">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="..\..\src\locale\SDL_locale.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\locale\winrt\SDL_syslocale.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\stdlib\SDL_getenv.c">
     <ClCompile Include="..\..\src\stdlib\SDL_getenv.c">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>

+ 4 - 0
VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj

@@ -44,6 +44,7 @@
     <ClInclude Include="..\..\include\SDL_keyboard.h" />
     <ClInclude Include="..\..\include\SDL_keyboard.h" />
     <ClInclude Include="..\..\include\SDL_keycode.h" />
     <ClInclude Include="..\..\include\SDL_keycode.h" />
     <ClInclude Include="..\..\include\SDL_loadso.h" />
     <ClInclude Include="..\..\include\SDL_loadso.h" />
+    <ClInclude Include="..\..\include\SDL_locale.h" />
     <ClInclude Include="..\..\include\SDL_log.h" />
     <ClInclude Include="..\..\include\SDL_log.h" />
     <ClInclude Include="..\..\include\SDL_main.h" />
     <ClInclude Include="..\..\include\SDL_main.h" />
     <ClInclude Include="..\..\include\SDL_mouse.h" />
     <ClInclude Include="..\..\include\SDL_mouse.h" />
@@ -124,6 +125,7 @@
     <ClInclude Include="..\..\src\SDL_fatal.h" />
     <ClInclude Include="..\..\src\SDL_fatal.h" />
     <ClInclude Include="..\..\src\SDL_hints_c.h" />
     <ClInclude Include="..\..\src\SDL_hints_c.h" />
     <ClInclude Include="..\..\src\SDL_internal.h" />
     <ClInclude Include="..\..\src\SDL_internal.h" />
+    <ClInclude Include="..\..\src\locale\SDL_syslocale.h" />
     <ClInclude Include="..\..\src\sensor\dummy\SDL_dummysensor.h" />
     <ClInclude Include="..\..\src\sensor\dummy\SDL_dummysensor.h" />
     <ClInclude Include="..\..\src\sensor\SDL_sensor_c.h" />
     <ClInclude Include="..\..\src\sensor\SDL_sensor_c.h" />
     <ClInclude Include="..\..\src\sensor\SDL_syssensor.h" />
     <ClInclude Include="..\..\src\sensor\SDL_syssensor.h" />
@@ -245,6 +247,8 @@
     <ClCompile Include="..\..\src\SDL_error.c" />
     <ClCompile Include="..\..\src\SDL_error.c" />
     <ClCompile Include="..\..\src\SDL_hints.c" />
     <ClCompile Include="..\..\src\SDL_hints.c" />
     <ClCompile Include="..\..\src\SDL_log.c" />
     <ClCompile Include="..\..\src\SDL_log.c" />
+    <ClCompile Include="..\..\src\locale\SDL_locale.c" />
+    <ClCompile Include="..\..\src\locale\winrt\SDL_syslocale.c" />
     <ClCompile Include="..\..\src\sensor\dummy\SDL_dummysensor.c" />
     <ClCompile Include="..\..\src\sensor\dummy\SDL_dummysensor.c" />
     <ClCompile Include="..\..\src\sensor\SDL_sensor.c" />
     <ClCompile Include="..\..\src\sensor\SDL_sensor.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_getenv.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_getenv.c" />

+ 12 - 0
VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters

@@ -84,6 +84,9 @@
     <ClInclude Include="..\..\include\SDL_loadso.h">
     <ClInclude Include="..\..\include\SDL_loadso.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="..\..\include\SDL_locale.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\include\SDL_log.h">
     <ClInclude Include="..\..\include\SDL_log.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
@@ -306,6 +309,9 @@
     <ClInclude Include="..\..\src\SDL_internal.h">
     <ClInclude Include="..\..\src\SDL_internal.h">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="..\..\src\locale\SDL_syslocale.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\src\thread\SDL_systhread.h">
     <ClInclude Include="..\..\src\thread\SDL_systhread.h">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClInclude>
     </ClInclude>
@@ -578,6 +584,12 @@
     <ClCompile Include="..\..\src\SDL_log.c">
     <ClCompile Include="..\..\src\SDL_log.c">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="..\..\src\locale\SDL_locale.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\locale\winrt\SDL_syslocale.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\stdlib\SDL_getenv.c">
     <ClCompile Include="..\..\src\stdlib\SDL_getenv.c">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>

+ 4 - 0
VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj

@@ -52,6 +52,7 @@
     <ClInclude Include="..\..\include\SDL_keyboard.h" />
     <ClInclude Include="..\..\include\SDL_keyboard.h" />
     <ClInclude Include="..\..\include\SDL_keycode.h" />
     <ClInclude Include="..\..\include\SDL_keycode.h" />
     <ClInclude Include="..\..\include\SDL_loadso.h" />
     <ClInclude Include="..\..\include\SDL_loadso.h" />
+    <ClInclude Include="..\..\include\SDL_locale.h" />
     <ClInclude Include="..\..\include\SDL_log.h" />
     <ClInclude Include="..\..\include\SDL_log.h" />
     <ClInclude Include="..\..\include\SDL_main.h" />
     <ClInclude Include="..\..\include\SDL_main.h" />
     <ClInclude Include="..\..\include\SDL_mouse.h" />
     <ClInclude Include="..\..\include\SDL_mouse.h" />
@@ -139,6 +140,7 @@
     <ClInclude Include="..\..\src\SDL_fatal.h" />
     <ClInclude Include="..\..\src\SDL_fatal.h" />
     <ClInclude Include="..\..\src\SDL_hints_c.h" />
     <ClInclude Include="..\..\src\SDL_hints_c.h" />
     <ClInclude Include="..\..\src\SDL_internal.h" />
     <ClInclude Include="..\..\src\SDL_internal.h" />
+    <ClInclude Include="..\..\src\locale\SDL_syslocale.h" />
     <ClInclude Include="..\..\src\sensor\dummy\SDL_dummysensor.h" />
     <ClInclude Include="..\..\src\sensor\dummy\SDL_dummysensor.h" />
     <ClInclude Include="..\..\src\sensor\SDL_sensor_c.h" />
     <ClInclude Include="..\..\src\sensor\SDL_sensor_c.h" />
     <ClInclude Include="..\..\src\sensor\SDL_syssensor.h" />
     <ClInclude Include="..\..\src\sensor\SDL_syssensor.h" />
@@ -277,6 +279,8 @@
     <ClCompile Include="..\..\src\SDL_error.c" />
     <ClCompile Include="..\..\src\SDL_error.c" />
     <ClCompile Include="..\..\src\SDL_hints.c" />
     <ClCompile Include="..\..\src\SDL_hints.c" />
     <ClCompile Include="..\..\src\SDL_log.c" />
     <ClCompile Include="..\..\src\SDL_log.c" />
+    <ClInclude Include="..\..\src\locale\SDL_locale.c" />
+    <ClInclude Include="..\..\src\locale\winrt\SDL_syslocale.c" />
     <ClCompile Include="..\..\src\sensor\dummy\SDL_dummysensor.c" />
     <ClCompile Include="..\..\src\sensor\dummy\SDL_dummysensor.c" />
     <ClCompile Include="..\..\src\sensor\SDL_sensor.c" />
     <ClCompile Include="..\..\src\sensor\SDL_sensor.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_getenv.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_getenv.c" />

+ 12 - 0
VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters

@@ -84,6 +84,9 @@
     <ClInclude Include="..\..\include\SDL_loadso.h">
     <ClInclude Include="..\..\include\SDL_loadso.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="..\..\include\SDL_locale.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\include\SDL_log.h">
     <ClInclude Include="..\..\include\SDL_log.h">
       <Filter>Header Files</Filter>
       <Filter>Header Files</Filter>
     </ClInclude>
     </ClInclude>
@@ -306,6 +309,9 @@
     <ClInclude Include="..\..\src\SDL_internal.h">
     <ClInclude Include="..\..\src\SDL_internal.h">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="..\..\src\locale\SDL_syslocale.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\src\thread\SDL_thread_c.h">
     <ClInclude Include="..\..\src\thread\SDL_thread_c.h">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClInclude>
     </ClInclude>
@@ -596,6 +602,12 @@
     <ClCompile Include="..\..\src\SDL_log.c">
     <ClCompile Include="..\..\src\SDL_log.c">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="..\..\src\locale\SDL_locale.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\locale\winrt\SDL_syslocale.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\stdlib\SDL_getenv.c">
     <ClCompile Include="..\..\src\stdlib\SDL_getenv.c">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>

+ 4 - 0
VisualC/SDL/SDL.vcxproj

@@ -239,6 +239,7 @@
     <ClInclude Include="..\..\include\SDL_keyboard.h" />
     <ClInclude Include="..\..\include\SDL_keyboard.h" />
     <ClInclude Include="..\..\include\SDL_keycode.h" />
     <ClInclude Include="..\..\include\SDL_keycode.h" />
     <ClInclude Include="..\..\include\SDL_loadso.h" />
     <ClInclude Include="..\..\include\SDL_loadso.h" />
+    <ClInclude Include="..\..\include\SDL_locale.h" />
     <ClInclude Include="..\..\include\SDL_log.h" />
     <ClInclude Include="..\..\include\SDL_log.h" />
     <ClInclude Include="..\..\include\SDL_main.h" />
     <ClInclude Include="..\..\include\SDL_main.h" />
     <ClInclude Include="..\..\include\SDL_messagebox.h" />
     <ClInclude Include="..\..\include\SDL_messagebox.h" />
@@ -331,6 +332,7 @@
     <ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h" />
     <ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h" />
     <ClInclude Include="..\..\src\libm\math_libm.h" />
     <ClInclude Include="..\..\src\libm\math_libm.h" />
     <ClInclude Include="..\..\src\libm\math_private.h" />
     <ClInclude Include="..\..\src\libm\math_private.h" />
+    <ClInclude Include="..\..\src\locale\SDL_syslocale.h" />
     <ClInclude Include="..\..\src\render\direct3d11\SDL_shaders_d3d11.h" />
     <ClInclude Include="..\..\src\render\direct3d11\SDL_shaders_d3d11.h" />
     <ClInclude Include="..\..\src\render\direct3d\SDL_shaders_d3d.h" />
     <ClInclude Include="..\..\src\render\direct3d\SDL_shaders_d3d.h" />
     <ClInclude Include="..\..\src\render\opengl\SDL_glfuncs.h" />
     <ClInclude Include="..\..\src\render\opengl\SDL_glfuncs.h" />
@@ -463,6 +465,8 @@
     <ClCompile Include="..\..\src\libm\s_sin.c" />
     <ClCompile Include="..\..\src\libm\s_sin.c" />
     <ClCompile Include="..\..\src\libm\s_tan.c" />
     <ClCompile Include="..\..\src\libm\s_tan.c" />
     <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c" />
     <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c" />
+    <ClCompile Include="..\..\src\locale\SDL_locale.c" />
+    <ClCompile Include="..\..\src\locale\windows\SDL_syslocale.c" />
     <ClCompile Include="..\..\src\power\SDL_power.c" />
     <ClCompile Include="..\..\src\power\SDL_power.c" />
     <ClCompile Include="..\..\src\power\windows\SDL_syspower.c" />
     <ClCompile Include="..\..\src\power\windows\SDL_syspower.c" />
     <ClCompile Include="..\..\src\render\direct3d11\SDL_shaders_d3d11.c" />
     <ClCompile Include="..\..\src\render\direct3d11\SDL_shaders_d3d11.c" />

+ 6 - 0
VisualC/SDL/SDL.vcxproj.filters

@@ -84,6 +84,9 @@
     <ClInclude Include="..\..\include\SDL_loadso.h">
     <ClInclude Include="..\..\include\SDL_loadso.h">
       <Filter>API Headers</Filter>
       <Filter>API Headers</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="..\..\include\SDL_locale.h">
+      <Filter>API Headers</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\include\SDL_log.h">
     <ClInclude Include="..\..\include\SDL_log.h">
       <Filter>API Headers</Filter>
       <Filter>API Headers</Filter>
     </ClInclude>
     </ClInclude>
@@ -269,6 +272,7 @@
     <ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h" />
     <ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h" />
     <ClInclude Include="..\..\src\libm\math_libm.h" />
     <ClInclude Include="..\..\src\libm\math_libm.h" />
     <ClInclude Include="..\..\src\libm\math_private.h" />
     <ClInclude Include="..\..\src\libm\math_private.h" />
+    <ClInclude Include="..\..\src\locale\SDL_syslocale.h" />
     <ClInclude Include="..\..\src\render\direct3d\SDL_shaders_d3d.h" />
     <ClInclude Include="..\..\src\render\direct3d\SDL_shaders_d3d.h" />
     <ClInclude Include="..\..\src\render\direct3d11\SDL_shaders_d3d11.h" />
     <ClInclude Include="..\..\src\render\direct3d11\SDL_shaders_d3d11.h" />
     <ClInclude Include="..\..\src\render\opengl\SDL_glfuncs.h" />
     <ClInclude Include="..\..\src\render\opengl\SDL_glfuncs.h" />
@@ -401,6 +405,8 @@
     <ClCompile Include="..\..\src\libm\s_sin.c" />
     <ClCompile Include="..\..\src\libm\s_sin.c" />
     <ClCompile Include="..\..\src\libm\s_tan.c" />
     <ClCompile Include="..\..\src\libm\s_tan.c" />
     <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c" />
     <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c" />
+    <ClCompile Include="..\..\src\locale\SDL_locale.c" />
+    <ClCompile Include="..\..\src\locale\windows\SDL_syslocale.c" />
     <ClCompile Include="..\..\src\power\SDL_power.c" />
     <ClCompile Include="..\..\src\power\SDL_power.c" />
     <ClCompile Include="..\..\src\power\windows\SDL_syspower.c" />
     <ClCompile Include="..\..\src\power\windows\SDL_syspower.c" />
     <ClCompile Include="..\..\src\render\direct3d\SDL_render_d3d.c" />
     <ClCompile Include="..\..\src\render\direct3d\SDL_render_d3d.c" />

+ 57 - 0
Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj

@@ -343,6 +343,22 @@
 		55FFA91A2122302B00D7CBED /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = 55FFA9192122302B00D7CBED /* SDL_syspower.h */; };
 		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 */; };
 		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 */; };
 		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 */; };
 		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 */; };
 		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 */; };
 		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 = "<group>"; };
 		55FFA9192122302B00D7CBED /* SDL_syspower.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_syspower.h; sourceTree = "<group>"; };
 		566726431DF72CF5001DD3DB /* SDL_dataqueue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_dataqueue.c; sourceTree = "<group>"; };
 		566726431DF72CF5001DD3DB /* SDL_dataqueue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_dataqueue.c; sourceTree = "<group>"; };
 		566726441DF72CF5001DD3DB /* SDL_dataqueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dataqueue.h; sourceTree = "<group>"; };
 		566726441DF72CF5001DD3DB /* SDL_dataqueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dataqueue.h; sourceTree = "<group>"; };
+		566E26ED2462770300718109 /* SDL_locale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_locale.h; sourceTree = "<group>"; };
+		566E26F42462774E00718109 /* SDL_syslocale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_syslocale.h; path = locale/SDL_syslocale.h; sourceTree = "<group>"; };
+		566E26F62462774E00718109 /* SDL_syslocale.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_syslocale.m; sourceTree = "<group>"; };
+		566E26F72462774E00718109 /* SDL_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_locale.c; path = locale/SDL_locale.c; sourceTree = "<group>"; };
 		56A6702D18565E450007D20F /* SDL_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_internal.h; sourceTree = "<group>"; };
 		56A6702D18565E450007D20F /* SDL_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_internal.h; sourceTree = "<group>"; };
 		56A6703118565E760007D20F /* SDL_dynapi_overrides.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dynapi_overrides.h; sourceTree = "<group>"; };
 		56A6703118565E760007D20F /* SDL_dynapi_overrides.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dynapi_overrides.h; sourceTree = "<group>"; };
 		56A6703218565E760007D20F /* SDL_dynapi_procs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dynapi_procs.h; sourceTree = "<group>"; };
 		56A6703218565E760007D20F /* SDL_dynapi_procs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dynapi_procs.h; sourceTree = "<group>"; };
@@ -1384,6 +1404,25 @@
 			name = Frameworks;
 			name = Frameworks;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		566E26F32462773A00718109 /* locale */ = {
+			isa = PBXGroup;
+			children = (
+				566E26F52462774E00718109 /* macosx */,
+				566E26F72462774E00718109 /* SDL_locale.c */,
+				566E26F42462774E00718109 /* SDL_syslocale.h */,
+			);
+			name = locale;
+			sourceTree = "<group>";
+		};
+		566E26F52462774E00718109 /* macosx */ = {
+			isa = PBXGroup;
+			children = (
+				566E26F62462774E00718109 /* SDL_syslocale.m */,
+			);
+			name = macosx;
+			path = locale/macosx;
+			sourceTree = "<group>";
+		};
 		56A6702F18565E4F0007D20F /* dynapi */ = {
 		56A6702F18565E4F0007D20F /* dynapi */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -1656,6 +1695,7 @@
 				AA7558781595D55500BBD41B /* SDL_keyboard.h */,
 				AA7558781595D55500BBD41B /* SDL_keyboard.h */,
 				AA7558791595D55500BBD41B /* SDL_keycode.h */,
 				AA7558791595D55500BBD41B /* SDL_keycode.h */,
 				AA75587A1595D55500BBD41B /* SDL_loadso.h */,
 				AA75587A1595D55500BBD41B /* SDL_loadso.h */,
+				566E26ED2462770300718109 /* SDL_locale.h */,
 				AA75587B1595D55500BBD41B /* SDL_log.h */,
 				AA75587B1595D55500BBD41B /* SDL_log.h */,
 				AA75587C1595D55500BBD41B /* SDL_main.h */,
 				AA75587C1595D55500BBD41B /* SDL_main.h */,
 				AA9FF9501637C6E5000DF050 /* SDL_messagebox.h */,
 				AA9FF9501637C6E5000DF050 /* SDL_messagebox.h */,
@@ -1708,6 +1748,7 @@
 				F35CEA6E20F51B7F003ECE98 /* hidapi */,
 				F35CEA6E20F51B7F003ECE98 /* hidapi */,
 				FD5F9D080E0E08B3008E885B /* joystick */,
 				FD5F9D080E0E08B3008E885B /* joystick */,
 				FD8BD8150E27E25900B52CD5 /* loadso */,
 				FD8BD8150E27E25900B52CD5 /* loadso */,
+				566E26F32462773A00718109 /* locale */,
 				F3E3C65322406963007D243C /* main */,
 				F3E3C65322406963007D243C /* main */,
 				56ED04DE118A8E9A00A56AA6 /* power */,
 				56ED04DE118A8E9A00A56AA6 /* power */,
 				041B2CE312FA0F680087D585 /* render */,
 				041B2CE312FA0F680087D585 /* render */,
@@ -1968,9 +2009,11 @@
 				52ED1DA2222889500061FCE0 /* SDL_audio.h in Headers */,
 				52ED1DA2222889500061FCE0 /* SDL_audio.h in Headers */,
 				52ED1DA3222889500061FCE0 /* SDL_syspower.h in Headers */,
 				52ED1DA3222889500061FCE0 /* SDL_syspower.h in Headers */,
 				52ED1DA4222889500061FCE0 /* SDL_blendmode.h in Headers */,
 				52ED1DA4222889500061FCE0 /* SDL_blendmode.h in Headers */,
+				566E26F92462774E00718109 /* SDL_syslocale.h in Headers */,
 				52ED1DA5222889500061FCE0 /* SDL_sensor_c.h in Headers */,
 				52ED1DA5222889500061FCE0 /* SDL_sensor_c.h in Headers */,
 				52ED1DA6222889500061FCE0 /* SDL_clipboard.h in Headers */,
 				52ED1DA6222889500061FCE0 /* SDL_clipboard.h in Headers */,
 				52ED1DA7222889500061FCE0 /* SDL_config_iphoneos.h in Headers */,
 				52ED1DA7222889500061FCE0 /* SDL_config_iphoneos.h in Headers */,
+				566E26EF2462770300718109 /* SDL_locale.h in Headers */,
 				52ED1DA8222889500061FCE0 /* SDL_config.h in Headers */,
 				52ED1DA8222889500061FCE0 /* SDL_config.h in Headers */,
 				52ED1DA9222889500061FCE0 /* SDL_copying.h in Headers */,
 				52ED1DA9222889500061FCE0 /* SDL_copying.h in Headers */,
 				52ED1DAA222889500061FCE0 /* SDL_egl_c.h in Headers */,
 				52ED1DAA222889500061FCE0 /* SDL_egl_c.h in Headers */,
@@ -2043,6 +2086,7 @@
 			isa = PBXHeadersBuildPhase;
 			isa = PBXHeadersBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
+				566E26F12462770300718109 /* SDL_locale.h in Headers */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
@@ -2106,9 +2150,11 @@
 				F3E3C6902241389A007D243C /* SDL_audio.h in Headers */,
 				F3E3C6902241389A007D243C /* SDL_audio.h in Headers */,
 				F3E3C6912241389A007D243C /* SDL_syspower.h in Headers */,
 				F3E3C6912241389A007D243C /* SDL_syspower.h in Headers */,
 				F3E3C6922241389A007D243C /* SDL_blendmode.h in Headers */,
 				F3E3C6922241389A007D243C /* SDL_blendmode.h in Headers */,
+				566E26FA2462774E00718109 /* SDL_syslocale.h in Headers */,
 				F3E3C6932241389A007D243C /* SDL_sensor_c.h in Headers */,
 				F3E3C6932241389A007D243C /* SDL_sensor_c.h in Headers */,
 				F3E3C6942241389A007D243C /* SDL_clipboard.h in Headers */,
 				F3E3C6942241389A007D243C /* SDL_clipboard.h in Headers */,
 				F3E3C6952241389A007D243C /* SDL_config_iphoneos.h in Headers */,
 				F3E3C6952241389A007D243C /* SDL_config_iphoneos.h in Headers */,
+				566E26F02462770300718109 /* SDL_locale.h in Headers */,
 				F3E3C6962241389A007D243C /* SDL_config.h in Headers */,
 				F3E3C6962241389A007D243C /* SDL_config.h in Headers */,
 				F3E3C6972241389A007D243C /* SDL_copying.h in Headers */,
 				F3E3C6972241389A007D243C /* SDL_copying.h in Headers */,
 				F3E3C6982241389A007D243C /* SDL_egl_c.h in Headers */,
 				F3E3C6982241389A007D243C /* SDL_egl_c.h in Headers */,
@@ -2181,6 +2227,7 @@
 			isa = PBXHeadersBuildPhase;
 			isa = PBXHeadersBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
+				566E26F22462770300718109 /* SDL_locale.h in Headers */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
@@ -2260,6 +2307,7 @@
 				AA7558A61595D55500BBD41B /* SDL_gesture.h in Headers */,
 				AA7558A61595D55500BBD41B /* SDL_gesture.h in Headers */,
 				AA7558A71595D55500BBD41B /* SDL_haptic.h in Headers */,
 				AA7558A71595D55500BBD41B /* SDL_haptic.h in Headers */,
 				AA7558A81595D55500BBD41B /* SDL_hints.h in Headers */,
 				AA7558A81595D55500BBD41B /* SDL_hints.h in Headers */,
+				566E26F82462774E00718109 /* SDL_syslocale.h in Headers */,
 				566726461DF72CF5001DD3DB /* SDL_dataqueue.h in Headers */,
 				566726461DF72CF5001DD3DB /* SDL_dataqueue.h in Headers */,
 				F30D9C9F212CD0990047DF2E /* SDL_syssensor.h in Headers */,
 				F30D9C9F212CD0990047DF2E /* SDL_syssensor.h in Headers */,
 				AA7558AA1595D55500BBD41B /* SDL_joystick.h in Headers */,
 				AA7558AA1595D55500BBD41B /* SDL_joystick.h in Headers */,
@@ -2290,6 +2338,7 @@
 				AA7558BE1595D55500BBD41B /* SDL_scancode.h in Headers */,
 				AA7558BE1595D55500BBD41B /* SDL_scancode.h in Headers */,
 				AA7558BF1595D55500BBD41B /* SDL_shape.h in Headers */,
 				AA7558BF1595D55500BBD41B /* SDL_shape.h in Headers */,
 				AA7558C01595D55500BBD41B /* SDL_stdinc.h in Headers */,
 				AA7558C01595D55500BBD41B /* SDL_stdinc.h in Headers */,
+				566E26EE2462770300718109 /* SDL_locale.h in Headers */,
 				FAD4F7021BA3C4E8008346CE /* SDL_sysjoystick_c.h in Headers */,
 				FAD4F7021BA3C4E8008346CE /* SDL_sysjoystick_c.h in Headers */,
 				AA7558C11595D55500BBD41B /* SDL_surface.h in Headers */,
 				AA7558C11595D55500BBD41B /* SDL_surface.h in Headers */,
 				AA7558C21595D55500BBD41B /* SDL_system.h in Headers */,
 				AA7558C21595D55500BBD41B /* SDL_system.h in Headers */,
@@ -2539,6 +2588,7 @@
 				52ED1DFC222889500061FCE0 /* SDL_rwops.c in Sources */,
 				52ED1DFC222889500061FCE0 /* SDL_rwops.c in Sources */,
 				52ED1DFD222889500061FCE0 /* hid.m in Sources */,
 				52ED1DFD222889500061FCE0 /* hid.m in Sources */,
 				52ED1DFE222889500061FCE0 /* SDL_vulkan_utils.c in Sources */,
 				52ED1DFE222889500061FCE0 /* SDL_vulkan_utils.c in Sources */,
+				566E27042462774E00718109 /* SDL_locale.c in Sources */,
 				52ED1DFF222889500061FCE0 /* SDL_error.c in Sources */,
 				52ED1DFF222889500061FCE0 /* SDL_error.c in Sources */,
 				52ED1E00222889500061FCE0 /* SDL.c in Sources */,
 				52ED1E00222889500061FCE0 /* SDL.c in Sources */,
 				52ED1E01222889500061FCE0 /* SDL_syscond.c in Sources */,
 				52ED1E01222889500061FCE0 /* SDL_syscond.c in Sources */,
@@ -2550,6 +2600,7 @@
 				52ED1E07222889500061FCE0 /* SDL_getenv.c in Sources */,
 				52ED1E07222889500061FCE0 /* SDL_getenv.c in Sources */,
 				52ED1E08222889500061FCE0 /* SDL_iconv.c in Sources */,
 				52ED1E08222889500061FCE0 /* SDL_iconv.c in Sources */,
 				52ED1E09222889500061FCE0 /* SDL_malloc.c in Sources */,
 				52ED1E09222889500061FCE0 /* SDL_malloc.c in Sources */,
+				566E26FE2462774E00718109 /* SDL_syslocale.m in Sources */,
 				A7FF6B6323AC3BC6005876C6 /* SDL_hidapi_gamecube.c in Sources */,
 				A7FF6B6323AC3BC6005876C6 /* SDL_hidapi_gamecube.c in Sources */,
 				52ED1E0A222889500061FCE0 /* SDL_hidapi_xbox360.c in Sources */,
 				52ED1E0A222889500061FCE0 /* SDL_hidapi_xbox360.c in Sources */,
 				52ED1E0B222889500061FCE0 /* SDL_qsort.c in Sources */,
 				52ED1E0B222889500061FCE0 /* SDL_qsort.c in Sources */,
@@ -2673,6 +2724,7 @@
 				F3E3C6EA2241389A007D243C /* SDL_rwops.c in Sources */,
 				F3E3C6EA2241389A007D243C /* SDL_rwops.c in Sources */,
 				F3E3C6EB2241389A007D243C /* hid.m in Sources */,
 				F3E3C6EB2241389A007D243C /* hid.m in Sources */,
 				F3E3C6EC2241389A007D243C /* SDL_vulkan_utils.c in Sources */,
 				F3E3C6EC2241389A007D243C /* SDL_vulkan_utils.c in Sources */,
+				566E27062462774E00718109 /* SDL_locale.c in Sources */,
 				F3E3C6ED2241389A007D243C /* SDL_error.c in Sources */,
 				F3E3C6ED2241389A007D243C /* SDL_error.c in Sources */,
 				F3E3C6EE2241389A007D243C /* SDL.c in Sources */,
 				F3E3C6EE2241389A007D243C /* SDL.c in Sources */,
 				F3E3C6EF2241389A007D243C /* SDL_syscond.c in Sources */,
 				F3E3C6EF2241389A007D243C /* SDL_syscond.c in Sources */,
@@ -2684,6 +2736,7 @@
 				F3E3C6F52241389A007D243C /* SDL_getenv.c in Sources */,
 				F3E3C6F52241389A007D243C /* SDL_getenv.c in Sources */,
 				F3E3C6F62241389A007D243C /* SDL_iconv.c in Sources */,
 				F3E3C6F62241389A007D243C /* SDL_iconv.c in Sources */,
 				F3E3C6F72241389A007D243C /* SDL_malloc.c in Sources */,
 				F3E3C6F72241389A007D243C /* SDL_malloc.c in Sources */,
+				566E27002462774E00718109 /* SDL_syslocale.m in Sources */,
 				A7FF6B6523AC3BC6005876C6 /* SDL_hidapi_gamecube.c in Sources */,
 				A7FF6B6523AC3BC6005876C6 /* SDL_hidapi_gamecube.c in Sources */,
 				F3E3C6F82241389A007D243C /* SDL_hidapi_xbox360.c in Sources */,
 				F3E3C6F82241389A007D243C /* SDL_hidapi_xbox360.c in Sources */,
 				F3E3C6F92241389A007D243C /* SDL_qsort.c in Sources */,
 				F3E3C6F92241389A007D243C /* SDL_qsort.c in Sources */,
@@ -2847,7 +2900,9 @@
 				FAB598731BB5C31600BE72C5 /* SDL_iconv.c in Sources */,
 				FAB598731BB5C31600BE72C5 /* SDL_iconv.c in Sources */,
 				FAB598741BB5C31600BE72C5 /* SDL_malloc.c in Sources */,
 				FAB598741BB5C31600BE72C5 /* SDL_malloc.c in Sources */,
 				FAB598751BB5C31600BE72C5 /* SDL_qsort.c in Sources */,
 				FAB598751BB5C31600BE72C5 /* SDL_qsort.c in Sources */,
+				566E27052462774E00718109 /* SDL_locale.c in Sources */,
 				F36839CE214790950000F255 /* SDL_dummysensor.c in Sources */,
 				F36839CE214790950000F255 /* SDL_dummysensor.c in Sources */,
+				566E26FF2462774E00718109 /* SDL_syslocale.m in Sources */,
 				A7C19D2B212E552C00DF2152 /* SDL_displayevents.c in Sources */,
 				A7C19D2B212E552C00DF2152 /* SDL_displayevents.c in Sources */,
 				FAB598761BB5C31600BE72C5 /* SDL_stdlib.c in Sources */,
 				FAB598761BB5C31600BE72C5 /* SDL_stdlib.c in Sources */,
 				FAB598771BB5C31600BE72C5 /* SDL_string.c in Sources */,
 				FAB598771BB5C31600BE72C5 /* SDL_string.c in Sources */,
@@ -2931,6 +2986,7 @@
 				FD6526760DE8FCDD002AD96B /* SDL_rwops.c in Sources */,
 				FD6526760DE8FCDD002AD96B /* SDL_rwops.c in Sources */,
 				F30D9CC6212CE92C0047DF2E /* hid.m in Sources */,
 				F30D9CC6212CE92C0047DF2E /* hid.m in Sources */,
 				4D7517201EE1D98200820EEA /* SDL_vulkan_utils.c in Sources */,
 				4D7517201EE1D98200820EEA /* SDL_vulkan_utils.c in Sources */,
+				566E27032462774E00718109 /* SDL_locale.c in Sources */,
 				FD6526780DE8FCDD002AD96B /* SDL_error.c in Sources */,
 				FD6526780DE8FCDD002AD96B /* SDL_error.c in Sources */,
 				FD65267A0DE8FCDD002AD96B /* SDL.c in Sources */,
 				FD65267A0DE8FCDD002AD96B /* SDL.c in Sources */,
 				FD65267B0DE8FCDD002AD96B /* SDL_syscond.c in Sources */,
 				FD65267B0DE8FCDD002AD96B /* SDL_syscond.c in Sources */,
@@ -2942,6 +2998,7 @@
 				FD3F4A760DEA620800C5B771 /* SDL_getenv.c in Sources */,
 				FD3F4A760DEA620800C5B771 /* SDL_getenv.c in Sources */,
 				FD3F4A770DEA620800C5B771 /* SDL_iconv.c in Sources */,
 				FD3F4A770DEA620800C5B771 /* SDL_iconv.c in Sources */,
 				FD3F4A780DEA620800C5B771 /* SDL_malloc.c in Sources */,
 				FD3F4A780DEA620800C5B771 /* SDL_malloc.c in Sources */,
+				566E26FD2462774E00718109 /* SDL_syslocale.m in Sources */,
 				A7FF6B6223AC3BC6005876C6 /* SDL_hidapi_gamecube.c in Sources */,
 				A7FF6B6223AC3BC6005876C6 /* SDL_hidapi_gamecube.c in Sources */,
 				F3BDD79220F51CB8004ECBF3 /* SDL_hidapi_xbox360.c in Sources */,
 				F3BDD79220F51CB8004ECBF3 /* SDL_hidapi_xbox360.c in Sources */,
 				FD3F4A790DEA620800C5B771 /* SDL_qsort.c in Sources */,
 				FD3F4A790DEA620800C5B771 /* SDL_qsort.c in Sources */,

+ 64 - 0
Xcode/SDL/SDL.xcodeproj/project.pbxproj

@@ -17,6 +17,10 @@
 		564624381FF821DA0074AC87 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624371FF821CB0074AC87 /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
 		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, ); }; };
 		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, ); }; };
 		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, ); }; };
 		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 */; };
 		56C5237F1D8F4985001F2F30 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; };
 		56C523811D8F498C001F2F30 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.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 = "<group>"; };
 		4D4820431F0F10B400EDC31C /* SDL_vulkan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_vulkan.h; sourceTree = "<group>"; };
 		564624351FF821B80074AC87 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
 		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; };
 		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 = "<group>"; };
+		566E26CC246274CB00718109 /* SDL_syslocale.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDL_syslocale.m; path = locale/macosx/SDL_syslocale.m; sourceTree = "<group>"; };
+		566E26CD246274CB00718109 /* SDL_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_locale.c; path = locale/SDL_locale.c; sourceTree = "<group>"; };
+		566E26CE246274CC00718109 /* SDL_syslocale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_syslocale.h; path = locale/SDL_syslocale.h; sourceTree = "<group>"; };
 		567E2F2017C44C35005F1892 /* SDL_filesystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_filesystem.h; sourceTree = "<group>"; };
 		567E2F2017C44C35005F1892 /* SDL_filesystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_filesystem.h; sourceTree = "<group>"; };
 		5C2EF7001FC9EF0F003F5197 /* SDL_egl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_egl.h; sourceTree = "<group>"; };
 		5C2EF7001FC9EF0F003F5197 /* SDL_egl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_egl.h; sourceTree = "<group>"; };
 		75E09158241EA924004729E1 /* SDL_virtualjoystick.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_virtualjoystick.c; sourceTree = "<group>"; };
 		75E09158241EA924004729E1 /* SDL_virtualjoystick.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_virtualjoystick.c; sourceTree = "<group>"; };
@@ -4662,6 +4670,7 @@
 				AA7557DA1595D4D800BBD41B /* SDL_keyboard.h */,
 				AA7557DA1595D4D800BBD41B /* SDL_keyboard.h */,
 				AA7557DB1595D4D800BBD41B /* SDL_keycode.h */,
 				AA7557DB1595D4D800BBD41B /* SDL_keycode.h */,
 				AA7557DC1595D4D800BBD41B /* SDL_loadso.h */,
 				AA7557DC1595D4D800BBD41B /* SDL_loadso.h */,
+				566E26792462701100718109 /* SDL_locale.h */,
 				AA7557DD1595D4D800BBD41B /* SDL_log.h */,
 				AA7557DD1595D4D800BBD41B /* SDL_log.h */,
 				AA7557DE1595D4D800BBD41B /* SDL_main.h */,
 				AA7557DE1595D4D800BBD41B /* SDL_main.h */,
 				AA9FF9591637CBF9000DF050 /* SDL_messagebox.h */,
 				AA9FF9591637CBF9000DF050 /* SDL_messagebox.h */,
@@ -4760,6 +4769,7 @@
 				A7D8A79D23E2513E00DCD162 /* joystick */,
 				A7D8A79D23E2513E00DCD162 /* joystick */,
 				A7D8A91123E2514000DCD162 /* libm */,
 				A7D8A91123E2514000DCD162 /* libm */,
 				A7D8A85D23E2513F00DCD162 /* loadso */,
 				A7D8A85D23E2513F00DCD162 /* loadso */,
+				566E26CB246274AE00718109 /* locale */,
 				A7D8A5AC23E2513D00DCD162 /* main */,
 				A7D8A5AC23E2513D00DCD162 /* main */,
 				A7D8A7DF23E2513F00DCD162 /* power */,
 				A7D8A7DF23E2513F00DCD162 /* power */,
 				A7D8A8DA23E2514000DCD162 /* render */,
 				A7D8A8DA23E2514000DCD162 /* render */,
@@ -4826,6 +4836,24 @@
 			name = Frameworks;
 			name = Frameworks;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		566E26CB246274AE00718109 /* locale */ = {
+			isa = PBXGroup;
+			children = (
+				566E26EA246274E800718109 /* macosx */,
+				566E26CD246274CB00718109 /* SDL_locale.c */,
+				566E26CE246274CC00718109 /* SDL_syslocale.h */,
+			);
+			name = locale;
+			sourceTree = "<group>";
+		};
+		566E26EA246274E800718109 /* macosx */ = {
+			isa = PBXGroup;
+			children = (
+				566E26CC246274CB00718109 /* SDL_syslocale.m */,
+			);
+			name = macosx;
+			sourceTree = "<group>";
+		};
 		75E09157241EA924004729E1 /* virtual */ = {
 		75E09157241EA924004729E1 /* virtual */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -5734,6 +5762,7 @@
 				A75FCD2323E25AB700529352 /* SDL_uikitmessagebox.h in Headers */,
 				A75FCD2323E25AB700529352 /* SDL_uikitmessagebox.h in Headers */,
 				A75FCD2423E25AB700529352 /* SDL_x11messagebox.h in Headers */,
 				A75FCD2423E25AB700529352 /* SDL_x11messagebox.h in Headers */,
 				A75FCD2523E25AB700529352 /* SDL_thread_c.h in Headers */,
 				A75FCD2523E25AB700529352 /* SDL_thread_c.h in Headers */,
+				566E26812462701100718109 /* SDL_locale.h in Headers */,
 				A75FCD2623E25AB700529352 /* SDL_cocoamessagebox.h in Headers */,
 				A75FCD2623E25AB700529352 /* SDL_cocoamessagebox.h in Headers */,
 				A75FCD2723E25AB700529352 /* SDL_x11shape.h in Headers */,
 				A75FCD2723E25AB700529352 /* SDL_x11shape.h in Headers */,
 				A75FCD2823E25AB700529352 /* SDL_cpuinfo.h in Headers */,
 				A75FCD2823E25AB700529352 /* SDL_cpuinfo.h in Headers */,
@@ -5816,6 +5845,7 @@
 				A75FCD7323E25AB700529352 /* SDL_yuv_c.h in Headers */,
 				A75FCD7323E25AB700529352 /* SDL_yuv_c.h in Headers */,
 				A75FCD7423E25AB700529352 /* scancodes_xfree86.h in Headers */,
 				A75FCD7423E25AB700529352 /* scancodes_xfree86.h in Headers */,
 				A75FCD7523E25AB700529352 /* SDL_syspower.h in Headers */,
 				A75FCD7523E25AB700529352 /* SDL_syspower.h in Headers */,
+				566E26E8246274CC00718109 /* SDL_syslocale.h in Headers */,
 				A75FDAFA23E35ED600529352 /* SDL_config_iphoneos.h in Headers */,
 				A75FDAFA23E35ED600529352 /* SDL_config_iphoneos.h in Headers */,
 				A75FCD7623E25AB700529352 /* SDL_x11clipboard.h in Headers */,
 				A75FCD7623E25AB700529352 /* SDL_x11clipboard.h in Headers */,
 				A75FCD7723E25AB700529352 /* SDL_name.h in Headers */,
 				A75FCD7723E25AB700529352 /* SDL_name.h in Headers */,
@@ -5975,6 +6005,7 @@
 				A75FCEDC23E25AC700529352 /* SDL_uikitmessagebox.h in Headers */,
 				A75FCEDC23E25AC700529352 /* SDL_uikitmessagebox.h in Headers */,
 				A75FCEDD23E25AC700529352 /* SDL_x11messagebox.h in Headers */,
 				A75FCEDD23E25AC700529352 /* SDL_x11messagebox.h in Headers */,
 				A75FCEDE23E25AC700529352 /* SDL_thread_c.h in Headers */,
 				A75FCEDE23E25AC700529352 /* SDL_thread_c.h in Headers */,
+				566E26822462701100718109 /* SDL_locale.h in Headers */,
 				A75FCEDF23E25AC700529352 /* SDL_cocoamessagebox.h in Headers */,
 				A75FCEDF23E25AC700529352 /* SDL_cocoamessagebox.h in Headers */,
 				A75FCEE023E25AC700529352 /* SDL_x11shape.h in Headers */,
 				A75FCEE023E25AC700529352 /* SDL_x11shape.h in Headers */,
 				A75FCEE123E25AC700529352 /* SDL_cpuinfo.h in Headers */,
 				A75FCEE123E25AC700529352 /* SDL_cpuinfo.h in Headers */,
@@ -6057,6 +6088,7 @@
 				A75FCF2C23E25AC700529352 /* SDL_yuv_c.h in Headers */,
 				A75FCF2C23E25AC700529352 /* SDL_yuv_c.h in Headers */,
 				A75FCF2D23E25AC700529352 /* scancodes_xfree86.h in Headers */,
 				A75FCF2D23E25AC700529352 /* scancodes_xfree86.h in Headers */,
 				A75FCF2E23E25AC700529352 /* SDL_syspower.h in Headers */,
 				A75FCF2E23E25AC700529352 /* SDL_syspower.h in Headers */,
+				566E26E9246274CC00718109 /* SDL_syslocale.h in Headers */,
 				A75FDAFB23E35ED700529352 /* SDL_config_iphoneos.h in Headers */,
 				A75FDAFB23E35ED700529352 /* SDL_config_iphoneos.h in Headers */,
 				A75FCF2F23E25AC700529352 /* SDL_x11clipboard.h in Headers */,
 				A75FCF2F23E25AC700529352 /* SDL_x11clipboard.h in Headers */,
 				A75FCF3023E25AC700529352 /* SDL_name.h in Headers */,
 				A75FCF3023E25AC700529352 /* SDL_name.h in Headers */,
@@ -6240,6 +6272,7 @@
 				A769B0AA23E259AE00872273 /* SDL_uikitmessagebox.h in Headers */,
 				A769B0AA23E259AE00872273 /* SDL_uikitmessagebox.h in Headers */,
 				A769B0AB23E259AE00872273 /* SDL_x11messagebox.h in Headers */,
 				A769B0AB23E259AE00872273 /* SDL_x11messagebox.h in Headers */,
 				A769B0AC23E259AE00872273 /* SDL_thread_c.h in Headers */,
 				A769B0AC23E259AE00872273 /* SDL_thread_c.h in Headers */,
+				566E267F2462701100718109 /* SDL_locale.h in Headers */,
 				A769B0AD23E259AE00872273 /* SDL_cocoamessagebox.h in Headers */,
 				A769B0AD23E259AE00872273 /* SDL_cocoamessagebox.h in Headers */,
 				A769B0AE23E259AE00872273 /* SDL_x11shape.h in Headers */,
 				A769B0AE23E259AE00872273 /* SDL_x11shape.h in Headers */,
 				A769B0AF23E259AE00872273 /* SDL_cpuinfo.h in Headers */,
 				A769B0AF23E259AE00872273 /* SDL_cpuinfo.h in Headers */,
@@ -6322,6 +6355,7 @@
 				A769B0FB23E259AE00872273 /* SDL_yuv_c.h in Headers */,
 				A769B0FB23E259AE00872273 /* SDL_yuv_c.h in Headers */,
 				A769B0FC23E259AE00872273 /* scancodes_xfree86.h in Headers */,
 				A769B0FC23E259AE00872273 /* scancodes_xfree86.h in Headers */,
 				A769B0FD23E259AE00872273 /* SDL_syspower.h in Headers */,
 				A769B0FD23E259AE00872273 /* SDL_syspower.h in Headers */,
+				566E26E6246274CC00718109 /* SDL_syslocale.h in Headers */,
 				A75FDAF923E35ED500529352 /* SDL_config_iphoneos.h in Headers */,
 				A75FDAF923E35ED500529352 /* SDL_config_iphoneos.h in Headers */,
 				A769B0FE23E259AE00872273 /* SDL_x11clipboard.h in Headers */,
 				A769B0FE23E259AE00872273 /* SDL_x11clipboard.h in Headers */,
 				A769B0FF23E259AE00872273 /* SDL_name.h in Headers */,
 				A769B0FF23E259AE00872273 /* SDL_name.h in Headers */,
@@ -6638,10 +6672,12 @@
 				A7D8B39923E2514200DCD162 /* SDL_blit_copy.h in Headers */,
 				A7D8B39923E2514200DCD162 /* SDL_blit_copy.h in Headers */,
 				A7D8B22B23E2514200DCD162 /* gl2.h in Headers */,
 				A7D8B22B23E2514200DCD162 /* gl2.h in Headers */,
 				A7D88A5023E2437C00DCD162 /* SDL_shape.h in Headers */,
 				A7D88A5023E2437C00DCD162 /* SDL_shape.h in Headers */,
+				566E26E2246274CC00718109 /* SDL_syslocale.h in Headers */,
 				A7D88A5123E2437C00DCD162 /* SDL_stdinc.h in Headers */,
 				A7D88A5123E2437C00DCD162 /* SDL_stdinc.h in Headers */,
 				A7D8ACCA23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */,
 				A7D8ACCA23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */,
 				A7D8BBB823E254E400DCD162 /* SDL_sysjoystick_c.h in Headers */,
 				A7D8BBB823E254E400DCD162 /* SDL_sysjoystick_c.h in Headers */,
 				A7D8B3B123E2514200DCD162 /* SDL_yuv_c.h in Headers */,
 				A7D8B3B123E2514200DCD162 /* SDL_yuv_c.h in Headers */,
+				566E267B2462701100718109 /* SDL_locale.h in Headers */,
 				A7D8B1F523E2514200DCD162 /* SDL_x11dyn.h in Headers */,
 				A7D8B1F523E2514200DCD162 /* SDL_x11dyn.h in Headers */,
 				A7D8AC8823E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */,
 				A7D8AC8823E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */,
 				A7D8AC0A23E2514100DCD162 /* SDL_shape_internals.h in Headers */,
 				A7D8AC0A23E2514100DCD162 /* SDL_shape_internals.h in Headers */,
@@ -6882,10 +6918,12 @@
 				A7D88C0823E24BED00DCD162 /* SDL_scancode.h in Headers */,
 				A7D88C0823E24BED00DCD162 /* SDL_scancode.h in Headers */,
 				A7D8B39A23E2514200DCD162 /* SDL_blit_copy.h in Headers */,
 				A7D8B39A23E2514200DCD162 /* SDL_blit_copy.h in Headers */,
 				A7D8B22C23E2514200DCD162 /* gl2.h in Headers */,
 				A7D8B22C23E2514200DCD162 /* gl2.h in Headers */,
+				566E26E3246274CC00718109 /* SDL_syslocale.h in Headers */,
 				A7D88C0A23E24BED00DCD162 /* SDL_shape.h in Headers */,
 				A7D88C0A23E24BED00DCD162 /* SDL_shape.h in Headers */,
 				A7D88C0C23E24BED00DCD162 /* SDL_stdinc.h in Headers */,
 				A7D88C0C23E24BED00DCD162 /* SDL_stdinc.h in Headers */,
 				A7D8ACCB23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */,
 				A7D8ACCB23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */,
 				A7D8B3B223E2514200DCD162 /* SDL_yuv_c.h in Headers */,
 				A7D8B3B223E2514200DCD162 /* SDL_yuv_c.h in Headers */,
+				566E267C2462701100718109 /* SDL_locale.h in Headers */,
 				A7D8B1F623E2514200DCD162 /* SDL_x11dyn.h in Headers */,
 				A7D8B1F623E2514200DCD162 /* SDL_x11dyn.h in Headers */,
 				A7D8AC8923E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */,
 				A7D8AC8923E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */,
 				A7D8AC0B23E2514100DCD162 /* SDL_shape_internals.h in Headers */,
 				A7D8AC0B23E2514100DCD162 /* SDL_shape_internals.h in Headers */,
@@ -6969,6 +7007,7 @@
 				A7D8AC9723E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */,
 				A7D8AC9723E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */,
 				A7D8B15023E2514200DCD162 /* SDL_x11messagebox.h in Headers */,
 				A7D8B15023E2514200DCD162 /* SDL_x11messagebox.h in Headers */,
 				A7D8B3F023E2514300DCD162 /* SDL_thread_c.h in Headers */,
 				A7D8B3F023E2514300DCD162 /* SDL_thread_c.h in Headers */,
+				566E267E2462701100718109 /* SDL_locale.h in Headers */,
 				A7D8AF0A23E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */,
 				A7D8AF0A23E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */,
 				A7D8B16823E2514200DCD162 /* SDL_x11shape.h in Headers */,
 				A7D8B16823E2514200DCD162 /* SDL_x11shape.h in Headers */,
 				A7D88D2723E24D3B00DCD162 /* SDL_cpuinfo.h in Headers */,
 				A7D88D2723E24D3B00DCD162 /* SDL_cpuinfo.h in Headers */,
@@ -7051,6 +7090,7 @@
 				A7D8B3B423E2514200DCD162 /* SDL_yuv_c.h in Headers */,
 				A7D8B3B423E2514200DCD162 /* SDL_yuv_c.h in Headers */,
 				A7D8BBA323E2514500DCD162 /* scancodes_xfree86.h in Headers */,
 				A7D8BBA323E2514500DCD162 /* scancodes_xfree86.h in Headers */,
 				A7D8B5D923E2514300DCD162 /* SDL_syspower.h in Headers */,
 				A7D8B5D923E2514300DCD162 /* SDL_syspower.h in Headers */,
+				566E26E5246274CC00718109 /* SDL_syslocale.h in Headers */,
 				A75FDAF823E35ED500529352 /* SDL_config_iphoneos.h in Headers */,
 				A75FDAF823E35ED500529352 /* SDL_config_iphoneos.h in Headers */,
 				A7D8B21023E2514200DCD162 /* SDL_x11clipboard.h in Headers */,
 				A7D8B21023E2514200DCD162 /* SDL_x11clipboard.h in Headers */,
 				A7D88D3923E24D3B00DCD162 /* SDL_name.h in Headers */,
 				A7D88D3923E24D3B00DCD162 /* SDL_name.h in Headers */,
@@ -7185,6 +7225,7 @@
 				A7D8BBE023E2574800DCD162 /* SDL_uikitopenglview.h in Headers */,
 				A7D8BBE023E2574800DCD162 /* SDL_uikitopenglview.h in Headers */,
 				A7D8B4AC23E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */,
 				A7D8B4AC23E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */,
 				A7D8B9EF23E2514400DCD162 /* SDL_drawpoint.h in Headers */,
 				A7D8B9EF23E2514400DCD162 /* SDL_drawpoint.h in Headers */,
+				566E26E1246274CC00718109 /* SDL_syslocale.h in Headers */,
 				A7D8B39E23E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */,
 				A7D8B39E23E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */,
 				A7D8B44023E2514300DCD162 /* SDL_sysmutex_c.h in Headers */,
 				A7D8B44023E2514300DCD162 /* SDL_sysmutex_c.h in Headers */,
 				A7D8BA4323E2514400DCD162 /* SDL_glesfuncs.h in Headers */,
 				A7D8BA4323E2514400DCD162 /* SDL_glesfuncs.h in Headers */,
@@ -7321,6 +7362,7 @@
 				A7D8BB9F23E2514500DCD162 /* scancodes_xfree86.h in Headers */,
 				A7D8BB9F23E2514500DCD162 /* scancodes_xfree86.h in Headers */,
 				A7D8BBE623E2574800DCD162 /* SDL_uikitviewcontroller.h in Headers */,
 				A7D8BBE623E2574800DCD162 /* SDL_uikitviewcontroller.h in Headers */,
 				A7D8AF1E23E2514100DCD162 /* SDL_cocoamouse.h in Headers */,
 				A7D8AF1E23E2514100DCD162 /* SDL_cocoamouse.h in Headers */,
+				566E267A2462701100718109 /* SDL_locale.h in Headers */,
 				A7D8BBEA23E2574800DCD162 /* SDL_uikitwindow.h in Headers */,
 				A7D8BBEA23E2574800DCD162 /* SDL_uikitwindow.h in Headers */,
 				A7D8AE8E23E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */,
 				A7D8AE8E23E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */,
 				A7D8BA4F23E2514400DCD162 /* SDL_shaders_gles2.h in Headers */,
 				A7D8BA4F23E2514400DCD162 /* SDL_shaders_gles2.h in Headers */,
@@ -7484,6 +7526,7 @@
 				A7D8BA7623E2514400DCD162 /* SDL_shaders_gl.h in Headers */,
 				A7D8BA7623E2514400DCD162 /* SDL_shaders_gl.h in Headers */,
 				A7D8B42B23E2514300DCD162 /* SDL_systhread_c.h in Headers */,
 				A7D8B42B23E2514300DCD162 /* SDL_systhread_c.h in Headers */,
 				AA7558231595D4D800BBD41B /* SDL_keycode.h in Headers */,
 				AA7558231595D4D800BBD41B /* SDL_keycode.h in Headers */,
+				566E26E4246274CC00718109 /* SDL_syslocale.h in Headers */,
 				A7D8B20923E2514200DCD162 /* SDL_x11keyboard.h in Headers */,
 				A7D8B20923E2514200DCD162 /* SDL_x11keyboard.h in Headers */,
 				A7D8AE9123E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */,
 				A7D8AE9123E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */,
 				A7D8B1F123E2514200DCD162 /* SDL_x11framebuffer.h in Headers */,
 				A7D8B1F123E2514200DCD162 /* SDL_x11framebuffer.h in Headers */,
@@ -7552,6 +7595,7 @@
 				A7D8BB6023E2514500DCD162 /* scancodes_linux.h in Headers */,
 				A7D8BB6023E2514500DCD162 /* scancodes_linux.h in Headers */,
 				A7D8B1F723E2514200DCD162 /* SDL_x11dyn.h in Headers */,
 				A7D8B1F723E2514200DCD162 /* SDL_x11dyn.h in Headers */,
 				A7D8BB6623E2514500DCD162 /* SDL_touch_c.h in Headers */,
 				A7D8BB6623E2514500DCD162 /* SDL_touch_c.h in Headers */,
+				566E267D2462701100718109 /* SDL_locale.h in Headers */,
 				A7D8B4AF23E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */,
 				A7D8B4AF23E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */,
 				A7D8AEEB23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */,
 				A7D8AEEB23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */,
 				A7D8B23323E2514200DCD162 /* gl2platform.h in Headers */,
 				A7D8B23323E2514200DCD162 /* gl2platform.h in Headers */,
@@ -7724,6 +7768,7 @@
 				A7D8BBB023E2514500DCD162 /* SDL_windowevents_c.h in Headers */,
 				A7D8BBB023E2514500DCD162 /* SDL_windowevents_c.h in Headers */,
 				DB313FD917554B71006C0E22 /* SDL_joystick.h in Headers */,
 				DB313FD917554B71006C0E22 /* SDL_joystick.h in Headers */,
 				A7D8AF0523E2514100DCD162 /* SDL_cocoavideo.h in Headers */,
 				A7D8AF0523E2514100DCD162 /* SDL_cocoavideo.h in Headers */,
+				566E26E7246274CC00718109 /* SDL_syslocale.h in Headers */,
 				DB313FDA17554B71006C0E22 /* SDL_keyboard.h in Headers */,
 				DB313FDA17554B71006C0E22 /* SDL_keyboard.h in Headers */,
 				A7D8ACC223E2514100DCD162 /* SDL_uikitevents.h in Headers */,
 				A7D8ACC223E2514100DCD162 /* SDL_uikitevents.h in Headers */,
 				A7D8BB3E23E2514500DCD162 /* SDL_gesture_c.h in Headers */,
 				A7D8BB3E23E2514500DCD162 /* SDL_gesture_c.h in Headers */,
@@ -7792,6 +7837,7 @@
 				A7D8AC0223E2514100DCD162 /* SDL_nullevents_c.h in Headers */,
 				A7D8AC0223E2514100DCD162 /* SDL_nullevents_c.h in Headers */,
 				A7D8B58623E2514300DCD162 /* SDL_sysjoystick.h in Headers */,
 				A7D8B58623E2514300DCD162 /* SDL_sysjoystick.h in Headers */,
 				A7D8BBCF23E2561600DCD162 /* SDL_steamcontroller.h in Headers */,
 				A7D8BBCF23E2561600DCD162 /* SDL_steamcontroller.h in Headers */,
+				566E26802462701100718109 /* SDL_locale.h in Headers */,
 				A7D8BB6223E2514500DCD162 /* scancodes_linux.h in Headers */,
 				A7D8BB6223E2514500DCD162 /* scancodes_linux.h in Headers */,
 				A7D8B1F923E2514200DCD162 /* SDL_x11dyn.h in Headers */,
 				A7D8B1F923E2514200DCD162 /* SDL_x11dyn.h in Headers */,
 				A7D8BB6823E2514500DCD162 /* SDL_touch_c.h in Headers */,
 				A7D8BB6823E2514500DCD162 /* SDL_touch_c.h in Headers */,
@@ -8393,6 +8439,7 @@
 				A75FCE2C23E25AB700529352 /* SDL_cocoakeyboard.m in Sources */,
 				A75FCE2C23E25AB700529352 /* SDL_cocoakeyboard.m in Sources */,
 				A75FCE2D23E25AB700529352 /* SDL_dynapi.c in Sources */,
 				A75FCE2D23E25AB700529352 /* SDL_dynapi.c in Sources */,
 				A75FCE2E23E25AB700529352 /* SDL_shaders_gl.c in Sources */,
 				A75FCE2E23E25AB700529352 /* SDL_shaders_gl.c in Sources */,
+				566E26DF246274CC00718109 /* SDL_locale.c in Sources */,
 				A75FCE2F23E25AB700529352 /* e_log.c in Sources */,
 				A75FCE2F23E25AB700529352 /* e_log.c in Sources */,
 				A75FCE3023E25AB700529352 /* SDL_cocoamessagebox.m in Sources */,
 				A75FCE3023E25AB700529352 /* SDL_cocoamessagebox.m in Sources */,
 				A75FCE3123E25AB700529352 /* SDL_blendfillrect.c in Sources */,
 				A75FCE3123E25AB700529352 /* SDL_blendfillrect.c in Sources */,
@@ -8465,6 +8512,7 @@
 				A75FCE7523E25AB700529352 /* SDL_rect.c in Sources */,
 				A75FCE7523E25AB700529352 /* SDL_rect.c in Sources */,
 				A75FCE7623E25AB700529352 /* SDL_cocoaopengles.m in Sources */,
 				A75FCE7623E25AB700529352 /* SDL_cocoaopengles.m in Sources */,
 				A75FCE7723E25AB700529352 /* SDL_qsort.c in Sources */,
 				A75FCE7723E25AB700529352 /* SDL_qsort.c in Sources */,
+				566E26D6246274CC00718109 /* SDL_syslocale.m in Sources */,
 				A75FCE7823E25AB700529352 /* SDL_hidapi_switch.c in Sources */,
 				A75FCE7823E25AB700529352 /* SDL_hidapi_switch.c in Sources */,
 				A75FCE7923E25AB700529352 /* SDL_strtokr.c in Sources */,
 				A75FCE7923E25AB700529352 /* SDL_strtokr.c in Sources */,
 				A75FCE7A23E25AB700529352 /* SDL_clipboardevents.c in Sources */,
 				A75FCE7A23E25AB700529352 /* SDL_clipboardevents.c in Sources */,
@@ -8589,6 +8637,7 @@
 				A75FCFE523E25AC700529352 /* SDL_cocoakeyboard.m in Sources */,
 				A75FCFE523E25AC700529352 /* SDL_cocoakeyboard.m in Sources */,
 				A75FCFE623E25AC700529352 /* SDL_dynapi.c in Sources */,
 				A75FCFE623E25AC700529352 /* SDL_dynapi.c in Sources */,
 				A75FCFE723E25AC700529352 /* SDL_shaders_gl.c in Sources */,
 				A75FCFE723E25AC700529352 /* SDL_shaders_gl.c in Sources */,
+				566E26E0246274CC00718109 /* SDL_locale.c in Sources */,
 				A75FCFE823E25AC700529352 /* e_log.c in Sources */,
 				A75FCFE823E25AC700529352 /* e_log.c in Sources */,
 				A75FCFE923E25AC700529352 /* SDL_cocoamessagebox.m in Sources */,
 				A75FCFE923E25AC700529352 /* SDL_cocoamessagebox.m in Sources */,
 				A75FCFEA23E25AC700529352 /* SDL_blendfillrect.c in Sources */,
 				A75FCFEA23E25AC700529352 /* SDL_blendfillrect.c in Sources */,
@@ -8661,6 +8710,7 @@
 				A75FD02E23E25AC700529352 /* SDL_rect.c in Sources */,
 				A75FD02E23E25AC700529352 /* SDL_rect.c in Sources */,
 				A75FD02F23E25AC700529352 /* SDL_cocoaopengles.m in Sources */,
 				A75FD02F23E25AC700529352 /* SDL_cocoaopengles.m in Sources */,
 				A75FD03023E25AC700529352 /* SDL_qsort.c in Sources */,
 				A75FD03023E25AC700529352 /* SDL_qsort.c in Sources */,
+				566E26D7246274CC00718109 /* SDL_syslocale.m in Sources */,
 				A75FD03123E25AC700529352 /* SDL_hidapi_switch.c in Sources */,
 				A75FD03123E25AC700529352 /* SDL_hidapi_switch.c in Sources */,
 				A75FD03223E25AC700529352 /* SDL_strtokr.c in Sources */,
 				A75FD03223E25AC700529352 /* SDL_strtokr.c in Sources */,
 				A75FD03323E25AC700529352 /* SDL_clipboardevents.c in Sources */,
 				A75FD03323E25AC700529352 /* SDL_clipboardevents.c in Sources */,
@@ -8879,12 +8929,14 @@
 				A769B1FD23E259AE00872273 /* SDL_blit_auto.c in Sources */,
 				A769B1FD23E259AE00872273 /* SDL_blit_auto.c in Sources */,
 				A769B1FE23E259AE00872273 /* SDL_x11keyboard.c in Sources */,
 				A769B1FE23E259AE00872273 /* SDL_x11keyboard.c in Sources */,
 				A769B1FF23E259AE00872273 /* SDL_keyboard.c in Sources */,
 				A769B1FF23E259AE00872273 /* SDL_keyboard.c in Sources */,
+				566E26DD246274CC00718109 /* SDL_locale.c in Sources */,
 				A769B20123E259AE00872273 /* SDL_rect.c in Sources */,
 				A769B20123E259AE00872273 /* SDL_rect.c in Sources */,
 				A769B20223E259AE00872273 /* SDL_cocoaopengles.m in Sources */,
 				A769B20223E259AE00872273 /* SDL_cocoaopengles.m in Sources */,
 				A769B20323E259AE00872273 /* SDL_qsort.c in Sources */,
 				A769B20323E259AE00872273 /* SDL_qsort.c in Sources */,
 				A75FDB5223E39D1700529352 /* hid.m in Sources */,
 				A75FDB5223E39D1700529352 /* hid.m in Sources */,
 				A769B20423E259AE00872273 /* SDL_hidapi_switch.c in Sources */,
 				A769B20423E259AE00872273 /* SDL_hidapi_switch.c in Sources */,
 				A769B20523E259AE00872273 /* SDL_strtokr.c in Sources */,
 				A769B20523E259AE00872273 /* SDL_strtokr.c in Sources */,
+				566E26D4246274CC00718109 /* SDL_syslocale.m in Sources */,
 				A769B20623E259AE00872273 /* SDL_clipboardevents.c in Sources */,
 				A769B20623E259AE00872273 /* SDL_clipboardevents.c in Sources */,
 				A769B20723E259AE00872273 /* SDL_x11framebuffer.c in Sources */,
 				A769B20723E259AE00872273 /* SDL_x11framebuffer.c in Sources */,
 				A769B20823E259AE00872273 /* k_cos.c in Sources */,
 				A769B20823E259AE00872273 /* k_cos.c in Sources */,
@@ -9097,10 +9149,12 @@
 				A7D8AAB123E2514100DCD162 /* SDL_syshaptic.c in Sources */,
 				A7D8AAB123E2514100DCD162 /* SDL_syshaptic.c in Sources */,
 				A7D8B5CA23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */,
 				A7D8B5CA23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */,
 				A7D8AC1023E2514100DCD162 /* SDL_video.c in Sources */,
 				A7D8AC1023E2514100DCD162 /* SDL_video.c in Sources */,
+				566E26D0246274CC00718109 /* SDL_syslocale.m in Sources */,
 				A7D8AB5623E2514100DCD162 /* SDL_offscreenopengl.c in Sources */,
 				A7D8AB5623E2514100DCD162 /* SDL_offscreenopengl.c in Sources */,
 				A7D8ACC423E2514100DCD162 /* SDL_uikitmetalview.m in Sources */,
 				A7D8ACC423E2514100DCD162 /* SDL_uikitmetalview.m in Sources */,
 				A7D8BA5C23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */,
 				A7D8BA5C23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */,
 				A7D8B14123E2514200DCD162 /* SDL_blit_1.c in Sources */,
 				A7D8B14123E2514200DCD162 /* SDL_blit_1.c in Sources */,
+				566E26D9246274CC00718109 /* SDL_locale.c in Sources */,
 				A7D8B17D23E2514200DCD162 /* SDL_x11dyn.c in Sources */,
 				A7D8B17D23E2514200DCD162 /* SDL_x11dyn.c in Sources */,
 				A7D8BB1623E2514500DCD162 /* SDL_mouse.c in Sources */,
 				A7D8BB1623E2514500DCD162 /* SDL_mouse.c in Sources */,
 				A7D8BADA23E2514500DCD162 /* e_rem_pio2.c in Sources */,
 				A7D8BADA23E2514500DCD162 /* e_rem_pio2.c in Sources */,
@@ -9292,10 +9346,12 @@
 				A7D8AAB223E2514100DCD162 /* SDL_syshaptic.c in Sources */,
 				A7D8AAB223E2514100DCD162 /* SDL_syshaptic.c in Sources */,
 				A7D8B5CB23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */,
 				A7D8B5CB23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */,
 				A7D8AC1123E2514100DCD162 /* SDL_video.c in Sources */,
 				A7D8AC1123E2514100DCD162 /* SDL_video.c in Sources */,
+				566E26D1246274CC00718109 /* SDL_syslocale.m in Sources */,
 				A7D8AB5723E2514100DCD162 /* SDL_offscreenopengl.c in Sources */,
 				A7D8AB5723E2514100DCD162 /* SDL_offscreenopengl.c in Sources */,
 				A7D8ACC523E2514100DCD162 /* SDL_uikitmetalview.m in Sources */,
 				A7D8ACC523E2514100DCD162 /* SDL_uikitmetalview.m in Sources */,
 				A7D8BA5D23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */,
 				A7D8BA5D23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */,
 				A7D8B14223E2514200DCD162 /* SDL_blit_1.c in Sources */,
 				A7D8B14223E2514200DCD162 /* SDL_blit_1.c in Sources */,
+				566E26DA246274CC00718109 /* SDL_locale.c in Sources */,
 				A7D8B17E23E2514200DCD162 /* SDL_x11dyn.c in Sources */,
 				A7D8B17E23E2514200DCD162 /* SDL_x11dyn.c in Sources */,
 				A7D8BB1723E2514500DCD162 /* SDL_mouse.c in Sources */,
 				A7D8BB1723E2514500DCD162 /* SDL_mouse.c in Sources */,
 				A7D8BADB23E2514500DCD162 /* e_rem_pio2.c in Sources */,
 				A7D8BADB23E2514500DCD162 /* e_rem_pio2.c in Sources */,
@@ -9466,12 +9522,14 @@
 				A7D8AD2723E2514100DCD162 /* SDL_blit_auto.c in Sources */,
 				A7D8AD2723E2514100DCD162 /* SDL_blit_auto.c in Sources */,
 				A7D8B1AA23E2514200DCD162 /* SDL_x11keyboard.c in Sources */,
 				A7D8B1AA23E2514200DCD162 /* SDL_x11keyboard.c in Sources */,
 				A7D8BB6D23E2514500DCD162 /* SDL_keyboard.c in Sources */,
 				A7D8BB6D23E2514500DCD162 /* SDL_keyboard.c in Sources */,
+				566E26DC246274CC00718109 /* SDL_locale.c in Sources */,
 				A7D8ACEB23E2514100DCD162 /* SDL_rect.c in Sources */,
 				A7D8ACEB23E2514100DCD162 /* SDL_rect.c in Sources */,
 				A7D8AE9E23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */,
 				A7D8AE9E23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */,
 				A7D8B96C23E2514400DCD162 /* SDL_qsort.c in Sources */,
 				A7D8B96C23E2514400DCD162 /* SDL_qsort.c in Sources */,
 				A75FDB5123E39D1700529352 /* hid.m in Sources */,
 				A75FDB5123E39D1700529352 /* hid.m in Sources */,
 				A7D8B55523E2514300DCD162 /* SDL_hidapi_switch.c in Sources */,
 				A7D8B55523E2514300DCD162 /* SDL_hidapi_switch.c in Sources */,
 				A7D8B96623E2514400DCD162 /* SDL_strtokr.c in Sources */,
 				A7D8B96623E2514400DCD162 /* SDL_strtokr.c in Sources */,
+				566E26D3246274CC00718109 /* SDL_syslocale.m in Sources */,
 				A7D8BB7923E2514500DCD162 /* SDL_clipboardevents.c in Sources */,
 				A7D8BB7923E2514500DCD162 /* SDL_clipboardevents.c in Sources */,
 				A7D8B18623E2514200DCD162 /* SDL_x11framebuffer.c in Sources */,
 				A7D8B18623E2514200DCD162 /* SDL_x11framebuffer.c in Sources */,
 				A7D8BAB923E2514400DCD162 /* k_cos.c in Sources */,
 				A7D8BAB923E2514400DCD162 /* k_cos.c in Sources */,
@@ -9635,6 +9693,7 @@
 				A7D8BB0923E2514500DCD162 /* k_tan.c in Sources */,
 				A7D8BB0923E2514500DCD162 /* k_tan.c in Sources */,
 				A7D8B15E23E2514200DCD162 /* SDL_x11vulkan.c in Sources */,
 				A7D8B15E23E2514200DCD162 /* SDL_x11vulkan.c in Sources */,
 				A7D8B8A823E2514400DCD162 /* SDL_diskaudio.c in Sources */,
 				A7D8B8A823E2514400DCD162 /* SDL_diskaudio.c in Sources */,
+				566E26CF246274CC00718109 /* SDL_syslocale.m in Sources */,
 				A7D8AFC023E2514200DCD162 /* SDL_egl.c in Sources */,
 				A7D8AFC023E2514200DCD162 /* SDL_egl.c in Sources */,
 				A7D8AC3323E2514100DCD162 /* SDL_RLEaccel.c in Sources */,
 				A7D8AC3323E2514100DCD162 /* SDL_RLEaccel.c in Sources */,
 				A7D8BBB123E2514500DCD162 /* SDL_assert.c in Sources */,
 				A7D8BBB123E2514500DCD162 /* SDL_assert.c in Sources */,
@@ -9706,6 +9765,7 @@
 				A7D8B15823E2514200DCD162 /* SDL_x11opengl.c in Sources */,
 				A7D8B15823E2514200DCD162 /* SDL_x11opengl.c in Sources */,
 				A7D8AEA023E2514100DCD162 /* SDL_cocoavulkan.m in Sources */,
 				A7D8AEA023E2514100DCD162 /* SDL_cocoavulkan.m in Sources */,
 				A7D8AB6123E2514100DCD162 /* SDL_offscreenwindow.c in Sources */,
 				A7D8AB6123E2514100DCD162 /* SDL_offscreenwindow.c in Sources */,
+				566E26D8246274CC00718109 /* SDL_locale.c in Sources */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
@@ -9805,6 +9865,7 @@
 				A7D8B5F623E2514300DCD162 /* SDL_syspower.c in Sources */,
 				A7D8B5F623E2514300DCD162 /* SDL_syspower.c in Sources */,
 				A7D8B1C723E2514200DCD162 /* SDL_x11touch.c in Sources */,
 				A7D8B1C723E2514200DCD162 /* SDL_x11touch.c in Sources */,
 				A7D8B95323E2514400DCD162 /* SDL_iconv.c in Sources */,
 				A7D8B95323E2514400DCD162 /* SDL_iconv.c in Sources */,
+				566E26DB246274CC00718109 /* SDL_locale.c in Sources */,
 				A7D8BAA023E2514400DCD162 /* s_fabs.c in Sources */,
 				A7D8BAA023E2514400DCD162 /* s_fabs.c in Sources */,
 				A7D8B1E523E2514200DCD162 /* SDL_x11shape.c in Sources */,
 				A7D8B1E523E2514200DCD162 /* SDL_x11shape.c in Sources */,
 				A7D8BC0423E2574800DCD162 /* SDL_uikitvulkan.m in Sources */,
 				A7D8BC0423E2574800DCD162 /* SDL_uikitvulkan.m in Sources */,
@@ -9880,6 +9941,7 @@
 				A7D8AC1223E2514100DCD162 /* SDL_video.c in Sources */,
 				A7D8AC1223E2514100DCD162 /* SDL_video.c in Sources */,
 				A7D8AB5823E2514100DCD162 /* SDL_offscreenopengl.c in Sources */,
 				A7D8AB5823E2514100DCD162 /* SDL_offscreenopengl.c in Sources */,
 				A7D8BA5E23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */,
 				A7D8BA5E23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */,
+				566E26D2246274CC00718109 /* SDL_syslocale.m in Sources */,
 				A7D8B14323E2514200DCD162 /* SDL_blit_1.c in Sources */,
 				A7D8B14323E2514200DCD162 /* SDL_blit_1.c in Sources */,
 				A7D8B17F23E2514200DCD162 /* SDL_x11dyn.c in Sources */,
 				A7D8B17F23E2514200DCD162 /* SDL_x11dyn.c in Sources */,
 				A7D8BB1823E2514500DCD162 /* SDL_mouse.c in Sources */,
 				A7D8BB1823E2514500DCD162 /* SDL_mouse.c in Sources */,
@@ -9999,6 +10061,7 @@
 				A7D8B76323E2514300DCD162 /* SDL_sysloadso.c in Sources */,
 				A7D8B76323E2514300DCD162 /* SDL_sysloadso.c in Sources */,
 				A7D8B16F23E2514200DCD162 /* SDL_x11xinput2.c in Sources */,
 				A7D8B16F23E2514200DCD162 /* SDL_x11xinput2.c in Sources */,
 				A7D8B5F823E2514300DCD162 /* SDL_syspower.c in Sources */,
 				A7D8B5F823E2514300DCD162 /* SDL_syspower.c in Sources */,
+				566E26DE246274CC00718109 /* SDL_locale.c in Sources */,
 				A7D8B1C923E2514200DCD162 /* SDL_x11touch.c in Sources */,
 				A7D8B1C923E2514200DCD162 /* SDL_x11touch.c in Sources */,
 				A7D8B95523E2514400DCD162 /* SDL_iconv.c in Sources */,
 				A7D8B95523E2514400DCD162 /* SDL_iconv.c in Sources */,
 				A7D8BAA223E2514400DCD162 /* s_fabs.c in Sources */,
 				A7D8BAA223E2514400DCD162 /* s_fabs.c in Sources */,
@@ -10074,6 +10137,7 @@
 				A7D8ACC823E2514100DCD162 /* SDL_uikitmetalview.m in Sources */,
 				A7D8ACC823E2514100DCD162 /* SDL_uikitmetalview.m in Sources */,
 				A7D8BBBA23E2560600DCD162 /* SDL_steamcontroller.c in Sources */,
 				A7D8BBBA23E2560600DCD162 /* SDL_steamcontroller.c in Sources */,
 				A7D8BA6023E2514400DCD162 /* SDL_shaders_gles2.c in Sources */,
 				A7D8BA6023E2514400DCD162 /* SDL_shaders_gles2.c in Sources */,
+				566E26D5246274CC00718109 /* SDL_syslocale.m in Sources */,
 				A7D8B14523E2514200DCD162 /* SDL_blit_1.c in Sources */,
 				A7D8B14523E2514200DCD162 /* SDL_blit_1.c in Sources */,
 				A7D8B18123E2514200DCD162 /* SDL_x11dyn.c in Sources */,
 				A7D8B18123E2514200DCD162 /* SDL_x11dyn.c in Sources */,
 				A7D8BB1A23E2514500DCD162 /* SDL_mouse.c in Sources */,
 				A7D8BB1A23E2514500DCD162 /* SDL_mouse.c in Sources */,

+ 42 - 1
configure

@@ -770,6 +770,7 @@ infodir
 docdir
 docdir
 oldincludedir
 oldincludedir
 includedir
 includedir
+runstatedir
 localstatedir
 localstatedir
 sharedstatedir
 sharedstatedir
 sysconfdir
 sysconfdir
@@ -981,6 +982,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE}'
 docdir='${datarootdir}/doc/${PACKAGE}'
@@ -1233,6 +1235,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
     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)
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1370,7 +1381,7 @@ fi
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir
+		libdir localedir mandir runstatedir
 do
 do
   eval ac_val=\$$ac_var
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
   # Remove trailing slashes.
@@ -1523,6 +1534,7 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/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/timer/*.c"
 SOURCES="$SOURCES $srcdir/src/video/*.c"
 SOURCES="$SOURCES $srcdir/src/video/*.c"
 SOURCES="$SOURCES $srcdir/src/video/yuv2rgb/*.c"
 SOURCES="$SOURCES $srcdir/src/video/yuv2rgb/*.c"
+SOURCES="$SOURCES $srcdir/src/locale/*.c"
 
 
 
 
 # Check whether --enable-atomic was given.
 # Check whether --enable-atomic was given.
@@ -24659,6 +24672,8 @@ CheckNoStrictAliasing
 
 
 CheckEventSignals
 CheckEventSignals
 
 
+have_locale=no
+
 case "$host" in
 case "$host" in
     *-*-linux*|*-*-uclinux*|*-*-gnu*|*-*-k*bsd*-gnu|*-*-bsdi*|*-*-freebsd*|*-*-dragonfly*|*-*-netbsd*|*-*-openbsd*|*-*-sysv5*|*-*-solaris*|*-*-hpux*|*-*-aix*|*-*-minix*|*-*-nto*)
     *-*-linux*|*-*-uclinux*|*-*-gnu*|*-*-k*bsd*-gnu|*-*-bsdi*|*-*-freebsd*|*-*-dragonfly*|*-*-netbsd*|*-*-openbsd*|*-*-sysv5*|*-*-solaris*|*-*-hpux*|*-*-aix*|*-*-minix*|*-*-nto*)
         case "$host" in
         case "$host" in
@@ -24746,6 +24761,9 @@ case "$host" in
         CheckRPATH
         CheckRPATH
         CheckVivanteVideo
         CheckVivanteVideo
 
 
+        SOURCES="$SOURCES $srcdir/src/locale/unix/*.c"
+        have_locale=yes
+
         # Set up files for the audio library
         # Set up files for the audio library
         if test x$enable_audio = xyes; then
         if test x$enable_audio = xyes; then
           case $ARCH in
           case $ARCH in
@@ -24923,6 +24941,10 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h
         # Set up the core platform files
         # Set up the core platform files
         SOURCES="$SOURCES $srcdir/src/core/windows/*.c"
         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
         # Set up files for the video library
         if test x$enable_video = xyes; then
         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"
             SOURCES="$SOURCES $srcdir/src/filesystem/haiku/*.cc"
             have_filesystem=yes
             have_filesystem=yes
         fi
         fi
+
+        # Set up files for the locale library
+        SOURCES="$SOURCES $srcdir/src/locale/haiku/*.cc"
+        have_locale=yes
+
         # The Haiku platform requires special setup.
         # The Haiku platform requires special setup.
         SOURCES="$srcdir/src/main/haiku/*.cc $SOURCES"
         SOURCES="$srcdir/src/main/haiku/*.cc $SOURCES"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lroot -lbe -lmedia -lgame -ldevice -ltextencoding"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lroot -lbe -lmedia -lgame -ldevice -ltextencoding"
@@ -25216,6 +25243,10 @@ fi
         CheckVulkan
         CheckVulkan
         CheckPTHREAD
         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
         # Set up files for the audio library
         if test x$enable_audio = xyes; then
         if test x$enable_audio = xyes; then
 
 
@@ -25337,6 +25368,10 @@ $as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h
         CheckPTHREAD
         CheckPTHREAD
         CheckHIDAPI
         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
         # Set up files for the audio library
         if test x$enable_audio = xyes; then
         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"
             SOURCES="$SOURCES $srcdir/src/timer/unix/*.c"
             have_timers=yes
             have_timers=yes
         fi
         fi
+        # Set up files for the locale library
+        SOURCES="$SOURCES $srcdir/src/locale/emscripten/*.c"
+        have_locale=yes
         ;;
         ;;
     *-*-riscos*)
     *-*-riscos*)
         ARCH=riscos
         ARCH=riscos
@@ -25549,6 +25587,9 @@ INSTALL_SDL2_CONFIG=$enable_sdl2_config
 
 
 # Verify that we have all the platform specific files we need
 # 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$have_joystick != xyes; then
     if test x$enable_joystick = xyes; then
     if test x$enable_joystick = xyes; then
 
 

+ 29 - 0
configure.ac

@@ -413,6 +413,7 @@ SOURCES="$SOURCES $srcdir/src/thread/*.c"
 SOURCES="$SOURCES $srcdir/src/timer/*.c"
 SOURCES="$SOURCES $srcdir/src/timer/*.c"
 SOURCES="$SOURCES $srcdir/src/video/*.c"
 SOURCES="$SOURCES $srcdir/src/video/*.c"
 SOURCES="$SOURCES $srcdir/src/video/yuv2rgb/*.c"
 SOURCES="$SOURCES $srcdir/src/video/yuv2rgb/*.c"
+SOURCES="$SOURCES $srcdir/src/locale/*.c"
 
 
 dnl Enable/disable various subsystems of the SDL library
 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.
 dnl Do this for every platform, but for some it doesn't mean anything, but better to catch it here anyhow.
 CheckEventSignals
 CheckEventSignals
 
 
+have_locale=no
+
 dnl Set up the configuration based on the host platform!
 dnl Set up the configuration based on the host platform!
 case "$host" in
 case "$host" in
     *-*-linux*|*-*-uclinux*|*-*-gnu*|*-*-k*bsd*-gnu|*-*-bsdi*|*-*-freebsd*|*-*-dragonfly*|*-*-netbsd*|*-*-openbsd*|*-*-sysv5*|*-*-solaris*|*-*-hpux*|*-*-aix*|*-*-minix*|*-*-nto*)
     *-*-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
         CheckRPATH
         CheckVivanteVideo
         CheckVivanteVideo
 
 
+        SOURCES="$SOURCES $srcdir/src/locale/unix/*.c"
+        have_locale=yes
+
         # Set up files for the audio library
         # Set up files for the audio library
         if test x$enable_audio = xyes; then
         if test x$enable_audio = xyes; then
           case $ARCH in
           case $ARCH in
@@ -3676,6 +3682,10 @@ case "$host" in
         # Set up the core platform files
         # Set up the core platform files
         SOURCES="$SOURCES $srcdir/src/core/windows/*.c"
         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
         # Set up files for the video library
         if test x$enable_video = xyes; then
         if test x$enable_video = xyes; then
             AC_DEFINE(SDL_VIDEO_DRIVER_WINDOWS, 1, [ ])
             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"
             SOURCES="$SOURCES $srcdir/src/filesystem/haiku/*.cc"
             have_filesystem=yes
             have_filesystem=yes
         fi
         fi
+
+        # Set up files for the locale library
+        SOURCES="$SOURCES $srcdir/src/locale/haiku/*.cc"
+        have_locale=yes
+
         # The Haiku platform requires special setup.
         # The Haiku platform requires special setup.
         SOURCES="$srcdir/src/main/haiku/*.cc $SOURCES"
         SOURCES="$srcdir/src/main/haiku/*.cc $SOURCES"
         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lroot -lbe -lmedia -lgame -ldevice -ltextencoding"
         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
         CheckVulkan
         CheckPTHREAD
         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
         # Set up files for the audio library
         if test x$enable_audio = xyes; then
         if test x$enable_audio = xyes; then
             AC_DEFINE(SDL_AUDIO_DRIVER_COREAUDIO, 1, [ ])
             AC_DEFINE(SDL_AUDIO_DRIVER_COREAUDIO, 1, [ ])
@@ -3966,6 +3985,10 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
         CheckPTHREAD
         CheckPTHREAD
         CheckHIDAPI
         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
         # Set up files for the audio library
         if test x$enable_audio = xyes; then
         if test x$enable_audio = xyes; then
             AC_DEFINE(SDL_AUDIO_DRIVER_COREAUDIO, 1, [ ])
             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"
             SOURCES="$SOURCES $srcdir/src/timer/unix/*.c"
             have_timers=yes
             have_timers=yes
         fi
         fi
+        # Set up files for the locale library
+        SOURCES="$SOURCES $srcdir/src/locale/emscripten/*.c"
+        have_locale=yes
         ;;
         ;;
     *-*-riscos*)
     *-*-riscos*)
         ARCH=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
 # 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$have_joystick != xyes; then
     if test x$enable_joystick = xyes; then
     if test x$enable_joystick = xyes; then
         AC_DEFINE(SDL_JOYSTICK_DUMMY, 1, [ ])
         AC_DEFINE(SDL_JOYSTICK_DUMMY, 1, [ ])

+ 1 - 0
include/SDL.h

@@ -59,6 +59,7 @@
 #include "SDL_timer.h"
 #include "SDL_timer.h"
 #include "SDL_version.h"
 #include "SDL_version.h"
 #include "SDL_video.h"
 #include "SDL_video.h"
+#include "SDL_locale.h"
 
 
 #include "begin_code.h"
 #include "begin_code.h"
 /* Set up for C function definitions, even when using C++ */
 /* Set up for C function definitions, even when using C++ */

+ 2 - 0
include/SDL_events.h

@@ -85,6 +85,8 @@ typedef enum
                                      Called on Android in onResume()
                                      Called on Android in onResume()
                                 */
                                 */
 
 
+    SDL_LOCALECHANGED,  /**< The user's locale preferences have changed. */
+
     /* Display events */
     /* Display events */
     SDL_DISPLAYEVENT   = 0x150,  /**< Display state change */
     SDL_DISPLAYEVENT   = 0x150,  /**< Display state change */
 
 

+ 15 - 0
include/SDL_hints.h

@@ -1348,6 +1348,21 @@ extern "C" {
 #define SDL_HINT_AUDIO_DEVICE_STREAM_NAME "SDL_AUDIO_DEVICE_STREAM_NAME"
 #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
  *  \brief  An enumeration of hint priorities
  */
  */

+ 101 - 0
include/SDL_locale.h

@@ -0,0 +1,101 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  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: */

+ 78 - 0
src/core/android/SDL_android.c

@@ -44,6 +44,8 @@
 #include "../../haptic/android/SDL_syshaptic_c.h"
 #include "../../haptic/android/SDL_syshaptic_c.h"
 
 
 #include <android/log.h>
 #include <android/log.h>
+#include <android/configuration.h>
+#include <android/asset_manager_jni.h>
 #include <sys/system_properties.h>
 #include <sys/system_properties.h>
 #include <pthread.h>
 #include <pthread.h>
 #include <sys/types.h>
 #include <sys/types.h>
@@ -2796,6 +2798,82 @@ SDL_bool Android_JNI_RequestPermission(const char *permission)
 	return bPermissionRequestResult;
 	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__ */
 #endif /* __ANDROID__ */
 
 
 /* vi: set ts=4 sw=4 expandtab: */
 /* vi: set ts=4 sw=4 expandtab: */

+ 3 - 0
src/core/android/SDL_android.h

@@ -104,6 +104,9 @@ void Android_JNI_InitTouch(void);
 JNIEnv *Android_JNI_GetEnv(void);
 JNIEnv *Android_JNI_GetEnv(void);
 int Android_JNI_SetupThread(void);
 int Android_JNI_SetupThread(void);
 
 
+/* Locale */
+int Android_JNI_GetLocale(char *buf, size_t buflen);
+
 /* Generic messages */
 /* Generic messages */
 int Android_JNI_SendMessage(int command, int param);
 int Android_JNI_SendMessage(int command, int param);
 
 

+ 1 - 0
src/dynapi/SDL_dynapi_overrides.h

@@ -763,3 +763,4 @@
 #define SDL_Metal_GetDrawableSize SDL_Metal_GetDrawableSize_REAL
 #define SDL_Metal_GetDrawableSize SDL_Metal_GetDrawableSize_REAL
 #define SDL_trunc SDL_trunc_REAL
 #define SDL_trunc SDL_trunc_REAL
 #define SDL_truncf SDL_truncf_REAL
 #define SDL_truncf SDL_truncf_REAL
+#define SDL_GetPreferredLocales SDL_GetPreferredLocales_REAL

+ 1 - 0
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(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(double,SDL_trunc,(double a),(a),return)
 SDL_DYNAPI_PROC(float,SDL_truncf,(float a),(a),return)
 SDL_DYNAPI_PROC(float,SDL_truncf,(float a),(a),return)
+SDL_DYNAPI_PROC(SDL_Locale *,SDL_GetPreferredLocales,(void),(),return)

+ 6 - 0
src/events/SDL_events.c

@@ -1009,6 +1009,12 @@ SDL_SendKeymapChangedEvent(void)
     return SDL_SendAppEvent(SDL_KEYMAPCHANGED);
     return SDL_SendAppEvent(SDL_KEYMAPCHANGED);
 }
 }
 
 
+int
+SDL_SendLocaleChangedEvent(void)
+{
+    return SDL_SendAppEvent(SDL_LOCALECHANGED);
+}
+
 int
 int
 SDL_EventsInit(void)
 SDL_EventsInit(void)
 {
 {

+ 1 - 0
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_SendAppEvent(SDL_EventType eventType);
 extern int SDL_SendSysWMEvent(SDL_SysWMmsg * message);
 extern int SDL_SendSysWMEvent(SDL_SysWMmsg * message);
 extern int SDL_SendKeymapChangedEvent(void);
 extern int SDL_SendKeymapChangedEvent(void);
+extern int SDL_SendLocaleChangedEvent(void);
 
 
 extern int SDL_SendQuit(void);
 extern int SDL_SendQuit(void);
 
 

+ 103 - 0
src/locale/SDL_locale.c

@@ -0,0 +1,103 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  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: */
+

+ 29 - 0
src/locale/SDL_syslocale.h

@@ -0,0 +1,29 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  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: */

+ 32 - 0
src/locale/android/SDL_syslocale.c

@@ -0,0 +1,32 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  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: */
+

+ 33 - 0
src/locale/dummy/SDL_syslocale.c

@@ -0,0 +1,33 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  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: */
+

+ 72 - 0
src/locale/emscripten/SDL_syslocale.c

@@ -0,0 +1,72 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  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 <emscripten.h>
+
+#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: */
+

+ 75 - 0
src/locale/haiku/SDL_syslocale.cc

@@ -0,0 +1,75 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  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 <LocaleRoster.h>
+
+#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: */
+

+ 76 - 0
src/locale/macosx/SDL_syslocale.m

@@ -0,0 +1,76 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  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 <Foundation/Foundation.h>
+
+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: */
+

+ 110 - 0
src/locale/unix/SDL_syslocale.c

@@ -0,0 +1,110 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  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: */
+

+ 119 - 0
src/locale/windows/SDL_syslocale.c

@@ -0,0 +1,119 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  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: */
+

+ 58 - 0
src/locale/winrt/SDL_syslocale.c

@@ -0,0 +1,58 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  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 <Windows.h>
+
+#include "../../SDL_internal.h"
+#include "../SDL_syslocale.h"
+
+/*using namespace Windows::Graphics::Display;*/
+#include <wchar.h>
+
+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: */
+

+ 5 - 0
src/main/haiku/SDL_BApp.h

@@ -22,6 +22,7 @@
 #define SDL_BAPP_H
 #define SDL_BAPP_H
 
 
 #include <InterfaceKit.h>
 #include <InterfaceKit.h>
+#include <LocaleRoster.h>
 #if SDL_VIDEO_OPENGL
 #if SDL_VIDEO_OPENGL
 #include <OpenGLKit.h>
 #include <OpenGLKit.h>
 #endif
 #endif
@@ -153,6 +154,10 @@ public:
             _HandleWindowResized(message);
             _HandleWindowResized(message);
             break;
             break;
 
 
+        case B_LOCALE_CHANGED:
+            SDL_SendLocaleChangedEvent();
+            break;
+
         case BAPP_SCREEN_CHANGED:
         case BAPP_SCREEN_CHANGED:
             /* TODO: Handle screen resize or workspace change */
             /* TODO: Handle screen resize or workspace change */
             break;
             break;

+ 12 - 0
src/video/cocoa/SDL_cocoaevents.m

@@ -117,6 +117,7 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
 }
 }
 
 
 - (id)init;
 - (id)init;
+- (void)localeDidChange:(NSNotification *)notification;
 @end
 @end
 
 
 @implementation SDLAppDelegate : NSObject
 @implementation SDLAppDelegate : NSObject
@@ -137,6 +138,11 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
                    selector:@selector(focusSomeWindow:)
                    selector:@selector(focusSomeWindow:)
                        name:NSApplicationDidBecomeActiveNotification
                        name:NSApplicationDidBecomeActiveNotification
                      object:nil];
                      object:nil];
+
+        [center addObserver:self
+                   selector:@selector(localeDidChange:)
+                       name:NSCurrentLocaleDidChangeNotification
+                     object:nil];
     }
     }
 
 
     return self;
     return self;
@@ -148,6 +154,7 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
 
 
     [center removeObserver:self name:NSWindowWillCloseNotification object:nil];
     [center removeObserver:self name:NSWindowWillCloseNotification object:nil];
     [center removeObserver:self name:NSApplicationDidBecomeActiveNotification object:nil];
     [center removeObserver:self name:NSApplicationDidBecomeActiveNotification object:nil];
+    [center removeObserver:self name:NSCurrentLocaleDidChangeNotification object:nil];
 
 
     [super dealloc];
     [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
 - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
 {
 {
     return (BOOL)SDL_SendDropFile(NULL, [filename UTF8String]) && SDL_SendDropComplete(NULL);
     return (BOOL)SDL_SendDropFile(NULL, [filename UTF8String]) && SDL_SendDropComplete(NULL);

+ 5 - 0
test/Makefile.in

@@ -37,6 +37,7 @@ TARGETS = \
 	testjoystick$(EXE) \
 	testjoystick$(EXE) \
 	testkeys$(EXE) \
 	testkeys$(EXE) \
 	testloadso$(EXE) \
 	testloadso$(EXE) \
+	testlocale$(EXE) \
 	testlock$(EXE) \
 	testlock$(EXE) \
 	testmessage$(EXE) \
 	testmessage$(EXE) \
 	testmultiaudio$(EXE) \
 	testmultiaudio$(EXE) \
@@ -303,6 +304,10 @@ controllermap$(EXE): $(srcdir)/controllermap.c
 testvulkan$(EXE): $(srcdir)/testvulkan.c
 testvulkan$(EXE): $(srcdir)/testvulkan.c
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
 
 
+testlocale$(EXE): $(srcdir)/testlocale.c
+	$(CC) -o $@ $? $(CFLAGS) $(LIBS)
+
+
 
 
 clean:
 clean:
 	rm -f $(TARGETS)
 	rm -f $(TARGETS)

+ 1 - 0
test/README

@@ -12,6 +12,7 @@ These are test programs for the SDL library:
 	testjoystick	List joysticks and watch joystick events
 	testjoystick	List joysticks and watch joystick events
 	testkeys	List the available keyboard keys
 	testkeys	List the available keyboard keys
 	testloadso	Tests the loadable library layer
 	testloadso	Tests the loadable library layer
+	testlocale  Test Locale API
 	testlock	Hacked up test of multi-threading and locking
 	testlock	Hacked up test of multi-threading and locking
 	testmultiaudio	Tests using several audio devices
 	testmultiaudio	Tests using several audio devices
 	testoverlay2	Tests the overlay flickering/scaling during playback.
 	testoverlay2	Tests the overlay flickering/scaling during playback.

+ 13 - 1
test/configure

@@ -640,6 +640,7 @@ infodir
 docdir
 docdir
 oldincludedir
 oldincludedir
 includedir
 includedir
+runstatedir
 localstatedir
 localstatedir
 sharedstatedir
 sharedstatedir
 sysconfdir
 sysconfdir
@@ -720,6 +721,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE}'
 docdir='${datarootdir}/doc/${PACKAGE}'
@@ -972,6 +974,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
     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)
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1109,7 +1120,7 @@ fi
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir
+		libdir localedir mandir runstatedir
 do
 do
   eval ac_val=\$$ac_var
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
   # Remove trailing slashes.
@@ -1262,6 +1273,7 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]

+ 67 - 0
test/testlocale.c

@@ -0,0 +1,67 @@
+/*
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  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 <stdio.h>
+#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: */