attributes specific to that object, such as the way that PANEL_ITEM_MENU can be used to
attach an existing menu to a menu button. However, the association between menus and the
items they are attached to does not imply “ownership.”
The owner of a menu is a server object. By default, (if NULL is specified as the owner) the
default server is used. Menus may be used only on the server specified; they may not be
shared across different servers. Thus, the menu owner is only a concern for applications that
spread across multiple servers. See Chapter 15, Nonvisual Objects, for details on opening a
connection to different servers.
The parent of a menu, however, may be a pullright item from another menu. See Section
11.8, “Pullright Menus,” later in this chapter.
Figure 11-6 shows the class hierarchy for the a menu object.
Generic
Object
Menu
Figure 11-6. Menu class hierarchy
Exclusive menus are created using the MENU_CHOICE_MENU package, as in the following ex-
ample:
Menu menu;
menu = (Menu)xv_create(NULL, MENU_CHOICE_MENU,
MENU_STRINGS, "choice1", "choice2", "choice3", NULL,
NULL);
Nonexclusive menus are created using the MENU_TOGGLE_MENU package, as in the following
example:
Menu menu;
Server_image image1, image2, image3;
menu = (Menu)xv_create(NULL, MENU_TOGGLE_MENU,
MENU_IMAGES, image1, image2, image3, NULL,
NULL);
278 XView Programming Manual
11.4 Displaying Menus
Menus are displayed (popped up) using the function menu_show().* It displays the speci-
fied menu and immediately returns. The function takes the form:
void
menu_show(menu, window, event, NULL);
Menu menu;
Xv_Window window;
Event *event;
The menu is a menu created from xv_create() or a menu extracted from an existing
XView object (such as a button menu). The X window associated with the menu calls
XGrabPointer() to grab the server’s mouse events. The pointer grab stays in effect until
the user releases the MENU mouse button (e.g., the ACTION_MENU action with
event_is_up() being TRUE). This is independent of the event that caused the menu to be
displayed. Releasing the MENU button results in the user having either made a selection, not
made a selection or pinned up the menu (provided that the menu has a pushpin).
The window attribute defines the window where the menu appears. The event parameter
contains the event that caused the decision to display the menu. The most common use for it
is to extract the x,y coordinate pair so as to remember the location of the pointer at the time
the menu was displayed. This event structure can be retrieved later by calling:
Event *event = (Event *)xv_get(menu, MENU_FIRST_EVENT);
Similarly, when the user releases the MENU button, this event can be retrieved using the
MENU_LAST_EVENT attribute.
The last parameter to menu_show() must be NULL. It actually represents a list of attribute-
value pairs but is used internally by other XView packages that utilize menus.
Menus can also be created at run time by procedures that are called whenever a menu is
needed. This is covered in Section 11.9, “Menu-generating Procedures.”
The routine MENU_DONE_PROC is called whenever a pop-up menu has been taken down (after
a menu item has been selected), pinned up, or simply dismissed without a selection being
made. This overrides the default action of setting XV_SHOW to FALSE, so this responsibility
lies with the MENU_DONE_PROC routine.
*This function is called internally by other XView objects such as scrollbars, menu buttons, and text subwindows to
display menus associated with them.
Menus
Menus 279
11.5 A Simple Program
Given the information provided so far, we can demonstrate how to pop up a menu. Example
11-1 shows how the canvas object tracks pointer events and calls menu_show() when the
ACTION_MENU event occurs.
Example 11-1. The simple_menu.c program
/*
* simple_menu.c -
* Demonstrate the use of an XView menu in a canvas subwindow.
* A Menu is brought up with the MENU mouse button. The choices
* in the menu toggle the display of the scrollbar next to the canvas.
*/
#include <xview/xview.h>
#include <xview/canvas.h>
#include <xview/scrollbar.h>
#define SCROLLBAR_KEY 100
#define MENU_KEY 200
main(argc,argv)
int argc;
char *argv[ ];
{
Frame frame;
Canvas canvas;
Scrollbar scrollbar;
Menu menu;
void menu_notify_proc(), pw_event_proc();
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
/*
* Create a frame, canvas and menu.
* A canvas receives input in its canvas_paint_window().
*/
frame = (Frame)xv_create(NULL, FRAME,
FRAME_LABEL, argv[0],
NULL);
canvas = (Canvas)xv_create(frame, CANVAS,
XV_WIDTH, 300,
XV_HEIGHT, 200,
NULL);
scrollbar = (Scrollbar)xv_create(canvas, SCROLLBAR,
SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL,
NULL);
menu = (Menu)xv_create(NULL, MENU,
MENU_TITLE_ITEM, "Scrollbar",
MENU_STRINGS, "On", "Off", NULL,
MENU_NOTIFY_PROC, menu_notify_proc,
XV_KEY_DATA, SCROLLBAR_KEY, scrollbar,
NULL);
280 XView Programming Manual
Example 11-1. The simple_menu.c program (continued)
xv_set(canvas_paint_window(canvas),
WIN_EVENT_PROC, pw_event_proc,
XV_KEY_DATA, MENU_KEY, menu,
NULL);
window_fit(frame);
window_main_loop(frame);
}
/*
* menu_notify_proc - toggle the display of the scrollbar
* based on which menu item was chosen.
*/
void
menu_notify_proc(menu, menu_item)
Menu menu;
Menu_item menu_item;
{
char *menu_choice = (char *)xv_get(menu_item, MENU_STRING);
int show_it = !strcmp(menu_choice, "On");
xv_set(xv_get(menu, XV_KEY_DATA, SCROLLBAR_KEY),
XV_SHOW, show_it,
NULL);
}
/*
* Call menu_show() to display menu.
*/
void
pw_event_proc(canvas_pw, event)
Xv_Window canvas_pw;
Event *event;
{
if (event_action(event) == ACTION_MENU && event_is_down(event)) {
Menu menu = (Menu)xv_get(canvas_pw, XV_KEY_DATA, MENU_KEY);
menu_show(menu, canvas_pw, event, NULL);
}
}
In Example 11-1 above, simple_menu.c shows the simplest and most common method for
creating and using pop-up menus. The menu, menu items, and callback routine are all
created at the same time using the call:
menu = (Menu)xv_create(NULL, MENU,
MENU_TITLE_ITEM, "Scrollbar",
MENU_STRINGS, "On", "Off", NULL,
MENU_NOTIFY_PROC, menu_notify_proc,
NULL);
Figure 11-7 shows the result of running simple_menu.c and selecting the menu.
Menus
Menus 281
Figure 11-7. Output of simple_menu.c when the menu is popped up
Since this menu is not attached to a menu button panel item and is not a pullright menu of
another menu item, a title bar is added using MENU_TITLE_ITEM. When a menu has a title,
the 0th menu item is the menu title. In the example above, the 0th menu item is the title item
labeled “Scrollbar.” The first menu item is the first item created after the title. Above, the
first menu item is the item labeled “On” and the second menu item is the item labeled “Off.”
When there is no title, the first menu item is placed in position zero. Add a title bar using
MENU_TITLE_ITEM only if the menu is a pop-up menu. Using titles on menus originating
from menu buttons is not OPEN LOOK-compliant.
The attribute MENU_STRINGS takes a list of strings and creates a menu item for each string.
NOTE
The
MENU
package, in contrast to the PANEL package, does not save strings which
you pass in as the menu item’s label (string). You should either pass a constant
string, as in the example above, or static storage that you have dynamically allo-
cated (e.g., malloc()).
menu_notify_proc() is a routine that is called whenever any of the menu items are
selected. The routine is passed a handle to the menu and the menu item selected. The canvas
serves no other purpose than to capture events—the event callback routine for the canvas
determines if the user generated the
ACTION_MENU event and, if so, calls menu_show().
The use of XV_KEY_DATA is used to associate one object with another. In this case, we asso-
ciate the scrollbar with the menu so when the menu callback routine is called, the scrollbar
can be retrieved easily. The menu, on the other hand, is associated with the canvas’s paint
window since that window is going to get the event that pops up the menu.
282 XView Programming Manual
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.