The use of XV_KEY_DATA removes the need for the menu and the scrollbar to be global vari-
ables. It also clarifies the association between the objects that would otherwise not be as
clear. Other examples of XV_KEY_DATA, including a complete discussion on usage, can be
found in Chapter 7, Panels, and Chapter 3, Creating XView Applications.
11.6 Creating Menu Items
As noted, the use of MENU_STRINGS results in the creation of menu items in-line; that is, they
are created automatically by the MENU package during the creation of the menu object. Other
methods for creating menu items in-line include using the attributes, MENU_ITEM and
MENU_ACTION_ITEM.*
MENU_ACTION_ITEM is used as a shortcut for separately specifying a label and a callback
routine:
menu = (Menu)xv_create(NULL, MENU,
MENU_ACTION_ITEM, "item1", callback1,
MENU_ACTION_ITEM, "item2", callback2,
...
NULL);
Two other methods for creating menu items are to:
Use a separate call to xv_create() with the MENUITEM package.
Provide a menu-generation routine.
The following subsections discuss the use of MENU_ITEM to create menu items in-line,
MENUITEM to create separate menu items, and MENU_GEN_PROC to specify a routine that cre-
ates menus.
11.6.1 Using MENU_ITEM
Using the attribute MENU_ITEM indicates that a new menu item is to be created and appended
to the existing menu. Use of this attribute means that the menu item is created in-line so a
separate call to xv_create() is not necessary. The form of the value portion of the attri-
bute is a NULL-terminated list of menu-item, attribute-value pairs:
extern void on_notify_proc(), off_notify_proc();
menu = (Menu)xv_create(NULL, MENU,
MENU_TITLE_ITEM, "Scrollbar",
MENU_ITEM,
MENU_STRING, "On",
MENU_NOTIFY_PROC, on_notify_proc,
NULL,
MENU_ITEM,
MENU_STRING, "Off",
MENU_NOTIFY_PROC, off_notify_proc,
NULL,
*The attributes MENU_IMAGES and MENU_ACTION_IMAGE are just like MENU_STRINGS and MENU_
ACTION_ITEM except that Server_images are used as labels rather than text.
Menus
Menus 283
NULL);
The code fragment shown above creates a menu with the same two menu items as shown in
the previous example, except that the menu items are created more directly by the use of
MENU_ITEM. Here we can specify item-specific attributes rather than accept all the defaults
for the menu. In this case, we set a different notification routine for each menu item.*
If you have a Server_image to display rather than a string, you can replace MENU_STRING
above with MENU_IMAGE and specify a Server_image rather than a string.
11.6.2 Using MENU_ACTION_ITEM
Rather than specifying menu item creation using a separate attribute-value list, the attribute
MENU_ACTION_ITEM can be used as a shortcut, as shown in the example below:
menu = (Menu)xv_create(NULL, MENU,
MENU_TITLE_ITEM, "Scrollbar",
MENU_ACTION_ITEM, "On", on_notify_proc,
MENU_ACTION_ITEM, "Off", off_notify_proc,
NULL);
The attribute MENU_ACTION_IMAGE, with a Server_image as its value, may be used inter-
changeably with MENU_ACTION_ITEM and its string value.
11.6.3 Using MENUITEM
The MENUITEM
package allows you to create separate menu items using separate calls to
xv_create(). The attributes used are menu item-specific attributes—the same as those
that are used in the MENU_ITEM attribute above.
Menu_item on, off;
on = (Menu_item)xv_create(NULL, MENUITEM,
MENU_STRING, "On",
MENU_NOTIFY_PROC, on_notify_proc,
NULL);
off = (Menu_item)xv_create(NULL, MENUITEM,
MENU_STRING, "Off",
MENU_NOTIFY_PROC, off_notify_proc,
NULL);
xv_set(menu,
MENU_APPEND_ITEM, on,
MENU_APPEND_ITEM, off,
NULL);
These menu items are not created in-line; they are created independently using separate calls
to xv_create(). They must therefore be added to the menu independently. In this case,
*Notification (callback) routines are discussed in Section 11.13, “Notification Procedures.”
284 XView Programming Manual
they are added using MENU_APPEND_ITEM (see the next section for more information).
11.7 Adding Menu Items
There are several methods for adding separately created menu items to menus. For a list of
menu item attributes, see the package summary at the end of this chapter. These attributes
can be used when you are using xv_set() on a menu.
The code fragment below demonstrates the use of MENU_APPEND_ITEM. The menu items are
created independently of the menu itself. They are added to the menu as they are created by
using the attribute MENU_APPEND_ITEM:
char *names[ ] = { "One", "Two", "Three", "Four", "Five" };
Menu menu;
Menu_item mi;
int i;
void my_notify_proc();
menu = (Menu)xv_create(NULL, MENU, NULL);
for (i = 0; i < 5; i++) {
mi = (Menu_item)xv_create(NULL, MENUITEM,
MENU_STRING, names[i],
MENU_NOTIFY_PROC, my_notify_proc,
MENU_RELEASE,
NULL);
xv_set(menu, MENU_APPEND_ITEM, mi, NULL);
}
This use of MENU_RELEASE is to indicate that the menu item is intended to be freed when the
item’s parent menu is destroyed. This attribute takes no value; specifying it is equivalent to
specifying a TRUE value. Not specifying it implies FALSE. In-line menu items have this attri-
bute set by default, but menu items that are not created in-line must set this attribute expli-
citly if you want them to be freed automatically. You do not want to set this attribute if you
intend to use this menu item in more than one menu or if you want to reuse it later. See Sec-
tion 11.17, “Destroying Menus.”
11.8 Pullright Menus
A pullright menu is simply another menu that is attached to a menu item. Note that for a
menu item to contain a pullright menu, the pullright menu must already have been created.
This means that any menu group should be created from the bottom up. The attributes
MENU_PULLRIGHT, MENU_PULLRIGHT_ITEM, and MENU_PULLRIGHT_IMAGE all allow a
pullright menu to be attached to a menu item.
In the first case, MENU_PULLRIGHT can be assigned to a menu item to attach an existing menu
to it, as shown below:
extern Server_image image1, image2, image3;
Menus
Menus 285
Menu image_menu, menu;
void image_notify_proc();
image_menu = (Menu)xv_create(NULL, MENU,
MENU_IMAGES, image1, image2, image3, NULL,
MENU_NOTIFY_PROC, image_notify_proc,
NULL);
menu = (Menu)xv_create(NULL, MENU,
MENU_ITEM,
MENU_STRING, "images",
MENU_PULLRIGHT, image_menu,
NULL,
NULL);
In the previous example, a menu of server images is created and is initialized to contain three
images. Another menu is created that is initialized for one menu item, but that menu item has
a pullright menu that is set to the menu_images menu.
The menu item created may also be initialized using the MENU_PULLRIGHT_ITEM attribute.
This attribute takes two parameters as its value: a string and a menu. Therefore, the above
code fragment could have been written:
menu = (Menu)xv_create(NULL, MENU,
MENU_PULLRIGHT_ITEM, "images", image_menu,
NULL);
Had the label for the pullright menu item been a Server_image rather than a string, the
call would look like:
extern Server_image label_image;
menu = (Menu)xv_create(NULL, MENU,
MENU_PULLRIGHT_IMAGE, label_image, image_menu,
NULL);
In the code fragment below, we use another piece of code to demonstrate the same principle.
This example demonstrates how a menu that represents font sizes may be set as the pullright
menu for a list of fonts:
Menu font_menu, size_menu;
Menu_item mi;
int i;
void notify_font();
char buf[4], *p;
...
size_menu = (Menu)xv_create(NULL, MENU,
MENU_NOTIFY_PROC, notify_size,
NULL);
286 XView Programming Manual
for (i = 8; i <= 20; i += 2) {
sprintf(buf, "%d", i);
p = strcpy(malloc(strlen(buf)+1), buf);
mi = (Menu_item)xv_create(NULL, MENUITEM,
MENU_STRING, p,
MENU_RELEASE,
MENU_RELEASE_IMAGE,
MENU_NOTIFY_PROC, notify_font,
NULL);
xv_set(size_menu, MENU_APPEND_ITEM, mi, NULL);
}
font_menu = (Menu)xv_create(NULL, MENU,
MENU_TITLE_ITEM, "Fonts",
MENU_PULLRIGHT_ITEM, "courier", size_menu,
MENU_PULLRIGHT_ITEM, "boston", size_menu,
MENU_PULLRIGHT_ITEM, "times-roman", size_menu,
MENU_PULLRIGHT_ITEM, "lucidasans", size_menu,
MENU_PULLRIGHT_ITEM, "palatino-roman", size_menu,
NULL);
Each item in the main menu (font_menu) has a pullright menu (size_menu) associated
with it. In the for loop where the string for the menu item is assigned, the data is allocated
using malloc() and buf is copied into the allocated data using strcpy(). We cannot
use buf directly, because unlike panel items, the menu item string is not copied by the MENU
package—we must pass in allocated data. Because of this, we also specify the attribute
MENU_RELEASE_IMAGE so that when the item is destroyed, the allocated data will be freed.
Also note that because we used xv_create() to create the menu item, we specify
MENU_RELEASE to indicate that the menu item should be freed when the parent menu is des-
troyed.
11.9 Menu-generating Procedures
In certain situations, the menu items for a particular menu cannot be known ahead of time.
For example, a mail application allows users to write mail messages to files in a designated
folder directory. If a menu is going to display the current folders in that directory, then the
menu items should be updated any time a folder is created or deleted from that directory. But
rather than updating the folder at the time the directory contents change, it would be better to
scan the directory and use each filename in the directory as a menu item.
For such situations, it is necessary to defer the creation of the folder menu until it needs to be
displayed. Therefore, you still create the pullright menu item so the user can select the item.
But rather than specifying a pullright menu associated with the item, specify a routine that
will generate the menu. When the menu needs to be displayed, the routine is called which
returns a menu.
To do this, you specify the attribute
MENU_GEN_PULLRIGHT when creating the menu item, as
shown below:
Menu menu, gen_folder_menu();
void change_to_folder();
Menus
Menus 287

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.