}; // enum AppEvent // Handle the next event and return what kind of event it was. private AppEvent HandleNextEvent(bool wait) { try { IntPtr dpy = Lock(); XEvent xevent; int timeout; // Processing any pending invalidates that we have. ProcessPendingInvalidates(); // Flush any requests that are in the outgoing queue. Xlib.XFlush(dpy); // Process "Quit". if (quit) { return(AppEvent.Quit); } // Process events that are already in the queue. // It is important that this be done before processing // short period timeouts or the events may never get // processed at all. if (Xlib.XEventsQueued (dpy, 2 /* QueuedAfterFlush */) != 0) { // Read the next event and dispatch it. Xlib.XNextEvent(dpy, out xevent); Unlock(); try { DispatchEvent(ref xevent); return(AppEvent.Regular); } finally { dpy = Lock(); } } // Do we have pending expose events to process? if (pendingExposes) { // Process the pending expose events. InputOutputWidget widget; while (exposeList != null) { widget = exposeList; exposeList = exposeList.nextExpose; Unlock(); try { widget.Expose(); } finally { dpy = Lock(); } } pendingExposes = false; return(AppEvent.Regular); } else { // Wait for the next event. if (wait) { timeout = Timer.GetNextTimeout(this); } else { timeout = 0; } if (timeout < 0) { // Make sure that we release the display lock // before calling "XNextEvent", so that other // threads can issue X requests while we are // waiting for the next event to occur. Unlock(); try { timeout = 100; if (Xlib.XNextEventWithTimeout (dpy, out xevent, timeout) > 0) { DispatchEvent(ref xevent); } } finally { dpy = Lock(); } return(AppEvent.Regular); } else { Unlock(); try { if (Xlib.XNextEventWithTimeout (dpy, out xevent, timeout) > 0) { DispatchEvent(ref xevent); return(AppEvent.Regular); } } finally { dpy = Lock(); } } } // Process timers that need to be activated. if (Timer.ActivateTimers(this)) { return(AppEvent.Timer); } } finally { Unlock(); } // If we get here, then there were no events processed. return(AppEvent.NoEvent); }