aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKaroly Lorentey2004-02-28 01:23:39 +0000
committerKaroly Lorentey2004-02-28 01:23:39 +0000
commit0b0d3e0bcefdde298893aaad2e816e1503cef222 (patch)
tree439342044857514ad784de0470f5546eb9c3ef9a /src
parent2fc0cf2aefa777e5fe48596e2d43774b28051931 (diff)
downloademacs-0b0d3e0bcefdde298893aaad2e816e1503cef222.tar.gz
emacs-0b0d3e0bcefdde298893aaad2e816e1503cef222.zip
Implemented suspending of emacsclient frames.
lib-src/emacsclient.c (quote_file_name): Renamed to quote_argument. (unquote_argument, handle_sigcont, handle_sigtstp): New functions. (out, in): New global variables for communicating with the Emacs process. (init_signals): Set up handlers for SIGCONT, SIGTSTP and SIGTTOU. (main): Changed out and in to global variables. Prepend `-eval' or '-file' to each argument. Use fsync to force sending the strings to Emacs. Removed obsolete -bad-version code. Support the -suspend command. Cleaned up newline handling. lisp/frame.el (suspend-frame): New function. Substitute key definition of suspend-emacs with suspend-frame. lisp/server.el (server-log): Cosmetic change in log format. (server-handle-delete-tty, server-handle-delete-frame): Added logging. (server-handle-suspend-tty, server-quote-arg): New functions. (server-start): Install server-handle-suspend-tty. (server-process-filter): Reorganized source code for clarity. Implemented -resume, -suspend and -ignore commands. lisp/term/x-win.el (x-initialize-window-system): Don't change the binding of C-z. src/cm.c: Replaced TTY_INPUT, TTY_OUTPUT, TTY_TERMSCRIPT calls with their macro expansion. src/dispnew.c: Ditto. src/frame.c: Ditto. src/keyboard.c: Ditto. src/sysdep.c: Ditto. src/keyboard.c (tty_read_avail_input): Don't read if the terminal is suspended. src/sysdep.c (discard_tty_input, init_sys_modes, reset_sys_modes): Ditto. src/term.c (tty_set_terminal_modes, tty_reset_terminal_modes): Ditto. src/term.c (Vsuspend_tty_functions, Vresume_tty_functions): New hooks. (syms_of_term): Defvar them. (term_init): Don't allow opening a new frame on a suspended tty device. (Fsuspend_tty, Fresume_tty): New functions. (syms_of_term): Defsubr them. src/termchar.c (struct tty_display_info): Update documentation of input and output. (TTY_INPUT, TTY_OUTPUT, TTY_TERMSCRIPT): Removed. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-105
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
64cmputc (c) 64cmputc (c)
65 char c; 65 char c;
66{ 66{
67 if (TTY_TERMSCRIPT (current_tty)) 67 if (current_tty->termscript)
68 putc (c & 0177, TTY_TERMSCRIPT (current_tty)); 68 putc (c & 0177, current_tty->termscript);
69 putc (c & 0177, TTY_OUTPUT (current_tty)); 69 putc (c & 0177, current_tty->output);
70 return c; 70 return c;
71} 71}
72 72
@@ -136,12 +136,12 @@ cmcheckmagic (struct tty_display_info *tty)
136 { 136 {
137 if (!MagicWrap (tty) || curY (tty) >= FrameRows (tty) - 1) 137 if (!MagicWrap (tty) || curY (tty) >= FrameRows (tty) - 1)
138 abort (); 138 abort ();
139 if (TTY_TERMSCRIPT (tty)) 139 if (tty->termscript)
140 putc ('\r', TTY_TERMSCRIPT (tty)); 140 putc ('\r', tty->termscript);
141 putc ('\r', TTY_OUTPUT (tty)); 141 putc ('\r', tty->output);
142 if (TTY_TERMSCRIPT (tty)) 142 if (tty->termscript)
143 putc ('\n', TTY_TERMSCRIPT (tty)); 143 putc ('\n', tty->termscript);
144 putc ('\n', TTY_OUTPUT (tty)); 144 putc ('\n', tty->output);
145 curX (tty) = 0; 145 curX (tty) = 0;
146 curY (tty)++; 146 curY (tty)++;
147 } 147 }
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,
3316 clear_current_matrices (f); 3316 clear_current_matrices (f);
3317 update_end (f); 3317 update_end (f);
3318 if (FRAME_TERMCAP_P (f)) 3318 if (FRAME_TERMCAP_P (f))
3319 fflush (TTY_OUTPUT (FRAME_TTY (f))); 3319 fflush (FRAME_TTY (f)->output);
3320 windows_or_buffers_changed++; 3320 windows_or_buffers_changed++;
3321 /* Mark all windows as inaccurate, so that every window will have 3321 /* Mark all windows as inaccurate, so that every window will have
3322 its redisplay done. */ 3322 its redisplay done. */
@@ -3659,7 +3659,7 @@ direct_output_for_insert (g)
3659 update_end (f); 3659 update_end (f);
3660 updated_row = NULL; 3660 updated_row = NULL;
3661 if (FRAME_TERMCAP_P (f)) 3661 if (FRAME_TERMCAP_P (f))
3662 fflush (TTY_OUTPUT (FRAME_TTY (f))); 3662 fflush (FRAME_TTY (f)->output);
3663 3663
3664 TRACE ((stderr, "direct output for insert\n")); 3664 TRACE ((stderr, "direct output for insert\n"));
3665 mark_window_display_accurate (it.window, 1); 3665 mark_window_display_accurate (it.window, 1);
@@ -3751,7 +3751,7 @@ direct_output_forward_char (n)
3751 } 3751 }
3752 3752
3753 if (FRAME_TERMCAP_P (f)) 3753 if (FRAME_TERMCAP_P (f))
3754 fflush (TTY_OUTPUT (FRAME_TTY (f))); 3754 fflush (FRAME_TTY (f)->output);
3755 redisplay_performed_directly_p = 1; 3755 redisplay_performed_directly_p = 1;
3756 return 1; 3756 return 1;
3757} 3757}
@@ -3849,9 +3849,9 @@ update_frame (f, force_p, inhibit_hairy_id_p)
3849 3849
3850 if (FRAME_TERMCAP_P (f)) 3850 if (FRAME_TERMCAP_P (f))
3851 { 3851 {
3852 if (TTY_TERMSCRIPT (FRAME_TTY (f))) 3852 if (FRAME_TTY (f)->termscript)
3853 fflush (TTY_TERMSCRIPT (FRAME_TTY (f))); 3853 fflush (FRAME_TTY (f)->termscript);
3854 fflush (TTY_OUTPUT (FRAME_TTY (f))); 3854 fflush (FRAME_TTY (f)->output);
3855 } 3855 }
3856 3856
3857 /* Check window matrices for lost pointers. */ 3857 /* Check window matrices for lost pointers. */
@@ -5133,18 +5133,18 @@ update_frame_1 (f, force_p, inhibit_id_p)
5133 Also flush out if likely to have more than 1k buffered 5133 Also flush out if likely to have more than 1k buffered
5134 otherwise. I'm told that some telnet connections get 5134 otherwise. I'm told that some telnet connections get
5135 really screwed by more than 1k output at once. */ 5135 really screwed by more than 1k output at once. */
5136 int outq = PENDING_OUTPUT_COUNT (TTY_OUTPUT (FRAME_TTY (f))); 5136 int outq = PENDING_OUTPUT_COUNT (FRAME_TTY (f)->output);
5137 if (outq > 900 5137 if (outq > 900
5138 || (outq > 20 && ((i - 1) % preempt_count == 0))) 5138 || (outq > 20 && ((i - 1) % preempt_count == 0)))
5139 { 5139 {
5140 fflush (TTY_OUTPUT (FRAME_TTY (f))); 5140 fflush (FRAME_TTY (f)->output);
5141 if (preempt_count == 1) 5141 if (preempt_count == 1)
5142 { 5142 {
5143#ifdef EMACS_OUTQSIZE 5143#ifdef EMACS_OUTQSIZE
5144 if (EMACS_OUTQSIZE (0, &outq) < 0) 5144 if (EMACS_OUTQSIZE (0, &outq) < 0)
5145 /* Probably not a tty. Ignore the error and reset 5145 /* Probably not a tty. Ignore the error and reset
5146 the outq count. */ 5146 the outq count. */
5147 outq = PENDING_OUTPUT_COUNT (TTY_OUTPUT (FRAME_TTY (f))); 5147 outq = PENDING_OUTPUT_COUNT (FRAME_TTY (f->output));
5148#endif 5148#endif
5149 outq *= 10; 5149 outq *= 10;
5150 if (baud_rate <= outq && baud_rate > 0) 5150 if (baud_rate <= outq && baud_rate > 0)
@@ -5999,7 +5999,7 @@ window_change_signal (signalnum) /* If we don't have an argument, */
5999 if (! tty->term_initted) 5999 if (! tty->term_initted)
6000 continue; 6000 continue;
6001 6001
6002 get_tty_size (fileno (TTY_INPUT (tty)), &width, &height); 6002 get_tty_size (fileno (tty->input), &width, &height);
6003 6003
6004 { 6004 {
6005 Lisp_Object tail, frame; 6005 Lisp_Object tail, frame;
@@ -6211,15 +6211,22 @@ FILE = nil means just close any termscript file currently open. */)
6211 (file) 6211 (file)
6212 Lisp_Object file; 6212 Lisp_Object file;
6213{ 6213{
6214 if (TTY_TERMSCRIPT (CURTTY ()) != 0) 6214 struct tty_display_info *tty;
6215 fclose (TTY_TERMSCRIPT (CURTTY ())); 6215
6216 TTY_TERMSCRIPT (CURTTY ()) = 0; 6216 if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
6217 error ("Current frame is not on a tty device");
6218
6219 tty = CURTTY ();
6220
6221 if (tty->termscript != 0)
6222 fclose (tty->termscript);
6223 tty->termscript = 0;
6217 6224
6218 if (! NILP (file)) 6225 if (! NILP (file))
6219 { 6226 {
6220 file = Fexpand_file_name (file, Qnil); 6227 file = Fexpand_file_name (file, Qnil);
6221 TTY_TERMSCRIPT (CURTTY ()) = fopen (SDATA (file), "w"); 6228 tty->termscript = fopen (SDATA (file), "w");
6222 if (TTY_TERMSCRIPT (CURTTY ()) == 0) 6229 if (tty->termscript == 0)
6223 report_file_error ("Opening termscript", Fcons (file, Qnil)); 6230 report_file_error ("Opening termscript", Fcons (file, Qnil));
6224 } 6231 }
6225 return Qnil; 6232 return Qnil;
@@ -6233,20 +6240,23 @@ Control characters in STRING will have terminal-dependent effects. */)
6233 (string) 6240 (string)
6234 Lisp_Object string; 6241 Lisp_Object string;
6235{ 6242{
6243 struct tty_display_info *tty;
6244
6236 /* ??? Perhaps we should do something special for multibyte strings here. */ 6245 /* ??? Perhaps we should do something special for multibyte strings here. */
6237 CHECK_STRING (string); 6246 CHECK_STRING (string);
6247
6238 if (! FRAME_TERMCAP_P (SELECTED_FRAME ())) 6248 if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
6239 error ("Current frame is not on a tty device"); 6249 error ("Current frame is not on a tty device");
6250
6251 tty = CURTTY ();
6240 6252
6241 if (TTY_TERMSCRIPT (CURTTY ())) 6253 if (tty->termscript)
6242 { 6254 {
6243 fwrite (SDATA (string), 1, SBYTES (string), 6255 fwrite (SDATA (string), 1, SBYTES (string), tty->termscript);
6244 TTY_TERMSCRIPT (CURTTY ())); 6256 fflush (tty->termscript);
6245 fflush (TTY_TERMSCRIPT (CURTTY ()));
6246 } 6257 }
6247 fwrite (SDATA (string), 1, SBYTES (string), 6258 fwrite (SDATA (string), 1, SBYTES (string), tty->output);
6248 TTY_OUTPUT (CURTTY ())); 6259 fflush (tty->output);
6249 fflush (TTY_OUTPUT (CURTTY ()));
6250 return Qnil; 6260 return Qnil;
6251} 6261}
6252 6262
@@ -6265,7 +6275,7 @@ terminate any keyboard macro currently executing. */)
6265 else 6275 else
6266 ring_bell (); 6276 ring_bell ();
6267 if (FRAME_TERMCAP_P (XFRAME (selected_frame))) 6277 if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
6268 fflush (TTY_OUTPUT (CURTTY ())); 6278 fflush (CURTTY ()->output);
6269 } 6279 }
6270 else 6280 else
6271 bitch_at_user (); 6281 bitch_at_user ();
@@ -6283,7 +6293,7 @@ bitch_at_user ()
6283 else 6293 else
6284 ring_bell (); 6294 ring_bell ();
6285 if (FRAME_TERMCAP_P (XFRAME (selected_frame))) 6295 if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
6286 fflush (TTY_OUTPUT (CURTTY ())); 6296 fflush (CURTTY ()->output);
6287} 6297}
6288 6298
6289 6299
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:
667 667
668 (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm"))) 668 (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
669 669
670Note that changing the size of one terminal frame automatically affects all. */) 670Note that changing the size of one terminal frame automatically
671affects all frames on the same terminal device. */)
671 (parms) 672 (parms)
672 Lisp_Object parms; 673 Lisp_Object parms;
673{ 674{
@@ -742,7 +743,7 @@ Note that changing the size of one terminal frame automatically affects all. */
742 743
743 { 744 {
744 int width, height; 745 int width, height;
745 get_tty_size (fileno (TTY_INPUT (FRAME_TTY (f))), &width, &height); 746 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
746 change_frame_size (f, height, width, 0, 0, 0); 747 change_frame_size (f, height, width, 0, 0, 0);
747 } 748 }
748 749
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,
6704 if (! tty->term_initted) /* In case we get called during bootstrap. */ 6704 if (! tty->term_initted) /* In case we get called during bootstrap. */
6705 return 0; 6705 return 0;
6706 6706
6707 if (! tty->input)
6708 return 0; /* The terminal is suspended. */
6709
6707 /* Determine how many characters we should *try* to read. */ 6710 /* Determine how many characters we should *try* to read. */
6708#ifdef FIONREAD 6711#ifdef FIONREAD
6709 /* Find out how much input is available. */ 6712 /* Find out how much input is available. */
6710 if (ioctl (fileno (TTY_INPUT (tty)), FIONREAD, &n_to_read) < 0) 6713 if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0)
6711 { 6714 {
6712 if (! noninteractive) 6715 if (! noninteractive)
6713 return -2; /* Close this display. */ 6716 return -2; /* Close this display. */
@@ -6722,7 +6725,7 @@ tty_read_avail_input (struct display *display,
6722#if defined (USG) || defined (DGUX) || defined(CYGWIN) 6725#if defined (USG) || defined (DGUX) || defined(CYGWIN)
6723 /* Read some input if available, but don't wait. */ 6726 /* Read some input if available, but don't wait. */
6724 n_to_read = sizeof cbuf; 6727 n_to_read = sizeof cbuf;
6725 fcntl (fileno (TTY_INPUT (tty)), F_SETFL, O_NDELAY); 6728 fcntl (fileno (tty->input), F_SETFL, O_NDELAY);
6726#else 6729#else
6727 you lose; 6730 you lose;
6728#endif 6731#endif
@@ -6732,7 +6735,7 @@ tty_read_avail_input (struct display *display,
6732 NREAD is set to the number of chars read. */ 6735 NREAD is set to the number of chars read. */
6733 do 6736 do
6734 { 6737 {
6735 nread = emacs_read (fileno (TTY_INPUT (tty)), cbuf, n_to_read); 6738 nread = emacs_read (fileno (tty->input), cbuf, n_to_read);
6736 /* POSIX infers that processes which are not in the session leader's 6739 /* POSIX infers that processes which are not in the session leader's
6737 process group won't get SIGHUP's at logout time. BSDI adheres to 6740 process group won't get SIGHUP's at logout time. BSDI adheres to
6738 this part standard and returns -1 from read (0) with errno==EIO 6741 this part standard and returns -1 from read (0) with errno==EIO
@@ -6770,7 +6773,7 @@ tty_read_avail_input (struct display *display,
6770 6773
6771#ifndef FIONREAD 6774#ifndef FIONREAD
6772#if defined (USG) || defined (DGUX) || defined (CYGWIN) 6775#if defined (USG) || defined (DGUX) || defined (CYGWIN)
6773 fcntl (fileno (TTY_INPUT (tty)), F_SETFL, 0); 6776 fcntl (fileno (tty->input), F_SETFL, 0);
6774#endif /* USG or DGUX or CYGWIN */ 6777#endif /* USG or DGUX or CYGWIN */
6775#endif /* no FIONREAD */ 6778#endif /* no FIONREAD */
6776 6779
@@ -10168,7 +10171,7 @@ On such systems, Emacs starts a subshell instead of suspending. */)
10168 call1 (Vrun_hooks, intern ("suspend-hook")); 10171 call1 (Vrun_hooks, intern ("suspend-hook"));
10169 10172
10170 GCPRO1 (stuffstring); 10173 GCPRO1 (stuffstring);
10171 get_tty_size (fileno (TTY_INPUT (CURTTY ())), &old_width, &old_height); 10174 get_tty_size (fileno (CURTTY ()->input), &old_width, &old_height);
10172 reset_all_sys_modes (); 10175 reset_all_sys_modes ();
10173 /* sys_suspend can get an error if it tries to fork a subshell 10176 /* sys_suspend can get an error if it tries to fork a subshell
10174 and the system resources aren't available for that. */ 10177 and the system resources aren't available for that. */
@@ -10184,7 +10187,7 @@ On such systems, Emacs starts a subshell instead of suspending. */)
10184 /* Check if terminal/window size has changed. 10187 /* Check if terminal/window size has changed.
10185 Note that this is not useful when we are running directly 10188 Note that this is not useful when we are running directly
10186 with a window system; but suspend should be disabled in that case. */ 10189 with a window system; but suspend should be disabled in that case. */
10187 get_tty_size (fileno (TTY_INPUT (CURTTY ())), &width, &height); 10190 get_tty_size (fileno (CURTTY ()->input), &width, &height);
10188 if (width != old_width || height != old_height) 10191 if (width != old_width || height != old_height)
10189 change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0); 10192 change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);
10190 10193
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 ()
274 274
275#ifdef VMS 275#ifdef VMS
276 end_kbd_input (); 276 end_kbd_input ();
277 SYS$QIOW (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0, 277 SYS$QIOW (0, fileno (CURTTY()->input), IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
278 &buf.main, 0, 0, terminator_mask, 0, 0); 278 &buf.main, 0, 0, terminator_mask, 0, 0);
279 queue_kbd_input (); 279 queue_kbd_input ();
280#else /* not VMS */ 280#else /* not VMS */
@@ -284,7 +284,8 @@ discard_tty_input ()
284 for (tty = tty_list; tty; tty = tty->next) 284 for (tty = tty_list; tty; tty = tty->next)
285 { 285 {
286 int zero = 0; 286 int zero = 0;
287 ioctl (fileno (TTY_INPUT (tty)), TIOCFLUSH, &zero); 287 if (tty->input)
288 ioctl (fileno (tty->input), TIOCFLUSH, &zero);
288 } 289 }
289 } 290 }
290#else /* not Apollo */ 291#else /* not Apollo */
@@ -296,8 +297,11 @@ discard_tty_input ()
296 struct tty_display_info *tty; 297 struct tty_display_info *tty;
297 for (tty = tty_list; tty; tty = tty->next) 298 for (tty = tty_list; tty; tty = tty->next)
298 { 299 {
299 EMACS_GET_TTY (fileno (TTY_INPUT (tty)), &buf); 300 if (tty->input) /* Is the device suspended? */
300 EMACS_SET_TTY (fileno (TTY_INPUT (tty)), &buf, 0); 301 {
302 EMACS_GET_TTY (fileno (tty->input), &buf);
303 EMACS_SET_TTY (fileno (tty->input), &buf, 0);
304 }
301 } 305 }
302 } 306 }
303#endif /* not MSDOS */ 307#endif /* not MSDOS */
@@ -322,7 +326,7 @@ stuff_char (char c)
322 326
323/* Should perhaps error if in batch mode */ 327/* Should perhaps error if in batch mode */
324#ifdef TIOCSTI 328#ifdef TIOCSTI
325 ioctl (fileno (TTY_INPUT (CURTTY())), TIOCSTI, &c); 329 ioctl (fileno (CURTTY()->input), TIOCSTI, &c);
326#else /* no TIOCSTI */ 330#else /* no TIOCSTI */
327 error ("Cannot stuff terminal input characters in this version of Unix"); 331 error ("Cannot stuff terminal input characters in this version of Unix");
328#endif /* no TIOCSTI */ 332#endif /* no TIOCSTI */
@@ -1005,7 +1009,7 @@ request_sigio ()
1005 return; 1009 return;
1006 1010
1007 /* XXX CURTTY() is bogus here. */ 1011 /* XXX CURTTY() is bogus here. */
1008 ioctl (fileno (TTY_INPUT (CURTTY ())), FIOASYNC, &on); 1012 ioctl (fileno (CURTTY ()->input), FIOASYNC, &on);
1009 interrupts_deferred = 0; 1013 interrupts_deferred = 0;
1010} 1014}
1011 1015
@@ -1018,7 +1022,7 @@ unrequest_sigio ()
1018 return; 1022 return;
1019 1023
1020 /* XXX CURTTY() is bogus here. */ 1024 /* XXX CURTTY() is bogus here. */
1021 ioctl (fileno (TTY_INPUT (CURTTY ())), FIOASYNC, &off); 1025 ioctl (fileno (CURTTY ()->input), FIOASYNC, &off);
1022 interrupts_deferred = 1; 1026 interrupts_deferred = 1;
1023} 1027}
1024 1028
@@ -1366,6 +1370,9 @@ nil means don't delete them until `list-processes' is run. */);
1366 if (noninteractive) 1370 if (noninteractive)
1367 return; 1371 return;
1368 1372
1373 if (!tty_out->output)
1374 return; /* The tty is suspended. */
1375
1369#ifdef VMS 1376#ifdef VMS
1370 if (!input_ef) 1377 if (!input_ef)
1371 input_ef = get_kbd_event_flag (); 1378 input_ef = get_kbd_event_flag ();
@@ -1404,13 +1411,13 @@ nil means don't delete them until `list-processes' is run. */);
1404 unconditionally will not cause any problems. */ 1411 unconditionally will not cause any problems. */
1405 if (! read_socket_hook && EQ (Vinitial_window_system, Qnil)) 1412 if (! read_socket_hook && EQ (Vinitial_window_system, Qnil))
1406#endif 1413#endif
1407 narrow_foreground_group (fileno (TTY_INPUT (tty_out))); 1414 narrow_foreground_group (fileno (tty_out->input));
1408#endif 1415#endif
1409 1416
1410 if (! tty_out->old_tty) 1417 if (! tty_out->old_tty)
1411 tty_out->old_tty = (struct emacs_tty *) xmalloc (sizeof (struct emacs_tty)); 1418 tty_out->old_tty = (struct emacs_tty *) xmalloc (sizeof (struct emacs_tty));
1412 1419
1413 EMACS_GET_TTY (fileno (TTY_INPUT (tty_out)), tty_out->old_tty); 1420 EMACS_GET_TTY (fileno (tty_out->input), tty_out->old_tty);
1414 1421
1415 tty = *tty_out->old_tty; 1422 tty = *tty_out->old_tty;
1416 1423
@@ -1626,23 +1633,23 @@ nil means don't delete them until `list-processes' is run. */);
1626 dos_ttraw (); 1633 dos_ttraw ();
1627#endif 1634#endif
1628 1635
1629 EMACS_SET_TTY (fileno (TTY_INPUT (tty_out)), &tty, 0); 1636 EMACS_SET_TTY (fileno (tty_out->input), &tty, 0);
1630 1637
1631 /* This code added to insure that, if flow-control is not to be used, 1638 /* This code added to insure that, if flow-control is not to be used,
1632 we have an unlocked terminal at the start. */ 1639 we have an unlocked terminal at the start. */
1633 1640
1634#ifdef TCXONC 1641#ifdef TCXONC
1635 if (!tty_out->flow_control) ioctl (fileno (TTY_INPUT (tty_out)), TCXONC, 1); 1642 if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TCXONC, 1);
1636#endif 1643#endif
1637#ifndef APOLLO 1644#ifndef APOLLO
1638#ifdef TIOCSTART 1645#ifdef TIOCSTART
1639 if (!tty_out->flow_control) ioctl (fileno (TTY_INPUT (tty_out)), TIOCSTART, 0); 1646 if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TIOCSTART, 0);
1640#endif 1647#endif
1641#endif 1648#endif
1642 1649
1643#if defined (HAVE_TERMIOS) || defined (HPUX9) 1650#if defined (HAVE_TERMIOS) || defined (HPUX9)
1644#ifdef TCOON 1651#ifdef TCOON
1645 if (!tty_out->flow_control) tcflow (fileno (TTY_INPUT (tty_out)), TCOON); 1652 if (!tty_out->flow_control) tcflow (fileno (tty_out->input), TCOON);
1646#endif 1653#endif
1647#endif 1654#endif
1648 1655
@@ -1662,7 +1669,7 @@ nil means don't delete them until `list-processes' is run. */);
1662 1669
1663#ifdef VMS 1670#ifdef VMS
1664/* Appears to do nothing when in PASTHRU mode. 1671/* Appears to do nothing when in PASTHRU mode.
1665 SYS$QIOW (0, fileno (TTY_INPUT (tty_out)), IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0, 1672 SYS$QIOW (0, fileno (tty_out->input), IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1666 interrupt_signal, oob_chars, 0, 0, 0, 0); 1673 interrupt_signal, oob_chars, 0, 0, 0, 0);
1667*/ 1674*/
1668 queue_kbd_input (0); 1675 queue_kbd_input (0);
@@ -1673,10 +1680,10 @@ nil means don't delete them until `list-processes' is run. */);
1673#ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */ 1680#ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1674 if (interrupt_input) 1681 if (interrupt_input)
1675 { 1682 {
1676 old_fcntl_owner[fileno (TTY_INPUT (tty_out))] = 1683 old_fcntl_owner[fileno (tty_out->input)] =
1677 fcntl (fileno (TTY_INPUT (tty_out)), F_GETOWN, 0); 1684 fcntl (fileno (tty_out->input), F_GETOWN, 0);
1678 fcntl (fileno (TTY_INPUT (tty_out)), F_SETOWN, getpid ()); 1685 fcntl (fileno (tty_out->input), F_SETOWN, getpid ());
1679 init_sigio (fileno (TTY_INPUT (tty_out))); 1686 init_sigio (fileno (tty_out->input));
1680 } 1687 }
1681#endif /* F_GETOWN */ 1688#endif /* F_GETOWN */
1682#endif /* F_SETOWN_BUG */ 1689#endif /* F_SETOWN_BUG */
@@ -1684,7 +1691,7 @@ nil means don't delete them until `list-processes' is run. */);
1684 1691
1685#ifdef BSD4_1 1692#ifdef BSD4_1
1686 if (interrupt_input) 1693 if (interrupt_input)
1687 init_sigio (fileno (TTY_INPUT (tty_out))); 1694 init_sigio (fileno (tty_out->input));
1688#endif 1695#endif
1689 1696
1690#ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */ 1697#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. */);
1694 /* This symbol is defined on recent USG systems. 1701 /* This symbol is defined on recent USG systems.
1695 Someone says without this call USG won't really buffer the file 1702 Someone says without this call USG won't really buffer the file
1696 even with a call to setbuf. */ 1703 even with a call to setbuf. */
1697 setvbuf (TTY_OUTPUT (tty_out), (char *) _sobuf, _IOFBF, sizeof _sobuf); 1704 setvbuf (tty_out->output, (char *) _sobuf, _IOFBF, sizeof _sobuf);
1698#else 1705#else
1699 setbuf (TTY_OUTPUT (tty_out), (char *) _sobuf); 1706 setbuf (tty_out->output, (char *) _sobuf);
1700#endif 1707#endif
1701 1708
1702 tty_set_terminal_modes (tty_out->display); 1709 tty_set_terminal_modes (tty_out->display);
@@ -1867,10 +1874,13 @@ reset_sys_modes (tty_out)
1867 if (!tty_out->term_initted) 1874 if (!tty_out->term_initted)
1868 return; 1875 return;
1869 1876
1877 if (!tty_out->output)
1878 return; /* The tty is suspended. */
1879
1870 /* Go to and clear the last line of the terminal. */ 1880 /* Go to and clear the last line of the terminal. */
1871 1881
1872 cmgoto (tty_out, FrameRows (tty_out) - 1, 0); 1882 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
1873 1883
1874 /* Code adapted from tty_clear_end_of_line. */ 1884 /* Code adapted from tty_clear_end_of_line. */
1875 if (tty_out->TS_clr_line) 1885 if (tty_out->TS_clr_line)
1876 { 1886 {
@@ -1880,13 +1890,13 @@ reset_sys_modes (tty_out)
1880 { /* have to do it the hard way */ 1890 { /* have to do it the hard way */
1881 int i; 1891 int i;
1882 turn_off_insert (tty_out); 1892 turn_off_insert (tty_out);
1883 1893
1884 for (i = curX (tty_out); i < FrameCols (tty_out) - 1; i++) 1894 for (i = curX (tty_out); i < FrameCols (tty_out) - 1; i++)
1885 { 1895 {
1886 fputc (' ', TTY_OUTPUT (tty_out)); 1896 fputc (' ', tty_out->output);
1887 } 1897 }
1888 } 1898 }
1889 1899
1890 cmgoto (tty_out, FrameRows (tty_out) - 1, 0); 1900 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
1891 fflush (tty_out->output); 1901 fflush (tty_out->output);
1892 1902
@@ -1902,11 +1912,11 @@ reset_sys_modes (tty_out)
1902#endif 1912#endif
1903 1913
1904 tty_reset_terminal_modes (tty_out->display); 1914 tty_reset_terminal_modes (tty_out->display);
1905 fflush (TTY_OUTPUT (tty_out)); 1915 fflush (tty_out->output);
1906#ifdef BSD_SYSTEM 1916#ifdef BSD_SYSTEM
1907#ifndef BSD4_1 1917#ifndef BSD4_1
1908 /* Avoid possible loss of output when changing terminal modes. */ 1918 /* Avoid possible loss of output when changing terminal modes. */
1909 fsync (fileno (TTY_OUTPUT (tty_out))); 1919 fsync (fileno (tty_out->output));
1910#endif 1920#endif
1911#endif 1921#endif
1912 1922
@@ -1915,24 +1925,24 @@ reset_sys_modes (tty_out)
1915#ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */ 1925#ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1916 if (interrupt_input) 1926 if (interrupt_input)
1917 { 1927 {
1918 reset_sigio (fileno (TTY_INPUT (tty_out))); 1928 reset_sigio (fileno (tty_out->input));
1919 fcntl (fileno (TTY_INPUT (tty_out)), F_SETOWN, 1929 fcntl (fileno (tty_out->input), F_SETOWN,
1920 old_fcntl_owner[fileno (TTY_INPUT (tty_out))]); 1930 old_fcntl_owner[fileno (tty_out->input)]);
1921 } 1931 }
1922#endif /* F_SETOWN */ 1932#endif /* F_SETOWN */
1923#endif /* F_SETOWN_BUG */ 1933#endif /* F_SETOWN_BUG */
1924#ifdef O_NDELAY 1934#ifdef O_NDELAY
1925 fcntl (fileno (TTY_INPUT (tty_out)), F_SETFL, 1935 fcntl (fileno (tty_out->input), F_SETFL,
1926 fcntl (fileno (TTY_INPUT (tty_out)), F_GETFL, 0) & ~O_NDELAY); 1936 fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NDELAY);
1927#endif 1937#endif
1928#endif /* F_SETFL */ 1938#endif /* F_SETFL */
1929#ifdef BSD4_1 1939#ifdef BSD4_1
1930 if (interrupt_input) 1940 if (interrupt_input)
1931 reset_sigio (fileno (TTY_INPUT (tty_out))); 1941 reset_sigio (fileno (tty_out->input));
1932#endif /* BSD4_1 */ 1942#endif /* BSD4_1 */
1933 1943
1934 if (tty_out->old_tty) 1944 if (tty_out->old_tty)
1935 while (EMACS_SET_TTY (fileno (TTY_INPUT (tty_out)), 1945 while (EMACS_SET_TTY (fileno (tty_out->input),
1936 tty_out->old_tty, 0) < 0 && errno == EINTR) 1946 tty_out->old_tty, 0) < 0 && errno == EINTR)
1937 ; 1947 ;
1938 1948
@@ -1952,7 +1962,7 @@ reset_sys_modes (tty_out)
1952#endif 1962#endif
1953 1963
1954#ifdef BSD_PGRPS 1964#ifdef BSD_PGRPS
1955 widen_foreground_group (fileno (TTY_INPUT (tty_out))); 1965 widen_foreground_group (fileno (tty_out->input));
1956#endif 1966#endif
1957} 1967}
1958 1968
@@ -2017,9 +2027,9 @@ init_vms_input ()
2017{ 2027{
2018 int status; 2028 int status;
2019 2029
2020 if (fileno (TTY_INPUT (CURTTY())) == 0) 2030 if (fileno (CURTTY ()->input)) == 0)
2021 { 2031 {
2022 status = SYS$ASSIGN (&input_dsc, &fileno (TTY_INPUT (CURTTY())), 0, 0); 2032 status = SYS$ASSIGN (&input_dsc, &fileno (CURTTY ()->input)), 0, 0);
2023 if (! (status & 1)) 2033 if (! (status & 1))
2024 LIB$STOP (status); 2034 LIB$STOP (status);
2025 } 2035 }
@@ -2030,7 +2040,7 @@ init_vms_input ()
2030void 2040void
2031stop_vms_input () 2041stop_vms_input ()
2032{ 2042{
2033 return SYS$DASSGN (fileno (TTY_INPUT (CURTTY()))); 2043 return SYS$DASSGN (fileno (CURTTY ()->input)));
2034} 2044}
2035 2045
2036short input_buffer; 2046short input_buffer;
@@ -2046,7 +2056,7 @@ queue_kbd_input ()
2046 2056
2047 waiting_for_ast = 0; 2057 waiting_for_ast = 0;
2048 stop_input = 0; 2058 stop_input = 0;
2049 status = SYS$QIO (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK, 2059 status = SYS$QIO (0, fileno (CURTTY()->input), IO$_READVBLK,
2050 &input_iosb, kbd_input_ast, 1, 2060 &input_iosb, kbd_input_ast, 1,
2051 &input_buffer, 1, 0, terminator_mask, 0, 0); 2061 &input_buffer, 1, 0, terminator_mask, 0, 0);
2052} 2062}
@@ -2163,7 +2173,7 @@ end_kbd_input ()
2163#endif 2173#endif
2164 if (LIB$AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */ 2174 if (LIB$AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
2165 { 2175 {
2166 SYS$CANCEL (fileno (TTY_INPUT (CURTTY()))); 2176 SYS$CANCEL (fileno (CURTTY()->input));
2167 return; 2177 return;
2168 } 2178 }
2169 2179
@@ -2172,7 +2182,7 @@ end_kbd_input ()
2172 SYS$CLREF (input_ef); 2182 SYS$CLREF (input_ef);
2173 waiting_for_ast = 1; 2183 waiting_for_ast = 1;
2174 stop_input = 1; 2184 stop_input = 1;
2175 SYS$CANCEL (fileno (TTY_INPUT (CURTTY()))); 2185 SYS$CANCEL (fileno (CURTTY()->input));
2176 SYS$SETAST (1); 2186 SYS$SETAST (1);
2177 SYS$WAITFR (input_ef); 2187 SYS$WAITFR (input_ef);
2178 waiting_for_ast = 0; 2188 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 *));
106 106
107Lisp_Object Vring_bell_function; 107Lisp_Object Vring_bell_function;
108 108
109/* Functions to call after a tty was deleted. */ 109/* Functions to call after deleting a tty. */
110Lisp_Object Vdelete_tty_after_functions; 110Lisp_Object Vdelete_tty_after_functions;
111 111
112/* Functions to call after suspending a tty. */
113Lisp_Object Vsuspend_tty_functions;
114
115/* Functions to call after resuming a tty. */
116Lisp_Object Vresume_tty_functions;
117
112/* Chain of all displays currently in use. */ 118/* Chain of all displays currently in use. */
113struct display *display_list; 119struct display *display_list;
114 120
@@ -231,10 +237,13 @@ tty_set_terminal_modes (struct display *display)
231{ 237{
232 struct tty_display_info *tty = display->display_info.tty; 238 struct tty_display_info *tty = display->display_info.tty;
233 239
234 OUTPUT_IF (tty, tty->TS_termcap_modes); 240 if (tty->output)
235 OUTPUT_IF (tty, tty->TS_cursor_visible); 241 {
236 OUTPUT_IF (tty, tty->TS_keypad_mode); 242 OUTPUT_IF (tty, tty->TS_termcap_modes);
237 losecursor (tty); 243 OUTPUT_IF (tty, tty->TS_cursor_visible);
244 OUTPUT_IF (tty, tty->TS_keypad_mode);
245 losecursor (tty);
246 }
238} 247}
239 248
240/* Reset termcap modes before exiting Emacs. */ 249/* Reset termcap modes before exiting Emacs. */
@@ -243,16 +252,19 @@ void
243tty_reset_terminal_modes (struct display *display) 252tty_reset_terminal_modes (struct display *display)
244{ 253{
245 struct tty_display_info *tty = display->display_info.tty; 254 struct tty_display_info *tty = display->display_info.tty;
246 255
247 turn_off_highlight (tty); 256 if (tty->output)
248 turn_off_insert (tty); 257 {
249 OUTPUT_IF (tty, tty->TS_end_keypad_mode); 258 turn_off_highlight (tty);
250 OUTPUT_IF (tty, tty->TS_cursor_normal); 259 turn_off_insert (tty);
251 OUTPUT_IF (tty, tty->TS_end_termcap_modes); 260 OUTPUT_IF (tty, tty->TS_end_keypad_mode);
252 OUTPUT_IF (tty, tty->TS_orig_pair); 261 OUTPUT_IF (tty, tty->TS_cursor_normal);
253 /* Output raw CR so kernel can track the cursor hpos. */ 262 OUTPUT_IF (tty, tty->TS_end_termcap_modes);
254 current_tty = tty; 263 OUTPUT_IF (tty, tty->TS_orig_pair);
255 cmputc ('\r'); 264 /* Output raw CR so kernel can track the cursor hpos. */
265 current_tty = tty;
266 cmputc ('\r');
267 }
256} 268}
257 269
258void 270void
@@ -619,9 +631,9 @@ tty_clear_end_of_line (int first_unused_hpos)
619 631
620 for (i = curX (tty); i < first_unused_hpos; i++) 632 for (i = curX (tty); i < first_unused_hpos; i++)
621 { 633 {
622 if (TTY_TERMSCRIPT (tty)) 634 if (tty->termscript)
623 fputc (' ', TTY_TERMSCRIPT (tty)); 635 fputc (' ', tty->termscript);
624 fputc (' ', TTY_OUTPUT (tty)); 636 fputc (' ', tty->output);
625 } 637 }
626 cmplus (tty, first_unused_hpos - curX (tty)); 638 cmplus (tty, first_unused_hpos - curX (tty));
627 } 639 }
@@ -807,12 +819,12 @@ tty_write_glyphs (struct glyph *string, int len)
807 if (produced > 0) 819 if (produced > 0)
808 { 820 {
809 fwrite (conversion_buffer, 1, produced, 821 fwrite (conversion_buffer, 1, produced,
810 TTY_OUTPUT (tty)); 822 tty->output);
811 if (ferror (TTY_OUTPUT (tty))) 823 if (ferror (tty->output))
812 clearerr (TTY_OUTPUT (tty)); 824 clearerr (tty->output);
813 if (TTY_TERMSCRIPT (tty)) 825 if (tty->termscript)
814 fwrite (conversion_buffer, 1, produced, 826 fwrite (conversion_buffer, 1, produced,
815 TTY_TERMSCRIPT (tty)); 827 tty->termscript);
816 } 828 }
817 len -= consumed; 829 len -= consumed;
818 n -= consumed; 830 n -= consumed;
@@ -833,12 +845,12 @@ tty_write_glyphs (struct glyph *string, int len)
833 if (terminal_coding.produced > 0) 845 if (terminal_coding.produced > 0)
834 { 846 {
835 fwrite (conversion_buffer, 1, terminal_coding.produced, 847 fwrite (conversion_buffer, 1, terminal_coding.produced,
836 TTY_OUTPUT (tty)); 848 tty->output);
837 if (ferror (TTY_OUTPUT (tty))) 849 if (ferror (tty->output))
838 clearerr (TTY_OUTPUT (tty)); 850 clearerr (tty->output);
839 if (TTY_TERMSCRIPT (tty)) 851 if (tty->termscript)
840 fwrite (conversion_buffer, 1, terminal_coding.produced, 852 fwrite (conversion_buffer, 1, terminal_coding.produced,
841 TTY_TERMSCRIPT (tty)); 853 tty->termscript);
842 } 854 }
843 } 855 }
844 856
@@ -927,12 +939,12 @@ tty_insert_glyphs (struct glyph *start, int len)
927 if (produced > 0) 939 if (produced > 0)
928 { 940 {
929 fwrite (conversion_buffer, 1, produced, 941 fwrite (conversion_buffer, 1, produced,
930 TTY_OUTPUT (tty)); 942 tty->output);
931 if (ferror (TTY_OUTPUT (tty))) 943 if (ferror (tty->output))
932 clearerr (TTY_OUTPUT (tty)); 944 clearerr (tty->output);
933 if (TTY_TERMSCRIPT (tty)) 945 if (tty->termscript)
934 fwrite (conversion_buffer, 1, produced, 946 fwrite (conversion_buffer, 1, produced,
935 TTY_TERMSCRIPT (tty)); 947 tty->termscript);
936 } 948 }
937 949
938 OUTPUT1_IF (tty, tty->TS_pad_inserted_char); 950 OUTPUT1_IF (tty, tty->TS_pad_inserted_char);
@@ -2240,7 +2252,11 @@ term_init (char *name, char *terminal_type, int must_succeed)
2240 2252
2241 display = get_named_tty_display (name); 2253 display = get_named_tty_display (name);
2242 if (display) 2254 if (display)
2243 return display; /* We have already opened a display there. */ 2255 {
2256 if (! display->display_info.tty->input)
2257 error ("%s already has a suspended frame on it, can't open it twice", name);
2258 return display;
2259 }
2244 2260
2245 display = create_display (); 2261 display = create_display ();
2246 tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info)); 2262 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.",
2550 /* Get frame size from system, or else from termcap. */ 2566 /* Get frame size from system, or else from termcap. */
2551 { 2567 {
2552 int height, width; 2568 int height, width;
2553 get_tty_size (fileno (TTY_INPUT (tty)), &width, &height); 2569 get_tty_size (fileno (tty->input), &width, &height);
2554 FrameCols (tty) = width; 2570 FrameCols (tty) = width;
2555 FrameRows (tty) = height; 2571 FrameRows (tty) = height;
2556 } 2572 }
@@ -2735,7 +2751,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2735 && tty->TS_end_standout_mode 2751 && tty->TS_end_standout_mode
2736 && !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode)); 2752 && !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode));
2737 2753
2738 UseTabs (tty) = tabs_safe_p (fileno (TTY_INPUT (tty))) && TabWidth (tty) == 8; 2754 UseTabs (tty) = tabs_safe_p (fileno (tty->input)) && TabWidth (tty) == 8;
2739 2755
2740 display->scroll_region_ok 2756 display->scroll_region_ok
2741 = (tty->Wcm->cm_abs 2757 = (tty->Wcm->cm_abs
@@ -2754,7 +2770,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
2754 2770
2755 display->fast_clear_end_of_line = tty->TS_clr_line != 0; 2771 display->fast_clear_end_of_line = tty->TS_clr_line != 0;
2756 2772
2757 init_baud_rate (fileno (TTY_INPUT (tty))); 2773 init_baud_rate (fileno (tty->input));
2758 2774
2759#ifdef AIXHFT 2775#ifdef AIXHFT
2760 /* The HFT system on AIX doesn't optimize for scrolling, so it's 2776 /* The HFT system on AIX doesn't optimize for scrolling, so it's
@@ -3067,6 +3083,134 @@ delete_display (struct display *dev)
3067 xfree (dev); 3083 xfree (dev);
3068} 3084}
3069 3085
3086
3087
3088DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0,
3089 doc: /* Suspend the terminal device TTY.
3090The terminal is restored to its default state, and Emacs closes all
3091access to the terminal device. Frames that use the device are not
3092deleted, but input is not read from them and if they change, their
3093display is not updated.
3094
3095TTY may a string (a device name), a frame, or nil for the display
3096device of the currently selected frame.
3097
3098This function runs `suspend-tty-functions' after suspending the
3099device. The functions are run with one arg, the name of the terminal
3100device.
3101
3102`suspend-tty' does nothing if it is called on an already suspended
3103device.
3104
3105A suspended terminal device may be resumed by calling `resume-tty' on
3106it. */)
3107 (tty)
3108 Lisp_Object tty;
3109{
3110 struct display *d = get_tty_display (tty);
3111 FILE *f;
3112
3113 if (!d)
3114 error ("Unknown tty device");
3115
3116 f = d->display_info.tty->input;
3117
3118 if (f)
3119 {
3120 reset_sys_modes (d->display_info.tty);
3121
3122 delete_keyboard_wait_descriptor (fileno (f));
3123
3124 fclose (f);
3125 if (f != d->display_info.tty->output)
3126 fclose (d->display_info.tty->output);
3127
3128 d->display_info.tty->input = 0;
3129 d->display_info.tty->output = 0;
3130
3131 if (FRAMEP (d->display_info.tty->top_frame))
3132 FRAME_SET_VISIBLE (XFRAME (d->display_info.tty->top_frame), 0);
3133
3134 /* Run `suspend-tty-functions'. */
3135 if (!NILP (Vrun_hooks))
3136 {
3137 Lisp_Object args[2];
3138 args[0] = intern ("suspend-tty-functions");
3139 if (d->display_info.tty->name)
3140 {
3141 args[1] = build_string (d->display_info.tty->name);
3142 }
3143 else
3144 args[1] = Qnil;
3145 Frun_hook_with_args (2, args);
3146 }
3147 }
3148
3149 return Qnil;
3150}
3151
3152
3153DEFUN ("resume-tty", Fresume_tty, Sresume_tty, 0, 1, 0,
3154 doc: /* Resume the previously suspended terminal device TTY.
3155The terminal is opened and reinitialized. Frames that used the
3156suspended device are revived.
3157
3158This function runs `resume-tty-functions' after resuming the device.
3159The functions are run with one arg, the name of the terminal device.
3160
3161`resume-tty' does nothing if it is called on a device that is not
3162suspended.
3163
3164TTY may a string (a device name), a frame, or nil for the display
3165device of the currently selected frame. */)
3166 (tty)
3167 Lisp_Object tty;
3168{
3169 struct display *d = get_tty_display (tty);
3170 int fd;
3171
3172 if (!d)
3173 error ("Unknown tty device");
3174
3175 if (!d->display_info.tty->input)
3176 {
3177 fd = emacs_open (d->display_info.tty->name, O_RDWR | O_NOCTTY, 0);
3178
3179#ifdef TIOCNOTTY
3180 /* Drop our controlling tty if it is the same device. */
3181 if (ioctl (fd, TIOCNOTTY, 0) != -1)
3182 {
3183 no_controlling_tty = 1;
3184 }
3185#endif
3186
3187 d->display_info.tty->output = fdopen (fd, "w+");
3188 d->display_info.tty->input = d->display_info.tty->output;
3189
3190 add_keyboard_wait_descriptor (fd);
3191
3192 if (FRAMEP (d->display_info.tty->top_frame))
3193 FRAME_SET_VISIBLE (XFRAME (d->display_info.tty->top_frame), 1);
3194
3195 init_sys_modes (d->display_info.tty);
3196
3197 /* Run `suspend-tty-functions'. */
3198 if (!NILP (Vrun_hooks))
3199 {
3200 Lisp_Object args[2];
3201 args[0] = intern ("resume-tty-functions");
3202 if (d->display_info.tty->name)
3203 {
3204 args[1] = build_string (d->display_info.tty->name);
3205 }
3206 else
3207 args[1] = Qnil;
3208 Frun_hook_with_args (2, args);
3209 }
3210 }
3211
3212 return Qnil;
3213}
3070 3214
3071 3215
3072void 3216void
@@ -3092,6 +3236,20 @@ The functions are run with one argument, the name of the tty to be deleted.
3092See `delete-tty'. */); 3236See `delete-tty'. */);
3093 Vdelete_tty_after_functions = Qnil; 3237 Vdelete_tty_after_functions = Qnil;
3094 3238
3239
3240 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions,
3241 doc: /* Functions to be run after suspending a tty.
3242The functions are run with one argument, the name of the tty to be suspended.
3243See `suspend-tty'. */);
3244 Vsuspend_tty_functions = Qnil;
3245
3246
3247 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions,
3248 doc: /* Functions to be run after resuming a tty.
3249The functions are run with one argument, the name of the tty that was revived.
3250See `resume-tty'. */);
3251 Vresume_tty_functions = Qnil;
3252
3095 Qframe_tty_name = intern ("frame-tty-name"); 3253 Qframe_tty_name = intern ("frame-tty-name");
3096 staticpro (&Qframe_tty_name); 3254 staticpro (&Qframe_tty_name);
3097 3255
@@ -3103,6 +3261,8 @@ See `delete-tty'. */);
3103 defsubr (&Sframe_tty_name); 3261 defsubr (&Sframe_tty_name);
3104 defsubr (&Sframe_tty_type); 3262 defsubr (&Sframe_tty_type);
3105 defsubr (&Sdelete_tty); 3263 defsubr (&Sdelete_tty);
3264 defsubr (&Ssuspend_tty);
3265 defsubr (&Sresume_tty);
3106 3266
3107 Fprovide (intern ("multi-tty"), Qnil); 3267 Fprovide (intern ("multi-tty"), Qnil);
3108 3268
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
42 42
43 /* Input/output */ 43 /* Input/output */
44 44
45 FILE *input; /* The stream to be used for terminal input. */ 45 FILE *input; /* The stream to be used for terminal input.
46 FILE *output; /* The stream to be used for terminal output. */ 46 NULL if the terminal is suspended. */
47 FILE *output; /* The stream to be used for terminal output.
48 NULL if the terminal is suspended. */
47 49
48 FILE *termscript; /* If nonzero, send all terminal output 50 FILE *termscript; /* If nonzero, send all terminal output
49 characters to this stream also. */ 51 characters to this stream also. */
@@ -200,9 +202,5 @@ extern struct tty_display_info *tty_list;
200 202
201#define CURTTY() FRAME_TTY (SELECTED_FRAME()) 203#define CURTTY() FRAME_TTY (SELECTED_FRAME())
202 204
203#define TTY_INPUT(t) ((t)->input)
204#define TTY_OUTPUT(t) ((t)->output)
205#define TTY_TERMSCRIPT(t) ((t)->termscript)
206
207/* arch-tag: bf9f0d49-842b-42fb-9348-ec8759b27193 205/* arch-tag: bf9f0d49-842b-42fb-9348-ec8759b27193
208 (do not change this comment) */ 206 (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
513 frames on the display when it calls this hook, so infinite 513 frames on the display when it calls this hook, so infinite
514 recursion is prevented. */ 514 recursion is prevented. */
515 void (*delete_display_hook) P_ ((struct display *)); 515 void (*delete_display_hook) P_ ((struct display *));
516
517}; 516};
518 517
519 518