Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
PsychError SCREENTextBounds(void) 
{
	//for debugging
	TextEncodingBase		textEncodingBase;
	TextEncodingVariant		textEncodingVariant;
	TextEncodingFormat		textEncodingFormat;
	
	///////
        PsychWindowRecordType           *winRec;
	char				*textCString;
	Str255				textPString;
	UniChar				*textUniString;
	OSStatus			callError;
	PsychRectType			resultPsychRect, resultPsychNormRect;
	ATSUTextLayout			textLayout;				//layout is a pointer to an opaque struct.
	int				stringLengthChars;
	int				uniCharBufferLengthElements, uniCharBufferLengthChars, uniCharBufferLengthBytes, yPositionIsBaseline;
	double			textHeightToBaseline;
	ByteCount			uniCharStringLengthBytes;
	TextToUnicodeInfo		textToUnicodeInfo;
	TextEncoding			textEncoding;
	ATSUStyle			atsuStyle;
	Boolean				foundFont;
	
	//for ATSU  style attributes
	PsychFontStructPtrType  psychFontRecord;

    			
        //all subfunctions should have these two lines.  
        PsychPushHelp(useString, synopsisString, seeAlsoString);
        if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
    
        //check for correct the number of arguments before getting involved
        PsychErrorExit(PsychCapNumInputArgs(5));   	
        PsychErrorExit(PsychRequireNumInputArgs(2)); 	
        PsychErrorExit(PsychCapNumOutputArgs(2));
	
	//get the window pointer and the text string and check that the window record has a font set
        PsychAllocInWindowRecordArg(1, kPsychArgRequired, &winRec);
	foundFont=PsychGetFontRecordFromFontNumber(winRec->textAttributes.textFontNumber, &psychFontRecord);
	if(!foundFont)
		PsychErrorExitMsg(PsychError_user, "Attempt to determine the bounds of text with no font or invalid font number");
		//it would be better to both prevent the user from setting invalid font numbers and init to the OS 9  default font.
	
	//read in the string and get its length and convert it to a unicode string.
	PsychAllocInCharArg(2, kPsychArgRequired, &textCString);
	stringLengthChars=strlen(textCString);
	if(stringLengthChars < 1) PsychErrorExitMsg(PsychError_user, "You asked me to compute the bounding box of an empty text string?!? Sorry, that's a no no...");
	if(stringLengthChars > 255) PsychErrorExitMsg(PsychError_unimplemented, "Cut corners and TextBounds will not accept a string longer than 255 characters");
	CopyCStringToPascal(textCString, textPString);
	uniCharBufferLengthChars= stringLengthChars * CHAR_TO_UNICODE_LENGTH_FACTOR;
	uniCharBufferLengthElements= uniCharBufferLengthChars + 1;		
	uniCharBufferLengthBytes= sizeof(UniChar) * uniCharBufferLengthElements;
	textUniString=(UniChar*)malloc(uniCharBufferLengthBytes);

    PsychCopyInDoubleArg(3, kPsychArgOptional, &(winRec->textAttributes.textPositionX));
    PsychCopyInDoubleArg(4, kPsychArgOptional, &(winRec->textAttributes.textPositionY));

	//Using a TextEncoding type describe the encoding of the text to be converteed.  
	textEncoding=CreateTextEncoding(kTextEncodingMacRoman, kMacRomanDefaultVariant, kTextEncodingDefaultFormat);
	//Take apart the encoding we just made to check it:
        textEncodingBase=GetTextEncodingBase(textEncoding);
        textEncodingVariant=GetTextEncodingVariant(textEncoding);
        textEncodingFormat=GetTextEncodingFormat(textEncoding);
	//Create a structure holding conversion information from the text encoding type we just created.
	callError=CreateTextToUnicodeInfoByEncoding(textEncoding,&textToUnicodeInfo);
	//Convert the text to a unicode string
	callError=ConvertFromPStringToUnicode(textToUnicodeInfo, textPString, (ByteCount)uniCharBufferLengthBytes,	&uniCharStringLengthBytes,	textUniString);
	//create the text layout object
	callError=ATSUCreateTextLayout(&textLayout);			
	//associate our unicode text string with the text layout object
	callError=ATSUSetTextPointerLocation(textLayout, textUniString, kATSUFromTextBeginning, kATSUToTextEnd, (UniCharCount)stringLengthChars);
	
	//create an ATSU style object
	callError=ATSUCreateStyle(&atsuStyle);
	callError=ATSUClearStyle(atsuStyle);
	
	//Not that we have a style object we have to set style charactersitics.  These include but are more general than Font Manager styles.  
	//ATSU Style objects have three sets of characteristics:  attributes, variations, and features.
	//attributes are things we need to set to match OS 9 behavior, such as the font ID, size, boldness, and italicization.
	//features are esoteric settings which we don't need for reproducing OS 9 behavior.  Whatever clearstyle sets should be fine.
	//font variations are axes of variation through the space of font characteristics.  The font definition includes available axes of variation.  Something else we can ignore for now.  
	PsychSetATSUStyleAttributesFromPsychWindowRecord(atsuStyle, winRec);
	//don't bother to set the variations of the style.
	//don't bother to set the features of the style.
	
	//associate the style with our layout object. This call assigns a style to every character of the string to be displayed.  
	callError=ATSUSetRunStyle(textLayout, atsuStyle, (UniCharArrayOffset)0, (UniCharCount)stringLengthChars);

	// Define the meaning of the y position of the specified drawing cursor.
	// We get the global setting from the Screen preference, but allow to override
	// it on a per-invocation basis via the optional 7th argument to 'DrawText':
	yPositionIsBaseline = PsychPrefStateGet_TextYPositionIsBaseline();
	PsychCopyInIntegerArg(5, kPsychArgOptional, &yPositionIsBaseline);
	 
	if (yPositionIsBaseline) {
		// Y position of drawing cursor defines distance between top of text and
		// baseline of text, i.e. the textheight excluding descenders of letters:

		// Need to compute offset via ATSU:
		ATSUTextMeasurement mleft, mright, mtop, mbottom;
        callError=ATSUGetUnjustifiedBounds(textLayout, kATSUFromTextBeginning, kATSUToTextEnd, &mleft, &mright, &mbottom, &mtop);
		if (callError) {
			PsychErrorExitMsg(PsychError_internal, "Failed to compute unjustified text height to baseline in call to ATSUGetUnjustifiedBounds().\n");    
		}

		// Only take height including ascenders into account, not the descenders.
		// MK: Honestly, i have no clue why this is the correct calculation (or if it is
		// the correct calculation), but visually it seems to provide the correct results
		// and i'm not a typographic expert and don't intend to become one...
		textHeightToBaseline = fabs(Fix2X(mbottom));
	}
	else {
		// Y position of drawing cursor defines top of text, therefore no offset (==0) needed:
		textHeightToBaseline = 0;
	}

	//Get the bounds for our text so that and create a texture of sufficient size to containt it. 
	ATSTrapezoid trapezoid;
	ItemCount oActualNumberOfBounds = 0;
	callError=ATSUGetGlyphBounds(textLayout, 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 0, NULL, &oActualNumberOfBounds);
	if (callError || oActualNumberOfBounds!=1) {
		PsychErrorExitMsg(PsychError_internal, "Failed to compute bounding box in call 1 to ATSUGetGlyphBounds() (nrbounds!=1)\n");    
	}
	callError=ATSUGetGlyphBounds(textLayout, 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseDeviceOrigins, 1, &trapezoid, &oActualNumberOfBounds);
	if (callError || oActualNumberOfBounds!=1) {
		PsychErrorExitMsg(PsychError_internal, "Failed to retrieve bounding box in call 2 to ATSUGetGlyphBounds() (nrbounds!=1)\n");    
	}
	
	resultPsychRect[kPsychLeft]=(Fix2X(trapezoid.upperLeft.x) < Fix2X(trapezoid.lowerLeft.x)) ? Fix2X(trapezoid.upperLeft.x) : Fix2X(trapezoid.lowerLeft.x);
	resultPsychRect[kPsychRight]=(Fix2X(trapezoid.upperRight.x) > Fix2X(trapezoid.lowerRight.x)) ? Fix2X(trapezoid.upperRight.x) : Fix2X(trapezoid.lowerRight.x);
	resultPsychRect[kPsychTop]=(Fix2X(trapezoid.upperLeft.y) < Fix2X(trapezoid.upperRight.y)) ? Fix2X(trapezoid.upperLeft.y) : Fix2X(trapezoid.upperRight.y);
	resultPsychRect[kPsychBottom]=(Fix2X(trapezoid.lowerLeft.y) > Fix2X(trapezoid.lowerRight.y)) ? Fix2X(trapezoid.lowerLeft.y) : Fix2X(trapezoid.lowerRight.y);
	
	PsychNormalizeRect(resultPsychRect, resultPsychNormRect);
	resultPsychRect[kPsychLeft]=resultPsychNormRect[kPsychLeft] + winRec->textAttributes.textPositionX;
	resultPsychRect[kPsychRight]=resultPsychNormRect[kPsychRight] + winRec->textAttributes.textPositionX;
	resultPsychRect[kPsychTop]=resultPsychNormRect[kPsychTop] + winRec->textAttributes.textPositionY - textHeightToBaseline;
	resultPsychRect[kPsychBottom]=resultPsychNormRect[kPsychBottom] + winRec->textAttributes.textPositionY - textHeightToBaseline;

	PsychCopyOutRectArg(1, FALSE, resultPsychNormRect);
	PsychCopyOutRectArg(2, FALSE, resultPsychRect);


	//release resources
	free((void*)textUniString);
	callError=ATSUDisposeStyle(atsuStyle);

    return(PsychError_none);
}