Commit b3e6f69c authored by Karoly Lorentey's avatar Karoly Lorentey
Browse files

Overhaul and simplify single_kboard API. Allow calls to `recursive-edit' in...

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
parent 0103b7c9
...@@ -401,12 +401,6 @@ is probably not very interesting for anyone else.) ...@@ -401,12 +401,6 @@ is probably not very interesting for anyone else.)
THINGS TO DO 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' ** `delete-frame' events are handled by `special-event-map'
immediately when read by `read_char'. This is fine but it prevents immediately when read by `read_char'. This is fine but it prevents
higher-level keymaps from binding that event to get notified of the higher-level keymaps from binding that event to get notified of the
...@@ -466,6 +460,10 @@ THINGS TO DO ...@@ -466,6 +460,10 @@ THINGS TO DO
Emacs with GTK support. If you want to play around with GTK 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 multidisplay (and don't mind core dumps), you can edit src/config.h
and define HAVE_GTK_MULTIDISPLAY there by hand. 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 ** Audit `face-valid-attribute-values' usage in customize and
elsewhere. Its return value depends on the current window system. elsewhere. Its return value depends on the current window system.
...@@ -477,10 +475,6 @@ THINGS TO DO ...@@ -477,10 +475,6 @@ THINGS TO DO
** frames-on-display-list should also accept frames. ** 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' ** Consider the `tty-type' frame parameter and the `display-tty-type'
function. They serve the exact same purpose. I think it may be function. They serve the exact same purpose. I think it may be
a good idea to eliminate one of them, preferably `tty-type'. a good idea to eliminate one of them, preferably `tty-type'.
...@@ -514,10 +508,6 @@ THINGS TO DO ...@@ -514,10 +508,6 @@ THINGS TO DO
instead of delete-frame-functions), instead of delete-frame-functions),
after-delete-terminal-functions, after-create-terminal-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 ** BULK RENAME: The `display-' prefix of new Lisp-level functions
conflicts with stuff like `display-time-mode'. Use `device-' conflicts with stuff like `display-time-mode'. Use `device-'
or `terminal-' instead. I think I prefer `terminal-'. or `terminal-' instead. I think I prefer `terminal-'.
...@@ -583,6 +573,8 @@ THINGS TO DO ...@@ -583,6 +573,8 @@ THINGS TO DO
by changing the modelines or some other frame-local display element by changing the modelines or some other frame-local display element
on the locked out displays. 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 ** 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 connection is closed and then later I try to connect to a new X
session: session:
...@@ -670,6 +662,9 @@ THINGS TO DO ...@@ -670,6 +662,9 @@ THINGS TO DO
terminals in xterm and konsole. The screen does flicker a bit, terminals in xterm and konsole. The screen does flicker a bit,
but it's so quick it isn't noticable. 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. ** Move baud_rate to struct display.
** Implement support for starting an interactive Emacs session without ** Implement support for starting an interactive Emacs session without
...@@ -1414,6 +1409,32 @@ DIARY OF CHANGES ...@@ -1414,6 +1409,32 @@ DIARY OF CHANGES
against `delete-frame-functions' throwing an error and preventing a against `delete-frame-functions' throwing an error and preventing a
frame delete. (patch-475) 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 ;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d
...@@ -755,9 +755,17 @@ The following commands are accepted by the client: ...@@ -755,9 +755,17 @@ The following commands are accepted by the client:
(with-selected-frame frame (with-selected-frame frame
(switch-to-buffer (or (car buffers) (switch-to-buffer (or (car buffers)
(get-buffer-create "*scratch*"))) (get-buffer-create "*scratch*")))
(display-startup-echo-area-message)) (display-startup-echo-area-message)
(unless inhibit-splash-screen (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. ;; Delete the client if necessary.
(cond (cond
......
...@@ -875,12 +875,11 @@ If KEYS is omitted or nil, the return value of `this-command-keys' is used. */) ...@@ -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; real_this_command= save_real_this_command;
current_kboard->Vlast_command = save_last_command; current_kboard->Vlast_command = save_last_command;
temporarily_switch_to_single_kboard (NULL);
{ {
Lisp_Object val; Lisp_Object val;
specbind (Qcommand_debug_status, Qnil); specbind (Qcommand_debug_status, Qnil);
temporarily_switch_to_single_kboard (NULL);
val = Ffuncall (count + 1, args); val = Ffuncall (count + 1, args);
UNGCPRO; UNGCPRO;
return unbind_to (speccount, val); return unbind_to (speccount, val);
......
...@@ -3308,7 +3308,7 @@ is nil and `use-dialog-box' is non-nil. */) ...@@ -3308,7 +3308,7 @@ is nil and `use-dialog-box' is non-nil. */)
Fraise_frame (mini_frame); 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); obj = read_filtered_event (1, 0, 0, 0);
cursor_in_echo_area = 0; cursor_in_echo_area = 0;
......
...@@ -1406,7 +1406,6 @@ The functions are run with one arg, the frame to be deleted. */) ...@@ -1406,7 +1406,6 @@ The functions are run with one arg, the frame to be deleted. */)
if (!NILP (Vrun_hooks) if (!NILP (Vrun_hooks)
&& NILP (Fframe_parameter (frame, intern ("tooltip")))) && NILP (Fframe_parameter (frame, intern ("tooltip"))))
{ {
int count = SPECPDL_INDEX ();
Lisp_Object args[2]; Lisp_Object args[2];
struct gcpro gcpro1, gcpro2; struct gcpro gcpro1, gcpro2;
......
...@@ -670,7 +670,6 @@ static void save_getcjmp (); ...@@ -670,7 +670,6 @@ static void save_getcjmp ();
static void restore_getcjmp P_ ((jmp_buf)); static void restore_getcjmp P_ ((jmp_buf));
static Lisp_Object apply_modifiers P_ ((int, Lisp_Object)); static Lisp_Object apply_modifiers P_ ((int, Lisp_Object));
static void clear_event P_ ((struct input_event *)); 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 Lisp_Object restore_kboard_configuration P_ ((Lisp_Object));
static SIGTYPE interrupt_signal P_ ((int signalnum)); static SIGTYPE interrupt_signal P_ ((int signalnum));
static void handle_interrupt P_ ((void)); static void handle_interrupt P_ ((void));
...@@ -1034,7 +1033,8 @@ This function is called by the editor initialization to begin editing. */) ...@@ -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 like it is done in the splash screen display, we have to
make sure that we restore single_kboard as command_loop_1 make sure that we restore single_kboard as command_loop_1
would have done if it were left normally. */ 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); record_unwind_protect (recursive_edit_unwind, buffer);
recursive_edit_1 (); recursive_edit_1 ();
...@@ -1054,6 +1054,8 @@ recursive_edit_unwind (buffer) ...@@ -1054,6 +1054,8 @@ recursive_edit_unwind (buffer)
} }
#if 0 /* These two functions are now replaced with
temporarily_switch_to_single_kboard. */
static void static void
any_kboard_state () any_kboard_state ()
{ {
...@@ -1084,6 +1086,7 @@ single_kboard_state () ...@@ -1084,6 +1086,7 @@ single_kboard_state ()
single_kboard = 1; single_kboard = 1;
#endif #endif
} }
#endif
/* If we're in single_kboard state for kboard KBOARD, /* If we're in single_kboard state for kboard KBOARD,
get out of it. */ get out of it. */
...@@ -1126,13 +1129,6 @@ push_kboard (k) ...@@ -1126,13 +1129,6 @@ push_kboard (k)
#endif #endif
} }
void
push_frame_kboard (f)
FRAME_PTR f;
{
push_kboard (f->terminal->kboard);
}
void void
pop_kboard () pop_kboard ()
{ {
...@@ -1153,37 +1149,55 @@ pop_kboard () ...@@ -1153,37 +1149,55 @@ pop_kboard ()
{ {
/* The terminal we remembered has been deleted. */ /* The terminal we remembered has been deleted. */
current_kboard = FRAME_KBOARD (SELECTED_FRAME ()); current_kboard = FRAME_KBOARD (SELECTED_FRAME ());
single_kboard = 0;
} }
kboard_stack = p->next; kboard_stack = p->next;
xfree (p); xfree (p);
#endif #endif
} }
/* Switch to single_kboard mode. If K is non-nil, set it as the /* Switch to single_kboard mode, making current_kboard the only KBOARD
current keyboard. Use record_unwind_protect to return to the from which further input is accepted. If F is non-nil, set its
previous state later. */ 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 void
temporarily_switch_to_single_kboard (k) temporarily_switch_to_single_kboard (f)
struct kboard *k; struct frame *f;
{ {
#ifdef MULTI_KBOARD #ifdef MULTI_KBOARD
int was_locked = single_kboard; int was_locked = single_kboard;
if (was_locked) if (was_locked)
{ {
if (k != NULL) if (f != NULL && FRAME_KBOARD (f) != current_kboard)
push_kboard (k); /* 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 else
/* This call is unnecessary, but helps
`restore_kboard_configuration' discover if somebody changed
`current_kboard' behind our back. */
push_kboard (current_kboard); push_kboard (current_kboard);
} }
else if (k != NULL) else if (f != NULL)
current_kboard = k; current_kboard = FRAME_KBOARD (f);
single_kboard_state (); single_kboard = 1;
record_unwind_protect (restore_kboard_configuration, record_unwind_protect (restore_kboard_configuration,
(was_locked ? Qt : Qnil)); (was_locked ? Qt : Qnil));
#endif #endif
} }
#if 0 /* This function is not needed anymore. */
void void
record_single_kboard_state () record_single_kboard_state ()
{ {
...@@ -1192,17 +1206,22 @@ record_single_kboard_state () ...@@ -1192,17 +1206,22 @@ record_single_kboard_state ()
record_unwind_protect (restore_kboard_configuration, record_unwind_protect (restore_kboard_configuration,
(single_kboard ? Qt : Qnil)); (single_kboard ? Qt : Qnil));
} }
#endif
static Lisp_Object static Lisp_Object
restore_kboard_configuration (was_locked) restore_kboard_configuration (was_locked)
Lisp_Object was_locked; Lisp_Object was_locked;
{ {
if (NILP (was_locked)) if (NILP (was_locked))
any_kboard_state (); single_kboard = 0;
else else
{ {
single_kboard_state (); struct kboard *prev = current_kboard;
single_kboard = 1;
pop_kboard (); pop_kboard ();
/* The pop should not change the kboard. */
if (single_kboard && current_kboard != prev)
abort ();
} }
return Qnil; return Qnil;
} }
...@@ -1253,9 +1272,11 @@ cmd_error (data) ...@@ -1253,9 +1272,11 @@ cmd_error (data)
Vquit_flag = Qnil; Vquit_flag = Qnil;
Vinhibit_quit = Qnil; Vinhibit_quit = Qnil;
#if 0 /* This shouldn't be necessary anymore. --lorentey */
#ifdef MULTI_KBOARD #ifdef MULTI_KBOARD
if (command_loop_level == 0 && minibuf_level == 0) if (command_loop_level == 0 && minibuf_level == 0)
any_kboard_state (); any_kboard_state ();
#endif
#endif #endif
return make_number (0); return make_number (0);
...@@ -1340,10 +1361,12 @@ command_loop () ...@@ -1340,10 +1361,12 @@ command_loop ()
while (1) while (1)
{ {
internal_catch (Qtop_level, top_level_1, Qnil); 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 /* Reset single_kboard in case top-level set it while
evaluating an -f option, or we are stuck there for some evaluating an -f option, or we are stuck there for some
other reason. */ other reason. */
any_kboard_state (); any_kboard_state ();
#endif
internal_catch (Qtop_level, command_loop_2, Qnil); internal_catch (Qtop_level, command_loop_2, Qnil);
executing_kbd_macro = Qnil; executing_kbd_macro = Qnil;
...@@ -1460,9 +1483,11 @@ command_loop_1 () ...@@ -1460,9 +1483,11 @@ command_loop_1 ()
int no_direct; int no_direct;
int prev_modiff = 0; int prev_modiff = 0;
struct buffer *prev_buffer = NULL; struct buffer *prev_buffer = NULL;
#if 0 /* This shouldn't be necessary anymore. --lorentey */
#ifdef MULTI_KBOARD #ifdef MULTI_KBOARD
int was_locked = single_kboard; int was_locked = single_kboard;
#endif #endif
#endif
int already_adjusted = 0; int already_adjusted = 0;
current_kboard->Vprefix_arg = Qnil; current_kboard->Vprefix_arg = Qnil;
...@@ -1919,10 +1944,11 @@ command_loop_1 () ...@@ -1919,10 +1944,11 @@ command_loop_1 ()
if (!NILP (current_kboard->defining_kbd_macro) if (!NILP (current_kboard->defining_kbd_macro)
&& NILP (current_kboard->Vprefix_arg)) && NILP (current_kboard->Vprefix_arg))
finalize_kbd_macro_chars (); finalize_kbd_macro_chars ();
#if 0 /* This shouldn't be necessary anymore. --lorentey */
#ifdef MULTI_KBOARD #ifdef MULTI_KBOARD
if (!was_locked) if (!was_locked)
any_kboard_state (); any_kboard_state ();
#endif
#endif #endif
} }
} }
...@@ -2405,10 +2431,6 @@ Lisp_Object print_help (); ...@@ -2405,10 +2431,6 @@ Lisp_Object print_help ();
static Lisp_Object kbd_buffer_get_event (); static Lisp_Object kbd_buffer_get_event ();
static void record_char (); static void record_char ();
#ifdef MULTI_KBOARD
static jmp_buf wrong_kboard_jmpbuf;
#endif
#define STOP_POLLING \ #define STOP_POLLING \
do { if (! polling_stopped_here) stop_polling (); \ do { if (! polling_stopped_here) stop_polling (); \
polling_stopped_here = 1; } while (0) polling_stopped_here = 1; } while (0)
...@@ -2435,15 +2457,19 @@ do { if (polling_stopped_here) start_polling (); \ ...@@ -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 if we used a mouse menu to read the input, or zero otherwise. If
USED_MOUSE_MENU is null, we don't dereference it. 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. */ Value is t if we showed a menu and the user rejected it. */
Lisp_Object 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 commandflag;
int nmaps; int nmaps;
Lisp_Object *maps; Lisp_Object *maps;
Lisp_Object prev_event; Lisp_Object prev_event;
int *used_mouse_menu; int *used_mouse_menu;
jmp_buf *wrong_kboard_jmpbuf;
{ {
volatile Lisp_Object c; volatile Lisp_Object c;
int count; int count;
...@@ -2456,6 +2482,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) ...@@ -2456,6 +2482,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
volatile int reread; volatile int reread;
struct gcpro gcpro1, gcpro2; struct gcpro gcpro1, gcpro2;
int polling_stopped_here = 0; int polling_stopped_here = 0;
struct kboard *orig_kboard = current_kboard;
also_record = Qnil; also_record = Qnil;
...@@ -2711,7 +2738,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) ...@@ -2711,7 +2738,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
/* This is going to exit from read_char /* This is going to exit from read_char
so we had better get rid of this frame's stuff. */ so we had better get rid of this frame's stuff. */
UNGCPRO; UNGCPRO;
longjmp (wrong_kboard_jmpbuf, 1); if (wrong_kboard_jmpbuf == NULL)
abort ();
longjmp (*wrong_kboard_jmpbuf, 1);
} }
} }
#endif #endif
...@@ -2845,6 +2874,20 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) ...@@ -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 /* If this has become non-nil here, it has been set by a timer
or sentinel or filter. */ or sentinel or filter. */
if (CONSP (Vunread_command_events)) if (CONSP (Vunread_command_events))
...@@ -2893,7 +2936,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) ...@@ -2893,7 +2936,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
/* This is going to exit from read_char /* This is going to exit from read_char
so we had better get rid of this frame's stuff. */ so we had better get rid of this frame's stuff. */
UNGCPRO; UNGCPRO;
longjmp (wrong_kboard_jmpbuf, 1); if (wrong_kboard_jmpbuf == NULL)
abort ();
longjmp (*wrong_kboard_jmpbuf, 1);
} }
} }
#endif #endif
...@@ -2940,7 +2985,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) ...@@ -2940,7 +2985,9 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
/* This is going to exit from read_char /* This is going to exit from read_char
so we had better get rid of this frame's stuff. */ so we had better get rid of this frame's stuff. */
UNGCPRO; UNGCPRO;
longjmp (wrong_kboard_jmpbuf, 1); if (wrong_kboard_jmpbuf == NULL)
abort ();
longjmp (*wrong_kboard_jmpbuf, 1);
} }
#endif #endif
} }
...@@ -2994,8 +3041,12 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) ...@@ -2994,8 +3041,12 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
if (!NILP (tem)) if (!NILP (tem))
{ {
#if 0 /* This shouldn't be necessary anymore. --lorentey */
int was_locked = single_kboard; int was_locked = single_kboard;
int count = SPECPDL_INDEX ();
record_single_kboard_state ();
#endif
last_input_char = c; last_input_char = c;
Fcommand_execute (tem, Qnil, Fvector (1, &last_input_char), Qt); Fcommand_execute (tem, Qnil, Fvector (1, &last_input_char), Qt);
...@@ -3006,9 +3057,12 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) ...@@ -3006,9 +3057,12 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
example banishing the mouse under mouse-avoidance-mode. */ example banishing the mouse under mouse-avoidance-mode. */
timer_resume_idle (); timer_resume_idle ();
#if 0 /* This shouldn't be necessary anymore. --lorentey */
/* Resume allowing input from any kboard, if that was true before. */ /* Resume allowing input from any kboard, if that was true before. */
if (!was_locked) if (!was_locked)
any_kboard_state (); any_kboard_state ();
unbind_to (count, Qnil);
#endif
goto retry; goto retry;
} }
...@@ -3251,7 +3305,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) ...@@ -3251,7 +3305,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
cancel_echoing (); cancel_echoing ();
do do
c = read_char (0, 0, 0, Qnil, 0); c = read_char (0, 0, 0, Qnil, 0, &wrong_kboard_jmpbuf);
while (BUFFERP (c)); while (BUFFERP (c));
/* Remove the help from the frame */ /* Remove the help from the frame */
unbind_to (count, Qnil); unbind_to (count, Qnil);
...@@ -3261,7 +3315,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) ...@@ -3261,7 +3315,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu)
{ {
cancel_echoing (); cancel_echoing ();
do do
c = read_char (0, 0, 0, Qnil, 0); c = read_char (0, 0, 0, Qnil, 0, &wrong_kboard_jmpbuf);
while (BUFFERP (c)); while (BUFFERP (c));