PsychError SCREENTexturizeOffscreenWindows(void) 
{
	PsychWindowRecordType	**windowRecordArray;
	int						i, numWindows; 

    
    //all subfunctions should have these two lines.  
    PsychPushHelp(useString, synopsisString, seeAlsoString);
    if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
	
	//check for superfluous or missing arguments
	PsychErrorExit(PsychCapNumInputArgs(0));   	
    PsychErrorExit(PsychRequireNumInputArgs(0)); 	

   	PsychCreateVolatileWindowRecordPointerList(&numWindows, &windowRecordArray);
	for(i=0;i<numWindows;i++){
			if(PsychIsOffscreenWindow(windowRecordArray[i])){
				PsychUpdateTargetWindowFromTargetDisplay(windowRecordArray[i]);
				PsychAllocateTexture(windowRecordArray[i]);
				PsychBindTexture(windowRecordArray[i]);
				PsychUpdateTexture(windowRecordArray[i]);
			}
	}
	PsychDestroyVolatileWindowRecordPointerList(windowRecordArray);

	
    return(PsychError_none);

}
/*
 *  void PsychQTExitMovies() - Shutdown handler.
 *
 *  This routine is called by Screen('CloseAll') and on clear Screen time to
 *  do final cleanup. It deletes all Quicktime textures and releases all Quicktime
 *  movie objects.
 *
 */
void PsychQTExitMovies(void)
{
    PsychWindowRecordType	**windowRecordArray;
    int				i, numWindows; 
    
    // Release all Quicktime related OpenGL textures:
    PsychCreateVolatileWindowRecordPointerList(&numWindows, &windowRecordArray);
    for(i=0; i<numWindows; i++) {
        // Delete all Quicktime textures:
        if ((windowRecordArray[i]->windowType == kPsychTexture) && (windowRecordArray[i]->targetSpecific.QuickTimeGLTexture !=NULL)) { 
            PsychCloseWindow(windowRecordArray[i]);
        }
    }
    PsychDestroyVolatileWindowRecordPointerList(windowRecordArray);
    
    // Release all movies:
    PsychQTDeleteAllMovies();
    
    // Shutdown Quicktime toolbox: We skip this, because according to Apple its not necessary,
    // and for some reason it reliably hangs Matlab, so one has to force-quit it :-(
    // Don't do this: ExitMovies();

#if PSYCH_SYSTEM == PSYCH_WINDOWS
    // Shutdown Quicktime core system:
    ExitMovies();
    
    // Shutdown Quicktime for Windows compatibility layer:
    TerminateQTML();
#endif
    
    return;
}
示例#3
0
void PsychFindScreenWindowFromScreenNumber(int screenNumber, PsychWindowRecordType **winRec)
{
	int							i, numWindows;
	PsychWindowRecordType		**windowArray;
	
	*winRec=NULL;
	if(screenNumber==kPsychUnaffiliatedWindow)
		return;
	PsychCreateVolatileWindowRecordPointerList(&numWindows, &windowArray);
	for(i=0;i<numWindows;i++){
		if(PsychIsOnscreenWindow(windowArray[i])){
			if(windowArray[i]->screenNumber==screenNumber){
				*winRec=windowArray[i];
				break;
			}
		}
	}
	PsychDestroyVolatileWindowRecordPointerList(windowArray);
	
} 
PsychError SCREENWindows(void) 

{

    PsychWindowRecordType	**windowRecordArray;

    int				i,numWindows;

    double			*windowPointers;

	

    //all sub functions should have these two lines

    PsychPushHelp(useString, synopsisString, seeAlsoString);

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



    PsychErrorExit(PsychCapNumOutputArgs(1));

    PsychErrorExit(PsychCapNumInputArgs(0));

    

    PsychCreateVolatileWindowRecordPointerList(&numWindows, &windowRecordArray);

    PsychAllocOutDoubleMatArg(1, FALSE, 1, numWindows, 0, &windowPointers);

    for(i=0;i<numWindows;i++)

        windowPointers[i]=windowRecordArray[i]->windowIndex;

    PsychDestroyVolatileWindowRecordPointerList(windowRecordArray);



    return(PsychError_none);	

}
/*
 *  void PsychGSExitMovies() - Shutdown handler.
 *
 *  This routine is called by Screen('CloseAll') and on clear Screen time to
 *  do final cleanup. It deletes all textures and releases all movie objects.
 *
 */
void PsychGSExitMovies(void)
{
    PsychWindowRecordType	**windowRecordArray;
    int				i, numWindows; 
    
    // Release all Quicktime related OpenGL textures:
    PsychCreateVolatileWindowRecordPointerList(&numWindows, &windowRecordArray);
    for(i=0; i<numWindows; i++) {
        // Delete all Quicktime textures:
        if ((windowRecordArray[i]->windowType == kPsychTexture) && (windowRecordArray[i]->targetSpecific.QuickTimeGLTexture !=NULL)) { 
            PsychCloseWindow(windowRecordArray[i]);
        }
    }
    PsychDestroyVolatileWindowRecordPointerList(windowRecordArray);
    
    // Release all movies:
    PsychGSDeleteAllMovies();

    firsttime = TRUE;
    
    return;
}
PsychError SCREENPreloadTextures(void)  
{	
	PsychWindowRecordType                   *windowRecord, *texwin;
	psych_bool                                 isArgThere;
        int                                     *texhandles;
        PsychWindowRecordType                   **windowRecordArray;        
        int                                     i, n, numWindows, myhandle; 
        double                                  *success;
        psych_bool*                                residency;
        GLuint*                                 texids;
        GLboolean*                              texresident;
        psych_bool                                 failed = false;
        GLclampf                                maxprio = 1.0f;
        GLenum                                  target;

	//all sub functions should have these two lines
	PsychPushHelp(useString, synopsisString,seeAlsoString);
	if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);};
	
	//check for superfluous arguments
	PsychErrorExit(PsychCapNumInputArgs(2));        //The maximum number of inputs
	PsychErrorExit(PsychRequireNumInputArgs(1));    //The minimum number of inputs
	PsychErrorExit(PsychCapNumOutputArgs(2));       //The maximum number of outputs
	
	//get the window record from the window record argument and get info from the window record
	PsychAllocInWindowRecordArg(1, kPsychArgRequired, &windowRecord);
		
	// Get optional texids vector:
	isArgThere = PsychIsArgPresent(PsychArgIn, 2);
        PsychAllocInIntegerListArg(2, FALSE, &n, &texhandles);
        if (n < 1) isArgThere=FALSE;
        
        // Enable this windowRecords framebuffer as current drawingtarget:
        PsychSetDrawingTarget(windowRecord);

		// Disable shader:
		PsychSetShader(windowRecord, 0);
	

        glDisable(GL_TEXTURE_2D);

	// Fetch global texturing mode:
	target=PsychGetTextureTarget(windowRecord);

        glEnable(target);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
        glColor4f(0, 0, 0, 0);
	// Setup identity modelview matrix:
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glLoadIdentity();

        PsychCreateVolatileWindowRecordPointerList(&numWindows, &windowRecordArray);            

        // Process vector of all texids for all requested textures:
        if (!isArgThere) {
            // No handles provided: In this case, we preload all textures:
            n=0;
            for(i=0; i<numWindows; i++) {                
                if (windowRecordArray[i]->windowType==kPsychTexture) {
                    n++;
                    // Prioritize this texture:
                    glPrioritizeTextures(1, (GLuint*) &(windowRecordArray[i]->textureNumber), &maxprio);
                    // Bind this texture:
                    glBindTexture(target, windowRecordArray[i]->textureNumber);
                    // Render a single textured point, thereby enforcing a texture upload:
                    glBegin(GL_QUADS);
                    glTexCoord2f(0,0); glVertex2i(10,10);
                    glTexCoord2f(0,1); glVertex2i(10,11);
                    glTexCoord2f(1,1); glVertex2i(11,11);
                    glTexCoord2f(1,0); glVertex2i(11,10);                    
                    glEnd();
                }
            }
            
            texids = (GLuint*) PsychMallocTemp(sizeof(GLuint) * n);
            texresident = (GLboolean*) PsychMallocTemp(sizeof(GLboolean) * n);

            n=0;
            for(i=0; i<numWindows; i++) {                
                if (windowRecordArray[i]->windowType==kPsychTexture) {
                    texids[n] = (GLuint) windowRecordArray[i]->textureNumber;
                    n++;
                }
            }
        }
        else {
            // Vector with texture handles provided: Just preload them.
            texids = (GLuint*) PsychMallocTemp(sizeof(GLuint) * n);
            texresident = (GLboolean*) PsychMallocTemp(sizeof(GLboolean) * n);
            myhandle=0;
            for (i=0; i<n; i++) {
                myhandle = texhandles[i];
                texwin = NULL;
                if (IsWindowIndex(myhandle)) FindWindowRecord(myhandle, &texwin);
                if (texwin && texwin->windowType==kPsychTexture) {
                    // Prioritize this texture:
                    glPrioritizeTextures(1, (GLuint*) &(texwin->textureNumber), &maxprio);
                    // Bind this texture:
                    glBindTexture(target, texwin->textureNumber);
                    // Render a single textured point, thereby enforcing a texture upload:
                    glBegin(GL_QUADS);
                    glTexCoord2f(0,0); glVertex2i(10,10);
                    glTexCoord2f(0,1); glVertex2i(10,11);
                    glTexCoord2f(1,1); glVertex2i(11,11);
                    glTexCoord2f(1,0); glVertex2i(11,10);                    
                    glEnd();
                    texids[i] = (GLuint) texwin->textureNumber;
                }
                else {
                    // This handle is invalid or at least no texture handle:
                    printf("PTB-ERROR! Screen('PreloadTextures'): Entry %i of texture handle vector (handle %i) is not a texture handle!\n",
                           i, myhandle);
                    failed = true;
                }
            }
        }
        
        // Restore old matrix from backup copy, undoing the global translation:
        glPopMatrix();
        // Disable texture engine:
        glDisable(GL_TEXTURE_2D);
        glDisable(target);

        // Wait for prefetch completion:
        glFinish();
        
        // We don't need these anymore:
        PsychDestroyVolatileWindowRecordPointerList(windowRecordArray);
        
        if (failed) {
            PsychErrorExitMsg(PsychError_user, "At least one texture handle in texids-vector was invalid! Aborted.");
        }
        
        // Query residency state of all preloaded textures:
        success = NULL;
        PsychAllocOutDoubleArg(1, FALSE, &success);
        *success = (double) glAreTexturesResident(n, texids, texresident);
        
        // Sync pipe again, just to be safe...
        glFinish();
        
        // Count them and copy them into output vector:
        PsychAllocOutBooleanMatArg(2, FALSE, n, 1, 1, &residency);
        
        for (i=0; i<n; i++) {
            residency[i] = (psych_bool) ((*success) ? TRUE : texresident[i]);
        }
        
        PsychTestForGLErrors();
        
 	// Done. Our PsychMallocTemp'ed arrays will be auto-released...
	return(PsychError_none);
}
示例#7
0
PsychError SCREENClose(void)

{

	PsychWindowRecordType 	*windowRecord;

        int			screenNumber;

        PsychWindowRecordType	**windowRecordArray;

        int			i, numWindows; 

	

        windowRecord=NULL;

        

	//all subfunctions should have these two lines.  

	PsychPushHelp(useString, synopsisString, seeAlsoString);

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

	

	PsychErrorExit(PsychCapNumInputArgs(1));      //The maximum number of inputs

        PsychErrorExit(PsychRequireNumInputArgs(0));  //The minimum required number of inputs	

	PsychErrorExit(PsychCapNumOutputArgs(0));     //The maximum number of outputs

	

	//Get the window record or exit with an error if the windex was bogus.

	// PsychAllocInWindowRecordArg(kPsychUseDefaultArgPosition, TRUE, &windowRecord);        

	PsychAllocInWindowRecordArg(kPsychUseDefaultArgPosition, kPsychArgOptional, &windowRecord);

        

        // Window handle of a specific window provided?

        if (windowRecord==NULL) {

            // No window handle provided: In this case, we close/destroy all textures:

            PsychCreateVolatileWindowRecordPointerList(&numWindows, &windowRecordArray);

            for(i=0;i<numWindows;i++) {

                if (windowRecordArray[i]->windowType==kPsychTexture) PsychCloseWindow(windowRecordArray[i]);

            }

            PsychDestroyVolatileWindowRecordPointerList(windowRecordArray);

            return(PsychError_none);	

        }

        

        // Window handle of a specific window or texture provided: Close it...

        if(PsychIsLastOnscreenWindow(windowRecord)){

		screenNumber=windowRecord->screenNumber;

		PsychCloseWindow(windowRecord);

		PsychReleaseScreen(screenNumber);

	}else	

		PsychCloseWindow(windowRecord);

    

	return(PsychError_none);	

}
示例#8
0
// Implement closing of all onscreen- and offscreen windows, release of all captured displays,
// releasing of all internal textures and memory buffers, stopping of internal helper threads,
// etc....
// This routine is normally called by SCREENCloseAll, but can be also called by the exit-handler,
// and diverse error-handlers for cleanup.
void ScreenCloseAllWindows(void)
{
    PsychWindowRecordType	**windowRecordArray;
    int						i, numWindows, numScreens;
    static unsigned int     recursionLevel = 0;
    
    // Recursive self-call?
    if (recursionLevel > 0) {
        // Ohoh: We are recursively calling ourselves, probably due to some
        // error condition triggered during our execution. This is bad, we need
        // to break the infinite recursion. How? We output a recursion warning,
        // then return as no-op:
        printf("PTB-ERROR: Error during error handling! ScreenCloseAllWindows() called recursively! Trying to break out of this vicious cycle...\n");
        printf("PTB-ERROR: Maybe it is a good idea to exit and restart Matlab/Octave.\n");

        // Skip to the release screen routine and hope for the best:
        goto critical_abort;
    }
    
    recursionLevel++;
    
    // Cold-Reset the drawing target:
    PsychColdResetDrawingTarget();

	// Reset the "userspaceGL" flag which tells PTB that userspace GL rendering was active
	// due to Screen('BeginOpenGL') command.
	PsychSetUserspaceGLFlag(FALSE);
	
	// Check for stale texture ressources:
	PsychRessourceCheckAndReminder(TRUE);	
	
    // Shutdown Quicktime subsystems if active:
	PsychExitMovieWriting();
    PsychExitMovies();
    PsychExitVideoCapture();

    // Close the windows: We do it reverse (descending) order so textures get closed
    // before the onscreen windows. In theory this shouldn't matter, but in practice,
    // more stress on the PsychCloseWindow() path. If we have bugs there, chances are
    // higher they get exposed this way, which long-term is a good thing(TM).
    PsychCreateVolatileWindowRecordPointerList(&numWindows, &windowRecordArray);
    for(i = numWindows - 1; i >= 0; i--) {
		if (PsychPrefStateGet_Verbosity()>5) { printf("PTB-DEBUG: In ScreenCloseAllWindows(): Destroying window %i\n", i); fflush(NULL); }
		PsychCloseWindow(windowRecordArray[i]);
	}
    PsychDestroyVolatileWindowRecordPointerList(windowRecordArray);

critical_abort:

    // Release all captured displays, unhide the cursor on each of them:
    numScreens=PsychGetNumDisplays();
    for(i=0;i<numScreens;i++){
        if(PsychIsScreenCaptured(i)) {
			PsychRestoreScreenSettings(i);
			PsychReleaseScreen(i);
		}
		 
		PsychShowCursor(i, -1);
    }

    recursionLevel--;
    
    return;
}
// Callback handler for Window manager: Handles some events
LONG FAR PASCAL WndProc(HWND hWnd, unsigned uMsg, unsigned wParam, LONG lParam)
{
  static PAINTSTRUCT ps;
  PsychWindowRecordType	**windowRecordArray;
  int i, numWindows; 

  // What event happened?
  switch(uMsg) {
    case WM_SYSCOMMAND:
      // System command received: We intercept system commands that would start
      // the screensaver or put the display into powersaving sleep-mode:
      switch(wParam) {
			case SC_SCREENSAVE:
			case SC_MONITORPOWER:
	  		return(0);
		}
    break;
	
	 case WM_LBUTTONDOWN:
		// Left mouse button depressed:
		mousebutton_l = TRUE;
	 break;

	 case WM_LBUTTONUP:
		// Left mouse button released:
		mousebutton_l = FALSE;
	 break;

	 case WM_MBUTTONDOWN:
		// Middle mouse button depressed:
		mousebutton_m = TRUE;
	 break;

	 case WM_MBUTTONUP:
		// Middle mouse button released:
		mousebutton_m = FALSE;
	 break;

	 case WM_RBUTTONDOWN:
		// Right mouse button depressed:
		mousebutton_r = TRUE;
	 break;

	 case WM_RBUTTONUP:
		// Right mouse button released:
		mousebutton_r = FALSE;
	 break;
	 
    case WM_PAINT:
      // Repaint event: This happens if a previously covered non-fullscreen window
      // got uncovered, so part of it needs to be redrawn. PTB's rendering model
      // doesn't have a concept of redrawing a stimulus. As this is mostly useful
      // for debugging, we just do a double doublebuffer swap in the hope that this
      // will restore the frontbuffer...
      BeginPaint(hWnd, &ps);
      EndPaint(hWnd, &ps);
      // Scan the list of windows to find onscreen window with handle hWnd:
      PsychCreateVolatileWindowRecordPointerList(&numWindows, &windowRecordArray);
      for(i = 0; i < numWindows; i++) {
			if (PsychIsOnscreenWindow(windowRecordArray[i]) &&
	    		 windowRecordArray[i]->targetSpecific.windowHandle == hWnd &&
				 windowRecordArray[i]->stereomode == 0) {
	  			// This is it! Initiate bufferswap twice:
	  			PsychOSFlipWindowBuffers(windowRecordArray[i]);
	  			PsychOSFlipWindowBuffers(windowRecordArray[i]);
			}
      }
      PsychDestroyVolatileWindowRecordPointerList(windowRecordArray);
      // Done.
      return 0;

    case WM_SIZE:
      // Window resize event: Only happens in debug-mode (non-fullscreen).
      // We resize the viewport accordingly and then trigger a repaint-op.
      glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
      PostMessage(hWnd, WM_PAINT, 0, 0);
      // printf("\nPTB-INFO: Onscreen window resized to: %i x %i.\n", (int) LOWORD(lParam), (int) HIWORD(lParam));
      return 0;

    case WM_CLOSE:
      // WM_CLOSE falls through to WM_CHAR and emulates an Abort-key press.
      // -> Manually closing an onscreen window does the same as pressing the Abort-key.
      wParam='@';
    case WM_CHAR:
      // Character received. We only care about one key, the '@' key.
      // Pressing '@' will immediately close all onscreen windows, show
      // the cursor and such. It is the emergency stop key.
      if (wParam=='@') {
	// Emergency shutdown:
	printf("\nPTB-INFO: Master-Abort key '@' pressed by user.\n");
	printf("PTB-INFO: Enforcing script abortion and restoring desktop by executing Screen('CloseAll') now!\n");
	printf("PTB-INFO: Please ignore the false error message (INTERNAL PSYCHTOOLBOX ERROR) caused by this...\n");
	ScreenCloseAllWindows();
	return(0);
      }
      break;
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}