diff options
| author | Richard M. Stallman | 1993-03-12 06:25:48 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1993-03-12 06:25:48 +0000 |
| commit | 5ec75a5586168826500d9444dc03dc663de78cc4 (patch) | |
| tree | c979f6968118312e59e8ec10184c760ffa906f07 /src | |
| parent | 6d05db8169016668035643f1da1c762d09c3eedf (diff) | |
| download | emacs-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.c | 227 |
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. */ |
| 364 | Lisp_Object Qmodifier_cache; | 364 | Lisp_Object Qmodifier_cache; |
| 365 | 365 | ||
| 366 | /* Symbols to use for non-text mouse positions. */ | 366 | /* Symbols to use for parts of windows. */ |
| 367 | Lisp_Object Qmode_line; | 367 | Lisp_Object Qmode_line; |
| 368 | Lisp_Object Qvertical_line; | 368 | Lisp_Object Qvertical_line; |
| 369 | Lisp_Object Qvertical_scroll_bar; | 369 | Lisp_Object Qvertical_scroll_bar; |
| 370 | Lisp_Object Qmenu_bar; | ||
| 371 | |||
| 372 | extern Lisp_Object Qmenu_enable; | ||
| 370 | 373 | ||
| 371 | Lisp_Object recursive_edit_unwind (), command_loop (); | 374 | Lisp_Object recursive_edit_unwind (), command_loop (); |
| 372 | Lisp_Object Fthis_command_keys (); | 375 | Lisp_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. */ |
| 2191 | static Lisp_Object | 2220 | static Lisp_Object |
| 2192 | make_lispy_switch_frame (frame) | 2221 | make_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 | ||
| 2823 | static Lisp_Object menu_bar_item (); | ||
| 2824 | static 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 | |||
| 2830 | Lisp_Object | ||
| 2831 | menu_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 | |||
| 2888 | static Lisp_Object | ||
| 2889 | menu_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 | |||
| 2934 | static Lisp_Object | ||
| 2935 | menu_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 | |||
| 2795 | static int echo_flag; | 2962 | static int echo_flag; |
| 2796 | static int echo_now; | 2963 | static 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); |