PsychError EyelinkGetTrackerVersion(void)
{
	int iVersion=0;
	char strVersion[40]="unknown tracker type";
	
	//all sub functions should have these two lines
	PsychPushHelp(useString, synopsisString, seeAlsoString);
	if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
	
	//check to see if the user supplied superfluous arguments
	PsychErrorExit(PsychCapNumInputArgs(0));
	PsychErrorExit(PsychRequireNumInputArgs(0));
	PsychErrorExit(PsychCapNumOutputArgs(2));
	
//	// Verify eyelink is up and running
//	EyelinkSystemIsConnected();
//	EyelinkSystemIsInitialized();
	
	iVersion = eyelink_get_tracker_version(strVersion);
	
	//   mexPrintf("Tracker Version: '%s'\n", strVersion );
	PsychCopyOutDoubleArg(1, TRUE, iVersion);
	PsychCopyOutCharArg(2, FALSE, strVersion);
	
	return(PsychError_none);	
}
PsychError COCOAEVENTBRIDGEPathToBundle(void) 
{

	Boolean						isNewArgThereFlag;
	int							newNameLength;
	char						*tempBundleFilePathNameStr, *localBundleFilePathNameStr;
	

	//all subfunctions should have these two lines.  
	PsychPushHelp(useString, synopsisString, seeAlsoString);
	if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};

    //check to see if the user supplied superfluous arguments
    PsychErrorExit(PsychCapNumOutputArgs(1));
    PsychErrorExit(PsychCapNumInputArgs(1));
	
	//first copy out the old path 
	GetPathToBundleString(&localBundleFilePathNameStr);
	PsychCopyOutCharArg(1, kPsychArgOptional, localBundleFilePathNameStr);
	
	//read in and retain the new name.  It arrives in a temporary variable
	isNewArgThereFlag=PsychAllocInCharArg(1, kPsychArgOptional, &tempBundleFilePathNameStr);
	if(isNewArgThereFlag){
		newNameLength=strlen(tempBundleFilePathNameStr);
		if(bundleFilePathNameStr != NULL)
			free((void*)bundleFilePathNameStr);
		bundleFilePathNameStr=(char*)malloc(sizeof(char) * (newNameLength + 1));
		strncpy(bundleFilePathNameStr, tempBundleFilePathNameStr, newNameLength + 1);
	}
		
    return(PsychError_none);	
}
PsychError SCREENTextFont(void) 
{

    boolean			doSetByName, doSetByNumber, foundFont;
    PsychWindowRecordType	*windowRecord;
    PsychFontStructType		*fontRecord;
    int				oldTextFontNumber, inputTextFontNumber;
    char			*oldTextFontName, *inputTextFontName;
    
    //all subfunctions should have these two lines.  
    PsychPushHelp(useString, synopsisString, seeAlsoString);
    if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
    
    //check for valid number of arguments
    PsychErrorExit(PsychRequireNumInputArgs(1));
    PsychErrorExit(PsychCapNumInputArgs(2));   	
    PsychErrorExit(PsychCapNumOutputArgs(2)); 
    
    //Get the window record
    PsychAllocInWindowRecordArg(kPsychUseDefaultArgPosition, TRUE, &windowRecord);
    
    //Save the old text size value and return it.
    oldTextFontNumber=windowRecord->textAttributes.textFontNumber;
    PsychCopyOutDoubleArg(2, FALSE, (double)oldTextFontNumber);
    oldTextFontName=windowRecord->textAttributes.textFontName;
    PsychCopyOutCharArg(1, FALSE, oldTextFontName); 
    
	
    //Fetch and set the new font if specified by name or number
    PsychCheckInputArgType(2, kPsychArgOptional, PsychArgType_double | PsychArgType_char);  //if the argument is there check that it is the right type.
    doSetByNumber= PsychCopyInIntegerArg(2, kPsychArgAnything, &inputTextFontNumber);
    doSetByName= PsychAllocInCharArg(2, kPsychArgAnything, &inputTextFontName);
    foundFont=0;
    if(doSetByNumber)
        foundFont=PsychGetFontRecordFromFontNumber(inputTextFontNumber, &fontRecord);
    if(doSetByName)
        foundFont=PsychGetFontRecordFromFontFamilyNameAndFontStyle(inputTextFontName, windowRecord->textAttributes.textStyle, &fontRecord);
    if(foundFont){
        strncpy(windowRecord->textAttributes.textFontName, fontRecord->fontFMFamilyName, 255);
        windowRecord->textAttributes.textFontNumber= fontRecord->fontNumber;
    }
    
    return(PsychError_none);

}
PsychError SCREENTextMode(void) 
{

    PsychTextDrawingModeType		newCopyMode;
    Str255							oldCopyModeName; 
    char							*newCopyModeName;
    psych_bool							doSetMode;
    PsychWindowRecordType			*windowRecord;
    psych_bool							nameError;                           
    
    //all subfunctions should have these two lines.  
    PsychPushHelp(useString, synopsisString, seeAlsoString);
    if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
    
    //check for valid number of arguments
    PsychErrorExit(PsychRequireNumInputArgs(1));
    PsychErrorExit(PsychCapNumInputArgs(2));   	
    PsychErrorExit(PsychCapNumOutputArgs(1)); 
    
    //Get the window record
    PsychAllocInWindowRecordArg(kPsychUseDefaultArgPosition, TRUE, &windowRecord);
    
    //Get the old copy mode & its name
    PsychGetTextDrawingModeNameFromTextDrawingModeConstant(oldCopyModeName, 255, windowRecord->textAttributes.textMode);
    PsychCopyOutCharArg(1, FALSE, oldCopyModeName);
    
    //Get the copy new mode string 
    doSetMode= PsychAllocInCharArg(2, FALSE, &newCopyModeName);
    if(doSetMode){
        nameError=PsychGetTextDrawingModeConstantFromTextDrawingModeName(&newCopyMode, newCopyModeName);
        if(nameError)
            PsychErrorExitMsg(PsychError_user, "Invalid text copy mode.  See Screen('TextModes') for a list of allowable modes");
		windowRecord->textAttributes.needsRebuild|=(windowRecord->textAttributes.textMode != newCopyMode) ? TRUE : FALSE;
        windowRecord->textAttributes.textMode=newCopyMode;	
    }
	
    return(PsychError_none);
}
示例#5
0
PsychError SCREENNull(void) 

{

	const double defaultMatrix[] = {1.1, 1.2, 1.3, 1.4, 2.1, 2.2, 2.3, 2.4};

	const double defaultM=2, defaultN=4; 

	double tempValue; 

	double *array;

	int i, m,n, p, numInArgs, numOutArgs, numNamedOutArgs;

	char *str;

	PsychArgFormatType format;

	const char defaultString[] = "I am the default string\n";

	





	//all sub functions should have these two lines

	PsychPushHelp(useString, synopsisString, seeAlsoString);

	if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};



	//demonstrate how we find the function and subfunction names

	//printf("Psychtoolbox function: %s, subfunction %s\n", PsychGetModuleName(), PsychGetFunctionName() );



	//copy all the input argument to their outputs if we have doubles, if not error.  

	numInArgs = PsychGetNumInputArgs();

	numOutArgs = PsychGetNumOutputArgs();

	numNamedOutArgs = PsychGetNumNamedOutputArgs();

	

	PsychErrorExit(PsychCapNumOutputArgs(numInArgs));

	

	

	/*

	printf("number of input arguments: %d\n", numInArgs);

	printf("number of output arguments: %d\n", numOutArgs);

	printf("number of named output arguments: %d\n", numNamedOutArgs);

	*/

	

		

	

	//iterate over each of the supplied inputs.  If the input is a two-dimensional array 

	//of doubles or a character array, then copy it to the output.  

	for(i=1;i<=numInArgs;i++){

		format = PsychGetArgType(i);

		switch(format){

			case PsychArgType_double:

				if(PsychGetArgM(i)==1 && PsychGetArgN(i)==1){

					tempValue=i;  //if 1x1 double then the default return value is the arg position.

					PsychCopyInDoubleArg(i, FALSE, &tempValue);

					PsychCopyOutDoubleArg(i, FALSE, tempValue);

				}else{

					PsychAllocInDoubleMatArg(i, FALSE, &m, &n, &p, &array);

					PsychCopyOutDoubleMatArg(i, FALSE, m, n, p, array);

				}

				break;

			case PsychArgType_char:

				str=NULL; //This tells PsychGetCharArg() to use its own (volatile) memory. 

				PsychAllocInCharArg(i, FALSE, &str); 

				PsychCopyOutCharArg(i, FALSE, str);

				break;

			case PsychArgType_default:

				PsychCopyOutCharArg(i, FALSE, defaultString);

				break;

		}

	}

		

	return(PsychError_none);

}
PsychError SCREENPreference(void)  
{

	PsychArgFormatType		arg1Type;
	char					*preferenceName, *newFontName;
	const char				*tableCreator, *oldDefaultFontName;
	Boolean					preferenceNameArgumentValid, booleanInput, ignoreCase, tempFlag, textAlphaBlendingFlag, suppressAllWarningsFlag;
	int						numInputArgs, i, newFontStyleNumber, newFontSize, tempInt;
	double					returnDoubleValue, inputDoubleValue;
	
	//all sub functions should have these two lines
	PsychPushHelp(useString, synopsisString,seeAlsoString);
	if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
	
	//check for superfluous or missing arguments
	PsychErrorExit(PsychCapNumInputArgs(3));			
	PsychErrorExit(PsychRequireNumInputArgs(1));		   
	PsychErrorExit(PsychCapNumOutputArgs(1));
	
	numInputArgs=PsychGetNumInputArgs();
	arg1Type=PsychGetArgType(1);
	preferenceNameArgumentValid=FALSE;
	
	//Cases which require both a window pointer or screen number and preference name.  Argument 1 is the wposn and argument 2 is the preference name.
	if( numInputArgs >= 2 && (PsychIsScreenNumberArg(1) || PsychIsScreenNumberArg(1)) && PsychGetArgType(2)==PsychArgType_char ){
		PsychAllocInCharArg(2, kPsychArgRequired, &preferenceName);
		//preferences which require window pointer or screen number argument which we DO NOT support  
		for(i=0;i<kPsychNumUnsupportedMacVideoPreferences;i++){
			if(PsychMatch(preferenceName, unsupportedMacVideoPreferenceNames[i]))
				PsychErrorExit(PsychError_unsupportedOS9Preference);
		}
		//insert here conditionals  to act on prefernces which accept a window pointer or screen number argument which we DO support.
		PsychErrorExit(PsychError_unrecognizedPreferenceName);
	}

	//Cases which do not require a wposn.  Argument 1 is the preference name.  if present Argument 2 is the new value
	if(arg1Type==PsychArgType_char){
		PsychAllocInCharArg(1, kPsychArgRequired, &preferenceName);
		//Preferernces which we do not support and which do not require a wposn
		for(i=0;i<kPsychNumUnsupportedMacNonVideoPreferences;i++){
			if(PsychMatch(preferenceName, unsupportedMacNonVideoPreferenceNames[i]))
				PsychErrorExit(PsychError_unsupportedOS9Preference);
		}
		//Preferences which we do support
		if(PsychMatch(preferenceName, "IgnoreCase")){
			ignoreCase=!PsychIsPsychMatchCaseSensitive();
			PsychCopyOutFlagArg(1, kPsychArgOptional, ignoreCase);
			if(numInputArgs==2){
				PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput);
				PsychSetPsychMatchCaseSenstive(!booleanInput);			
			}
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "Tick0Secs")){
			if(PsychCopyInDoubleArg(2, kPsychArgOptional, &inputDoubleValue) && inputDoubleValue==PsychGetNanValue())
				PsychEstimateGetSecsValueAtTickCountZero();
			returnDoubleValue=PsychGetEstimatedSecsValueAtTickCountZero();
			PsychCopyOutDoubleArg(1, kPsychArgOptional, returnDoubleValue);
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "PsychTableVersion")){
			if(numInputArgs==2)
				PsychErrorExit(PsychError_extraInputArg);
			PsychCopyOutDoubleArg(1, kPsychArgOptional, (double)PsychPrefStateGet_PsychTableVersion());
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "PsychTableCreator")){
			if(numInputArgs==2)
				PsychErrorExit(PsychError_extraInputArg);
			tableCreator=PsychPrefStateGet_PsychTableCreator();
			PsychCopyOutCharArg(1, kPsychArgOptional, tableCreator);
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "Process")){
			if(numInputArgs==2)
				PsychErrorExit(PsychError_extraInputArg);
			PsychCopyOutDoubleArg(1, kPsychArgOptional, (double)getpid());
			preferenceNameArgumentValid=TRUE;


		}else 
		if(PsychMatch(preferenceName, "DefaultFontName")){
			PsychPrefStateGet_DefaultFontName(&oldDefaultFontName);
			PsychCopyOutCharArg(1, kPsychArgOptional, oldDefaultFontName);
			if(numInputArgs==2){
				PsychAllocInCharArg(2, kPsychArgRequired, &newFontName);
				PsychPrefStateSet_DefaultFontName(newFontName);
			}
			preferenceNameArgumentValid=TRUE;
			
		}else 
		if(PsychMatch(preferenceName, "DefaultFontStyle")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DefaultTextStyle());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &newFontStyleNumber);
				PsychPrefStateSet_DefaultTextStyle(newFontStyleNumber);
			}
			preferenceNameArgumentValid=TRUE;
		}else
		if(PsychMatch(preferenceName, "DefaultTextYPositionIsBaseline")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_TextYPositionIsBaseline());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				PsychPrefStateSet_TextYPositionIsBaseline(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "DefaultFontSize")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DefaultTextSize());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &newFontSize);
				PsychPrefStateSet_DefaultTextSize(newFontSize);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "DebugMakeTexture")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DebugMakeTexture());
			if(numInputArgs==2){
				PsychCopyInFlagArg(2, kPsychArgRequired, &tempFlag);
				PsychPrefStateSet_DebugMakeTexture(tempFlag);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "SkipSyncTests")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_SkipSyncTests());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				PsychPrefStateSet_SkipSyncTests(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "VisualDebugLevel")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VisualDebugLevel());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				PsychPrefStateSet_VisualDebugLevel(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "VBLTimestampingMode")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VBLTimestampingMode());
			if(numInputArgs==2){
                            PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
                            PsychPrefStateSet_VBLTimestampingMode(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "ConserveVRAM")){
					PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_ConserveVRAM());
					if(numInputArgs==2){
						PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
						PsychPrefStateSet_ConserveVRAM(tempInt);
					}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "Verbosity")){
					PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_Verbosity());
					if(numInputArgs==2){
						PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
						PsychPrefStateSet_Verbosity(tempInt);
					}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "EmulateOldPTB")){
				PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_EmulateOldPTB());
				if(numInputArgs==2){
					PsychCopyInFlagArg(2, kPsychArgRequired, &tempFlag);
					PsychPrefStateSet_EmulateOldPTB(tempFlag);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "Enable3DGraphics")){
				PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_3DGfx());
				if(numInputArgs==2){
					PsychCopyInFlagArg(2, kPsychArgRequired, &tempFlag);
					PsychPrefStateSet_3DGfx(tempFlag);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "TextAlphaBlending")){
				textAlphaBlendingFlag=PsychPrefStateGet_TextAlphaBlending();
				PsychCopyOutFlagArg(1, kPsychArgOptional, textAlphaBlendingFlag);
				if(numInputArgs==2){
					PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput);
					PsychPrefStateSet_TextAlphaBlending(booleanInput);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "SuppressAllWarnings")){
				suppressAllWarningsFlag=PsychPrefStateGet_SuppressAllWarnings();
				PsychCopyOutFlagArg(1, kPsychArgOptional, suppressAllWarningsFlag);
				if(numInputArgs==2){
					PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput);
					PsychPrefStateSet_SuppressAllWarnings(booleanInput);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			PsychErrorExit(PsychError_unrecognizedPreferenceName);
	}
	
	if(!preferenceNameArgumentValid)
		PsychErrorExitMsg(PsychError_user, "Invalid arguments to preferences command");
		
	return(PsychError_none);
}
示例#7
0
PsychError IOPORTWrite(void)
{
 	static char useString[] = "[nwritten, when, errmsg, prewritetime, postwritetime, lastchecktime] = IOPort('Write', handle, data [, blocking=1]);";
	static char synopsisString[] = 
		"Write data to device, specified by 'handle'.\n"
		"'data' must be a vector of data items to write, or a matrix (in which case data "
		"in the matrix will be transmitted in column-major order, ie., first the first "
		"column, then the 2nd column etc...), either with data elements of uint8 class "
		"or a (1 Byte per char) character string. The optional flag 'blocking' if "
		"set to 0 will ask the write function to not block, but return immediately, ie. "
		"data is sent/written in the background while your code continues to execute - There "
		"may be an arbitrary delay until data transmission is really finished. The default "
		"setting is 1, ie. blocking writes - The function waits until data transmission is really "
		"finished. You can also use blocking == 2 to request a different mode "
		"for blocking writes, where IOPort is polling for write-completion instead of "
		"a more cpu friendly wait. This may decrease latency for certain applications. "
		"Another even more agressive polling method is implemented via blocking == 3 on "
		"Linux systems with some limited set of hardware, e.g., real native serial ports.\n"
		"On systems without any support for specific polling modes, the 2 or 3 settings are treated "
		"as a standard blocking write.\n\n"
		"Optionally, the function returns the following return arguments:\n"
		"'nwritten' Number of bytes written -- Should match amount of data provided on success.\n"
		"'when' A timestamp of write completion: This is only meaningful in blocking mode!\n"
		"'errmsg' A system defined error message if something wen't wrong.\n"
		"The following three timestamps are for low-level debugging and special purpose:\n"
		"'prewritetime' A timestamp taken immediately before submitting the write request. "
		"'postwritetime' A timestamp taken immediately after submitting the write request. "
		"'lastchecktime' A timestamp taken at the time of last check for write completion if applicable. ";
		
	static char seeAlsoString[] = "";
	
	char			errmsg[1024];
	int				handle, blocking, m, n, p, nwritten;
	psych_uint8*	inData = NULL;
	char*			inChars = NULL;
	void*			writedata = NULL;
	double			timestamp[4] = {0, 0, 0, 0};
	errmsg[0] = 0;

	// Setup online help: 
	PsychPushHelp(useString, synopsisString, seeAlsoString);
	if(PsychIsGiveHelp()) {PsychGiveHelp(); return(PsychError_none); };
	
	PsychErrorExit(PsychCapNumInputArgs(3));     // The maximum number of inputs
	PsychErrorExit(PsychRequireNumInputArgs(2)); // The required number of inputs	
	PsychErrorExit(PsychCapNumOutputArgs(6));	 // The maximum number of outputs

	// Get required port handle:
	PsychCopyInIntegerArg(1, kPsychArgRequired, &handle);

	// Get the data:
	switch(PsychGetArgType(2)) {
		case PsychArgType_uint8:
			PsychAllocInUnsignedByteMatArg(2, kPsychArgRequired, &m, &n, &p, &inData);
			if (p!=1 || m * n == 0) PsychErrorExitMsg(PsychError_user, "'data' is not a vector or 2D matrix, but some higher dimensional matrix!");
			n = m * n;
			writedata = (void*) inData;
		break;
		
		case PsychArgType_char:
			PsychAllocInCharArg(2, kPsychArgRequired, &inChars);
			n = strlen(inChars);
			writedata = (void*) inChars;
		break;
		
		default:
			PsychErrorExitMsg(PsychError_user, "Invalid type for 'data' vector: Must be an uint8 or char vector.");
	}
	
	
	// Get optional blocking flag: Defaults to one -- blocking.
	blocking = 1;
	PsychCopyInIntegerArg(3, kPsychArgOptional, &blocking);

	// Write data:
	nwritten = PsychWriteIOPort(handle, writedata, n, blocking, errmsg, &timestamp[0]);
	if (nwritten < 0 && verbosity > 0) printf("IOPort: Error: %s\n", errmsg); 
	
	PsychCopyOutDoubleArg(1, kPsychArgOptional, nwritten);
	PsychCopyOutDoubleArg(2, kPsychArgOptional, timestamp[0]);
	PsychCopyOutCharArg(3, kPsychArgOptional, errmsg);
	PsychCopyOutDoubleArg(4, kPsychArgOptional, timestamp[1]);
	PsychCopyOutDoubleArg(5, kPsychArgOptional, timestamp[2]);
	PsychCopyOutDoubleArg(6, kPsychArgOptional, timestamp[3]);
	
    return(PsychError_none);
}
示例#8
0
PsychError IOPORTRead(void)
{
 	static char useString[] = "[data, when, errmsg] = IOPort('Read', handle [, blocking=0] [, amount]);";
	static char synopsisString[] = 
		"Read data from device, specified by 'handle'.\n"
		"Returned 'data' will be a row vector of read data bytes. 'when' will be a receive "
		"timestamp of when the data read was complete. 'errmsg' will be a human readable "
		"char string with an error message if any error occured, otherwise an empty string. "
		"The optional flag 'blocking' if set to 0 will ask the read function to not block, "
		"but return immediately: The read function will return whatever amount of data is "
		"currently available in the internal input queue, but at most 'amount' bytes if 'amount' "
		"is specified. If no data is available, it will return an empty matrix. This is the default.\n"
		"If 'blocking' is set to 1, you must specify the 'amount' of bytes to receive and the "
		"function will wait until that exact amount of data is available, then return it."
		"Even in blocking mode, the function will return if no data becomes available within "
		"the time period specified by the configuration setting 'ReadTimeout' (see help for "
		"'OpenSerialPort' for description). In some situations, the read function may return "
		"less data than requested, e.g., in specific error cases, where a read could only "
		"get partially satisfied.";
		
	static char seeAlsoString[] = "'Write', 'OpenSerialPort', 'ConfigureSerialPort'";
	
	char			errmsg[1024];
	int				handle, blocking, nread, amount, i;
	psych_uint8*	readbuffer;
	double*			outbuffer;
	double			timestamp;	
	errmsg[0] = 0;
	
	// Setup online help: 
	PsychPushHelp(useString, synopsisString, seeAlsoString);
	if(PsychIsGiveHelp()) {PsychGiveHelp(); return(PsychError_none); };
	
	PsychErrorExit(PsychCapNumInputArgs(3));     // The maximum number of inputs
	PsychErrorExit(PsychRequireNumInputArgs(1)); // The required number of inputs	
	PsychErrorExit(PsychCapNumOutputArgs(3));	 // The maximum number of outputs

	// Get required port handle:
	PsychCopyInIntegerArg(1, kPsychArgRequired, &handle);
	
	// Get optional blocking flag: Defaults to 0 -- non-blocking.
	blocking = 0;
	PsychCopyInIntegerArg(2, kPsychArgOptional, &blocking);

	// Get optional maximum or exact amount to read:
	amount = INT_MAX;
	if (!PsychCopyInIntegerArg(3, kPsychArgOptional, &amount)) {
		// Not spec'd:
		if (blocking > 0) PsychErrorExitMsg(PsychError_user, "When issuing a 'Read' in blocking mode, you must specify the exact 'amount' to read, but 'amount' was omitted!");
	}
	
	if (amount < 0) PsychErrorExitMsg(PsychError_user, "Invalid (negative) 'amount' of data to read!");
	
	// Read data:
	nread = PsychReadIOPort(handle, (void**) &readbuffer, amount, blocking, errmsg, &timestamp);
	
	// Allocate outbuffer of proper size:
	PsychAllocOutDoubleMatArg(1, kPsychArgOptional, 1, ((nread >=0) ? nread : 0), 1, &outbuffer);

	// Copy to outbuffer: We copy our uint8 values to a double matrix. This is arguably a bit of a waste of
	// memory and bandwidth, but it simplifies interfacing with Octave, old Matlab versions and possible
	// future runtime environments a lot:
	if (nread > 0) for (i=0; i<nread; i++) outbuffer[i] = readbuffer[i];
	
	if (nread < 0 && verbosity > 0) printf("IOPort: Error: %s\n", errmsg); 

	// Return timestamp and errmsg, if any:
	PsychCopyOutDoubleArg(2, kPsychArgOptional, timestamp);
	PsychCopyOutCharArg(3, kPsychArgOptional, errmsg);
	
    return(PsychError_none);
}
示例#9
0
// Open a serial port on a serial port device:
PsychError IOPORTOpenSerialPort(void)
{
 	static char useString[] = "[handle, errmsg] = IOPort('OpenSerialPort', port [, configString]);";
	static char synopsisString[] = 
		"Open a serial port device, return a 'handle' to it.\n"
		"If a port can't be opened, the function will abort with error, unless the "
		"level of verbosity is set to zero, in which case the function will silently "
		"fail, but return an invalid (negative) handle to signal the failure to the "
		"calling script. The optional return argument 'errmsg' contains a text string "
		"which is either empty on success, or contains a descriptive error message. \n"
		"'port' is usually a name string that defines the serial port device "
		"to open. On MS-Windows this could be, e.g., 'COM1' or 'COM2' etc. On "
		"Apple OS/X, it is the path to a BSD device file, e.g., '/dev/cu.usbserial-FT3Z95V5' "
		"for a serial-over-USB device with unique id FT3Z95V5. On GNU/Linux it could be "
		"'/dev/ttyS0' for the first real serial port, or '/dev/ttyUSB0' for the first "
		"serial-over-USB device.\n\n"
		"The optional string 'configString' is a string with pairs of paramName=paramValue "
		"tokens, separated by a delimiter, e.g., a space. It allows to specify specific "
		"values 'paramValue' to specific serial port parameters 'paramName'. Not all "
		"parameters are supported by all operating systems, and all settings have reasonable "
		"defaults. Settings unknown to a specific operating system are ignored.\n"
		"The following is a list of (possibly) supported parameters with their defaults:\n\n"
		"BaudRate=9600 -- The baud transmission rate of the connection. Standard baud rates include "
		"110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200, 128000 and "
		"256000 bits per second. Not all values may be supported by all operating systems and drivers.\n\n"
		"Parity=None   -- Type of parity checking: None, Even, Odd.\n\n"
		"DataBits=8    -- Number of data bits per packet: 5,6,7 or 8, on Windows also 16.\n\n"
		"StopBits=1    -- Number of stop bits per packet: 1 or 2.\n\n"
		"FlowControl=None  -- Type of flow control: None, Hardware (RTS/CTS lines), Software (XON/XOFF characters).\n\n"
		"Terminator=os default  -- Type of terminator, given as ASCII character value, e.g., 13 for char(13) aka CR. Currently unused\n\n"
		"DTR=os default	-- Setting for 'Data Terminal Ready' pin: 0 or 1.\n\n"
		"RTS=os default	-- Setting for 'Request To Send' pin: 0 or 1.\n\n"
		"BreakBehaviour=Ignore -- Behaviour if a 'Break Condition' is detected on the line: Ignore, Flush, Zero. On Windows, this setting is ignored.\n\n"
		"OutputBufferSize=4096 -- Size of output buffer in bytes.\n\n"
		"InputBufferSize=4096 -- Size of input buffer in bytes. You can't read more than that amount per read command.\n\n"
		"HardwareBufferSizes=input,output -- Set size of the hardware driver internal input and output buffers in bytes. "
		"E.g., HardwareBufferSizes=32768,8192 would set the input buffer to 32768 bytes and the output buffer to 8192 bytes. "
		"This function is currently only supported on Windows, ignored on other systems. It is only a polite hint to the driver, "
		"the serial port driver is free to ignore the request and choose any buffer sizes or buffering strategy it finds appropriate. "
		"By default, this parameter is not set by IOPort and the hardware driver uses some built-in reasonable setting.\n\n"
		"The following timeout values are inter-byte timeouts. You specify how much time reception or "
		"transmission of a single byte is allowed to take. Timeout occurs if more than that time elapses "
		"between send/reception of two consecutive bytes or if the total amount of time exceeds the "
		"number of bytes, times the interbyte timeout value. A value of zero means not to use any timeout, "
		"in which case a blocking read or write may take forever. If a timeout occurs, the read or write "
		"operation will be aborted. \n"
		"Granularity of timeout settings is 100 msecs on OS/X and Linux, 1 msec on Windows, all values "
		"are rounded to the closest value matching that granularity. The minimal timeout is 100 msecs "
		"on OS/X and Linux, about 6 msecs on Windows.\n\n"
		"SendTimeout=1.0 -- Interbyte send timeout in seconds. Only used on Windows.\n\n"
		"ReceiveTimeout=1.0 -- Interbyte receive timeout in seconds.\n\n"
		"ReceiveLatency=0.000001 -- Latency in seconds for processing of new input bytes. Only used on OS/X.\n\n"
		"PollLatency=0.0005 (0.005 on Windows) -- Latency between polls in seconds for polling in some 'Read' operations.\n\n"
		"ProcessingMode=Raw -- Mode of input/output processing: Raw or Cooked. On Windows, only Raw (binary) mode is supported.\n\n"
		"StartBackgroundRead=readGranularity -- Enable asynchronous background read operations on the port. This is only supported "
		"on Linux and OS/X for now. A parallel background thread is started which tries to fetch 'readGranularity' bytes of data, "
		"polling the port every 'PollLatency' seconds for at least 'readGranularity' bytes of data. 'InputBufferSize' must be an "
		"integral multiple of 'readGranularity' for this to work. Later IOPort('Read') commands will pull collected data from "
		"the InputBuffer in quanta of at most 'readGranularity' bytes per invocation. This function is useful for background "
		"data collection from devices that stream some data at a constant rate. You set up background read, let the parallel "
		"thread do all data collection in the background and collect the data at the end of a session with a sequence of "
		"IOPort('Read') calls. This way, data collection doesn't clutter your main experiment script.\n\n"
		"StopBackgroundRead -- Stop running background read operation, discard all pending data.\n\n";

	static char seeAlsoString[] = "'CloseAll'";	 
  	
	#if PSYCH_SYSTEM == PSYCH_WINDOWS
	// Difference to Unices: PollLatency defaults to 5 msecs instead of 0.5 msecs due to shoddy windows scheduler:
	static char defaultConfig[] = "BaudRate=9600 Parity=None DataBits=8 StopBits=1 FlowControl=None PollLatency=0.005 ReceiveLatency=0.000001 SendTimeout=1.0 ReceiveTimeout=1.0 ProcessingMode=Raw BreakBehaviour=Ignore OutputBufferSize=4096 InputBufferSize=4096"; 
	#else
	static char defaultConfig[] = "BaudRate=9600 Parity=None DataBits=8 StopBits=1 FlowControl=None PollLatency=0.0005 ReceiveLatency=0.000001 SendTimeout=1.0 ReceiveTimeout=1.0 ProcessingMode=Raw BreakBehaviour=Ignore OutputBufferSize=4096 InputBufferSize=4096"; 
	#endif
	
	char		finalConfig[2000];
	char		errmsg[1024];
	char*		portSpec = NULL;
	char*		configString = NULL;
	PsychSerialDeviceRecord* device = NULL;
	int			handle;
	
	// Setup online help: 
	PsychPushHelp(useString, synopsisString, seeAlsoString);
	if(PsychIsGiveHelp()) {PsychGiveHelp(); return(PsychError_none); };
	
	PsychErrorExit(PsychCapNumInputArgs(2));     // The maximum number of inputs
	PsychErrorExit(PsychRequireNumInputArgs(1)); // The required number of inputs	
	PsychErrorExit(PsychCapNumOutputArgs(2));	 // The maximum number of outputs

	// Get required portSpec:
	PsychAllocInCharArg(1, kPsychArgRequired, &portSpec);
	
	// Get the optional configString:
	if (!PsychAllocInCharArg(2, kPsychArgOptional, &configString)) {
		// No config string specified: Assign default string:
		sprintf(finalConfig, "%s", defaultConfig);
	}
	else {
		// Config string provided: Prepend it to default string. That way, all settings
		// spec'd by usercode will override the defaultConfig, but non-specified settings
		// will be provided by defaultConfig:
		sprintf(finalConfig, "%s %s", configString, defaultConfig);		
	}
	
	// Search for a free slot:
	if (portRecordCount >= PSYCH_MAX_IOPORTS) PsychErrorExitMsg(PsychError_user, "Maximum number of open Input/Output ports exceeded.");
	
	// Iterate until end or free slot:
	for (handle=0; (handle < PSYCH_MAX_IOPORTS) && (portRecordBank[handle].portType); handle++);
	if (portRecordBank[handle].portType) PsychErrorExitMsg(PsychError_user, "Maximum number of open Input/Output ports exceeded.");
	// handle is index into our port record...

	// Call OS specific open routine for serial port:
	device = PsychIOOSOpenSerialPort(portSpec, finalConfig, errmsg);

	// Copy out optional errmsg string:
	PsychCopyOutCharArg(2, kPsychArgOptional, errmsg);
	
	if (device == NULL) {
		// Special case: Could not open port, but verbosity level is zero, no conventional
		// error return possible as this would clutter the console with output. Simply cancel
		// open op and return a negative handle to signal failure to user code:
		PsychCopyOutDoubleArg(1, kPsychArgRequired, -1);
		return(PsychError_none);
	}
	
	// If we reach this point, then device is the pointer to the class specific device struct and the
	// open operation was successfull. Build port struct:
	portRecordBank[handle].portType = kPsychIOPortSerial;
	portRecordBank[handle].device = (void*) device;
	portRecordCount++;
	
	// Return handle to new serial port object:
	PsychCopyOutDoubleArg(1, kPsychArgRequired, (double) handle);
	
    return(PsychError_none);
}
PsychError SCREENPreference(void)  
{

	PsychArgFormatType		arg1Type;
	char					*preferenceName, *newFontName;
	const char				*tableCreator, *oldDefaultFontName;
	psych_bool				preferenceNameArgumentValid, booleanInput, ignoreCase, tempFlag, textAlphaBlendingFlag, suppressAllWarningsFlag;
	int						numInputArgs, i, newFontStyleNumber, newFontSize, tempInt, tempInt2, tempInt3, tempInt4;
	double					returnDoubleValue, inputDoubleValue;
	double					maxStddev, maxDeviation, maxDuration;
	int						minSamples;
    double                  *dheads = NULL;

	//all sub functions should have these two lines
	PsychPushHelp(useString, synopsisString,seeAlsoString);
	if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
	
	//check for superfluous or missing arguments
	PsychErrorExit(PsychCapNumInputArgs(5));			
	PsychErrorExit(PsychRequireNumInputArgs(1));		   
	PsychErrorExit(PsychCapNumOutputArgs(4));
	
	numInputArgs=PsychGetNumInputArgs();
	arg1Type=PsychGetArgType(1);
	preferenceNameArgumentValid=FALSE;
	
	//Cases which require both a window pointer or screen number and preference name.  Argument 1 is the wposn and argument 2 is the preference name.
	if( numInputArgs >= 2 && (PsychIsScreenNumberArg(1) || PsychIsScreenNumberArg(1)) && PsychGetArgType(2)==PsychArgType_char ){
		PsychAllocInCharArg(2, kPsychArgRequired, &preferenceName);
		//preferences which require window pointer or screen number argument which we DO NOT support  
		for(i=0;i<kPsychNumUnsupportedMacVideoPreferences;i++){
			if(PsychMatch(preferenceName, unsupportedMacVideoPreferenceNames[i]))
				PsychErrorExit(PsychError_unsupportedOS9Preference);
		}
		//insert here conditionals  to act on prefernces which accept a window pointer or screen number argument which we DO support.
		PsychErrorExit(PsychError_unrecognizedPreferenceName);
	}

	//Cases which do not require a wposn.  Argument 1 is the preference name.  if present Argument 2 is the new value
	if(arg1Type==PsychArgType_char){
		PsychAllocInCharArg(1, kPsychArgRequired, &preferenceName);
		//Preferernces which we do not support and which do not require a wposn
		for(i=0;i<kPsychNumUnsupportedMacNonVideoPreferences;i++){
			if(PsychMatch(preferenceName, unsupportedMacNonVideoPreferenceNames[i]))
				PsychErrorExit(PsychError_unsupportedOS9Preference);
		}
		//Preferences which we do support
		if(PsychMatch(preferenceName, "IgnoreCase")){
			ignoreCase=!PsychIsPsychMatchCaseSensitive();
			PsychCopyOutFlagArg(1, kPsychArgOptional, ignoreCase);
			if(numInputArgs==2){
				PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput);
				PsychSetPsychMatchCaseSenstive(!booleanInput);			
			}
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "Tick0Secs")){
			if(PsychCopyInDoubleArg(2, kPsychArgOptional, &inputDoubleValue) && inputDoubleValue==PsychGetNanValue())
				PsychEstimateGetSecsValueAtTickCountZero();
			returnDoubleValue=PsychGetEstimatedSecsValueAtTickCountZero();
			PsychCopyOutDoubleArg(1, kPsychArgOptional, returnDoubleValue);
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "PsychTableVersion")){
			if(numInputArgs==2)
				PsychErrorExit(PsychError_extraInputArg);
			PsychCopyOutDoubleArg(1, kPsychArgOptional, (double)PsychPrefStateGet_PsychTableVersion());
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "PsychTableCreator")){
			if(numInputArgs==2)
				PsychErrorExit(PsychError_extraInputArg);
			tableCreator=PsychPrefStateGet_PsychTableCreator();
			PsychCopyOutCharArg(1, kPsychArgOptional, tableCreator);
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "Process")){
			if(numInputArgs==2)
				PsychErrorExit(PsychError_extraInputArg);
			PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) (psych_int64) getpid());
			preferenceNameArgumentValid=TRUE;


		}else 
		if(PsychMatch(preferenceName, "DefaultFontName")){
			PsychPrefStateGet_DefaultFontName(&oldDefaultFontName);
			PsychCopyOutCharArg(1, kPsychArgOptional, oldDefaultFontName);
			if(numInputArgs==2){
				PsychAllocInCharArg(2, kPsychArgRequired, &newFontName);
				PsychPrefStateSet_DefaultFontName(newFontName);
			}
			preferenceNameArgumentValid=TRUE;			
		}else 
		if(PsychMatch(preferenceName, "TextEncodingLocale")){
			PsychCopyOutCharArg(1, kPsychArgOptional, PsychGetUnicodeTextConversionLocale());
			if(numInputArgs==2){
				PsychAllocInCharArg(2, kPsychArgRequired, &newFontName);
				if (!PsychSetUnicodeTextConversionLocale(newFontName)) PsychErrorExitMsg(PsychError_user, "Setting the 'TextEncodingLocale' failed, most likely because you provided an invalid/unknown locale setting string.");
			}
			preferenceNameArgumentValid=TRUE;			
		}else 
		if(PsychMatch(preferenceName, "DefaultFontStyle")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DefaultTextStyle());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &newFontStyleNumber);
				PsychPrefStateSet_DefaultTextStyle(newFontStyleNumber);
			}
			preferenceNameArgumentValid=TRUE;
		}else
		if(PsychMatch(preferenceName, "OverrideMultimediaEngine")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_UseGStreamer());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				PsychPrefStateSet_UseGStreamer(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else
		if(PsychMatch(preferenceName, "DefaultTextYPositionIsBaseline")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_TextYPositionIsBaseline());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				PsychPrefStateSet_TextYPositionIsBaseline(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "TextAntiAliasing")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_TextAntiAliasing());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				PsychPrefStateSet_TextAntiAliasing(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "TextRenderer")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_TextRenderer());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				PsychPrefStateSet_TextRenderer(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "DefaultFontSize")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DefaultTextSize());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &newFontSize);
				PsychPrefStateSet_DefaultTextSize(newFontSize);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "DebugMakeTexture")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DebugMakeTexture());
			if(numInputArgs==2){
				PsychCopyInFlagArg(2, kPsychArgRequired, &tempFlag);
				PsychPrefStateSet_DebugMakeTexture(tempFlag);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "SkipSyncTests")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_SkipSyncTests());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				PsychPrefStateSet_SkipSyncTests(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "VisualDebugLevel")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VisualDebugLevel());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				PsychPrefStateSet_VisualDebugLevel(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "VBLTimestampingMode")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VBLTimestampingMode());
			if(numInputArgs>=2){
                            PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
                            PsychPrefStateSet_VBLTimestampingMode(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "SyncTestSettings")){
			PsychPrefStateGet_SynctestThresholds(&maxStddev, &minSamples, &maxDeviation, &maxDuration);
			PsychCopyOutDoubleArg(1, kPsychArgOptional, maxStddev);
			PsychCopyOutDoubleArg(2, kPsychArgOptional, minSamples);
			PsychCopyOutDoubleArg(3, kPsychArgOptional, maxDeviation);
			PsychCopyOutDoubleArg(4, kPsychArgOptional, maxDuration);
			if(numInputArgs>=2){
							PsychCopyInDoubleArg( 2, kPsychArgOptional, &maxStddev);
                            PsychCopyInIntegerArg(3, kPsychArgOptional, &minSamples);
							PsychCopyInDoubleArg( 4, kPsychArgOptional, &maxDeviation);
							PsychCopyInDoubleArg( 5, kPsychArgOptional, &maxDuration);
							PsychPrefStateSet_SynctestThresholds(maxStddev, minSamples, maxDeviation, maxDuration);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "VBLEndlineOverride")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VBLEndlineOverride());
			if(numInputArgs>=2){
                            PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
                            PsychPrefStateSet_VBLEndlineOverride(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else
			if(PsychMatch(preferenceName, "DefaultVideocaptureEngine")){
				PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VideoCaptureEngine());
				if(numInputArgs==2){
					PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
					PsychPrefStateSet_VideoCaptureEngine(tempInt);
				}
			preferenceNameArgumentValid=TRUE;
		}else
			if(PsychMatch(preferenceName, "WindowShieldingLevel")){
				PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_WindowShieldingLevel());
				if(numInputArgs==2){
					PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
					PsychPrefStateSet_WindowShieldingLevel(tempInt);
				}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "ConserveVRAM") || PsychMatch(preferenceName, "Workarounds1")){
					PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_ConserveVRAM());
					if(numInputArgs==2){
						PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
						PsychPrefStateSet_ConserveVRAM(tempInt);
					}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "Verbosity")){
					PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_Verbosity());
					if(numInputArgs==2){
						PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
						PsychPrefStateSet_Verbosity(tempInt);
					}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "FrameRectCorrection")){
					PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_FrameRectCorrection());
					if(numInputArgs==2){
						PsychCopyInDoubleArg(2, kPsychArgRequired, &inputDoubleValue);
						PsychPrefStateSet_FrameRectCorrection(inputDoubleValue);
					}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "EmulateOldPTB")){
				PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_EmulateOldPTB());
				if(numInputArgs==2){
					PsychCopyInFlagArg(2, kPsychArgRequired, &tempFlag);
					PsychPrefStateSet_EmulateOldPTB(tempFlag);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "Enable3DGraphics")){
				PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_3DGfx());
				if(numInputArgs==2){
					PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
					PsychPrefStateSet_3DGfx(tempInt);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "TextAlphaBlending")){
				textAlphaBlendingFlag=PsychPrefStateGet_TextAlphaBlending();
				PsychCopyOutFlagArg(1, kPsychArgOptional, textAlphaBlendingFlag);
				if(numInputArgs==2){
					PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput);
					PsychPrefStateSet_TextAlphaBlending(booleanInput);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "SuppressAllWarnings")){
				suppressAllWarningsFlag=PsychPrefStateGet_SuppressAllWarnings();
				PsychCopyOutFlagArg(1, kPsychArgOptional, suppressAllWarningsFlag);
				if(numInputArgs==2){
					PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput);
					PsychPrefStateSet_SuppressAllWarnings(booleanInput);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "SynchronizeDisplays")){
				if(numInputArgs >= 2) {
					// This is a special call: It currently doesn't set a preference setting,
					// but instead triggers an instantaneous synchronization of all available
					// display heads, if possible. We may have a more clever and "standard" interface
					// interface for this later on, but for first tests this will do.
					// Syncmethod is hard-coded to 0 -> Use whatever's available to sync.
					// timeout for retries is 5.0 seconds.
					// Acceptable residual offset is +/- 2 scanlines.
					// Returns the real residual offset after sync.
					PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
					if (!PsychCopyInIntegerArg(3, kPsychArgOptional, &tempInt3)) {
                        // No screenId specified: Resync default screen or whatever...
                        tempInt2 = 0;
                        if (PsychSynchronizeDisplayScreens(&tempInt2, NULL, &tempInt, tempInt, 5.0, 2)!=PsychError_none) PsychErrorExitMsg(PsychError_user, "Sync failed for reasons mentioned above.");
                    } else {
                        // Specific screenId provided: Resync crtc's associated with this screenId if possible:
                        tempInt2 = 1;
                        if (PsychSynchronizeDisplayScreens(&tempInt2, &tempInt3, &tempInt, tempInt, 5.0, 2)!=PsychError_none) PsychErrorExitMsg(PsychError_user, "Sync failed for reasons mentioned above.");
                    }
                    
					PsychCopyOutDoubleArg(1, kPsychArgOptional, tempInt);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "ScreenToHead")){
				// screenId is required:
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				if (tempInt < 0 || tempInt >= PsychGetNumDisplays() || tempInt >= kPsychMaxPossibleDisplays) PsychErrorExitMsg(PsychError_user, "Invalid screenId provided. Out of valid range!");

				// Return old mappings for this screenId:
                for (tempInt2 = 0; (tempInt2 < kPsychMaxPossibleCrtcs) && (PsychPrefStateGet_ScreenToHead(tempInt, tempInt2) >= 0); tempInt2++);
                PsychAllocOutDoubleMatArg(1, kPsychArgOptional, 2, tempInt2, 1, &dheads);
                
                tempInt4 = 0;
                for (tempInt3 = 0; tempInt3 < tempInt2; tempInt3++) {
                    dheads[tempInt4++] = (double) PsychPrefStateGet_ScreenToHead(tempInt, tempInt3);
                    dheads[tempInt4++] = (double) PsychPrefStateGet_ScreenToCrtcId(tempInt, tempInt3);
                }
                
                // Optionally retrieve and set new mappings for this screenId:
				if(numInputArgs>=3) {
					// Set new headId for screenId:
					PsychCopyInIntegerArg(3, kPsychArgRequired, &tempInt2);
					if (tempInt2 < 0) PsychErrorExitMsg(PsychError_user, "Invalid negative headId provided!");

					// Set new crtcId for screenId:
					PsychCopyInIntegerArg(4, kPsychArgRequired, &tempInt3);
					if (tempInt3 < 0) PsychErrorExitMsg(PsychError_user, "Invalid negative crtcId provided!");

                    // Assign primary head by default (index 0), but allow optionally others as well:
                    tempInt4 = 0;
					PsychCopyInIntegerArg(5, kPsychArgOptional, &tempInt4);
					if (tempInt4 < 0 || tempInt4 >= kPsychMaxPossibleCrtcs) PsychErrorExitMsg(PsychError_user, "Invalid rankId provided! Too many heads for one screen!");

					PsychPrefStateSet_ScreenToHead(tempInt, tempInt2, tempInt3, tempInt4);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			PsychErrorExit(PsychError_unrecognizedPreferenceName);
	}
	
	if(!preferenceNameArgumentValid)
		PsychErrorExitMsg(PsychError_user, "Invalid arguments to preferences command");
		
	return(PsychError_none);
}
PsychError SCREENBlendFunction(void)
{
	PsychWindowRecordType 	*windowRecord;
	GLenum					oldSource, oldDestination, newSource, newDestination;
	char					*oldSoureStr, *oldDestinationStr, *newSourceStr, *newDestinationStr;
	int						oldSourceStrSize, oldDestinationStrSize, isSourceStringValid, isDestinationStringValid;
	psych_bool					isSourceSupplied, isDestinationSupplied, isSourceChoiceValid, isDestinationChoiceValid;
	double					*oldColorMask, *newColorMask;
	int						m, n, p;
	
	//all subfunctions should have these two lines.  
	PsychPushHelp(useString, synopsisString, seeAlsoString);
	if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};

	PsychErrorExit(PsychCapNumInputArgs(4));		//The maximum number of inputs
	PsychErrorExit(PsychRequireNumInputArgs(1));	//The required number of inputs
	PsychErrorExit(PsychCapNumOutputArgs(3));		//The maximum number of outputs

	//Get the window record or exit with an error if the windex was bogus.
	PsychAllocInWindowRecordArg(kPsychUseDefaultArgPosition, TRUE, &windowRecord);

	//Retreive the old source and destination factors and return them from the Screen call as strings
	PsychGetAlphaBlendingFactorsFromWindow(windowRecord, &oldSource, &oldDestination);

	oldSourceStrSize=PsychGetAlphaBlendingFactorStringFromConstant(oldSource, NULL);
	oldDestinationStrSize=PsychGetAlphaBlendingFactorStringFromConstant(oldDestination, NULL);
	
	oldSoureStr=(char *)malloc(sizeof(char) * oldSourceStrSize);
	oldDestinationStr=(char *)malloc(sizeof(char) * oldDestinationStrSize);

	PsychGetAlphaBlendingFactorStringFromConstant(oldSource, oldSoureStr);
	PsychGetAlphaBlendingFactorStringFromConstant(oldDestination, oldDestinationStr);

	PsychCopyOutCharArg(1, kPsychArgOptional, oldSoureStr);
	PsychCopyOutCharArg(2, kPsychArgOptional, oldDestinationStr);
	
	free((void *)oldSoureStr);
	free((void *)oldDestinationStr);

	//Get the new settings if they are present and set them.
	newSource=oldSource;
	newDestination=oldDestination;

	isSourceSupplied= PsychAllocInCharArg(2, kPsychArgOptional, &newSourceStr);
	isDestinationSupplied= PsychAllocInCharArg(3, kPsychArgOptional, &newDestinationStr);

	if(isSourceSupplied){
		isSourceStringValid=PsychGetAlphaBlendingFactorConstantFromString(newSourceStr, &newSource);
		if(!isSourceStringValid) PsychErrorExitMsg(PsychError_user, "Supplied string argument 'sourceFactorNew' is invalid");

		isSourceChoiceValid=PsychValidateBlendingConstantForSource(newSource);
		if(!isSourceChoiceValid) PsychErrorExitMsg(PsychError_user, "The blending factor supplied for the source is only valid only for the destination");
	}

	if(isDestinationSupplied){
		isDestinationStringValid=PsychGetAlphaBlendingFactorConstantFromString(newDestinationStr, &newDestination);
		if(!isDestinationStringValid) PsychErrorExitMsg(PsychError_user, "Supplied string argument 'destinationFactorNew' is invalid");

		isDestinationChoiceValid=PsychValidateBlendingConstantForDestination(newDestination);
		if(!isDestinationChoiceValid) PsychErrorExitMsg(PsychError_user, "The blending factor supplied for the destination is only valid only for the source");
	}

	PsychStoreAlphaBlendingFactorsForWindow(windowRecord, newSource, newDestination);

	// Check if alpha blending is possible for this windowRecord:
	if ((newSource != GL_ONE || newDestination != GL_ZERO) && !((windowRecord->bpc < 16) || (windowRecord->bpc == 16 && (windowRecord->gfxcaps & kPsychGfxCapFPBlend16)) || (windowRecord->bpc == 32 && (windowRecord->gfxcaps & kPsychGfxCapFPBlend32)))) {
		// Nope. Alpha blending requested but not possible for this windowRecord with this gfx-hardware.
		if (PsychPrefStateGet_Verbosity() > 1) {
			printf("PTB-WARNING: Screen('Blendfunction') called to enable alpha-blending on a window (handle=%i) which doesn't support\n", windowRecord->windowIndex);
			printf("PTB-WARNING: alpha-blending at its current color resolution of %i bits per color component on your hardware.\n", windowRecord->bpc);
			printf("PTB-WARNING: Won't enable blending. Either lower the color resolution of the window (see help PsychImaging) or\n");
			printf("PTB-WARNING: upgrade your graphics hardware.\n\n");
		}
	}
	
	// Create return array with encoded old colormask:
	PsychAllocOutDoubleMatArg(3, kPsychArgOptional, 1, 4, 1, &oldColorMask);
	oldColorMask[0] = (windowRecord->colorMask[0]) ? 1 : 0;
	oldColorMask[1] = (windowRecord->colorMask[1]) ? 1 : 0;
	oldColorMask[2] = (windowRecord->colorMask[2]) ? 1 : 0;
	oldColorMask[3] = (windowRecord->colorMask[3]) ? 1 : 0;

	// Any new colormask provided?
	if (PsychAllocInDoubleMatArg(4, kPsychArgOptional, &m, &n, &p, &newColorMask)) {
		// Yes. Assign it:
		if (p!=1 || m*n != 4)  PsychErrorExitMsg(PsychError_user, "The colorMaskNew argument must be a 4 element row- or column vector!");

		windowRecord->colorMask[0] = (newColorMask[0] > 0) ? GL_TRUE : GL_FALSE;
		windowRecord->colorMask[1] = (newColorMask[1] > 0) ? GL_TRUE : GL_FALSE;
		windowRecord->colorMask[2] = (newColorMask[2] > 0) ? GL_TRUE : GL_FALSE;
		windowRecord->colorMask[3] = (newColorMask[3] > 0) ? GL_TRUE : GL_FALSE;
	}
	
	return(PsychError_none);
}
示例#12
0
PsychError SCREENTextFont(void) 
{
    psych_bool			doSetByName, doSetByNumber, foundFont;
    PsychWindowRecordType	*windowRecord;
#if PSYCH_SYSTEM == PSYCH_OSX
    PsychFontStructType		*fontRecord;
#endif
    int				oldTextFontNumber, inputTextFontNumber;
    char			*oldTextFontName, *inputTextFontName;
    int             oldTextStyle, newTextStyle;
    
    //all subfunctions should have these two lines.  
    PsychPushHelp(useString, synopsisString, seeAlsoString);
    if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
    
    //check for valid number of arguments
    PsychErrorExit(PsychRequireNumInputArgs(1));
    PsychErrorExit(PsychCapNumInputArgs(3));
    PsychErrorExit(PsychCapNumOutputArgs(3));
    
    //Get the window record
    PsychAllocInWindowRecordArg(kPsychUseDefaultArgPosition, TRUE, &windowRecord);
    
    //Save the old text font value and return it.
    oldTextFontNumber=windowRecord->textAttributes.textFontNumber;
    PsychCopyOutDoubleArg(2, FALSE, (double)oldTextFontNumber);
    oldTextFontName=(char*) windowRecord->textAttributes.textFontName;
    PsychCopyOutCharArg(1, FALSE, oldTextFontName);
    oldTextStyle = windowRecord->textAttributes.textStyle;
    PsychCopyOutDoubleArg(3, FALSE, (double) oldTextStyle);
	
    //Fetch and set the new font if specified by name or number
    PsychCheckInputArgType(2, kPsychArgOptional, PsychArgType_double | PsychArgType_char);  //if the argument is there check that it is the right type.
    doSetByNumber= PsychCopyInIntegerArg(2, kPsychArgAnything, &inputTextFontNumber);
    doSetByName= PsychAllocInCharArg(2, kPsychArgAnything, &inputTextFontName);
    foundFont=0;
#if PSYCH_SYSTEM == PSYCH_OSX
    if(doSetByNumber) {
        foundFont=PsychGetFontRecordFromFontNumber(inputTextFontNumber, &fontRecord);
    }
    
    if(doSetByName) {
        if (PsychCopyInIntegerArg(3, FALSE, &newTextStyle)) windowRecord->textAttributes.textStyle = newTextStyle;
        foundFont=PsychGetFontRecordFromFontFamilyNameAndFontStyle(inputTextFontName, windowRecord->textAttributes.textStyle, &fontRecord);
    }
    
    if(foundFont) {
        strncpy((char*) windowRecord->textAttributes.textFontName, (char*) fontRecord->fontFMFamilyName, 255);
        windowRecord->textAttributes.textFontNumber = fontRecord->fontNumber;
        windowRecord->textAttributes.textStyle = fontRecord->fontFMStyle;
    }
	else {
		// Font not found. Is this textrenderer 2 with a font given by name?
		if (doSetByName && (PsychPrefStateGet_TextRenderer() > 1)) {
			// Yes: Must be a special font specifier string for the renderer plugin. Just assign it directly:
			strncpy((char*) windowRecord->textAttributes.textFontName, inputTextFontName, 255);

			// Don't have a valid fontNumber: Just assign a zero...
			windowRecord->textAttributes.textFontNumber = 0;
		}
        else {
            // Restore old text style setting:
            windowRecord->textAttributes.textStyle = oldTextStyle;
        }
	}
    
    return(PsychError_none);
#else
    // Special case for MS-Windows and Linux:
    if(doSetByNumber) printf("PTB-WARNING: Sorry, selecting font by number in Screen('TextFont') is not yet supported on Windows or Linux. Command ignored.\n");
    if(doSetByName && (strncmp(windowRecord->textAttributes.textFontName, inputTextFontName, 255 )!=0)) {
      strncpy(windowRecord->textAttributes.textFontName, inputTextFontName, 255);
      windowRecord->textAttributes.textFontNumber= 0;
      // Set the rebuild flag:
      windowRecord->textAttributes.needsRebuild=TRUE;
    }
    
    // New and different text style provided?
    if (PsychCopyInIntegerArg(3, FALSE, &newTextStyle) && (windowRecord->textAttributes.textStyle != newTextStyle)) {
        windowRecord->textAttributes.textStyle = newTextStyle;
        // Set the rebuild flag:
        windowRecord->textAttributes.needsRebuild=TRUE;
    }

    return(PsychError_none);
#endif
}
PsychError SCREENPreference(void)  
{

	PsychArgFormatType		arg1Type;
	char					*preferenceName, *newFontName;
	const char				*tableCreator, *oldDefaultFontName;
	Boolean					preferenceNameArgumentValid, booleanInput, ignoreCase, tempFlag, textAlphaBlendingFlag, suppressAllWarningsFlag;
	int						numInputArgs, i, newFontStyleNumber, newFontSize, tempInt, tempInt2, tempInt3;
	double					returnDoubleValue, inputDoubleValue;
	
	//all sub functions should have these two lines
	PsychPushHelp(useString, synopsisString,seeAlsoString);
	if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
	
	//check for superfluous or missing arguments
	PsychErrorExit(PsychCapNumInputArgs(3));			
	PsychErrorExit(PsychRequireNumInputArgs(1));		   
	PsychErrorExit(PsychCapNumOutputArgs(1));
	
	numInputArgs=PsychGetNumInputArgs();
	arg1Type=PsychGetArgType(1);
	preferenceNameArgumentValid=FALSE;
	
	//Cases which require both a window pointer or screen number and preference name.  Argument 1 is the wposn and argument 2 is the preference name.
	if( numInputArgs >= 2 && (PsychIsScreenNumberArg(1) || PsychIsScreenNumberArg(1)) && PsychGetArgType(2)==PsychArgType_char ){
		PsychAllocInCharArg(2, kPsychArgRequired, &preferenceName);
		//preferences which require window pointer or screen number argument which we DO NOT support  
		for(i=0;i<kPsychNumUnsupportedMacVideoPreferences;i++){
			if(PsychMatch(preferenceName, unsupportedMacVideoPreferenceNames[i]))
				PsychErrorExit(PsychError_unsupportedOS9Preference);
		}
		//insert here conditionals  to act on prefernces which accept a window pointer or screen number argument which we DO support.
		PsychErrorExit(PsychError_unrecognizedPreferenceName);
	}

	//Cases which do not require a wposn.  Argument 1 is the preference name.  if present Argument 2 is the new value
	if(arg1Type==PsychArgType_char){
		PsychAllocInCharArg(1, kPsychArgRequired, &preferenceName);
		//Preferernces which we do not support and which do not require a wposn
		for(i=0;i<kPsychNumUnsupportedMacNonVideoPreferences;i++){
			if(PsychMatch(preferenceName, unsupportedMacNonVideoPreferenceNames[i]))
				PsychErrorExit(PsychError_unsupportedOS9Preference);
		}
		//Preferences which we do support
		if(PsychMatch(preferenceName, "IgnoreCase")){
			ignoreCase=!PsychIsPsychMatchCaseSensitive();
			PsychCopyOutFlagArg(1, kPsychArgOptional, ignoreCase);
			if(numInputArgs==2){
				PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput);
				PsychSetPsychMatchCaseSenstive(!booleanInput);			
			}
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "Tick0Secs")){
			if(PsychCopyInDoubleArg(2, kPsychArgOptional, &inputDoubleValue) && inputDoubleValue==PsychGetNanValue())
				PsychEstimateGetSecsValueAtTickCountZero();
			returnDoubleValue=PsychGetEstimatedSecsValueAtTickCountZero();
			PsychCopyOutDoubleArg(1, kPsychArgOptional, returnDoubleValue);
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "PsychTableVersion")){
			if(numInputArgs==2)
				PsychErrorExit(PsychError_extraInputArg);
			PsychCopyOutDoubleArg(1, kPsychArgOptional, (double)PsychPrefStateGet_PsychTableVersion());
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "PsychTableCreator")){
			if(numInputArgs==2)
				PsychErrorExit(PsychError_extraInputArg);
			tableCreator=PsychPrefStateGet_PsychTableCreator();
			PsychCopyOutCharArg(1, kPsychArgOptional, tableCreator);
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "Process")){
			if(numInputArgs==2)
				PsychErrorExit(PsychError_extraInputArg);
			PsychCopyOutDoubleArg(1, kPsychArgOptional, (double)getpid());
			preferenceNameArgumentValid=TRUE;


		}else 
		if(PsychMatch(preferenceName, "DefaultFontName")){
			PsychPrefStateGet_DefaultFontName(&oldDefaultFontName);
			PsychCopyOutCharArg(1, kPsychArgOptional, oldDefaultFontName);
			if(numInputArgs==2){
				PsychAllocInCharArg(2, kPsychArgRequired, &newFontName);
				PsychPrefStateSet_DefaultFontName(newFontName);
			}
			preferenceNameArgumentValid=TRUE;
			
		}else 
		if(PsychMatch(preferenceName, "DefaultFontStyle")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DefaultTextStyle());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &newFontStyleNumber);
				PsychPrefStateSet_DefaultTextStyle(newFontStyleNumber);
			}
			preferenceNameArgumentValid=TRUE;
		}else
		if(PsychMatch(preferenceName, "DefaultTextYPositionIsBaseline")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_TextYPositionIsBaseline());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				PsychPrefStateSet_TextYPositionIsBaseline(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "TextAntiAliasing")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_TextAntiAliasing());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				PsychPrefStateSet_TextAntiAliasing(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "TextRenderer")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_TextRenderer());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				PsychPrefStateSet_TextRenderer(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "DefaultFontSize")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DefaultTextSize());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &newFontSize);
				PsychPrefStateSet_DefaultTextSize(newFontSize);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
		if(PsychMatch(preferenceName, "DebugMakeTexture")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DebugMakeTexture());
			if(numInputArgs==2){
				PsychCopyInFlagArg(2, kPsychArgRequired, &tempFlag);
				PsychPrefStateSet_DebugMakeTexture(tempFlag);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "SkipSyncTests")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_SkipSyncTests());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				PsychPrefStateSet_SkipSyncTests(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "VisualDebugLevel")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VisualDebugLevel());
			if(numInputArgs==2){
				PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
				PsychPrefStateSet_VisualDebugLevel(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "VBLTimestampingMode")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VBLTimestampingMode());
			if(numInputArgs>=2){
                            PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
                            PsychPrefStateSet_VBLTimestampingMode(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "VBLEndlineOverride")){
			PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VBLEndlineOverride());
			if(numInputArgs>=2){
                            PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
                            PsychPrefStateSet_VBLEndlineOverride(tempInt);
			}
			preferenceNameArgumentValid=TRUE;
		}else
			if(PsychMatch(preferenceName, "DefaultVideocaptureEngine")){
				PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VideoCaptureEngine());
				if(numInputArgs==2){
					PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
					PsychPrefStateSet_VideoCaptureEngine(tempInt);
				}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "ConserveVRAM") || PsychMatch(preferenceName, "Workarounds1")){
					PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_ConserveVRAM());
					if(numInputArgs==2){
						PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
						PsychPrefStateSet_ConserveVRAM(tempInt);
					}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "Verbosity")){
					PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_Verbosity());
					if(numInputArgs==2){
						PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
						PsychPrefStateSet_Verbosity(tempInt);
					}
			preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "EmulateOldPTB")){
				PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_EmulateOldPTB());
				if(numInputArgs==2){
					PsychCopyInFlagArg(2, kPsychArgRequired, &tempFlag);
					PsychPrefStateSet_EmulateOldPTB(tempFlag);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "Enable3DGraphics")){
				PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_3DGfx());
				if(numInputArgs==2){
					PsychCopyInFlagArg(2, kPsychArgRequired, &tempFlag);
					PsychPrefStateSet_3DGfx(tempFlag);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "TextAlphaBlending")){
				textAlphaBlendingFlag=PsychPrefStateGet_TextAlphaBlending();
				PsychCopyOutFlagArg(1, kPsychArgOptional, textAlphaBlendingFlag);
				if(numInputArgs==2){
					PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput);
					PsychPrefStateSet_TextAlphaBlending(booleanInput);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "SuppressAllWarnings")){
				suppressAllWarningsFlag=PsychPrefStateGet_SuppressAllWarnings();
				PsychCopyOutFlagArg(1, kPsychArgOptional, suppressAllWarningsFlag);
				if(numInputArgs==2){
					PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput);
					PsychPrefStateSet_SuppressAllWarnings(booleanInput);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			if(PsychMatch(preferenceName, "SynchronizeDisplays")){
				if(numInputArgs==2){
					// This is a special call: It currently doesn't set a preference setting,
					// but instead triggers an instantaneous synchronization of all available
					// display heads, if possible. We may have a more clever and "standard" interface
					// interface for this later on, but for first tests this will do.
					// Syncmethod is hard-coded to 0 -> Use whatever's available to sync.
					// timeout for retries is 5.0 seconds.
					// Acceptable residual offset is +/- 2 scanlines.
					// Returns the real residual offset after sync.
					PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt);
					tempInt2 = 0;
					if (PsychSynchronizeDisplayScreens(&tempInt2, NULL, &tempInt, tempInt, 5.0, 2)!=PsychError_none) PsychErrorExitMsg(PsychError_user, "Sync failed for reasons mentioned above.");
					PsychCopyOutDoubleArg(1, kPsychArgOptional, tempInt);
				}
				preferenceNameArgumentValid=TRUE;
		}else 
			PsychErrorExit(PsychError_unrecognizedPreferenceName);
	}
	
	if(!preferenceNameArgumentValid)
		PsychErrorExitMsg(PsychError_user, "Invalid arguments to preferences command");
		
	return(PsychError_none);
}
/* Set capture device specific parameters:
* Currently, the named parameters are a subset of the parameters supported by the
* IIDC specification, mapped to more convenient names.
*
* Input: pname = Name string to specify the parameter.
*        value = Either DBL_MAX to not set but only query the parameter, or some other
*                value, that we try to set in the Firewire camera.
*
* Returns: Old value of the setting
*/
double PsychARVideoCaptureSetParameter(int capturehandle, const char* pname, double value)
{
	unsigned int minval, maxval, intval, oldintval;
	int triggercount;
	
	double oldvalue = DBL_MAX; // Initialize return value to the "unknown/unsupported" default.
	psych_bool assigned = false;
	psych_bool present  = false;
	
	// Retrieve device record for handle:
	PsychVidcapRecordType* capdev = PsychGetARVidcapRecord(capturehandle);
	
	oldintval = 0xFFFFFFFF;
	
	// Round value to integer:
	intval = (int) (value + 0.5);
	
	// Check parameter name pname and call the appropriate subroutine:
	if (strcmp(pname, "TriggerCount")==0 || strcmp(pname, "WaitTriggerCount")==0) {
		// Query of cameras internal trigger counter or waiting for a specific
		// value in the counter requested. Trigger counters are special features,
		// (so called "Smart Features" or "Advanced Features" in the IIDC spec)
		// which are only available on selected cameras.
		// We currently only know how to do this on Basler cameras.
		return(-2);
	}
	
	if (strcmp(pname, "PrintParameters")==0) {
		// Special command: List and print all features...
		printf("PTB-INFO: The camera provides the following information and featureset:\n");
		ar2VideoDispOption();
		return(0);
	}

	// Return current framerate:
	if (strcmp(pname, "GetFramerate")==0) {
		PsychCopyOutDoubleArg(1, FALSE, capdev->fps);
		return(0);
	}
	
	// Return current ROI of camera, as requested (and potentially modified during
	// PsychOpenCaptureDevice(). This is a read-only parameter, as the ROI can
	// only be set during Screen('OpenVideoCapture').
	if (strcmp(pname, "GetROI")==0) {
		PsychCopyOutRectArg(1, FALSE, capdev->roirect);
		return(0);
	}
	
	// Return vendor name string:
	if (strcmp(pname, "GetVendorname")==0) {
		PsychCopyOutCharArg(1, FALSE, "Unknown Vendor");
		return(0);
	}
	
	// Return model name string:
	if (strcmp(pname, "GetModelname")==0) {
		PsychCopyOutCharArg(1, FALSE, "Unknown Model");
		return(0);
	}
	
//	if (strstr(pname, "Brightness")!=0) {
//		assigned = true;
//		feature = DC1394_FEATURE_BRIGHTNESS;    
//	}
//	
//	if (strstr(pname, "Gain")!=0) {
//		assigned = true;
//		feature = DC1394_FEATURE_GAIN;    
//	}
//	
//	if (strstr(pname, "Exposure")!=0) {
//		assigned = true;
//		feature = DC1394_FEATURE_EXPOSURE;    
//	}
//	
//	if (strstr(pname, "Shutter")!=0) {
//		assigned = true;
//		feature = DC1394_FEATURE_SHUTTER;    
//	}
//	
//	if (strstr(pname, "Sharpness")!=0) {
//		assigned = true;
//		feature = DC1394_FEATURE_SHARPNESS;    
//	}
//	
//	if (strstr(pname, "Saturation")!=0) {
//		assigned = true;
//		feature = DC1394_FEATURE_SATURATION;    
//	}
//	
//	if (strstr(pname, "Gamma")!=0) {
//		assigned = true;
//		feature = DC1394_FEATURE_GAMMA;    
//	}
	
	// Check if feature is present on this camera:
	// Not supported yet:
	present = FALSE;
	
//	if (dc1394_feature_is_present(capdev->camera, feature, &present)!=DC1394_SUCCESS) {
//		if(PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Failed to query presence of feature %s on camera %i! Ignored.\n", pname, capturehandle);
//		fflush(NULL);
//	}
//	else
	
	if (present) {
		// Feature is available:
/*		
		// Retrieve current value:
		if (dc1394_feature_get_value(capdev->camera, feature, &oldintval)!=DC1394_SUCCESS) {
			if(PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Failed to query value of feature %s on camera %i! Ignored.\n", pname, capturehandle);
			fflush(NULL);
		}
		else {      
			// Do we want to set the value?
			if (value != DBL_MAX) {
				// Query allowed bounds for its value:
				if (dc1394_feature_get_boundaries(capdev->camera, feature, &minval, &maxval)!=DC1394_SUCCESS) {
					if(PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Failed to query valid value range for feature %s on camera %i! Ignored.\n", pname, capturehandle);
					fflush(NULL);
				}
				else {
					// Sanity check against range:
					if (intval < minval || intval > maxval) {
						if(PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Requested setting %i for parameter %s not in allowed range (%i - %i) for camera %i. Ignored.\n",
																   intval, pname, minval, maxval, capturehandle);
						fflush(NULL);      
					}
					else {
						// Ok intval is valid for this feature: Can we manually set this feature?
						// Switch feature to manual control mode:
						if (dc1394_feature_set_mode(capdev->camera, feature, DC1394_FEATURE_MODE_MANUAL)!=DC1394_SUCCESS) {
							if(PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Failed to set feature %s on camera %i to manual control! Ignored.\n", pname, capturehandle);
							fflush(NULL);
						}
						else {
							// Ok, try to set the features new value:
							if (dc1394_feature_set_value(capdev->camera, feature, intval)!=DC1394_SUCCESS) {
								if(PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Failed to set value of feature %s on camera %i to %i! Ignored.\n", pname, capturehandle,
																		   intval);
								fflush(NULL);
							}
						}
					}
				}
			}
			else {
				// Don't want to set new value. Do we want to reset feature into auto-mode?
				// Prefixing a parameter name with "Auto"
				// does not switch the parameter into manual
				// control mode + set its value, as normal,
				// but it switches the parameter into automatic
				// mode, if automatic mode is supported by the
				// device.
				if (strstr(pname, "Auto")!=0) {
					// Switch to automatic control requested - Try it:
					if (dc1394_feature_set_mode(capdev->camera, feature, DC1394_FEATURE_MODE_AUTO)!=DC1394_SUCCESS) {
						if(PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Failed to set feature %s on camera %i to automatic control! Ignored.\n", pname, capturehandle);
						fflush(NULL);
					}
				}
			}
		}
*/
	}
	else {
		if(PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Requested capture device setting %s not available on cam %i. Ignored.\n", pname, capturehandle);
		fflush(NULL);
	}
	
	// Output a warning on unknown parameters:
	if (!assigned) {
		if(PsychPrefStateGet_Verbosity()>1) printf("PTB-WARNING: Screen('SetVideoCaptureParameter', ...) called with unknown parameter %s. Ignored...\n",
												   pname);
		fflush(NULL);
	}
	
	if (assigned && oldintval!=0xFFFFFFFF) oldvalue = (double) oldintval;
	
	// Return the old value. Could be DBL_MAX if parameter was unknown or not accepted for some reason.
	return(oldvalue);
}
PsychError COCOAEVENTBRIDGEGetChar(void) 
{
	static Boolean				firstTime=TRUE;
    double						returnValue, inputValue;
	static	Boolean wasWindowOpenedFlag=FALSE;
	Boolean						isThere, inputValueBoolean, lostKeyWindowFlag;
//	InitializeCocoaProc			CocoaInitializeCocoa;
	char						readChar[2];
	double						readTime;
	int							numKeypresses, numOutputArgs;
	CFDictionaryRef				keypressDictionary=NULL, keypressModifierFlags=NULL;
	CFStringRef					keypressCharacter=NULL;
	CFNumberRef					keypressTime=NULL, keypressAddress=NULL, keypressTickCount=NULL;
	double						keypressTimeDouble, keypressTickCountDouble;
	char						keypressCharacterUTF8[2];
	CFRange						characterRange;
	UniChar						keypressCharacterUnicode[1];
	double						keypressCharacterAsValue, nowGetSecs, nowTickCount, characterTickCount, keypressAddressDouble;
	Boolean						loadBundleError;
	//for the return structure in the second argument
	const char *charTimeFieldNames[]={"ticks", "secs", "address", "alphaLock", "commandKey", "controlKey", "optionKey", "shiftKey", "numericKeypad", "functionKey"};
    int 	numStructElements=1, numStructFieldNames=10;
	PsychGenericScriptType	*charTimeStruct;
	CFNumberRef					alphaLock, commandKey, controlKey, optionKey, shiftKey, numericKeypad, helpKey, functionKey;
	char						alphaLockCFlag, commandKeyCFlag, controlKeyCFlag, optionKeyCFlag, shiftKeyCFlag, numericKeypadCFlag, helpKeyCFlag, functionKeyCFlag;
	

	//all subfunctions should have these two lines.  
	PsychPushHelp(useString, synopsisString, seeAlsoString);
	if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};

    //check to see if the user supplied superfluous arguments
    PsychErrorExit(PsychCapNumOutputArgs(2));
    PsychErrorExit(PsychCapNumInputArgs(1));

	loadBundleError=LoadCocoaBundle();
	if(loadBundleError)
		PsychErrorExitMsg(PsychError_internal, "Failed to load the cocoa bundle.");
		
    
	//Open the window.  OpenGetCharWindow() and MakeGetCharWindowInvisible() only act once if called repeatedly.
	OpenGetCharWindow();
	#ifndef DEBUG_USE_VISIBLE_WINDOW
	MakeGetCharWindowInvisible();
	#endif

	StartKeyGathering();
	MakeKeyWindow();
	lostKeyWindowFlag=FALSE;
	while(GetNumKeypresses() < 1){
		PsychWaitIntervalSeconds((double)0.005);
		//this would become an infinite loop if the user moves focus to another window, because our key collection window would never
		//receive input.  Therefore we detect if our window loses keyWindow status.  We could be more forceful about this and bring the 
		//window back into focus, if we have access to NSApplication within our Cocoa bundle.  
		lostKeyWindowFlag=!IsKeyWindow();
		if(lostKeyWindowFlag)
			break;
	}
	
//	StopKeyGathering();
//	if(!lostKeyWindowFlag)
//		RevertKeyWindow();	//restores the key window to what it was before we took it.
    if(!lostKeyWindowFlag){
		keypressDictionary=(CFDictionaryRef)CopyReadNextKeypress();
		if(keypressDictionary != NULL){			
			keypressCharacter=CFDictionaryGetValue(keypressDictionary, CFSTR("character"));
			keypressTime=CFDictionaryGetValue(keypressDictionary, CFSTR("time"));
			keypressModifierFlags=CFDictionaryGetValue(keypressDictionary, CFSTR("modifierFlags"));
			keypressTickCount=CFDictionaryGetValue(keypressDictionary, CFSTR("tickCount"));
			CFNumberGetValue(keypressTickCount, kCFNumberDoubleType, &keypressTickCountDouble);
			keypressAddress=CFDictionaryGetValue(keypressDictionary, CFSTR("keyCode"));
			CFNumberGetValue(keypressAddress, kCFNumberDoubleType, &keypressAddressDouble);
			
			characterRange.location=0;
			characterRange.length=1;
			CFStringGetCharacters(keypressCharacter, characterRange, keypressCharacterUnicode);
			if(keypressCharacterUnicode[0] <= (UniChar)127){  //it's a UTF8, MATLAB knows how do display this
				keypressCharacterUTF8[0]=(char)(keypressCharacterUnicode[0]); //throw out what MATLAB will not print.
				keypressCharacterUTF8[1]='\0';
				//mexPrintf("character:  %s\n", keypressCharacterUTF8);
				PsychCopyOutCharArg(1, kPsychArgOptional, keypressCharacterUTF8);
			}else{
				keypressCharacterAsValue=(double)(keypressCharacterUnicode[0]);
				//mexPrintf("character:  %f\n",  keypressCharacterAsValue);
				PsychCopyOutDoubleArg(1, kPsychArgOptional, keypressCharacterAsValue);
			}
	//		CFStringGetCString(keypressCharacter, keypressCharacterUTF8, 2, kCFStringEncodingUTF8);
			CFNumberGetValue(keypressTime, kCFNumberDoubleType ,&keypressTimeDouble);
	//		mexPrintf("time:       %d\n", keypressTimeDouble);
	//		PsychCopyOutDoubleArg(2, kPsychArgOptional, keypressTimeDouble);
			

			numOutputArgs= PsychGetNumOutputArgs();
			if(numOutputArgs==2){
				alphaLock= CFDictionaryGetValue(keypressModifierFlags, CFSTR("NSAlphaShiftKeyMask"));
				CFNumberGetValue(alphaLock, kCFNumberCharType, &alphaLockCFlag);
				commandKey= CFDictionaryGetValue(keypressModifierFlags, CFSTR("NSCommandKeyMask"));
				CFNumberGetValue(commandKey, kCFNumberCharType, &commandKeyCFlag);
				controlKey= CFDictionaryGetValue(keypressModifierFlags, CFSTR("NSControlKeyMask"));
				CFNumberGetValue(controlKey, kCFNumberCharType, &controlKeyCFlag);
				optionKey= CFDictionaryGetValue(keypressModifierFlags, CFSTR("NSAlternateKeyMask"));
				CFNumberGetValue(optionKey, kCFNumberCharType, &optionKeyCFlag);
				shiftKey= CFDictionaryGetValue(keypressModifierFlags, CFSTR("NSShiftKeyMask"));
				CFNumberGetValue(shiftKey, kCFNumberCharType, &shiftKeyCFlag);
				numericKeypad= CFDictionaryGetValue(keypressModifierFlags, CFSTR("NSNumericPadKeyMask"));
				CFNumberGetValue(numericKeypad, kCFNumberCharType, &numericKeypadCFlag);
	//			helpKey= CFDictionaryGetValue(keypressModifierFlags, CFSTR("NSHelpKeyMask"));
	//			CFNumberGetValue(helpKey, kCFNumberCharType, &helpKeyCFlag);
				functionKey= CFDictionaryGetValue(keypressModifierFlags, CFSTR("NSFunctionKeyMask"));
				CFNumberGetValue(functionKey, kCFNumberCharType, &functionKeyCFlag);
				
				PsychAllocOutStructArray(2, TRUE, numStructElements, numStructFieldNames, charTimeFieldNames,  &charTimeStruct);
	//			missing from OS X
	//			PsychSetStructArrayBooleanElement("mouseButton", 0, , charTimeStruct);
	//			same in OS X and OS 9
				PsychSetStructArrayDoubleElement("ticks", 0, keypressTickCountDouble, charTimeStruct);
				PsychSetStructArrayDoubleElement("secs", 0, keypressTimeDouble, charTimeStruct);	  
				PsychSetStructArrayDoubleElement("address", 0, keypressAddressDouble, charTimeStruct);	  
				PsychSetStructArrayBooleanElement("alphaLock", 0, (Boolean)alphaLockCFlag, charTimeStruct);
				PsychSetStructArrayBooleanElement("commandKey", 0, (Boolean)commandKeyCFlag, charTimeStruct);
				PsychSetStructArrayBooleanElement("controlKey", 0, (Boolean)controlKeyCFlag, charTimeStruct);
				PsychSetStructArrayBooleanElement("optionKey", 0, (Boolean)optionKeyCFlag, charTimeStruct);
	//			new for OS X
				PsychSetStructArrayBooleanElement("shiftKey", 0, (Boolean)shiftKeyCFlag, charTimeStruct);
				PsychSetStructArrayBooleanElement("numericKeypad", 0, (Boolean)numericKeypadCFlag, charTimeStruct);
	//			PsychSetStructArrayBooleanElement("helpKey", 0, (Boolean)helpKeyCFlag, charTimeStruct);
				PsychSetStructArrayBooleanElement("functionKey", 0, (Boolean)functionKeyCFlag, charTimeStruct);
				
			}
			CFRelease(keypressDictionary);
		} //close:  if(keypressDictionary != NULL){
	}else{//  if(!lostKeyWindowFlag){
		//If we get to here, that means that GetChar was called, set its key gathering window to be the key window, and while waiting
		//for key input another window was made the key window.  How should we handle this case?  Here we return nan for both arguments.
		//If we prefer to return an error, this could be done in the .m file wrapper, "Getchar" instead of here in "CocoaEventBridge('Getchar');
		PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychGetNanValue());
		PsychCopyOutDoubleArg(2, kPsychArgOptional, PsychGetNanValue());
	}
	
    return(PsychError_none);	
}