mirror of
https://github.com/AxioDL/boo.git
synced 2025-12-09 05:27:58 +00:00
Merge branch 'master' of ssh://git.axiodl.com:6431/AxioDL/boo
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
#include "boo/inputdev/DeviceBase.hpp"
|
||||
#include "boo/inputdev/DeviceToken.hpp"
|
||||
#include "IHIDDevice.hpp"
|
||||
#include <cstdarg>
|
||||
#include "lib/inputdev/IHIDDevice.hpp"
|
||||
|
||||
namespace boo {
|
||||
|
||||
@@ -37,25 +36,25 @@ size_t DeviceBase::receiveUSBInterruptTransfer(uint8_t* data, size_t length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned DeviceBase::getVendorId() {
|
||||
unsigned DeviceBase::getVendorId() const {
|
||||
if (m_token)
|
||||
return m_token->getVendorId();
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned DeviceBase::getProductId() {
|
||||
unsigned DeviceBase::getProductId() const {
|
||||
if (m_token)
|
||||
return m_token->getProductId();
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string_view DeviceBase::getVendorName() {
|
||||
std::string_view DeviceBase::getVendorName() const {
|
||||
if (m_token)
|
||||
return m_token->getVendorName();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string_view DeviceBase::getProductName() {
|
||||
std::string_view DeviceBase::getProductName() const {
|
||||
if (m_token)
|
||||
return m_token->getProductName();
|
||||
return {};
|
||||
@@ -63,14 +62,14 @@ std::string_view DeviceBase::getProductName() {
|
||||
|
||||
#if _WIN32
|
||||
#if !WINDOWS_STORE
|
||||
const PHIDP_PREPARSED_DATA DeviceBase::getReportDescriptor() {
|
||||
PHIDP_PREPARSED_DATA DeviceBase::getReportDescriptor() const {
|
||||
if (m_hidDev)
|
||||
return m_hidDev->_getReportDescriptor();
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
std::vector<uint8_t> DeviceBase::getReportDescriptor() {
|
||||
std::vector<uint8_t> DeviceBase::getReportDescriptor() const {
|
||||
if (m_hidDev)
|
||||
return m_hidDev->_getReportDescriptor();
|
||||
return {};
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "boo/inputdev/DeviceFinder.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#if _WIN32
|
||||
#include <Dbt.h>
|
||||
#include <hidclass.h>
|
||||
@@ -10,6 +13,79 @@ namespace boo {
|
||||
|
||||
DeviceFinder* DeviceFinder::skDevFinder = nullptr;
|
||||
|
||||
DeviceFinder::DeviceFinder(std::unordered_set<uint64_t> types) {
|
||||
if (skDevFinder) {
|
||||
fmt::print(stderr, fmt("only one instance of CDeviceFinder may be constructed"));
|
||||
std::abort();
|
||||
}
|
||||
skDevFinder = this;
|
||||
for (const uint64_t& typeHash : types) {
|
||||
const DeviceSignature* sigIter = BOO_DEVICE_SIGS;
|
||||
while (sigIter->m_name) {
|
||||
if (sigIter->m_typeHash == typeHash)
|
||||
m_types.push_back(sigIter);
|
||||
++sigIter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeviceFinder::~DeviceFinder() {
|
||||
if (m_listener)
|
||||
m_listener->stopScanning();
|
||||
skDevFinder = nullptr;
|
||||
}
|
||||
|
||||
bool DeviceFinder::_insertToken(std::unique_ptr<DeviceToken>&& token) {
|
||||
if (!DeviceSignature::DeviceMatchToken(*token, m_types)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_tokensLock.lock();
|
||||
const TInsertedDeviceToken insertedTok = m_tokens.emplace(token->getDevicePath(), std::move(token));
|
||||
m_tokensLock.unlock();
|
||||
deviceConnected(*insertedTok.first->second);
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeviceFinder::_removeToken(const std::string& path) {
|
||||
const auto preCheck = m_tokens.find(path);
|
||||
if (preCheck == m_tokens.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceToken& tok = *preCheck->second;
|
||||
std::shared_ptr<DeviceBase> dev = tok.m_connectedDev;
|
||||
tok._deviceClose();
|
||||
deviceDisconnected(tok, dev.get());
|
||||
m_tokensLock.lock();
|
||||
m_tokens.erase(preCheck);
|
||||
m_tokensLock.unlock();
|
||||
}
|
||||
|
||||
bool DeviceFinder::startScanning() {
|
||||
if (!m_listener)
|
||||
m_listener = IHIDListenerNew(*this);
|
||||
if (m_listener)
|
||||
return m_listener->startScanning();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceFinder::stopScanning() {
|
||||
if (!m_listener)
|
||||
m_listener = IHIDListenerNew(*this);
|
||||
if (m_listener)
|
||||
return m_listener->stopScanning();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceFinder::scanNow() {
|
||||
if (!m_listener)
|
||||
m_listener = IHIDListenerNew(*this);
|
||||
if (m_listener)
|
||||
return m_listener->scanNow();
|
||||
return false;
|
||||
}
|
||||
|
||||
#if _WIN32 && !WINDOWS_STORE
|
||||
/* Windows-specific WM_DEVICECHANGED handler */
|
||||
LRESULT DeviceFinder::winDevChangedHandler(WPARAM wParam, LPARAM lParam) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "boo/inputdev/DeviceSignature.hpp"
|
||||
#include "boo/inputdev/DeviceToken.hpp"
|
||||
#include "boo/inputdev/GenericPad.hpp"
|
||||
#include "IHIDDevice.hpp"
|
||||
#include "lib/inputdev/IHIDDevice.hpp"
|
||||
|
||||
namespace boo {
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "boo/inputdev/DolphinSmashAdapter.hpp"
|
||||
#include "boo/inputdev/DeviceSignature.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
@@ -54,7 +55,7 @@ void DolphinSmashAdapter::transferCycle() {
|
||||
if (recvSz != 37 || payload[0] != 0x21)
|
||||
return;
|
||||
|
||||
// printf("RECEIVED DATA %zu %02X\n", recvSz, payload[0]);
|
||||
// fmt::print("RECEIVED DATA {} {:02X}\n", recvSz, payload[0]);
|
||||
|
||||
std::lock_guard<std::mutex> lk(m_callbackLock);
|
||||
if (!m_callback)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#include "boo/inputdev/DualshockPad.hpp"
|
||||
#include "boo/inputdev/DeviceSignature.hpp"
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <memory.h>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
inline uint16_t bswap16(uint16_t val) { return _byteswap_ushort(val); }
|
||||
@@ -42,16 +43,20 @@ void DualshockPad::deviceDisconnected() {
|
||||
|
||||
void DualshockPad::initialCycle() {
|
||||
#if 0
|
||||
uint8_t setupCommand[5] = {0xF4, 0x42, 0x0c, 0x00, 0x00}; //Tells controller to start sending changes on in pipe
|
||||
if (!sendHIDReport(setupCommand, 5, HIDReportType::Feature, 0xF4))
|
||||
{
|
||||
deviceError("Unable to send complete packet! Request size %x\n", sizeof(setupCommand));
|
||||
return;
|
||||
}
|
||||
uint8_t btAddr[8];
|
||||
receiveHIDReport(btAddr, sizeof(btAddr), HIDReportType::Feature, 0xF5);
|
||||
for (int i = 0; i < 6; i++)
|
||||
m_btAddress[5 - i] = btAddr[i + 2]; // Copy into buffer reversed, so it is LSB first
|
||||
// Tells controller to start sending changes on in pipe
|
||||
uint8_t setupCommand[5] = {0xF4, 0x42, 0x0c, 0x00, 0x00};
|
||||
|
||||
if (!sendHIDReport(setupCommand, 5, HIDReportType::Feature, 0xF4)) {
|
||||
deviceError("Unable to send complete packet! Request size {:x}\n", sizeof(setupCommand));
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t btAddr[8];
|
||||
receiveHIDReport(btAddr, sizeof(btAddr), HIDReportType::Feature, 0xF5);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
// Copy into buffer reversed, so it is LSB first
|
||||
m_btAddress[5 - i] = btAddr[i + 2];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,12 @@ class HIDListenerBSD final : public IHIDListener {
|
||||
|
||||
public:
|
||||
HIDListenerBSD(DeviceFinder& finder) : m_finder(finder) {}
|
||||
~HIDListenerBSD() override = default;
|
||||
|
||||
~HIDListenerBSD() {}
|
||||
bool startScanning() override { return false; }
|
||||
bool stopScanning() override { return false; }
|
||||
|
||||
bool startScanning() { return false; }
|
||||
bool stopScanning() { return false; }
|
||||
|
||||
bool scanNow() { return false; }
|
||||
bool scanNow() override { return false; }
|
||||
};
|
||||
|
||||
IHIDListener* IHIDListenerNew(DeviceFinder& finder) { return new HIDListenerBSD(finder); }
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#include "IHIDDevice.hpp"
|
||||
#include "lib/inputdev/IHIDDevice.hpp"
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "lib/inputdev/IOKitPointer.hpp"
|
||||
|
||||
#include <IOKit/hid/IOHIDLib.h>
|
||||
#include <IOKit/hid/IOHIDDevicePlugin.h>
|
||||
#include <IOKit/usb/IOUSBLib.h>
|
||||
#include "IOKitPointer.hpp"
|
||||
#include <thread>
|
||||
|
||||
namespace boo {
|
||||
|
||||
@@ -23,7 +26,7 @@ class HIDDeviceIOKit : public IHIDDevice {
|
||||
std::condition_variable m_initCond;
|
||||
std::thread m_thread;
|
||||
|
||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) {
|
||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) override {
|
||||
if (m_usbIntf) {
|
||||
IOReturn res = m_usbIntf->WritePipe(m_usbIntf.storage(), m_usbIntfOutPipe, (void*)data, length);
|
||||
return res == kIOReturnSuccess;
|
||||
@@ -31,7 +34,7 @@ class HIDDeviceIOKit : public IHIDDevice {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) {
|
||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) override {
|
||||
if (m_usbIntf) {
|
||||
UInt32 readSize = length;
|
||||
IOReturn res = m_usbIntf->ReadPipe(m_usbIntf.storage(), m_usbIntfInPipe, data, &readSize);
|
||||
@@ -42,7 +45,7 @@ class HIDDeviceIOKit : public IHIDDevice {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> _getReportDescriptor() {
|
||||
std::vector<uint8_t> _getReportDescriptor() override {
|
||||
if (m_hidIntf) {
|
||||
if (CFTypeRef desc = IOHIDDeviceGetProperty(m_hidIntf.get(), CFSTR(kIOHIDReportDescriptorKey))) {
|
||||
CFIndex len = CFDataGetLength(CFDataRef(desc));
|
||||
@@ -54,7 +57,7 @@ class HIDDeviceIOKit : public IHIDDevice {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {
|
||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override {
|
||||
/* HACK: A bug in IOBluetoothGamepadHIDDriver prevents raw output report transmission
|
||||
* USB driver appears to work correctly */
|
||||
if (m_hidIntf && !m_isBt) {
|
||||
@@ -64,7 +67,7 @@ class HIDDeviceIOKit : public IHIDDevice {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {
|
||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override {
|
||||
if (m_hidIntf) {
|
||||
CFIndex readSize = length;
|
||||
IOReturn res = IOHIDDeviceGetReport(m_hidIntf.get(), IOHIDReportType(tp), message, data, &readSize);
|
||||
@@ -273,13 +276,13 @@ class HIDDeviceIOKit : public IHIDDevice {
|
||||
device->m_hidIntf.reset();
|
||||
}
|
||||
|
||||
void _deviceDisconnected() { m_runningTransferLoop = false; }
|
||||
void _deviceDisconnected() override { m_runningTransferLoop = false; }
|
||||
|
||||
public:
|
||||
HIDDeviceIOKit(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
|
||||
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
|
||||
|
||||
void _startThread() {
|
||||
void _startThread() override {
|
||||
std::unique_lock<std::mutex> lk(m_initMutex);
|
||||
DeviceType dType = m_token.getDeviceType();
|
||||
if (dType == DeviceType::USB)
|
||||
@@ -295,7 +298,7 @@ public:
|
||||
m_initCond.wait(lk);
|
||||
}
|
||||
|
||||
~HIDDeviceIOKit() {
|
||||
~HIDDeviceIOKit() override {
|
||||
m_runningTransferLoop = false;
|
||||
if (m_thread.joinable())
|
||||
m_thread.detach();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "IHIDDevice.hpp"
|
||||
#include "lib/inputdev/IHIDDevice.hpp"
|
||||
|
||||
namespace boo {
|
||||
|
||||
@@ -11,13 +11,13 @@ public:
|
||||
HIDDeviceNX(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
|
||||
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
|
||||
|
||||
void _deviceDisconnected() {}
|
||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) { return false; }
|
||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) { return 0; }
|
||||
std::vector<uint8_t> _getReportDescriptor() { return {}; }
|
||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) { return false; }
|
||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) { return 0; }
|
||||
void _startThread() {}
|
||||
void _deviceDisconnected() override {}
|
||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) override { return false; }
|
||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) override { return 0; }
|
||||
std::vector<uint8_t> _getReportDescriptor() override { return {}; }
|
||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override { return false; }
|
||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override { return 0; }
|
||||
void _startThread() override {}
|
||||
};
|
||||
|
||||
std::shared_ptr<IHIDDevice> IHIDDeviceNew(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
||||
#include "IHIDDevice.hpp"
|
||||
|
||||
#include "lib/inputdev/IHIDDevice.hpp"
|
||||
|
||||
#include "boo/inputdev/DeviceToken.hpp"
|
||||
#include "boo/inputdev/DeviceBase.hpp"
|
||||
|
||||
@@ -9,12 +11,12 @@ class HIDDeviceUWP : public IHIDDevice {
|
||||
public:
|
||||
HIDDeviceUWP(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {}
|
||||
|
||||
void _deviceDisconnected() {}
|
||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) { return false; }
|
||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) { return 0; }
|
||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) { return false; }
|
||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) { return false; }
|
||||
void _startThread() {}
|
||||
void _deviceDisconnected() override {}
|
||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) override { return false; }
|
||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) override { return 0; }
|
||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override { return false; }
|
||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override { return false; }
|
||||
void _startThread() override {}
|
||||
};
|
||||
|
||||
std::shared_ptr<IHIDDevice> IHIDDeviceNew(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
#include "IHIDDevice.hpp"
|
||||
#include "lib/inputdev/IHIDDevice.hpp"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#include "boo/inputdev/DeviceToken.hpp"
|
||||
#include "boo/inputdev/DeviceBase.hpp"
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include "boo/inputdev/HIDParser.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <fcntl.h>
|
||||
#include <libudev.h>
|
||||
#include <stropts.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usbdevice_fs.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/hidraw.h>
|
||||
#include <fcntl.h>
|
||||
#include <stropts.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include "boo/inputdev/HIDParser.hpp"
|
||||
|
||||
namespace boo {
|
||||
|
||||
@@ -40,7 +42,7 @@ class HIDDeviceUdev final : public IHIDDevice {
|
||||
std::condition_variable m_initCond;
|
||||
std::thread m_thread;
|
||||
|
||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) {
|
||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) override {
|
||||
if (m_devFd) {
|
||||
usbdevfs_bulktransfer xfer = {m_usbIntfOutPipe | USB_DIR_OUT, (unsigned)length, 30, (void*)data};
|
||||
int ret = ioctl(m_devFd, USBDEVFS_BULK, &xfer);
|
||||
@@ -51,7 +53,7 @@ class HIDDeviceUdev final : public IHIDDevice {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) {
|
||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) override {
|
||||
if (m_devFd) {
|
||||
usbdevfs_bulktransfer xfer = {m_usbIntfInPipe | USB_DIR_IN, (unsigned)length, 30, data};
|
||||
return ioctl(m_devFd, USBDEVFS_BULK, &xfer);
|
||||
@@ -102,7 +104,7 @@ class HIDDeviceUdev final : public IHIDDevice {
|
||||
}
|
||||
|
||||
/* Request that kernel disconnects existing driver */
|
||||
usbdevfs_ioctl disconnectReq = {0, USBDEVFS_DISCONNECT, NULL};
|
||||
usbdevfs_ioctl disconnectReq = {0, USBDEVFS_DISCONNECT, nullptr};
|
||||
ioctl(fd, USBDEVFS_IOCTL, &disconnectReq);
|
||||
|
||||
/* Return control to main thread */
|
||||
@@ -209,9 +211,9 @@ class HIDDeviceUdev final : public IHIDDevice {
|
||||
udev_device_unref(udevDev);
|
||||
}
|
||||
|
||||
void _deviceDisconnected() { m_runningTransferLoop = false; }
|
||||
void _deviceDisconnected() override { m_runningTransferLoop = false; }
|
||||
|
||||
std::vector<uint8_t> _getReportDescriptor() {
|
||||
std::vector<uint8_t> _getReportDescriptor() override {
|
||||
/* Report descriptor size */
|
||||
int reportDescSize;
|
||||
if (ioctl(m_devFd, HIDIOCGRDESCSIZE, &reportDescSize) == -1)
|
||||
@@ -227,7 +229,7 @@ class HIDDeviceUdev final : public IHIDDevice {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {
|
||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override {
|
||||
if (m_devFd) {
|
||||
if (tp == HIDReportType::Feature) {
|
||||
int ret = ioctl(m_devFd, HIDIOCSFEATURE(length), data);
|
||||
@@ -244,7 +246,7 @@ class HIDDeviceUdev final : public IHIDDevice {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {
|
||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override {
|
||||
if (m_devFd) {
|
||||
if (tp == HIDReportType::Feature) {
|
||||
data[0] = message;
|
||||
@@ -261,7 +263,7 @@ public:
|
||||
HIDDeviceUdev(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
|
||||
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
|
||||
|
||||
void _startThread() {
|
||||
void _startThread() override {
|
||||
std::unique_lock<std::mutex> lk(m_initMutex);
|
||||
DeviceType dType = m_token.getDeviceType();
|
||||
if (dType == DeviceType::USB)
|
||||
@@ -277,7 +279,7 @@ public:
|
||||
m_initCond.wait(lk);
|
||||
}
|
||||
|
||||
~HIDDeviceUdev() {
|
||||
~HIDDeviceUdev() override {
|
||||
m_runningTransferLoop = false;
|
||||
if (m_thread.joinable())
|
||||
m_thread.detach();
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
||||
#include "IHIDDevice.hpp"
|
||||
#include "lib/inputdev/IHIDDevice.hpp"
|
||||
|
||||
#include "boo/inputdev/DeviceToken.hpp"
|
||||
#include "boo/inputdev/DeviceBase.hpp"
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#include <algorithm>
|
||||
#include <condition_variable>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
@@ -27,8 +29,8 @@ class HIDDeviceWinUSB final : public IHIDDevice {
|
||||
DeviceToken& m_token;
|
||||
std::shared_ptr<DeviceBase> m_devImp;
|
||||
|
||||
HANDLE m_devHandle = 0;
|
||||
HANDLE m_hidHandle = 0;
|
||||
HANDLE m_devHandle = nullptr;
|
||||
HANDLE m_hidHandle = nullptr;
|
||||
WINUSB_INTERFACE_HANDLE m_usbHandle = nullptr;
|
||||
unsigned m_usbIntfInPipe = 0;
|
||||
unsigned m_usbIntfOutPipe = 0;
|
||||
@@ -39,21 +41,22 @@ class HIDDeviceWinUSB final : public IHIDDevice {
|
||||
std::condition_variable m_initCond;
|
||||
std::thread m_thread;
|
||||
|
||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) {
|
||||
bool _sendUSBInterruptTransfer(const uint8_t* data, size_t length) override {
|
||||
if (m_usbHandle) {
|
||||
ULONG lengthTransferred = 0;
|
||||
if (!WinUsb_WritePipe(m_usbHandle, m_usbIntfOutPipe, (PUCHAR)data, (ULONG)length, &lengthTransferred, NULL) ||
|
||||
lengthTransferred != length)
|
||||
if (!WinUsb_WritePipe(m_usbHandle, m_usbIntfOutPipe, (PUCHAR)data, (ULONG)length, &lengthTransferred, nullptr) ||
|
||||
lengthTransferred != length) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) {
|
||||
size_t _receiveUSBInterruptTransfer(uint8_t* data, size_t length) override {
|
||||
if (m_usbHandle) {
|
||||
ULONG lengthTransferred = 0;
|
||||
if (!WinUsb_ReadPipe(m_usbHandle, m_usbIntfInPipe, (PUCHAR)data, (ULONG)length, &lengthTransferred, NULL))
|
||||
if (!WinUsb_ReadPipe(m_usbHandle, m_usbIntfInPipe, (PUCHAR)data, (ULONG)length, &lengthTransferred, nullptr))
|
||||
return 0;
|
||||
return lengthTransferred;
|
||||
}
|
||||
@@ -66,8 +69,8 @@ class HIDDeviceWinUSB final : public IHIDDevice {
|
||||
|
||||
/* POSIX.. who needs it?? -MS */
|
||||
device->m_devHandle =
|
||||
CreateFileA(device->m_devPath.data(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
||||
CreateFileA(device->m_devPath.data(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, nullptr,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr);
|
||||
if (INVALID_HANDLE_VALUE == device->m_devHandle) {
|
||||
device->m_devImp->deviceError(fmt("Unable to open {}@{}: {}\n"),
|
||||
device->m_token.getProductName(), device->m_devPath, GetLastError());
|
||||
@@ -150,8 +153,8 @@ class HIDDeviceWinUSB final : public IHIDDevice {
|
||||
/* POSIX.. who needs it?? -MS */
|
||||
device->m_overlapped.hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
||||
device->m_hidHandle =
|
||||
CreateFileA(device->m_devPath.data(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
||||
CreateFileA(device->m_devPath.data(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, nullptr,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr);
|
||||
if (INVALID_HANDLE_VALUE == device->m_hidHandle) {
|
||||
device->m_devImp->deviceError(fmt("Unable to open {}@{}: {}\n"),
|
||||
device->m_token.getProductName(), device->m_devPath, GetLastError());
|
||||
@@ -199,14 +202,14 @@ class HIDDeviceWinUSB final : public IHIDDevice {
|
||||
device->m_hidHandle = nullptr;
|
||||
}
|
||||
|
||||
void _deviceDisconnected() { m_runningTransferLoop = false; }
|
||||
void _deviceDisconnected() override { m_runningTransferLoop = false; }
|
||||
|
||||
std::vector<uint8_t> m_sendBuf;
|
||||
std::vector<uint8_t> m_recvBuf;
|
||||
|
||||
const PHIDP_PREPARSED_DATA _getReportDescriptor() { return m_preparsedData; }
|
||||
const PHIDP_PREPARSED_DATA _getReportDescriptor() override { return m_preparsedData; }
|
||||
|
||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {
|
||||
bool _sendHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override {
|
||||
size_t maxOut = std::max(m_minFeatureSz, std::max(m_minOutputSz, length));
|
||||
if (m_sendBuf.size() < maxOut)
|
||||
m_sendBuf.resize(maxOut);
|
||||
@@ -250,7 +253,7 @@ class HIDDeviceWinUSB final : public IHIDDevice {
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {
|
||||
size_t _receiveHIDReport(uint8_t* data, size_t length, HIDReportType tp, uint32_t message) override {
|
||||
size_t maxIn = std::max(m_minFeatureSz, std::max(m_minInputSz, length));
|
||||
if (m_recvBuf.size() < maxIn)
|
||||
m_recvBuf.resize(maxIn);
|
||||
@@ -273,7 +276,7 @@ public:
|
||||
HIDDeviceWinUSB(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp)
|
||||
: m_token(token), m_devImp(devImp), m_devPath(token.getDevicePath()) {}
|
||||
|
||||
void _startThread() {
|
||||
void _startThread() override {
|
||||
std::unique_lock<std::mutex> lk(m_initMutex);
|
||||
DeviceType dType = m_token.getDeviceType();
|
||||
if (dType == DeviceType::USB)
|
||||
@@ -287,7 +290,7 @@ public:
|
||||
m_initCond.wait(lk);
|
||||
}
|
||||
|
||||
~HIDDeviceWinUSB() {
|
||||
~HIDDeviceWinUSB() override {
|
||||
m_runningTransferLoop = false;
|
||||
if (m_thread.joinable())
|
||||
m_thread.detach();
|
||||
|
||||
@@ -16,8 +16,7 @@ class HIDDeviceBSD final : public IHIDDevice {
|
||||
|
||||
public:
|
||||
HIDDeviceBSD(DeviceToken& token, DeviceBase& devImp) : m_token(token), m_devImp(devImp) {}
|
||||
|
||||
~HIDDeviceBSD() {}
|
||||
~HIDDeviceBSD() override = default;
|
||||
};
|
||||
|
||||
std::shared_ptr<IHIDDevice> IHIDDeviceNew(DeviceToken& token, const std::shared_ptr<DeviceBase>& devImp) {
|
||||
|
||||
@@ -108,7 +108,7 @@ class HIDListenerIOKit : public IHIDListener {
|
||||
|
||||
listener->m_finder._insertToken(std::make_unique<DeviceToken>(DeviceType::USB, vid, pid, vstr, pstr, devPath));
|
||||
|
||||
// printf("ADDED %08X %s\n", obj.get(), devPath);
|
||||
// fmt::print(fmt("ADDED {:08X} {}\n"), obj.get(), devPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ class HIDListenerIOKit : public IHIDListener {
|
||||
if (IORegistryEntryGetPath(obj.get(), kIOServicePlane, devPath) != 0)
|
||||
continue;
|
||||
listener->m_finder._removeToken(devPath);
|
||||
// printf("REMOVED %08X %s\n", obj.get(), devPath);
|
||||
// fmt::print(fmt("REMOVED {:08X} {}\n"), obj.get(), devPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ class HIDListenerIOKit : public IHIDListener {
|
||||
|
||||
listener->m_finder._insertToken(std::make_unique<DeviceToken>(DeviceType::HID, vidv, pidv, vstr, pstr, devPath));
|
||||
|
||||
// printf("ADDED %08X %s\n", obj, devPath);
|
||||
// fmt::print(fmt("ADDED {:08X} {}\n"), obj, devPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ class HIDListenerIOKit : public IHIDListener {
|
||||
if (IORegistryEntryGetPath(obj.get(), kIOServicePlane, devPath) != 0)
|
||||
continue;
|
||||
listener->m_finder._removeToken(devPath);
|
||||
// printf("REMOVED %08X %s\n", obj, devPath);
|
||||
// fmt::print(fmt("REMOVED {:08X} {}\n"), obj, devPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,23 +263,23 @@ public:
|
||||
m_scanningEnabled = false;
|
||||
}
|
||||
|
||||
~HIDListenerIOKit() {
|
||||
~HIDListenerIOKit() override {
|
||||
// CFRunLoopRemoveSource(m_listenerRunLoop, IONotificationPortGetRunLoopSource(m_llPort), kCFRunLoopDefaultMode);
|
||||
IONotificationPortDestroy(m_llPort);
|
||||
}
|
||||
|
||||
/* Automatic device scanning */
|
||||
bool startScanning() {
|
||||
bool startScanning() override {
|
||||
m_scanningEnabled = true;
|
||||
return true;
|
||||
}
|
||||
bool stopScanning() {
|
||||
bool stopScanning() override {
|
||||
m_scanningEnabled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Manual device scanning */
|
||||
bool scanNow() {
|
||||
bool scanNow() override {
|
||||
IOObjectPointer<io_iterator_t> iter;
|
||||
if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(m_usbClass), &iter) == kIOReturnSuccess) {
|
||||
devicesConnectedUSBLL(this, iter.get());
|
||||
|
||||
@@ -8,9 +8,9 @@ class HIDListenerNX : public IHIDListener {
|
||||
public:
|
||||
HIDListenerNX(DeviceFinder& finder) : m_finder(finder) {}
|
||||
|
||||
bool startScanning() { return false; }
|
||||
bool stopScanning() { return false; }
|
||||
bool scanNow() { return false; }
|
||||
bool startScanning() override { return false; }
|
||||
bool stopScanning() override { return false; }
|
||||
bool scanNow() override { return false; }
|
||||
};
|
||||
|
||||
std::unique_ptr<IHIDListener> IHIDListenerNew(DeviceFinder& finder) { return std::make_unique<HIDListenerNX>(finder); }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
||||
|
||||
#include "boo/inputdev/IHIDListener.hpp"
|
||||
#include "boo/inputdev/DeviceFinder.hpp"
|
||||
|
||||
@@ -9,11 +10,11 @@ public:
|
||||
HIDListenerUWP(DeviceFinder& finder) {}
|
||||
|
||||
/* Automatic device scanning */
|
||||
bool startScanning() { return false; }
|
||||
bool stopScanning() { return false; }
|
||||
bool startScanning() override { return false; }
|
||||
bool stopScanning() override { return false; }
|
||||
|
||||
/* Manual device scanning */
|
||||
bool scanNow() { return false; }
|
||||
bool scanNow() override { return false; }
|
||||
};
|
||||
|
||||
std::unique_ptr<IHIDListener> IHIDListenerNew(DeviceFinder& finder) { return std::make_unique<HIDListenerUWP>(finder); }
|
||||
|
||||
@@ -118,14 +118,14 @@ class HIDListenerUdev final : public IHIDListener {
|
||||
}
|
||||
|
||||
#if 0
|
||||
udev_list_entry* att = nullptr;
|
||||
udev_list_entry_foreach(att, attrs)
|
||||
{
|
||||
const char* name = udev_list_entry_get_name(att);
|
||||
const char* val = udev_list_entry_get_value(att);
|
||||
fprintf(stderr, "%s %s\n", name, val);
|
||||
}
|
||||
fprintf(stderr, "\n\n");
|
||||
udev_list_entry* att = nullptr;
|
||||
udev_list_entry_foreach(att, attrs)
|
||||
{
|
||||
const char* name = udev_list_entry_get_name(att);
|
||||
const char* val = udev_list_entry_get_value(att);
|
||||
fmt::print(stderr, fmt("{} {}\n"), name, val);
|
||||
}
|
||||
std::fputs("\n\n", stderr);
|
||||
#endif
|
||||
|
||||
m_finder._insertToken(std::make_unique<DeviceToken>(type, vid, pid, manuf, product, devPath));
|
||||
@@ -187,7 +187,7 @@ public:
|
||||
m_udevThread = std::thread(std::bind(&HIDListenerUdev::_udevProc, this), this);
|
||||
}
|
||||
|
||||
~HIDListenerUdev() {
|
||||
~HIDListenerUdev() override {
|
||||
pthread_cancel(m_udevThread.native_handle());
|
||||
if (m_udevThread.joinable())
|
||||
m_udevThread.join();
|
||||
@@ -195,17 +195,17 @@ public:
|
||||
}
|
||||
|
||||
/* Automatic device scanning */
|
||||
bool startScanning() {
|
||||
bool startScanning() override {
|
||||
m_scanningEnabled = true;
|
||||
return true;
|
||||
}
|
||||
bool stopScanning() {
|
||||
bool stopScanning() override {
|
||||
m_scanningEnabled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Manual device scanning */
|
||||
bool scanNow() {
|
||||
bool scanNow() override {
|
||||
udev_enumerate* uenum = udev_enumerate_new(GetUdev());
|
||||
udev_enumerate_add_match_subsystem(uenum, "usb");
|
||||
udev_enumerate_add_match_subsystem(uenum, "bluetooth");
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS 1 /* STFU MSVC */
|
||||
|
||||
#include "boo/inputdev/IHIDListener.hpp"
|
||||
#include "boo/inputdev/DeviceFinder.hpp"
|
||||
#include "boo/inputdev/XInputPad.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
|
||||
#include "boo/inputdev/DeviceFinder.hpp"
|
||||
#include "boo/inputdev/XInputPad.hpp"
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
@@ -51,17 +54,17 @@ class HIDListenerWinUSB final : public IHIDListener {
|
||||
CHAR szVid[MAX_DEVICE_ID_LEN], szPid[MAX_DEVICE_ID_LEN], szMi[MAX_DEVICE_ID_LEN];
|
||||
|
||||
/* List all connected HID devices */
|
||||
hDevInfo = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE);
|
||||
hDevInfo = SetupDiGetClassDevs(nullptr, 0, 0, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE);
|
||||
if (hDevInfo == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
for (i = 0;; ++i) {
|
||||
if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, TypeGUID, i, &DeviceInterfaceData))
|
||||
if (!SetupDiEnumDeviceInterfaces(hDevInfo, nullptr, TypeGUID, i, &DeviceInterfaceData))
|
||||
break;
|
||||
|
||||
DeviceInterfaceDetailData.wtf.cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||
if (!SetupDiGetDeviceInterfaceDetailA(hDevInfo, &DeviceInterfaceData, &DeviceInterfaceDetailData.wtf,
|
||||
sizeof(DeviceInterfaceDetailData), NULL, &DeviceInfoData))
|
||||
sizeof(DeviceInterfaceDetailData), nullptr, &DeviceInfoData))
|
||||
continue;
|
||||
|
||||
r = CM_Get_Device_IDA(DeviceInfoData.DevInst, szDeviceInstanceID, MAX_PATH, 0);
|
||||
@@ -73,7 +76,7 @@ class HIDListenerWinUSB final : public IHIDListener {
|
||||
szVid[0] = '\0';
|
||||
szPid[0] = '\0';
|
||||
szMi[0] = '\0';
|
||||
while (pszToken != NULL) {
|
||||
while (pszToken != nullptr) {
|
||||
for (j = 0; j < 3; ++j) {
|
||||
if (strncmp(pszToken, arPrefix[j], 4) == 0) {
|
||||
switch (j) {
|
||||
@@ -91,14 +94,14 @@ class HIDListenerWinUSB final : public IHIDListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
pszToken = strtok_s(NULL, "\\#&", &pszNextToken);
|
||||
pszToken = strtok_s(nullptr, "\\#&", &pszNextToken);
|
||||
}
|
||||
|
||||
if (!szVid[0] || !szPid[0])
|
||||
continue;
|
||||
|
||||
unsigned vid = strtol(szVid + 4, NULL, 16);
|
||||
unsigned pid = strtol(szPid + 4, NULL, 16);
|
||||
unsigned vid = strtol(szVid + 4, nullptr, 16);
|
||||
unsigned pid = strtol(szPid + 4, nullptr, 16);
|
||||
|
||||
CHAR productW[1024] = {0};
|
||||
// CHAR product[1024] = {0};
|
||||
@@ -121,8 +124,8 @@ class HIDListenerWinUSB final : public IHIDListener {
|
||||
|
||||
if (type == DeviceType::HID) {
|
||||
HANDLE devHnd = CreateFileA(DeviceInterfaceDetailData.wtf.DevicePath, GENERIC_WRITE | GENERIC_READ,
|
||||
FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
||||
FILE_SHARE_WRITE | FILE_SHARE_READ, nullptr, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr);
|
||||
if (INVALID_HANDLE_VALUE == devHnd)
|
||||
continue;
|
||||
PHIDP_PREPARSED_DATA preparsedData;
|
||||
@@ -227,29 +230,29 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
~HIDListenerWinUSB() {
|
||||
~HIDListenerWinUSB() override {
|
||||
m_xinputRunning = false;
|
||||
if (m_xinputThread.joinable())
|
||||
m_xinputThread.join();
|
||||
}
|
||||
|
||||
/* Automatic device scanning */
|
||||
bool startScanning() {
|
||||
bool startScanning() override {
|
||||
m_scanningEnabled = true;
|
||||
return true;
|
||||
}
|
||||
bool stopScanning() {
|
||||
bool stopScanning() override {
|
||||
m_scanningEnabled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Manual device scanning */
|
||||
bool scanNow() {
|
||||
bool scanNow() override {
|
||||
_pollDevices(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _extDevConnect(const char* path) {
|
||||
bool _extDevConnect(const char* path) override {
|
||||
char upperPath[1024];
|
||||
strcpy_s(upperPath, 1024, path);
|
||||
CharUpperA(upperPath);
|
||||
@@ -258,7 +261,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _extDevDisconnect(const char* path) {
|
||||
bool _extDevDisconnect(const char* path) override {
|
||||
char upperPath[1024];
|
||||
strcpy_s(upperPath, 1024, path);
|
||||
CharUpperA(upperPath);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "boo/inputdev/HIDParser.hpp"
|
||||
#include <map>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <map>
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
@@ -11,251 +13,257 @@ namespace boo {
|
||||
* http://www.usb.org/developers/hidpage/HID1_11.pdf
|
||||
*/
|
||||
|
||||
static const char* UsagePageNames[] = {"Undefined", "Generic Desktop", "Simulation", "VR", "Sport",
|
||||
"Game Controls", "Generic Device", "Keyboard", "LEDs", "Button",
|
||||
"Ordinal", "Telephony", "Consumer", "Digitizer"};
|
||||
constexpr std::array<const char*, 14> UsagePageNames{
|
||||
"Undefined", "Generic Desktop", "Simulation", "VR", "Sport",
|
||||
"Game Controls", "Generic Device", "Keyboard", "LEDs", "Button",
|
||||
"Ordinal", "Telephony", "Consumer", "Digitizer",
|
||||
};
|
||||
|
||||
static const char* GenericDesktopUsages[] = {"Undefined",
|
||||
"Pointer",
|
||||
"Mouse",
|
||||
"Reserved",
|
||||
"Joystick",
|
||||
"Game Pad",
|
||||
"Keyboard",
|
||||
"Keypad",
|
||||
"Multi-axis Controller",
|
||||
"Tablet PC System Controls",
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
"X",
|
||||
"Y",
|
||||
"Z",
|
||||
"Rx",
|
||||
"Ry",
|
||||
"Rz",
|
||||
"Slider",
|
||||
"Dial",
|
||||
"Wheel",
|
||||
"Hat Switch",
|
||||
"Counted Buffer",
|
||||
"Byte Count",
|
||||
"Motion Wakeup",
|
||||
"Start",
|
||||
"Select",
|
||||
"Reserved",
|
||||
"Vx",
|
||||
"Vy",
|
||||
"Vz",
|
||||
"Vbrx",
|
||||
"Vbry",
|
||||
"Vbrz",
|
||||
"Vno",
|
||||
"Feature Notification",
|
||||
"Resolution Multiplier",
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
"System Control",
|
||||
"System Power Down",
|
||||
"System Sleep",
|
||||
"System Wake Up",
|
||||
"System Context Menu",
|
||||
"System Main Menu",
|
||||
"System App Menu",
|
||||
"System Menu Help",
|
||||
"System Menu Exit",
|
||||
"System Menu Select",
|
||||
"System Menu Right",
|
||||
"System Menu Left",
|
||||
"System Menu Up",
|
||||
"System Menu Down",
|
||||
"System Cold Restart",
|
||||
"System Warm Restart",
|
||||
"D-pad Up",
|
||||
"D-pad Down",
|
||||
"D-pad Right",
|
||||
"D-pad Left",
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
"System Dock",
|
||||
"System Undock",
|
||||
"System Setup",
|
||||
"System Break",
|
||||
"System Debugger Break",
|
||||
"Application Break",
|
||||
"Application Debugger Break",
|
||||
"System Speaker Mute",
|
||||
"System Hibernate",
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
"System Display Invert",
|
||||
"System Display Internal",
|
||||
"System Display External",
|
||||
"System Display Both",
|
||||
"System Display Dual",
|
||||
"System Display Toggle Int/Ext"};
|
||||
constexpr std::array<const char*, 182> GenericDesktopUsages{
|
||||
"Undefined",
|
||||
"Pointer",
|
||||
"Mouse",
|
||||
"Reserved",
|
||||
"Joystick",
|
||||
"Game Pad",
|
||||
"Keyboard",
|
||||
"Keypad",
|
||||
"Multi-axis Controller",
|
||||
"Tablet PC System Controls",
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
"X",
|
||||
"Y",
|
||||
"Z",
|
||||
"Rx",
|
||||
"Ry",
|
||||
"Rz",
|
||||
"Slider",
|
||||
"Dial",
|
||||
"Wheel",
|
||||
"Hat Switch",
|
||||
"Counted Buffer",
|
||||
"Byte Count",
|
||||
"Motion Wakeup",
|
||||
"Start",
|
||||
"Select",
|
||||
"Reserved",
|
||||
"Vx",
|
||||
"Vy",
|
||||
"Vz",
|
||||
"Vbrx",
|
||||
"Vbry",
|
||||
"Vbrz",
|
||||
"Vno",
|
||||
"Feature Notification",
|
||||
"Resolution Multiplier",
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
"System Control",
|
||||
"System Power Down",
|
||||
"System Sleep",
|
||||
"System Wake Up",
|
||||
"System Context Menu",
|
||||
"System Main Menu",
|
||||
"System App Menu",
|
||||
"System Menu Help",
|
||||
"System Menu Exit",
|
||||
"System Menu Select",
|
||||
"System Menu Right",
|
||||
"System Menu Left",
|
||||
"System Menu Up",
|
||||
"System Menu Down",
|
||||
"System Cold Restart",
|
||||
"System Warm Restart",
|
||||
"D-pad Up",
|
||||
"D-pad Down",
|
||||
"D-pad Right",
|
||||
"D-pad Left",
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
"System Dock",
|
||||
"System Undock",
|
||||
"System Setup",
|
||||
"System Break",
|
||||
"System Debugger Break",
|
||||
"Application Break",
|
||||
"Application Debugger Break",
|
||||
"System Speaker Mute",
|
||||
"System Hibernate",
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
"System Display Invert",
|
||||
"System Display Internal",
|
||||
"System Display External",
|
||||
"System Display Both",
|
||||
"System Display Dual",
|
||||
"System Display Toggle Int/Ext",
|
||||
};
|
||||
|
||||
static const char* GameUsages[] = {"Undefined",
|
||||
"3D Game Controller",
|
||||
"Pinball Device",
|
||||
"Gun Device",
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
"Point of View",
|
||||
"Turn Right/Left",
|
||||
"Pitch Forward/Backward",
|
||||
"Roll Right/Left",
|
||||
"Move Right/Left",
|
||||
"Move Forward/Backward",
|
||||
"Move Up/Down",
|
||||
"Lean Right/Left",
|
||||
"Lean Forward/Backward",
|
||||
"Height of POV",
|
||||
"Flipper",
|
||||
"Secondary Flipper",
|
||||
"Bump",
|
||||
"New Game",
|
||||
"Shoot Ball",
|
||||
"Player",
|
||||
"Gun Bolt",
|
||||
"Gun Clip",
|
||||
"Gun Selector",
|
||||
"Gun Single Shot",
|
||||
"Gun Burst",
|
||||
"Gun Automatic",
|
||||
"Gun Safety",
|
||||
"Gemepad Fire/Jump",
|
||||
nullptr,
|
||||
"Gamepad Trigger"};
|
||||
constexpr std::array<const char*, 58> GameUsages{
|
||||
"Undefined",
|
||||
"3D Game Controller",
|
||||
"Pinball Device",
|
||||
"Gun Device",
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
"Point of View",
|
||||
"Turn Right/Left",
|
||||
"Pitch Forward/Backward",
|
||||
"Roll Right/Left",
|
||||
"Move Right/Left",
|
||||
"Move Forward/Backward",
|
||||
"Move Up/Down",
|
||||
"Lean Right/Left",
|
||||
"Lean Forward/Backward",
|
||||
"Height of POV",
|
||||
"Flipper",
|
||||
"Secondary Flipper",
|
||||
"Bump",
|
||||
"New Game",
|
||||
"Shoot Ball",
|
||||
"Player",
|
||||
"Gun Bolt",
|
||||
"Gun Clip",
|
||||
"Gun Selector",
|
||||
"Gun Single Shot",
|
||||
"Gun Burst",
|
||||
"Gun Automatic",
|
||||
"Gun Safety",
|
||||
"Gemepad Fire/Jump",
|
||||
nullptr,
|
||||
"Gamepad Trigger",
|
||||
};
|
||||
|
||||
enum class HIDCollectionType : uint8_t {
|
||||
Physical,
|
||||
@@ -380,21 +388,31 @@ HIDMainItem::HIDMainItem(uint32_t flags, HIDUsagePage usagePage, HIDUsage usage,
|
||||
, m_reportSize(reportSize) {}
|
||||
|
||||
const char* HIDMainItem::GetUsagePageName() const {
|
||||
if (int(m_usagePage) >= std::extent<decltype(UsagePageNames)>::value)
|
||||
const auto index = size_t(m_usagePage);
|
||||
|
||||
if (index >= UsagePageNames.size()) {
|
||||
return nullptr;
|
||||
return UsagePageNames[int(m_usagePage)];
|
||||
}
|
||||
|
||||
return UsagePageNames[index];
|
||||
}
|
||||
|
||||
const char* HIDMainItem::GetUsageName() const {
|
||||
const auto index = size_t(m_usage);
|
||||
|
||||
switch (m_usagePage) {
|
||||
case HIDUsagePage::GenericDesktop:
|
||||
if (int(m_usage) >= std::extent<decltype(GenericDesktopUsages)>::value)
|
||||
if (index >= GenericDesktopUsages.size()) {
|
||||
return nullptr;
|
||||
return GenericDesktopUsages[int(m_usage)];
|
||||
}
|
||||
return GenericDesktopUsages[index];
|
||||
|
||||
case HIDUsagePage::Game:
|
||||
if (int(m_usage) >= std::extent<decltype(GameUsages)>::value)
|
||||
if (index >= GameUsages.size()) {
|
||||
return nullptr;
|
||||
return GameUsages[int(m_usage)];
|
||||
}
|
||||
return GameUsages[index];
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
@@ -443,17 +461,17 @@ HIDParser::ParserStatus HIDParser::Parse(const PHIDP_PREPARSED_DATA descriptorDa
|
||||
USHORT length = caps.NumberInputButtonCaps;
|
||||
std::vector<HIDP_BUTTON_CAPS> bCaps(caps.NumberInputButtonCaps, HIDP_BUTTON_CAPS());
|
||||
HidP_GetButtonCaps(HidP_Input, bCaps.data(), &length, descriptorData);
|
||||
for (const HIDP_BUTTON_CAPS& caps : bCaps) {
|
||||
if (caps.IsRange) {
|
||||
int usage = caps.Range.UsageMin;
|
||||
for (int i = caps.Range.DataIndexMin; i <= caps.Range.DataIndexMax; ++i, ++usage) {
|
||||
inputItems.insert(std::make_pair(
|
||||
i, HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage), HIDUsage(usage), std::make_pair(0, 1), 1)));
|
||||
for (const HIDP_BUTTON_CAPS& buttonCaps : bCaps) {
|
||||
if (buttonCaps.IsRange) {
|
||||
int usage = buttonCaps.Range.UsageMin;
|
||||
for (int i = buttonCaps.Range.DataIndexMin; i <= buttonCaps.Range.DataIndexMax; ++i, ++usage) {
|
||||
inputItems.emplace(i, HIDMainItem(buttonCaps.BitField, HIDUsagePage(buttonCaps.UsagePage), HIDUsage(usage),
|
||||
std::make_pair(0, 1), 1));
|
||||
}
|
||||
} else {
|
||||
inputItems.insert(std::make_pair(caps.NotRange.DataIndex,
|
||||
HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage),
|
||||
HIDUsage(caps.NotRange.Usage), std::make_pair(0, 1), 1)));
|
||||
inputItems.emplace(buttonCaps.NotRange.DataIndex,
|
||||
HIDMainItem(buttonCaps.BitField, HIDUsagePage(buttonCaps.UsagePage),
|
||||
HIDUsage(buttonCaps.NotRange.Usage), std::make_pair(0, 1), 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -463,19 +481,19 @@ HIDParser::ParserStatus HIDParser::Parse(const PHIDP_PREPARSED_DATA descriptorDa
|
||||
USHORT length = caps.NumberInputValueCaps;
|
||||
std::vector<HIDP_VALUE_CAPS> vCaps(caps.NumberInputValueCaps, HIDP_VALUE_CAPS());
|
||||
HidP_GetValueCaps(HidP_Input, vCaps.data(), &length, descriptorData);
|
||||
for (const HIDP_VALUE_CAPS& caps : vCaps) {
|
||||
if (caps.IsRange) {
|
||||
int usage = caps.Range.UsageMin;
|
||||
for (int i = caps.Range.DataIndexMin; i <= caps.Range.DataIndexMax; ++i, ++usage) {
|
||||
inputItems.insert(
|
||||
std::make_pair(i, HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage), HIDUsage(usage),
|
||||
std::make_pair(caps.LogicalMin, caps.LogicalMax), caps.BitSize)));
|
||||
for (const HIDP_VALUE_CAPS& valueCaps : vCaps) {
|
||||
if (valueCaps.IsRange) {
|
||||
int usage = valueCaps.Range.UsageMin;
|
||||
for (int i = valueCaps.Range.DataIndexMin; i <= valueCaps.Range.DataIndexMax; ++i, ++usage) {
|
||||
inputItems.emplace(i, HIDMainItem(valueCaps.BitField, HIDUsagePage(valueCaps.UsagePage), HIDUsage(usage),
|
||||
std::make_pair(valueCaps.LogicalMin, valueCaps.LogicalMax),
|
||||
valueCaps.BitSize));
|
||||
}
|
||||
} else {
|
||||
inputItems.insert(
|
||||
std::make_pair(caps.NotRange.DataIndex,
|
||||
HIDMainItem(caps.BitField, HIDUsagePage(caps.UsagePage), HIDUsage(caps.NotRange.Usage),
|
||||
HIDRange(caps.LogicalMin, caps.LogicalMax), caps.BitSize)));
|
||||
inputItems.emplace(valueCaps.NotRange.DataIndex,
|
||||
HIDMainItem(valueCaps.BitField, HIDUsagePage(valueCaps.UsagePage),
|
||||
HIDUsage(valueCaps.NotRange.Usage),
|
||||
HIDRange(valueCaps.LogicalMin, valueCaps.LogicalMax), valueCaps.BitSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -804,9 +822,9 @@ void HIDParser::ScanValues(const std::function<bool(const HIDMainItem& item, int
|
||||
continue;
|
||||
int32_t value = 0;
|
||||
if (it != end) {
|
||||
const HIDP_DATA& data = *it;
|
||||
if (data.DataIndex == idx) {
|
||||
value = data.RawValue;
|
||||
const HIDP_DATA& hidData = *it;
|
||||
if (hidData.DataIndex == idx) {
|
||||
value = hidData.RawValue;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "boo/inputdev/DeviceToken.hpp"
|
||||
#include "boo/inputdev/DeviceBase.hpp"
|
||||
#include <memory>
|
||||
|
||||
#include "boo/inputdev/DeviceBase.hpp"
|
||||
#include "boo/inputdev/DeviceToken.hpp"
|
||||
|
||||
#if _WIN32
|
||||
#include <hidsdi.h>
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../CFPointer.hpp"
|
||||
#include "lib/CFPointer.hpp"
|
||||
#include <IOKit/IOTypes.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/IOCFPlugIn.h>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#include "boo/inputdev/NintendoPowerA.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "boo/inputdev/DeviceSignature.hpp"
|
||||
#include <memory.h>
|
||||
|
||||
namespace boo {
|
||||
NintendoPowerA::NintendoPowerA(DeviceToken* token)
|
||||
: TDeviceBase<INintendoPowerACallback>(dev_typeid(NintendoPowerA), token) {}
|
||||
@@ -33,12 +36,10 @@ void NintendoPowerA::finalCycle() {}
|
||||
|
||||
void NintendoPowerA::receivedHIDReport(const uint8_t* data, size_t length, HIDReportType tp, uint32_t message) {}
|
||||
|
||||
bool NintendoPowerAState::operator==(const NintendoPowerAState& other) {
|
||||
return !memcmp(this, &other, sizeof(NintendoPowerAState));
|
||||
bool NintendoPowerAState::operator==(const NintendoPowerAState& other) const {
|
||||
return memcmp(this, &other, sizeof(NintendoPowerAState)) == 0;
|
||||
}
|
||||
|
||||
bool NintendoPowerAState::operator!=(const NintendoPowerAState& other) {
|
||||
return memcmp(this, &other, sizeof(NintendoPowerAState));
|
||||
}
|
||||
bool NintendoPowerAState::operator!=(const NintendoPowerAState& other) const { return !operator==(other); }
|
||||
|
||||
} // namespace boo
|
||||
|
||||
Reference in New Issue
Block a user