diff options
| author | Richard M. Stallman | 1994-03-02 04:11:11 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-03-02 04:11:11 +0000 |
| commit | b7c49376aa8ed74ceb9d7409bfba0ab22e83e45e (patch) | |
| tree | 99ad308d4ea03e591473afbe5aeeb5f5cd44bc24 | |
| parent | 8351baf2f9508981603199ba657f6d720dc2dc44 (diff) | |
| download | emacs-b7c49376aa8ed74ceb9d7409bfba0ab22e83e45e.tar.gz emacs-b7c49376aa8ed74ceb9d7409bfba0ab22e83e45e.zip | |
(menu_bar_items): Accept old vector as arg. Return a vector.
(menu_bar_one_keymap, menu_bar_item): Associated changes.
(make_lispy_event): Use FRAME_MENU_BAR_LINES as vector.
| -rw-r--r-- | src/keyboard.c | 209 |
1 files changed, 131 insertions, 78 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index 6d190e213d1..fc9ce849e00 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -985,35 +985,6 @@ command_loop_1 () | |||
| 985 | && !NILP (Ffboundp (Qrecompute_lucid_menubar))) | 985 | && !NILP (Ffboundp (Qrecompute_lucid_menubar))) |
| 986 | call0 (Qrecompute_lucid_menubar); | 986 | call0 (Qrecompute_lucid_menubar); |
| 987 | 987 | ||
| 988 | #if 0 /* This is done in xdisp.c now. */ | ||
| 989 | #ifdef MULTI_FRAME | ||
| 990 | for (tem = Vframe_list; CONSP (tem); tem = XCONS (tem)->cdr) | ||
| 991 | { | ||
| 992 | struct frame *f = XFRAME (XCONS (tem)->car); | ||
| 993 | struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f)); | ||
| 994 | |||
| 995 | /* If the user has switched buffers or windows, we need to | ||
| 996 | recompute to reflect the new bindings. But we'll | ||
| 997 | recompute when update_mode_lines is set too; that means | ||
| 998 | that people can use force-mode-line-update to request | ||
| 999 | that the menu bar be recomputed. The adverse effect on | ||
| 1000 | the rest of the redisplay algorithm is about the same as | ||
| 1001 | windows_or_buffers_changed anyway. */ | ||
| 1002 | if (windows_or_buffers_changed | ||
| 1003 | || update_mode_lines | ||
| 1004 | || (XFASTINT (w->last_modified) < MODIFF | ||
| 1005 | && (XFASTINT (w->last_modified) | ||
| 1006 | <= XBUFFER (w->buffer)->save_modified))) | ||
| 1007 | { | ||
| 1008 | struct buffer *prev = current_buffer; | ||
| 1009 | current_buffer = XBUFFER (w->buffer); | ||
| 1010 | FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (); | ||
| 1011 | current_buffer = prev; | ||
| 1012 | } | ||
| 1013 | } | ||
| 1014 | #endif /* MULTI_FRAME */ | ||
| 1015 | #endif /* 0 */ | ||
| 1016 | |||
| 1017 | /* Read next key sequence; i gets its length. */ | 988 | /* Read next key sequence; i gets its length. */ |
| 1018 | i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])), Qnil); | 989 | i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])), Qnil); |
| 1019 | 990 | ||
| @@ -2509,26 +2480,32 @@ make_lispy_event (event) | |||
| 2509 | if (row < FRAME_MENU_BAR_LINES (f)) | 2480 | if (row < FRAME_MENU_BAR_LINES (f)) |
| 2510 | #endif | 2481 | #endif |
| 2511 | { | 2482 | { |
| 2512 | Lisp_Object items; | 2483 | Lisp_Object items, item; |
| 2513 | 2484 | ||
| 2514 | #ifdef USE_X_TOOLKIT | 2485 | #ifdef USE_X_TOOLKIT |
| 2515 | /* The click happened in the menubar. | 2486 | /* The click happened in the menubar. |
| 2516 | Look for the menu item selected. */ | 2487 | Look for the menu item selected. */ |
| 2517 | items = map_event_to_object (event, f); | 2488 | item = map_event_to_object (event, f); |
| 2518 | 2489 | ||
| 2519 | XFASTINT (event->y) = 1; | 2490 | XFASTINT (event->y) = 1; |
| 2520 | #else /* not USE_X_TOOLKIT */ | 2491 | #else /* not USE_X_TOOLKIT */ |
| 2521 | int hpos; | 2492 | int hpos; |
| 2493 | int i; | ||
| 2522 | 2494 | ||
| 2523 | items = FRAME_MENU_BAR_ITEMS (f); | 2495 | items = FRAME_MENU_BAR_ITEMS (f); |
| 2524 | for (; CONSP (items); items = XCONS (items)->cdr) | 2496 | for (i = 0; i < XVECTOR (items)->size; i += 3) |
| 2525 | { | 2497 | { |
| 2526 | Lisp_Object pos, string; | 2498 | Lisp_Object pos, string; |
| 2527 | pos = Fcdr (Fcdr (Fcar (items))); | 2499 | string = XVECTOR (items)->contents[i + 1]; |
| 2528 | string = Fcar (Fcdr (Fcar (items))); | 2500 | pos = XVECTOR (items)->contents[i + 2]; |
| 2501 | if (NILP (string)) | ||
| 2502 | break; | ||
| 2529 | if (column >= XINT (pos) | 2503 | if (column >= XINT (pos) |
| 2530 | && column < XINT (pos) + XSTRING (string)->size) | 2504 | && column < XINT (pos) + XSTRING (string)->size) |
| 2531 | break; | 2505 | { |
| 2506 | item = XVECTOR (items)->contents[i]; | ||
| 2507 | break; | ||
| 2508 | } | ||
| 2532 | } | 2509 | } |
| 2533 | #endif /* not USE_X_TOOLKIT */ | 2510 | #endif /* not USE_X_TOOLKIT */ |
| 2534 | 2511 | ||
| @@ -2539,11 +2516,7 @@ make_lispy_event (event) | |||
| 2539 | Fcons (make_number (event->timestamp), | 2516 | Fcons (make_number (event->timestamp), |
| 2540 | Qnil)))); | 2517 | Qnil)))); |
| 2541 | 2518 | ||
| 2542 | if (CONSP (items)) | 2519 | return Fcons (item, Fcons (position, Qnil)); |
| 2543 | return Fcons (Fcar (Fcar (items)), | ||
| 2544 | Fcons (position, Qnil)); | ||
| 2545 | else | ||
| 2546 | return Fcons (Qnil, Fcons (position, Qnil)); | ||
| 2547 | } | 2520 | } |
| 2548 | 2521 | ||
| 2549 | window = window_from_coordinates (f, column, row, &part); | 2522 | window = window_from_coordinates (f, column, row, &part); |
| @@ -3476,15 +3449,24 @@ map_prompt (map) | |||
| 3476 | return Qnil; | 3449 | return Qnil; |
| 3477 | } | 3450 | } |
| 3478 | 3451 | ||
| 3479 | static Lisp_Object menu_bar_item (); | 3452 | static void menu_bar_item (); |
| 3480 | static Lisp_Object menu_bar_one_keymap (); | 3453 | static void menu_bar_one_keymap (); |
| 3454 | |||
| 3455 | /* These variables hold the vector under construction within | ||
| 3456 | menu_bar_items and its subroutines, and the current index | ||
| 3457 | for storing into that vector. */ | ||
| 3458 | static Lisp_Object menu_bar_items_vector; | ||
| 3459 | static Lisp_Object menu_bar_items_index; | ||
| 3481 | 3460 | ||
| 3482 | /* Return a list of menu items for a menu bar, appropriate | 3461 | /* Return a vector of menu items for a menu bar, appropriate |
| 3483 | to the current buffer. | 3462 | to the current buffer. Each item has three elements in the vector: |
| 3484 | The elements have the form (KEY STRING . nil). */ | 3463 | KEY STRING nil. |
| 3464 | |||
| 3465 | OLD is an old vector we can optionally reuse, or nil. */ | ||
| 3485 | 3466 | ||
| 3486 | Lisp_Object | 3467 | Lisp_Object |
| 3487 | menu_bar_items () | 3468 | menu_bar_items (old) |
| 3469 | Lisp_Object old; | ||
| 3488 | { | 3470 | { |
| 3489 | /* The number of keymaps we're scanning right now, and the number of | 3471 | /* The number of keymaps we're scanning right now, and the number of |
| 3490 | keymaps we have allocated space for. */ | 3472 | keymaps we have allocated space for. */ |
| @@ -3501,6 +3483,10 @@ menu_bar_items () | |||
| 3501 | int mapno; | 3483 | int mapno; |
| 3502 | Lisp_Object oquit; | 3484 | Lisp_Object oquit; |
| 3503 | 3485 | ||
| 3486 | int i; | ||
| 3487 | |||
| 3488 | struct gcpro gcpro1; | ||
| 3489 | |||
| 3504 | /* In order to build the menus, we need to call the keymap | 3490 | /* In order to build the menus, we need to call the keymap |
| 3505 | accessors. They all call QUIT. But this function is called | 3491 | accessors. They all call QUIT. But this function is called |
| 3506 | during redisplay, during which a quit is fatal. So inhibit | 3492 | during redisplay, during which a quit is fatal. So inhibit |
| @@ -3510,6 +3496,14 @@ menu_bar_items () | |||
| 3510 | oquit = Vinhibit_quit; | 3496 | oquit = Vinhibit_quit; |
| 3511 | Vinhibit_quit = Qt; | 3497 | Vinhibit_quit = Qt; |
| 3512 | 3498 | ||
| 3499 | if (!NILP (old)) | ||
| 3500 | menu_bar_items_vector = old; | ||
| 3501 | else | ||
| 3502 | menu_bar_items_vector = Fmake_vector (make_number (24), Qnil); | ||
| 3503 | menu_bar_items_index = 0; | ||
| 3504 | |||
| 3505 | GCPRO1 (menu_bar_items_vector); | ||
| 3506 | |||
| 3513 | /* Build our list of keymaps. | 3507 | /* Build our list of keymaps. |
| 3514 | If we recognize a function key and replace its escape sequence in | 3508 | If we recognize a function key and replace its escape sequence in |
| 3515 | keybuf with its symbol, or if the sequence starts with a mouse | 3509 | keybuf with its symbol, or if the sequence starts with a mouse |
| @@ -3551,29 +3545,63 @@ menu_bar_items () | |||
| 3551 | 3545 | ||
| 3552 | tem = Fkeymapp (def); | 3546 | tem = Fkeymapp (def); |
| 3553 | if (!NILP (tem)) | 3547 | if (!NILP (tem)) |
| 3554 | result = menu_bar_one_keymap (def, result); | 3548 | menu_bar_one_keymap (def); |
| 3555 | } | 3549 | } |
| 3556 | 3550 | ||
| 3551 | /* Move to the end those items that should be at the end. */ | ||
| 3552 | |||
| 3557 | for (tail = Vmenu_bar_final_items; CONSP (tail); tail = XCONS (tail)->cdr) | 3553 | for (tail = Vmenu_bar_final_items; CONSP (tail); tail = XCONS (tail)->cdr) |
| 3558 | { | 3554 | { |
| 3559 | Lisp_Object elt; | 3555 | int i; |
| 3556 | int end = menu_bar_items_index; | ||
| 3557 | |||
| 3558 | for (i = 0; i < end; i += 3) | ||
| 3559 | if (EQ (XCONS (tail)->car, XVECTOR (menu_bar_items_vector)->contents[i])) | ||
| 3560 | { | ||
| 3561 | Lisp_Object tem; | ||
| 3562 | end -= 3; | ||
| 3563 | #define EXCH(a, b) tem = a, a = b, b = tem | ||
| 3564 | EXCH (XVECTOR (menu_bar_items_vector)->contents[i], | ||
| 3565 | XVECTOR (menu_bar_items_vector)->contents[end]); | ||
| 3566 | EXCH (XVECTOR (menu_bar_items_vector)->contents[i + 1], | ||
| 3567 | XVECTOR (menu_bar_items_vector)->contents[end + 1]); | ||
| 3568 | EXCH (XVECTOR (menu_bar_items_vector)->contents[i + 2], | ||
| 3569 | XVECTOR (menu_bar_items_vector)->contents[end + 2]); | ||
| 3570 | #undef EXCH | ||
| 3571 | i -= 3; | ||
| 3572 | } | ||
| 3573 | } | ||
| 3560 | 3574 | ||
| 3561 | elt = Fassq (XCONS (tail)->car, result); | 3575 | /* Add nil, nil, nil at the end. */ |
| 3562 | if (!NILP (elt)) | 3576 | i = menu_bar_items_index; |
| 3563 | result = Fcons (elt, Fdelq (elt, result)); | 3577 | if (i + 3 > XVECTOR (menu_bar_items_vector)->size) |
| 3578 | { | ||
| 3579 | Lisp_Object tem; | ||
| 3580 | int newsize = 2 * i; | ||
| 3581 | tem = Fmake_vector (make_number (2 * i), Qnil); | ||
| 3582 | bcopy (XVECTOR (menu_bar_items_vector)->contents, | ||
| 3583 | XVECTOR (tem)->contents, i * sizeof (Lisp_Object)); | ||
| 3584 | menu_bar_items_vector = tem; | ||
| 3564 | } | 3585 | } |
| 3586 | /* Add this item. */ | ||
| 3587 | XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil; | ||
| 3588 | XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil; | ||
| 3589 | XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil; | ||
| 3590 | menu_bar_items_index = i; | ||
| 3565 | 3591 | ||
| 3566 | result = Fnreverse (result); | ||
| 3567 | Vinhibit_quit = oquit; | 3592 | Vinhibit_quit = oquit; |
| 3568 | return result; | 3593 | UNGCPRO; |
| 3594 | return menu_bar_items_vector; | ||
| 3569 | } | 3595 | } |
| 3570 | 3596 | ||
| 3571 | /* Scan one map KEYMAP, accumulating any menu items it defines | 3597 | /* Scan one map KEYMAP, accumulating any menu items it defines |
| 3572 | that have not yet been seen in RESULT. Return the updated RESULT. */ | 3598 | that have not yet been seen in RESULT. Return the updated RESULT. |
| 3599 | *OLD is the frame's old menu bar list; we swipe elts from that | ||
| 3600 | to avoid consing. */ | ||
| 3573 | 3601 | ||
| 3574 | static Lisp_Object | 3602 | static void |
| 3575 | menu_bar_one_keymap (keymap, result) | 3603 | menu_bar_one_keymap (keymap) |
| 3576 | Lisp_Object keymap, result; | 3604 | Lisp_Object keymap; |
| 3577 | { | 3605 | { |
| 3578 | Lisp_Object tail, item, key, binding, item_string, table; | 3606 | Lisp_Object tail, item, key, binding, item_string, table; |
| 3579 | 3607 | ||
| @@ -3589,12 +3617,10 @@ menu_bar_one_keymap (keymap, result) | |||
| 3589 | { | 3617 | { |
| 3590 | item_string = XCONS (binding)->car; | 3618 | item_string = XCONS (binding)->car; |
| 3591 | if (XTYPE (item_string) == Lisp_String) | 3619 | if (XTYPE (item_string) == Lisp_String) |
| 3592 | result = menu_bar_item (key, item_string, | 3620 | menu_bar_item (key, item_string, Fcdr (binding)); |
| 3593 | Fcdr (binding), result); | ||
| 3594 | } | 3621 | } |
| 3595 | else if (EQ (binding, Qundefined)) | 3622 | else if (EQ (binding, Qundefined)) |
| 3596 | result = menu_bar_item (key, item_string, | 3623 | menu_bar_item (key, item_string, binding); |
| 3597 | binding, result); | ||
| 3598 | } | 3624 | } |
| 3599 | else if (XTYPE (item) == Lisp_Vector) | 3625 | else if (XTYPE (item) == Lisp_Vector) |
| 3600 | { | 3626 | { |
| @@ -3610,17 +3636,13 @@ menu_bar_one_keymap (keymap, result) | |||
| 3610 | { | 3636 | { |
| 3611 | item_string = XCONS (binding)->car; | 3637 | item_string = XCONS (binding)->car; |
| 3612 | if (XTYPE (item_string) == Lisp_String) | 3638 | if (XTYPE (item_string) == Lisp_String) |
| 3613 | result = menu_bar_item (key, item_string, | 3639 | menu_bar_item (key, item_string, Fcdr (binding)); |
| 3614 | Fcdr (binding), result); | ||
| 3615 | } | 3640 | } |
| 3616 | else if (EQ (binding, Qundefined)) | 3641 | else if (EQ (binding, Qundefined)) |
| 3617 | result = menu_bar_item (key, item_string, | 3642 | menu_bar_item (key, item_string, binding); |
| 3618 | binding, result); | ||
| 3619 | } | 3643 | } |
| 3620 | } | 3644 | } |
| 3621 | } | 3645 | } |
| 3622 | |||
| 3623 | return result; | ||
| 3624 | } | 3646 | } |
| 3625 | 3647 | ||
| 3626 | /* This is used as the handler when calling internal_condition_case_1. */ | 3648 | /* This is used as the handler when calling internal_condition_case_1. */ |
| @@ -3632,19 +3654,29 @@ menu_bar_item_1 (arg) | |||
| 3632 | return Qnil; | 3654 | return Qnil; |
| 3633 | } | 3655 | } |
| 3634 | 3656 | ||
| 3635 | static Lisp_Object | 3657 | static void |
| 3636 | menu_bar_item (key, item_string, def, result) | 3658 | menu_bar_item (key, item_string, def) |
| 3637 | Lisp_Object key, item_string, def, result; | 3659 | Lisp_Object key, item_string, def; |
| 3638 | { | 3660 | { |
| 3639 | Lisp_Object tem; | 3661 | Lisp_Object tem; |
| 3640 | Lisp_Object enabled; | 3662 | Lisp_Object enabled; |
| 3663 | int i; | ||
| 3641 | 3664 | ||
| 3642 | if (EQ (def, Qundefined)) | 3665 | if (EQ (def, Qundefined)) |
| 3643 | { | 3666 | { |
| 3644 | /* If a map has an explicit nil as definition, | 3667 | /* If a map has an explicit nil as definition, |
| 3645 | discard any previously made menu bar item. */ | 3668 | discard any previously made menu bar item. */ |
| 3646 | tem = Fassq (key, result); | 3669 | |
| 3647 | return Fdelq (tem, result); | 3670 | for (i = 0; i < menu_bar_items_index; i += 3) |
| 3671 | if (EQ (key, XVECTOR (menu_bar_items_vector)->contents[i])) | ||
| 3672 | { | ||
| 3673 | if (menu_bar_items_index > i + 3) | ||
| 3674 | bcopy (&XVECTOR (menu_bar_items_vector)->contents[i + 3], | ||
| 3675 | &XVECTOR (menu_bar_items_vector)->contents[i], | ||
| 3676 | (menu_bar_items_index - i - 3) * sizeof (Lisp_Object)); | ||
| 3677 | menu_bar_items_index -= 3; | ||
| 3678 | return; | ||
| 3679 | } | ||
| 3648 | } | 3680 | } |
| 3649 | 3681 | ||
| 3650 | /* See if this entry is enabled. */ | 3682 | /* See if this entry is enabled. */ |
| @@ -3662,13 +3694,34 @@ menu_bar_item (key, item_string, def, result) | |||
| 3662 | menu_bar_item_1); | 3694 | menu_bar_item_1); |
| 3663 | } | 3695 | } |
| 3664 | 3696 | ||
| 3665 | /* Add an entry for this key and string | 3697 | /* Ignore this item if it's not enabled. */ |
| 3666 | if there is none yet. */ | 3698 | if (NILP (enabled)) |
| 3667 | tem = Fassq (key, result); | 3699 | return; |
| 3668 | if (!NILP (enabled) && NILP (tem)) | ||
| 3669 | result = Fcons (Fcons (key, Fcons (item_string, Qnil)), result); | ||
| 3670 | 3700 | ||
| 3671 | return result; | 3701 | /* If there's already such an item, don't make another. */ |
| 3702 | for (i = 0; i < menu_bar_items_index; i += 3) | ||
| 3703 | if (EQ (key, XVECTOR (menu_bar_items_vector)->contents[i])) | ||
| 3704 | break; | ||
| 3705 | |||
| 3706 | /* If we did not find this item, add it at the end. */ | ||
| 3707 | if (i == menu_bar_items_index) | ||
| 3708 | { | ||
| 3709 | /* If vector is too small, get a bigger one. */ | ||
| 3710 | if (i + 3 > XVECTOR (menu_bar_items_vector)->size) | ||
| 3711 | { | ||
| 3712 | Lisp_Object tem; | ||
| 3713 | int newsize = 2 * i; | ||
| 3714 | tem = Fmake_vector (make_number (2 * i), Qnil); | ||
| 3715 | bcopy (XVECTOR (menu_bar_items_vector)->contents, | ||
| 3716 | XVECTOR (tem)->contents, i * sizeof (Lisp_Object)); | ||
| 3717 | menu_bar_items_vector = tem; | ||
| 3718 | } | ||
| 3719 | /* Add this item. */ | ||
| 3720 | XVECTOR (menu_bar_items_vector)->contents[i++] = key; | ||
| 3721 | XVECTOR (menu_bar_items_vector)->contents[i++] = item_string; | ||
| 3722 | XVECTOR (menu_bar_items_vector)->contents[i++] = Qnil; | ||
| 3723 | menu_bar_items_index = i; | ||
| 3724 | } | ||
| 3672 | } | 3725 | } |
| 3673 | 3726 | ||
| 3674 | /* Read a character using menus based on maps in the array MAPS. | 3727 | /* Read a character using menus based on maps in the array MAPS. |