summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cm.c18
-rw-r--r--src/dispnew.c58
-rw-r--r--src/frame.c5
-rw-r--r--src/keyboard.c15
-rw-r--r--src/sysdep.c96
-rw-r--r--src/term.c234
-rw-r--r--src/termchar.h10
-rw-r--r--src/termhooks.h1
8 files changed, 309 insertions, 128 deletions
diff --git a/src/cm.c b/src/cm.c
index 5ce03483b06..9f9cc0e0a34 100644
--- a/src/cm.c
+++ b/src/cm.c
@@ -64,9 +64,9 @@ int
cmputc (c)
char c;
{
- if (TTY_TERMSCRIPT (current_tty))
- putc (c & 0177, TTY_TERMSCRIPT (current_tty));
- putc (c & 0177, TTY_OUTPUT (current_tty));
+ if (current_tty->termscript)
+ putc (c & 0177, current_tty->termscript);
+ putc (c & 0177, current_tty->output);
return c;
}
@@ -136,12 +136,12 @@ cmcheckmagic (struct tty_display_info *tty)
{
if (!MagicWrap (tty) || curY (tty) >= FrameRows (tty) - 1)
abort ();
- if (TTY_TERMSCRIPT (tty))
- putc ('\r', TTY_TERMSCRIPT (tty));
- putc ('\r', TTY_OUTPUT (tty));
- if (TTY_TERMSCRIPT (tty))
- putc ('\n', TTY_TERMSCRIPT (tty));
- putc ('\n', TTY_OUTPUT (tty));
+ if (tty->termscript)
+ putc ('\r', tty->termscript);
+ putc ('\r', tty->output);
+ if (tty->termscript)
+ putc ('\n', tty->termscript);
+ putc ('\n', tty->output);
curX (tty) = 0;
curY (tty)++;
}
diff --git a/src/dispnew.c b/src/dispnew.c
index aaf3c440f34..8a3d7013c3e 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -3316,7 +3316,7 @@ DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
clear_current_matrices (f);
update_end (f);
if (FRAME_TERMCAP_P (f))
- fflush (TTY_OUTPUT (FRAME_TTY (f)));
+ fflush (FRAME_TTY (f)->output);
windows_or_buffers_changed++;
/* Mark all windows as inaccurate, so that every window will have
its redisplay done. */
@@ -3659,7 +3659,7 @@ direct_output_for_insert (g)
update_end (f);
updated_row = NULL;
if (FRAME_TERMCAP_P (f))
- fflush (TTY_OUTPUT (FRAME_TTY (f)));
+ fflush (FRAME_TTY (f)->output);
TRACE ((stderr, "direct output for insert\n"));
mark_window_display_accurate (it.window, 1);
@@ -3751,7 +3751,7 @@ direct_output_forward_char (n)
}
if (FRAME_TERMCAP_P (f))
- fflush (TTY_OUTPUT (FRAME_TTY (f)));
+ fflush (FRAME_TTY (f)->output);
redisplay_performed_directly_p = 1;
return 1;
}
@@ -3849,9 +3849,9 @@ update_frame (f, force_p, inhibit_hairy_id_p)
if (FRAME_TERMCAP_P (f))
{
- if (TTY_TERMSCRIPT (FRAME_TTY (f)))
- fflush (TTY_TERMSCRIPT (FRAME_TTY (f)));
- fflush (TTY_OUTPUT (FRAME_TTY (f)));
+ if (FRAME_TTY (f)->termscript)
+ fflush (FRAME_TTY (f)->termscript);
+ fflush (FRAME_TTY (f)->output);
}
/* Check window matrices for lost pointers. */
@@ -5133,18 +5133,18 @@ update_frame_1 (f, force_p, inhibit_id_p)
Also flush out if likely to have more than 1k buffered
otherwise. I'm told that some telnet connections get
really screwed by more than 1k output at once. */
- int outq = PENDING_OUTPUT_COUNT (TTY_OUTPUT (FRAME_TTY (f)));
+ int outq = PENDING_OUTPUT_COUNT (FRAME_TTY (f)->output);
if (outq > 900
|| (outq > 20 && ((i - 1) % preempt_count == 0)))
{
- fflush (TTY_OUTPUT (FRAME_TTY (f)));
+ fflush (FRAME_TTY (f)->output);
if (preempt_count == 1)
{
#ifdef EMACS_OUTQSIZE
if (EMACS_OUTQSIZE (0, &outq) < 0)
/* Probably not a tty. Ignore the error and reset
the outq count. */
- outq = PENDING_OUTPUT_COUNT (TTY_OUTPUT (FRAME_TTY (f)));
+ outq = PENDING_OUTPUT_COUNT (FRAME_TTY (f->output));
#endif
outq *= 10;
if (baud_rate <= outq && baud_rate > 0)
@@ -5999,7 +5999,7 @@ window_change_signal (signalnum) /* If we don't have an argument, */
if (! tty->term_initted)
continue;
- get_tty_size (fileno (TTY_INPUT (tty)), &width, &height);
+ get_tty_size (fileno (tty->input), &width, &height);
{
Lisp_Object tail, frame;
@@ -6211,15 +6211,22 @@ FILE = nil means just close any termscript file currently open. */)
(file)
Lisp_Object file;
{
- if (TTY_TERMSCRIPT (CURTTY ()) != 0)
- fclose (TTY_TERMSCRIPT (CURTTY ()));
- TTY_TERMSCRIPT (CURTTY ()) = 0;
+ struct tty_display_info *tty;
+
+ if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
+ error ("Current frame is not on a tty device");
+
+ tty = CURTTY ();
+
+ if (tty->termscript != 0)
+ fclose (tty->termscript);
+ tty->termscript = 0;
if (! NILP (file))
{
file = Fexpand_file_name (file, Qnil);
- TTY_TERMSCRIPT (CURTTY ()) = fopen (SDATA (file), "w");
- if (TTY_TERMSCRIPT (CURTTY ()) == 0)
+ tty->termscript = fopen (SDATA (file), "w");
+ if (tty->termscript == 0)
report_file_error ("Opening termscript", Fcons (file, Qnil));
}
return Qnil;
@@ -6233,20 +6240,23 @@ Control characters in STRING will have terminal-dependent effects. */)
(string)
Lisp_Object string;
{
+ struct tty_display_info *tty;
+
/* ??? Perhaps we should do something special for multibyte strings here. */
CHECK_STRING (string);
+
if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
error ("Current frame is not on a tty device");
+
+ tty = CURTTY ();
- if (TTY_TERMSCRIPT (CURTTY ()))
+ if (tty->termscript)
{
- fwrite (SDATA (string), 1, SBYTES (string),
- TTY_TERMSCRIPT (CURTTY ()));
- fflush (TTY_TERMSCRIPT (CURTTY ()));
+ fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
+ fflush (tty->termscript);
}
- fwrite (SDATA (string), 1, SBYTES (string),
- TTY_OUTPUT (CURTTY ()));
- fflush (TTY_OUTPUT (CURTTY ()));
+ fwrite (SDATA (string), 1, SBYTES (string), tty->output);
+ fflush (tty->output);
return Qnil;
}
@@ -6265,7 +6275,7 @@ terminate any keyboard macro currently executing. */)
else
ring_bell ();
if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
- fflush (TTY_OUTPUT (CURTTY ()));
+ fflush (CURTTY ()->output);
}
else
bitch_at_user ();
@@ -6283,7 +6293,7 @@ bitch_at_user ()
else
ring_bell ();
if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
- fflush (TTY_OUTPUT (CURTTY ()));
+ fflush (CURTTY ()->output);
}
diff --git a/src/frame.c b/src/frame.c
index 8ffabfa8b89..c7b5491500f 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -667,7 +667,8 @@ and the `tty-type' parameter specifies the terminal type. Example:
(make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
-Note that changing the size of one terminal frame automatically affects all. */)
+Note that changing the size of one terminal frame automatically
+affects all frames on the same terminal device. */)
(parms)
Lisp_Object parms;
{
@@ -742,7 +743,7 @@ Note that changing the size of one terminal frame automatically affects all. */
{
int width, height;
- get_tty_size (fileno (TTY_INPUT (FRAME_TTY (f))), &width, &height);
+ get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
change_frame_size (f, height, width, 0, 0, 0);
}
diff --git a/src/keyboard.c b/src/keyboard.c
index 2c6edc68f99..5bcd53a260f 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -6704,10 +6704,13 @@ tty_read_avail_input (struct display *display,
if (! tty->term_initted) /* In case we get called during bootstrap. */
return 0;
+ if (! tty->input)
+ return 0; /* The terminal is suspended. */
+
/* Determine how many characters we should *try* to read. */
#ifdef FIONREAD
/* Find out how much input is available. */
- if (ioctl (fileno (TTY_INPUT (tty)), FIONREAD, &n_to_read) < 0)
+ if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0)
{
if (! noninteractive)
return -2; /* Close this display. */
@@ -6722,7 +6725,7 @@ tty_read_avail_input (struct display *display,
#if defined (USG) || defined (DGUX) || defined(CYGWIN)
/* Read some input if available, but don't wait. */
n_to_read = sizeof cbuf;
- fcntl (fileno (TTY_INPUT (tty)), F_SETFL, O_NDELAY);
+ fcntl (fileno (tty->input), F_SETFL, O_NDELAY);
#else
you lose;
#endif
@@ -6732,7 +6735,7 @@ tty_read_avail_input (struct display *display,
NREAD is set to the number of chars read. */
do
{
- nread = emacs_read (fileno (TTY_INPUT (tty)), cbuf, n_to_read);
+ nread = emacs_read (fileno (tty->input), cbuf, n_to_read);
/* POSIX infers that processes which are not in the session leader's
process group won't get SIGHUP's at logout time. BSDI adheres to
this part standard and returns -1 from read (0) with errno==EIO
@@ -6770,7 +6773,7 @@ tty_read_avail_input (struct display *display,
#ifndef FIONREAD
#if defined (USG) || defined (DGUX) || defined (CYGWIN)
- fcntl (fileno (TTY_INPUT (tty)), F_SETFL, 0);
+ fcntl (fileno (tty->input), F_SETFL, 0);
#endif /* USG or DGUX or CYGWIN */
#endif /* no FIONREAD */
@@ -10168,7 +10171,7 @@ On such systems, Emacs starts a subshell instead of suspending. */)
call1 (Vrun_hooks, intern ("suspend-hook"));
GCPRO1 (stuffstring);
- get_tty_size (fileno (TTY_INPUT (CURTTY ())), &old_width, &old_height);
+ get_tty_size (fileno (CURTTY ()->input), &old_width, &old_height);
reset_all_sys_modes ();
/* sys_suspend can get an error if it tries to fork a subshell
and the system resources aren't available for that. */
@@ -10184,7 +10187,7 @@ On such systems, Emacs starts a subshell instead of suspending. */)
/* Check if terminal/window size has changed.
Note that this is not useful when we are running directly
with a window system; but suspend should be disabled in that case. */
- get_tty_size (fileno (TTY_INPUT (CURTTY ())), &width, &height);
+ get_tty_size (fileno (CURTTY ()->input), &width, &height);
if (width != old_width || height != old_height)
change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);
diff --git a/src/sysdep.c b/src/sysdep.c
index febf59253e1..d4693f99a94 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -274,7 +274,7 @@ discard_tty_input ()
#ifdef VMS
end_kbd_input ();
- SYS$QIOW (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
+ SYS$QIOW (0, fileno (CURTTY()->input), IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
&buf.main, 0, 0, terminator_mask, 0, 0);
queue_kbd_input ();
#else /* not VMS */
@@ -284,7 +284,8 @@ discard_tty_input ()
for (tty = tty_list; tty; tty = tty->next)
{
int zero = 0;
- ioctl (fileno (TTY_INPUT (tty)), TIOCFLUSH, &zero);
+ if (tty->input)
+ ioctl (fileno (tty->input), TIOCFLUSH, &zero);
}
}
#else /* not Apollo */
@@ -296,8 +297,11 @@ discard_tty_input ()
struct tty_display_info *tty;
for (tty = tty_list; tty; tty = tty->next)
{
- EMACS_GET_TTY (fileno (TTY_INPUT (tty)), &buf);
- EMACS_SET_TTY (fileno (TTY_INPUT (tty)), &buf, 0);
+ if (tty->input) /* Is the device suspended? */
+ {
+ EMACS_GET_TTY (fileno (tty->input), &buf);
+ EMACS_SET_TTY (fileno (tty->input), &buf, 0);
+ }
}
}
#endif /* not MSDOS */
@@ -322,7 +326,7 @@ stuff_char (char c)
/* Should perhaps error if in batch mode */
#ifdef TIOCSTI
- ioctl (fileno (TTY_INPUT (CURTTY())), TIOCSTI, &c);
+ ioctl (fileno (CURTTY()->input), TIOCSTI, &c);
#else /* no TIOCSTI */
error ("Cannot stuff terminal input characters in this version of Unix");
#endif /* no TIOCSTI */
@@ -1005,7 +1009,7 @@ request_sigio ()
return;
/* XXX CURTTY() is bogus here. */
- ioctl (fileno (TTY_INPUT (CURTTY ())), FIOASYNC, &on);
+ ioctl (fileno (CURTTY ()->input), FIOASYNC, &on);
interrupts_deferred = 0;
}
@@ -1018,7 +1022,7 @@ unrequest_sigio ()
return;
/* XXX CURTTY() is bogus here. */
- ioctl (fileno (TTY_INPUT (CURTTY ())), FIOASYNC, &off);
+ ioctl (fileno (CURTTY ()->input), FIOASYNC, &off);
interrupts_deferred = 1;
}
@@ -1366,6 +1370,9 @@ nil means don't delete them until `list-processes' is run. */);
if (noninteractive)
return;
+ if (!tty_out->output)
+ return; /* The tty is suspended. */
+
#ifdef VMS
if (!input_ef)
input_ef = get_kbd_event_flag ();
@@ -1404,13 +1411,13 @@ nil means don't delete them until `list-processes' is run. */);
unconditionally will not cause any problems. */
if (! read_socket_hook && EQ (Vinitial_window_system, Qnil))
#endif
- narrow_foreground_group (fileno (TTY_INPUT (tty_out)));
+ narrow_foreground_group (fileno (tty_out->input));
#endif
if (! tty_out->old_tty)
tty_out->old_tty = (struct emacs_tty *) xmalloc (sizeof (struct emacs_tty));
- EMACS_GET_TTY (fileno (TTY_INPUT (tty_out)), tty_out->old_tty);
+ EMACS_GET_TTY (fileno (tty_out->input), tty_out->old_tty);
tty = *tty_out->old_tty;
@@ -1626,23 +1633,23 @@ nil means don't delete them until `list-processes' is run. */);
dos_ttraw ();
#endif
- EMACS_SET_TTY (fileno (TTY_INPUT (tty_out)), &tty, 0);
+ EMACS_SET_TTY (fileno (tty_out->input), &tty, 0);
/* This code added to insure that, if flow-control is not to be used,
we have an unlocked terminal at the start. */
#ifdef TCXONC
- if (!tty_out->flow_control) ioctl (fileno (TTY_INPUT (tty_out)), TCXONC, 1);
+ if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TCXONC, 1);
#endif
#ifndef APOLLO
#ifdef TIOCSTART
- if (!tty_out->flow_control) ioctl (fileno (TTY_INPUT (tty_out)), TIOCSTART, 0);
+ if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TIOCSTART, 0);
#endif
#endif
#if defined (HAVE_TERMIOS) || defined (HPUX9)
#ifdef TCOON
- if (!tty_out->flow_control) tcflow (fileno (TTY_INPUT (tty_out)), TCOON);
+ if (!tty_out->flow_control) tcflow (fileno (tty_out->input), TCOON);
#endif
#endif
@@ -1662,7 +1669,7 @@ nil means don't delete them until `list-processes' is run. */);
#ifdef VMS
/* Appears to do nothing when in PASTHRU mode.
- SYS$QIOW (0, fileno (TTY_INPUT (tty_out)), IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
+ SYS$QIOW (0, fileno (tty_out->input), IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
interrupt_signal, oob_chars, 0, 0, 0, 0);
*/
queue_kbd_input (0);
@@ -1673,10 +1680,10 @@ nil means don't delete them until `list-processes' is run. */);
#ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
if (interrupt_input)
{
- old_fcntl_owner[fileno (TTY_INPUT (tty_out))] =
- fcntl (fileno (TTY_INPUT (tty_out)), F_GETOWN, 0);
- fcntl (fileno (TTY_INPUT (tty_out)), F_SETOWN, getpid ());
- init_sigio (fileno (TTY_INPUT (tty_out)));
+ old_fcntl_owner[fileno (tty_out->input)] =
+ fcntl (fileno (tty_out->input), F_GETOWN, 0);
+ fcntl (fileno (tty_out->input), F_SETOWN, getpid ());
+ init_sigio (fileno (tty_out->input));
}
#endif /* F_GETOWN */
#endif /* F_SETOWN_BUG */
@@ -1684,7 +1691,7 @@ nil means don't delete them until `list-processes' is run. */);
#ifdef BSD4_1
if (interrupt_input)
- init_sigio (fileno (TTY_INPUT (tty_out)));
+ init_sigio (fileno (tty_out->input));
#endif
#ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
@@ -1694,9 +1701,9 @@ nil means don't delete them until `list-processes' is run. */);
/* This symbol is defined on recent USG systems.
Someone says without this call USG won't really buffer the file
even with a call to setbuf. */
- setvbuf (TTY_OUTPUT (tty_out), (char *) _sobuf, _IOFBF, sizeof _sobuf);
+ setvbuf (tty_out->output, (char *) _sobuf, _IOFBF, sizeof _sobuf);
#else
- setbuf (TTY_OUTPUT (tty_out), (char *) _sobuf);
+ setbuf (tty_out->output, (char *) _sobuf);
#endif
tty_set_terminal_modes (tty_out->display);
@@ -1867,10 +1874,13 @@ reset_sys_modes (tty_out)
if (!tty_out->term_initted)
return;
+ if (!tty_out->output)
+ return; /* The tty is suspended. */
+
/* Go to and clear the last line of the terminal. */
cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
-
+
/* Code adapted from tty_clear_end_of_line. */
if (tty_out->TS_clr_line)
{
@@ -1880,13 +1890,13 @@ reset_sys_modes (tty_out)
{ /* have to do it the hard way */
int i;
turn_off_insert (tty_out);
-
+
for (i = curX (tty_out); i < FrameCols (tty_out) - 1; i++)
- {
- fputc (' ', TTY_OUTPUT (tty_out));
- }
+ {
+ fputc (' ', tty_out->output);
+ }
}
-
+
cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
fflush (tty_out->output);
@@ -1902,11 +1912,11 @@ reset_sys_modes (tty_out)
#endif
tty_reset_terminal_modes (tty_out->display);
- fflush (TTY_OUTPUT (tty_out));
+ fflush (tty_out->output);
#ifdef BSD_SYSTEM
#ifndef BSD4_1
/* Avoid possible loss of output when changing terminal modes. */
- fsync (fileno (TTY_OUTPUT (tty_out)));
+ fsync (fileno (tty_out->output));
#endif
#endif
@@ -1915,24 +1925,24 @@ reset_sys_modes (tty_out)
#ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
if (interrupt_input)
{
- reset_sigio (fileno (TTY_INPUT (tty_out)));
- fcntl (fileno (TTY_INPUT (tty_out)), F_SETOWN,
- old_fcntl_owner[fileno (TTY_INPUT (tty_out))]);
+ reset_sigio (fileno (tty_out->input));
+ fcntl (fileno (tty_out->input), F_SETOWN,
+ old_fcntl_owner[fileno (tty_out->input)]);
}
#endif /* F_SETOWN */
#endif /* F_SETOWN_BUG */
#ifdef O_NDELAY
- fcntl (fileno (TTY_INPUT (tty_out)), F_SETFL,
- fcntl (fileno (TTY_INPUT (tty_out)), F_GETFL, 0) & ~O_NDELAY);
+ fcntl (fileno (tty_out->input), F_SETFL,
+ fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NDELAY);
#endif
#endif /* F_SETFL */
#ifdef BSD4_1
if (interrupt_input)
- reset_sigio (fileno (TTY_INPUT (tty_out)));
+ reset_sigio (fileno (tty_out->input));
#endif /* BSD4_1 */
if (tty_out->old_tty)
- while (EMACS_SET_TTY (fileno (TTY_INPUT (tty_out)),
+ while (EMACS_SET_TTY (fileno (tty_out->input),
tty_out->old_tty, 0) < 0 && errno == EINTR)
;
@@ -1952,7 +1962,7 @@ reset_sys_modes (tty_out)
#endif
#ifdef BSD_PGRPS
- widen_foreground_group (fileno (TTY_INPUT (tty_out)));
+ widen_foreground_group (fileno (tty_out->input));
#endif
}
@@ -2017,9 +2027,9 @@ init_vms_input ()
{
int status;
- if (fileno (TTY_INPUT (CURTTY())) == 0)
+ if (fileno (CURTTY ()->input)) == 0)
{
- status = SYS$ASSIGN (&input_dsc, &fileno (TTY_INPUT (CURTTY())), 0, 0);
+ status = SYS$ASSIGN (&input_dsc, &fileno (CURTTY ()->input)), 0, 0);
if (! (status & 1))
LIB$STOP (status);
}
@@ -2030,7 +2040,7 @@ init_vms_input ()
void
stop_vms_input ()
{
- return SYS$DASSGN (fileno (TTY_INPUT (CURTTY())));
+ return SYS$DASSGN (fileno (CURTTY ()->input)));
}
short input_buffer;
@@ -2046,7 +2056,7 @@ queue_kbd_input ()
waiting_for_ast = 0;
stop_input = 0;
- status = SYS$QIO (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK,
+ status = SYS$QIO (0, fileno (CURTTY()->input), IO$_READVBLK,
&input_iosb, kbd_input_ast, 1,
&input_buffer, 1, 0, terminator_mask, 0, 0);
}
@@ -2163,7 +2173,7 @@ end_kbd_input ()
#endif
if (LIB$AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
{
- SYS$CANCEL (fileno (TTY_INPUT (CURTTY())));
+ SYS$CANCEL (fileno (CURTTY()->input));
return;
}
@@ -2172,7 +2182,7 @@ end_kbd_input ()
SYS$CLREF (input_ef);
waiting_for_ast = 1;
stop_input = 1;
- SYS$CANCEL (fileno (TTY_INPUT (CURTTY())));
+ SYS$CANCEL (fileno (CURTTY()->input));
SYS$SETAST (1);
SYS$WAITFR (input_ef);
waiting_for_ast = 0;
diff --git a/src/term.c b/src/term.c
index e3b176c51ea..785f2a3bb33 100644
--- a/src/term.c
+++ b/src/term.c
@@ -106,9 +106,15 @@ void delete_tty_output P_ ((struct frame *));
Lisp_Object Vring_bell_function;
-/* Functions to call after a tty was deleted. */
+/* Functions to call after deleting a tty. */
Lisp_Object Vdelete_tty_after_functions;
+/* Functions to call after suspending a tty. */
+Lisp_Object Vsuspend_tty_functions;
+
+/* Functions to call after resuming a tty. */
+Lisp_Object Vresume_tty_functions;
+
/* Chain of all displays currently in use. */
struct display *display_list;
@@ -231,10 +237,13 @@ tty_set_terminal_modes (struct display *display)
{
struct tty_display_info *tty = display->display_info.tty;
- OUTPUT_IF (tty, tty->TS_termcap_modes);
- OUTPUT_IF (tty, tty->TS_cursor_visible);
- OUTPUT_IF (tty, tty->TS_keypad_mode);
- losecursor (tty);
+ if (tty->output)
+ {
+ OUTPUT_IF (tty, tty->TS_termcap_modes);
+ OUTPUT_IF (tty, tty->TS_cursor_visible);
+ OUTPUT_IF (tty, tty->TS_keypad_mode);
+ losecursor (tty);
+ }
}
/* Reset termcap modes before exiting Emacs. */
@@ -243,16 +252,19 @@ void
tty_reset_terminal_modes (struct display *display)
{
struct tty_display_info *tty = display->display_info.tty;
-
- turn_off_highlight (tty);
- turn_off_insert (tty);
- OUTPUT_IF (tty, tty->TS_end_keypad_mode);
- OUTPUT_IF (tty, tty->TS_cursor_normal);
- OUTPUT_IF (tty, tty->TS_end_termcap_modes);
- OUTPUT_IF (tty, tty->TS_orig_pair);
- /* Output raw CR so kernel can track the cursor hpos. */
- current_tty = tty;
- cmputc ('\r');
+
+ if (tty->output)
+ {
+ turn_off_highlight (tty);
+ turn_off_insert (tty);
+ OUTPUT_IF (tty, tty->TS_end_keypad_mode);
+ OUTPUT_IF (tty, tty->TS_cursor_normal);
+ OUTPUT_IF (tty, tty->TS_end_termcap_modes);
+ OUTPUT_IF (tty, tty->TS_orig_pair);
+ /* Output raw CR so kernel can track the cursor hpos. */
+ current_tty = tty;
+ cmputc ('\r');
+ }
}
void
@@ -619,9 +631,9 @@ tty_clear_end_of_line (int first_unused_hpos)
for (i = curX (tty); i < first_unused_hpos; i++)
{
- if (TTY_TERMSCRIPT (tty))
- fputc (' ', TTY_TERMSCRIPT (tty));
- fputc (' ', TTY_OUTPUT (tty));
+ if (tty->termscript)
+ fputc (' ', tty->termscript);
+ fputc (' ', tty->output);
}
cmplus (tty, first_unused_hpos - curX (tty));
}
@@ -807,12 +819,12 @@ tty_write_glyphs (struct glyph *string, int len)
if (produced > 0)
{
fwrite (conversion_buffer, 1, produced,
- TTY_OUTPUT (tty));
- if (ferror (TTY_OUTPUT (tty)))
- clearerr (TTY_OUTPUT (tty));
- if (TTY_TERMSCRIPT (tty))
+ tty->output);
+ if (ferror (tty->output))
+ clearerr (tty->output);
+ if (tty->termscript)
fwrite (conversion_buffer, 1, produced,
- TTY_TERMSCRIPT (tty));
+ tty->termscript);
}
len -= consumed;
n -= consumed;
@@ -833,12 +845,12 @@ tty_write_glyphs (struct glyph *string, int len)
if (terminal_coding.produced > 0)
{
fwrite (conversion_buffer, 1, terminal_coding.produced,
- TTY_OUTPUT (tty));
- if (ferror (TTY_OUTPUT (tty)))
- clearerr (TTY_OUTPUT (tty));
- if (TTY_TERMSCRIPT (tty))
+ tty->output);
+ if (ferror (tty->output))
+ clearerr (tty->output);
+ if (tty->termscript)
fwrite (conversion_buffer, 1, terminal_coding.produced,
- TTY_TERMSCRIPT (tty));
+ tty->termscript);
}
}
@@ -927,12 +939,12 @@ tty_insert_glyphs (struct glyph *start, int len)
if (produced > 0)
{
fwrite (conversion_buffer, 1, produced,
- TTY_OUTPUT (tty));
- if (ferror (TTY_OUTPUT (tty)))
- clearerr (TTY_OUTPUT (tty));
- if (TTY_TERMSCRIPT (tty))
+ tty->output);
+ if (ferror (tty->output))
+ clearerr (tty->output);
+ if (tty->termscript)
fwrite (conversion_buffer, 1, produced,
- TTY_TERMSCRIPT (tty));
+ tty->termscript);
}
OUTPUT1_IF (tty, tty->TS_pad_inserted_char);
@@ -2240,7 +2252,11 @@ term_init (char *name, char *terminal_type, int must_succeed)
display = get_named_tty_display (name);
if (display)
- return display; /* We have already opened a display there. */
+ {
+ if (! display->display_info.tty->input)
+ error ("%s already has a suspended frame on it, can't open it twice", name);
+ return display;
+ }
display = create_display ();
tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info));
@@ -2550,7 +2566,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
/* Get frame size from system, or else from termcap. */
{
int height, width;
- get_tty_size (fileno (TTY_INPUT (tty)), &width, &height);
+ get_tty_size (fileno (tty->input), &width, &height);
FrameCols (tty) = width;
FrameRows (tty) = height;
}
@@ -2735,7 +2751,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
&& tty->TS_end_standout_mode
&& !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode));
- UseTabs (tty) = tabs_safe_p (fileno (TTY_INPUT (tty))) && TabWidth (tty) == 8;
+ UseTabs (tty) = tabs_safe_p (fileno (tty->input)) && TabWidth (tty) == 8;
display->scroll_region_ok
= (tty->Wcm->cm_abs
@@ -2754,7 +2770,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
display->fast_clear_end_of_line = tty->TS_clr_line != 0;
- init_baud_rate (fileno (TTY_INPUT (tty)));
+ init_baud_rate (fileno (tty->input));
#ifdef AIXHFT
/* The HFT system on AIX doesn't optimize for scrolling, so it's
@@ -3067,6 +3083,134 @@ delete_display (struct display *dev)
xfree (dev);
}
+
+
+DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0,
+ doc: /* Suspend the terminal device TTY.
+The terminal is restored to its default state, and Emacs closes all
+access to the terminal device. Frames that use the device are not
+deleted, but input is not read from them and if they change, their
+display is not updated.
+
+TTY may a string (a device name), a frame, or nil for the display
+device of the currently selected frame.
+
+This function runs `suspend-tty-functions' after suspending the
+device. The functions are run with one arg, the name of the terminal
+device.
+
+`suspend-tty' does nothing if it is called on an already suspended
+device.
+
+A suspended terminal device may be resumed by calling `resume-tty' on
+it. */)
+ (tty)
+ Lisp_Object tty;
+{
+ struct display *d = get_tty_display (tty);
+ FILE *f;
+
+ if (!d)
+ error ("Unknown tty device");
+
+ f = d->display_info.tty->input;
+
+ if (f)
+ {
+ reset_sys_modes (d->display_info.tty);
+
+ delete_keyboard_wait_descriptor (fileno (f));
+
+ fclose (f);
+ if (f != d->display_info.tty->output)
+ fclose (d->display_info.tty->output);
+
+ d->display_info.tty->input = 0;
+ d->display_info.tty->output = 0;
+
+ if (FRAMEP (d->display_info.tty->top_frame))
+ FRAME_SET_VISIBLE (XFRAME (d->display_info.tty->top_frame), 0);
+
+ /* Run `suspend-tty-functions'. */
+ if (!NILP (Vrun_hooks))
+ {
+ Lisp_Object args[2];
+ args[0] = intern ("suspend-tty-functions");
+ if (d->display_info.tty->name)
+ {
+ args[1] = build_string (d->display_info.tty->name);
+ }
+ else
+ args[1] = Qnil;
+ Frun_hook_with_args (2, args);
+ }
+ }
+
+ return Qnil;
+}
+
+
+DEFUN ("resume-tty", Fresume_tty, Sresume_tty, 0, 1, 0,
+ doc: /* Resume the previously suspended terminal device TTY.
+The terminal is opened and reinitialized. Frames that used the
+suspended device are revived.
+
+This function runs `resume-tty-functions' after resuming the device.
+The functions are run with one arg, the name of the terminal device.
+
+`resume-tty' does nothing if it is called on a device that is not
+suspended.
+
+TTY may a string (a device name), a frame, or nil for the display
+device of the currently selected frame. */)
+ (tty)
+ Lisp_Object tty;
+{
+ struct display *d = get_tty_display (tty);
+ int fd;
+
+ if (!d)
+ error ("Unknown tty device");
+
+ if (!d->display_info.tty->input)
+ {
+ fd = emacs_open (d->display_info.tty->name, O_RDWR | O_NOCTTY, 0);
+
+#ifdef TIOCNOTTY
+ /* Drop our controlling tty if it is the same device. */
+ if (ioctl (fd, TIOCNOTTY, 0) != -1)
+ {
+ no_controlling_tty = 1;
+ }
+#endif
+
+ d->display_info.tty->output = fdopen (fd, "w+");
+ d->display_info.tty->input = d->display_info.tty->output;
+
+ add_keyboard_wait_descriptor (fd);
+
+ if (FRAMEP (d->display_info.tty->top_frame))
+ FRAME_SET_VISIBLE (XFRAME (d->display_info.tty->top_frame), 1);
+
+ init_sys_modes (d->display_info.tty);
+
+ /* Run `suspend-tty-functions'. */
+ if (!NILP (Vrun_hooks))
+ {
+ Lisp_Object args[2];
+ args[0] = intern ("resume-tty-functions");
+ if (d->display_info.tty->name)
+ {
+ args[1] = build_string (d->display_info.tty->name);
+ }
+ else
+ args[1] = Qnil;
+ Frun_hook_with_args (2, args);
+ }
+ }
+
+ return Qnil;
+}
void
@@ -3092,6 +3236,20 @@ The functions are run with one argument, the name of the tty to be deleted.
See `delete-tty'. */);
Vdelete_tty_after_functions = Qnil;
+
+ DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions,
+ doc: /* Functions to be run after suspending a tty.
+The functions are run with one argument, the name of the tty to be suspended.
+See `suspend-tty'. */);
+ Vsuspend_tty_functions = Qnil;
+
+
+ DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions,
+ doc: /* Functions to be run after resuming a tty.
+The functions are run with one argument, the name of the tty that was revived.
+See `resume-tty'. */);
+ Vresume_tty_functions = Qnil;
+
Qframe_tty_name = intern ("frame-tty-name");
staticpro (&Qframe_tty_name);
@@ -3103,6 +3261,8 @@ See `delete-tty'. */);
defsubr (&Sframe_tty_name);
defsubr (&Sframe_tty_type);
defsubr (&Sdelete_tty);
+ defsubr (&Ssuspend_tty);
+ defsubr (&Sresume_tty);
Fprovide (intern ("multi-tty"), Qnil);
diff --git a/src/termchar.h b/src/termchar.h
index fbf91f2458f..3053061c1b7 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -42,8 +42,10 @@ struct tty_display_info
/* Input/output */
- FILE *input; /* The stream to be used for terminal input. */
- FILE *output; /* The stream to be used for terminal output. */
+ FILE *input; /* The stream to be used for terminal input.
+ NULL if the terminal is suspended. */
+ FILE *output; /* The stream to be used for terminal output.
+ NULL if the terminal is suspended. */
FILE *termscript; /* If nonzero, send all terminal output
characters to this stream also. */
@@ -200,9 +202,5 @@ extern struct tty_display_info *tty_list;
#define CURTTY() FRAME_TTY (SELECTED_FRAME())
-#define TTY_INPUT(t) ((t)->input)
-#define TTY_OUTPUT(t) ((t)->output)
-#define TTY_TERMSCRIPT(t) ((t)->termscript)
-
/* arch-tag: bf9f0d49-842b-42fb-9348-ec8759b27193
(do not change this comment) */
diff --git a/src/termhooks.h b/src/termhooks.h
index c79e77379b1..6b2b0d07867 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -513,7 +513,6 @@ struct display
frames on the display when it calls this hook, so infinite
recursion is prevented. */
void (*delete_display_hook) P_ ((struct display *));
-
};