lots of HID implementation (OS X only for now)

This commit is contained in:
Jack Andersen
2015-04-20 18:02:43 -10:00
parent 03a325b8ac
commit edaebc5e50
17 changed files with 443 additions and 18 deletions

View File

@@ -1,13 +1,18 @@
#ifndef CDEVICEBASE
#define CDEVICEBASE
#include "CDeviceToken.hpp"
class CDeviceToken;
class IHIDDevice;
class CDeviceBase
{
CDeviceToken* m_token;
IHIDDevice* m_hidDev;
public:
inline CDeviceBase(CDeviceToken* token, IHIDDevice* hidDev)
: m_token(token), m_hidDev(hidDev) {}
void _deviceDisconnected();
virtual void deviceDisconnected()=0;
};
#endif // CDEVICEBASE

View File

@@ -1,5 +1,131 @@
#ifndef CDEVICEFINDER_HPP
#define CDEVICEFINDER_HPP
#include <set>
#include <mutex>
#include <stdexcept>
#include "CDeviceToken.hpp"
#include "IHIDListener.hpp"
#include "DeviceClasses.hpp"
static class CDeviceFinder* skDevFinder = NULL;
class CDeviceFinder
{
public:
friend class CHIDListenerIOKit;
friend class CHIDListenerUdev;
friend class CHIDListenerWin32;
static inline CDeviceFinder* instance() {return skDevFinder;}
private:
/* Types this finder is interested in (immutable) */
EDeviceMask m_types;
/* Platform-specific USB event registration
* (for auto-scanning, NULL if not registered) */
IHIDListener* m_listener;
/* Set of presently-connected device tokens */
TDeviceTokens m_tokens;
std::mutex m_tokensLock;
/* Friend methods for platform-listener to find/insert/remove
* tokens with type-filtering */
inline bool _hasToken(TDeviceHandle handle)
{
auto preCheck = m_tokens.find(handle);
if (preCheck != m_tokens.end())
return true;
return false;
}
inline void _insertToken(CDeviceToken&& token)
{
if (BooDeviceMatchToken(token, m_types)) {
m_tokensLock.lock();
m_tokens.insert(std::make_pair(token.getDeviceHandle(), token));
m_tokensLock.unlock();
}
}
inline void _removeToken(TDeviceHandle handle)
{
auto preCheck = m_tokens.find(handle);
if (preCheck != m_tokens.end())
{
CDeviceToken& tok = preCheck->second;
tok._deviceClose();
m_tokensLock.lock();
m_tokens.erase(preCheck);
m_tokensLock.unlock();
}
}
public:
class CDeviceTokensHandle
{
CDeviceFinder& m_finder;
public:
inline CDeviceTokensHandle(CDeviceFinder& finder) : m_finder(finder)
{m_finder.m_tokensLock.lock();}
inline ~CDeviceTokensHandle() {m_finder.m_tokensLock.unlock();}
inline TDeviceTokens::iterator begin() {return m_finder.m_tokens.begin();}
inline TDeviceTokens::iterator end() {return m_finder.m_tokens.end();}
};
/* Application must specify its interested device-types */
CDeviceFinder(EDeviceMask types, bool autoScan=true)
: m_types(types), m_listener(NULL)
{
if (skDevFinder)
throw std::runtime_error("only one instance of CDeviceFinder may be constructed");
skDevFinder = this;
if (autoScan)
startScanning();
}
~CDeviceFinder()
{
if (m_listener)
m_listener->stopScanning();
delete m_listener;
skDevFinder = NULL;
}
/* Get interested device-type mask */
inline EDeviceMask getTypes() const {return m_types;}
/* Iterable set of tokens */
inline CDeviceTokensHandle getTokens() {return CDeviceTokensHandle(*this);}
/* Automatic device scanning */
inline bool startScanning()
{
if (!m_listener)
m_listener = IHIDListenerNew(*this);
if (m_listener)
return m_listener->startScanning();
return false;
}
inline bool stopScanning()
{
if (!m_listener)
m_listener = IHIDListenerNew(*this);
if (m_listener)
return m_listener->stopScanning();
return false;
}
/* Manual device scanning */
inline bool scanNow()
{
if (!m_listener)
m_listener = IHIDListenerNew(*this);
if (m_listener)
return m_listener->scanNow();
return false;
}
};
#endif // CDEVICEFINDER_HPP

View File

@@ -2,21 +2,65 @@
#define CDEVICETOKEN
#include <string>
#include <IOKit/hid/IOHIDDevice.h>
#include "CDeviceBase.hpp"
#include "DeviceClasses.hpp"
#if __APPLE__
#include <IOKit/hid/IOHIDLib.h>
typedef IOHIDDeviceRef TDeviceHandle;
#elif _WIN32
#elif __linux__
#endif
class CDeviceBase;
class CDeviceToken
{
std::string m_name;
#if __APPLE__
unsigned m_vendorId;
unsigned m_productId;
std::string m_vendorName;
std::string m_productName;
TDeviceHandle m_devHandle;
#elif _WIN32
#elif __linux__
#endif
friend CDeviceBase;
CDeviceBase* m_connectedDev;
public:
const std::string& getName() const;
CDeviceBase* getDevice() const;
inline CDeviceToken(unsigned vid, unsigned pid, const char* vname, const char* pname, TDeviceHandle handle)
: m_vendorId(vid), m_productId(pid), m_devHandle(handle), m_connectedDev(NULL)
{
if (vname)
m_vendorName = vname;
if (pname)
m_productName = pname;
}
inline unsigned getVendorId() const {return m_vendorId;}
inline unsigned getProductId() const {return m_productId;}
inline const std::string& getVendorName() const {return m_vendorName;}
inline const std::string& getProductName() const {return m_productName;}
inline TDeviceHandle getDeviceHandle() const {return m_devHandle;}
inline bool isDeviceOpen() const {return m_connectedDev;}
inline CDeviceBase* openAndGetDevice()
{
if (!m_connectedDev)
m_connectedDev = BooDeviceNew(this);
return m_connectedDev;
}
inline void _deviceClose()
{
if (m_connectedDev)
m_connectedDev->deviceDisconnected();
m_connectedDev = NULL;
}
inline CDeviceToken operator =(const CDeviceToken& other)
{return CDeviceToken(other);}
inline bool operator ==(const CDeviceToken& rhs) const
{return m_devHandle == rhs.m_devHandle;}
inline bool operator <(const CDeviceToken& rhs) const
{return m_devHandle < rhs.m_devHandle;}
};
#endif // CDEVICETOKEN

View File

@@ -1,5 +1,17 @@
#ifndef CDOLPHINSMASHADAPTER_HPP
#define CDOLPHINSMASHADAPTER_HPP
#include "CDeviceBase.hpp"
class CDolphinSmashAdapter final : public CDeviceBase
{
void deviceDisconnected();
public:
CDolphinSmashAdapter(CDeviceToken* token, IHIDDevice* hidDev)
: CDeviceBase(token, hidDev)
{
}
};
#endif // CDOLPHINSMASHADAPTER_HPP

View File

@@ -0,0 +1,24 @@
#ifndef CDEVICECLASSES_HPP
#define CDEVICECLASSES_HPP
#include "CDolphinSmashAdapter.hpp"
#include "CRevolutionPad.hpp"
#include "CCafeProPad.hpp"
#include "CDualshockPad.hpp"
#include "CGenericPad.hpp"
enum EDeviceMask
{
DEV_NONE = 0,
DEV_DOL_SMASH_ADAPTER = 1<<0,
DEV_RVL_PAD = 1<<1,
DEV_CAFE_PRO_PAD = 1<<2,
DEV_DUALSHOCK_PAD = 1<<3,
DEV_GENERIC_PAD = 1<<4,
DEV_ALL = 0xff
};
bool BooDeviceMatchToken(const CDeviceToken& token, EDeviceMask mask);
CDeviceBase* BooDeviceNew(CDeviceToken* token);
#endif // CDEVICECLASSES_HPP