rev |
line source |
nuclear@1
|
1 /************************************************************************************
|
nuclear@1
|
2
|
nuclear@1
|
3 Filename : OVR_Win32_HIDDevice.h
|
nuclear@1
|
4 Content : Win32 HID device implementation.
|
nuclear@1
|
5 Created : February 22, 2013
|
nuclear@1
|
6 Authors : Lee Cooper
|
nuclear@1
|
7
|
nuclear@1
|
8 Copyright : Copyright 2013 Oculus VR, Inc. All Rights reserved.
|
nuclear@1
|
9
|
nuclear@1
|
10 Use of this software is subject to the terms of the Oculus license
|
nuclear@1
|
11 agreement provided at the time of installation or download, or which
|
nuclear@1
|
12 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@1
|
13
|
nuclear@1
|
14 *************************************************************************************/
|
nuclear@1
|
15
|
nuclear@1
|
16 #ifndef OVR_Win32_HIDDevice_h
|
nuclear@1
|
17 #define OVR_Win32_HIDDevice_h
|
nuclear@1
|
18
|
nuclear@1
|
19 #include "OVR_HIDDevice.h"
|
nuclear@1
|
20 #include "OVR_Win32_DeviceManager.h"
|
nuclear@1
|
21
|
nuclear@1
|
22 #include <windows.h>
|
nuclear@1
|
23 #include <setupapi.h>
|
nuclear@1
|
24
|
nuclear@1
|
25 //-------------------------------------------------------------------------------------
|
nuclear@1
|
26 // Define needed "hidsdi.h" functionality to avoid requiring DDK installation.
|
nuclear@1
|
27 // #include "hidsdi.h"
|
nuclear@1
|
28
|
nuclear@1
|
29 #ifndef _HIDSDI_H
|
nuclear@1
|
30 #define _HIDSDI_H
|
nuclear@1
|
31 #include <pshpack4.h>
|
nuclear@1
|
32
|
nuclear@1
|
33 #define HIDP_STATUS_SUCCESS (0x11 << 16)
|
nuclear@1
|
34 struct HIDP_PREPARSED_DATA;
|
nuclear@1
|
35
|
nuclear@1
|
36 struct HIDD_ATTRIBUTES
|
nuclear@1
|
37 {
|
nuclear@1
|
38 ULONG Size; // = sizeof (struct _HIDD_ATTRIBUTES)
|
nuclear@1
|
39 USHORT VendorID;
|
nuclear@1
|
40 USHORT ProductID;
|
nuclear@1
|
41 USHORT VersionNumber;
|
nuclear@1
|
42 };
|
nuclear@1
|
43
|
nuclear@1
|
44 struct HIDP_CAPS
|
nuclear@1
|
45 {
|
nuclear@1
|
46 USHORT Usage;
|
nuclear@1
|
47 USHORT UsagePage;
|
nuclear@1
|
48 USHORT InputReportByteLength;
|
nuclear@1
|
49 USHORT OutputReportByteLength;
|
nuclear@1
|
50 USHORT FeatureReportByteLength;
|
nuclear@1
|
51 USHORT Reserved[17];
|
nuclear@1
|
52
|
nuclear@1
|
53 USHORT NumberLinkCollectionNodes;
|
nuclear@1
|
54 USHORT NumberInputButtonCaps;
|
nuclear@1
|
55 USHORT NumberInputValueCaps;
|
nuclear@1
|
56 USHORT NumberInputDataIndices;
|
nuclear@1
|
57 USHORT NumberOutputButtonCaps;
|
nuclear@1
|
58 USHORT NumberOutputValueCaps;
|
nuclear@1
|
59 USHORT NumberOutputDataIndices;
|
nuclear@1
|
60 USHORT NumberFeatureButtonCaps;
|
nuclear@1
|
61 USHORT NumberFeatureValueCaps;
|
nuclear@1
|
62 USHORT NumberFeatureDataIndices;
|
nuclear@1
|
63 };
|
nuclear@1
|
64
|
nuclear@1
|
65 #include <poppack.h>
|
nuclear@1
|
66 #endif
|
nuclear@1
|
67
|
nuclear@1
|
68
|
nuclear@1
|
69 namespace OVR { namespace Win32 {
|
nuclear@1
|
70
|
nuclear@1
|
71 class HIDDeviceManager;
|
nuclear@1
|
72 class DeviceManager;
|
nuclear@1
|
73
|
nuclear@1
|
74 //-------------------------------------------------------------------------------------
|
nuclear@1
|
75 // ***** Win32 HIDDevice
|
nuclear@1
|
76
|
nuclear@1
|
77 class HIDDevice : public OVR::HIDDevice, public DeviceManagerThread::Notifier
|
nuclear@1
|
78 {
|
nuclear@1
|
79 public:
|
nuclear@1
|
80
|
nuclear@1
|
81 HIDDevice(HIDDeviceManager* manager);
|
nuclear@1
|
82
|
nuclear@1
|
83 // This is a minimal constructor used during enumeration for us to pass
|
nuclear@1
|
84 // a HIDDevice to the visit function (so that it can query feature reports).
|
nuclear@1
|
85 HIDDevice(HIDDeviceManager* manager, HANDLE device);
|
nuclear@1
|
86
|
nuclear@1
|
87 ~HIDDevice();
|
nuclear@1
|
88
|
nuclear@1
|
89 bool HIDInitialize(const String& path);
|
nuclear@1
|
90 void HIDShutdown();
|
nuclear@1
|
91
|
nuclear@1
|
92 // OVR::HIDDevice
|
nuclear@1
|
93 bool SetFeatureReport(UByte* data, UInt32 length);
|
nuclear@1
|
94 bool GetFeatureReport(UByte* data, UInt32 length);
|
nuclear@1
|
95
|
nuclear@1
|
96
|
nuclear@1
|
97 // DeviceManagerThread::Notifier
|
nuclear@1
|
98 void OnOverlappedEvent(HANDLE hevent);
|
nuclear@1
|
99 UInt64 OnTicks(UInt64 ticksMks);
|
nuclear@1
|
100 bool OnDeviceMessage(DeviceMessageType messageType, const String& devicePath, bool* error);
|
nuclear@1
|
101
|
nuclear@1
|
102 private:
|
nuclear@1
|
103 bool openDevice();
|
nuclear@1
|
104 bool initInfo();
|
nuclear@1
|
105 bool initializeRead();
|
nuclear@1
|
106 bool processReadResult();
|
nuclear@1
|
107 void closeDevice();
|
nuclear@1
|
108 void closeDeviceOnIOError();
|
nuclear@1
|
109
|
nuclear@1
|
110 bool inMinimalMode;
|
nuclear@1
|
111 HIDDeviceManager* HIDManager;
|
nuclear@1
|
112 HANDLE Device;
|
nuclear@1
|
113 HIDDeviceDesc DevDesc;
|
nuclear@1
|
114
|
nuclear@1
|
115 OVERLAPPED ReadOverlapped;
|
nuclear@1
|
116 bool ReadRequested;
|
nuclear@1
|
117
|
nuclear@1
|
118 enum { ReadBufferSize = 96 };
|
nuclear@1
|
119 UByte ReadBuffer[ReadBufferSize];
|
nuclear@1
|
120
|
nuclear@1
|
121 UInt16 InputReportBufferLength;
|
nuclear@1
|
122 UInt16 OutputReportBufferLength;
|
nuclear@1
|
123 UInt16 FeatureReportBufferLength;
|
nuclear@1
|
124 };
|
nuclear@1
|
125
|
nuclear@1
|
126 //-------------------------------------------------------------------------------------
|
nuclear@1
|
127 // ***** Win32 HIDDeviceManager
|
nuclear@1
|
128
|
nuclear@1
|
129 class HIDDeviceManager : public OVR::HIDDeviceManager
|
nuclear@1
|
130 {
|
nuclear@1
|
131 friend class HIDDevice;
|
nuclear@1
|
132 public:
|
nuclear@1
|
133
|
nuclear@1
|
134 HIDDeviceManager(DeviceManager* manager);
|
nuclear@1
|
135 virtual ~HIDDeviceManager();
|
nuclear@1
|
136
|
nuclear@1
|
137 virtual bool Initialize();
|
nuclear@1
|
138 virtual void Shutdown();
|
nuclear@1
|
139
|
nuclear@1
|
140 virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor);
|
nuclear@1
|
141 virtual OVR::HIDDevice* Open(const String& path);
|
nuclear@1
|
142
|
nuclear@1
|
143 // Fills HIDDeviceDesc by using the path.
|
nuclear@1
|
144 // Returns 'true' if successful, 'false' otherwise.
|
nuclear@1
|
145 bool GetHIDDeviceDesc(const String& path, HIDDeviceDesc* pdevDesc) const;
|
nuclear@1
|
146
|
nuclear@1
|
147 GUID GetHIDGuid() { return HidGuid; }
|
nuclear@1
|
148
|
nuclear@1
|
149 static HIDDeviceManager* CreateInternal(DeviceManager* manager);
|
nuclear@1
|
150
|
nuclear@1
|
151 private:
|
nuclear@1
|
152
|
nuclear@1
|
153 DeviceManager* Manager; // Back pointer can just be a raw pointer.
|
nuclear@1
|
154
|
nuclear@1
|
155 HMODULE hHidLib;
|
nuclear@1
|
156 GUID HidGuid;
|
nuclear@1
|
157
|
nuclear@1
|
158 // Macros to declare and resolve needed functions from library.
|
nuclear@1
|
159 #define OVR_DECLARE_HIDFUNC(func, rettype, args) \
|
nuclear@1
|
160 typedef rettype (__stdcall *PFn_##func) args; \
|
nuclear@1
|
161 PFn_##func func;
|
nuclear@1
|
162 #define OVR_RESOLVE_HIDFUNC(func) \
|
nuclear@1
|
163 func = (PFn_##func)::GetProcAddress(hHidLib, #func)
|
nuclear@1
|
164
|
nuclear@1
|
165 OVR_DECLARE_HIDFUNC(HidD_GetHidGuid, void, (GUID *hidGuid));
|
nuclear@1
|
166 OVR_DECLARE_HIDFUNC(HidD_SetNumInputBuffers, BOOLEAN, (HANDLE hidDev, ULONG numberBuffers));
|
nuclear@1
|
167 OVR_DECLARE_HIDFUNC(HidD_GetFeature, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength));
|
nuclear@1
|
168 OVR_DECLARE_HIDFUNC(HidD_SetFeature, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength));
|
nuclear@1
|
169 OVR_DECLARE_HIDFUNC(HidD_GetAttributes, BOOLEAN, (HANDLE hidDev, HIDD_ATTRIBUTES *attributes));
|
nuclear@1
|
170 OVR_DECLARE_HIDFUNC(HidD_GetManufacturerString, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength));
|
nuclear@1
|
171 OVR_DECLARE_HIDFUNC(HidD_GetProductString, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength));
|
nuclear@1
|
172 OVR_DECLARE_HIDFUNC(HidD_GetSerialNumberString, BOOLEAN, (HANDLE hidDev, PVOID buffer, ULONG bufferLength));
|
nuclear@1
|
173 OVR_DECLARE_HIDFUNC(HidD_GetPreparsedData, BOOLEAN, (HANDLE hidDev, HIDP_PREPARSED_DATA **preparsedData));
|
nuclear@1
|
174 OVR_DECLARE_HIDFUNC(HidD_FreePreparsedData, BOOLEAN, (HIDP_PREPARSED_DATA *preparsedData));
|
nuclear@1
|
175 OVR_DECLARE_HIDFUNC(HidP_GetCaps, NTSTATUS,(HIDP_PREPARSED_DATA *preparsedData, HIDP_CAPS* caps));
|
nuclear@1
|
176
|
nuclear@1
|
177 HANDLE CreateHIDFile(const char* path, bool exclusiveAccess = true) const
|
nuclear@1
|
178 {
|
nuclear@1
|
179 return ::CreateFileA(path, GENERIC_WRITE|GENERIC_READ,
|
nuclear@1
|
180 (!exclusiveAccess) ? (FILE_SHARE_READ|FILE_SHARE_WRITE) : 0x0,
|
nuclear@1
|
181 NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
|
nuclear@1
|
182 }
|
nuclear@1
|
183
|
nuclear@1
|
184 // Helper functions to fill in HIDDeviceDesc from open device handle.
|
nuclear@1
|
185 bool initVendorProductVersion(HANDLE hidDev, HIDDeviceDesc* desc) const;
|
nuclear@1
|
186 bool initUsage(HANDLE hidDev, HIDDeviceDesc* desc) const;
|
nuclear@1
|
187 void initStrings(HANDLE hidDev, HIDDeviceDesc* desc) const;
|
nuclear@1
|
188
|
nuclear@1
|
189 bool getFullDesc(HANDLE hidDev, HIDDeviceDesc* desc) const;
|
nuclear@1
|
190 };
|
nuclear@1
|
191
|
nuclear@1
|
192 }} // namespace OVR::Win32
|
nuclear@1
|
193
|
nuclear@1
|
194 #endif // OVR_Win32_HIDDevice_h
|