/* CENTRY */ void APIENTRY glutMainLoop(void) { #if !defined(_WIN32) if (!__glutDisplay) __glutFatalUsage("main loop entered with out proper initialization."); #endif if (!__glutWindowListSize) __glutFatalUsage( "main loop entered with no windows created."); for (;;) { if (__glutWindowWorkList) { GLUTwindow *remainder, *work; work = __glutWindowWorkList; __glutWindowWorkList = NULL; if (work) { remainder = processWindowWorkList(work); if (remainder) { *beforeEnd = __glutWindowWorkList; __glutWindowWorkList = remainder; } } } if (__glutIdleFunc || __glutWindowWorkList) { idleWait(); } else { if (__glutTimerList) { waitForSomething(); } else { processEventsAndTimeouts(); } } } }
static void idleWait(void) { if (XPending(__glutDisplay)) { processEventsAndTimeouts(); } else { if (__glutTimerList) { handleTimeouts(); } } /* Make sure idle func still exists! */ if (__glutIdleFunc) { __glutIdleFunc(); } }
/*********************************************************** * FUNCTION: idleWait * * DESCRIPTION: check for events, then call idle function ***********************************************************/ static void idleWait(void) { if (gBlock.PendingEvent()) { processEventsAndTimeouts(); } else { if (__glutTimerList) handleTimeouts(); } /* Make sure idle func still exists! */ if(gState.currentWindow) gState.currentWindow->LockGL(); if (gState.idle) { gState.idle(); } if(gState.currentWindow) gState.currentWindow->UnlockGL(); }
/*********************************************************** * FUNCTION: waitForSomething * * DESCRIPTION: use gBlock to wait for a new event or timeout ***********************************************************/ static void waitForSomething(void) { bigtime_t timeout = __glutTimerList->timeout; bigtime_t now = system_time(); if (gBlock.PendingEvent()) goto immediatelyHandleEvent; if(timeout>now) gBlock.WaitEvent(timeout-now); if (gBlock.PendingEvent()) { immediatelyHandleEvent: processEventsAndTimeouts(); } else { if (__glutTimerList) handleTimeouts(); } }
/*********************************************************** * FUNCTION: glutMainLoop (3.1) * * DESCRIPTION: enter the event processing loop ***********************************************************/ void glutMainLoop() { if (!gState.windowListSize) __glutFatalUsage("main loop entered with no windows created."); if(gState.currentWindow) gState.currentWindow->UnlockGL(); for (;;) { if (gState.idle) { idleWait(); } else { if (__glutTimerList) { waitForSomething(); } else { processEventsAndTimeouts(); } } } }
/* CENTRY */ void APIENTRY glutMainLoop(void) { #if !defined(_WIN32) if (!__glutDisplay) __glutFatalUsage("main loop entered with out proper initialization."); #endif if (!__glutWindowListSize) __glutFatalUsage( "main loop entered with no windows created."); for (;;) { if (__glutWindowWorkList) { GLUTwindow *remainder, *work; work = __glutWindowWorkList; __glutWindowWorkList = NULL; if (work) { remainder = processWindowWorkList(work); if (remainder) { *beforeEnd = __glutWindowWorkList; __glutWindowWorkList = remainder; } } } if (__glutIdleFunc || __glutWindowWorkList) { idleWait(); } else { if (__glutTimerList) { waitForSomething(); } else { processEventsAndTimeouts(); } #if defined(_WIN32) // If there is no idle function, go to sleep for a millisecond (we // still need to possibly service timers) or until there is some // event in our queue. MsgWaitForMultipleObjects(0, NULL, FALSE, 1, QS_ALLEVENTS); #endif } } }
/* CENTRY */ void GLUTAPIENTRY glutMainLoop(void) { #if !defined(_WIN32) if (!__glutDisplay) __glutFatalUsage("main loop entered with out proper initialization."); #endif if (!__glutWindowListSize) __glutFatalUsage( "main loop entered with no windows created."); for (;;) { __glutProcessWindowWorkLists(); if (__glutIdleFunc || __glutWindowWorkList) { idleWait(); } else { if (__glutTimerList) { waitForSomething(); } else { processEventsAndTimeouts(); } } } }
static void waitForSomething(void) { #if defined(__vms) && ( __VMS_VER < 70000000 ) static struct timeval6 zerotime = {0}; unsigned int timer_efn; #define timer_id 'glut' /* random :-) number */ unsigned int wait_mask; #else static struct timeval zerotime = {0, 0}; #if !defined(_WIN32) fd_set fds; #endif #endif #ifdef OLD_VMS struct timeval6 now, timeout, waittime; #else struct timeval now, timeout, waittime; #endif #if !defined(_WIN32) int rc; #endif /* Flush X protocol since XPending does not do this implicitly. */ XFlush(__glutDisplay); if (XPending(__glutDisplay)) { /* It is possible (but quite rare) that XFlush may have needed to wait for a writable X connection file descriptor, and in the process, may have had to read off X protocol from the file descriptor. If XPending is true, this case occured and we should avoid waiting in select since X protocol buffered within Xlib is due to be processed and potentially no more X protocol is on the file descriptor, so we would risk waiting improperly in select. */ goto immediatelyHandleXinput; } #if defined(__vms) && ( __VMS_VER < 70000000 ) timeout = __glutTimerList->timeout; GETTIMEOFDAY(&now); wait_mask = 1 << (__glutConnectionFD & 31); if (IS_AFTER(now, timeout)) { /* We need an event flag for the timer. */ /* XXX The `right' way to do this is to use LIB$GET_EF, but since it needs to be in the same cluster as the EFN for the display, we will have hack it. */ timer_efn = __glutConnectionFD - 1; if ((timer_efn / 32) != (__glutConnectionFD / 32)) { timer_efn = __glutConnectionFD + 1; } rc = SYS$CLREF(timer_efn); rc = SYS$SETIMR(timer_efn, &timeout, NULL, timer_id, 0); wait_mask |= 1 << (timer_efn & 31); } else { timer_efn = 0; } rc = SYS$WFLOR(__glutConnectionFD, wait_mask); if (timer_efn != 0 && SYS$CLREF(timer_efn) == SS$_WASCLR) { rc = SYS$CANTIM(timer_id, PSL$C_USER); } /* XXX There does not seem to be checking of "rc" in the code above. Can any of the SYS$ routines above fail? */ #else /* not vms6.2 or lower */ #if !defined(_WIN32) FD_ZERO(&fds); FD_SET(__glutConnectionFD, &fds); #endif timeout = __glutTimerList->timeout; GETTIMEOFDAY(&now); if (IS_AFTER(now, timeout)) { TIMEDELTA(waittime, timeout, now); } else { waittime = zerotime; } #if !defined(_WIN32) rc = select(__glutConnectionFD + 1, &fds, NULL, NULL, &waittime); if (rc < 0 && errno != EINTR) __glutFatalError("select error."); #else MsgWaitForMultipleObjects(0, NULL, FALSE, waittime.tv_sec*1000 + waittime.tv_usec/1000, QS_ALLINPUT); #endif #endif /* not vms6.2 or lower */ /* Without considering the cause of select unblocking, check for pending X events and handle any timeouts (by calling processEventsAndTimeouts). We always look for X events even if select returned with 0 (indicating a timeout); otherwise we risk starving X event processing by continous timeouts. */ if (XPending(__glutDisplay)) { immediatelyHandleXinput: processEventsAndTimeouts(); } else { if (__glutTimerList) handleTimeouts(); } }