aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1993-03-12 06:25:48 +0000
committerRichard M. Stallman1993-03-12 06:25:48 +0000
commit5ec75a5586168826500d9444dc03dc663de78cc4 (patch)
treec979f6968118312e59e8ec10184c760ffa906f07 /src
parent6d05db8169016668035643f1da1c762d09c3eedf (diff)
downloademacs-5ec75a5586168826500d9444dc03dc663de78cc4.tar.gz
emacs-5ec75a5586168826500d9444dc03dc663de78cc4.zip
(syms_of_keyboard): Set up Qmenu_bar.
(menu_bar_items): New function. (menu_bar_one_keymap, menu_bar_item): New functions. (make_lispy_event): Handle menu bar events. (read_key_sequence): Make dummy prefix `menu-bar' for menu bar events.
Diffstat (limited to 'src')
-rw-r--r--src/keyboard.c227
1 files changed, 206 insertions, 21 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 0f5953632b1..c942e16c265 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -363,10 +363,13 @@ Lisp_Object Qevent_symbol_element_mask;
363 apply_modifiers. */ 363 apply_modifiers. */
364Lisp_Object Qmodifier_cache; 364Lisp_Object Qmodifier_cache;
365 365
366/* Symbols to use for non-text mouse positions. */ 366/* Symbols to use for parts of windows. */
367Lisp_Object Qmode_line; 367Lisp_Object Qmode_line;
368Lisp_Object Qvertical_line; 368Lisp_Object Qvertical_line;
369Lisp_Object Qvertical_scroll_bar; 369Lisp_Object Qvertical_scroll_bar;
370Lisp_Object Qmenu_bar;
371
372extern Lisp_Object Qmenu_enable;
370 373
371Lisp_Object recursive_edit_unwind (), command_loop (); 374Lisp_Object recursive_edit_unwind (), command_loop ();
372Lisp_Object Fthis_command_keys (); 375Lisp_Object Fthis_command_keys ();
@@ -2004,13 +2007,40 @@ make_lispy_event (event)
2004 if (event->kind == mouse_click) 2007 if (event->kind == mouse_click)
2005 { 2008 {
2006 int part; 2009 int part;
2007 Lisp_Object window = 2010 struct frame *f = XFRAME (event->frame_or_window);
2008 window_from_coordinates (XFRAME (event->frame_or_window), 2011 Lisp_Object window
2009 XINT (event->x), XINT (event->y), 2012 = window_from_coordinates (f, XINT (event->x), XINT (event->y),
2010 &part); 2013 &part);
2011 Lisp_Object posn; 2014 Lisp_Object posn;
2012 2015
2013 if (XTYPE (window) != Lisp_Window) 2016 if (XINT (event->y) < FRAME_MENU_BAR_LINES (f))
2017 {
2018 int hpos;
2019 Lisp_Object items;
2020 items = FRAME_MENU_BAR_ITEMS (f);
2021 for (; CONSP (items); items = XCONS (items)->cdr)
2022 {
2023 Lisp_Object pos, string;
2024 pos = Fcdr (Fcdr (Fcar (items)));
2025 string = Fcar (Fcdr (Fcar (items)));
2026 if (XINT (event->x) > XINT (pos)
2027 && XINT (event->x) <= XINT (pos) + XSTRING (string)->size)
2028 break;
2029 }
2030 position
2031 = Fcons (event->frame_or_window,
2032 Fcons (Qmenu_bar,
2033 Fcons (Fcons (event->x, event->y),
2034 Fcons (make_number (event->timestamp),
2035 Qnil))));
2036
2037 if (CONSP (items))
2038 return Fcons (Fcar (Fcar (items)),
2039 Fcons (position, Qnil));
2040 else
2041 return Fcons (Qnil, Fcons (position, Qnil));
2042 }
2043 else if (XTYPE (window) != Lisp_Window)
2014 posn = Qnil; 2044 posn = Qnil;
2015 else 2045 else
2016 { 2046 {
@@ -2030,12 +2060,12 @@ make_lispy_event (event)
2030 XINT (event->y))); 2060 XINT (event->y)));
2031 } 2061 }
2032 2062
2033 position = 2063 position
2034 Fcons (window, 2064 = Fcons (window,
2035 Fcons (posn, 2065 Fcons (posn,
2036 Fcons (Fcons (event->x, event->y), 2066 Fcons (Fcons (event->x, event->y),
2037 Fcons (make_number (event->timestamp), 2067 Fcons (make_number (event->timestamp),
2038 Qnil)))); 2068 Qnil))));
2039 } 2069 }
2040 else 2070 else
2041 { 2071 {
@@ -2097,13 +2127,13 @@ make_lispy_event (event)
2097 2127
2098 { 2128 {
2099 /* Get the symbol we should use for the mouse click. */ 2129 /* Get the symbol we should use for the mouse click. */
2100 Lisp_Object head = 2130 Lisp_Object head
2101 modify_event_symbol (button, 2131 = modify_event_symbol (button,
2102 event->modifiers, 2132 event->modifiers,
2103 Qmouse_click, 2133 Qmouse_click,
2104 lispy_mouse_names, &mouse_syms, 2134 lispy_mouse_names, &mouse_syms,
2105 (sizeof (lispy_mouse_names) 2135 (sizeof (lispy_mouse_names)
2106 / sizeof (lispy_mouse_names[0]))); 2136 / sizeof (lispy_mouse_names[0])));
2107 2137
2108 if (event->modifiers & drag_modifier) 2138 if (event->modifiers & drag_modifier)
2109 return Fcons (head, 2139 return Fcons (head,
@@ -2186,7 +2216,6 @@ make_lispy_movement (frame, bar_window, part, x, y, time)
2186 } 2216 }
2187} 2217}
2188 2218
2189
2190/* Construct a switch frame event. */ 2219/* Construct a switch frame event. */
2191static Lisp_Object 2220static Lisp_Object
2192make_lispy_switch_frame (frame) 2221make_lispy_switch_frame (frame)
@@ -2194,7 +2223,6 @@ make_lispy_switch_frame (frame)
2194{ 2223{
2195 return Fcons (Qswitch_frame, Fcons (frame, Qnil)); 2224 return Fcons (Qswitch_frame, Fcons (frame, Qnil));
2196} 2225}
2197
2198 2226
2199/* Manipulating modifiers. */ 2227/* Manipulating modifiers. */
2200 2228
@@ -2792,6 +2820,145 @@ map_prompt (map)
2792 return Qnil; 2820 return Qnil;
2793} 2821}
2794 2822
2823static Lisp_Object menu_bar_item ();
2824static Lisp_Object menu_bar_one_keymap ();
2825
2826/* Return a list of menu items for a menu bar, appropriate
2827 to the current buffer.
2828 The elements have the form (KEY STRING . nil). */
2829
2830Lisp_Object
2831menu_bar_items ()
2832{
2833 /* The number of keymaps we're scanning right now, and the number of
2834 keymaps we have allocated space for. */
2835 int nmaps;
2836
2837 /* maps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1]
2838 in the current keymaps, or nil where it is not a prefix. */
2839 Lisp_Object *maps;
2840
2841 Lisp_Object def, tem;
2842
2843 Lisp_Object result;
2844
2845 int mapno;
2846
2847 /* Build our list of keymaps.
2848 If we recognize a function key and replace its escape sequence in
2849 keybuf with its symbol, or if the sequence starts with a mouse
2850 click and we need to switch buffers, we jump back here to rebuild
2851 the initial keymaps from the current buffer. */
2852 {
2853 Lisp_Object *tmaps;
2854
2855 nmaps = current_minor_maps (0, &tmaps) + 2;
2856 maps = (Lisp_Object *) alloca (nmaps * sizeof (maps[0]));
2857 bcopy (tmaps, maps, (nmaps - 2) * sizeof (maps[0]));
2858#ifdef USE_TEXT_PROPERTIES
2859 maps[nmaps-2] = get_local_map (PT, current_buffer);
2860#else
2861 maps[nmaps-2] = current_buffer->local_map;
2862#endif
2863 maps[nmaps-1] = global_map;
2864 }
2865
2866 /* Look up in each map the dummy prefix key `menu-bar'. */
2867
2868 result = Qnil;
2869
2870 for (mapno = 0; mapno < nmaps; mapno++)
2871 {
2872 if (! NILP (maps[mapno]))
2873 def = get_keyelt (access_keymap (maps[mapno], Qmenu_bar, 1));
2874 else
2875 def = Qnil;
2876
2877 tem = Fkeymapp (def);
2878 if (!NILP (tem))
2879 result = menu_bar_one_keymap (def, result);
2880 }
2881
2882 return result;
2883}
2884
2885/* Scan one map KEYMAP, accumulating any menu items it defines
2886 that have not yet been seen in RESULT. Return the updated RESULT. */
2887
2888static Lisp_Object
2889menu_bar_one_keymap (keymap, result)
2890 Lisp_Object keymap, result;
2891{
2892 Lisp_Object tail, item, key, binding, item_string, table;
2893
2894 /* Loop over all keymap entries that have menu strings. */
2895 for (tail = keymap; XTYPE (tail) == Lisp_Cons; tail = XCONS (tail)->cdr)
2896 {
2897 item = XCONS (tail)->car;
2898 if (XTYPE (item) == Lisp_Cons)
2899 {
2900 key = XCONS (item)->car;
2901 binding = XCONS (item)->cdr;
2902 if (XTYPE (binding) == Lisp_Cons)
2903 {
2904 item_string = XCONS (binding)->car;
2905 if (XTYPE (item_string) == Lisp_String)
2906 result = menu_bar_item (key, item_string,
2907 Fcdr (binding), result);
2908 }
2909 }
2910 else if (XTYPE (item) == Lisp_Vector)
2911 {
2912 /* Loop over the char values represented in the vector. */
2913 int len = XVECTOR (item)->size;
2914 int c;
2915 for (c = 0; c < len; c++)
2916 {
2917 Lisp_Object character;
2918 XFASTINT (character) = c;
2919 binding = XVECTOR (item)->contents[c];
2920 if (XTYPE (binding) == Lisp_Cons)
2921 {
2922 item_string = XCONS (binding)->car;
2923 if (XTYPE (item_string) == Lisp_String)
2924 result = menu_bar_item (key, item_string,
2925 Fcdr (binding), result);
2926 }
2927 }
2928 }
2929 }
2930
2931 return result;
2932}
2933
2934static Lisp_Object
2935menu_bar_item (key, item_string, def, result)
2936 Lisp_Object key, item_string, def, result;
2937{
2938 Lisp_Object tem, elt;
2939 Lisp_Object enabled;
2940
2941 /* See if this entry is enabled. */
2942 enabled = Qt;
2943
2944 if (XTYPE (def) == Lisp_Symbol)
2945 {
2946 /* No property, or nil, means enable.
2947 Otherwise, enable if value is not nil. */
2948 tem = Fget (def, Qmenu_enable);
2949 if (!NILP (tem))
2950 enabled = Feval (tem);
2951 }
2952
2953 /* Add an entry for this key and string
2954 if there is none yet. */
2955 elt = Fassq (key, result);
2956 if (!NILP (enabled) && NILP (elt))
2957 result = Fcons (Fcons (key, Fcons (item_string, Qnil)), result);
2958
2959 return result;
2960}
2961
2795static int echo_flag; 2962static int echo_flag;
2796static int echo_now; 2963static int echo_now;
2797 2964
@@ -3391,6 +3558,22 @@ read_key_sequence (keybuf, bufsize, prompt)
3391 goto replay_key; 3558 goto replay_key;
3392 } 3559 }
3393 } 3560 }
3561 else
3562 {
3563 Lisp_Object posn = POSN_BUFFER_POSN (EVENT_START (key));
3564
3565 /* Handle menu-bar events:
3566 insert the dummy prefix char `menu-bar'. */
3567 if (EQ (posn, Qmenu_bar))
3568 {
3569 if (t + 1 >= bufsize)
3570 error ("key sequence too long");
3571 keybuf[t] = posn;
3572 keybuf[t+1] = key;
3573 mock_input = t + 2;
3574 goto replay_sequence;
3575 }
3576 }
3394 } 3577 }
3395 } 3578 }
3396 3579
@@ -4287,6 +4470,8 @@ syms_of_keyboard ()
4287 staticpro (&Qvertical_line); 4470 staticpro (&Qvertical_line);
4288 Qvertical_scroll_bar = intern ("vertical-scroll-bar"); 4471 Qvertical_scroll_bar = intern ("vertical-scroll-bar");
4289 staticpro (&Qvertical_scroll_bar); 4472 staticpro (&Qvertical_scroll_bar);
4473 Qmenu_bar = intern ("menu-bar");
4474 staticpro (&Qmenu_bar);
4290 4475
4291 Qabove_handle = intern ("above-handle"); 4476 Qabove_handle = intern ("above-handle");
4292 staticpro (&Qabove_handle); 4477 staticpro (&Qabove_handle);