/* * 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; }
/* * 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 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); }
// 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; }