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