int PsychHIDReturnEventFromEventBuffer(int deviceIndex, int outArgIndex, double maxWaitTimeSecs) { unsigned int navail, j; PsychHIDEventRecord evt; PsychGenericScriptType *retevent; double* foo = NULL; PsychGenericScriptType *outMat; double *v; const char *FieldNames[] = { "Type", "Time", "Pressed", "Keycode", "CookedKey", "ButtonStates", "Motion", "X", "Y", "NormX", "NormY", "Valuators" }; if (deviceIndex < 0) deviceIndex = PsychHIDGetDefaultKbQueueDevice(); if (!hidEventBuffer[deviceIndex]) return(0); PsychLockMutex(&hidEventBufferMutex[deviceIndex]); navail = hidEventBufferWritePos[deviceIndex] - hidEventBufferReadPos[deviceIndex]; // If nothing available and we're asked to wait for something, then wait: if ((navail == 0) && (maxWaitTimeSecs > 0)) { // Wait for something: PsychTimedWaitCondition(&hidEventBufferCondition[deviceIndex], &hidEventBufferMutex[deviceIndex], maxWaitTimeSecs); // Recompute number of available events: navail = hidEventBufferWritePos[deviceIndex] - hidEventBufferReadPos[deviceIndex]; } // Check if anything available, copy it if so: if (navail) { memcpy(&evt, &(hidEventBuffer[deviceIndex][hidEventBufferReadPos[deviceIndex] % hidEventBufferCapacity[deviceIndex]]), sizeof(PsychHIDEventRecord)); hidEventBufferReadPos[deviceIndex]++; } PsychUnlockMutex(&hidEventBufferMutex[deviceIndex]); if (navail) { // Return event struct: switch (evt.type) { case 0: // Press/Release case 1: // Motion/Valuator change PsychAllocOutStructArray(outArgIndex, kPsychArgOptional, 1, 12, FieldNames, &retevent); break; case 2: // Touch begin case 3: // Touch update/move case 4: // Touch end case 5: // Touch sequence compromised marker. If this one shows up - with magic touch point // id 0xffffffff btw., then the user script knows the sequence was cut short / aborted // by some higher priority consumer, e.g., some global gesture recognizer. PsychAllocOutStructArray(outArgIndex, kPsychArgOptional, 1, 12, FieldNames, &retevent); break; default: PsychErrorExitMsg(PsychError_internal, "Unhandled keyboard queue event type!"); } PsychSetStructArrayDoubleElement("Type", 0, (double) evt.type, retevent); PsychSetStructArrayDoubleElement("Time", 0, evt.timestamp, retevent); PsychSetStructArrayDoubleElement("Pressed", 0, (double) (evt.status & (1 << 0)) ? 1 : 0, retevent); PsychSetStructArrayDoubleElement("Keycode", 0, (double) evt.rawEventCode, retevent); PsychSetStructArrayDoubleElement("CookedKey", 0, (double) evt.cookedEventCode, retevent); PsychSetStructArrayDoubleElement("ButtonStates", 0, (double) evt.buttonStates, retevent); PsychSetStructArrayDoubleElement("Motion", 0, (double) (evt.status & (1 << 1)) ? 1 : 0, retevent); PsychSetStructArrayDoubleElement("X", 0, (double) evt.X, retevent); PsychSetStructArrayDoubleElement("Y", 0, (double) evt.Y, retevent); PsychSetStructArrayDoubleElement("NormX", 0, (double) evt.normX, retevent); PsychSetStructArrayDoubleElement("NormY", 0, (double) evt.normY, retevent); // Copy out all valuators (including redundant (X,Y) again: PsychAllocateNativeDoubleMat(1, evt.numValuators, 1, &v, &outMat); for (j = 0; j < evt.numValuators; j++) *(v++) = (double) evt.valuators[j]; PsychSetStructArrayNativeElement("Valuators", 0, outMat, retevent); return(navail - 1); } else { // Return empty matrix: PsychCopyOutDoubleMatArg(outArgIndex, kPsychArgOptional, 0, 0, 0, foo); return(0); } }
/* PsychCopyFontRecordToNativeStruct() Accept an array of pointers to psych font structures and the lenght of the array. Allocate and fill a native font struct array for the outside scripting environment */ void PsychCopyFontRecordsToNativeStructArray(int numFonts, PsychFontStructType **fontStructs, PsychGenericScriptType **fontStructArray) { int i, arrayIndex; PsychFontStructPtrType fontElement; PsychGenericScriptType *styleNameList; Str255 styleName; //for the outer font struct int numFontFieldNames=10; const char *fontFieldNames[]={"number", "name", "QuickDrawName", "PostScriptName", "familyName", "styleCode", "styleNames", "file", "metrics", "locale" }; //for the metrics meta struct int numMetaMetricsFieldNames=2; const char *metaMetricsFieldNames[]={"verticalMetrics", "horizontalMetrics"}; PsychGenericScriptType *metaMetrics; //for the metrics structs int numMetricsFieldNames=13; const char *metricsFieldNames[]={"ascent", "descent", "leading", "avgAdvanceWidth", "minLeftSideBearing", "minRightSideBearing", "stemWidth","stemHeight","capHeight","xHeight","italicAngle","underlinePosition","underlineThickness" }; PsychGenericScriptType *horizontalMetrics, *verticalMetrics; //for locale int numLocaleFieldNames=5; const char *localeFieldNames[]={"language", "languageVariant", "region", "regionVariant", "fullName"}; PsychGenericScriptType *locale; //convert the linked list of font structures to a struct array for the scripting environment. PsychAllocOutStructArray(kPsychNoArgReturn, FALSE, numFonts, numFontFieldNames, fontFieldNames, fontStructArray); for(arrayIndex=0; arrayIndex<numFonts; ++arrayIndex){ fontElement=fontStructs[arrayIndex]; PsychSetStructArrayDoubleElement("number", arrayIndex, fontElement->fontNumber, *fontStructArray); PsychSetStructArrayStringElement("name", arrayIndex, (char*) fontElement->fontFMName, *fontStructArray); PsychSetStructArrayStringElement("QuickDrawName", arrayIndex, (char*) fontElement->fontFamilyQuickDrawName, *fontStructArray); PsychSetStructArrayStringElement("PostScriptName", arrayIndex, (char*) fontElement->fontPostScriptName, *fontStructArray); PsychSetStructArrayStringElement("familyName", arrayIndex, (char*) fontElement->fontFMFamilyName, *fontStructArray); //style PsychSetStructArrayDoubleElement("styleCode", arrayIndex, (double)fontElement->fontFMStyle, *fontStructArray); PsychAllocOutCellVector(kPsychNoArgReturn, FALSE, fontElement->fontFMNumStyles, &styleNameList); for(i=0;i<fontElement->fontFMNumStyles;i++){ PsychGetFMFontStyleNameFromIndex(i, fontElement->fontFMStyle, (char*) styleName, 255); PsychSetCellVectorStringElement(i, (const char*) styleName, styleNameList); } PsychSetStructArrayNativeElement("styleNames", arrayIndex, styleNameList, *fontStructArray); PsychSetStructArrayStringElement("file", arrayIndex, fontElement->fontFile, *fontStructArray); //metrics PsychAllocOutStructArray(kPsychNoArgReturn, FALSE, 1, numMetaMetricsFieldNames, metaMetricsFieldNames, &metaMetrics); PsychAllocOutStructArray(kPsychNoArgReturn, FALSE, 1, numMetricsFieldNames, metricsFieldNames, &horizontalMetrics); PsychAllocOutStructArray(kPsychNoArgReturn, FALSE, 1, numMetricsFieldNames, metricsFieldNames, &verticalMetrics); //horizontal PsychSetStructArrayDoubleElement("ascent", 0, fontElement->horizontalMetrics.ascent, horizontalMetrics); PsychSetStructArrayDoubleElement("descent", 0, fontElement->horizontalMetrics.descent, horizontalMetrics); PsychSetStructArrayDoubleElement("leading", 0, fontElement->horizontalMetrics.leading, horizontalMetrics); PsychSetStructArrayDoubleElement("avgAdvanceWidth", 0, fontElement->horizontalMetrics.avgAdvanceWidth, horizontalMetrics); PsychSetStructArrayDoubleElement("minLeftSideBearing", 0, fontElement->horizontalMetrics.minLeftSideBearing, horizontalMetrics); PsychSetStructArrayDoubleElement("minRightSideBearing", 0, fontElement->horizontalMetrics.minRightSideBearing, horizontalMetrics); PsychSetStructArrayDoubleElement("stemWidth", 0, fontElement->horizontalMetrics.stemWidth, horizontalMetrics); PsychSetStructArrayDoubleElement("stemHeight", 0, fontElement->horizontalMetrics.stemHeight, horizontalMetrics); PsychSetStructArrayDoubleElement("capHeight", 0, fontElement->horizontalMetrics.capHeight, horizontalMetrics); PsychSetStructArrayDoubleElement("xHeight", 0, fontElement->horizontalMetrics.xHeight, horizontalMetrics); PsychSetStructArrayDoubleElement("italicAngle", 0, fontElement->horizontalMetrics.italicAngle, horizontalMetrics); PsychSetStructArrayDoubleElement("underlinePosition", 0, fontElement->horizontalMetrics.underlinePosition, horizontalMetrics); PsychSetStructArrayDoubleElement("underlineThickness", 0, fontElement->horizontalMetrics.underlineThickness, horizontalMetrics); //vertical PsychSetStructArrayDoubleElement("ascent", 0, fontElement->verticalMetrics.ascent, verticalMetrics); PsychSetStructArrayDoubleElement("descent", 0, fontElement->verticalMetrics.descent, verticalMetrics); PsychSetStructArrayDoubleElement("leading", 0, fontElement->verticalMetrics.leading, verticalMetrics); PsychSetStructArrayDoubleElement("avgAdvanceWidth", 0, fontElement->verticalMetrics.avgAdvanceWidth, verticalMetrics); PsychSetStructArrayDoubleElement("minLeftSideBearing", 0, fontElement->verticalMetrics.minLeftSideBearing, verticalMetrics); PsychSetStructArrayDoubleElement("minRightSideBearing", 0, fontElement->verticalMetrics.minRightSideBearing, verticalMetrics); PsychSetStructArrayDoubleElement("stemWidth", 0, fontElement->verticalMetrics.stemWidth, verticalMetrics); PsychSetStructArrayDoubleElement("stemHeight", 0, fontElement->verticalMetrics.stemHeight, verticalMetrics); PsychSetStructArrayDoubleElement("capHeight", 0, fontElement->verticalMetrics.capHeight, verticalMetrics); PsychSetStructArrayDoubleElement("xHeight", 0, fontElement->verticalMetrics.xHeight, verticalMetrics); PsychSetStructArrayDoubleElement("italicAngle", 0, fontElement->verticalMetrics.italicAngle, verticalMetrics); PsychSetStructArrayDoubleElement("underlinePosition", 0, fontElement->verticalMetrics.underlinePosition, verticalMetrics); PsychSetStructArrayDoubleElement("underlineThickness", 0, fontElement->verticalMetrics.underlineThickness, verticalMetrics); PsychSetStructArrayNativeElement("horizontalMetrics", 0, horizontalMetrics, metaMetrics); PsychSetStructArrayNativeElement("verticalMetrics", 0, verticalMetrics, metaMetrics); PsychSetStructArrayNativeElement("metrics", arrayIndex, metaMetrics, *fontStructArray); //locale PsychAllocOutStructArray(kPsychNoArgReturn, FALSE, 1, numLocaleFieldNames, localeFieldNames, &locale); PsychSetStructArrayStringElement("language", 0, (char*) fontElement->locale.language, locale); PsychSetStructArrayStringElement("languageVariant", 0, (char*) fontElement->locale.languageVariant, locale); PsychSetStructArrayStringElement("region", 0, (char*) fontElement->locale.region, locale); PsychSetStructArrayStringElement("regionVariant", 0, (char*) fontElement->locale.regionVariant, locale); PsychSetStructArrayStringElement("fullName", 0, (char*) fontElement->locale.fullName, locale); PsychSetStructArrayNativeElement("locale", arrayIndex, locale, *fontStructArray); } }
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); }