4.5 Busy Frames
When running the Push Me application, you might notice a delay between the time that the
Hello button is pressed and the time that the subframe is displayed. If a delay might confuse
the user about what might be happening, you can provide visual feedback that the application
is at work. You can set the FRAME_BUSY attribute for the frame that issues the request that
might cause the delay. In Example 4-6 we set the XV_SHOW attribute in the base frame. Thus,
show_cmd_frame() might have looked like the following code fragment:
xv_set(baseframe, FRAME_BUSY, TRUE, NULL);
xv_set(subframe, XV_SHOW, TRUE, NULL);
xv_set(baseframe, FRAME_BUSY, FALSE, NULL);
The effect of this action is that the base frame’s header will be grayed out and the cursor will
change to a timeout cursor. When the subframe has been displayed, the base frame’s appear-
ance is resumed and the cursor restored. If excessively long delays are expected, then this
method might not be adequate—all other buttons and events are suspended until the callback
routine has returned control to the Notiﬁer.
Note that FRAME_BUSY only grays the title bar and sets the busy cursor for the frame passed
to xv_set(). If your application has many subframes and you wish each of them to
become busy, you need to set this attribute for each frame.
4.6 Frame Sizes
The size of any type of frame can be set or queried using either of two convenience functions
available from the FRAME package. They are frame_get_rect() and frame_set_
rect(). Both use a Rect data type. The origin of the frame as well as its width and height
can be set using frame_set_rect(). Of course, the frame must already be created in
order to use this function. In the following code, the frame is set at 10,10 on the screen and
the dimensions are set to 200 by 300:
rect.r_top = rect.r_left = 10;
rect.r_width = 200;
rect.r_height = 300;
frame = (Frame)xv_create(NULL, FRAME, NULL);
74 XView Programming Manual
Conversely, the dimensions as well as the position of the frame can be gotten:
extern Frame frame;
extern Rect rect;
printf("frame is at %d, %d and is %d by %d\n",
rect.r_left, rect.r_top, rect.r_width, rect.r_height);
If the position of a subframe is queried with:
the values returned will be relative to the parent frame. Note: a subframe here is any frame
that is created with another frame as its owner, for example:
subframe = xv_create(frame, FRAME, ..., NULL);
4.7 Frame Colors
In general the frame’s color is determined from the value associated with the OpenWin-
dows.WindowColor resource. This color will be inherited by the frame and its subwin-
dows. In order to maintain a consistent look across tools, applications should not override
the colors chosen by the frame.
However, some applications may need to override the default color for the frame. This can
be done by creating a CMS and setting it on the frame (see Chapter 21, Color, for informa-
tion on CMS). Doing so will cause the frame to inherit the color at index 0 as the back-
ground color and the color at index n-1 as the foreground color. If the application wants the
frame to inherit colors different than those at indices 0 and n-1, it must explicitly set those
WIN_FOREGROUND_COLOR and WIN_BACKGROUND_COLOR. Note that this must
happen in an xv_set() after the frame is created as the frame will override these values
during create and use the X resource values.
This is shown in Example 4-8.
Example 4-8. Changing a frame’s color
* This program demonstrates how to set the frame’s foreground and
* background color and make it propagate to the children of the frame.
#define RED 0
#define BLUE 1
Example 4-8. Changing a frame’s color (continued)
(void)xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, 0);
cms = xv_create(NULL, CMS,
CMS_SIZE, CMS_CONTROL_COLORS + 2,
CMS_NAMED_COLORS, "red", "blue" , NULL,
frame = (Frame)xv_create(NULL, FRAME, NULL);
WIN_FOREGROUND_COLOR, CMS_CONTROL_COLORS + RED,
WIN_BACKGROUND_COLOR, CMS_CONTROL_COLORS + BLUE,
panel = (Panel)xv_create(frame, PANEL, NULL);
(void) xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Push Me",
4.8 Child Windows
The very purpose of frames is to manage subwindows such as panels and canvases. Basi-
cally, parenting responsibilities are handled transparently by XView and do not require inter-
vention by the programmer. When creating a new object (such as a panel), you simply spec-
ify the frame as the panel’s parent or owner.
There are several attributes that can obtain subwindows and subframes from the frame.
FRAME_NTH_SUBWINDOW and FRAME_NTH_SUBFRAME are attributes that can be used with
xv_get(). Assuming the application has created a subframe, the following code fragment
will return the ﬁrst subframe created:
subframe = (Frame)xv_get(frame, FRAME_NTH_SUBFRAME, 1);
76 XView Programming Manual
Similarly, if a frame creates a panel and then a canvas, you can get the canvas (because it was
the second one created) by using the call:
canvas = (Canvas)xv_get(frame, FRAME_NTH_SUBWINDOW, 2);
If you attempt to get a subwindow or subframe index but it does not exist, xv_get() will
Laying out subwindows in frames is somewhat automatic, but more explicit layouts can be
accomplished by using the macro deﬁned in <xview/frame.h> called frame_fit_all().
This macro loops on xv_get() to get each FRAME_NTH_SUBWINDOW and call win-
dow_fit() to make sure that all the subwindows ﬁt in the frame (if possible). win-
dow_fit() also serves as a hint for the frame to give it permission to resize any of its
subwindows whenever a resize event occurs. For example, say a frame contains a canvas
subwindow, but that subwindow’s dimensions are set via XV_WIDTH and XV_HEIGHT. If the
user uses the window manager to resize the frame, the frame may or may not resize the can-
vas depending on whether or not it was given permission to do so via either of the calls to
window_fit(), window_fit_height(), or window_fit_width(). See Chapter
5, Canvases and Openwin, for more information on window_fit().
4.9 Window Loop
The procedure xv_window_loop() maps the frame passed and makes all of the applica-
tion’s other frames and windows “busy” in a way similar to using the attribute FRAME_BUSY.
However, this procedure does not cause the cursor to change to a stopwatch and the frame
header does not show the gray pattern. xv_window_loop() does not lock the screen.
The form of this procedure is:
xv_window_loop() does not return until a call to xv_window_return() is made.
The form for xv_window_return() is:
The frame passed in to xv_window_loop() can have more than one subwindow of any
Making a frame busy in this way should normally be done in a callback associated with the
frame. For example, a callback originating from a button on the frame. The return value pas-
sed in to xv_window_return() is the value returned by xv_window_loop(). Since
the screen is not locked using xv_window_loop() the user might be able to dismiss the
frame using the window manager. Doing this will cause the application to hang since
xv_window_return() was not called. You can avoid this by attaching a destroy proce-
dure to the frame; in the destroy procedure, issue a call to xv_window_return().
4.10 Removing Decorations
If a frame does not wish to be controlled by the window manager, and thus have no window
manager decorations such as resize corners or pins, the frame should set
WIN_TOP_LEVEL_NO_DECOR to TRUE. This attribute is only valid when the frame is created.
For more information, see the discussion of override_redirect in Volume One, Xlib
4.11 Setting Properties and Saving Command-line Options
Several frame attributes support setting window properties according to the speciﬁcations of
the ICCCM (see Volume Zero, X Protocol Reference Manual, for more information on
ICCCM). These attributes support the WM_SAVE_YOURSELF and WM_COMMAND protocols that
set an application’s startup options. Also refer to Section 20.9.5, “Modifying A Frame’s
Destruction,” for more information on saving command-line options.
FRAME_WM_COMMAND_ARGC_ARGV lets an application set the command-line options that can
be used to (re)start it. The options passed, in addition to XView options, are stored on a
WM_COMMAND on the frame window. The options passed are stored by XView
and will be added to the XView options on the WM_COMMAND property on the frame window,
upon receiving a WM_SAVE_YOURSELF request from the session/window manager. The pro-
gram xprop can be used to display a window’s properties. Only one base frame window of
the application needs to have this property set. This property is read possibly by a session
manager to restart clients. The ﬁrst argument is the number of strings passed in the second
argument. The second argument is a pointer to an array containing the command-line option
strings. The strings passed are copied and cached on the frame. The following code shows
an example using FRAME_WM_COMMAND_ARGC_ARGV.
int argc = 0;
argv[argc++] = "-I"
argv[argc++] = "ls"
argv[argc++] = "-bold_font"
argv[argc++] = "courier-bold-14"
* This ensures that the above options are stored
* on the base frame
argc, argv, NULL);
Setting this attribute’s arguments to NULL and -1 prevents any command-line option informa-
tion from being saved on the frame. If there are two or more base frames in the application,
the second and subsequent base frames should set their FRAME_WM_COMMAND_ARGC_ARGV
attributes’ arguments to NULL and -1 if they want to avoid multiple invocations of the same
application by the session manager.
78 XView Programming Manual