PsychError PSYCHHIDReceiveReports(void) { long error=0; int deviceIndex; mxArray **mxErrPtr; const mxArray *mxOptions,*mx; PsychPushHelp(useString,synopsisString,seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; PsychErrorExit(PsychCapNumOutputArgs(1)); PsychErrorExit(PsychCapNumInputArgs(2)); PsychCopyInIntegerArg(1,TRUE,&deviceIndex); if(deviceIndex < 0 || deviceIndex >= MAXDEVICEINDEXS) PrintfExit("Sorry. Can't cope with deviceNumber %d (more than %d). Please tell [email protected]",deviceIndex, (int) MAXDEVICEINDEXS-1); /* "\"options.print\" =1 (default 0) enables diagnostic printing of a summary of each report when our callback routine receives it. " "\"options.printCrashers\" =1 (default 0) enables diagnostic printing of the creation of the callback source and its addition to the CFRunLoop. " "\"options.maxReports\" (default 10000) allocate space for at least this many reports, shared among all devices. " "\"options.maxReportSize\" (default 65) allocate this many bytes per report. " */ //optionsPrintReportSummary=0; // options.print //optionsPrintCrashers=0; // options.printCrashers //optionsMaxReports=10000; // options.maxReports //optionsMaxReportSize=65; // options.maxReportSize //optionsSecs=0.010; // options.secs mxOptions=PsychGetInArgMxPtr(2); if(mxOptions!=NULL){ mx=mxGetField(mxOptions,0,"print"); if(mx!=NULL)optionsPrintReportSummary=(psych_bool)mxGetScalar(mx); mx=mxGetField(mxOptions,0,"printCrashers"); if(mx!=NULL)optionsPrintCrashers=(psych_bool)mxGetScalar(mx); mx=mxGetField(mxOptions,0,"secs"); if(mx!=NULL)optionsSecs=mxGetScalar(mx); mx=mxGetField(mxOptions,0,"consistencyChecks"); if(mx!=NULL)optionsConsistencyChecks=(psych_bool)mxGetScalar(mx); // Changing maxReports or maxReportSize triggers a reallocation of // buffer memory: mx=mxGetField(mxOptions,0,"maxReports"); if(mx!=NULL) { oneShotRealloc = TRUE; optionsMaxReports = (int) mxGetScalar(mx); } mx=mxGetField(mxOptions,0,"maxReportSize"); if(mx!=NULL) { oneShotRealloc = TRUE; optionsMaxReportSize = (int) mxGetScalar(mx); } } // Sanity check: if(optionsMaxReports < 1) PsychErrorExitMsg(PsychError_user, "PsychHID ReceiveReports: Sorry, requested maxReports count must be at least 1!"); if(optionsMaxReportSize < 1) PsychErrorExitMsg(PsychError_user, "PsychHID ReceiveReports: Sorry, requested maxReportSize must be at least 1 byte!"); if(optionsMaxReportSize > MAXREPORTSIZE) { printf("PsychHID ReceiveReports: Sorry, requested maximum report size %d bytes exceeds built-in maximum of %d bytes.\n", optionsMaxReportSize, (int) MAXREPORTSIZE); PsychErrorExitMsg(PsychError_user, "Invalid option.maxReportSize provided!"); } // Start reception of reports: This will also allocate memory for the reports // on first invocation for this deviceIndex: error = ReceiveReports(deviceIndex); mxErrPtr=PsychGetOutArgMxPtr(1); if(mxErrPtr!=NULL){ const char *fieldNames[]={"n", "name", "description"}; char *name="",*description=""; mxArray *fieldValue; PsychHIDErrors(NULL, error,&name,&description); // Get error name and description, if available. *mxErrPtr=mxCreateStructMatrix(1,1,3,fieldNames); fieldValue=mxCreateString(name); if(fieldValue==NULL)PrintfExit("PSYCHHIDReceiveReports: Couldn't allocate \"err\"."); mxSetField(*mxErrPtr,0,"name",fieldValue); fieldValue=mxCreateString(description); if(fieldValue==NULL)PrintfExit("PSYCHHIDReceiveReports: Couldn't allocate \"err\"."); mxSetField(*mxErrPtr,0,"description",fieldValue); fieldValue=mxCreateDoubleMatrix(1,1,mxREAL); if(fieldValue==NULL)PrintfExit("PSYCHHIDReceiveReports: Couldn't allocate \"err\"."); *mxGetPr(fieldValue)=(double)error; mxSetField(*mxErrPtr,0,"n",fieldValue); } return(PsychError_none); }
PsychError PSYCHHIDReceiveReports(void) { long error=0; int deviceIndex; mxArray **mxErrPtr; const mxArray *mxOptions,*mx; PsychPushHelp(useString,synopsisString,seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; PsychErrorExit(PsychCapNumOutputArgs(1)); PsychErrorExit(PsychCapNumInputArgs(2)); PsychCopyInIntegerArg(1,TRUE,&deviceIndex); /* "\"options.print\" =1 (default 0) enables diagnostic printing of a summary of each report when our callback routine receives it. " "\"options.printCrashers\" =1 (default 0) enables diagnostic printing of the creation of the callback source and its addition to the CFRunLoop. " "\"options.maxReports\" (default 10000) allocate space for at least this many reports, shared among all devices. " "\"options.maxReportSize\" (default 64) allocate this many bytes per report. " */ //optionsPrintReportSummary=0; // options.print //optionsPrintCrashers=0; // options.printCrashers //optionsMaxReports=10000; // options.maxReports //optionsMaxReportSize=64; // options.maxReportSize //optionsSecs=0.010; // options.secs mxOptions=PsychGetInArgMxPtr(2); if(mxOptions!=NULL){ mx=mxGetField(mxOptions,0,"print"); if(mx!=NULL)optionsPrintReportSummary=(psych_bool)mxGetScalar(mx); mx=mxGetField(mxOptions,0,"printCrashers"); if(mx!=NULL)optionsPrintCrashers=(psych_bool)mxGetScalar(mx); mx=mxGetField(mxOptions,0,"maxReports"); if(mx!=NULL)optionsMaxReports=(int)mxGetScalar(mx); mx=mxGetField(mxOptions,0,"maxReportSize"); if(mx!=NULL)optionsMaxReportSize=(int)mxGetScalar(mx); mx=mxGetField(mxOptions,0,"secs"); if(mx!=NULL)optionsSecs=mxGetScalar(mx); mx=mxGetField(mxOptions,0,"consistencyChecks"); if(mx!=NULL)optionsConsistencyChecks=(psych_bool)mxGetScalar(mx); } if(optionsMaxReports>MAXREPORTS)printf("PsychHID ReceiveReports: Sorry, maxReports is fixed at %d.\n",(int)MAXREPORTS); if(optionsMaxReportSize>MAXREPORTSIZE)printf("PsychHID ReceiveReports: Sorry, maxReportSize is fixed at %d.\n",(int)MAXREPORTSIZE); error=ReceiveReports(deviceIndex); mxErrPtr=PsychGetOutArgMxPtr(1); if(mxErrPtr!=NULL){ const char *fieldNames[]={"n", "name", "description"}; char *name="",*description=""; mxArray *fieldValue; PsychHIDErrors(NULL, error,&name,&description); // Get error name and description, if available. *mxErrPtr=mxCreateStructMatrix(1,1,3,fieldNames); fieldValue=mxCreateString(name); if(fieldValue==NULL)PrintfExit("PSYCHHIDReceiveReports: Couldn't allocate \"err\"."); mxSetField(*mxErrPtr,0,"name",fieldValue); fieldValue=mxCreateString(description); if(fieldValue==NULL)PrintfExit("PSYCHHIDReceiveReports: Couldn't allocate \"err\"."); mxSetField(*mxErrPtr,0,"description",fieldValue); fieldValue=mxCreateDoubleMatrix(1,1,mxREAL); if(fieldValue==NULL)PrintfExit("PSYCHHIDReceiveReports: Couldn't allocate \"err\"."); *mxGetPr(fieldValue)=(double)error; mxSetField(*mxErrPtr,0,"n",fieldValue); } return(PsychError_none); }
PsychError PSYCHHIDSetReport(void) { long error; pRecDevice device; int deviceIndex; int reportType; // kIOHIDReportTypeInput=0, kIOHIDReportTypeOutput=1, or kIOHIDReportTypeFeature=2 int reportID; unsigned char *reportBuffer; int reportSize; const mxArray *report; mxArray **outErr; int i; PsychPushHelp(useString,synopsisString,seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; PsychErrorExit(PsychCapNumOutputArgs(1)); PsychErrorExit(PsychCapNumInputArgs(4)); outErr=PsychGetOutArgMxPtr(1); assert(outErr!=NULL); PsychCopyInIntegerArg(1,TRUE,&deviceIndex); PsychCopyInIntegerArg(2,TRUE,&reportType); PsychCopyInIntegerArg(3,TRUE,&reportID); report=PsychGetInArgMxPtr(4); reportBuffer=(void *)mxGetPr(report); assert(reportBuffer!=NULL); switch(mxGetClassID(report)){ case mxCHAR_CLASS: case mxINT8_CLASS: case mxUINT8_CLASS: case mxINT16_CLASS: case mxUINT16_CLASS: case mxINT32_CLASS: case mxUINT32_CLASS: break; default: PrintfExit("\"report\" array must be char or integer (8-, 16-, or 32-bit)."); break; } reportSize=mxGetElementSize(report)*mxGetNumberOfElements(report); PsychHIDVerifyInit(); device=PsychHIDGetDeviceRecordPtrFromIndex(deviceIndex); if(reportSize>0 && reportID!=0) *reportBuffer=0xff&reportID; // copy low byte of reportID to first byte of report. // Apple defines constants for the reportType with values (0,1,2) that are one less that those specified by USB (1,2,3). assert(kIOHIDReportTypeInput==0 && kIOHIDReportTypeOutput==1 && kIOHIDReportTypeFeature==2); if(reportType==0){ printf("SetReport(reportType %d, reportID %d, report ",reportType,reportID); for(i=0;i<reportSize;i++)printf("%d ",(int)reportBuffer[i]); printf(")\n"); error=0; }else{ if(1){ IOHIDDeviceInterface122 **interface; interface=(IOHIDDeviceInterface122 **)(device->interface); if(interface)error=(*interface)->setReport(interface,reportType-1,reportID,reportBuffer,(UInt32)reportSize,50,NULL,NULL,NULL); else PrintfExit("PsychHID SetReport: Bad interface.\n"); }else error=HIDSetReport(device,reportType-1,reportID,reportBuffer,(UInt32)reportSize); } if(reportID==0x11){ PsychGetPrecisionTimerSeconds(&AInScanStart); } //if(error)printf("Warning: PsychHID: HIDSetReport error %ld (0x%lx).",error,error); if(0){ *outErr=mxCreateDoubleMatrix(1,1,mxREAL); if(*outErr==NULL)PrintfExit("Couldn't allocate \"err\"."); *mxGetPr(*outErr)=(double)error; }else{ const char *fieldNames[]={"n", "name", "description"}; char *name="",*description=""; mxArray *fieldValue; PsychHIDErrors(error,&name,&description); *outErr=mxCreateStructMatrix(1,1,3,fieldNames); fieldValue=mxCreateString(name); if(fieldValue==NULL)PrintfExit("Couldn't allocate \"err\"."); mxSetField(*outErr,0,"name",fieldValue); fieldValue=mxCreateString(description); if(fieldValue==NULL)PrintfExit("Couldn't allocate \"err\"."); mxSetField(*outErr,0,"description",fieldValue); fieldValue=mxCreateDoubleMatrix(1,1,mxREAL); if(fieldValue==NULL)PrintfExit("Couldn't allocate \"err\"."); *mxGetPr(fieldValue)=(double)error; mxSetField(*outErr,0,"n",fieldValue); } return(PsychError_none); }