5
Canvases and Openwin
Perhaps the most important object in the XView Toolkit is a canvas—the area in which an
application displays graphics and handles input. The canvas object is similar to that of a
painter’s canvas. The artist’s painting is drawn onto the canvas and the canvas is mounted in
a frame. The canvas may be larger than the frame, but the person looking at the canvas only
sees what is within the boundaries of the frame. If the canvas is larger than what is viewable,
the painting can be moved around making different portions of the canvas visible.
An XView canvas object allows the user to view a graphic image that is too large for the
window or even the display screen. The viewable portion of the graphic image is part of the
viewport or view window of the image. Many different views of the image can use the same
canvas object. While each view maintains its own idea of what it is displaying, the canvas
object manages all the view windows as well as the graphic image that all views share. The
ability for the canvas to maintain different views of the graphic image is a property that is
inherited from the canvas’s superclass, the OPENWIN package. These properties provide for
splitting and scrolling views. You cannot create a canvas object with multiple views; views
are split and joined generally by the user via the attached scrollbars. It is possible to pro-
grammatically split and scroll views, but OPEN LOOK’s interface specification indicates that
scrollbars provide the ability to split views. When a view is split, each new view may be fur-
ther split into two more views, and so on. All the views are still a part of the same canvas
object.
The OPENWIN package is an example of a hidden class. You cannot instantiate an openwin
object independently from canvas or text subwindows. Figure 5-1 shows the openwin and
canvas object hierarchy.
Generic
Object
(Drawable) Window Canvas(Openwin)
Figure 5-1. Canvas class hierarchy
Canvases and
Openwin
Canvases and Openwin 85
Chapter 8, Text Subwindows, contains information about text subwindows. The canvas
object is different from the text object in that it maintains an image that can be manipulated
by the user. The openwin object, and thus the canvas object, are broken down into three
parts: the main subwindow, the view window, and the paint window.
Each view displays a portion of a corresponding paint window. The paint window need not
be the size of the corresponding view or the canvas subwindow. Figure 5-2 shows an
example of one canvas object providing separate views into one graphic image. What each
view displays is independent of what the other views display. A view may even display a
portion of an image that is currently displayed in another view.
Figure 5-2. A canvas subwindow with multiple views
5.1 Canvas Model
The components of a canvas subwindow and their relationships can be seen in Figure 5-3. To
summarize, three types of windows are involved with the canvas object:
Canvas Subwindow Owned by a frame and manages one or more views. The canvas is
subclassed from the
OPENWIN package so all Openwin attributes must
be set to the instance of the canvas object.
View Window Represents the visible portion of the paint window—whenever the
paint window associated with a view window changes, it is reflected
in the view window. If there is more than one view window, the
views are tiled. Vertical and/or horizontal scrollbars can be attached
to the view subwindow to allow the user to modify which portion of
86 XView Programming Manual
paint window
(contains graphic)
view window
(contains no
graphic, has
scrollbars)
canvas subwindow
(displays union of view
window and paint window)
frame
(contains canvas)
Figure 5-3. Canvases, views, and paint windows
the paint window is displayed for that particular view. The size of the view window can vary
among all the views. Only views can be split. No graphics or user events take place in this
window.
Canvases and
Openwin
Canvases and Openwin 87
Paint Window Graphics and events (mouse/keyboard) take place in the paint win-
dow. There is one paint window per view window. All paint win-
dows in the canvas are the same size regardless of the size of the can-
vas or of the corresponding view windows. When a view is split, the
old view reduces in size and a new view is created. With the new
view, a new paint window is created that is identical to the paint win-
dow from the old view. This includes the same visual, width, height,
depth, and graphic image. However, callback functions and event
masks are not inherited and must be manually installed in all new
paint windows.
5.2 Creating a Canvas
The CANVAS package is defined in the header file <xview/canvas.h> so programs that use can-
vases must include this file. This header file includes the OPENWIN package automatically.
Like all objects in XView, a canvas is created with xv_create():
Canvas canvas;
canvas = (Canvas)xv_create(owner, CANVAS,
attrs
);
Here, xv_create() returns a handle to a new canvas subwindow. The owner of a canvas
must be a FRAME object. All three subwindows of the canvas are created at this point: the
canvas subwindow, the view window and the paint window. By using this syntax, the attri-
butes of the canvas default to those set for the CANVAS package plus any attributes that may
be inherited from the owner of the canvas.
The windows in the canvas object inherit many of their attributes from the canvas’s parent,
screen, or display (depending on the window property). However, some attributes are set or
reset explicitly. For example, the attribute CANVAS_RETAINED, which controls whether the
server should retain windows, is turned on.* Toggling this attribute causes the canvas to
cycle through all of the paint windows and change their WIN_RETAINED attribute. Also, the
window has its BitGravity set to NorthWestGravity by default. This value is set by
the attribute CANVAS_FIXED_IMAGE. If TRUE, then the BitGravity property on the paint
window is set to NorthWestGravity. If FALSE, BitGravity is set to ForgetGrav-
ity. This is discussed in more detail in Section 5.3, “The Repaint Procedure.”
The width and height of the paint window and the view window default to the size of the can-
vas when it is realized. Unless otherwise specified, those sizes are governed by the object
that is the owner of the canvas.
*CANVAS_RETAINED does not affect the view windows, which are not retained.
88 XView Programming Manual
5.2.1 Drawing in a Canvas
The use of canvases implies that your application wants to display a graphic image that the
user can either manipulate or generate. In conventional (not server-client based) windowing
systems, when you request to create a window, you usually get a window back that you can
draw into. This is not exactly true for X. Although you get a window back from the request,
you are not guaranteed to be able to draw into it until it has been successfully mapped
(displayed) on the screen. In the general case for XView, this does not happen until
xv_main_loop() is called. Therefore, you should not do the following:
canvas = (Canvas)xv_create(frame, CANVAS, NULL);
win = (Window)xv_get(canvas_paint_window(canvas), XV_XID);
XDrawString(dpy, win, gc, x, y, "Hello World.", 11);
Instead, you should design your program such that your repaint routine knows exactly what
the contents of the canvas should be so that it can reproduce the image. Here are two helpful
hints for typical applications:
Use your repaint proc. Never call any graphics routines before xv_main_loop() is
called. Routines that draw anything into windows should be called directly or indirectly
from your canvas repaint procedure or event handler.
Use internal data. The repaint routine should be able to repaint a canvas window based
on some sort of internal data. To maintain system performance, the data should be in
core; it should not be on disk (in a file), from a network connection or from interaction
with the user. If the data is received from those media, the data should already have been
updated by the time the repaint routine is called.
To give you an idea of the issues involved here, we’ll look at several common applications
that typically use canvases.
5.2.1.1 Draw programs
Draw programs are usually applications that maintain a display list of geometric shapes such
as lines, circles, rectangles and so on. The user generates these shapes using the mouse or
keyboard. The canvas’s
WIN_EVENT_PROC procedure handles mouse and keyboard input
from the user, and the user interface generally describes the shape that is currently being
drawn.
When the user initiates mouse clicks, drags or keyboard actions, the event handler picks up
these events and is fully expected to modify the canvas window accordingly (e.g., by “rubber
banding” the object). Upon receipt of the appropriate event (button release, perhaps), the
event handler adds the new geometric item to the display list.
In order to reconstruct what the canvas should be displaying, the repaint routine references
the updated display list. Obviously, the display list should contain enough information in it
to be able to tell the repaint routine what colors to use, line thickness, and so on.
Canvases and
Openwin
Canvases and Openwin 89

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.