From e5c435f2818d82cfaf8fc626418536985f0e188b Mon Sep 17 00:00:00 2001 From: Roland Rossgotterer Date: Thu, 14 Feb 2019 16:08:40 +0100 Subject: [PATCH] Add function to retrieve all available joystick buttons --- src/blackcore/inputmanager.cpp | 5 +++ src/blackcore/inputmanager.h | 4 +++ src/blackinput/joystick.h | 3 ++ src/blackinput/linux/joysticklinux.cpp | 6 ++++ src/blackinput/linux/joysticklinux.h | 3 ++ src/blackinput/macos/joystickmacos.h | 13 ++++++-- src/blackinput/macos/joystickmacos.mm | 36 ++++++++++++++++------ src/blackinput/win/joystickwindows.cpp | 42 ++++++++++++++++++-------- src/blackinput/win/joystickwindows.h | 15 ++++++--- 9 files changed, 97 insertions(+), 30 deletions(-) diff --git a/src/blackcore/inputmanager.cpp b/src/blackcore/inputmanager.cpp index cbb4a1a34..f89cf83a2 100644 --- a/src/blackcore/inputmanager.cpp +++ b/src/blackcore/inputmanager.cpp @@ -133,6 +133,11 @@ namespace BlackCore m_joystick.reset(); } + CJoystickButtonList CInputManager::getAllAvailableJoystickButtons() const + { + return m_joystick->getAllAvailableJoystickButtons(); + } + int CInputManager::bindImpl(const QString &action, QObject *receiver, std::function function) { static int index = 0; diff --git a/src/blackcore/inputmanager.h b/src/blackcore/inputmanager.h index 118a890ea..d6180d3c5 100644 --- a/src/blackcore/inputmanager.h +++ b/src/blackcore/inputmanager.h @@ -17,6 +17,7 @@ #include "blackinput/joystick.h" #include "blackinput/keyboard.h" #include "blackmisc/input/hotkeycombination.h" +#include "blackmisc/input/joystickbuttonlist.h" #include "blackmisc/settingscache.h" #include "blackmisc/icons.h" @@ -96,6 +97,9 @@ namespace BlackCore //! Releases all devices void releaseDevices(); + //! \copydoc BlackInput::IJoystick::getAllAvailableJoystickButtons() + BlackMisc::Input::CJoystickButtonList getAllAvailableJoystickButtons() const; + signals: //! Event hotkeyfunction occured void remoteActionFromLocal(const QString &action, bool argument); diff --git a/src/blackinput/joystick.h b/src/blackinput/joystick.h index 8d17f60c1..d52039a08 100644 --- a/src/blackinput/joystick.h +++ b/src/blackinput/joystick.h @@ -36,6 +36,9 @@ namespace BlackInput //! Creates a native joystick handler object static std::unique_ptr create(QObject *parent = nullptr); + //! Get all available joystick buttons + virtual BlackMisc::Input::CJoystickButtonList getAllAvailableJoystickButtons() const { return {}; } + signals: //! Joystick button combination has changed void buttonCombinationChanged(const BlackMisc::Input::CHotkeyCombination &); diff --git a/src/blackinput/linux/joysticklinux.cpp b/src/blackinput/linux/joysticklinux.cpp index ae405f793..4d675dd30 100644 --- a/src/blackinput/linux/joysticklinux.cpp +++ b/src/blackinput/linux/joysticklinux.cpp @@ -86,6 +86,12 @@ namespace BlackInput reloadDevices(inputDevicesDir()); } + CJoystickButtonList CJoystickLinux::getAllAvailableJoystickButtons() const + { + // We don't know which buttons are available yet. + return {}; + } + void CJoystickLinux::cleanupJoysticks() { for (auto it = m_joystickDevices.begin(); it != m_joystickDevices.end();) diff --git a/src/blackinput/linux/joysticklinux.h b/src/blackinput/linux/joysticklinux.h index 02a72c401..df2d167ad 100644 --- a/src/blackinput/linux/joysticklinux.h +++ b/src/blackinput/linux/joysticklinux.h @@ -73,6 +73,9 @@ namespace BlackInput //! \brief Destructor virtual ~CJoystickLinux() = default; + //! \copydoc BlackInput::IJoystick::getAllAvailableJoystickButtons() + virtual BlackMisc::Input::CJoystickButtonList getAllAvailableJoystickButtons() const override; + private: friend class IJoystick; diff --git a/src/blackinput/macos/joystickmacos.h b/src/blackinput/macos/joystickmacos.h index 186fae420..24d209dd9 100644 --- a/src/blackinput/macos/joystickmacos.h +++ b/src/blackinput/macos/joystickmacos.h @@ -13,6 +13,7 @@ //! \file #include "blackinput/joystick.h" +#include "blackmisc/input/joystickbutton.h" #include #include @@ -35,12 +36,15 @@ namespace BlackInput //! Initialize device bool init(const IOHIDDeviceRef device); + //! Get all available device buttons + BlackMisc::Input::CJoystickButtonList getDeviceButtons() const; + //! Return the native IOHIDDeviceRef IOHIDDeviceRef getNativeDevice() const { return m_deviceRef; } signals: //! Joystick button changed - void buttonChanged(const QString &name, int index, bool isPressed); + void buttonChanged(const BlackMisc::Input::CJoystickButton &joystickButton, bool isPressed); private: friend bool operator == (const CJoystickDevice &lhs, const CJoystickDevice &rhs); @@ -55,7 +59,7 @@ namespace BlackInput QString m_deviceName = "unknown"; //!< Device name // IOHIDDeviceRef is owned by IOHIDManager. Do not release it. IOHIDDeviceRef m_deviceRef = nullptr; - QHash m_joystickDeviceInputs; + QHash m_joystickDeviceInputs; }; //! MacOS implemenation of IJoystick @@ -73,6 +77,9 @@ namespace BlackInput //! Destructor virtual ~CJoystickMacOS() override; + //! \copydoc BlackInput::IJoystick::getAllAvailableJoystickButtons() + virtual BlackMisc::Input::CJoystickButtonList getAllAvailableJoystickButtons() const override; + protected: virtual bool init() override; @@ -88,7 +95,7 @@ namespace BlackInput //! Remove joystick device void removeJoystickDevice(const IOHIDDeviceRef device); - void joystickButtonChanged(const QString &name, int index, bool isPressed); + void joystickButtonChanged(const BlackMisc::Input::CJoystickButton &joystickButton, bool isPressed); static void matchCallback(void* context, IOReturn result, void* sender, IOHIDDeviceRef device); static void removeCallback(void* context, IOReturn result, void* sender, IOHIDDeviceRef device); diff --git a/src/blackinput/macos/joystickmacos.mm b/src/blackinput/macos/joystickmacos.mm index 3ff6d0e63..1464c19a2 100644 --- a/src/blackinput/macos/joystickmacos.mm +++ b/src/blackinput/macos/joystickmacos.mm @@ -17,6 +17,7 @@ #include using namespace BlackMisc; +using namespace BlackMisc::Input; namespace BlackInput { @@ -52,8 +53,8 @@ namespace BlackInput { CLogMessage(static_cast(nullptr)).debug() << "Found joystick button " << m_joystickDeviceInputs.size(); - int size = m_joystickDeviceInputs.size(); - m_joystickDeviceInputs.insert(elementRef, size); + int number = m_joystickDeviceInputs.size(); + m_joystickDeviceInputs.insert(elementRef, { m_deviceName, number }); IOHIDDeviceRegisterInputValueCallback(device, valueCallback, this); } } @@ -66,15 +67,20 @@ namespace BlackInput return true; } + CJoystickButtonList CJoystickDevice::getDeviceButtons() const + { + return CSequence(m_joystickDeviceInputs.values()); + } + void CJoystickDevice::processButtonEvent(IOHIDValueRef value) { IOHIDElementRef element = IOHIDValueGetElement(value); - int buttonNumber = m_joystickDeviceInputs.value(element, -1); - if (buttonNumber != -1) + CJoystickButton joystickButton = m_joystickDeviceInputs.value(element); + if (joystickButton.isValid()) { bool isPressed = IOHIDValueGetIntegerValue(value) == 1; - if (isPressed) { emit buttonChanged(m_deviceName, buttonNumber, true); } - else { emit buttonChanged(m_deviceName, buttonNumber, false); } + if (isPressed) { emit buttonChanged(joystickButton, true); } + else { emit buttonChanged(joystickButton, false); } } } @@ -104,6 +110,16 @@ namespace BlackInput } } + CJoystickButtonList CJoystickMacOS::getAllAvailableJoystickButtons() const + { + CJoystickButtonList availableButtons; + for (const CJoystickDevice *device : as_const(m_joystickDevices)) + { + availableButtons.push_back(device->getDeviceButtons()); + } + return availableButtons; + } + bool CJoystickMacOS::init() { m_hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); @@ -182,11 +198,11 @@ namespace BlackInput } } - void CJoystickMacOS::joystickButtonChanged(const QString &name, int index, bool isPressed) + void CJoystickMacOS::joystickButtonChanged(const CJoystickButton &joystickButton, bool isPressed) { - BlackMisc::Input::CHotkeyCombination oldCombination(m_buttonCombination); - if (isPressed) { m_buttonCombination.addJoystickButton({name, index}); } - else { m_buttonCombination.removeJoystickButton({name, index}); } + CHotkeyCombination oldCombination(m_buttonCombination); + if (isPressed) { m_buttonCombination.addJoystickButton(joystickButton); } + else { m_buttonCombination.removeJoystickButton(joystickButton); } if (oldCombination != m_buttonCombination) { diff --git a/src/blackinput/win/joystickwindows.cpp b/src/blackinput/win/joystickwindows.cpp index aec5e13b7..28dc39e0c 100644 --- a/src/blackinput/win/joystickwindows.cpp +++ b/src/blackinput/win/joystickwindows.cpp @@ -81,6 +81,16 @@ namespace BlackInput return true; } + CJoystickButtonList CJoystickDevice::getDeviceButtons() const + { + CJoystickButtonList buttons; + for (const CJoystickDeviceInput &deviceInput : m_joystickDeviceInputs) + { + buttons.push_back(deviceInput.m_button); + } + return buttons; + } + void CJoystickDevice::timerEvent(QTimerEvent *event) { Q_UNUSED(event); @@ -123,8 +133,8 @@ namespace BlackInput const qint32 buttonIndex = input.m_offset - DIJOFS_BUTTON0; bool isPressed = state.rgbButtons[buttonIndex] & 0x80; - if (isPressed) { emit buttonChanged(m_deviceName, buttonIndex, true); } - else { emit buttonChanged(m_deviceName, buttonIndex, false); } + if (isPressed) { emit buttonChanged(input.m_button, true); } + else { emit buttonChanged(input.m_button, false); } } return hr; @@ -138,12 +148,11 @@ namespace BlackInput if (dev->guidType != GUID_Button) return DIENUM_CONTINUE; CJoystickDeviceInput deviceInput; - deviceInput.m_number = joystickDevice->m_joystickDeviceInputs.size(); - deviceInput.m_offset = DIJOFS_BUTTON(deviceInput.m_number); - deviceInput.m_name = QString::fromWCharArray(dev->tszName); + int number = joystickDevice->m_joystickDeviceInputs.size(); + deviceInput.m_offset = DIJOFS_BUTTON(number); + deviceInput.m_button = CJoystickButton(joystickDevice->m_deviceName, DIJOFS_BUTTON(number) - DIJOFS_BUTTON0); joystickDevice->m_joystickDeviceInputs.append(deviceInput); - CLogMessage(static_cast(nullptr)).debug() << "Found joystick button" << QString::fromWCharArray(dev->tszName); return DIENUM_CONTINUE; @@ -196,6 +205,16 @@ namespace BlackInput destroyHelperWindow(); } + CJoystickButtonList CJoystickWindows::getAllAvailableJoystickButtons() const + { + CJoystickButtonList availableButtons; + for (const CJoystickDevice *device : as_const(m_joystickDevices)) + { + availableButtons.push_back(device->getDeviceButtons()); + } + return availableButtons; + } + void ReleaseDirectInput(IDirectInput8 *obj) { if (obj) { obj->Release(); } @@ -304,11 +323,11 @@ namespace BlackInput } } - void CJoystickWindows::joystickButtonChanged(const QString &name, int index, bool isPressed) + void CJoystickWindows::joystickButtonChanged(const CJoystickButton &joystickButton, bool isPressed) { BlackMisc::Input::CHotkeyCombination oldCombination(m_buttonCombination); - if (isPressed) { m_buttonCombination.addJoystickButton({name, index}); } - else { m_buttonCombination.removeJoystickButton({name, index}); } + if (isPressed) { m_buttonCombination.addJoystickButton(joystickButton); } + else { m_buttonCombination.removeJoystickButton(joystickButton); } if (oldCombination != m_buttonCombination) { @@ -338,8 +357,7 @@ namespace BlackInput bool operator == (CJoystickDeviceInput const &lhs, CJoystickDeviceInput const &rhs) { - return lhs.m_number == rhs.m_number && - lhs.m_offset == rhs.m_offset && - lhs.m_name == rhs.m_name; + return lhs.m_offset == rhs.m_offset && + lhs.m_button == rhs.m_button; } } // ns diff --git a/src/blackinput/win/joystickwindows.h b/src/blackinput/win/joystickwindows.h index d338e6e85..cb823de58 100644 --- a/src/blackinput/win/joystickwindows.h +++ b/src/blackinput/win/joystickwindows.h @@ -33,9 +33,8 @@ namespace BlackInput //! Joystick device input/button struct CJoystickDeviceInput { - int m_number; //!< Input number - int m_offset; //!< Input offset - QString m_name; //!< Input name + int m_offset; //!< Input offset + BlackMisc::Input::CJoystickButton m_button; //!< Joystick button }; //! Joystick device @@ -50,9 +49,12 @@ namespace BlackInput //! Initialize DirectInput device bool init(HWND helperWindow); + //! Get all available device buttons + BlackMisc::Input::CJoystickButtonList getDeviceButtons() const; + signals: //! Joystick button changed - void buttonChanged(const QString &name, int index, bool isPressed); + void buttonChanged(const BlackMisc::Input::CJoystickButton &joystickButton, bool isPressed); protected: //! Timer based updates @@ -108,6 +110,9 @@ namespace BlackInput //! \brief Destructor virtual ~CJoystickWindows() override; + //! \copydoc BlackInput::IJoystick::getAllAvailableJoystickButtons() + virtual BlackMisc::Input::CJoystickButtonList getAllAvailableJoystickButtons() const override; + private: friend class IJoystick; @@ -129,7 +134,7 @@ namespace BlackInput //! Add new joystick device void addJoystickDevice(const DIDEVICEINSTANCE *pdidInstance); - void joystickButtonChanged(const QString &name, int index, bool isPressed); + void joystickButtonChanged(const BlackMisc::Input::CJoystickButton &joystickButton, bool isPressed); //! Joystick enumeration callback static BOOL CALLBACK enumJoysticksCallback(const DIDEVICEINSTANCE *pdidInstance, VOID *pContext);