Commit 4ca927b4 authored by Karoly Lorentey's avatar Karoly Lorentey
Browse files

Fix C-g handling with multiple ttys.

src/sysdep.c (init_sys_modes): Disable interrupt and quit keys on
secondary terminals.  Added a big fat comment about this.

lib-src/emacsclient.c (init_signals): Don't pass SIGINT and SIGQUIT to Emacs.

src/keyboard.c (interrupt_signal): Exit Emacs if there are no frames
on the controlling tty.  Otherwise set internal_last_event_frame to
the controlling tty's top frame.

src/term.c (ring_bell, tty_ring_bell): Don't look at updating_frame.

git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-52
parent 8f1ce423
......@@ -133,14 +133,12 @@ THINGS TO DO
the fly in write_glyphs, which might be problematic, as color
approximation is currently done in lisp (term/tty-colors.el).)
** frame-creation-function should always create a frame that is on the
same display as the selected frame. Maybe frame-creation-function
should simply be removed and make-frame changed to do the right
thing.
** Fix interactive use of temacs. There are face-related SEGVs, most
likely because of changes in realize_default_face, realize_face.
** Very strange bug: visible-bell does not work on secondary
terminals. This might be something xterm (konsole) specific.
** Allow opening an X session after -nw.
** Find out the best way to support suspending Emacs with multiple
......@@ -149,7 +147,7 @@ THINGS TO DO
extend emacsclient to handle suspend/resume. A `kill -STOP' almost
works right now.)
** Exiting Emacs while there are emacsclient frames don't restore the
** Exiting Emacs while there are emacsclient frames doesn't restore the
ttys to their default states.
** Move baud_rate to struct display.
......@@ -182,9 +180,6 @@ THINGS TO DO
why raw terminal support is broken again. I really do need to
understand input.)
** Make sure C-g goes to the right frame with ttys. This is hard, as
SIGINT doesn't have a tty parameter. :-(
** I have seen a case when Emacs with multiple ttys fell into a loop
eating 100% of CPU time. Strace showed this loop:
......@@ -212,7 +207,8 @@ THINGS TO DO
about face problems. This can even lock up Emacs (if the recursive
frame sets single_kboard). Update: the face problems are caused by
bugs in term.el, not in multi-tty. The lockup is caused by
single_kboard mode.
single_kboard mode, and is not easily solvable. The best thing to
do is to simply refuse to create a tty frame of type `eterm'.
DIARY OF CHANGES
----------------
......@@ -520,4 +516,26 @@ DIARY OF CHANGES
(Fixed.)
-- frame-creation-function should always create a frame that is on the
same display as the selected frame. Maybe frame-creation-function
should simply be removed and make-frame changed to do the right
thing.
(Done, with a nice hack. frame-creation-function is now frame-local.)
-- Fix C-g on raw ttys.
(Done. I disabled the interrupt/quit keys on all secondary
terminals, so Emacs sees C-g as normal input. This looks like an
overkill, because emacsclient has extra code to pass SIGINT to
Emacs, so C-g should remain the interrupt/quit key on emacsclient
frames. See the next entry why implementing this distinction would
be a bad idea.)
-- Make sure C-g goes to the right frame with ttys. This is hard, as
SIGINT doesn't have a tty parameter. :-(
(Done, the previous change fixes this as a pleasant side effect.)
;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d
......@@ -299,8 +299,14 @@ init_signals (void)
{
/* Set up signal handlers. */
signal (SIGWINCH, pass_signal_to_emacs);
/* Don't pass SIGINT and SIGQUIT to Emacs, because it has no way of
deciding which terminal the signal came from. C-g is now a
normal input event on secondary terminals. */
#if 0
signal (SIGINT, pass_signal_to_emacs);
signal (SIGQUIT, pass_signal_to_emacs);
#endif
}
......
......@@ -10279,6 +10279,7 @@ interrupt_signal (signalnum) /* If we don't have an argument, */
{
/* Must preserve main program's value of errno. */
int old_errno = errno;
struct display *display;
#if defined (USG) && !defined (POSIX_SIGNALS)
/* USG systems forget handlers when they are used;
......@@ -10287,24 +10288,27 @@ interrupt_signal (signalnum) /* If we don't have an argument, */
signal (SIGQUIT, interrupt_signal);
#endif /* USG */
if (! tty_list)
/* See if we have a display on our controlling terminal. */
display = get_named_tty_display (NULL);
if (!display)
{
/* If there are no tty frames, exit Emacs.
Emacs should exit on SIGINT if and only if there are no
frames on its controlling tty and the signal came from there.
We can check for the first condition, but (alas) not for the
second. The best we can do is that we only exit if we are
sure that the SIGINT was from the controlling tty, i.e., if
there are no termcap frames.
*/
/* If there are no frames there, let's pretend that we are a
well-behaving UN*X program and quit. */
Fkill_emacs (Qnil);
errno = old_errno;
return;
}
else
{
/* Otherwise, the SIGINT was probably generated by C-g. */
/* Set internal_last_event_frame to the top frame of the
controlling tty, if we have a frame there. We disable the
interrupt key on secondary ttys, so the SIGINT must have come
from the controlling tty. */
internal_last_event_frame = display->display_info.tty->top_frame;
handle_interrupt ();
handle_interrupt ();
}
errno = old_errno;
}
......@@ -10437,7 +10441,7 @@ handle_interrupt ()
}
if (waiting_for_input && !echoing)
quit_throw_to_read_char ();
quit_throw_to_read_char ();
}
/* Handle a C-g by making read_char return C-g. */
......@@ -10700,7 +10704,8 @@ init_keyboard ()
only if the current session was a tty session. Now an Emacs
session may have multiple display types, so we always handle
SIGINT. There is special code in interrupt_signal to exit
Emacs on SIGINT when there are no termcap frames. */
Emacs on SIGINT when there are no termcap frames on the
controlling terminal. */
signal (SIGINT, interrupt_signal);
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
/* For systems with SysV TERMIO, C-g is set up for both SIGINT and
......
......@@ -1453,11 +1453,34 @@ nil means don't delete them until `list-processes' is run. */);
tty.main.c_cflag &= ~PARENB;/* Don't check parity */
}
#endif
tty.main.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */
/* Set up C-g for both SIGQUIT and SIGINT.
We don't know which we will get, but we handle both alike
so which one it really gives us does not matter. */
tty.main.c_cc[VQUIT] = quit_char;
if (tty_out->input == stdin)
{
tty.main.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */
/* Set up C-g for both SIGQUIT and SIGINT.
We don't know which we will get, but we handle both alike
so which one it really gives us does not matter. */
tty.main.c_cc[VQUIT] = quit_char;
}
else
{
/* We normally don't get interrupt or quit signals from tty
devices other than our controlling terminal; therefore,
we must handle C-g as normal input. Unfortunately, this
means that the interrupt and quit feature must be
disabled on secondary ttys, or we would not even see the
keypress.
Note that even though emacsclient could have special code
to pass SIGINT to Emacs, we should _not_ enable
interrupt/quit keys for emacsclient frames. This means
that we can't break out of loops in C code from a
secondary tty frame, but we can always decide what
display the C-g came from, which is more important from a
usability point of view. (Consider the case when two
people work together using the same Emacs instance.) */
tty.main.c_cc[VINTR] = CDISABLE;
tty.main.c_cc[VQUIT] = CDISABLE;
}
tty.main.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
tty.main.c_cc[VTIME] = 0; /* no matter how long that takes. */
#ifdef VSWTCH
......
......@@ -176,9 +176,7 @@ extern char *tgetstr ();
void
ring_bell ()
{
struct frame *f = (updating_frame
? updating_frame
: XFRAME (selected_frame));
struct frame *f = XFRAME (selected_frame);
if (!NILP (Vring_bell_function))
{
......@@ -206,10 +204,7 @@ ring_bell ()
void
tty_ring_bell ()
{
struct frame *f = (updating_frame
? updating_frame
: XFRAME (selected_frame));
struct frame *f = XFRAME (selected_frame);
struct tty_display_info *tty = FRAME_TTY (f);
OUTPUT (tty, (tty->TS_visible_bell && visible_bell
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment