static void fghSleepForEvents( void ) { fg_time_t msec; if( fghHavePendingWork( ) ) return; msec = fghNextTimer( ); /* XXX Should use GLUT timers for joysticks... */ /* XXX Dumb; forces granularity to .01sec */ if( fgState.NumActiveJoysticks>0 && ( msec > 10 ) ) msec = 10; fgPlatformSleepForEvents ( msec ); }
/* * Does the magic required to relinquish the CPU until something interesting * happens. */ static void fghSleepForEvents( void ) { long msec; if( fgState.IdleCallback || fghHavePendingRedisplays( ) ) return; msec = fghNextTimer( ); /* XXX Use GLUT timers for joysticks... */ /* XXX Dumb; forces granularity to .01sec */ if( fghHaveJoystick( ) && ( msec > 10 ) ) msec = 10; #if TARGET_HOST_UNIX_X11 /* * Possibly due to aggressive use of XFlush() and friends, * it is possible to have our socket drained but still have * unprocessed events. (Or, this may just be normal with * X, anyway?) We do non-trivial processing of X events * after the event-reading loop, in any case, so we * need to allow that we may have an empty socket but non- * empty event queue. */ if( ! XPending( fgDisplay.Display ) ) { fd_set fdset; int err; int socket; struct timeval wait; socket = ConnectionNumber( fgDisplay.Display ); FD_ZERO( &fdset ); FD_SET( socket, &fdset ); wait.tv_sec = msec / 1000; wait.tv_usec = (msec % 1000) * 1000; err = select( socket+1, &fdset, NULL, NULL, &wait ); //if( ( -1 == err ) && ( errno != EINTR ) ) // fgWarning ( "freeglut select() error: %d", errno ); } #elif TARGET_HOST_WIN32 || TARGET_HOST_WINCE MsgWaitForMultipleObjects( 0, NULL, FALSE, msec, QS_ALLEVENTS ); #endif }