Add function to retrieve all available joystick buttons

This commit is contained in:
Roland Rossgotterer
2019-02-14 16:08:40 +01:00
committed by Mat Sutcliffe
parent 2503a55dae
commit e5c435f281
9 changed files with 97 additions and 30 deletions

View File

@@ -133,6 +133,11 @@ namespace BlackCore
m_joystick.reset(); m_joystick.reset();
} }
CJoystickButtonList CInputManager::getAllAvailableJoystickButtons() const
{
return m_joystick->getAllAvailableJoystickButtons();
}
int CInputManager::bindImpl(const QString &action, QObject *receiver, std::function<void (bool)> function) int CInputManager::bindImpl(const QString &action, QObject *receiver, std::function<void (bool)> function)
{ {
static int index = 0; static int index = 0;

View File

@@ -17,6 +17,7 @@
#include "blackinput/joystick.h" #include "blackinput/joystick.h"
#include "blackinput/keyboard.h" #include "blackinput/keyboard.h"
#include "blackmisc/input/hotkeycombination.h" #include "blackmisc/input/hotkeycombination.h"
#include "blackmisc/input/joystickbuttonlist.h"
#include "blackmisc/settingscache.h" #include "blackmisc/settingscache.h"
#include "blackmisc/icons.h" #include "blackmisc/icons.h"
@@ -96,6 +97,9 @@ namespace BlackCore
//! Releases all devices //! Releases all devices
void releaseDevices(); void releaseDevices();
//! \copydoc BlackInput::IJoystick::getAllAvailableJoystickButtons()
BlackMisc::Input::CJoystickButtonList getAllAvailableJoystickButtons() const;
signals: signals:
//! Event hotkeyfunction occured //! Event hotkeyfunction occured
void remoteActionFromLocal(const QString &action, bool argument); void remoteActionFromLocal(const QString &action, bool argument);

View File

@@ -36,6 +36,9 @@ namespace BlackInput
//! Creates a native joystick handler object //! Creates a native joystick handler object
static std::unique_ptr<IJoystick> create(QObject *parent = nullptr); static std::unique_ptr<IJoystick> create(QObject *parent = nullptr);
//! Get all available joystick buttons
virtual BlackMisc::Input::CJoystickButtonList getAllAvailableJoystickButtons() const { return {}; }
signals: signals:
//! Joystick button combination has changed //! Joystick button combination has changed
void buttonCombinationChanged(const BlackMisc::Input::CHotkeyCombination &); void buttonCombinationChanged(const BlackMisc::Input::CHotkeyCombination &);

View File

@@ -86,6 +86,12 @@ namespace BlackInput
reloadDevices(inputDevicesDir()); reloadDevices(inputDevicesDir());
} }
CJoystickButtonList CJoystickLinux::getAllAvailableJoystickButtons() const
{
// We don't know which buttons are available yet.
return {};
}
void CJoystickLinux::cleanupJoysticks() void CJoystickLinux::cleanupJoysticks()
{ {
for (auto it = m_joystickDevices.begin(); it != m_joystickDevices.end();) for (auto it = m_joystickDevices.begin(); it != m_joystickDevices.end();)

View File

@@ -73,6 +73,9 @@ namespace BlackInput
//! \brief Destructor //! \brief Destructor
virtual ~CJoystickLinux() = default; virtual ~CJoystickLinux() = default;
//! \copydoc BlackInput::IJoystick::getAllAvailableJoystickButtons()
virtual BlackMisc::Input::CJoystickButtonList getAllAvailableJoystickButtons() const override;
private: private:
friend class IJoystick; friend class IJoystick;

View File

@@ -13,6 +13,7 @@
//! \file //! \file
#include "blackinput/joystick.h" #include "blackinput/joystick.h"
#include "blackmisc/input/joystickbutton.h"
#include <QHash> #include <QHash>
#include <IOKit/hid/IOHIDManager.h> #include <IOKit/hid/IOHIDManager.h>
@@ -35,12 +36,15 @@ namespace BlackInput
//! Initialize device //! Initialize device
bool init(const IOHIDDeviceRef device); bool init(const IOHIDDeviceRef device);
//! Get all available device buttons
BlackMisc::Input::CJoystickButtonList getDeviceButtons() const;
//! Return the native IOHIDDeviceRef //! Return the native IOHIDDeviceRef
IOHIDDeviceRef getNativeDevice() const { return m_deviceRef; } IOHIDDeviceRef getNativeDevice() const { return m_deviceRef; }
signals: signals:
//! Joystick button changed //! Joystick button changed
void buttonChanged(const QString &name, int index, bool isPressed); void buttonChanged(const BlackMisc::Input::CJoystickButton &joystickButton, bool isPressed);
private: private:
friend bool operator == (const CJoystickDevice &lhs, const CJoystickDevice &rhs); friend bool operator == (const CJoystickDevice &lhs, const CJoystickDevice &rhs);
@@ -55,7 +59,7 @@ namespace BlackInput
QString m_deviceName = "unknown"; //!< Device name QString m_deviceName = "unknown"; //!< Device name
// IOHIDDeviceRef is owned by IOHIDManager. Do not release it. // IOHIDDeviceRef is owned by IOHIDManager. Do not release it.
IOHIDDeviceRef m_deviceRef = nullptr; IOHIDDeviceRef m_deviceRef = nullptr;
QHash<IOHIDElementRef, int> m_joystickDeviceInputs; QHash<IOHIDElementRef, BlackMisc::Input::CJoystickButton> m_joystickDeviceInputs;
}; };
//! MacOS implemenation of IJoystick //! MacOS implemenation of IJoystick
@@ -73,6 +77,9 @@ namespace BlackInput
//! Destructor //! Destructor
virtual ~CJoystickMacOS() override; virtual ~CJoystickMacOS() override;
//! \copydoc BlackInput::IJoystick::getAllAvailableJoystickButtons()
virtual BlackMisc::Input::CJoystickButtonList getAllAvailableJoystickButtons() const override;
protected: protected:
virtual bool init() override; virtual bool init() override;
@@ -88,7 +95,7 @@ namespace BlackInput
//! Remove joystick device //! Remove joystick device
void removeJoystickDevice(const IOHIDDeviceRef 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 matchCallback(void* context, IOReturn result, void* sender, IOHIDDeviceRef device);
static void removeCallback(void* context, IOReturn result, void* sender, IOHIDDeviceRef device); static void removeCallback(void* context, IOReturn result, void* sender, IOHIDDeviceRef device);

View File

@@ -17,6 +17,7 @@
#include <array> #include <array>
using namespace BlackMisc; using namespace BlackMisc;
using namespace BlackMisc::Input;
namespace BlackInput namespace BlackInput
{ {
@@ -52,8 +53,8 @@ namespace BlackInput
{ {
CLogMessage(static_cast<CJoystickMacOS *>(nullptr)).debug() << "Found joystick button " << m_joystickDeviceInputs.size(); CLogMessage(static_cast<CJoystickMacOS *>(nullptr)).debug() << "Found joystick button " << m_joystickDeviceInputs.size();
int size = m_joystickDeviceInputs.size(); int number = m_joystickDeviceInputs.size();
m_joystickDeviceInputs.insert(elementRef, size); m_joystickDeviceInputs.insert(elementRef, { m_deviceName, number });
IOHIDDeviceRegisterInputValueCallback(device, valueCallback, this); IOHIDDeviceRegisterInputValueCallback(device, valueCallback, this);
} }
} }
@@ -66,15 +67,20 @@ namespace BlackInput
return true; return true;
} }
CJoystickButtonList CJoystickDevice::getDeviceButtons() const
{
return CSequence<CJoystickButton>(m_joystickDeviceInputs.values());
}
void CJoystickDevice::processButtonEvent(IOHIDValueRef value) void CJoystickDevice::processButtonEvent(IOHIDValueRef value)
{ {
IOHIDElementRef element = IOHIDValueGetElement(value); IOHIDElementRef element = IOHIDValueGetElement(value);
int buttonNumber = m_joystickDeviceInputs.value(element, -1); CJoystickButton joystickButton = m_joystickDeviceInputs.value(element);
if (buttonNumber != -1) if (joystickButton.isValid())
{ {
bool isPressed = IOHIDValueGetIntegerValue(value) == 1; bool isPressed = IOHIDValueGetIntegerValue(value) == 1;
if (isPressed) { emit buttonChanged(m_deviceName, buttonNumber, true); } if (isPressed) { emit buttonChanged(joystickButton, true); }
else { emit buttonChanged(m_deviceName, buttonNumber, false); } 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() bool CJoystickMacOS::init()
{ {
m_hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); 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); CHotkeyCombination oldCombination(m_buttonCombination);
if (isPressed) { m_buttonCombination.addJoystickButton({name, index}); } if (isPressed) { m_buttonCombination.addJoystickButton(joystickButton); }
else { m_buttonCombination.removeJoystickButton({name, index}); } else { m_buttonCombination.removeJoystickButton(joystickButton); }
if (oldCombination != m_buttonCombination) if (oldCombination != m_buttonCombination)
{ {

View File

@@ -81,6 +81,16 @@ namespace BlackInput
return true; 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) void CJoystickDevice::timerEvent(QTimerEvent *event)
{ {
Q_UNUSED(event); Q_UNUSED(event);
@@ -123,8 +133,8 @@ namespace BlackInput
const qint32 buttonIndex = input.m_offset - DIJOFS_BUTTON0; const qint32 buttonIndex = input.m_offset - DIJOFS_BUTTON0;
bool isPressed = state.rgbButtons[buttonIndex] & 0x80; bool isPressed = state.rgbButtons[buttonIndex] & 0x80;
if (isPressed) { emit buttonChanged(m_deviceName, buttonIndex, true); } if (isPressed) { emit buttonChanged(input.m_button, true); }
else { emit buttonChanged(m_deviceName, buttonIndex, false); } else { emit buttonChanged(input.m_button, false); }
} }
return hr; return hr;
@@ -138,12 +148,11 @@ namespace BlackInput
if (dev->guidType != GUID_Button) return DIENUM_CONTINUE; if (dev->guidType != GUID_Button) return DIENUM_CONTINUE;
CJoystickDeviceInput deviceInput; CJoystickDeviceInput deviceInput;
deviceInput.m_number = joystickDevice->m_joystickDeviceInputs.size(); int number = joystickDevice->m_joystickDeviceInputs.size();
deviceInput.m_offset = DIJOFS_BUTTON(deviceInput.m_number); deviceInput.m_offset = DIJOFS_BUTTON(number);
deviceInput.m_name = QString::fromWCharArray(dev->tszName); deviceInput.m_button = CJoystickButton(joystickDevice->m_deviceName, DIJOFS_BUTTON(number) - DIJOFS_BUTTON0);
joystickDevice->m_joystickDeviceInputs.append(deviceInput); joystickDevice->m_joystickDeviceInputs.append(deviceInput);
CLogMessage(static_cast<CJoystickWindows *>(nullptr)).debug() << "Found joystick button" << QString::fromWCharArray(dev->tszName); CLogMessage(static_cast<CJoystickWindows *>(nullptr)).debug() << "Found joystick button" << QString::fromWCharArray(dev->tszName);
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
@@ -196,6 +205,16 @@ namespace BlackInput
destroyHelperWindow(); 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) void ReleaseDirectInput(IDirectInput8 *obj)
{ {
if (obj) { obj->Release(); } 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); BlackMisc::Input::CHotkeyCombination oldCombination(m_buttonCombination);
if (isPressed) { m_buttonCombination.addJoystickButton({name, index}); } if (isPressed) { m_buttonCombination.addJoystickButton(joystickButton); }
else { m_buttonCombination.removeJoystickButton({name, index}); } else { m_buttonCombination.removeJoystickButton(joystickButton); }
if (oldCombination != m_buttonCombination) if (oldCombination != m_buttonCombination)
{ {
@@ -338,8 +357,7 @@ namespace BlackInput
bool operator == (CJoystickDeviceInput const &lhs, CJoystickDeviceInput const &rhs) bool operator == (CJoystickDeviceInput const &lhs, CJoystickDeviceInput const &rhs)
{ {
return lhs.m_number == rhs.m_number && return lhs.m_offset == rhs.m_offset &&
lhs.m_offset == rhs.m_offset && lhs.m_button == rhs.m_button;
lhs.m_name == rhs.m_name;
} }
} // ns } // ns

View File

@@ -33,9 +33,8 @@ namespace BlackInput
//! Joystick device input/button //! Joystick device input/button
struct CJoystickDeviceInput struct CJoystickDeviceInput
{ {
int m_number; //!< Input number int m_offset; //!< Input offset
int m_offset; //!< Input offset BlackMisc::Input::CJoystickButton m_button; //!< Joystick button
QString m_name; //!< Input name
}; };
//! Joystick device //! Joystick device
@@ -50,9 +49,12 @@ namespace BlackInput
//! Initialize DirectInput device //! Initialize DirectInput device
bool init(HWND helperWindow); bool init(HWND helperWindow);
//! Get all available device buttons
BlackMisc::Input::CJoystickButtonList getDeviceButtons() const;
signals: signals:
//! Joystick button changed //! Joystick button changed
void buttonChanged(const QString &name, int index, bool isPressed); void buttonChanged(const BlackMisc::Input::CJoystickButton &joystickButton, bool isPressed);
protected: protected:
//! Timer based updates //! Timer based updates
@@ -108,6 +110,9 @@ namespace BlackInput
//! \brief Destructor //! \brief Destructor
virtual ~CJoystickWindows() override; virtual ~CJoystickWindows() override;
//! \copydoc BlackInput::IJoystick::getAllAvailableJoystickButtons()
virtual BlackMisc::Input::CJoystickButtonList getAllAvailableJoystickButtons() const override;
private: private:
friend class IJoystick; friend class IJoystick;
@@ -129,7 +134,7 @@ namespace BlackInput
//! Add new joystick device //! Add new joystick device
void addJoystickDevice(const DIDEVICEINSTANCE *pdidInstance); 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 //! Joystick enumeration callback
static BOOL CALLBACK enumJoysticksCallback(const DIDEVICEINSTANCE *pdidInstance, VOID *pContext); static BOOL CALLBACK enumJoysticksCallback(const DIDEVICEINSTANCE *pdidInstance, VOID *pContext);