Events and event handling under the hood
I've just been working through some simple programs using SDL and it made me think back to some Java GUIs I've written.
In the simple SDL programs, I have a loop that checks for any events (keypresses, mouse clicks etc...) and reacts to them. Essentially it's polling for input.
In Java, you attach listeners to the GUI objects and the listeners get triggered when certain events occur.
My question is, does Java just handle this polling loop in the background for us and work out things like which GUI control was clicked so that it can trigger the correct listener, or is there something more complex going on?
I know Qt has a similar event system to Java where you use slots to connect a handler to a GUI control. Is this also just handling all the polling and working out which control was clicked for us? Or again, is there something more complex going on?
UPDATE
Maybe I wasn't clear enough with the question. I'm really looking to find out how an event bridges the OS Layer - A开发者_Go百科pplication layer boundary. Does the application poll the OS layer and pull event information into the application? Or does the OS have some way to interrupt/notify the application that an event has occurred and push the event info to the application.
A third solution has been suggested to me that the application calls a blocking native function like:
Event e = someNativeFunction(); // blocks until someNativeFunction() returns an event
"...does Java just handle this polling loop in the background for us...?"
Pretty much, yes. The UI system provides the program with access to a queue that contains events that have occurred and the target. The program runs through a loop requesting items from this queue and then does whatever. Libraries like Qt and Java call special functions within the widget classes that tell them an event has happened so that the system can function from there, however stipulated by the API. The library has to translate from the system specific window ID to the class governing that widget in order to do so.
Qt provides access to this function in the form of protected, virtual onXxxxEvent()
functions. The standard behavior of many widgets is to generate signals in response to events, but these are always some translated form of the event specific to the particular widget. Qt provides you access to this so that you can override the way a widget handles an event or to add additional behavior for events it never listened to before (through subclassing).
Each UI system is slightly different but they are all basically the same in this manner in my experience. We're talking raw win32 and Xlib here.
As said by answerers before, it is system specific, and could be implemented either way.
If I remember the Windows API right (long years ago), there was a "Window function" which got called for every event, and I made a big switch to choose the right action depending on event type.
I think most toolkits abstract this away, like the Java AWT with its event dispatch queue.
For the X protocol, the input events (as well as "your window needs to be painted") come as event messages over the wire, and it is up to the toolkit library to convert this either in a application function call or add them to a queue to be queried later.
The X protocol in fact works (basically) with two byte-streams: one from application ("client") to system ("server"), one in the other direction. The client sends request packages, the server sends back results (for some types of requests), errors (if some request could not be fulfilled for some reason), and events (when something happens on the display, like a mouse move, key press, window resize, ...).
For local displays on modern systems this is usually implemented by some shared memory mechanism, but in principle this can go over TCP (or today mostly over SSH) for remote connections (thus "over the wire").
I once started to create a pure Java X client implementation (didn't complete, as I found other more interesting things to do), and there I simply used a Socket with its InputStream and OutputStream to connect to the server. Thus, in principle I used the blocking native read()
function of the Socket-InputStream to wait for events (and results and errors). I could have used a java.nio.SocketChannel in nonblocking mode, too, and then basically I would had a polling loop (doing other things between, of course). (Or I could use a selector, waiting until new readable data is there - thus blocking, too.)
I have no idea what mechanism the AWT-for-X implementation used by the Linux and Solaris implementations of Java are using - I suppose they are based on some native toolkit, which in turn is based on the X client library (for C) "Xlib", but I don't know whether there is polling, blocking wait or being called by someone in the base.
I'm not familiar with Qt, but in Java basically, yes. In practice it gets more complicated, with modal dialogs and the like, but basically it is getting the events from the underlying OS (for keyboard and mouse) and posting them as events on the EventQueue, and the various components get those events and use and consume them or pass them along as they wish.
The listener framework allows the component to determine what the event was about and pass the appropriate information about it the appropriate listener.
It is oldest resource but, by the way Java AWT/Swing event queue
精彩评论