Browse Source

Updated SDL to latest.

Mark Sibly 9 years ago
parent
commit
26d75713b7
100 changed files with 1930 additions and 1238 deletions
  1. 8 2
      modules/sdl2/SDL/include/SDL_config.h
  2. 8 1
      modules/sdl2/SDL/include/SDL_hints.h
  3. 1 1
      modules/sdl2/SDL/include/SDL_main.h
  4. 3 1
      modules/sdl2/SDL/include/SDL_mouse.h
  5. 3 3
      modules/sdl2/SDL/include/SDL_platform.h
  6. 21 1
      modules/sdl2/SDL/include/SDL_syswm.h
  7. 3 3
      modules/sdl2/SDL/include/SDL_video.h
  8. 8 11
      modules/sdl2/SDL/src/audio/SDL_audio.c
  9. 104 16
      modules/sdl2/SDL/src/audio/alsa/SDL_alsa_audio.c
  10. 1 22
      modules/sdl2/SDL/src/audio/coreaudio/SDL_coreaudio.c
  11. 1 14
      modules/sdl2/SDL/src/audio/psp/SDL_pspaudio.c
  12. 2 1
      modules/sdl2/SDL/src/audio/pulseaudio/SDL_pulseaudio.c
  13. 118 61
      modules/sdl2/SDL/src/core/android/SDL_android.c
  14. 22 0
      modules/sdl2/SDL/src/core/winrt/SDL_winrtapp_direct3d.cpp
  15. 4 0
      modules/sdl2/SDL/src/core/winrt/SDL_winrtapp_direct3d.h
  16. 2 0
      modules/sdl2/SDL/src/dynapi/SDL_dynapi.h
  17. 52 40
      modules/sdl2/SDL/src/events/SDL_events.c
  18. 1 1
      modules/sdl2/SDL/src/events/SDL_gesture.c
  19. 21 2
      modules/sdl2/SDL/src/filesystem/unix/SDL_sysfilesystem.c
  20. 2 10
      modules/sdl2/SDL/src/haptic/windows/SDL_xinputhaptic.c
  21. 0 1
      modules/sdl2/SDL/src/joystick/SDL_gamecontroller.c
  22. 7 0
      modules/sdl2/SDL/src/joystick/SDL_gamecontrollerdb.h
  23. 1 2
      modules/sdl2/SDL/src/joystick/android/SDL_sysjoystick.c
  24. 19 19
      modules/sdl2/SDL/src/joystick/android/SDL_sysjoystick_c.h
  25. 5 13
      modules/sdl2/SDL/src/joystick/darwin/SDL_sysjoystick.c
  26. 19 19
      modules/sdl2/SDL/src/joystick/emscripten/SDL_sysjoystick_c.h
  27. 2 2
      modules/sdl2/SDL/src/joystick/psp/SDL_sysjoystick.c
  28. 3 12
      modules/sdl2/SDL/src/joystick/windows/SDL_windowsjoystick.c
  29. 1 1
      modules/sdl2/SDL/src/joystick/windows/SDL_xinputjoystick.c
  30. 5 3
      modules/sdl2/SDL/src/main/android/SDL_android_main.c
  31. 4 2
      modules/sdl2/SDL/src/main/haiku/SDL_BeApp.cc
  32. 2 2
      modules/sdl2/SDL/src/render/SDL_render.c
  33. 9 1
      modules/sdl2/SDL/src/render/psp/SDL_render_psp.c
  34. 273 220
      modules/sdl2/SDL/src/stdlib/SDL_qsort.c
  35. 5 0
      modules/sdl2/SDL/src/thread/SDL_systhread.h
  36. 53 6
      modules/sdl2/SDL/src/thread/SDL_thread.c
  37. 1 0
      modules/sdl2/SDL/src/thread/SDL_thread_c.h
  38. 2 2
      modules/sdl2/SDL/src/thread/psp/SDL_systhread.c
  39. 3 8
      modules/sdl2/SDL/src/thread/pthread/SDL_systhread.c
  40. 1 0
      modules/sdl2/SDL/src/thread/stdcpp/SDL_systhread.cpp
  41. 13 44
      modules/sdl2/SDL/src/thread/windows/SDL_systhread.c
  42. 15 14
      modules/sdl2/SDL/src/timer/SDL_timer.c
  43. 4 0
      modules/sdl2/SDL/src/timer/windows/SDL_systimer.c
  44. 2 1
      modules/sdl2/SDL/src/video/SDL_egl.c
  45. 22 6
      modules/sdl2/SDL/src/video/SDL_video.c
  46. 14 2
      modules/sdl2/SDL/src/video/android/SDL_androidmouse.c
  47. 1 0
      modules/sdl2/SDL/src/video/android/SDL_androidmouse.h
  48. 3 0
      modules/sdl2/SDL/src/video/android/SDL_androidvideo.c
  49. 3 13
      modules/sdl2/SDL/src/video/cocoa/SDL_cocoaclipboard.m
  50. 12 26
      modules/sdl2/SDL/src/video/cocoa/SDL_cocoaevents.m
  51. 6 17
      modules/sdl2/SDL/src/video/cocoa/SDL_cocoakeyboard.m
  52. 1 1
      modules/sdl2/SDL/src/video/cocoa/SDL_cocoamodes.h
  53. 33 123
      modules/sdl2/SDL/src/video/cocoa/SDL_cocoamodes.m
  54. 10 8
      modules/sdl2/SDL/src/video/cocoa/SDL_cocoamouse.m
  55. 7 8
      modules/sdl2/SDL/src/video/cocoa/SDL_cocoamousetap.m
  56. 1 3
      modules/sdl2/SDL/src/video/cocoa/SDL_cocoashape.m
  57. 35 81
      modules/sdl2/SDL/src/video/cocoa/SDL_cocoawindow.m
  58. 4 0
      modules/sdl2/SDL/src/video/emscripten/SDL_emscriptenmouse.c
  59. 4 11
      modules/sdl2/SDL/src/video/mir/SDL_mirdyn.c
  60. 3 3
      modules/sdl2/SDL/src/video/mir/SDL_mirdyn.h
  61. 127 87
      modules/sdl2/SDL/src/video/mir/SDL_mirevents.c
  62. 1 1
      modules/sdl2/SDL/src/video/mir/SDL_mirevents.h
  63. 11 17
      modules/sdl2/SDL/src/video/mir/SDL_mirframebuffer.c
  64. 140 7
      modules/sdl2/SDL/src/video/mir/SDL_mirmouse.c
  65. 77 10
      modules/sdl2/SDL/src/video/mir/SDL_mirsym.h
  66. 19 17
      modules/sdl2/SDL/src/video/mir/SDL_mirvideo.c
  67. 5 2
      modules/sdl2/SDL/src/video/mir/SDL_mirvideo.h
  68. 160 29
      modules/sdl2/SDL/src/video/mir/SDL_mirwindow.c
  69. 19 4
      modules/sdl2/SDL/src/video/mir/SDL_mirwindow.h
  70. 2 2
      modules/sdl2/SDL/src/video/psp/SDL_pspevents.c
  71. 1 1
      modules/sdl2/SDL/src/video/psp/SDL_pspvideo.c
  72. 9 0
      modules/sdl2/SDL/src/video/raspberry/SDL_rpimouse.c
  73. 0 1
      modules/sdl2/SDL/src/video/uikit/SDL_uikitappdelegate.m
  74. 4 0
      modules/sdl2/SDL/src/video/uikit/SDL_uikitevents.m
  75. 2 0
      modules/sdl2/SDL/src/video/uikit/SDL_uikitopengles.h
  76. 28 1
      modules/sdl2/SDL/src/video/uikit/SDL_uikitopengles.m
  77. 6 0
      modules/sdl2/SDL/src/video/uikit/SDL_uikitvideo.h
  78. 67 48
      modules/sdl2/SDL/src/video/uikit/SDL_uikitvideo.m
  79. 19 19
      modules/sdl2/SDL/src/video/uikit/SDL_uikitviewcontroller.h
  80. 4 0
      modules/sdl2/SDL/src/video/uikit/SDL_uikitviewcontroller.m
  81. 2 4
      modules/sdl2/SDL/src/video/vivante/SDL_vivantevideo.c
  82. 0 17
      modules/sdl2/SDL/src/video/wayland/SDL_waylanddyn.c
  83. 2 4
      modules/sdl2/SDL/src/video/wayland/SDL_waylanddyn.h
  84. 2 3
      modules/sdl2/SDL/src/video/wayland/SDL_waylandevents.c
  85. 18 9
      modules/sdl2/SDL/src/video/wayland/SDL_waylandmouse.c
  86. 18 1
      modules/sdl2/SDL/src/video/wayland/SDL_waylandsym.h
  87. 0 1
      modules/sdl2/SDL/src/video/wayland/SDL_waylandvideo.c
  88. 0 1
      modules/sdl2/SDL/src/video/wayland/SDL_waylandvideo.h
  89. 48 35
      modules/sdl2/SDL/src/video/windows/SDL_windowsmodes.c
  90. 1 1
      modules/sdl2/SDL/src/video/windows/SDL_windowsopengles.c
  91. 2 1
      modules/sdl2/SDL/src/video/winrt/SDL_winrtevents.cpp
  92. 7 0
      modules/sdl2/SDL/src/video/winrt/SDL_winrtevents_c.h
  93. 44 0
      modules/sdl2/SDL/src/video/winrt/SDL_winrtkeyboard.cpp
  94. 61 2
      modules/sdl2/SDL/src/video/winrt/SDL_winrtmouse.cpp
  95. 9 3
      modules/sdl2/SDL/src/video/winrt/SDL_winrtvideo.cpp
  96. 0 15
      modules/sdl2/SDL/src/video/x11/SDL_x11dyn.c
  97. 0 6
      modules/sdl2/SDL/src/video/x11/SDL_x11dyn.h
  98. 20 24
      modules/sdl2/SDL/src/video/x11/SDL_x11events.c
  99. 1 0
      modules/sdl2/SDL/src/video/x11/SDL_x11keyboard.c
  100. 1 1
      modules/sdl2/SDL/src/video/x11/SDL_x11modes.c

+ 8 - 2
modules/sdl2/SDL/include/SDL_config.h

@@ -33,16 +33,22 @@
 #include "SDL_config_premake.h"
 #elif defined(__WIN32__)
 #include "SDL_config_windows.h"
-#elif defined(__WINRT__)
-#include "SDL_config_winrt.h"
 #elif defined(__MACOSX__)
 #include "SDL_config_macosx.h"
+#elif defined(__LINUX__)
+#include "SDL_config_linux.h"
+#elif defined(EMSCRIPTEN)
+#include "SDL_config_emscripten.h"
+/*
+#elif defined(__WINRT__)
+#include "SDL_config_winrt.h"
 #elif defined(__IPHONEOS__)
 #include "SDL_config_iphoneos.h"
 #elif defined(__ANDROID__)
 #include "SDL_config_android.h"
 #elif defined(__PSP__)
 #include "SDL_config_psp.h"
+*/
 #else
 /* This is a minimal configuration just to get SDL running on new platforms */
 #include "SDL_config_minimal.h"

+ 8 - 1
modules/sdl2/SDL/include/SDL_hints.h

@@ -369,7 +369,7 @@ extern "C" {
 *  Use this hint in case you need to set SDL's threads stack size to other than the default.
 *  This is specially useful if you build SDL against a non glibc libc library (such as musl) which
 *  provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses).
-*  Support for this hint is currently available only in the pthread backend.
+*  Support for this hint is currently available only in the pthread, Windows, and PSP backend.
 */
 #define SDL_HINT_THREAD_STACK_SIZE              "SDL_THREAD_STACK_SIZE"
 
@@ -547,6 +547,13 @@ extern "C" {
 */
 #define SDL_HINT_MAC_BACKGROUND_APP    "SDL_MAC_BACKGROUND_APP"
 
+/**
+ *  \brief Allow mouse click events when clicking to focus an SDL window
+ *
+ *  This hint only applies to Mac OS X.
+ */
+#define SDL_HINT_MAC_MOUSE_FOCUS_CLICKTHROUGH "SDL_MAC_MOUSE_FOCUS_CLICKTHROUGH"
+
 /**
  * \brief Android APK expansion main file version. Should be a string number like "1", "2" etc.
  *

+ 1 - 1
modules/sdl2/SDL/include/SDL_main.h

@@ -63,7 +63,7 @@
 /* On Android SDL provides a Java class in SDLActivity.java that is the
    main activity entry point.
 
-   See README-android.txt for more details on extending that class.
+   See README-android.md for more details on extending that class.
  */
 #define SDL_MAIN_NEEDED
 

+ 3 - 1
modules/sdl2/SDL/include/SDL_mouse.h

@@ -254,9 +254,11 @@ extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetCursor(void);
 extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetDefaultCursor(void);
 
 /**
- *  \brief Frees a cursor created with SDL_CreateCursor().
+ *  \brief Frees a cursor created with SDL_CreateCursor() or similar functions.
  *
  *  \sa SDL_CreateCursor()
+ *  \sa SDL_CreateColorCursor()
+ *  \sa SDL_CreateSystemCursor()
  */
 extern DECLSPEC void SDLCALL SDL_FreeCursor(SDL_Cursor * cursor);
 

+ 3 - 3
modules/sdl2/SDL/include/SDL_platform.h

@@ -79,9 +79,9 @@
 /* if not compiling for iPhone */
 #undef __MACOSX__
 #define __MACOSX__  1
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
-# error SDL for Mac OS X only supports deploying on 10.5 and above.
-#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1050 */
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+# error SDL for Mac OS X only supports deploying on 10.6 and above.
+#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1060 */
 #endif /* TARGET_OS_IPHONE */
 #endif /* defined(__APPLE__) */
 

+ 21 - 1
modules/sdl2/SDL/include/SDL_syswm.h

@@ -106,6 +106,10 @@ typedef struct ANativeWindow ANativeWindow;
 typedef void *EGLSurface;
 #endif
 
+#if defined(SDL_VIDEO_DRIVER_VIVANTE)
+#include "SDL_egl.h"
+#endif
+
 /**
  *  These are the various supported windowing subsystems
  */
@@ -120,7 +124,8 @@ typedef enum
     SDL_SYSWM_WAYLAND,
     SDL_SYSWM_MIR,
     SDL_SYSWM_WINRT,
-    SDL_SYSWM_ANDROID
+    SDL_SYSWM_ANDROID,
+    SDL_SYSWM_VIVANTE
 } SDL_SYSWM_TYPE;
 
 /**
@@ -166,6 +171,13 @@ struct SDL_SysWMmsg
             int dummy;
             /* No UIKit window events yet */
         } uikit;
+#endif
+#if defined(SDL_VIDEO_DRIVER_VIVANTE)
+        struct
+        {
+            int dummy;
+            /* No Vivante window events yet */
+        } vivante;
 #endif
         /* Can't have an empty union */
         int dummy;
@@ -259,6 +271,14 @@ struct SDL_SysWMinfo
         } android;
 #endif
 
+#if defined(SDL_VIDEO_DRIVER_VIVANTE)
+        struct
+        {
+            EGLNativeDisplayType display;
+            EGLNativeWindowType window;
+        } vivante;
+#endif
+
         /* Can't have an empty union */
         int dummy;
     } info;

+ 3 - 3
modules/sdl2/SDL/include/SDL_video.h

@@ -449,7 +449,7 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window * window);
  *               ::SDL_WINDOW_MINIMIZED,     ::SDL_WINDOW_INPUT_GRABBED,
  *               ::SDL_WINDOW_ALLOW_HIGHDPI.
  *
- *  \return The id of the window created, or zero if window creation failed.
+ *  \return The created window, or NULL if window creation failed.
  *
  *  If the window is created with the SDL_WINDOW_ALLOW_HIGHDPI flag, its size
  *  in pixels may differ from its size in screen coordinates on platforms with
@@ -468,7 +468,7 @@ extern DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title,
  *
  *  \param data A pointer to driver-dependent window creation data
  *
- *  \return The id of the window created, or zero if window creation failed.
+ *  \return The created window, or NULL if window creation failed.
  *
  *  \sa SDL_DestroyWindow()
  */
@@ -1017,7 +1017,7 @@ extern DECLSPEC void SDLCALL SDL_DestroyWindow(SDL_Window * window);
 
 
 /**
- *  \brief Returns whether the screensaver is currently enabled (default on).
+ *  \brief Returns whether the screensaver is currently enabled (default off).
  *
  *  \sa SDL_EnableScreenSaver()
  *  \sa SDL_DisableScreenSaver()

+ 8 - 11
modules/sdl2/SDL/src/audio/SDL_audio.c

@@ -27,6 +27,7 @@
 #include "SDL_audio_c.h"
 #include "SDL_audiomem.h"
 #include "SDL_sysaudio.h"
+#include "../thread/SDL_systhread.h"
 
 #define _THIS SDL_AudioDevice *_this
 
@@ -1191,19 +1192,15 @@ open_audio_device(const char *devname, int iscapture,
     /* Start the audio thread if necessary */
     if (!current_audio.impl.ProvidesOwnCallbackThread) {
         /* Start the audio thread */
+
+        /* !!! FIXME: we don't force the audio thread stack size here because it calls into user code, but maybe we should? */
+        /* buffer queueing callback only needs a few bytes, so make the stack tiny. */
         char name[64];
+        const size_t stacksize = (device->spec.callback == SDL_BufferQueueDrainCallback) ? 64 * 1024 : 0;
+
         SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) device->id);
-/* !!! FIXME: this is nasty. */
-#if defined(__WIN32__) && !defined(HAVE_LIBC)
-#undef SDL_CreateThread
-#if SDL_DYNAMIC_API
-        device->thread = SDL_CreateThread_REAL(SDL_RunAudio, name, device, NULL, NULL);
-#else
-        device->thread = SDL_CreateThread(SDL_RunAudio, name, device, NULL, NULL);
-#endif
-#else
-        device->thread = SDL_CreateThread(SDL_RunAudio, name, device);
-#endif
+        device->thread = SDL_CreateThreadInternal(SDL_RunAudio, name, stacksize, device);
+
         if (device->thread == NULL) {
             SDL_CloseAudioDevice(device->id);
             SDL_SetError("Couldn't create audio thread");

+ 104 - 16
modules/sdl2/SDL/src/audio/alsa/SDL_alsa_audio.c

@@ -85,6 +85,9 @@ static int (*ALSA_snd_pcm_nonblock) (snd_pcm_t *, int);
 static int (*ALSA_snd_pcm_wait)(snd_pcm_t *, int);
 static int (*ALSA_snd_pcm_sw_params_set_avail_min)
   (snd_pcm_t *, snd_pcm_sw_params_t *, snd_pcm_uframes_t);
+static int (*ALSA_snd_device_name_hint) (int, const char *, void ***);
+static char* (*ALSA_snd_device_name_get_hint) (const void *, const char *);
+static int (*ALSA_snd_device_name_free_hint) (void **);
 
 #ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC
 #define snd_pcm_hw_params_sizeof ALSA_snd_pcm_hw_params_sizeof
@@ -144,6 +147,10 @@ load_alsa_syms(void)
     SDL_ALSA_SYM(snd_pcm_nonblock);
     SDL_ALSA_SYM(snd_pcm_wait);
     SDL_ALSA_SYM(snd_pcm_sw_params_set_avail_min);
+    SDL_ALSA_SYM(snd_device_name_hint);
+    SDL_ALSA_SYM(snd_device_name_get_hint);
+    SDL_ALSA_SYM(snd_device_name_free_hint);
+
     return 0;
 }
 
@@ -196,25 +203,27 @@ LoadALSALibrary(void)
 #endif /* SDL_AUDIO_DRIVER_ALSA_DYNAMIC */
 
 static const char *
-get_audio_device(int channels)
+get_audio_device(void *handle, const int channels)
 {
     const char *device;
 
+    if (handle != NULL) {
+        return (const char *) handle;
+    }
+
+    /* !!! FIXME: we also check "SDL_AUDIO_DEVICE_NAME" at the higher level. */
     device = SDL_getenv("AUDIODEV");    /* Is there a standard variable name? */
-    if (device == NULL) {
-        switch (channels) {
-        case 6:
-            device = "plug:surround51";
-            break;
-        case 4:
-            device = "plug:surround40";
-            break;
-        default:
-            device = "default";
-            break;
-        }
+    if (device != NULL) {
+        return device;
+    }
+
+    if (channels == 6) {
+        return "plug:surround51";
+    } else if (channels == 4) {
+        return "plug:surround40";
     }
-    return device;
+
+    return "default";
 }
 
 
@@ -487,7 +496,7 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
     /* Open the audio device */
     /* Name of device should depend on # channels in spec */
     status = ALSA_snd_pcm_open(&pcm_handle,
-                               get_audio_device(this->spec.channels),
+                               get_audio_device(handle, this->spec.channels),
                                SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
 
     if (status < 0) {
@@ -656,6 +665,84 @@ ALSA_Deinitialize(void)
     UnloadALSALibrary();
 }
 
+static void
+add_device(const int iscapture, const char *name, const char *_desc)
+{
+    char *desc = NULL;
+    char *handle = NULL;
+    char *ptr = NULL;
+
+    if (!name || !_desc) {
+        return;  /* nothing we can do with this...? */
+    }
+
+    desc = SDL_strdup(_desc);
+    if (!desc) {
+        return;  /* oh well, out of memory. Skip it. */
+    }
+
+    /* some strings have newlines, like "HDA NVidia, HDMI 0\nHDMI Audio Output" */
+    for (ptr = strchr(desc, '\n'); ptr; ptr = strchr(ptr + 1, '\n')) {
+        *ptr = ' ';
+    }
+
+    handle = SDL_strdup(name);
+    if (handle != NULL) {
+        SDL_AddAudioDevice(iscapture, desc, handle);
+    }
+
+    SDL_free(desc);
+}
+
+static void
+ALSA_DetectDevices(void)
+{
+    void **hints = NULL;
+    int i;
+
+    /* !!! FIXME: use udev instead. */
+    /* We won't deal with disconnects and hotplugs without udev, but at least
+       you'll get a reasonable device list at startup. */
+#if 1 /*!SDL_USE_LIBUDEV */
+    if (ALSA_snd_device_name_hint(-1, "pcm", &hints) == -1) {
+        return;  /* oh well. */
+    }
+
+    for (i = 0; hints[i]; i++) {
+        char *name = ALSA_snd_device_name_get_hint(hints[i], "NAME");
+        char *desc = ALSA_snd_device_name_get_hint(hints[i], "DESC");
+        char *ioid = ALSA_snd_device_name_get_hint(hints[i], "IOID");
+
+        if ((ioid == NULL) || (SDL_strcmp(ioid, "Output") == 0)) {
+            add_device(SDL_FALSE, name, desc);
+        }
+
+        if ((ioid == NULL) || (SDL_strcmp(ioid, "Input") == 0)) {
+            add_device(SDL_TRUE, name, desc);
+        }
+
+        free(name);
+        free(desc);
+        free(ioid);
+    }
+
+    ALSA_snd_device_name_free_hint(hints);
+#else
+#error Fill in udev support here.
+#endif
+}
+
+static void
+ALSA_FreeDeviceHandle(void *handle)
+{
+#if 1 /*!SDL_USE_LIBUDEV*/
+    SDL_free(handle);
+#else
+#error Fill in udev support here.
+#endif
+}
+
+
 static int
 ALSA_Init(SDL_AudioDriverImpl * impl)
 {
@@ -664,13 +751,14 @@ ALSA_Init(SDL_AudioDriverImpl * impl)
     }
 
     /* Set the function pointers */
+    impl->DetectDevices = ALSA_DetectDevices;
     impl->OpenDevice = ALSA_OpenDevice;
     impl->WaitDevice = ALSA_WaitDevice;
     impl->GetDeviceBuf = ALSA_GetDeviceBuf;
     impl->PlayDevice = ALSA_PlayDevice;
     impl->CloseDevice = ALSA_CloseDevice;
     impl->Deinitialize = ALSA_Deinitialize;
-    impl->OnlyHasDefaultOutputDevice = 1;       /* !!! FIXME: Add device enum! */
+    impl->FreeDeviceHandle = ALSA_FreeDeviceHandle;
 
     return 1;   /* this audio target is available. */
 }

+ 1 - 22
modules/sdl2/SDL/src/audio/coreaudio/SDL_coreaudio.c

@@ -406,13 +406,7 @@ COREAUDIO_CloseDevice(_THIS)
             AudioUnitSetProperty(this->hidden->audioUnit,
                                  kAudioUnitProperty_SetRenderCallback,
                                  scope, bus, &callback, sizeof(callback));
-
-            #if MACOSX_COREAUDIO
-            CloseComponent(this->hidden->audioUnit);
-            #else
             AudioComponentInstanceDispose(this->hidden->audioUnit);
-            #endif
-
             this->hidden->audioUnitOpened = 0;
         }
         SDL_free(this->hidden->buffer);
@@ -482,13 +476,8 @@ prepare_audiounit(_THIS, void *handle, int iscapture,
 {
     OSStatus result = noErr;
     AURenderCallbackStruct callback;
-#if MACOSX_COREAUDIO
-    ComponentDescription desc;
-    Component comp = NULL;
-#else
     AudioComponentDescription desc;
     AudioComponent comp = NULL;
-#endif
     const AudioUnitElement output_bus = 0;
     const AudioUnitElement input_bus = 1;
     const AudioUnitElement bus = ((iscapture) ? input_bus : output_bus);
@@ -507,11 +496,10 @@ prepare_audiounit(_THIS, void *handle, int iscapture,
 
 #if MACOSX_COREAUDIO
     desc.componentSubType = kAudioUnitSubType_DefaultOutput;
-    comp = FindNextComponent(NULL, &desc);
 #else
     desc.componentSubType = kAudioUnitSubType_RemoteIO;
-    comp = AudioComponentFindNext(NULL, &desc);
 #endif
+    comp = AudioComponentFindNext(NULL, &desc);
 
     if (comp == NULL) {
         SDL_SetError("Couldn't find requested CoreAudio component");
@@ -519,17 +507,8 @@ prepare_audiounit(_THIS, void *handle, int iscapture,
     }
 
     /* Open & initialize the audio unit */
-#if MACOSX_COREAUDIO
-    result = OpenAComponent(comp, &this->hidden->audioUnit);
-    CHECK_RESULT("OpenAComponent");
-#else
-    /*
-       AudioComponentInstanceNew only available on iPhone OS 2.0 and Mac OS X 10.6
-       We can't use OpenAComponent on iPhone because it is not present
-     */
     result = AudioComponentInstanceNew(comp, &this->hidden->audioUnit);
     CHECK_RESULT("AudioComponentInstanceNew");
-#endif
 
     this->hidden->audioUnitOpened = 1;
 

+ 1 - 14
modules/sdl2/SDL/src/audio/psp/SDL_pspaudio.c

@@ -66,20 +66,7 @@ PSPAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
     this->spec.freq = 44100;
 
     /* Update the fragment size as size in bytes. */
-/*  SDL_CalculateAudioSpec(this->spec); MOD */
-    switch (this->spec.format) {
-    case AUDIO_U8:
-        this->spec.silence = 0x80;
-        break;
-    default:
-        this->spec.silence = 0x00;
-        break;
-    }
-    this->spec.size = SDL_AUDIO_BITSIZE(this->spec.format) / 8;
-    this->spec.size *= this->spec.channels;
-    this->spec.size *= this->spec.samples;
-
-/* ========================================== */
+    SDL_CalculateAudioSpec(&this->spec);
 
     /* Allocate the mixing buffer.  Its size and starting address must
        be a multiple of 64 bytes.  Our sample count is already a multiple of

+ 2 - 1
modules/sdl2/SDL/src/audio/pulseaudio/SDL_pulseaudio.c

@@ -46,6 +46,7 @@
 #include "../SDL_audio_c.h"
 #include "SDL_pulseaudio.h"
 #include "SDL_loadso.h"
+#include "../../thread/SDL_systhread.h"
 
 #if (PA_API_VERSION < 12)
 /** Return non-zero if the passed state is one of the connected states */
@@ -646,7 +647,7 @@ PULSEAUDIO_DetectDevices()
     WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_source_info_list(hotplug_context, SourceInfoCallback, NULL));
 
     /* ok, we have a sane list, let's set up hotplug notifications now... */
-    hotplug_thread = SDL_CreateThread(HotplugThread, "PulseHotplug", NULL);
+    hotplug_thread = SDL_CreateThreadInternal(HotplugThread, "PulseHotplug", 256 * 1024, NULL);
 }
 
 static void

+ 118 - 61
modules/sdl2/SDL/src/core/android/SDL_android.c

@@ -561,6 +561,7 @@ int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, i
 {
     jboolean audioBufferStereo;
     int audioBufferFrames;
+    jboolean isCopy;
 
     JNIEnv *env = Android_JNI_GetEnv();
 
@@ -602,7 +603,7 @@ int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, i
         return 0;
     }
 
-    jboolean isCopy = JNI_FALSE;
+    isCopy = JNI_FALSE;
     if (audioBuffer16Bit) {
         audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);
         audioBufferFrames = (*env)->GetArrayLength(env, (jshortArray)audioBuffer);
@@ -654,10 +655,12 @@ void Android_JNI_CloseAudioDevice(void)
 /* If the parameter silent is truthy then SDL_SetError() will not be called. */
 static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent)
 {
-    SDL_assert(LocalReferenceHolder_IsActive());
     JNIEnv *mEnv = Android_JNI_GetEnv();
+    jthrowable exception;
+
+    SDL_assert(LocalReferenceHolder_IsActive());
 
-    jthrowable exception = (*mEnv)->ExceptionOccurred(mEnv);
+    exception = (*mEnv)->ExceptionOccurred(mEnv);
     if (exception != NULL) {
         jmethodID mid;
 
@@ -667,13 +670,16 @@ static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent)
         if (!silent) {
             jclass exceptionClass = (*mEnv)->GetObjectClass(mEnv, exception);
             jclass classClass = (*mEnv)->FindClass(mEnv, "java/lang/Class");
+            jstring exceptionName;
+            const char* exceptionNameUTF8;
+            jstring exceptionMessage;
 
             mid = (*mEnv)->GetMethodID(mEnv, classClass, "getName", "()Ljava/lang/String;");
-            jstring exceptionName = (jstring)(*mEnv)->CallObjectMethod(mEnv, exceptionClass, mid);
-            const char* exceptionNameUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionName, 0);
+            exceptionName = (jstring)(*mEnv)->CallObjectMethod(mEnv, exceptionClass, mid);
+            exceptionNameUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionName, 0);
 
             mid = (*mEnv)->GetMethodID(mEnv, exceptionClass, "getMessage", "()Ljava/lang/String;");
-            jstring exceptionMessage = (jstring)(*mEnv)->CallObjectMethod(mEnv, exception, mid);
+            exceptionMessage = (jstring)(*mEnv)->CallObjectMethod(mEnv, exception, mid);
 
             if (exceptionMessage != NULL) {
                 const char* exceptionMessageUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionMessage, 0);
@@ -856,6 +862,7 @@ int Android_JNI_FileOpen(SDL_RWops* ctx,
     struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
     JNIEnv *mEnv = Android_JNI_GetEnv();
     int retval;
+    jstring fileNameJString;
 
     if (!LocalReferenceHolder_Init(&refs, mEnv)) {
         LocalReferenceHolder_Cleanup(&refs);        
@@ -867,7 +874,7 @@ int Android_JNI_FileOpen(SDL_RWops* ctx,
         return -1;
     }
 
-    jstring fileNameJString = (*mEnv)->NewStringUTF(mEnv, fileName);
+    fileNameJString = (*mEnv)->NewStringUTF(mEnv, fileName);
     ctx->hidden.androidio.fileNameRef = (*mEnv)->NewGlobalRef(mEnv, fileNameJString);
     ctx->hidden.androidio.inputStreamRef = NULL;
     ctx->hidden.androidio.readableByteChannelRef = NULL;
@@ -886,10 +893,11 @@ size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer,
 
     if (ctx->hidden.androidio.assetFileDescriptorRef) {
         size_t bytesMax = size * maxnum;
+        size_t result;
         if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && ctx->hidden.androidio.position + bytesMax > ctx->hidden.androidio.size) {
             bytesMax = ctx->hidden.androidio.size - ctx->hidden.androidio.position;
         }
-        size_t result = read(ctx->hidden.androidio.fd, buffer, bytesMax );
+        result = read(ctx->hidden.androidio.fd, buffer, bytesMax );
         if (result > 0) {
             ctx->hidden.androidio.position += result;
             LocalReferenceHolder_Cleanup(&refs);
@@ -901,19 +909,23 @@ size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer,
         jlong bytesRemaining = (jlong) (size * maxnum);
         jlong bytesMax = (jlong) (ctx->hidden.androidio.size -  ctx->hidden.androidio.position);
         int bytesRead = 0;
+        JNIEnv *mEnv;
+        jobject readableByteChannel;
+        jmethodID readMethod;
+        jobject byteBuffer;
 
         /* Don't read more bytes than those that remain in the file, otherwise we get an exception */
         if (bytesRemaining >  bytesMax) bytesRemaining = bytesMax;
 
-        JNIEnv *mEnv = Android_JNI_GetEnv();
+        mEnv = Android_JNI_GetEnv();
         if (!LocalReferenceHolder_Init(&refs, mEnv)) {
             LocalReferenceHolder_Cleanup(&refs);            
             return 0;
         }
 
-        jobject readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef;
-        jmethodID readMethod = (jmethodID)ctx->hidden.androidio.readMethod;
-        jobject byteBuffer = (*mEnv)->NewDirectByteBuffer(mEnv, buffer, bytesRemaining);
+        readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef;
+        readMethod = (jmethodID)ctx->hidden.androidio.readMethod;
+        byteBuffer = (*mEnv)->NewDirectByteBuffer(mEnv, buffer, bytesRemaining);
 
         while (bytesRemaining > 0) {
             /* result = readableByteChannel.read(...); */
@@ -1003,6 +1015,7 @@ Sint64 Android_JNI_FileSize(SDL_RWops* ctx)
 Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence)
 {
     if (ctx->hidden.androidio.assetFileDescriptorRef) {
+        off_t ret;
         switch (whence) {
             case RW_SEEK_SET:
                 if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && offset > ctx->hidden.androidio.size) offset = ctx->hidden.androidio.size;
@@ -1021,11 +1034,12 @@ Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence)
         }
         whence = SEEK_SET;
 
-        off_t ret = lseek(ctx->hidden.androidio.fd, (off_t)offset, SEEK_SET);
+        ret = lseek(ctx->hidden.androidio.fd, (off_t)offset, SEEK_SET);
         if (ret == -1) return -1;
         ctx->hidden.androidio.position = ret - ctx->hidden.androidio.offset;
     } else {
         Sint64 newPosition;
+        Sint64 movement;
 
         switch (whence) {
             case RW_SEEK_SET:
@@ -1049,17 +1063,18 @@ Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence)
             newPosition = ctx->hidden.androidio.size;
         }
 
-        Sint64 movement = newPosition - ctx->hidden.androidio.position;
+        movement = newPosition - ctx->hidden.androidio.position;
         if (movement > 0) {
             unsigned char buffer[4096];
 
             /* The easy case where we're seeking forwards */
             while (movement > 0) {
                 Sint64 amount = sizeof (buffer);
+                size_t result;
                 if (amount > movement) {
                     amount = movement;
                 }
-                size_t result = Android_JNI_FileRead(ctx, buffer, 1, amount);
+                result = Android_JNI_FileRead(ctx, buffer, 1, amount);
                 if (result <= 0) {
                     /* Failed to read/skip the required amount, so fail */
                     return -1;
@@ -1092,21 +1107,23 @@ static jobject Android_JNI_GetSystemServiceObject(const char* name)
     struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
     JNIEnv* env = Android_JNI_GetEnv();
     jobject retval = NULL;
+    jstring service;
+    jmethodID mid;
+    jobject context;
+    jobject manager;
 
     if (!LocalReferenceHolder_Init(&refs, env)) {
         LocalReferenceHolder_Cleanup(&refs);
         return NULL;
     }
 
-    jstring service = (*env)->NewStringUTF(env, name);
-
-    jmethodID mid;
+    service = (*env)->NewStringUTF(env, name);
 
     mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;");
-    jobject context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
+    context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
 
     mid = (*env)->GetMethodID(env, mActivityClass, "getSystemServiceFromUiThread", "(Ljava/lang/String;)Ljava/lang/Object;");
-    jobject manager = (*env)->CallObjectMethod(env, context, mid, service);
+    manager = (*env)->CallObjectMethod(env, context, mid, service);
 
     (*env)->DeleteLocalRef(env, service);
 
@@ -1118,11 +1135,12 @@ static jobject Android_JNI_GetSystemServiceObject(const char* name)
 #define SETUP_CLIPBOARD(error) \
     struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); \
     JNIEnv* env = Android_JNI_GetEnv(); \
+    jobject clipboard; \
     if (!LocalReferenceHolder_Init(&refs, env)) { \
         LocalReferenceHolder_Cleanup(&refs); \
         return error; \
     } \
-    jobject clipboard = Android_JNI_GetSystemServiceObject("clipboard"); \
+    clipboard = Android_JNI_GetSystemServiceObject("clipboard"); \
     if (!clipboard) { \
         LocalReferenceHolder_Cleanup(&refs); \
         return error; \
@@ -1133,14 +1151,17 @@ static jobject Android_JNI_GetSystemServiceObject(const char* name)
 
 int Android_JNI_SetClipboardText(const char* text)
 {
+    /* Watch out for C89 scoping rules because of the macro */
     SETUP_CLIPBOARD(-1)
 
-    jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "setText", "(Ljava/lang/CharSequence;)V");
-    jstring string = (*env)->NewStringUTF(env, text);
-    (*env)->CallVoidMethod(env, clipboard, mid, string);
-    (*env)->DeleteGlobalRef(env, clipboard);
-    (*env)->DeleteLocalRef(env, string);
-
+    /* Nest the following in a scope to avoid C89 declaration rules triggered by the macro */
+    {
+        jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "setText", "(Ljava/lang/CharSequence;)V");
+        jstring string = (*env)->NewStringUTF(env, text);
+        (*env)->CallVoidMethod(env, clipboard, mid, string);
+        (*env)->DeleteGlobalRef(env, clipboard);
+        (*env)->DeleteLocalRef(env, string);
+    }
     CLEANUP_CLIPBOARD();
 
     return 0;
@@ -1148,25 +1169,30 @@ int Android_JNI_SetClipboardText(const char* text)
 
 char* Android_JNI_GetClipboardText(void)
 {
+    /* Watch out for C89 scoping rules because of the macro */
     SETUP_CLIPBOARD(SDL_strdup(""))
 
-    jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "getText", "()Ljava/lang/CharSequence;");
-    jobject sequence = (*env)->CallObjectMethod(env, clipboard, mid);
-    (*env)->DeleteGlobalRef(env, clipboard);
-    if (sequence) {
-        mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, sequence), "toString", "()Ljava/lang/String;");
-        jstring string = (jstring)((*env)->CallObjectMethod(env, sequence, mid));
-        const char* utf = (*env)->GetStringUTFChars(env, string, 0);
-        if (utf) {
-            char* text = SDL_strdup(utf);
-            (*env)->ReleaseStringUTFChars(env, string, utf);
-
-            CLEANUP_CLIPBOARD();
-
-            return text;
+    /* Nest the following in a scope to avoid C89 declaration rules triggered by the macro */
+    {
+        jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "getText", "()Ljava/lang/CharSequence;");
+        jobject sequence = (*env)->CallObjectMethod(env, clipboard, mid);
+        (*env)->DeleteGlobalRef(env, clipboard);
+        if (sequence) {
+            jstring string;
+            const char* utf;
+            mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, sequence), "toString", "()Ljava/lang/String;");
+            string = (jstring)((*env)->CallObjectMethod(env, sequence, mid));
+            utf = (*env)->GetStringUTFChars(env, string, 0);
+            if (utf) {
+                char* text = SDL_strdup(utf);
+                (*env)->ReleaseStringUTFChars(env, string, utf);
+
+                CLEANUP_CLIPBOARD();
+
+                return text;
+            }
         }
     }
-
     CLEANUP_CLIPBOARD();    
 
     return SDL_strdup("");
@@ -1174,10 +1200,13 @@ char* Android_JNI_GetClipboardText(void)
 
 SDL_bool Android_JNI_HasClipboardText(void)
 {
+    jmethodID mid;
+    jboolean has;
+    /* Watch out for C89 scoping rules because of the macro */
     SETUP_CLIPBOARD(SDL_FALSE)
 
-    jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "hasText", "()Z");
-    jboolean has = (*env)->CallBooleanMethod(env, clipboard, mid);
+    mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "hasText", "()Z");
+    has = (*env)->CallBooleanMethod(env, clipboard, mid);
     (*env)->DeleteGlobalRef(env, clipboard);
 
     CLEANUP_CLIPBOARD();
@@ -1194,49 +1223,61 @@ int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seco
 {
     struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
     JNIEnv* env = Android_JNI_GetEnv();
+    jmethodID mid;
+    jobject context;
+    jstring action;
+    jclass cls;
+    jobject filter;
+    jobject intent;
+    jstring iname;
+    jmethodID imid;
+    jstring bname;
+    jmethodID bmid;
     if (!LocalReferenceHolder_Init(&refs, env)) {
         LocalReferenceHolder_Cleanup(&refs);
         return -1;
     }
 
-    jmethodID mid;
 
     mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;");
-    jobject context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
+    context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
 
-    jstring action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED");
+    action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED");
 
-    jclass cls = (*env)->FindClass(env, "android/content/IntentFilter");
+    cls = (*env)->FindClass(env, "android/content/IntentFilter");
 
     mid = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V");
-    jobject filter = (*env)->NewObject(env, cls, mid, action);
+    filter = (*env)->NewObject(env, cls, mid, action);
 
     (*env)->DeleteLocalRef(env, action);
 
     mid = (*env)->GetMethodID(env, mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;");
-    jobject intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter);
+    intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter);
 
     (*env)->DeleteLocalRef(env, filter);
 
     cls = (*env)->GetObjectClass(env, intent);
 
-    jstring iname;
-    jmethodID imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I");
+    imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I");
 
+    /* Watch out for C89 scoping rules because of the macro */
 #define GET_INT_EXTRA(var, key) \
+    int var; \
     iname = (*env)->NewStringUTF(env, key); \
-    int var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \
+    var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \
     (*env)->DeleteLocalRef(env, iname);
 
-    jstring bname;
-    jmethodID bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z");
+    bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z");
 
+    /* Watch out for C89 scoping rules because of the macro */
 #define GET_BOOL_EXTRA(var, key) \
+    int var; \
     bname = (*env)->NewStringUTF(env, key); \
-    int var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \
+    var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \
     (*env)->DeleteLocalRef(env, bname);
 
     if (plugged) {
+        /* Watch out for C89 scoping rules because of the macro */
         GET_INT_EXTRA(plug, "plugged") /* == BatteryManager.EXTRA_PLUGGED (API 5) */
         if (plug == -1) {
             LocalReferenceHolder_Cleanup(&refs);
@@ -1248,6 +1289,7 @@ int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seco
     }
 
     if (charged) {
+        /* Watch out for C89 scoping rules because of the macro */
         GET_INT_EXTRA(status, "status") /* == BatteryManager.EXTRA_STATUS (API 5) */
         if (status == -1) {
             LocalReferenceHolder_Cleanup(&refs);
@@ -1267,8 +1309,20 @@ int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seco
     }
 
     if (percent) {
-        GET_INT_EXTRA(level, "level") /* == BatteryManager.EXTRA_LEVEL (API 5) */
-        GET_INT_EXTRA(scale, "scale") /* == BatteryManager.EXTRA_SCALE (API 5) */
+        int level;
+        int scale;
+        
+        /* Watch out for C89 scoping rules because of the macro */
+        {
+            GET_INT_EXTRA(level_temp, "level") /* == BatteryManager.EXTRA_LEVEL (API 5) */
+            level = level_temp;
+        }
+        /* Watch out for C89 scoping rules because of the macro */
+        {
+            GET_INT_EXTRA(scale_temp, "scale") /* == BatteryManager.EXTRA_SCALE (API 5) */
+            scale = scale_temp;
+        }
+        
         if ((level == -1) || (scale == -1)) {
             LocalReferenceHolder_Cleanup(&refs);
             return -1;
@@ -1321,14 +1375,16 @@ void Android_JNI_PollInputDevices(void)
 int Android_JNI_SendMessage(int command, int param)
 {
     JNIEnv *env = Android_JNI_GetEnv();
+    jmethodID mid;
+    jboolean success;
     if (!env) {
         return -1;
     }
-    jmethodID mid = (*env)->GetStaticMethodID(env, mActivityClass, "sendMessage", "(II)Z");
+    mid = (*env)->GetStaticMethodID(env, mActivityClass, "sendMessage", "(II)Z");
     if (!mid) {
         return -1;
     }
-    jboolean success = (*env)->CallStaticBooleanMethod(env, mActivityClass, mid, command, param);
+    success = (*env)->CallStaticBooleanMethod(env, mActivityClass, mid, command, param);
     return success ? 0 : -1;
 }
 
@@ -1340,11 +1396,12 @@ void Android_JNI_SuspendScreenSaver(SDL_bool suspend)
 void Android_JNI_ShowTextInput(SDL_Rect *inputRect)
 {
     JNIEnv *env = Android_JNI_GetEnv();
+    jmethodID mid;
     if (!env) {
         return;
     }
 
-    jmethodID mid = (*env)->GetStaticMethodID(env, mActivityClass, "showTextInput", "(IIII)Z");
+    mid = (*env)->GetStaticMethodID(env, mActivityClass, "showTextInput", "(IIII)Z");
     if (!mid) {
         return;
     }

+ 22 - 0
modules/sdl2/SDL/src/core/winrt/SDL_winrtapp_direct3d.cpp

@@ -254,6 +254,18 @@ void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView)
 
     CoreApplication::Exiting +=
         ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnExiting);
+
+#if NTDDI_VERSION >= NTDDI_WIN10
+    /* HACK ALERT!  Xbox One doesn't seem to detect gamepads unless something
+       gets registered to receive Win10's Windows.Gaming.Input.Gamepad.GamepadAdded
+       events.  We'll register an event handler for these events here, to make
+       sure that gamepad detection works later on, if requested.
+    */
+    Windows::Gaming::Input::Gamepad::GamepadAdded +=
+        ref new Windows::Foundation::EventHandler<Windows::Gaming::Input::Gamepad^>(
+            this, &SDL_WinRTApp::OnGamepadAdded
+        );
+#endif
 }
 
 #if NTDDI_VERSION > NTDDI_WIN8
@@ -832,3 +844,13 @@ void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone:
 }
 #endif
 
+#if NTDDI_VERSION >= NTDDI_WIN10
+void SDL_WinRTApp::OnGamepadAdded(Platform::Object ^sender, Windows::Gaming::Input::Gamepad ^gamepad)
+{
+    /* HACK ALERT: Nothing needs to be done here, as this method currently
+       only exists to allow something to be registered with Win10's
+       GamepadAdded event, an operation that seems to be necessary to get
+       Xinput-based detection to work on Xbox One.
+    */
+}
+#endif

+ 4 - 0
modules/sdl2/SDL/src/core/winrt/SDL_winrtapp_direct3d.h

@@ -80,6 +80,10 @@ protected:
     void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args);
 #endif
 
+#if NTDDI_VERSION >= NTDDI_WIN10
+    void OnGamepadAdded(Platform::Object ^sender, Windows::Gaming::Input::Gamepad ^gamepad);
+#endif
+
 private:
     bool m_windowClosed;
     bool m_windowVisible;

+ 2 - 0
modules/sdl2/SDL/src/dynapi/SDL_dynapi.h

@@ -47,6 +47,8 @@
 #define SDL_DYNAMIC_API 0
 #elif SDL_BUILDING_WINRT /* probaly not useful on WinRT, given current .dll loading restrictions */
 #define SDL_DYNAMIC_API 0
+#elif __PSP__
+#define SDL_DYNAMIC_API 0
 #elif defined(__clang_analyzer__)
 #define SDL_DYNAMIC_API 0  /* Turn off for static analysis, so reports are more clear. */
 #endif

+ 52 - 40
modules/sdl2/SDL/src/events/SDL_events.c

@@ -48,6 +48,8 @@ typedef struct SDL_EventWatcher {
 
 static SDL_EventWatcher *SDL_event_watchers = NULL;
 
+static SDL_sem *wait_sem;
+
 typedef struct {
     Uint32 bits[8];
 } SDL_DisabledEventBlock;
@@ -193,7 +195,7 @@ SDL_AddEvent(SDL_Event * event)
     SDL_EventEntry *entry;
     const int initial_count = SDL_AtomicGet(&SDL_EventQ.count);
     int final_count;
-
+	
     if (initial_count >= SDL_MAX_QUEUED_EVENTS) {
         SDL_SetError("Event queue is full (%d events)", initial_count);
         return 0;
@@ -226,6 +228,8 @@ SDL_AddEvent(SDL_Event * event)
         SDL_EventQ.tail = entry;
         entry->prev = NULL;
         entry->next = NULL;
+        
+        SDL_SemPost( wait_sem );
     }
 
     final_count = SDL_AtomicAdd(&SDL_EventQ.count, 1) + 1;
@@ -269,6 +273,8 @@ SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action,
 {
     int i, used;
 
+    if( !wait_sem ) wait_sem=SDL_CreateSemaphore( 0 );
+
     /* Don't look after we've quit */
     if (!SDL_AtomicGet(&SDL_EventQ.active)) {
         /* We get a few spurious events at shutdown, so don't warn then */
@@ -284,55 +290,54 @@ SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action,
             for (i = 0; i < numevents; ++i) {
                 used += SDL_AddEvent(&events[i]);
             }
+            
+//            SDL_SemPost( wait_sem );
+            
         } else {
             SDL_EventEntry *entry, *next;
             SDL_SysWMEntry *wmmsg, *wmmsg_next;
-            SDL_Event tmpevent;
             Uint32 type;
 
-            /* If 'events' is NULL, just see if they exist */
-            if (events == NULL) {
-                action = SDL_PEEKEVENT;
-                numevents = 1;
-                events = &tmpevent;
-            }
-
-            /* Clean out any used wmmsg data
-               FIXME: Do we want to retain the data for some period of time?
-             */
-            for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg; wmmsg = wmmsg_next) {
-                wmmsg_next = wmmsg->next;
-                wmmsg->next = SDL_EventQ.wmmsg_free;
-                SDL_EventQ.wmmsg_free = wmmsg;
+            if (action == SDL_GETEVENT) {
+                /* Clean out any used wmmsg data
+                   FIXME: Do we want to retain the data for some period of time?
+                 */
+                for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg; wmmsg = wmmsg_next) {
+                    wmmsg_next = wmmsg->next;
+                    wmmsg->next = SDL_EventQ.wmmsg_free;
+                    SDL_EventQ.wmmsg_free = wmmsg;
+                }
+                SDL_EventQ.wmmsg_used = NULL;
             }
-            SDL_EventQ.wmmsg_used = NULL;
 
-            for (entry = SDL_EventQ.head; entry && used < numevents; entry = next) {
+            for (entry = SDL_EventQ.head; entry && (!events || used < numevents); entry = next) {
                 next = entry->next;
                 type = entry->event.type;
                 if (minType <= type && type <= maxType) {
-                    events[used] = entry->event;
-                    if (entry->event.type == SDL_SYSWMEVENT) {
-                        /* We need to copy the wmmsg somewhere safe.
-                           For now we'll guarantee it's valid at least until
-                           the next call to SDL_PeepEvents()
-                         */
-                        if (SDL_EventQ.wmmsg_free) {
-                            wmmsg = SDL_EventQ.wmmsg_free;
-                            SDL_EventQ.wmmsg_free = wmmsg->next;
-                        } else {
-                            wmmsg = (SDL_SysWMEntry *)SDL_malloc(sizeof(*wmmsg));
+                    if (events) {
+                        events[used] = entry->event;
+                        if (entry->event.type == SDL_SYSWMEVENT) {
+                            /* We need to copy the wmmsg somewhere safe.
+                               For now we'll guarantee it's valid at least until
+                               the next call to SDL_PeepEvents()
+                             */
+                            if (SDL_EventQ.wmmsg_free) {
+                                wmmsg = SDL_EventQ.wmmsg_free;
+                                SDL_EventQ.wmmsg_free = wmmsg->next;
+                            } else {
+                                wmmsg = (SDL_SysWMEntry *)SDL_malloc(sizeof(*wmmsg));
+                            }
+                            wmmsg->msg = *entry->event.syswm.msg;
+                            wmmsg->next = SDL_EventQ.wmmsg_used;
+                            SDL_EventQ.wmmsg_used = wmmsg;
+                            events[used].syswm.msg = &wmmsg->msg;
                         }
-                        wmmsg->msg = *entry->event.syswm.msg;
-                        wmmsg->next = SDL_EventQ.wmmsg_used;
-                        SDL_EventQ.wmmsg_used = wmmsg;
-                        events[used].syswm.msg = &wmmsg->msg;
-                    }
-                    ++used;
 
-                    if (action == SDL_GETEVENT) {
-                        SDL_CutEvent(entry);
+                        if (action == SDL_GETEVENT) {
+                            SDL_CutEvent(entry);
+                        }
                     }
+                    ++used;
                 }
             }
         }
@@ -439,8 +444,6 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout)
         switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
         case -1:
             return 0;
-        case 1:
-            return 1;
         case 0:
             if (timeout == 0) {
                 /* Polling and no events, just return */
@@ -450,8 +453,17 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout)
                 /* Timeout expired and no events */
                 return 0;
             }
-            SDL_Delay(10);
+            
+//          SDL_SemWait( wait_sem );
+            
+         	SDL_SemWaitTimeout( wait_sem,10 );	//ugly, but ensures pump events gets called every 10ms.
+           	
+//          SDL_Delay(10);
+
             break;
+        default:
+            /* Has events */
+            return 1;
         }
     }
 }

+ 1 - 1
modules/sdl2/SDL/src/events/SDL_gesture.c

@@ -21,7 +21,7 @@
 
 #include "../SDL_internal.h"
 
-/* General mouse handling code for SDL */
+/* General gesture handling code for SDL */
 
 #include "SDL_events.h"
 #include "SDL_endian.h"

+ 21 - 2
modules/sdl2/SDL/src/filesystem/unix/SDL_sysfilesystem.c

@@ -33,7 +33,7 @@
 #include <sys/types.h>
 #include <limits.h>
 
-#ifdef __FREEBSD__
+#if defined(__FREEBSD__) || defined(__OPENBSD__)
 #include <sys/sysctl.h>
 #endif
 
@@ -90,7 +90,26 @@ SDL_GetBasePath(void)
             return NULL;
         }
     }
-#elif defined(__SOLARIS__)
+#endif
+#if defined(__OPENBSD__)
+    char **retvalargs;
+    size_t len;
+    const int mib[] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV };
+    if (sysctl(mib, 4, NULL, &len, NULL, 0) != -1) {
+        retvalargs = SDL_malloc(len);
+        if (!retvalargs) {
+            SDL_OutOfMemory();
+            return NULL;
+        }
+        sysctl(mib, 4, retvalargs, &len, NULL, 0);
+        retval = SDL_malloc(PATH_MAX + 1);
+        if (retval)
+            realpath(retvalargs[0], retval);
+
+        SDL_free(retvalargs);
+    }
+#endif
+#if defined(__SOLARIS__)
     const char *path = getexecname();
     if ((path != NULL) && (path[0] == '/')) { /* must be absolute path... */
         retval = SDL_strdup(path);

+ 2 - 10
modules/sdl2/SDL/src/haptic/windows/SDL_xinputhaptic.c

@@ -33,6 +33,7 @@
 #include "SDL_xinputhaptic_c.h"
 #include "../../core/windows/SDL_xinput.h"
 #include "../../joystick/windows/SDL_windowsjoystick_c.h"
+#include "../../thread/SDL_systhread.h"
 
 /*
  * Internal stuff.
@@ -205,17 +206,8 @@ SDL_XINPUT_HapticOpenFromUserIndex(SDL_Haptic *haptic, const Uint8 userid)
     }
 
     SDL_snprintf(threadName, sizeof(threadName), "SDLXInputDev%d", (int)userid);
+    haptic->hwdata->thread = SDL_CreateThreadInternal(SDL_RunXInputHaptic, threadName, 64 * 1024, haptic->hwdata);
 
-#if defined(__WIN32__) && !defined(HAVE_LIBC)  /* !!! FIXME: this is nasty. */
-#undef SDL_CreateThread
-#if SDL_DYNAMIC_API
-    haptic->hwdata->thread = SDL_CreateThread_REAL(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL);
-#else
-    haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL);
-#endif
-#else
-    haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata);
-#endif
     if (haptic->hwdata->thread == NULL) {
         SDL_DestroyMutex(haptic->hwdata->mutex);
         SDL_free(haptic->effects);

+ 0 - 1
modules/sdl2/SDL/src/joystick/SDL_gamecontroller.c

@@ -861,7 +861,6 @@ SDL_GameControllerInit(void)
 {
     int i = 0;
     const char *pMappingString = NULL;
-    s_pSupportedControllers = NULL;
     pMappingString = s_ControllerMappings[i];
     while (pMappingString) {
         SDL_GameControllerAddMapping(pMappingString);

+ 7 - 0
modules/sdl2/SDL/src/joystick/SDL_gamecontrollerdb.h

@@ -61,6 +61,7 @@ static const char *s_ControllerMappings [] =
     "5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
 #endif
 #if defined(__LINUX__)
+    "03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
     "03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
     "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
     "030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
@@ -71,6 +72,12 @@ static const char *s_ControllerMappings [] =
     "030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */
     "030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
     "030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
+    "03000000380700008433000011010000,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
+    "03000000380700008483000011010000,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
+    "03000000380700003847000090040000,Mad Catz Wired Xbox 360 Controller (SFIV),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
+    "03000000380700008034000011010000,Mad Catz fightstick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
+    "03000000380700008084000011010000,Mad Catz fightstick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
+    "03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
     "03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
     "050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
     "050000003620000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,",

+ 1 - 2
modules/sdl2/SDL/src/joystick/android/SDL_sysjoystick.c

@@ -340,7 +340,6 @@ Android_RemoveJoystick(int device_id)
         return -1;
     }
 
-    const int retval = item->device_instance;
     if (item->joystick) {
         item->joystick->hwdata = NULL;
     }
@@ -376,7 +375,7 @@ Android_RemoveJoystick(int device_id)
     
     SDL_free(item->name);
     SDL_free(item);
-    return retval;
+    return numjoysticks;
 }
 
 

+ 19 - 19
modules/sdl2/SDL/src/joystick/android/SDL_sysjoystick_c.h

@@ -1,23 +1,23 @@
 /*
- Simple DirectMedia Layer
- Copyright (C) 1997-2016 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.
- */
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2016 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"
 

+ 5 - 13
modules/sdl2/SDL/src/joystick/darwin/SDL_sysjoystick.c

@@ -422,6 +422,7 @@ JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDevic
 {
     recDevice *device;
     int device_index = 0;
+    io_service_t ioservice;
 
     if (res != kIOReturnSuccess) {
         return;
@@ -451,20 +452,11 @@ JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDevic
     device->instance_id = ++s_joystick_instance_id;
 
     /* We have to do some storage of the io_service_t for SDL_HapticOpenFromJoystick */
-
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
-    if (IOHIDDeviceGetService != NULL) {  /* weak reference: available in 10.6 and later. */
-#endif
-
-        const io_service_t ioservice = IOHIDDeviceGetService(ioHIDDeviceObject);
+    ioservice = IOHIDDeviceGetService(ioHIDDeviceObject);
 #if SDL_HAPTIC_IOKIT
-        if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK)) {
-            device->ffservice = ioservice;
-            MacHaptic_MaybeAddDevice(ioservice);
-        }
-#endif
-
-#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+    if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK)) {
+        device->ffservice = ioservice;
+        MacHaptic_MaybeAddDevice(ioservice);
     }
 #endif
 

+ 19 - 19
modules/sdl2/SDL/src/joystick/emscripten/SDL_sysjoystick_c.h

@@ -1,23 +1,23 @@
 /*
- Simple DirectMedia Layer
- Copyright (C) 1997-2016 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.
- */
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2016 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"
 

+ 2 - 2
modules/sdl2/SDL/src/joystick/psp/SDL_sysjoystick.c

@@ -34,9 +34,9 @@
 
 #include "SDL_events.h"
 #include "SDL_error.h"
-#include "SDL_thread.h"
 #include "SDL_mutex.h"
 #include "SDL_timer.h"
+#include "../../thread/SDL_systhread.h"
 
 /* Current pad state */
 static SceCtrlData pad = { .Lx = 0, .Ly = 0, .Buttons = 0 };
@@ -116,7 +116,7 @@ int SDL_SYS_JoystickInit(void)
         return SDL_SetError("Can't create input semaphore");
     }
     running = 1;
-    if((thread = SDL_CreateThread(JoystickUpdate, "JoySitckThread",NULL)) == NULL) {
+    if((thread = SDL_CreateThreadInternal(JoystickUpdate, "JoystickThread", 4096, NULL)) == NULL) {
         return SDL_SetError("Can't create input thread");
     }
 

+ 3 - 12
modules/sdl2/SDL/src/joystick/windows/SDL_windowsjoystick.c

@@ -35,13 +35,13 @@
 #include "SDL_error.h"
 #include "SDL_assert.h"
 #include "SDL_events.h"
-#include "SDL_thread.h"
 #include "SDL_timer.h"
 #include "SDL_mutex.h"
 #include "SDL_events.h"
 #include "SDL_hints.h"
 #include "SDL_joystick.h"
 #include "../SDL_sysjoystick.h"
+#include "../../thread/SDL_systhread.h"
 #if !SDL_EVENTS_DISABLED
 #include "../../events/SDL_events_c.h"
 #endif
@@ -301,18 +301,9 @@ SDL_SYS_JoystickInit(void)
     SDL_SYS_JoystickDetect();
 
     if (!s_threadJoystick) {
-        s_bJoystickThreadQuit = SDL_FALSE;
         /* spin up the thread to detect hotplug of devices */
-#if defined(__WIN32__) && !defined(HAVE_LIBC)
-#undef SDL_CreateThread
-#if SDL_DYNAMIC_API
-        s_threadJoystick= SDL_CreateThread_REAL(SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL);
-#else
-        s_threadJoystick= SDL_CreateThread(SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL);
-#endif
-#else
-        s_threadJoystick = SDL_CreateThread(SDL_JoystickThread, "SDL_joystick", NULL);
-#endif
+        s_bJoystickThreadQuit = SDL_FALSE;
+        s_threadJoystick = SDL_CreateThreadInternal(SDL_JoystickThread, "SDL_joystick", 64 * 1024, NULL);
     }
     return SDL_SYS_NumJoysticks();
 }

+ 1 - 1
modules/sdl2/SDL/src/joystick/windows/SDL_xinputjoystick.c

@@ -376,7 +376,7 @@ SDL_SYS_IsXInputGamepad_DeviceIndex(int device_index)
     for (index = device_index; index > 0; index--)
         device = device->pNext;
 
-    return (device->SubType == XINPUT_DEVSUBTYPE_GAMEPAD);
+    return device->bXInputDevice;
 }
 
 #else /* !SDL_JOYSTICK_XINPUT */

+ 5 - 3
modules/sdl2/SDL/src/main/android/SDL_android_main.c

@@ -22,6 +22,8 @@ JNIEXPORT int JNICALL Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jc
     int i;
     int argc;
     int status;
+    int len;
+    char** argv;
 
     /* This interface could expand with ABI negotiation, callbacks, etc. */
     SDL_Android_Init(env, cls);
@@ -30,8 +32,8 @@ JNIEXPORT int JNICALL Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jc
 
     /* Prepare the arguments. */
 
-    int len = (*env)->GetArrayLength(env, array);
-    char* argv[1 + len + 1];
+    len = (*env)->GetArrayLength(env, array);
+    argv = SDL_stack_alloc(char*, 1 + len + 1);
     argc = 0;
     /* Use the name "app_process" so PHYSFS_platformCalcBaseDir() works.
        https://bitbucket.org/MartinFelis/love-android-sdl2/issue/23/release-build-crash-on-start
@@ -66,7 +68,7 @@ JNIEXPORT int JNICALL Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jc
     for (i = 0; i < argc; ++i) {
         SDL_free(argv[i]);
     }
-
+    SDL_stack_free(argv);
     /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */
     /* exit(status); */
 

+ 4 - 2
modules/sdl2/SDL/src/main/haiku/SDL_BeApp.cc

@@ -31,7 +31,6 @@
 
 #include "SDL_BApp.h"	/* SDL_BApp class definition */
 #include "SDL_BeApp.h"
-#include "SDL_thread.h"
 #include "SDL_timer.h"
 #include "SDL_error.h"
 
@@ -40,6 +39,9 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+
+#include "../../thread/SDL_systhread.h"
+
 /* Flag to tell whether or not the Be application is active or not */
 int SDL_BeAppActive = 0;
 static SDL_Thread *SDL_AppThread = NULL;
@@ -62,7 +64,7 @@ SDL_InitBeApp(void)
 {
     /* Create the BApplication that handles appserver interaction */
     if (SDL_BeAppActive <= 0) {
-        SDL_AppThread = SDL_CreateThread(StartBeApp, "SDLApplication", NULL);
+        SDL_AppThread = SDL_CreateThreadInternal(StartBeApp, "SDLApplication", 0, NULL);
         if (SDL_AppThread == NULL) {
             return SDL_SetError("Couldn't create BApplication thread");
         }

+ 2 - 2
modules/sdl2/SDL/src/render/SDL_render.c

@@ -1156,9 +1156,9 @@ UpdateLogicalSize(SDL_Renderer *renderer)
 
     if (renderer->integer_scale) {
         if (want_aspect > real_aspect) {
-            scale = w / renderer->logical_w;
+            scale = (float)(w / renderer->logical_w);
         } else {
-            scale = h / renderer->logical_h;
+            scale = (float)(h / renderer->logical_h);
         }
         viewport.w = (int)SDL_ceil(renderer->logical_w * scale);
         viewport.x = (w - viewport.w) / 2;

+ 9 - 1
modules/sdl2/SDL/src/render/psp/SDL_render_psp.c

@@ -50,6 +50,8 @@ static SDL_Renderer *PSP_CreateRenderer(SDL_Window * window, Uint32 flags);
 static void PSP_WindowEvent(SDL_Renderer * renderer,
                              const SDL_WindowEvent *event);
 static int PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
+static int PSP_SetTextureColorMod(SDL_Renderer * renderer,
+                                   SDL_Texture * texture);
 static int PSP_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
                               const SDL_Rect * rect, const void *pixels,
                               int pitch);
@@ -359,6 +361,7 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
 
     renderer->WindowEvent = PSP_WindowEvent;
     renderer->CreateTexture = PSP_CreateTexture;
+    renderer->SetTextureColorMod = PSP_SetTextureColorMod;
     renderer->UpdateTexture = PSP_UpdateTexture;
     renderer->LockTexture = PSP_LockTexture;
     renderer->UnlockTexture = PSP_UnlockTexture;
@@ -501,6 +504,11 @@ PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
     return 0;
 }
 
+static int
+PSP_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
+{
+    return SDL_Unsupported();
+}
 
 void
 TextureActivate(SDL_Texture * texture)
@@ -853,7 +861,7 @@ PSP_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
                     Uint32 pixel_format, void * pixels, int pitch)
 
 {
-        return 0;
+    return SDL_Unsupported();
 }
 
 

+ 273 - 220
modules/sdl2/SDL/src/stdlib/SDL_qsort.c

@@ -1,46 +1,23 @@
-/* qsort.c
- * (c) 1998 Gareth McCaughan
- *
- * This is a drop-in replacement for the C library's |qsort()| routine.
- *
- * Features:
- *   - Median-of-three pivoting (and more)
- *   - Truncation and final polishing by a single insertion sort
- *   - Early truncation when no swaps needed in pivoting step
- *   - Explicit recursion, guaranteed not to overflow
- *   - A few little wrinkles stolen from the GNU |qsort()|.
- *   - separate code for non-aligned / aligned / word-size objects
- *
- * This code may be reproduced freely provided
- *   - this file is retained unaltered apart from minor
- *     changes for portability and efficiency
- *   - no changes are made to this comment
- *   - any changes that *are* made are clearly flagged
- *   - the _ID string below is altered by inserting, after
- *     the date, the string " altered" followed at your option
- *     by other material. (Exceptions: you may change the name
- *     of the exported routine without changing the ID string.
- *     You may change the values of the macros TRUNC_* and
- *     PIVOT_THRESHOLD without changing the ID string, provided
- *     they remain constants with TRUNC_nonaligned, TRUNC_aligned
- *     and TRUNC_words/WORD_BYTES between 8 and 24, and
- *     PIVOT_THRESHOLD between 32 and 200.)
- *
- * You may use it in anything you like; you may make money
- * out of it; you may distribute it in object form or as
- * part of an executable without including source code;
- * you don't have to credit me. (But it would be nice if
- * you did.)
- *
- * If you find problems with this code, or find ways of
- * making it significantly faster, please let me know!
- * My e-mail address, valid as of early 1998 and certainly
- * OK for at least the next 18 months, is
- *    [email protected]
- * Thanks!
- *
- * Gareth McCaughan   Peterhouse   Cambridge   1998
- */
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2016 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.
+*/
 
 #if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS)
 #define SDL_DISABLE_ANALYZE_MACROS 1
@@ -48,11 +25,6 @@
 
 #include "../SDL_internal.h"
 
-/*
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-*/
 #include "SDL_stdinc.h"
 #include "SDL_assert.h"
 
@@ -62,34 +34,128 @@ SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, c
 {
     qsort(base, nmemb, size, compare);
 }
+
 #else
 
 #ifdef assert
 #undef assert
 #endif
-#define assert(X) SDL_assert(X)
+#define assert SDL_assert
 #ifdef malloc
 #undef malloc
 #endif
-#define malloc	SDL_malloc
+#define malloc SDL_malloc
 #ifdef free
 #undef free
 #endif
-#define free	SDL_free
+#define free SDL_free
 #ifdef memcpy
 #undef memcpy
 #endif
-#define memcpy	SDL_memcpy
+#define memcpy SDL_memcpy
 #ifdef memmove
 #undef memmove
 #endif
-#define memmove	SDL_memmove
-#ifdef qsort
-#undef qsort
+#define memmove SDL_memmove
+#ifdef qsortG
+#undef qsortG
 #endif
-#define qsort	SDL_qsort
+#define qsortG SDL_qsort
+
+/*
+This code came from Gareth McCaughan, under the zlib license.
+Specifically this: https://www.mccaughan.org.uk/software/qsort.c-1.14
+
+Everything below this comment until the HAVE_QSORT #endif was from Gareth
+(any minor changes will be noted inline).
+
+Thank you to Gareth for relicensing this code under the zlib license for our
+benefit!
+
+--ryan.
+*/
+
+/* This is a drop-in replacement for the C library's |qsort()| routine.
+ *
+ * It is intended for use where you know or suspect that your
+ * platform's qsort is bad. If that isn't the case, then you
+ * should probably use the qsort your system gives you in preference
+ * to mine -- it will likely have been tested and tuned better.
+ *
+ * Features:
+ *   - Median-of-three pivoting (and more)
+ *   - Truncation and final polishing by a single insertion sort
+ *   - Early truncation when no swaps needed in pivoting step
+ *   - Explicit recursion, guaranteed not to overflow
+ *   - A few little wrinkles stolen from the GNU |qsort()|.
+ *     (For the avoidance of doubt, no code was stolen, only
+ *     broad ideas.)
+ *   - separate code for non-aligned / aligned / word-size objects
+ *
+ * Earlier releases of this code used an idiosyncratic licence
+ * I wrote myself, because I'm an idiot. The code is now released
+ * under the "zlib/libpng licence"; you will find the actual
+ * terms in the next comment. I request (but do not require)
+ * that if you make any changes beyond the name of the exported
+ * routine and reasonable tweaks to the TRUNC_* and
+ * PIVOT_THRESHOLD values, you modify the _ID string so as
+ * to make it clear that you have changed the code.
+ *
+ * If you find problems with this code, or find ways of
+ * making it significantly faster, please let me know!
+ * My e-mail address, valid as of early 2016 and for the
+ * foreseeable future, is
+ *    [email protected]
+ * Thanks!
+ *
+ * Gareth McCaughan
+ */
+
+/* Copyright (c) 1998-2016 Gareth McCaughan
+ *
+ * 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.
+ */
 
-static const char _ID[] = "<qsort.c gjm 1.12 1998-03-19>";
+/* Revision history since release:
+ *   1998-03-19 v1.12 First release I have any records of.
+ *   2007-09-02 v1.13 Fix bug kindly reported by Dan Bodoh
+ *                    (premature termination of recursion).
+ *                    Add a few clarifying comments.
+ *                    Minor improvements to debug output.
+ *   2016-02-21 v1.14 Replace licence with 2-clause BSD,
+ *                    and clarify a couple of things in
+ *                    comments. No code changes.
+ */
+
+/* BEGIN SDL CHANGE ... commented this out with an #if 0 block. --ryan. */
+#if 0
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define DEBUG_QSORT
+
+static char _ID[]="<qsort.c gjm 1.14 2016-02-21>";
+#endif
+/* END SDL CHANGE ... commented this out with an #if 0 block. --ryan. */
 
 /* How many bytes are there per word? (Must be a power of 2,
  * and must in fact equal sizeof(int).)
@@ -110,7 +176,7 @@ static const char _ID[] = "<qsort.c gjm 1.12 1998-03-19>";
  */
 #define TRUNC_nonaligned	12
 #define TRUNC_aligned		12
-#define TRUNC_words		12*WORD_BYTES   /* nb different meaning */
+#define TRUNC_words		12*WORD_BYTES	/* nb different meaning */
 
 /* We use a simple pivoting algorithm for shortish sub-arrays
  * and a more complicated one for larger ones. The threshold
@@ -118,11 +184,7 @@ static const char _ID[] = "<qsort.c gjm 1.12 1998-03-19>";
  */
 #define PIVOT_THRESHOLD 40
 
-typedef struct
-{
-    char *first;
-    char *last;
-} stack_entry;
+typedef struct { char * first; char * last; } stack_entry;
 #define pushLeft {stack[stacktop].first=ffirst;stack[stacktop++].last=last;}
 #define pushRight {stack[stacktop].first=first;stack[stacktop++].last=llast;}
 #define doLeft {first=ffirst;llast=last;continue;}
@@ -197,7 +259,9 @@ typedef struct
  *        16-bit |int|s and 4096-bit |size_t|s. :-)
  */
 
-/* The recursion logic is the same in each case: */
+/* The recursion logic is the same in each case.
+ * We keep chopping up until we reach subarrays of size
+ * strictly less than Trunc; we leave these unsorted. */
 #define Recurse(Trunc)				\
       { size_t l=last-ffirst,r=llast-first;	\
         if (l<Trunc) {				\
@@ -209,9 +273,9 @@ typedef struct
         else doLeft				\
       }
 
-/* and so is the pivoting logic: */
+/* and so is the pivoting logic (note: last is inclusive): */
 #define Pivot(swapper,sz)			\
-  if ((size_t)(last-first)>PIVOT_THRESHOLD*sz) mid=pivot_big(first,mid,last,sz,compare);\
+  if (last-first>PIVOT_THRESHOLD*sz) mid=pivot_big(first,mid,last,sz,compare);\
   else {	\
     if (compare(first,mid)<0) {			\
       if (compare(mid,last)>0) {		\
@@ -235,26 +299,28 @@ typedef struct
 
 /* and so is the partitioning logic: */
 #define Partition(swapper,sz) {			\
-  int swapped=0;				\
   do {						\
     while (compare(first,pivot)<0) first+=sz;	\
     while (compare(pivot,last)<0) last-=sz;	\
     if (first<last) {				\
-      swapper(first,last); swapped=1;		\
+      swapper(first,last);			\
       first+=sz; last-=sz; }			\
     else if (first==last) { first+=sz; last-=sz; break; }\
   } while (first<=last);			\
-  if (!swapped) pop				\
 }
 
 /* and so is the pre-insertion-sort operation of putting
  * the smallest element into place as a sentinel.
  * Doing this makes the inner loop nicer. I got this
  * idea from the GNU implementation of qsort().
+ * We find the smallest element from the first |nmemb|,
+ * or the first |limit|, whichever is smaller;
+ * therefore we must have ensured that the globally smallest
+ * element is in the first |limit|.
  */
 #define PreInsertion(swapper,limit,sz)		\
   first=base;					\
-  last=first + (nmemb>limit ? limit : nmemb-1)*sz;\
+  last=first + ((nmemb>limit ? limit : nmemb)-1)*sz;\
   while (last!=base) {				\
     if (compare(first,last)>0) first=last;	\
     last-=sz; }					\
@@ -294,188 +360,175 @@ typedef struct
 
 /* ---------------------------------------------------------------------- */
 
-static char *
-pivot_big(char *first, char *mid, char *last, size_t size,
-          int compare(const void *, const void *))
-{
-    size_t d = (((last - first) / size) >> 3) * size;
-    char *m1, *m2, *m3;
-    {
-        char *a = first, *b = first + d, *c = first + 2 * d;
+static char * pivot_big(char *first, char *mid, char *last, size_t size,
+                        int compare(const void *, const void *)) {
+  int d=(((last-first)/size)>>3)*size;
 #ifdef DEBUG_QSORT
-        fprintf(stderr, "< %d %d %d\n", *(int *) a, *(int *) b, *(int *) c);
+fprintf(stderr, "pivot_big: first=%p last=%p size=%lu n=%lu\n", first, (unsigned long)last, size, (unsigned long)((last-first+1)/size));
 #endif
-        m1 = compare(a, b) < 0 ?
-            (compare(b, c) < 0 ? b : (compare(a, c) < 0 ? c : a))
-            : (compare(a, c) < 0 ? a : (compare(b, c) < 0 ? c : b));
-    }
-    {
-        char *a = mid - d, *b = mid, *c = mid + d;
+  char *m1,*m2,*m3;
+  { char *a=first, *b=first+d, *c=first+2*d;
 #ifdef DEBUG_QSORT
-        fprintf(stderr, ". %d %d %d\n", *(int *) a, *(int *) b, *(int *) c);
+fprintf(stderr,"< %d %d %d @ %p %p %p\n",*(int*)a,*(int*)b,*(int*)c, a,b,c);
 #endif
-        m2 = compare(a, b) < 0 ?
-            (compare(b, c) < 0 ? b : (compare(a, c) < 0 ? c : a))
-            : (compare(a, c) < 0 ? a : (compare(b, c) < 0 ? c : b));
-    }
-    {
-        char *a = last - 2 * d, *b = last - d, *c = last;
+    m1 = compare(a,b)<0 ?
+           (compare(b,c)<0 ? b : (compare(a,c)<0 ? c : a))
+         : (compare(a,c)<0 ? a : (compare(b,c)<0 ? c : b));
+  }
+  { char *a=mid-d, *b=mid, *c=mid+d;
 #ifdef DEBUG_QSORT
-        fprintf(stderr, "> %d %d %d\n", *(int *) a, *(int *) b, *(int *) c);
+fprintf(stderr,". %d %d %d @ %p %p %p\n",*(int*)a,*(int*)b,*(int*)c, a,b,c);
 #endif
-        m3 = compare(a, b) < 0 ?
-            (compare(b, c) < 0 ? b : (compare(a, c) < 0 ? c : a))
-            : (compare(a, c) < 0 ? a : (compare(b, c) < 0 ? c : b));
-    }
+    m2 = compare(a,b)<0 ?
+           (compare(b,c)<0 ? b : (compare(a,c)<0 ? c : a))
+         : (compare(a,c)<0 ? a : (compare(b,c)<0 ? c : b));
+  }
+  { char *a=last-2*d, *b=last-d, *c=last;
+#ifdef DEBUG_QSORT
+fprintf(stderr,"> %d %d %d @ %p %p %p\n",*(int*)a,*(int*)b,*(int*)c, a,b,c);
+#endif
+    m3 = compare(a,b)<0 ?
+           (compare(b,c)<0 ? b : (compare(a,c)<0 ? c : a))
+         : (compare(a,c)<0 ? a : (compare(b,c)<0 ? c : b));
+  }
 #ifdef DEBUG_QSORT
-    fprintf(stderr, "-> %d %d %d\n", *(int *) m1, *(int *) m2, *(int *) m3);
+fprintf(stderr,"-> %d %d %d @ %p %p %p\n",*(int*)m1,*(int*)m2,*(int*)m3, m1,m2,m3);
 #endif
-    return compare(m1, m2) < 0 ?
-        (compare(m2, m3) < 0 ? m2 : (compare(m1, m3) < 0 ? m3 : m1))
-        : (compare(m1, m3) < 0 ? m1 : (compare(m2, m3) < 0 ? m3 : m2));
+  return compare(m1,m2)<0 ?
+           (compare(m2,m3)<0 ? m2 : (compare(m1,m3)<0 ? m3 : m1))
+         : (compare(m1,m3)<0 ? m1 : (compare(m2,m3)<0 ? m3 : m2));
 }
 
 /* ---------------------------------------------------------------------- */
 
-static void
-qsort_nonaligned(void *base, size_t nmemb, size_t size,
-                 int (*compare) (const void *, const void *))
-{
-
-    stack_entry stack[STACK_SIZE];
-    int stacktop = 0;
-    char *first, *last;
-    char *pivot = malloc(size);
-    size_t trunc = TRUNC_nonaligned * size;
-    assert(pivot != 0);
-
-    first = (char *) base;
-    last = first + (nmemb - 1) * size;
-
-    if ((size_t) (last - first) > trunc) {
-        char *ffirst = first, *llast = last;
-        while (1) {
-            /* Select pivot */
-            {
-                char *mid = first + size * ((last - first) / size >> 1);
-                Pivot(SWAP_nonaligned, size);
-                memcpy(pivot, mid, size);
-            }
-            /* Partition. */
-            Partition(SWAP_nonaligned, size);
-            /* Prepare to recurse/iterate. */
-        Recurse(trunc)}
+static void qsort_nonaligned(void *base, size_t nmemb, size_t size,
+           int (*compare)(const void *, const void *)) {
+
+  stack_entry stack[STACK_SIZE];
+  int stacktop=0;
+  char *first,*last;
+  char *pivot=malloc(size);
+  size_t trunc=TRUNC_nonaligned*size;
+  assert(pivot!=0);
+
+  first=(char*)base; last=first+(nmemb-1)*size;
+
+  if (last-first>=trunc) {
+    char *ffirst=first, *llast=last;
+    while (1) {
+      /* Select pivot */
+      { char * mid=first+size*((last-first)/size >> 1);
+        Pivot(SWAP_nonaligned,size);
+        memcpy(pivot,mid,size);
+      }
+      /* Partition. */
+      Partition(SWAP_nonaligned,size);
+      /* Prepare to recurse/iterate. */
+      Recurse(trunc)
     }
-    PreInsertion(SWAP_nonaligned, TRUNC_nonaligned, size);
-    Insertion(SWAP_nonaligned);
-    free(pivot);
+  }
+  PreInsertion(SWAP_nonaligned,TRUNC_nonaligned,size);
+  Insertion(SWAP_nonaligned);
+  free(pivot);
 }
 
-static void
-qsort_aligned(void *base, size_t nmemb, size_t size,
-              int (*compare) (const void *, const void *))
-{
-
-    stack_entry stack[STACK_SIZE];
-    int stacktop = 0;
-    char *first, *last;
-    char *pivot = malloc(size);
-    size_t trunc = TRUNC_aligned * size;
-    assert(pivot != 0);
-
-    first = (char *) base;
-    last = first + (nmemb - 1) * size;
-
-    if ((size_t) (last - first) > trunc) {
-        char *ffirst = first, *llast = last;
-        while (1) {
-            /* Select pivot */
-            {
-                char *mid = first + size * ((last - first) / size >> 1);
-                Pivot(SWAP_aligned, size);
-                memcpy(pivot, mid, size);
-            }
-            /* Partition. */
-            Partition(SWAP_aligned, size);
-            /* Prepare to recurse/iterate. */
-        Recurse(trunc)}
+static void qsort_aligned(void *base, size_t nmemb, size_t size,
+           int (*compare)(const void *, const void *)) {
+
+  stack_entry stack[STACK_SIZE];
+  int stacktop=0;
+  char *first,*last;
+  char *pivot=malloc(size);
+  size_t trunc=TRUNC_aligned*size;
+  assert(pivot!=0);
+
+  first=(char*)base; last=first+(nmemb-1)*size;
+
+  if (last-first>=trunc) {
+    char *ffirst=first,*llast=last;
+    while (1) {
+      /* Select pivot */
+      { char * mid=first+size*((last-first)/size >> 1);
+        Pivot(SWAP_aligned,size);
+        memcpy(pivot,mid,size);
+      }
+      /* Partition. */
+      Partition(SWAP_aligned,size);
+      /* Prepare to recurse/iterate. */
+      Recurse(trunc)
     }
-    PreInsertion(SWAP_aligned, TRUNC_aligned, size);
-    Insertion(SWAP_aligned);
-    free(pivot);
+  }
+  PreInsertion(SWAP_aligned,TRUNC_aligned,size);
+  Insertion(SWAP_aligned);
+  free(pivot);
 }
 
-static void
-qsort_words(void *base, size_t nmemb,
-            int (*compare) (const void *, const void *))
-{
+static void qsort_words(void *base, size_t nmemb,
+           int (*compare)(const void *, const void *)) {
 
-    stack_entry stack[STACK_SIZE];
-    int stacktop = 0;
-    char *first, *last;
-    char *pivot = malloc(WORD_BYTES);
-    assert(pivot != 0);
+  stack_entry stack[STACK_SIZE];
+  int stacktop=0;
+  char *first,*last;
+  char *pivot=malloc(WORD_BYTES);
+  assert(pivot!=0);
 
-    first = (char *) base;
-    last = first + (nmemb - 1) * WORD_BYTES;
+  first=(char*)base; last=first+(nmemb-1)*WORD_BYTES;
 
-    if (last - first > TRUNC_words) {
-        char *ffirst = first, *llast = last;
-        while (1) {
+  if (last-first>=TRUNC_words) {
+    char *ffirst=first, *llast=last;
+    while (1) {
 #ifdef DEBUG_QSORT
-            fprintf(stderr, "Doing %d:%d: ",
-                    (first - (char *) base) / WORD_BYTES,
-                    (last - (char *) base) / WORD_BYTES);
+fprintf(stderr,"Doing %d:%d: ",
+        (first-(char*)base)/WORD_BYTES,
+        (last-(char*)base)/WORD_BYTES);
 #endif
-            /* Select pivot */
-            {
-                char *mid =
-                    first + WORD_BYTES * ((last - first) / (2 * WORD_BYTES));
-                Pivot(SWAP_words, WORD_BYTES);
-                *(int *) pivot = *(int *) mid;
-            }
+      /* Select pivot */
+      { char * mid=first+WORD_BYTES*((last-first) / (2*WORD_BYTES));
+        Pivot(SWAP_words,WORD_BYTES);
+        *(int*)pivot=*(int*)mid;
 #ifdef DEBUG_QSORT
-            fprintf(stderr, "pivot=%d\n", *(int *) pivot);
+fprintf(stderr,"pivot = %p = #%lu = %d\n", mid, (unsigned long)(((int*)mid)-((int*)base)), *(int*)mid);
 #endif
-            /* Partition. */
-            Partition(SWAP_words, WORD_BYTES);
-            /* Prepare to recurse/iterate. */
-        Recurse(TRUNC_words)}
-    }
-    PreInsertion(SWAP_words, (TRUNC_words / WORD_BYTES), WORD_BYTES);
-    /* Now do insertion sort. */
-    last = ((char *) base) + nmemb * WORD_BYTES;
-    for (first = ((char *) base) + WORD_BYTES; first != last;
-         first += WORD_BYTES) {
-        /* Find the right place for |first|. My apologies for var reuse */
-        int *pl = (int *) (first - WORD_BYTES), *pr = (int *) first;
-        *(int *) pivot = *(int *) first;
-        for (; compare(pl, pivot) > 0; pr = pl, --pl) {
-            *pr = *pl;
-        }
-        if (pr != (int *) first)
-            *pr = *(int *) pivot;
+      }
+      /* Partition. */
+      Partition(SWAP_words,WORD_BYTES);
+#ifdef DEBUG_QSORT
+fprintf(stderr, "after partitioning first=#%lu last=#%lu\n", (first-(char*)base)/4lu, (last-(char*)base)/4lu);
+#endif
+      /* Prepare to recurse/iterate. */
+      Recurse(TRUNC_words)
     }
-    free(pivot);
+  }
+  PreInsertion(SWAP_words,(TRUNC_words/WORD_BYTES),WORD_BYTES);
+  /* Now do insertion sort. */
+  last=((char*)base)+nmemb*WORD_BYTES;
+  for (first=((char*)base)+WORD_BYTES;first!=last;first+=WORD_BYTES) {
+    /* Find the right place for |first|. My apologies for var reuse */
+    int *pl=(int*)(first-WORD_BYTES),*pr=(int*)first;
+    *(int*)pivot=*(int*)first;
+    for (;compare(pl,pivot)>0;pr=pl,--pl) {
+      *pr=*pl; }
+    if (pr!=(int*)first) *pr=*(int*)pivot;
+  }
+  free(pivot);
 }
 
 /* ---------------------------------------------------------------------- */
 
-void
-qsort(void *base, size_t nmemb, size_t size,
-      int (*compare) (const void *, const void *))
-{
+extern void qsortG(void *base, size_t nmemb, size_t size,
+           int (*compare)(const void *, const void *)) {
 
-    if (nmemb <= 1)
-        return;
-    if (((uintptr_t) base | size) & (WORD_BYTES - 1))
-        qsort_nonaligned(base, nmemb, size, compare);
-    else if (size != WORD_BYTES)
-        qsort_aligned(base, nmemb, size, compare);
-    else
-        qsort_words(base, nmemb, compare);
+  if (nmemb<=1) return;
+  if (((int)base|size)&(WORD_BYTES-1))
+    qsort_nonaligned(base,nmemb,size,compare);
+  else if (size!=WORD_BYTES)
+    qsort_aligned(base,nmemb,size,compare);
+  else
+    qsort_words(base,nmemb,compare);
 }
 
-#endif /* !SDL_qsort */
+
+#endif /* HAVE_QSORT */
 
 /* vi: set ts=4 sw=4 expandtab: */
+

+ 5 - 0
modules/sdl2/SDL/src/thread/SDL_systhread.h

@@ -60,6 +60,11 @@ extern SDL_TLSData *SDL_SYS_GetTLSData();
 /* Set the thread local storage for this thread */
 extern int SDL_SYS_SetTLSData(SDL_TLSData *data);
 
+/* This is for internal SDL use, so we don't need #ifdefs everywhere. */
+extern SDL_Thread *
+SDL_CreateThreadInternal(int (SDLCALL * fn) (void *), const char *name,
+                         const size_t stacksize, void *data);
+
 #endif /* _SDL_systhread_h */
 
 /* vi: set ts=4 sw=4 expandtab: */

+ 53 - 6
modules/sdl2/SDL/src/thread/SDL_thread.c

@@ -26,6 +26,7 @@
 #include "SDL_thread.h"
 #include "SDL_thread_c.h"
 #include "SDL_systhread.h"
+#include "SDL_hints.h"
 #include "../SDL_error_c.h"
 
 
@@ -304,15 +305,15 @@ SDL_RunThread(void *data)
 #endif
 
 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
-DECLSPEC SDL_Thread *SDLCALL
-SDL_CreateThread(int (SDLCALL * fn) (void *),
-                 const char *name, void *data,
+static SDL_Thread *
+SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
+                 const char *name, const size_t stacksize, void *data,
                  pfnSDL_CurrentBeginThread pfnBeginThread,
                  pfnSDL_CurrentEndThread pfnEndThread)
 #else
-DECLSPEC SDL_Thread *SDLCALL
-SDL_CreateThread(int (SDLCALL * fn) (void *),
-                 const char *name, void *data)
+static SDL_Thread *
+SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
+                const char *name, const size_t stacksize, void *data)
 #endif
 {
     SDL_Thread *thread;
@@ -362,6 +363,8 @@ SDL_CreateThread(int (SDLCALL * fn) (void *),
         return (NULL);
     }
 
+    thread->stacksize = stacksize;
+
     /* Create the thread and go! */
 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
     ret = SDL_SYS_CreateThread(thread, args, pfnBeginThread, pfnEndThread);
@@ -386,6 +389,50 @@ SDL_CreateThread(int (SDLCALL * fn) (void *),
     return (thread);
 }
 
+#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
+DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThread(int (SDLCALL * fn) (void *),
+                 const char *name, void *data,
+                 pfnSDL_CurrentBeginThread pfnBeginThread,
+                 pfnSDL_CurrentEndThread pfnEndThread)
+#else
+DECLSPEC SDL_Thread *SDLCALL
+SDL_CreateThread(int (SDLCALL * fn) (void *),
+                 const char *name, void *data)
+#endif
+{
+    /* !!! FIXME: in 2.1, just make stackhint part of the usual API. */
+    const char *stackhint = SDL_GetHint(SDL_HINT_THREAD_STACK_SIZE);
+    size_t stacksize = 0;
+
+    /* If the SDL_HINT_THREAD_STACK_SIZE exists, use it */
+    if (stackhint != NULL) {
+        char *endp = NULL;
+        const Sint64 hintval = SDL_strtoll(stackhint, &endp, 10);
+        if ((*stackhint != '\0') && (*endp == '\0')) {  /* a valid number? */
+            if (hintval > 0) {  /* reject bogus values. */
+                stacksize = (size_t) hintval;
+            }
+        }
+    }
+
+#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
+    return SDL_CreateThreadWithStackSize(fn, name, stacksize, data, pfnBeginThread, pfnEndThread);
+#else
+    return SDL_CreateThreadWithStackSize(fn, name, stacksize, data);
+#endif
+}
+
+SDL_Thread *
+SDL_CreateThreadInternal(int (SDLCALL * fn) (void *), const char *name,
+                         const size_t stacksize, void *data) {
+#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD
+    return SDL_CreateThreadWithStackSize(fn, name, stacksize, data, NULL, NULL);
+#else
+    return SDL_CreateThreadWithStackSize(fn, name, stacksize, data);
+#endif
+}
+
 SDL_threadID
 SDL_GetThreadID(SDL_Thread * thread)
 {

+ 1 - 0
modules/sdl2/SDL/src/thread/SDL_thread_c.h

@@ -59,6 +59,7 @@ struct SDL_Thread
     SDL_atomic_t state;  /* SDL_THREAD_STATE_* */
     SDL_error errbuf;
     char *name;
+    size_t stacksize;  /* 0 for default, >0 for user-specified stack size. */
     void *data;
 };
 

+ 2 - 2
modules/sdl2/SDL/src/thread/psp/SDL_systhread.c

@@ -52,8 +52,8 @@ int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
         priority = status.currentPriority;
     }
 
-    thread->handle = sceKernelCreateThread("SDL thread", ThreadEntry,
-                           priority, 0x8000,
+    thread->handle = sceKernelCreateThread(thread->name, ThreadEntry,
+                           priority, thread->stacksize ? ((int) thread->stacksize) : 0x8000,
                            PSP_THREAD_ATTR_VFPU, NULL);
     if (thread->handle < 0) {
         return SDL_SetError("sceKernelCreateThread() failed");

+ 3 - 8
modules/sdl2/SDL/src/thread/pthread/SDL_systhread.c

@@ -45,7 +45,6 @@
 
 #include "SDL_platform.h"
 #include "SDL_thread.h"
-#include "SDL_hints.h"
 #include "../SDL_thread_c.h"
 #include "../SDL_systhread.h"
 #ifdef __ANDROID__
@@ -87,7 +86,6 @@ int
 SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
 {
     pthread_attr_t type;
-    const char *hint = SDL_GetHint(SDL_HINT_THREAD_STACK_SIZE);
 
     /* do this here before any threads exist, so there's no race condition. */
     #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)
@@ -108,12 +106,9 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
     }
     pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE);
     
-    /* If the SDL_HINT_THREAD_STACK_SIZE exists and it seems to be a positive number, use it */
-    if (hint && hint[0] >= '0' && hint[0] <= '9') {
-        const size_t stacksize = (size_t) SDL_atoi(hint);
-        if (stacksize > 0) {
-            pthread_attr_setstacksize(&type, stacksize);
-        }
+    /* Set caller-requested stack size. Otherwise: use the system default. */
+    if (thread->stacksize) {
+        pthread_attr_setstacksize(&type, (size_t) thread->stacksize);
     }
 
     /* Create the thread and go! */

+ 1 - 0
modules/sdl2/SDL/src/thread/stdcpp/SDL_systhread.cpp

@@ -48,6 +48,7 @@ int
 SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
 {
     try {
+        // !!! FIXME: no way to set a thread stack size here.
         std::thread cpp_thread(RunThread, args);
         thread->handle = (void *) new std::thread(std::move(cpp_thread));
         return 0;

+ 13 - 44
modules/sdl2/SDL/src/thread/windows/SDL_systhread.c

@@ -121,6 +121,7 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
 #endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */
     pThreadStartParms pThreadParms =
         (pThreadStartParms) SDL_malloc(sizeof(tThreadStartParms));
+    const DWORD flags = thread->stacksize ? STACK_SIZE_PARAM_IS_A_RESERVATION : 0;
     if (!pThreadParms) {
         return SDL_OutOfMemory();
     }
@@ -129,15 +130,18 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
     /* Also save the real parameters we have to pass to thread function */
     pThreadParms->args = args;
 
+    /* thread->stacksize == 0 means "system default", same as win32 expects */
     if (pfnBeginThread) {
         unsigned threadid = 0;
         thread->handle = (SYS_ThreadHandle)
-            ((size_t) pfnBeginThread(NULL, 0, RunThreadViaBeginThreadEx,
-                                     pThreadParms, 0, &threadid));
+            ((size_t) pfnBeginThread(NULL, (unsigned int) thread->stacksize,
+                                     RunThreadViaBeginThreadEx,
+                                     pThreadParms, flags, &threadid));
     } else {
         DWORD threadid = 0;
-        thread->handle = CreateThread(NULL, 0, RunThreadViaCreateThread,
-                                      pThreadParms, 0, &threadid);
+        thread->handle = CreateThread(NULL, thread->stacksize,
+                                      RunThreadViaCreateThread,
+                                      pThreadParms, flags, &threadid);
     }
     if (thread->handle == NULL) {
         return SDL_SetError("Not enough resources to create thread");
@@ -145,9 +149,6 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
     return 0;
 }
 
-#if 0  /* !!! FIXME: revisit this later. See https://bugzilla.libsdl.org/show_bug.cgi?id=2089 */
-#ifdef _MSC_VER
-#pragma warning(disable : 4733)
 #pragma pack(push,8)
 typedef struct tagTHREADNAME_INFO
 {
@@ -158,48 +159,20 @@ typedef struct tagTHREADNAME_INFO
 } THREADNAME_INFO;
 #pragma pack(pop)
 
-static EXCEPTION_DISPOSITION
-ignore_exception(void *a, void *b, void *c, void *d)
-{
-    return ExceptionContinueExecution;
-}
-#endif
-#endif
-
 void
 SDL_SYS_SetupThread(const char *name)
 {
-    if (name != NULL) {
-        #if 0 /* !!! FIXME: revisit this later. See https://bugzilla.libsdl.org/show_bug.cgi?id=2089 */
-        #if (defined(_MSC_VER) && defined(_M_IX86))
-        /* This magic tells the debugger to name a thread if it's listening.
-            The inline asm sets up SEH (__try/__except) without C runtime
-            support. See Microsoft Systems Journal, January 1997:
-            http://www.microsoft.com/msj/0197/exception/exception.aspx */
-        INT_PTR handler = (INT_PTR) ignore_exception;
+    if ((name != NULL) && IsDebuggerPresent()) {
+        /* This magic tells the debugger to name a thread if it's listening. */
         THREADNAME_INFO inf;
-
+        SDL_zero(inf);
         inf.dwType = 0x1000;
         inf.szName = name;
         inf.dwThreadID = (DWORD) -1;
         inf.dwFlags = 0;
 
-        __asm {   /* set up SEH */
-            push handler
-            push fs:[0]
-            mov fs:[0],esp
-        }
-
-        /* The program itself should ignore this bogus exception. */
-        RaiseException(0x406D1388, 0, sizeof(inf)/sizeof(DWORD), (DWORD*)&inf);
-
-        __asm {  /* tear down SEH. */
-            mov eax,[esp]
-            mov fs:[0], eax
-            add esp, 8
-        }
-        #endif
-        #endif
+        /* The debugger catches this, renames the thread, continues on. */
+        RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR*) &inf);
     }
 }
 
@@ -230,11 +203,7 @@ SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
 void
 SDL_SYS_WaitThread(SDL_Thread * thread)
 {
-#if __WINRT__
     WaitForSingleObjectEx(thread->handle, INFINITE, FALSE);
-#else
-    WaitForSingleObject(thread->handle, INFINITE);
-#endif
     CloseHandle(thread->handle);
 }
 

+ 15 - 14
modules/sdl2/SDL/src/timer/SDL_timer.c

@@ -24,7 +24,7 @@
 #include "SDL_timer_c.h"
 #include "SDL_atomic.h"
 #include "SDL_cpuinfo.h"
-#include "SDL_thread.h"
+#include "../thread/SDL_systhread.h"
 
 /* #define DEBUG_TIMERS */
 
@@ -112,6 +112,9 @@ SDL_TimerThread(void *_data)
      *  2. Handle any timers that should dispatch this cycle
      *  3. Wait until next dispatch time or new timer arrives
      */
+     
+    tick=SDL_GetTicks();
+    
     for ( ; ; ) {
         /* Pending and freelist maintenance */
         SDL_AtomicLock(&data->lock);
@@ -145,7 +148,7 @@ SDL_TimerThread(void *_data)
         /* Initial delay if there are no timers */
         delay = SDL_MUTEX_MAXWAIT;
 
-        tick = SDL_GetTicks();
+        //tick = SDL_GetTicks();
 
         /* Process all the pending timers for this tick */
         while (data->timers) {
@@ -154,6 +157,7 @@ SDL_TimerThread(void *_data)
             if ((Sint32)(tick-current->scheduled) < 0) {
                 /* Scheduled for the future, wait a bit */
                 delay = (current->scheduled - tick);
+                delay-=1;
                 break;
             }
 
@@ -185,6 +189,7 @@ SDL_TimerThread(void *_data)
 
         /* Adjust the delay based on processing time */
         now = SDL_GetTicks();
+        
         interval = (now - tick);
         if (interval > delay) {
             delay = 0;
@@ -197,7 +202,11 @@ SDL_TimerThread(void *_data)
            That's okay, it just means we run through the loop a few
            extra times.
          */
-        SDL_SemWaitTimeout(data->sem, delay);
+        if( SDL_SemWaitTimeout(data->sem, delay)==SDL_MUTEX_TIMEDOUT ){
+        	tick=now+delay;
+        }else{
+        	tick=SDL_GetTicks();
+        }
     }
     return 0;
 }
@@ -221,17 +230,9 @@ SDL_TimerInit(void)
         }
 
         SDL_AtomicSet(&data->active, 1);
-        /* !!! FIXME: this is nasty. */
-#if defined(__WIN32__) && !defined(HAVE_LIBC)
-#undef SDL_CreateThread
-#if SDL_DYNAMIC_API
-        data->thread = SDL_CreateThread_REAL(SDL_TimerThread, name, data, NULL, NULL);
-#else
-        data->thread = SDL_CreateThread(SDL_TimerThread, name, data, NULL, NULL);
-#endif
-#else
-        data->thread = SDL_CreateThread(SDL_TimerThread, name, data);
-#endif
+
+        /* Timer threads use a callback into the app, so we can't set a limited stack size here. */
+        data->thread = SDL_CreateThreadInternal(SDL_TimerThread, name, 0, data);
         if (!data->thread) {
             SDL_TimerQuit();
             return -1;

+ 4 - 0
modules/sdl2/SDL/src/timer/windows/SDL_systimer.c

@@ -189,6 +189,10 @@ SDL_Delay(Uint32 ms)
     }
     WaitForSingleObjectEx(mutex, ms, FALSE);
 #else
+    if (!ticks_started) {
+        SDL_TicksInit();
+    }
+
     Sleep(ms);
 #endif
 }

+ 2 - 1
modules/sdl2/SDL/src/video/SDL_egl.c

@@ -558,7 +558,8 @@ int
 SDL_EGL_GetSwapInterval(_THIS)
 {
     if (!_this->egl_data) {
-        return SDL_SetError("EGL not initialized");
+        SDL_SetError("EGL not initialized");
+        return 0;
     }
     
     return _this->egl_data->egl_swapinterval;

+ 22 - 6
modules/sdl2/SDL/src/video/SDL_video.c

@@ -719,7 +719,9 @@ SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi)
 		if (_this->GetDisplayDPI(_this, display, ddpi, hdpi, vdpi) == 0) {
 			return 0;
 		}
-	}
+    } else {
+        return SDL_Unsupported();
+    }
 
 	return -1;
 }
@@ -1309,11 +1311,6 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
 static void
 SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags)
 {
-    window->windowed.x = window->x;
-    window->windowed.y = window->y;
-    window->windowed.w = window->w;
-    window->windowed.h = window->h;
-
     if (flags & SDL_WINDOW_MAXIMIZED) {
         SDL_MaximizeWindow(window);
     }
@@ -1413,6 +1410,25 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
             window->y = bounds.y + (bounds.h - h) / 2;
         }
     }
+    window->windowed.x = window->x;
+    window->windowed.y = window->y;
+    window->windowed.w = window->w;
+    window->windowed.h = window->h;
+
+    if (flags & SDL_WINDOW_FULLSCREEN) {
+        SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+        int displayIndex;
+        SDL_Rect bounds;
+
+        displayIndex = SDL_GetIndexOfDisplay(display);
+        SDL_GetDisplayBounds(displayIndex, &bounds);
+
+        window->x = bounds.x;
+        window->y = bounds.y;
+        window->w = bounds.w;
+        window->h = bounds.h;
+    }
+
     window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN);
     window->last_fullscreen_flags = window->flags;
     window->opacity = 1.0f;

+ 14 - 2
modules/sdl2/SDL/src/video/android/SDL_androidmouse.c

@@ -37,10 +37,18 @@
 #define BUTTON_PRIMARY 1
 #define BUTTON_SECONDARY 2
 #define BUTTON_TERTIARY 4
+#define BUTTON_BACK 8
+#define BUTTON_FORWARD 16
 
-void Android_OnMouse( int androidButton, int action, float x, float y) {
-    static Uint8 SDLButton;
+static Uint8 SDLButton;
+
+void
+Android_InitMouse(void)
+{
+    SDLButton = 0;
+}
 
+void Android_OnMouse( int androidButton, int action, float x, float y) {
     if (!Android_Window) {
         return;
     }
@@ -53,6 +61,10 @@ void Android_OnMouse( int androidButton, int action, float x, float y) {
                 SDLButton = SDL_BUTTON_RIGHT;
             } else if (androidButton == BUTTON_TERTIARY) {
                 SDLButton = SDL_BUTTON_MIDDLE;
+            } else if (androidButton == BUTTON_FORWARD) {
+                SDLButton = SDL_BUTTON_X1;
+            } else if (androidButton == BUTTON_BACK) {
+                SDLButton = SDL_BUTTON_X2;
             }
             SDL_SendMouseMotion(Android_Window, 0, 0, x, y);
             SDL_SendMouseButton(Android_Window, 0, SDL_PRESSED, SDLButton);

+ 1 - 0
modules/sdl2/SDL/src/video/android/SDL_androidmouse.h

@@ -24,6 +24,7 @@
 
 #include "SDL_androidvideo.h"
 
+extern void Android_InitMouse(void);
 extern void Android_OnMouse( int button, int action, float x, float y);
 
 #endif /* _SDL_androidmouse_h */

+ 3 - 0
modules/sdl2/SDL/src/video/android/SDL_androidvideo.c

@@ -36,6 +36,7 @@
 #include "SDL_androidclipboard.h"
 #include "SDL_androidevents.h"
 #include "SDL_androidkeyboard.h"
+#include "SDL_androidmouse.h"
 #include "SDL_androidtouch.h"
 #include "SDL_androidwindow.h"
 
@@ -181,6 +182,8 @@ Android_VideoInit(_THIS)
 
     Android_InitTouch();
 
+    Android_InitMouse();
+
     /* We're done! */
     return 0;
 }

+ 3 - 13
modules/sdl2/SDL/src/video/cocoa/SDL_cocoaclipboard.m

@@ -25,23 +25,13 @@
 #include "SDL_cocoavideo.h"
 #include "../../events/SDL_clipboardevents_c.h"
 
-static NSString *
-GetTextFormat(_THIS)
-{
-    if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5) {
-        return NSPasteboardTypeString;
-    } else {
-        return NSStringPboardType;
-    }
-}
-
 int
 Cocoa_SetClipboardText(_THIS, const char *text)
 { @autoreleasepool
 {
     SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
     NSPasteboard *pasteboard;
-    NSString *format = GetTextFormat(_this);
+    NSString *format = NSPasteboardTypeString;
 
     pasteboard = [NSPasteboard generalPasteboard];
     data->clipboard_count = [pasteboard declareTypes:[NSArray arrayWithObject:format] owner:nil];
@@ -55,12 +45,12 @@ Cocoa_GetClipboardText(_THIS)
 { @autoreleasepool
 {
     NSPasteboard *pasteboard;
-    NSString *format = GetTextFormat(_this);
+    NSString *format = NSPasteboardTypeString;
     NSString *available;
     char *text;
 
     pasteboard = [NSPasteboard generalPasteboard];
-    available = [pasteboard availableTypeFromArray: [NSArray arrayWithObject:format]];
+    available = [pasteboard availableTypeFromArray:[NSArray arrayWithObject:format]];
     if ([available isEqualToString:format]) {
         NSString* string;
         const char *utf8;

+ 12 - 26
modules/sdl2/SDL/src/video/cocoa/SDL_cocoaevents.m

@@ -114,28 +114,23 @@
      */
     for (NSWindow *window in [NSApp orderedWindows]) {
         if (window != win && [window canBecomeKeyWindow]) {
-            if ([window respondsToSelector:@selector(isOnActiveSpace)]) {
-                if (![window isOnActiveSpace]) {
-                    continue;
-                }
+            if (![window isOnActiveSpace]) {
+                continue;
             }
             [window makeKeyAndOrderFront:self];
             return;
         }
     }
 
-    /* If a window wasn't found above, iterate through all visible windows
-     * (including the 'About' window, if it's shown) and make the first one key.
-     * Note that +[NSWindow windowNumbersWithOptions:] was added in 10.6.
+    /* If a window wasn't found above, iterate through all visible windows in
+     * the active Space in z-order (including the 'About' window, if it's shown)
+     * and make the first one key.
      */
-    if ([NSWindow respondsToSelector:@selector(windowNumbersWithOptions:)]) {
-        /* Get all visible windows in the active Space, in z-order. */
-        for (NSNumber *num in [NSWindow windowNumbersWithOptions:0]) {
-            NSWindow *window = [NSApp windowWithWindowNumber:[num integerValue]];
-            if (window && window != win && [window canBecomeKeyWindow]) {
-                [window makeKeyAndOrderFront:self];
-                return;
-            }
+    for (NSNumber *num in [NSWindow windowNumbersWithOptions:0]) {
+        NSWindow *window = [NSApp windowWithWindowNumber:[num integerValue]];
+        if (window && window != win && [window canBecomeKeyWindow]) {
+            [window makeKeyAndOrderFront:self];
+            return;
         }
     }
 }
@@ -291,7 +286,7 @@ CreateApplicationMenus(void)
 
 
     /* Add the fullscreen view toggle menu option, if supported */
-    if ([NSApp respondsToSelector:@selector(setPresentationOptions:)]) {
+    if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) {
         /* Create the view menu */
         viewMenu = [[NSMenu alloc] initWithTitle:@"View"];
 
@@ -321,16 +316,7 @@ Cocoa_RegisterApp(void)
 
         const char *hint = SDL_GetHint(SDL_HINT_MAC_BACKGROUND_APP);
         if (!hint || *hint == '0') {
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
-			if ([NSApp respondsToSelector:@selector(setActivationPolicy:)]) {
-#endif
-				[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
-			} else {
-				ProcessSerialNumber psn = {0, kCurrentProcess};
-				TransformProcessType(&psn, kProcessTransformToForegroundApplication);
-			}
-#endif
+            [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
             [NSApp activateIgnoringOtherApps:YES];
 		}
 		

+ 6 - 17
modules/sdl2/SDL/src/video/cocoa/SDL_cocoakeyboard.m

@@ -69,14 +69,6 @@
     SDL_SendKeyboardText(str);
 }
 
-- (void)insertText:(id)insertString
-{
-    /* This method is part of NSTextInput and not NSTextInputClient, but
-     * apparently it still might be called in OS X 10.5 and can cause beeps if
-     * the implementation is missing: http://crbug.com/47890 */
-    [self insertText:insertString replacementRange:NSMakeRange(0, 0)];
-}
-
 - (void)doCommandBySelector:(SEL)myselector
 {
     /* No need to do anything since we are not using Cocoa
@@ -102,7 +94,7 @@
 
 - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange;
 {
-    if ([aString isKindOfClass: [NSAttributedString class]]) {
+    if ([aString isKindOfClass:[NSAttributedString class]]) {
         aString = [aString string];
     }
 
@@ -150,10 +142,10 @@
             aRange.location, aRange.length, windowHeight,
             NSStringFromRect(rect));
 
-    if ([[self window] respondsToSelector:@selector(convertRectToScreen:)]) {
-        rect = [[self window] convertRectToScreen:rect];
+    if ([window respondsToSelector:@selector(convertRectToScreen:)]) {
+        rect = [window convertRectToScreen:rect];
     } else {
-        rect.origin = [[self window] convertBaseToScreen:rect.origin];
+        rect.origin = [window convertBaseToScreen:rect.origin];
     }
 
     return rect;
@@ -498,11 +490,8 @@ Cocoa_InitKeyboard(_THIS)
     SDL_SetScancodeName(SDL_SCANCODE_RALT, "Right Option");
     SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Command");
 
-    /* On pre-10.6, you might have the initial capslock key state wrong. */
-    if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_6) {
-        data->modifierFlags = [NSEvent modifierFlags];
-        SDL_ToggleModState(KMOD_CAPS, (data->modifierFlags & NSAlphaShiftKeyMask) != 0);
-    }
+    data->modifierFlags = [NSEvent modifierFlags];
+    SDL_ToggleModState(KMOD_CAPS, (data->modifierFlags & NSAlphaShiftKeyMask) != 0);
 }
 
 void

+ 1 - 1
modules/sdl2/SDL/src/video/cocoa/SDL_cocoamodes.h

@@ -30,7 +30,7 @@ typedef struct
 
 typedef struct
 {
-    const void *moderef;
+    CGDisplayModeRef moderef;
 } SDL_DisplayModeData;
 
 extern void Cocoa_InitModes(_THIS);

+ 33 - 123
modules/sdl2/SDL/src/video/cocoa/SDL_cocoamodes.m

@@ -56,25 +56,6 @@ Cocoa_ToggleMenuBar(const BOOL show)
 #endif
 }
 
-
-/* !!! FIXME: clean out the pre-10.6 code when it makes sense to do so. */
-#define FORCE_OLD_API 0
-
-#if FORCE_OLD_API
-#undef MAC_OS_X_VERSION_MIN_REQUIRED
-#define MAC_OS_X_VERSION_MIN_REQUIRED 1050
-#endif
-
-static BOOL
-IS_SNOW_LEOPARD_OR_LATER()
-{
-#if FORCE_OLD_API
-    return NO;
-#else
-    return floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5;
-#endif
-}
-
 static int
 CG_SetError(const char *prefix, CGDisplayErr result)
 {
@@ -119,59 +100,40 @@ CG_SetError(const char *prefix, CGDisplayErr result)
 }
 
 static SDL_bool
-GetDisplayMode(_THIS, const void *moderef, CVDisplayLinkRef link, SDL_DisplayMode *mode)
+GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CVDisplayLinkRef link, SDL_DisplayMode *mode)
 {
     SDL_DisplayModeData *data;
     long width = 0;
     long height = 0;
     long bpp = 0;
     long refreshRate = 0;
+    CFStringRef fmt;
 
     data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
     if (!data) {
         return SDL_FALSE;
     }
-    data->moderef = moderef;
-
-    if (IS_SNOW_LEOPARD_OR_LATER()) {
-        CGDisplayModeRef vidmode = (CGDisplayModeRef) moderef;
-        CFStringRef fmt = CGDisplayModeCopyPixelEncoding(vidmode);
-        width = (long) CGDisplayModeGetWidth(vidmode);
-        height = (long) CGDisplayModeGetHeight(vidmode);
-        refreshRate = (long) (CGDisplayModeGetRefreshRate(vidmode) + 0.5);
-
-        if (CFStringCompare(fmt, CFSTR(IO32BitDirectPixels),
-                            kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
-            bpp = 32;
-        } else if (CFStringCompare(fmt, CFSTR(IO16BitDirectPixels),
-                            kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
-            bpp = 16;
-        } else if (CFStringCompare(fmt, CFSTR(kIO30BitDirectPixels),
-                            kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
-            bpp = 30;
-        } else {
-            bpp = 0;  /* ignore 8-bit and such for now. */
-        }
-
-        CFRelease(fmt);
+    data->moderef = vidmode;
+
+    fmt = CGDisplayModeCopyPixelEncoding(vidmode);
+    width = (long) CGDisplayModeGetWidth(vidmode);
+    height = (long) CGDisplayModeGetHeight(vidmode);
+    refreshRate = (long) (CGDisplayModeGetRefreshRate(vidmode) + 0.5);
+
+    if (CFStringCompare(fmt, CFSTR(IO32BitDirectPixels),
+                        kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+        bpp = 32;
+    } else if (CFStringCompare(fmt, CFSTR(IO16BitDirectPixels),
+                        kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+        bpp = 16;
+    } else if (CFStringCompare(fmt, CFSTR(kIO30BitDirectPixels),
+                        kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+        bpp = 30;
+    } else {
+        bpp = 0;  /* ignore 8-bit and such for now. */
     }
 
-    #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
-    if (!IS_SNOW_LEOPARD_OR_LATER()) {
-        CFNumberRef number;
-        double refresh;
-        CFDictionaryRef vidmode = (CFDictionaryRef) moderef;
-        number = CFDictionaryGetValue(vidmode, kCGDisplayWidth);
-        CFNumberGetValue(number, kCFNumberLongType, &width);
-        number = CFDictionaryGetValue(vidmode, kCGDisplayHeight);
-        CFNumberGetValue(number, kCFNumberLongType, &height);
-        number = CFDictionaryGetValue(vidmode, kCGDisplayBitsPerPixel);
-        CFNumberGetValue(number, kCFNumberLongType, &bpp);
-        number = CFDictionaryGetValue(vidmode, kCGDisplayRefreshRate);
-        CFNumberGetValue(number, kCFNumberDoubleType, &refresh);
-        refreshRate = (long) (refresh + 0.5);
-    }
-    #endif
+    CFRelease(fmt);
 
     /* CGDisplayModeGetRefreshRate returns 0 for many non-CRT displays. */
     if (refreshRate == 0 && link != NULL) {
@@ -204,22 +166,6 @@ GetDisplayMode(_THIS, const void *moderef, CVDisplayLinkRef link, SDL_DisplayMod
     return SDL_TRUE;
 }
 
-static void
-Cocoa_ReleaseDisplayMode(_THIS, const void *moderef)
-{
-    if (IS_SNOW_LEOPARD_OR_LATER()) {
-        CGDisplayModeRelease((CGDisplayModeRef) moderef);  /* NULL is ok */
-    }
-}
-
-static void
-Cocoa_ReleaseDisplayModeList(_THIS, CFArrayRef modelist)
-{
-    if (IS_SNOW_LEOPARD_OR_LATER()) {
-        CFRelease(modelist);  /* NULL is ok */
-    }
-}
-
 static const char *
 Cocoa_GetDisplayName(CGDirectDisplayID displayID)
 {
@@ -262,7 +208,7 @@ Cocoa_InitModes(_THIS)
             SDL_VideoDisplay display;
             SDL_DisplayData *displaydata;
             SDL_DisplayMode mode;
-            const void *moderef = NULL;
+            CGDisplayModeRef moderef = NULL;
             CVDisplayLinkRef link = NULL;
 
             if (pass == 0) {
@@ -279,15 +225,7 @@ Cocoa_InitModes(_THIS)
                 continue;
             }
 
-            if (IS_SNOW_LEOPARD_OR_LATER()) {
-                moderef = CGDisplayCopyDisplayMode(displays[i]);
-            }
-
-            #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
-            if (!IS_SNOW_LEOPARD_OR_LATER()) {
-                moderef = CGDisplayCurrentMode(displays[i]);
-            }
-            #endif
+            moderef = CGDisplayCopyDisplayMode(displays[i]);
 
             if (!moderef) {
                 continue;
@@ -295,7 +233,7 @@ Cocoa_InitModes(_THIS)
 
             displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata));
             if (!displaydata) {
-                Cocoa_ReleaseDisplayMode(_this, moderef);
+                CGDisplayModeRelease(moderef);
                 continue;
             }
             displaydata->display = displays[i];
@@ -307,7 +245,7 @@ Cocoa_InitModes(_THIS)
             display.name = (char *)Cocoa_GetDisplayName(displays[i]);
             if (!GetDisplayMode(_this, moderef, link, &mode)) {
                 CVDisplayLinkRelease(link);
-                Cocoa_ReleaseDisplayMode(_this, moderef);
+                CGDisplayModeRelease(moderef);
                 SDL_free(display.name);
                 SDL_free(displaydata);
                 continue;
@@ -396,17 +334,7 @@ void
 Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
 {
     SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
-    CFArrayRef modes = NULL;
-
-    if (IS_SNOW_LEOPARD_OR_LATER()) {
-        modes = CGDisplayCopyAllDisplayModes(data->display, NULL);
-    }
-
-    #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
-    if (!IS_SNOW_LEOPARD_OR_LATER()) {
-        modes = CGDisplayAvailableModes(data->display);
-    }
-    #endif
+    CFArrayRef modes = CGDisplayCopyAllDisplayModes(data->display, NULL);
 
     if (modes) {
         CVDisplayLinkRef link = NULL;
@@ -416,37 +344,19 @@ Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
         CVDisplayLinkCreateWithCGDisplay(data->display, &link);
 
         for (i = 0; i < count; i++) {
-            const void *moderef = CFArrayGetValueAtIndex(modes, i);
+            CGDisplayModeRef moderef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
             SDL_DisplayMode mode;
             if (GetDisplayMode(_this, moderef, link, &mode)) {
-                if (IS_SNOW_LEOPARD_OR_LATER()) {
-                    CGDisplayModeRetain((CGDisplayModeRef) moderef);
-                }
+                CGDisplayModeRetain(moderef);
                 SDL_AddDisplayMode(display, &mode);
             }
         }
 
         CVDisplayLinkRelease(link);
-        Cocoa_ReleaseDisplayModeList(_this, modes);
+        CFRelease(modes);
     }
 }
 
-static CGError
-Cocoa_SwitchMode(_THIS, CGDirectDisplayID display, const void *mode)
-{
-    if (IS_SNOW_LEOPARD_OR_LATER()) {
-        return CGDisplaySetDisplayMode(display, (CGDisplayModeRef) mode, NULL);
-    }
- 
-    #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
-    if (!IS_SNOW_LEOPARD_OR_LATER()) {
-        return CGDisplaySwitchToMode(display, (CFDictionaryRef) mode);
-    }
-    #endif
-
-    return kCGErrorFailure;
-}
-
 int
 Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
 {
@@ -462,7 +372,7 @@ Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
 
     if (data == display->desktop_mode.driverdata) {
         /* Restoring desktop mode */
-        Cocoa_SwitchMode(_this, displaydata->display, data->moderef);
+        CGDisplaySetDisplayMode(displaydata->display, data->moderef, NULL);
 
         if (CGDisplayIsMain(displaydata->display)) {
             CGReleaseAllDisplays();
@@ -487,7 +397,7 @@ Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
         }
 
         /* Do the physical switch */
-        result = Cocoa_SwitchMode(_this, displaydata->display, data->moderef);
+        result = CGDisplaySetDisplayMode(displaydata->display, data->moderef, NULL);
         if (result != kCGErrorSuccess) {
             CG_SetError("CGDisplaySwitchToMode()", result);
             goto ERR_NO_SWITCH;
@@ -532,11 +442,11 @@ Cocoa_QuitModes(_THIS)
         }
 
         mode = (SDL_DisplayModeData *) display->desktop_mode.driverdata;
-        Cocoa_ReleaseDisplayMode(_this, mode->moderef);
+        CGDisplayModeRelease(mode->moderef);
 
         for (j = 0; j < display->num_display_modes; j++) {
             mode = (SDL_DisplayModeData*) display->display_modes[j].driverdata;
-            Cocoa_ReleaseDisplayMode(_this, mode->moderef);
+            CGDisplayModeRelease(mode->moderef);
         }
 
     }

+ 10 - 8
modules/sdl2/SDL/src/video/cocoa/SDL_cocoamouse.m

@@ -226,13 +226,15 @@ Cocoa_WarpMouseGlobal(int x, int y)
 
     Cocoa_HandleMouseWarp(point.x, point.y);
 
-    /* According to the docs, this was deprecated in 10.6, but it's still
-     * around. The substitute requires a CGEventSource, but I'm not entirely
-     * sure how we'd procure the right one for this event.
-     */
-    CGSetLocalEventsSuppressionInterval(0.0);
     CGWarpMouseCursorPosition(point);
-    CGSetLocalEventsSuppressionInterval(0.25);
+
+    /* CGWarpMouse causes a short delay by default, which is preventable by
+     * Calling this directly after. CGSetLocalEventsSuppressionInterval can also
+     * prevent it, but it's deprecated as of OS X 10.6.
+     */
+    if (!mouse->relative_mode) {
+        CGAssociateMouseAndMouseCursorPosition(YES);
+    }
 
     /* CGWarpMouseCursorPosition doesn't generate a window event, unlike our
      * other implementations' APIs. Send what's appropriate.
@@ -314,7 +316,7 @@ Cocoa_GetGlobalMouseState(int *x, int *y)
 
     for (NSScreen *screen in [NSScreen screens]) {
         NSRect frame = [screen frame];
-        if (NSPointInRect(cocoaLocation, frame)) {
+        if (NSMouseInRect(cocoaLocation, frame, NO)) {
             *x = (int) cocoaLocation.x;
             *y = (int) ((frame.origin.y + frame.size.height) - cocoaLocation.y);
             break;
@@ -396,7 +398,7 @@ Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
     /* Ignore events that aren't inside the client area (i.e. title bar.) */
     if ([event window]) {
         NSRect windowRect = [[[event window] contentView] frame];
-        if (!NSPointInRect([event locationInWindow], windowRect)) {
+        if (!NSMouseInRect([event locationInWindow], windowRect, NO)) {
             return;
         }
     }

+ 7 - 8
modules/sdl2/SDL/src/video/cocoa/SDL_cocoamousetap.m

@@ -32,8 +32,8 @@
 #if SDL_MAC_NO_SANDBOX
 
 #include "SDL_keyboard.h"
-#include "SDL_thread.h"
 #include "SDL_cocoavideo.h"
+#include "../../thread/SDL_systhread.h"
 
 #include "../../events/SDL_mouse_c.h"
 
@@ -96,7 +96,7 @@ Cocoa_MouseTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event
     eventLocation = CGEventGetUnflippedLocation(event);
     windowRect = [nswindow contentRectForFrameRect:[nswindow frame]];
 
-    if (!NSPointInRect(NSPointFromCGPoint(eventLocation), windowRect)) {
+    if (!NSMouseInRect(NSPointFromCGPoint(eventLocation), windowRect, NO)) {
 
         /* This is in CGs global screenspace coordinate system, which has a
          * flipped Y.
@@ -109,15 +109,14 @@ Cocoa_MouseTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event
             newLocation.x = NSMaxX(windowRect) - 1.0;
         }
 
-        if (eventLocation.y < NSMinY(windowRect)) {
+        if (eventLocation.y <= NSMinY(windowRect)) {
             newLocation.y -= (NSMinY(windowRect) - eventLocation.y + 1);
-        } else if (eventLocation.y >= NSMaxY(windowRect)) {
-            newLocation.y += (eventLocation.y - NSMaxY(windowRect) + 1);
+        } else if (eventLocation.y > NSMaxY(windowRect)) {
+            newLocation.y += (eventLocation.y - NSMaxY(windowRect));
         }
 
-        CGSetLocalEventsSuppressionInterval(0);
         CGWarpMouseCursorPosition(newLocation);
-        CGSetLocalEventsSuppressionInterval(0.25);
+        CGAssociateMouseAndMouseCursorPosition(YES);
 
         if ((CGEventMaskBit(type) & movementEventsMask) == 0) {
             /* For click events, we just constrain the event to the window, so
@@ -203,7 +202,7 @@ Cocoa_InitMouseEventTap(SDL_MouseData* driverdata)
 
     tapdata->runloopStartedSemaphore = SDL_CreateSemaphore(0);
     if (tapdata->runloopStartedSemaphore) {
-        tapdata->thread = SDL_CreateThread(&Cocoa_MouseTapThread, "Event Tap Loop", tapdata);
+        tapdata->thread = SDL_CreateThreadInternal(&Cocoa_MouseTapThread, "Event Tap Loop", 512 * 1024, tapdata);
         if (!tapdata->thread) {
             SDL_DestroySemaphore(tapdata->runloopStartedSemaphore);
         }

+ 1 - 3
modules/sdl2/SDL/src/video/cocoa/SDL_cocoashape.m

@@ -35,9 +35,7 @@ Cocoa_CreateShaper(SDL_Window* window)
     SDL_WindowData* windata = (SDL_WindowData*)window->driverdata;
     [windata->nswindow setOpaque:NO];
 
-    if ([windata->nswindow respondsToSelector:@selector(setStyleMask:)]) {
-        [windata->nswindow setStyleMask:NSBorderlessWindowMask];
-    }
+    [windata->nswindow setStyleMask:NSBorderlessWindowMask];
 
     SDL_WindowShaper* result = result = malloc(sizeof(SDL_WindowShaper));
     result->window = window;

+ 35 - 81
modules/sdl2/SDL/src/video/cocoa/SDL_cocoawindow.m

@@ -80,20 +80,20 @@
 
 - (void)sendEvent:(NSEvent *)event
 {
-  [super sendEvent:event];
+    [super sendEvent:event];
 
-  if ([event type] != NSLeftMouseUp) {
-      return;
-  }
+    if ([event type] != NSLeftMouseUp) {
+        return;
+    }
 
-  id delegate = [self delegate];
-  if (![delegate isKindOfClass:[Cocoa_WindowListener class]]) {
-      return;
-  }
+    id delegate = [self delegate];
+    if (![delegate isKindOfClass:[Cocoa_WindowListener class]]) {
+        return;
+    }
 
-  if ([delegate isMoving]) {
-      [delegate windowDidFinishMoving];
-  }
+    if ([delegate isMoving]) {
+        [delegate windowDidFinishMoving];
+    }
 }
 
 /* We'll respond to selectors by doing nothing so we don't beep.
@@ -138,10 +138,7 @@
         NSURL *fileURL = [[NSURL fileURLWithPath:path] autorelease];
         NSNumber *isAlias = nil;
 
-        /* Functionality for resolving URL aliases was added with OS X 10.6. */
-        if ([fileURL respondsToSelector:@selector(getResourceValue:forKey:error:)]) {
-            [fileURL getResourceValue:&isAlias forKey:NSURLIsAliasFileKey error:nil];
-        }
+        [fileURL getResourceValue:&isAlias forKey:NSURLIsAliasFileKey error:nil];
 
         /* If the URL is an alias, resolve it. */
         if ([isAlias boolValue]) {
@@ -218,10 +215,10 @@ GetHintCtrlClickEmulateRightClick()
 	return hint != NULL && *hint != '0';
 }
 
-static unsigned int
+static NSUInteger
 GetWindowStyle(SDL_Window * window)
 {
-    unsigned int style;
+    NSUInteger style = 0;
 
     if (window->flags & SDL_WINDOW_FULLSCREEN) {
         style = NSBorderlessWindowMask;
@@ -239,21 +236,17 @@ GetWindowStyle(SDL_Window * window)
 }
 
 static SDL_bool
-SetWindowStyle(SDL_Window * window, unsigned int style)
+SetWindowStyle(SDL_Window * window, NSUInteger style)
 {
     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
     NSWindow *nswindow = data->nswindow;
 
-    if (![nswindow respondsToSelector: @selector(setStyleMask:)]) {
-        return SDL_FALSE;
-    }
-
     /* The view responder chain gets messed with during setStyleMask */
     if ([[nswindow contentView] nextResponder] == data->listener) {
         [[nswindow contentView] setNextResponder:nil];
     }
 
-    [nswindow performSelector: @selector(setStyleMask:) withObject: (id)(uintptr_t)style];
+    [nswindow setStyleMask:style];
 
     /* The view responder chain gets messed with during setStyleMask */
     if ([[nswindow contentView] nextResponder] != data->listener) {
@@ -317,9 +310,7 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
 
     [view setNextResponder:self];
 
-    if ([view respondsToSelector:@selector(setAcceptsTouchEvents:)]) {
-        [view setAcceptsTouchEvents:YES];
-    }
+    [view setAcceptsTouchEvents:YES];
 }
 
 - (void)observeValueForKeyPath:(NSString *)keyPath
@@ -604,12 +595,9 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
         [NSMenu setMenuBarVisible:NO];
     }
 
-    /* On pre-10.6, you might have the capslock key state wrong now because we can't check here. */
-    if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_6) {
-        const unsigned int newflags = [NSEvent modifierFlags] & NSAlphaShiftKeyMask;
-        _data->videodata->modifierFlags = (_data->videodata->modifierFlags & ~NSAlphaShiftKeyMask) | newflags;
-        SDL_ToggleModState(KMOD_CAPS, newflags != 0);
-    }
+    const unsigned int newflags = [NSEvent modifierFlags] & NSAlphaShiftKeyMask;
+    _data->videodata->modifierFlags = (_data->videodata->modifierFlags & ~NSAlphaShiftKeyMask) | newflags;
+    SDL_ToggleModState(KMOD_CAPS, newflags != 0);
 }
 
 - (void)windowDidResignKey:(NSNotification *)aNotification
@@ -839,14 +827,7 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
     /* Ignore events that aren't inside the client area (i.e. title bar.) */
     if ([theEvent window]) {
         NSRect windowRect = [[[theEvent window] contentView] frame];
-
-        /* add one to size, since NSPointInRect is exclusive of the bottom
-           edges, which mean it misses the top of the window by one pixel
-           (as the origin is the bottom left). */
-        windowRect.size.width += 1;
-        windowRect.size.height += 1;
-
-        if (!NSPointInRect([theEvent locationInWindow], windowRect)) {
+        if (!NSMouseInRect([theEvent locationInWindow], windowRect, NO)) {
             return;
         }
     }
@@ -974,13 +955,8 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
             cgpoint.x = window->x + x;
             cgpoint.y = window->y + y;
 
-            /* According to the docs, this was deprecated in 10.6, but it's still
-             * around. The substitute requires a CGEventSource, but I'm not entirely
-             * sure how we'd procure the right one for this event.
-             */
-            CGSetLocalEventsSuppressionInterval(0.0);
             CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
-            CGSetLocalEventsSuppressionInterval(0.25);
+            CGAssociateMouseAndMouseCursorPosition(YES);
 
             Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
 #endif
@@ -1093,6 +1069,7 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
 - (void)rightMouseDown:(NSEvent *)theEvent;
 - (BOOL)mouseDownCanMoveWindow;
 - (void)drawRect:(NSRect)dirtyRect;
+- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent;
 @end
 
 @implementation SDLView
@@ -1132,6 +1109,12 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
                      cursor:[NSCursor invisibleCursor]];
     }
 }
+
+- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
+{
+    const char *hint = SDL_GetHint(SDL_HINT_MAC_MOUSE_FOCUS_CLICKTHROUGH);
+    return hint && *hint != '0';
+}
 @end
 
 static int
@@ -1488,27 +1471,6 @@ Cocoa_RestoreWindow(_THIS, SDL_Window * window)
     }
 }}
 
-static NSWindow *
-Cocoa_RebuildWindow(SDL_WindowData * data, NSWindow * nswindow, unsigned style)
-{
-    if (!data->created) {
-        /* Don't mess with other people's windows... */
-        return nswindow;
-    }
-
-    [data->listener close];
-    data->nswindow = [[SDLWindow alloc] initWithContentRect:[[nswindow contentView] frame] styleMask:style backing:NSBackingStoreBuffered defer:NO screen:[nswindow screen]];
-    [data->nswindow setContentView:[nswindow contentView]];
-    [data->nswindow registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]];
-    /* See comment in SetupWindowData. */
-    [data->nswindow setOneShot:NO];
-    [data->listener listen:data];
-
-    [nswindow close];
-
-    return data->nswindow;
-}
-
 void
 Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
 { @autoreleasepool
@@ -1550,11 +1512,7 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
             rect.origin.y += (screenRect.size.height - rect.size.height);
         }
 
-        if ([nswindow respondsToSelector: @selector(setStyleMask:)]) {
-            [nswindow performSelector: @selector(setStyleMask:) withObject: (id)NSBorderlessWindowMask];
-        } else {
-            nswindow = Cocoa_RebuildWindow(data, nswindow, NSBorderlessWindowMask);
-        }
+        [nswindow setStyleMask:NSBorderlessWindowMask];
     } else {
         rect.origin.x = window->windowed.x;
         rect.origin.y = window->windowed.y;
@@ -1562,16 +1520,12 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
         rect.size.height = window->windowed.h;
         ConvertNSRect([nswindow screen], fullscreen, &rect);
 
-        if ([nswindow respondsToSelector: @selector(setStyleMask:)]) {
-            [nswindow performSelector: @selector(setStyleMask:) withObject: (id)(uintptr_t)GetWindowStyle(window)];
+        [nswindow setStyleMask:GetWindowStyle(window)];
 
-            /* Hack to restore window decorations on Mac OS X 10.10 */
-            NSRect frameRect = [nswindow frame];
-            [nswindow setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO];
-            [nswindow setFrame:frameRect display:NO];
-        } else {
-            nswindow = Cocoa_RebuildWindow(data, nswindow, GetWindowStyle(window));
-        }
+        /* Hack to restore window decorations on Mac OS X 10.10 */
+        NSRect frameRect = [nswindow frame];
+        [nswindow setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO];
+        [nswindow setFrame:frameRect display:NO];
     }
 
     /* The view responder chain gets messed with during setStyleMask */

+ 4 - 0
modules/sdl2/SDL/src/video/emscripten/SDL_emscriptenmouse.c

@@ -58,11 +58,13 @@ Emscripten_CreateDefaultCursor()
     return cursor;
 }
 
+/*
 static SDL_Cursor*
 Emscripten_CreateCursor(SDL_Surface* sruface, int hot_x, int hot_y)
 {
     return Emscripten_CreateDefaultCursor();
 }
+*/
 
 static SDL_Cursor*
 Emscripten_CreateSystemCursor(SDL_SystemCursor id)
@@ -200,7 +202,9 @@ Emscripten_InitMouse()
 {
     SDL_Mouse* mouse = SDL_GetMouse();
 
+/*
     mouse->CreateCursor         = Emscripten_CreateCursor;
+*/ 
     mouse->ShowCursor           = Emscripten_ShowCursor;
     mouse->FreeCursor           = Emscripten_FreeCursor;
     mouse->WarpMouse            = Emscripten_WarpMouse;

+ 4 - 11
modules/sdl2/SDL/src/video/mir/SDL_mirdyn.c

@@ -84,9 +84,8 @@ MIR_GetSym(const char *fnname, int *pHasModule)
 /* Define all the function pointers and wrappers... */
 #define SDL_MIR_MODULE(modname) int SDL_MIR_HAVE_##modname = 0;
 #define SDL_MIR_SYM(rc,fn,params) SDL_DYNMIRFN_##fn MIR_##fn = NULL;
+#define SDL_MIR_SYM_CONST(type,name) SDL_DYMMIRCONST_##name MIR_##name = NULL;
 #include "SDL_mirsym.h"
-#undef SDL_MIR_MODULE
-#undef SDL_MIR_SYM
 
 static int mir_load_refcount = 0;
 
@@ -103,9 +102,8 @@ SDL_MIR_UnloadSymbols(void)
             /* set all the function pointers to NULL. */
 #define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 0;
 #define SDL_MIR_SYM(rc,fn,params) MIR_##fn = NULL;
+#define SDL_MIR_SYM_CONST(type,name) MIR_##name = NULL;
 #include "SDL_mirsym.h"
-#undef SDL_MIR_MODULE
-#undef SDL_MIR_SYM
 
 
 #ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC
@@ -138,16 +136,12 @@ SDL_MIR_LoadSymbols(void)
         }
 
 #define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 1; /* default yes */
-#define SDL_MIR_SYM(rc,fn,params)
 #include "SDL_mirsym.h"
-#undef SDL_MIR_MODULE
-#undef SDL_MIR_SYM
 
 #define SDL_MIR_MODULE(modname) thismod = &SDL_MIR_HAVE_##modname;
 #define SDL_MIR_SYM(rc,fn,params) MIR_##fn = (SDL_DYNMIRFN_##fn) MIR_GetSym(#fn,thismod);
+#define SDL_MIR_SYM_CONST(type,name) MIR_##name = *(SDL_DYMMIRCONST_##name*) MIR_GetSym(#name,thismod);
 #include "SDL_mirsym.h"
-#undef SDL_MIR_MODULE
-#undef SDL_MIR_SYM
 
         if ((SDL_MIR_HAVE_MIR_CLIENT) && (SDL_MIR_HAVE_XKBCOMMON)) {
             /* all required symbols loaded. */
@@ -162,9 +156,8 @@ SDL_MIR_LoadSymbols(void)
 
 #define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 1; /* default yes */
 #define SDL_MIR_SYM(rc,fn,params) MIR_##fn = fn;
+#define SDL_MIR_SYM_CONST(type,name) MIR_##name = name;
 #include "SDL_mirsym.h"
-#undef SDL_MIR_MODULE
-#undef SDL_MIR_SYM
 
 #endif
     }

+ 3 - 3
modules/sdl2/SDL/src/video/mir/SDL_mirdyn.h

@@ -36,13 +36,13 @@ int SDL_MIR_LoadSymbols(void);
 void SDL_MIR_UnloadSymbols(void);
 
 /* Declare all the function pointers and wrappers... */
-#define SDL_MIR_MODULE(modname)
 #define SDL_MIR_SYM(rc,fn,params) \
     typedef rc (*SDL_DYNMIRFN_##fn) params; \
     extern SDL_DYNMIRFN_##fn MIR_##fn;
+#define SDL_MIR_SYM_CONST(type, name) \
+    typedef type SDL_DYMMIRCONST_##name; \
+    extern SDL_DYMMIRCONST_##name MIR_##name;
 #include "SDL_mirsym.h"
-#undef SDL_MIR_MODULE
-#undef SDL_MIR_SYM
 
 #ifdef __cplusplus
 }

+ 127 - 87
modules/sdl2/SDL/src/video/mir/SDL_mirevents.c

@@ -58,7 +58,7 @@ CheckKeyboardFocus(SDL_Window* sdl_window)
 {
     SDL_Window* keyboard_window = SDL_GetKeyboardFocus();
 
-    if (keyboard_window != sdl_window)
+    if (sdl_window && keyboard_window != sdl_window)
         SDL_SetKeyboardFocus(sdl_window);
 }
 
@@ -68,51 +68,68 @@ CheckKeyboardFocus(SDL_Window* sdl_window)
    a single key press produces a character.
 */
 static void
-HandleKeyEvent(MirKeyEvent const ev, SDL_Window* window)
+HandleKeyEvent(MirKeyboardEvent const* key_event, SDL_Window* window)
 {
-    uint32_t scancode = SDL_SCANCODE_UNKNOWN;
-    Uint8 key_state = ev.action == mir_key_action_up ? SDL_RELEASED : SDL_PRESSED;
+    xkb_keysym_t key_code;
+    Uint8 key_state;
+    int event_scancode;
+    uint32_t sdl_scancode = SDL_SCANCODE_UNKNOWN;
+
+    MirKeyboardAction action = MIR_mir_keyboard_event_action(key_event);
+
+    key_state      = SDL_PRESSED;
+    key_code       = MIR_mir_keyboard_event_key_code(key_event);
+    event_scancode = MIR_mir_keyboard_event_scan_code(key_event);
+
+    if (action == mir_keyboard_action_up)
+        key_state = SDL_RELEASED;
 
     CheckKeyboardFocus(window);
 
-    if (ev.scan_code < SDL_arraysize(xfree86_scancode_table2))
-        scancode = xfree86_scancode_table2[ev.scan_code];
+    if (event_scancode < SDL_arraysize(xfree86_scancode_table2))
+        sdl_scancode = xfree86_scancode_table2[event_scancode];
 
-    if (scancode != SDL_SCANCODE_UNKNOWN)
-        SDL_SendKeyboardKey(key_state, scancode);
+    if (sdl_scancode != SDL_SCANCODE_UNKNOWN)
+        SDL_SendKeyboardKey(key_state, sdl_scancode);
 
     if (key_state == SDL_PRESSED)
-        HandleKeyText(ev.key_code);
+        HandleKeyText(key_code);
 }
 
 static void
-HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirMotionButton button_state)
+HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirPointerEvent const* pointer)
 {
-    static uint32_t last_sdl_button;
-    uint32_t sdl_button;
+    uint32_t sdl_button           = SDL_BUTTON_LEFT;
+    MirPointerButton button_state = mir_pointer_button_primary;
+
+    static uint32_t old_button_states = 0;
+    uint32_t new_button_states = MIR_mir_pointer_event_buttons(pointer);
+
+    // XOR on our old button states vs our new states to get the newley pressed/released button
+    button_state = new_button_states ^ old_button_states;
 
     switch (button_state) {
-        case mir_motion_button_primary:
+        case mir_pointer_button_primary:
             sdl_button = SDL_BUTTON_LEFT;
             break;
-        case mir_motion_button_secondary:
+        case mir_pointer_button_secondary:
             sdl_button = SDL_BUTTON_RIGHT;
             break;
-        case mir_motion_button_tertiary:
+        case mir_pointer_button_tertiary:
             sdl_button = SDL_BUTTON_MIDDLE;
             break;
-        case mir_motion_button_forward:
+        case mir_pointer_button_forward:
             sdl_button = SDL_BUTTON_X1;
             break;
-        case mir_motion_button_back:
+        case mir_pointer_button_back:
             sdl_button = SDL_BUTTON_X2;
             break;
         default:
-            sdl_button = last_sdl_button;
             break;
     }
 
-    last_sdl_button = sdl_button;
+    old_button_states = new_button_states;
+
     SDL_SendMouseButton(sdl_window, 0, state, sdl_button);
 }
 
@@ -148,71 +165,91 @@ AddTouchDevice(int device_id)
 }
 
 static void
-HandleTouchEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_window)
+HandleTouchEvent(MirTouchEvent const* touch, int device_id, SDL_Window* sdl_window)
 {
-    int device_id = motion.device_id;
-    int id = motion.pointer_coordinates[cord_index].id;
+    int i, point_count;
+    point_count = MIR_mir_touch_event_point_count(touch);
 
-    int width  = sdl_window->w;
-    int height = sdl_window->h;
-    float x   = motion.pointer_coordinates[cord_index].x;
-    float y   = motion.pointer_coordinates[cord_index].y;
+    AddTouchDevice(device_id);
 
-    float n_x = x / width;
-    float n_y = y / height;
-    float pressure = motion.pointer_coordinates[cord_index].pressure;
+    for (i = 0; i < point_count; i++) {
+        int id = MIR_mir_touch_event_id(touch, i);
 
-    AddTouchDevice(motion.device_id);
+        int width  = sdl_window->w;
+        int height = sdl_window->h;
 
-    switch (motion.action) {
-        case mir_motion_action_down:
-        case mir_motion_action_pointer_down:
-            HandleTouchPress(device_id, id, SDL_TRUE, n_x, n_y, pressure);
-            break;
-        case mir_motion_action_up:
-        case mir_motion_action_pointer_up:
-            HandleTouchPress(device_id, id, SDL_FALSE, n_x, n_y, pressure);
-            break;
-        case mir_motion_action_hover_move:
-        case mir_motion_action_move:
-            HandleTouchMotion(device_id, id, n_x, n_y, pressure);
-            break;
-        default:
-            break;
+        float x = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_x);
+        float y = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_y);
+
+        float n_x = x / width;
+        float n_y = y / height;
+
+        float pressure = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_pressure);
+
+        switch (MIR_mir_touch_event_action(touch, i)) {
+            case mir_touch_action_up:
+                HandleTouchPress(device_id, id, SDL_FALSE, n_x, n_y, pressure);
+                break;
+            case mir_touch_action_down:
+                HandleTouchPress(device_id, id, SDL_TRUE, n_x, n_y, pressure);
+                break;
+            case mir_touch_action_change:
+                HandleTouchMotion(device_id, id, n_x, n_y, pressure);
+                break;
+        }
     }
 }
 
 static void
-HandleMouseEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_window)
+HandleMouseEvent(MirPointerEvent const* pointer, SDL_Window* sdl_window)
 {
     SDL_SetMouseFocus(sdl_window);
 
-    switch (motion.action) {
-        case mir_motion_action_down:
-        case mir_motion_action_pointer_down:
-            HandleMouseButton(sdl_window, SDL_PRESSED, motion.button_state);
+    switch (MIR_mir_pointer_event_action(pointer)) {
+        case mir_pointer_action_button_down:
+            HandleMouseButton(sdl_window, SDL_PRESSED, pointer);
             break;
-        case mir_motion_action_up:
-        case mir_motion_action_pointer_up:
-            HandleMouseButton(sdl_window, SDL_RELEASED, motion.button_state);
+        case mir_pointer_action_button_up:
+            HandleMouseButton(sdl_window, SDL_RELEASED, pointer);
             break;
-        case mir_motion_action_hover_move:
-        case mir_motion_action_move:
-            HandleMouseMotion(sdl_window,
-                              motion.pointer_coordinates[cord_index].x,
-                              motion.pointer_coordinates[cord_index].y);
+        case mir_pointer_action_motion: {
+            int x, y;
+            int hscroll, vscroll;
+            SDL_Mouse* mouse = SDL_GetMouse();
+            x = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_x);
+            y = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_y);
+            hscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_hscroll);
+            vscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_vscroll);
+
+            if (mouse && (mouse->x != x || mouse->y != y))
+                HandleMouseMotion(sdl_window, x, y);
+            if (vscroll != 0 || hscroll != 0)
+                HandleMouseScroll(sdl_window, hscroll, vscroll);
+        }
             break;
-        case mir_motion_action_outside:
+        case mir_pointer_action_leave:
             SDL_SetMouseFocus(NULL);
             break;
-        case mir_motion_action_scroll:
-            HandleMouseScroll(sdl_window,
-                              motion.pointer_coordinates[cord_index].hscroll,
-                              motion.pointer_coordinates[cord_index].vscroll);
+        case mir_pointer_action_enter:
+        default:
+            break;
+    }
+}
+
+static void
+MIR_HandleInput(MirInputEvent const* input_event, SDL_Window* window)
+{
+    switch (MIR_mir_input_event_get_type(input_event)) {
+        case (mir_input_event_type_key):
+            HandleKeyEvent(MIR_mir_input_event_get_keyboard_event(input_event), window);
+            break;
+        case (mir_input_event_type_pointer):
+            HandleMouseEvent(MIR_mir_input_event_get_pointer_event(input_event), window);
             break;
-        case mir_motion_action_cancel:
-        case mir_motion_action_hover_enter:
-        case mir_motion_action_hover_exit:
+        case (mir_input_event_type_touch):
+            HandleTouchEvent(MIR_mir_input_event_get_touch_event(input_event),
+                             MIR_mir_input_event_get_device_id(input_event),
+                             window);
             break;
         default:
             break;
@@ -220,32 +257,35 @@ HandleMouseEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_wi
 }
 
 static void
-HandleMotionEvent(MirMotionEvent const motion, SDL_Window* sdl_window)
+MIR_HandleResize(MirResizeEvent const* resize_event, SDL_Window* window)
 {
-    int cord_index;
-    for (cord_index = 0; cord_index < motion.pointer_count; cord_index++) {
-        if (motion.pointer_coordinates[cord_index].tool_type == mir_motion_tool_type_finger) {
-            HandleTouchEvent(motion, cord_index, sdl_window);
-        }
-        else {
-            HandleMouseEvent(motion, cord_index, sdl_window);
-        }
-    }
+    int new_w = MIR_mir_resize_event_get_width (resize_event);
+    int new_h = MIR_mir_resize_event_get_height(resize_event);
+
+    int old_w = window->w;
+    int old_h = window->h;
+
+    if (new_w != old_w || new_h != old_h)
+        SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, new_w, new_h);
 }
 
 void
-MIR_HandleInput(MirSurface* surface, MirEvent const* ev, void* context)
+MIR_HandleEvent(MirSurface* surface, MirEvent const* ev, void* context)
 {
-    SDL_Window* window = (SDL_Window*)context;
-    switch (ev->type) {
-        case (mir_event_type_key):
-            HandleKeyEvent(ev->key, window);
-            break;
-        case (mir_event_type_motion):
-            HandleMotionEvent(ev->motion, window);
-            break;
-        default:
-            break;
+    MirEventType event_type = MIR_mir_event_get_type(ev);
+    SDL_Window* window      = (SDL_Window*)context;
+
+    if (window) {
+        switch (event_type) {
+            case (mir_event_type_input):
+                MIR_HandleInput(MIR_mir_event_get_input_event(ev), window);
+                break;
+            case (mir_event_type_resize):
+                MIR_HandleResize(MIR_mir_event_get_resize_event(ev), window);
+                break;
+            default:
+                break;
+        }
     }
 }
 

+ 1 - 1
modules/sdl2/SDL/src/video/mir/SDL_mirevents.h

@@ -29,7 +29,7 @@
 #include <mir_toolkit/mir_client_library.h>
 
 extern void
-MIR_HandleInput(MirSurface* surface, MirEvent const* ev, void* context);
+MIR_HandleEvent(MirSurface* surface, MirEvent const* ev, void* context);
 
 #endif /* _SDL_mirevents_h */
 

+ 11 - 17
modules/sdl2/SDL/src/video/mir/SDL_mirframebuffer.c

@@ -39,7 +39,11 @@ static const Uint32 mir_pixel_format_to_sdl_format[] = {
     SDL_PIXELFORMAT_BGR888,   /* mir_pixel_format_xbgr_8888 */
     SDL_PIXELFORMAT_ARGB8888, /* mir_pixel_format_argb_8888 */
     SDL_PIXELFORMAT_RGB888,   /* mir_pixel_format_xrgb_8888 */
-    SDL_PIXELFORMAT_BGR24     /* mir_pixel_format_bgr_888   */
+    SDL_PIXELFORMAT_BGR24,    /* mir_pixel_format_bgr_888   */
+    SDL_PIXELFORMAT_RGB24,    /* mir_pixel_format_rgb_888   */
+    SDL_PIXELFORMAT_RGB565,   /* mir_pixel_format_rgb_565   */
+    SDL_PIXELFORMAT_RGBA5551, /* mir_pixel_format_rgba_5551 */
+    SDL_PIXELFORMAT_RGBA4444  /* mir_pixel_format_rgba_4444 */
 };
 
 Uint32
@@ -53,19 +57,13 @@ MIR_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format,
                             void** pixels, int* pitch)
 {
     MIR_Data* mir_data = _this->driverdata;
-    MIR_Window* mir_window;
-    MirSurfaceParameters surfaceparm;
 
     mir_data->software = SDL_TRUE;
 
     if (MIR_CreateWindow(_this, window) < 0)
         return SDL_SetError("Failed to created a mir window.");
 
-    mir_window = window->driverdata;
-
-    MIR_mir_surface_get_parameters(mir_window->surface, &surfaceparm);
-
-    *format = MIR_GetSDLPixelFormat(surfaceparm.pixel_format);
+    *format = MIR_GetSDLPixelFormat(mir_data->pixel_format);
     if (*format == SDL_PIXELFORMAT_UNKNOWN)
         return SDL_SetError("Unknown pixel format");
 
@@ -75,12 +73,6 @@ MIR_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format,
     if (*pixels == NULL)
         return SDL_OutOfMemory();
 
-    mir_window->surface = MIR_mir_connection_create_surface_sync(mir_data->connection, &surfaceparm);
-    if (!MIR_mir_surface_is_valid(mir_window->surface)) {
-        const char* error = MIR_mir_surface_get_error_message(mir_window->surface);
-        return SDL_SetError("Failed to created a mir surface: %s", error);
-    }
-
     return 0;
 }
 
@@ -91,12 +83,14 @@ MIR_UpdateWindowFramebuffer(_THIS, SDL_Window* window,
     MIR_Window* mir_window = window->driverdata;
 
     MirGraphicsRegion region;
+    MirBufferStream* bs;
     int i, j, x, y, w, h, start;
     int bytes_per_pixel, bytes_per_row, s_stride, d_stride;
     char* s_dest;
     char* pixels;
 
-    MIR_mir_surface_get_graphics_region(mir_window->surface, &region);
+    bs = MIR_mir_surface_get_buffer_stream(mir_window->surface);
+    MIR_mir_buffer_stream_get_graphics_region(bs, &region);
 
     s_dest = region.vaddr;
     pixels = (char*)window->surface->pixels;
@@ -138,13 +132,13 @@ MIR_UpdateWindowFramebuffer(_THIS, SDL_Window* window,
 
         bytes_per_row =  bytes_per_pixel * w;
         for (j = 0; j < h; j++) {
-            memcpy(s_dest, pixels, bytes_per_row);
+            SDL_memcpy(s_dest, pixels, bytes_per_row);
             pixels += s_stride;
             s_dest += d_stride;
         }
     }
 
-    MIR_mir_surface_swap_buffers_sync(mir_window->surface);
+    MIR_mir_buffer_stream_swap_buffers_sync(bs);
 
     return 0;
 }

+ 140 - 7
modules/sdl2/SDL/src/video/mir/SDL_mirmouse.c

@@ -27,13 +27,22 @@
 
 #if SDL_VIDEO_DRIVER_MIR
 
-#include "SDL_mirmouse.h"
-
 #include "../../events/SDL_mouse_c.h"
+#include "../SDL_sysvideo.h"
 #include "SDL_assert.h"
 
 #include "SDL_mirdyn.h"
 
+#include "SDL_mirvideo.h"
+#include "SDL_mirmouse.h"
+#include "SDL_mirwindow.h"
+
+typedef struct
+{
+    MirCursorConfiguration* conf;
+    MirBufferStream*        stream;
+} MIR_Cursor;
+
 static SDL_Cursor*
 MIR_CreateDefaultCursor()
 {
@@ -41,6 +50,18 @@ MIR_CreateDefaultCursor()
 
     cursor = SDL_calloc(1, sizeof(SDL_Cursor));
     if (cursor) {
+
+        MIR_Cursor* mir_cursor = SDL_calloc(1, sizeof(MIR_Cursor));
+        if (mir_cursor) {
+            mir_cursor->conf   = NULL;
+            mir_cursor->stream = NULL;
+            cursor->driverdata = mir_cursor;
+        }
+        else {
+            SDL_OutOfMemory();
+            SDL_free(cursor);
+            cursor = NULL;
+        }
     }
     else {
         SDL_OutOfMemory();
@@ -49,58 +70,170 @@ MIR_CreateDefaultCursor()
     return cursor;
 }
 
+static void
+CopySurfacePixelsToMirStream(SDL_Surface* surface, MirBufferStream* stream)
+{
+    char* dest, *pixels;
+    int i, s_w, s_h, r_stride, p_stride, bytes_per_pixel, bytes_per_row;
+
+    MirGraphicsRegion region;
+    MIR_mir_buffer_stream_get_graphics_region(stream, &region);
+
+    s_w = surface->w;
+    s_h = surface->h;
+
+    bytes_per_pixel = surface->format->BytesPerPixel;
+    bytes_per_row   = bytes_per_pixel * s_w;
+
+    dest = region.vaddr;
+    pixels = (char*)surface->pixels;
+
+    r_stride = region.stride;
+    p_stride = surface->pitch;
+
+    for (i = 0; i < s_h; i++)
+    {
+        SDL_memcpy(dest, pixels, bytes_per_row);
+        dest   += r_stride;
+        pixels += p_stride;
+    }
+}
+
 static SDL_Cursor*
-MIR_CreateCursor(SDL_Surface* sruface, int hot_x, int hot_y)
+MIR_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
 {
-    return MIR_CreateDefaultCursor();
+    MirCursorConfiguration* conf;
+    MirBufferStream*        stream;
+
+    int s_w = surface->w;
+    int s_h = surface->h;
+
+    MIR_Data* mir_data     = (MIR_Data*)SDL_GetVideoDevice()->driverdata;
+    SDL_Cursor* cursor     = MIR_CreateDefaultCursor();
+    MIR_Cursor* mir_cursor;
+
+    if (!cursor) {
+        return NULL;
+    }
+
+    mir_cursor = (MIR_Cursor*)cursor->driverdata;
+
+    stream = MIR_mir_connection_create_buffer_stream_sync(mir_data->connection,
+                                                          s_w, s_h, mir_data->pixel_format,
+                                                          mir_buffer_usage_software);
+
+    conf = MIR_mir_cursor_configuration_from_buffer_stream(stream, hot_x, hot_y);
+
+    CopySurfacePixelsToMirStream(surface, stream);
+    MIR_mir_buffer_stream_swap_buffers_sync(stream);
+
+    mir_cursor->conf   = conf;
+    mir_cursor->stream = stream;
+
+    return cursor;
 }
 
 static SDL_Cursor*
 MIR_CreateSystemCursor(SDL_SystemCursor id)
 {
+    char const* cursor_name = NULL;
+    MirCursorConfiguration* conf;
+    SDL_Cursor* cursor = MIR_CreateDefaultCursor();
+
+    if (!cursor) {
+        return NULL;
+    }
+
     switch(id) {
         case SDL_SYSTEM_CURSOR_ARROW:
+            cursor_name = MIR_mir_arrow_cursor_name;
             break;
         case SDL_SYSTEM_CURSOR_IBEAM:
+            cursor_name = MIR_mir_caret_cursor_name;
             break;
         case SDL_SYSTEM_CURSOR_WAIT:
+            cursor_name = MIR_mir_busy_cursor_name;
             break;
         case SDL_SYSTEM_CURSOR_CROSSHAIR:
+            /* Unsupported */
+            cursor_name = MIR_mir_arrow_cursor_name;
             break;
         case SDL_SYSTEM_CURSOR_WAITARROW:
+            cursor_name = MIR_mir_busy_cursor_name;
             break;
         case SDL_SYSTEM_CURSOR_SIZENWSE:
+            cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
             break;
         case SDL_SYSTEM_CURSOR_SIZENESW:
+            cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
             break;
         case SDL_SYSTEM_CURSOR_SIZEWE:
+            cursor_name = MIR_mir_horizontal_resize_cursor_name;
             break;
         case SDL_SYSTEM_CURSOR_SIZENS:
+            cursor_name = MIR_mir_vertical_resize_cursor_name;
             break;
         case SDL_SYSTEM_CURSOR_SIZEALL:
+            cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
             break;
         case SDL_SYSTEM_CURSOR_NO:
+            /* Unsupported */
+            cursor_name = MIR_mir_closed_hand_cursor_name;
             break;
         case SDL_SYSTEM_CURSOR_HAND:
+            cursor_name = MIR_mir_open_hand_cursor_name;
             break;
         default:
             SDL_assert(0);
             return NULL;
     }
 
-    return MIR_CreateDefaultCursor();
+    conf = MIR_mir_cursor_configuration_from_name(cursor_name);
+
+    cursor->driverdata = conf;
+
+    return cursor;
 }
 
 static void
 MIR_FreeCursor(SDL_Cursor* cursor)
 {
-    if (cursor)
-      SDL_free(cursor);
+    if (cursor) {
+
+        if (cursor->driverdata) {
+            MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
+
+            if (mir_cursor->conf)
+                MIR_mir_cursor_configuration_destroy(mir_cursor->conf);
+            if (mir_cursor->stream)
+                MIR_mir_buffer_stream_release_sync(mir_cursor->stream);
+
+            SDL_free(mir_cursor);
+        }
+
+        SDL_free(cursor);
+    }
 }
 
 static int
 MIR_ShowCursor(SDL_Cursor* cursor)
 {
+    MIR_Data* mir_data      = (MIR_Data*)SDL_GetVideoDevice()->driverdata;
+    MIR_Window* mir_window  = mir_data->current_window;
+
+    if (cursor && cursor->driverdata) {
+        if (mir_window && MIR_mir_surface_is_valid(mir_window->surface)) {
+            MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
+
+            if (mir_cursor->conf) {
+                MIR_mir_wait_for(MIR_mir_surface_configure_cursor(mir_window->surface, mir_cursor->conf));
+            }
+        }
+    }
+    else if(mir_window && MIR_mir_surface_is_valid(mir_window->surface)) {
+        MIR_mir_wait_for(MIR_mir_surface_configure_cursor(mir_window->surface, NULL));
+    }
+    
     return 0;
 }
 

+ 77 - 10
modules/sdl2/SDL/src/video/mir/SDL_mirsym.h

@@ -21,29 +21,96 @@
 
 /* *INDENT-OFF* */
 
+#ifndef SDL_MIR_MODULE
+#define SDL_MIR_MODULE(modname)
+#endif
+
+#ifndef SDL_MIR_SYM
+#define SDL_MIR_SYM(rc,fn,params)
+#endif
+
+#ifndef SDL_MIR_SYM_CONST
+#define SDL_MIR_SYM_CONST(type, name)
+#endif
+
 SDL_MIR_MODULE(MIR_CLIENT)
 SDL_MIR_SYM(MirDisplayConfiguration*,mir_connection_create_display_config,(MirConnection *connection))
-SDL_MIR_SYM(MirSurface *,mir_connection_create_surface_sync,(MirConnection *connection, MirSurfaceParameters const *params))
+SDL_MIR_SYM(MirSurface *,mir_surface_create_sync,(MirSurfaceSpec* spec))
+SDL_MIR_SYM(MirEGLNativeWindowType,mir_buffer_stream_get_egl_native_window,(MirBufferStream *surface))
+SDL_MIR_SYM(void,mir_buffer_stream_get_graphics_region,(MirBufferStream *stream, MirGraphicsRegion *graphics_region))
+SDL_MIR_SYM(void,mir_buffer_stream_swap_buffers_sync,(MirBufferStream *stream))
+SDL_MIR_SYM(void,mir_surface_set_event_handler,(MirSurface *surface, mir_surface_event_callback callback, void* context))
+SDL_MIR_SYM(MirSurfaceSpec*,mir_connection_create_spec_for_normal_surface,(MirConnection *connection, int width, int height, MirPixelFormat format))
+SDL_MIR_SYM(MirSurfaceSpec*,mir_connection_create_spec_for_changes,(MirConnection *connection))
+SDL_MIR_SYM(void,mir_surface_spec_set_buffer_usage,(MirSurfaceSpec *spec, MirBufferUsage usage))
+SDL_MIR_SYM(void,mir_surface_spec_set_name,(MirSurfaceSpec *spec, char const *name))
+SDL_MIR_SYM(void,mir_surface_spec_release,(MirSurfaceSpec *spec))
+SDL_MIR_SYM(void,mir_surface_spec_set_width,(MirSurfaceSpec *spec, unsigned width))
+SDL_MIR_SYM(void,mir_surface_spec_set_height,(MirSurfaceSpec *spec, unsigned height))
+SDL_MIR_SYM(void,mir_surface_spec_set_min_width,(MirSurfaceSpec *spec, unsigned min_width))
+SDL_MIR_SYM(void,mir_surface_spec_set_min_height,(MirSurfaceSpec *spec, unsigned min_height))
+SDL_MIR_SYM(void,mir_surface_spec_set_max_width,(MirSurfaceSpec *spec, unsigned max_width))
+SDL_MIR_SYM(void,mir_surface_spec_set_max_height,(MirSurfaceSpec *spec, unsigned max_height))
+SDL_MIR_SYM(void,mir_surface_spec_set_type,(MirSurfaceSpec *spec, MirSurfaceType type))
+SDL_MIR_SYM(void,mir_surface_spec_set_state,(MirSurfaceSpec *spec, MirSurfaceState state))
+SDL_MIR_SYM(void,mir_surface_apply_spec,(MirSurface *surface, MirSurfaceSpec *spec))
+SDL_MIR_SYM(void,mir_surface_get_parameters,(MirSurface *surface, MirSurfaceParameters *params))
+SDL_MIR_SYM(MirBufferStream*,mir_surface_get_buffer_stream,(MirSurface *surface))
+SDL_MIR_SYM(MirCursorConfiguration*,mir_cursor_configuration_from_buffer_stream,(MirBufferStream* stream, int hot_x, int hot_y))
+SDL_MIR_SYM(MirBufferStream*,mir_connection_create_buffer_stream_sync,(MirConnection *connection, int w, int h, MirPixelFormat format, MirBufferUsage usage))
+SDL_MIR_SYM(MirKeyboardAction,mir_keyboard_event_action,(MirKeyboardEvent const *event))
+SDL_MIR_SYM(xkb_keysym_t,mir_keyboard_event_key_code,(MirKeyboardEvent const *event))
+SDL_MIR_SYM(int,mir_keyboard_event_scan_code,(MirKeyboardEvent const *event))
+SDL_MIR_SYM(bool,mir_pointer_event_button_state,(MirPointerEvent const *event, MirPointerButton button))
+SDL_MIR_SYM(MirPointerButtons,mir_pointer_event_buttons,(MirPointerEvent const *event))
+SDL_MIR_SYM(MirInputDeviceId,mir_input_event_get_device_id,(MirInputEvent const* ev))
+SDL_MIR_SYM(MirTouchId,mir_touch_event_id,(MirTouchEvent const *event, size_t touch_index))
+SDL_MIR_SYM(float,mir_touch_event_axis_value,(MirTouchEvent const *event, size_t touch_index, MirTouchAxis axis))
+SDL_MIR_SYM(MirTouchAction,mir_touch_event_action,(MirTouchEvent const *event, size_t touch_index))
+SDL_MIR_SYM(MirPointerAction,mir_pointer_event_action,(MirPointerEvent const *event))
+SDL_MIR_SYM(float,mir_pointer_event_axis_value,(MirPointerEvent const *event, MirPointerAxis))
+SDL_MIR_SYM(MirEventType,mir_event_get_type,(MirEvent const *event))
+SDL_MIR_SYM(MirInputEventType,mir_input_event_get_type,(MirInputEvent const *event))
+SDL_MIR_SYM(MirInputEvent const*,mir_event_get_input_event,(MirEvent const *event))
+SDL_MIR_SYM(MirResizeEvent const*,mir_event_get_resize_event,(MirEvent const *event))
+SDL_MIR_SYM(MirKeyboardEvent const*,mir_input_event_get_keyboard_event,(MirInputEvent const *event))
+SDL_MIR_SYM(MirPointerEvent const*,mir_input_event_get_pointer_event,(MirInputEvent const *event))
+SDL_MIR_SYM(MirTouchEvent const*,mir_input_event_get_touch_event,(MirInputEvent const *event))
+SDL_MIR_SYM(unsigned int,mir_touch_event_point_count,(MirTouchEvent const *event))
 SDL_MIR_SYM(void,mir_connection_get_available_surface_formats,(MirConnection* connection, MirPixelFormat* formats, unsigned const int format_size, unsigned int *num_valid_formats))
 SDL_MIR_SYM(MirEGLNativeDisplayType,mir_connection_get_egl_native_display,(MirConnection *connection))
-SDL_MIR_SYM(MirBool,mir_connection_is_valid,(MirConnection *connection))
+SDL_MIR_SYM(bool,mir_connection_is_valid,(MirConnection *connection))
 SDL_MIR_SYM(void,mir_connection_release,(MirConnection *connection))
+SDL_MIR_SYM(MirPixelFormat,mir_connection_get_egl_pixel_format,(MirConnection* connection, void* egldisplay, void* eglconfig))
 SDL_MIR_SYM(MirConnection *,mir_connect_sync,(char const *server, char const *app_name))
 SDL_MIR_SYM(void,mir_display_config_destroy,(MirDisplayConfiguration* display_configuration))
-SDL_MIR_SYM(MirEGLNativeWindowType,mir_surface_get_egl_native_window,(MirSurface *surface))
 SDL_MIR_SYM(char const *,mir_surface_get_error_message,(MirSurface *surface))
-SDL_MIR_SYM(void,mir_surface_get_graphics_region,(MirSurface *surface, MirGraphicsRegion *graphics_region))
-SDL_MIR_SYM(void,mir_surface_get_parameters,(MirSurface *surface, MirSurfaceParameters *parameters))
-SDL_MIR_SYM(MirBool,mir_surface_is_valid,(MirSurface *surface))
+SDL_MIR_SYM(bool,mir_surface_is_valid,(MirSurface *surface))
 SDL_MIR_SYM(void,mir_surface_release_sync,(MirSurface *surface))
-SDL_MIR_SYM(void,mir_surface_set_event_handler,(MirSurface *surface, MirEventDelegate const *event_handler))
-SDL_MIR_SYM(MirWaitHandle*,mir_surface_set_type,(MirSurface *surface, MirSurfaceType type))
-SDL_MIR_SYM(MirWaitHandle*,mir_surface_set_state,(MirSurface *surface, MirSurfaceState state))
-SDL_MIR_SYM(void,mir_surface_swap_buffers_sync,(MirSurface *surface))
+SDL_MIR_SYM(void,mir_buffer_stream_release_sync,(MirBufferStream *stream))
+SDL_MIR_SYM(MirCursorConfiguration*,mir_cursor_configuration_from_name,(char const* cursor_name))
+SDL_MIR_SYM(MirWaitHandle*,mir_surface_configure_cursor,(MirSurface* surface, MirCursorConfiguration const* conf))
+SDL_MIR_SYM(void,mir_cursor_configuration_destroy,(MirCursorConfiguration* conf))
+SDL_MIR_SYM(void,mir_wait_for,(MirWaitHandle* handle))
+SDL_MIR_SYM(int,mir_resize_event_get_width,(MirResizeEvent const* resize_event))
+SDL_MIR_SYM(int,mir_resize_event_get_height,(MirResizeEvent const* resize_event))
+
+SDL_MIR_SYM_CONST(char const*,mir_omnidirectional_resize_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_busy_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_arrow_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_caret_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_vertical_resize_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_horizontal_resize_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_open_hand_cursor_name)
+SDL_MIR_SYM_CONST(char const*,mir_closed_hand_cursor_name)
 
 SDL_MIR_MODULE(XKBCOMMON)
 SDL_MIR_SYM(int,xkb_keysym_to_utf8,(xkb_keysym_t keysym, char *buffer, size_t size))
 
+#undef SDL_MIR_MODULE
+#undef SDL_MIR_SYM
+#undef SDL_MIR_SYM_CONST
+
 /* *INDENT-ON* */
 
 /* vi: set ts=4 sw=4 expandtab: */

+ 19 - 17
modules/sdl2/SDL/src/video/mir/SDL_mirvideo.c

@@ -27,13 +27,13 @@
 
 #if SDL_VIDEO_DRIVER_MIR
 
+#include "SDL_mirwindow.h"
 #include "SDL_video.h"
 
 #include "SDL_mirframebuffer.h"
 #include "SDL_mirmouse.h"
 #include "SDL_miropengl.h"
 #include "SDL_mirvideo.h"
-#include "SDL_mirwindow.h"
 
 #include "SDL_mirdyn.h"
 
@@ -146,29 +146,29 @@ MIR_CreateDevice(int device_index)
     device->GL_GetProcAddress  = MIR_GL_GetProcAddress;
 
     /* mirwindow */
-    device->CreateWindow        = MIR_CreateWindow;
-    device->DestroyWindow       = MIR_DestroyWindow;
-    device->GetWindowWMInfo     = MIR_GetWindowWMInfo;
-    device->SetWindowFullscreen = MIR_SetWindowFullscreen;
-    device->MaximizeWindow      = MIR_MaximizeWindow;
-    device->MinimizeWindow      = MIR_MinimizeWindow;
-    device->RestoreWindow       = MIR_RestoreWindow;
+    device->CreateWindow         = MIR_CreateWindow;
+    device->DestroyWindow        = MIR_DestroyWindow;
+    device->GetWindowWMInfo      = MIR_GetWindowWMInfo;
+    device->SetWindowFullscreen  = MIR_SetWindowFullscreen;
+    device->MaximizeWindow       = MIR_MaximizeWindow;
+    device->MinimizeWindow       = MIR_MinimizeWindow;
+    device->RestoreWindow        = MIR_RestoreWindow;
+    device->ShowWindow           = MIR_RestoreWindow;
+    device->HideWindow           = MIR_HideWindow;
+    device->SetWindowSize        = MIR_SetWindowSize;
+    device->SetWindowMinimumSize = MIR_SetWindowMinimumSize;
+    device->SetWindowMaximumSize = MIR_SetWindowMaximumSize;
+    device->SetWindowTitle       = MIR_SetWindowTitle;
 
     device->CreateWindowFrom     = NULL;
-    device->SetWindowTitle       = NULL;
     device->SetWindowIcon        = NULL;
-    device->SetWindowPosition    = NULL;
-    device->SetWindowSize        = NULL;
-    device->SetWindowMinimumSize = NULL;
-    device->SetWindowMaximumSize = NULL;
-    device->ShowWindow           = NULL;
-    device->HideWindow           = NULL;
     device->RaiseWindow          = NULL;
     device->SetWindowBordered    = NULL;
     device->SetWindowGammaRamp   = NULL;
     device->GetWindowGammaRamp   = NULL;
     device->SetWindowGrab        = NULL;
     device->OnWindowEnter        = NULL;
+    device->SetWindowPosition    = NULL;
 
     /* mirframebuffer */
     device->CreateWindowFramebuffer  = MIR_CreateWindowFramebuffer;
@@ -272,8 +272,10 @@ MIR_VideoInit(_THIS)
 {
     MIR_Data* mir_data = _this->driverdata;
 
-    mir_data->connection = MIR_mir_connect_sync(NULL, __PRETTY_FUNCTION__);
-    mir_data->software = SDL_FALSE;
+    mir_data->connection     = MIR_mir_connect_sync(NULL, __PRETTY_FUNCTION__);
+    mir_data->current_window = NULL;
+    mir_data->software       = SDL_FALSE;
+    mir_data->pixel_format   = mir_pixel_format_invalid;
 
     if (!MIR_mir_connection_is_valid(mir_data->connection))
         return SDL_SetError("Failed to connect to the Mir Server");

+ 5 - 2
modules/sdl2/SDL/src/video/mir/SDL_mirvideo.h

@@ -29,11 +29,14 @@
 #include <EGL/egl.h>
 #include <mir_toolkit/mir_client_library.h>
 
+typedef struct MIR_Window MIR_Window;
+
 typedef struct
 {
     MirConnection* connection;
-    SDL_bool software;
-    
+    MIR_Window*    current_window;
+    SDL_bool       software;
+    MirPixelFormat pixel_format;
 } MIR_Data;
 
 #endif /* _SDL_mirvideo_h_ */

+ 160 - 29
modules/sdl2/SDL/src/video/mir/SDL_mirwindow.c

@@ -55,7 +55,7 @@ FindValidPixelFormat(MIR_Data* mir_data)
 
     MirPixelFormat formats[pf_size];
     MIR_mir_connection_get_available_surface_formats(mir_data->connection, formats,
-                                                 pf_size, &valid_formats);
+                                                     pf_size, &valid_formats);
 
     for (f = 0; f < valid_formats; f++) {
         MirPixelFormat cur_pf = formats[f];
@@ -77,21 +77,10 @@ MIR_CreateWindow(_THIS, SDL_Window* window)
 {
     MIR_Window* mir_window;
     MIR_Data* mir_data;
+    MirPixelFormat pixel_format;
+    MirBufferUsage buffer_usage;
 
-    MirSurfaceParameters surfaceparm =
-    {
-        .name = "MirSurface",
-        .width = window->w,
-        .height = window->h,
-        .pixel_format = mir_pixel_format_invalid,
-        .buffer_usage = mir_buffer_usage_hardware,
-        .output_id = mir_display_output_id_invalid
-    };
-
-    MirEventDelegate delegate = {
-        MIR_HandleInput,
-        window
-    };
+    MirSurfaceSpec* spec;
 
     mir_window = SDL_calloc(1, sizeof(MIR_Window));
     if (!mir_window)
@@ -100,9 +89,6 @@ MIR_CreateWindow(_THIS, SDL_Window* window)
     mir_data = _this->driverdata;
     window->driverdata = mir_window;
 
-    if (mir_data->software)
-        surfaceparm.buffer_usage = mir_buffer_usage_software;
-
     if (window->x == SDL_WINDOWPOS_UNDEFINED)
         window->x = 0;
 
@@ -112,12 +98,37 @@ MIR_CreateWindow(_THIS, SDL_Window* window)
     mir_window->mir_data = mir_data;
     mir_window->sdl_window = window;
 
-    surfaceparm.pixel_format = FindValidPixelFormat(mir_data);
-    if (surfaceparm.pixel_format == mir_pixel_format_invalid) {
+    if (window->flags & SDL_WINDOW_OPENGL) {
+        pixel_format = MIR_mir_connection_get_egl_pixel_format(mir_data->connection,
+                                                               _this->egl_data->egl_display,
+                                                               _this->egl_data->egl_config);
+    }
+    else {
+        pixel_format = FindValidPixelFormat(mir_data);
+    }
+
+    mir_data->pixel_format = pixel_format;
+    if (pixel_format == mir_pixel_format_invalid) {
         return SDL_SetError("Failed to find a valid pixel format.");
     }
 
-    mir_window->surface = MIR_mir_connection_create_surface_sync(mir_data->connection, &surfaceparm);
+    buffer_usage = mir_buffer_usage_hardware;
+    if (mir_data->software)
+        buffer_usage = mir_buffer_usage_software;
+
+    spec = MIR_mir_connection_create_spec_for_normal_surface(mir_data->connection,
+                                                             window->w,
+                                                             window->h,
+                                                             pixel_format);
+
+    MIR_mir_surface_spec_set_buffer_usage(spec, buffer_usage);
+    MIR_mir_surface_spec_set_name(spec, "Mir surface");
+
+    mir_window->surface = MIR_mir_surface_create_sync(spec);
+    MIR_mir_surface_set_event_handler(mir_window->surface, MIR_HandleEvent, window);
+
+    MIR_mir_surface_spec_release(spec);
+
     if (!MIR_mir_surface_is_valid(mir_window->surface)) {
         const char* error = MIR_mir_surface_get_error_message(mir_window->surface);
         return SDL_SetError("Failed to created a mir surface: %s", error);
@@ -125,7 +136,8 @@ MIR_CreateWindow(_THIS, SDL_Window* window)
 
     if (window->flags & SDL_WINDOW_OPENGL) {
         EGLNativeWindowType egl_native_window =
-                        (EGLNativeWindowType)MIR_mir_surface_get_egl_native_window(mir_window->surface);
+                        (EGLNativeWindowType)MIR_mir_buffer_stream_get_egl_native_window(
+                                                       MIR_mir_surface_get_buffer_stream(mir_window->surface));
 
         mir_window->egl_surface = SDL_EGL_CreateSurface(_this, egl_native_window);
 
@@ -138,7 +150,7 @@ MIR_CreateWindow(_THIS, SDL_Window* window)
         mir_window->egl_surface = EGL_NO_SURFACE;
     }
 
-    MIR_mir_surface_set_event_handler(mir_window->surface, &delegate);
+    mir_data->current_window = mir_window;
 
     return 0;
 }
@@ -146,13 +158,15 @@ MIR_CreateWindow(_THIS, SDL_Window* window)
 void
 MIR_DestroyWindow(_THIS, SDL_Window* window)
 {
-    MIR_Data* mir_data = _this->driverdata;
+    MIR_Data* mir_data     = _this->driverdata;
     MIR_Window* mir_window = window->driverdata;
 
     if (mir_data) {
         SDL_EGL_DestroySurface(_this, mir_window->egl_surface);
         MIR_mir_surface_release_sync(mir_window->surface);
 
+        mir_data->current_window = NULL;
+
         SDL_free(mir_window);
     }
     window->driverdata = NULL;
@@ -180,49 +194,166 @@ MIR_SetWindowFullscreen(_THIS, SDL_Window* window,
                         SDL_VideoDisplay* display,
                         SDL_bool fullscreen)
 {
+    MIR_Data*   mir_data   = _this->driverdata;
     MIR_Window* mir_window = window->driverdata;
+    MirSurfaceSpec* spec;
+    MirSurfaceState state;
 
     if (IsSurfaceValid(mir_window) < 0)
         return;
 
     if (fullscreen) {
-        MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_fullscreen);
+        state = mir_surface_state_fullscreen;
     } else {
-        MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_restored);
+        state = mir_surface_state_restored;
     }
+
+    spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
+    MIR_mir_surface_spec_set_state(spec, state);
+
+    MIR_mir_surface_apply_spec(mir_window->surface, spec);
+    MIR_mir_surface_spec_release(spec);
 }
 
 void
 MIR_MaximizeWindow(_THIS, SDL_Window* window)
 {
+    MIR_Data*   mir_data   = _this->driverdata;
     MIR_Window* mir_window = window->driverdata;
+    MirSurfaceSpec* spec;
 
     if (IsSurfaceValid(mir_window) < 0)
         return;
 
-    MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_maximized);
+    spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
+    MIR_mir_surface_spec_set_state(spec, mir_surface_state_maximized);
+
+    MIR_mir_surface_apply_spec(mir_window->surface, spec);
+    MIR_mir_surface_spec_release(spec);
 }
 
 void
 MIR_MinimizeWindow(_THIS, SDL_Window* window)
 {
+    MIR_Data*   mir_data   = _this->driverdata;
     MIR_Window* mir_window = window->driverdata;
+    MirSurfaceSpec* spec;
 
     if (IsSurfaceValid(mir_window) < 0)
         return;
 
-    MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_minimized);
+    spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
+    MIR_mir_surface_spec_set_state(spec, mir_surface_state_minimized);
+
+    MIR_mir_surface_apply_spec(mir_window->surface, spec);
+    MIR_mir_surface_spec_release(spec);
 }
 
 void
 MIR_RestoreWindow(_THIS, SDL_Window * window)
 {
+    MIR_Data*   mir_data   = _this->driverdata;
     MIR_Window* mir_window = window->driverdata;
+    MirSurfaceSpec* spec;
 
     if (IsSurfaceValid(mir_window) < 0)
         return;
 
-    MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_restored);
+    spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
+    MIR_mir_surface_spec_set_state(spec, mir_surface_state_restored);
+
+    MIR_mir_surface_apply_spec(mir_window->surface, spec);
+    MIR_mir_surface_spec_release(spec);
+}
+
+void
+MIR_HideWindow(_THIS, SDL_Window* window)
+{
+    MIR_Data*   mir_data   = _this->driverdata;
+    MIR_Window* mir_window = window->driverdata;
+    MirSurfaceSpec* spec;
+
+    if (IsSurfaceValid(mir_window) < 0)
+        return;
+
+    spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
+    MIR_mir_surface_spec_set_state(spec, mir_surface_state_hidden);
+
+    MIR_mir_surface_apply_spec(mir_window->surface, spec);
+    MIR_mir_surface_spec_release(spec);
+}
+
+void
+MIR_SetWindowSize(_THIS, SDL_Window* window)
+{
+    MIR_Data*   mir_data   = _this->driverdata;
+    MIR_Window* mir_window = window->driverdata;
+    MirSurfaceSpec* spec;
+
+    if (IsSurfaceValid(mir_window) < 0)
+        return;
+
+    /* You cannot set the x/y of a mir window! So only update w/h */
+    spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
+    MIR_mir_surface_spec_set_width (spec, window->w);
+    MIR_mir_surface_spec_set_height(spec, window->h);
+
+    MIR_mir_surface_apply_spec(mir_window->surface, spec);
+    MIR_mir_surface_spec_release(spec);
+}
+
+void
+MIR_SetWindowMinimumSize(_THIS, SDL_Window* window)
+{
+    MIR_Data*   mir_data   = _this->driverdata;
+    MIR_Window* mir_window = window->driverdata;
+    MirSurfaceSpec* spec;
+
+    if (IsSurfaceValid(mir_window) < 0)
+        return;
+
+    spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
+    MIR_mir_surface_spec_set_min_width (spec, window->min_w);
+    MIR_mir_surface_spec_set_min_height(spec, window->min_h);
+
+    MIR_mir_surface_apply_spec(mir_window->surface, spec);
+    MIR_mir_surface_spec_release(spec);
+}
+
+void
+MIR_SetWindowMaximumSize(_THIS, SDL_Window* window)
+{
+    MIR_Data*   mir_data   = _this->driverdata;
+    MIR_Window* mir_window = window->driverdata;
+    MirSurfaceSpec* spec;
+
+    if (IsSurfaceValid(mir_window) < 0)
+        return;
+
+    spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
+    MIR_mir_surface_spec_set_max_width (spec, window->max_w);
+    MIR_mir_surface_spec_set_max_height(spec, window->max_h);
+
+    MIR_mir_surface_apply_spec(mir_window->surface, spec);
+    MIR_mir_surface_spec_release(spec);
+}
+
+void
+MIR_SetWindowTitle(_THIS, SDL_Window* window)
+{
+    MIR_Data*   mir_data   = _this->driverdata;
+    MIR_Window* mir_window = window->driverdata;
+    char const* title = window->title ? window->title : "";
+    MirSurfaceSpec* spec;
+
+    if (IsSurfaceValid(mir_window) < 0)
+        return;
+
+    spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
+    MIR_mir_surface_spec_set_name(spec, title);
+
+    MIR_mir_surface_apply_spec(mir_window->surface, spec);
+    MIR_mir_surface_spec_release(spec);
 }
 
 #endif /* SDL_VIDEO_DRIVER_MIR */

+ 19 - 4
modules/sdl2/SDL/src/video/mir/SDL_mirwindow.h

@@ -31,13 +31,13 @@
 
 #include "SDL_mirvideo.h"
 
-typedef struct {
+struct MIR_Window {
     SDL_Window* sdl_window;
-    MIR_Data* mir_data;
+    MIR_Data*   mir_data;
 
     MirSurface* surface;
-    EGLSurface egl_surface;
-} MIR_Window;
+    EGLSurface  egl_surface;
+};
 
 
 extern int
@@ -60,9 +60,24 @@ MIR_MinimizeWindow(_THIS, SDL_Window* window);
 extern void
 MIR_RestoreWindow(_THIS, SDL_Window* window);
 
+extern void
+MIR_HideWindow(_THIS, SDL_Window* window);
+
 extern SDL_bool
 MIR_GetWindowWMInfo(_THIS, SDL_Window* window, SDL_SysWMinfo* info);
 
+extern void
+MIR_SetWindowSize(_THIS, SDL_Window* window);
+
+extern void
+MIR_SetWindowMinimumSize(_THIS, SDL_Window* window);
+
+extern void
+MIR_SetWindowMaximumSize(_THIS, SDL_Window* window);
+
+extern void
+MIR_SetWindowTitle(_THIS, SDL_Window* window);
+
 #endif /* _SDL_mirwindow_h */
 
 /* vi: set ts=4 sw=4 expandtab: */

+ 2 - 2
modules/sdl2/SDL/src/video/psp/SDL_pspevents.c

@@ -31,8 +31,8 @@
 #include "../../events/SDL_keyboard_c.h"
 #include "SDL_pspvideo.h"
 #include "SDL_pspevents_c.h"
-#include "SDL_thread.h"
 #include "SDL_keyboard.h"
+#include "../../thread/SDL_systhread.h"
 #include <psphprm.h>
 
 #ifdef PSPIRKEYB
@@ -264,7 +264,7 @@ void PSP_EventInit(_THIS)
         return;
     }
     running = 1;
-    if((thread = SDL_CreateThread(EventUpdate, "PSPInputThread",NULL)) == NULL) {
+    if((thread = SDL_CreateThreadInternal(EventUpdate, "PSPInputThread", 4096, NULL)) == NULL) {
         SDL_SetError("Can't create input thread\n");
         return;
     }

+ 1 - 1
modules/sdl2/SDL/src/video/psp/SDL_pspvideo.c

@@ -234,7 +234,7 @@ PSP_CreateWindow(_THIS, SDL_Window * window)
 int
 PSP_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
 {
-    return -1;
+    return SDL_Unsupported();
 }
 
 void

+ 9 - 0
modules/sdl2/SDL/src/video/raspberry/SDL_rpimouse.c

@@ -70,7 +70,16 @@ RPI_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
     SDL_assert(surface->pitch == surface->w * 4);
     
     cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
+    if (cursor == NULL) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
     curdata = (RPI_CursorData *) SDL_calloc(1, sizeof(*curdata));
+    if (curdata == NULL) {
+        SDL_OutOfMemory();
+        SDL_free(cursor);
+        return NULL;
+    }
 
     curdata->hot_x = hot_x;
     curdata->hot_y = hot_y;

+ 0 - 1
modules/sdl2/SDL/src/video/uikit/SDL_uikitappdelegate.m

@@ -333,7 +333,6 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 {
     NSBundle *bundle = [NSBundle mainBundle];
-    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
 
 #if SDL_IPHONE_LAUNCHSCREEN
     /* The normal launch screen is displayed until didFinishLaunching returns,

+ 4 - 0
modules/sdl2/SDL/src/video/uikit/SDL_uikitevents.m

@@ -26,6 +26,7 @@
 
 #include "SDL_uikitvideo.h"
 #include "SDL_uikitevents.h"
+#include "SDL_uikitopengles.h"
 
 #import <Foundation/Foundation.h>
 
@@ -62,6 +63,9 @@ UIKit_PumpEvents(_THIS)
     do {
         result = CFRunLoopRunInMode((CFStringRef)UITrackingRunLoopMode, seconds, TRUE);
     } while(result == kCFRunLoopRunHandledSource);
+
+    /* See the comment in the function definition. */
+    UIKit_GL_RestoreCurrentContext();
 }
 
 #endif /* SDL_VIDEO_DRIVER_UIKIT */

+ 2 - 0
modules/sdl2/SDL/src/video/uikit/SDL_uikitopengles.h

@@ -33,6 +33,8 @@ extern void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context);
 extern void *UIKit_GL_GetProcAddress(_THIS, const char *proc);
 extern int UIKit_GL_LoadLibrary(_THIS, const char *path);
 
+extern void UIKit_GL_RestoreCurrentContext();
+
 #endif
 
 /* vi: set ts=4 sw=4 expandtab: */

+ 28 - 1
modules/sdl2/SDL/src/video/uikit/SDL_uikitopengles.m

@@ -140,10 +140,19 @@ UIKit_GL_CreateContext(_THIS, SDL_Window * window)
         EAGLSharegroup *sharegroup = nil;
         CGFloat scale = 1.0;
         int samples = 0;
+        int major = _this->gl_config.major_version;
+        int minor = _this->gl_config.minor_version;
 
         /* The EAGLRenderingAPI enum values currently map 1:1 to major GLES
          * versions. */
-        EAGLRenderingAPI api = _this->gl_config.major_version;
+        EAGLRenderingAPI api = major;
+
+        /* iOS currently doesn't support GLES >3.0. iOS 6 also only supports up
+         * to GLES 2.0. */
+        if (major > 3 || (major == 3 && (minor > 0 || !UIKit_IsSystemVersionAtLeast(7.0)))) {
+            SDL_SetError("OpenGL ES %d.%d context could not be created", major, minor);
+            return NULL;
+        }
 
         if (_this->gl_config.multisamplebuffers > 0) {
             samples = _this->gl_config.multisamplesamples;
@@ -217,6 +226,24 @@ UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
     }
 }
 
+void
+UIKit_GL_RestoreCurrentContext()
+{
+    @autoreleasepool {
+        /* Some iOS system functionality (such as Dictation on the on-screen
+         keyboard) uses its own OpenGL ES context but doesn't restore the
+         previous one when it's done. This is a workaround to make sure the
+         expected SDL-created OpenGL ES context is active after the OS is
+         finished running its own code for the frame. If this isn't done, the
+         app may crash or have other nasty symptoms when Dictation is used.
+         */
+        EAGLContext *context = (__bridge EAGLContext *) SDL_GL_GetCurrentContext();
+        if (context != NULL && [EAGLContext currentContext] != context) {
+            [EAGLContext setCurrentContext:context];
+        }
+    }
+}
+
 #endif /* SDL_VIDEO_DRIVER_UIKIT */
 
 /* vi: set ts=4 sw=4 expandtab: */

+ 6 - 0
modules/sdl2/SDL/src/video/uikit/SDL_uikitvideo.h

@@ -25,6 +25,12 @@
 
 #include "../SDL_sysvideo.h"
 
+@interface SDL_VideoData : NSObject
+
+@property (nonatomic) id pasteboardObserver;
+
+@end
+
 void UIKit_SuspendScreenSaver(_THIS);
 
 BOOL UIKit_IsSystemVersionAtLeast(double version);

+ 67 - 48
modules/sdl2/SDL/src/video/uikit/SDL_uikitvideo.m

@@ -36,9 +36,14 @@
 #include "SDL_uikitmodes.h"
 #include "SDL_uikitwindow.h"
 #include "SDL_uikitopengles.h"
+#include "SDL_uikitclipboard.h"
 
 #define UIKITVID_DRIVER_NAME "uikit"
 
+@implementation SDL_VideoData
+
+@end
+
 /* Initialization/Query functions */
 static int UIKit_VideoInit(_THIS);
 static void UIKit_VideoQuit(_THIS);
@@ -53,61 +58,75 @@ UIKit_Available(void)
 
 static void UIKit_DeleteDevice(SDL_VideoDevice * device)
 {
-    SDL_free(device);
+    @autoreleasepool {
+        CFRelease(device->driverdata);
+        SDL_free(device);
+    }
 }
 
 static SDL_VideoDevice *
 UIKit_CreateDevice(int devindex)
 {
-    SDL_VideoDevice *device;
+    @autoreleasepool {
+        SDL_VideoDevice *device;
+        SDL_VideoData *data;
+
+        /* Initialize all variables that we clean on shutdown */
+        device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+        if (device) {
+            data = [SDL_VideoData new];
+        } else {
+            SDL_free(device);
+            SDL_OutOfMemory();
+            return (0);
+        }
 
-    /* Initialize all variables that we clean on shutdown */
-    device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
-    if (!device) {
-        SDL_free(device);
-        SDL_OutOfMemory();
-        return (0);
+        device->driverdata = (void *) CFBridgingRetain(data);
+
+        /* Set the function pointers */
+        device->VideoInit = UIKit_VideoInit;
+        device->VideoQuit = UIKit_VideoQuit;
+        device->GetDisplayModes = UIKit_GetDisplayModes;
+        device->SetDisplayMode = UIKit_SetDisplayMode;
+        device->PumpEvents = UIKit_PumpEvents;
+        device->SuspendScreenSaver = UIKit_SuspendScreenSaver;
+        device->CreateWindow = UIKit_CreateWindow;
+        device->SetWindowTitle = UIKit_SetWindowTitle;
+        device->ShowWindow = UIKit_ShowWindow;
+        device->HideWindow = UIKit_HideWindow;
+        device->RaiseWindow = UIKit_RaiseWindow;
+        device->SetWindowBordered = UIKit_SetWindowBordered;
+        device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
+        device->DestroyWindow = UIKit_DestroyWindow;
+        device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
+        device->GetDisplayUsableBounds = UIKit_GetDisplayUsableBounds;
+
+    #if SDL_IPHONE_KEYBOARD
+        device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
+        device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
+        device->HideScreenKeyboard = UIKit_HideScreenKeyboard;
+        device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown;
+        device->SetTextInputRect = UIKit_SetTextInputRect;
+    #endif
+
+        device->SetClipboardText = UIKit_SetClipboardText;
+        device->GetClipboardText = UIKit_GetClipboardText;
+        device->HasClipboardText = UIKit_HasClipboardText;
+
+        /* OpenGL (ES) functions */
+        device->GL_MakeCurrent      = UIKit_GL_MakeCurrent;
+        device->GL_GetDrawableSize  = UIKit_GL_GetDrawableSize;
+        device->GL_SwapWindow       = UIKit_GL_SwapWindow;
+        device->GL_CreateContext    = UIKit_GL_CreateContext;
+        device->GL_DeleteContext    = UIKit_GL_DeleteContext;
+        device->GL_GetProcAddress   = UIKit_GL_GetProcAddress;
+        device->GL_LoadLibrary      = UIKit_GL_LoadLibrary;
+        device->free = UIKit_DeleteDevice;
+
+        device->gl_config.accelerated = 1;
+
+        return device;
     }
-
-    /* Set the function pointers */
-    device->VideoInit = UIKit_VideoInit;
-    device->VideoQuit = UIKit_VideoQuit;
-    device->GetDisplayModes = UIKit_GetDisplayModes;
-    device->SetDisplayMode = UIKit_SetDisplayMode;
-    device->PumpEvents = UIKit_PumpEvents;
-    device->SuspendScreenSaver = UIKit_SuspendScreenSaver;
-    device->CreateWindow = UIKit_CreateWindow;
-    device->SetWindowTitle = UIKit_SetWindowTitle;
-    device->ShowWindow = UIKit_ShowWindow;
-    device->HideWindow = UIKit_HideWindow;
-    device->RaiseWindow = UIKit_RaiseWindow;
-    device->SetWindowBordered = UIKit_SetWindowBordered;
-    device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
-    device->DestroyWindow = UIKit_DestroyWindow;
-    device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
-    device->GetDisplayUsableBounds = UIKit_GetDisplayUsableBounds;
-
-#if SDL_IPHONE_KEYBOARD
-    device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
-    device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
-    device->HideScreenKeyboard = UIKit_HideScreenKeyboard;
-    device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown;
-    device->SetTextInputRect = UIKit_SetTextInputRect;
-#endif
-
-    /* OpenGL (ES) functions */
-    device->GL_MakeCurrent      = UIKit_GL_MakeCurrent;
-    device->GL_GetDrawableSize  = UIKit_GL_GetDrawableSize;
-    device->GL_SwapWindow       = UIKit_GL_SwapWindow;
-    device->GL_CreateContext    = UIKit_GL_CreateContext;
-    device->GL_DeleteContext    = UIKit_GL_DeleteContext;
-    device->GL_GetProcAddress   = UIKit_GL_GetProcAddress;
-    device->GL_LoadLibrary      = UIKit_GL_LoadLibrary;
-    device->free = UIKit_DeleteDevice;
-
-    device->gl_config.accelerated = 1;
-
-    return device;
 }
 
 VideoBootStrap UIKIT_bootstrap = {

+ 19 - 19
modules/sdl2/SDL/src/video/uikit/SDL_uikitviewcontroller.h

@@ -1,23 +1,23 @@
 /*
- Simple DirectMedia Layer
- Copyright (C) 1997-2016 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.
- */
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2016 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.
+*/
 
 #import <UIKit/UIKit.h>
 

+ 4 - 0
modules/sdl2/SDL/src/video/uikit/SDL_uikitviewcontroller.m

@@ -33,6 +33,7 @@
 #include "SDL_uikitvideo.h"
 #include "SDL_uikitmodes.h"
 #include "SDL_uikitwindow.h"
+#include "SDL_uikitopengles.h"
 
 #if SDL_IPHONE_KEYBOARD
 #include "keyinfotable.h"
@@ -102,6 +103,9 @@
 {
     /* Don't run the game loop while a messagebox is up */
     if (!UIKit_ShowingMessageBox()) {
+        /* See the comment in the function definition. */
+        UIKit_GL_RestoreCurrentContext();
+
         animationCallback(animationCallbackParam);
     }
 }

+ 2 - 4
modules/sdl2/SDL/src/video/vivante/SDL_vivantevideo.c

@@ -366,12 +366,13 @@ VIVANTE_HideWindow(_THIS, SDL_Window * window)
 SDL_bool
 VIVANTE_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
 {
-/*
     SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+    SDL_DisplayData *displaydata = SDL_GetDisplayDriverData(0);
 
     if (info->version.major == SDL_MAJOR_VERSION &&
         info->version.minor == SDL_MINOR_VERSION) {
         info->subsystem = SDL_SYSWM_VIVANTE;
+        info->info.vivante.display = displaydata->native_display;
         info->info.vivante.window = data->native_window;
         return SDL_TRUE;
     } else {
@@ -379,9 +380,6 @@ VIVANTE_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
                      SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
         return SDL_FALSE;
     }
-*/
-    SDL_Unsupported();
-    return SDL_FALSE;
 }
 
 /*****************************************************************************/

+ 0 - 17
modules/sdl2/SDL/src/video/wayland/SDL_waylanddyn.c

@@ -94,9 +94,6 @@ WAYLAND_GetSym(const char *fnname, int *pHasModule)
 #define SDL_WAYLAND_SYM(rc,fn,params) SDL_DYNWAYLANDFN_##fn WAYLAND_##fn = NULL;
 #define SDL_WAYLAND_INTERFACE(iface) const struct wl_interface *WAYLAND_##iface = NULL;
 #include "SDL_waylandsym.h"
-#undef SDL_WAYLAND_MODULE
-#undef SDL_WAYLAND_SYM
-#undef SDL_WAYLAND_INTERFACE
 
 static int wayland_load_refcount = 0;
 
@@ -115,9 +112,6 @@ SDL_WAYLAND_UnloadSymbols(void)
 #define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = NULL;
 #define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = NULL;
 #include "SDL_waylandsym.h"
-#undef SDL_WAYLAND_MODULE
-#undef SDL_WAYLAND_SYM
-#undef SDL_WAYLAND_INTERFACE
 
 
 #ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
@@ -150,20 +144,12 @@ SDL_WAYLAND_LoadSymbols(void)
         }
 
 #define SDL_WAYLAND_MODULE(modname) SDL_WAYLAND_HAVE_##modname = 1; /* default yes */
-#define SDL_WAYLAND_SYM(rc,fn,params)
-#define SDL_WAYLAND_INTERFACE(iface)
 #include "SDL_waylandsym.h"
-#undef SDL_WAYLAND_MODULE
-#undef SDL_WAYLAND_SYM
-#undef SDL_WAYLAND_INTERFACE
 
 #define SDL_WAYLAND_MODULE(modname) thismod = &SDL_WAYLAND_HAVE_##modname;
 #define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = (SDL_DYNWAYLANDFN_##fn) WAYLAND_GetSym(#fn,thismod);
 #define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = (struct wl_interface *) WAYLAND_GetSym(#iface,thismod);
 #include "SDL_waylandsym.h"
-#undef SDL_WAYLAND_MODULE
-#undef SDL_WAYLAND_SYM
-#undef SDL_WAYLAND_INTERFACE
 
         if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT) {
             /* all required symbols loaded. */
@@ -180,9 +166,6 @@ SDL_WAYLAND_LoadSymbols(void)
 #define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = fn;
 #define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = &iface;
 #include "SDL_waylandsym.h"
-#undef SDL_WAYLAND_MODULE
-#undef SDL_WAYLAND_SYM
-#undef SDL_WAYLAND_INTERFACE
 
 #endif
     }

+ 2 - 4
modules/sdl2/SDL/src/video/wayland/SDL_waylanddyn.h

@@ -53,10 +53,7 @@ void SDL_WAYLAND_UnloadSymbols(void);
     extern SDL_DYNWAYLANDFN_##fn WAYLAND_##fn;
 #define SDL_WAYLAND_INTERFACE(iface) extern const struct wl_interface *WAYLAND_##iface;
 #include "SDL_waylandsym.h"
-#undef SDL_WAYLAND_MODULE
-#undef SDL_WAYLAND_SYM
-#undef SDL_WAYLAND_INTERFACE
- 
+
 
 #ifdef __cplusplus
 }
@@ -79,6 +76,7 @@ void SDL_WAYLAND_UnloadSymbols(void);
 #define wl_proxy_get_user_data (*WAYLAND_wl_proxy_get_user_data)
 #define wl_proxy_add_listener (*WAYLAND_wl_proxy_add_listener)
 #define wl_proxy_marshal_constructor (*WAYLAND_wl_proxy_marshal_constructor)
+#define wl_proxy_marshal_constructor_versioned (*WAYLAND_wl_proxy_marshal_constructor_versioned)
 
 #define wl_seat_interface (*WAYLAND_wl_seat_interface)
 #define wl_surface_interface (*WAYLAND_wl_surface_interface)

+ 2 - 3
modules/sdl2/SDL/src/video/wayland/SDL_waylandevents.c

@@ -40,7 +40,6 @@
 #include <sys/select.h>
 #include <sys/mman.h>
 #include <poll.h>
-#include <errno.h>
 #include <unistd.h>
 #include <xkbcommon/xkbcommon.h>
 
@@ -302,9 +301,9 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
  
     window = wl_surface_get_user_data(surface);
 
-    input->keyboard_focus = window;
-    window->keyboard_device = input;
     if (window) {
+        input->keyboard_focus = window;
+        window->keyboard_device = input;
         SDL_SetKeyboardFocus(window->sdlwindow);
     }
 }

+ 18 - 9
modules/sdl2/SDL/src/video/wayland/SDL_waylandmouse.c

@@ -27,7 +27,6 @@
 #define _GNU_SOURCE
 #endif
 
-#include <errno.h>
 #include <sys/types.h>
 #include <sys/mman.h>
 #include <fcntl.h>
@@ -70,7 +69,6 @@ wayland_create_tmp_file(off_t size)
 
     xdg_path = SDL_getenv("XDG_RUNTIME_DIR");
     if (!xdg_path) {
-        errno = ENOENT;
         return -1;
     }
 
@@ -116,8 +114,7 @@ create_buffer_from_shm(Wayland_CursorData *d,
     shm_fd = wayland_create_tmp_file(size);
     if (shm_fd < 0)
     {
-        fprintf(stderr, "creating mouse cursor buffer failed!\n");
-        return -1;
+        return SDL_SetError("Creating mouse cursor buffer failed.");
     }
 
     d->shm_data = mmap(NULL,
@@ -128,8 +125,8 @@ create_buffer_from_shm(Wayland_CursorData *d,
                        0);
     if (d->shm_data == MAP_FAILED) {
         d->shm_data = NULL;
-        fprintf (stderr, "mmap () failed\n");
         close (shm_fd);
+        return SDL_SetError("mmap() failed.");
     }
 
     shm_pool = wl_shm_create_pool(data->shm, shm_fd, size);
@@ -159,6 +156,11 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
         SDL_VideoDevice *vd = SDL_GetVideoDevice ();
         SDL_VideoData *wd = (SDL_VideoData *) vd->driverdata;
         Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData));
+        if (!data) {
+            SDL_OutOfMemory();
+            free(cursor);
+            return NULL;
+        }
         cursor->driverdata = (void *) data;
 
         /* Assume ARGB8888 */
@@ -169,7 +171,7 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
         if (create_buffer_from_shm (data,
                                     surface->w,
                                     surface->h,
-                                    WL_SHM_FORMAT_XRGB8888) < 0)
+                                    WL_SHM_FORMAT_ARGB8888) < 0)
         {
             free (cursor->driverdata);
             free (cursor);
@@ -187,6 +189,8 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
         data->hot_y = hot_y;
         data->w = surface->w;
         data->h = surface->h;
+    } else {
+        SDL_OutOfMemory();
     }
 
     return cursor;
@@ -200,6 +204,11 @@ CreateCursorFromWlCursor(SDL_VideoData *d, struct wl_cursor *wlcursor)
     cursor = calloc(1, sizeof (*cursor));
     if (cursor) {
         Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData));
+        if (!data) {
+            SDL_OutOfMemory();
+            free(cursor);
+            return NULL;
+        }
         cursor->driverdata = (void *) data;
 
         data->buffer = WAYLAND_wl_cursor_image_get_buffer(wlcursor->images[0]);
@@ -322,13 +331,13 @@ Wayland_ShowCursor(SDL_Cursor *cursor)
     {
         Wayland_CursorData *data = cursor->driverdata;
 
-        wl_surface_attach(data->surface, data->buffer, 0, 0);
-        wl_surface_damage(data->surface, 0, 0, data->w, data->h);
-        wl_surface_commit(data->surface);
         wl_pointer_set_cursor (pointer, 0,
                                data->surface,
                                data->hot_x,
                                data->hot_y);
+        wl_surface_attach(data->surface, data->buffer, 0, 0);
+        wl_surface_damage(data->surface, 0, 0, data->w, data->h);
+        wl_surface_commit(data->surface);
     }
     else
     {

+ 18 - 1
modules/sdl2/SDL/src/video/wayland/SDL_waylandsym.h

@@ -21,6 +21,18 @@
 
 /* *INDENT-OFF* */
 
+#ifndef SDL_WAYLAND_MODULE
+#define SDL_WAYLAND_MODULE(modname)
+#endif
+
+#ifndef SDL_WAYLAND_SYM
+#define SDL_WAYLAND_SYM(rc,fn,params)
+#endif
+
+#ifndef SDL_WAYLAND_INTERFACE
+#define SDL_WAYLAND_INTERFACE(iface)
+#endif
+
 SDL_WAYLAND_MODULE(WAYLAND_CLIENT)
 SDL_WAYLAND_SYM(void, wl_proxy_marshal, (struct wl_proxy *, uint32_t, ...))
 SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_create, (struct wl_proxy *, const struct wl_interface *))
@@ -55,6 +67,9 @@ SDL_WAYLAND_SYM(void, wl_list_insert_list, (struct wl_list *, struct wl_list *))
 SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_4)
 SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor, (struct wl_proxy *, uint32_t opcode, const struct wl_interface *interface, ...))
 
+SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_10)
+SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor_versioned, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, ...))
+
 SDL_WAYLAND_INTERFACE(wl_seat_interface)
 SDL_WAYLAND_INTERFACE(wl_surface_interface)
 SDL_WAYLAND_INTERFACE(wl_shm_pool_interface)
@@ -99,8 +114,10 @@ SDL_WAYLAND_SYM(enum xkb_state_component, xkb_state_update_mask, (struct xkb_sta
                       xkb_layout_index_t latched_layout,\
                       xkb_layout_index_t locked_layout) )
 
+#undef SDL_WAYLAND_MODULE
+#undef SDL_WAYLAND_SYM
+#undef SDL_WAYLAND_INTERFACE
 
 /* *INDENT-ON* */
 
 /* vi: set ts=4 sw=4 expandtab: */
-//SDL_WAYLAND_SYM(ret, fn, params)

+ 0 - 1
modules/sdl2/SDL/src/video/wayland/SDL_waylandvideo.c

@@ -253,7 +253,6 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
     } else if (strcmp(interface, "wl_shm") == 0) {
         d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
         d->cursor_theme = WAYLAND_wl_cursor_theme_load(NULL, 32, d->shm);
-        d->default_cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr");
 
 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
     } else if (strcmp(interface, "qt_touch_extension") == 0) {

+ 0 - 1
modules/sdl2/SDL/src/video/wayland/SDL_waylandvideo.h

@@ -42,7 +42,6 @@ typedef struct {
     struct wl_compositor *compositor;
     struct wl_shm *shm;
     struct wl_cursor_theme *cursor_theme;
-    struct wl_cursor *default_cursor;
     struct wl_pointer *pointer;
     struct wl_shell *shell;
 

+ 48 - 35
modules/sdl2/SDL/src/video/windows/SDL_windowsmodes.c

@@ -70,40 +70,16 @@ WIN_GetMonitorDPI(HMONITOR hMonitor,
     return TRUE;
 }
 
-static SDL_bool
-WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
+static void
+WIN_UpdateDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
 {
     SDL_VideoData *vid_data = (SDL_VideoData *) _this->driverdata;
-    SDL_DisplayModeData *data;
-    DEVMODE devmode;
+    SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata;
     HDC hdc;
 
-    devmode.dmSize = sizeof(devmode);
-    devmode.dmDriverExtra = 0;
-    if (!EnumDisplaySettings(deviceName, index, &devmode)) {
-        return SDL_FALSE;
-    }
-
-    data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
-    if (!data) {
-        return SDL_FALSE;
-    }
-    data->DeviceMode = devmode;
     data->DeviceMode.dmFields =
         (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY |
          DM_DISPLAYFLAGS);
-    data->ScaleX = 1.0f;
-    data->ScaleY = 1.0f;
-    data->DiagDPI = 0.0f;
-    data->HorzDPI = 0.0f;
-    data->VertDPI = 0.0f;
-
-    /* Fill in the mode information */
-    mode->format = SDL_PIXELFORMAT_UNKNOWN;
-    mode->w = devmode.dmPelsWidth;
-    mode->h = devmode.dmPelsHeight;
-    mode->refresh_rate = devmode.dmDisplayFrequency;
-    mode->driverdata = data;
 
     if (index == ENUM_CURRENT_SETTINGS
         && (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) {
@@ -113,8 +89,8 @@ WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mod
         int logical_width = GetDeviceCaps( hdc, HORZRES );
         int logical_height = GetDeviceCaps( hdc, VERTRES );
 
-        data->ScaleX = (float)logical_width / devmode.dmPelsWidth;
-        data->ScaleY = (float)logical_height / devmode.dmPelsHeight;
+        data->ScaleX = (float)logical_width / data->DeviceMode.dmPelsWidth;
+        data->ScaleY = (float)logical_height / data->DeviceMode.dmPelsHeight;
         mode->w = logical_width;
         mode->h = logical_height;
 
@@ -127,8 +103,8 @@ WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mod
             dpi_data.vid_data = vid_data;
             dpi_data.mode = mode;
             dpi_data.mode_data = data;
-            monitor_rect.left = devmode.dmPosition.x;
-            monitor_rect.top = devmode.dmPosition.y;
+            monitor_rect.left = data->DeviceMode.dmPosition.x;
+            monitor_rect.top = data->DeviceMode.dmPosition.y;
             monitor_rect.right = monitor_rect.left + 1;
             monitor_rect.bottom = monitor_rect.top + 1;
             EnumDisplayMonitors(NULL, &monitor_rect, WIN_GetMonitorDPI, (LPARAM)&dpi_data);
@@ -176,10 +152,10 @@ WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mod
         } else if (bmi->bmiHeader.biBitCount == 4) {
             mode->format = SDL_PIXELFORMAT_INDEX4LSB;
         }
-    } else {
+    } else if (mode->format == SDL_PIXELFORMAT_UNKNOWN) {
         /* FIXME: Can we tell what this will be? */
-        if ((devmode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) {
-            switch (devmode.dmBitsPerPel) {
+        if ((data->DeviceMode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) {
+            switch (data->DeviceMode.dmBitsPerPel) {
             case 32:
                 mode->format = SDL_PIXELFORMAT_RGB888;
                 break;
@@ -201,6 +177,42 @@ WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mod
             }
         }
     }
+}
+
+static SDL_bool
+WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
+{
+    SDL_DisplayModeData *data;
+    DEVMODE devmode;
+
+    devmode.dmSize = sizeof(devmode);
+    devmode.dmDriverExtra = 0;
+    if (!EnumDisplaySettings(deviceName, index, &devmode)) {
+        return SDL_FALSE;
+    }
+
+    data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
+    if (!data) {
+        return SDL_FALSE;
+    }
+
+    mode->driverdata = data;
+    data->DeviceMode = devmode;
+
+    /* Default basic information */
+    data->ScaleX = 1.0f;
+    data->ScaleY = 1.0f;
+    data->DiagDPI = 0.0f;
+    data->HorzDPI = 0.0f;
+    data->VertDPI = 0.0f;
+
+    mode->format = SDL_PIXELFORMAT_UNKNOWN;
+    mode->w = data->DeviceMode.dmPelsWidth;
+    mode->h = data->DeviceMode.dmPelsHeight;
+    mode->refresh_rate = data->DeviceMode.dmDisplayFrequency;
+
+    /* Fill in the mode information */
+    WIN_UpdateDisplayMode(_this, deviceName, index, mode);
     return SDL_TRUE;
 }
 
@@ -330,7 +342,7 @@ WIN_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi,
         *vdpi = data->VertDPI;
     }
 
-    return data->DiagDPI != 0.0f ? 0 : -1;
+    return data->DiagDPI != 0.0f ? 0 : SDL_SetError("Couldn't get DPI");
 }
 
 int
@@ -427,6 +439,7 @@ WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
         return SDL_SetError("ChangeDisplaySettingsEx() failed: %s", reason);
     }
     EnumDisplaySettings(displaydata->DeviceName, ENUM_CURRENT_SETTINGS, &data->DeviceMode);
+    WIN_UpdateDisplayMode(_this, displaydata->DeviceName, ENUM_CURRENT_SETTINGS, mode);
     return 0;
 }
 

+ 1 - 1
modules/sdl2/SDL/src/video/windows/SDL_windowsopengles.c

@@ -133,7 +133,7 @@ WIN_GLES_SetSwapInterval(_THIS, int interval)
      * from working if we do (the window contents freeze and don't swap properly). So, we ignore
      * the request for now.
      */
-    SDL_EGL_SetSwapInterval( _this,interval );
+     SDL_EGL_SetSwapInterval( _this,interval );
 //    SDL_Log("WARNING: Ignoring SDL_GL_SetSwapInterval call due to ANGLE bug");
     return 0;
 }

+ 2 - 1
modules/sdl2/SDL/src/video/winrt/SDL_winrtevents.cpp

@@ -40,6 +40,7 @@ using Windows::UI::Core::CoreCursor;
 #include "SDL_system.h"
 
 extern "C" {
+#include "../../thread/SDL_systhread.h"
 #include "../SDL_sysvideo.h"
 #include "../../events/SDL_events_c.h"
 }
@@ -113,7 +114,7 @@ WINRT_CycleXAMLThread()
 
             _mutex = SDL_CreateMutex();
             _threadState = ThreadState_Running;
-            _XAMLThread = SDL_CreateThread(WINRT_XAMLThreadMain, "SDL/XAML App Thread", nullptr);
+            _XAMLThread = SDL_CreateThreadInternal(WINRT_XAMLThreadMain, "SDL/XAML App Thread", 0, nullptr);
 
             SDL_LockMutex(_mutex);
             while (_threadState != ThreadState_Yielding) {

+ 7 - 0
modules/sdl2/SDL/src/video/winrt/SDL_winrtevents_c.h

@@ -67,6 +67,13 @@ extern void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args);
 extern void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args);
 extern void WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^args);
 
+#if NTDDI_VERSION >= NTDDI_WIN10
+extern SDL_bool WINRT_HasScreenKeyboardSupport(_THIS);
+extern void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window);
+extern void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window);
+extern SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window);
+#endif  // NTDDI_VERSION >= ...
+
 /* XAML Thread Management */
 extern void WINRT_CycleXAMLThread();
 

+ 44 - 0
modules/sdl2/SDL/src/video/winrt/SDL_winrtkeyboard.cpp

@@ -383,4 +383,48 @@ WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArg
     }
 }
 
+
+#if NTDDI_VERSION >= NTDDI_WIN10
+
+SDL_bool WINRT_HasScreenKeyboardSupport(_THIS)
+{
+    return SDL_TRUE;
+}
+
+void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window)
+{
+    using namespace Windows::UI::ViewManagement;
+    InputPane ^ inputPane = InputPane::GetForCurrentView();
+    if (inputPane) {
+        inputPane->TryShow();
+    }
+}
+
+void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window)
+{
+    using namespace Windows::UI::ViewManagement;
+    InputPane ^ inputPane = InputPane::GetForCurrentView();
+    if (inputPane) {
+        inputPane->TryHide();
+    }
+}
+
+SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window)
+{
+    using namespace Windows::UI::ViewManagement;
+    InputPane ^ inputPane = InputPane::GetForCurrentView();
+    if (inputPane) {
+        // [email protected]: checking inputPane->Visible doesn't seem to detect visibility,
+        //   at least not on the Windows Phone 10.0.10240.0 emulator.  Checking
+        //   the size of inputPane->OccludedRect, however, does seem to work.
+        Windows::Foundation::Rect rect = inputPane->OccludedRect;
+        if (rect.Width > 0 && rect.Height > 0) {
+            return SDL_TRUE;
+        }
+    }
+    return SDL_FALSE;
+}
+
+#endif  // NTDDI_VERSION >= ...
+
 #endif // SDL_VIDEO_DRIVER_WINRT

+ 61 - 2
modules/sdl2/SDL/src/video/winrt/SDL_winrtmouse.cpp

@@ -26,6 +26,7 @@
  * Windows includes:
  */
 #include <Windows.h>
+#include <windows.ui.core.h>
 using namespace Windows::UI::Core;
 using Windows::UI::Core::CoreCursor;
 
@@ -116,11 +117,69 @@ WINRT_ShowCursor(SDL_Cursor * cursor)
         return 0;
     }
 
+    CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread();
     if (cursor) {
         CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata;
-        CoreWindow::GetForCurrentThread()->PointerCursor = *theCursor;
+        coreWindow->PointerCursor = *theCursor;
     } else {
-        CoreWindow::GetForCurrentThread()->PointerCursor = nullptr;
+        // HACK ALERT: TL;DR - Hiding the cursor in WinRT/UWP apps is weird, and
+        //   a Win32-style cursor resource file must be directly included in apps,
+        //   otherwise hiding the cursor will cause mouse-motion data to never be
+        //   received.
+        //
+        // Here's the lengthy explanation:
+        //
+        // There are two ways to hide a cursor in WinRT/UWP apps.
+        // Both involve setting the WinRT CoreWindow's (which is somewhat analogous
+        // to a Win32 HWND) 'PointerCursor' property.
+        //
+        // The first way to hide a cursor sets PointerCursor to nullptr.  This
+        // is, arguably, the easiest to implement for an app.  It does have an
+        // unfortunate side-effect: it'll prevent mouse-motion events from being
+        // sent to the app (via CoreWindow).
+        //
+        // The second way to hide a cursor sets PointerCursor to a transparent
+        // cursor.  This allows mouse-motion events to be sent to the app, but is
+        // more difficult to set up, as:
+        //   1. WinRT/UWP, while providing a few stock cursors, does not provide
+        //      a completely transparent cursor.
+        //   2. WinRT/UWP allows apps to provide custom-built cursors, but *ONLY*
+        //      if they are linked directly inside the app, via Win32-style
+        //      cursor resource files.  APIs to create cursors at runtime are
+        //      not provided to apps, and attempting to link-to or use Win32
+        //      cursor-creation APIs could cause an app to fail Windows Store
+        //      certification.
+        //
+        // SDL can use either means of hiding the cursor.  It provides a Win32-style
+        // set of cursor resource files in its source distribution, inside
+        // src/main/winrt/.  If those files are linked to an SDL-for-WinRT/UWP app
+        // (by including them in a MSVC project, for example), SDL will attempt to
+        // use those, if and when the cursor is hidden via SDL APIs.  If those
+        // files are not linked in, SDL will attempt to hide the cursor via the
+        // 'set PointerCursor to nullptr' means (which, if you recall, causes
+        // mouse-motion data to NOT be sent to the app!).
+        //
+        // Tech notes:
+        //  - SDL's blank cursor resource uses a resource ID of 5000.
+        //  - SDL's cursor resources consist of the following two files:
+        //     - src/main/winrt/SDL2-WinRTResource_BlankCursor.cur -- cursor pixel data
+        //     - src/main/winrt/SDL2-WinRTResources.rc             -- declares the cursor resource, and its ID (of 5000)
+        //
+
+        const unsigned int win32CursorResourceID = 5000;  
+        CoreCursor ^ blankCursor = ref new CoreCursor(CoreCursorType::Custom, win32CursorResourceID);
+
+        // Set 'PointerCursor' to 'blankCursor' in a way that shouldn't throw
+        // an exception if the app hasn't loaded that resource.
+        ABI::Windows::UI::Core::ICoreCursor * iblankCursor = reinterpret_cast<ABI::Windows::UI::Core::ICoreCursor *>(blankCursor);
+        ABI::Windows::UI::Core::ICoreWindow * icoreWindow = reinterpret_cast<ABI::Windows::UI::Core::ICoreWindow *>(coreWindow);
+        HRESULT hr = icoreWindow->put_PointerCursor(iblankCursor);
+        if (FAILED(hr)) {
+            // The app doesn't contain the cursor resource, or some other error
+            // occurred.  Just use the other, but mouse-motion-preventing, means of
+            // hiding the cursor.
+            coreWindow->PointerCursor = nullptr;
+        }
     }
     return 0;
 }

+ 9 - 3
modules/sdl2/SDL/src/video/winrt/SDL_winrtvideo.cpp

@@ -118,15 +118,13 @@ WINRT_CreateDevice(int devindex)
     device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
     if (!device) {
         SDL_OutOfMemory();
-        if (device) {
-            SDL_free(device);
-        }
         return (0);
     }
 
     data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
     if (!data) {
         SDL_OutOfMemory();
+        SDL_free(device);
         return (0);
     }
     SDL_zerop(data);
@@ -142,6 +140,14 @@ WINRT_CreateDevice(int devindex)
     device->SetDisplayMode = WINRT_SetDisplayMode;
     device->PumpEvents = WINRT_PumpEvents;
     device->GetWindowWMInfo = WINRT_GetWindowWMInfo;
+
+#if NTDDI_VERSION >= NTDDI_WIN10
+    device->HasScreenKeyboardSupport = WINRT_HasScreenKeyboardSupport;
+    device->ShowScreenKeyboard = WINRT_ShowScreenKeyboard;
+    device->HideScreenKeyboard = WINRT_HideScreenKeyboard;
+    device->IsScreenKeyboardShown = WINRT_IsScreenKeyboardShown;
+#endif
+
 #ifdef SDL_VIDEO_OPENGL_EGL
     device->GL_LoadLibrary = WINRT_GLES_LoadLibrary;
     device->GL_GetProcAddress = WINRT_GLES_GetProcAddress;

+ 0 - 15
modules/sdl2/SDL/src/video/x11/SDL_x11dyn.c

@@ -106,11 +106,8 @@ X11_GetSym(const char *fnname, int *pHasModule)
 #endif /* SDL_VIDEO_DRIVER_X11_DYNAMIC */
 
 /* Define all the function pointers and wrappers... */
-#define SDL_X11_MODULE(modname)
 #define SDL_X11_SYM(rc,fn,params,args,ret) SDL_DYNX11FN_##fn X11_##fn = NULL;
 #include "SDL_x11sym.h"
-#undef SDL_X11_MODULE
-#undef SDL_X11_SYM
 
 /* Annoying varargs entry point... */
 #ifdef X_HAVE_UTF8_STRING
@@ -120,10 +117,7 @@ SDL_DYNX11FN_XGetICValues X11_XGetICValues = NULL;
 
 /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
 #define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 0;
-#define SDL_X11_SYM(rc,fn,params,args,ret)
 #include "SDL_x11sym.h"
-#undef SDL_X11_MODULE
-#undef SDL_X11_SYM
 
 static int x11_load_refcount = 0;
 
@@ -139,8 +133,6 @@ SDL_X11_UnloadSymbols(void)
 #define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 0;
 #define SDL_X11_SYM(rc,fn,params,args,ret) X11_##fn = NULL;
 #include "SDL_x11sym.h"
-#undef SDL_X11_MODULE
-#undef SDL_X11_SYM
 
 #ifdef X_HAVE_UTF8_STRING
             X11_XCreateIC = NULL;
@@ -177,16 +169,11 @@ SDL_X11_LoadSymbols(void)
         }
 
 #define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1; /* default yes */
-#define SDL_X11_SYM(a,fn,x,y,z)
 #include "SDL_x11sym.h"
-#undef SDL_X11_MODULE
-#undef SDL_X11_SYM
 
 #define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
 #define SDL_X11_SYM(a,fn,x,y,z) X11_##fn = (SDL_DYNX11FN_##fn) X11_GetSym(#fn,thismod);
 #include "SDL_x11sym.h"
-#undef SDL_X11_MODULE
-#undef SDL_X11_SYM
 
 #ifdef X_HAVE_UTF8_STRING
         X11_XCreateIC = (SDL_DYNX11FN_XCreateIC)
@@ -209,8 +196,6 @@ SDL_X11_LoadSymbols(void)
 #define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1; /* default yes */
 #define SDL_X11_SYM(a,fn,x,y,z) X11_##fn = (SDL_DYNX11FN_##fn) fn;
 #include "SDL_x11sym.h"
-#undef SDL_X11_MODULE
-#undef SDL_X11_SYM
 
 #ifdef X_HAVE_UTF8_STRING
         X11_XCreateIC = XCreateIC;

+ 0 - 6
modules/sdl2/SDL/src/video/x11/SDL_x11dyn.h

@@ -86,13 +86,10 @@ int SDL_X11_LoadSymbols(void);
 void SDL_X11_UnloadSymbols(void);
 
 /* Declare all the function pointers and wrappers... */
-#define SDL_X11_MODULE(modname)
 #define SDL_X11_SYM(rc,fn,params,args,ret) \
     typedef rc (*SDL_DYNX11FN_##fn) params; \
     extern SDL_DYNX11FN_##fn X11_##fn;
 #include "SDL_x11sym.h"
-#undef SDL_X11_MODULE
-#undef SDL_X11_SYM
 
 /* Annoying varargs entry point... */
 #ifdef X_HAVE_UTF8_STRING
@@ -104,10 +101,7 @@ extern SDL_DYNX11FN_XGetICValues X11_XGetICValues;
 
 /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
 #define SDL_X11_MODULE(modname) extern int SDL_X11_HAVE_##modname;
-#define SDL_X11_SYM(rc,fn,params,args,ret)
 #include "SDL_x11sym.h"
-#undef SDL_X11_MODULE
-#undef SDL_X11_SYM
 
 #ifdef __cplusplus
 }

+ 20 - 24
modules/sdl2/SDL/src/video/x11/SDL_x11events.c

@@ -840,32 +840,10 @@ X11_DispatchEvent(_THIS)
                    xevent.xconfigure.x, xevent.xconfigure.y,
                    xevent.xconfigure.width, xevent.xconfigure.height);
 #endif
-            long border_left = 0;
-            long border_top = 0;
-            if (data->xwindow) {
-                Atom _net_frame_extents = X11_XInternAtom(display, "_NET_FRAME_EXTENTS", 0);
-                Atom type;
-                int format;
-                unsigned long nitems, bytes_after;
-                unsigned char *property;
-                if (X11_XGetWindowProperty(display, data->xwindow,
-                        _net_frame_extents, 0, 16, 0,
-                        XA_CARDINAL, &type, &format,
-                        &nitems, &bytes_after, &property) == Success) {
-                    if (type != None && nitems == 4)
-                    {
-                        border_left = ((long*)property)[0];
-                        border_top = ((long*)property)[2];
-                    }
-                    X11_XFree(property);
-                }
-            }
-
             if (xevent.xconfigure.x != data->last_xconfigure.x ||
                 xevent.xconfigure.y != data->last_xconfigure.y) {
                 SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED,
-                                    xevent.xconfigure.x - border_left,
-                                    xevent.xconfigure.y - border_top);
+                                    xevent.xconfigure.x, xevent.xconfigure.y);
 #ifdef SDL_USE_IBUS
                 if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){
                     /* Update IBus candidate list position */
@@ -1175,6 +1153,24 @@ X11_DispatchEvent(_THIS)
                    right approach, but it seems to work. */
                 X11_UpdateKeymap(_this);
                 SDL_SendKeymapChangedEvent();
+            } else if (xevent.xproperty.atom == videodata->_NET_FRAME_EXTENTS) {
+                Atom type;
+                int format;
+                unsigned long nitems, bytes_after;
+                unsigned char *property;
+                if (X11_XGetWindowProperty(display, data->xwindow, videodata->_NET_FRAME_EXTENTS, 0, 16, 0, XA_CARDINAL, &type, &format, &nitems, &bytes_after, &property) == Success) {
+                    if (type != None && nitems == 4) {
+                        data->border_left = (int) ((long*)property)[0];
+                        data->border_right = (int) ((long*)property)[1];
+                        data->border_top = (int) ((long*)property)[2];
+                        data->border_bottom = (int) ((long*)property)[3];
+                    }
+                    X11_XFree(property);
+
+                    #ifdef DEBUG_XEVENTS
+                    printf("New _NET_FRAME_EXTENTS: left=%d right=%d, top=%d, bottom=%d\n", data->border_left, data->border_right, data->border_top, data->border_bottom);
+                    #endif
+                }
             }
         }
         break;
@@ -1229,11 +1225,11 @@ X11_DispatchEvent(_THIS)
         break;
 
     case SelectionNotify: {
+            Atom target = xevent.xselection.target;
 #ifdef DEBUG_XEVENTS
             printf("window %p: SelectionNotify (requestor = %ld, target = %ld)\n", data,
                 xevent.xselection.requestor, xevent.xselection.target);
 #endif
-            Atom target = xevent.xselection.target;
             if (target == data->xdnd_req) {
                 /* read data */
                 SDL_x11Prop p;

+ 1 - 0
modules/sdl2/SDL/src/video/x11/SDL_x11keyboard.c

@@ -129,6 +129,7 @@ static const struct {
     { XK_Control_R, SDL_SCANCODE_RCTRL },
     { XK_Shift_R, SDL_SCANCODE_RSHIFT },
     { XK_Alt_R, SDL_SCANCODE_RALT },
+    { XK_ISO_Level3_Shift, SDL_SCANCODE_RALT },
     { XK_Meta_R, SDL_SCANCODE_RGUI },
     { XK_Super_R, SDL_SCANCODE_RGUI },
     { XK_Mode_switch, SDL_SCANCODE_MODE },

+ 1 - 1
modules/sdl2/SDL/src/video/x11/SDL_x11modes.c

@@ -1070,7 +1070,7 @@ X11_GetDisplayDPI(_THIS, SDL_VideoDisplay * sdl_display, float * ddpi, float * h
         *vdpi = data->vdpi;
     }
 
-    return data->ddpi != 0.0f ? 0 : -1;
+    return data->ddpi != 0.0f ? 0 : SDL_SetError("Couldn't get DPI");
 }
 
 int

Some files were not shown because too many files changed in this diff