Re: XForms: idle callback question

Steve Lamont (spl@szechuan.ucsd.edu)
Mon, 3 Nov 97 21:23:41 PST

To subscribers of the xforms list from spl@szechuan.ucsd.edu (Steve Lamont) :

> To register an idle callback, use the following routine
>
> FL_APPEVENT_CB
> fl_set_idle_callback(FL_APPEVENT_CB callback, void *user_data)
>
> Then during idle periods it is called as such:
>
> int callback(xev, user_data);
>
> I can get the callback to compile in without errors but I'm confused on how I
> go about registering it. What does that first FL_APPEVENT_CB mean and where
> does it go? I tried using the fl_set_idle_callback() line and it tells me
> theres an error before FL_APPEVENT_CB. Any hints on what it is I'm doing
> wrong? Thanks in advance.

FL_APPEVENT_CB is the type of value which fl_set_idle_callback()
returns. If you look at the definition in forms.h, you'll see

typedef int (*FL_APPEVENT_CB) (XEvent *, void *);

So, what fl_set_idle_callback() returns to you is the address of the
entry point (or, in C parlance, pointer to function) of the *previous*
idle callback. If there is no existing idle callback then it returns
NULL. In practice, you can generally ignore the return value.

For instance, if you have an idle callback called, for want of any
other name, `my_idle_callback', defined as

int my_idle_callback( XEvent *xev, void *user_data )

{

do_something_useful_here();

return 0;

}

you'd register it with the statement

[...]

( void ) fl_set_idle_callback( my_idle_callback,
( void *) whatever );

[...]

If you have no data to pass to the callback, you may code

( void ) fl_set_idle_callback( my_idle_callback, NULL );

Note a problem here, by the way of a digression from the answer to the
poster's question, which exposes something of a design misfeature:
while you can get the pointer to the previous idle callback function
when you set a new idle callback, you can't get the pointer to its
data, so unless the original callback was registered with NULL for
`user_data', it is impossible properly to re-register the old
callback.

My own solution to this problem is to register my own callback manager
and then register my callbacks with that manager. The manager then
keeps track of the current callback and its argument. If a new
callback is registered, the old callback and its data pointer are
pushed onto a stack and the new callback is called until it returns
a completion status, at which point the old callback is popped off the
stack and executed as if it had not been preempted.

Another method I've used is similar, except that instead of a stack, I
arrange the callback pointers into a ring and execute each callback
in round robin fashion.

In either cas, if I run out of callback work, I just unregister my
handler and resume normal operations.

This is probably more elaborate than most applications need but it
allows me to manage several background tasks such as reading or
writing data, managing graphics, and doing long running calculations,
while maintaining a high degree of interactivity.

spl
_________________________________________________
To unsubscribe, send the message "unsubscribe" to
xforms-request@bob.usuf2.usuhs.mil or see
http://bob.usuf2.usuhs.mil/mailserv/xforms.html
Xforms Home Page: http://bragg.phys.uwm.edu/xforms
List Archive: http://bob.usuf2.usuhs.mil/mailserv/list-archives/