diff --git a/libBoo.pri b/libBoo.pri index acbd12b..752282a 100644 --- a/libBoo.pri +++ b/libBoo.pri @@ -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 diff --git a/src/inputdev/CHIDDeviceIOKit.cpp b/src/inputdev/CHIDDeviceIOKit.cpp index c4ee698..7e84f8c 100644 --- a/src/inputdev/CHIDDeviceIOKit.cpp +++ b/src/inputdev/CHIDDeviceIOKit.cpp @@ -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 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 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 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 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; } diff --git a/src/inputdev/CHIDListenerIOKit.cpp b/src/inputdev/CHIDListenerIOKit.cpp index ee7604c..7be2019 100644 --- a/src/inputdev/CHIDListenerIOKit.cpp +++ b/src/inputdev/CHIDListenerIOKit.cpp @@ -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; } diff --git a/src/mac/CCGLContext.cpp b/src/mac/CCGLContext.cpp index a7eeaf6..7e3217c 100644 --- a/src/mac/CCGLContext.cpp +++ b/src/mac/CCGLContext.cpp @@ -2,6 +2,9 @@ #include "CCGLContext.hpp" #include +namespace boo +{ + CCGLContext::CCGLContext() : m_minVersion(3), m_majVersion(3) @@ -58,4 +61,7 @@ int CCGLContext::blueDepth() const { return -1; } + +} + #endif \ No newline at end of file