Skip to content

Commit

Permalink
ControllerInterface: replace Reinitialize with RefreshDevices
Browse files Browse the repository at this point in the history
The SDL backend crashes when you close a joystick after SDL_Quit has
been called. Some backends don't need to be shutdown and
re-initialized everytime, we can just ask to enumerate devices again.
  • Loading branch information
ligfx committed Dec 1, 2016
1 parent cebb4d8 commit 3e69d06
Show file tree
Hide file tree
Showing 21 changed files with 79 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Source/Core/DolphinWX/Input/InputConfigDiag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace ciface
{
namespace Android
{
void Init();
void PopulateDevices();
class Touchscreen : public Core::Device
{
private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class ControllerInterface : public ciface::Core::DeviceContainer

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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
1 change: 1 addition & 0 deletions Source/Core/InputCommon/ControllerInterface/OSX/OSX.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace ciface
namespace OSX
{
void Init(void* window);
void PopulateDevices(void* window);
void DeInit();

void DeviceElementDebugPrint(const void*, void*);
Expand Down
6 changes: 6 additions & 0 deletions Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace ciface
{
namespace Quartz
{
void Init(void* window);
void PopulateDevices(void* window);
void DeInit();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{
namespace Quartz
{
void Init(void* window)
void PopulateDevices(void* window)
{
g_controller_interface.AddDevice(std::make_shared<KeyboardAndMouse>(window));
}
Expand Down
6 changes: 6 additions & 0 deletions Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions Source/Core/InputCommon/ControllerInterface/SDL/SDL.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace ciface
namespace SDL
{
void Init();
void PopulateDevices();

class Joystick : public Core::Device
{
Expand Down
6 changes: 6 additions & 0 deletions Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ void Init()
return;
}
}
}

void PopulateDevices()
{
if (!hXInput)
return;

XINPUT_CAPABILITIES caps;
for (int i = 0; i != 4; ++i)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace ciface
namespace XInput
{
void Init();
void PopulateDevices();
void DeInit();

class Device : public Core::Device
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace ciface
{
namespace XInput2
{
void Init(void* const hwnd);
void PopulateDevices(void* const hwnd);

class KeyboardMouse : public Core::Device
{
Expand Down
13 changes: 8 additions & 5 deletions Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
Expand Down Expand Up @@ -182,8 +187,6 @@ void Init()
}
udev_enumerate_unref(enumerate);
udev_unref(udev);

StartHotplugThread();
}

void Shutdown()
Expand Down
1 change: 1 addition & 0 deletions Source/Core/InputCommon/ControllerInterface/evdev/evdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace ciface
namespace evdev
{
void Init();
void PopulateDevices();
void Shutdown();

class evdevDevice : public Core::Device
Expand Down

0 comments on commit 3e69d06

Please sign in to comment.