Xv_Window window;
Canvas canvas;
CANVAS_EACH_PAINT_WINDOW(canvas, window)
draw_into_window(window);
CANVAS_END_EACH
Because the paint windows are different from the view windows, a slightly different method
is used for getting view windows:
Xv_Window view;
Canvas canvas;
int i = 0;
while (window = (Xv_Window)xv_get(canvas, OPENWIN_NTH_VIEW, i)) {
/* process
window
*/
i++;
}
There is also a macro that loops through all the views in the canvas:
Xv_Window view;
Canvas canvas;
OPENWIN_EACH_VIEW(canvas, view)
...
OPENWIN_END_EACH
You can get the paint window associated with a view by using the attribute CANVAS_
VIEW_PAINT_WINDOW
:
Xv_Window view;
Xv_Window paint_window;
paint_window = (Xv_Window)xv_get(view, CANVAS_VIEW_PAINT_WINDOW);
This is useful in situations where you are given the view window and need to get the paint
window associated with it. For example, the routines called when views are split or joined
are passed handles to view windows. When a view is split, you will need to get the paint
window associated with the new view to install event or repaint callbacks.
5.7 Handling Input in the Canvas Package
This section discusses, to a limited degree, the method for handling and specifying events in
a canvas. For a detailed discussion of the types of events used and the proper method for
handling them, see Chapter 6, Handling Input.
Canvases and
Openwin
Canvases and Openwin 105
5.7.1 Default Events
The default canvas_paint_window event mask is composed of: KBD_USE, KBD_DONE,
WIN_MOUSE_BUTTONS, ACTION_HELP, and WIN_ASCII_EVENTS. Other events may be added
to the window event mask by using xv_set() and passing the appropriate parameters. The
following shows how to enable notification once the Meta key has gone down by enabling
META events:
xv_set(canvas_paint_window(canvas),
WIN_CONSUME_EVENT, WIN_META_EVENTS,
NULL);
An application that does not need to know about release events can ignore all release events
from mouse buttons and keyboard keys, by enabling WIN_UP_EVENTS by calling:
xv_set(canvas_paint_window(canvas),
WIN_CONSUME_EVENT, WIN_UP_EVENTS,
NULL);
5.7.2 Notification of Events
In addition to specifying which events the application needs to know about, the program
should also install an event callback routine that is called when one of the specified events
takes place. The callback routine for event handling is installed using WIN_EVENT_PROC.
Included are samples that demonstrate how to handle events appropriately using a combina-
tion of repaint and event callback routines. However, for a complete discussion of events,
you should consult Chapter 6, Handling Input, and Chapter 20, The Notifier.
The sample program, canvas_event.c, in Example 5-3 first creates a base frame. Then it cre-
ates a canvas with the attribute CANVAS_X_PAINT_WINDOW set to TRUE because its repaint
procedure (repaint_proc) uses Xlib routines to clear the window and draw text strings in
the canvas.
Next we specify the events that the application should handle when they occur on the
paint_window. We are going to listen for keyboard events, pointer motion events and
pointer button events. We have not assigned any responses to these events yet; we have just
registered them for this window with XView so that the application will be called back if
they occur.
We then set the paint window’s event handling procedure to be event_proc. This is the
routine that will decide what to do when the events occur. XView is then started up by
calling xv_main_loop(), in which event processing starts.
The event_proc is called by the Notifier whenever a registered event takes place in any
view that has an event handling procedure set. The event_proc looks at the type of event
it has received and determines the appropriate message to display in the paint window. There
is a different message for each type of event that we have registered. There are three mes-
sage buffers, one each for keyboard events, pointer motion events and pointer button events.
After the message buffers are updated, the repaint procedure is called to display them. Note
106 XView Programming Manual
that we are reusing the repaint_proc, instead of writing more code just to display the
messages. See Section 5.2.1, “Drawing in a Canvas.”
If the event we have received is of no interest to us, then we return. It is important to do this
because the events WIN_REPAINT and WIN_RESIZE are delivered regardless of the events we
have registered with the Notifier. These two events will eventually result in the Notifier
calling the repaint procedure anyway, so it is not necessary to call it redundantly from here.
See Chapter 6, Handling Input, for details about this.
In canvas_event.c, the repaint_proc simply clears the paint window and then displays
the three messages in it, at a fixed position and using the default font. In the case of a pure
repaint callback (from the Notifier, not the event_proc), the messages will just repeat the
last event’s messages.
Example 5-3. The canvas_event.c program
/*
* canvas_event.c
* Demonstrates how to get keyboard and mouse events in an canvas
* window. Looks for keyboards, pointer movement and button
* events and displays the info in the canvas.
*/
#include <X11/Xlib.h>
#include <xview/xview.h>
#include <xview/canvas.h>
#include <xview/xv_xrect.h>
void event_proc(), repaint_proc();
char kbd_msg[128], ptr_msg[128], but_msg[128];
/*
* main()
* Create a canvas specifying a repaint procedure.
* Get the paint window for the canvas and set the input
* mask and the event procedure.
*/
main(argc, argv)
int argc;
char *argv[ ];
{
Frame frame;
Canvas canvas;
/* Initialize XView */
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
/* Create windows -- base frame and canvas. */
frame = (Frame)xv_create(NULL, FRAME, NULL);
canvas = (Canvas)xv_create(frame, CANVAS,
XV_WIDTH, 300,
XV_HEIGHT, 110,
CANVAS_X_PAINT_WINDOW, TRUE,
CANVAS_REPAINT_PROC, repaint_proc,
NULL);
window_fit(frame);
/* Set input mask */
xv_set(canvas_paint_window(canvas),
Canvases and
Openwin
Canvases and Openwin 107
Example 5-3. The canvas_event.c program (continued)
WIN_EVENT_PROC, event_proc,
WIN_CONSUME_EVENTS,
KBD_DONE, KBD_USE, LOC_DRAG, LOC_MOVE, LOC_WINENTER,
LOC_WINEXIT, WIN_ASCII_EVENTS, WIN_MOUSE_BUTTONS,
NULL,
NULL);
/* Initial messages */
strcpy(kbd_msg, "Keyboard: key press events");
strcpy(ptr_msg, "Pointer: pointer movement events");
strcpy(but_msg, "Button: button press events");
/* Start event loop */
xv_main_loop(frame);
}
/*
* event_proc()
* Called when an event is received in the canvas window.
* Updates the keyboard, pointer and button message strings
* and then calls repaint_proc() to paint them to the window.
*/
void
event_proc(window, event)
Xv_Window window;
Event *event;
{
if (event_is_ascii(event))
sprintf(kbd_msg, "Keyboard: key ’%c’ %d pressed at %d,%d",
event_action(event), event_action(event),
event_x(event), event_y(event));
else
switch (event_action(event)) {
case KBD_USE:
sprintf(kbd_msg, "Keyboard: got keyboard focus");
break;
case KBD_DONE:
sprintf(kbd_msg, "Keyboard: lost keyboard focus");
break;
case LOC_MOVE:
sprintf(ptr_msg, "Pointer: moved to %d,%d",
event_x(event), event_y(event));
break;
case LOC_DRAG:
sprintf(ptr_msg, "Pointer: dragged to %d,%d",
event_x(event), event_y(event));
break;
case LOC_WINENTER:
sprintf(ptr_msg, "Pointer: entered window at %d,%d",
event_x(event), event_y(event));
break;
case LOC_WINEXIT:
sprintf(ptr_msg, "Pointer: exited window at %d,%d",
event_x(event), event_y(event));
break;
case ACTION_SELECT:
case MS_LEFT:
108 XView Programming Manual
Example 5-3. The canvas_event.c program (continued)
sprintf(but_msg, "Button: Select (Left) at %d,%d",
event_x(event), event_y(event));
break;
case ACTION_ADJUST:
case MS_MIDDLE:
sprintf(but_msg, "Button: Adjust (Middle) at %d,%d",
event_x(event), event_y(event));
break;
case ACTION_MENU:
case MS_RIGHT:
sprintf(but_msg, "Button: Menu (Right) at %d,%d",
event_x(event), event_y(event));
break;
default:
return;
}
/* call repaint proc directly to update messages */
repaint_proc((Canvas)NULL, window,
(Display *)xv_get(window, XV_DISPLAY),
xv_get(window, XV_XID), (Xv_xrectlist *) NULL);
}
/*
* repaint_proc()
* Called to repaint the canvas in response to damage events
* and the initial painting of the canvas window.
* Displays the keyboard, pointer and button message strings
* after erasing the previous messages.
*/
void
repaint_proc(canvas, paint_window, dpy, xwin, xrects)
Canvas canvas; /* Ignored */
Xv_Window paint_window; /* Ignored */
Display *dpy;
Window xwin;
Xv_xrectlist *xrects; /* Ignored */
{
GC gc = DefaultGC(dpy, DefaultScreen(dpy));
XClearWindow(dpy, xwin);
XDrawString(dpy, xwin, gc, 25, 25, kbd_msg, strlen(kbd_msg));
XDrawString(dpy, xwin, gc, 25, 50, ptr_msg, strlen(ptr_msg));
XDrawString(dpy, xwin, gc, 25, 75, but_msg, strlen(but_msg));
}
The result produced by Example 5-3 is shown in Figure 5-6.
Canvases and
Openwin
Canvases and Openwin 109
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.