PsychError SCREENglPoint(void) { PsychColorType color; double *xPosition, *yPosition, dotSize; PsychWindowRecordType *windowRecord; int whiteValue; psych_bool isArgThere; //all sub functions should have these two lines PsychPushHelp(useString, synopsisString,seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; //check for superfluous arguments PsychErrorExit(PsychCapNumInputArgs(5)); //The maximum number of inputs PsychErrorExit(PsychCapNumOutputArgs(0)); //The maximum number of outputs //get the window record from the window record argument and get info from the window record PsychAllocInWindowRecordArg(kPsychUseDefaultArgPosition, TRUE, &windowRecord); //Get the color argument or use the default, then coerce to the form determened by the window depth. isArgThere=PsychCopyInColorArg(kPsychUseDefaultArgPosition, FALSE, &color); if(!isArgThere){ whiteValue=PsychGetWhiteValueFromWindow(windowRecord); PsychLoadColorStruct(&color, kPsychIndexColor, whiteValue ); //index mode will coerce to any other. } PsychCoerceColorMode( &color); //get the x and y position values. PsychAllocInDoubleArg(3, TRUE, &xPosition); PsychAllocInDoubleArg(4, TRUE, &yPosition); dotSize=1; //set the default PsychCopyInDoubleArg(5, FALSE, &dotSize); // Enable this windowRecords framebuffer as current drawingtarget: PsychSetDrawingTarget(windowRecord); // Set default draw shader: PsychSetShader(windowRecord, -1); PsychUpdateAlphaBlendingFactorLazily(windowRecord); PsychSetGLColor(&color, windowRecord); glEnable(GL_POINT_SMOOTH); glPointSize((float)dotSize); glBegin(GL_POINTS); glVertex2d( (GLdouble)*xPosition, *yPosition); glEnd(); glDisable(GL_POINT_SMOOTH); glPointSize(1); // Mark end of drawing op. This is needed for single buffered drawing: PsychFlushGL(windowRecord); //All psychfunctions require this. return(PsychError_none); }
PsychError SCREENgluDisk(void) { PsychColorType color; double *xPosition, *yPosition, dotSize; PsychWindowRecordType *windowRecord; int depthValue, whiteValue, colorPlaneSize, numColorPlanes; boolean isArgThere; GLUquadricObj *diskQuadric; //all sub functions should have these two lines PsychPushHelp(useString, synopsisString,seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; //check for superfluous arguments PsychErrorExit(PsychCapNumInputArgs(5)); //The maximum number of inputs PsychErrorExit(PsychCapNumOutputArgs(0)); //The maximum number of outputs //get the window record from the window record argument and get info from the window record PsychAllocInWindowRecordArg(kPsychUseDefaultArgPosition, TRUE, &windowRecord); //Get the depth from the window, we need this to interpret the color argument. depthValue=PsychGetWindowDepthValueFromWindowRecord(windowRecord); numColorPlanes=PsychGetNumPlanesFromDepthValue(depthValue); colorPlaneSize=PsychGetColorSizeFromDepthValue(depthValue); //Get the color argument or use the default, then coerce to the form determened by the window depth. isArgThere=PsychCopyInColorArg(kPsychUseDefaultArgPosition, FALSE, &color); if(!isArgThere){ whiteValue=PsychGetWhiteValueFromDepthValue(depthValue); PsychLoadColorStruct(&color, kPsychIndexColor, whiteValue ); //index mode will coerce to any other. } PsychCoerceColorModeFromSizes(numColorPlanes, colorPlaneSize, &color); //get the x and y position values. PsychAllocInDoubleArg(3, TRUE, &xPosition); PsychAllocInDoubleArg(4, TRUE, &yPosition); dotSize=1; //set the default PsychCopyInDoubleArg(5, FALSE, &dotSize); //Set the color and draw the rect. Note that all GL drawing commands should be sandwiched between PsychSetGLContext(windowRecord); PsychUpdateAlphaBlendingFactorLazily(windowRecord); PsychSetGLColor(&color, depthValue); glPushMatrix(); glTranslated(*xPosition,*yPosition,0); diskQuadric=gluNewQuadric(); gluDisk(diskQuadric, 0, dotSize, 30, 30); gluDeleteQuadric(diskQuadric); glPopMatrix(); //PsychGLRect(rect); PsychFlushGL(windowRecord); //OS X: This does nothing if we are multi buffered, otherwise it glFlushes //All psychfunctions require this. return(PsychError_none); }
psych_bool PsychCopyInWindowIndexArg(int position, psych_bool required, PsychWindowIndexType *windowIndex) { double *arg; psych_bool isThere; if(position==kPsychUseDefaultArgPosition) position = kPsychDefaultNumdexArgPosition; isThere=PsychAllocInDoubleArg(position,required,&arg); if(!isThere) return(FALSE); *windowIndex = (PsychWindowIndexType)*arg; if(IsWindowIndex(*windowIndex)) return(TRUE); else{ PsychErrorExitMsg(PsychError_invalidWindex,NULL); return(FALSE); //only to satisfy the compiler with a return statement. } }
PsychError SCREENLineStipple(void) { PsychWindowRecordType *winRec; static GLushort stipplePatternTemp; boolean isFactorThere, isPatternThere, isFlagThere, didChange; double *newFactor; boolean *newPatternArray; int numInputVectorElements; PsychNativeBooleanType *oldPatternArray; boolean *newEnableFlag; //all sub functions should have these two lines PsychPushHelp(useString, synopsisString,seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; //check for superfluous arguments PsychErrorExit(PsychCapNumInputArgs(4)); //The maximum number of inputs PsychErrorExit(PsychCapNumOutputArgs(3)); //The maximum number of outputs //get the window record from the window record argument and get info from the window record PsychAllocInWindowRecordArg(1, kPsychArgRequired, &winRec); //return existing values PsychCopyOutFlagArg(1, kPsychArgOptional, winRec->stippleEnabled); PsychCopyOutDoubleArg(2, kPsychArgOptional, (double)winRec->stippleFactor); PsychAllocOutBooleanMatArg(3, kPsychArgOptional, 1, 16, 0, &oldPatternArray); ConvertShortToStippleArray(oldPatternArray, winRec->stipplePattern); //read in new values didChange=FALSE; isFlagThere=PsychAllocInFlagArg(2, kPsychArgOptional, &newEnableFlag); if(isFlagThere && *newEnableFlag != winRec->stippleEnabled){ didChange=TRUE; winRec->stippleEnabled=*newEnableFlag; } isFactorThere=PsychAllocInDoubleArg(3, kPsychArgOptional, &newFactor); if(isFactorThere && (GLint)(*newFactor) != winRec->stippleFactor){ didChange=TRUE; winRec->stippleFactor=(GLint)(*newFactor); } //NOTE: fix PsychAllocInFlagArgVector so that it limits to numInputVectorElements. isPatternThere=PsychAllocInFlagArgVector(4, kPsychArgOptional, &numInputVectorElements, &newPatternArray); if(isPatternThere){ if(numInputVectorElements != 16) PsychErrorExitMsg(PsychError_inputMatrixIllegalDimensionSize, "Argument \"stipplePattern\" should be a vector of 16 elements in size"); ConvertStippleArrayToShort(newPatternArray, &stipplePatternTemp); if(stipplePatternTemp != winRec->stipplePattern){ didChange=TRUE; winRec->stipplePattern=stipplePatternTemp; } } //Update GL context according to new settings. if(didChange){ //avoids unnecessary context switches PsychSetGLContext(winRec); glLineStipple(winRec->stippleFactor, winRec->stipplePattern); if(winRec->stippleEnabled) glEnable(GL_LINE_STIPPLE); else glDisable(GL_LINE_STIPPLE); } //All psychfunctions require this. return(PsychError_none); }
void PsychRenderArc(unsigned int mode) { PsychColorType color; PsychRectType rect; double *startAngle, *arcAngle, *penWidth, *penHeight; PsychWindowRecordType *windowRecord; int depthValue, whiteValue, colorPlaneSize, numColorPlanes; double dotSize; boolean isArgThere; GLUquadric *diskQuadric = NULL; //get the window record from the window record argument and get info from the window record PsychAllocInWindowRecordArg(kPsychUseDefaultArgPosition, TRUE, &windowRecord); //Get the depth from the window, we need this to interpret the color argument. depthValue=PsychGetWindowDepthValueFromWindowRecord(windowRecord); numColorPlanes=PsychGetNumPlanesFromDepthValue(depthValue); colorPlaneSize=PsychGetColorSizeFromDepthValue(depthValue); //Get the color argument or use the default, then coerce to the form determened by the window depth. isArgThere=PsychCopyInColorArg(kPsychUseDefaultArgPosition, FALSE, &color); if(!isArgThere){ whiteValue=PsychGetWhiteValueFromDepthValue(depthValue); PsychLoadColorStruct(&color, kPsychIndexColor, whiteValue ); //index mode will coerce to any other. } PsychCoerceColorModeFromSizes(numColorPlanes, colorPlaneSize, &color); // Get the rect to which the object should be inscribed: Default is "full screen" PsychMakeRect(rect, 0, 0, PsychGetWidthFromRect(windowRecord->rect), PsychGetHeightFromRect(windowRecord->rect)); PsychCopyInRectArg(3, FALSE, rect); double w=PsychGetWidthFromRect(rect); double h=PsychGetHeightFromRect(rect); double cx, cy, aspect; PsychGetCenterFromRectAbsolute(rect, &cx, &cy); if (w==0 || h==0) PsychErrorExitMsg(PsychError_user, "Invalid rect (width or height equals zero) provided!"); // Get start angle: PsychAllocInDoubleArg(4, TRUE, &startAngle); PsychAllocInDoubleArg(5, TRUE, &arcAngle); if (mode==2) { // Get pen width and height: penWidth=NULL; penHeight=NULL; PsychAllocInDoubleArg(6, FALSE, &penWidth); PsychAllocInDoubleArg(7, FALSE, &penHeight); // Check if penWidth and penHeight spec'd. If so, they // need to be equal: if (penWidth && penHeight && (*penWidth!=*penHeight)) { PsychErrorExitMsg(PsychError_user, "penWidth and penHeight must be equal on OS-X if both are specified!"); } dotSize=1; if (penWidth) dotSize = *penWidth; if (penHeight) dotSize = *penHeight; } // Setup OpenGL context: PsychSetGLContext(windowRecord); PsychUpdateAlphaBlendingFactorLazily(windowRecord); PsychSetGLColor(&color, depthValue); // Backup our modelview matrix: glMatrixMode(GL_MODELVIEW); glPushMatrix(); // Position disk at center of rect: glTranslated(cx, cy, 0); // Scale in order to fit to rect in case w!=h: glScaled(1.0, -h/w, 1.0); // Draw filled partial disk: diskQuadric=gluNewQuadric(); switch (mode) { case 1: // One pixel thin arc: InnerRadius = OuterRadius - 1 gluPartialDisk(diskQuadric, (w/2) - 1.0, w/2, w, 2, *startAngle, *arcAngle); break; case 2: // dotSize thick arc: InnerRadius = OuterRadius - dotsize gluPartialDisk(diskQuadric, (dotSize < (w/2)) ? (w/2) - dotSize : 0, w/2, w, 2, *startAngle, *arcAngle); break; case 3: // Filled arc: gluPartialDisk(diskQuadric, 0, w/2, w, 1, *startAngle, *arcAngle); break; } gluDeleteQuadric(diskQuadric); // Restore old matrix: glPopMatrix(); return; }
PsychError MACHPRIORITYMachPriority(void) { //double *returnValue; //int newPriority; const char *outerStructFieldNames[]={"thread", "flavor", "policy"}; const char *policyStructFieldNames[]={"period", "computation", "constraint", "preemptible"}; int numOuterStructDimensions=1, numOuterStructFieldNames=3, numPolicyStructDimensions=1, numPolicyStructFieldNames=4; PsychGenericScriptType *outerStructArray, *policyStructArray; int kernError, numInputArgs; thread_act_t threadID; static thread_policy_flavor_t currentThreadFlavor=THREAD_STANDARD_POLICY; struct thread_time_constraint_policy oldPolicyInfo, newPolicyInfo; mach_msg_type_number_t msgTypeNumber; boolean_t getDefault; char *flavorStr; boolean setNewMode; double *periodArg, *computationArg, *constraintArg, *preemptibleArg; char errorMessageStr[256]; //check to see if the user supplied superfluous arguments PsychErrorExit(PsychCapNumOutputArgs(1)); PsychErrorExit(PsychCapNumInputArgs(4)); //actually we permit only zero or three arguments. numInputArgs=PsychGetNumInputArgs(); if(numInputArgs==4) setNewMode=TRUE; else if(numInputArgs==0) setNewMode=FALSE; else PsychErrorExitMsg(PsychError_user,"Incorrect number of arguments. Either zero or four arguments accepted"); //read the current settings threadID= mach_thread_self(); currentThreadFlavor=THREAD_TIME_CONSTRAINT_POLICY; msgTypeNumber=THREAD_TIME_CONSTRAINT_POLICY_COUNT; getDefault=FALSE; kernError= thread_policy_get(threadID, currentThreadFlavor, (int *)&oldPolicyInfo, &msgTypeNumber, &getDefault); if(kernError != KERN_SUCCESS) PsychErrorExitMsg(PsychError_internal,"\"thread_policy_get()\" returned and error when reading current thread policy"); //fill in the outgoig struct with current thread settings values. //outer struct PsychAllocOutStructArray(1, FALSE, numOuterStructDimensions, numOuterStructFieldNames, outerStructFieldNames, &outerStructArray); PsychSetStructArrayDoubleElement("thread", 0, (double)threadID, outerStructArray); flavorStr=GetFlavorStringFromFlavorConstant(currentThreadFlavor); PsychSetStructArrayStringElement("flavor", 0, flavorStr, outerStructArray); //enclosed policy struct PsychAllocOutStructArray(-1, FALSE, numPolicyStructDimensions, numPolicyStructFieldNames, policyStructFieldNames, &policyStructArray); PsychSetStructArrayDoubleElement("period", 0, (double)oldPolicyInfo.period, policyStructArray); PsychSetStructArrayDoubleElement("computation", 0, (double)oldPolicyInfo.computation, policyStructArray); PsychSetStructArrayDoubleElement("constraint", 0, (double)oldPolicyInfo.constraint, policyStructArray); PsychSetStructArrayDoubleElement("preemptible", 0, (double)oldPolicyInfo.preemptible, policyStructArray); PsychSetStructArrayStructElement("policy",0, policyStructArray, outerStructArray); //Set the priority if(setNewMode){ //if there is only one argument then it must be the flavor argument re PsychAllocInDoubleArg(1, TRUE, &periodArg); PsychAllocInDoubleArg(2, TRUE, &computationArg); PsychAllocInDoubleArg(3, TRUE, &constraintArg); PsychAllocInDoubleArg(4, TRUE, &preemptibleArg); newPolicyInfo.period=(uint32_t)*periodArg; newPolicyInfo.computation=(uint32_t)*computationArg; newPolicyInfo.constraint=(uint32_t)*constraintArg; newPolicyInfo.preemptible=(boolean_t)*preemptibleArg; kernError= thread_policy_set(threadID, THREAD_TIME_CONSTRAINT_POLICY, (int *)&newPolicyInfo, THREAD_TIME_CONSTRAINT_POLICY_COUNT); if(kernError != KERN_SUCCESS){ sprintf(errorMessageStr,"%s%d", "\"thread_policy_set()\" returned and error when setting new thread policy: ", (int)kernError); PsychErrorExitMsg(PsychError_internal, errorMessageStr); } } return(PsychError_none); }