# HG changeset patch # User Richard M. Stallman # Date 737183867 0 # Node ID f258c79c91628d8de212ffbf0c5f2b62060a3d36 # Parent e4595f258dddd48f925256143e1d83db994e1d87 (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. diff -r e4595f258ddd -r f258c79c9162 src/xmenu.c --- a/src/xmenu.c Tue May 11 23:23:34 1993 +0000 +++ b/src/xmenu.c Wed May 12 05:17:47 1993 +0000 @@ -100,13 +100,16 @@ \(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 @@ char ***names; int **enables; Lisp_Object **obj_list; + Lisp_Object *prefixes; int *items; char *title; char *error_name; @@ -213,7 +217,7 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ *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 @@ 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 @@ 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 @@ *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 @@ /* 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 @@ } 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 @@ 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 @@ /* 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); } }