Re: FreeGlut and Lush [PATCH INCLUDED]
Leon Bottou <[email protected]>
| Newsgroups | gmane.lisp.lush.devel |
|---|---|
| Message-ID | <[email protected]> |
The attached patch adds the following glutGet codes. These provide means to use glutMainLoopEvent() without having to poll in a busy loop. glutGet(GLUT_CONNECTION) --- Returns a system dependent integer indicating how to wait for window system events pertaining to the windows managed by freeglut. - Unix: returns a file descriptor for function select() - Win32: always returns -1 because the message source is implicit in the windows API. - Other: to be defined glutGet(GLUT_IDLE_TIME) --- Returns the expected idle time. The main loop should not wait more than the expected idle time (in milliseconds) before calling glutMainLoopEvent() again. Remark1: The main loop must still call glutMainLoopEvent() as soon as there are pending window system events. But it should also call glutMainLoopEvent() within the specified idle time regardless of the presence of pending window system events. This is used for timers, joysticks, etc... Remark2: A return value of 0 indicates that glutMainLoopEvent() has something do The patch also includes a fix for bug #944577. Remark: The choice of GLEnum constants for GLUT_CONNECTION and GLUT_IDLE_TIME was made almost randomly. I could not find a document explaining the policy for these choices. - Leon Bottou
multiloop.patch
(text/x-diff, 5.5 KB)
Index: include/GL/freeglut_ext.h
===================================================================
RCS file: /cvsroot/freeglut/freeglut/freeglut/include/GL/freeglut_ext.h,v
retrieving revision 1.14
diff -u -3 -p -r1.14 freeglut_ext.h
--- include/GL/freeglut_ext.h 15 Mar 2004 06:16:47 -0000 1.14
+++ include/GL/freeglut_ext.h 4 May 2004 15:18:55 -0000
@@ -57,6 +57,9 @@
#define GLUT_RENDERING_CONTEXT 0x01FD
+#define GLUT_CONNECTION 0x1001
+#define GLUT_IDLE_TIME 0x1002
+
/*
* Process loop function, see freeglut_main.c
*/
Index: src/freeglut_internal.h
===================================================================
RCS file: /cvsroot/freeglut/freeglut/freeglut/src/freeglut_internal.h,v
retrieving revision 1.44
diff -u -3 -p -r1.44 freeglut_internal.h
--- src/freeglut_internal.h 15 Mar 2004 13:42:20 -0000 1.44
+++ src/freeglut_internal.h 4 May 2004 15:18:55 -0000
@@ -845,6 +845,27 @@ void fgDisplayCursor( void );
long fgElapsedTime( void );
/*
+ * Expected idle time as per glutGet(GLUT_IDLE_TIME)
+ *
+ * This means that the main loop should not wait more
+ * than the expected idle time (in milliseconds)
+ * before calling glutMainLoopEvent() again.
+ *
+ * Remark1: The main loop must still call glutMainLoopEvent()
+ * as soon as there are pending window system events.
+ * But it should also call glutMainLoopEvent() within
+ * the specified idle time regardless of the presence
+ * of pending window system events. This is used for
+ * timers, joysticks, etc...
+ *
+ * Remark2: A return value of 0 indicates that
+ * glutMainLoopEvent() has something do
+ * to immediately.
+ */
+
+long fgIdleTime( void );
+
+/*
* List functions
*/
void fgListInit(SFG_List *list);
Index: src/freeglut_main.c
===================================================================
RCS file: /cvsroot/freeglut/freeglut/freeglut/src/freeglut_main.c,v
retrieving revision 1.100
diff -u -3 -p -r1.100 freeglut_main.c
--- src/freeglut_main.c 22 Mar 2004 10:19:25 -0000 1.100
+++ src/freeglut_main.c 4 May 2004 15:18:55 -0000
@@ -444,35 +444,69 @@ static int fgHavePendingRedisplays (void
fgEnumWindows( fgHavePendingRedisplaysCallback, &enumerator );
return !!enumerator.data;
}
+
/*
- * Returns the number of GLUT ticks (milliseconds) till the next timer event.
+ * Expected idle time as per glutGet(GLUT_IDLE_TIME)
+ *
+ * This means that the main loop should not wait more
+ * than the expected idle time before calling
+ * glutMainLoopEvent() again.
+ *
+ * Remark1: The main loop must still call glutMainLoopEvent()
+ * as soon as there are pending window system events.
+ * But it should also call glutMainLoopEvent() within
+ * the specified idle time regardless of the presence
+ * of pending window system events. This is used for
+ * timers, joysticks, etc...
+ *
+ * Remark2: A return value of 0 indicates that
+ * glutMainLoopEvent() has something do
+ * to immediately.
*/
-static long fgNextTimer( void )
+long fgIdleTime( void )
{
long ret = INT_MAX;
SFG_Timer *timer = fgState.Timers.First;
+
+ /* GUI events */
+#if TARGET_HOST_WIN32 || TARGET_HOST_WINCE
+ MSG stMsg;
+ if ( PeekMessage( &stMsg, NULL, 0, 0, PM_NOREMOVE ) )
+ return 0;
+#elif TARGET_HOST_UNIX_X11
+ if( XPending( fgDisplay.Display ) )
+ return 0;
+#endif
+
+ /* Internal events */
+ if( fgState.IdleCallback || fgHavePendingRedisplays( ) )
+ return 0;
+ /* Timers */
if( timer )
ret = timer->TriggerTime - fgElapsedTime();
if( ret < 0 )
ret = 0;
+ /* Joystick */
+ if( fgHaveJoystick( ) ) /* XXX Use GLUT timers for joysticks... */
+ ret = MIN( ret, 10 ); /* XXX Dumb; forces granularity to .01sec */
+
+ /* Return */
return ret;
}
+
+
/*
* Does the magic required to relinquish the CPU until something interesting
* happens.
*/
static void fgSleepForEvents( void )
{
- long msec;
+ long msec = fgIdleTime( );
- if( fgState.IdleCallback || fgHavePendingRedisplays( ) )
- return;
-
- msec = fgNextTimer( );
- if( fgHaveJoystick( ) ) /* XXX Use GLUT timers for joysticks... */
- msec = MIN( msec, 10 ); /* XXX Dumb; forces granularity to .01sec */
+ if ( msec <= 0 )
+ return;
#if TARGET_HOST_UNIX_X11
/*
@@ -573,8 +607,11 @@ void FGAPIENTRY glutMainLoopEvent( void
exit( 0 );
}
- fgState.ExecState = GLUT_EXEC_STATE_STOP;
- return;
+ if( fgState.ActionOnWindowClose == GLUT_ACTION_GLUTMAINLOOP_RETURNS )
+ {
+ fgState.ExecState = GLUT_EXEC_STATE_STOP;
+ return;
+ }
}
break;
Index: src/freeglut_state.c
===================================================================
RCS file: /cvsroot/freeglut/freeglut/freeglut/src/freeglut_state.c,v
retrieving revision 1.25
diff -u -3 -p -r1.25 freeglut_state.c
--- src/freeglut_state.c 16 Mar 2004 08:38:28 -0000 1.25
+++ src/freeglut_state.c 4 May 2004 15:18:56 -0000
@@ -463,6 +463,15 @@ int FGAPIENTRY glutGet( GLenum eWhat )
return fgState.UseCurrentContext ? GLUT_USE_CURRENT_CONTEXT
: GLUT_CREATE_NEW_CONTEXT;
+ case GLUT_IDLE_TIME:
+ return fgIdleTime( );
+
+ case GLUT_CONNECTION:
+#if TARGET_HOST_UNIX_X11
+ return ConnectionNumber( fgDisplay.Display );
+#endif
+ return -1;
+
default:
fgWarning( "glutGet(): missing enum handle %i\n", eWhat );
break;