Next: Other Canvas Routines, Previous: Canvas Types, Up: Canvas Object [Contents][Index]
The canvas class is designed to maximize the programmer’s ability to
deal with situations where standard form classes may not be flexible
enough. With canvases, the programmer has complete control over
everything that can happen to a window. It thus doesn’t work like
other objects that get returned by fl_do_forms()
etc.
or have their callbacks invoked.
Instead the user can request that for specific X
events (not
XForms object events like FL_PRESS
, FL_KEYPRESS
etc.!)
callbacks are invoked that receive all information about the
XEvent
that led to their invocation. This obviously requires
some understanding of how the X Window system works.
The interaction with a canvas is typically set up as follows. First,
you register the X
events you’re interested in and their
handlers using the following routine
typedef int (*FL_HANDLE_CANVAS)(FL_OBJECT *obj, Window win, int win_width, int win_height, XEvent *xev, void *user_data); void fl_add_canvas_handler(FL_OBJECT *obj, int event, FL_HANDLE_CANVAS handler, void *user_data);
where event
is the XEvent
type, e.g., Expose
etc.
The fl_add_canvas_handler()
function first registers a
procedure with the event dispatching system of the Forms Library, then
it figures out the event masks corresponding to the event event
and invokes fl_addto_selected_xevent()
to solicit the
event from the server. Other book keeping (e.g., drawing the box that
encloses the canvas, etc.) is done by the object handler.
When a canvas handler is installed the library tries to set the
correct mask for the the XEvent
(which then tells the X Window
system which events to pass on to the Forms Library). But since
translation from an XEvent
to an XEvent
mask is not
unique, the default translation of the XEvent
to a mask may or
may not match exactly the intention of the application. Two events,
namely MotionNotify
and ButtonPress
, are likely
candidates that need further clarification from the application. There
are two functions to add or delete from the mask,
fl_addto_selected_xevent()
and
fl_remove_selected_xevent()
.
By default, when a mouse motion handler (i.e., for the
MotionNotify
events) is registered, it is assumed that, while
the application wants to be informed about mouse movements, it’s not
interested in a continous motion monitoring (tracking), thus per
default MotionNotify
events are requested with
PointerMotionHintMask
being set in the mask to reduce the
number of events generated. If this is not the case and in fact the
application wants to use the mouse motion as some type of graphics
control, the default behavior would appear "jerky" as not every mouse
motion is reported. To change the default behavior so that every mouse
motion is reported, you need to call
fl_remove_selected_xevent()
with mask set to
PointerMotionHintMask
. Furthermore, the mouse motion is
reported regardless if a mouse button is pressed or not. If the
application is interested in mouse motion only when a mouse button is
pressed fl_remove_selected_xevent()
should be called with
a mask of PointerMotionMask|PointerMotionHintMask
.
With ButtonPress
events you need to call
fl_addto_selected_xevent()
with a mask of
OwnerGrabButtonMask
if you are to add or remove other canvas
handlers in the button press handler.
To remove a registered handler, use
void fl_remove_canvas_handler(FL_OBJECT *obj, int event, FL_CANVAS_HANDLER handler);
After this function call the canvas ceases to receive the events for
event
. The corresponding default bits in the XEvent
mask
as were set by fl_add_canvas_handler()
are cleared.
If you added extra ones with fl_addto_selected_xevent()
you should reset them using fl_remove_selected_xevent()
.
To obtain the window ID of a canvas, use
Window fl_get_canvas_id(FL_OBJECT *obj);
or use the generic function (macro) (recommended)
Window FL_ObjWin(FL_OBJECT *obj);
Of course, the window ID only has a meaning after the form/canvas is
shown. When the canvas or the form the canvas is on is hidden (via
fl_hide_object()
or fl_hide_form()
), the
canvas window may be destroyed. If the canvas is shown again, a new
window ID for the canvas may be created. Thus recording the canvas
window ID in a static variable is not the right thing to do. It is
much safer (and it doesn’t add any run-time overhead) to obtain the
canvas window ID via FL_ObjWin()
whenever it’s needed. If
your application must show and hide the canvas/form repeatedly, you
might consider to "unmap" the window, a way of removing the window
from the screen without actually destroying it and later re-mapping
the window to show it. The Xlib API functions for doing this are
XUnmapWindow()
and XMapWindow()
. Both require two
arguments. the display, which you can determine by calling
fl_get_display()
and the window ID, which can be obtained
by using form->window
if you want to (un)map a form or
FL_ObjWin(obj)
for a canvas.
Next: Other Canvas Routines, Previous: Canvas Types, Up: Canvas Object [Contents][Index]