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();
}
CJoystickButtonList CInputManager::getAllAvailableJoystickButtons() const
{
return m_joystick->getAllAvailableJoystickButtons();
}
int CInputManager::bindImpl(const QString &action, QObject *receiver, std::function<void (bool)> function)
{
static int index = 0;

View File

@@ -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);

View File

@@ -36,6 +36,9 @@ namespace BlackInput
//! Creates a native joystick handler object
static std::unique_ptr<IJoystick> 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 &);

View File

@@ -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();)

View File

@@ -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;

View File

@@ -13,6 +13,7 @@
//! \file
#include "blackinput/joystick.h"
#include "blackmisc/input/joystickbutton.h"
#include <QHash>
#include <IOKit/hid/IOHIDManager.h>
@@ -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<IOHIDElementRef, int> m_joystickDeviceInputs;
QHash<IOHIDElementRef, BlackMisc::Input::CJoystickButton> 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);

View File

@@ -17,6 +17,7 @@
#include <array>
using namespace BlackMisc;
using namespace BlackMisc::Input;
namespace BlackInput
{
@@ -52,8 +53,8 @@ namespace BlackInput
{
CLogMessage(static_cast<CJoystickMacOS *>(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<CJoystickButton>(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)
{

View File

@@ -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<CJoystickWindows *>(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

View File

@@ -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);