1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-27 07:37:33 +00:00

(Fx_popup_menu): Add a vector of prefix keys for the panes.

(keymap_panes): Allocate that vector.
(single_keymap_panes): Fill in that vector.
(xmenu_show): Return a list of events, not just one event.
This commit is contained in:
Richard M. Stallman 1993-05-12 05:17:47 +00:00
parent 9d330ad06a
commit 819012f055

View File

@ -100,13 +100,16 @@ a definition; actually, the \"definition\" in such a key binding looks like\n\
\(STRING . REAL-DEFINITION). To give the menu a title, put a string into\n\
the keymap as a top-level element.\n\n\
You can also use a list of keymaps as MENU.\n\
Then each keymap makes a separate pane.\n\n\
Then each keymap makes a separate pane.\n\
When MENU is a keymap or a list of keymaps, the return value\n\
is a list of events.\n\n\
Alternatively, you can specify a menu of multiple panes\n\
with a list of the form (TITLE PANE1 PANE2...),\n\
where each pane is a list of form (TITLE ITEM1 ITEM2...).\n\
Each ITEM is normally a cons cell (STRING . VALUE);\n\
but a string can appear as an item--that makes a nonselectable line\n\
in the menu.")
in the menu.\n\
With this form of menu, the return value is VALUE from the chosen item.")
(position, menu)
Lisp_Object position, menu;
{
@ -117,6 +120,7 @@ in the menu.")
char ***names;
int **enables;
Lisp_Object **obj_list;
Lisp_Object *prefixes;
int *items;
char *title;
char *error_name;
@ -213,7 +217,7 @@ in the menu.")
/* Extract the detailed info to make one pane. */
number_of_panes = keymap_panes (&obj_list, &menus, &names, &enables,
&items, maps, nmaps);
&items, &prefixes, maps, nmaps);
/* The menu title seems to be ignored,
so put it in the pane title. */
if (menus[0] == 0)
@ -225,6 +229,7 @@ in the menu.")
ltitle = Fcar (menu);
CHECK_STRING (ltitle, 1);
title = (char *) XSTRING (ltitle)->data;
prefixes = 0;
number_of_panes = list_of_panes (&obj_list, &menus, &names, &enables,
&items, Fcdr (menu));
}
@ -261,8 +266,8 @@ in the menu.")
abort ();
selection = xmenu_show (root, XMenu_xpos, XMenu_ypos, names, enables,
menus, items, number_of_panes, obj_list, title,
&error_name);
menus, prefixes, items, number_of_panes, obj_list,
title, &error_name);
}
UNBLOCK_INPUT;
/* fprintf (stderr, "selection = %x\n", selection); */
@ -298,12 +303,13 @@ struct indices {
Lisp_Object
xmenu_show (parent, startx, starty, line_list, enable_list, pane_list,
line_cnt, pane_cnt, item_list, title, error)
prefixes, line_cnt, pane_cnt, item_list, title, error)
Window parent;
int startx, starty; /* upper left corner position BROKEN */
char **line_list[]; /* list of strings for items */
int *enable_list[]; /* list of strings for items */
char *pane_list[]; /* list of pane titles */
Lisp_Object *prefixes; /* Prefix key for each pane */
char *title;
int pane_cnt; /* total number of panes */
Lisp_Object *item_list[]; /* All items */
@ -405,6 +411,12 @@ xmenu_show (parent, startx, starty, line_list, enable_list, pane_list,
fprintf (stderr, "pane= %d line = %d\n", panes, selidx);
#endif
entry = item_list[panes][selidx];
if (prefixes != 0)
{
entry = Fcons (entry, Qnil);
if (!NILP (prefixes[panes]))
entry = Fcons (prefixes[panes], entry);
}
break;
case XM_FAILURE:
/* free (datap_save); */
@ -435,12 +447,13 @@ syms_of_xmenu ()
KEYMAPS is a vector of keymaps. NMAPS gives the length of KEYMAPS. */
int
keymap_panes (vector, panes, names, enables, items, keymaps, nmaps)
keymap_panes (vector, panes, names, enables, items, prefixes, keymaps, nmaps)
Lisp_Object ***vector; /* RETURN all menu objects */
char ***panes; /* RETURN pane names */
char ****names; /* RETURN all line names */
int ***enables; /* RETURN enable-flags of lines */
int **items; /* RETURN number of items per pane */
Lisp_Object **prefixes; /* RETURN vector of prefix keys, per pane */
Lisp_Object *keymaps;
int nmaps;
{
@ -459,13 +472,14 @@ keymap_panes (vector, panes, names, enables, items, keymaps, nmaps)
*items = (int *) xmalloc (npanes_allocated * sizeof (int));
*names = (char ***) xmalloc (npanes_allocated * sizeof (char **));
*enables = (int **) xmalloc (npanes_allocated * sizeof (int *));
*prefixes = (Lisp_Object *) xmalloc (npanes_allocated * sizeof (Lisp_Object));
/* Loop over the given keymaps, making a pane for each map.
But don't make a pane that is empty--ignore that map instead.
P is the number of panes we have made so far. */
for (mapno = 0; mapno < nmaps; mapno++)
single_keymap_panes (keymaps[mapno], panes, vector, names, enables, items,
&p, &npanes_allocated, "");
prefixes, &p, &npanes_allocated, "");
/* Return the number of panes. */
return p;
@ -476,7 +490,7 @@ keymap_panes (vector, panes, names, enables, items, keymaps, nmaps)
The other arguments are passed along
or point to local variables of the previous function. */
single_keymap_panes (keymap, panes, vector, names, enables, items,
single_keymap_panes (keymap, panes, vector, names, enables, items, prefixes,
p_ptr, npanes_allocated_ptr, pane_name)
Lisp_Object keymap;
Lisp_Object ***vector; /* RETURN all menu objects */
@ -484,6 +498,7 @@ single_keymap_panes (keymap, panes, vector, names, enables, items,
char ****names; /* RETURN all line names */
int ***enables; /* RETURN enable flags of lines */
int **items; /* RETURN number of items per pane */
Lisp_Object **prefixes; /* RETURN vector of prefix keys, per pane */
int *p_ptr;
int *npanes_allocated_ptr;
char *pane_name;
@ -508,6 +523,10 @@ single_keymap_panes (keymap, panes, vector, names, enables, items,
*items
= (int *) xrealloc (*items,
*npanes_allocated_ptr * sizeof (int));
*prefixes
= (Lisp_Object *) xrealloc (*prefixes,
(*npanes_allocated_ptr
* sizeof (Lisp_Object)));
*names
= (char ***) xrealloc (*names,
*npanes_allocated_ptr * sizeof (char **));
@ -519,6 +538,10 @@ single_keymap_panes (keymap, panes, vector, names, enables, items,
/* When a menu comes from keymaps, don't give names to the panes. */
(*panes)[*p_ptr] = pane_name;
/* Normally put nil as pane's prefix key.
Caller will override this if appropriate. */
(*prefixes)[*p_ptr] = Qnil;
/* Get the length of the list level of the keymap. */
i = XFASTINT (Flength (keymap));
@ -563,7 +586,7 @@ single_keymap_panes (keymap, panes, vector, names, enables, items,
}
tem = Fkeymapp (def);
if (XSTRING (item2)->data[0] == '@' && !NILP (tem))
pending_maps = Fcons (Fcons (def, item2),
pending_maps = Fcons (Fcons (def, Fcons (item2, XCONS (item)->car)),
pending_maps);
else
{
@ -609,7 +632,7 @@ single_keymap_panes (keymap, panes, vector, names, enables, items,
tem = Fkeymapp (def);
if (XSTRING (item2)->data[0] == '@' && !NILP (tem))
pending_maps = Fcons (Fcons (def, item2),
pending_maps = Fcons (Fcons (def, Fcons (item2, character)),
pending_maps);
else
{
@ -642,12 +665,15 @@ single_keymap_panes (keymap, panes, vector, names, enables, items,
/* Process now any submenus which want to be panes at this level. */
while (!NILP (pending_maps))
{
Lisp_Object elt;
Lisp_Object elt, eltcdr;
int panenum = *p_ptr;
elt = Fcar (pending_maps);
eltcdr = XCONS (elt)->cdr;
single_keymap_panes (Fcar (elt), panes, vector, names, enables, items,
p_ptr, npanes_allocated_ptr,
prefixes, p_ptr, npanes_allocated_ptr,
/* Add 1 to discard the @. */
(char *) XSTRING (XCONS (elt)->cdr)->data + 1);
(char *) XSTRING (XCONS (eltcdr)->car)->data + 1);
(*prefixes)[panenum] = XCONS (eltcdr)->cdr;
pending_maps = Fcdr (pending_maps);
}
}