In glutMainLoop, the checking of ExecState, and wether it's equal to
[freeglut] / src / fg_main.c
index 3b32f06..0f47c8d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * freeglut_main.c
+ * fg_main.c
  *
  * The windows message processing methods.
  *
 
 #include <GL/freeglut.h>
 #include "fg_internal.h"
-#ifdef HAVE_ERRNO_H
-#    include <errno.h>
-#endif
+#include <errno.h>
 #include <stdarg.h>
-#ifdef  HAVE_VFPRINTF
-#    define VFPRINTF(s,f,a) vfprintf((s),(f),(a))
-#elif defined(HAVE__DOPRNT)
-#    define VFPRINTF(s,f,a) _doprnt((f),(a),(s))
-#else
-#    define VFPRINTF(s,f,a)
-#endif
 
 /*
  * Try to get the maximum value allowed for ints, falling back to the minimum
@@ -54,7 +45,7 @@
 #    define MIN(a,b) (((a)<(b)) ? (a) : (b))
 #endif
 
-extern void fgPlatformProcessWork   ( SFG_Window *window );
+extern void fgProcessWork   ( SFG_Window *window );
 extern fg_time_t fgPlatformSystemTime ( void );
 extern void fgPlatformSleepForEvents( fg_time_t msec );
 extern void fgPlatformProcessSingleEvent ( void );
@@ -163,7 +154,7 @@ static void fghcbProcessWork( SFG_Window *window,
                               SFG_Enumerator *enumerator )
 {
     if( window->State.WorkMask )
-               fgPlatformProcessWork ( window );
+        fgProcessWork ( window );
 
     fgEnumSubWindows( window, fghcbProcessWork, enumerator );
 }
@@ -289,7 +280,7 @@ void fgError( const char *fmt, ... )
         fprintf( stderr, "freeglut ");
         if( fgState.ProgramName )
             fprintf( stderr, "(%s): ", fgState.ProgramName );
-        VFPRINTF( stderr, fmt, ap );
+        vfprintf( stderr, fmt, ap );
         fprintf( stderr, "\n" );
 
         va_end( ap );
@@ -322,7 +313,7 @@ void fgWarning( const char *fmt, ... )
         fprintf( stderr, "freeglut ");
         if( fgState.ProgramName )
             fprintf( stderr, "(%s): ", fgState.ProgramName );
-        VFPRINTF( stderr, fmt, ap );
+        vfprintf( stderr, fmt, ap );
         fprintf( stderr, "\n" );
 
         va_end( ap );
@@ -385,15 +376,15 @@ static void fghSleepForEvents( void )
     msec = fghNextTimer( );
     /* XXX Should use GLUT timers for joysticks... */
     /* XXX Dumb; forces granularity to .01sec */
-    if( fgState.NumActiveJoysticks>0 && ( msec > 10 ) )     
+    if( fgState.NumActiveJoysticks>0 && ( msec > 10 ) )
         msec = 10;
 
-       fgPlatformSleepForEvents ( msec );
+    fgPlatformSleepForEvents ( msec );
 }
 
 
 /* Step through the work list */
-void fgPlatformProcessWork(SFG_Window *window)
+void fgProcessWork(SFG_Window *window)
 {
     unsigned int workMask = window->State.WorkMask;
     /* Now clear it so that any callback generated by the actions below can set work again */
@@ -432,13 +423,17 @@ void fgPlatformProcessWork(SFG_Window *window)
         }
     }
 
-    if (workMask & GLUT_DISPLAY_WORK)
+    /* check window state's workmask as well as some of the above callbacks might have generated redisplay requests. We can deal with those right now instead of wait for the next mainloop iteration. */
+    if (workMask & GLUT_DISPLAY_WORK || window->State.WorkMask & GLUT_DISPLAY_WORK)
     {
         if( window->State.Visible )
-            fghRedrawWindow ( window );
+        {
+            /* Strip out display work from the work list */
+            /* NB: do this before the display callback is called as user might call postredisplay in his display callback */
+            window->State.WorkMask &= ~GLUT_DISPLAY_WORK;
 
-        /* Strip out display work that might have ended up on work list now as some of the above genereates callbacks */
-        window->State.WorkMask &= ~GLUT_DISPLAY_WORK;
+            fghRedrawWindow ( window );
+        }
     }
 }
 
@@ -461,6 +456,13 @@ void FGAPIENTRY glutMainLoopEvent( void )
     /* Perform work on the window (position, reshape, display, etc) */
     fghProcessWork( );
 
+    /* Check OpenGL error state if requested.
+     * Don't call if no more open windows (can happen if user closes window from
+     * title bar), would lead to infinite error loop in glutReportErrors
+     */
+    if (fgState.GLDebugSwitch && fgStructure.CurrentWindow)
+        glutReportErrors( );
+
     fgCloseWindows( );
 }
 
@@ -477,14 +479,16 @@ void FGAPIENTRY glutMainLoop( void )
     if (!fgStructure.Windows.First)
         fgError(" ERROR:  glutMainLoop called with no windows created.");
 
-       fgPlatformMainLoopPreliminaryWork ();
+    fgPlatformMainLoopPreliminaryWork ();
 
     fgState.ExecState = GLUT_EXEC_STATE_RUNNING ;
-    while( fgState.ExecState == GLUT_EXEC_STATE_RUNNING )
+    for(;;)
     {
         SFG_Window *window;
 
         glutMainLoopEvent( );
+        if( fgState.ExecState != GLUT_EXEC_STATE_RUNNING )
+            break;
         /*
          * Step through the list of windows, seeing if there are any
          * that are not menus