Example 7-7. The panel_repaint.c program (continued)
#define PANEL_GC_KEY 101 /* any arbitrary number */
main(argc, argv)
int argc;
char *argv[ ];
{
Display *display;
Frame frame;
Panel panel;
int quit();
void panel_repaint();
XGCValues gcvalues;
Server_image grey;
Mask gcmask = 0L;
GC gc;
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
frame = (Frame)xv_create(XV_NULL, FRAME, NULL);
panel = (Panel)xv_create(frame, PANEL,
PANEL_REPAINT_PROC, panel_repaint,
NULL);
(void) xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Quit",
PANEL_NOTIFY_PROC, quit,
PANEL_CLIENT_DATA, frame,
NULL);
window_fit(frame);
grey = (Server_image)xv_create(NULL, SERVER_IMAGE,
XV_WIDTH, gray1_width,
XV_HEIGHT, gray1_height,
SERVER_IMAGE_DEPTH, 1, /* clarify for completeness*/
SERVER_IMAGE_BITS, gray1_bits,
NULL);
display = (Display *)xv_get(panel, XV_DISPLAY);
gcvalues.stipple = (Pixmap) xv_get(grey, XV_XID);
gcvalues.fill_style = FillOpaqueStippled;
gcvalues.plane_mask = 1L;
gcvalues.graphics_exposures = False;
gcvalues.foreground = BlackPixel(display, DefaultScreen(display));
gcvalues.background = WhitePixel(display, DefaultScreen(display));
gcmask = GCStipple | GCFillStyle | GCPlaneMask |
GCGraphicsExposures | GCForeground | GCBackground;
gc = XCreateGC(display, xv_get(panel, XV_XID), gcmask, &gcvalues);
/* attach the GC to the panel for use by the repaint proc above */
xv_set(panel, XV_KEY_DATA, PANEL_GC_KEY, gc, NULL);
xv_main_loop(frame);
exit(0);
}
Panels
Panels 203
Example 7-7. The panel_repaint.c program (continued)
/*
* repaint procedure for the panel paints a gray pattern over the
* entire panel. Use the GC attached to the panel via XV_KEY_DATA.
*/
void
panel_repaint(panel, pw, p_area)
Panel panel;
Xv_Window pw;
Rectlist p_area;
{
/* get the GC attached to the panel in main() */
GC gc = (GC)xv_get(panel, XV_KEY_DATA, PANEL_GC_KEY);
/* call XFillRectangle on the entire size of the panel window */
XFillRectangle(xv_get(panel, XV_DISPLAY), xv_get(pw, XV_XID), gc,
0, 0, xv_get(pw, XV_WIDTH), xv_get(pw, XV_HEIGHT));
/* Note this repaints the entire panel. It is best to */
/* repaint just the rectangles passed in p_area */
}
quit(item)
Panel_item item;
{
Frame frame = (Frame)xv_get(item, PANEL_CLIENT_DATA);
xv_destroy_safe(frame);
}
The output produced by this program is shown in Figure 7-21.
Figure 7-21. Panel with gray background
204 XView Programming Manual
The PANEL package does not retain its paint windows by default, so the repaint routine may
be called more frequently than one might expect. Therefore, when the panel is created, the
attribute WIN_RETAINED may be set to TRUE; otherwise, the routine should try to be as com-
putationally cheap as possible to maintain good performance. It is not recommended that
you retain the panel’s window unless you have provided a repaint routine that might utilize
graphics expensively. Typically, you will set the background to a solid color, render a pat-
tern, or display an image.
If a panel item is added, deleted or moved, then the repaint routine is called regardless of
whether or not the panel’s window is retained.
7.19.3 Painting Panel Items
To repaint either an individual item or an entire panel, use:
panel_paint(panel_object, paint_behavior)
Panel_item panel_object;
Panel_setting paint_behavior;
The panel_object may be a panel item or a panel itself. If it is a panel, the items within
the panel are repainted one by one. The argument paint_behavior is either
PANEL_CLEAR, which causes the rectangle occupied by the panel or item to be cleared prior
to repainting, or PANEL_NO_CLEAR, which causes repainting to be done without any prior
clearing. This setting will override the default paint behavior set in the panel item’s
PANEL_PAINT attribute.
7.19.4 Panel Event Handling
This section describes how the PANEL package handles events. If you require a behavior not
provided by default, you can write your own event handling procedure for either an individu-
al item or the panel as a whole. The default behavior for handling panel events conforms to
OPEN LOOK and should be sufficient for most users. This section is intended only for expert
users.
WARNING
Changing the default PANEL package event handling behavior allows you to cre-
ate applications that are not OPENLOOK-compliant.
The default event handling mechanism for panels processes events for all the panel items in a
uniform way. A single routine reads the events, updates an internal state machine, and maps
the event to an action to be taken by the item. Actions fall into two categories: previewing
and accepting. The previewing action gives the user visual feedback indicating what will
happen when the mouse button is released. The accepting action causes the item’s value to
be changed and/or its notify procedure to be called, with the event passed as an argument.
Panels
Panels 205
The default event-to-action mapping is given in Table 7-3.
Table 7-3. Default Event to Action Mapping
Event Action
Begin previewing.SELECT button down or drag with SELECT button down.
Drag with SELECT button down. Update previewing.
Cancel preview.Drag out of item rectangle with SELECT button down.
SELECT button up Accept.
MENU button down Display menu & accept user’s
selection.
Keystroke Accept keystroke if text item.
What actually happens when an item is told to perform one of the above actions depends on
the type of item. For example, when asked to begin previewing, a button item inverts its la-
bel, a message item does nothing, a slider item redraws the shaded area of its slider bar, etc.
ASCII events and some action events (described in Chapter 6, Handling Input) are auto-
matically redirected towards the item with keyboard focus. Since only one item at a time
may receive keyboard events, if there is more than one item in the panel that can receive key-
board input, the one that is receiving the keyboard events has a solid location cursor (a small
or large solid triangle, also referred to as a caret). You may use
PANEL_CARET_ITEM with
xv_set() or xv_get() to set or get the item that currently has the keyboard focus.
Handling events by the application in panels is a task best avoided since the panel does this
automatically. But there are certainly situations where the application might like to super-
vise or handle events itself. In such situations, there are several methods available for event
handling. You can use:
• notify_interpose_event_func()
• PANEL_BACKGROUND_PROC
• PANEL_EVENT_PROC
For normal panels, each of these methods should be used on the panel itself. However, for
the SCROLLABLE_PANEL, the event handler must be set on the panel’s paint window(s) exact-
ly as is done for canvases (using the attribute WIN_EVENT_PROC).
Each of these methods works somewhat differently from one another, but they all have one
thing in common: they are notified when events happen in panels.
206 XView Programming Manual
7.19.5 Using an Interpose Function
The Notifier’s interpose functions may be installed on panels just as they are for any other
window-based package. This is the recommended method for special event handling for
panels and for panel items, since it allows you to interfere with the normal event processing
for the destination panel (or panel item). However, events can continue to be dispatched to
the panel (panel item) through the use of the notify_next_event_func(). Refer to
Chapter 20, The Notifier, for details on interposition.
7.19.6 Using PANEL_BACKGROUND_PROC
The PANEL_BACKGROUND_PROC is similar to the WIN_EVENT_PROC except that the notifica-
tion routine is only notified of events that do not happen in, or are redirected to, any panel
items. The application would want to know about events that are not sent to panel items:
extern void my_event_proc();
panel = (Panel)xv_create(frame, PANEL,
PANEL_BACKGROUND_PROC, my_event_proc,
NULL);
The parameters to the routine for PANEL_BACKGROUND_PROC are:
void
my_event_proc(panel, event)
Panel panel;
Event *event;
The PANEL_BACKGROUND_PROC does not, by default, get keyboard events passed to it.
Therefore, rather than trying to set this mask explicitly in the panel’s window, the attribute
PANEL_ACCEPT_KEYSTROKE can be set to TRUE. With this attribute set, ASCII events and
function-key events are passed to the routine, provided there are no panel items that accept
keyboard input. If there are such items, those panel items will continue to get keyboard
events regardless of the attribute
PANEL_ACCEPT_KEYSTROKE. If you wish to get keyboard
events instead of the panel items that consume those events, you should use an event inter-
posing function discussed in Chapter 20.
7.19.7 Using PANEL_EVENT_PROC
Just as
PANEL_BACKGROUND_PROC specifies a routine to handle events that happen outside of
panel items, you can also get events that happen only within panel items using
PANEL_EVENT_PROC.
xv_set(panel, PANEL_EVENT_PROC, my_event_proc, NULL);
Using this routine causes the default event handling for that item to be ignored in favor of the
new event procedure. In other words, this routine does interfere with the normal event pro-
cessing for panel items, and the panel item’s callback routine is no longer automatically
called by the PANEL package.
Panels
Panels 207
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.