/src/ois/src/win32/extras/WiiMote/hiddevice.cpp

https://bitbucket.org/cabalistic/ogredeps/ · C++ · 205 lines · 153 code · 35 blank · 17 comment · 30 complexity · 78c598ecb4cb5d989801a8d40f4f55c3 MD5 · raw file

  1. #include "OISConfig.h"
  2. #ifdef OIS_WIN32_WIIMOTE_SUPPORT
  3. //cWiimote 0.2 by Kevin Forbes (http://simulatedcomicproduct.com)
  4. //This code is public domain, and comes with no warranty. The user takes full responsibility for anything that happens as a result from using this code.
  5. //This was based in part on Alan Macek <www.alanmacek.com>'s USB interface library
  6. //Edited for Toshiba Stack support (hopefully also all others) by
  7. //Sean Stellingwerff (http://sean.stellingwerff.com) using information
  8. //gathered from http://www.lvr.com/hidpage.htm (Thanks a million! :D)
  9. //#include "stdafx.h"
  10. #include "hiddevice.h"
  11. extern "C"
  12. {
  13. #include "hidsdi.h"
  14. #include <Setupapi.h>
  15. }
  16. #pragma comment(lib, "setupapi.lib")
  17. #pragma comment(lib, "hid.lib")
  18. HIDP_CAPS Capabilities;
  19. PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;
  20. cHIDDevice::cHIDDevice() : mConnected(false), mHandle(NULL), mEvent(NULL)
  21. {
  22. }
  23. cHIDDevice::~cHIDDevice()
  24. {
  25. if (mConnected)
  26. {
  27. Disconnect();
  28. }
  29. }
  30. bool cHIDDevice::Disconnect()
  31. {
  32. bool retval = false;
  33. if (mConnected)
  34. {
  35. retval = (CloseHandle(mHandle) == TRUE && CloseHandle(mEvent) == TRUE);
  36. mConnected = false;
  37. }
  38. return retval;
  39. }
  40. bool cHIDDevice::Connect(unsigned short device_id, unsigned short vendor_id, int index)
  41. {
  42. if (mConnected)
  43. {
  44. if (!Disconnect())
  45. {
  46. return false;
  47. }
  48. }
  49. // Find the wiimote(s)
  50. //for (int i = 0; i <= index; i++)
  51. OpenDevice( device_id, vendor_id, index );
  52. return mConnected;
  53. }
  54. bool cHIDDevice::OpenDevice(unsigned short device_id, unsigned short vendor_id, int index)
  55. {
  56. //Use a series of API calls to find a HID with a specified Vendor IF and Product ID.
  57. HIDD_ATTRIBUTES Attributes;
  58. SP_DEVICE_INTERFACE_DATA devInfoData;
  59. bool LastDevice = FALSE;
  60. bool MyDeviceDetected = FALSE;
  61. int MemberIndex = 0;
  62. int MembersFound = 0;
  63. GUID HidGuid;
  64. ULONG Length;
  65. LONG Result;
  66. HANDLE hDevInfo;
  67. ULONG Required;
  68. Length = 0;
  69. detailData = NULL;
  70. mHandle=NULL;
  71. HidD_GetHidGuid(&HidGuid);
  72. hDevInfo=SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
  73. devInfoData.cbSize = sizeof(devInfoData);
  74. MemberIndex = 0;
  75. MembersFound = 0;
  76. LastDevice = FALSE;
  77. do
  78. {
  79. Result=SetupDiEnumDeviceInterfaces(hDevInfo, 0, &HidGuid, MemberIndex, &devInfoData);
  80. if (Result != 0)
  81. {
  82. Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, NULL, 0, &Length, NULL);
  83. detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
  84. detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  85. Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, detailData, Length, &Required, NULL);
  86. mHandle=CreateFile(detailData->DevicePath, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING, 0, NULL);
  87. Attributes.Size = sizeof(Attributes);
  88. Result = HidD_GetAttributes(mHandle, &Attributes);
  89. //Is it the desired device?
  90. MyDeviceDetected = FALSE;
  91. if (Attributes.VendorID == vendor_id)
  92. {
  93. if (Attributes.ProductID == device_id)
  94. {
  95. if (MembersFound == index)
  96. {
  97. //Both the Vendor ID and Product ID match.
  98. //printf("Wiimote found!\n");
  99. mConnected = true;
  100. GetCapabilities();
  101. WriteHandle=CreateFile(detailData->DevicePath, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL);
  102. MyDeviceDetected = TRUE;
  103. PrepareForOverlappedTransfer();
  104. mEvent = CreateEvent(NULL, TRUE, TRUE, "");
  105. mOverlapped.Offset = 0;
  106. mOverlapped.OffsetHigh = 0;
  107. mOverlapped.hEvent = mEvent;
  108. } else {
  109. //The Product ID doesn't match.
  110. CloseHandle(mHandle);
  111. }
  112. MembersFound++;
  113. }
  114. } else {
  115. CloseHandle(mHandle);
  116. }
  117. free(detailData);
  118. } else {
  119. LastDevice=TRUE;
  120. }
  121. MemberIndex = MemberIndex + 1;
  122. } while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
  123. SetupDiDestroyDeviceInfoList(hDevInfo);
  124. return MyDeviceDetected;
  125. }
  126. bool cHIDDevice::WriteToDevice(unsigned const char * OutputReport, int num_bytes)
  127. {
  128. bool retval = false;
  129. if (mConnected)
  130. {
  131. DWORD bytes_written;
  132. retval = (WriteFile( WriteHandle, OutputReport, num_bytes, &bytes_written, &mOverlapped) == TRUE);
  133. retval = retval && bytes_written == num_bytes;
  134. }
  135. return retval;
  136. }
  137. void cHIDDevice::PrepareForOverlappedTransfer()
  138. {
  139. //Get a handle to the device for the overlapped ReadFiles.
  140. ReadHandle=CreateFile(detailData->DevicePath, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
  141. }
  142. void cHIDDevice::GetCapabilities()
  143. {
  144. //Get the Capabilities structure for the device.
  145. PHIDP_PREPARSED_DATA PreparsedData;
  146. HidD_GetPreparsedData(mHandle, &PreparsedData);
  147. HidP_GetCaps(PreparsedData, &Capabilities);
  148. //No need for PreparsedData any more, so free the memory it's using.
  149. HidD_FreePreparsedData(PreparsedData);
  150. }
  151. bool cHIDDevice::ReadFromDevice(unsigned const char * buffer, int max_bytes, int & bytes_read, int timeout)
  152. {
  153. bool retval = false;
  154. if (mConnected)
  155. {
  156. ReadFile( ReadHandle, (LPVOID)buffer,max_bytes,(LPDWORD)&bytes_read,(LPOVERLAPPED) &mOverlapped);
  157. DWORD Result = WaitForSingleObject(mEvent, timeout);
  158. if (Result == WAIT_OBJECT_0)
  159. {
  160. retval = true;
  161. }
  162. else
  163. {
  164. CancelIo(mHandle);
  165. }
  166. ResetEvent(mEvent);
  167. }
  168. return retval;
  169. }
  170. #endif