PageRenderTime 35ms CodeModel.GetById 12ms app.highlight 19ms RepoModel.GetById 2ms app.codeStats 0ms

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