oculus1
diff libovr/Src/win32/OVR_Win32_HIDDevice.cpp @ 1:e2f9e4603129
added LibOVR and started a simple vr wrapper.
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 14 Sep 2013 16:14:59 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libovr/Src/win32/OVR_Win32_HIDDevice.cpp Sat Sep 14 16:14:59 2013 +0300 1.3 @@ -0,0 +1,637 @@ 1.4 +/************************************************************************************ 1.5 + 1.6 +Filename : OVR_Win32_HIDDevice.cpp 1.7 +Content : Win32 HID device implementation. 1.8 +Created : February 22, 2013 1.9 +Authors : Lee Cooper 1.10 + 1.11 +Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. 1.12 + 1.13 +Use of this software is subject to the terms of the Oculus license 1.14 +agreement provided at the time of installation or download, or which 1.15 +otherwise accompanies this software in either electronic or hard copy form. 1.16 + 1.17 +*************************************************************************************/ 1.18 + 1.19 +#include "OVR_Win32_HIDDevice.h" 1.20 +#include "OVR_Win32_DeviceManager.h" 1.21 + 1.22 +#include "Kernel/OVR_System.h" 1.23 +#include "Kernel/OVR_Log.h" 1.24 + 1.25 +namespace OVR { namespace Win32 { 1.26 + 1.27 +//------------------------------------------------------------------------------------- 1.28 +// HIDDevicePathWrapper is a simple class used to extract HID device file path 1.29 +// through SetupDiGetDeviceInterfaceDetail. We use a class since this is a bit messy. 1.30 +class HIDDevicePathWrapper 1.31 +{ 1.32 + SP_INTERFACE_DEVICE_DETAIL_DATA_A* pData; 1.33 +public: 1.34 + HIDDevicePathWrapper() : pData(0) { } 1.35 + ~HIDDevicePathWrapper() { if (pData) OVR_FREE(pData); } 1.36 + 1.37 + const char* GetPath() const { return pData ? pData->DevicePath : 0; } 1.38 + 1.39 + bool InitPathFromInterfaceData(HDEVINFO hdevInfoSet, SP_DEVICE_INTERFACE_DATA* pidata); 1.40 +}; 1.41 + 1.42 +bool HIDDevicePathWrapper::InitPathFromInterfaceData(HDEVINFO hdevInfoSet, SP_DEVICE_INTERFACE_DATA* pidata) 1.43 +{ 1.44 + DWORD detailSize = 0; 1.45 + // SetupDiGetDeviceInterfaceDetailA returns "not enough buffer error code" 1.46 + // doe size request. Just check valid size. 1.47 + SetupDiGetDeviceInterfaceDetailA(hdevInfoSet, pidata, NULL, 0, &detailSize, NULL); 1.48 + if (!detailSize || 1.49 + ((pData = (SP_INTERFACE_DEVICE_DETAIL_DATA_A*)OVR_ALLOC(detailSize)) == 0)) 1.50 + return false; 1.51 + pData->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA_A); 1.52 + 1.53 + if (!SetupDiGetDeviceInterfaceDetailA(hdevInfoSet, pidata, pData, detailSize, NULL, NULL)) 1.54 + return false; 1.55 + return true; 1.56 +} 1.57 + 1.58 + 1.59 +//------------------------------------------------------------------------------------- 1.60 +// **** Win32::DeviceManager 1.61 + 1.62 +HIDDeviceManager::HIDDeviceManager(DeviceManager* manager) 1.63 + : Manager(manager) 1.64 +{ 1.65 + hHidLib = ::LoadLibraryA("hid.dll"); 1.66 + OVR_ASSERT_LOG(hHidLib, ("Couldn't load Win32 'hid.dll'.")); 1.67 + 1.68 + OVR_RESOLVE_HIDFUNC(HidD_GetHidGuid); 1.69 + OVR_RESOLVE_HIDFUNC(HidD_SetNumInputBuffers); 1.70 + OVR_RESOLVE_HIDFUNC(HidD_GetFeature); 1.71 + OVR_RESOLVE_HIDFUNC(HidD_SetFeature); 1.72 + OVR_RESOLVE_HIDFUNC(HidD_GetAttributes); 1.73 + OVR_RESOLVE_HIDFUNC(HidD_GetManufacturerString); 1.74 + OVR_RESOLVE_HIDFUNC(HidD_GetProductString); 1.75 + OVR_RESOLVE_HIDFUNC(HidD_GetSerialNumberString); 1.76 + OVR_RESOLVE_HIDFUNC(HidD_GetPreparsedData); 1.77 + OVR_RESOLVE_HIDFUNC(HidD_FreePreparsedData); 1.78 + OVR_RESOLVE_HIDFUNC(HidP_GetCaps); 1.79 + 1.80 + if (HidD_GetHidGuid) 1.81 + HidD_GetHidGuid(&HidGuid); 1.82 +} 1.83 + 1.84 +HIDDeviceManager::~HIDDeviceManager() 1.85 +{ 1.86 + ::FreeLibrary(hHidLib); 1.87 +} 1.88 + 1.89 +bool HIDDeviceManager::Initialize() 1.90 +{ 1.91 + return true; 1.92 +} 1.93 + 1.94 +void HIDDeviceManager::Shutdown() 1.95 +{ 1.96 + LogText("OVR::Win32::HIDDeviceManager - shutting down.\n"); 1.97 +} 1.98 + 1.99 +bool HIDDeviceManager::Enumerate(HIDEnumerateVisitor* enumVisitor) 1.100 +{ 1.101 + HDEVINFO hdevInfoSet; 1.102 + SP_DEVICE_INTERFACE_DATA interfaceData; 1.103 + interfaceData.cbSize = sizeof(interfaceData); 1.104 + 1.105 + // Get handle to info data set describing all available HIDs. 1.106 + hdevInfoSet = SetupDiGetClassDevsA(&HidGuid, NULL, NULL, DIGCF_INTERFACEDEVICE | DIGCF_PRESENT); 1.107 + if (hdevInfoSet == INVALID_HANDLE_VALUE) 1.108 + return false; 1.109 + 1.110 + for(int deviceIndex = 0; 1.111 + SetupDiEnumDeviceInterfaces(hdevInfoSet, NULL, &HidGuid, deviceIndex, &interfaceData); 1.112 + deviceIndex++) 1.113 + { 1.114 + // For each device, we extract its file path and open it to get attributes, 1.115 + // such as vendor and product id. If anything goes wrong, we move onto next device. 1.116 + HIDDevicePathWrapper pathWrapper; 1.117 + if (!pathWrapper.InitPathFromInterfaceData(hdevInfoSet, &interfaceData)) 1.118 + continue; 1.119 + 1.120 + // Look for the device to check if it is already opened. 1.121 + Ptr<DeviceCreateDesc> existingDevice = Manager->FindDevice(pathWrapper.GetPath()); 1.122 + // if device exists and it is opened then most likely the CreateHIDFile 1.123 + // will fail; therefore, we just set Enumerated to 'true' and continue. 1.124 + if (existingDevice && existingDevice->pDevice) 1.125 + { 1.126 + existingDevice->Enumerated = true; 1.127 + continue; 1.128 + } 1.129 + 1.130 + // open device in non-exclusive mode for detection... 1.131 + HANDLE hidDev = CreateHIDFile(pathWrapper.GetPath(), false); 1.132 + if (hidDev == INVALID_HANDLE_VALUE) 1.133 + continue; 1.134 + 1.135 + HIDDeviceDesc devDesc; 1.136 + devDesc.Path = pathWrapper.GetPath(); 1.137 + if (initVendorProductVersion(hidDev, &devDesc) && 1.138 + enumVisitor->MatchVendorProduct(devDesc.VendorId, devDesc.ProductId) && 1.139 + initUsage(hidDev, &devDesc)) 1.140 + { 1.141 + initStrings(hidDev, &devDesc); 1.142 + 1.143 + // Construct minimal device that the visitor callback can get feature reports from. 1.144 + Win32::HIDDevice device(this, hidDev); 1.145 + enumVisitor->Visit(device, devDesc); 1.146 + } 1.147 + 1.148 + ::CloseHandle(hidDev); 1.149 + } 1.150 + 1.151 + SetupDiDestroyDeviceInfoList(hdevInfoSet); 1.152 + return true; 1.153 +} 1.154 + 1.155 +bool HIDDeviceManager::GetHIDDeviceDesc(const String& path, HIDDeviceDesc* pdevDesc) const 1.156 +{ 1.157 + // open device in non-exclusive mode for detection... 1.158 + HANDLE hidDev = CreateHIDFile(path, false); 1.159 + if (hidDev == INVALID_HANDLE_VALUE) 1.160 + return false; 1.161 + 1.162 + pdevDesc->Path = path; 1.163 + getFullDesc(hidDev, pdevDesc); 1.164 + 1.165 + ::CloseHandle(hidDev); 1.166 + return true; 1.167 +} 1.168 + 1.169 +OVR::HIDDevice* HIDDeviceManager::Open(const String& path) 1.170 +{ 1.171 + 1.172 + Ptr<Win32::HIDDevice> device = *new Win32::HIDDevice(this); 1.173 + 1.174 + if (device->HIDInitialize(path)) 1.175 + { 1.176 + device->AddRef(); 1.177 + return device; 1.178 + } 1.179 + 1.180 + return NULL; 1.181 +} 1.182 + 1.183 +bool HIDDeviceManager::getFullDesc(HANDLE hidDev, HIDDeviceDesc* desc) const 1.184 +{ 1.185 + 1.186 + if (!initVendorProductVersion(hidDev, desc)) 1.187 + { 1.188 + return false; 1.189 + } 1.190 + 1.191 + if (!initUsage(hidDev, desc)) 1.192 + { 1.193 + return false; 1.194 + } 1.195 + 1.196 + initStrings(hidDev, desc); 1.197 + 1.198 + return true; 1.199 +} 1.200 + 1.201 +bool HIDDeviceManager::initVendorProductVersion(HANDLE hidDev, HIDDeviceDesc* desc) const 1.202 +{ 1.203 + HIDD_ATTRIBUTES attr; 1.204 + attr.Size = sizeof(attr); 1.205 + if (!HidD_GetAttributes(hidDev, &attr)) 1.206 + return false; 1.207 + desc->VendorId = attr.VendorID; 1.208 + desc->ProductId = attr.ProductID; 1.209 + desc->VersionNumber = attr.VersionNumber; 1.210 + return true; 1.211 +} 1.212 + 1.213 +bool HIDDeviceManager::initUsage(HANDLE hidDev, HIDDeviceDesc* desc) const 1.214 +{ 1.215 + bool result = false; 1.216 + HIDP_CAPS caps; 1.217 + HIDP_PREPARSED_DATA* preparsedData = 0; 1.218 + 1.219 + if (!HidD_GetPreparsedData(hidDev, &preparsedData)) 1.220 + return false; 1.221 + 1.222 + if (HidP_GetCaps(preparsedData, &caps) == HIDP_STATUS_SUCCESS) 1.223 + { 1.224 + desc->Usage = caps.Usage; 1.225 + desc->UsagePage = caps.UsagePage; 1.226 + result = true; 1.227 + } 1.228 + HidD_FreePreparsedData(preparsedData); 1.229 + return result; 1.230 +} 1.231 + 1.232 +void HIDDeviceManager::initStrings(HANDLE hidDev, HIDDeviceDesc* desc) const 1.233 +{ 1.234 + // Documentation mentions 126 as being the max for USB. 1.235 + wchar_t strBuffer[196]; 1.236 + 1.237 + // HidD_Get*String functions return nothing in buffer on failure, 1.238 + // so it's ok to do this without further error checking. 1.239 + strBuffer[0] = 0; 1.240 + HidD_GetManufacturerString(hidDev, strBuffer, sizeof(strBuffer)); 1.241 + desc->Manufacturer = strBuffer; 1.242 + 1.243 + strBuffer[0] = 0; 1.244 + HidD_GetProductString(hidDev, strBuffer, sizeof(strBuffer)); 1.245 + desc->Product = strBuffer; 1.246 + 1.247 + strBuffer[0] = 0; 1.248 + HidD_GetSerialNumberString(hidDev, strBuffer, sizeof(strBuffer)); 1.249 + desc->SerialNumber = strBuffer; 1.250 +} 1.251 + 1.252 +//------------------------------------------------------------------------------------- 1.253 +// **** Win32::HIDDevice 1.254 + 1.255 +HIDDevice::HIDDevice(HIDDeviceManager* manager) 1.256 + : HIDManager(manager), inMinimalMode(false), Device(0), ReadRequested(false) 1.257 +{ 1.258 + memset(&ReadOverlapped, 0, sizeof(OVERLAPPED)); 1.259 +} 1.260 + 1.261 +// This is a minimal constructor used during enumeration for us to pass 1.262 +// a HIDDevice to the visit function (so that it can query feature reports). 1.263 +HIDDevice::HIDDevice(HIDDeviceManager* manager, HANDLE device) 1.264 + : HIDManager(manager), inMinimalMode(true), Device(device), ReadRequested(true) 1.265 +{ 1.266 + memset(&ReadOverlapped, 0, sizeof(OVERLAPPED)); 1.267 +} 1.268 + 1.269 +HIDDevice::~HIDDevice() 1.270 +{ 1.271 + if (!inMinimalMode) 1.272 + { 1.273 + HIDShutdown(); 1.274 + } 1.275 +} 1.276 + 1.277 +bool HIDDevice::HIDInitialize(const String& path) 1.278 +{ 1.279 + 1.280 + DevDesc.Path = path; 1.281 + 1.282 + if (!openDevice()) 1.283 + { 1.284 + LogText("OVR::Win32::HIDDevice - Failed to open HIDDevice: ", path); 1.285 + return false; 1.286 + } 1.287 + 1.288 + 1.289 + HIDManager->Manager->pThread->AddTicksNotifier(this); 1.290 + HIDManager->Manager->pThread->AddMessageNotifier(this); 1.291 + 1.292 + LogText("OVR::Win32::HIDDevice - Opened '%s'\n" 1.293 + " Manufacturer:'%s' Product:'%s' Serial#:'%s'\n", 1.294 + DevDesc.Path.ToCStr(), 1.295 + DevDesc.Manufacturer.ToCStr(), DevDesc.Product.ToCStr(), 1.296 + DevDesc.SerialNumber.ToCStr()); 1.297 + 1.298 + return true; 1.299 +} 1.300 + 1.301 +bool HIDDevice::initInfo() 1.302 +{ 1.303 + // Device must have been successfully opened. 1.304 + OVR_ASSERT(Device); 1.305 + 1.306 + // Get report lengths. 1.307 + HIDP_PREPARSED_DATA* preparsedData = 0; 1.308 + if (!HIDManager->HidD_GetPreparsedData(Device, &preparsedData)) 1.309 + { 1.310 + return false; 1.311 + } 1.312 + 1.313 + HIDP_CAPS caps; 1.314 + if (HIDManager->HidP_GetCaps(preparsedData, &caps) != HIDP_STATUS_SUCCESS) 1.315 + { 1.316 + HIDManager->HidD_FreePreparsedData(preparsedData); 1.317 + return false; 1.318 + } 1.319 + 1.320 + InputReportBufferLength = caps.InputReportByteLength; 1.321 + OutputReportBufferLength = caps.OutputReportByteLength; 1.322 + FeatureReportBufferLength= caps.FeatureReportByteLength; 1.323 + HIDManager->HidD_FreePreparsedData(preparsedData); 1.324 + 1.325 + if (ReadBufferSize < InputReportBufferLength) 1.326 + { 1.327 + OVR_ASSERT_LOG(false, ("Input report buffer length is bigger than read buffer.")); 1.328 + return false; 1.329 + } 1.330 + 1.331 + // Get device desc. 1.332 + if (!HIDManager->getFullDesc(Device, &DevDesc)) 1.333 + { 1.334 + OVR_ASSERT_LOG(false, ("Failed to get device desc while initializing device.")); 1.335 + return false; 1.336 + } 1.337 + 1.338 + return true; 1.339 +} 1.340 + 1.341 +bool HIDDevice::openDevice() 1.342 +{ 1.343 + memset(&ReadOverlapped, 0, sizeof(OVERLAPPED)); 1.344 + 1.345 + Device = HIDManager->CreateHIDFile(DevDesc.Path.ToCStr()); 1.346 + if (Device == INVALID_HANDLE_VALUE) 1.347 + { 1.348 + OVR_DEBUG_LOG(("Failed 'CreateHIDFile' while opening device, error = 0x%X.", 1.349 + ::GetLastError())); 1.350 + Device = 0; 1.351 + return false; 1.352 + } 1.353 + 1.354 + if (!HIDManager->HidD_SetNumInputBuffers(Device, 128)) 1.355 + { 1.356 + OVR_ASSERT_LOG(false, ("Failed 'HidD_SetNumInputBuffers' while initializing device.")); 1.357 + ::CloseHandle(Device); 1.358 + Device = 0; 1.359 + return false; 1.360 + } 1.361 + 1.362 + 1.363 + // Create a manual-reset non-signaled event. 1.364 + ReadOverlapped.hEvent = ::CreateEvent(0, TRUE, FALSE, 0); 1.365 + 1.366 + if (!ReadOverlapped.hEvent) 1.367 + { 1.368 + OVR_ASSERT_LOG(false, ("Failed to create event.")); 1.369 + ::CloseHandle(Device); 1.370 + Device = 0; 1.371 + return false; 1.372 + } 1.373 + 1.374 + if (!initInfo()) 1.375 + { 1.376 + OVR_ASSERT_LOG(false, ("Failed to get HIDDevice info.")); 1.377 + 1.378 + ::CloseHandle(ReadOverlapped.hEvent); 1.379 + memset(&ReadOverlapped, 0, sizeof(OVERLAPPED)); 1.380 + 1.381 + ::CloseHandle(Device); 1.382 + Device = 0; 1.383 + return false; 1.384 + } 1.385 + 1.386 + if (!initializeRead()) 1.387 + { 1.388 + OVR_ASSERT_LOG(false, ("Failed to get intialize read for HIDDevice.")); 1.389 + 1.390 + ::CloseHandle(ReadOverlapped.hEvent); 1.391 + memset(&ReadOverlapped, 0, sizeof(OVERLAPPED)); 1.392 + 1.393 + ::CloseHandle(Device); 1.394 + Device = 0; 1.395 + return false; 1.396 + } 1.397 + 1.398 + return true; 1.399 +} 1.400 + 1.401 +void HIDDevice::HIDShutdown() 1.402 +{ 1.403 + 1.404 + HIDManager->Manager->pThread->RemoveTicksNotifier(this); 1.405 + HIDManager->Manager->pThread->RemoveMessageNotifier(this); 1.406 + 1.407 + closeDevice(); 1.408 + LogText("OVR::Win32::HIDDevice - Closed '%s'\n", DevDesc.Path.ToCStr()); 1.409 +} 1.410 + 1.411 +bool HIDDevice::initializeRead() 1.412 +{ 1.413 + 1.414 + if (!ReadRequested) 1.415 + { 1.416 + HIDManager->Manager->pThread->AddOverlappedEvent(this, ReadOverlapped.hEvent); 1.417 + ReadRequested = true; 1.418 + } 1.419 + 1.420 + // Read resets the event... 1.421 + while(::ReadFile(Device, ReadBuffer, InputReportBufferLength, 0, &ReadOverlapped)) 1.422 + { 1.423 + processReadResult(); 1.424 + } 1.425 + 1.426 + if (GetLastError() != ERROR_IO_PENDING) 1.427 + { 1.428 + // Some other error (such as unplugged). 1.429 + closeDeviceOnIOError(); 1.430 + return false; 1.431 + } 1.432 + 1.433 + return true; 1.434 +} 1.435 + 1.436 +bool HIDDevice::processReadResult() 1.437 +{ 1.438 + 1.439 + OVR_ASSERT(ReadRequested); 1.440 + 1.441 + DWORD bytesRead = 0; 1.442 + 1.443 + if (GetOverlappedResult(Device, &ReadOverlapped, &bytesRead, FALSE)) 1.444 + { 1.445 + // We've got data. 1.446 + if (Handler) 1.447 + { 1.448 + Handler->OnInputReport(ReadBuffer, bytesRead); 1.449 + } 1.450 + 1.451 + // TBD: Not needed? 1.452 + // Event should be reset by Read call... 1.453 + ReadOverlapped.Pointer = 0; 1.454 + ReadOverlapped.Internal = 0; 1.455 + ReadOverlapped.InternalHigh = 0; 1.456 + return true; 1.457 + } 1.458 + else 1.459 + { 1.460 + if (GetLastError() != ERROR_IO_PENDING) 1.461 + { 1.462 + closeDeviceOnIOError(); 1.463 + return false; 1.464 + } 1.465 + } 1.466 + 1.467 + return false; 1.468 +} 1.469 + 1.470 +void HIDDevice::closeDevice() 1.471 +{ 1.472 + if (ReadRequested) 1.473 + { 1.474 + HIDManager->Manager->pThread->RemoveOverlappedEvent(this, ReadOverlapped.hEvent); 1.475 + ReadRequested = false; 1.476 + // Must call this to avoid Win32 assertion; CloseHandle is not enough. 1.477 + ::CancelIo(Device); 1.478 + } 1.479 + 1.480 + ::CloseHandle(ReadOverlapped.hEvent); 1.481 + memset(&ReadOverlapped, 0, sizeof(OVERLAPPED)); 1.482 + 1.483 + ::CloseHandle(Device); 1.484 + Device = 0; 1.485 +} 1.486 + 1.487 +void HIDDevice::closeDeviceOnIOError() 1.488 +{ 1.489 + LogText("OVR::Win32::HIDDevice - Lost connection to '%s'\n", DevDesc.Path.ToCStr()); 1.490 + closeDevice(); 1.491 +} 1.492 + 1.493 +bool HIDDevice::SetFeatureReport(UByte* data, UInt32 length) 1.494 +{ 1.495 + if (!ReadRequested) 1.496 + return false; 1.497 + 1.498 + return HIDManager->HidD_SetFeature(Device, data, (ULONG) length) != FALSE; 1.499 +} 1.500 + 1.501 +bool HIDDevice::GetFeatureReport(UByte* data, UInt32 length) 1.502 +{ 1.503 + if (!ReadRequested) 1.504 + return false; 1.505 + 1.506 + return HIDManager->HidD_GetFeature(Device, data, (ULONG) length) != FALSE; 1.507 +} 1.508 + 1.509 +void HIDDevice::OnOverlappedEvent(HANDLE hevent) 1.510 +{ 1.511 + OVR_UNUSED(hevent); 1.512 + OVR_ASSERT(hevent == ReadOverlapped.hEvent); 1.513 + 1.514 + if (processReadResult()) 1.515 + { 1.516 + // Proceed to read again. 1.517 + initializeRead(); 1.518 + } 1.519 +} 1.520 + 1.521 +UInt64 HIDDevice::OnTicks(UInt64 ticksMks) 1.522 +{ 1.523 + if (Handler) 1.524 + { 1.525 + return Handler->OnTicks(ticksMks); 1.526 + } 1.527 + 1.528 + return DeviceManagerThread::Notifier::OnTicks(ticksMks); 1.529 +} 1.530 + 1.531 +bool HIDDevice::OnDeviceMessage(DeviceMessageType messageType, 1.532 + const String& devicePath, 1.533 + bool* error) 1.534 +{ 1.535 + 1.536 + // Is this the correct device? 1.537 + if (DevDesc.Path.CompareNoCase(devicePath) != 0) 1.538 + { 1.539 + return false; 1.540 + } 1.541 + 1.542 + if (messageType == DeviceMessage_DeviceAdded && !Device) 1.543 + { 1.544 + // A closed device has been re-added. Try to reopen. 1.545 + if (!openDevice()) 1.546 + { 1.547 + LogError("OVR::Win32::HIDDevice - Failed to reopen a device '%s' that was re-added.\n", devicePath.ToCStr()); 1.548 + *error = true; 1.549 + return true; 1.550 + } 1.551 + 1.552 + LogText("OVR::Win32::HIDDevice - Reopened device '%s'\n", devicePath.ToCStr()); 1.553 + } 1.554 + 1.555 + HIDHandler::HIDDeviceMessageType handlerMessageType = HIDHandler::HIDDeviceMessage_DeviceAdded; 1.556 + if (messageType == DeviceMessage_DeviceAdded) 1.557 + { 1.558 + } 1.559 + else if (messageType == DeviceMessage_DeviceRemoved) 1.560 + { 1.561 + handlerMessageType = HIDHandler::HIDDeviceMessage_DeviceRemoved; 1.562 + } 1.563 + else 1.564 + { 1.565 + OVR_ASSERT(0); 1.566 + } 1.567 + 1.568 + if (Handler) 1.569 + { 1.570 + Handler->OnDeviceMessage(handlerMessageType); 1.571 + } 1.572 + 1.573 + *error = false; 1.574 + return true; 1.575 +} 1.576 + 1.577 +HIDDeviceManager* HIDDeviceManager::CreateInternal(Win32::DeviceManager* devManager) 1.578 +{ 1.579 + 1.580 + if (!System::IsInitialized()) 1.581 + { 1.582 + // Use custom message, since Log is not yet installed. 1.583 + OVR_DEBUG_STATEMENT(Log::GetDefaultLog()-> 1.584 + LogMessage(Log_Debug, "HIDDeviceManager::Create failed - OVR::System not initialized"); ); 1.585 + return 0; 1.586 + } 1.587 + 1.588 + Ptr<Win32::HIDDeviceManager> manager = *new Win32::HIDDeviceManager(devManager); 1.589 + 1.590 + if (manager) 1.591 + { 1.592 + if (manager->Initialize()) 1.593 + { 1.594 + manager->AddRef(); 1.595 + } 1.596 + else 1.597 + { 1.598 + manager.Clear(); 1.599 + } 1.600 + } 1.601 + 1.602 + return manager.GetPtr(); 1.603 +} 1.604 + 1.605 +} // namespace Win32 1.606 + 1.607 +//------------------------------------------------------------------------------------- 1.608 +// ***** Creation 1.609 + 1.610 +// Creates a new HIDDeviceManager and initializes OVR. 1.611 +HIDDeviceManager* HIDDeviceManager::Create() 1.612 +{ 1.613 + OVR_ASSERT_LOG(false, ("Standalone mode not implemented yet.")); 1.614 + 1.615 + if (!System::IsInitialized()) 1.616 + { 1.617 + // Use custom message, since Log is not yet installed. 1.618 + OVR_DEBUG_STATEMENT(Log::GetDefaultLog()-> 1.619 + LogMessage(Log_Debug, "HIDDeviceManager::Create failed - OVR::System not initialized"); ); 1.620 + return 0; 1.621 + } 1.622 + 1.623 + Ptr<Win32::HIDDeviceManager> manager = *new Win32::HIDDeviceManager(NULL); 1.624 + 1.625 + if (manager) 1.626 + { 1.627 + if (manager->Initialize()) 1.628 + { 1.629 + manager->AddRef(); 1.630 + } 1.631 + else 1.632 + { 1.633 + manager.Clear(); 1.634 + } 1.635 + } 1.636 + 1.637 + return manager.GetPtr(); 1.638 +} 1.639 + 1.640 +} // namespace OVR