The FOX Event Loop Daniel Gehriger The FOX event loop waits for, and dispatches: (1) GUI events, (2) timer events, (3) signaled file handles (descriptors), (4) signals. In addition, the event loop also handles (5) idle time updating, also known as "chores". To retrieve the next event, the event loop calls the FXApp member function bool getNextEvent(FXRawEvent& msg, FXbool blocking). If the second parameter, blocking, is TRUE, the function will block (not return) until: - either a GUI event (1) occurred, - a file handle (3) has been signaled, - or a timer (2) is due. The getNextEvent function returns true if a new GUI event (1) occurred. In this case, the first parameter, msg, contains a new event message. In any other case the function returns false. Note that if getNextEvent returns due to an expired timer event (2), this will only be dispateched the NEXT time you call getNextEvent. Here is how the most important part of the event loop works: bool FXApp::getNextEvent(FXRawEvent& msg, FXbool blocking) { 1. check list of timers(2) and handle ALL past due timers. 2. check list of signals(5) and handle them. 3. check if there are GUI events(1) in the message queue 3.1. -> if there are GUI events, return TRUE and pass the message in "msg" to the caller function. 3.2. -> if there are no GUI events, continue: 4. check list of chores(5) and handle (and remove) the next in the list. 5. check if FXApp::refresher points to a widget in the FOX widget tree, meaning that a GUI updated is needed for it. 5.1. -> if FXApp::refresher points at some widget, send a SEL_UPDATE event to it. Then repoint FXApp::refresher to the next widget, found by depth-first traversal. At this point, getNextEvent() returns with FALSE, indicating that no GUI event is in the message queue. The next time getNextEvent() is called, the next widget will be sent the SEL_UPDATE event. 5.2. -> if FXApp::refresher was NULL, this means that all widgets have been updated during past getNextEvent() calls. If the application requested another GUI refresh by calling FXApp::refresh(), we now start over by pointing FXApp::refresher to the application's root window, and exit with FALSE. 5.3. -> if no widget needs updating, and no new GUI update has been requested, continue: 6. check if new chores(5) have been added to its list of chores. If so, exit with FALSE. 7. check once again, just as in 3., for GUI events(1). They could have appeared during (4) to (6). 7.1 -> if there are GUI events, return TRUE and pass the message in "msg" to the caller function. 7.2 -> if there are no GUI events, continue: 8. if the caller requested getNextEvent() not to block ("blocking" = FALSE), return with FALSE. 9. check the list of timers(2). 9.1. -> if there are due timers, calculate the time until the next timer is due. Then block until the due time, waiting for new GUI events(1) or signaled file descriptors (3). 9.2. -> if there are no due timers, block indefinitely, waiting for new GUI events(1) or signaled file descriptors (3). 10. if 9.1. returned due to the timeout, return FALSE. The due timer will be handled in step 1. the next time getNextEvent() is called. 11. if 9.1/9.2 returned due to signaled file descriptors(3), handle these. 12. if 9.1/9.2 returned due to new GUI events(1), return TRUE and pass the message in "msg" to the caller function. 13. otherwise, return FALSE. }