Merge pull request #4343 from ligfx/fixsdlcrash
ControllerInterface: Fix crashes when using SDL controllers
This commit is contained in:
commit
a95e3c875e
|
@ -894,7 +894,7 @@ void InputConfigDialog::RefreshDevices(wxCommandEvent&)
|
||||||
bool was_unpaused = Core::PauseAndLock(true);
|
bool was_unpaused = Core::PauseAndLock(true);
|
||||||
|
|
||||||
// refresh devices
|
// refresh devices
|
||||||
g_controller_interface.Reinitialize();
|
g_controller_interface.RefreshDevices();
|
||||||
|
|
||||||
// update all control references
|
// update all control references
|
||||||
UpdateControlReferences();
|
UpdateControlReferences();
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace ciface
|
||||||
{
|
{
|
||||||
namespace Android
|
namespace Android
|
||||||
{
|
{
|
||||||
void Init()
|
void PopulateDevices()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
g_controller_interface.AddDevice(std::make_shared<Touchscreen>(i));
|
g_controller_interface.AddDevice(std::make_shared<Touchscreen>(i));
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace ciface
|
||||||
{
|
{
|
||||||
namespace Android
|
namespace Android
|
||||||
{
|
{
|
||||||
void Init();
|
void PopulateDevices();
|
||||||
class Touchscreen : public Core::Device
|
class Touchscreen : public Core::Device
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -55,41 +55,70 @@ void ControllerInterface::Initialize(void* const hwnd)
|
||||||
m_hwnd = hwnd;
|
m_hwnd = hwnd;
|
||||||
|
|
||||||
#ifdef CIFACE_USE_DINPUT
|
#ifdef CIFACE_USE_DINPUT
|
||||||
ciface::DInput::Init((HWND)hwnd);
|
// nothing needed
|
||||||
#endif
|
#endif
|
||||||
#ifdef CIFACE_USE_XINPUT
|
#ifdef CIFACE_USE_XINPUT
|
||||||
ciface::XInput::Init();
|
ciface::XInput::Init();
|
||||||
#endif
|
#endif
|
||||||
#ifdef CIFACE_USE_XLIB
|
#ifdef CIFACE_USE_XLIB
|
||||||
ciface::XInput2::Init(hwnd);
|
// nothing needed
|
||||||
#endif
|
#endif
|
||||||
#ifdef CIFACE_USE_OSX
|
#ifdef CIFACE_USE_OSX
|
||||||
ciface::OSX::Init(hwnd);
|
ciface::OSX::Init(hwnd);
|
||||||
ciface::Quartz::Init(hwnd);
|
// nothing needed for Quartz
|
||||||
#endif
|
#endif
|
||||||
#ifdef CIFACE_USE_SDL
|
#ifdef CIFACE_USE_SDL
|
||||||
ciface::SDL::Init();
|
ciface::SDL::Init();
|
||||||
#endif
|
#endif
|
||||||
#ifdef CIFACE_USE_ANDROID
|
#ifdef CIFACE_USE_ANDROID
|
||||||
ciface::Android::Init();
|
// nothing needed
|
||||||
#endif
|
#endif
|
||||||
#ifdef CIFACE_USE_EVDEV
|
#ifdef CIFACE_USE_EVDEV
|
||||||
ciface::evdev::Init();
|
ciface::evdev::Init();
|
||||||
#endif
|
#endif
|
||||||
#ifdef CIFACE_USE_PIPES
|
#ifdef CIFACE_USE_PIPES
|
||||||
ciface::Pipes::Init();
|
// nothing needed
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_is_init = true;
|
m_is_init = true;
|
||||||
|
RefreshDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerInterface::Reinitialize()
|
void ControllerInterface::RefreshDevices()
|
||||||
{
|
{
|
||||||
if (!m_is_init)
|
if (!m_is_init)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Shutdown();
|
{
|
||||||
Initialize(m_hwnd);
|
std::lock_guard<std::mutex> lk(m_devices_mutex);
|
||||||
|
m_devices.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CIFACE_USE_DINPUT
|
||||||
|
ciface::DInput::PopulateDevices(reinterpret_cast<HWND>(m_hwnd));
|
||||||
|
#endif
|
||||||
|
#ifdef CIFACE_USE_XINPUT
|
||||||
|
ciface::XInput::PopulateDevices();
|
||||||
|
#endif
|
||||||
|
#ifdef CIFACE_USE_XLIB
|
||||||
|
ciface::XInput2::PopulateDevices(m_hwnd);
|
||||||
|
#endif
|
||||||
|
#ifdef CIFACE_USE_OSX
|
||||||
|
ciface::OSX::PopulateDevices(m_hwnd);
|
||||||
|
ciface::Quartz::PopulateDevices(m_hwnd);
|
||||||
|
#endif
|
||||||
|
#ifdef CIFACE_USE_SDL
|
||||||
|
ciface::SDL::PopulateDevices();
|
||||||
|
#endif
|
||||||
|
#ifdef CIFACE_USE_ANDROID
|
||||||
|
ciface::Android::PopulateDevices();
|
||||||
|
#endif
|
||||||
|
#ifdef CIFACE_USE_EVDEV
|
||||||
|
ciface::evdev::PopulateDevices();
|
||||||
|
#endif
|
||||||
|
#ifdef CIFACE_USE_PIPES
|
||||||
|
ciface::Pipes::PopulateDevices();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -102,6 +131,19 @@ void ControllerInterface::Shutdown()
|
||||||
if (!m_is_init)
|
if (!m_is_init)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(m_devices_mutex);
|
||||||
|
|
||||||
|
for (const auto& d : m_devices)
|
||||||
|
{
|
||||||
|
// Set outputs to ZERO before destroying device
|
||||||
|
for (ciface::Core::Device::Output* o : d->Outputs())
|
||||||
|
o->SetState(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_devices.clear();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CIFACE_USE_XINPUT
|
#ifdef CIFACE_USE_XINPUT
|
||||||
ciface::XInput::DeInit();
|
ciface::XInput::DeInit();
|
||||||
#endif
|
#endif
|
||||||
|
@ -126,17 +168,6 @@ void ControllerInterface::Shutdown()
|
||||||
ciface::evdev::Shutdown();
|
ciface::evdev::Shutdown();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lk(m_devices_mutex);
|
|
||||||
|
|
||||||
for (const auto& d : m_devices)
|
|
||||||
{
|
|
||||||
// Set outputs to ZERO before destroying device
|
|
||||||
for (ciface::Core::Device::Output* o : d->Outputs())
|
|
||||||
o->SetState(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_devices.clear();
|
|
||||||
|
|
||||||
m_is_init = false;
|
m_is_init = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ public:
|
||||||
|
|
||||||
ControllerInterface() : m_is_init(false), m_hwnd(nullptr) {}
|
ControllerInterface() : m_is_init(false), m_hwnd(nullptr) {}
|
||||||
void Initialize(void* const hwnd);
|
void Initialize(void* const hwnd);
|
||||||
void Reinitialize();
|
void RefreshDevices();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void AddDevice(std::shared_ptr<ciface::Core::Device> device);
|
void AddDevice(std::shared_ptr<ciface::Core::Device> device);
|
||||||
void RemoveDevice(std::function<bool(const ciface::Core::Device*)> callback);
|
void RemoveDevice(std::function<bool(const ciface::Core::Device*)> callback);
|
||||||
|
|
|
@ -44,7 +44,7 @@ std::string GetDeviceName(const LPDIRECTINPUTDEVICE8 device)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init(HWND hwnd)
|
void PopulateDevices(HWND hwnd)
|
||||||
{
|
{
|
||||||
IDirectInput8* idi8;
|
IDirectInput8* idi8;
|
||||||
if (FAILED(DirectInput8Create(GetModuleHandle(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8,
|
if (FAILED(DirectInput8Create(GetModuleHandle(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8,
|
||||||
|
|
|
@ -20,6 +20,6 @@ BOOL CALLBACK DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVO
|
||||||
BOOL CALLBACK DIEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
|
BOOL CALLBACK DIEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
|
||||||
std::string GetDeviceName(const LPDIRECTINPUTDEVICE8 device);
|
std::string GetDeviceName(const LPDIRECTINPUTDEVICE8 device);
|
||||||
|
|
||||||
void Init(HWND hwnd);
|
void PopulateDevices(HWND hwnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace ciface
|
||||||
namespace OSX
|
namespace OSX
|
||||||
{
|
{
|
||||||
void Init(void* window);
|
void Init(void* window);
|
||||||
|
void PopulateDevices(void* window);
|
||||||
void DeInit();
|
void DeInit();
|
||||||
|
|
||||||
void DeviceElementDebugPrint(const void*, void*);
|
void DeviceElementDebugPrint(const void*, void*);
|
||||||
|
|
|
@ -182,6 +182,12 @@ void Init(void* window)
|
||||||
IOHIDManagerUnscheduleFromRunLoop(HIDManager, CFRunLoopGetCurrent(), OurRunLoop);
|
IOHIDManagerUnscheduleFromRunLoop(HIDManager, CFRunLoopGetCurrent(), OurRunLoop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PopulateDevices(void* window)
|
||||||
|
{
|
||||||
|
DeInit();
|
||||||
|
Init(window);
|
||||||
|
}
|
||||||
|
|
||||||
void DeInit()
|
void DeInit()
|
||||||
{
|
{
|
||||||
// This closes all devices as well
|
// This closes all devices as well
|
||||||
|
|
|
@ -41,7 +41,7 @@ static double StringToDouble(const std::string& text)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init()
|
void PopulateDevices()
|
||||||
{
|
{
|
||||||
// Search the Pipes directory for files that we can open in read-only,
|
// Search the Pipes directory for files that we can open in read-only,
|
||||||
// non-blocking mode. The device name is the virtual name of the file.
|
// non-blocking mode. The device name is the virtual name of the file.
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace Pipes
|
||||||
// SET {L, R} [0, 1]
|
// SET {L, R} [0, 1]
|
||||||
// SET {MAIN, C} [0, 1] [0, 1]
|
// SET {MAIN, C} [0, 1] [0, 1]
|
||||||
|
|
||||||
void Init();
|
void PopulateDevices();
|
||||||
|
|
||||||
class PipeDevice : public Core::Device
|
class PipeDevice : public Core::Device
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace ciface
|
||||||
{
|
{
|
||||||
namespace Quartz
|
namespace Quartz
|
||||||
{
|
{
|
||||||
void Init(void* window);
|
void PopulateDevices(void* window);
|
||||||
void DeInit();
|
void DeInit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace ciface
|
||||||
{
|
{
|
||||||
namespace Quartz
|
namespace Quartz
|
||||||
{
|
{
|
||||||
void Init(void* window)
|
void PopulateDevices(void* window)
|
||||||
{
|
{
|
||||||
g_controller_interface.AddDevice(std::make_shared<KeyboardAndMouse>(window));
|
g_controller_interface.AddDevice(std::make_shared<KeyboardAndMouse>(window));
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,12 @@ void Init()
|
||||||
// Failed to initialize
|
// Failed to initialize
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopulateDevices()
|
||||||
|
{
|
||||||
|
if (!(SDL_WasInit(SDL_INIT_EVERYTHING) & SDL_INIT_JOYSTICK))
|
||||||
|
return;
|
||||||
|
|
||||||
// joysticks
|
// joysticks
|
||||||
for (int i = 0; i < SDL_NumJoysticks(); ++i)
|
for (int i = 0; i < SDL_NumJoysticks(); ++i)
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace ciface
|
||||||
namespace SDL
|
namespace SDL
|
||||||
{
|
{
|
||||||
void Init();
|
void Init();
|
||||||
|
void PopulateDevices();
|
||||||
|
|
||||||
class Joystick : public Core::Device
|
class Joystick : public Core::Device
|
||||||
{
|
{
|
||||||
|
|
|
@ -85,6 +85,12 @@ void Init()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopulateDevices()
|
||||||
|
{
|
||||||
|
if (!hXInput)
|
||||||
|
return;
|
||||||
|
|
||||||
XINPUT_CAPABILITIES caps;
|
XINPUT_CAPABILITIES caps;
|
||||||
for (int i = 0; i != 4; ++i)
|
for (int i = 0; i != 4; ++i)
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace ciface
|
||||||
namespace XInput
|
namespace XInput
|
||||||
{
|
{
|
||||||
void Init();
|
void Init();
|
||||||
|
void PopulateDevices();
|
||||||
void DeInit();
|
void DeInit();
|
||||||
|
|
||||||
class Device : public Core::Device
|
class Device : public Core::Device
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace ciface
|
||||||
namespace XInput2
|
namespace XInput2
|
||||||
{
|
{
|
||||||
// This function will add zero or more KeyboardMouse objects to devices.
|
// This function will add zero or more KeyboardMouse objects to devices.
|
||||||
void Init(void* const hwnd)
|
void PopulateDevices(void* const hwnd)
|
||||||
{
|
{
|
||||||
Display* dpy = XOpenDisplay(nullptr);
|
Display* dpy = XOpenDisplay(nullptr);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace ciface
|
||||||
{
|
{
|
||||||
namespace XInput2
|
namespace XInput2
|
||||||
{
|
{
|
||||||
void Init(void* const hwnd);
|
void PopulateDevices(void* const hwnd);
|
||||||
|
|
||||||
class KeyboardMouse : public Core::Device
|
class KeyboardMouse : public Core::Device
|
||||||
{
|
{
|
||||||
|
|
|
@ -141,10 +141,15 @@ static void StopHotplugThread()
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
s_devnode_name_map.clear();
|
s_devnode_name_map.clear();
|
||||||
|
PopulateDevices();
|
||||||
|
StartHotplugThread();
|
||||||
|
}
|
||||||
|
|
||||||
// During initialization we use udev to iterate over all /dev/input/event* devices.
|
void PopulateDevices()
|
||||||
// Note: the Linux kernel is currently limited to just 32 event devices. If this ever
|
{
|
||||||
// changes, hopefully udev will take care of this.
|
// We use udev to iterate over all /dev/input/event* devices.
|
||||||
|
// Note: the Linux kernel is currently limited to just 32 event devices. If
|
||||||
|
// this ever changes, hopefully udev will take care of this.
|
||||||
|
|
||||||
udev* udev = udev_new();
|
udev* udev = udev_new();
|
||||||
_assert_msg_(PAD, udev != nullptr, "Couldn't initialize libudev.");
|
_assert_msg_(PAD, udev != nullptr, "Couldn't initialize libudev.");
|
||||||
|
@ -182,8 +187,6 @@ void Init()
|
||||||
}
|
}
|
||||||
udev_enumerate_unref(enumerate);
|
udev_enumerate_unref(enumerate);
|
||||||
udev_unref(udev);
|
udev_unref(udev);
|
||||||
|
|
||||||
StartHotplugThread();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace ciface
|
||||||
namespace evdev
|
namespace evdev
|
||||||
{
|
{
|
||||||
void Init();
|
void Init();
|
||||||
|
void PopulateDevices();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
class evdevDevice : public Core::Device
|
class evdevDevice : public Core::Device
|
||||||
|
|
Loading…
Reference in New Issue