[WIN] react to joystick connect/disconnect (fixes #12653 and #11220) + refactor
authorCrystalP <CrystalP@xbmc.org>
Fri, 16 Mar 2012 03:20:08 +0000 (23:20 -0400)
committerCrystalP <CrystalP@xbmc.org>
Sun, 18 Mar 2012 22:32:26 +0000 (18:32 -0400)
Fixes access violation soon after unplugging a controller as XBMC and SDL
were not aware of the removal.

xbmc/input/SDLJoystick.cpp
xbmc/input/SDLJoystick.h
xbmc/linux/HALManager.cpp
xbmc/windowing/windows/WinEventsWin32.cpp

index 4caad37..ee4b589 100644 (file)
@@ -408,4 +408,24 @@ float CJoystick::SetDeadzone(float val)
   return val;
 }
 
+bool CJoystick::Reinitialize()
+{
+  // Restart SDL joystick subsystem
+  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+  if (SDL_WasInit(SDL_INIT_JOYSTICK) !=  0)
+  {
+    CLog::Log(LOGERROR, "Stop joystick subsystem failed");
+    return false;
+  }
+  if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0)
+  {
+    CLog::Log(LOGERROR, "Restart joystick subsystem failed : %s",SDL_GetError());
+    return false;
+  }
+
+  Initialize();
+
+  return true;
+}
+
 #endif
index a08364f..e7803d1 100644 (file)
@@ -64,6 +64,7 @@ public:
   float GetAmount(int axis);
   float GetAmount() { return GetAmount(m_AxisId); }
   float SetDeadzone(float val);
+  bool Reinitialize();
 
 private:
   void SetAxisActive(bool active=true) { m_ActiveFlags = active?(m_ActiveFlags|JACTIVE_AXIS):(m_ActiveFlags&(~JACTIVE_AXIS)); }
index d660a4e..78f0edc 100644 (file)
@@ -511,19 +511,9 @@ void CHALManager::AddDevice(const char *udi)
         if(m_Joysticks.size() < 2 || m_bMultipleJoysticksSupport)
         {
           // Restart SDL joystick subsystem
-          SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
-          if (SDL_WasInit(SDL_INIT_JOYSTICK) !=  0)
-          {
-            CLog::Log(LOGERROR, "HAL: Stop joystick subsystem failed");
-            break;
-          }
-          if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0)
-          {
-            CLog::Log(LOGERROR, "HAL: Restart joystick subsystem failed : %s",SDL_GetError());
+          if (!g_Joystick.Reinitialize())
             break;
-          }
 
-          g_Joystick.Initialize();
           if (m_Notifications)
             CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, g_localizeStrings.Get(13024), dev.FriendlyName.c_str(), TOAST_DISPLAY_TIME, false);
         }
@@ -576,20 +566,11 @@ bool CHALManager::RemoveDevice(const char *udi)
       if(m_Joysticks.size() < 3 || m_bMultipleJoysticksSupport)
       {
         // Restart SDL joystick subsystem
-        SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
-        if (SDL_WasInit(SDL_INIT_JOYSTICK) !=  0)
-        {
-          CLog::Log(LOGERROR, "HAL: Stop joystick subsystem failed");
+        if (!g_Joystick.Reinitialize())
           return false;
-        }
-        if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0)
-        {
-          CLog::Log(LOGERROR, "HAL: Restart joystick subsystem failed : %s",SDL_GetError());
-          return false;
-        }
 
-        g_Joystick.Initialize();
-        CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(13025), m_Joysticks[i].FriendlyName.c_str(), TOAST_DISPLAY_TIME, false);
+        if (m_Notifications)
+          CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(13025), m_Joysticks[i].FriendlyName.c_str(), TOAST_DISPLAY_TIME, false);
       }
       m_Joysticks.erase(m_Joysticks.begin() + i);
       return true;
index 83a9f64..1efd651 100644 (file)
@@ -27,6 +27,9 @@
 #include "Application.h"
 #include "input/XBMC_vkeys.h"
 #include "input/MouseStat.h"
+#if defined(HAS_SDL_JOYSTICK)
+#include "input/SDLJoystick.h"
+#endif
 #include "storage/MediaManager.h"
 #include "windowing/WindowingFactory.h"
 #include <dbt.h>
@@ -688,7 +691,12 @@ LRESULT CALLBACK CWinEventsWin32::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
           case DBT_DEVICEARRIVAL:
           case DBT_DEVICEREMOVECOMPLETE:
             if (((_DEV_BROADCAST_HEADER*) lParam)->dbcd_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
+            {
               g_peripherals.TriggerDeviceScan(PERIPHERAL_BUS_USB);
+#if defined(HAS_SDL_JOYSTICK)
+              g_Joystick.Reinitialize();
+#endif
+            }
         }
         break;
       }