nuclear@1: /************************************************************************************ nuclear@1: nuclear@1: Filename : OVR_HIDDeviceImpl.h nuclear@1: Content : Implementation of HIDDevice. nuclear@1: Created : March 7, 2013 nuclear@1: Authors : Lee Cooper nuclear@1: nuclear@1: Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved. nuclear@1: nuclear@1: Use of this software is subject to the terms of the Oculus license nuclear@1: agreement provided at the time of installation or download, or which nuclear@1: otherwise accompanies this software in either electronic or hard copy form. nuclear@1: nuclear@1: *************************************************************************************/ nuclear@1: nuclear@1: #ifndef OVR_HIDDeviceImpl_h nuclear@1: #define OVR_HIDDeviceImpl_h nuclear@1: nuclear@1: //#include "OVR_Device.h" nuclear@1: #include "OVR_DeviceImpl.h" nuclear@1: nuclear@1: namespace OVR { nuclear@1: nuclear@1: //------------------------------------------------------------------------------------- nuclear@1: class HIDDeviceCreateDesc : public DeviceCreateDesc nuclear@1: { nuclear@1: public: nuclear@1: HIDDeviceCreateDesc(DeviceFactory* factory, DeviceType type, const HIDDeviceDesc& hidDesc) nuclear@1: : DeviceCreateDesc(factory, type), HIDDesc(hidDesc) { } nuclear@1: HIDDeviceCreateDesc(const HIDDeviceCreateDesc& other) nuclear@1: : DeviceCreateDesc(other.pFactory, other.Type), HIDDesc(other.HIDDesc) { } nuclear@1: nuclear@1: virtual bool MatchDevice(const String& path) nuclear@1: { nuclear@1: // should it be case insensitive? nuclear@1: return HIDDesc.Path.CompareNoCase(path) == 0; nuclear@1: } nuclear@1: nuclear@1: HIDDeviceDesc HIDDesc; nuclear@1: }; nuclear@1: nuclear@1: //------------------------------------------------------------------------------------- nuclear@1: template nuclear@1: class HIDDeviceImpl : public DeviceImpl, public HIDDevice::HIDHandler nuclear@1: { nuclear@1: public: nuclear@1: HIDDeviceImpl(HIDDeviceCreateDesc* createDesc, DeviceBase* parent) nuclear@1: : DeviceImpl(createDesc, parent) nuclear@1: { nuclear@1: } nuclear@1: nuclear@1: // HIDDevice::Handler interface. nuclear@1: virtual void OnDeviceMessage(HIDDeviceMessageType messageType) nuclear@1: { nuclear@1: MessageType handlerMessageType; nuclear@1: switch (messageType) { nuclear@1: case HIDDeviceMessage_DeviceAdded: nuclear@1: handlerMessageType = Message_DeviceAdded; nuclear@1: break; nuclear@1: nuclear@1: case HIDDeviceMessage_DeviceRemoved: nuclear@1: handlerMessageType = Message_DeviceRemoved; nuclear@1: break; nuclear@1: nuclear@1: default: OVR_ASSERT(0); return; nuclear@1: } nuclear@1: nuclear@1: // Do device notification. nuclear@1: { nuclear@1: Lock::Locker scopeLock(this->HandlerRef.GetLock()); nuclear@1: nuclear@1: if (this->HandlerRef.GetHandler()) nuclear@1: { nuclear@1: MessageDeviceStatus status(handlerMessageType, this, OVR::DeviceHandle(this->pCreateDesc)); nuclear@1: this->HandlerRef.GetHandler()->OnMessage(status); nuclear@1: } nuclear@1: } nuclear@1: nuclear@1: // Do device manager notification. nuclear@1: DeviceManagerImpl* manager = this->GetManagerImpl(); nuclear@1: switch (handlerMessageType) { nuclear@1: case Message_DeviceAdded: nuclear@1: manager->CallOnDeviceAdded(this->pCreateDesc); nuclear@1: break; nuclear@1: nuclear@1: case Message_DeviceRemoved: nuclear@1: manager->CallOnDeviceRemoved(this->pCreateDesc); nuclear@1: break; nuclear@1: nuclear@1: default:; nuclear@1: } nuclear@1: } nuclear@1: nuclear@1: virtual bool Initialize(DeviceBase* parent) nuclear@1: { nuclear@1: // Open HID device. nuclear@1: HIDDeviceDesc& hidDesc = *getHIDDesc(); nuclear@1: HIDDeviceManager* pManager = GetHIDDeviceManager(); nuclear@1: nuclear@1: nuclear@1: HIDDevice* device = pManager->Open(hidDesc.Path); nuclear@1: if (!device) nuclear@1: { nuclear@1: return false; nuclear@1: } nuclear@1: nuclear@1: InternalDevice = *device; nuclear@1: InternalDevice->SetHandler(this); nuclear@1: nuclear@1: // AddRef() to parent, forcing chain to stay alive. nuclear@1: DeviceImpl::pParent = parent; nuclear@1: nuclear@1: return true; nuclear@1: } nuclear@1: nuclear@1: virtual void Shutdown() nuclear@1: { nuclear@1: InternalDevice->SetHandler(NULL); nuclear@1: nuclear@1: // Remove the handler, if any. nuclear@1: this->HandlerRef.SetHandler(0); nuclear@1: nuclear@1: DeviceImpl::pParent.Clear(); nuclear@1: } nuclear@1: nuclear@1: DeviceManager* GetDeviceManager() nuclear@1: { nuclear@1: return DeviceImpl::pCreateDesc->GetManagerImpl(); nuclear@1: } nuclear@1: nuclear@1: HIDDeviceManager* GetHIDDeviceManager() nuclear@1: { nuclear@1: return DeviceImpl::pCreateDesc->GetManagerImpl()->GetHIDDeviceManager(); nuclear@1: } nuclear@1: nuclear@1: nuclear@1: struct WriteData nuclear@1: { nuclear@1: enum { BufferSize = 64 }; nuclear@1: UByte Buffer[64]; nuclear@1: UPInt Size; nuclear@1: nuclear@1: WriteData(UByte* data, UPInt size) : Size(size) nuclear@1: { nuclear@1: OVR_ASSERT(size <= BufferSize); nuclear@1: memcpy(Buffer, data, size); nuclear@1: } nuclear@1: }; nuclear@1: nuclear@1: bool SetFeatureReport(UByte* data, UInt32 length) nuclear@1: { nuclear@1: WriteData writeData(data, length); nuclear@1: nuclear@1: // Push call with wait. nuclear@1: bool result = false; nuclear@1: nuclear@1: ThreadCommandQueue* pQueue = this->GetManagerImpl()->GetThreadQueue(); nuclear@1: if (!pQueue->PushCallAndWaitResult(this, &HIDDeviceImpl::setFeatureReport, &result, writeData)) nuclear@1: return false; nuclear@1: nuclear@1: return result; nuclear@1: } nuclear@1: nuclear@1: bool setFeatureReport(const WriteData& data) nuclear@1: { nuclear@1: return InternalDevice->SetFeatureReport((UByte*) data.Buffer, (UInt32) data.Size); nuclear@1: } nuclear@1: nuclear@1: bool GetFeatureReport(UByte* data, UInt32 length) nuclear@1: { nuclear@1: bool result = false; nuclear@1: nuclear@1: ThreadCommandQueue* pQueue = this->GetManagerImpl()->GetThreadQueue(); nuclear@1: if (!pQueue->PushCallAndWaitResult(this, &HIDDeviceImpl::getFeatureReport, &result, data, length)) nuclear@1: return false; nuclear@1: nuclear@1: return result; nuclear@1: } nuclear@1: nuclear@1: bool getFeatureReport(UByte* data, UInt32 length) nuclear@1: { nuclear@1: return InternalDevice->GetFeatureReport(data, length); nuclear@1: } nuclear@1: nuclear@1: protected: nuclear@1: HIDDevice* GetInternalDevice() const nuclear@1: { nuclear@1: return InternalDevice; nuclear@1: } nuclear@1: nuclear@1: HIDDeviceDesc* getHIDDesc() const nuclear@1: { return &getCreateDesc()->HIDDesc; } nuclear@1: nuclear@1: HIDDeviceCreateDesc* getCreateDesc() const nuclear@1: { return (HIDDeviceCreateDesc*) &(*DeviceImpl::pCreateDesc); } nuclear@1: nuclear@1: private: nuclear@1: Ptr InternalDevice; nuclear@1: }; nuclear@1: nuclear@1: } // namespace OVR nuclear@1: nuclear@1: #endif