20.9.1 Uses of Interposition
Typically, it is application-level code that uses interposition. But, in general, any client’s
creator may want to use interposition. There are many reasons why an application might
want to interpose a function in the call path to a client’s event handler.
An application may want to use the fact that a client has received a particular event as a
trigger for some application-specific processing.
An application may want to filter the events to a client, thus modifying the client’s behav-
ior.
An application may want to extend the functionality of a client by handling events that
the client is not programmed to handle.
XView window objects utilize the Notifier for much of their communication and cooperation.
Thus, if an application wanted to monitor the user actions directed to a particular window, the
application would use interposition to get into the flow of control.
20.9.2 Interface to Interposition
The Notifier supports interposition by keeping track of how interposition functions are
ordered for each type of event for each client. Here is a typical example of interposition:
An application creates a client. The client has set up its own client event handler using
notify_set_event_func(). XView does this internally, using a default event han-
dler, when you create a window based object.
The application tells the Notifier that it wants to interpose a function in front of the
client’s event handler by calling notify_interpose_event_func(), which uses
the same calling sequence as notify_set_event_func().
When the application’s interposed function is called, it tells the Notifier to call the next
function, i.e., the client’s function, via a call to notify_next_event_func(),
which uses the same calling sequence as that passed to the interposer function.
Note that you can only interpose if a base event handler has been set with
notify_set_*_func (one of the notify_set functions). If no function is set,
notify_interpose_*_func() will return an error.
20.9.3 Registering an Interposer
This section lists the routines that allow you to interpose your own function in front of an
event handler. The arguments to each notify_interpose_*_func() function like the
associated notify_set_*_func() function described in the previous sections on the
Notifier. Refer to the associated notify_set_*_func() description, or to the XView
Reference Manual for details on the various arguments.
Notifier
The Notifier 489
notify_interpose_destroy_func()
notify_interpose_exception_func()
notify_interpose_event_func()
notify_interpose_input_func()
notify_interpose_itimer_func()
notify_interpose_output_func()
notify_interpose_signal_func()
notify_interpose_wait3_func()
The return values from these functions may be NOTIFY_OK, NOTIFY_UNKNOWN_CLIENT,
NOTIFY_NO_CONDITION, NOTIFY_UNEXPECTED, or NOTIFY_FUNC_LIMIT. For NOTIFY_OK
the interposition was successful. For NOTIFY_UNKNOWN_CLIENT the client is not known to
the notifier. For NOTIFY_NO_CONDITION there is no event handler of the type specified. For
NOTIFY_FUNC_LIMIT the level of interposition was exceeded. NOTIFY_FUNC_LIMIT means
you are trying to use more than the maximum allowed levels of interposition.
If the return value is something other than NOTIFY_OK, then notify_errno contains the
error code.
20.9.4 Invoking the Next Function
This section lists the routines that you call from your interposed function in order to invoke
the next function in the interposition sequence (if you want to override the normal sequence,
do not use these routines). The arguments to each notify_next_*_func() function are
the same as the arguments passed to the interposer function. Refer to the XView Reference
Manual, for details on the arguments.
notify_next_destroy_func()
notify_next_exception_func()
notify_next_event_func()
notify_next_input_func()
notify_next_itimer_func()
notify_next_output_func()
notify_next_signal_func()
notify_next_wait3_func()
The return value for these functions may be one of the following:
NOTIFY_DONE,
NOTIFY_IGNORED, or NOTIFY_UNEXPECTED. NOTIFY_DONE indicates that the event was
acted on in some way. This implies that no further action is required by the client. If the safe
event handler returns NOTIFY_IGNORED, this indicates that the event failed to provoke any
490 XView Programming Manual
action. If the immediate client event handler returns NOTIFY_IGNORED, then the same notifi-
cation will be delivered to the safe client event handler when it is safe. A value of
NOTIFY_UNEXPECTED indicates the event was not handled and not recognized. This return
value may indicate an error condition.
20.9.5 Removing an Interposed Function
This section presents a list of routines that allow you to remove the interposer function that
you installed using a notify_interpose_*_func() call. The arguments to each
notify_remove_*_func() function are the same as the arguments passed to the associ-
ated notify_set_*_func() function described in previous sections. Refer to the previ-
ous section, or to the XView Reference Manual, for details on these arguments. Note the one
exception to this rule is that the arguments to notify_remove_itimer_func() are a
subset of the arguments to notify_set_itimer_func().
notify_remove_destroy_func()
notify_remove_exception_func()
notify_remove_event_func()
notify_remove_input_func()
notify_remove_itimer_func()
notify_remove_output_func()
notify_remove_signal_func()
notify_remove_wait3_func()
If the function returns successfully, the return value will be
NOTIFY_OK. Otherwise, the error
codes are the same as those associated with the notify_interpose_*_func() calls.
20.9.6 An Interposition Example
You can notice when a frame opens or closes by interposing in front of the frame’s client
event handler. The client event handler that you want to interpose in front of is the default
client event handler supplied by XView. To register an interposer, the following routine is
used:
Notify_error
notify_interpose_event_func(client, event_func, type)
Notify_client client;
Notify_func event_func;
Notify_event_type type;
The client must be the handle of the Notifier client in front of which you are interposing.
In XView, this is the handle returned from xv_create(), for a Tty subwindow or a
Notifier
The Notifier 491
Textsw, the handle is the OPENWIN_NTH_VIEW of the window. For a Canvas, the handle
returned from is CANVAS_NTH_PAINT_WINDOW.
Let’s say that the application is displaying some animation and wants to do the necessary
computation only when the frame is open. It can use interposition to notice when the frame
opens or closes.
In Example 20-5, note the call to notify_next_event_func(). This function transfers
control to the frame’s client event handler through the Notifier. The routine
notify_next_event_func() takes the same arguments as the interposer.
Example 20-5. Transferring control through the Notifier
#include <xview/xview.h>
main()
{
Frame frame;
Notify_value my_frame_interposer();
/* Create the frame */
frame = xv_create(NULL, FRAME, NULL);
/* Interpose in front of the frames event handler */
(void) notify_interpose_event_func(frame,
my_frame_interposer, NOTIFY_SAFE);
...
/* Show frame and start dispatching events */
xv_main_loop(frame);
}
Notify_value
my_frame_interposer(frame, event, arg, type)
Frame frame;
Event *event;
Notify_arg arg;
Notify_event_type type;
{
int closed_initial, closed_current;
Notify_value value;
/* Determine initial state of frame */
closed_initial = (int) xv_get(frame, FRAME_CLOSED);
/* Let frame operate on the event */
value = notify_next_event_func(frame, (Notify_event)event, arg, type);
/* Determine current state of frame */
closed_current = (int) xv_get(frame, FRAME_CLOSED);
/* Change animation if states differ */
if (closed_initial != closed_current) {
if (closed_current) {
/* Turn off animation because closed */
(void) notify_set_itimer_func(me, my_animation,
ITIMER_REAL, ITIMER_NULL, ITIMER_NULL);
492 XView Programming Manual
Example 20-5. Transferring control through the Notifier (continued)
} else {
/* Turn on animation because opened */
(void) notify_set_itimer_func(me, my_animation,
ITIMER_REAL, &NOTIFY_POLLING_ITIMER, ITIMER_NULL);
}
}
return (value);
}
In Example 20-5, the base event handler is intended to handle the event (so that the frame
gets closed/opened). If the interposed function replaces the base event handler and you do
not want the base event handler to be called at all, your interposed procedure should not call
notify_next_event_func().
20.9.7 Interposing on Resize Events
Another use of interposition is to give your application more control over the layout of its
subwindows. To do this, you set up an interpose event handler which checks if the event type
is
WIN_RESIZE. If so, rather than calling notify_next_event_func() to dispatch the
event to the normal handler for resizing, you call your own resize routine:
Notify_value
my_frame_interposer(frame, event, arg, type)
Frame frame;
Event *event;
Notify_arg arg;
Notify_event_type type;
{
Notify_value value;
if (event_action(event) == WIN_RESIZE)
value = resize(frame);
else
value = notify_next_event_func(frame, (Notify_event)event, arg, type);
return(value);
}
20.9.8 Modifying an Object’s Destruction
Suppose an application must detect when the user selects the “Quit” menu item in order to
perform some application-specific confirmation. To accomplish this, the application should
Notifier
The Notifier 493

Get Volume 7A: XView Programming Manual now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.