Mercurial > emacs
comparison src/keyboard.c @ 2149:9e21e9f8bb0d
(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.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Fri, 12 Mar 1993 06:25:48 +0000 |
parents | 63d15b0e048e |
children | f74e9c948380 |
comparison
equal
deleted
inserted
replaced
2148:9b8040c3f320 | 2149:9e21e9f8bb0d |
---|---|
361 Qmodifier_cache, which is an alist mapping modifier masks onto | 361 Qmodifier_cache, which is an alist mapping modifier masks onto |
362 modified versions of BASE. If present, this helps speed up | 362 modified versions of BASE. If present, this helps speed up |
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 (); |
373 | 376 |
374 /* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt | 377 /* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt |
2002 | 2005 |
2003 /* Build the position as appropriate for this mouse click. */ | 2006 /* Build the position as appropriate for this mouse click. */ |
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 { |
2017 XSETINT (event->x, | 2047 XSETINT (event->x, |
2018 (XINT (event->x) - XINT (XWINDOW (window)->left))); | 2048 (XINT (event->x) - XINT (XWINDOW (window)->left))); |
2028 buffer_posn_from_coords (XWINDOW (window), | 2058 buffer_posn_from_coords (XWINDOW (window), |
2029 XINT (event->x), | 2059 XINT (event->x), |
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 { |
2042 Lisp_Object window = event->frame_or_window; | 2072 Lisp_Object window = event->frame_or_window; |
2043 Lisp_Object portion_whole = Fcons (event->x, event->y); | 2073 Lisp_Object portion_whole = Fcons (event->x, event->y); |
2095 the up_modifier set. */ | 2125 the up_modifier set. */ |
2096 abort (); | 2126 abort (); |
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, |
2110 Fcons (start_pos, | 2140 Fcons (start_pos, |
2111 Fcons (position, | 2141 Fcons (position, |
2184 Qnil)))), | 2214 Qnil)))), |
2185 Qnil)); | 2215 Qnil)); |
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) |
2193 Lisp_Object frame; | 2222 Lisp_Object 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 |
2201 /* Parse the name of SYMBOL, and return the set of modifiers it contains. | 2229 /* Parse the name of SYMBOL, and return the set of modifiers it contains. |
2202 | 2230 |
2790 map = Fcdr (map); | 2818 map = Fcdr (map); |
2791 } | 2819 } |
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 |
2798 /* Read a character like read_char but optionally prompt based on maps | 2965 /* Read a character like read_char but optionally prompt based on maps |
2799 in the array MAPS. NMAPS is the length of MAPS. Return nil if we | 2966 in the array MAPS. NMAPS is the length of MAPS. Return nil if we |
3387 midst of a key sequence, delay it until the end. */ | 3554 midst of a key sequence, delay it until the end. */ |
3388 if (t > 0) | 3555 if (t > 0) |
3389 { | 3556 { |
3390 delayed_switch_frame = key; | 3557 delayed_switch_frame = key; |
3391 goto replay_key; | 3558 goto replay_key; |
3559 } | |
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; | |
3392 } | 3575 } |
3393 } | 3576 } |
3394 } | 3577 } |
3395 } | 3578 } |
3396 | 3579 |
4285 staticpro (&Qmode_line); | 4468 staticpro (&Qmode_line); |
4286 Qvertical_line = intern ("vertical-line"); | 4469 Qvertical_line = intern ("vertical-line"); |
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); |
4293 Qhandle = intern ("handle"); | 4478 Qhandle = intern ("handle"); |
4294 staticpro (&Qhandle); | 4479 staticpro (&Qhandle); |