brought mac in sync from udev edits

This commit is contained in:
Jack Andersen 2015-04-30 15:11:25 -10:00
parent 1125e20b6e
commit d32dbbd694
4 changed files with 110 additions and 170 deletions

View File

@ -19,15 +19,6 @@ HEADERS += \
$$PWD/src/inputdev/IHIDDevice.hpp \
$$PWD/include/inputdev/SDeviceSignature.hpp
unix:!macx:HEADERS += \
$$PWD/include/x11/CGLXContext.hpp
macx:HEADERS += \
$$PWD/include/mac/CCGLContext.hpp
win32:HEADERS += \
$$PWD/include/win/CWGLContext.hpp
SOURCES += \
$$PWD/InputDeviceClasses.cpp \
$$PWD/src/CSurface.cpp \
@ -40,27 +31,45 @@ SOURCES += \
$$PWD/src/inputdev/CDualshockPad.cpp \
$$PWD/src/inputdev/CGenericPad.cpp \
$$PWD/src/inputdev/CDeviceBase.cpp \
$$PWD/src/inputdev/CHIDListenerUdev.cpp \
$$PWD/src/inputdev/CHIDDeviceUdev.cpp \
$$PWD/src/inputdev/SDeviceSignature.cpp
unix:!macx:SOURCES += \
$$PWD/src/x11/CGLXContext.cpp
unix:!macx {
HEADERS += \
$$PWD/include/x11/CGLXContext.hpp
macx:SOURCES += \
$$PWD/src/mac/CCGLContext.cpp \
$$PWD/src/inputdev/CHIDDeviceIOKit.cpp \
$$PWD/src/inputdev/CHIDListenerIOKit.cpp
SOURCES += \
$$PWD/src/x11/CGLXContext.cpp
}
macx:OBJECTIVE_SOURCES += \
$$PWD/src/mac/CCGLCocoaView.mm \
linux {
SOURCES += \
$$PWD/src/inputdev/CHIDListenerUdev.cpp \
$$PWD/src/inputdev/CHIDDeviceUdev.cpp
LIBS += -ludev
}
win32:SOURCES += \
$$PWD/src/win/CWGLContext.cpp \
$$PWD/src/inputdev/CHIDDeviceWin32.cpp \
$$PWD/src/inputdev/CHIDListenerWin32.cpp
macx {
HEADERS += \
$$PWD/include/mac/CCGLContext.hpp
SOURCES += \
$$PWD/src/mac/CCGLContext.cpp \
$$PWD/src/inputdev/CHIDDeviceIOKit.cpp \
$$PWD/src/inputdev/CHIDListenerIOKit.cpp
OBJECTIVE_SOURCES += \
$$PWD/src/mac/CCGLCocoaView.mm
}
win32 {
HEADERS += \
$$PWD/include/win/CWGLContext.hpp
SOURCES += \
$$PWD/src/win/CWGLContext.cpp \
$$PWD/src/inputdev/CHIDDeviceWin32.cpp \
$$PWD/src/inputdev/CHIDListenerWin32.cpp
}
INCLUDEPATH += $$PWD/include
unix:!macx:LIBS += -ludev

View File

@ -25,7 +25,6 @@ class CHIDDeviceIOKit final : public IHIDDevice
std::mutex m_initMutex;
std::condition_variable m_initCond;
std::thread* m_thread;
CFRunLoopRef m_runLoop = NULL;
bool _sendUSBInterruptTransfer(uint8_t pipe, const uint8_t* data, size_t length)
{
@ -50,7 +49,7 @@ class CHIDDeviceIOKit final : public IHIDDevice
return 0;
}
static void _threadProcLL(CHIDDeviceIOKit* device)
static void _threadProcUSBLL(CHIDDeviceIOKit* device)
{
char thrName[128];
snprintf(thrName, 128, "%s Transfer Thread", device->m_token.getProductName().c_str());
@ -148,6 +147,7 @@ class CHIDDeviceIOKit final : public IHIDDevice
device->m_initCond.notify_one();
/* Start transfer loop */
device->m_devImp.initialCycle();
while (device->m_runningTransferLoop)
device->m_devImp.transferCycle();
device->m_devImp.finalCycle();
@ -160,6 +160,23 @@ class CHIDDeviceIOKit final : public IHIDDevice
}
static void _threadProcBTLL(CHIDDeviceIOKit* device)
{
std::unique_lock<std::mutex> lk(device->m_initMutex);
/* Return control to main thread */
device->m_runningTransferLoop = true;
lk.unlock();
device->m_initCond.notify_one();
/* Start transfer loop */
device->m_devImp.initialCycle();
while (device->m_runningTransferLoop)
device->m_devImp.transferCycle();
device->m_devImp.finalCycle();
}
static void _inputReport(CHIDDeviceIOKit* device,
IOReturn result,
@ -178,49 +195,29 @@ class CHIDDeviceIOKit final : public IHIDDevice
device->_deviceDisconnected();
}
static void _threadProcHL(CHIDDeviceIOKit* device)
static void _threadProcHID(CHIDDeviceIOKit* device)
{
char thrName[128];
snprintf(thrName, 128, "%s HID Thread", device->m_token.getProductName().c_str());
pthread_setname_np(thrName);
__block std::unique_lock<std::mutex> lk(device->m_initMutex);
device->m_runLoop = CFRunLoopGetCurrent();
CFRunLoopAddObserver(device->m_runLoop,
CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopEntry, false, 0,
^(CFRunLoopObserverRef, CFRunLoopActivity) {
lk.unlock();
device->m_initCond.notify_one();
}), kCFRunLoopCommonModes);
std::unique_lock<std::mutex> lk(device->m_initMutex);
uint8_t* inputBuf = new uint8_t[MAX_REPORT_SIZE];
io_registry_entry_t devServ = IORegistryEntryFromPath(kIOMasterPortDefault, device->m_devPath.c_str());
IOHIDDeviceRef dev = IOHIDDeviceCreate(kCFAllocatorDefault, devServ);
IOHIDDeviceRegisterInputReportCallback(dev, inputBuf, MAX_REPORT_SIZE,
(IOHIDReportCallback)_inputReport, device);
IOHIDDeviceRegisterRemovalCallback(dev, (IOHIDCallback)_disconnect, device);
IOHIDDeviceScheduleWithRunLoop(dev, device->m_runLoop, kCFRunLoopDefaultMode);
IOHIDDeviceOpen(dev, kIOHIDOptionsTypeNone);
CFRunLoopRun();
if (device->m_runLoop)
IOHIDDeviceClose(dev, kIOHIDOptionsTypeNone);
CFRelease(dev);
/* Return control to main thread */
device->m_runningTransferLoop = true;
lk.unlock();
device->m_initCond.notify_one();
/* Start transfer loop */
device->m_devImp.initialCycle();
while (device->m_runningTransferLoop)
device->m_devImp.transferCycle();
device->m_devImp.finalCycle();
}
void _deviceDisconnected()
{
CFRunLoopRef rl = m_runLoop;
m_runLoop = NULL;
if (rl)
CFRunLoopStop(rl);
m_runningTransferLoop = false;
}
bool _sendHIDReport(const uint8_t* data, size_t length)
{
if (m_runLoop)
{
}
return false;
}
@ -233,19 +230,22 @@ public:
{
devImp.m_hidDev = this;
std::unique_lock<std::mutex> lk(m_initMutex);
if (lowLevel)
m_thread = new std::thread(_threadProcLL, this);
CDeviceToken::TDeviceType dType = token.getDeviceType();
if (dType == CDeviceToken::DEVTYPE_USB)
m_thread = new std::thread(_threadProcUSBLL, this);
else if (dType == CDeviceToken::DEVTYPE_BLUETOOTH)
m_thread = new std::thread(_threadProcBTLL, this);
else if (dType == CDeviceToken::DEVTYPE_GENERICHID)
m_thread = new std::thread(_threadProcHID, this);
else
m_thread = new std::thread(_threadProcHL, this);
throw std::runtime_error("invalid token supplied to device constructor");
m_initCond.wait(lk);
}
~CHIDDeviceIOKit()
{
if (m_runLoop)
CFRunLoopStop(m_runLoop);
m_runningTransferLoop = false;
m_thread->detach();
m_thread->join();
delete m_thread;
}

View File

@ -57,72 +57,12 @@ class CHIDListenerIOKit final : public IHIDListener
CDeviceFinder& m_finder;
CFRunLoopRef m_listenerRunLoop;
IOHIDManagerRef m_hidManager;
IONotificationPortRef m_llPort;
io_iterator_t m_llAddNotif, m_llRemoveNotif;
bool m_scanningEnabled;
static void deviceConnected(CHIDListenerIOKit* listener,
IOReturn,
void*,
IOHIDDeviceRef device)
{
if (!listener->m_scanningEnabled)
return;
io_string_t devPath;
if (IORegistryEntryGetPath(IOHIDDeviceGetService(device), kIOServicePlane, devPath) != 0)
return;
if (listener->m_finder._hasToken(devPath))
return;
CFIndex vid, pid;
CFNumberGetValue((CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)), kCFNumberCFIndexType, &vid);
CFNumberGetValue((CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey)), kCFNumberCFIndexType, &pid);
CFStringRef manuf = (CFStringRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDManufacturerKey));
CFStringRef product = (CFStringRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
listener->m_finder._insertToken(CDeviceToken(vid, pid,
CFStringGetCStringPtr(manuf, kCFStringEncodingUTF8),
CFStringGetCStringPtr(product, kCFStringEncodingUTF8),
devPath));
}
static void deviceDisconnected(CHIDListenerIOKit* listener,
IOReturn ret,
void* sender,
IOHIDDeviceRef device)
{
if (CFRunLoopGetCurrent() != listener->m_listenerRunLoop)
{
CFRunLoopPerformBlock(listener->m_listenerRunLoop, kCFRunLoopDefaultMode, ^{
deviceDisconnected(listener, ret, sender, device);
});
CFRunLoopWakeUp(listener->m_listenerRunLoop);
return;
}
io_string_t devPath;
if (IORegistryEntryGetPath(IOHIDDeviceGetService(device), kIOServicePlane, devPath) != 0)
return;
listener->m_finder._removeToken(devPath);
}
static void applyDevice(IOHIDDeviceRef device, CHIDListenerIOKit* listener)
{
io_string_t devPath;
if (IORegistryEntryGetPath(IOHIDDeviceGetService(device), kIOServicePlane, devPath) != 0)
return;
if (listener->m_finder._hasToken(devPath))
return;
CFIndex vid, pid;
CFNumberGetValue((CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)), kCFNumberCFIndexType, &vid);
CFNumberGetValue((CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey)), kCFNumberCFIndexType, &pid);
CFStringRef manuf = (CFStringRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDManufacturerKey));
CFStringRef product = (CFStringRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
listener->m_finder._insertToken(CDeviceToken(vid, pid,
CFStringGetCStringPtr(manuf, kCFStringEncodingUTF8),
CFStringGetCStringPtr(product, kCFStringEncodingUTF8),
devPath));
}
static void devicesConnectedLL(CHIDListenerIOKit* listener,
io_iterator_t iterator)
static void devicesConnectedUSBLL(CHIDListenerIOKit* listener,
io_iterator_t iterator)
{
io_object_t obj;
while ((obj = IOIteratorNext(iterator)))
@ -165,7 +105,12 @@ class CHIDListenerIOKit final : public IHIDListener
getUSBStringDescriptor(dev, vstridx, vstr);
getUSBStringDescriptor(dev, pstridx, pstr);
listener->m_finder._insertToken(CDeviceToken(vid, pid, vstr, pstr, devPath));
if (!listener->m_finder._insertToken(CDeviceToken(CDeviceToken::DEVTYPE_USB,
vid, pid, vstr, pstr, devPath)))
{
/* Matched-insertion failed; see if generic HID interface is available */
/* TODO: Do */
}
//printf("ADDED %08X %s\n", obj, devPath);
(*dev)->Release(dev);
@ -175,13 +120,13 @@ class CHIDListenerIOKit final : public IHIDListener
}
static void devicesDisconnectedLL(CHIDListenerIOKit* listener,
io_iterator_t iterator)
static void devicesDisconnectedUSBLL(CHIDListenerIOKit* listener,
io_iterator_t iterator)
{
if (CFRunLoopGetCurrent() != listener->m_listenerRunLoop)
{
CFRunLoopPerformBlock(listener->m_listenerRunLoop, kCFRunLoopDefaultMode, ^{
devicesDisconnectedLL(listener, iterator);
devicesDisconnectedUSBLL(listener, iterator);
});
CFRunLoopWakeUp(listener->m_listenerRunLoop);
return;
@ -203,48 +148,27 @@ public:
: m_finder(finder)
{
/* Register HID Manager */
m_hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDManagerOptionNone);
IOHIDManagerSetDeviceMatching(m_hidManager, NULL);
IOHIDManagerRegisterDeviceMatchingCallback(m_hidManager, (IOHIDDeviceCallback)deviceConnected, this);
IOHIDManagerRegisterDeviceRemovalCallback(m_hidManager, (IOHIDDeviceCallback)deviceDisconnected, this);
/* Register Low-Level USB Matcher */
m_listenerRunLoop = CFRunLoopGetCurrent();
IOHIDManagerScheduleWithRunLoop(m_hidManager, m_listenerRunLoop, kCFRunLoopDefaultMode);
IOReturn ret = IOHIDManagerOpen(m_hidManager, kIOHIDManagerOptionNone);
if (ret != kIOReturnSuccess)
throw std::runtime_error("error establishing IOHIDManager");
/* Initial HID Device Add */
m_scanningEnabled = true;
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
/* Register Low-Level Matcher */
m_llPort = IONotificationPortCreate(kIOMasterPortDefault);
CFRunLoopAddSource(m_listenerRunLoop, IONotificationPortGetRunLoopSource(m_llPort), kCFRunLoopDefaultMode);
CFRunLoopSourceRef rlSrc = IONotificationPortGetRunLoopSource(m_llPort);
CFRunLoopAddSource(m_listenerRunLoop, rlSrc, kCFRunLoopDefaultMode);
CFMutableDictionaryRef matchDict = IOServiceMatching(kIOUSBDeviceClassName);
CFIndex nintendoVid = VID_NINTENDO;
CFIndex smashPid = PID_SMASH_ADAPTER;
CFNumberRef nintendoVidNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &nintendoVid);
CFNumberRef smashPidNum = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &smashPid);
CFDictionaryAddValue(matchDict, CFSTR(kUSBVendorID), nintendoVidNum);
CFDictionaryAddValue(matchDict, CFSTR(kUSBProductID), smashPidNum);
CFRelease(nintendoVidNum);
CFRelease(smashPidNum);
CFRetain(matchDict);
io_iterator_t initialIt;
m_scanningEnabled = true;
kern_return_t llRet =
IOServiceAddMatchingNotification(m_llPort, kIOMatchedNotification, matchDict,
(IOServiceMatchingCallback)devicesConnectedLL, this, &initialIt);
if (llRet == 0)
devicesConnectedLL(this, initialIt);
(IOServiceMatchingCallback)devicesConnectedUSBLL, this, &m_llAddNotif);
if (llRet == kIOReturnSuccess)
devicesConnectedUSBLL(this, m_llAddNotif);
llRet =
IOServiceAddMatchingNotification(m_llPort, kIOTerminatedNotification, matchDict,
(IOServiceMatchingCallback)devicesDisconnectedLL, this, &initialIt);
if (llRet == 0)
devicesDisconnectedLL(this, initialIt);
(IOServiceMatchingCallback)devicesDisconnectedUSBLL, this, &m_llRemoveNotif);
if (llRet == kIOReturnSuccess)
devicesDisconnectedUSBLL(this, m_llRemoveNotif);
m_scanningEnabled = false;
@ -252,10 +176,9 @@ public:
~CHIDListenerIOKit()
{
IOHIDManagerUnscheduleFromRunLoop(m_hidManager, m_listenerRunLoop, kCFRunLoopDefaultMode);
IOHIDManagerClose(m_hidManager, kIOHIDManagerOptionNone);
CFRelease(m_hidManager);
CFRunLoopRemoveSource(m_listenerRunLoop, IONotificationPortGetRunLoopSource(m_llPort), kCFRunLoopDefaultMode);
IOObjectRelease(m_llAddNotif);
IOObjectRelease(m_llRemoveNotif);
IONotificationPortDestroy(m_llPort);
}
@ -274,11 +197,13 @@ public:
/* Manual device scanning */
bool scanNow()
{
CFSetRef devs = IOHIDManagerCopyDevices(m_hidManager);
m_finder.m_tokensLock.lock();
CFSetApplyFunction(devs, (CFSetApplierFunction)applyDevice, this);
m_finder.m_tokensLock.unlock();
CFRelease(devs);
io_iterator_t iter;
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
IOServiceMatching(kIOUSBDeviceClassName), &iter) == kIOReturnSuccess)
{
devicesConnectedUSBLL(this, iter);
IOObjectRelease(iter);
}
return true;
}

View File

@ -2,6 +2,9 @@
#include "CCGLContext.hpp"
#include <iostream>
namespace boo
{
CCGLContext::CCGLContext()
: m_minVersion(3),
m_majVersion(3)
@ -58,4 +61,7 @@ int CCGLContext::blueDepth() const
{
return -1;
}
}
#endif