aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2003-05-04 01:27:32 +0000
committerStefan Monnier2003-05-04 01:27:32 +0000
commit0695ce9138846ceb06db58f1fc5b3d174074a4f1 (patch)
treeff5a731b76f728d4f58927ec9a9dcbf20824277f /src
parent09dae035eb8ee4de88a5270a58bfc8ca16f8c60a (diff)
downloademacs-0695ce9138846ceb06db58f1fc5b3d174074a4f1.tar.gz
emacs-0695ce9138846ceb06db58f1fc5b3d174074a4f1.zip
(struct skp): New struct, to pass args through map_keymap.
(single_keymap_panes): Use it and map_keymap. (single_menu_item): Use skp as well.
Diffstat (limited to 'src')
-rw-r--r--src/xmenu.c102
1 files changed, 45 insertions, 57 deletions
diff --git a/src/xmenu.c b/src/xmenu.c
index 6c289c45316..68aad9c46e8 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -136,8 +136,6 @@ static Lisp_Object xmenu_show P_ ((struct frame *, int, int, int, int,
136static void keymap_panes P_ ((Lisp_Object *, int, int)); 136static void keymap_panes P_ ((Lisp_Object *, int, int));
137static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object, 137static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
138 int, int)); 138 int, int));
139static void single_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object *,
140 int, int, int *));
141static void list_of_panes P_ ((Lisp_Object)); 139static void list_of_panes P_ ((Lisp_Object));
142static void list_of_items P_ ((Lisp_Object)); 140static void list_of_items P_ ((Lisp_Object));
143 141
@@ -410,6 +408,17 @@ keymap_panes (keymaps, nmaps, notreal)
410 finish_menu_items (); 408 finish_menu_items ();
411} 409}
412 410
411/* Args passed between single_keymap_panes and single_menu_item. */
412struct skp
413 {
414 Lisp_Object pending_maps;
415 int maxdepth, notreal;
416 int notbuttons;
417 };
418
419static void single_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
420 struct skp*));
421
413/* This is a recursive subroutine of keymap_panes. 422/* This is a recursive subroutine of keymap_panes.
414 It handles one keymap, KEYMAP. 423 It handles one keymap, KEYMAP.
415 The other arguments are passed along 424 The other arguments are passed along
@@ -427,10 +436,13 @@ single_keymap_panes (keymap, pane_name, prefix, notreal, maxdepth)
427 int notreal; 436 int notreal;
428 int maxdepth; 437 int maxdepth;
429{ 438{
430 Lisp_Object pending_maps = Qnil; 439 struct skp skp;
431 Lisp_Object tail, item; 440 struct gcpro gcpro1;
432 struct gcpro gcpro1, gcpro2; 441
433 int notbuttons = 0; 442 skp.pending_maps = Qnil;
443 skp.maxdepth = maxdepth;
444 skp.notreal = notreal;
445 skp.notbuttons = 0;
434 446
435 if (maxdepth <= 0) 447 if (maxdepth <= 0)
436 return; 448 return;
@@ -442,68 +454,44 @@ single_keymap_panes (keymap, pane_name, prefix, notreal, maxdepth)
442 add a prefix when (if) we see the first button. After that, notbuttons 454 add a prefix when (if) we see the first button. After that, notbuttons
443 is set to 0, to mark that we have seen a button and all non button 455 is set to 0, to mark that we have seen a button and all non button
444 items need a prefix. */ 456 items need a prefix. */
445 notbuttons = menu_items_used; 457 skp.notbuttons = menu_items_used;
446#endif 458#endif
447 459
448 for (tail = keymap; CONSP (tail); tail = XCDR (tail)) 460 GCPRO1 (skp.pending_maps);
449 { 461 map_keymap (keymap, single_menu_item, Qnil, &skp, 1);
450 GCPRO2 (keymap, pending_maps); 462 UNGCPRO;
451 /* Look at each key binding, and if it is a menu item add it
452 to this menu. */
453 item = XCAR (tail);
454 if (CONSP (item))
455 single_menu_item (XCAR (item), XCDR (item),
456 &pending_maps, notreal, maxdepth, &notbuttons);
457 else if (VECTORP (item))
458 {
459 /* Loop over the char values represented in the vector. */
460 int len = XVECTOR (item)->size;
461 int c;
462 for (c = 0; c < len; c++)
463 {
464 Lisp_Object character;
465 XSETFASTINT (character, c);
466 single_menu_item (character, XVECTOR (item)->contents[c],
467 &pending_maps, notreal, maxdepth, &notbuttons);
468 }
469 }
470 UNGCPRO;
471 }
472 463
473 /* Process now any submenus which want to be panes at this level. */ 464 /* Process now any submenus which want to be panes at this level. */
474 while (!NILP (pending_maps)) 465 while (CONSP (skp.pending_maps))
475 { 466 {
476 Lisp_Object elt, eltcdr, string; 467 Lisp_Object elt, eltcdr, string;
477 elt = Fcar (pending_maps); 468 elt = XCAR (skp.pending_maps);
478 eltcdr = XCDR (elt); 469 eltcdr = XCDR (elt);
479 string = XCAR (eltcdr); 470 string = XCAR (eltcdr);
480 /* We no longer discard the @ from the beginning of the string here. 471 /* We no longer discard the @ from the beginning of the string here.
481 Instead, we do this in xmenu_show. */ 472 Instead, we do this in xmenu_show. */
482 single_keymap_panes (Fcar (elt), string, 473 single_keymap_panes (Fcar (elt), string,
483 XCDR (eltcdr), notreal, maxdepth - 1); 474 XCDR (eltcdr), notreal, maxdepth - 1);
484 pending_maps = Fcdr (pending_maps); 475 skp.pending_maps = XCDR (skp.pending_maps);
485 } 476 }
486} 477}
487 478
488/* This is a subroutine of single_keymap_panes that handles one 479/* This is a subroutine of single_keymap_panes that handles one
489 keymap entry. 480 keymap entry.
490 KEY is a key in a keymap and ITEM is its binding. 481 KEY is a key in a keymap and ITEM is its binding.
491 PENDING_MAPS_PTR points to a list of keymaps waiting to be made into 482 SKP->PENDING_MAPS_PTR is a list of keymaps waiting to be made into
492 separate panes. 483 separate panes.
493 If NOTREAL is nonzero, only check for equivalent key bindings, don't 484 If SKP->NOTREAL is nonzero, only check for equivalent key bindings, don't
494 evaluate expressions in menu items and don't make any menu. 485 evaluate expressions in menu items and don't make any menu.
495 If we encounter submenus deeper than MAXDEPTH levels, ignore them. 486 If we encounter submenus deeper than SKP->MAXDEPTH levels, ignore them.
496 NOTBUTTONS_PTR is only used when simulating toggle boxes and radio 487 SKP->NOTBUTTONS is only used when simulating toggle boxes and radio
497 buttons. It points to variable notbuttons in single_keymap_panes, 488 buttons. It keeps track of if we have seen a button in this menu or
498 which keeps track of if we have seen a button in this menu or not. */ 489 not. */
499 490
500static void 491static void
501single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth, 492single_menu_item (key, item, dummy, skp)
502 notbuttons_ptr) 493 Lisp_Object key, item, dummy;
503 Lisp_Object key, item; 494 struct skp *skp;
504 Lisp_Object *pending_maps_ptr;
505 int maxdepth, notreal;
506 int *notbuttons_ptr;
507{ 495{
508 Lisp_Object map, item_string, enabled; 496 Lisp_Object map, item_string, enabled;
509 struct gcpro gcpro1, gcpro2; 497 struct gcpro gcpro1, gcpro2;
@@ -511,19 +499,19 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth,
511 499
512 /* Parse the menu item and leave the result in item_properties. */ 500 /* Parse the menu item and leave the result in item_properties. */
513 GCPRO2 (key, item); 501 GCPRO2 (key, item);
514 res = parse_menu_item (item, notreal, 0); 502 res = parse_menu_item (item, skp->notreal, 0);
515 UNGCPRO; 503 UNGCPRO;
516 if (!res) 504 if (!res)
517 return; /* Not a menu item. */ 505 return; /* Not a menu item. */
518 506
519 map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP]; 507 map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP];
520 508
521 if (notreal) 509 if (skp->notreal)
522 { 510 {
523 /* We don't want to make a menu, just traverse the keymaps to 511 /* We don't want to make a menu, just traverse the keymaps to
524 precompute equivalent key bindings. */ 512 precompute equivalent key bindings. */
525 if (!NILP (map)) 513 if (!NILP (map))
526 single_keymap_panes (map, Qnil, key, 1, maxdepth - 1); 514 single_keymap_panes (map, Qnil, key, 1, skp->maxdepth - 1);
527 return; 515 return;
528 } 516 }
529 517
@@ -534,8 +522,8 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth,
534 { 522 {
535 if (!NILP (enabled)) 523 if (!NILP (enabled))
536 /* An enabled separate pane. Remember this to handle it later. */ 524 /* An enabled separate pane. Remember this to handle it later. */
537 *pending_maps_ptr = Fcons (Fcons (map, Fcons (item_string, key)), 525 skp->pending_maps = Fcons (Fcons (map, Fcons (item_string, key)),
538 *pending_maps_ptr); 526 skp->pending_maps);
539 return; 527 return;
540 } 528 }
541 529
@@ -550,10 +538,10 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth,
550 Lisp_Object selected 538 Lisp_Object selected
551 = XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED]; 539 = XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED];
552 540
553 if (*notbuttons_ptr) 541 if (skp->notbuttons)
554 /* The first button. Line up previous items in this menu. */ 542 /* The first button. Line up previous items in this menu. */
555 { 543 {
556 int index = *notbuttons_ptr; /* Index for first item this menu. */ 544 int index = skp->notbuttons; /* Index for first item this menu. */
557 int submenu = 0; 545 int submenu = 0;
558 Lisp_Object tem; 546 Lisp_Object tem;
559 while (index < menu_items_used) 547 while (index < menu_items_used)
@@ -583,7 +571,7 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth,
583 index += MENU_ITEMS_ITEM_LENGTH; 571 index += MENU_ITEMS_ITEM_LENGTH;
584 } 572 }
585 } 573 }
586 *notbuttons_ptr = 0; 574 skp->notbuttons = 0;
587 } 575 }
588 576
589 /* Calculate prefix, if any, for this item. */ 577 /* Calculate prefix, if any, for this item. */
@@ -593,7 +581,7 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth,
593 prefix = build_string (NILP (selected) ? "( ) " : "(*) "); 581 prefix = build_string (NILP (selected) ? "( ) " : "(*) ");
594 } 582 }
595 /* Not a button. If we have earlier buttons, then we need a prefix. */ 583 /* Not a button. If we have earlier buttons, then we need a prefix. */
596 else if (!*notbuttons_ptr && SREF (item_string, 0) != '\0' 584 else if (!skp->notbuttons && SREF (item_string, 0) != '\0'
597 && SREF (item_string, 0) != '-') 585 && SREF (item_string, 0) != '-')
598 prefix = build_string (" "); 586 prefix = build_string (" ");
599 587
@@ -620,7 +608,7 @@ single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth,
620 if (! (NILP (map) || NILP (enabled))) 608 if (! (NILP (map) || NILP (enabled)))
621 { 609 {
622 push_submenu_start (); 610 push_submenu_start ();
623 single_keymap_panes (map, Qnil, key, 0, maxdepth - 1); 611 single_keymap_panes (map, Qnil, key, 0, skp->maxdepth - 1);
624 push_submenu_end (); 612 push_submenu_end ();
625 } 613 }
626#endif 614#endif