Mercurial > emacs
changeset 53229:33c3c7c16e13
lib-src/emacsclient.c: Implemented --here option (open a new Emacs tty). Needs more work.
(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
author | Karoly Lorentey <lorentey@elte.hu> |
---|---|
date | Fri, 26 Dec 2003 04:24:54 +0000 |
parents | c5b253fd2504 |
children | dfd82236be81 |
files | README.multi-tty lib-src/emacsclient.c lib-src/pty.c lib-src/pty.h lisp/server.el src/dispextern.h src/dispnew.c src/emacs.c src/frame.c src/frame.h src/keyboard.c src/lisp.h src/macterm.c src/scroll.c src/sysdep.c src/term.c src/termchar.h src/termhooks.h src/w32inevt.c src/w32term.c src/window.c src/xdisp.c src/xterm.c |
diffstat | 23 files changed, 1208 insertions(+), 312 deletions(-) [+] |
line wrap: on
line diff
--- a/README.multi-tty Thu Dec 25 07:36:05 2003 +0000 +++ b/README.multi-tty Fri Dec 26 04:24:54 2003 +0000 @@ -25,19 +25,18 @@ ------ 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. - -To try it out, start up emacs, and evaluate the following: +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. - (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm"))) +To try it out, start up the emacs server (M-x server-start), and then +start emacsclient with -(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. + emacsclient -h + +If you exit emacs, both terminals are restored to their previous +states. X, Mac, Windows and DOS support is broken. @@ -50,6 +49,8 @@ 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 --------- @@ -76,15 +77,50 @@ (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. @@ -96,27 +132,14 @@ 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.
--- a/lib-src/emacsclient.c Thu Dec 25 07:36:05 2003 +0000 +++ b/lib-src/emacsclient.c Fri Dec 26 04:24:54 2003 +0000 @@ -41,6 +41,54 @@ # 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 + + + +/* 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 */ + + + +/****************************************/ + char *getenv (), *getwd (); char *getcwd (); @@ -63,6 +111,9 @@ /* 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; @@ -78,6 +129,7 @@ { "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' }, @@ -95,7 +147,7 @@ while (1) { int opt = getopt_long (argc, argv, - "VHnea:s:d:", longopts, 0); + "VHnea:s:d:h", longopts, 0); if (opt == EOF) break; @@ -134,6 +186,10 @@ exit (0); break; + case 'h': + here = 1; + break; + case 'H': print_help_and_exit (); break; @@ -144,6 +200,12 @@ break; } } + + if (here) { + nowait = 0; + display = 0; + } + } void @@ -157,6 +219,7 @@ 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\ @@ -247,6 +310,455 @@ } } + +#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 */ #if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM) @@ -312,7 +824,7 @@ /* 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); @@ -484,6 +996,38 @@ 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++) @@ -512,11 +1056,14 @@ } 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"); @@ -524,8 +1071,25 @@ /* 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..."); @@ -546,6 +1110,7 @@ printf ("\n"); fflush (stdout); + reset_tty (); return 0; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib-src/pty.c Fri Dec 26 04:24:54 2003 +0000 @@ -0,0 +1,20 @@ +/* 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 Thu Jan 01 00:00:00 1970 +0000 +++ b/lib-src/pty.h Fri Dec 26 04:24:54 2003 +0000 @@ -0,0 +1,224 @@ +/* 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 + + +/* 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 + + +/* 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 + + +/* 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 */ + +/* 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
--- a/lisp/server.el Thu Dec 25 07:36:05 2003 +0000 +++ b/lisp/server.el Fri Dec 26 04:24:54 2003 +0000 @@ -319,6 +319,15 @@ (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))))
--- a/src/dispextern.h Thu Dec 25 07:36:05 2003 +0000 +++ b/src/dispextern.h Fri Dec 26 04:24:54 2003 +0000 @@ -2555,7 +2555,7 @@ /* 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));
--- a/src/dispnew.c Thu Dec 25 07:36:05 2003 +0000 +++ b/src/dispnew.c Fri Dec 26 04:24:54 2003 +0000 @@ -3321,7 +3321,7 @@ 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. */ @@ -3461,7 +3461,7 @@ /* 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; @@ -3658,7 +3658,7 @@ 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); @@ -3749,7 +3749,7 @@ cursor_to (y, x); } - fflush (stdout); + fflush (TTY_OUTPUT (CURTTY ())); redisplay_performed_directly_p = 1; return 1; } @@ -5102,18 +5102,18 @@ 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) @@ -5893,28 +5893,34 @@ #endif int old_errno = errno; - get_frame_size (&width, &height); - - /* 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; - } - } + 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) { + + 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; } @@ -5969,10 +5975,11 @@ { 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, @@ -6162,7 +6169,7 @@ putchar (07); else ring_bell (); - fflush (stdout); + fflush (TTY_OUTPUT (CURTTY ())); } else bitch_at_user (); @@ -6179,7 +6186,7 @@ error ("Keyboard macro terminated by a command ringing the bell"); else ring_bell (); - fflush (stdout); + fflush (TTY_OUTPUT (CURTTY ())); }
--- a/src/emacs.c Thu Dec 25 07:36:05 2003 +0000 +++ b/src/emacs.c Fri Dec 26 04:24:54 2003 +0000 @@ -1564,7 +1564,7 @@ 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. */ }
--- a/src/frame.c Thu Dec 25 07:36:05 2003 +0000 +++ b/src/frame.c Fri Dec 26 04:24:54 2003 +0000 @@ -114,8 +114,6 @@ 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; @@ -550,6 +548,7 @@ 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; @@ -637,12 +636,15 @@ 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); @@ -746,6 +748,15 @@ 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); @@ -979,7 +990,10 @@ 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. */ @@ -1056,7 +1070,10 @@ 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. */ @@ -4081,9 +4098,6 @@ = 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;
--- a/src/frame.h Thu Dec 25 07:36:05 2003 +0000 +++ b/src/frame.h Fri Dec 26 04:24:54 2003 +0000 @@ -28,9 +28,7 @@ /* 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 @@ -71,7 +69,7 @@ #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. */ @@ -743,7 +741,10 @@ 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) ? \ @@ -799,8 +800,6 @@ extern Lisp_Object Vframe_list; extern Lisp_Object Vdefault_frame_alist; -extern Lisp_Object Vterminal_frame; - extern Lisp_Object Vmouse_highlight; /* The currently selected frame. */
--- a/src/keyboard.c Thu Dec 25 07:36:05 2003 +0000 +++ b/src/keyboard.c Fri Dec 26 04:24:54 2003 +0000 @@ -22,10 +22,10 @@ #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" @@ -89,9 +89,6 @@ 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 @@ -6588,7 +6585,7 @@ 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 @@ -6597,7 +6594,6 @@ 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 */ @@ -6605,88 +6601,121 @@ 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; -#endif -#endif + you lose; +#endif +#endif + + /* 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) + { + 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? */ +#if 0 + nread < 0 && (errno == EAGAIN +#ifdef EFAULT + || errno == EFAULT +#endif +#ifdef EBADSLT + || errno == EBADSLT +#endif + ) +#else + 0 +#endif + ); + +#ifndef FIONREAD +#if defined (USG) || defined (DGUX) || defined (CYGWIN) + 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 */ - /* 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); -#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); -#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? */ -#if 0 - nread < 0 && (errno == EAGAIN -#ifdef EFAULT - || errno == EFAULT -#endif -#ifdef EBADSLT - || errno == EBADSLT -#endif - ) -#else - 0 -#endif - ); - -#ifndef FIONREAD -#if defined (USG) || defined (DGUX) || defined (CYGWIN) - fcntl (input_fd, F_SETFL, 0); -#endif /* USG or DGUX or CYGWIN */ -#endif /* no FIONREAD */ + /* XXX Select frame corresponding to the tty. */ + for (i = 0; i < nread; i++) { buf[i].kind = ASCII_KEYSTROKE_EVENT; @@ -10058,6 +10087,9 @@ 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); @@ -10066,7 +10098,7 @@ 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. */ @@ -10082,7 +10114,7 @@ /* 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);
--- a/src/lisp.h Thu Dec 25 07:36:05 2003 +0000 +++ b/src/lisp.h Fri Dec 26 04:24:54 2003 +0000 @@ -2946,7 +2946,6 @@ 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));
--- a/src/macterm.c Thu Dec 25 07:36:05 2003 +0000 +++ b/src/macterm.c Fri Dec 26 04:24:54 2003 +0000 @@ -7598,7 +7598,7 @@ /* 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
--- a/src/scroll.c Thu Dec 25 07:36:05 2003 +0000 +++ b/src/scroll.c Fri Dec 26 04:24:54 2003 +0000 @@ -22,9 +22,9 @@ #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"
--- a/src/sysdep.c Thu Dec 25 07:36:05 2003 +0000 +++ b/src/sysdep.c Fri Dec 26 04:24:54 2003 +0000 @@ -246,11 +246,6 @@ 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 @@ -263,16 +258,7 @@ SIGMASKTYPE sigprocmask_set; -/* 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 () @@ -290,22 +276,28 @@ #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 */ @@ -330,7 +322,7 @@ /* 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 */ @@ -354,7 +346,7 @@ #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 */ @@ -362,7 +354,7 @@ 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. */ @@ -375,16 +367,16 @@ 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 */ @@ -947,7 +939,7 @@ #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; } @@ -961,7 +953,7 @@ #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; } @@ -976,7 +968,7 @@ if (read_socket_hook) return; - ioctl (input_fd, FIOASYNC, &on); + ioctl (fileno (TTY_INPUT (CURTTY())), FIOASYNC, &on); interrupts_deferred = 0; } @@ -988,7 +980,7 @@ if (read_socket_hook) return; - ioctl (input_fd, FIOASYNC, &off); + ioctl (fileno (TTY_INPUT (CURTTY())), FIOASYNC, &off); interrupts_deferred = 1; } @@ -1009,7 +1001,7 @@ 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); } @@ -1022,7 +1014,7 @@ if (read_socket_hook) return; - ioctl (input_fd, FIOASYNC, &off); + ioctl (fileno (TTY_INPUT (CURTTY())), FIOASYNC, &off); interrupts_deferred = 1; } @@ -1088,7 +1080,7 @@ 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); } @@ -1097,7 +1089,7 @@ 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); } @@ -1300,8 +1292,8 @@ } void -init_sys_modes (otty) - struct tty_output *otty; +init_sys_modes (tty_out) + struct tty_output *tty_out; { struct emacs_tty tty; @@ -1357,7 +1349,7 @@ #ifndef VMS4_4 sys_access_reinit (); #endif -#endif /* not VMS */ +#endif /* VMS */ #ifdef BSD_PGRPS if (! read_socket_hook && EQ (Vwindow_system, Qnil)) @@ -1370,14 +1362,14 @@ if (!read_socket_hook && EQ (Vwindow_system, Qnil)) #endif { - EMACS_GET_TTY (input_fd, &otty->old_tty); - - otty->old_tty_valid = 1; - - tty = otty->old_tty; + EMACS_GET_TTY (fileno (TTY_INPUT (tty_out)), &tty_out->old_tty); + + tty_out->old_tty_valid = 1; + + 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. */ @@ -1542,7 +1534,7 @@ 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. */ @@ -1560,28 +1552,28 @@ 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 @@ -1601,7 +1593,7 @@ #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); @@ -1614,9 +1606,9 @@ 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 */ @@ -1624,7 +1616,7 @@ #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. */ @@ -1634,9 +1626,9 @@ /* 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 @@ -1649,26 +1641,37 @@ #endif ) #endif - set_terminal_modes (otty); - - if (!otty->term_initted - && FRAMEP (Vterminal_frame) - && FRAME_TERMCAP_P (XFRAME (Vterminal_frame))) - init_frame_faces (XFRAME (Vterminal_frame)); - - if (otty->term_initted && no_redraw_on_reenter) + set_terminal_modes (tty_out); + + 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 (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. @@ -1679,7 +1682,7 @@ { struct emacs_tty tty; - EMACS_GET_TTY (input_fd, &tty); + EMACS_GET_TTY (fileno (TTY_INPUT (CURTTY())), &tty); return EMACS_TTY_TABS_OK (&tty); } @@ -1688,7 +1691,8 @@ 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; { @@ -1697,7 +1701,7 @@ /* 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 { @@ -1711,7 +1715,7 @@ /* 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 { @@ -1724,7 +1728,7 @@ 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; @@ -1794,8 +1798,8 @@ /* 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; @@ -1804,7 +1808,7 @@ 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 @@ -1834,12 +1838,12 @@ } #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 @@ -1849,12 +1853,13 @@ 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 @@ -1862,8 +1867,9 @@ 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 */ @@ -1874,7 +1880,7 @@ /* 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 @@ -1947,9 +1953,9 @@ { 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); } @@ -1960,7 +1966,7 @@ void stop_vms_input () { - return SYS$DASSGN (input_fd); + return SYS$DASSGN (fileno (TTY_INPUT (CURTTY()))); } short input_buffer; @@ -1976,7 +1982,7 @@ 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); } @@ -2093,7 +2099,7 @@ #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; } @@ -2102,7 +2108,7 @@ 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;
--- a/src/term.c Thu Dec 25 07:36:05 2003 +0000 +++ b/src/term.c Fri Dec 26 04:24:54 2003 +0000 @@ -28,10 +28,10 @@ #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" @@ -123,7 +123,7 @@ 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 *)); @@ -792,12 +792,11 @@ } 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++) @@ -925,8 +924,7 @@ 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; @@ -944,8 +942,8 @@ 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; @@ -1028,7 +1026,7 @@ { char *buf; struct glyph *glyph = NULL; - struct frame *f, *sf; + struct frame *f; if (len <= 0) return; @@ -1039,8 +1037,7 @@ return; } - sf = XFRAME (selected_frame); - f = updating_frame ? updating_frame : sf; + f = updating_frame ? updating_frame : XFRAME (selected_frame); if (TS_ins_multi_chars) { @@ -1159,7 +1156,7 @@ 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; @@ -1170,7 +1167,7 @@ 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; @@ -1179,11 +1176,11 @@ /* 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) @@ -1191,7 +1188,7 @@ 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) @@ -1199,7 +1196,7 @@ 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; } @@ -1212,15 +1209,15 @@ 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 (); } } @@ -2475,7 +2472,7 @@ /* 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; }
--- a/src/termchar.h Thu Dec 25 07:36:05 2003 +0000 +++ b/src/termchar.h Fri Dec 26 04:24:54 2003 +0000 @@ -39,8 +39,16 @@ 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? */
--- a/src/termhooks.h Thu Dec 25 07:36:05 2003 +0000 +++ b/src/termhooks.h Fri Dec 26 04:24:54 2003 +0000 @@ -371,7 +371,7 @@ #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 *));
--- a/src/w32inevt.c Thu Dec 25 07:36:05 2003 +0000 +++ b/src/w32inevt.c Fri Dec 26 04:24:54 2003 +0000 @@ -642,7 +642,7 @@ } 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;
--- a/src/w32term.c Thu Dec 25 07:36:05 2003 +0000 +++ b/src/w32term.c Fri Dec 26 04:24:54 2003 +0000 @@ -4078,8 +4078,7 @@ */ 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;
--- a/src/window.c Thu Dec 25 07:36:05 2003 +0000 +++ b/src/window.c Fri Dec 26 04:24:54 2003 +0000 @@ -6384,7 +6384,6 @@ { 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;
--- a/src/xdisp.c Thu Dec 25 07:36:05 2003 +0000 +++ b/src/xdisp.c Fri Dec 26 04:24:54 2003 +0000 @@ -736,10 +736,6 @@ #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; @@ -2012,7 +2008,7 @@ /* 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); @@ -7559,11 +7555,11 @@ { 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) @@ -7574,7 +7570,7 @@ f->resized_p = 0; } } - + frame_garbaged = 0; if (changed_count) ++windows_or_buffers_changed; @@ -7610,7 +7606,7 @@ /* 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 */ @@ -9687,17 +9683,16 @@ if (face_change_count) ++windows_or_buffers_changed; - if (! FRAME_WINDOW_P (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. */ + if (FRAME_TERMCAP_P (sf) + && FRAME_TTY (sf)->previous_terminal_frame != sf) + { + /* 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); - } - previous_terminal_frame = sf; + FRAME_TTY (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 @@ -9719,6 +9714,7 @@ } } + /* Notice any pending interrupt request to change frame size. */ do_pending_window_change (1); @@ -10076,7 +10072,7 @@ { 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
--- a/src/xterm.c Thu Dec 25 07:36:05 2003 +0000 +++ b/src/xterm.c Fri Dec 26 04:24:54 2003 +0000 @@ -7057,8 +7057,7 @@ 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;