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);