(here): New variable.
(decode_options): Use it.
(ec_get_tty, ec_set_tty, init_tty, window_change, hang_up_signal): New functions.
(window_change_signal, init_signals, reset_tty, init_pty, copy_from_to): Ditto.
(pty_conversation): Ditto.
(main): Use them.
(master, pty_name, old_tty, tty, old_tty_valid, tty_erase_char): New variables.
(flow_control, meta_key, _sobuf, in_conversation, quit_conversation): Ditto.
lisp/server.el (server-process-filter): Added support for opening a new terminal frame.
dispextern.h (get_frame_size): Renamed to get_tty_size, added tty_output parameter.
dispnew.c (Fredraw_frame): fflush the current terminal instead of stdout.
(direct_output_for_insert, direct_output_forward_char, update_frame_1): Ditto.
(Fding, bitch_at_user): Ditto.
(update_frame_1): Count pending output for current terminal instead of stdout.
(window_change_signal): Resize all terminals.
(change_frame_size): Don't resize all terminals to the same size.
frame.c (Vterminal_frame): Removed.
(syms_of_frame): Removed declaration of Vterminal_frame.
(make_terminal_frame): Set the top frame of the terminal to the new frame.
(Fmake_terminal_frame): Get a new frame size from get_tty_size, don't copy it.
(do_switch_frame): Handle terminal frame visibility.
(next_frame, prev_frame): Skip over frames on different terminals.
frame.h (Vterminal_frame): Removed.
keyboard.c (input_fd): Removed.
(read_avail_input): Removed first argument from read_socket_hook.
Try to read from each available tty, until one succeeds.
(Fsuspend_emacs): Don't suspend if there are multiple terminals.
lisp.h (get_frame_size): Removed superflous declaration.
xterm.c (Xtread_socket): Removed first parameter.
macterm.h (XTread_socket): Ditto.
w32inevt.c (w32_console_read_socket): Ditto.
w32term.c (w32_read_socket): Ditto.
sysdep.c (input_fd): Removed.
(change_input_fd): Removed.
(discard_tty_input): Discard pending input on _all_ input descriptors.
(stuff_char, tabs_safe_p): Use current terminal instead of input_fd.
(init_baud_rate, request_sigio, unrequest_sigio): Ditto.
(init_sys_modes, reset_sys_modes): Ditto.
(narrow_foreground_group, widen_foreground_group): Use stdin.
(init_sys_modes, reset_sys_modes): otty parameter renamed to tty_out.
(get_frame_size): Renamed to get_tty_size, added tty_out parameter.
term.c (read_socket_hook): Removed first parameter.
(clear_end_of_line): Use updating_frame, if possible.
(write_glyphs, insert_glyphs, ins_del_lines): Ditto.
(term_init): Renamed get_frame_size to get_tty_size.
termchar.h (struct tty_output): New entries: top_frame,
previous_terminal_frame.
termhooks.h (read_socket_hook): Removed first parameter.
window.c (init_window_once): Removed reference to Vterminal_frame.
xdisp.c (previous_terminal_frame): Moved to struct tty_output.
(redisplay_internal): Updated to use previous_terminal_frame in tty_output.
Allow for simultaneous refresh of multiple ttys.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-5
------
We can create frames on new tty devices, but there are problems with
-refresh (only the (single) selected frame is refreshed), and input is
-read only from the initial terminal. At the moment, the type of the
-new terminals must be the same as the initial terminal.
+redisplay. Input is read from all terminals (NOT via MULTIKBOARD!).
+At the moment, the type of the new terminals must be the same as the
+initial terminal. Emacsclient is extended to support opening a new
+terminal frame.
-To try it out, start up emacs, and evaluate the following:
+To try it out, start up the emacs server (M-x server-start), and then
+start emacsclient with
- (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
+ emacsclient -h
-(With your own values, of course.) If you switch to the new frame
-with M-x other-frame, the new tty is refreshed with the frame
-contents. The result of input from the original terminal appears on
-the new. If you exit emacs, both terminals are restored to their
-previous states.
+If you exit emacs, both terminals are restored to their previous
+states.
X, Mac, Windows and DOS support is broken.
specify a terminal device (`tty' parameter) and a terminal type
(`tty-type' parameter) to `make-terminal-frame'.
+** Emacsclient has been extended to support opening a new terminal
+ frame.
CHANGELOG
---------
(Done, new frame parameters: `tty' and `tty-type'.)
+-- Implement support for reading from multiple terminals.
+
+ (Done, read_avail_input tries to read from each terminal, until one
+ succeeds.)
+
+-- other-frame should cycle through the frames on the `current'
+ terminal.
+
+ (Done. A little fragile, but seems to work.)
+
+-- Support different terminal sizes.
+
+ (Done, no problem.)
+
+-- Make sure terminal resizes are handled gracefully. (Could be
+ problematic.)
+
+ (Done. We don't get SIGWINCH for additional ttys, though.)
+
+-- Extend emacsclient to automatically open a new tty when it connects
+ to Emacs.
+
+ (Done. It's an ugly hack, needs more work.)
+
+-- Redisplay must refresh the topmost frame on all terminals, not just
+ the initial terminal.
+
+ (Done, but introduced ugly redisplay problems. Ugh.)
+
+
THINGS TO DO
------------
+** Fix redisplay problems.
+
** Make make-terminal-frame look up the tty and tty-type parameters
from the currently selected terminal before the global default.
** Move optimalization parameters (costs) from union output_data to
struct frame.
+** Provide a way for emacsclient to tell Emacs that the tty has been
+ resized.
+
** Implement terminal deletion, i.e., closing the tty device and
restoring its previous state without exiting Emacs. This should be
exported to the Lisp interpreter.
Currently, they are still stored in global variables, so we don't
really support multiple terminal types.
-** Support different terminal sizes. (Should be solved by the
- previous entry.)
-
-** Make sure terminal resizes are handled gracefully. (Could be
- problematic.)
-** Implement support for reading from multiple terminals.
-
-** other-frame should cycle through the frames on the `current'
- terminal. This means that Emacs must know from which terminal the
- last keyboard event came from. (Multikeyboard support may help
- with this.)
-
-** Redisplay must refresh the topmost on all terminals, not just
- the initial terminal.
+** Each keypress should automatically select the frame corresponding
+ to the terminal that it was coming from. This means that Emacs
+ must know from which terminal the last keyboard event came from.
+ (Multikeyboard support may help with this.)
** Make struct tty_output available from Lisp.
-** Extend emacsclient to automatically open a new tty when it connects
- to Emacs.
-
** Implement support for starting an interactive Emacs session without
an initial frame. (The user would connect to it and open frames
later, with emacsclient.) Not necessary a good idea.
# include <pwd.h>
#endif /* not VMS */
+
+/****************************************/
+
+#include <errno.h>
+#include <signal.h>
+
+#ifndef INCLUDED_FCNTL
+#define INCLUDED_FCNTL
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_TERMIOS
+#ifndef NO_TERMIO
+#include <termio.h>
+#endif
+#include <termios.h>
+#endif /* not HAVE_TERMIOS */
+
+#ifdef __GNU_LIBRARY__
+#include <sys/ioctl.h>
+#include <termios.h>
+#endif
+
+#if (defined (POSIX) || defined (NEED_UNISTD_H)) && defined (HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+
+\f
+/* Try to establish the correct character to disable terminal functions
+ in a system-independent manner. Note that USG (at least) define
+ _POSIX_VDISABLE as 0! */
+
+#ifdef _POSIX_VDISABLE
+#define CDISABLE _POSIX_VDISABLE
+#else /* not _POSIX_VDISABLE */
+#ifdef CDEL
+#undef CDISABLE
+#define CDISABLE CDEL
+#else /* not CDEL */
+#define CDISABLE 255
+#endif /* not CDEL */
+#endif /* not _POSIX_VDISABLE */
+\f
+
+
+/****************************************/
+
char *getenv (), *getwd ();
char *getcwd ();
/* The display on which Emacs should work. --display. */
char *display = NULL;
+/* Nonzero means open a new Emacs frame on the current terminal. */
+int here = 0;
+
/* If non-NULL, the name of an editor to fallback to if the server
is not running. --alternate-editor. */
const char * alternate_editor = NULL;
{ "eval", no_argument, NULL, 'e' },
{ "help", no_argument, NULL, 'H' },
{ "version", no_argument, NULL, 'V' },
+ { "here", no_argument, NULL, 'h' },
{ "alternate-editor", required_argument, NULL, 'a' },
{ "socket-name", required_argument, NULL, 's' },
{ "display", required_argument, NULL, 'd' },
while (1)
{
int opt = getopt_long (argc, argv,
- "VHnea:s:d:", longopts, 0);
+ "VHnea:s:d:h", longopts, 0);
if (opt == EOF)
break;
exit (0);
break;
+ case 'h':
+ here = 1;
+ break;
+
case 'H':
print_help_and_exit ();
break;
break;
}
}
+
+ if (here) {
+ nowait = 0;
+ display = 0;
+ }
+
}
void
The following OPTIONS are accepted:\n\
-V, --version Just print a version info and return\n\
-H, --help Print this usage information message\n\
+-h, --here Open a new Emacs frame on the current terminal\n\
-n, --no-wait Don't wait for the server to return\n\
-e, --eval Evaluate the FILE arguments as ELisp expressions\n\
-d, --display=DISPLAY Visit the file in the given display\n\
}
}
+\f
+#ifdef HAVE_TERMIOS
+
+/* Adapted from emacs_get_tty() in sysdep.c. */
+int
+ec_get_tty (int fd, struct termios *settings)
+{
+ bzero (settings, sizeof (struct termios));
+ if (tcgetattr (fd, settings) < 0)
+ return -1;
+ return 0;
+}
+
+/* Adapted from emacs_set_tty() in sysdep.c. */
+int
+ec_set_tty (int fd, struct termios *settings, int flushp)
+{
+ /* Set the primary parameters - baud rate, character size, etcetera. */
+
+ int i;
+ /* We have those nifty POSIX tcmumbleattr functions.
+ William J. Smith <wjs@wiis.wang.com> writes:
+ "POSIX 1003.1 defines tcsetattr to return success if it was
+ able to perform any of the requested actions, even if some
+ of the requested actions could not be performed.
+ We must read settings back to ensure tty setup properly.
+ AIX requires this to keep tty from hanging occasionally." */
+ /* This make sure that we don't loop indefinitely in here. */
+ for (i = 0 ; i < 10 ; i++)
+ if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, settings) < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ else
+ return -1;
+ }
+ else
+ {
+ struct termios new;
+
+ bzero (&new, sizeof (new));
+ /* Get the current settings, and see if they're what we asked for. */
+ tcgetattr (fd, &new);
+ /* We cannot use memcmp on the whole structure here because under
+ * aix386 the termios structure has some reserved field that may
+ * not be filled in.
+ */
+ if ( new.c_iflag == settings->c_iflag
+ && new.c_oflag == settings->c_oflag
+ && new.c_cflag == settings->c_cflag
+ && new.c_lflag == settings->c_lflag
+ && memcmp (new.c_cc, settings->c_cc, NCCS) == 0)
+ break;
+ else
+ continue;
+ }
+ return 0;
+}
+
+int master;
+char *pty_name;
+
+struct termios old_tty;
+struct termios tty;
+int old_tty_valid;
+
+int tty_erase_char;
+int flow_control = 0;
+int meta_key = 0;
+char _sobuf[BUFSIZ];
+
+/* Adapted from init_sys_modes() in sysdep.c. */
+int
+init_tty ()
+{
+ if (! isatty (0))
+ {
+ fprintf (stderr, "%s: Input is not a terminal", "init_tty");
+ return 0;
+ }
+
+ ec_get_tty (0, &old_tty);
+ old_tty_valid = 1;
+ tty = old_tty;
+
+ tty_erase_char = old_tty.c_cc[VERASE];
+
+ tty.c_iflag |= (IGNBRK); /* Ignore break condition */
+ tty.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
+#ifdef INLCR
+ tty.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
+#endif
+#ifdef ISTRIP
+ tty.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
+#endif
+ tty.c_lflag &= ~ECHO; /* Disable echo */
+ tty.c_lflag &= ~ICANON; /* Disable erase/kill processing */
+#ifdef IEXTEN
+ tty.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
+#endif
+ tty.c_lflag |= ISIG; /* Enable signals */
+ if (flow_control)
+ {
+ tty.c_iflag |= IXON; /* Enable start/stop output control */
+#ifdef IXANY
+ tty.c_iflag &= ~IXANY;
+#endif /* IXANY */
+ }
+ else
+ tty.c_iflag &= ~IXON; /* Disable start/stop output control */
+ tty.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
+ on output */
+ tty.c_oflag &= ~TAB3; /* Disable tab expansion */
+#ifdef CS8
+ if (meta_key)
+ {
+ tty.c_cflag |= CS8; /* allow 8th bit on input */
+ tty.c_cflag &= ~PARENB; /* Don't check parity */
+ }
+#endif
+ tty.c_cc[VINTR] = CDISABLE;
+ tty.c_cc[VQUIT] = CDISABLE;
+ tty.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
+ tty.c_cc[VTIME] = 0; /* no matter how long that takes. */
+#ifdef VSWTCH
+ tty.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use of C-z */
+#endif
+
+#ifdef VSUSP
+ tty.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
+#endif /* VSUSP */
+#ifdef V_DSUSP
+ tty.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
+#endif /* V_DSUSP */
+#ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
+ tty.c_cc[VDSUSP] = CDISABLE;
+#endif /* VDSUSP */
+#ifdef VLNEXT
+ tty.c_cc[VLNEXT] = CDISABLE;
+#endif /* VLNEXT */
+#ifdef VREPRINT
+ tty.c_cc[VREPRINT] = CDISABLE;
+#endif /* VREPRINT */
+#ifdef VWERASE
+ tty.c_cc[VWERASE] = CDISABLE;
+#endif /* VWERASE */
+#ifdef VDISCARD
+ tty.c_cc[VDISCARD] = CDISABLE;
+#endif /* VDISCARD */
+
+ if (flow_control)
+ {
+#ifdef VSTART
+ tty.c_cc[VSTART] = '\021';
+#endif /* VSTART */
+#ifdef VSTOP
+ tty.c_cc[VSTOP] = '\023';
+#endif /* VSTOP */
+ }
+ else
+ {
+#ifdef VSTART
+ tty.c_cc[VSTART] = CDISABLE;
+#endif /* VSTART */
+#ifdef VSTOP
+ tty.c_cc[VSTOP] = CDISABLE;
+#endif /* VSTOP */
+ }
+
+#ifdef SET_LINE_DISCIPLINE
+ /* Need to explicitly request TERMIODISC line discipline or
+ Ultrix's termios does not work correctly. */
+ tty.c_line = SET_LINE_DISCIPLINE;
+#endif
+
+#ifdef AIX
+#ifndef IBMR2AIX
+ /* AIX enhanced edit loses NULs, so disable it. */
+ tty.c_line = 0;
+ tty.c_iflag &= ~ASCEDIT;
+#else
+ tty.c_cc[VSTRT] = 255;
+ tty.c_cc[VSTOP] = 255;
+ tty.c_cc[VSUSP] = 255;
+ tty.c_cc[VDSUSP] = 255;
+#endif /* IBMR2AIX */
+ if (flow_control)
+ {
+#ifdef VSTART
+ tty.c_cc[VSTART] = '\021';
+#endif /* VSTART */
+#ifdef VSTOP
+ tty.c_cc[VSTOP] = '\023';
+#endif /* VSTOP */
+ }
+ /* Also, PTY overloads NUL and BREAK.
+ don't ignore break, but don't signal either, so it looks like NUL.
+ This really serves a purpose only if running in an XTERM window
+ or via TELNET or the like, but does no harm elsewhere. */
+ tty.c_iflag &= ~IGNBRK;
+ tty.c_iflag &= ~BRKINT;
+#endif /* AIX */
+
+ ec_set_tty (0, &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 (!flow_control) ioctl (0, TCXONC, 1);
+#endif
+#ifndef APOLLO
+#ifdef TIOCSTART
+ if (!flow_control) ioctl (0, TIOCSTART, 0);
+#endif
+#endif
+
+#if defined (HAVE_TERMIOS) || defined (HPUX9)
+#ifdef TCOON
+ if (!flow_control) tcflow (0, TCOON);
+#endif
+#endif
+
+#ifdef _IOFBF
+ /* 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 (stdout, (char *) _sobuf, _IOFBF, sizeof _sobuf);
+#else
+ setbuf (stdout, (char *) _sobuf);
+#endif
+
+ return 1;
+}
+
+void
+window_change ()
+{
+ int width, height;
+
+#ifdef TIOCGWINSZ
+ {
+ /* BSD-style. */
+ struct winsize size;
+
+ if (ioctl (0, TIOCGWINSZ, &size) == -1)
+ width = height = 0;
+ else
+ {
+ width = size.ws_col;
+ height = size.ws_row;
+ }
+ }
+#else
+#ifdef TIOCGSIZE
+ {
+ /* SunOS - style. */
+ struct ttysize size;
+
+ if (ioctl (0, TIOCGSIZE, &size) == -1)
+ width = height = 0;
+ else
+ {
+ width = size.ts_cols;
+ height = size.ts_lines;
+ }
+ }
+#endif /* not SunOS-style */
+#endif /* not BSD-style */
+
+#ifdef TIOCSWINSZ
+ {
+ /* BSD-style. */
+ struct winsize size;
+ size.ws_row = height;
+ size.ws_col = width;
+
+ ioctl (master, TIOCSWINSZ, &size);
+ }
+#else
+#ifdef TIOCSSIZE
+ {
+ /* SunOS - style. */
+ struct ttysize size;
+ size.ts_lines = height;
+ size.ts_cols = width;
+
+ ioctl (master, TIOCGSIZE, &size);
+ }
+#endif /* not SunOS-style */
+#endif /* not BSD-style */
+}
+
+int in_conversation = 0;
+int quit_conversation = 0;
+
+SIGTYPE
+hang_up_signal (int signalnum)
+{
+ int old_errno = errno;
+
+ if (! in_conversation)
+ return;
+
+ quit_conversation = 1;
+
+ errno = old_errno;
+}
+
+SIGTYPE
+window_change_signal (int signalnum)
+{
+ int old_errno = errno;
+
+ if (! in_conversation)
+ goto end;
+
+ window_change();
+
+ end:
+ signal (SIGWINCH, window_change_signal);
+ errno = old_errno;
+}
+
+int
+init_signals ()
+{
+ /* Set up signal handlers. */
+ signal (SIGWINCH, window_change_signal);
+ signal (SIGHUP, hang_up_signal);
+
+ return 1;
+}
+
+
+
+/* Adapted from reset_sys_modes in sysdep.c. */
+int
+reset_tty ()
+{
+ fflush (stdout);
+#ifdef BSD_SYSTEM
+#ifndef BSD4_1
+ /* Avoid possible loss of output when changing terminal modes. */
+ fsync (fileno (stdout));
+#endif
+#endif
+
+#ifdef F_SETFL
+#ifdef O_NDELAY
+ fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NDELAY);
+#endif
+#endif /* F_SETFL */
+
+ if (old_tty_valid)
+ while (ec_set_tty (0, &old_tty, 0) < 0 && errno == EINTR)
+ ;
+
+ return 1;
+}
+
+
+int
+init_pty ()
+{
+ master = getpt ();
+ if (master < 0)
+ return 0;
+
+ if (grantpt (master) < 0 || unlockpt (master) < 0)
+ goto close_master;
+ pty_name = strdup (ptsname (master));
+ if (! pty_name)
+ goto close_master;
+
+ /* Propagate window size. */
+ window_change ();
+
+ return 1;
+
+ close_master:
+ close (master);
+ return 0;
+}
+
+int
+copy_from_to (int in, int out)
+{
+ static char buf[BUFSIZ];
+ int nread = read (in, &buf, BUFSIZ);
+ if (nread == 0)
+ return 1; /* EOF */
+ else if (nread < 0 && errno != EAGAIN)
+ return 0; /* Error */
+ else if (nread > 0)
+ {
+ int r = 0;
+ int written = 0;
+
+ do {
+ r = write (out, &buf, nread);
+ } while ((r < 0 && errno == EAGAIN)
+ || (r > 0 && (written += r) && written != nread));
+
+ if (r < 0)
+ return 0; /* Error */
+ }
+ return 1;
+}
+
+int
+pty_conversation ()
+{
+ fd_set set;
+
+ in_conversation = 1;
+
+ while (! quit_conversation) {
+ int res;
+
+ FD_ZERO (&set);
+ FD_SET (master, &set);
+ FD_SET (1, &set);
+ res = select (FD_SETSIZE, &set, NULL, NULL, NULL);
+ if (res < 0)
+ {
+ if (errno != EINTR)
+ return 0;
+ }
+ else if (res > 0)
+ {
+ if (FD_ISSET (master, &set))
+ {
+ /* Copy Emacs output to stdout. */
+ if (! copy_from_to (master, 0))
+ return 1;
+ }
+ if (FD_ISSET (1, &set))
+ {
+ /* Forward user input to Emacs. */
+ if (! copy_from_to (1, master))
+ return 1;
+ }
+ }
+ }
+ return 1;
+}
+
+#endif /* HAVE_TERMIOS */
\f
#if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM)
/* Process options. */
decode_options (argc, argv);
- if ((argc - optind < 1) && !eval)
+ if ((argc - optind < 1) && !eval && !here)
{
fprintf (stderr, "%s: file name or argument required\n", progname);
fprintf (stderr, "Try `%s --help' for more information\n", progname);
fprintf (out, " ");
}
+ if (here)
+ {
+ if (! init_signals ())
+ {
+ fprintf (stderr, "%s: ", argv[0]);
+ perror ("fdopen");
+ fail (argc, argv);
+ }
+
+ if (! init_tty ())
+ {
+ reset_tty ();
+ fprintf (stderr, "%s: ", argv[0]);
+ perror ("fdopen");
+ fail (argc, argv);
+ }
+
+ if (! init_pty ())
+ {
+ reset_tty ();
+ fprintf (stderr, "%s: ", argv[0]);
+ perror ("fdopen");
+ fail (argc, argv);
+ }
+
+ fprintf (out, "-pty ");
+ quote_file_name (pty_name, out);
+ fprintf (out, " ");
+ quote_file_name (getenv("TERM"), out);
+ fprintf (out, " ");
+ }
+
if ((argc - optind > 0))
{
for (i = optind; i < argc; i++)
}
else
{
- while ((str = fgets (string, BUFSIZ, stdin)))
- {
- quote_file_name (str, out);
- }
- fprintf (out, " ");
+ if (!here)
+ {
+ while ((str = fgets (string, BUFSIZ, stdin)))
+ {
+ quote_file_name (str, out);
+ }
+ fprintf (out, " ");
+ }
}
fprintf (out, "\n");
/* Maybe wait for an answer. */
if (nowait)
- return 0;
+ {
+ reset_tty ();
+ return 0;
+ }
+ if (here)
+ {
+ if (! pty_conversation ())
+ {
+ reset_tty ();
+ fprintf (stderr, "%s: ", argv[0]);
+ perror ("fdopen");
+ fail (argc, argv);
+ }
+ close (master);
+ reset_tty ();
+ return 0;
+ }
+
if (!eval)
{
printf ("Waiting for Emacs...");
printf ("\n");
fflush (stdout);
+ reset_tty ();
return 0;
}
--- /dev/null
+/* Terminal initialization for emacsclient.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
--- /dev/null
+/* Terminal initialization for emacsclient.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Adapted from systty.h */
+
+
+#ifdef HAVE_TERMIOS
+#define HAVE_TCATTR
+#endif
+
+\f
+/* Include the proper files. */
+#ifdef HAVE_TERMIO
+#ifdef __DGUX
+#include <sys/ioctl.h>
+#endif
+#ifndef NO_TERMIO
+#include <termio.h>
+#endif /* not NO_TERMIO */
+#ifndef INCLUDED_FCNTL
+#define INCLUDED_FCNTL
+#include <fcntl.h>
+#endif
+#else /* not HAVE_TERMIO */
+#ifdef HAVE_TERMIOS
+#if defined(_AIX) && defined(_I386)
+#include <termios.h> /* termios.h needs to be before termio.h */
+#include <termio.h>
+#else /* not (_AIX && _I386) */
+#ifndef NO_TERMIO
+#include <termio.h>
+#endif
+#include <termios.h>
+#endif /* not (_AIX && _I386) */
+#define INCLUDED_FCNTL
+#include <fcntl.h>
+#else /* neither HAVE_TERMIO nor HAVE_TERMIOS */
+#ifndef VMS
+#ifndef DOS_NT
+#include <sgtty.h>
+#endif /* not DOS_NT */
+#else /* VMS */
+#include <descrip.h>
+static struct iosb
+{
+ short status;
+ short offset;
+ short termlen;
+ short term;
+} input_iosb;
+
+extern int waiting_for_ast;
+extern int stop_input;
+extern int input_ef;
+extern int timer_ef;
+extern int process_ef;
+extern int input_eflist;
+extern int timer_eflist;
+
+static $DESCRIPTOR (input_dsc, "TT");
+static int terminator_mask[2] = { 0, 0 };
+
+static struct sensemode {
+ short status;
+ unsigned char xmit_baud;
+ unsigned char rcv_baud;
+ unsigned char crfill;
+ unsigned char lffill;
+ unsigned char parity;
+ unsigned char unused;
+ char class;
+ char type;
+ short scr_wid;
+ unsigned long tt_char : 24, scr_len : 8;
+ unsigned long tt2_char;
+} sensemode_iosb;
+#endif /* VMS */
+#endif /* not HAVE_TERMIOS */
+#endif /* not HAVE_TERMIO */
+
+#ifdef __GNU_LIBRARY__
+#include <sys/ioctl.h>
+#include <termios.h>
+#endif
+
+#ifdef AIXHFT
+/* Get files for keyboard remapping */
+#define HFNKEYS 2
+#include <sys/hft.h>
+#include <sys/devinfo.h>
+#endif
+
+/* Get rid of LLITOUT in 4.1, since it is said to stimulate kernel bugs. */
+#ifdef BSD4_1
+#undef LLITOUT
+#define LLITOUT 0
+#endif /* 4.1 */
+
+#ifdef NEED_BSDTTY
+#include <sys/bsdtty.h>
+#endif
+
+#if defined (HPUX) && defined (HAVE_PTYS)
+#include <sys/ptyio.h>
+#endif
+
+#ifdef AIX
+#include <sys/pty.h>
+#endif /* AIX */
+
+#if (defined (POSIX) || defined (NEED_UNISTD_H)) && defined (HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#ifdef SYSV_PTYS
+#include <sys/types.h>
+#include <sys/tty.h>
+#ifdef titan
+#include <sys/ttyhw.h>
+#include <sys/stream.h>
+#endif
+#ifndef NO_PTY_H
+#include <sys/pty.h>
+#endif
+#endif
+
+/* saka@pfu.fujitsu.co.JP writes:
+ FASYNC defined in this file. But, FASYNC don't working.
+ so no problem, because unrequest_sigio only need. */
+#if defined (pfa)
+#include <sys/file.h>
+#endif
+
+\f
+/* Special cases - inhibiting the use of certain features. */
+
+#ifdef APOLLO
+#undef TIOCSTART
+#endif
+
+#ifdef XENIX
+#undef TIOCGETC /* Avoid confusing some conditionals that test this. */
+#endif
+
+#ifdef BROKEN_TIOCGETC
+#undef TIOCGETC /* Avoid confusing some conditionals that test this. */
+#endif
+
+/* UNIPLUS systems may have FIONREAD. */
+#ifdef UNIPLUS
+#include <sys.ioctl.h>
+#endif
+
+/* Allow m- file to inhibit use of FIONREAD. */
+#ifdef BROKEN_FIONREAD
+#undef FIONREAD
+#undef ASYNC
+#endif
+
+/* Interrupt input is not used if there is no FIONREAD. */
+#ifndef FIONREAD
+#undef SIGIO
+#endif
+
+/* On TERMIOS systems, the tcmumbleattr calls take care of these
+ parameters, and it's a bad idea to use them (on AIX, it makes the
+ tty hang for a long time). */
+#if defined (TIOCGLTC) && !defined (HAVE_TERMIOS)
+#define HAVE_LTCHARS
+#endif
+
+#if defined (TIOCGETC) && !defined (HAVE_TERMIOS)
+#define HAVE_TCHARS
+#endif
+
+\f
+/* Try to establish the correct character to disable terminal functions
+ in a system-independent manner. Note that USG (at least) define
+ _POSIX_VDISABLE as 0! */
+
+#ifdef _POSIX_VDISABLE
+#define CDISABLE _POSIX_VDISABLE
+#else /* not _POSIX_VDISABLE */
+#ifdef CDEL
+#undef CDISABLE
+#define CDISABLE CDEL
+#else /* not CDEL */
+#define CDISABLE 255
+#endif /* not CDEL */
+#endif /* not _POSIX_VDISABLE */
+\f
+/* Get the number of characters queued for output. */
+
+/* EMACS_OUTQSIZE(FD, int *SIZE) stores the number of characters
+ queued for output to the terminal FD in *SIZE, if FD is a tty.
+ Returns -1 if there was an error (i.e. FD is not a tty), 0
+ otherwise. */
+#ifdef TIOCOUTQ
+#define EMACS_OUTQSIZE(fd, size) (ioctl ((fd), TIOCOUTQ, (size)))
+#endif
+
+#ifdef HAVE_TERMIO
+#ifdef TCOUTQ
+#undef EMACS_OUTQSIZE
+#define EMACS_OUTQSIZE(fd, size) (ioctl ((fd), TCOUTQ, (size)))
+#endif
+#endif
(server-select-display display)
(error (process-send-string proc (nth 1 err))
(setq request "")))))
+ ;; Open a new tty at the client.
+ ((and (equal "-pty" arg) (string-match "\\([^ ]*\\) \\([^ ]*\\) " request))
+ (let ((pty (server-unquote-arg (match-string 1 request)))
+ (type (server-unquote-arg (match-string 2 request))))
+ (setq request (substring request (match-end 0)))
+ (condition-case err
+ (make-terminal-frame `((tty . ,pty) (tty-type . ,type)))
+ (error (process-send-string proc (nth 1 err))
+ (setq request "")))))
;; ARG is a line number option.
((string-match "\\`\\+[0-9]+\\'" arg)
(setq lineno (string-to-int (substring arg 1))))
/* Defined in sysdep.c */
-void get_frame_size P_ ((int *, int *));
+void get_tty_size P_ ((struct tty_output *, int *, int *));
void request_sigio P_ ((void));
void unrequest_sigio P_ ((void));
int tabs_safe_p P_ ((void));
clear_frame ();
clear_current_matrices (f);
update_end (f);
- fflush (stdout);
+ fflush (TTY_OUTPUT (FRAME_TTY (f)));
windows_or_buffers_changed++;
/* Mark all windows as inaccurate, so that every window will have
its redisplay done. */
/* If we can't insert glyphs, we can use this method only
at the end of a line. */
- if (!TTY_CHAR_INS_DEL_OK (CURTTY ()))
+ if (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f)))
if (PT != ZV && FETCH_BYTE (PT_BYTE) != '\n')
return 0;
rif->update_window_end_hook (w, 1, 0);
update_end (f);
updated_row = NULL;
- fflush (stdout);
+ fflush (TTY_OUTPUT (CURTTY ());
TRACE ((stderr, "direct output for insert\n"));
mark_window_display_accurate (it.window, 1);
cursor_to (y, x);
}
- fflush (stdout);
+ fflush (TTY_OUTPUT (CURTTY ()));
redisplay_performed_directly_p = 1;
return 1;
}
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 (stdout);
+ int outq = PENDING_OUTPUT_COUNT (TTY_OUTPUT (FRAME_TTY (f)));
if (outq > 900
|| (outq > 20 && ((i - 1) % preempt_count == 0)))
{
- fflush (stdout);
+ fflush (TTY_OUTPUT (FRAME_TTY (f)));
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 (stdout);
+ outq = PENDING_OUTPUT_COUNT (TTY_OUTPUT (FRAME_TTY (f)));
#endif
outq *= 10;
if (baud_rate <= outq && baud_rate > 0)
#endif
int old_errno = errno;
- get_frame_size (&width, &height);
+ struct tty_output *tty;
+
+ /* The frame size change obviously applies to a single
+ termcap-controlled terminal, but we can't decide which.
+ Therefore, we resize the frames corresponding to each tty.
+
+ XXX In fact we only get the signal for the initial terminal.
+ */
+ for (tty = tty_list; tty; tty = tty->next) {
- /* The frame size change obviously applies to a termcap-controlled
- frame. Find such a frame in the list, and assume it's the only
- one (since the redisplay code always writes to stdout, not a
- FILE * specified in the frame structure). Record the new size,
- but don't reallocate the data structures now. Let that be done
- later outside of the signal handler. */
-
- {
- Lisp_Object tail, frame;
-
- FOR_EACH_FRAME (tail, frame)
- {
- if (FRAME_TERMCAP_P (XFRAME (frame)))
- {
- change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
- break;
- }
- }
+ get_tty_size (tty, &width, &height);
+
+ {
+ Lisp_Object tail, frame;
+
+ FOR_EACH_FRAME (tail, frame)
+ {
+ if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty)
+ {
+ /* Record the new sizes, but don't reallocate the data structures
+ now. Let that be done later outside of the signal handler. */
+ change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
+ break;
+ }
+ }
+ }
}
-
+
signal (SIGWINCH, window_change_signal);
errno = old_errno;
}
{
Lisp_Object tail, frame;
- if (! FRAME_WINDOW_P (f))
+ if (FRAME_MSDOS_P (f))
{
- /* When using termcap, or on MS-DOS, all frames use
- the same screen, so a change in size affects all frames. */
+ /* On MS-DOS, all frames use the same screen, so a change in
+ size affects all frames. Termcap now supports multiple
+ ttys. */
FOR_EACH_FRAME (tail, frame)
if (! FRAME_WINDOW_P (XFRAME (frame)))
change_frame_size_1 (XFRAME (frame), newheight, newwidth,
putchar (07);
else
ring_bell ();
- fflush (stdout);
+ fflush (TTY_OUTPUT (CURTTY ()));
}
else
bitch_at_user ();
error ("Keyboard macro terminated by a command ringing the bell");
else
ring_bell ();
- fflush (stdout);
+ fflush (TTY_OUTPUT (CURTTY ()));
}
if (!noninteractive)
{
#ifdef VMS
- init_vms_input ();/* init_display calls get_frame_size, that needs this. */
+ init_vms_input ();/* init_display calls get_tty_size, that needs this. */
#endif /* VMS */
init_display (); /* Determine terminal type. Calls init_sys_modes. */
}
Lisp_Object Qface_set_after_frame_default;
-
-Lisp_Object Vterminal_frame;
Lisp_Object Vdefault_frame_alist;
Lisp_Object Vdefault_frame_scroll_bars;
Lisp_Object Vmouse_position_function;
f->output_data.tty = term_init (tty, tty_type);
else
f->output_data.tty = term_dummy_init ();
+ f->output_data.tty->top_frame = frame;
#ifdef CANNOT_DUMP
FRAME_FOREGROUND_PIXEL(f) = FACE_TTY_DEFAULT_FG_COLOR;
FRAME_BACKGROUND_PIXEL(f) = FACE_TTY_DEFAULT_BG_COLOR;
type[SBYTES (tty_type)] = 0;
}
-
f = make_terminal_frame (name, type);
}
- change_frame_size (f, FRAME_LINES (sf),
- FRAME_COLS (sf), 0, 0, 0);
+ {
+ int width, height;
+ get_tty_size (FRAME_TTY (f), &width, &height);
+ change_frame_size (f, height, width, 0, 0, 0);
+ }
+
adjust_glyphs (f);
calculate_costs (f);
XSETFRAME (frame, f);
if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
+ if (FRAME_TERMCAP_P (XFRAME (selected_frame))
+ && FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_TTY (XFRAME (selected_frame)) == FRAME_TTY (XFRAME (frame)))
+ {
+ XFRAME (selected_frame)->async_visible = 0;
+ XFRAME (frame)->async_visible = 1;
+ FRAME_TTY (XFRAME (frame))->top_frame = frame;
+ }
+
selected_frame = frame;
if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
last_nonminibuf_frame = XFRAME (selected_frame);
f = XCAR (tail);
if (passed
- && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
+ && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
+ || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame)))))
{
/* Decide whether this frame is eligible to be returned. */
if (EQ (frame, f) && !NILP (prev))
return prev;
- if (FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
+ if ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
+ || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame))))
{
/* Decide whether this frame is eligible to be returned,
according to minibuf. */
= intern ("inhibit-default-face-x-resources");
staticpro (&Qinhibit_default_face_x_resources);
- DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
- doc: /* The initial frame-object, which represents Emacs's stdout. */);
-
DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
doc: /* Non-nil if all of emacs is iconified and frame updates are not needed. */);
Vemacs_iconified = Qnil;
\f
/* Miscellanea. */
-/* Nonzero means don't assume anything about current contents of
- actual terminal frame */
-
+/* Nonzero means there is at least one garbaged frame. */
extern int frame_garbaged;
/* Nonzero means FRAME_MESSAGE_BUF (selected_frame) is being used by
#if !defined(HAVE_X_WINDOWS)
-#define PIX_TYPE int
+#define PIX_TYPE unsigned long
/* A (mostly empty) x_output structure definition for building Emacs
on Unix and GNU/Linux without X support. */
Also, if a frame used to be invisible, but has just become visible,
it must be marked as garbaged, since redisplay hasn't been keeping
- up its contents. */
+ up its contents.
+
+ Note that a tty frame is visible if and only if it is the topmost
+ frame. */
#define FRAME_SAMPLE_VISIBILITY(f) \
(((f)->async_visible && (f)->visible != (f)->async_visible) ? \
extern Lisp_Object Vframe_list;
extern Lisp_Object Vdefault_frame_alist;
-extern Lisp_Object Vterminal_frame;
-
extern Lisp_Object Vmouse_highlight;
\f
/* The currently selected frame. */
#include <config.h>
#include <signal.h>
#include <stdio.h>
+#include "lisp.h"
#include "systty.h" /* This must be included befor termchar.h. */
#include "termchar.h"
#include "termopts.h"
-#include "lisp.h"
#include "termhooks.h"
#include "macros.h"
#include "keyboard.h"
int interrupt_input_pending;
-/* File descriptor to use for input. */
-extern int input_fd;
-
#ifdef HAVE_WINDOW_SYSTEM
/* Make all keyboard buffers much bigger when using X windows. */
#ifdef MAC_OS8
if (read_socket_hook)
/* No need for FIONREAD or fcntl; just say don't wait. */
- nread = (*read_socket_hook) (input_fd, buf, KBD_BUFFER_SIZE, expected);
+ nread = (*read_socket_hook) (buf, KBD_BUFFER_SIZE, expected);
else
{
/* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
unsigned char cbuf[KBD_BUFFER_SIZE - 1];
int n_to_read;
- /* Determine how many characters we should *try* to read. */
#ifdef WINDOWSNT
return 0;
#else /* not WINDOWSNT */
n_to_read = dos_keysns ();
if (n_to_read == 0)
return 0;
+
+ cbuf[0] = dos_keyread ();
+ nread = 1;
+
#else /* not MSDOS */
+
+ struct tty_output *tty;
+ nread = 0;
+
+ /* Try to read from each available tty, until one succeeds. */
+ for (tty = tty_list; tty && !nread; tty = tty->next) {
+
+ /* Determine how many characters we should *try* to read. */
#ifdef FIONREAD
- /* Find out how much input is available. */
- if (ioctl (input_fd, FIONREAD, &n_to_read) < 0)
- /* Formerly simply reported no input, but that sometimes led to
- a failure of Emacs to terminate.
- SIGHUP seems appropriate if we can't reach the terminal. */
- /* ??? Is it really right to send the signal just to this process
- rather than to the whole process group?
- Perhaps on systems with FIONREAD Emacs is alone in its group. */
- {
- if (! noninteractive)
- kill (getpid (), SIGHUP);
- else
- n_to_read = 0;
- }
- if (n_to_read == 0)
- return 0;
- if (n_to_read > sizeof cbuf)
- n_to_read = sizeof cbuf;
+ /* Find out how much input is available. */
+ if (ioctl (fileno (TTY_INPUT (tty)), FIONREAD, &n_to_read) < 0)
+ {
+ /* Formerly simply reported no input, but that sometimes led to
+ a failure of Emacs to terminate.
+ SIGHUP seems appropriate if we can't reach the terminal. */
+ /* ??? Is it really right to send the signal just to this process
+ rather than to the whole process group?
+ Perhaps on systems with FIONREAD Emacs is alone in its group. */
+ if (! noninteractive)
+ {
+ if (! tty_list->next)
+ kill (getpid (), SIGHUP); /* This was the last terminal. */
+ else
+ n_to_read = 0; /* XXX tty should be closed here. */
+ }
+ else
+ {
+ n_to_read = 0;
+ }
+ }
+ if (n_to_read == 0)
+ continue;
+ if (n_to_read > sizeof cbuf)
+ n_to_read = sizeof cbuf;
#else /* no FIONREAD */
#if defined (USG) || defined (DGUX) || defined(CYGWIN)
- /* Read some input if available, but don't wait. */
- n_to_read = sizeof cbuf;
- fcntl (input_fd, F_SETFL, O_NDELAY);
+ /* Read some input if available, but don't wait. */
+ n_to_read = sizeof cbuf;
+ fcntl (fileno (TTY_INPUT (tty)), F_SETFL, O_NDELAY);
#else
- you lose;
+ you lose;
#endif
#endif
-#endif /* not MSDOS */
-#endif /* not WINDOWSNT */
- /* Now read; for one reason or another, this will not block.
- NREAD is set to the number of chars read. */
- do
- {
-#ifdef MSDOS
- cbuf[0] = dos_keyread ();
- nread = 1;
-#else
- nread = emacs_read (input_fd, cbuf, n_to_read);
-#endif
- /* 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
- when the control tty is taken away.
- Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
- if (nread == -1 && errno == EIO)
- kill (0, SIGHUP);
+ /* Now read; for one reason or another, this will not block.
+ NREAD is set to the number of chars read. */
+ do
+ {
+ nread = emacs_read (fileno (TTY_INPUT (tty)), 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
+ when the control tty is taken away.
+ Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
+ if (nread == -1 && errno == EIO)
+ {
+ if (! tty_list->next)
+ kill (0, SIGHUP); /* This was the last terminal. */
+ else
+ ; /* XXX tty should be closed here. */
+ }
#if defined (AIX) && (! defined (aix386) && defined (_BSD))
- /* The kernel sometimes fails to deliver SIGHUP for ptys.
- This looks incorrect, but it isn't, because _BSD causes
- O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
- and that causes a value other than 0 when there is no input. */
- if (nread == 0)
- kill (0, SIGHUP);
+ /* The kernel sometimes fails to deliver SIGHUP for ptys.
+ This looks incorrect, but it isn't, because _BSD causes
+ O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
+ and that causes a value other than 0 when there is no input. */
+ if (nread == 0)
+ {
+ if (! tty_list->next)
+ kill (0, SIGHUP); /* This was the last terminal. */
+ else
+ ; /* XXX tty should be closed here. */
+ }
#endif
- }
- while (
- /* We used to retry the read if it was interrupted.
- But this does the wrong thing when O_NDELAY causes
- an EAGAIN error. Does anybody know of a situation
- where a retry is actually needed? */
+ }
+ while (
+ /* We used to retry the read if it was interrupted.
+ But this does the wrong thing when O_NDELAY causes
+ an EAGAIN error. Does anybody know of a situation
+ where a retry is actually needed? */
#if 0
- nread < 0 && (errno == EAGAIN
+ nread < 0 && (errno == EAGAIN
#ifdef EFAULT
- || errno == EFAULT
+ || errno == EFAULT
#endif
#ifdef EBADSLT
- || errno == EBADSLT
+ || errno == EBADSLT
#endif
- )
+ )
#else
- 0
+ 0
#endif
- );
-
+ );
+
#ifndef FIONREAD
#if defined (USG) || defined (DGUX) || defined (CYGWIN)
- fcntl (input_fd, F_SETFL, 0);
+ fcntl (fileno (TTY_INPUT (tty)), F_SETFL, 0);
#endif /* USG or DGUX or CYGWIN */
#endif /* no FIONREAD */
+
+ } /* for each tty */
+
+ if (! nread)
+ return 0;
+
+#endif /* not MSDOS */
+#endif /* not WINDOWSNT */
+
+ /* XXX Select frame corresponding to the tty. */
+
for (i = 0; i < nread; i++)
{
buf[i].kind = ASCII_KEYSTROKE_EVENT;
int width, height;
struct gcpro gcpro1;
+ if (tty_list && tty_list->next)
+ error ("Suspend is not supported with multiple ttys");
+
if (!NILP (stuffstring))
CHECK_STRING (stuffstring);
call1 (Vrun_hooks, intern ("suspend-hook"));
GCPRO1 (stuffstring);
- get_frame_size (&old_width, &old_height);
+ get_tty_size (CURTTY (), &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. */
/* 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_frame_size (&width, &height);
+ get_tty_size (CURTTY (), &width, &height);
if (width != old_width || height != old_height)
change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);
extern void reset_sys_modes P_ ((struct tty_output *));
extern void init_all_sys_modes P_ ((void));
extern void reset_all_sys_modes P_ ((void));
-extern void get_frame_size P_ ((int *, int *));
extern void wait_for_termination P_ ((int));
extern void flush_pending_output P_ ((int));
extern void child_setup_tty P_ ((int));
/* Emacs calls this whenever it wants to read an input event from the
user. */
int
-XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
+XTread_socket (struct input_event *bufp, int numchars, int expected)
{
int count = 0;
#if USE_CARBON_EVENTS
#include <config.h>
#include <stdio.h>
#include <string.h>
+#include "lisp.h"
#include "systty.h" /* For emacs_tty in termchar.h */
#include "termchar.h"
-#include "lisp.h"
#include "dispextern.h"
#include "keyboard.h"
#include "frame.h"
int emacs_ospeed;
-/* The file descriptor for Emacs's input terminal.
- Under Unix, this is normally zero except when using X;
- under VMS, we place the input channel number here. */
-int input_fd;
-
void croak P_ ((char *));
#ifdef AIXHFT
SIGMASKTYPE sigprocmask_set;
\f
-/* Specify a different file descriptor for further input operations. */
-
-void
-change_input_fd (fd)
- int fd;
-{
- input_fd = fd;
-}
-
-/* Discard pending input on descriptor input_fd. */
+/* Discard pending input on all input descriptors. */
void
discard_tty_input ()
#ifdef VMS
end_kbd_input ();
- SYS$QIOW (0, input_fd, IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
+ SYS$QIOW (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
&buf.main, 0, 0, terminator_mask, 0, 0);
queue_kbd_input ();
#else /* not VMS */
#ifdef APOLLO
{
int zero = 0;
- ioctl (input_fd, TIOCFLUSH, &zero);
+ ioctl (fileno (TTY_INPUT (CURTTY())), TIOCFLUSH, &zero);
}
#else /* not Apollo */
#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
while (dos_keyread () != -1)
;
#else /* not MSDOS */
- EMACS_GET_TTY (input_fd, &buf);
- EMACS_SET_TTY (input_fd, &buf, 0);
+ {
+ struct tty_output 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);
+ }
+ }
#endif /* not MSDOS */
#endif /* not Apollo */
#endif /* not VMS */
/* Should perhaps error if in batch mode */
#ifdef TIOCSTI
- ioctl (input_fd, TIOCSTI, &c);
+ ioctl (fileno (TTY_INPUT (CURTTY())), TIOCSTI, &c);
#else /* no TIOCSTI */
error ("Cannot stuff terminal input characters in this version of Unix");
#endif /* no TIOCSTI */
#ifdef VMS
struct sensemode sg;
- SYS$QIOW (0, input_fd, IO$_SENSEMODE, &sg, 0, 0,
+ SYS$QIOW (0, fileno (TTY_INPUT (CURTTY())), IO$_SENSEMODE, &sg, 0, 0,
&sg.class, 12, 0, 0, 0, 0 );
emacs_ospeed = sg.xmit_baud;
#else /* not VMS */
struct termios sg;
sg.c_cflag = B9600;
- tcgetattr (input_fd, &sg);
+ tcgetattr (fileno (TTY_INPUT (CURTTY())), &sg);
emacs_ospeed = cfgetospeed (&sg);
#if defined (USE_GETOBAUD) && defined (getobaud)
/* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
sg.c_cflag = B9600;
#ifdef HAVE_TCATTR
- tcgetattr (input_fd, &sg);
+ tcgetattr (fileno (TTY_INPUT (CURTTY())), &sg);
#else
- ioctl (input_fd, TCGETA, &sg);
+ ioctl (fileno (TTY_INPUT (CURTTY())), TCGETA, &sg);
#endif
emacs_ospeed = sg.c_cflag & CBAUD;
#else /* neither VMS nor TERMIOS nor TERMIO */
struct sgttyb sg;
sg.sg_ospeed = B9600;
- if (ioctl (input_fd, TIOCGETP, &sg) < 0)
+ if (ioctl (fileno (TTY_INPUT (CURTTY())), TIOCGETP, &sg) < 0)
abort ();
emacs_ospeed = sg.sg_ospeed;
#endif /* not HAVE_TERMIO */
#ifdef SIGWINCH
sigunblock (sigmask (SIGWINCH));
#endif
- fcntl (input_fd, F_SETFL, old_fcntl_flags | FASYNC);
+ fcntl (fileno (TTY_INPUT (CURTTY())), F_SETFL, old_fcntl_flags | FASYNC);
interrupts_deferred = 0;
}
#ifdef SIGWINCH
sigblock (sigmask (SIGWINCH));
#endif
- fcntl (input_fd, F_SETFL, old_fcntl_flags);
+ fcntl (fileno (TTY_INPUT (CURTTY())), F_SETFL, old_fcntl_flags);
interrupts_deferred = 1;
}
if (read_socket_hook)
return;
- ioctl (input_fd, FIOASYNC, &on);
+ ioctl (fileno (TTY_INPUT (CURTTY())), FIOASYNC, &on);
interrupts_deferred = 0;
}
if (read_socket_hook)
return;
- ioctl (input_fd, FIOASYNC, &off);
+ ioctl (fileno (TTY_INPUT (CURTTY())), FIOASYNC, &off);
interrupts_deferred = 1;
}
sigemptyset (&st);
sigaddset (&st, SIGIO);
- ioctl (input_fd, FIOASYNC, &on);
+ ioctl (fileno (TTY_INPUT (CURTTY())), FIOASYNC, &on);
interrupts_deferred = 0;
sigprocmask (SIG_UNBLOCK, &st, (sigset_t *)0);
}
if (read_socket_hook)
return;
- ioctl (input_fd, FIOASYNC, &off);
+ ioctl (fileno (TTY_INPUT (CURTTY())), FIOASYNC, &off);
interrupts_deferred = 1;
}
setpgrp (0, inherited_pgroup);
if (inherited_pgroup != me)
- EMACS_SET_TTY_PGRP (input_fd, &me);
+ EMACS_SET_TTY_PGRP (fileno (stdin), &me); /* stdin is intentional here */
setpgrp (0, me);
}
widen_foreground_group ()
{
if (inherited_pgroup != getpid ())
- EMACS_SET_TTY_PGRP (input_fd, &inherited_pgroup);
+ EMACS_SET_TTY_PGRP (fileno (stdin), &inherited_pgroup); /* stdin is intentional here */
setpgrp (0, inherited_pgroup);
}
}
void
-init_sys_modes (otty)
- struct tty_output *otty;
+init_sys_modes (tty_out)
+ struct tty_output *tty_out;
{
struct emacs_tty tty;
#ifndef VMS4_4
sys_access_reinit ();
#endif
-#endif /* not VMS */
+#endif /* VMS */
#ifdef BSD_PGRPS
if (! read_socket_hook && EQ (Vwindow_system, Qnil))
if (!read_socket_hook && EQ (Vwindow_system, Qnil))
#endif
{
- EMACS_GET_TTY (input_fd, &otty->old_tty);
+ EMACS_GET_TTY (fileno (TTY_INPUT (tty_out)), &tty_out->old_tty);
- otty->old_tty_valid = 1;
+ tty_out->old_tty_valid = 1;
- tty = otty->old_tty;
+ tty = tty_out->old_tty;
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
- XSETINT (Vtty_erase_char, otty->old_tty.main.c_cc[VERASE]);
+ XSETINT (Vtty_erase_char, tty_out->old_tty.main.c_cc[VERASE]);
#ifdef DGUX
/* This allows meta to be sent on 8th bit. */
tty.tchars.t_stopc = '\023';
}
- tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | otty->old_tty.lmode;
+ tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | tty_out->old_tty.lmode;
#ifdef ultrix
/* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
anything, and leaving it in breaks the meta key. Go figure. */
tty.ltchars = new_ltchars;
#endif /* HAVE_LTCHARS */
#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
- if (!otty->term_initted)
+ if (!tty_out->term_initted)
internal_terminal_init ();
dos_ttraw ();
#endif
- EMACS_SET_TTY (input_fd, &tty, 0);
+ EMACS_SET_TTY (fileno (TTY_INPUT (tty_out)), &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 (!flow_control) ioctl (input_fd, TCXONC, 1);
+ if (!flow_control) ioctl (fileno (TTY_INPUT (tty_out)), TCXONC, 1);
#endif
#ifndef APOLLO
#ifdef TIOCSTART
- if (!flow_control) ioctl (input_fd, TIOCSTART, 0);
+ if (!flow_control) ioctl (fileno (TTY_INPUT (tty_out)), TIOCSTART, 0);
#endif
#endif
#if defined (HAVE_TERMIOS) || defined (HPUX9)
#ifdef TCOON
- if (!flow_control) tcflow (input_fd, TCOON);
+ if (!flow_control) tcflow (fileno (TTY_INPUT (tty_out)), TCOON);
#endif
#endif
#ifdef VMS
/* Appears to do nothing when in PASTHRU mode.
- SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
+ SYS$QIOW (0, fileno (TTY_INPUT (tty_out)), IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
interrupt_signal, oob_chars, 0, 0, 0, 0);
*/
queue_kbd_input (0);
if (interrupt_input
&& ! read_socket_hook && EQ (Vwindow_system, Qnil))
{
- old_fcntl_owner = fcntl (input_fd, F_GETOWN, 0);
- fcntl (input_fd, F_SETOWN, getpid ());
- init_sigio (input_fd);
+ old_fcntl_owner = 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)));
}
#endif /* F_GETOWN */
#endif /* F_SETOWN_BUG */
#ifdef BSD4_1
if (interrupt_input)
- init_sigio (input_fd);
+ init_sigio (fileno (TTY_INPUT (tty_out)));
#endif
#ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
/* 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 (stdout, (char *) _sobuf, _IOFBF, sizeof _sobuf);
+ setvbuf (TTY_OUTPUT (tty_out), (char *) _sobuf, _IOFBF, sizeof _sobuf);
#else
- setbuf (stdout, (char *) _sobuf);
+ setbuf (TTY_OUTPUT (tty_out), (char *) _sobuf);
#endif
#ifdef HAVE_WINDOW_SYSTEM
/* Emacs' window system on MSDOG uses the `internal terminal' and therefore
#endif
)
#endif
- set_terminal_modes (otty);
+ set_terminal_modes (tty_out);
- if (!otty->term_initted
- && FRAMEP (Vterminal_frame)
- && FRAME_TERMCAP_P (XFRAME (Vterminal_frame)))
- init_frame_faces (XFRAME (Vterminal_frame));
+ if (!tty_out->term_initted)
+ {
+ Lisp_Object tail, frame;
+ FOR_EACH_FRAME (tail, frame)
+ {
+ if (FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_TTY (XFRAME (frame)) == tty_out)
+ init_frame_faces (XFRAME (frame));
+ }
+ }
- if (otty->term_initted && no_redraw_on_reenter)
+ if (tty_out->term_initted && no_redraw_on_reenter)
{
if (display_completed)
direct_output_forward_char (0);
}
else
{
+ Lisp_Object tail, frame;
frame_garbaged = 1;
- if (FRAMEP (Vterminal_frame))
- FRAME_GARBAGED_P (XFRAME (Vterminal_frame)) = 1;
+ FOR_EACH_FRAME (tail, frame)
+ {
+ if (FRAME_TERMCAP_P (XFRAME (frame))
+ && FRAME_TTY (XFRAME (frame)) == tty_out)
+ FRAME_GARBAGED_P (XFRAME (frame)) = 1;
+ }
}
- otty->term_initted = 1;
+ tty_out->term_initted = 1;
}
/* Return nonzero if safe to use tabs in output.
{
struct emacs_tty tty;
- EMACS_GET_TTY (input_fd, &tty);
+ EMACS_GET_TTY (fileno (TTY_INPUT (CURTTY())), &tty);
return EMACS_TTY_TABS_OK (&tty);
}
\f
We store 0 if there's no valid information. */
void
-get_frame_size (widthp, heightp)
+get_tty_size (tty_out, widthp, heightp)
+ struct tty_output *tty_out;
int *widthp, *heightp;
{
/* BSD-style. */
struct winsize size;
- if (ioctl (input_fd, TIOCGWINSZ, &size) == -1)
+ if (ioctl (fileno (TTY_INPUT (tty_out)), TIOCGWINSZ, &size) == -1)
*widthp = *heightp = 0;
else
{
/* SunOS - style. */
struct ttysize size;
- if (ioctl (input_fd, TIOCGSIZE, &size) == -1)
+ if (ioctl (fileno (TTY_INPUT (tty_out)), TIOCGSIZE, &size) == -1)
*widthp = *heightp = 0;
else
{
struct sensemode tty;
- SYS$QIOW (0, input_fd, IO$_SENSEMODE, &tty, 0, 0,
+ SYS$QIOW (0, fileno (TTY_INPUT (CURTTY())), IO$_SENSEMODE, &tty, 0, 0,
&tty.class, 12, 0, 0, 0, 0);
*widthp = tty.scr_wid;
*heightp = tty.scr_len;
/* Prepare the terminal for exiting Emacs; move the cursor to the
bottom of the frame, turn off interrupt-driven I/O, etc. */
void
-reset_sys_modes (otty)
- struct tty_output *otty;
+reset_sys_modes (tty_out)
+ struct tty_output *tty_out;
{
struct frame *sf;
fflush (stdout);
return;
}
- if (!otty->term_initted)
+ if (!tty_out->term_initted)
return;
#ifdef HAVE_WINDOW_SYSTEM
/* Emacs' window system on MSDOG uses the `internal terminal' and therefore
}
#endif
- reset_terminal_modes (otty);
- fflush (stdout);
+ reset_terminal_modes (tty_out);
+ fflush (TTY_OUTPUT (tty_out));
#ifdef BSD_SYSTEM
#ifndef BSD4_1
/* Avoid possible loss of output when changing terminal modes. */
- fsync (fileno (stdout));
+ fsync (TTY_OUTPUT (tty_out));
#endif
#endif
if (interrupt_input)
{
reset_sigio ();
- fcntl (input_fd, F_SETOWN, old_fcntl_owner);
+ fcntl (fileno (TTY_INPUT (tty_out)), F_SETOWN, old_fcntl_owner);
}
#endif /* F_SETOWN */
#endif /* F_SETOWN_BUG */
#ifdef O_NDELAY
- fcntl (input_fd, F_SETFL, fcntl (input_fd, F_GETFL, 0) & ~O_NDELAY);
+ fcntl (fileno (TTY_INPUT (tty_out)), F_SETFL,
+ fcntl (fileno (TTY_INPUT (tty_out)), F_GETFL, 0) & ~O_NDELAY);
#endif
#endif /* F_SETFL */
#ifdef BSD4_1
reset_sigio ();
#endif /* BSD4_1 */
- if (otty->old_tty_valid)
- while (EMACS_SET_TTY (input_fd, &otty->old_tty, 0) < 0 && errno == EINTR)
+ if (tty_out->old_tty_valid)
+ while (EMACS_SET_TTY (fileno (TTY_INPUT (tty_out)),
+ &tty_out->old_tty, 0) < 0 && errno == EINTR)
;
#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
/* Ultrix's termios *ignores* any line discipline except TERMIODISC.
A different old line discipline is therefore not restored, yet.
Restore the old line discipline by hand. */
- ioctl (0, TIOCSETD, &otty->old_tty.main.c_line);
+ ioctl (0, TIOCSETD, &tty_out->old_tty.main.c_line);
#endif
#ifdef AIXHFT
{
int status;
- if (input_fd == 0)
+ if (fileno (TTY_INPUT (CURTTY())) == 0)
{
- status = SYS$ASSIGN (&input_dsc, &input_fd, 0, 0);
+ status = SYS$ASSIGN (&input_dsc, &fileno (TTY_INPUT (CURTTY())), 0, 0);
if (! (status & 1))
LIB$STOP (status);
}
void
stop_vms_input ()
{
- return SYS$DASSGN (input_fd);
+ return SYS$DASSGN (fileno (TTY_INPUT (CURTTY())));
}
short input_buffer;
waiting_for_ast = 0;
stop_input = 0;
- status = SYS$QIO (0, input_fd, IO$_READVBLK,
+ status = SYS$QIO (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK,
&input_iosb, kbd_input_ast, 1,
&input_buffer, 1, 0, terminator_mask, 0, 0);
}
#endif
if (LIB$AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
{
- SYS$CANCEL (input_fd);
+ SYS$CANCEL (fileno (TTY_INPUT (CURTTY())));
return;
}
SYS$CLREF (input_ef);
waiting_for_ast = 1;
stop_input = 1;
- SYS$CANCEL (input_fd);
+ SYS$CANCEL (fileno (TTY_INPUT (CURTTY())));
SYS$SETAST (1);
SYS$WAITFR (input_ef);
waiting_for_ast = 0;
#include <sys/file.h>
+#include "lisp.h"
#include "systty.h" /* For emacs_tty in termchar.h */
#include "termchar.h"
#include "termopts.h"
-#include "lisp.h"
#include "charset.h"
#include "coding.h"
#include "keyboard.h"
void (*write_glyphs_hook) P_ ((struct glyph *, int));
void (*delete_glyphs_hook) P_ ((int));
-int (*read_socket_hook) P_ ((int, struct input_event *, int, int));
+int (*read_socket_hook) P_ ((struct input_event *, int, int));
void (*frame_up_to_date_hook) P_ ((struct frame *));
}
else
{ /* have to do it the hard way */
- struct frame *sf = XFRAME (selected_frame);
turn_off_insert ();
/* Do not write in last row last col with Auto-wrap on. */
- if (AutoWrap && curY == FRAME_LINES (sf) - 1
- && first_unused_hpos == FRAME_COLS (sf))
+ if (AutoWrap && curY == FRAME_LINES (f) - 1
+ && first_unused_hpos == FRAME_COLS (f))
first_unused_hpos--;
for (i = curX; i < first_unused_hpos; i++)
register int len;
{
int produced, consumed;
- struct frame *sf = XFRAME (selected_frame);
- struct frame *f = updating_frame ? updating_frame : sf;
+ struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame);
unsigned char conversion_buffer[1024];
int conversion_buffer_size = sizeof conversion_buffer;
since that would scroll the whole frame on some terminals. */
if (AutoWrap
- && curY + 1 == FRAME_LINES (sf)
- && (curX + len) == FRAME_COLS (sf))
+ && curY + 1 == FRAME_LINES (f)
+ && (curX + len) == FRAME_COLS (f))
len --;
if (len <= 0)
return;
{
char *buf;
struct glyph *glyph = NULL;
- struct frame *f, *sf;
+ struct frame *f;
if (len <= 0)
return;
return;
}
- sf = XFRAME (selected_frame);
- f = updating_frame ? updating_frame : sf;
+ f = updating_frame ? updating_frame : XFRAME (selected_frame);
if (TS_ins_multi_chars)
{
char *multi = n > 0 ? TS_ins_multi_lines : TS_del_multi_lines;
char *single = n > 0 ? TS_ins_line : TS_del_line;
char *scroll = n > 0 ? TS_rev_scroll : TS_fwd_scroll;
- struct frame *sf;
+ struct frame *f;
register int i = n > 0 ? n : -n;
register char *buf;
return;
}
- sf = XFRAME (selected_frame);
+ f = (updating_frame ? updating_frame : XFRAME (selected_frame));
/* If the lines below the insertion are being pushed
into the end of the window, this is the same as clearing;
/* If the lines below the deletion are blank lines coming
out of the end of the window, don't bother,
as there will be a matching inslines later that will flush them. */
- if (TTY_SCROLL_REGION_OK (FRAME_TTY (sf))
+ if (TTY_SCROLL_REGION_OK (FRAME_TTY (f))
&& vpos + i >= specified_window)
return;
- if (!TTY_MEMORY_BELOW_FRAME (FRAME_TTY (sf))
- && vpos + i >= FRAME_LINES (sf))
+ if (!TTY_MEMORY_BELOW_FRAME (FRAME_TTY (f))
+ && vpos + i >= FRAME_LINES (f))
return;
if (multi)
raw_cursor_to (vpos, 0);
background_highlight ();
buf = tparam (multi, 0, 0, i);
- OUTPUT (FRAME_TTY (sf), buf);
+ OUTPUT (FRAME_TTY (f), buf);
xfree (buf);
}
else if (single)
raw_cursor_to (vpos, 0);
background_highlight ();
while (--i >= 0)
- OUTPUT (FRAME_TTY (sf), single);
+ OUTPUT (FRAME_TTY (f), single);
if (TF_teleray)
curX = 0;
}
raw_cursor_to (vpos, 0);
background_highlight ();
while (--i >= 0)
- OUTPUTL (FRAME_TTY (sf), scroll, specified_window - vpos);
+ OUTPUTL (FRAME_TTY (f), scroll, specified_window - vpos);
set_scroll_region (0, specified_window);
}
- if (!TTY_SCROLL_REGION_OK (FRAME_TTY (sf))
- && TTY_MEMORY_BELOW_FRAME (FRAME_TTY (sf))
+ if (!TTY_SCROLL_REGION_OK (FRAME_TTY (f))
+ && TTY_MEMORY_BELOW_FRAME (FRAME_TTY (f))
&& n < 0)
{
- cursor_to (FRAME_LINES (sf) + n, 0);
+ cursor_to (FRAME_LINES (f) + n, 0);
clear_to_end ();
}
}
/* Get frame size from system, or else from termcap. */
{
int height, width;
- get_frame_size (&width, &height);
+ get_tty_size (tty, &width, &height);
FRAME_COLS (sf) = width;
FRAME_LINES (sf) = height;
}
int term_initted; /* 1 if we have been through init_sys_modes. */
int old_tty_valid; /* 1 if outer tty status has been recorded. */
+
+
+ /* Redisplay. */
+
+ /* XXX This may cause problems with GC. */
+ Lisp_Object top_frame; /* The topmost frame on this tty. */
-
+ /* The previous terminal frame we displayed on this tty. */
+ struct frame *previous_terminal_frame;
+
/* Pixel values.
XXX What are these used for? */
#define EVENT_INIT(event) bzero (&(event), sizeof (struct input_event))
/* Called to read input events. */
-extern int (*read_socket_hook) P_ ((int, struct input_event *, int, int));
+extern int (*read_socket_hook) P_ ((struct input_event *, int, int));
/* Called when a frame's display becomes entirely up to date. */
extern void (*frame_up_to_date_hook) P_ ((struct frame *));
}
int
-w32_console_read_socket (int sd, struct input_event *bufp, int numchars,
+w32_console_read_socket (struct input_event *bufp, int numchars,
int expected)
{
BOOL no_events = TRUE;
*/
int
-w32_read_socket (sd, bufp, numchars, expected)
- register int sd;
+w32_read_socket (bufp, numchars, expected)
/* register */ struct input_event *bufp;
/* register */ int numchars;
int expected;
{
struct frame *f = make_terminal_frame (0, 0);
XSETFRAME (selected_frame, f);
- Vterminal_frame = selected_frame;
minibuf_window = f->minibuffer_window;
selected_window = f->selected_window;
last_nonminibuf_frame = f;
#define CLEAR_FACE_CACHE_COUNT 500
static int clear_face_cache_count;
-/* Record the previous terminal frame we displayed. */
-
-static struct frame *previous_terminal_frame;
-
/* Non-zero while redisplay_internal is in progress. */
int redisplaying_p;
/* If realized faces have been removed, e.g. because of face
attribute changes of named faces, recompute them. When running
- in batch mode, the face cache of Vterminal_frame is null. If
+ in batch mode, the face cache of the initial frame is null. If
we happen to get called, make a dummy face cache. */
if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
init_frame_faces (it->f);
{
Lisp_Object tail, frame;
int changed_count = 0;
-
+
FOR_EACH_FRAME (tail, frame)
{
struct frame *f = XFRAME (frame);
-
+
if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
{
if (f->resized_p)
f->resized_p = 0;
}
}
-
+
frame_garbaged = 0;
if (changed_count)
++windows_or_buffers_changed;
/* When Emacs starts, selected_frame may be a visible terminal
frame, even if we run under a window system. If we let this
through, a message would be displayed on the terminal. */
- if (EQ (selected_frame, Vterminal_frame)
+ if (!FRAME_WINDOW_P (XFRAME (selected_frame))
&& !NILP (Vwindow_system))
return 0;
#endif /* HAVE_WINDOW_SYSTEM */
if (face_change_count)
++windows_or_buffers_changed;
- if (! FRAME_WINDOW_P (sf)
- && previous_terminal_frame != sf)
+ if (FRAME_TERMCAP_P (sf)
+ && FRAME_TTY (sf)->previous_terminal_frame != sf)
{
- /* Since frames on an ASCII terminal share the same display
- area, displaying a different frame means redisplay the whole
- thing. */
+ /* Since frames on a single ASCII terminal share the same
+ display area, displaying a different frame means redisplay
+ the whole thing. */
windows_or_buffers_changed++;
SET_FRAME_GARBAGED (sf);
- XSETFRAME (Vterminal_frame, sf);
+ FRAME_TTY (sf)->previous_terminal_frame = sf;
}
- previous_terminal_frame = sf;
/* Set the visible flags for all frames. Do this before checking
for resized or garbaged frames; they want to know if their frames
}
}
+
/* Notice any pending interrupt request to change frame size. */
do_pending_window_change (1);
{
struct frame *f = XFRAME (frame);
- if (FRAME_WINDOW_P (f) || f == sf)
+ if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
{
if (! EQ (frame, selected_frame))
/* Select the frame, for the sake of frame-local
EXPECTED is nonzero if the caller knows input is available. */
static int
-XTread_socket (sd, bufp, numchars, expected)
- register int sd;
+XTread_socket (bufp, numchars, expected)
/* register */ struct input_event *bufp;
/* register */ int numchars;
int expected;