diff --git a/Source/Core/DolphinWX/Input/InputConfigDiag.cpp b/Source/Core/DolphinWX/Input/InputConfigDiag.cpp index 7434371e1bf1..3ebbc1253c91 100644 --- a/Source/Core/DolphinWX/Input/InputConfigDiag.cpp +++ b/Source/Core/DolphinWX/Input/InputConfigDiag.cpp @@ -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(); diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp index a5e995f6cc0e..983108f356f4 100644 --- a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp @@ -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(i)); diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.h b/Source/Core/InputCommon/ControllerInterface/Android/Android.h index 987aaed86306..bf588719c2f2 100644 --- a/Source/Core/InputCommon/ControllerInterface/Android/Android.h +++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.h @@ -11,7 +11,7 @@ namespace ciface { namespace Android { -void Init(); +void PopulateDevices(); class Touchscreen : public Core::Device { private: diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp index c6f250a157b5..635284d2c538 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp @@ -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 lk(m_devices_mutex); + m_devices.clear(); + } + +#ifdef CIFACE_USE_DINPUT + ciface::DInput::PopulateDevices(reinterpret_cast(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 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 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; } diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h index c89edd29b5b6..845c6cbbf64a 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h @@ -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 device); void RemoveDevice(std::function callback); diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp b/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp index 83394852afda..aacbcd55f826 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInput.cpp @@ -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, diff --git a/Source/Core/InputCommon/ControllerInterface/DInput/DInput.h b/Source/Core/InputCommon/ControllerInterface/DInput/DInput.h index 94e4cb4fe3bf..951eabebb9f8 100644 --- a/Source/Core/InputCommon/ControllerInterface/DInput/DInput.h +++ b/Source/Core/InputCommon/ControllerInterface/DInput/DInput.h @@ -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); } } diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h index c2104774b72c..ac1db3e89a2d 100644 --- a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.h @@ -9,6 +9,7 @@ namespace ciface namespace OSX { void Init(void* window); +void PopulateDevices(void* window); void DeInit(); void DeviceElementDebugPrint(const void*, void*); diff --git a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm index e575260a89ad..9aeeec59fb9c 100644 --- a/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm +++ b/Source/Core/InputCommon/ControllerInterface/OSX/OSX.mm @@ -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 diff --git a/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.cpp b/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.cpp index 6e93a581d108..6f09214f5b09 100644 --- a/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.cpp @@ -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. diff --git a/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.h b/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.h index a2e26db99471..3cb79fee39ad 100644 --- a/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.h +++ b/Source/Core/InputCommon/ControllerInterface/Pipes/Pipes.h @@ -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 { diff --git a/Source/Core/InputCommon/ControllerInterface/Quartz/Quartz.h b/Source/Core/InputCommon/ControllerInterface/Quartz/Quartz.h index 3e08410f6b1c..03f6ca9993be 100644 --- a/Source/Core/InputCommon/ControllerInterface/Quartz/Quartz.h +++ b/Source/Core/InputCommon/ControllerInterface/Quartz/Quartz.h @@ -8,7 +8,7 @@ namespace ciface { namespace Quartz { -void Init(void* window); +void PopulateDevices(void* window); void DeInit(); } } diff --git a/Source/Core/InputCommon/ControllerInterface/Quartz/Quartz.mm b/Source/Core/InputCommon/ControllerInterface/Quartz/Quartz.mm index 6fdac0e798fb..a090b421a535 100644 --- a/Source/Core/InputCommon/ControllerInterface/Quartz/Quartz.mm +++ b/Source/Core/InputCommon/ControllerInterface/Quartz/Quartz.mm @@ -10,7 +10,7 @@ { namespace Quartz { -void Init(void* window) +void PopulateDevices(void* window) { g_controller_interface.AddDevice(std::make_shared(window)); } diff --git a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp index 8f8265e8d093..7da8e66fc68f 100644 --- a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp +++ b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp @@ -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) diff --git a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.h b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.h index e104af7715f7..c41bb5761441 100644 --- a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.h +++ b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.h @@ -21,6 +21,7 @@ namespace ciface namespace SDL { void Init(); +void PopulateDevices(); class Joystick : public Core::Device { diff --git a/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp b/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp index d39b0b8e1e52..3d8650820ef4 100644 --- a/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp +++ b/Source/Core/InputCommon/ControllerInterface/XInput/XInput.cpp @@ -85,6 +85,12 @@ void Init() return; } } +} + +void PopulateDevices() +{ + if (!hXInput) + return; XINPUT_CAPABILITIES caps; for (int i = 0; i != 4; ++i) diff --git a/Source/Core/InputCommon/ControllerInterface/XInput/XInput.h b/Source/Core/InputCommon/ControllerInterface/XInput/XInput.h index 0dda9a93dab9..52530e9a0051 100644 --- a/Source/Core/InputCommon/ControllerInterface/XInput/XInput.h +++ b/Source/Core/InputCommon/ControllerInterface/XInput/XInput.h @@ -23,6 +23,7 @@ namespace ciface namespace XInput { void Init(); +void PopulateDevices(); void DeInit(); class Device : public Core::Device diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp index de3490f2e0f2..29ac62f32c55 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.cpp @@ -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); diff --git a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h index 80df03db70f0..5c5124cb3bf5 100644 --- a/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h +++ b/Source/Core/InputCommon/ControllerInterface/Xlib/XInput2.h @@ -18,7 +18,7 @@ namespace ciface { namespace XInput2 { -void Init(void* const hwnd); +void PopulateDevices(void* const hwnd); class KeyboardMouse : public Core::Device { diff --git a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp index d3f8f5fd36e1..bee0c44a02cd 100644 --- a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp +++ b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp @@ -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() diff --git a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.h b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.h index dc8e917e2346..513c5a67f22a 100644 --- a/Source/Core/InputCommon/ControllerInterface/evdev/evdev.h +++ b/Source/Core/InputCommon/ControllerInterface/evdev/evdev.h @@ -15,6 +15,7 @@ namespace ciface namespace evdev { void Init(); +void PopulateDevices(); void Shutdown(); class evdevDevice : public Core::Device