aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1994-03-02 04:11:11 +0000
committerRichard M. Stallman1994-03-02 04:11:11 +0000
commitb7c49376aa8ed74ceb9d7409bfba0ab22e83e45e (patch)
tree99ad308d4ea03e591473afbe5aeeb5f5cd44bc24
parent8351baf2f9508981603199ba657f6d720dc2dc44 (diff)
downloademacs-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.c209
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
3479static Lisp_Object menu_bar_item (); 3452static void menu_bar_item ();
3480static Lisp_Object menu_bar_one_keymap (); 3453static 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. */
3458static Lisp_Object menu_bar_items_vector;
3459static 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
3486Lisp_Object 3467Lisp_Object
3487menu_bar_items () 3468menu_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
3574static Lisp_Object 3602static void
3575menu_bar_one_keymap (keymap, result) 3603menu_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
3635static Lisp_Object 3657static void
3636menu_bar_item (key, item_string, def, result) 3658menu_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.