aboutsummaryrefslogtreecommitdiffstats
path: root/LibOVR/Src/OVR_OSX_HIDDevice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'LibOVR/Src/OVR_OSX_HIDDevice.cpp')
-rw-r--r--LibOVR/Src/OVR_OSX_HIDDevice.cpp280
1 files changed, 140 insertions, 140 deletions
diff --git a/LibOVR/Src/OVR_OSX_HIDDevice.cpp b/LibOVR/Src/OVR_OSX_HIDDevice.cpp
index e93cf67..69c9cef 100644
--- a/LibOVR/Src/OVR_OSX_HIDDevice.cpp
+++ b/LibOVR/Src/OVR_OSX_HIDDevice.cpp
@@ -3,9 +3,9 @@ Filename : OVR_OSX_HIDDevice.cpp
Content : OSX HID device implementation.
Created : February 26, 2013
Authors : Lee Cooper
-
+
Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
-
+
Use of this software is subject to the terms of the Oculus license
agreement provided at the time of installation or download, or which
otherwise accompanies this software in either electronic or hard copy form.
@@ -19,7 +19,7 @@ otherwise accompanies this software in either electronic or hard copy form.
namespace OVR { namespace OSX {
static const UInt32 MAX_QUEUED_INPUT_REPORTS = 5;
-
+
//-------------------------------------------------------------------------------------
// **** OSX::DeviceManager
@@ -49,21 +49,21 @@ bool HIDDeviceManager::initializeManager()
{
return true;
}
-
+
HIDManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
-
+
if (!HIDManager)
{
return false;
}
-
+
// Create a Matching Dictionary
CFMutableDictionaryRef matchDict =
CFDictionaryCreateMutable(kCFAllocatorDefault,
2,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
-
+
// Specify a device manufacturer in the Matching Dictionary
UInt32 vendorId = Oculus_VendorId;
CFNumberRef vendorIdRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vendorId);
@@ -74,15 +74,15 @@ bool HIDDeviceManager::initializeManager()
IOHIDManagerSetDeviceMatching(HIDManager, matchDict);
CFRelease(vendorIdRef);
CFRelease(matchDict);
-
+
// Register a callback for USB device detection with the HID Manager
IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, &staticDeviceMatchingCallback, this);
-
+
IOHIDManagerScheduleWithRunLoop(HIDManager, getRunLoop(), kCFRunLoopDefaultMode);
return true;
}
-
+
bool HIDDeviceManager::Initialize()
{
return initializeManager();
@@ -92,38 +92,38 @@ void HIDDeviceManager::Shutdown()
{
OVR_ASSERT_LOG(HIDManager, ("Should have called 'Initialize' before 'Shutdown'."));
CFRelease(HIDManager);
-
+
LogText("OVR::OSX::HIDDeviceManager - shutting down.\n");
}
-
+
bool HIDDeviceManager::getIntProperty(IOHIDDeviceRef device, CFStringRef propertyName, SInt32* pResult)
{
-
+
CFTypeRef ref = IOHIDDeviceGetProperty(device, propertyName);
if (!ref)
{
return false;
}
-
+
if (CFGetTypeID(ref) != CFNumberGetTypeID())
{
return false;
}
-
+
CFNumberGetValue((CFNumberRef) ref, kCFNumberSInt32Type, pResult);
return true;
}
-
+
bool HIDDeviceManager::initVendorProductVersion(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc)
{
-
+
if (!getVendorId(device, &(pDevDesc->VendorId)))
{
return false;
}
-
+
if (!getProductId(device, &(pDevDesc->ProductId)))
{
return false;
@@ -135,30 +135,30 @@ bool HIDDeviceManager::initVendorProductVersion(IOHIDDeviceRef device, HIDDevice
return false;
}
pDevDesc->VersionNumber = result;
-
+
return true;
}
bool HIDDeviceManager::initUsage(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc)
{
-
+
SInt32 result;
-
+
if (!getIntProperty(device, CFSTR(kIOHIDPrimaryUsagePageKey), &result))
{
return false;
}
-
+
pDevDesc->UsagePage = result;
-
+
if (!getIntProperty(device, CFSTR(kIOHIDPrimaryUsageKey), &result))
{
return false;
}
-
+
pDevDesc->Usage = result;
-
+
return true;
}
@@ -166,14 +166,14 @@ bool HIDDeviceManager::initSerialNumber(IOHIDDeviceRef device, HIDDeviceDesc* pD
{
return getSerialNumberString(device, &(pDevDesc->SerialNumber));
}
-
+
bool HIDDeviceManager::initStrings(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc)
{
// Regardless of whether they fail we'll try and get the remaining.
getStringProperty(device, CFSTR(kIOHIDManufacturerKey), &(pDevDesc->Manufacturer));
getStringProperty(device, CFSTR(kIOHIDProductKey), &(pDevDesc->Product));
-
+
return true;
}
@@ -181,9 +181,9 @@ bool HIDDeviceManager::getStringProperty(IOHIDDeviceRef device,
CFStringRef propertyName,
String* pResult)
{
-
+
CFStringRef str = (CFStringRef) IOHIDDeviceGetProperty(device, propertyName);
-
+
if (!str)
{
return false;
@@ -191,7 +191,7 @@ bool HIDDeviceManager::getStringProperty(IOHIDDeviceRef device,
CFIndex length = CFStringGetLength(str);
CFRange range = CFRangeMake(0, length);
-
+
// Test the conversion first to get required buffer size.
CFIndex bufferLength;
CFIndex numberOfChars = CFStringGetBytes(str,
@@ -202,15 +202,15 @@ bool HIDDeviceManager::getStringProperty(IOHIDDeviceRef device,
NULL,
0,
&bufferLength);
-
+
if (numberOfChars == 0)
{
return false;
}
-
+
// Now allocate buffer.
char* buffer = new char[bufferLength+1];
-
+
numberOfChars = CFStringGetBytes(str,
range,
kCFStringEncodingUTF8,
@@ -223,55 +223,55 @@ bool HIDDeviceManager::getStringProperty(IOHIDDeviceRef device,
buffer[bufferLength] = '\0';
*pResult = String(buffer);
-
+
return true;
}
-
+
bool HIDDeviceManager::getVendorId(IOHIDDeviceRef device, UInt16* pResult)
{
SInt32 result;
-
+
if (!getIntProperty(device, CFSTR(kIOHIDVendorIDKey), &result))
{
return false;
}
-
+
*pResult = result;
return true;
}
-
+
bool HIDDeviceManager::getProductId(IOHIDDeviceRef device, UInt16* pResult)
{
SInt32 result;
-
+
if (!getIntProperty(device, CFSTR(kIOHIDProductIDKey), &result))
{
return false;
}
-
+
*pResult = result;
-
+
return true;
}
-
+
bool HIDDeviceManager::getLocationId(IOHIDDeviceRef device, SInt32* pResult)
{
SInt32 result;
-
+
if (!getIntProperty(device, CFSTR(kIOHIDLocationIDKey), &result))
{
return false;
}
-
+
*pResult = result;
-
+
return true;
}
-
+
bool HIDDeviceManager::getSerialNumberString(IOHIDDeviceRef device, String* pResult)
{
-
+
if (!getStringProperty(device, CFSTR(kIOHIDSerialNumberKey), pResult))
{
return false;
@@ -279,7 +279,7 @@ bool HIDDeviceManager::getSerialNumberString(IOHIDDeviceRef device, String* pRes
return true;
}
-
+
bool HIDDeviceManager::getPath(IOHIDDeviceRef device, String* pPath)
{
@@ -288,7 +288,7 @@ bool HIDDeviceManager::getPath(IOHIDDeviceRef device, String* pPath)
{
return false;
}
-
+
UInt16 vendorId;
if (!getVendorId(device, &vendorId))
{
@@ -300,13 +300,13 @@ bool HIDDeviceManager::getPath(IOHIDDeviceRef device, String* pPath)
{
return false;
}
-
+
String serialNumber;
if (!getSerialNumberString(device, &serialNumber))
{
return false;
}
-
+
StringBuffer buffer;
buffer.AppendFormat("%s:vid=%04hx:pid=%04hx:ser=%s",
@@ -314,9 +314,9 @@ bool HIDDeviceManager::getPath(IOHIDDeviceRef device, String* pPath)
vendorId,
productId,
serialNumber.ToCStr());
-
+
*pPath = String(buffer);
-
+
return true;
}
@@ -326,31 +326,31 @@ bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor)
{
return false;
}
-
+
CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager);
if (!deviceSet)
return false;
-
+
CFIndex deviceCount = CFSetGetCount(deviceSet);
-
+
// Allocate a block of memory and read the set into it.
IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount);
CFSetGetValues(deviceSet, (const void **) devices);
-
+
// Iterate over devices.
for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
{
IOHIDDeviceRef hidDev = devices[deviceIndex];
-
+
if (!hidDev)
{
continue;
}
-
+
HIDDeviceDesc devDesc;
-
+
if (getPath(hidDev, &(devDesc.Path)) &&
initVendorProductVersion(hidDev, &devDesc) &&
enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId) &&
@@ -368,17 +368,17 @@ bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor)
existingDevice->Enumerated = true;
continue;
}
-
+
// Construct minimal device that the visitor callback can get feature reports from.
OSX::HIDDevice device(this, hidDev);
-
+
enumVisitor->Visit(device, devDesc);
}
}
-
+
OVR_FREE(devices);
CFRelease(deviceSet);
-
+
return true;
}
@@ -393,30 +393,30 @@ OVR::HIDDevice* HIDDeviceManager::Open(const String& path)
}
device->AddRef();
-
+
return device;
}
-
+
bool HIDDeviceManager::getFullDesc(IOHIDDeviceRef device, HIDDeviceDesc* desc)
{
-
+
if (!initVendorProductVersion(device, desc))
{
return false;
}
-
+
if (!initUsage(device, desc))
{
return false;
}
-
+
if (!initSerialNumber(device, desc))
{
return false;
}
-
+
initStrings(device, desc);
-
+
return true;
}
@@ -430,7 +430,7 @@ void HIDDeviceManager::staticDeviceMatchingCallback(void *inContext,
HIDDeviceDesc hidDevDesc;
hidMgr->getPath(inIOHIDDeviceRef, &hidDevDesc.Path);
hidMgr->getFullDesc(inIOHIDDeviceRef, &hidDevDesc);
-
+
hidMgr->DevManager->DetectHIDDevice(hidDevDesc);
}
@@ -443,7 +443,7 @@ HIDDevice::HIDDevice(HIDDeviceManager* manager)
Device = NULL;
RepluggedNotificationPort = 0;
}
-
+
// This is a minimal constructor used during enumeration for us to pass
// a HIDDevice to the visit function (so that it can query feature reports).
HIDDevice::HIDDevice(HIDDeviceManager* manager, IOHIDDeviceRef device)
@@ -478,16 +478,16 @@ bool HIDDevice::HIDInitialize(const String& path)
closeDevice(false);
return false;
}
-
+
HIDManager->DevManager->pThread->AddTicksNotifier(this);
-
+
LogText("OVR::OSX::HIDDevice - Opened '%s'\n"
" Manufacturer:'%s' Product:'%s' Serial#:'%s'\n",
DevDesc.Path.ToCStr(),
DevDesc.Manufacturer.ToCStr(), DevDesc.Product.ToCStr(),
DevDesc.SerialNumber.ToCStr());
-
+
return true;
}
@@ -495,8 +495,8 @@ bool HIDDevice::initInfo()
{
// Device must have been successfully opened.
OVR_ASSERT(Device);
-
-
+
+
// Get report lengths.
SInt32 bufferLength;
bool getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxInputReportSizeKey), &bufferLength);
@@ -510,21 +510,21 @@ bool HIDDevice::initInfo()
getResult = HIDManager->getIntProperty(Device, CFSTR(kIOHIDMaxFeatureReportSizeKey), &bufferLength);
OVR_ASSERT(getResult);
FeatureReportBufferLength = (UInt16) bufferLength;
-
-
+
+
if (ReadBufferSize < InputReportBufferLength)
{
OVR_ASSERT_LOG(false, ("Input report buffer length is bigger than read buffer."));
return false;
}
-
+
// Get device desc.
if (!HIDManager->getFullDesc(Device, &DevDesc))
{
OVR_ASSERT_LOG(false, ("Failed to get device desc while initializing device."));
return false;
}
-
+
return true;
}
@@ -555,53 +555,53 @@ void HIDDevice::deviceAddedCallback(io_iterator_t iterator)
while (IOIteratorNext(iterator))
;
}
-
+
bool HIDDevice::openDevice()
{
-
+
// Have to iterate through devices again to generate paths.
CFSetRef deviceSet = IOHIDManagerCopyDevices(HIDManager->HIDManager);
CFIndex deviceCount = CFSetGetCount(deviceSet);
-
+
// Allocate a block of memory and read the set into it.
IOHIDDeviceRef* devices = (IOHIDDeviceRef*) OVR_ALLOC(sizeof(IOHIDDeviceRef) * deviceCount);
CFSetGetValues(deviceSet, (const void **) devices);
-
-
+
+
// Iterate over devices.
IOHIDDeviceRef device = NULL;
for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
{
IOHIDDeviceRef tmpDevice = devices[deviceIndex];
-
+
if (!tmpDevice)
{
continue;
}
-
+
String path;
if (!HIDManager->getPath(tmpDevice, &path))
{
continue;
}
-
+
if (path == DevDesc.Path)
{
device = tmpDevice;
break;
}
}
-
-
+
+
OVR_FREE(devices);
-
+
if (!device)
{
CFRelease(deviceSet);
return false;
}
-
+
// Attempt to open device.
if (IOHIDDeviceOpen(device, kIOHIDOptionsTypeSeizeDevice)
!= kIOReturnSuccess)
@@ -613,11 +613,11 @@ bool HIDDevice::openDevice()
// Retain the device before we release the set.
CFRetain(device);
CFRelease(deviceSet);
-
-
+
+
Device = device;
-
+
if (!initInfo())
{
IOHIDDeviceClose(Device, kIOHIDOptionsTypeSeizeDevice);
@@ -625,13 +625,13 @@ bool HIDDevice::openDevice()
Device = NULL;
return false;
}
-
-
+
+
// Setup the Run Loop and callbacks.
IOHIDDeviceScheduleWithRunLoop(Device,
HIDManager->getRunLoop(),
kCFRunLoopDefaultMode);
-
+
IOHIDDeviceRegisterInputReportCallback(Device,
ReadBuffer,
ReadBufferSize,
@@ -641,15 +641,15 @@ bool HIDDevice::openDevice()
IOHIDDeviceRegisterRemovalCallback(Device,
staticDeviceRemovedCallback,
this);
-
+
return true;
}
-
+
void HIDDevice::HIDShutdown()
{
HIDManager->DevManager->pThread->RemoveTicksNotifier(this);
-
+
if (Device != NULL) // Device may already have been closed if unplugged.
{
closeDevice(false);
@@ -658,25 +658,25 @@ void HIDDevice::HIDShutdown()
IOObjectRelease(RepluggedNotification);
if (RepluggedNotificationPort)
IONotificationPortDestroy(RepluggedNotificationPort);
-
+
LogText("OVR::OSX::HIDDevice - HIDShutdown '%s'\n", DevDesc.Path.ToCStr());
}
bool HIDDevice::setupDevicePluggedInNotification()
{
-
+
// Setup notification when devices are plugged in.
RepluggedNotificationPort = IONotificationPortCreate(kIOMasterPortDefault);
-
+
CFRunLoopSourceRef notificationRunLoopSource =
IONotificationPortGetRunLoopSource(RepluggedNotificationPort);
-
+
CFRunLoopAddSource(HIDManager->getRunLoop(),
notificationRunLoopSource,
kCFRunLoopDefaultMode);
-
+
CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
-
+
// Have to specify vendorId and productId. Doesn't seem to accept additional
// things like serial number.
SInt32 vendorId = DevDesc.VendorId;
@@ -685,14 +685,14 @@ bool HIDDevice::setupDevicePluggedInNotification()
&vendorId);
CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef);
CFRelease(numberRef);
-
+
SInt32 deviceProductId = DevDesc.ProductId;
numberRef = CFNumberCreate(kCFAllocatorDefault,
kCFNumberSInt32Type,
&deviceProductId);
CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef);
CFRelease(numberRef);
-
+
kern_return_t result =
IOServiceAddMatchingNotification(RepluggedNotificationPort,
kIOMatchedNotification,
@@ -700,26 +700,26 @@ bool HIDDevice::setupDevicePluggedInNotification()
staticDeviceAddedCallback,
this,
&RepluggedNotification);
-
+
if (result != KERN_SUCCESS)
{
CFRelease(RepluggedNotificationPort);
RepluggedNotificationPort = 0;
return false;
}
-
+
// Iterate through to arm.
while (IOIteratorNext(RepluggedNotification))
{
}
-
+
return true;
}
void HIDDevice::closeDevice(bool wasUnplugged)
{
OVR_ASSERT(Device != NULL);
-
+
if (!wasUnplugged)
{
// Clear the registered callbacks.
@@ -728,18 +728,18 @@ void HIDDevice::closeDevice(bool wasUnplugged)
InputReportBufferLength,
NULL,
this);
-
+
IOHIDDeviceRegisterRemovalCallback(Device, NULL, this);
-
+
IOHIDDeviceUnscheduleFromRunLoop(Device,
HIDManager->getRunLoop(),
kCFRunLoopDefaultMode);
IOHIDDeviceClose(Device, kIOHIDOptionsTypeNone);
}
-
+
CFRelease(Device);
Device = NULL;
-
+
LogText("OVR::OSX::HIDDevice - HID Device Closed '%s'\n", DevDesc.Path.ToCStr());
}
@@ -755,26 +755,26 @@ void HIDDevice::staticHIDReportCallback(void* pContext,
return pDevice->hidReportCallback(pReport, (UInt32)reportLength);
}
-void HIDDevice::hidReportCallback(UByte* pData, UInt32 length)
+void HIDDevice::hidReportCallback(const UByte* pData, UInt32 length)
{
-
+
// We got data.
if (Handler)
{
Handler->OnInputReport(pData, length);
}
}
-
+
void HIDDevice::staticDeviceRemovedCallback(void* pContext, IOReturn result, void* pSender)
{
HIDDevice* pDevice = (HIDDevice*) pContext;
pDevice->deviceRemovedCallback();
}
-
+
void HIDDevice::deviceRemovedCallback()
{
Ptr<HIDDevice> _this(this); // prevent from release
-
+
Ptr<DeviceCreateDesc> existingHIDDev = HIDManager->DevManager->FindHIDDevice(DevDesc);
if (existingHIDDev && existingHIDDev->pDevice)
{
@@ -788,16 +788,16 @@ CFStringRef HIDDevice::generateRunLoopModeString(IOHIDDeviceRef device)
const UInt32 safeBuffSize = 256;
char nameBuff[safeBuffSize];
OVR_sprintf(nameBuff, safeBuffSize, "%016lX", device);
-
+
return CFStringCreateWithCString(NULL, nameBuff, kCFStringEncodingASCII);
}
-
+
bool HIDDevice::SetFeatureReport(UByte* data, UInt32 length)
{
-
+
if (!Device)
return false;
-
+
UByte reportID = data[0];
if (reportID == 0)
@@ -806,13 +806,13 @@ bool HIDDevice::SetFeatureReport(UByte* data, UInt32 length)
data++;
length--;
}
-
+
IOReturn result = IOHIDDeviceSetReport( Device,
kIOHIDReportTypeFeature,
reportID,
data,
length);
-
+
return (result == kIOReturnSuccess);
}
@@ -820,29 +820,29 @@ bool HIDDevice::GetFeatureReport(UByte* data, UInt32 length)
{
if (!Device)
return false;
-
+
CFIndex bufferLength = length;
-
+
// Report id is in first byte of the buffer.
IOReturn result = IOHIDDeviceGetReport(Device, kIOHIDReportTypeFeature, data[0], data, &bufferLength);
-
+
return (result == kIOReturnSuccess);
}
-
+
UInt64 HIDDevice::OnTicks(UInt64 ticksMks)
{
-
+
if (Handler)
{
return Handler->OnTicks(ticksMks);
}
-
+
return DeviceManagerThread::Notifier::OnTicks(ticksMks);
}
HIDDeviceManager* HIDDeviceManager::CreateInternal(OSX::DeviceManager* devManager)
{
-
+
if (!System::IsInitialized())
{
// Use custom message, since Log is not yet installed.
@@ -867,7 +867,7 @@ HIDDeviceManager* HIDDeviceManager::CreateInternal(OSX::DeviceManager* devManage
return manager.GetPtr();
}
-
+
} // namespace OSX
//-------------------------------------------------------------------------------------
@@ -877,7 +877,7 @@ HIDDeviceManager* HIDDeviceManager::CreateInternal(OSX::DeviceManager* devManage
HIDDeviceManager* HIDDeviceManager::Create()
{
OVR_ASSERT_LOG(false, ("Standalone mode not implemented yet."));
-
+
if (!System::IsInitialized())
{
// Use custom message, since Log is not yet installed.
@@ -887,7 +887,7 @@ HIDDeviceManager* HIDDeviceManager::Create()
}
Ptr<OSX::HIDDeviceManager> manager = *new OSX::HIDDeviceManager(NULL);
-
+
if (manager)
{
if (manager->Initialize())