diff options
| author | Karoly Lorentey | 2004-02-28 01:23:39 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2004-02-28 01:23:39 +0000 |
| commit | 0b0d3e0bcefdde298893aaad2e816e1503cef222 (patch) | |
| tree | 439342044857514ad784de0470f5546eb9c3ef9a /src | |
| parent | 2fc0cf2aefa777e5fe48596e2d43774b28051931 (diff) | |
| download | emacs-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.c | 18 | ||||
| -rw-r--r-- | src/dispnew.c | 58 | ||||
| -rw-r--r-- | src/frame.c | 5 | ||||
| -rw-r--r-- | src/keyboard.c | 15 | ||||
| -rw-r--r-- | src/sysdep.c | 96 | ||||
| -rw-r--r-- | src/term.c | 234 | ||||
| -rw-r--r-- | src/termchar.h | 10 | ||||
| -rw-r--r-- | src/termhooks.h | 1 |
8 files changed, 309 insertions, 128 deletions
| @@ -64,9 +64,9 @@ int | |||
| 64 | cmputc (c) | 64 | cmputc (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 | ||
| 670 | Note that changing the size of one terminal frame automatically affects all. */) | 670 | Note that changing the size of one terminal frame automatically |
| 671 | affects 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 () | |||
| 2030 | void | 2040 | void |
| 2031 | stop_vms_input () | 2041 | stop_vms_input () |
| 2032 | { | 2042 | { |
| 2033 | return SYS$DASSGN (fileno (TTY_INPUT (CURTTY()))); | 2043 | return SYS$DASSGN (fileno (CURTTY ()->input))); |
| 2034 | } | 2044 | } |
| 2035 | 2045 | ||
| 2036 | short input_buffer; | 2046 | short 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 | ||
| 107 | Lisp_Object Vring_bell_function; | 107 | Lisp_Object Vring_bell_function; |
| 108 | 108 | ||
| 109 | /* Functions to call after a tty was deleted. */ | 109 | /* Functions to call after deleting a tty. */ |
| 110 | Lisp_Object Vdelete_tty_after_functions; | 110 | Lisp_Object Vdelete_tty_after_functions; |
| 111 | 111 | ||
| 112 | /* Functions to call after suspending a tty. */ | ||
| 113 | Lisp_Object Vsuspend_tty_functions; | ||
| 114 | |||
| 115 | /* Functions to call after resuming a tty. */ | ||
| 116 | Lisp_Object Vresume_tty_functions; | ||
| 117 | |||
| 112 | /* Chain of all displays currently in use. */ | 118 | /* Chain of all displays currently in use. */ |
| 113 | struct display *display_list; | 119 | struct 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 | |||
| 243 | tty_reset_terminal_modes (struct display *display) | 252 | tty_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 | ||
| 258 | void | 270 | void |
| @@ -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 | |||
| 3088 | DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0, | ||
| 3089 | doc: /* Suspend the terminal device TTY. | ||
| 3090 | The terminal is restored to its default state, and Emacs closes all | ||
| 3091 | access to the terminal device. Frames that use the device are not | ||
| 3092 | deleted, but input is not read from them and if they change, their | ||
| 3093 | display is not updated. | ||
| 3094 | |||
| 3095 | TTY may a string (a device name), a frame, or nil for the display | ||
| 3096 | device of the currently selected frame. | ||
| 3097 | |||
| 3098 | This function runs `suspend-tty-functions' after suspending the | ||
| 3099 | device. The functions are run with one arg, the name of the terminal | ||
| 3100 | device. | ||
| 3101 | |||
| 3102 | `suspend-tty' does nothing if it is called on an already suspended | ||
| 3103 | device. | ||
| 3104 | |||
| 3105 | A suspended terminal device may be resumed by calling `resume-tty' on | ||
| 3106 | it. */) | ||
| 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 | |||
| 3153 | DEFUN ("resume-tty", Fresume_tty, Sresume_tty, 0, 1, 0, | ||
| 3154 | doc: /* Resume the previously suspended terminal device TTY. | ||
| 3155 | The terminal is opened and reinitialized. Frames that used the | ||
| 3156 | suspended device are revived. | ||
| 3157 | |||
| 3158 | This function runs `resume-tty-functions' after resuming the device. | ||
| 3159 | The 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 | ||
| 3162 | suspended. | ||
| 3163 | |||
| 3164 | TTY may a string (a device name), a frame, or nil for the display | ||
| 3165 | device 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 | ||
| 3072 | void | 3216 | void |
| @@ -3092,6 +3236,20 @@ The functions are run with one argument, the name of the tty to be deleted. | |||
| 3092 | See `delete-tty'. */); | 3236 | See `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. | ||
| 3242 | The functions are run with one argument, the name of the tty to be suspended. | ||
| 3243 | See `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. | ||
| 3249 | The functions are run with one argument, the name of the tty that was revived. | ||
| 3250 | See `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 | ||