Beispiel #1
0
int prHIDDequeueElement(VMGlobals *g, int numArgsPushed)
{

	PyrSlot *a = g->sp - 2; //class
	PyrSlot *b = g->sp - 1; //locID device
	PyrSlot *c = g->sp; //element cookie
	int locID, cookieNum;
	int err = slotIntVal(b, &locID);
	if (err) return err;
	err = slotIntVal(c, &cookieNum);
	if (err) return err;
	IOHIDElementCookie cookie = (IOHIDElementCookie) cookieNum;
	//look for the right device:
    pRecDevice  pCurrentHIDDevice = HIDGetFirstDevice ();
	while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID))
        pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice);
	if(!pCurrentHIDDevice) return errFailed;
	//look for the right element:
	pRecElement pCurrentHIDElement =  HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeAll);
    while (pCurrentHIDElement && (pCurrentHIDElement->cookie != cookie))
        pCurrentHIDElement = HIDGetNextDeviceElement (pCurrentHIDElement, kHIDElementTypeAll);
	if(!pCurrentHIDElement) return errFailed;
	HIDDequeueElement(pCurrentHIDDevice, pCurrentHIDElement);
	return errNone;
}
/* 
    PsychHIDGetDeviceRecordPtrFromIndex()
    
    The inverse of PsychHIDGetIndexFromRecord()
    
    Accept the index from the list of device records and return a pointer to the indicated record.  Externally the list is one-indexed.  
*/
pRecDevice PsychHIDGetDeviceRecordPtrFromIndex(int deviceIndex)
{
    int				i;
    pRecDevice 		currentDevice=NULL;

    PsychHIDVerifyInit();
    i=1;
    for(currentDevice=HIDGetFirstDevice(); currentDevice != NULL; currentDevice=HIDGetNextDevice(currentDevice)){    
        if(i==deviceIndex) {
            #if PSYCH_SYSTEM != PSYCH_OSX
                if (!currentDevice->interface) {
                    currentDevice->interface = (void*) hid_open_path(currentDevice->transport);
                    if (!currentDevice->interface) PsychErrorExitMsg(PsychError_system, "HIDLIB Failed to open USB device!");

                    // Set read ops on device to non-blocking:
                    hid_set_nonblocking((hid_device*) currentDevice->interface, 1);
                }
            #endif
            return(currentDevice);
        }
        ++i;
    }
    
    PsychErrorExitMsg(PsychError_user, "Invalid device index specified. Has a device been unplugged? Try rebuilding the device list");
    return(NULL);  //make the compiler happy.
}
Beispiel #3
0
int prHIDGetValue(VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 2; //class
	PyrSlot *b = g->sp - 1; //locID device
	PyrSlot *c = g->sp; //element cookie
	int locID, cookieNum;
	int err = slotIntVal(b, &locID);
	if (err) return err;
	err = slotIntVal(c, &cookieNum);
	if (err) return err;
	IOHIDElementCookie cookie = (IOHIDElementCookie) cookieNum;
	//look for the right device:
    pRecDevice  pCurrentHIDDevice = HIDGetFirstDevice ();
	while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID))
        pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice);
	if(!pCurrentHIDDevice) return errFailed;
	//look for the right element:
	pRecElement pCurrentHIDElement =  HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeAll);
	// use gElementCookie to find current element
    while (pCurrentHIDElement && (pCurrentHIDElement->cookie != cookie))
        pCurrentHIDElement = HIDGetNextDeviceElement (pCurrentHIDElement, kHIDElementTypeAll);

	if (pCurrentHIDElement)
    {
		SInt32 value = HIDGetElementValue (pCurrentHIDDevice, pCurrentHIDElement);
		 // if it's not a button and it's not a hatswitch then calibrate
		if(( pCurrentHIDElement->type != kIOHIDElementTypeInput_Button ) &&
			( pCurrentHIDElement->usagePage == 0x01 && pCurrentHIDElement->usage != kHIDUsage_GD_Hatswitch))
			value = HIDCalibrateValue ( value, pCurrentHIDElement );
		SetInt(a, value);
	}
	else SetNil(a);
	return errNone;

}
Beispiel #4
0
int prHIDBuildElementList(VMGlobals *g, int numArgsPushed)
{

	PyrSlot *a = g->sp - 2; //class
	PyrSlot *b = g->sp - 1; //locID device
	PyrSlot *c = g->sp; //array

	int locID;
	int err = slotIntVal(b, &locID);
	if (err) return err;
	//look for the right device:
    pRecDevice  pCurrentHIDDevice = HIDGetFirstDevice ();
	while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID))
        pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice);
	if(!pCurrentHIDDevice) return errFailed;

	pRecElement	devElement =  HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeAll );
	UInt32 numElements = HIDCountDeviceElements (pCurrentHIDDevice, kHIDElementTypeAll );

//		PyrObject* devAllElementsArray = newPyrArray(g->gc, numElements * sizeof(PyrObject), 0 , true);
		PyrObject *devAllElementsArray = c->uo;
//		post("numElements: %d\n", numElements);
		numElements = sc_clip(numElements, 0, devAllElementsArray->size);
		for(uint i=0; i<numElements; i++){
			if(devElement){
				char cstrElementName [256];
				PyrObject* devElementArray = newPyrArray(g->gc, 8 * sizeof(PyrObject), 0 , true);
				// type name (1)
				HIDGetTypeName((IOHIDElementType) devElement->type, cstrElementName);
				PyrString *devstring = newPyrString(g->gc, cstrElementName, 0, true);
				SetObject(devElementArray->slots+devElementArray->size++, devstring);
				//g->gc->GCWrite(devElementArray, (PyrObject*) devstring);
				//usage (2)
				HIDGetUsageName (devElement->usagePage, devElement->usage, cstrElementName);
				PyrString *usestring = newPyrString(g->gc, cstrElementName, 0, true);
				SetObject(devElementArray->slots+devElementArray->size++, usestring);
				//g->gc->GCWrite(devElementArray, (PyrObject*) usestring);
				//cookie (3)
				SetInt(devElementArray->slots+devElementArray->size++, (long) devElement->cookie);
				// min (4)
				SetInt(devElementArray->slots+devElementArray->size++, (long) devElement->min);
				// max (5)
				SetInt(devElementArray->slots+devElementArray->size++, (long) devElement->max);

				// IO type as int: (6)
				SetInt(devElementArray->slots+devElementArray->size++, (int) devElement->type);
				// Usage page as int: (7)
				SetInt(devElementArray->slots+devElementArray->size++, (long) devElement->usagePage);
				// Usage type as int: (8)
				SetInt(devElementArray->slots+devElementArray->size++, (long) devElement->usage);

				SetObject(devAllElementsArray->slots+i, devElementArray);
				//g->gc->GCWrite(devAllElementsArray, (PyrObject*) devElementArray);
			}
			devElement =  HIDGetNextDeviceElement (devElement, kHIDElementTypeAll);
		}
	SetObject(a, devAllElementsArray);
	return errNone;

}
Beispiel #5
0
void PushQueueEvents_CalibratedValue (){

	IOHIDEventStruct event;
	pRecDevice  pCurrentHIDDevice = HIDGetFirstDevice ();

	int numdevs = gNumberOfHIDDevices;
	unsigned char result;
	for(int i=0; i< numdevs; i++){

		result = HIDGetEvent(pCurrentHIDDevice, (void*) &event);
		if(result && compiledOK) {
			SInt32 value = event.value;
			int vendorID = pCurrentHIDDevice->vendorID;
			int productID = pCurrentHIDDevice->productID;
			int locID = pCurrentHIDDevice->locID;
			IOHIDElementCookie cookie = (IOHIDElementCookie) event.elementCookie;
			pRecElement pCurrentHIDElement =  HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeAll);
	// use gElementCookie to find current element
			while (pCurrentHIDElement && ( (pCurrentHIDElement->cookie) != cookie))
			pCurrentHIDElement = HIDGetNextDeviceElement (pCurrentHIDElement, kHIDElementTypeAll);

			if (pCurrentHIDElement)
			{
			value = HIDCalibrateValue(value, pCurrentHIDElement);
			//find element to calibrate
			VMGlobals *g = gMainVMGlobals;
			pthread_mutex_lock (&gLangMutex);
			g->canCallOS = false; // cannot call the OS
			++g->sp; SetObject(g->sp, s_hid->u.classobj); // Set the class HIDService
			//set arguments:
			++g->sp;SetInt(g->sp, vendorID);
			++g->sp;SetInt(g->sp, productID);
			++g->sp;SetInt(g->sp, locID);
			++g->sp;SetInt(g->sp, (int) cookie);
			++g->sp;SetInt(g->sp, value);
			runInterpreter(g, s_hidAction, 6);
			g->canCallOS = false; // cannot call the OS
			pthread_mutex_unlock (&gLangMutex);
			}
		}
	/* FIXME: this does not seem to be working!
		if ( !HIDIsValidDevice(pCurrentHIDDevice) )
		{ // readError
		 post("HID: read Error\n");
			int locID = pCurrentHIDDevice->locID;
			VMGlobals *g = gMainVMGlobals;
			pthread_mutex_lock (&gLangMutex);
			g->canCallOS = false; // cannot call the OS
			++g->sp; SetObject(g->sp, s_hid->u.classobj); // Set the class HIDService
			++g->sp;SetInt(g->sp, locID);
			runInterpreter(g, s_readError, 2);
			g->canCallOS = false; // cannot call the OS
			pthread_mutex_unlock (&gLangMutex);
		}*/
	pCurrentHIDDevice = HIDGetNextDevice(pCurrentHIDDevice);
	}
}
Beispiel #6
0
int prHIDSetValue(VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 3; //class
	PyrSlot *b = g->sp - 2; //locID
	PyrSlot *c = g->sp - 1; //element device
	PyrSlot *d = g->sp; //value cookie
	int locID, cookieNum, value;
	int err = slotIntVal(b, &locID);
	if (err) return err;
	err = slotIntVal(c, &cookieNum);
	if (err) return err;
	IOHIDElementCookie cookie = (IOHIDElementCookie) cookieNum;
	err = slotIntVal(d, &value);
	if (err) return err;
	//look for the right device:
    pRecDevice  pCurrentHIDDevice = HIDGetFirstDevice ();
	while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID))
        pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice);
	if(!pCurrentHIDDevice) return errFailed;
	//look for the right element:
	pRecElement pCurrentHIDElement =  HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeAll);
	// use gElementCookie to find current element
    while (pCurrentHIDElement && (pCurrentHIDElement->cookie != cookie))
        pCurrentHIDElement = HIDGetNextDeviceElement (pCurrentHIDElement, kHIDElementTypeAll);
//struct IOHIDEventStruct
//{
//    IOHIDElementType	type;
//    IOHIDElementCookie	elementCookie;
//    SInt32		value;
//    AbsoluteTime	timestamp;
//    UInt32		longValueSize;
//    void *		longValue;
//};

	if (pCurrentHIDElement)
    {
		IOHIDEventStruct event =
		{
			kIOHIDElementTypeOutput,
			pCurrentHIDElement->cookie,
			value,
			{0},
			sizeof(int),
			NULL
		};
		SInt32 value = HIDSetElementValue (pCurrentHIDDevice, pCurrentHIDElement, &event);
		 // if it's not a button and it's not a hatswitch then calibrate
	//	if(( pCurrentHIDElement->type != kIOHIDElementTypeInput_Button ) &&
	//		( pCurrentHIDElement->usagePage == 0x01 && pCurrentHIDElement->usage != kHIDUsage_GD_Hatswitch))
	//		value = HIDCalibrateValue ( value, pCurrentHIDElement );
		SetInt(a, value);
	}
	else SetNil(a);
	return errNone;

}
PsychError PSYCHHIDGetDevices(void) 
{
    pRecDevice 			currentDevice=NULL;
    
    const char *deviceFieldNames[]={"usagePageValue", "usageValue", "usageName", "index", "transport", "vendorID", "productID", "version", 
                                    "manufacturer", "product", "serialNumber", "locationID", "totalElements", "features", "inputs", 
                                    "outputs", "collections", "axes", "buttons", "hats", "sliders", "dials", "wheels"};
    int numDeviceStructElements, numDeviceStructFieldNames=23, deviceIndex;
    PsychGenericScriptType	*deviceStruct;		
    char usageName[PSYCH_HID_MAX_DEVICE_ELEMENT_USAGE_NAME_LENGTH];


    PsychPushHelp(useString, synopsisString, seeAlsoString);
    if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};

    PsychErrorExit(PsychCapNumOutputArgs(1));
    PsychErrorExit(PsychCapNumInputArgs(0));
    PsychHIDVerifyInit();
    numDeviceStructElements=(int)HIDCountDevices();
    PsychAllocOutStructArray(1, FALSE, numDeviceStructElements, numDeviceStructFieldNames, deviceFieldNames, &deviceStruct);
    deviceIndex=0;
    for(currentDevice=HIDGetFirstDevice(); currentDevice != NULL; currentDevice=HIDGetNextDevice(currentDevice)){
        PsychSetStructArrayDoubleElement("usagePageValue",	deviceIndex, 	(double)currentDevice->usagePage,	deviceStruct);
        PsychSetStructArrayDoubleElement("usageValue",		deviceIndex, 	(double)currentDevice->usage, 		deviceStruct);
        HIDGetUsageName (currentDevice->usagePage, currentDevice->usage, usageName);
        PsychSetStructArrayStringElement("usageName",		deviceIndex, 	usageName, 				deviceStruct);
        PsychSetStructArrayDoubleElement("index",		deviceIndex, 	(double)deviceIndex+1, 			deviceStruct);
        PsychSetStructArrayStringElement("transport",		deviceIndex, 	currentDevice->transport, 		deviceStruct);
        PsychSetStructArrayDoubleElement("vendorID",		deviceIndex, 	(double)currentDevice->vendorID, 	deviceStruct);
        PsychSetStructArrayDoubleElement("productID",		deviceIndex, 	(double)currentDevice->productID, 	deviceStruct);
        PsychSetStructArrayDoubleElement("version",		deviceIndex, 	(double)currentDevice->version, 	deviceStruct);
        PsychSetStructArrayStringElement("manufacturer",	deviceIndex, 	currentDevice->manufacturer, 		deviceStruct);
        PsychSetStructArrayStringElement("product",		deviceIndex, 	currentDevice->product, 		deviceStruct);
        PsychSetStructArrayStringElement("serialNumber",	deviceIndex, 	currentDevice->serial, 			deviceStruct);
        PsychSetStructArrayDoubleElement("locationID",		deviceIndex, 	(double)currentDevice->locID, 		deviceStruct);
        PsychSetStructArrayDoubleElement("totalElements",	deviceIndex, 	(double)currentDevice->totalElements, 	deviceStruct);
        PsychSetStructArrayDoubleElement("features",		deviceIndex, 	(double)currentDevice->features, 	deviceStruct);
        PsychSetStructArrayDoubleElement("inputs",		deviceIndex, 	(double)currentDevice->inputs, 		deviceStruct);
        PsychSetStructArrayDoubleElement("outputs",		deviceIndex, 	(double)currentDevice->outputs, 	deviceStruct);
        PsychSetStructArrayDoubleElement("collections",		deviceIndex, 	(double)currentDevice->collections, 	deviceStruct);
        PsychSetStructArrayDoubleElement("axes",		deviceIndex, 	(double)currentDevice->axis, 		deviceStruct);
        PsychSetStructArrayDoubleElement("buttons",		deviceIndex, 	(double)currentDevice->buttons, 	deviceStruct);
        PsychSetStructArrayDoubleElement("hats",		deviceIndex, 	(double)currentDevice->hats, 		deviceStruct);
        PsychSetStructArrayDoubleElement("sliders",		deviceIndex, 	(double)currentDevice->sliders, 	deviceStruct);
        PsychSetStructArrayDoubleElement("dials",		deviceIndex, 	(double)currentDevice->dials, 		deviceStruct);
        PsychSetStructArrayDoubleElement("wheels",		deviceIndex, 	(double)currentDevice->wheels, 		deviceStruct);
        ++deviceIndex; 
    }

    return(PsychError_none);	
}
// releases all device queues for quit or rebuild (must be called)
// does not release device interfaces, application must call ReleaseHIDDeviceList on exit
IOReturn HIDReleaseAllDeviceQueues( void )
{
	IOReturn result = kIOReturnSuccess;
	IOHIDDeviceRef tIOHIDDeviceRef = HIDGetFirstDevice();
	while ( tIOHIDDeviceRef ) {
		result = HIDDequeueDevice( tIOHIDDeviceRef );
		
		if ( kIOReturnSuccess != result ) {
			HIDReportErrorNum( "Could not dequeue device.", result );
		}
		tIOHIDDeviceRef = HIDGetNextDevice( tIOHIDDeviceRef );
	}
	return result;
} /* HIDReleaseAllDeviceQueues */
/* 
    PsychHIDGetDeviceRecordPtrFromIndex()
    
    The inverse of PsychHIDGetIndexFromRecord()
    
    Accept the index from the list of device records and return a pointer to the indicated record.  Externally the list is one-indexed.  
*/
pRecDevice PsychHIDGetDeviceRecordPtrFromIndex(int deviceIndex)
{
    int				i;
    pRecDevice 			currentDevice=NULL;

    PsychHIDVerifyInit();
    i=1;
    for(currentDevice=HIDGetFirstDevice(); currentDevice != NULL; currentDevice=HIDGetNextDevice(currentDevice)){    
        if(i==deviceIndex)
            return(currentDevice);
        ++i;
    }
    PsychErrorExitMsg(PsychError_internal, "Invalid device index specified.  Has a device has been unplugged? Try rebuilding the device list");
    return(NULL);  //make the compiler happy.
}
Beispiel #10
0
int prHIDGetElementListSize(VMGlobals *g, int numArgsPushed)
{
	PyrSlot *a = g->sp - 1; //class
	PyrSlot *b = g->sp; //locID device
	int locID;
	int err = slotIntVal(b, &locID);
	if (err) return err;
    pRecDevice  pCurrentHIDDevice = HIDGetFirstDevice ();
	while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID))
        pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice);
	if(!pCurrentHIDDevice) return errFailed;
	UInt32 numElements = HIDCountDeviceElements (pCurrentHIDDevice, kHIDElementTypeAll );
	SetInt(a, numElements);
	return errNone;
}
Beispiel #11
0
int prHIDDequeueDevice(VMGlobals *g, int numArgsPushed)
{

	PyrSlot *a = g->sp - 1; //class
	PyrSlot *b = g->sp; //locID device
	int locID;
	int err = slotIntVal(b, &locID);
	if (err) return err;
	//look for the right device:
    pRecDevice  pCurrentHIDDevice = HIDGetFirstDevice ();
	while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID))
        pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice);
	if(!pCurrentHIDDevice) return errFailed;
	HIDDequeueDevice(pCurrentHIDDevice);
	return errNone;
}
/*
    PsychHIDGetDeviceListByUsage()
    
    
*/ 
void PsychHIDGetDeviceListByUsage(long usagePage, long usage, int *numDeviceIndices, int *deviceIndices, pRecDevice *deviceRecords)
{
    pRecDevice 			currentDevice;
    int				currentDeviceIndex;

    PsychHIDVerifyInit();
    currentDeviceIndex=0;
    *numDeviceIndices=0;
    for(currentDevice=HIDGetFirstDevice(); currentDevice != NULL; currentDevice=HIDGetNextDevice(currentDevice)){    
        ++currentDeviceIndex;     
        if(currentDevice->usagePage==usagePage && currentDevice->usage==usage){
            deviceRecords[*numDeviceIndices]=currentDevice;
            deviceIndices[*numDeviceIndices]=currentDeviceIndex;  //the array is 0-indexed, devices are 1-indexed.   
            ++(*numDeviceIndices);
        }
    }
}
Beispiel #13
0
/*
    PsychHIDGetDeviceListByUsages()
 */
void PsychHIDGetDeviceListByUsages(int numUsages, long *usagePages, long *usages, int *numDeviceIndices, int *deviceIndices, pRecDevice *deviceRecords)
{
    pRecDevice currentDevice;
    int        currentDeviceIndex;
    int        currentUsage;
    long       *usagePage;
    long       *usage;

    PsychHIDVerifyInit();
    *numDeviceIndices = 0;
    for (usagePage = usagePages, usage = usages, currentUsage = 0; currentUsage < numUsages; usagePage++, usage++, currentUsage++) {
        currentDeviceIndex = 0;
        for (currentDevice = HIDGetFirstDevice(); currentDevice != NULL; currentDevice = HIDGetNextDevice(currentDevice)) {
            ++currentDeviceIndex;
            if (IOHIDDevice_GetPrimaryUsagePage(currentDevice) == *usagePage && IOHIDDevice_GetPrimaryUsage(currentDevice) == *usage) {
                deviceRecords[*numDeviceIndices] = currentDevice;
                deviceIndices[*numDeviceIndices] = currentDeviceIndex;  //the array is 0-indexed, devices are 1-indexed.
                ++(*numDeviceIndices);
            }
        }
    }
}
Beispiel #14
0
static Boolean SetupHIDInputs (void)
{
	UInt32	aUsage = 0;
	UInt32	aUsagePage = 0;
	pRecDevice pDevice = NULL;
   
	InitHIDInputArray ();
	HIDUpdateDeviceList(&aUsagePage, &aUsage, 1); // will do the right thing the first time
    pDevice = HIDGetFirstDevice(); // get the first device
	while(pDevice) {
		printf("Device: %s, %s.\n", pDevice->manufacturer, pDevice->product);
		// if the device has 4 axis try to use it
		if ((pDevice->axis >= 3) && (GetInputElements (pDevice))) // if we can find the axis needed use else continue
			break;
		pDevice = HIDGetNextDevice(pDevice); // check next device
	}
	if (pDevice) // means we found a valid device
	{
		printf("Using Device: %s, %s.\n", pDevice->manufacturer, pDevice->product);
		return true;
	}
	else
		return false;
}
Beispiel #15
0
unsigned char HIDConfigureAction (pRecDevice * ppDevice, pRecElement * ppElement, float timeout)
{
    unsigned long devices, maxElements = 0;
    long * saveValueArray;
    pRecDevice pDevice = NULL;
    pRecElement pElement = NULL;
    short deviceNum = 0;
    unsigned char found = 0, done = 0;
	clock_t start = clock (), end;
    unsigned long i;
    
     if (0 == HIDHaveDeviceList ())   // if we do not have a device list
		if (0 == HIDBuildDeviceList (0, 0)) // if we could not build anorther list (use generic usage and page)
			return 0; // return 0

    // build list of device and elements to save current values
    devices = HIDCountDevices ();
    pDevice = HIDGetFirstDevice ();
    while (pDevice)
    {
		if (HIDCountDeviceElements (pDevice, kHIDElementTypeIO) > maxElements)
			maxElements = HIDCountDeviceElements (pDevice, kHIDElementTypeIO);
		pDevice = HIDGetNextDevice (pDevice);
	}
	saveValueArray = (long *) malloc (sizeof (long) * devices * maxElements); // 2D array to save values
	for (i = 0; i < devices * maxElements; i++) // clear array
		*(saveValueArray + i) = 0x00000000;
		
	// store current values
	deviceNum = 0;
	pDevice = HIDGetFirstDevice ();
	while (pDevice)
	{
		short elementNum = 0;
		pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeIO);
		while (pElement)
		{
			*(saveValueArray + (deviceNum * maxElements) + elementNum) = HIDGetElementValue (pDevice, pElement);
			pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); 
			elementNum++;
		}
		pDevice = HIDGetNextDevice (pDevice);
		deviceNum++;
    }
    
    // poll all devices and elements, compare current value to save +/- kPercentMove
    while ((!found) && (!done))
    {
		double secs;
		// are we done?
		end = clock();
		secs = (double)(end - start) / CLOCKS_PER_SEC;
		if (secs > timeout)
			done = 1;
		deviceNum = 0;
		pDevice = HIDGetFirstDevice ();
		while (pDevice)
		{
			short elementNum = 0;
			pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeIO);
			while (pElement)
			{
				long initialValue = *(saveValueArray + (deviceNum * maxElements) + elementNum);
				long value = HIDGetElementValue (pDevice, pElement);
				long delta = (float)(pElement->max - pElement->min) * kPercentMove * 0.01;
				if (((initialValue + delta) < value) || ((initialValue - delta) > value))
				{
					found = 1;
					break;
				}
				pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); 
				elementNum++;
			}
			if (found)
				break;
			pDevice = HIDGetNextDevice (pDevice);
			deviceNum++;
		}
    }
    
    // return device and element moved
    if (found)
    {
		*ppDevice = pDevice;
		*ppElement = pElement;
		return 1;
    }
	else
	{
		*ppDevice = NULL;
		*ppElement = NULL;
		return 0;
	}
}
Beispiel #16
0
// Get matching element from config record
// takes a pre-allocated and filled out config record
// search for matching device
// return pDevice, pElement and cookie for action
long HIDGetElementConfig (pRecSaveHID pConfigRec, pRecDevice * ppDevice, pRecElement * ppElement)
{
	if (!pConfigRec->locID && !pConfigRec->vendorID && !pConfigRec->productID && !pConfigRec->usage && !pConfigRec->usagePage) { // early out
		*ppDevice = NULL;
		*ppElement = NULL;
		return pConfigRec->actionCookie;
	}

    pRecDevice pDevice, pFoundDevice = NULL;
    pRecElement pElement, pFoundElement = NULL;
     // compare to current device list for matches
    // look for device
    if (pConfigRec->locID && pConfigRec->vendorID && pConfigRec->productID)
    { // look for specific device type plug in to same port
		pDevice = HIDGetFirstDevice ();
		while (pDevice)
		{
			if ((pConfigRec->locID == pDevice->locID) &&
			(pConfigRec->vendorID == pDevice->vendorID) &&
			(pConfigRec->productID == pDevice->productID))
			pFoundDevice = pDevice;
			if (pFoundDevice)
				break;
			pDevice = HIDGetNextDevice (pDevice);
		}
		if (pFoundDevice)
		{
			pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
			while (pElement)
			{
				if (pConfigRec->cookie == pElement->cookie)
					pFoundElement = pElement;
				if (pFoundElement)
					break;
				pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); 
			}
			// if no cookie match (should NOT occur) match on usage
			pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
			while (pElement)
			{
				if ((pConfigRec->usageE == pElement->usage) &&
					(pConfigRec->usagePageE == pElement->usagePage))
					pFoundElement = pElement;
				if (pFoundElement)
					break;
				pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); 
			}
			if (pElement) {
				// set min and max values if same device
				pElement->minReport = pConfigRec->minReport;
				pElement->maxReport = pConfigRec->maxReport;
			}
		}
    }
    // if we have not found a match, look at just vendor and product
    if ((NULL == pFoundDevice) && (pConfigRec->vendorID && pConfigRec->productID))
    {
		pDevice = HIDGetFirstDevice ();
		while (pDevice)
		{
			if ((pConfigRec->vendorID == pDevice->vendorID) &&
			(pConfigRec->productID == pDevice->productID))
			pFoundDevice = pDevice;
			if (pFoundDevice)
			break;
			pDevice = HIDGetNextDevice (pDevice);
		}
		// match elements by cookie since same device type
		if (pFoundDevice)
		{
			pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
			while (pElement)
			{
				if (pConfigRec->cookie == pElement->cookie)
					pFoundElement = pElement;
				if (pFoundElement)
					break;
				pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); 
			}
			// if no cookie match (should NOT occur) match on usage
			pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
			while (pElement)
			{
				if ((pConfigRec->usageE == pElement->usage) &&
					(pConfigRec->usagePageE == pElement->usagePage))
					pFoundElement = pElement;
				if (pFoundElement)
					break;
				pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); 
			}
			if (pElement) {
				// set min and max values if same device
				pElement->minReport = pConfigRec->minReport;
				pElement->maxReport = pConfigRec->maxReport;
				
			}
		}
    }
	// can't find matching device return NULL, do not return first device
    if ((NULL == pFoundDevice) || (NULL == pFoundElement))
    {
		// no HID device
		*ppDevice = NULL;
		*ppElement = NULL;
		return pConfigRec->actionCookie;
    }
    else
    {
		// HID device
		*ppDevice = pFoundDevice;
		*ppElement = pFoundElement;
		return pConfigRec->actionCookie;
    }
}
/*
    PsychHIDGetDeviceListByUsage()
*/ 
void PsychHIDGetDeviceListByUsage(long usagePage, long usage, int *numDeviceIndices, int *deviceIndices, pRecDevice *deviceRecords)
{
    pRecDevice 			currentDevice;
    int				currentDeviceIndex;

    PsychHIDVerifyInit();
    currentDeviceIndex=0;
    *numDeviceIndices=0;
    for(currentDevice=HIDGetFirstDevice(); currentDevice != NULL; currentDevice=HIDGetNextDevice(currentDevice)){    
        ++currentDeviceIndex;
#ifndef __LP64__        
        if(currentDevice->usagePage==usagePage && currentDevice->usage==usage){
#else
        if(IOHIDDevice_GetUsagePage(currentDevice) == usagePage && IOHIDDevice_GetUsage(currentDevice) == usage){
#endif
            deviceRecords[*numDeviceIndices]=currentDevice;
            deviceIndices[*numDeviceIndices]=currentDeviceIndex;  //the array is 0-indexed, devices are 1-indexed.   
            ++(*numDeviceIndices);
        }
    }
}
 
/*
    PsychHIDGetDeviceListByUsages()
 */ 
void PsychHIDGetDeviceListByUsages(int numUsages, long *usagePages, long *usages, int *numDeviceIndices, int *deviceIndices, pRecDevice *deviceRecords)
{
    pRecDevice 			currentDevice;
    int				currentDeviceIndex;
    int				currentUsage;
    long 			*usagePage;
    long			*usage;
	
    PsychHIDVerifyInit();
    *numDeviceIndices=0;
    for(usagePage=usagePages, usage=usages, currentUsage=0; currentUsage<numUsages; usagePage++, usage++, currentUsage++){
		currentDeviceIndex=0;
		for(currentDevice=HIDGetFirstDevice(); currentDevice != NULL; currentDevice=HIDGetNextDevice(currentDevice)){    
			++currentDeviceIndex;     
#ifndef __LP64__        
			if(currentDevice->usagePage==*usagePage && currentDevice->usage==*usage){
#else
            if(IOHIDDevice_GetPrimaryUsagePage(currentDevice) == *usagePage && IOHIDDevice_GetPrimaryUsage(currentDevice) == *usage){
#endif
				deviceRecords[*numDeviceIndices]=currentDevice;
				deviceIndices[*numDeviceIndices]=currentDeviceIndex;  //the array is 0-indexed, devices are 1-indexed.   
				++(*numDeviceIndices);
			}
		}
	}
}


/*
    PsychHIDGetIndexFromRecord()
    
    The inverse of PsychHIDGetDeviceRecordPtrFromIndex. 
    
    This O(n) where n is the number of device elements.   We could make it O(1) if we modified
    the element structure in the HID Utilities library to include a field specifying the index of the element or 
    collection.
    
    Note that if PsychHIDGetIndexFromRecord() is O(n) then its caller, PsychHIDGetCollections, is O(n^2) for each
    device, whereas if PsychHIDGetIndexFromRecord() is O(1) then psychHIDGetCollections becomes O(n) for each 
    device.   
*/
int PsychHIDGetIndexFromRecord(pRecDevice deviceRecord, pRecElement elementRecord, HIDElementTypeMask typeMask)
{
    int 		elementIndex;
    pRecElement		currentElement;						
    
    if(elementRecord==NULL)
        return(0);
    elementIndex=1;
    for(currentElement=HIDGetFirstDeviceElement(deviceRecord, typeMask);
        currentElement != elementRecord && currentElement != NULL;
        currentElement=HIDGetNextDeviceElement(currentElement, typeMask))
        ++elementIndex;
    if(currentElement==elementRecord)
        return(elementIndex);
    else{
        PsychErrorExitMsg(PsychError_internal, "Element record not found within device record");
        return(0); //make the compiler happy
    }
}
long HIDRestoreElementConfig (FILE * fileRef, pRecDevice * ppDevice, pRecElement * ppElement)
{
    // Device: serial,vendorID, productID, location, usagePage, usage
    // Element: cookie, usagePage, usage,
    
    pRecDevice pDevice, pFoundDevice = NULL;
    pRecElement pElement, pFoundElement = NULL;
 
    recSaveHID restoreRec;
    
    fread ((void *) &restoreRec, 1, sizeof (recSaveHID), fileRef);

    // compare to current device list for matches
    // look for device
    if (restoreRec.locID && restoreRec.vendorID && restoreRec.productID)
	{ // look for specific device type plug in to same port
		pDevice = HIDGetFirstDevice ();
		while (pDevice)
		{
			if ((restoreRec.locID == pDevice->locID) &&
			(restoreRec.vendorID == pDevice->vendorID) &&
			(restoreRec.productID == pDevice->productID))
			pFoundDevice = pDevice;
			if (pFoundDevice)
				break;
			pDevice = HIDGetNextDevice (pDevice);
		}
		if (pFoundDevice)
		{
			pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
			while (pElement)
			{
				if (restoreRec.cookie == pElement->cookie)
					pFoundElement = pElement;
				if (pFoundElement)
					break;
				pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); 
			}
			// if no cookie match (should NOT occur) match on usage
			pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
			while (pElement)
			{
				if ((restoreRec.usageE == pElement->usage) &&
					(restoreRec.usagePageE == pElement->usagePage))
					pFoundElement = pElement;
				if (pFoundElement)
					break;
				pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); 
			}
		}
	}
    // if we have not found a match, look at just vendor and product
    if ((NULL == pFoundDevice) &&
	(restoreRec.vendorID && restoreRec.productID))
    {
		pDevice = HIDGetFirstDevice ();
		while (pDevice)
		{
			if ((restoreRec.vendorID == pDevice->vendorID) &&
			(restoreRec.productID == pDevice->productID))
			pFoundDevice = pDevice;
			if (pFoundDevice)
			break;
			pDevice = HIDGetNextDevice (pDevice);
		}
		// match elements by cookie since same device type
		if (pFoundDevice)
		{
			pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
			while (pElement)
			{
				if (restoreRec.cookie == pElement->cookie)
					pFoundElement = pElement;
				if (pFoundElement)
					break;
				pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); 
			}
			// if no cookie match (should NOT occur) match on usage
			pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
			while (pElement)
			{
				if ((restoreRec.usageE == pElement->usage) &&
					(restoreRec.usagePageE == pElement->usagePage))
					pFoundElement = pElement;
				if (pFoundElement)
					break;
				pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); 
			}
		}
    }
    // if we have not found a match look for just same type of device
    if ((NULL == pFoundDevice) && (restoreRec.usage && restoreRec.usagePage))
    {
		pDevice = HIDGetFirstDevice ();
		while (pDevice)
		{
			if ((restoreRec.usage == pDevice->usage) && (restoreRec.usagePage == pDevice->usagePage))
				pFoundDevice = pDevice;
			if (pFoundDevice)
				break;
			pDevice = HIDGetNextDevice (pDevice);
		}
		// match elements by type
		if (pFoundDevice)
		{
			pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
			while (pElement)
			{
				if ((restoreRec.usageE == pElement->usage) &&
					(restoreRec.usagePageE == pElement->usagePage))
					pFoundElement = pElement;
				if (pFoundElement)
					break;
				pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); 
			}
		}
    }
    // if still not found just get first device
    if (NULL == pFoundDevice)
    {
		pFoundDevice = HIDGetFirstDevice ();
		// match elements by type
		if (pFoundDevice)
		{
			pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO);
			while (pElement)
			{
				if ((restoreRec.usageE == pElement->usage) &&
					(restoreRec.usagePageE == pElement->usagePage))
					pFoundElement = pElement;
				if (pFoundElement)
					break;
				pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); 
			}
		}
    }
    if ((NULL == pFoundDevice) || (NULL == pFoundElement))
    {
		// no HID device
		*ppDevice = NULL;
		*ppElement = NULL;
		return restoreRec.actionCookie;
    }
    else
    {
		// no HID device
		*ppDevice = pFoundDevice;
		*ppElement = pFoundElement;
		return restoreRec.actionCookie;
    }
  
}
Beispiel #19
0
void Controller::Setup()
{
	#if defined(WIN32)
		ZeroMemory( &_currentControllerRawState, sizeof(XINPUT_STATE));
		
		_dwResult = XInputGetState(_controllerID, &_currentControllerRawState);
		
		if (_dwResult == ERROR_SUCCESS)
		{
			sysLog.Printf("Controller %d connected!", _controllerID+1);
			_connected = true;
		}
		else
		{
			sysLog.Printf("Controller %d not present...", _controllerID+1);
			ZeroMemory( &_currentControllerRawState, sizeof(XINPUT_STATE));
			_currentControllerInput.LeftThumbstickX = 
			_currentControllerInput.LeftThumbstickY =
			_currentControllerInput.RightThumbstickX =
			_currentControllerInput.RightThumbstickY = 
			_currentControllerInput.LeftTriggerValue = 
			_currentControllerInput.RightTriggerValue = 
			_currentControllerInput.Buttons = 0;
			_connected = false;
		}
	
	#elif defined(__APPLE__)
		unsigned long usagePage = 0;
		unsigned long usage = 0;
		if (!HIDHaveDeviceList())
		{	
			HIDBuildDeviceList(usagePage, usage);
		}
		
		_device = HIDGetFirstDevice();
		while (_device != NULL)
		{
			//is this device already taken by another controller? 
			bool breakIt = false;
			for (int i=0; i < MAX_CONTROLLERS; i++)
			{
				Controller* check = &theControllerManager.GetController(i);
				if ((check != this) && (check->_device == _device))
				{
					_device = HIDGetNextDevice(_device);
					if (_device == NULL)
					{
						breakIt = true;
					}
				}
			}
			if (breakIt)
			{
				break;
			}
			
			std::string manufacturer = _device->manufacturer;
			std::string product = _device->product;
			if (manufacturer.length() > 0)
				manufacturer = manufacturer.substr(1, manufacturer.length()-1).c_str(); //trimming off the initial copyright symbol so matching won't be dumb
			if (
				((manufacturer == "Microsoft Corporation") && (product == "Controller"))
				|| ((manufacturer == "icrosoft") && (product == "Wireless 360 Controller"))
				)
			{
				sysLog.Printf("Controller %d connected!", _controllerID+1);
				_connected = true;
				break;
			}
			
			_device = HIDGetNextDevice(_device);
		}
		if (_device == NULL)
		{
			sysLog.Printf("Controller %d not present...", _controllerID+1);
			_connected = false;
		}
		else
		{
			pRecElement current_element = HIDGetFirstDeviceElement(_device, kHIDElementTypeIO);
			while (current_element != NULL)
			{
				_elements[(unsigned int)current_element->cookie] = current_element;
				current_element = HIDGetNextDeviceElement(current_element, kHIDElementTypeIO);
			}
		}
	#elif defined(__linux__)
		_currentControllerInput.LeftThumbstickX = 
		_currentControllerInput.LeftThumbstickY =
		_currentControllerInput.RightThumbstickX =
		_currentControllerInput.RightThumbstickY = 
		_currentControllerInput.LeftTriggerValue = 
		_currentControllerInput.RightTriggerValue = 
		_currentControllerInput.Buttons = 0;
		char* devicePath;
		if (_controllerID == 0)
			devicePath = LINUX_CONTROLLER_1_PATH;
		else
			devicePath = LINUX_CONTROLLER_2_PATH;

		_deviceFD = open(devicePath, O_RDONLY | O_NONBLOCK);
		if (_deviceFD < 0)
		{
			sysLog.Printf("Controller %d not present...", _controllerID+1);
			_connected = false;
		}
		else
		{
			sysLog.Printf("Controller %d connected!", _controllerID+1);
			_connected = true;
		}

		// Discover the force feedback device.
		bool foundFirstController = false;
		_ffFD = -1;
		for (int i = 0; i < MAX_LINUX_EVENT_INTERFACES; i++)
		{
			std::stringstream ss;
			ss << i;
			String eventDev = LINUX_EVENT_INTERFACE + ss.str();
			int fd = open(eventDev.c_str(), O_RDWR);
			if (fd >= 0)
		 	{
				char name[256] = "Unknown";
				ioctl(fd, EVIOCGNAME(sizeof(name)), name);
				if (strcmp(name, "Microsoft X-Box 360 pad") == 0)
				{
					if (_controllerID == 0)
					{
						_ffFD = fd;
						break;
					}
					else
					{
						if (foundFirstController)
						{
							_ffFD = fd;
							break;
						}
						else
						{
							foundFirstController = true;
							close(fd);
						}
					}
				}
				else
				{
					close(fd);
				}
			}
		}
		if (_ffFD < 0)
		{
			sysLog.Printf("Error opening Force Feedback device for controller %d!", _controllerID+1);
		}
		else
		{
			_ffEffect.type = FF_RUMBLE;
			_ffEffect.id = -1;
			_ffEffect.u.rumble.strong_magnitude = 0;
			_ffEffect.u.rumble.weak_magnitude = 0;
			_ffEffect.replay.length = 0x7fff;
			_ffEffect.replay.delay = 0;
			_ffPlay.type = EV_FF;
			_ffPlay.value = 1;
		}
	#endif
}
Beispiel #20
0
int prHIDBuildDeviceList(VMGlobals *g, int numArgsPushed)
{
	//build a device list
	PyrSlot *a = g->sp - 2;
	PyrSlot *b = g->sp - 1; //usagePage
	PyrSlot *c = g->sp;		//usage

	int usagePage, usage, err;
	if(IsNil(b))
		usagePage = 0;
	else
	{
		err = slotIntVal(b, &usagePage);
		if (err) return err;
	}
	if(IsNil(c))
		usage = 0;
	else
	{
		err = slotIntVal(c, &usage);
		if (err) return err;
	}

	//pass in usage & usagepage
	//kHIDUsage_GD_Joystick kHIDUsage_GD_GamePad
	//UInt32 usagePage = kHIDPage_GenericDesktop;
	//UInt32 usage = NULL;

	Boolean result = HIDBuildDeviceList (usagePage, usage);
	// returns false if no device found (ignored in this case) - returns always false ?

	if(result) post("no HID devices found\n");

	int numdevs = HIDCountDevices();
	gNumberOfHIDDevices = numdevs;
	if(!numdevs){
		SetNil(a);
		return errNone;
	}
	//post("number of devices: %d", numdevs);
	char cstrDeviceName [256];

    pRecDevice  pCurrentHIDDevice = HIDGetFirstDevice ();
	PyrObject* allDevsArray = newPyrArray(g->gc, numdevs * sizeof(PyrObject), 0 , true);
	for(int i=0; i<numdevs; i++){
		//device:
		PyrObject* devNameArray = newPyrArray(g->gc, 8 * sizeof(PyrObject), 0 , true);
		//manufacturer:
		PyrString *devstring = newPyrString(g->gc, pCurrentHIDDevice->manufacturer, 0, true);
		SetObject(devNameArray->slots+devNameArray->size++, devstring);
		g->gc->GCWrite(devNameArray, (PyrObject*) devstring);
		//product name:
		devstring = newPyrString(g->gc, pCurrentHIDDevice->product, 0, true);
		SetObject(devNameArray->slots+devNameArray->size++, devstring);
		g->gc->GCWrite(devNameArray, (PyrObject*) devstring);
		//usage
		HIDGetUsageName (pCurrentHIDDevice->usagePage, pCurrentHIDDevice->usage, cstrDeviceName);
		devstring = newPyrString(g->gc, cstrDeviceName, 0, true);
		SetObject(devNameArray->slots+devNameArray->size++, devstring);
		g->gc->GCWrite(devNameArray, (PyrObject*) devstring);
		//vendor id
		SetInt(devNameArray->slots+devNameArray->size++, pCurrentHIDDevice->vendorID);
		//product id
		SetInt(devNameArray->slots+devNameArray->size++, pCurrentHIDDevice->productID);
		//locID
		SetInt(devNameArray->slots+devNameArray->size++, pCurrentHIDDevice->locID);

		//version
		SetInt(devNameArray->slots+devNameArray->size++, pCurrentHIDDevice->version);

		//serial
		devstring = newPyrString(g->gc, pCurrentHIDDevice->serial, 0, true);
		SetObject(devNameArray->slots+devNameArray->size++, devstring);
		g->gc->GCWrite(devNameArray, (PyrObject*) devstring);

		SetObject(allDevsArray->slots+allDevsArray->size++, devNameArray);
		g->gc->GCWrite(allDevsArray, (PyrObject*) devNameArray);
		pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice);

	}

	//UInt32 outnum =  HIDCountDeviceElements (pCurrentHIDDevice, kHIDElementTypeOutput);
	//post("number of outputs: %d \n", outnum);
	SetObject(a, allDevsArray);

	return errNone;
}