.TH XMENU 3X "29 January 1986" "X Version 10" .SH NAME XMenu - X Deck of cards Menu System .SH SYNOPSIS .nf .B #include .PP .B XMenu *XMenuCreate(parent, xdef_env) .B Window parent; .B char *xdef_env; .PP .B int XMenuAddPane(menu, label, active) .B XMenu *menu; .B char *label; .B int active; .PP .B int XMenuAddSelection(menu, pane, data, label, active) .B XMenu *menu; .B int pane; .B char *data; .B char *label; .B int active; .PP .B int XMenuInsertPane(menu, pane, label, active) .B XMenu *menu; .B int pane; .B char *label; .B int active; .PP .B int XMenuInsertSelection(menu, pane,selection, data, label, active) .B XMenu *menu; .B int pane, selection; .B caddr_d data; .B char *label; .B int active; .PP .B int XMenuFindPane(menu, label) .B XMenu *menu; .B char *label; .PP .B int XMenuFindSelection(menu, pane, label) .B XMenu *menu; .B int pane; .B char *label; .PP .B int XMenuChangePane(menu, pane, label) .B XMenu *menu; .B int pane; .B char *label; .PP .B int XMenuChangeSelection(menu, pane,selection, data,d_sw, label,l_sw) .B XMenu *menu; .B int pane, selection; .B char *data; .B int d_sw; .B char *label; .B int l_sw; .PP .B int XMenuSetPane(menu, pane, active) .B XMenu *menu; .B int pane; .B int active; .PP .B int XMenuSetSelection(menu, pane, selection, active) .B XMenu *menu; .B int pane, selection; .B int active; .PP .B int XMenuDeletePane(menu, pane) .B XMenu *menu; .B int pane; .PP .B int XMenuDeleteSelection(menu, pane, selection) .B XMenu menu; .B int pane, selection; .PP .B int XMenuRecompute(menu) .B XMenu *menu; .PP .B XMenuEventHandler(handler) .B int (*handler)(); .PP .B int XMenuLocate(menu, pane,selection, x,y, ulx,uly, width,height) .B XMenu *menu; .B int pane, selection; .B int x, y; .B int *ulx, *uly; .B int *width, *height; .PP .B XMenuSetFreeze(menu, freeze) .B XMenu *menu; .B int freeze; .PP .B int XMenuActivate(menu, pane,selection, x,y, event_mask, data) .B XMenu *menu; .B int *pane, *selection; .B int x, y; .B int event_mask; .B char **data; .PP .B XMenuDestroy(menu) .B XMenu *menu; .PP .B char *XMenuError() .fi .SH DESCRIPTION .PP .I XMenu is an .I X Window System Utility Package that implements a `deck of cards' menu system. .I XMenu is intended for use in conjunction with .I Xlib, the \fIC Language X Window System Interface Library.\fP .PP In a `deck of cards' menu system a menu is composed of several cards or panes. The panes are stacked as if they were a deck of playing cards that were fanned out. Each of these panes has one or more selections. A user interacts with a `deck of cards' menu by sliding the mouse cursor across the panes of the menu. As the mouse cursor enters each pane it will rise to the top of the deck and become `current'. If the current pane is an active pane it will be `activated', or made available for selection. To indicate this its background will then change from the patterned inactive background to a solid color and the selections on that pane will be activated. If the current pane is not an active pane (a setable state) then it will not be activated. To indicate this its background will continue to be the patterned inactive background and no selections on the pane will be activated. The pane previously containing the mouse will lower (preserving its stacking order). If it was activated it will then become deactivated, its background changing back to the inactive pattern. Because of this action it is not possible to have more than one current pane at any one time. When the mouse cursor enters an active selection in a pane that has been activated then that selection will become activated and be high lighted. If the selection is not active or the pane has not been activated then the selection will not be activated and will not be high lighted. Selection high lighting is accomplished in one of two ways depending upon the state of the user's .I Xdefaults variables. If `box' mode high lighting is in effect, the menu selection will be activated by placing a high light box around the selection as the mouse cursor enters the selection's active region and removing it (deactivating the selection) as the cursor leaves. If `invert' mode high lighting is in effect, the menu selection will be activated by inverting the background and foreground colors within the selection's active region as the mouse cursor enters it and reinverting them as the cursor leaves. .PP The application specifies a mouse event that will signify that the user has made a selection. Any time that the selection mouse event is received by .I XMenu one of several results will occur, depending upon the state of the menu system at the time of the event. If the selection event occurs while the mouse cursor is in an activated selection the data that has been stored with that selection will be returned to the application program. The data stored is in the form of a generic pointer to memory (char *). This allows the application programmer to completely define the interpretation of the selection data by recasting the data pointer as is desired. .PP An application constructs a menu by first creating the .I XMenu object. Once the .I XMenu object has been created then panes and selections are added in order as is needed. Typically panes contain related selections that are `described' by the pane's label. For example, you might create a pane labeled `Mail' that has selections labeled `Read', `Send', `Forward', `Refile' and `Delete'. There is no real need for the panes in a menu to be related to each other but typically they are related by default by the fact that they are all being utilized the application that created the menu. .PP The .I XMenu system is maintained (menus, panes and selections) via routines in the .I XMenu library. The library contains the following routines: .PP .TP 8 .B XMenuCreate In order for a process to create a menu, it is necessary for that process to have opened a connection to an .I X display server and have a window in hand that will be designated as the parent window of the menu being created (remember that .I X is designed such that child windows of a parent window are clipped to the borders of the parent). Typically the .I X root window ( .I RootWindow ) is used for this purpose. When the connection is open and a parent window chosen, the application calls .I XMenuCreate passing it the parent window and a null-terminated string. The string designates the default environment name that will be used by XMenu to read the users .I Xdefaults variables. Typically the application name is used for this purpose (a good software engineering practice is to use element zero of the applications argument vector, argv[0], as the default environment since this is the name by which the application was called from the shell). All .I user setable parameters are set via the .I Xdefaults mechanism. If any parameters do not have .I Xdefaults values then they default to preset .I XMenu internal values. The .I Xdefaults parameters are listed below along with their preset internal values. If the create operation is successful .I XMenuCreate will return an .I XMenu object. If it fails NULL will be returned. .PP .TP 8 .B XMenuAddPane Once a menu has been created the application may then begin adding panes and subsequently selections. Panes are added by calling .I XMenuAddPane. .I XMenuAddPane adds additional panes to a menu in call order. That is, panes will appear in the menu with the first pane added being at the front of the pane stack and the last pane added being at the back of the pane stack. .I XMenuAddPane takes the following arguments: The menu to which the pane is being added; A null-terminated string that will be the label for the new pane; and an flag that designates whether or not the pane is to be considered active for selection. It is sometimes useful to add inactive panes to indicate a currently unavailable but planned set of selections. If the add operation is successful the index number of the pane just added will be returned. If it fails XM_FAILURE will be returned. Further panes may be added at a later time but remember that when this routine is used to add panes they are always added to the back of the pane stack! .PP .TP 8 .B XMenuAddSelection Once a pane has been added to a menu is it possible to begin adding selections to that pane. Selections are added to panes in much the same way as panes are added to menus. Selections are added by calling .I XMenuAddSelection. .I XMenuAddSelection adds additional selections to a pane in call order. That is, selections will appear in the pane with the first selection added being at the top of the pane and the last selection added being at the bottom of the pane. .I XMenuAddSelection takes the following arguments: The menu containing the pane to which the selection is being added; The index number of the pane to which the selection is being added; A null-terminated string that will be the label for the new selection; A (char *) data value that will be returned by .I XMenuActivate whenever the new selection is selected by the menu's user; and a flag that designates whether or not the selection will be considered active. It is sometimes useful to add inactive selections which may become active as the application state changes. If the add operation is successful then the index number of the selection just added will be returned. If it fails XM_FAILURE will be returned. Further selections may be added at a later time but remember when this routine is used to add selections they are always added to the bottom of a pane! .PP .TP 8 .B XMenuInsertPane This routine allows the application to insert menu panes into a menu in random order. If the index number of the pane being inserted matches the index number of a pane that already exists, then the existing pane is displaced backward (its index number and the index numbers of all following planes increased by one) in the menu and the new pane inserted in its place. Panes may be inserted into any menu provided that the index number of the pane being inserted is no more than one greater than the index number of the last pane in the menu. For example, if a menu contains 4 panes with index numbers 0 through 3 then it is possible to insert a new pane with an index number from 0 through 4 inclusive. It is possible to use .I XMenuInsertPane in place of .I XMenuAddPane but in situations where panes are simply being added to a menu one after another then the use of the simpler and more efficient .I XMenuAddPane routine is encouraged. .I XMenuInsertPane takes the following arguments: The menu into which the pane is being inserted; the index number of the new pane; a null-terminated string that will be the label for the new pane; and an int that designates whether or not the pane will to be considered active for selection. It is sometimes useful to add inactive panes to indicate a currently unavailable but planned set of selections. If the insert operation is successful the index number of the pane just inserted will be returned. If it fails XM_FAILURE will be returned. .PP .TP 8 .B XMenuInsertSelection This routine allows the application to insert selections into a menu pane in random order. If the index number of the selection being inserted matches the index number of a selection that already exists in the specified pane, then the existing selection is displaced downward (its index number and the index numbers of all following selections increased by one) in the pane and the new selection inserted in its place. Selections may be inserted into any pane provided that the index number of the selection being inserted is no more than one greater than the index number of the last selection in the pane. For example, if a pane contains 4 selections numbered 0 through 3 then it is possible to insert a new selection with an index number from 0 through 4 inclusive. It is possible to use .I XMenuInsertSelection in place of .I XMenuAddSelection but in situations where selections are simply being added to a pane one after another then the use of the simpler and more efficient .I XMenuAddSelection routine is encouraged. .I XMenuInsertSelection takes the following arguments: the menu containing the pane into which the selection is being inserted; the index number of the pane to which the selection is being inserted; the desired index number of the new selection; a null-terminated string that will be the label for the new selection; A (char *) data value that will be returned by .I XMenuActivate whenever the new selection is selected by a user; and an int that designates whether or not the selection will be considered active for selection. It is sometimes useful to insert inactive selections which may become active as the application state changes. If the insert operation is successful the index number of the selection just inserted will be returned. If it fails XM_FAILURE will be returned. .PP .TP 8 .B XMenuFindPane This routine allows the application to find the index number of a pane whose label matches a given NULL terminated string. .I XMenuFindPane takes the following arguments: the menu containing the pane whose index number is being searched for; and a null terminated string to be searched for. If the find operation is successful then the index number of the first pane whose label matches the given string will be returned. If it fails XM_FAILURE will be returned. .PP .TP 8 .B XMenuFindSelection This routine allows the application to find the index number of a selection whose label matches a given NULL terminated string. .I XMenuFindSelection takes the following arguments: the menu containing the pane which contains the selection being searched for; the index number of the pane which contains the selection being searched for; and a null terminated string to be searched for. If the find operation is successful then the index number of the first selection whose label matched the given string will be returned. If is fails XM_FAILURE will be returned. .PP .TP 8 .B XMenuChangePane This routine allows the application to change a pane's label on the fly. This is useful for situations where a state change in the application must be reflected in the menu. .I XMenuChangePane takes the following arguments: the menu containing the pane whose label is being changed; the index number of that pane in the specified menu; and a null-terminated string that will be the used as the new pane label. If the change operation is successful the index number of the pane just changed will be returned. If it fails XM_FAILURE will be returned. .I XMenuChangePane may be called any time after the pane being changed has been added / inserted into the specified menu. .PP .TP 8 .B XMenuChangeSelection This routine allows the application to change a selection's data and label on the fly. This is useful for situations where a state change in the application must be reflected in the menu. .I XMenuChangeSelection takes the following arguments: the menu containing the pane that contains the selection to be changed; the index number of that pane in the menu; the index number of the selection to be changed; a (char *) new data value for the selection; an int that indicates whether or not to actually store the new data value (in case only the label is being changed); Aanull-terminated string that will be the used as the new selection label; and an int that indicates whether or not to actually store the new label (incase only the data value is being changed). If the change operation is successful the index number of the selection just changed will be returned. If it fails XM_FAILURE will be returned. .I XMenuChangeSelection may be called anytime after the pane selection being changed has been added to the specified pane and menu. .PP .TP 8 .B XMenuSetPane .I XMenuSetPane allows the application to make an active pane inactive or an inactive pane active. This provides the application with the ability to restrict the usage of certain panes to times when they may or may not have a valid purpose. In addition this allows the application to activate and utilize dummy panes that were added at menu creation time as place holders for future selections. .I XMenuSetPane takes the following arguments: the menu containing the pane to be activated or deactivated; the index number of that pane in the specified menu; and an int that designates whether or not the pane is to be considered active for selection. If the set operation is successful the index number of the pane just set will be returned. If it fails XM_FAILURE will be returned. .I XMenuSetPane may be called anytime after the pane being set has been added / inserted into the specified menu. .PP .TP 8 .B XMenuSetSelection .I XMenuSetSelection allows the application to make an active selection inactive or an inactive selection active. This provides the application with the ability to restrict the usage of certain selections to times when they may or may not have a valid purpose. In addition this allows the application to activate and utilize selections that were added at menu creation time with a future purpose in mind. .I XMenuSetSelection takes the following arguments: the menu containing the pane that contains the selection to be activated or deactivated; the index number of that pane in the menu; the index number of the selection to be activated / deactivated; and an int that designates whether or not to make the specified selection active. If the set operation is successful the index number of the selection just set will be returned. If it fails XM_FAILURE will be returned. .I XMenuSetSelection may be called anytime after the pane selection being set has been added to the specified pane and menu. .PP .TP 8 .B XMenuDeletePane This routine allows the application to delete panes when they will no longer be needed. .I XMenuDeletePane takes the following arguments: the menu containing the pane to be deleted; and the index number of that pane in the specified menu. .PP .TP 8 .B XMenuDeleteSelection This routine allows the application to delete selections when they will no longer be needed. .I XMenuDeleteSelection takes the following arguments: the menu containing the pane which contains the selection to be deleted; the index number of the pane containing the selection to be deleted; and the index number of the selection to be deleted in that pane. .PP .TP 8 .B XMenuRecompute After the initial menu configuration has been constructed (in fact, anytime that the menu configuration, a pane label or selection label is altered), the menu dependencies need to be recomputed. .I XMenu will do this automatically if needed when .I XMenuLocate or .I XMenuActivate is called. In the interest of efficiency it is suggested that the application call .I XMenuRecompute prior to any calls to .I XMenuLocate or .I XMenuActivate. This need only be done if .I XMenuAddPane, .I XMenuAddSelection, .I XMenuInsertPane, .I XMenuInsertSelection, .I XMenuChangePane, .I XMenuChangeSelection, .I XMenuDeletePane, or .I XMenuDeleteSelection have been called since the last call to .I XMenuRecompute or .I XMenuActivate. If .I XMenuRecompute is called before the first pane has been added to the menu a error will result indicating that the menu has not been initialized. The most efficient state is achieved if a sequence of panes and selections are added or modified in order and then a single call is immediately made to .I XMenuRecompute. In this way all operations will batched and all dependencies will be up to date by the time the next .I XMenuActivate call occurs. If the recompute operation is successful XM_SUCCESS will be be returned. If it fails XM_FAILURE will be returned. .PP .TP 8 .B XMenuEventHandler Since .I XMenu shares the .I Xlib event queue with the application, it is possible that .I X events selected by the application will arrive and be queued while a menu is posted. Before a menu is posted, it is up to the application to decide what will happen to events that do occur while the menu is posted. .I XMenuEventHandler allows the application to specify an asynchronous event handling routine. .I XMenuEventHandler takes only one argument which is a pointer to a routine which returns int. This routine will be called by .I XMenuActivate if it encounters an event that it does not recognize. The format of the handler should be as follows: .br .B int handler(event) .br .B XEvent *event; .br If no action is taken by the application (i.e., no event handler is specified) .I XMenuActivate will discard any events that they do not recognize. .PP .TP 8 .B XMenuLocate This routine provides an application will all the necessary data to properly locate and position a menu with respect to the parent window. .I XMenuLocate takes the following arguments: the menu that is being located; the index number of the current pane; the index number of the current selection; the X and Y coordinates of where the application would like the center of the current selection (in the current pane) to be; and four return value pointers to int that will be filled in by the routine. The four return value pointers are set to the following values (respectively): the upper left X and Y coordinates of the entire menu (relative to the parent window); and the overall width and height of the entire menu. If the locate operation is successful XM_SUCCESS will be be returned. If it fails XM_FAILURE will be returned. .PP .TP 8 .B XMenuSetFreeze This routine allows the application to forcibly override the .I Xdefaults setting of the `freeze' parameter. If freeze mode is turned on the bits under where the menu will appear are saved by .I XMenu then the .I X server is frozen and remains frozed while the menu is activated. Immediately after the menu is deactivated the bits under the menu are restored to their original state and the server is unfrozen. This routine is necessary for certain applications that must guarantee that the screen contents are not damaged by .I XMenu. XMenuSetFreeze takes two arguments: The menu to be set and an int that indicates whether or not to place the menu in freeze mode. .PP .TP 8 .B XMenuActivate .I XMenuActivate maps a given menu to the display and activates the menu for user selection. Before .I XMenuActivate is called it is suggested that the application synchronize the X connection and and process all events in the .I Xlib internal event queue. This guarantees that a minimum of asynchronous call-backs to the applications event handler routine (or discards if no application event handler is specified). .I XMenuActivate guarantees that no unprocessed events of its own will be left in the .I Xlib event queue upon its return. .I XMenuActivate takes the following arguments: the menu that is to be posted; the desired current pane and selection; the X and Y menu position; the mouse button event mask; and a pointer to a pointer to char (char **). The menu is positioned within the menu's parent window such that the specified X and Y location (relative to the parent window) is in the center of the specified current selection in the current pane. The mouse button event mask provided by the application should be suitable for an .I XGrabMouse operation. It provides the application with a way to indicate which mouse events will be used to identify a selection request. Every time .I XMenuActivate returns, the pane and selection indices are left at their last known values (i.e., the last current pane and selection indices). The following are the defined return states for this routine: .LP .nf .ta 1i 1.5i 1) If the selection that is current at the time a selection request is made is active then the data pointer will be set to the data associated with that particular selection and XM_SUCCESS is returned. 2) If the selection that is current at the time a selection request is made is not active then the data pointer will be left untouched and XM_IA_SELECT will be returned. 3) If there is no selection current at the time a selection request is made then the data pointer will be left untouched and XM_NO_SELECT will be returned. 4) If at any time an error occurs the data pointer is left untouched and XM_FAILURE is returned. .fi .PP .TP 8 .B XMenuDestroy When the application is no longer intending to use a menu .I XMenuDestroy should be called. .I XMenuDestroy frees all resources (both .I X resources and system resources) that are being held by the menu. .I XMenuDestroy takes only one argument, the menu to be destroyed. WARNING! Using a menu after it has been destroyed is to invite disaster! .PP .TP 8 .B XMenuError When called .I XMenuError will return a null-terminated string that describes the current error state of the .I XMenu library. The string returned is static in the .I XMenu library and should not be modified or freed. The error state is set every time an .I XMenu routine returns a status condition. .I XMenuError takes no arguments. .SH X DEFAULTS .PP .TP 8 .B MenuFreeze Determines whether or not to grab the .I X server while a menu is posted. One of: on, off. The default value is off. .PP .TP 8 .B MenuStyle Determines the menu display style. One of: left_hand, right_hand, center. The default value is right_hand. .PP .TP 8 .B MenuMode Determines the menu selection high light mode. One of: box, invert. If box mode is chosen then the SelectionBorderWidth and SelectionBorderColor parameters effect the box line width and color respectively. If invert mode is chose then the SelectionForeground and MenuBackground colors are used for the inversion. The default value is invert. .PP .TP 8 .B MenuMouse Determines the color of the mouse cursor while it is within the menu. Any valid .I X color may be used. The default value is black. .PP .TP 8 .B MenuBackground Determines the menu background color. Any valid .I X color may be used. The default value is white. .PP .TP 8 .B MenuInactivePattern Determines which of the five possible bitmap patterns will be used to tile inactive panes. One of: dimple1, dimple3, gray1, gray3, cross_weave. The default value is gray3. .PP .TP 8 .B PaneStyle Determines the display style of all menu panes. One of: flush_left, flush_right, center. The default value is center. .PP .TP 8 .B PaneFont Determines the font used for the label (heading text) of each pane. Any valid .I X font may be used. The default value is 8x13. .PP .TP 8 .B PaneForeground Determines the pane foreground color. This is the color used for the label (heading text) in each pane. Any valid .I X color may be used. The default value is black. .PP .TP 8 .B PaneBorder Determines the color of all menu pane borders. Any valid .I X color may be used. The default value is black. .PP .TP 8 .B PaneBorderWidth Determines the width (in pixels) of all menu pane borders. Any integer greater than or equal to 0 may be used. The default value is 2. .PP .TP 8 .B PaneSpread Determines the horizontal spread of menu panes. Any double greater than or equal to 0.0 may be used. A value of 1.0 specifies a one to one ratio between horizontal spread and vertical spread. A value less than 1.0 will compress the menu panes inward and a value greater than 1.0 will expand them outward. The default value is 1.0. .PP .TP 8 .B SelectionStyle Determines the display style of all menu selections. One of: flush_left, flush_right, center. The default value is flush_left. .PP .TP 8 .B SelectionFont Determines the font used for the text in each selection. Any valid X font may be used. The default value is 6x10. .PP .TP 8 .B SelectionForeground Determines the selection foreground color. This is the color used for the text in each selection. Any valid .I X color may be used. The default value is black. .PP .TP 8 .B SelectionBorder Determines the color of all menu selection borders. Any valid .I X color may be used. The default value is black. .PP .TP 8 .B SelectionBorderWidth Determines the width (in pixels) of all menu selection borders. Any integer greater than or equal to 0 may be used. The default value is 1. .PP .TP 8 .B SelectionSpread Determines the inter-selection spread. Any double greater than or equal to 0.0 may be used. A value of 1.0 specifies that 1.0 times the height of the current selection font will be used for padding The default value is 0.25. .SH DIAGNOSTICS .PP Since .I XMenu uses the .I Xlib library, the .I XIOError and .I XError .I Xlib routines may be set by the application to change how asynchronous error reporting occurs. .PP Synchronous error reporting is primarily accomplished by examining the return values of routines and using the .I XMenuError routine. Although its use is discouraged, synchronous error reporting may also be accomplished by having the application directly examine the value of the .I _XMErrorCode global variable. .I _XMErrorCode is set every time an .I XMenu routine returns a status condition. The following sequence of symbols is provided in .I XMenu.h and may be used to index the null-terminated description strings in the global error string array .I _XMErrorList. .LP .nf .ta \w'XME_CREATE_WINDOW 'u + .5i XME_CODE_COUNT Total number of entries in \fI_XMErrorList\fP (17). XME_NO_ERROR -> ``No error'' XME_NOT_INIT -> ``Menu not initialized'' XME_ARG_BOUNDS -> ``Argument out of bounds'' XME_P_NOT_FOUND -> ``Pane not found'' XME_S_NOT_FOUND -> ``Selection not found'' XME_STYLE_PARAM -> ``Invalid menu style parameter'' XME_GRAB_MOUSE -> ``Unable to grab mouse'' XME_INTERP_LOC -> ``Unable to interpret locator'' XME_CALLOC -> ``Unable to calloc memory'' XME_CREATE_ASSOC -> ``Unable to create XAssocTable'' XME_STORE_BITMAP -> ``Unable to store bitmap'' XME_MAKE_TILES -> ``Unable to make tile pixmaps'' XME_MAKE_PIXMAP -> ``Unable to make pixmap'' XME_CREATE_CURSOR -> ``Unable to create cursor'' XME_OPEN_FONT -> ``Unable to open font'' XME_CREATE_WINDOW -> ``Unable to create windows'' XME_CREATE_TRANSP -> ``Unable to create transparencies'' .fi .SH FILES .PP /usr/include/X/XMenu.h, /usr/lib/libXMenu.a, /usr/include/X/Xlib.h, /usr/lib/libX.a .SH SEE ALSO Xlib(3x), X(1), X(8c) .SH AUTHOR .PP Copyright 1985, 1986, Massachusetts Institute of Technology. .PP See \fIX(1)\fP for a complete copyright notice. .PP Tony Della Fera (MIT Project Athena, DEC) .SH BUGS .PP There is a problem that necessitates an additional round trip time when panes are activated and deactivated. In order for this to be fixed efficiently, a change needs to be made to the .I X protocol.