diff options
| author | Richard M. Stallman | 1993-05-12 05:17:47 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1993-05-12 05:17:47 +0000 |
| commit | 819012f0555783d74d7f7fcf381a993ceac457e8 (patch) | |
| tree | 5c7de2ee4460c9c3b15a1e036d8124644508f7ca /src | |
| parent | 9d330ad06a4d1e48bcd2ab65ad0f92651a4e2adf (diff) | |
| download | emacs-819012f0555783d74d7f7fcf381a993ceac457e8.tar.gz emacs-819012f0555783d74d7f7fcf381a993ceac457e8.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xmenu.c | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/src/xmenu.c b/src/xmenu.c index bcd67ae5446..6e154b07986 100644 --- a/src/xmenu.c +++ b/src/xmenu.c | |||
| @@ -100,13 +100,16 @@ a definition; actually, the \"definition\" in such a key binding looks like\n\ | |||
| 100 | \(STRING . REAL-DEFINITION). To give the menu a title, put a string into\n\ | 100 | \(STRING . REAL-DEFINITION). To give the menu a title, put a string into\n\ |
| 101 | the keymap as a top-level element.\n\n\ | 101 | the keymap as a top-level element.\n\n\ |
| 102 | You can also use a list of keymaps as MENU.\n\ | 102 | You can also use a list of keymaps as MENU.\n\ |
| 103 | Then each keymap makes a separate pane.\n\n\ | 103 | Then each keymap makes a separate pane.\n\ |
| 104 | When MENU is a keymap or a list of keymaps, the return value\n\ | ||
| 105 | is a list of events.\n\n\ | ||
| 104 | Alternatively, you can specify a menu of multiple panes\n\ | 106 | Alternatively, you can specify a menu of multiple panes\n\ |
| 105 | with a list of the form (TITLE PANE1 PANE2...),\n\ | 107 | with a list of the form (TITLE PANE1 PANE2...),\n\ |
| 106 | where each pane is a list of form (TITLE ITEM1 ITEM2...).\n\ | 108 | where each pane is a list of form (TITLE ITEM1 ITEM2...).\n\ |
| 107 | Each ITEM is normally a cons cell (STRING . VALUE);\n\ | 109 | Each ITEM is normally a cons cell (STRING . VALUE);\n\ |
| 108 | but a string can appear as an item--that makes a nonselectable line\n\ | 110 | but a string can appear as an item--that makes a nonselectable line\n\ |
| 109 | in the menu.") | 111 | in the menu.\n\ |
| 112 | With this form of menu, the return value is VALUE from the chosen item.") | ||
| 110 | (position, menu) | 113 | (position, menu) |
| 111 | Lisp_Object position, menu; | 114 | Lisp_Object position, menu; |
| 112 | { | 115 | { |
| @@ -117,6 +120,7 @@ in the menu.") | |||
| 117 | char ***names; | 120 | char ***names; |
| 118 | int **enables; | 121 | int **enables; |
| 119 | Lisp_Object **obj_list; | 122 | Lisp_Object **obj_list; |
| 123 | Lisp_Object *prefixes; | ||
| 120 | int *items; | 124 | int *items; |
| 121 | char *title; | 125 | char *title; |
| 122 | char *error_name; | 126 | char *error_name; |
| @@ -213,7 +217,7 @@ in the menu.") | |||
| 213 | 217 | ||
| 214 | /* Extract the detailed info to make one pane. */ | 218 | /* Extract the detailed info to make one pane. */ |
| 215 | number_of_panes = keymap_panes (&obj_list, &menus, &names, &enables, | 219 | number_of_panes = keymap_panes (&obj_list, &menus, &names, &enables, |
| 216 | &items, maps, nmaps); | 220 | &items, &prefixes, maps, nmaps); |
| 217 | /* The menu title seems to be ignored, | 221 | /* The menu title seems to be ignored, |
| 218 | so put it in the pane title. */ | 222 | so put it in the pane title. */ |
| 219 | if (menus[0] == 0) | 223 | if (menus[0] == 0) |
| @@ -225,6 +229,7 @@ in the menu.") | |||
| 225 | ltitle = Fcar (menu); | 229 | ltitle = Fcar (menu); |
| 226 | CHECK_STRING (ltitle, 1); | 230 | CHECK_STRING (ltitle, 1); |
| 227 | title = (char *) XSTRING (ltitle)->data; | 231 | title = (char *) XSTRING (ltitle)->data; |
| 232 | prefixes = 0; | ||
| 228 | number_of_panes = list_of_panes (&obj_list, &menus, &names, &enables, | 233 | number_of_panes = list_of_panes (&obj_list, &menus, &names, &enables, |
| 229 | &items, Fcdr (menu)); | 234 | &items, Fcdr (menu)); |
| 230 | } | 235 | } |
| @@ -261,8 +266,8 @@ in the menu.") | |||
| 261 | abort (); | 266 | abort (); |
| 262 | 267 | ||
| 263 | selection = xmenu_show (root, XMenu_xpos, XMenu_ypos, names, enables, | 268 | selection = xmenu_show (root, XMenu_xpos, XMenu_ypos, names, enables, |
| 264 | menus, items, number_of_panes, obj_list, title, | 269 | menus, prefixes, items, number_of_panes, obj_list, |
| 265 | &error_name); | 270 | title, &error_name); |
| 266 | } | 271 | } |
| 267 | UNBLOCK_INPUT; | 272 | UNBLOCK_INPUT; |
| 268 | /* fprintf (stderr, "selection = %x\n", selection); */ | 273 | /* fprintf (stderr, "selection = %x\n", selection); */ |
| @@ -298,12 +303,13 @@ struct indices { | |||
| 298 | 303 | ||
| 299 | Lisp_Object | 304 | Lisp_Object |
| 300 | xmenu_show (parent, startx, starty, line_list, enable_list, pane_list, | 305 | xmenu_show (parent, startx, starty, line_list, enable_list, pane_list, |
| 301 | line_cnt, pane_cnt, item_list, title, error) | 306 | prefixes, line_cnt, pane_cnt, item_list, title, error) |
| 302 | Window parent; | 307 | Window parent; |
| 303 | int startx, starty; /* upper left corner position BROKEN */ | 308 | int startx, starty; /* upper left corner position BROKEN */ |
| 304 | char **line_list[]; /* list of strings for items */ | 309 | char **line_list[]; /* list of strings for items */ |
| 305 | int *enable_list[]; /* list of strings for items */ | 310 | int *enable_list[]; /* list of strings for items */ |
| 306 | char *pane_list[]; /* list of pane titles */ | 311 | char *pane_list[]; /* list of pane titles */ |
| 312 | Lisp_Object *prefixes; /* Prefix key for each pane */ | ||
| 307 | char *title; | 313 | char *title; |
| 308 | int pane_cnt; /* total number of panes */ | 314 | int pane_cnt; /* total number of panes */ |
| 309 | Lisp_Object *item_list[]; /* All items */ | 315 | Lisp_Object *item_list[]; /* All items */ |
| @@ -405,6 +411,12 @@ xmenu_show (parent, startx, starty, line_list, enable_list, pane_list, | |||
| 405 | fprintf (stderr, "pane= %d line = %d\n", panes, selidx); | 411 | fprintf (stderr, "pane= %d line = %d\n", panes, selidx); |
| 406 | #endif | 412 | #endif |
| 407 | entry = item_list[panes][selidx]; | 413 | entry = item_list[panes][selidx]; |
| 414 | if (prefixes != 0) | ||
| 415 | { | ||
| 416 | entry = Fcons (entry, Qnil); | ||
| 417 | if (!NILP (prefixes[panes])) | ||
| 418 | entry = Fcons (prefixes[panes], entry); | ||
| 419 | } | ||
| 408 | break; | 420 | break; |
| 409 | case XM_FAILURE: | 421 | case XM_FAILURE: |
| 410 | /* free (datap_save); */ | 422 | /* free (datap_save); */ |
| @@ -435,12 +447,13 @@ syms_of_xmenu () | |||
| 435 | KEYMAPS is a vector of keymaps. NMAPS gives the length of KEYMAPS. */ | 447 | KEYMAPS is a vector of keymaps. NMAPS gives the length of KEYMAPS. */ |
| 436 | 448 | ||
| 437 | int | 449 | int |
| 438 | keymap_panes (vector, panes, names, enables, items, keymaps, nmaps) | 450 | keymap_panes (vector, panes, names, enables, items, prefixes, keymaps, nmaps) |
| 439 | Lisp_Object ***vector; /* RETURN all menu objects */ | 451 | Lisp_Object ***vector; /* RETURN all menu objects */ |
| 440 | char ***panes; /* RETURN pane names */ | 452 | char ***panes; /* RETURN pane names */ |
| 441 | char ****names; /* RETURN all line names */ | 453 | char ****names; /* RETURN all line names */ |
| 442 | int ***enables; /* RETURN enable-flags of lines */ | 454 | int ***enables; /* RETURN enable-flags of lines */ |
| 443 | int **items; /* RETURN number of items per pane */ | 455 | int **items; /* RETURN number of items per pane */ |
| 456 | Lisp_Object **prefixes; /* RETURN vector of prefix keys, per pane */ | ||
| 444 | Lisp_Object *keymaps; | 457 | Lisp_Object *keymaps; |
| 445 | int nmaps; | 458 | int nmaps; |
| 446 | { | 459 | { |
| @@ -459,13 +472,14 @@ keymap_panes (vector, panes, names, enables, items, keymaps, nmaps) | |||
| 459 | *items = (int *) xmalloc (npanes_allocated * sizeof (int)); | 472 | *items = (int *) xmalloc (npanes_allocated * sizeof (int)); |
| 460 | *names = (char ***) xmalloc (npanes_allocated * sizeof (char **)); | 473 | *names = (char ***) xmalloc (npanes_allocated * sizeof (char **)); |
| 461 | *enables = (int **) xmalloc (npanes_allocated * sizeof (int *)); | 474 | *enables = (int **) xmalloc (npanes_allocated * sizeof (int *)); |
| 475 | *prefixes = (Lisp_Object *) xmalloc (npanes_allocated * sizeof (Lisp_Object)); | ||
| 462 | 476 | ||
| 463 | /* Loop over the given keymaps, making a pane for each map. | 477 | /* Loop over the given keymaps, making a pane for each map. |
| 464 | But don't make a pane that is empty--ignore that map instead. | 478 | But don't make a pane that is empty--ignore that map instead. |
| 465 | P is the number of panes we have made so far. */ | 479 | P is the number of panes we have made so far. */ |
| 466 | for (mapno = 0; mapno < nmaps; mapno++) | 480 | for (mapno = 0; mapno < nmaps; mapno++) |
| 467 | single_keymap_panes (keymaps[mapno], panes, vector, names, enables, items, | 481 | single_keymap_panes (keymaps[mapno], panes, vector, names, enables, items, |
| 468 | &p, &npanes_allocated, ""); | 482 | prefixes, &p, &npanes_allocated, ""); |
| 469 | 483 | ||
| 470 | /* Return the number of panes. */ | 484 | /* Return the number of panes. */ |
| 471 | return p; | 485 | return p; |
| @@ -476,7 +490,7 @@ keymap_panes (vector, panes, names, enables, items, keymaps, nmaps) | |||
| 476 | The other arguments are passed along | 490 | The other arguments are passed along |
| 477 | or point to local variables of the previous function. */ | 491 | or point to local variables of the previous function. */ |
| 478 | 492 | ||
| 479 | single_keymap_panes (keymap, panes, vector, names, enables, items, | 493 | single_keymap_panes (keymap, panes, vector, names, enables, items, prefixes, |
| 480 | p_ptr, npanes_allocated_ptr, pane_name) | 494 | p_ptr, npanes_allocated_ptr, pane_name) |
| 481 | Lisp_Object keymap; | 495 | Lisp_Object keymap; |
| 482 | Lisp_Object ***vector; /* RETURN all menu objects */ | 496 | Lisp_Object ***vector; /* RETURN all menu objects */ |
| @@ -484,6 +498,7 @@ single_keymap_panes (keymap, panes, vector, names, enables, items, | |||
| 484 | char ****names; /* RETURN all line names */ | 498 | char ****names; /* RETURN all line names */ |
| 485 | int ***enables; /* RETURN enable flags of lines */ | 499 | int ***enables; /* RETURN enable flags of lines */ |
| 486 | int **items; /* RETURN number of items per pane */ | 500 | int **items; /* RETURN number of items per pane */ |
| 501 | Lisp_Object **prefixes; /* RETURN vector of prefix keys, per pane */ | ||
| 487 | int *p_ptr; | 502 | int *p_ptr; |
| 488 | int *npanes_allocated_ptr; | 503 | int *npanes_allocated_ptr; |
| 489 | char *pane_name; | 504 | char *pane_name; |
| @@ -508,6 +523,10 @@ single_keymap_panes (keymap, panes, vector, names, enables, items, | |||
| 508 | *items | 523 | *items |
| 509 | = (int *) xrealloc (*items, | 524 | = (int *) xrealloc (*items, |
| 510 | *npanes_allocated_ptr * sizeof (int)); | 525 | *npanes_allocated_ptr * sizeof (int)); |
| 526 | *prefixes | ||
| 527 | = (Lisp_Object *) xrealloc (*prefixes, | ||
| 528 | (*npanes_allocated_ptr | ||
| 529 | * sizeof (Lisp_Object))); | ||
| 511 | *names | 530 | *names |
| 512 | = (char ***) xrealloc (*names, | 531 | = (char ***) xrealloc (*names, |
| 513 | *npanes_allocated_ptr * sizeof (char **)); | 532 | *npanes_allocated_ptr * sizeof (char **)); |
| @@ -519,6 +538,10 @@ single_keymap_panes (keymap, panes, vector, names, enables, items, | |||
| 519 | /* When a menu comes from keymaps, don't give names to the panes. */ | 538 | /* When a menu comes from keymaps, don't give names to the panes. */ |
| 520 | (*panes)[*p_ptr] = pane_name; | 539 | (*panes)[*p_ptr] = pane_name; |
| 521 | 540 | ||
| 541 | /* Normally put nil as pane's prefix key. | ||
| 542 | Caller will override this if appropriate. */ | ||
| 543 | (*prefixes)[*p_ptr] = Qnil; | ||
| 544 | |||
| 522 | /* Get the length of the list level of the keymap. */ | 545 | /* Get the length of the list level of the keymap. */ |
| 523 | i = XFASTINT (Flength (keymap)); | 546 | i = XFASTINT (Flength (keymap)); |
| 524 | 547 | ||
| @@ -563,7 +586,7 @@ single_keymap_panes (keymap, panes, vector, names, enables, items, | |||
| 563 | } | 586 | } |
| 564 | tem = Fkeymapp (def); | 587 | tem = Fkeymapp (def); |
| 565 | if (XSTRING (item2)->data[0] == '@' && !NILP (tem)) | 588 | if (XSTRING (item2)->data[0] == '@' && !NILP (tem)) |
| 566 | pending_maps = Fcons (Fcons (def, item2), | 589 | pending_maps = Fcons (Fcons (def, Fcons (item2, XCONS (item)->car)), |
| 567 | pending_maps); | 590 | pending_maps); |
| 568 | else | 591 | else |
| 569 | { | 592 | { |
| @@ -609,7 +632,7 @@ single_keymap_panes (keymap, panes, vector, names, enables, items, | |||
| 609 | 632 | ||
| 610 | tem = Fkeymapp (def); | 633 | tem = Fkeymapp (def); |
| 611 | if (XSTRING (item2)->data[0] == '@' && !NILP (tem)) | 634 | if (XSTRING (item2)->data[0] == '@' && !NILP (tem)) |
| 612 | pending_maps = Fcons (Fcons (def, item2), | 635 | pending_maps = Fcons (Fcons (def, Fcons (item2, character)), |
| 613 | pending_maps); | 636 | pending_maps); |
| 614 | else | 637 | else |
| 615 | { | 638 | { |
| @@ -642,12 +665,15 @@ single_keymap_panes (keymap, panes, vector, names, enables, items, | |||
| 642 | /* Process now any submenus which want to be panes at this level. */ | 665 | /* Process now any submenus which want to be panes at this level. */ |
| 643 | while (!NILP (pending_maps)) | 666 | while (!NILP (pending_maps)) |
| 644 | { | 667 | { |
| 645 | Lisp_Object elt; | 668 | Lisp_Object elt, eltcdr; |
| 669 | int panenum = *p_ptr; | ||
| 646 | elt = Fcar (pending_maps); | 670 | elt = Fcar (pending_maps); |
| 671 | eltcdr = XCONS (elt)->cdr; | ||
| 647 | single_keymap_panes (Fcar (elt), panes, vector, names, enables, items, | 672 | single_keymap_panes (Fcar (elt), panes, vector, names, enables, items, |
| 648 | p_ptr, npanes_allocated_ptr, | 673 | prefixes, p_ptr, npanes_allocated_ptr, |
| 649 | /* Add 1 to discard the @. */ | 674 | /* Add 1 to discard the @. */ |
| 650 | (char *) XSTRING (XCONS (elt)->cdr)->data + 1); | 675 | (char *) XSTRING (XCONS (eltcdr)->car)->data + 1); |
| 676 | (*prefixes)[panenum] = XCONS (eltcdr)->cdr; | ||
| 651 | pending_maps = Fcdr (pending_maps); | 677 | pending_maps = Fcdr (pending_maps); |
| 652 | } | 678 | } |
| 653 | } | 679 | } |