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; }
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 PSYCHHIDGetElements(void) { pRecDevice specDevice=NULL; UInt32 numDeviceElements; const char *elementFieldNames[]={"typeMaskName", "name", "deviceIndex", "elementIndex", "typeValue", "typeName", "usagePageValue", "usageValue", "usageName", "dataSize", "rangeMin", "rangeMax", "scaledRangeMin", "scaledRangeMax", "relative", "wrapping", "nonLinear", "preferredState", "nullState", "calMin", "calMax", "scalingMin", "scalingMax"}; int numElementStructElements, numElementStructFieldNames=23, elementIndex, deviceIndex; PsychGenericScriptType *elementStruct; pRecElement currentElement; char elementTypeName[PSYCH_HID_MAX_DEVICE_ELEMENT_TYPE_NAME_LENGTH]; char usageName[PSYCH_HID_MAX_DEVICE_ELEMENT_USAGE_NAME_LENGTH]; char *typeMaskName; HIDElementTypeMask typeMask; //all subfunctions should have these two lines PsychPushHelp(useString, synopsisString, seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; PsychErrorExit(PsychCapNumOutputArgs(1)); PsychErrorExit(PsychCapNumInputArgs(1)); PsychCopyInIntegerArg(1, TRUE, &deviceIndex); PsychHIDVerifyInit(); specDevice= PsychHIDGetDeviceRecordPtrFromIndex(deviceIndex); PsychHIDVerifyOpenDeviceInterfaceFromDeviceRecordPtr(specDevice); numDeviceElements= HIDCountDeviceElements(specDevice, kHIDElementTypeIO); numElementStructElements = (int)numDeviceElements; PsychAllocOutStructArray(1, FALSE, numElementStructElements, numElementStructFieldNames, elementFieldNames, &elementStruct); elementIndex=0; for(currentElement=HIDGetFirstDeviceElement(specDevice,kHIDElementTypeIO); currentElement != NULL; currentElement=HIDGetNextDeviceElement(currentElement, kHIDElementTypeIO)) { typeMask=HIDConvertElementTypeToMask (currentElement->type); PsychHIDGetTypeMaskStringFromTypeMask(typeMask, &typeMaskName); PsychSetStructArrayStringElement("typeMaskName", elementIndex, typeMaskName, elementStruct); PsychSetStructArrayStringElement("name", elementIndex, currentElement->name, elementStruct); PsychSetStructArrayDoubleElement("deviceIndex", elementIndex, (double)deviceIndex, elementStruct); PsychSetStructArrayDoubleElement("elementIndex", elementIndex, (double)elementIndex+1, elementStruct); PsychSetStructArrayDoubleElement("typeValue", elementIndex, (double)currentElement->type, elementStruct); HIDGetTypeName(currentElement->type, elementTypeName); PsychSetStructArrayStringElement("typeName", elementIndex, elementTypeName, elementStruct); PsychSetStructArrayDoubleElement("usagePageValue", elementIndex, (double)currentElement->usagePage, elementStruct); PsychSetStructArrayDoubleElement("usageValue", elementIndex, (double)currentElement->usage, elementStruct); HIDGetUsageName (currentElement->usagePage, currentElement->usage, usageName); PsychSetStructArrayStringElement("usageName", elementIndex, usageName, elementStruct); PsychSetStructArrayDoubleElement("dataSize", elementIndex, (double)currentElement->size, elementStruct); PsychSetStructArrayDoubleElement("rangeMin", elementIndex, (double)currentElement->min, elementStruct); PsychSetStructArrayDoubleElement("rangeMax", elementIndex, (double)currentElement->max, elementStruct); PsychSetStructArrayDoubleElement("scaledRangeMin", elementIndex, (double)currentElement->scaledMin, elementStruct); PsychSetStructArrayDoubleElement("scaledRangeMax", elementIndex, (double)currentElement->scaledMax, elementStruct); PsychSetStructArrayDoubleElement("relative", elementIndex, (double)currentElement->relative, elementStruct); //psych_bool flag PsychSetStructArrayDoubleElement("wrapping", elementIndex, (double)currentElement->wrapping, elementStruct); //psych_bool flag PsychSetStructArrayDoubleElement("nonLinear", elementIndex, (double)currentElement->nonLinear, elementStruct); //psych_bool flag PsychSetStructArrayDoubleElement("preferredState", elementIndex, (double)currentElement->preferredState, elementStruct); //psych_bool flag PsychSetStructArrayDoubleElement("nullState", elementIndex, (double)currentElement->nullState, elementStruct); //psych_bool flag PsychSetStructArrayDoubleElement("calMin", elementIndex, (double)currentElement->calMin, elementStruct); PsychSetStructArrayDoubleElement("calMax", elementIndex, (double)currentElement->calMax, elementStruct); PsychSetStructArrayDoubleElement("scalingMin", elementIndex, (double)currentElement->userMin, elementStruct); PsychSetStructArrayDoubleElement("scalingMax", elementIndex, (double)currentElement->userMax, elementStruct); ++elementIndex; } return(PsychError_none); }
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; }
PsychError PSYCHHIDGetCollections(void) { pRecDevice specDevice=NULL; UInt32 numDeviceElements; const char *elementFieldNames[]={"typeMaskName", "name", "deviceIndex", "collectionIndex", "typeValue", "typeName", "usagePageValue", "usageValue", "usageName", "memberCollectionIndices", "memberElementIndices"}; int i, numElementStructElements, numElementStructFieldNames=11, elementIndex, deviceIndex; PsychGenericScriptType *elementStruct, *memberCollectionIndicesMat, *memberIOElementIndicesMat; pRecElement currentElement; char elementTypeName[PSYCH_HID_MAX_DEVICE_ELEMENT_TYPE_NAME_LENGTH]; char usageName[PSYCH_HID_MAX_DEVICE_ELEMENT_USAGE_NAME_LENGTH]; char *typeMaskName; HIDElementTypeMask typeMask; pRecElement *memberCollectionRecords, *memberIOElementRecords; double *memberCollectionIndices, *memberIOElementIndices; int numSubCollections, numSubIOElements; PsychPushHelp(useString, synopsisString, seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; PsychErrorExit(PsychCapNumOutputArgs(1)); PsychErrorExit(PsychCapNumInputArgs(1)); PsychCopyInIntegerArg(1, TRUE, &deviceIndex); PsychHIDVerifyInit(); specDevice= PsychHIDGetDeviceRecordPtrFromIndex(deviceIndex); PsychHIDVerifyOpenDeviceInterfaceFromDeviceRecordPtr(specDevice); numDeviceElements= HIDCountDeviceElements(specDevice, kHIDElementTypeCollection); numElementStructElements = (int)numDeviceElements; PsychAllocOutStructArray(1, FALSE, numElementStructElements, numElementStructFieldNames, elementFieldNames, &elementStruct); elementIndex=0; for(currentElement=HIDGetFirstDeviceElement(specDevice,kHIDElementTypeCollection); currentElement != NULL; currentElement=HIDGetNextDeviceElement(currentElement, kHIDElementTypeCollection)) { typeMask=HIDConvertElementTypeToMask (currentElement->type); PsychHIDGetTypeMaskStringFromTypeMask(typeMask, &typeMaskName); PsychSetStructArrayStringElement("typeMaskName", elementIndex, typeMaskName, elementStruct); PsychSetStructArrayStringElement("name", elementIndex, currentElement->name, elementStruct); PsychSetStructArrayDoubleElement("deviceIndex", elementIndex, (double)deviceIndex, elementStruct); PsychSetStructArrayDoubleElement("collectionIndex", elementIndex, (double)elementIndex+1, elementStruct); PsychSetStructArrayDoubleElement("typeValue", elementIndex, (double)currentElement->type, elementStruct); HIDGetTypeName(currentElement->type, elementTypeName); PsychSetStructArrayStringElement("typeName", elementIndex, elementTypeName, elementStruct); PsychSetStructArrayDoubleElement("usagePageValue", elementIndex, (double)currentElement->usagePage, elementStruct); PsychSetStructArrayDoubleElement("usageValue", elementIndex, (double)currentElement->usage, elementStruct); HIDGetUsageName (currentElement->usagePage, currentElement->usage, usageName); PsychSetStructArrayStringElement("usageName", elementIndex, usageName, elementStruct); //find and return the indices of this collection's member collections and indices numSubCollections=PsychHIDCountCollectionElements(currentElement, kHIDElementTypeCollection); numSubIOElements=PsychHIDCountCollectionElements(currentElement, kHIDElementTypeIO); memberCollectionRecords=(pRecElement*)PsychMallocTemp(sizeof(pRecElement) * numSubCollections); memberIOElementRecords=(pRecElement*)PsychMallocTemp(sizeof(pRecElement) * numSubIOElements); PsychHIDFindCollectionElements(currentElement, kHIDElementTypeCollection, memberCollectionRecords, numSubCollections); PsychHIDFindCollectionElements(currentElement, kHIDElementTypeIO, memberIOElementRecords, numSubIOElements); memberCollectionIndices=NULL; PsychAllocateNativeDoubleMat(1, numSubCollections, 1, &memberCollectionIndices, &memberCollectionIndicesMat); memberIOElementIndices=NULL; PsychAllocateNativeDoubleMat(1, numSubIOElements, 1, &memberIOElementIndices, &memberIOElementIndicesMat); for(i=0;i<numSubCollections;i++) memberCollectionIndices[i]=PsychHIDGetIndexFromRecord(specDevice, memberCollectionRecords[i], kHIDElementTypeCollection); for(i=0;i<numSubIOElements;i++) memberIOElementIndices[i]=PsychHIDGetIndexFromRecord(specDevice, memberIOElementRecords[i], kHIDElementTypeIO); PsychFreeTemp(memberCollectionRecords); PsychFreeTemp(memberIOElementRecords); PsychSetStructArrayNativeElement("memberCollectionIndices", elementIndex, memberCollectionIndicesMat, elementStruct); PsychSetStructArrayNativeElement("memberElementIndices", elementIndex, memberIOElementIndicesMat, elementStruct); ++elementIndex; } return(PsychError_none); }