PsychError PSYCHHIDReceiveReportsStop(void) 
{
	long error=0;
	int deviceIndex;
	mxArray **outErr;

    PsychPushHelp(useString,synopsisString,seeAlsoString);
    if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
    PsychErrorExit(PsychCapNumOutputArgs(1));
    PsychErrorExit(PsychCapNumInputArgs(1));
	PsychCopyInIntegerArg(1,TRUE,&deviceIndex);
	
	error=ReceiveReportsStop(deviceIndex);

	outErr=PsychGetOutArgMxPtr(1);
	if(outErr!=NULL){
		char *name="",*description="";
		const char *fieldNames[]={"n", "name", "description"};
		mxArray *fieldValue;

		PsychHIDErrors(NULL, error,&name,&description); // Get error name and description, if available.
		*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);	
}
예제 #2
0
void JOYSTICKGetAxis(int nlhs, mxArray *plhs[], int nrhs, CONSTmxArray *prhs[])
{

	ProjectTable *joystickTable=GetProjectTable();
	int  numSticks, numAxes, fetchedAxis;
	CONSTmxArray *numArg;
	double stickNum;
	SDL_Joystick *pStick;


	if(joystickTable->giveHelp){GiveHelp(useGetAxis,synopsisGetAxis);return;}
	numArg = joystickTable->joystickNumberArgument; 
	if(numArg == NULL || nlhs > 1 || nrhs > 1 || nrhs < 1 || !mxIsDouble(numArg) || (mxGetM(numArg) * mxGetN(numArg) != 1 ||
		!mxIsDouble(prhs[0]) || mxGetM(prhs[0]) * mxGetN(prhs[0]) != 1)){
		GiveUsageExit(useGetAxis);
	}
	numSticks = SDL_NumJoysticks();
	stickNum = mxGetPr(numArg)[0];
	if(stickNum > numSticks)
		PrintfExit("The joystick number %d passed to JOYSTICK 'GetAxis' exceeds the number of joysticks, %d",stickNum,numSticks);
	if(stickNum < 1)
		PrintfExit("The joystick number passed to JOYSTICK 'GetButton' must be greater than 0");
	pStick = GetJoystickObjFromNum((int)stickNum-1);
	if(pStick == NULL)
		PrintfExit("JOYSTICK 'GetAxis' can not open joystick number %d",stickNum);
	numAxes = SDL_JoystickNumAxes(pStick);
	fetchedAxis = (int)mxGetPr(prhs[0])[0];
	if(fetchedAxis > numAxes || fetchedAxis < 0)
		PrintfExit("The axis number %d passed to JOYSTICK 'GetAxis' is oustide the allowable range",fetchedAxis);
	plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);	
	SDL_JoystickUpdate();
	mxGetPr(plhs[0])[0] = SDL_JoystickGetAxis(pStick, fetchedAxis-1);
	
}
예제 #3
0
void JOYSTICKGetNumButtons(int nlhs, mxArray *plhs[], int nrhs, CONSTmxArray *prhs[])
{

	ProjectTable *joystickTable=GetProjectTable();
	int  numSticks;
	CONSTmxArray *numArg;
	double stickNum;
	SDL_Joystick *pStick;

	prhs;
	if(joystickTable->giveHelp){GiveHelp(useGetNumButtons,synopsisGetNumButtons);return;}
	numArg = joystickTable->joystickNumberArgument; 
	if(numArg == NULL || nlhs > 1 || nrhs > 0 || !mxIsDouble(numArg) || (mxGetM(numArg) * mxGetN(numArg) != 1))
		GiveUsageExit(useGetNumButtons);
	numSticks = SDL_NumJoysticks();
	stickNum = mxGetPr(numArg)[0];
	if(stickNum > numSticks)
		PrintfExit("The joystick number %d passed to JOYSTICK 'GetNumButtons' exceeds the number of joysticks, %d",stickNum,numSticks);
	if(stickNum < 1)
		PrintfExit("The joystick number passed to JOYSTICK 'GetNumButtons' must be greater than 0");
	pStick = GetJoystickObjFromNum((int)stickNum-1);
	if(pStick == NULL)
		PrintfExit("JOYSTICK 'GetNumButtons' can not open joystick number %d",stickNum);
	plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);	
	mxGetPr(plhs[0])[0] = SDL_JoystickNumButtons(pStick);
		
}
예제 #4
0
/*
    WaitNextEventOrQuit()
    
    
*/
Boolean WaitNextEventOrQuit(int mask,EventRecord *eventPtr,unsigned long sleep,RgnHandle mouseRgn)
{
	Boolean wne;

	if(CommandPeriod()){
			PrintfExit("User typed cmd-. Exiting.");
	}
	wne=WaitNextEvent(mask,eventPtr,sleep,mouseRgn);
	if(wne && IsCommandPeriod(eventPtr)){
			PrintfExit("User typed cmd-. Exiting.");
	}
	return wne;
}
void InitializeSynopsis(void)
{
	int i=0;
	const char **synopsis = synopsisSYNOPSIS;  // abbreviate the long name

	synopsis[i++] = "Usage:";

	synopsis[i++] = "numberOfDevices=PsychHID('NumDevices')";
	synopsis[i++] = "numberOfElements=PsychHID('NumElements',deviceNumber)";
	synopsis[i++] = "numberOfCollections=PsychHID('NumCollections',deviceNumber)";
    synopsis[i++] = "devices=PsychHID('Devices')";
	synopsis[i++] = "elements=PsychHID('Elements',deviceNumber)";
	synopsis[i++] = "collections=PsychHID('Collections',deviceNumber)";
	synopsis[i++] = "elementState=PsychHID('RawState',deviceNumber,elementNumber)";
	synopsis[i++] = "elementState=PsychHID('CalibratedState',deviceNumber,elementNumber)";
	synopsis[i++] = "[keyIsDown,secs,keyCode]=PsychHID('KbCheck' [, deviceNumber][, scanList])";
	synopsis[i++] = "[report,err]=PsychHID('GetReport',deviceNumber,reportType,reportID,reportBytes)";
	synopsis[i++] = "err=PsychHID('SetReport',deviceNumber,reportType,reportID,report)";
	synopsis[i++] = "\n\nQueue based keyboard queries: See 'help KbQueueCreate' for explanations:\n\n";
	synopsis[i++] = "PsychHID('KbQueueCreate', [deviceNumber], [keyFlags])";
	synopsis[i++] = "PsychHID('KbQueueRelease')"; 
	synopsis[i++] = "PsychHID('KbQueueFlush')"; 
	synopsis[i++] = "PsychHID('KbQueueStart')"; 
	synopsis[i++] = "PsychHID('KbQueueStop')"; 
	synopsis[i++] = "[keyIsDown, firstKeyPressTimes, firstKeyReleaseTimes, lastKeyPressTimes, lastKeyReleaseTimes]=PsychHID('KbQueueCheck')"; 
	synopsis[i++] = "secs=PsychHID('KbTriggerWait', KeysUsage, [deviceNumber])"; 
	synopsis[i++] = NULL;  // this tells PsychDisplayPsychHIDSynopsis where to stop
	if (i > MAX_SYNOPSIS_STRINGS) {
		PrintfExit("%s: increase dimension of synopsis[] from %ld to at least %ld and recompile.",__FILE__,(long)MAX_SYNOPSIS_STRINGS,(long)i);
	}
}
예제 #6
0
// Initialize usage info -- function overview:
void InitializeSynopsis(void)
{
	int i=0;
	const char **synopsis = synopsisSYNOPSIS;  //abbreviate the long name
	
	synopsis[i++] = "IOPort - A Psychtoolbox driver for general port I/O:\n";

	synopsis[i++] = "\nGeneral information:\n";
	synopsis[i++] = "version = IOPort('Version');";
	synopsis[i++] = "oldlevel = IOPort('Verbosity' [,level]);";

	synopsis[i++] = "\nGeneral commands for all types of input/output ports:\n";
	synopsis[i++] = "IOPort('Close', handle);";
	synopsis[i++] = "IOPort('CloseAll');";
	synopsis[i++] = "[nwritten, when, errmsg, prewritetime, postwritetime, lastchecktime] = IOPort('Write', handle, data [, blocking=1]);";
	synopsis[i++] = "IOPort('Flush', handle);"; 
	synopsis[i++] = "[data, when, errmsg] = IOPort('Read', handle [, blocking=0] [, amount]);";
	synopsis[i++] = "navailable = IOPort('BytesAvailable', handle);";
	synopsis[i++] = "IOPort('Purge', handle);";

	synopsis[i++] = "\nCommands specific to serial ports:\n";
	synopsis[i++] = "[handle, errmsg] = IOPort('OpenSerialPort', port [, configString]);";
	synopsis[i++] = "IOPort('ConfigureSerialPort', handle, configString);";

	synopsis[i++] = NULL;  //this tells IOPORTDisplaySynopsis where to stop
	if (i > MAX_SYNOPSIS_STRINGS) {
		PrintfExit("%s: increase dimension of synopsis[] from %ld to at least %ld and recompile.",__FILE__,(long)MAX_SYNOPSIS_STRINGS,(long)i);
	}
}
예제 #7
0
/*
ROUTINE: WaitTicks
PURPOSE:
  Wait ticks (60.15 Hz), then return.
*/
void WaitTicks(long ticks)
{
  ticks+=TickCount();
  while(TickCount()+30<ticks)if(CommandPeriod())PrintfExit("User typed cmd-. Exiting.");
  while(TickCount()<ticks) ;
  return;
}
예제 #8
0
void JOYSTICKGetHat(int nlhs, mxArray *plhs[], int nrhs, CONSTmxArray *prhs[])
{

	ProjectTable *joystickTable=GetProjectTable();
	int  numSticks, numHats, fetchedHat;
	CONSTmxArray *numArg;
	double stickNum;
	SDL_Joystick *pStick;
	Uint8 hatVal; 


	if(joystickTable->giveHelp){GiveHelp(useGetHat,synopsisGetHat);return;}
	numArg = joystickTable->joystickNumberArgument; 
	if(numArg == NULL || nlhs > 1 || nrhs > 1 || nrhs < 1 || !mxIsDouble(numArg) || (mxGetM(numArg) * mxGetN(numArg) != 1 ||
		!mxIsDouble(prhs[0]) || (mxGetM(prhs[0]) * mxGetN(prhs[0])) != 1)){
		GiveUsageExit(useGetHat);
	}
	numSticks = SDL_NumJoysticks();
	stickNum = mxGetPr(numArg)[0];
	if(stickNum > numSticks)
		PrintfExit("The joystick number %d passed to JOYSTICK 'GetHat' exceeds the number of joysticks, %d",stickNum,numSticks);
	if(stickNum < 1)
		PrintfExit("The joystick number passed to JOYSTICK 'GetHat' must be greater than 0");
	pStick = GetJoystickObjFromNum((int)stickNum-1);
	if(pStick == NULL)
		PrintfExit("JOYSTICK 'GetHat' can not open joystick number %d",stickNum);
	numHats = SDL_JoystickNumHats(pStick);
	fetchedHat = (int)mxGetPr(prhs[0])[0];
	if(fetchedHat > numHats || fetchedHat < 0)
		PrintfExit("The axis number %d passed to JOYSTICK 'GetHat' is oustide the allowable range",fetchedHat);
	SDL_JoystickUpdate();
	hatVal = SDL_JoystickGetHat(pStick, fetchedHat-1);
	plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);	
	switch(hatVal){
		case SDL_HAT_CENTERED:	mxGetPr(plhs[0])[0] = 0; break; 
		case SDL_HAT_UP:		mxGetPr(plhs[0])[0] = 1; break; 
		case SDL_HAT_RIGHT:		mxGetPr(plhs[0])[0] = 2; break; 
		case SDL_HAT_DOWN:		mxGetPr(plhs[0])[0] = 3; break;
		case SDL_HAT_LEFT:		mxGetPr(plhs[0])[0] = 4; break; 
		case SDL_HAT_RIGHTUP:	mxGetPr(plhs[0])[0] = 5; break; 
		case SDL_HAT_RIGHTDOWN: mxGetPr(plhs[0])[0] = 6; break; 
		case SDL_HAT_LEFTUP:	mxGetPr(plhs[0])[0] = 7; break; 
		case SDL_HAT_LEFTDOWN:	mxGetPr(plhs[0])[0] = 8; break; 
	}
	
}
void CheckRunLoopSource(int deviceIndex,char *caller,int line){
	CFRunLoopSourceRef currentSource;
	pRecDevice device;
	IOHIDDeviceInterface122** interface;
	
	device=PsychHIDGetDeviceRecordPtrFromIndex(deviceIndex);
	if(!HIDIsValidDevice(device))PrintfExit("PsychHID: Invalid device.\n");
	interface=device->interface;
	if(interface==NULL)PrintfExit("PsychHID: No interface for device.\n");
	currentSource=(*interface)->getAsyncEventSource(interface);
	if(source[deviceIndex] != currentSource)printf("%s (%d): source[%d] %4.4lx != current source %4.4lx.\n"
			,caller,line,(int)deviceIndex,(unsigned long)source[deviceIndex],(unsigned long)currentSource);

	if(ready[deviceIndex] && (source[deviceIndex]!=NULL) && !CFRunLoopContainsSource(CFRunLoopGetCurrent(),source[deviceIndex],myRunLoopMode))
		printf("%d: %s(%d): \"ready\" but source not in CFRunLoop.\n",(int)deviceIndex,caller,line);
	if(!ready[deviceIndex] && (source[deviceIndex]!=NULL) && CFRunLoopContainsSource(CFRunLoopGetCurrent(),source[deviceIndex],myRunLoopMode))
		printf("%d: %s(%d): \"!ready\" yet source is in CFRunLoop.\n",(int)deviceIndex,caller,line);
}
mxArray *CreateMXFSampleRaw(const FSAMPLE_RAW *fs)
{
   const char *fieldNames[] = {"raw_pupil","raw_cr","pupil_area","cr_area","pupil_dimension",
								"cr_dimension", "window_position","pupil_cr"};
   const int fieldCount=sizeof(fieldNames)/sizeof(*fieldNames);   
   mxArray *struct_array_ptr, *mx;
   
//   if ((*fs).type != SAMPLE_TYPE)
////      PrintfExit("wrong pointer argument\n");
//      mexPrintf("wrong pointer argument\n");
 
   /* Create a 1-by-1 structmatrix. */  
   struct_array_ptr = mxCreateStructMatrix(1,1,fieldCount,fieldNames);   
   if (struct_array_ptr == NULL)
      PrintfExit("Could not create struct matrix (probably out of memory)\n");

   mx = mxCreateDoubleMatrix(1,2,mxREAL);
   mxGetPr(mx)[0] = (*fs).raw_pupil[0];
   mxGetPr(mx)[1] = (*fs).raw_pupil[1];
   mxSetField(struct_array_ptr,0,"raw_pupil",mx);

   mx = mxCreateDoubleMatrix(1,2,mxREAL);
   mxGetPr(mx)[0] = (*fs).raw_cr[0];
   mxGetPr(mx)[1] = (*fs).raw_cr[1];
   mxSetField(struct_array_ptr,0,"raw_cr",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*fs).cr_area;
   mxSetField(struct_array_ptr,0,"cr_area",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*fs).pupil_area;
   mxSetField(struct_array_ptr,0,"pupil_area",mx);

   mx = mxCreateDoubleMatrix(1,2,mxREAL);
   mxGetPr(mx)[0] = (*fs).pupil_dimension[0];
   mxGetPr(mx)[1] = (*fs).pupil_dimension[1];
   mxSetField(struct_array_ptr,0,"pupil_dimension",mx);

   mx = mxCreateDoubleMatrix(1,2,mxREAL);
   mxGetPr(mx)[0] = (*fs).cr_dimension[0];
   mxGetPr(mx)[1] = (*fs).cr_dimension[1];
   mxSetField(struct_array_ptr,0,"cr_dimension",mx);

   mx = mxCreateDoubleMatrix(1,2,mxREAL);
   mxGetPr(mx)[0] = (*fs).window_position[0];
   mxGetPr(mx)[1] = (*fs).window_position[1];
   mxSetField(struct_array_ptr,0,"window_position",mx);

   mx = mxCreateDoubleMatrix(1,2,mxREAL);
   mxGetPr(mx)[0] = (*fs).pupil_cr[0];
   mxGetPr(mx)[1] = (*fs).pupil_cr[1];
   mxSetField(struct_array_ptr,0,"pupil_cr",mx);
              
   return struct_array_ptr;
}
// GiveMeReports is called solely by PsychHIDGiveMeReports, but the code resides here
// in PsychHIDReceiveReports because it uses the typedefs and static variables that
// are defined solely in this file. The linked lists of reports are unknown outside of this file.
PsychError GiveMeReports(int deviceIndex,int reportBytes)
{
	mwSize dims[]={1,1};
	mxArray **outReports;
	ReportStruct *r,*rTail;
	const char *fieldNames[]={"report", "device", "time"};
	mxArray *fieldValue;
	unsigned char *reportBuffer;
	int i,n;
    unsigned int j;
	long error=0;
	double now;
	
	CountReports("GiveMeReports beginning.");

	outReports=PsychGetOutArgMxPtr(1); 
	r=deviceReportsPtr[deviceIndex];
	n=0;
	while(r!=NULL){
		n++;
		rTail=r;
		r=r->next;
	}
	*outReports=mxCreateStructMatrix(1,n,3,fieldNames);
	r=deviceReportsPtr[deviceIndex];
	PsychGetPrecisionTimerSeconds(&now);
	for(i=n-1;i>=0;i--){
		// assert(r!=NULL);
		if(r->error)error=r->error;
		dims[0]=1;
		//printf("%2d: r->bytes %2d, reportBytes %4d, -%4.1f s\n",i,(int)r->bytes,(int)reportBytes, now-r->time);
		if(r->bytes> (unsigned int) reportBytes)r->bytes=reportBytes;
		dims[1]=r->bytes;
		fieldValue=mxCreateNumericArray(2,(void *)dims,mxUINT8_CLASS,mxREAL);
		reportBuffer=(void *)mxGetData(fieldValue);
		for(j=0;j<r->bytes;j++)reportBuffer[j]=r->report[j];
		if(fieldValue==NULL)PrintfExit("Couldn't allocate report array.");
		mxSetField(*outReports,i,"report",fieldValue);
		fieldValue=mxCreateDoubleMatrix(1,1,mxREAL);
		*mxGetPr(fieldValue)=(double)r->deviceIndex;
		mxSetField(*outReports,i,"device",fieldValue);
		fieldValue=mxCreateDoubleMatrix(1,1,mxREAL);
		*mxGetPr(fieldValue)=r->time;
		mxSetField(*outReports,i,"time",fieldValue);
		r=r->next;
	}
	if(deviceReportsPtr[deviceIndex]!=NULL){
		// transfer all these now-obsolete reports to the free list
		rTail->next=freeReportsPtr;
		freeReportsPtr=deviceReportsPtr[deviceIndex];
		deviceReportsPtr[deviceIndex]=NULL;
	}
	CountReports("GiveMeReports end.");
	return error;
}
예제 #12
0
void InitializeSynopsis(void)
{
	int i=0;
	const char **synopsis = synopsisSYNOPSIS;  // abbreviate the long name

	synopsis[i++] = "Usage:";

	synopsis[i++] = "\n\nGeneral commands:\n\n";
    synopsis[i++] = "rc = PsychHID('KeyboardHelper', commandCode)";
    
	synopsis[i++] = "\n\nSupport for generic USB-HID devices:\n\n";
	synopsis[i++] = "numberOfDevices=PsychHID('NumDevices')";
	synopsis[i++] = "numberOfElements=PsychHID('NumElements',deviceNumber)";
	synopsis[i++] = "numberOfCollections=PsychHID('NumCollections',deviceNumber)";
	synopsis[i++] = "devices=PsychHID('Devices' [, deviceClass])";
	synopsis[i++] = "elements=PsychHID('Elements',deviceNumber)";
	synopsis[i++] = "collections=PsychHID('Collections',deviceNumber)";
	synopsis[i++] = "elementState=PsychHID('RawState',deviceNumber,elementNumber)";
	synopsis[i++] = "elementState=PsychHID('CalibratedState',deviceNumber,elementNumber)";
	synopsis[i++] = "[keyIsDown,secs,keyCode]=PsychHID('KbCheck' [, deviceNumber][, scanList])";
	synopsis[i++] = "[report,err]=PsychHID('GetReport',deviceNumber,reportType,reportID,reportBytes)";
	synopsis[i++] = "err=PsychHID('SetReport',deviceNumber,reportType,reportID,report)";
	synopsis[i++] = "[reports,err]=PsychHID('GiveMeReports',deviceNumber,[reportBytes])";
	synopsis[i++] = "err=PsychHID('ReceiveReports',deviceNumber[,options])";
	synopsis[i++] = "err=PsychHID('ReceiveReportsStop',deviceNumber)";
    
	synopsis[i++] = "\n\nQueue based keyboard queries: See 'help KbQueueCreate' for explanations:\n\n";
	synopsis[i++] = "PsychHID('KbQueueCreate', [deviceNumber], [keyFlags])";
	synopsis[i++] = "PsychHID('KbQueueRelease' [, deviceIndex])"; 
	synopsis[i++] = "[navail] = PsychHID('KbQueueFlush' [, deviceIndex][, flushType=1])"; 
	synopsis[i++] = "PsychHID('KbQueueStart' [, deviceIndex])"; 
	synopsis[i++] = "PsychHID('KbQueueStop' [, deviceIndex])"; 
	synopsis[i++] = "[keyIsDown, firstKeyPressTimes, firstKeyReleaseTimes, lastKeyPressTimes, lastKeyReleaseTimes]=PsychHID('KbQueueCheck' [, deviceIndex])"; 
	synopsis[i++] = "secs=PsychHID('KbTriggerWait', KeysUsage, [deviceNumber])";
	synopsis[i++] = "[event, navail] = PsychHID('KbQueueGetEvent' [, deviceIndex][, maxWaitTimeSecs=0])";

	synopsis[i++] = "\n\nSupport for access to generic USB devices: See 'help ColorCal2' for one usage example:\n\n";
	synopsis[i++] = "usbHandle = PsychHID('OpenUSBDevice', vendorID, deviceID [, configurationId=0])";
	synopsis[i++] = "PsychHID('CloseUSBDevice' [, usbHandle])";
	synopsis[i++] = "outData = PsychHID('USBControlTransfer', usbHandle, bmRequestType, bRequest, wValue, wIndex, wLength, inData)";

	synopsis[i++] = NULL;  // this tells PsychDisplayPsychHIDSynopsis where to stop
	if (i > MAX_SYNOPSIS_STRINGS) {
		PrintfExit("%s: increase dimension of synopsis[] from %ld to at least %ld and recompile.",__FILE__,(long)MAX_SYNOPSIS_STRINGS,(long)i);
	}
}
예제 #13
0
void InitializeSynopsis()
{
    int i=0;
    const char **synopsis = synopsisSYNOPSIS;  //abbreviate the long name

    synopsis[i++] = "Usage:";

    synopsis[i++] = "numFonts=FontInfo('NumFonts')";
    synopsis[i++] = "fontInfoStructArray=FontInfo('Fonts')";
    synopsis[i++] = "versionInfo=FontInfo('Version')";


    synopsis[i++] = NULL;  //this tells PsychDisplayScreenSynopsis where to stop
	if (i > MAX_SYNOPSIS_STRINGS) {
        PrintfExit("%s: increase dimension of synopsis[] from %ld to at least %ld and recompile.",__FILE__,(long)MAX_SYNOPSIS_STRINGS,(long)i);
	}
}
PsychError PSYCHHIDGiveMeReports(void) 
{
	long error=0;
	int deviceIndex;
	int reportBytes=1024;
	mxArray **outErr;
	pRecDevice device;

    PsychPushHelp(useString,synopsisString,seeAlsoString);
    if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
    PsychErrorExit(PsychCapNumOutputArgs(2));
    PsychErrorExit(PsychCapNumInputArgs(2));
	PsychCopyInIntegerArg(1,TRUE,&deviceIndex);
	PsychCopyInIntegerArg(2,false,&reportBytes);

	PsychHIDVerifyInit();
    device=PsychHIDGetDeviceRecordPtrFromIndex(deviceIndex);
	if(!HIDIsValidDevice(device))PrintfExit("PsychHID:GiveMeReports: Invalid device.\n");

	// reports
	error=GiveMeReports(deviceIndex,reportBytes); // PsychHIDReceiveReports.c
	
	// err
	outErr=PsychGetOutArgMxPtr(2); // outErr==NULL if optional argument is absent.
	if(outErr!=NULL){
		const char *fieldNames[]={"n", "name", "description"};
		mxArray *fieldValue;
		char *name="",*description="";

		PsychHIDErrors(error,&name,&description); // Get error name and description, if available.
		*outErr=mxCreateStructMatrix(1,1,3,fieldNames);
		fieldValue=mxCreateString(name);
		mxSetField(*outErr,0,"name",fieldValue);
		fieldValue=mxCreateString(description);
		mxSetField(*outErr,0,"description",fieldValue);
		fieldValue=mxCreateDoubleMatrix(1,1,mxREAL);
		*mxGetPr(fieldValue)=(double)error;
		mxSetField(*outErr,0,"n",fieldValue);
	}
    return(PsychError_none);	
}
SDL_Joystick *GetJoystickObjFromNum(int joystickNum)
{
	static SDL_Joystick *pJoysticks[MAXIMUM_NUM_JOYSTICKS];
	static Boolean firstTime=1;
	int i;

	
	if(firstTime){
		for(i=0;i<MAXIMUM_NUM_JOYSTICKS;i++)
			pJoysticks[i] = NULL;
		firstTime = 0;
	}
	if(SDL_JoystickOpened(joystickNum)){
		if(pJoysticks[joystickNum] == NULL)
			PrintfExit("GetJoystickObjFromNum could not find the stored joystick object");
	}
	else{
		pJoysticks[joystickNum] = SDL_JoystickOpen(joystickNum);
	}
	return pJoysticks[joystickNum];
}
예제 #16
0
void InitializeSynopsis(void)
{
	int i=0;
	const char **synopsis = synopsisSYNOPSIS;  // abbreviate the long name

	synopsis[i++] = "Usage:";

	synopsis[i++] = "numberOfDevices=PsychHID('NumDevices')";
	synopsis[i++] = "numberOfElements=PsychHID('NumElements',deviceNumber)";
	synopsis[i++] = "numberOfCollections=PsychHID('NumCollections',deviceNumber)";
    synopsis[i++] = "devices=PsychHID('Devices')";
	synopsis[i++] = "elements=PsychHID('Elements',deviceNumber)";
	synopsis[i++] = "collections=PsychHID('Collections',deviceNumber)";
	synopsis[i++] = "elementState=PsychHID('RawState',deviceNumber,elementNumber)";
	synopsis[i++] = "elementState=PsychHID('CalibratedState',deviceNumber,elementNumber)";
	synopsis[i++] = "[keyIsDown,secs,keyCode]=PsychHID('KbCheck',[deviceNumber])";
	synopsis[i++] = "[report,err]=PsychHID('GetReport',deviceNumber,reportType,reportID,reportBytes)";
	synopsis[i++] = "err=PsychHID('SetReport',deviceNumber,reportType,reportID,report)";

	synopsis[i++] = NULL;  // this tells PsychDisplayPsychHIDSynopsis where to stop
	if (i > MAX_SYNOPSIS_STRINGS) {
		PrintfExit("%s: increase dimension of synopsis[] from %ld to at least %ld and recompile.",__FILE__,(long)MAX_SYNOPSIS_STRINGS,(long)i);
	}
}
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 PSYCHHIDGetReport(void) 
{
	long error=0;
	pRecDevice device;
	int deviceIndex;
	int reportType; // 1=input, 2=output, 3=feature
	unsigned char *reportBuffer;
	UInt32 reportBytes=0;
	int reportBufferSize=0;
	int reportID=0;
	long dims[]={1,1};
	mxArray **outReport,**outErr;
	char *name="",*description="",string[256];
	IOHIDDeviceInterface122** interface=NULL;
	boolean reportAvailable;
	double reportTime;

    PsychPushHelp(useString,synopsisString,seeAlsoString);
    if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
    PsychErrorExit(PsychCapNumOutputArgs(2));
    PsychErrorExit(PsychCapNumInputArgs(4));
	PsychCopyInIntegerArg(1,TRUE,&deviceIndex);
	PsychCopyInIntegerArg(2,TRUE,&reportType);
	PsychCopyInIntegerArg(3,TRUE,&reportID);
	PsychCopyInIntegerArg(4,TRUE,&reportBufferSize);
	outReport=PsychGetOutArgMxPtr(1); 
	outErr=PsychGetOutArgMxPtr(2); // outErr==NULL if optional argument is absent.
	dims[0]=1;
	dims[1]=reportBufferSize;
	*outReport=mxCreateNumericArray(2,(void *)dims,mxUINT8_CLASS,mxREAL);
	if(*outReport==NULL)PrintfExit("Couldn't allocate report array.");
	reportBuffer=(void *)mxGetData(*outReport);
	if(reportBuffer==NULL)PrintfExit("Couldn't allocate report buffer.");
	reportBytes=reportBufferSize;
	PsychHIDVerifyInit();
    device=PsychHIDGetDeviceRecordPtrFromIndex(deviceIndex);
	if(!HIDIsValidDevice(device))PrintfExit("PsychHID:GetReport: Invalid device.\n");
	interface=device->interface;
	if(interface==NULL)PrintfExit("PsychHID:GetReport: No interface for device.\n");
	if(reportType==0){
		printf("GetReport(reportType %d, reportID %d, reportBytes %d)\n",reportType,reportID,(int)reportBytes);
	}else{
		// Apple defines constants for the reportType with values (0,1,2) that are one less that those specified by USB (1,2,3).
		if(0){
			// HIDGetReport
			error=HIDGetReport(device,reportType-1,reportID,reportBuffer,&reportBytes);
		}
		if(0){
			// getReport
			error=(*interface)->getReport(interface,reportType-1,reportID,reportBuffer,&reportBytes,-1,nil,nil,nil);
		}
		if(0){
			// handleReport
		}
		if(1){
			// using setInterruptReportHandlerCallback and CFRunLoopRunInMode
			error=ReceiveReports(deviceIndex);
			error=GiveMeReport(deviceIndex,&reportAvailable,reportBuffer,&reportBytes,&reportTime);
		}else{
			// using getReport
			if(error==0)reportAvailable=1;
			PsychGetPrecisionTimerSeconds(&reportTime);
		}
	}
	if(outReport==NULL)PrintfExit("Output argument is required."); // I think MATLAB always provides this.
	if(error==0 && reportBytes>reportBufferSize){
		error=2;
		name="Warning";
		description=string;
		sprintf(description,"GetReport overflow. Expected %ld but received %ld bytes.",(long)reportBufferSize,(long)reportBytes); 
	}
	if(error==0 && reportBytes<reportBufferSize){
		// Reduce the declared size of the array to that of the received report.
		if(reportBytes>0)error=3;
		name="Warning";
		description=string;
		sprintf(description,"GetReport expected %ld but received %ld bytes.",(long)reportBufferSize,(long)reportBytes);
		mxSetN(*outReport,reportBytes);
	}
	if(outErr!=NULL){
		const char *fieldNames[]={"n", "name", "description", "reportLength", "reportTime"};
		mxArray *fieldValue;

		PsychHIDErrors(error,&name,&description); // Get error name and description, if available.
		*outErr=mxCreateStructMatrix(1,1,5,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);
		fieldValue=mxCreateDoubleMatrix(1,1,mxREAL);
		if(fieldValue==NULL)PrintfExit("Couldn't allocate \"err\".");
		if(reportAvailable)*mxGetPr(fieldValue)=(double)reportBytes;
		else *mxGetPr(fieldValue)=-1.0;
		mxSetField(*outErr,0,"reportLength",fieldValue);
		fieldValue=mxCreateDoubleMatrix(1,1,mxREAL);
		if(fieldValue==NULL)PrintfExit("Couldn't allocate \"err\".");
		*mxGetPr(fieldValue)=reportTime;
		mxSetField(*outErr,0,"reportTime",fieldValue);
	}
    return(PsychError_none);	
}
/* Do all the report processing: Iterates in a fetch loop
 * until either no more reports pending for processing, error condition,
 * or a maximum allowable processing time of optionSecs seconds has been
 * exceeded.
 *
 * Calls hidlib function hid_read() to get reports, one at a time, enqueues
 * it in our own reports lists for later retrieval by 'GiveMeReports' or
 * 'GiveMeReport'.
 *
 */
PsychError ReceiveReports(int deviceIndex)
{
    double deadline, now;

    pRecDevice device;
    int n, m;
    unsigned int i;
    ReportStruct *r;
    long error = 0;

    CountReports("ReceiveReports beginning.");
    if(freeReportsPtr==NULL) PrintfExit("No free reports.");

    if(deviceIndex < 0 || deviceIndex > MAXDEVICEINDEXS-1) PrintfExit("Sorry. Can't cope with deviceNumber %d (more than %d). Please tell [email protected]",deviceIndex, (int) MAXDEVICEINDEXS-1);

    PsychHIDVerifyInit();
    device = PsychHIDGetDeviceRecordPtrFromIndex(deviceIndex);
    last_hid_device = (hid_device*) device->interface;
    
    PsychGetAdjustedPrecisionTimerSeconds(&deadline);
    deadline += optionsSecs;
    
    // Iterate until deadline reached or no more pending reports to process:
    while (TRUE) {
        // Test for timeout:
        PsychGetAdjustedPrecisionTimerSeconds(&now);
        if (now >= deadline) break;
                
        CountReports("ReportCallback beginning.");
        
        // take report from free list.
        if(freeReportsPtr == NULL){
            // Darn. We're full. It might be elegant to discard oldest report, but for now, we'll just ignore the new one.
            printf("PsychHID: WARNING! ReportCallback warning. No more free reports. Discarding new report.\n");
            break;
        }
        
        r = freeReportsPtr;
        freeReportsPtr = r->next;
        r->next=NULL;
        
        // install report into the device's list.
        r->next = deviceReportsPtr[deviceIndex];
        deviceReportsPtr[deviceIndex] = r;
        
        // fill in the rest of the report struct
        r->deviceIndex = deviceIndex;

        // Fetch the actual data: Bytes fetched, or zero for no reports available, or
        // -1 for error condition.
        r->error = hid_read((hid_device*) device->interface, &(r->report[0]), MAXREPORTSIZE);
        if (r->error >= 0) {
            // Success: Reset error, assign size of retrieved report:
            r->bytes = r->error;
            r->error = 0;
        }
        else {
            // Error: No data assigned.
            r->bytes = 0;
            
            // Signal error return code -1:
            error = -1;
            
            // Abort fetch loop:
            break;
        }
        
        // Timestamp processing:
        PsychGetPrecisionTimerSeconds(&r->time);

        if (optionsPrintReportSummary) {
            // print diagnostic summary of the report
            int serial;
            
            serial = r->report[62] + 256 * r->report[63]; // 32-bit serial number at end of AInScan report from PMD-1208FS
            printf("Got input report %4d: %2ld bytes, dev. %d, %4.0f ms. ", serial, (long) r->bytes, deviceIndex, 1000 * (r->time - AInScanStart));
            if(r->bytes>0) {
                printf(" report ");
                n = r->bytes;
                if (n > 6) n=6;
                for(i=0; i < (unsigned int) n; i++) printf("%3d ", (int) r->report[i]);
                m = r->bytes - 2;
                if (m > (int) i) {
                    printf("... ");
                    i = m;
                }
                for(; i < r->bytes; i++) printf("%3d ", (int) r->report[i]);
            }
            printf("\n");
        }
        CountReports("ReportCallback end.");
        
        // If no data has been returned then we're done for now:
        if (r->bytes == 0) break;
    }
    
	CountReports("ReceiveReports end.");
	return error;
}
예제 #20
0
void InitializeSynopsis()
{
	int i=0;
	const char **synopsis = synopsisSYNOPSIS;  //abbreviate the long name

	synopsis[i++] = "Usage:";

	// OS-9 PTB emulation:
	synopsis[i++] = "\n% Activate compatibility mode: Try to behave like the old MacOS-9 Psychtoolbox:";
	synopsis[i++] = "oldEnableFlag=Screen('Preference', 'EmulateOldPTB', [enableFlag]);";

	// Open or close a window or texture:
	synopsis[i++] = "\n% Open or close a window or texture:";
	synopsis[i++] = "[windowPtr,rect]=Screen('OpenWindow',windowPtrOrScreenNumber [,color] [,rect] [,pixelSize] [,numberOfBuffers] [,stereomode] [,multisample][,imagingmode][,specialFlags][,clientRect]);";	
	synopsis[i++] = "[windowPtr,rect]=Screen('OpenOffscreenWindow',windowPtrOrScreenNumber [,color] [,rect] [,pixelSize] [,specialFlags] [,multiSample]);";
	synopsis[i++] = "textureIndex=Screen('MakeTexture', WindowIndex, imageMatrix [, optimizeForDrawAngle=0] [, specialFlags=0] [, floatprecision=0] [, textureOrientation=0] [, textureShader=0]);";
	synopsis[i++] = "oldParams = Screen('PanelFitter', windowPtr [, newParams]);";
	synopsis[i++] = "Screen('Close', [windowOrTextureIndex or list of textureIndices/offscreenWindowIndices]);";
	synopsis[i++] = "Screen('CloseAll');";
	
	// Draw lines lines solids like QuickDraw and DirectX (OS 9 and Windows)
	synopsis[i++] = "\n%  Draw lines and solids like QuickDraw and DirectX (OS 9 and Windows):";
	synopsis[i++] = "currentbuffer = Screen('SelectStereoDrawBuffer', windowPtr [, bufferid] [, param1]);";
	synopsis[i++] = "Screen('DrawLine', windowPtr [,color], fromH, fromV, toH, toV [,penWidth]);";
	synopsis[i++] = "Screen('DrawArc',windowPtr,[color],[rect],startAngle,arcAngle)";
	synopsis[i++] = "Screen('FrameArc',windowPtr,[color],[rect],startAngle,arcAngle[,penWidth] [,penHeight] [,penMode])";
	synopsis[i++] = "Screen('FillArc',windowPtr,[color],[rect],startAngle,arcAngle)";
	synopsis[i++] = "Screen('FillRect', windowPtr [,color] [,rect] );";
	synopsis[i++] = "Screen('FrameRect', windowPtr [,color] [,rect] [,penWidth]);";
	synopsis[i++] = "Screen('FillOval', windowPtr [,color] [,rect] [,perfectUpToMaxDiameter]);";
	synopsis[i++] = "Screen('FrameOval', windowPtr [,color] [,rect] [,penWidth] [,penHeight] [,penMode]);";
	synopsis[i++] = "Screen('FramePoly', windowPtr [,color], pointList [,penWidth]);";
	synopsis[i++] = "Screen('FillPoly', windowPtr [,color], pointList [, isConvex]);";	
	
	// New OpenGL-based functions for OS X
	synopsis[i++] = "\n% New OpenGL functions for OS X:";
	synopsis[i++] = "Screen('glPoint', windowPtr, color, x, y [,size]);";
	synopsis[i++] = "Screen('gluDisk', windowPtr, color, x, y [,size]);";
	synopsis[i++] = "Screen('DrawDots', windowPtr, xy [,size] [,color] [,center] [,dot_type]);";
	synopsis[i++] = "Screen('DrawLines', windowPtr, xy [,width] [,colors] [,center] [,smooth]);";
	synopsis[i++] = "[sourceFactorOld, destinationFactorOld, colorMaskOld]=Screen('BlendFunction', windowIndex, [sourceFactorNew], [destinationFactorNew], [colorMaskNew]);";

	// Draw Text in windows
	synopsis[i++] = "\n% Draw Text in windows";
	synopsis[i++] = "textModes = Screen('TextModes');";
	synopsis[i++] = "oldCopyMode=Screen('TextMode', windowPtr [,textMode]);";
	synopsis[i++] = "oldTextSize=Screen('TextSize', windowPtr [,textSize]);";
	synopsis[i++] = "oldStyle=Screen('TextStyle', windowPtr [,style]);";
	synopsis[i++] = "[oldFontName,oldFontNumber]=Screen(windowPtr,'TextFont' [,fontNameOrNumber]);";
	synopsis[i++] = "[normBoundsRect, offsetBoundsRect]= Screen('TextBounds', windowPtr, text [,x] [,y] [,yPositionIsBaseline] [,swapTextDirection]);";
	synopsis[i++] = "[newX,newY]=Screen('DrawText', windowPtr, text [,x] [,y] [,color] [,backgroundColor] [,yPositionIsBaseline] [,swapTextDirection]);";
	synopsis[i++] = "oldTextColor=Screen('TextColor', windowPtr [,colorVector]);";
	synopsis[i++] = "oldTextBackgroundColor=Screen('TextBackgroundColor', windowPtr [,colorVector]);";
	
	// Copy an image, very quickly, between textures and onscreen windows
	synopsis[i++] = "\n% Copy an image, very quickly, between textures, offscreen windows and onscreen windows.";
	synopsis[i++] = "[resident [texidresident]] = Screen('PreloadTextures', windowPtr [, texids]);";
	synopsis[i++] = "Screen('DrawTexture', windowPointer, texturePointer [,sourceRect] [,destinationRect] [,rotationAngle] [, filterMode] [, globalAlpha] [, modulateColor] [, textureShader] [, specialFlags] [, auxParameters]);";	
	synopsis[i++] = "Screen('DrawTextures', windowPointer, texturePointer(s) [, sourceRect(s)] [, destinationRect(s)] [, rotationAngle(s)] [, filterMode(s)] [, globalAlpha(s)] [, modulateColor(s)] [, textureShader] [, specialFlags] [, auxParameters]);";
	synopsis[i++] = "Screen('CopyWindow', srcWindowPtr, dstWindowPtr, [srcRect], [dstRect], [copyMode])";

	// Copy an image, slowly, between matrices and windows
	synopsis[i++] = "\n% Copy an image, slowly, between matrices and windows :";
	synopsis[i++] = "imageArray=Screen('GetImage', windowPtr [,rect] [,bufferName] [,floatprecision=0] [,nrchannels=3])";
	synopsis[i++] = "Screen('PutImage', windowPtr, imageArray [,rect]);";
	
	// Synchronize with the window's screen (on-screen only):
	synopsis[i++] = "\n% Synchronize with the window's screen (on-screen only):";
	synopsis[i++] = "[VBLTimestamp StimulusOnsetTime FlipTimestamp Missed Beampos] = Screen('Flip', windowPtr [, when] [, dontclear] [, dontsync] [, multiflip]);";
	synopsis[i++] = "[VBLTimestamp StimulusOnsetTime FlipTimestamp Missed Beampos] = Screen('AsyncFlipBegin', windowPtr [, when] [, dontclear] [, dontsync] [, multiflip]);";
	synopsis[i++] = "[VBLTimestamp StimulusOnsetTime FlipTimestamp Missed Beampos] = Screen('AsyncFlipEnd', windowPtr);";
	synopsis[i++] = "[VBLTimestamp StimulusOnsetTime FlipTimestamp Missed Beampos] = Screen('AsyncFlipCheckEnd', windowPtr);";
	synopsis[i++] = "[VBLTimestamp StimulusOnsetTime swapCertainTime] = Screen('WaitUntilAsyncFlipCertain', windowPtr);";
	synopsis[i++] = "[info] = Screen('GetFlipInfo', windowPtr [, infoType=0] [, auxArg1]);";
	synopsis[i++] = "[telapsed] = Screen('DrawingFinished', windowPtr [, dontclear] [, sync]);";
	synopsis[i++] = "framesSinceLastWait = Screen('WaitBlanking', windowPtr [, waitFrames]);";

	// Load color lookup table of the window's screen (on-screen only)
	synopsis[i++] = "\n% Load color lookup table of the window's screen (on-screen only):";
	synopsis[i++] = "[gammatable, dacbits, reallutsize] = Screen('ReadNormalizedGammaTable', windowPtrOrScreenNumber [, physicalDisplay]);";
	synopsis[i++] = "Screen('LoadNormalizedGammaTable', windowPtrOrScreenNumber, table [, loadOnNextFlip] [, physicalDisplay]);";
	synopsis[i++] = "oldclut = Screen('LoadCLUT', windowPtrOrScreenNumber [, clut] [, startEntry=0] [, bits=8]);";

	// Get and set information about a window or screen.
	synopsis[i++] = "\n% Get (and set) information about a window or screen:";
	synopsis[i++] = "screenNumbers=Screen('Screens' [, physicalDisplays]);";	
	synopsis[i++] = "windowPtrs=Screen('Windows');";
	synopsis[i++] = "kind=Screen(windowPtr, 'WindowKind');";
	synopsis[i++] = "isOffscreen=Screen(windowPtr,'IsOffscreen');";
	synopsis[i++] = "hz=Screen('FrameRate', windowPtrOrScreenNumber [, mode] [, reqFrameRate]);";	
	synopsis[i++] = "hz=Screen('NominalFrameRate', windowPtrOrScreenNumber [, mode] [, reqFrameRate]);";	
	synopsis[i++] = "[ monitorFlipInterval nrValidSamples stddev ]=Screen('GetFlipInterval', windowPtr [, nrSamples] [, stddev] [, timeout]);";
	synopsis[i++] = "screenNumber=Screen('WindowScreenNumber', windowPtr);";
	synopsis[i++] = "rect=Screen('Rect', windowPtrOrScreenNumber [, realFBSize=0]);";
	synopsis[i++] = "pixelSize=Screen('PixelSize', windowPtrOrScreenNumber);";
	synopsis[i++] = "pixelSizes=Screen('PixelSizes', windowPtrOrScreenNumber);";
	synopsis[i++] = "[width, height]=Screen('WindowSize', windowPointerOrScreenNumber [, realFBSize=0]);";
	synopsis[i++] = "[width, height]=Screen('DisplaySize', ScreenNumber);";
	synopsis[i++] = "[oldmaximumvalue, oldclampcolors, oldapplyToDoubleInputMakeTexture] = Screen('ColorRange', windowPtr [, maximumvalue][, clampcolors][, applyToDoubleInputMakeTexture]);";
	synopsis[i++] = "info = Screen('GetWindowInfo', windowPtr [, infoType=0] [, auxArg1]);";
	synopsis[i++] = "resolutions=Screen('Resolutions', screenNumber);";
	synopsis[i++] = "oldResolution=Screen('Resolution', screenNumber [, newwidth] [, newheight] [, newHz] [, newPixelSize] [, specialMode]);";
 	synopsis[i++] = "oldSettings = Screen('ConfigureDisplay', setting, screenNumber, outputId [, newwidth][, newheight][, newHz][, newX][, newY]);";

	// Get and set information about the environment, computer, and video card (i.e. screen):
	synopsis[i++] = "\n% Get/set details of environment, computer, and video card (i.e. screen):";
	synopsis[i++] = "struct=Screen('Version');";
	synopsis[i++] = "comp=Screen('Computer');";
	synopsis[i++] = "oldBool=Screen('Preference', 'IgnoreCase' [,bool]);";
	synopsis[i++] = "tick0Secs=Screen('Preference', 'Tick0Secs', tick0Secs);";
	synopsis[i++] = "psychTableVersion=Screen('Preference', 'PsychTableVersion');";
	synopsis[i++] = "mexFunctionName=Screen('Preference', 'PsychTableCreator');";
	synopsis[i++] = "proc=Screen('Preference', 'Process');";   
	synopsis[i++] = "Screen('Preference','SkipSyncTests', skipTest);";
	synopsis[i++] = "Screen('Preference','VisualDebugLevel', level (valid values between 0 and 5));";
	synopsis[i++] = "Screen('Preference', 'ConserveVRAM', mode (valid values between 0 and 3));";
	synopsis[i++] = "Screen('Preference', 'Enable3DGraphics', [enableFlag]);";

		
	//synopsis[i++] = "\n% Set clipping region (on- or off- screen):";
	
	// Helper functions.  Don't call these directly, use eponymous wrappers.
	synopsis[i++] = "\n% Helper functions.  Don't call these directly, use eponymous wrappers:";
	synopsis[i++] ="[x, y, buttonVector, hasKbFocus, valuators]= Screen('GetMouseHelper', numButtons [, screenNumber][, mouseIndex]);";
	synopsis[i++] = "Screen('HideCursorHelper', windowPntr [, mouseIndex]);";
	synopsis[i++] = "Screen('ShowCursorHelper', windowPntr [, cursorshapeid][, mouseIndex]);";
	synopsis[i++] = "Screen('SetMouseHelper', windowPntrOrScreenNumber, x, y [, mouseIndex]);";
	
	// Internal testing of Screen
	synopsis[i++] = "\n% Internal testing of Screen";
	synopsis[i++] =  "timeList= Screen('GetTimelist');";
	synopsis[i++] =  "Screen('ClearTimelist');";
	synopsis[i++] =  "Screen('Preference','DebugMakeTexture', enableDebugging);";
	
	// Movie and multimedia handling functions:
	synopsis[i++] = "\n% Movie and multimedia playback functions:";
	synopsis[i++] =  "[ moviePtr [duration] [fps] [width] [height] [count] [aspectRatio]]=Screen('OpenMovie', windowPtr, moviefile [, async=0] [, preloadSecs=1] [, specialFlags1=0][, pixelFormat=4][, maxNumberThreads=-1]);";
	synopsis[i++] =  "Screen('CloseMovie', moviePtr);";
	synopsis[i++] =  "[ texturePtr [timeindex]]=Screen('GetMovieImage', windowPtr, moviePtr, [waitForImage], [fortimeindex], [specialFlags = 0] [, specialFlags2 = 0]);";
	synopsis[i++] =  "[droppedframes] = Screen('PlayMovie', moviePtr, rate, [loop], [soundvolume]);";
 	synopsis[i++] =  "timeindex = Screen('GetMovieTimeIndex', moviePtr);";
 	synopsis[i++] =  "[oldtimeindex] = Screen('SetMovieTimeIndex', moviePtr, timeindex [, indexIsFrames=0]);";
 	synopsis[i++] =  "moviePtr = Screen('CreateMovie', windowPtr, movieFile [, width][, height][, frameRate=30][, movieOptions][, numChannels=4][, bitdepth=8]);";
	synopsis[i++] =  "Screen('FinalizeMovie', moviePtr);";
 	synopsis[i++] =  "Screen('AddFrameToMovie', windowPtr [,rect] [,bufferName] [,moviePtr=0] [,frameduration=1]);";
 	synopsis[i++] =  "Screen('AddAudioBufferToMovie', moviePtr, audioBuffer);";

	// Video capture support:
	synopsis[i++] = "\n% Video capture functions:";
	synopsis[i++] = "devices = Screen('VideoCaptureDevices' [, engineId]);";
    synopsis[i++] = "videoPtr =Screen('OpenVideoCapture', windowPtr [, deviceIndex][, roirectangle][, pixeldepth][, numbuffers][, allowfallback][, targetmoviename][, recordingflags][, captureEngineType][, bitdepth=8]);";
	synopsis[i++] = "Screen('CloseVideoCapture', capturePtr);";
    synopsis[i++] = "[fps starttime] = Screen('StartVideoCapture', capturePtr [, captureRateFPS] [, dropframes=0] [, startAt]);";
    synopsis[i++] = "droppedframes = Screen('StopVideoCapture', capturePtr [, discardFrames=1]);";
    synopsis[i++] = "[ texturePtr [capturetimestamp] [droppedcount] [average_intensityOrRawImageMatrix]]=Screen('GetCapturedImage', windowPtr, capturePtr [, waitForImage=1] [,oldTexture] [,specialmode] [,targetmemptr]);";
	synopsis[i++] = "oldvalue = Screen('SetVideoCaptureParameter', capturePtr, 'parameterName' [, value]);"; 

	// Low level OpenGL calls - directly translated to C via very thin wrapper functions:
	synopsis[i++] = "\n% Low level direct access to OpenGL-API functions:";
	synopsis[i++] = "% Online info for each function available by opening a terminal window";
	synopsis[i++] = "% and typing 'man Functionname' + Enter.\n";
	synopsis[i++] = "Screen('glPushMatrix', windowPtr);";
	synopsis[i++] = "Screen('glPopMatrix', windowPtr);";
	synopsis[i++] = "Screen('glLoadIdentity', windowPtr);";
	synopsis[i++] = "Screen('glTranslate', windowPtr, tx, ty [, tz]);";
	synopsis[i++] = "Screen('glScale', windowPtr, sx, sy [, sz]);";
	synopsis[i++] = "Screen('glRotate', windowPtr, angle, [rx = 0], [ry = 0] ,[rz = 1]);";
	
	// Interfacing with external OpenGL rendering code (MOGL and external OpenGL Mexfiles):
	synopsis[i++] = "\n% Support for 3D graphics rendering and for interfacing with external OpenGL code:";
	synopsis[i++] = "Screen('Preference', 'Enable3DGraphics', [enableFlag]);  % Enable 3D gfx support.";
	synopsis[i++] = "Screen('BeginOpenGL', windowPtr [, sharecontext]);  % Prepare window for external OpenGL drawing.";
	synopsis[i++] = "Screen('EndOpenGL', windowPtr);  % Finish external OpenGL drawing.";
	synopsis[i++] = "[targetwindow, IsOpenGLRendering] = Screen('GetOpenGLDrawMode');";
	synopsis[i++] = "[textureHandle rect] = Screen('SetOpenGLTextureFromMemPointer', windowPtr, textureHandle, imagePtr, width, height, depth [, upsidedown][, target][, glinternalformat][, gltype][, extdataformat][, specialFlags]);";
	synopsis[i++] = "[textureHandle rect] = Screen('SetOpenGLTexture', windowPtr, textureHandle, glTexid, target [, glWidth][, glHeight][, glDepth][, textureShader][, specialFlags]);";
	synopsis[i++] = "[ gltexid gltextarget texcoord_u texcoord_v ] =Screen('GetOpenGLTexture', windowPtr, textureHandle [, x][, y]);";
	
	synopsis[i++] = "\n% Support for plugins and for builtin high performance image processing pipeline:";
	synopsis[i++] = "[ret1, ret2, ...] = Screen('HookFunction', windowPtr, 'Subcommand', 'HookName', arg1, arg2, ...);";
	synopsis[i++] = "proxyPtr = Screen('OpenProxy', windowPtr [, imagingmode]);";
	synopsis[i++] = "transtexid = Screen('TransformTexture', sourceTexture, transformProxyPtr [, sourceTexture2][, targetTexture][, specialFlags]);";
	
	synopsis[i++] = NULL;  //this tells PsychDisplayScreenSynopsis where to stop

	if (i > MAX_SYNOPSIS_STRINGS) {
		PrintfExit("%s: increase dimension of synopsis[] from %ld to at least %ld and recompile.",__FILE__,(long)MAX_SYNOPSIS_STRINGS,(long)i);
	}
}
PsychError ReceiveReports(int deviceIndex)
{
	long error=0;
	pRecDevice device;
	IOHIDDeviceInterface122** interface=NULL;
	int reason; // kCFRunLoopRunFinished, kCFRunLoopRunStopped, kCFRunLoopRunTimedOut, kCFRunLoopRunHandledSource

	CountReports("ReceiveReports beginning.");
	if(freeReportsPtr==NULL)PrintfExit("No free reports.");

	PsychHIDVerifyInit();
	device=PsychHIDGetDeviceRecordPtrFromIndex(deviceIndex);
	if(!HIDIsValidDevice(device))PrintfExit("PsychHID: Invalid device.\n");
	interface=device->interface;
	if(interface==NULL)PrintfExit("PsychHID: No interface for device.\n");
	if(deviceIndex<0 || deviceIndex>MAXDEVICEINDEXS-1)PrintfExit("Sorry. Can't cope with deviceNumber %d (more than %d). Please tell [email protected]",deviceIndex,(int)MAXDEVICEINDEXS-1);
	CheckRunLoopSource(deviceIndex,"ReceiveReports",__LINE__);
	if(!ready[deviceIndex]){
		// setInterruptReportHandlerCallback
		static unsigned char buffer[MAXREPORTSIZE];
		psych_uint32 bufferSize=MAXREPORTSIZE;
		psych_bool createSource;

		createSource=(source[deviceIndex]==NULL);
		if(createSource){
			if(optionsPrintCrashers && createSource)printf("%d: createAsyncEventSource\n",deviceIndex);
			error=(*interface)->createAsyncEventSource(interface,&(source[deviceIndex]));
			if(error)PrintfExit("ReceiveReports - createAsyncEventSource error 0x%lx.",error);
			if(0 && optionsPrintCrashers && createSource)
				printf("%d: source %4.4lx validity %d, CFRunLoopContainsSource is %d.\n",deviceIndex,(unsigned long)source[deviceIndex]
					   ,CFRunLoopSourceIsValid(source[deviceIndex])
					   ,CFRunLoopContainsSource(CFRunLoopGetCurrent(),source[deviceIndex],myRunLoopMode));
		}
		if(optionsPrintCrashers && createSource)printf("%d: getAsyncEventSource\n",deviceIndex);
		CheckRunLoopSource(deviceIndex,"ReceiveReports",__LINE__);
		if(optionsPrintCrashers && createSource)printf("%d: CFRunLoopAddSource\n",deviceIndex);
		CFRunLoopAddSource(CFRunLoopGetCurrent(),source[deviceIndex],myRunLoopMode);
		if(0 && optionsPrintCrashers && createSource)printf("%d: source %4.4lx validity %d, CFRunLoopContainsSource is %d.\n",deviceIndex,(unsigned long)source[deviceIndex]
			   ,CFRunLoopSourceIsValid(source[deviceIndex])
			   ,CFRunLoopContainsSource(CFRunLoopGetCurrent(),source[deviceIndex],myRunLoopMode));
		ready[deviceIndex]=1;
		CheckRunLoopSource(deviceIndex,"ReceiveReports",__LINE__);
		if(optionsPrintCrashers && createSource)printf("%d: setInterruptReportHandlerCallback\n",deviceIndex);
		error=(*interface)->setInterruptReportHandlerCallback(interface,buffer,bufferSize,ReportCallback,buffer,(void *)deviceIndex);
		if(error)PrintfExit("ReceiveReports - setInterruptReportHandlerCallback error 0x%lx.",error);
		if(optionsPrintCrashers && createSource)printf("%d: CFRunLoopRunInMode.\n",deviceIndex);
	}
	//printf("%d: CFRunLoopRunInMode\n",deviceIndex);
	reason=CFRunLoopRunInMode(myRunLoopMode,optionsSecs,false);
	if(reason!=kCFRunLoopRunTimedOut && reason!=kCFRunLoopRunHandledSource){
		char *s;
		switch(reason){
			case kCFRunLoopRunFinished: s="kCFRunLoopRunFinished"; break;
			case kCFRunLoopRunStopped: s="kCFRunLoopRunStopped"; break;
			case kCFRunLoopRunTimedOut: s="kCFRunLoopRunTimedOut"; break;
			case kCFRunLoopRunHandledSource: s="kCFRunLoopRunHandledSource"; break;
			default: s="of unknown reason.";
		}
		printf("RunLoop ended at %.3f s because %s.\n",CFAbsoluteTimeGetCurrent()-AInScanStart,s);			
	}
	CountReports("ReceiveReports end.");
	return error;
}
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);	
}
mxArray *CreateMXIEvent(const IEVENT *ie)
{
   const char *fieldNames[] = {"time","type","read","eye","sttime","entime","hstx","hsty",
                               "gstx","gsty","sta","henx","heny","genx","geny",
                               "ena","havx","havy","gavx","gavy","ava","avel","pvel",
                               "svel","evel","supd_x","eupd_x","supd_y","eupd_y","status"};
   const int fieldCount=sizeof(fieldNames)/sizeof(*fieldNames);   
   mxArray *struct_array_ptr, *mx; 
   
   if ((*ie).type == SAMPLE_TYPE)
      PrintfExit("CreateMXIEvent : wrong pointer argument\n");
 
   /* Create a 1-by-1 structmatrix. */  
   struct_array_ptr = mxCreateStructMatrix(1,1,fieldCount,fieldNames);   
   if (struct_array_ptr == NULL)
      PrintfExit("Could not create struct matrix (probably out of memory)\n");

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).time;
   mxSetField(struct_array_ptr,0,"time",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).type;
   mxSetField(struct_array_ptr,0,"type",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).read;
   mxSetField(struct_array_ptr,0,"read",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).eye;
   mxSetField(struct_array_ptr,0,"eye",mx);  
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).sttime;
   mxSetField(struct_array_ptr,0,"sttime",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).entime;
   mxSetField(struct_array_ptr,0,"entime",mx);     
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).hstx;
   mxSetField(struct_array_ptr,0,"hstx",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).hsty;
   mxSetField(struct_array_ptr,0,"hsty",mx);       

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).gstx;
   mxSetField(struct_array_ptr,0,"gstx",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).gsty;
   mxSetField(struct_array_ptr,0,"gsty",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).sta;
   mxSetField(struct_array_ptr,0,"sta",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).henx;
   mxSetField(struct_array_ptr,0,"henx",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).heny;
   mxSetField(struct_array_ptr,0,"heny",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).genx;
   mxSetField(struct_array_ptr,0,"genx",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).geny;
   mxSetField(struct_array_ptr,0,"geny",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).ena;
   mxSetField(struct_array_ptr,0,"ena",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).havx;
   mxSetField(struct_array_ptr,0,"havx",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).havy;
   mxSetField(struct_array_ptr,0,"havy",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).gavx;
   mxSetField(struct_array_ptr,0,"gavx",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).gavy;
   mxSetField(struct_array_ptr,0,"gavy",mx);   
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).ava;
   mxSetField(struct_array_ptr,0,"ava",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).avel;
   mxSetField(struct_array_ptr,0,"avel",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).pvel;
   mxSetField(struct_array_ptr,0,"pvel",mx); 
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).svel;
   mxSetField(struct_array_ptr,0,"svel",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).evel;
   mxSetField(struct_array_ptr,0,"evel",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).supd_x;
   mxSetField(struct_array_ptr,0,"supd_x",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).eupd_x;
   mxSetField(struct_array_ptr,0,"eupd_x",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).supd_y;
   mxSetField(struct_array_ptr,0,"supd_y",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).eupd_y;
   mxSetField(struct_array_ptr,0,"eupd_y",mx);
   
   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*ie).status;
   mxSetField(struct_array_ptr,0,"status",mx);
   
   return struct_array_ptr;
}
/* this function is very similar to CreateMXISample
   and actually contains exactly the
   same code, except that the argument is different (FSAMPLE * here).
   I needed to copy everything, because there is no way to check if
   a pointer is a FSAMPLE *, or a ISAMPLE *, and they contain exactly
   the same fields (only some types are different)
   it would be much nicer if there was only one function 
   which would return a SAMPLE structure. */
mxArray *CreateMXFSample(const FSAMPLE *fs)
{
   const char *fieldNames[] = {"time","type","flags","px","py","hx","hy","pa","gx","gy",
                               "rx","ry","status","input","buttons","htype","hdata"};
   const int fieldCount=sizeof(fieldNames)/sizeof(*fieldNames);   
   mxArray *struct_array_ptr, *mx; 
   
   if ((*fs).type != SAMPLE_TYPE){
     // PrintfExit("CreateMXFSample: wrong pointer argument\n");
     printf("CreateMXFSample: wrong pointer argument\n");
	 return(NULL);
	}
 
   /* Create a 1-by-1 structmatrix. */  
   struct_array_ptr = mxCreateStructMatrix(1,1,fieldCount,fieldNames);   
   if (struct_array_ptr == NULL)
      PrintfExit("Could not create struct matrix (probably out of memory)\n");

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*fs).time;
   mxSetField(struct_array_ptr,0,"time",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*fs).type;
   mxSetField(struct_array_ptr,0,"type",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*fs).flags;
   mxSetField(struct_array_ptr,0,"flags",mx);
   
   mx = mxCreateDoubleMatrix(1,2,mxREAL);
   mxGetPr(mx)[0] = (*fs).px[0];
   mxGetPr(mx)[1] = (*fs).px[1];
   mxSetField(struct_array_ptr,0,"px",mx);
      
   mx = mxCreateDoubleMatrix(1,2,mxREAL);
   mxGetPr(mx)[0] = (*fs).py[0];
   mxGetPr(mx)[1] = (*fs).py[1];
   mxSetField(struct_array_ptr,0,"py",mx);
   
   mx = mxCreateDoubleMatrix(1,2,mxREAL);
   mxGetPr(mx)[0] = (*fs).hx[0];
   mxGetPr(mx)[1] = (*fs).hx[1];
   mxSetField(struct_array_ptr,0,"hx",mx);
         
   mx = mxCreateDoubleMatrix(1,2,mxREAL);
   mxGetPr(mx)[0] = (*fs).hy[0];
   mxGetPr(mx)[1] = (*fs).hy[1];
   mxSetField(struct_array_ptr,0,"hy",mx); 

   mx = mxCreateDoubleMatrix(1,2,mxREAL);
   mxGetPr(mx)[0] = (*fs).pa[0];
   mxGetPr(mx)[1] = (*fs).pa[1];
   mxSetField(struct_array_ptr,0,"pa",mx);    
   
   mx = mxCreateDoubleMatrix(1,2,mxREAL);
   mxGetPr(mx)[0] = (*fs).gx[0];
   mxGetPr(mx)[1] = (*fs).gx[1];
   mxSetField(struct_array_ptr,0,"gx",mx);    
   
   mx = mxCreateDoubleMatrix(1,2,mxREAL);
   mxGetPr(mx)[0] = (*fs).gy[0];
   mxGetPr(mx)[1] = (*fs).gy[1];
   mxSetField(struct_array_ptr,0,"gy",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*fs).rx;
   mxSetField(struct_array_ptr,0,"rx",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*fs).ry;
   mxSetField(struct_array_ptr,0,"ry",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*fs).status;
   mxSetField(struct_array_ptr,0,"status",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*fs).input;
   mxSetField(struct_array_ptr,0,"input",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*fs).buttons;
   mxSetField(struct_array_ptr,0,"buttons",mx);

   mx = mxCreateDoubleMatrix(1,1,mxREAL);
   mxGetPr(mx)[0] = (*fs).htype;
   mxSetField(struct_array_ptr,0,"htype",mx);
           
   mx = mxCreateDoubleMatrix(1,8,mxREAL);
   mxGetPr(mx)[0] = (*fs).hdata[0];
   mxGetPr(mx)[1] = (*fs).hdata[1];
   mxGetPr(mx)[2] = (*fs).hdata[2];
   mxGetPr(mx)[3] = (*fs).hdata[3];
   mxGetPr(mx)[4] = (*fs).hdata[4];
   mxGetPr(mx)[5] = (*fs).hdata[5];
   mxGetPr(mx)[6] = (*fs).hdata[6];
   mxGetPr(mx)[7] = (*fs).hdata[7];         
   mxSetField(struct_array_ptr,0,"hdata",mx);    
              
   return struct_array_ptr;
}
예제 #25
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, CONSTmxArray *prhs[])
{
	static psych_bool firstTime=1,deferAvailable;
	long priorityLevel=-1;
	double a;
	Stuff stuff;
	psych_bool isString,oldMatlabBackgrounding;

	plhs;
	InitMEX();
	isString=nrhs>0 && (mxIsChar(prhs[0]) || mxIsCell(prhs[0]));
	if(nlhs>1 || nrhs<1 || nrhs>2 || (isString && nlhs>0))PrintfExit("Usage:\n\n%s",useRush);
	switch(nrhs){
	case 2:
		a=mxGetScalar(prhs[1]);
		if(a!=0 && a!=0.5 && a!=1 && a!=2 && a!=3 && a!=4 && a!=5 && a!=6 && a!=7)
			PrintfExit("Illegal priorityLevel %.1f. Must be 0, 0.5, 1, 2, 3, 4, 5, 6, or 7. Usage:\n%s",a,useRush);
		priorityLevel=a;
		if(a==0.5)priorityLevel=-1;
	case 1:
		if(!isString){
			// special case: get an array of timings
			double s,s0;
			long j;

			stuff.getTimes=mxGetScalar(prhs[0]);
			if(stuff.getTimes<1)
				PrintfExit("The first argument must be either a string (or strings) or a number.");
			plhs[0]=mxCreateDoubleMatrix(1,stuff.getTimes,mxREAL);
			if(plhs[0]==NULL)PrintfExit("Couldn't allocate %ld element array.",stuff.getTimes);
			stuff.mxTimes=plhs[0];
			stuff.iterations=10000;
			s=Seconds();
			s=Seconds();
			s0=Seconds()-s;
			s=Seconds();
			for(j=0;j<stuff.iterations;j++) ;
			s=Seconds()-s-s0;
			stuff.iterations=(0.001-s0)*stuff.iterations/s;
			// That many iterations plus a call to Seconds() should take 1 ms.
		}else stuff.getTimes=0;
		break;
	}
	if(1){
		// concatenate array or cell array of strings
		int error=0;
		mxArray *out,*in;

		in=(mxArray *)prhs[0];
		error=mexCallMATLAB(1,&out,1,&in,"CatStr"); // Psychtoolbox:PsychOneliners:CatStr.m
		stuff.mxString=out;
	}else{
		stuff.mxString=prhs[0];
	}
	stuff.trapErrors=1;
	stuff.error=0;
	
	#if TARGET_OS_MAC
		if(CanControlMatlabBackgrounding()){
			oldMatlabBackgrounding=MatlabBackgrounding(0);
		}else{
			if(firstTime){
				// Backgrounding is dangerous. Matlab would give time to another process while priority is raised.
				// Checking the enabled flag (on the disk) is slow, so we only do it once if backgrounding's off. But
				// if it's on, we give an error, and check again next time.
				if(IsMatlabBackgroundingEnabled()){
					PrintfExit("Rush: please turn off Matlab's \"Backgrounding\" Preference, in the File menu.\n");
				}else firstTime=0;
			}
		}
	#endif

	mexEvalString("lasterr('');");

	Rush(priorityLevel,&fun,&stuff);

	if(CanControlMatlabBackgrounding())MatlabBackgrounding(oldMatlabBackgrounding);
	if(stuff.error)mexErrMsgTxt("mexCallMATLAB error during Rush");	// never happens
	{
		// if there's a message in LASTERR, print it as an error, with a preface
		int nlhs=1,nrhs=0,error=0;
		mxArray *plhs[1]={NULL},*prhs[1]={NULL};
		char string[512]="Error during Rush: ",*errorMsg;

		errorMsg=string+strlen(string);
		error=mexCallMATLAB(nlhs,plhs,nrhs,prhs,"lasterr");
		error=mxGetString(plhs[0],errorMsg,sizeof(string)-strlen(string));
		if(strlen(errorMsg)>0)mexErrMsgTxt(string);
	}
}
예제 #26
0
void InitializeSynopsis()
{
	int i=0;
	const char **synopsis = synopsisSYNOPSIS;  //abbreviate the long name

	synopsis[i++] = "\n% This is main function of the Eyelink toolbox";
	synopsis[i++] = "Usage:";
   synopsis[i++] = "\n% For general advice, try:";
   synopsis[i++] = "help eyelink";
   synopsis[i++] = "\n% For a more detailed explanation of any eyelink function, just add a question mark \"?\".";
   synopsis[i++] = "% E.g. for 'Initialize',try either of these equivalent forms:";
   synopsis[i++] = "eyelink('Initialize?')";
   synopsis[i++] = "eyelink Initialize?";
   synopsis[i++] = "% If you think you've found a bug,\n";
   synopsis[i++] = "Please report on the forum, see: http://psychtoolbox.org/\n";

	// Init or close eyelink
	synopsis[i++] = "\n% Initialize or shutdown Eyelink connection:";
	synopsis[i++] = "[status =] Eyelink('Initialize' [, displayCallbackFunction])";
	synopsis[i++] = "[status =] Eyelink('InitializeDummy' [, displayCallbackFunction])";
	synopsis[i++] = "status = Eyelink('IsConnected')";
	synopsis[i++] = "Eyelink('Shutdown')";
	synopsis[i++] = "oldlevel = Eyelink('Verbosity' [,level]);";
	synopsis[i++] = "Eyelink('TestSuite')";
	synopsis[i++] = "[status =] Eyelink('OpenFile','filename')";
	synopsis[i++] = "[status =] Eyelink('CloseFile')";
	synopsis[i++] = "[status =] Eyelink('ReceiveFile',['filename'], ['dest'], ['dest_is_path'])";
	
	// Calibration
	synopsis[i++] = "\n% Calibration:";
	synopsis[i++] = "[result =] Eyelink('StartSetup' [, stype=0])";
	synopsis[i++] = "[status = ] Eyelink('DriftCorrStart', x, y [,dtype=0][, dodraw=1][, allow_setup=0])";
	synopsis[i++] = "[result = ] Eyelink('ApplyDriftCorr')";
	synopsis[i++] = "[result, tx, ty] = Eyelink('TargetCheck')";
	synopsis[i++] = "[result = ] Eyelink('AcceptTrigger')";
	
	// Start or stop recording, Data acquisition
	synopsis[i++] = "\n% Start or stop recording and acquiring data:";
	synopsis[i++] = "[startrecording_error =] Eyelink('StartRecording' [,file_samples, file_events, link_samples, link_events] )";
	synopsis[i++] = "Eyelink('Stoprecording')";
	synopsis[i++] = "error = Eyelink('CheckRecording')";
	synopsis[i++] =  "eyeused = Eyelink('EyeAvailable')";
	synopsis[i++] = "NewOrOld = Eyelink('NewFloatSampleAvailable')";
	synopsis[i++] = "sample = Eyelink('NewestFloatSample')";
	synopsis[i++] = "[sample, raw] = Eyelink('NewestFloatSampleRaw' [, eye])";
	synopsis[i++] = "type = Eyelink('GetNextDataType')";
	synopsis[i++]  = "item = Eyelink('GetFloatData', type)";
	synopsis[i++]  = "[item, raw] = Eyelink('GetFloatDataRaw', type [, eye])";
	synopsis[i++]  = "[samples, events, drained] = Eyelink('GetQueuedData'[, eye])";
    
	// Misc eyelink communication:
	synopsis[i++] = "\n% Miscellaneous functions to communicate with Eyelink:";
	synopsis[i++] = "result = Eyelink('ButtonStates')";
	synopsis[i++] = "[status =] Eyelink('Command', 'formatstring', [...])";
	synopsis[i++] = "[status =] Eyelink('Message', 'formatstring', [...])";
	synopsis[i++] = "[result =] Eyelink('SendKeyButton', code, mods, state)";
	synopsis[i++] = "[time =] Eyelink('TrackerTime')";
	synopsis[i++] = "[offset =] Eyelink('TimeOffset')";
	synopsis[i++] = "[status =] Eyelink('RequestTime')";
	synopsis[i++] = "[time =] Eyelink('ReadTime')";

	synopsis[i++] = "\n% Miscellaneous Eyelink functions:";
	synopsis[i++] = "[result =] Eyelink('WaitForModeReady', maxwait)";
	synopsis[i++] = "[result =] Eyelink('ImageModeDisplay')";
	synopsis[i++] = "mode = Eyelink('CurrentMode')";
	synopsis[i++] = "result = Eyelink('CalResult')";
	synopsis[i++] = "Eyelink('SetOfflineMode')";
	synopsis[i++] = "[version, versionString]  = Eyelink('GetTrackerVersion')";
	synopsis[i++] = "[time =] Eyelink('TrackerTime')";
	synopsis[i++] = "[offset =] Eyelink('TimeOffset')";

	// Place Holder
	synopsis[i++] = "\n\n\n\n% EyelinkToolbox version for the OpenGL PsychToolbox";
	synopsis[i++] = "% The EyelinkToolbox was developed by:";
	synopsis[i++] = "\tFrans Cornelissen";
	synopsis[i++] = "\tEnno Peters";
	synopsis[i++] = "\tJohn Palmer";
	synopsis[i++] = "\tChris Burns";
	synopsis[i++] = "\tMario Kleiner";
	synopsis[i++] = "\tErik Flister";
	
	synopsis[i++] = NULL;  //this tells PsychDisplayScreenSynopsis where to stop
	if (i > MAX_SYNOPSIS_STRINGS) {
		PrintfExit("%s: increase dimension of synopsis[] from %ld to at least %ld and recompile.",__FILE__,(long)MAX_SYNOPSIS_STRINGS,(long)i);
	}
}
/* Do all the report processing for all devices: Iterates in a fetch loop
 * until error condition, or a maximum allowable processing time of
 * optionSecs seconds has been exceeded.
 *
 * Calls hidlib function hid_read() to get reports, one at a time, enqueues
 * it in our own reports lists for later retrieval by 'GiveMeReports' or
 * 'GiveMeReport'.
 *
 */
PsychError ReceiveReports(int deviceIndex)
{
    int rateLimit[MAXDEVICEINDEXS] = { 0 };
    double deadline, now;
    pRecDevice device;
    int n, m;
    unsigned int i;
    ReportStruct *r;
    long error = 0;

    PsychHIDVerifyInit();

    if(deviceIndex < 0 || deviceIndex >= MAXDEVICEINDEXS) PrintfExit("Sorry. Can't cope with deviceNumber %d (more than %d). Please tell [email protected]",deviceIndex, (int) MAXDEVICEINDEXS-1);

    // Allocate report buffers if needed:
    PsychHIDAllocateReports(deviceIndex);

    CountReports("ReceiveReports beginning.");
    if (freeReportsPtr[deviceIndex] == NULL) PrintfExit("No free reports.");

    // Enable this device for hid report reception:
    ready[deviceIndex] = TRUE;

    PsychGetAdjustedPrecisionTimerSeconds(&now);
    deadline = now + optionsSecs;
    
    // Iterate until deadline reached or no more pending reports to process:
    while ((error == 0) && (now <= deadline)) {
        // Iterate over all active devices:
        for (deviceIndex = 0; deviceIndex < MAXDEVICEINDEXS; deviceIndex++) {            
            // Test for timeout:
            PsychGetAdjustedPrecisionTimerSeconds(&now);
            if (now > deadline) break;

            // Skip this device if it isn't enabled to receive hid reports:
            if (!ready[deviceIndex]) continue;
            
            // Free target report buffers?
            if(freeReportsPtr[deviceIndex] == NULL) {
                // Darn. We're full. It might be elegant to discard oldest report, but for now, we'll just ignore the new one.
                if (!rateLimit[deviceIndex]) printf("PsychHID: WARNING! ReportCallback warning. No more free reports for deviceIndex %i. Discarding new report.\n", deviceIndex);
                rateLimit[deviceIndex] = 1;
                continue;
            }
            
            // Handle one report for this device:
            CountReports("ReportCallback beginning.");

            device = PsychHIDGetDeviceRecordPtrFromIndex(deviceIndex);
            last_hid_device = (hid_device*) device->interface;

            // Get a report struct to fill in:
            r = freeReportsPtr[deviceIndex];

            // Fetch the actual data: Bytes fetched, or zero for no reports available, or
            // -1 for error condition.
            r->error = hid_read((hid_device*) device->interface, &(r->report[0]), MaxDeviceReportSize[deviceIndex]);

            // Skip remainder if no data received:
            if (r->error == 0) continue;

            // Ok, we got something, even if it is only an error code. Need
            // to move the (r)eport from the free list to the received list:
            freeReportsPtr[deviceIndex] = r->next;
            r->next=NULL;
            
            // install report into the device's list.
            r->next = deviceReportsPtr[deviceIndex];
            deviceReportsPtr[deviceIndex] = r;
            
            // fill in the rest of the report struct
            r->deviceIndex = deviceIndex;
            
            // Timestamp processing:
            PsychGetPrecisionTimerSeconds(&r->time);

            // Success or error?
            if (r->error > 0) {
                // Success: Reset error, assign size of retrieved report:
                r->bytes = r->error;
                r->error = 0;
            }
            else {
                // Error: No data assigned.
                r->bytes = 0;
                
                // Signal error return code -1:
                error = -1;
                
                // Abort fetch loop:
                break;
            }

            if (optionsPrintReportSummary) {
                // print diagnostic summary of the report
                int serial;
                
                serial = r->report[62] + 256 * r->report[63]; // 32-bit serial number at end of AInScan report from PMD-1208FS
                printf("Got input report %4d: %2ld bytes, dev. %d, %4.0f ms. ", serial, (long) r->bytes, deviceIndex, 1000 * (r->time - AInScanStart));
                if(r->bytes>0) {
                    printf(" report ");
                    n = r->bytes;
                    if (n > 6) n=6;
                    for(i=0; i < (unsigned int) n; i++) printf("%3d ", (int) r->report[i]);
                    m = r->bytes - 2;
                    if (m > (int) i) {
                        printf("... ");
                        i = m;
                    }
                    for(; i < r->bytes; i++) printf("%3d ", (int) r->report[i]);
                }
                printf("\n");
            }
            CountReports("ReportCallback end.");
        }
    }
    
    CountReports("ReceiveReports end.");
    return error;
}
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);	
}
예제 #29
0
void PsychGiveUsageExit(void)
{  
	PrintfExit("Usage:\n\n%s",functionUseHELP);
}
예제 #30
0
void InitializeSynopsis()
{
	int i=0;
	const char **synopsis = synopsisSYNOPSIS;  //abbreviate the long name

	synopsis[i++] = "Usage:";

	// Open or close a window or texture:
	synopsis[i++] = "\n% Open or close a window or texture:";
	synopsis[i++] = "[windowPtr,rect]=Screen('OpenWindow',windowPtrOrScreenNumber [,color] [,rect] [,pixelSize] [,numberOfBuffers] [,stereomode]);";	
        synopsis[i++] = "[windowPtr,rect]=Screen('OpenOffscreenWindow',windowPtrOrScreenNumber [,color] [,rect] [,pixelSize]);";
	synopsis[i++] = "textureIndex=Screen('MakeTexture', WindowIndex, imageMatrix);";	
	synopsis[i++] = "Screen('Close', windowOrTextureIndex);";
	synopsis[i++] = "Screen('CloseAll');";
	
	// Draw lines lines solids like QuickDraw and DirectX (OS 9 and Windows)
	synopsis[i++] = "\n%  Draw lines and solids like QuickDraw and DirectX (OS 9 and Windows):";
	synopsis[i++] = "Screen('SelectStereoDrawBuffer', windowPtr, bufferid);";
	synopsis[i++] = "Screen('DrawLine', windowPtr [,color], fromH, fromV, toH, toV [,penWidth]);";
	synopsis[i++] = "Screen('FillRect', windowPtr [,color] [,rect] );";
	synopsis[i++] = "Screen('FrameRect', windowPtr [,color] [,rect] [,penWidth]);";
	synopsis[i++] = "Screen('FillOval', windowPtr [,color] [,rect]);";
	synopsis[i++] = "Screen('FrameOval', windowPtr [,color] [,rect] [,penWidth] [,penHeight] [,penMode]);";
	synopsis[i++] = "Screen('FillPoly', windowPtr [,color], pointList);";	
	
	
	// New OpenGL-based functions for OS X
	synopsis[i++] = "\n% New OpenGL functions for OS X:";
	synopsis[i++] = "Screen('glPoint', windowPtr, color, x, y [,size]);";
	synopsis[i++] = "Screen('gluDisk', windowPtr, color, x, y [,size]);";
	synopsis[i++] = "Screen('DrawDots', windowPtr, xy [,size] [,color] [,center] [,dot_type]);";
	synopsis[i++] = "Screen('DrawLines', windowPtr, xy [,width] ,colors [,center] [,smooth]);";
        synopsis[i++] = "[sourceFactorOld, destinationFactorOld]=('BlendFunction', windowIndex, [sourceFactorNew], [destinationFactorNew]);";

	// Draw Text in windows
	synopsis[i++] = "\n% Draw Text in windows";
	synopsis[i++] = "textModes = Screen('TextModes');";
	synopsis[i++] = "oldCopyMode=Screen('TextMode', windowPtr [,textMode]);";
	synopsis[i++] = "oldTextSize=Screen('TextSize', windowPtr [,textSize]);";
	synopsis[i++] = "oldStyle=Screen('TextStyle', windowPtr [,style]);";
	synopsis[i++] = "[oldFontName,oldFontNumber]=Screen(windowPtr,'TextFont' [,fontNameOrNumber]);";
	synopsis[i++] = "[normBoundsRect, offsetBoundsRect]=Screen('TextBounds', windowPtr, text);";
	synopsis[i++] = "[newX,newY]=Screen('DrawText', windowPtr, text [,x] [,y] [,color]);";
	synopsis[i++] = "oldTextColor=Screen('TextColor', windowPtr [,colorVector]);";
	synopsis[i++] = "oldTextBackgroundColor=Screen('TextBackgroundColor', windowPtr [,colorVector]);";
	
	// Copy an image, very quickly, between textures and onscreen windows
	synopsis[i++] = "\n% Copy an image, very quickly, between textures and onscreen windows.";
	synopsis[i++] = "Screen('DrawTexture', windowPointer, texturePointer [,sourceRect] [,destinationRect] [,rotationAngle] [, filterMode] [, globalAlpha]);";	

	// Copy an image, slowly, between matrices and windows
	synopsis[i++] = "\n% Copy an image, slowly, between matrices and windows :";
	synopsis[i++] = "imageArray=Screen('GetImage', windowPtr [,rect] [,bufferName]);";
	synopsis[i++] = "Screen('PutImage', windowPtr, imageArray [,rect]);";
	
	// Synchronize with the window's screen (on-screen only):
	synopsis[i++] = "\n% Synchronize with the window's screen (on-screen only):";
	synopsis[i++] = "[VBLTimestamp StimulusOnsetTime FlipTimestamp Missed Beampos] = Screen('Flip', windowPtr [, when] [, dontclear] [, dontsync] [, multiflip]);";
        synopsis[i++] = "[telapsed] = Screen('DrawingFinished', windowPtr [, dontclear] [, sync]);";

	// Load color lookup table of the window's screen (on-screen only)
	synopsis[i++] = "\n% Load color lookup table of the window's screen (on-screen only):";
	synopsis[i++] = "Screen('ReadNormalizedGammaTable', windowPtrOrScreenNumber);";
	synopsis[i++] = "Screen('LoadNormalizedGammaTable', windowPtrOrScreenNumber, table);";
		
	// Get and set information about a window or screen.
	synopsis[i++] = "\n% Get (and set) information about a window or screen:";
	synopsis[i++] = "screenNumbers=Screen('Screens);";	
	synopsis[i++] = "windowPtrs=Screen('Windows');";
	synopsis[i++] = "kind=Screen(windowPtr, 'WindowKind');";
	synopsis[i++] = "isOffscreen=Screen(windowPtr,'IsOffscreen');";
	synopsis[i++] = "hz=Screen('FrameRate', windowPtrOrScreenNumber);";	
	synopsis[i++] = "hz=Screen('NominalFrameRate', windowPtrOrScreenNumber);";	
	synopsis[i++] = "[ monitorFlipInterval nrValidSamples stddev ]=Screen('GetFlipInterval', windowPtr [, nrSamples] [, stddev] [, timeout]);";
        synopsis[i++] = "screenNumber=Screen('WindowScreenNumber', windowPtr);";
	synopsis[i++] = "rect=Screen('Rect', windowPtrOrScreenNumber);";
	synopsis[i++] = "pixelSize=Screen('PixelSize', windowPtrOrScreenNumber);";
	synopsis[i++] = "pixelSizes=Screen('PixelSizes', windowPtrOrScreenNumber);";
	synopsis[i++] = "[width, height]=Screen('WindowSize', windowPointerOrScreenNumber);";

	
	// Get and set information about the environment, computer, and video card (i.e. screen):
	synopsis[i++] = "\n% Get/set details of environment, computer, and video card (i.e. screen):";
	synopsis[i++] = "struct=Screen('Version');";
	synopsis[i++] = "comp=Screen('Computer');";
	synopsis[i++] = "oldBool=Screen('Preference', 'IgnoreCase' [,bool]);";
	synopsis[i++] = "tick0Secs=Screen('Preference', 'Tick0Secs', tick0Secs);";
	synopsis[i++] = "psychTableVersion=Screen('Preference', 'PsychTableVersion');";
	synopsis[i++] = "mexFunctionName=Screen('Preference', 'PsychTableCreator');";
	synopsis[i++] = "proc=Screen('Preference', 'Process');";   
	synopsis[i++] = "oldBool=Screen('Preference','Backgrounding');";
	synopsis[i++] = "oldSecondsMultiplier=Screen('Preference', 'SecondsMultiplier');";
	synopsis[i++] = "Screen('Preference','SkipSyncTests', skipTest);";
	synopsis[i++] = "Screen('Preference','VisualDebugLevel', level (valid values between 0 and 5));";
        synopsis[i++] = "Screen('Preference', 'ConserveVRAM', mode (valid values between 0 and 3));";
		
	//synopsis[i++] = "\n% Set clipping region (on- or off- screen):";
	
	// Helper functions.  Don't call these directly, use eponymous wrappers.
	synopsis[i++] = "\n% Helper functions.  Don't call these directly, use eponymous wrappers:";
	synopsis[i++] ="[x, y, buttonVector]= Screen('GetMouseHelper', numButtons);";
	synopsis[i++] = "Screen('HideCursorHelper', windowPntr);";
	synopsis[i++] = "Screen('ShowCursorHelper', windowPntr);";
	synopsis[i++] = "Screen('SetMouseHelper', windowPntrOrScreenNumber, x, y);";
	
	// Internal testing of Screen
	synopsis[i++] = "\n% Internal testing of Screen";
	synopsis[i++] =  "timeList= Screen('GetTimelist');";
	synopsis[i++] =  "Screen('ClearTimelist');";
	synopsis[i++] =  "Screen('Preference','DebugMakeTexture', enableDebugging);";
	
	synopsis[i++] = NULL;  //this tells PsychDisplayScreenSynopsis where to stop
	if (i > MAX_SYNOPSIS_STRINGS) {
		PrintfExit("%s: increase dimension of synopsis[] from %ld to at least %ld and recompile.",__FILE__,(long)MAX_SYNOPSIS_STRINGS,(long)i);
	}
}