From b3e6f69c10973ff7b040ced07a3a084960619681 Mon Sep 17 00:00:00 2001 From: Karoly Lorentey Date: Tue, 3 Jan 2006 01:50:46 +0000 Subject: [PATCH] Overhaul and simplify single_kboard API. Allow calls to `recursive-edit' in process filters. Small fixes. * lisp/server.el (server-process-filter): Protect `display-splash-screen' call in a condition-case. Explain why. * src/callint.c (Fcall_interactively): Update call to `temporarily_switch_to_single_kboard'. * src/fns.c (Fy_or_n_p): Ditto. * src/frame.c (Fdelete_frame): Remove unused variable `count'. * src/keyboard.c (wrong_kboard_jmpbuf): Remove global variable. * src/keyboard.c (read_char): Add wrong_kboard_jmpbuf parameter to allow for recursive calls. Update longjmp invocations. Remember the original current_kboard, and longjmp to `wrong_kboard_jmpbuf' when a filter, timer or sentinel changes it. Comment out unnecessary calls to `record_single_kboard_state' and `any_kboard_state'. Update recursive calls. * src/keyboard.c (read_key_sequence): Add `wrong_kboard_jmpbuf' local variable. Update setjmp and read_char calls. Abort if interrupted_kboard died in read_char. * src/keyboard.c (any_kboard_state, single_kboard_state) (record_single_kboard_state): Comment out obsolete functions. (push_frame_kboard): Remove function. (pop_kboard): Switch out of single_kboard mode if the kboard has been deleted. (temporarily_switch_to_single_kboard): Change first parameter to a frame pointer. Throw an error when caller wants to change kboards while in single_kboard mode. (restore_kboard_configuration): Abort if pop_kboard changed the kboard in single_kboard mode. (Frecursive_edit): Switch to single_kboard mode only in nested command loops. (cmd_error, command_loop, command_loop_1, timer_check): Comment out unnecessary call to `any_kboard_state' and `record_single_kboard_state'. * src/keyboard.c (delete_kboard): Exit single_kboard mode if we have just deleted that kboard. * src/keyboard.c (interrupt_signal): Use `Fkill_emacs' to exit Emacs, not `fatal_error_signal'. * src/keyboard.h (read_char, single_kboard_state) (record_single_kboard_state): Remove. (temporarily_switch_to_single_kboard): Update. * src/lread.c: Include setjmp.h. Update declaration of `read_char'. (read_filtered_event): Call `read_char' with a local `wrong_kboard_jmpbuf'. * src/minibuf.c (read_minibuf): Update call to `temporarily_switch_to_single_kboard'. * src/termchar.h (tty_display_info): Rename `previous_terminal_frame' member to `previous_frame'. * src/xdisp.c (redisplay_internal): Update references to `previous_terminal_frame'. (display_mode_line, Fformat_mode_line): Replace calls to `push_frame_kboard' with `push_kboard'. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-489 --- README.multi-tty | 49 +++++++++++----- lisp/server.el | 12 +++- src/callint.c | 3 +- src/fns.c | 2 +- src/frame.c | 1 - src/keyboard.c | 147 ++++++++++++++++++++++++++++++++++------------- src/keyboard.h | 5 +- src/lread.c | 12 ++-- src/minibuf.c | 2 +- src/termchar.h | 4 +- src/xdisp.c | 8 +-- 11 files changed, 170 insertions(+), 75 deletions(-) diff --git a/README.multi-tty b/README.multi-tty index 60050f9f77..7ad6bf5b31 100644 --- a/README.multi-tty +++ b/README.multi-tty @@ -401,12 +401,6 @@ is probably not very interesting for anyone else.) THINGS TO DO ------------ -** Let-binding `overriding-terminal-local-map' on a brand new frame - does not seem to work correctly. (See `fancy-splash-screens'.) - The keymap seems to be set up right, but events go to another - terminal. Or is it `unread-command-events' that gets Emacs - confused? Investigate. - ** `delete-frame' events are handled by `special-event-map' immediately when read by `read_char'. This is fine but it prevents higher-level keymaps from binding that event to get notified of the @@ -466,6 +460,10 @@ THINGS TO DO Emacs with GTK support. If you want to play around with GTK multidisplay (and don't mind core dumps), you can edit src/config.h and define HAVE_GTK_MULTIDISPLAY there by hand. + + Update: Han reports that GTK+ version 2.8.9 almost gets display + disconnects right. GTK will probably be fully fixed by the time + multi-tty gets into the trunk. ** Audit `face-valid-attribute-values' usage in customize and elsewhere. Its return value depends on the current window system. @@ -477,10 +475,6 @@ THINGS TO DO ** frames-on-display-list should also accept frames. -** I smell something funny around pop_kboard's "deleted kboard" case. - Determine what are the circumstances of this case, and fix any - bug that comes to light. - ** Consider the `tty-type' frame parameter and the `display-tty-type' function. They serve the exact same purpose. I think it may be a good idea to eliminate one of them, preferably `tty-type'. @@ -514,10 +508,6 @@ THINGS TO DO instead of delete-frame-functions), after-delete-terminal-functions, after-create-terminal-functions. -** Fix set-input-mode for multi-tty. It's a truly horrible interface; - what if we'd blow it up into several separate functions (with a - compatibility definition)? - ** BULK RENAME: The `display-' prefix of new Lisp-level functions conflicts with stuff like `display-time-mode'. Use `device-' or `terminal-' instead. I think I prefer `terminal-'. @@ -583,6 +573,8 @@ THINGS TO DO by changing the modelines or some other frame-local display element on the locked out displays. + Update: In fact struct kboard does have an echo_string slot. + ** The session management module is prone to crashes when the X connection is closed and then later I try to connect to a new X session: @@ -670,6 +662,9 @@ THINGS TO DO terminals in xterm and konsole. The screen does flicker a bit, but it's so quick it isn't noticable. + (Update: This is probably some problem with padding or whatnot on + the secondary terminals.) + ** Move baud_rate to struct display. ** Implement support for starting an interactive Emacs session without @@ -1414,6 +1409,32 @@ DIARY OF CHANGES against `delete-frame-functions' throwing an error and preventing a frame delete. (patch-475) +-- Fix set-input-mode for multi-tty. It's a truly horrible interface; + what if we'd blow it up into several separate functions (with a + compatibility definition)? + + (Done. See `set-input-interrupt-mode', `set-output-flow-control', + `set-input-meta-mode' and `set-quit-char'.) (patch-457) + +-- Let-binding `overriding-terminal-local-map' on a brand new frame + does not seem to work correctly. (See `fancy-splash-screens'.) + The keymap seems to be set up right, but events go to another + terminal. Or is it `unread-command-events' that gets Emacs + confused? Investigate. + + (Emacs was confused because a process filter entered + `recursive-edit' while Emacs was reading input. I added support + for this in the input system.) (patch-489) + +-- I smell something funny around pop_kboard's "deleted kboard" case. + Determine what are the circumstances of this case, and fix any + bug that comes to light. + + (It happens simply because single_kboard's terminal is sometimes + deleted while executing a command on it, for example the one that + kills the terminal. There was no bug here, but I rewrote the whole + single_kboard mess anyway.) (patch-489) + ;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d diff --git a/lisp/server.el b/lisp/server.el index f8f3c510d0..382befd534 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -755,9 +755,17 @@ The following commands are accepted by the client: (with-selected-frame frame (switch-to-buffer (or (car buffers) (get-buffer-create "*scratch*"))) - (display-startup-echo-area-message)) + (display-startup-echo-area-message) (unless inhibit-splash-screen - (display-splash-screen))) + (condition-case err + ;; This looks scary because `fancy-splash-screens' + ;; will call `recursive-edit' from a process filter. + ;; However, that should be safe to do now. + (display-splash-screen) + ;; `recursive-edit' will throw an error if Emacs is + ;; already doing a recursive edit elsewhere. Catch it + ;; here so that we can finish normally. + (error nil))))) ;; Delete the client if necessary. (cond diff --git a/src/callint.c b/src/callint.c index d44d2f20ca..38db2ea92e 100644 --- a/src/callint.c +++ b/src/callint.c @@ -875,12 +875,11 @@ If KEYS is omitted or nil, the return value of `this-command-keys' is used. */) real_this_command= save_real_this_command; current_kboard->Vlast_command = save_last_command; - temporarily_switch_to_single_kboard (NULL); - { Lisp_Object val; specbind (Qcommand_debug_status, Qnil); + temporarily_switch_to_single_kboard (NULL); val = Ffuncall (count + 1, args); UNGCPRO; return unbind_to (speccount, val); diff --git a/src/fns.c b/src/fns.c index 70b9cf0d30..48048c5a83 100644 --- a/src/fns.c +++ b/src/fns.c @@ -3308,7 +3308,7 @@ is nil and `use-dialog-box' is non-nil. */) Fraise_frame (mini_frame); } - temporarily_switch_to_single_kboard (FRAME_KBOARD (SELECTED_FRAME ())); + temporarily_switch_to_single_kboard (SELECTED_FRAME ()); obj = read_filtered_event (1, 0, 0, 0); cursor_in_echo_area = 0; diff --git a/src/frame.c b/src/frame.c index 9648783ee7..6b848ea2fe 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1406,7 +1406,6 @@ The functions are run with one arg, the frame to be deleted. */) if (!NILP (Vrun_hooks) && NILP (Fframe_parameter (frame, intern ("tooltip")))) { - int count = SPECPDL_INDEX (); Lisp_Object args[2]; struct gcpro gcpro1, gcpro2; diff --git a/src/keyboard.c b/src/keyboard.c index 6646ea62e6..cd10c1fde6 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -670,7 +670,6 @@ static void save_getcjmp (); static void restore_getcjmp P_ ((jmp_buf)); static Lisp_Object apply_modifiers P_ ((int, Lisp_Object)); static void clear_event P_ ((struct input_event *)); -static void any_kboard_state P_ ((void)); static Lisp_Object restore_kboard_configuration P_ ((Lisp_Object)); static SIGTYPE interrupt_signal P_ ((int signalnum)); static void handle_interrupt P_ ((void)); @@ -1034,7 +1033,8 @@ This function is called by the editor initialization to begin editing. */) like it is done in the splash screen display, we have to make sure that we restore single_kboard as command_loop_1 would have done if it were left normally. */ - temporarily_switch_to_single_kboard (FRAME_KBOARD (SELECTED_FRAME ())); + if (command_loop_level > 0) + temporarily_switch_to_single_kboard (SELECTED_FRAME ()); record_unwind_protect (recursive_edit_unwind, buffer); recursive_edit_1 (); @@ -1054,6 +1054,8 @@ recursive_edit_unwind (buffer) } +#if 0 /* These two functions are now replaced with + temporarily_switch_to_single_kboard. */ static void any_kboard_state () { @@ -1084,6 +1086,7 @@ single_kboard_state () single_kboard = 1; #endif } +#endif /* If we're in single_kboard state for kboard KBOARD, get out of it. */ @@ -1126,13 +1129,6 @@ push_kboard (k) #endif } -void -push_frame_kboard (f) - FRAME_PTR f; -{ - push_kboard (f->terminal->kboard); -} - void pop_kboard () { @@ -1153,37 +1149,55 @@ pop_kboard () { /* The terminal we remembered has been deleted. */ current_kboard = FRAME_KBOARD (SELECTED_FRAME ()); + single_kboard = 0; } kboard_stack = p->next; xfree (p); #endif } -/* Switch to single_kboard mode. If K is non-nil, set it as the - current keyboard. Use record_unwind_protect to return to the - previous state later. */ +/* Switch to single_kboard mode, making current_kboard the only KBOARD + from which further input is accepted. If F is non-nil, set its + KBOARD as the current keyboard. + + This function uses record_unwind_protect to return to the previous + state later. + + If Emacs is already in single_kboard mode, and F's keyboard is + locked, then this function will throw an errow. */ void -temporarily_switch_to_single_kboard (k) - struct kboard *k; +temporarily_switch_to_single_kboard (f) + struct frame *f; { #ifdef MULTI_KBOARD int was_locked = single_kboard; if (was_locked) { - if (k != NULL) - push_kboard (k); + if (f != NULL && FRAME_KBOARD (f) != current_kboard) + /* We can not switch keyboards while in single_kboard mode. + This can legally happen when Lisp code calls + `recursive-edit' (or `read-minibuffer' or `y-or-n-p') after + it switched to a locked frame. This kind of situation is + likely to happen when server.el connects to a new + terminal. */ + error ("Terminal %d is locked, cannot read from it", + FRAME_TERMINAL (f)->id); else + /* This call is unnecessary, but helps + `restore_kboard_configuration' discover if somebody changed + `current_kboard' behind our back. */ push_kboard (current_kboard); } - else if (k != NULL) - current_kboard = k; - single_kboard_state (); + else if (f != NULL) + current_kboard = FRAME_KBOARD (f); + single_kboard = 1; record_unwind_protect (restore_kboard_configuration, (was_locked ? Qt : Qnil)); #endif } +#if 0 /* This function is not needed anymore. */ void record_single_kboard_state () { @@ -1192,17 +1206,22 @@ record_single_kboard_state () record_unwind_protect (restore_kboard_configuration, (single_kboard ? Qt : Qnil)); } +#endif static Lisp_Object restore_kboard_configuration (was_locked) Lisp_Object was_locked; { if (NILP (was_locked)) - any_kboard_state (); + single_kboard = 0; else { - single_kboard_state (); + struct kboard *prev = current_kboard; + single_kboard = 1; pop_kboard (); + /* The pop should not change the kboard. */ + if (single_kboard && current_kboard != prev) + abort (); } return Qnil; } @@ -1253,9 +1272,11 @@ cmd_error (data) Vquit_flag = Qnil; Vinhibit_quit = Qnil; +#if 0 /* This shouldn't be necessary anymore. --lorentey */ #ifdef MULTI_KBOARD if (command_loop_level == 0 && minibuf_level == 0) any_kboard_state (); +#endif #endif return make_number (0); @@ -1340,10 +1361,12 @@ command_loop () while (1) { internal_catch (Qtop_level, top_level_1, Qnil); +#if 0 /* This shouldn't be necessary anymore. --lorentey */ /* Reset single_kboard in case top-level set it while evaluating an -f option, or we are stuck there for some other reason. */ any_kboard_state (); +#endif internal_catch (Qtop_level, command_loop_2, Qnil); executing_kbd_macro = Qnil; @@ -1460,9 +1483,11 @@ command_loop_1 () int no_direct; int prev_modiff = 0; struct buffer *prev_buffer = NULL; +#if 0 /* This shouldn't be necessary anymore. --lorentey */ #ifdef MULTI_KBOARD int was_locked = single_kboard; #endif +#endif int already_adjusted = 0; current_kboard->Vprefix_arg = Qnil; @@ -1919,10 +1944,11 @@ command_loop_1 () if (!NILP (current_kboard->defining_kbd_macro) && NILP (current_kboard->Vprefix_arg)) finalize_kbd_macro_chars (); - +#if 0 /* This shouldn't be necessary anymore. --lorentey */ #ifdef MULTI_KBOARD if (!was_locked) - any_kboard_state (); + any_kboard_state (); +#endif #endif } } @@ -2405,10 +2431,6 @@ Lisp_Object print_help (); static Lisp_Object kbd_buffer_get_event (); static void record_char (); -#ifdef MULTI_KBOARD -static jmp_buf wrong_kboard_jmpbuf; -#endif - #define STOP_POLLING \ do { if (! polling_stopped_here) stop_polling (); \ polling_stopped_here = 1; } while (0) @@ -2435,15 +2457,19 @@ do { if (polling_stopped_here) start_polling (); \ if we used a mouse menu to read the input, or zero otherwise. If USED_MOUSE_MENU is null, we don't dereference it. + WRONG_KBOARD_JMPBUF should be a stack context to longjmp to in case + we find input on another keyboard. + Value is t if we showed a menu and the user rejected it. */ Lisp_Object -read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) +read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu, wrong_kboard_jmpbuf) int commandflag; int nmaps; Lisp_Object *maps; Lisp_Object prev_event; int *used_mouse_menu; + jmp_buf *wrong_kboard_jmpbuf; { volatile Lisp_Object c; int count; @@ -2456,6 +2482,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) volatile int reread; struct gcpro gcpro1, gcpro2; int polling_stopped_here = 0; + struct kboard *orig_kboard = current_kboard; also_record = Qnil; @@ -2711,7 +2738,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) /* This is going to exit from read_char so we had better get rid of this frame's stuff. */ UNGCPRO; - longjmp (wrong_kboard_jmpbuf, 1); + if (wrong_kboard_jmpbuf == NULL) + abort (); + longjmp (*wrong_kboard_jmpbuf, 1); } } #endif @@ -2845,6 +2874,20 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) } } + /* Notify the caller if a timer or sentinel or filter in the sit_for + calls above have changed the current kboard. This could happen + if they start a recursive edit, like the fancy splash screen in + server.el's filter. If this longjmp wasn't here, + read_key_sequence would interpret the next key sequence using the + wrong translation tables and function keymaps. */ + if (NILP (c) && current_kboard != orig_kboard) + { + UNGCPRO; + if (wrong_kboard_jmpbuf == NULL) + abort (); + longjmp (*wrong_kboard_jmpbuf, 1); + } + /* If this has become non-nil here, it has been set by a timer or sentinel or filter. */ if (CONSP (Vunread_command_events)) @@ -2893,7 +2936,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) /* This is going to exit from read_char so we had better get rid of this frame's stuff. */ UNGCPRO; - longjmp (wrong_kboard_jmpbuf, 1); + if (wrong_kboard_jmpbuf == NULL) + abort (); + longjmp (*wrong_kboard_jmpbuf, 1); } } #endif @@ -2940,7 +2985,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) /* This is going to exit from read_char so we had better get rid of this frame's stuff. */ UNGCPRO; - longjmp (wrong_kboard_jmpbuf, 1); + if (wrong_kboard_jmpbuf == NULL) + abort (); + longjmp (*wrong_kboard_jmpbuf, 1); } #endif } @@ -2994,8 +3041,12 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) if (!NILP (tem)) { +#if 0 /* This shouldn't be necessary anymore. --lorentey */ int was_locked = single_kboard; - + int count = SPECPDL_INDEX (); + record_single_kboard_state (); +#endif + last_input_char = c; Fcommand_execute (tem, Qnil, Fvector (1, &last_input_char), Qt); @@ -3006,9 +3057,12 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) example banishing the mouse under mouse-avoidance-mode. */ timer_resume_idle (); +#if 0 /* This shouldn't be necessary anymore. --lorentey */ /* Resume allowing input from any kboard, if that was true before. */ if (!was_locked) any_kboard_state (); + unbind_to (count, Qnil); +#endif goto retry; } @@ -3251,7 +3305,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) cancel_echoing (); do - c = read_char (0, 0, 0, Qnil, 0); + c = read_char (0, 0, 0, Qnil, 0, &wrong_kboard_jmpbuf); while (BUFFERP (c)); /* Remove the help from the frame */ unbind_to (count, Qnil); @@ -3261,7 +3315,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) { cancel_echoing (); do - c = read_char (0, 0, 0, Qnil, 0); + c = read_char (0, 0, 0, Qnil, 0, &wrong_kboard_jmpbuf); while (BUFFERP (c)); } } @@ -4522,10 +4576,11 @@ timer_check (do_it_now) int count = SPECPDL_INDEX (); Lisp_Object old_deactivate_mark = Vdeactivate_mark; +#if 0 /* This shouldn't be necessary anymore. --lorentey */ /* On unbind_to, resume allowing input from any kboard, if that was true before. */ record_single_kboard_state (); - +#endif /* Mark the timer as triggered to prevent problems if the lisp code fails to reschedule it right. */ vector[0] = Qt; @@ -8739,6 +8794,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, int junk; #endif + jmp_buf *volatile wrong_kboard_jmpbuf = alloca (sizeof (jmp_buf)); + struct gcpro gcpro1; GCPRO1 (fake_prefixed_keys); @@ -8775,7 +8832,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, /* Read the first char of the sequence specially, before setting up any keymaps, in case a filter runs and switches buffers on us. */ first_event = read_char (NILP (prompt), 0, submaps, last_nonmenu_event, - &junk); + &junk, NULL); #endif /* GOBBLE_FIRST_EVENT */ orig_local_map = get_local_map (PT, current_buffer, Qlocal_map); @@ -8951,8 +9008,17 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, #ifdef MULTI_KBOARD KBOARD *interrupted_kboard = current_kboard; struct frame *interrupted_frame = SELECTED_FRAME (); - if (setjmp (wrong_kboard_jmpbuf)) + if (setjmp (*wrong_kboard_jmpbuf)) { + int found = 0; + struct kboard *k; + + for (k = all_kboards; k; k = k->next_kboard) + if (k == interrupted_kboard) + found = 1; + if (!found) + abort (); + if (!NILP (delayed_switch_frame)) { interrupted_kboard->kbd_queue @@ -8986,7 +9052,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, #endif key = read_char (NILP (prompt), nmaps, (Lisp_Object *) submaps, last_nonmenu_event, - &used_mouse_menu); + &used_mouse_menu, wrong_kboard_jmpbuf); } /* read_char returns t when it shows a menu and the user rejects it. @@ -10466,7 +10532,7 @@ interrupt_signal (signalnum) /* If we don't have an argument, */ { /* If there are no frames there, let's pretend that we are a well-behaving UN*X program and quit. */ - fatal_error_signal (SIGTERM); + Fkill_emacs (Qnil); } else { @@ -11034,7 +11100,8 @@ delete_kboard (kb) && FRAMEP (selected_frame) && FRAME_LIVE_P (XFRAME (selected_frame))) { - current_kboard = XFRAME (selected_frame)->terminal->kboard; + current_kboard = FRAME_KBOARD (XFRAME (selected_frame)); + single_kboard = 0; if (current_kboard == kb) abort (); } diff --git a/src/keyboard.h b/src/keyboard.h index 6c320a4fad..19a38ed744 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -305,7 +305,6 @@ struct input_event; extern Lisp_Object parse_modifiers P_ ((Lisp_Object)); extern Lisp_Object reorder_modifiers P_ ((Lisp_Object)); -extern Lisp_Object read_char P_ ((int, int, Lisp_Object *, Lisp_Object, int *)); /* Parent keymap of terminal-local function-key-map instances. */ extern Lisp_Object Vfunction_key_map; @@ -318,13 +317,11 @@ extern int parse_menu_item P_ ((Lisp_Object, int, int)); extern void echo_now P_ ((void)); extern void init_kboard P_ ((KBOARD *)); extern void delete_kboard P_ ((KBOARD *)); -extern void single_kboard_state P_ ((void)); extern void not_single_kboard_state P_ ((KBOARD *)); extern void push_kboard P_ ((struct kboard *)); extern void push_frame_kboard P_ ((struct frame *)); extern void pop_kboard P_ ((void)); -extern void temporarily_switch_to_single_kboard P_ ((struct kboard *)); -extern void record_single_kboard_state P_ ((void)); +extern void temporarily_switch_to_single_kboard P_ ((struct frame *)); extern void record_asynch_buffer_change P_ ((void)); extern SIGTYPE input_poll_signal P_ ((int)); extern void start_polling P_ ((void)); diff --git a/src/lread.c b/src/lread.c index 6555737fa5..236ebebda1 100644 --- a/src/lread.c +++ b/src/lread.c @@ -27,6 +27,7 @@ Boston, MA 02110-1301, USA. */ #include #include #include +#include #include "lisp.h" #include "intervals.h" #include "buffer.h" @@ -434,7 +435,7 @@ static void substitute_in_interval P_ ((INTERVAL, Lisp_Object)); /* Get a character from the tty. */ -extern Lisp_Object read_char (); +extern Lisp_Object read_char P_ ((int, int, Lisp_Object *, Lisp_Object, int *, jmp_buf *)); /* Read input events until we get one that's acceptable for our purposes. @@ -459,7 +460,8 @@ read_filtered_event (no_switch_frame, ascii_required, error_nonascii, input_method) int no_switch_frame, ascii_required, error_nonascii, input_method; { - register Lisp_Object val, delayed_switch_frame; + volatile register Lisp_Object val, delayed_switch_frame; + jmp_buf *volatile wrong_kboard_jmpbuf = alloca (sizeof (jmp_buf)); #ifdef HAVE_WINDOW_SYSTEM if (display_hourglass_p) @@ -470,10 +472,12 @@ read_filtered_event (no_switch_frame, ascii_required, error_nonascii, /* Read until we get an acceptable event. */ retry: + setjmp (*wrong_kboard_jmpbuf); + val = read_char (0, 0, 0, (input_method ? Qnil : Qt), - 0); - + 0, wrong_kboard_jmpbuf); + if (BUFFERP (val)) goto retry; diff --git a/src/minibuf.c b/src/minibuf.c index 795acb1988..7f3f7fe87e 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -552,7 +552,7 @@ read_minibuf (map, initial, prompt, backup_n, expflag, if (minibuffer_auto_raise) Fraise_frame (mini_frame); - temporarily_switch_to_single_kboard (XFRAME (mini_frame)->terminal->kboard); + temporarily_switch_to_single_kboard (XFRAME (mini_frame)); /* We have to do this after saving the window configuration since that is what restores the current buffer. */ diff --git a/src/termchar.h b/src/termchar.h index f4b58f105b..9e9819b97c 100644 --- a/src/termchar.h +++ b/src/termchar.h @@ -68,8 +68,8 @@ struct tty_display_info Lisp_Object top_frame; /* The topmost frame on this tty. */ - /* The previous terminal frame we displayed on this tty. */ - struct frame *previous_terminal_frame; + /* The previous frame we displayed on this tty. */ + struct frame *previous_frame; /* Strings, numbers and flags taken from the termcap entry. */ diff --git a/src/xdisp.c b/src/xdisp.c index 6dd0a1f3e6..ca6c8f793a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10549,14 +10549,14 @@ redisplay_internal (preserve_echo_area) ++windows_or_buffers_changed; if (FRAME_TERMCAP_P (sf) - && FRAME_TTY (sf)->previous_terminal_frame != sf) + && FRAME_TTY (sf)->previous_frame != sf) { /* Since frames on a single ASCII terminal share the same display area, displaying a different frame means redisplay the whole thing. */ windows_or_buffers_changed++; SET_FRAME_GARBAGED (sf); - FRAME_TTY (sf)->previous_terminal_frame = sf; + FRAME_TTY (sf)->previous_frame = sf; } /* Set the visible flags for all frames. Do this before checking @@ -16194,7 +16194,7 @@ display_mode_line (w, face_id, format) /* Temporarily make frame's keyboard the current kboard so that kboard-local variables in the mode_line_format will get the right values. */ - push_frame_kboard (it.f); + push_kboard (FRAME_KBOARD (it.f)); display_mode_element (&it, 0, 0, 0, format, Qnil, 0); pop_kboard (); @@ -16908,7 +16908,7 @@ are the selected window and the window's buffer). */) = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil))); } - push_frame_kboard (it.f); + push_kboard (FRAME_KBOARD (it.f)); display_mode_element (&it, 0, 0, 0, format, Qnil, 0); pop_kboard (); -- 2.20.1