[XForms] pathc to add client message callback
Jeff
wd4nmq at comcast.net
Thu May 27 18:32:05 EDT 2004
To all,
Ok, here is the patch for adding the an X client message handling callback.
Why did I do this?
I had an app that periodically went to a server to get a list to display
in a list box. However, when the server code was in the apps main
execution thread the user was "locked out" while all the network DNS
lookups, connection to, transfer from, and desconnection took place.
Your input was locked out because your main form was not getting events,
mouse, keyboard, etc, off of the X event queue.
Now, my first step was to thread the server access code. This way the
main form's event loop would still run while the data was being
retrieved from the server. But, since the Xforms code is not re-entrant,
the thread could not just update the xforms list box. You had to do
strange girations in the main loop code using mutexes. It's explained in
the Xforms manual.
This seemed like a lot of work and added even more complexity as more
"worker threads" were added. Plus, I had done a Windows C++ app, heh, it
pays the bills, that does kinda of the same thing. I had the main thread
that handled the gui, and several threads that monitored things and then
sent messages to the gui thread's message loop to display the data.
X also has a call to that, XSendEvent(). With this you can have
different threads, or apps, send messages to another threads or apps
windows. One of those messages is called a client message.
Now, using the new fl_register_client_message() and fl_get_winID()
calls, my server thread simply gets the data and uses XSendEvent()
passing the pointer to the data to notify the main form to display the
data. No mutexes waits or anthing else. We simply use the event queue
that is already in place.
As I stated, there are two new functions.
The first is
FL_EXPORT Window fl_get_winID(
FL_FORM *form
);
This returns the window id of the form. This is needed by XSendEvent()
to know where to send the client message.
FL_EXPORT FL_CLIENT_CALLBACK fl_register_client_callback(
FL_FORM *form,
FL_CLIENT_CALLBACK rcb
);
It is used just like any of the xforms calls to register a callback.
Here I use it to register clientCallback().
fl_register_client_callback(fd_testEvent->testEvent, (void *)
clientCallback);
int clientCallback(FL_FORM *form, XEvent *xev){
printf("We are in the client function, time = %d\n",
xev->xclient.data.l[0]);
return 1;
}
I then have a thread the periodically uses XSendEvent() to send the
current time. Simplistic, but demonstrates it's use.
Now you can have several worker threads and only one gui thread and no
mutexes or delaying. All the worker threads just send their data via
XSendEvent() to a client message event type.
Now, there are ways in X to register data types called atoms to
disquinish what the data format is. Just look on the web for Xlib Atoms.
Also rad up on XSendEvent() which is an Xlib call.
Angus and Jean-Marc, if you like I can write a manual section for this.
Jeff
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: xform.patch
Url: attachments/20040527/4e1f151c/attachment-0010.pl
More information about the Xforms
mailing list