Merge audio capture work back into the mainline. default tip
authorRyan C. Gordon <icculus@icculus.org>
Sun, 28 Aug 2016 13:36:13 -0400
changeset 10286 3b884985835c
parent 10267 b1f031450499 (current diff)
parent 10285 9859cda24699 (diff)
Merge audio capture work back into the mainline.
VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj
VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters
VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj
VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj.filters
VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj
VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters
VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj
VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj.filters
VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj
VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters
src/audio/alsa/SDL_alsa_audio.c
--- a/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj	Fri Aug 12 22:50:48 2016 -0400
+++ b/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj	Sun Aug 28 13:36:13 2016 -0400
@@ -155,6 +155,7 @@
     <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
     <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtevents_c.h" />
+    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtmouse_c.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtopengles.h" />
@@ -310,6 +311,14 @@
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
+    </ClCompile>
     <ClCompile Include="..\..\src\video\winrt\SDL_winrtkeyboard.cpp">
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
--- a/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters	Fri Aug 12 22:50:48 2016 -0400
+++ b/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters	Sun Aug 28 13:36:13 2016 -0400
@@ -399,6 +399,9 @@
     <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2.h">
       <Filter>Source Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\atomic\SDL_atomic.c">
@@ -713,5 +716,8 @@
     <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file
--- a/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj	Fri Aug 12 22:50:48 2016 -0400
+++ b/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj	Sun Aug 28 13:36:13 2016 -0400
@@ -272,6 +272,7 @@
     <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
     <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtevents_c.h" />
+    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtmouse_c.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtopengles.h" />
@@ -407,6 +408,12 @@
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+    </ClCompile>
     <ClCompile Include="..\..\src\video\winrt\SDL_winrtkeyboard.cpp">
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
--- a/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj.filters	Fri Aug 12 22:50:48 2016 -0400
+++ b/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj.filters	Sun Aug 28 13:36:13 2016 -0400
@@ -369,6 +369,9 @@
     <ClInclude Include="..\..\src\video\SDL_egl_c.h">
       <Filter>Source Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\atomic\SDL_atomic.c">
@@ -671,5 +674,8 @@
     <ClCompile Include="..\..\src\video\SDL_egl.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file
--- a/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj	Fri Aug 12 22:50:48 2016 -0400
+++ b/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj	Sun Aug 28 13:36:13 2016 -0400
@@ -138,6 +138,7 @@
     <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
     <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtevents_c.h" />
+    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtmouse_c.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtopengles.h" />
@@ -274,6 +275,12 @@
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+    </ClCompile>
     <ClCompile Include="..\..\src\video\winrt\SDL_winrtkeyboard.cpp">
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
--- a/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters	Fri Aug 12 22:50:48 2016 -0400
+++ b/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters	Sun Aug 28 13:36:13 2016 -0400
@@ -378,6 +378,9 @@
     <ClInclude Include="..\..\src\thread\windows\SDL_systhread_c.h">
       <Filter>Source Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\atomic\SDL_atomic.c">
@@ -683,5 +686,8 @@
     <ClCompile Include="..\..\src\thread\generic\SDL_syscond.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file
--- a/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj	Fri Aug 12 22:50:48 2016 -0400
+++ b/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj	Sun Aug 28 13:36:13 2016 -0400
@@ -175,6 +175,14 @@
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
+    </ClCompile>
     <ClCompile Include="..\..\src\video\winrt\SDL_winrtkeyboard.cpp">
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
@@ -352,6 +360,7 @@
     <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
     <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtevents_c.h" />
+    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtmouse_c.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtopengles.h" />
--- a/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj.filters	Fri Aug 12 22:50:48 2016 -0400
+++ b/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj.filters	Sun Aug 28 13:36:13 2016 -0400
@@ -316,6 +316,9 @@
     <ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\include\begin_code.h">
@@ -711,6 +714,9 @@
     <ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h">
       <Filter>Source Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="Header Files">
--- a/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj	Fri Aug 12 22:50:48 2016 -0400
+++ b/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj	Sun Aug 28 13:36:13 2016 -0400
@@ -152,6 +152,7 @@
     <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
     <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtevents_c.h" />
+    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtmouse_c.h" />
     <ClInclude Include="..\..\src\video\winrt\SDL_winrtopengles.h" />
@@ -308,6 +309,14 @@
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
+      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
+    </ClCompile>
     <ClCompile Include="..\..\src\video\winrt\SDL_winrtkeyboard.cpp">
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
       <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
--- a/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters	Fri Aug 12 22:50:48 2016 -0400
+++ b/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters	Sun Aug 28 13:36:13 2016 -0400
@@ -390,6 +390,9 @@
     <ClInclude Include="..\..\src\thread\windows\SDL_systhread_c.h">
       <Filter>Source Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\atomic\SDL_atomic.c">
@@ -707,5 +710,8 @@
     <ClCompile Include="..\..\src\thread\windows\SDL_syssem.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file
--- a/include/SDL.h	Fri Aug 12 22:50:48 2016 -0400
+++ b/include/SDL.h	Sun Aug 28 13:36:13 2016 -0400
@@ -95,8 +95,8 @@
  *  This function initializes specific SDL subsystems
  *
  *  Subsystem initialization is ref-counted, you must call
- *  SDL_QuitSubSystem for each SDL_InitSubSystem to correctly
- *  shutdown a subsystem manually (or call SDL_Quit to force shutdown).
+ *  SDL_QuitSubSystem() for each SDL_InitSubSystem() to correctly
+ *  shutdown a subsystem manually (or call SDL_Quit() to force shutdown).
  *  If a subsystem is already loaded then this call will
  *  increase the ref-count and return.
  */
--- a/include/SDL_gamecontroller.h	Fri Aug 12 22:50:48 2016 -0400
+++ b/include/SDL_gamecontroller.h	Sun Aug 28 13:36:13 2016 -0400
@@ -93,7 +93,7 @@
  *      }
  *  }
  *
- *  Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is:
+ *  Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping() you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is:
  *  guid,name,mappings
  *
  *  Where GUID is the string value from SDL_JoystickGetGUIDString(), name is the human readable string for the device and mappings are controller mappings to joystick ones.
@@ -136,14 +136,14 @@
 /**
  *  Get a mapping string for a GUID
  *
- *  \return the mapping string.  Must be freed with SDL_free.  Returns NULL if no mapping is available
+ *  \return the mapping string.  Must be freed with SDL_free().  Returns NULL if no mapping is available
  */
 extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForGUID( SDL_JoystickGUID guid );
 
 /**
  *  Get a mapping string for an open GameController
  *
- *  \return the mapping string.  Must be freed with SDL_free.  Returns NULL if no mapping is available
+ *  \return the mapping string.  Must be freed with SDL_free().  Returns NULL if no mapping is available
  */
 extern DECLSPEC char * SDLCALL SDL_GameControllerMapping( SDL_GameController * gamecontroller );
 
--- a/include/SDL_hints.h	Fri Aug 12 22:50:48 2016 -0400
+++ b/include/SDL_hints.h	Sun Aug 28 13:36:13 2016 -0400
@@ -431,7 +431,7 @@
  *  privacy policy.
  *
  *  To setup a URL to an app's privacy policy, set SDL_HINT_WINRT_PRIVACY_POLICY_URL
- *  before calling any SDL_Init functions.  The contents of the hint should
+ *  before calling any SDL_Init() functions.  The contents of the hint should
  *  be a valid URL.  For example, "http://www.example.com".
  *
  *  The default value is "", which will prevent SDL from adding a privacy policy
@@ -461,7 +461,7 @@
  *  The contents of this hint should be encoded as a UTF8 string.
  *
  *  The default value is "Privacy Policy".  This hint should only be set during app
- *  initialization, preferably before any calls to SDL_Init.
+ *  initialization, preferably before any calls to SDL_Init().
  *
  *  For additional information on linking to a privacy policy, see the documentation for
  *  SDL_HINT_WINRT_PRIVACY_POLICY_URL.
--- a/include/SDL_joystick.h	Fri Aug 12 22:50:48 2016 -0400
+++ b/include/SDL_joystick.h	Sun Aug 28 13:36:13 2016 -0400
@@ -24,7 +24,7 @@
  *
  *  Include file for SDL joystick event handling
  *
- * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks, with the exact joystick
+ * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks(), with the exact joystick
  *   behind a device_index changing as joysticks are plugged and unplugged.
  *
  * The term "instance_id" is the current instantiation of a joystick device in the system, if the joystick is removed and then re-inserted
--- a/include/SDL_keyboard.h	Fri Aug 12 22:50:48 2016 -0400
+++ b/include/SDL_keyboard.h	Sun Aug 28 13:36:13 2016 -0400
@@ -136,7 +136,7 @@
  *          copy it.  If the key doesn't have a name, this function returns an
  *          empty string ("").
  *
- *  \sa SDL_Key
+ *  \sa SDL_Keycode
  */
 extern DECLSPEC const char *SDLCALL SDL_GetKeyName(SDL_Keycode key);
 
--- a/include/SDL_mouse.h	Fri Aug 12 22:50:48 2016 -0400
+++ b/include/SDL_mouse.h	Sun Aug 28 13:36:13 2016 -0400
@@ -41,7 +41,7 @@
 typedef struct SDL_Cursor SDL_Cursor;   /* Implementation dependent */
 
 /**
- * \brief Cursor types for SDL_CreateSystemCursor.
+ * \brief Cursor types for SDL_CreateSystemCursor().
  */
 typedef enum
 {
--- a/include/SDL_video.h	Fri Aug 12 22:50:48 2016 -0400
+++ b/include/SDL_video.h	Sun Aug 28 13:36:13 2016 -0400
@@ -789,7 +789,7 @@
  *  \return 0 on success, or -1 on error.
  *
  *  \sa SDL_GetWindowSurface()
- *  \sa SDL_UpdateWindowSurfaceRect()
+ *  \sa SDL_UpdateWindowSurface()
  */
 extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window * window,
                                                          const SDL_Rect * rects,
--- a/src/audio/alsa/SDL_alsa_audio.c	Fri Aug 12 22:50:48 2016 -0400
+++ b/src/audio/alsa/SDL_alsa_audio.c	Sun Aug 28 13:36:13 2016 -0400
@@ -699,90 +699,196 @@
     return 0;
 }
 
+typedef struct ALSA_Device
+{
+    char *name;
+    SDL_bool iscapture;
+    struct ALSA_Device *next;
+} ALSA_Device;
+
 static void
-ALSA_Deinitialize(void)
+add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSeen)
 {
-    UnloadALSALibrary();
+    ALSA_Device *dev = SDL_malloc(sizeof (ALSA_Device));
+    char *desc = ALSA_snd_device_name_get_hint(hint, "DESC");
+    char *handle = NULL;
+    char *ptr;
+
+    if (!desc) {
+        SDL_free(dev);
+        return;
+    } else if (!dev) {
+        free(desc);
+        return;
+    }
+
+    SDL_assert(name != NULL);
+
+    /* some strings have newlines, like "HDA NVidia, HDMI 0\nHDMI Audio Output".
+       just chop the extra lines off, this seems to get a reasonable device
+       name without extra details. */
+    if ((ptr = strchr(desc, '\n')) != NULL) {
+        *ptr = '\0';
+    }
+
+    /*printf("ALSA: adding %s device '%s' (%s)\n", iscapture ? "capture" : "output", name, desc);*/
+
+    handle = SDL_strdup(name);
+    if (!handle) {
+        free(desc);
+        SDL_free(dev);
+        return;
+    }
+
+    SDL_AddAudioDevice(iscapture, desc, handle);
+    free(desc);
+
+    dev->name = handle;
+    dev->iscapture = iscapture;
+    dev->next = *pSeen;
+    *pSeen = dev;
 }
 
-static void
-add_device(const int iscapture, const char *name, const char *_desc)
+
+static SDL_atomic_t ALSA_hotplug_shutdown;
+static SDL_Thread *ALSA_hotplug_thread;
+
+static int SDLCALL
+ALSA_HotplugThread(void *arg)
 {
-    char *desc = NULL;
-    char *handle = NULL;
-    char *ptr = NULL;
+    SDL_sem *first_run_semaphore = (SDL_sem *) arg;
+    ALSA_Device *devices = NULL;
+    ALSA_Device *next;
+    ALSA_Device *dev;
+    Uint32 ticks;
 
-    if (!name || !_desc) {
-        return;  /* nothing we can do with this...? */
+    while (!SDL_AtomicGet(&ALSA_hotplug_shutdown)) {
+        void **hints = NULL;
+        if (ALSA_snd_device_name_hint(-1, "pcm", &hints) != -1) {
+            ALSA_Device *unseen = devices;
+            ALSA_Device *seen = NULL;
+            ALSA_Device *prev;
+            int i;
+
+            for (i = 0; hints[i]; i++) {
+                char *name = ALSA_snd_device_name_get_hint(hints[i], "NAME");
+                if (!name) {
+                    continue;
+                }
+
+                /* only want physical hardware interfaces */
+                if (SDL_strncmp(name, "hw:", 3) == 0) {
+                    char *ioid = ALSA_snd_device_name_get_hint(hints[i], "IOID");
+                    const SDL_bool isoutput = (ioid == NULL) || (SDL_strcmp(ioid, "Output") == 0);
+                    const SDL_bool isinput = (ioid == NULL) || (SDL_strcmp(ioid, "Input") == 0);
+                    SDL_bool have_output = SDL_FALSE;
+                    SDL_bool have_input = SDL_FALSE;
+
+                    free(ioid);
+
+                    if (!isoutput && !isinput) {
+                        free(name);
+                        continue;
+                    }
+
+                    prev = NULL;
+                    for (dev = unseen; dev; dev = next) {
+                        next = dev->next;
+                        if ( (SDL_strcmp(dev->name, name) == 0) && (((isinput) && dev->iscapture) || ((isoutput) && !dev->iscapture)) ) {
+                            if (prev) {
+                                prev->next = next;
+                            } else {
+                                unseen = next;
+                            }
+                            dev->next = seen;
+                            seen = dev;
+                            if (isinput) have_input = SDL_TRUE;
+                            if (isoutput) have_output = SDL_TRUE;
+                        } else {
+                            prev = dev;
+                        }
+                    }
+
+                    if (isinput && !have_input) {
+                        add_device(SDL_TRUE, name, hints[i], &seen);
+                    }
+                    if (isoutput && !have_output) {
+                        add_device(SDL_FALSE, name, hints[i], &seen);
+                    }
+                }
+
+                free(name);
+            }
+
+            ALSA_snd_device_name_free_hint(hints);
+
+            devices = seen;   /* now we have a known-good list of attached devices. */
+
+            /* report anything still in unseen as removed. */
+            for (dev = unseen; dev; dev = next) {
+                /*printf("ALSA: removing %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/
+                next = dev->next;
+                SDL_RemoveAudioDevice(dev->iscapture, dev->name);
+                SDL_free(dev->name);
+                SDL_free(dev);
+            }
+        }
+
+        /* On first run, tell ALSA_DetectDevices() that we have a complete device list so it can return. */
+        if (first_run_semaphore) {
+            SDL_SemPost(first_run_semaphore);
+            first_run_semaphore = NULL;  /* let other thread clean it up. */
+        }
+
+        /* Block awhile before checking again, unless we're told to stop. */
+        ticks = SDL_GetTicks() + 5000;
+        while (!SDL_AtomicGet(&ALSA_hotplug_shutdown) && !SDL_TICKS_PASSED(SDL_GetTicks(), ticks)) {
+            SDL_Delay(100);
+        }
     }
 
-    desc = SDL_strdup(_desc);
-    if (!desc) {
-        return;  /* oh well, out of memory. Skip it. */
+    /* Shutting down! Clean up any data we've gathered. */
+    for (dev = devices; dev; dev = next) {
+        /*printf("ALSA: at shutdown, removing %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/
+        next = dev->next;
+        SDL_free(dev->name);
+        SDL_free(dev);
     }
 
-    /* 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);
+    return 0;
 }
 
 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) {
+    /* Start the device detection thread here, wait for an initial iteration to complete. */
+    SDL_sem *semaphore = SDL_CreateSemaphore(0);
+    if (!semaphore) {
         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");
+    SDL_AtomicSet(&ALSA_hotplug_shutdown, 0);
 
-        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_hotplug_thread = SDL_CreateThread(ALSA_HotplugThread, "SDLHotplugALSA", semaphore);
+    if (ALSA_hotplug_thread) {
+        SDL_SemWait(semaphore);  /* wait for the first iteration to finish. */
     }
 
-    ALSA_snd_device_name_free_hint(hints);
-#else
-#error Fill in udev support here.
-#endif
+    SDL_DestroySemaphore(semaphore);
 }
 
 static void
-ALSA_FreeDeviceHandle(void *handle)
+ALSA_Deinitialize(void)
 {
-#if 1 /*!SDL_USE_LIBUDEV*/
-    SDL_free(handle);
-#else
-#error Fill in udev support here.
-#endif
+    if (ALSA_hotplug_thread != NULL) {
+        SDL_AtomicSet(&ALSA_hotplug_shutdown, 1);
+        SDL_WaitThread(ALSA_hotplug_thread, NULL);
+        ALSA_hotplug_thread = NULL;
+    }
+
+    UnloadALSALibrary();
 }
 
-
 static int
 ALSA_Init(SDL_AudioDriverImpl * impl)
 {
@@ -798,7 +904,6 @@
     impl->PlayDevice = ALSA_PlayDevice;
     impl->CloseDevice = ALSA_CloseDevice;
     impl->Deinitialize = ALSA_Deinitialize;
-    impl->FreeDeviceHandle = ALSA_FreeDeviceHandle;
     impl->CaptureFromDevice = ALSA_CaptureFromDevice;
     impl->FlushCapture = ALSA_FlushCapture;
 
--- a/src/joystick/SDL_gamecontroller.c	Fri Aug 12 22:50:48 2016 -0400
+++ b/src/joystick/SDL_gamecontroller.c	Sun Aug 28 13:36:13 2016 -0400
@@ -106,6 +106,35 @@
 int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state);
 
 /*
+ * If there is an existing add event in the queue, it needs to be modified
+ * to have the right value for which, because the number of controllers in
+ * the system is now one less.
+ */
+static void UpdateEventsForDeviceRemoval()
+{
+    int i, num_events;
+    SDL_Event *events;
+
+    num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEADDED);
+    if (num_events <= 0) {
+        return;
+    }
+
+    events = SDL_stack_alloc(SDL_Event, num_events);
+    if (!events) {
+        return;
+    }
+
+    num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEADDED);
+    for (i = 0; i < num_events; ++i) {
+        --events[i].cdevice.which;
+    }
+    SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
+
+    SDL_stack_free(events);
+}
+
+/*
  * Event filter to fire controller events from joystick ones
  */
 int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event)
@@ -223,9 +252,12 @@
             while (controllerlist) {
                 if (controllerlist->joystick->instance_id == event->jdevice.which) {
                     SDL_Event deviceevent;
+
                     deviceevent.type = SDL_CONTROLLERDEVICEREMOVED;
                     deviceevent.cdevice.which = event->jdevice.which;
                     SDL_PushEvent(&deviceevent);
+
+                    UpdateEventsForDeviceRemoval();
                     break;
                 }
                 controllerlist = controllerlist->next;
--- a/src/joystick/SDL_joystick.c	Fri Aug 12 22:50:48 2016 -0400
+++ b/src/joystick/SDL_joystick.c	Sun Aug 28 13:36:13 2016 -0400
@@ -497,6 +497,71 @@
 
 /* These are global for SDL_sysjoystick.c and SDL_events.c */
 
+void SDL_PrivateJoystickAdded(int device_index)
+{
+#if !SDL_EVENTS_DISABLED
+    SDL_Event event;
+
+    event.type = SDL_JOYDEVICEADDED;
+
+    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
+        event.jdevice.which = device_index;
+        if ( (SDL_EventOK == NULL) ||
+             (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
+            SDL_PushEvent(&event);
+        }
+    }
+#endif /* !SDL_EVENTS_DISABLED */
+}
+
+/*
+ * If there is an existing add event in the queue, it needs to be modified
+ * to have the right value for which, because the number of controllers in
+ * the system is now one less.
+ */
+static void UpdateEventsForDeviceRemoval()
+{
+    int i, num_events;
+    SDL_Event *events;
+
+    num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEADDED);
+    if (num_events <= 0) {
+        return;
+    }
+
+    events = SDL_stack_alloc(SDL_Event, num_events);
+    if (!events) {
+        return;
+    }
+
+    num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEADDED);
+    for (i = 0; i < num_events; ++i) {
+        --events[i].jdevice.which;
+    }
+    SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
+
+    SDL_stack_free(events);
+}
+
+void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
+{
+#if !SDL_EVENTS_DISABLED
+    SDL_Event event;
+
+    event.type = SDL_JOYDEVICEREMOVED;
+
+    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
+        event.jdevice.which = device_instance;
+        if ( (SDL_EventOK == NULL) ||
+             (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
+            SDL_PushEvent(&event);
+        }
+    }
+
+    UpdateEventsForDeviceRemoval();
+#endif /* !SDL_EVENTS_DISABLED */
+}
+
 int
 SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value)
 {
--- a/src/joystick/SDL_joystick_c.h	Fri Aug 12 22:50:48 2016 -0400
+++ b/src/joystick/SDL_joystick_c.h	Sun Aug 28 13:36:13 2016 -0400
@@ -33,6 +33,8 @@
 
 
 /* Internal event queueing functions */
+extern void SDL_PrivateJoystickAdded(int device_index);
+extern void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance);
 extern int SDL_PrivateJoystickAxis(SDL_Joystick * joystick,
                                    Uint8 axis, Sint16 value);
 extern int SDL_PrivateJoystickBall(SDL_Joystick * joystick,
@@ -41,8 +43,8 @@
                                   Uint8 hat, Uint8 value);
 extern int SDL_PrivateJoystickButton(SDL_Joystick * joystick,
                                      Uint8 button, Uint8 state);
-extern void SDL_PrivateJoystickBatteryLevel( SDL_Joystick * joystick,
-    SDL_JoystickPowerLevel ePowerLevel );
+extern void SDL_PrivateJoystickBatteryLevel(SDL_Joystick * joystick,
+                                            SDL_JoystickPowerLevel ePowerLevel);
 
 /* Internal sanity checking functions */
 extern int SDL_PrivateJoystickValid(SDL_Joystick * joystick);
--- a/src/joystick/android/SDL_sysjoystick.c	Fri Aug 12 22:50:48 2016 -0400
+++ b/src/joystick/android/SDL_sysjoystick.c	Sun Aug 28 13:36:13 2016 -0400
@@ -27,10 +27,6 @@
 #include "SDL_error.h"
 #include "SDL_events.h"
 
-#if !SDL_EVENTS_DISABLED
-#include "../../events/SDL_events_c.h"
-#endif
-
 #include "SDL_joystick.h"
 #include "SDL_hints.h"
 #include "SDL_assert.h"
@@ -252,9 +248,6 @@
 {
     SDL_JoystickGUID guid;
     SDL_joylist_item *item;
-#if !SDL_EVENTS_DISABLED
-    SDL_Event event;
-#endif
     
     if(JoystickByDeviceId(device_id) != NULL || name == NULL) {
         return -1;
@@ -299,17 +292,7 @@
     /* Need to increment the joystick count before we post the event */
     ++numjoysticks;
 
-#if !SDL_EVENTS_DISABLED
-    event.type = SDL_JOYDEVICEADDED;
-
-    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
-        event.jdevice.which = (numjoysticks - 1);
-        if ( (SDL_EventOK == NULL) ||
-             (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
-            SDL_PushEvent(&event);
-        }
-    }
-#endif /* !SDL_EVENTS_DISABLED */
+    SDL_PrivateJoystickAdded(numjoysticks - 1);
 
 #ifdef DEBUG_JOYSTICK
     SDL_Log("Added joystick %s with device_id %d", name, device_id);
@@ -323,9 +306,6 @@
 {
     SDL_joylist_item *item = SDL_joylist;
     SDL_joylist_item *prev = NULL;
-#if !SDL_EVENTS_DISABLED
-    SDL_Event event;
-#endif
     
     /* Don't call JoystickByDeviceId here or there'll be an infinite loop! */
     while (item != NULL) {
@@ -357,17 +337,7 @@
     /* Need to decrement the joystick count before we post the event */
     --numjoysticks;
 
-#if !SDL_EVENTS_DISABLED
-    event.type = SDL_JOYDEVICEREMOVED;
-
-    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
-        event.jdevice.which = item->device_instance;
-        if ( (SDL_EventOK == NULL) ||
-             (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
-            SDL_PushEvent(&event);
-        }
-    }
-#endif /* !SDL_EVENTS_DISABLED */
+    SDL_PrivateJoystickRemoved(item->device_instance);
 
 #ifdef DEBUG_JOYSTICK
     SDL_Log("Removed joystick with device_id %d", device_id);
@@ -538,6 +508,10 @@
 void
 SDL_SYS_JoystickClose(SDL_Joystick * joystick)
 {
+    SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata;
+    if (item) {
+        item->joystick = NULL;
+    }
 }
 
 /* Function to perform any system-specific joystick related cleanup */
--- a/src/joystick/darwin/SDL_sysjoystick.c	Fri Aug 12 22:50:48 2016 -0400
+++ b/src/joystick/darwin/SDL_sysjoystick.c	Sun Aug 28 13:36:13 2016 -0400
@@ -34,9 +34,6 @@
 #include "SDL_sysjoystick_c.h"
 #include "SDL_events.h"
 #include "../../haptic/darwin/SDL_syshaptic_c.h"    /* For haptic hot plugging */
-#if !SDL_EVENTS_DISABLED
-#include "../../events/SDL_events_c.h"
-#endif
 
 #define SDL_JOYSTICK_RUNLOOP_MODE CFSTR("SDLJoystick")
 
@@ -154,21 +151,7 @@
     MacHaptic_MaybeRemoveDevice(device->ffservice);
 #endif
 
-/* !!! FIXME: why isn't there an SDL_PrivateJoyDeviceRemoved()? */
-#if !SDL_EVENTS_DISABLED
-    {
-        SDL_Event event;
-        event.type = SDL_JOYDEVICEREMOVED;
-
-        if (SDL_GetEventState(event.type) == SDL_ENABLE) {
-            event.jdevice.which = device->instance_id;
-            if ((SDL_EventOK == NULL)
-                || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
-                SDL_PushEvent(&event);
-            }
-        }
-    }
-#endif /* !SDL_EVENTS_DISABLED */
+    SDL_PrivateJoystickRemoved(device->instance_id);
 }
 
 
@@ -249,6 +232,7 @@
                             case kHIDUsage_GD_DPadLeft:
                             case kHIDUsage_GD_Start:
                             case kHIDUsage_GD_Select:
+                            case kHIDUsage_GD_SystemMainMenu:
                                 if (!ElementAlreadyAdded(cookie, pDevice->firstButton)) {
                                     element = (recElement *) SDL_calloc(1, sizeof (recElement));
                                     if (element) {
@@ -475,21 +459,7 @@
         ++device_index;  /* bump by one since we counted by pNext. */
     }
 
-/* !!! FIXME: why isn't there an SDL_PrivateJoyDeviceAdded()? */
-#if !SDL_EVENTS_DISABLED
-    {
-        SDL_Event event;
-        event.type = SDL_JOYDEVICEADDED;
-
-        if (SDL_GetEventState(event.type) == SDL_ENABLE) {
-            event.jdevice.which = device_index;
-            if ((SDL_EventOK == NULL)
-                || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
-                SDL_PushEvent(&event);
-            }
-        }
-    }
-#endif /* !SDL_EVENTS_DISABLED */
+    SDL_PrivateJoystickAdded(device_index);
 }
 
 static SDL_bool
--- a/src/joystick/emscripten/SDL_sysjoystick.c	Fri Aug 12 22:50:48 2016 -0400
+++ b/src/joystick/emscripten/SDL_sysjoystick.c	Sun Aug 28 13:36:13 2016 -0400
@@ -27,10 +27,6 @@
 #include "SDL_error.h"
 #include "SDL_events.h"
 
-#if !SDL_EVENTS_DISABLED
-#include "../../events/SDL_events_c.h"
-#endif
-
 #include "SDL_joystick.h"
 #include "SDL_hints.h"
 #include "SDL_assert.h"
@@ -57,10 +53,6 @@
       return 1;
     }
 
-#if !SDL_EVENTS_DISABLED
-    SDL_Event event;
-#endif
-
     item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item));
     if (item == NULL) {
         return 1;
@@ -105,20 +97,12 @@
     }
 
     ++numjoysticks;
+
+    SDL_PrivateJoystickAdded(numjoysticks - 1);
+
 #ifdef DEBUG_JOYSTICK
     SDL_Log("Number of joysticks is %d", numjoysticks);
 #endif
-#if !SDL_EVENTS_DISABLED
-    event.type = SDL_JOYDEVICEADDED;
-
-    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
-        event.jdevice.which = numjoysticks - 1;
-        if ( (SDL_EventOK == NULL) ||
-             (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
-            SDL_PushEvent(&event);
-        }
-    }
-#endif /* !SDL_EVENTS_DISABLED */
 
 #ifdef DEBUG_JOYSTICK
     SDL_Log("Added joystick with index %d", item->index);
@@ -132,9 +116,6 @@
 {
     SDL_joylist_item *item = SDL_joylist;
     SDL_joylist_item *prev = NULL;
-#if !SDL_EVENTS_DISABLED
-    SDL_Event event;
-#endif
 
     while (item != NULL) {
         if (item->index == gamepadEvent->index) {
@@ -165,17 +146,7 @@
     /* Need to decrement the joystick count before we post the event */
     --numjoysticks;
 
-#if !SDL_EVENTS_DISABLED
-    event.type = SDL_JOYDEVICEREMOVED;
-
-    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
-        event.jdevice.which = item->device_instance;
-        if ( (SDL_EventOK == NULL) ||
-             (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
-            SDL_PushEvent(&event);
-        }
-    }
-#endif /* !SDL_EVENTS_DISABLED */
+	SDL_PrivateJoystickRemoved(item->device_instance);
 
 #ifdef DEBUG_JOYSTICK
     SDL_Log("Removed joystick with id %d", item->device_instance);
@@ -377,6 +348,10 @@
 void
 SDL_SYS_JoystickClose(SDL_Joystick * joystick)
 {
+    SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata;
+    if (item) {
+        item->joystick = NULL;
+    }
 }
 
 /* Function to perform any system-specific joystick related cleanup */
--- a/src/joystick/iphoneos/SDL_sysjoystick.m	Fri Aug 12 22:50:48 2016 -0400
+++ b/src/joystick/iphoneos/SDL_sysjoystick.m	Sun Aug 28 13:36:13 2016 -0400
@@ -26,16 +26,13 @@
 /* needed for SDL_IPHONE_MAX_GFORCE macro */
 #include "SDL_config_iphoneos.h"
 
+#include "SDL_events.h"
 #include "SDL_joystick.h"
 #include "SDL_hints.h"
 #include "SDL_stdinc.h"
 #include "../SDL_sysjoystick.h"
 #include "../SDL_joystick_c.h"
 
-#if !SDL_EVENTS_DISABLED
-#include "../../events/SDL_events_c.h"
-#endif
-
 #import <CoreMotion/CoreMotion.h>
 
 #ifdef SDL_JOYSTICK_MFI
@@ -127,9 +124,6 @@
 SDL_SYS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
 {
     SDL_JoystickDeviceItem *device = deviceList;
-#if !SDL_EVENTS_DISABLED
-    SDL_Event event;
-#endif
 
     while (device != NULL) {
         if (device->controller == controller) {
@@ -172,17 +166,7 @@
 
     ++numjoysticks;
 
-#if !SDL_EVENTS_DISABLED
-    event.type = SDL_JOYDEVICEADDED;
-
-    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
-        event.jdevice.which = numjoysticks - 1;
-        if ((SDL_EventOK == NULL) ||
-            (*SDL_EventOK)(SDL_EventOKParam, &event)) {
-            SDL_PushEvent(&event);
-        }
-    }
-#endif /* !SDL_EVENTS_DISABLED */
+    SDL_PrivateJoystickAdded(numjoysticks - 1);
 }
 
 static SDL_JoystickDeviceItem *
@@ -191,9 +175,6 @@
     SDL_JoystickDeviceItem *prev = NULL;
     SDL_JoystickDeviceItem *next = NULL;
     SDL_JoystickDeviceItem *item = deviceList;
-#if !SDL_EVENTS_DISABLED
-    SDL_Event event;
-#endif
 
     if (device == NULL) {
         return NULL;
@@ -234,17 +215,7 @@
 
     --numjoysticks;
 
-#if !SDL_EVENTS_DISABLED
-    event.type = SDL_JOYDEVICEREMOVED;
-
-    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
-        event.jdevice.which = device->instance_id;
-        if ((SDL_EventOK == NULL) ||
-            (*SDL_EventOK)(SDL_EventOKParam, &event)) {
-            SDL_PushEvent(&event);
-        }
-    }
-#endif /* !SDL_EVENTS_DISABLED */
+	SDL_PrivateJoystickRemoved(device->instance_id);
 
     SDL_free(device->name);
     SDL_free(device);
--- a/src/joystick/linux/SDL_sysjoystick.c	Fri Aug 12 22:50:48 2016 -0400
+++ b/src/joystick/linux/SDL_sysjoystick.c	Sun Aug 28 13:36:13 2016 -0400
@@ -42,11 +42,6 @@
 #include "../SDL_joystick_c.h"
 #include "SDL_sysjoystick_c.h"
 
-/* !!! FIXME: move this somewhere else. */
-#if !SDL_EVENTS_DISABLED
-#include "../../events/SDL_events_c.h"
-#endif
-
 /* This isn't defined in older Linux kernel headers */
 #ifndef SYN_DROPPED
 #define SYN_DROPPED 3
@@ -176,9 +171,6 @@
     char namebuf[128];
     SDL_JoystickGUID guid;
     SDL_joylist_item *item;
-#if !SDL_EVENTS_DISABLED
-    SDL_Event event;
-#endif
 
     if (path == NULL) {
         return -1;
@@ -239,18 +231,7 @@
     /* Need to increment the joystick count before we post the event */
     ++numjoysticks;
 
-    /* !!! FIXME: Move this to an SDL_PrivateJoyDeviceAdded() function? */
-#if !SDL_EVENTS_DISABLED
-    event.type = SDL_JOYDEVICEADDED;
-
-    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
-        event.jdevice.which = (numjoysticks - 1);
-        if ( (SDL_EventOK == NULL) ||
-             (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
-            SDL_PushEvent(&event);
-        }
-    }
-#endif /* !SDL_EVENTS_DISABLED */
+    SDL_PrivateJoystickAdded(numjoysticks - 1);
 
     return numjoysticks;
 }
@@ -262,9 +243,6 @@
 {
     SDL_joylist_item *item;
     SDL_joylist_item *prev = NULL;
-#if !SDL_EVENTS_DISABLED
-    SDL_Event event;
-#endif
 
     if (path == NULL) {
         return -1;
@@ -290,18 +268,7 @@
             /* Need to decrement the joystick count before we post the event */
             --numjoysticks;
 
-            /* !!! FIXME: Move this to an SDL_PrivateJoyDeviceRemoved() function? */
-#if !SDL_EVENTS_DISABLED
-            event.type = SDL_JOYDEVICEREMOVED;
-
-            if (SDL_GetEventState(event.type) == SDL_ENABLE) {
-                event.jdevice.which = item->device_instance;
-                if ( (SDL_EventOK == NULL) ||
-                     (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
-                    SDL_PushEvent(&event);
-                }
-            }
-#endif /* !SDL_EVENTS_DISABLED */
+            SDL_PrivateJoystickRemoved(item->device_instance);
 
             SDL_free(item->path);
             SDL_free(item->name);
--- a/src/joystick/windows/SDL_dinputjoystick.c	Fri Aug 12 22:50:48 2016 -0400
+++ b/src/joystick/windows/SDL_dinputjoystick.c	Sun Aug 28 13:36:13 2016 -0400
@@ -240,11 +240,23 @@
     static GUID IID_ValveStreamingGamepad = { MAKELONG(0x28DE, 0x11FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
     static GUID IID_X360WiredGamepad = { MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
     static GUID IID_X360WirelessGamepad = { MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
+    static GUID IID_XOneWiredGamepad = { MAKELONG(0x045E, 0x02FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
+    static GUID IID_XOneWirelessGamepad = { MAKELONG(0x045E, 0x02DD), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
+    static GUID IID_XOneNewWirelessGamepad = { MAKELONG(0x045E, 0x02D1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
+    static GUID IID_XOneSWirelessGamepad = { MAKELONG(0x045E, 0x02EA), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
+    static GUID IID_XOneSBluetoothGamepad = { MAKELONG(0x045E, 0x02E0), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
+    static GUID IID_XOneEliteWirelessGamepad = { MAKELONG(0x045E, 0x02E3), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
 
     static const GUID *s_XInputProductGUID[] = {
         &IID_ValveStreamingGamepad,
-        &IID_X360WiredGamepad,   /* Microsoft's wired X360 controller for Windows. */
-        &IID_X360WirelessGamepad /* Microsoft's wireless X360 controller for Windows. */
+        &IID_X360WiredGamepad,         /* Microsoft's wired X360 controller for Windows. */
+        &IID_X360WirelessGamepad,      /* Microsoft's wireless X360 controller for Windows. */
+        &IID_XOneWiredGamepad,         /* Microsoft's wired Xbox One controller for Windows. */
+        &IID_XOneWirelessGamepad,      /* Microsoft's wireless Xbox One controller for Windows. */
+        &IID_XOneNewWirelessGamepad,   /* Microsoft's updated wireless Xbox One controller (w/ 3.5 mm jack) for Windows. */
+        &IID_XOneSWirelessGamepad,     /* Microsoft's wireless Xbox One S controller for Windows. */
+        &IID_XOneSBluetoothGamepad,    /* Microsoft's Bluetooth Xbox One S controller for Windows. */
+        &IID_XOneEliteWirelessGamepad  /* Microsoft's wireless Xbox One Elite controller for Windows. */
     };
 
     size_t iDevice;
--- a/src/joystick/windows/SDL_windowsjoystick.c	Fri Aug 12 22:50:48 2016 -0400
+++ b/src/joystick/windows/SDL_windowsjoystick.c	Sun Aug 28 13:36:13 2016 -0400
@@ -42,9 +42,6 @@
 #include "SDL_joystick.h"
 #include "../SDL_sysjoystick.h"
 #include "../../thread/SDL_systhread.h"
-#if !SDL_EVENTS_DISABLED
-#include "../../events/SDL_events_c.h"
-#endif
 #include "../../core/windows/SDL_windows.h"
 #if !defined(__WINRT__)
 #include <dbt.h>
@@ -327,9 +324,6 @@
 SDL_SYS_JoystickDetect()
 {
     JoyStick_DeviceData *pCurList = NULL;
-#if !SDL_EVENTS_DISABLED
-    SDL_Event event;
-#endif
 
     /* only enum the devices if the joystick thread told us something changed */
     if (!s_bDeviceAdded && !s_bDeviceRemoved) {
@@ -361,17 +355,7 @@
             SDL_DINPUT_MaybeRemoveDevice(&pCurList->dxdevice);
         }
 
-#if !SDL_EVENTS_DISABLED
-        SDL_zero(event);
-        event.type = SDL_JOYDEVICEREMOVED;
-
-        if (SDL_GetEventState(event.type) == SDL_ENABLE) {
-            event.jdevice.which = pCurList->nInstanceID;
-            if ((!SDL_EventOK) || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
-                SDL_PushEvent(&event);
-            }
-        }
-#endif /* !SDL_EVENTS_DISABLED */
+        SDL_PrivateJoystickRemoved(pCurList->nInstanceID);
 
         pListNext = pCurList->pNext;
         SDL_free(pCurList->joystickname);
@@ -392,17 +376,8 @@
                     SDL_DINPUT_MaybeAddDevice(&pNewJoystick->dxdevice);
                 }
 
-#if !SDL_EVENTS_DISABLED
-                SDL_zero(event);
-                event.type = SDL_JOYDEVICEADDED;
+                SDL_PrivateJoystickAdded(device_index);
 
-                if (SDL_GetEventState(event.type) == SDL_ENABLE) {
-                    event.jdevice.which = device_index;
-                    if ((!SDL_EventOK) || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
-                        SDL_PushEvent(&event);
-                    }
-                }
-#endif /* !SDL_EVENTS_DISABLED */
                 pNewJoystick->send_add_event = SDL_FALSE;
             }
             device_index++;
--- a/src/video/psp/SDL_pspvideo.c	Fri Aug 12 22:50:48 2016 -0400
+++ b/src/video/psp/SDL_pspvideo.c	Sun Aug 28 13:36:13 2016 -0400
@@ -92,6 +92,7 @@
     if (gldata == NULL) {
         SDL_OutOfMemory();
         SDL_free(device);
+        SDL_free(phdata);
         return NULL;
     }
     device->gl_data = gldata;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/winrt/SDL_winrtgamebar.cpp	Sun Aug 28 13:36:13 2016 -0400
@@ -0,0 +1,196 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
+
+  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"
+
+#if SDL_VIDEO_DRIVER_WINRT
+
+/* Windows includes */
+#include <roapi.h>
+#include <windows.foundation.h>
+#include <EventToken.h>
+
+
+/* SDL includes */
+extern "C" {
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+}
+#include "SDL_winrtvideo_cpp.h"
+
+
+/* Game Bar events can come in off the main thread.  Use the following
+   WinRT CoreDispatcher to deal with them on SDL's thread.
+*/
+static Platform::WeakReference WINRT_MainThreadDispatcher;
+
+
+/* Win10's initial SDK (the 10.0.10240.0 release) does not include references
+   to Game Bar APIs, as the Game Bar was released via Win10 10.0.10586.0.
+
+   Declare its WinRT/COM interface here, to allow compilation with earlier
+   Windows SDKs.
+*/
+MIDL_INTERFACE("1DB9A292-CC78-4173-BE45-B61E67283EA7")
+IGameBarStatics_ : public IInspectable
+{
+public:
+    virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged( 
+        __FIEventHandler_1_IInspectable *handler,
+        Windows::Foundation::EventRegistrationToken *token) = 0;
+    
+    virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged( 
+        Windows::Foundation::EventRegistrationToken token) = 0;
+    
+    virtual HRESULT STDMETHODCALLTYPE add_IsInputRedirectedChanged( 
+        __FIEventHandler_1_IInspectable *handler,
+        Windows::Foundation::EventRegistrationToken *token) = 0;
+    
+    virtual HRESULT STDMETHODCALLTYPE remove_IsInputRedirectedChanged( 
+        Windows::Foundation::EventRegistrationToken token) = 0;
+    
+    virtual HRESULT STDMETHODCALLTYPE get_Visible( 
+        boolean *value) = 0;
+    
+    virtual HRESULT STDMETHODCALLTYPE get_IsInputRedirected( 
+        boolean *value) = 0;
+};
+
+/* Declare the game bar's COM GUID */
+static GUID IID_IGameBarStatics_ = { MAKELONG(0xA292, 0x1DB9), 0xCC78, 0x4173, { 0xBE, 0x45, 0xB6, 0x1E, 0x67, 0x28, 0x3E, 0xA7 } };
+
+/* Retrieves a pointer to the game bar, or NULL if it is not available.
+   If a pointer is returned, it's ->Release() method must be called
+   after the caller has finished using it.
+*/
+static IGameBarStatics_ *
+WINRT_GetGameBar()
+{
+    wchar_t *wClassName = L"Windows.Gaming.UI.GameBar";
+    HSTRING hClassName;
+    IActivationFactory *pActivationFactory = NULL;
+    IGameBarStatics_ *pGameBar = NULL;
+    HRESULT hr;
+
+    hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName);
+    if (FAILED(hr)) {
+        goto done;
+    }
+
+    hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory);
+    if (FAILED(hr)) {
+        goto done;
+    }
+
+    pActivationFactory->QueryInterface(IID_IGameBarStatics_, (void **) &pGameBar);
+
+done:
+    if (pActivationFactory) {
+        pActivationFactory->Release();
+    }
+    if (hClassName) {
+        ::WindowsDeleteString(hClassName);
+    }
+    return pGameBar;
+}
+
+static void
+WINRT_HandleGameBarIsInputRedirected_MainThread()
+{
+    IGameBarStatics_ *gameBar;
+    boolean isInputRedirected = 0;
+    if (!WINRT_MainThreadDispatcher) {
+        /* The game bar event handler has been deregistered! */
+        return;
+    }
+    gameBar = WINRT_GetGameBar();
+    if (!gameBar) {
+        /* Shouldn't happen, but just in case... */
+        return;
+    }
+    if (SUCCEEDED(gameBar->get_IsInputRedirected(&isInputRedirected))) {
+        if ( ! isInputRedirected) {
+            /* Input-control is now back to the SDL app. Restore the cursor,
+               in case Windows does not (it does not in either Win10
+               10.0.10240.0 or 10.0.10586.0, maybe later version(s) too.
+            */
+            SDL_Cursor *cursor = SDL_GetCursor();
+            SDL_SetCursor(cursor);
+        }
+    }
+    gameBar->Release();
+}
+
+static void
+WINRT_HandleGameBarIsInputRedirected_NonMainThread(Platform::Object ^ o1, Platform::Object ^o2)
+{
+    Windows::UI::Core::CoreDispatcher ^dispatcher = WINRT_MainThreadDispatcher.Resolve<Windows::UI::Core::CoreDispatcher>();
+    if (dispatcher) {
+        dispatcher->RunAsync(
+            Windows::UI::Core::CoreDispatcherPriority::Normal,
+            ref new Windows::UI::Core::DispatchedHandler(&WINRT_HandleGameBarIsInputRedirected_MainThread));
+    }
+}
+
+void
+WINRT_InitGameBar(_THIS)
+{
+    SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata;
+    IGameBarStatics_ *gameBar = WINRT_GetGameBar();
+    if (gameBar) {
+        /* GameBar.IsInputRedirected events can come in via something other than
+           the main/SDL thread.
+
+           Get a WinRT 'CoreDispatcher' that can be used to call back into the
+           SDL thread.
+        */
+        WINRT_MainThreadDispatcher = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher;
+        Windows::Foundation::EventHandler<Platform::Object ^> ^handler = \
+            ref new Windows::Foundation::EventHandler<Platform::Object ^>(&WINRT_HandleGameBarIsInputRedirected_NonMainThread);
+        __FIEventHandler_1_IInspectable * pHandler = reinterpret_cast<__FIEventHandler_1_IInspectable *>(handler);
+        gameBar->add_IsInputRedirectedChanged(pHandler, &driverdata->gameBarIsInputRedirectedToken);
+        gameBar->Release();
+    }
+}
+
+void
+WINRT_QuitGameBar(_THIS)
+{
+    SDL_VideoData *driverdata;
+    IGameBarStatics_ *gameBar;
+    if (!_this || !_this->driverdata) {
+        return;
+    }
+    gameBar = WINRT_GetGameBar();
+    if (!gameBar) {
+        return;
+    }
+    driverdata = (SDL_VideoData *)_this->driverdata;
+    if (driverdata->gameBarIsInputRedirectedToken.Value) {
+        gameBar->remove_IsInputRedirectedChanged(driverdata->gameBarIsInputRedirectedToken);
+        driverdata->gameBarIsInputRedirectedToken.Value = 0;
+    }
+    WINRT_MainThreadDispatcher = nullptr;
+    gameBar->Release();
+}
+
+#endif /* SDL_VIDEO_DRIVER_WINRT */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/winrt/SDL_winrtgamebar_cpp.h	Sun Aug 28 13:36:13 2016 -0400
@@ -0,0 +1,35 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+#ifndef _SDL_winrtgamebar_h
+#define _SDL_winrtgamebar_h
+
+#ifdef __cplusplus
+/* These are exported as C++ functions, rather than C, to fix a compilation
+   bug with MSVC 2013, for Windows 8.x builds. */
+extern void WINRT_InitGameBar(_THIS);
+extern void WINRT_QuitGameBar(_THIS);
+#endif
+
+#endif /* _SDL_winrtmouse_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/winrt/SDL_winrtvideo.cpp	Fri Aug 12 22:50:48 2016 -0400
+++ b/src/video/winrt/SDL_winrtvideo.cpp	Sun Aug 28 13:36:13 2016 -0400
@@ -61,6 +61,7 @@
 #include "../../core/winrt/SDL_winrtapp_xaml.h"
 #include "SDL_winrtvideo_cpp.h"
 #include "SDL_winrtevents_c.h"
+#include "SDL_winrtgamebar_cpp.h"
 #include "SDL_winrtmouse_c.h"
 #include "SDL_main.h"
 #include "SDL_system.h"
@@ -127,7 +128,6 @@
         SDL_free(device);
         return (0);
     }
-    SDL_zerop(data);
     device->driverdata = data;
 
     /* Set the function pointers */
@@ -178,6 +178,7 @@
     }
     WINRT_InitMouse(_this);
     WINRT_InitTouch(_this);
+    WINRT_InitGameBar(_this);
 
     return 0;
 }
@@ -420,6 +421,7 @@
 void
 WINRT_VideoQuit(_THIS)
 {
+    WINRT_QuitGameBar(_this);
     WINRT_QuitMouse(_this);
 }
 
--- a/src/video/winrt/SDL_winrtvideo_cpp.h	Fri Aug 12 22:50:48 2016 -0400
+++ b/src/video/winrt/SDL_winrtvideo_cpp.h	Sun Aug 28 13:36:13 2016 -0400
@@ -46,6 +46,11 @@
      * passed to eglGetDisplay and eglCreateWindowSurface:
      */
     IUnknown *winrtEglWindow;
+
+    /* Event token(s), for unregistering WinRT event handler(s).
+       These are just a struct with a 64-bit integer inside them
+    */
+    Windows::Foundation::EventRegistrationToken gameBarIsInputRedirectedToken;
 } SDL_VideoData;
 
 /* The global, WinRT, SDL Window.