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);
|
||||
|
||||
// refresh devices
|
||||
g_controller_interface.Reinitialize();
|
||||
g_controller_interface.RefreshDevices();
|
||||
|
||||
// update all control references
|
||||
UpdateControlReferences();
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace ciface
|
|||
{
|
||||
namespace Android
|
||||
{
|
||||
void Init()
|
||||
void PopulateDevices()
|
||||
{
|
||||
for (int i = 0; i < 8; ++i)
|
||||
g_controller_interface.AddDevice(std::make_shared<Touchscreen>(i));
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace ciface
|
|||
{
|
||||
namespace Android
|
||||
{
|
||||
void Init();
|
||||
void PopulateDevices();
|
||||
class Touchscreen : public Core::Device
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -55,41 +55,70 @@ void ControllerInterface::Initialize(void* const hwnd)
|
|||
m_hwnd = hwnd;
|
||||
|
||||
#ifdef CIFACE_USE_DINPUT
|
||||
ciface::DInput::Init((HWND)hwnd);
|
||||
// nothing needed
|
||||
#endif
|
||||
#ifdef CIFACE_USE_XINPUT
|
||||
ciface::XInput::Init();
|
||||
#endif
|
||||
#ifdef CIFACE_USE_XLIB
|
||||
ciface::XInput2::Init(hwnd);
|
||||
// nothing needed
|
||||
#endif
|
||||
#ifdef CIFACE_USE_OSX
|
||||
ciface::OSX::Init(hwnd);
|
||||
ciface::Quartz::Init(hwnd);
|
||||
// nothing needed for Quartz
|
||||
#endif
|
||||
#ifdef CIFACE_USE_SDL
|
||||
ciface::SDL::Init();
|
||||
#endif
|
||||
#ifdef CIFACE_USE_ANDROID
|
||||
ciface::Android::Init();
|
||||
// nothing needed
|
||||
#endif
|
||||
#ifdef CIFACE_USE_EVDEV
|
||||
ciface::evdev::Init();
|
||||
#endif
|
||||
#ifdef CIFACE_USE_PIPES
|
||||
ciface::Pipes::Init();
|
||||
// nothing needed
|
||||
#endif
|
||||
|
||||
m_is_init = true;
|
||||
RefreshDevices();
|
||||
}
|
||||
|
||||
void ControllerInterface::Reinitialize()
|
||||
void ControllerInterface::RefreshDevices()
|
||||
{
|
||||
if (!m_is_init)
|
||||
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)
|
||||
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
|
||||
ciface::XInput::DeInit();
|
||||
#endif
|
||||
|
@ -126,17 +168,6 @@ void ControllerInterface::Shutdown()
|
|||
ciface::evdev::Shutdown();
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ public:
|
|||
|
||||
ControllerInterface() : m_is_init(false), m_hwnd(nullptr) {}
|
||||
void Initialize(void* const hwnd);
|
||||
void Reinitialize();
|
||||
void RefreshDevices();
|
||||
void Shutdown();
|
||||
void AddDevice(std::shared_ptr<ciface::Core::Device> device);
|
||||
void RemoveDevice(std::function<bool(const ciface::Core::Device*)> callback);
|
||||
|
|
|
@ -44,7 +44,7 @@ std::string GetDeviceName(const LPDIRECTINPUTDEVICE8 device)
|
|||
return result;
|
||||
}
|
||||
|
||||
void Init(HWND hwnd)
|
||||
void PopulateDevices(HWND hwnd)
|
||||
{
|
||||
IDirectInput8* idi8;
|
||||
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);
|
||||
std::string GetDeviceName(const LPDIRECTINPUTDEVICE8 device);
|
||||
|
||||
void Init(HWND hwnd);
|
||||
void PopulateDevices(HWND hwnd);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace ciface
|
|||
namespace OSX
|
||||
{
|
||||
void Init(void* window);
|
||||
void PopulateDevices(void* window);
|
||||
void DeInit();
|
||||
|
||||
void DeviceElementDebugPrint(const void*, void*);
|
||||
|
|
|
@ -182,6 +182,12 @@ void Init(void* window)
|
|||
IOHIDManagerUnscheduleFromRunLoop(HIDManager, CFRunLoopGetCurrent(), OurRunLoop);
|
||||
}
|
||||
|
||||
void PopulateDevices(void* window)
|
||||
{
|
||||
DeInit();
|
||||
Init(window);
|
||||
}
|
||||
|
||||
void DeInit()
|
||||
{
|
||||
// This closes all devices as well
|
||||
|
|
|
@ -41,7 +41,7 @@ static double StringToDouble(const std::string& text)
|
|||
return result;
|
||||
}
|
||||
|
||||
void Init()
|
||||
void PopulateDevices()
|
||||
{
|
||||
// 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.
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Pipes
|
|||
// SET {L, R} [0, 1]
|
||||
// SET {MAIN, C} [0, 1] [0, 1]
|
||||
|
||||
void Init();
|
||||
void PopulateDevices();
|
||||
|
||||
class PipeDevice : public Core::Device
|
||||
{
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace ciface
|
|||
{
|
||||
namespace Quartz
|
||||
{
|
||||
void Init(void* window);
|
||||
void PopulateDevices(void* window);
|
||||
void DeInit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace ciface
|
|||
{
|
||||
namespace Quartz
|
||||
{
|
||||
void Init(void* window)
|
||||
void PopulateDevices(void* window)
|
||||
{
|
||||
g_controller_interface.AddDevice(std::make_shared<KeyboardAndMouse>(window));
|
||||
}
|
||||
|
|
|
@ -47,6 +47,12 @@ void Init()
|
|||
// Failed to initialize
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void PopulateDevices()
|
||||
{
|
||||
if (!(SDL_WasInit(SDL_INIT_EVERYTHING) & SDL_INIT_JOYSTICK))
|
||||
return;
|
||||
|
||||
// joysticks
|
||||
for (int i = 0; i < SDL_NumJoysticks(); ++i)
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace ciface
|
|||
namespace SDL
|
||||
{
|
||||
void Init();
|
||||
void PopulateDevices();
|
||||
|
||||
class Joystick : public Core::Device
|
||||
{
|
||||
|
|
|
@ -85,6 +85,12 @@ void Init()
|
|||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PopulateDevices()
|
||||
{
|
||||
if (!hXInput)
|
||||
return;
|
||||
|
||||
XINPUT_CAPABILITIES caps;
|
||||
for (int i = 0; i != 4; ++i)
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace ciface
|
|||
namespace XInput
|
||||
{
|
||||
void Init();
|
||||
void PopulateDevices();
|
||||
void DeInit();
|
||||
|
||||
class Device : public Core::Device
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace ciface
|
|||
namespace XInput2
|
||||
{
|
||||
// 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);
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace ciface
|
|||
{
|
||||
namespace XInput2
|
||||
{
|
||||
void Init(void* const hwnd);
|
||||
void PopulateDevices(void* const hwnd);
|
||||
|
||||
class KeyboardMouse : public Core::Device
|
||||
{
|
||||
|
|
|
@ -141,10 +141,15 @@ static void StopHotplugThread()
|
|||
void Init()
|
||||
{
|
||||
s_devnode_name_map.clear();
|
||||
PopulateDevices();
|
||||
StartHotplugThread();
|
||||
}
|
||||
|
||||
// During initialization 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.
|
||||
void PopulateDevices()
|
||||
{
|
||||
// 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();
|
||||
_assert_msg_(PAD, udev != nullptr, "Couldn't initialize libudev.");
|
||||
|
@ -182,8 +187,6 @@ void Init()
|
|||
}
|
||||
udev_enumerate_unref(enumerate);
|
||||
udev_unref(udev);
|
||||
|
||||
StartHotplugThread();
|
||||
}
|
||||
|
||||
void Shutdown()
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace ciface
|
|||
namespace evdev
|
||||
{
|
||||
void Init();
|
||||
void PopulateDevices();
|
||||
void Shutdown();
|
||||
|
||||
class evdevDevice : public Core::Device
|
||||
|
|
Loading…
Reference in New Issue