Part IV Using a Pre-emptive Handler (XForms (Forms Library) - Version 1.2 (Rev. 4) A Graphical User Interface Toolkit for X)

Next: Part V, Previous: Part IV New Buttons, Up: Top [Contents][Index]

## 31 Using a Pre-emptive Handler

Pre-emptive handlers came into being due to reasons not related to developing new classes. They are provided for the application programs to have access to the current state or event of a particular object. However, with some care, this preemptive handler can be used to override parts of the original built-in handler thus yielding a new class of objects.

As mentioned earlier, an object module communicates with the main module via events. Central part of the module is the event handler, which determines how an object responds to various events such as mouse clicks or a key presses. Now a pre-emptive handler is a function which, if installed, gets called first by the main module when an event for the object occurs. The pre-emptive handler has the option to override the built-in handler by informing the main module not to call the built-in handler (and a possibly also installed post handler), thus altering the behavior of the object. A post handler, on the other hand, is called when the object handler has finished its tasks and thus does not offer the capability of overriding the built-in handler. It is much safer, however.

The API to install a pre- or post-handler for an object is as follows

    typedef int (*FL_HANDLEPTR)(FL_OBJECT *obj, int event,
                                FL_Coord mx, FL_Coord my,
                                int key, void *raw_event);

    void fl_set_object_prehandler(FL_OBJECT *obj,
                                  FL_HANDLEPTR pre_handler);
    void fl_set_object_posthandler(FL_OBJECT *obj,
                                   FL_HANDLEPTR post_handler);

`event` is a generic event of the Forms Library, that is, `FL_DRAW`, `FL_ENTER` etc. Parameters `mx` and `my` are the mouse position and `key` is the key pressed. The last parameter `raw_event` is a pointer to the XEvent (cast to a void pointer due to the different types of Xevents) that caused the invocation of the pre- or post-handler. But note: not all events of the Form Library have a corresponding Xevent and thus dereferencing of `xev` should only be done after making sure it is not `NULL`.

The pre- and post-handler have the same function prototype as the built-in handler. Actually they are called with exactly the same parameters by the event dispatcher. The pre-handler should return `FL_PREEMPT` to prevent the dispatcher from calling the normal object handler for events and `!FL_PREEMPT` if the objects handler for is to be invoked next. The post-handler may return whatever it wants since the return value is not used. Note that a post-handler will receive all events even if the object the post-handler is registered for does not. For example, a post-handler for a box (a static object that only receives `FL_DRAW`) receives all events.

Note that when an object has been de-activated using `fl_deactivate_object()` (or the whole form the object belongs to is de-activated via calls of `fl_deactivate_form()` or `fl_deactivate_all_forms()`) also pre-emptive and post-handlers won’t get invoked for the object.

See the demo programs `preemptive.c` and `xyplotall.c` for examples. Bear in mind that modifying the built-in behavior is in general not a good idea. Using a pre-emptive handler for the purpose of "peeking", however, is quite legitimate and can be useful in some situations.

Next: Part V, Previous: Part IV New Buttons, Up: Top [Contents][Index]