/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
- #include "OISConfig.h"
- #ifdef OIS_WIN32_WIIMOTE_SUPPORT
- //cWiimote 0.2 by Kevin Forbes (http://simulatedcomicproduct.com)
- //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.
- //This was based in part on Alan Macek <www.alanmacek.com>'s USB interface library
-
- //Edited for Toshiba Stack support (hopefully also all others) by
- //Sean Stellingwerff (http://sean.stellingwerff.com) using information
- //gathered from http://www.lvr.com/hidpage.htm (Thanks a million! :D)
-
- //#include "stdafx.h"
- #include "hiddevice.h"
-
- extern "C"
- {
- #include "hidsdi.h"
- #include <Setupapi.h>
- }
- #pragma comment(lib, "setupapi.lib")
- #pragma comment(lib, "hid.lib")
-
- HIDP_CAPS Capabilities;
- PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;
-
- cHIDDevice::cHIDDevice() : mConnected(false), mHandle(NULL), mEvent(NULL)
- {
- }
-
-
- cHIDDevice::~cHIDDevice()
- {
- if (mConnected)
- {
- Disconnect();
- }
- }
-
- bool cHIDDevice::Disconnect()
- {
- bool retval = false;
- if (mConnected)
- {
- retval = (CloseHandle(mHandle) == TRUE && CloseHandle(mEvent) == TRUE);
-
- mConnected = false;
- }
-
- return retval;
- }
-
- bool cHIDDevice::Connect(unsigned short device_id, unsigned short vendor_id, int index)
- {
- if (mConnected)
- {
- if (!Disconnect())
- {
- return false;
- }
- }
-
- // Find the wiimote(s)
- //for (int i = 0; i <= index; i++)
- OpenDevice( device_id, vendor_id, index );
-
- return mConnected;
- }
-
- bool cHIDDevice::OpenDevice(unsigned short device_id, unsigned short vendor_id, int index)
- {
- //Use a series of API calls to find a HID with a specified Vendor IF and Product ID.
- HIDD_ATTRIBUTES Attributes;
- SP_DEVICE_INTERFACE_DATA devInfoData;
- bool LastDevice = FALSE;
- bool MyDeviceDetected = FALSE;
- int MemberIndex = 0;
- int MembersFound = 0;
- GUID HidGuid;
- ULONG Length;
- LONG Result;
- HANDLE hDevInfo;
- ULONG Required;
-
- Length = 0;
- detailData = NULL;
- mHandle=NULL;
-
- HidD_GetHidGuid(&HidGuid);
- hDevInfo=SetupDiGetClassDevs(&HidGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
-
- devInfoData.cbSize = sizeof(devInfoData);
-
- MemberIndex = 0;
- MembersFound = 0;
- LastDevice = FALSE;
-
- do
- {
- Result=SetupDiEnumDeviceInterfaces(hDevInfo, 0, &HidGuid, MemberIndex, &devInfoData);
- if (Result != 0)
- {
- Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, NULL, 0, &Length, NULL);
-
- detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
- detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
- Result = SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInfoData, detailData, Length, &Required, NULL);
-
- mHandle=CreateFile(detailData->DevicePath, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING, 0, NULL);
- Attributes.Size = sizeof(Attributes);
-
- Result = HidD_GetAttributes(mHandle, &Attributes);
- //Is it the desired device?
-
- MyDeviceDetected = FALSE;
-
- if (Attributes.VendorID == vendor_id)
- {
- if (Attributes.ProductID == device_id)
- {
- if (MembersFound == index)
- {
- //Both the Vendor ID and Product ID match.
- //printf("Wiimote found!\n");
- mConnected = true;
- GetCapabilities();
-
- WriteHandle=CreateFile(detailData->DevicePath, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL);
- MyDeviceDetected = TRUE;
-
- PrepareForOverlappedTransfer();
-
- mEvent = CreateEvent(NULL, TRUE, TRUE, "");
- mOverlapped.Offset = 0;
- mOverlapped.OffsetHigh = 0;
- mOverlapped.hEvent = mEvent;
-
- } else {
- //The Product ID doesn't match.
- CloseHandle(mHandle);
- }
-
- MembersFound++;
- }
- } else {
- CloseHandle(mHandle);
- }
- free(detailData);
- } else {
- LastDevice=TRUE;
- }
- MemberIndex = MemberIndex + 1;
- } while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
-
- SetupDiDestroyDeviceInfoList(hDevInfo);
- return MyDeviceDetected;
- }
-
- bool cHIDDevice::WriteToDevice(unsigned const char * OutputReport, int num_bytes)
- {
- bool retval = false;
- if (mConnected)
- {
- DWORD bytes_written;
- retval = (WriteFile( WriteHandle, OutputReport, num_bytes, &bytes_written, &mOverlapped) == TRUE);
- retval = retval && bytes_written == num_bytes;
- }
- return retval;
- }
-
- void cHIDDevice::PrepareForOverlappedTransfer()
- {
- //Get a handle to the device for the overlapped ReadFiles.
- ReadHandle=CreateFile(detailData->DevicePath, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- }
-
- void cHIDDevice::GetCapabilities()
- {
- //Get the Capabilities structure for the device.
- PHIDP_PREPARSED_DATA PreparsedData;
- HidD_GetPreparsedData(mHandle, &PreparsedData);
- HidP_GetCaps(PreparsedData, &Capabilities);
-
- //No need for PreparsedData any more, so free the memory it's using.
- HidD_FreePreparsedData(PreparsedData);
- }
-
- bool cHIDDevice::ReadFromDevice(unsigned const char * buffer, int max_bytes, int & bytes_read, int timeout)
- {
- bool retval = false;
- if (mConnected)
- {
- ReadFile( ReadHandle, (LPVOID)buffer,max_bytes,(LPDWORD)&bytes_read,(LPOVERLAPPED) &mOverlapped);
- DWORD Result = WaitForSingleObject(mEvent, timeout);
- if (Result == WAIT_OBJECT_0)
- {
- retval = true;
- }
- else
- {
- CancelIo(mHandle);
- }
- ResetEvent(mEvent);
- }
- return retval;
- }
- #endif