diff options
| author | Stefan Monnier | 2003-05-04 01:27:32 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2003-05-04 01:27:32 +0000 |
| commit | 0695ce9138846ceb06db58f1fc5b3d174074a4f1 (patch) | |
| tree | ff5a731b76f728d4f58927ec9a9dcbf20824277f /src | |
| parent | 09dae035eb8ee4de88a5270a58bfc8ca16f8c60a (diff) | |
| download | emacs-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.c | 102 |
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, | |||
| 136 | static void keymap_panes P_ ((Lisp_Object *, int, int)); | 136 | static void keymap_panes P_ ((Lisp_Object *, int, int)); |
| 137 | static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object, | 137 | static void single_keymap_panes P_ ((Lisp_Object, Lisp_Object, Lisp_Object, |
| 138 | int, int)); | 138 | int, int)); |
| 139 | static void single_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object *, | ||
| 140 | int, int, int *)); | ||
| 141 | static void list_of_panes P_ ((Lisp_Object)); | 139 | static void list_of_panes P_ ((Lisp_Object)); |
| 142 | static void list_of_items P_ ((Lisp_Object)); | 140 | static 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. */ | ||
| 412 | struct skp | ||
| 413 | { | ||
| 414 | Lisp_Object pending_maps; | ||
| 415 | int maxdepth, notreal; | ||
| 416 | int notbuttons; | ||
| 417 | }; | ||
| 418 | |||
| 419 | static 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, ¬buttons); | ||
| 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, ¬buttons); | ||
| 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 | ||
| 500 | static void | 491 | static void |
| 501 | single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth, | 492 | single_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 |