diff options
| author | Richard M. Stallman | 1992-09-05 00:09:33 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1992-09-05 00:09:33 +0000 |
| commit | 7d6de00206efe33822b90da86be372d7ac38d30d (patch) | |
| tree | 8c3bcd04b830eb4e513669df4e87226f244d153b | |
| parent | 088831f649662badc2c1aaac2b195339e5376be9 (diff) | |
| download | emacs-7d6de00206efe33822b90da86be372d7ac38d30d.tar.gz emacs-7d6de00206efe33822b90da86be372d7ac38d30d.zip | |
(last_nonmenu_event): New var.
(syms_of_keyboard): New Lisp var.
(read_key_sequence): Use that instead of prev_event.
(read_char): Call read_char_menu_prompt here.
Accept 4 new args to pass to it. Include them in recursive call.
Don't delay before starting echo if prev_event was a mouse event.
Test for eof in batch mode now understands C is a Lisp_Object.
(read_key_sequence): Don't call it here; always call read_char.
Don't change last_event_buffer after a mouse menu input.
(read_char_menu_prompt): Arg PROMPT deleted.
Return nil if nothing to do.
(read_key_sequence): Keep track of prev_event.
Pass new proper args to read_char_menu_prompt.
(read_char_menu_prompt): New arg prev_event. Use Fx_popup_menu.
Handle any number of keymaps, not just LOCAL and GLOBAL.
Invert meaning of arg PROMPT. Test of menu_prompting was backwards.
(keymap_table): No longer static.
| -rw-r--r-- | src/keyboard.c | 357 |
1 files changed, 240 insertions, 117 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index c8b5299b7e3..8988a5e762c 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -141,6 +141,10 @@ int num_input_keys; | |||
| 141 | /* Last input character read as a command. */ | 141 | /* Last input character read as a command. */ |
| 142 | Lisp_Object last_command_char; | 142 | Lisp_Object last_command_char; |
| 143 | 143 | ||
| 144 | /* Last input character read as a command, not counting menus | ||
| 145 | reached by the mouse. */ | ||
| 146 | Lisp_Object last_nonmenu_event; | ||
| 147 | |||
| 144 | /* Last input character read for any purpose. */ | 148 | /* Last input character read for any purpose. */ |
| 145 | Lisp_Object last_input_char; | 149 | Lisp_Object last_input_char; |
| 146 | 150 | ||
| @@ -1052,9 +1056,22 @@ static Lisp_Object kbd_buffer_get_event (); | |||
| 1052 | -1 means do not do redisplay, but do do autosaving. | 1056 | -1 means do not do redisplay, but do do autosaving. |
| 1053 | 1 means do both. */ | 1057 | 1 means do both. */ |
| 1054 | 1058 | ||
| 1059 | /* The arguments MAPS and NMAPS are for menu prompting. | ||
| 1060 | MAPS is an array of keymaps; NMAPS is the length of MAPS. | ||
| 1061 | |||
| 1062 | PREV_EVENT is the previous input event, or nil if we are reading | ||
| 1063 | the first event of a key sequence. | ||
| 1064 | |||
| 1065 | If we use a mouse menu to read the input, we store 1 into *USED_MOUSE_MENU. | ||
| 1066 | Otherwise we store 0 there. */ | ||
| 1067 | |||
| 1055 | Lisp_Object | 1068 | Lisp_Object |
| 1056 | read_char (commandflag) | 1069 | read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) |
| 1057 | int commandflag; | 1070 | int commandflag; |
| 1071 | int nmaps; | ||
| 1072 | Lisp_Object *maps; | ||
| 1073 | Lisp_Object prev_event; | ||
| 1074 | int *used_mouse_menu; | ||
| 1058 | { | 1075 | { |
| 1059 | register Lisp_Object c; | 1076 | register Lisp_Object c; |
| 1060 | int count; | 1077 | int count; |
| @@ -1118,9 +1135,17 @@ read_char (commandflag) | |||
| 1118 | { | 1135 | { |
| 1119 | Lisp_Object tem0; | 1136 | Lisp_Object tem0; |
| 1120 | 1137 | ||
| 1121 | tem0 = sit_for (echo_keystrokes, 0, 1, 1); | 1138 | /* After a mouse event, start echoing right away. |
| 1122 | if (EQ (tem0, Qt)) | 1139 | This is because we are probably about to display a menu, |
| 1140 | and we don't want to delay before doing so. */ | ||
| 1141 | if (XTYPE (prev_event) == Lisp_Cons) | ||
| 1123 | echo (); | 1142 | echo (); |
| 1143 | else | ||
| 1144 | { | ||
| 1145 | tem0 = sit_for (echo_keystrokes, 0, 1, 1); | ||
| 1146 | if (EQ (tem0, Qt)) | ||
| 1147 | echo (); | ||
| 1148 | } | ||
| 1124 | } | 1149 | } |
| 1125 | 1150 | ||
| 1126 | /* Maybe auto save due to number of keystrokes or idle time. */ | 1151 | /* Maybe auto save due to number of keystrokes or idle time. */ |
| @@ -1136,55 +1161,65 @@ read_char (commandflag) | |||
| 1136 | restore_getcjmp (temp); | 1161 | restore_getcjmp (temp); |
| 1137 | } | 1162 | } |
| 1138 | 1163 | ||
| 1164 | /* Try reading a character via menu prompting. | ||
| 1165 | Try this before the sit-for, because the sit-for | ||
| 1166 | would do the wrong thing if we are supposed to do | ||
| 1167 | menu prompting. */ | ||
| 1168 | c = Qnil; | ||
| 1169 | if (INTERACTIVE && !NILP (prev_event)) | ||
| 1170 | c = read_char_menu_prompt (nmaps, maps, prev_event, used_mouse_menu); | ||
| 1171 | |||
| 1139 | /* Slow down auto saves logarithmically in size of current buffer, | 1172 | /* Slow down auto saves logarithmically in size of current buffer, |
| 1140 | and garbage collect while we're at it. */ | 1173 | and garbage collect while we're at it. */ |
| 1141 | { | 1174 | if (NILP (c)) |
| 1142 | int delay_level, buffer_size; | 1175 | { |
| 1143 | 1176 | int delay_level, buffer_size; | |
| 1144 | if (! MINI_WINDOW_P (XWINDOW (selected_window))) | 1177 | |
| 1145 | last_non_minibuf_size = Z - BEG; | 1178 | if (! MINI_WINDOW_P (XWINDOW (selected_window))) |
| 1146 | buffer_size = (last_non_minibuf_size >> 8) + 1; | 1179 | last_non_minibuf_size = Z - BEG; |
| 1147 | delay_level = 0; | 1180 | buffer_size = (last_non_minibuf_size >> 8) + 1; |
| 1148 | while (buffer_size > 64) | 1181 | delay_level = 0; |
| 1149 | delay_level++, buffer_size -= buffer_size >> 2; | 1182 | while (buffer_size > 64) |
| 1150 | if (delay_level < 4) delay_level = 4; | 1183 | delay_level++, buffer_size -= buffer_size >> 2; |
| 1151 | /* delay_level is 4 for files under around 50k, 7 at 100k, | 1184 | if (delay_level < 4) delay_level = 4; |
| 1152 | 9 at 200k, 11 at 300k, and 12 at 500k. It is 15 at 1 meg. */ | 1185 | /* delay_level is 4 for files under around 50k, 7 at 100k, |
| 1153 | 1186 | 9 at 200k, 11 at 300k, and 12 at 500k. It is 15 at 1 meg. */ | |
| 1154 | /* Auto save if enough time goes by without input. */ | 1187 | |
| 1155 | if (commandflag != 0 | 1188 | /* Auto save if enough time goes by without input. */ |
| 1156 | && num_input_chars > last_auto_save | 1189 | if (commandflag != 0 |
| 1157 | && XTYPE (Vauto_save_timeout) == Lisp_Int | 1190 | && num_input_chars > last_auto_save |
| 1158 | && XINT (Vauto_save_timeout) > 0) | 1191 | && XTYPE (Vauto_save_timeout) == Lisp_Int |
| 1159 | { | 1192 | && XINT (Vauto_save_timeout) > 0) |
| 1160 | Lisp_Object tem0; | 1193 | { |
| 1161 | int delay = delay_level * XFASTINT (Vauto_save_timeout) / 4; | 1194 | Lisp_Object tem0; |
| 1162 | tem0 = sit_for (delay, 0, 1, 1); | 1195 | int delay = delay_level * XFASTINT (Vauto_save_timeout) / 4; |
| 1163 | if (EQ (tem0, Qt)) | 1196 | tem0 = sit_for (delay, 0, 1, 1); |
| 1164 | { | 1197 | if (EQ (tem0, Qt)) |
| 1165 | jmp_buf temp; | 1198 | { |
| 1166 | save_getcjmp (temp); | 1199 | jmp_buf temp; |
| 1167 | Fdo_auto_save (Qnil, Qnil); | 1200 | save_getcjmp (temp); |
| 1168 | restore_getcjmp (temp); | 1201 | Fdo_auto_save (Qnil, Qnil); |
| 1169 | 1202 | restore_getcjmp (temp); | |
| 1170 | /* If we have auto-saved and there is still no input | 1203 | |
| 1171 | available, garbage collect if there has been enough | 1204 | /* If we have auto-saved and there is still no input |
| 1172 | consing going on to make it worthwhile. */ | 1205 | available, garbage collect if there has been enough |
| 1173 | if (!detect_input_pending () | 1206 | consing going on to make it worthwhile. */ |
| 1174 | && consing_since_gc > gc_cons_threshold / 2) | 1207 | if (!detect_input_pending () |
| 1175 | Fgarbage_collect (); | 1208 | && consing_since_gc > gc_cons_threshold / 2) |
| 1176 | } | 1209 | Fgarbage_collect (); |
| 1177 | } | 1210 | } |
| 1178 | } | 1211 | } |
| 1212 | } | ||
| 1179 | 1213 | ||
| 1180 | /* Actually read a character, waiting if necessary. */ | 1214 | /* Actually read a character, waiting if necessary. */ |
| 1181 | c = kbd_buffer_get_event (); | 1215 | if (NILP (c)) |
| 1216 | c = kbd_buffer_get_event (); | ||
| 1182 | 1217 | ||
| 1183 | if (NILP (c)) | 1218 | if (NILP (c)) |
| 1184 | abort (); /* Don't think this can happen. */ | 1219 | abort (); /* Don't think this can happen. */ |
| 1185 | 1220 | ||
| 1186 | /* Terminate Emacs in batch mode if at eof. */ | 1221 | /* Terminate Emacs in batch mode if at eof. */ |
| 1187 | if (noninteractive && c < 0) | 1222 | if (noninteractive && XTYPE (c) == Lisp_Int && XINT (c) < 0) |
| 1188 | Fkill_emacs (make_number (1)); | 1223 | Fkill_emacs (make_number (1)); |
| 1189 | 1224 | ||
| 1190 | non_reread: | 1225 | non_reread: |
| @@ -1278,7 +1313,7 @@ read_char (commandflag) | |||
| 1278 | if (EQ (c, make_number (040))) | 1313 | if (EQ (c, make_number (040))) |
| 1279 | { | 1314 | { |
| 1280 | cancel_echoing (); | 1315 | cancel_echoing (); |
| 1281 | c = read_char (0); | 1316 | c = read_char (0, 0, 0, Qnil, 0); |
| 1282 | } | 1317 | } |
| 1283 | } | 1318 | } |
| 1284 | 1319 | ||
| @@ -1543,8 +1578,8 @@ kbd_buffer_get_event () | |||
| 1543 | kbd_fetch_ptr = kbd_buffer; | 1578 | kbd_fetch_ptr = kbd_buffer; |
| 1544 | /* Do the redirection specified by the focus_frame | 1579 | /* Do the redirection specified by the focus_frame |
| 1545 | member now, before we return this event. */ | 1580 | member now, before we return this event. */ |
| 1546 | kbd_fetch_ptr->frame = | 1581 | kbd_fetch_ptr->frame |
| 1547 | XFRAME (FRAME_FOCUS_FRAME (kbd_fetch_ptr->frame)); | 1582 | = XFRAME (FRAME_FOCUS_FRAME (kbd_fetch_ptr->frame)); |
| 1548 | 1583 | ||
| 1549 | #ifdef MULTI_FRAME | 1584 | #ifdef MULTI_FRAME |
| 1550 | XSET (Vlast_event_frame, Lisp_Frame, kbd_fetch_ptr->frame); | 1585 | XSET (Vlast_event_frame, Lisp_Frame, kbd_fetch_ptr->frame); |
| @@ -2233,54 +2268,85 @@ static int echo_flag; | |||
| 2233 | static int echo_now; | 2268 | static int echo_now; |
| 2234 | 2269 | ||
| 2235 | /* Read a character like read_char but optionally prompt based on maps | 2270 | /* Read a character like read_char but optionally prompt based on maps |
| 2236 | LOCAL and GLOBAL. | 2271 | in the array MAPS. NMAPS is the length of MAPS. |
| 2272 | |||
| 2273 | PREV_EVENT is the previous input event, or nil if we are reading | ||
| 2274 | the first event of a key sequence. | ||
| 2275 | |||
| 2276 | If we use a mouse menu to read the input, we store 1 into *USED_MOUSE_MENU. | ||
| 2277 | Otherwise we store 0 there. | ||
| 2237 | 2278 | ||
| 2238 | The prompting is done based on the prompt-string of the map | 2279 | The prompting is done based on the prompt-string of the map |
| 2239 | and the strings associated with various map elements. */ | 2280 | and the strings associated with various map elements. */ |
| 2240 | 2281 | ||
| 2241 | Lisp_Object | 2282 | Lisp_Object |
| 2242 | read_char_menu_prompt (prompt, local, global) | 2283 | read_char_menu_prompt (nmaps, maps, prev_event, used_mouse_menu) |
| 2243 | int prompt; | 2284 | int nmaps; |
| 2244 | Lisp_Object local, global; | 2285 | Lisp_Object *maps; |
| 2286 | Lisp_Object prev_event; | ||
| 2287 | int *used_mouse_menu; | ||
| 2245 | { | 2288 | { |
| 2246 | register Lisp_Object rest, name; | 2289 | int mapno; |
| 2247 | Lisp_Object hmap; | 2290 | register Lisp_Object name; |
| 2248 | int nlength; | 2291 | int nlength; |
| 2249 | int width = FRAME_WIDTH (selected_frame) - 4; | 2292 | int width = FRAME_WIDTH (selected_frame) - 4; |
| 2250 | char *menu = (char *) alloca (width); | 2293 | char *menu = (char *) alloca (width + 4); |
| 2294 | int idx = -1; | ||
| 2295 | Lisp_Object rest, vector; | ||
| 2296 | |||
| 2297 | *used_mouse_menu = 0; | ||
| 2251 | 2298 | ||
| 2252 | /* Use local over global Menu maps */ | 2299 | /* Use local over global Menu maps */ |
| 2253 | 2300 | ||
| 2254 | if (menu_prompting) | 2301 | if (! menu_prompting) |
| 2255 | return read_char (!prompt); | 2302 | return Qnil; |
| 2256 | 2303 | ||
| 2257 | /* We can't get prompt strings from dense keymaps. */ | 2304 | /* Get the menu name from the first map that has one (a prompt string). */ |
| 2258 | if (CONSP (local) | 2305 | for (mapno = 0; mapno < nmaps; mapno++) |
| 2259 | && EQ (Fcar (local), Qkeymap) | 2306 | { |
| 2260 | && !(CONSP (XCONS (local)->cdr) | 2307 | name = map_prompt (maps[mapno]); |
| 2261 | && XTYPE (XCONS (XCONS (local)->cdr)->car) == Lisp_Vector)) | 2308 | if (!NILP (name)) |
| 2262 | hmap = local; | 2309 | break; |
| 2263 | else if (CONSP (global) | 2310 | } |
| 2264 | && EQ (Fcar (global), Qkeymap) | ||
| 2265 | && !(CONSP (XCONS (global)->cdr) | ||
| 2266 | && XTYPE (XCONS (XCONS (global)->cdr)->car) == Lisp_Vector)) | ||
| 2267 | hmap = global; | ||
| 2268 | else | ||
| 2269 | return read_char (!prompt); | ||
| 2270 | 2311 | ||
| 2271 | /* Get the map's prompt string. */ | 2312 | /* If we don't have any menus, just read a character normally. */ |
| 2272 | name = map_prompt (hmap); | ||
| 2273 | if (NILP (name)) | 2313 | if (NILP (name)) |
| 2274 | return read_char (!prompt); | 2314 | return Qnil; |
| 2315 | |||
| 2316 | #ifdef HAVE_X_MENU | ||
| 2317 | /* If we got to this point via a mouse click, | ||
| 2318 | use a real menu for mouse selection. */ | ||
| 2319 | if (XTYPE (prev_event) == Lisp_Cons) | ||
| 2320 | { | ||
| 2321 | /* Display the menu and get the selection. */ | ||
| 2322 | Lisp_Object *realmaps | ||
| 2323 | = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object)); | ||
| 2324 | Lisp_Object value; | ||
| 2325 | int nmaps1 = 0; | ||
| 2326 | |||
| 2327 | /* Use the maps that are not nil. */ | ||
| 2328 | for (mapno = 0; mapno < nmaps; mapno++) | ||
| 2329 | if (!NILP (maps[mapno])) | ||
| 2330 | realmaps[nmaps1++] = maps[mapno]; | ||
| 2331 | |||
| 2332 | value = Fx_popup_menu (prev_event, Flist (nmaps1, realmaps)); | ||
| 2333 | if (NILP (value)) | ||
| 2334 | XSET (value, Lisp_Int, quit_char); | ||
| 2335 | *used_mouse_menu = 1; | ||
| 2336 | return value; | ||
| 2337 | } | ||
| 2338 | #endif /* HAVE_X_MENU */ | ||
| 2275 | 2339 | ||
| 2276 | /* Prompt string always starts with map's prompt, and a space. */ | 2340 | /* Prompt string always starts with map's prompt, and a space. */ |
| 2277 | strcpy (menu, XSTRING (name)->data); | 2341 | strcpy (menu, XSTRING (name)->data); |
| 2278 | nlength = XSTRING (name)->size; | 2342 | nlength = XSTRING (name)->size; |
| 2343 | menu[nlength++] = ':'; | ||
| 2279 | menu[nlength++] = ' '; | 2344 | menu[nlength++] = ' '; |
| 2280 | menu[nlength] = 0; | 2345 | menu[nlength] = 0; |
| 2281 | 2346 | ||
| 2282 | /* Start prompting at start of map. */ | 2347 | /* Start prompting at start of first map. */ |
| 2283 | rest = hmap; /* Current menu item */ | 2348 | mapno = 0; |
| 2349 | rest = maps[mapno]; | ||
| 2284 | 2350 | ||
| 2285 | /* Present the documented bindings, a line at a time. */ | 2351 | /* Present the documented bindings, a line at a time. */ |
| 2286 | while (1) | 2352 | while (1) |
| @@ -2290,54 +2356,92 @@ read_char_menu_prompt (prompt, local, global) | |||
| 2290 | Lisp_Object obj; | 2356 | Lisp_Object obj; |
| 2291 | int ch; | 2357 | int ch; |
| 2292 | 2358 | ||
| 2293 | /* If reached end of map, start at beginning. */ | ||
| 2294 | if (NILP (Fcdr (rest))) rest = hmap; | ||
| 2295 | |||
| 2296 | /* Loop over elements of map. */ | 2359 | /* Loop over elements of map. */ |
| 2297 | while (!NILP (rest) && i < width) | 2360 | while (i < width) |
| 2298 | { | 2361 | { |
| 2299 | Lisp_Object s; | 2362 | Lisp_Object s, elt; |
| 2300 | |||
| 2301 | /* Look for conses whose cadrs are strings. */ | ||
| 2302 | s = Fcar_safe (Fcdr_safe (Fcar_safe (rest))); | ||
| 2303 | if (XTYPE (s) != Lisp_String) | ||
| 2304 | /* Ignore all other elements. */ | ||
| 2305 | ; | ||
| 2306 | /* If first such element, or enough room, add string to prompt. */ | ||
| 2307 | else if (XSTRING (s)->size + i < width | ||
| 2308 | || !notfirst) | ||
| 2309 | { | ||
| 2310 | int thiswidth; | ||
| 2311 | 2363 | ||
| 2312 | /* Punctuate between strings. */ | 2364 | /* If reached end of map, start at beginning of next map. */ |
| 2313 | if (notfirst) | 2365 | if (NILP (rest)) |
| 2366 | { | ||
| 2367 | mapno++; | ||
| 2368 | /* At end of last map, wrap around to first map if just starting, | ||
| 2369 | or end this line if already have something on it. */ | ||
| 2370 | if (mapno == nmaps) | ||
| 2314 | { | 2371 | { |
| 2315 | strcpy (menu + i, ", "); | 2372 | if (notfirst) |
| 2316 | i += 2; | 2373 | break; |
| 2374 | else | ||
| 2375 | mapno = 0; | ||
| 2317 | } | 2376 | } |
| 2318 | notfirst = 1; | 2377 | rest = maps[mapno]; |
| 2319 | |||
| 2320 | /* Add as much of string as fits. */ | ||
| 2321 | thiswidth = XSTRING (s)->size; | ||
| 2322 | if (thiswidth + i > width) | ||
| 2323 | thiswidth = width - i; | ||
| 2324 | bcopy (XSTRING (s)->data, menu + i, thiswidth); | ||
| 2325 | i += thiswidth; | ||
| 2326 | } | 2378 | } |
| 2379 | |||
| 2380 | /* Look at the next element of the map. */ | ||
| 2381 | if (idx >= 0) | ||
| 2382 | elt = XVECTOR (vector)->contents[idx]; | ||
| 2327 | else | 2383 | else |
| 2384 | elt = Fcar_safe (rest); | ||
| 2385 | |||
| 2386 | if (idx < 0 && XTYPE (elt) == Lisp_Vector) | ||
| 2328 | { | 2387 | { |
| 2329 | /* If some elts don't fit, show there are more. */ | 2388 | /* If we found a dense table in the keymap, |
| 2330 | strcpy (menu + i, "..."); | 2389 | advanced past it, but start scanning its contents. */ |
| 2331 | break; | 2390 | rest = Fcdr_safe (rest); |
| 2391 | vector = elt; | ||
| 2392 | idx = 0; | ||
| 2332 | } | 2393 | } |
| 2394 | else | ||
| 2395 | { | ||
| 2396 | /* An ordinary element. */ | ||
| 2397 | s = Fcar_safe (Fcdr_safe (elt)); | ||
| 2398 | if (XTYPE (s) != Lisp_String) | ||
| 2399 | /* Ignore the element if it has no prompt string. */ | ||
| 2400 | ; | ||
| 2401 | /* If we have room for the prompt string, add it to this line. | ||
| 2402 | If this is the first on the line, always add it. */ | ||
| 2403 | else if (XSTRING (s)->size + i < width | ||
| 2404 | || !notfirst) | ||
| 2405 | { | ||
| 2406 | int thiswidth; | ||
| 2333 | 2407 | ||
| 2334 | /* Move past this element. */ | 2408 | /* Punctuate between strings. */ |
| 2335 | rest = Fcdr_safe (rest); | 2409 | if (notfirst) |
| 2410 | { | ||
| 2411 | strcpy (menu + i, ", "); | ||
| 2412 | i += 2; | ||
| 2413 | } | ||
| 2414 | notfirst = 1; | ||
| 2415 | |||
| 2416 | /* Add as much of string as fits. */ | ||
| 2417 | thiswidth = XSTRING (s)->size; | ||
| 2418 | if (thiswidth + i > width) | ||
| 2419 | thiswidth = width - i; | ||
| 2420 | bcopy (XSTRING (s)->data, menu + i, thiswidth); | ||
| 2421 | i += thiswidth; | ||
| 2422 | } | ||
| 2423 | else | ||
| 2424 | { | ||
| 2425 | /* If this element does not fit, end the line now, | ||
| 2426 | and save the element for the next line. */ | ||
| 2427 | strcpy (menu + i, "..."); | ||
| 2428 | break; | ||
| 2429 | } | ||
| 2430 | |||
| 2431 | /* Move past this element. */ | ||
| 2432 | if (idx >= 0 && idx + 1 >= XVECTOR (rest)->size) | ||
| 2433 | /* Handle reaching end of dense table. */ | ||
| 2434 | idx = -1; | ||
| 2435 | if (idx >= 0) | ||
| 2436 | idx++; | ||
| 2437 | else | ||
| 2438 | rest = Fcdr_safe (rest); | ||
| 2439 | } | ||
| 2336 | } | 2440 | } |
| 2337 | 2441 | ||
| 2338 | /* Prompt with that and read response. */ | 2442 | /* Prompt with that and read response. */ |
| 2339 | message1 (menu); | 2443 | message1 (menu); |
| 2340 | obj = read_char (1); | 2444 | obj = read_char (1, 0, 0, Qnil, 0); |
| 2341 | 2445 | ||
| 2342 | if (XTYPE (obj) != Lisp_Int) | 2446 | if (XTYPE (obj) != Lisp_Int) |
| 2343 | return obj; | 2447 | return obj; |
| @@ -2350,7 +2454,6 @@ read_char_menu_prompt (prompt, local, global) | |||
| 2350 | return obj; | 2454 | return obj; |
| 2351 | } | 2455 | } |
| 2352 | } | 2456 | } |
| 2353 | |||
| 2354 | 2457 | ||
| 2355 | /* Reading key sequences. */ | 2458 | /* Reading key sequences. */ |
| 2356 | 2459 | ||
| @@ -2518,6 +2621,8 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 2518 | int fkey_start = 0, fkey_end = 0; | 2621 | int fkey_start = 0, fkey_end = 0; |
| 2519 | Lisp_Object fkey_map = Vfunction_key_map; | 2622 | Lisp_Object fkey_map = Vfunction_key_map; |
| 2520 | 2623 | ||
| 2624 | last_nonmenu_event = Qnil; | ||
| 2625 | |||
| 2521 | if (INTERACTIVE) | 2626 | if (INTERACTIVE) |
| 2522 | { | 2627 | { |
| 2523 | if (prompt) | 2628 | if (prompt) |
| @@ -2561,6 +2666,7 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 2561 | || (first_binding >= nmaps && fkey_start < t)) | 2666 | || (first_binding >= nmaps && fkey_start < t)) |
| 2562 | { | 2667 | { |
| 2563 | Lisp_Object key; | 2668 | Lisp_Object key; |
| 2669 | int used_mouse_menu = 0; | ||
| 2564 | 2670 | ||
| 2565 | if (t >= bufsize) | 2671 | if (t >= bufsize) |
| 2566 | error ("key sequence too long"); | 2672 | error ("key sequence too long"); |
| @@ -2578,10 +2684,8 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 2578 | { | 2684 | { |
| 2579 | struct buffer *buf; | 2685 | struct buffer *buf; |
| 2580 | 2686 | ||
| 2581 | if (!prompt && INTERACTIVE) | 2687 | key = read_char (!prompt, nmaps, submaps, last_nonmenu_event, |
| 2582 | key = read_char_menu_prompt (prompt, Qnil, Qnil); | 2688 | &used_mouse_menu); |
| 2583 | else | ||
| 2584 | key = read_char (!prompt); | ||
| 2585 | 2689 | ||
| 2586 | /* The above routines return -1 at the end of a macro. | 2690 | /* The above routines return -1 at the end of a macro. |
| 2587 | Emacs 18 handles this by returning immediately with a | 2691 | Emacs 18 handles this by returning immediately with a |
| @@ -2593,7 +2697,10 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 2593 | 2697 | ||
| 2594 | #ifdef MULTI_FRAME | 2698 | #ifdef MULTI_FRAME |
| 2595 | /* What buffer was this event typed/moused at? */ | 2699 | /* What buffer was this event typed/moused at? */ |
| 2596 | if (XTYPE (key) == Lisp_Int || XTYPE (key) == Lisp_Symbol) | 2700 | if (used_mouse_menu) |
| 2701 | /* Never change last_event_buffer for using a menu. */ | ||
| 2702 | buf = last_event_buffer; | ||
| 2703 | else if (XTYPE (key) == Lisp_Int || XTYPE (key) == Lisp_Symbol) | ||
| 2597 | buf = (XBUFFER | 2704 | buf = (XBUFFER |
| 2598 | (XWINDOW | 2705 | (XWINDOW |
| 2599 | (FRAME_SELECTED_WINDOW | 2706 | (FRAME_SELECTED_WINDOW |
| @@ -2638,6 +2745,12 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 2638 | submaps + first_binding) | 2745 | submaps + first_binding) |
| 2639 | + first_binding); | 2746 | + first_binding); |
| 2640 | keybuf[t++] = key; | 2747 | keybuf[t++] = key; |
| 2748 | /* Normally, last_nonmenu_event gets the previous key we read. | ||
| 2749 | But when a mouse popup menu is being used, | ||
| 2750 | we don't update last_nonmenu_event; it continues to hold the mouse | ||
| 2751 | event that preceded the first level of menu. */ | ||
| 2752 | if (!used_mouse_menu) | ||
| 2753 | last_nonmenu_event = key; | ||
| 2641 | 2754 | ||
| 2642 | /* If the sequence is unbound, see if we can hang a function key | 2755 | /* If the sequence is unbound, see if we can hang a function key |
| 2643 | off the end of it. We only want to scan real keyboard input | 2756 | off the end of it. We only want to scan real keyboard input |
| @@ -3418,11 +3531,17 @@ syms_of_keyboard () | |||
| 3418 | 3531 | ||
| 3419 | DEFVAR_LISP ("disabled-command-hook", &Vdisabled_command_hook, | 3532 | DEFVAR_LISP ("disabled-command-hook", &Vdisabled_command_hook, |
| 3420 | "Value is called instead of any command that is disabled\n\ | 3533 | "Value is called instead of any command that is disabled\n\ |
| 3421 | (has a non-nil `disabled' property)."); | 3534 | \(has a non-nil `disabled' property)."); |
| 3422 | 3535 | ||
| 3423 | DEFVAR_LISP ("last-command-char", &last_command_char, | 3536 | DEFVAR_LISP ("last-command-char", &last_command_char, |
| 3424 | "Last terminal input key that was part of a command."); | 3537 | "Last terminal input key that was part of a command."); |
| 3425 | 3538 | ||
| 3539 | DEFVAR_LISP ("last-nonmenu-event", &last_nonmenu_event, | ||
| 3540 | "Last terminal input key in a command, except for mouse menus.\n\ | ||
| 3541 | Mouse menus give back keys that don't look like mouse events;\n\ | ||
| 3542 | this variable holds the actual mouse event that led to the menu,\n\ | ||
| 3543 | so that you can determine whether the command was run by mouse or not."); | ||
| 3544 | |||
| 3426 | DEFVAR_LISP ("last-input-char", &last_input_char, | 3545 | DEFVAR_LISP ("last-input-char", &last_input_char, |
| 3427 | "Last terminal input key."); | 3546 | "Last terminal input key."); |
| 3428 | 3547 | ||
| @@ -3503,9 +3622,13 @@ If string is of length N, character codes N and up are untranslated."); | |||
| 3503 | Vkeyboard_translate_table = Qnil; | 3622 | Vkeyboard_translate_table = Qnil; |
| 3504 | 3623 | ||
| 3505 | DEFVAR_BOOL ("menu-prompting", &menu_prompting, | 3624 | DEFVAR_BOOL ("menu-prompting", &menu_prompting, |
| 3506 | "Non-nil means prompt with menus in echo area when appropriate.\n\ | 3625 | "Non-nil means prompt with menus when appropriate.\n\ |
| 3507 | This is done when reading from a keymap that has a prompt string,\n\ | 3626 | This is done when reading from a keymap that has a prompt string,\n\ |
| 3508 | for elements that have prompt strings."); | 3627 | for elements that have prompt strings.\n\ |
| 3628 | The menu is displayed on the screen\n\ | ||
| 3629 | if X menus were enabled at configuration\n\ | ||
| 3630 | time and the previous event was a mouse click prefix key.\n\ | ||
| 3631 | Otherwise, menu prompting uses the echo area."); | ||
| 3509 | menu_prompting = 1; | 3632 | menu_prompting = 1; |
| 3510 | 3633 | ||
| 3511 | DEFVAR_LISP ("menu-prompt-more-char", &menu_prompt_more_char, | 3634 | DEFVAR_LISP ("menu-prompt-more-char", &menu_prompt_more_char, |