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); }
PsychError PSYCHHIDGetNumDevices(void) { psych_uint32 numDevices; PsychPushHelp(useString, synopsisString, seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; PsychErrorExit(PsychCapNumOutputArgs(1)); PsychErrorExit(PsychCapNumInputArgs(0)); PsychHIDVerifyInit(); numDevices=HIDCountDevices(); PsychCopyOutDoubleArg(1, FALSE, (double)numDevices); return(PsychError_none); }
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; } }
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; }