Commit 28d440ab authored by Karoly Lorentey's avatar Karoly Lorentey
Browse files

Implemented multiple tty support.

README.multi-tty: New file.

src/termchar.h (struct terminal): Renamed to struct tty_output.  Added name, type,
input, output, termscript, old_tty, term_initted, old_tty_valid,
background_pixel, foreground_pixel, next fields.
(TERMINAL_*): Renamed to TTY_* for brevity.
(CURRENT_TERMINAL): Renamed to CURTTY for brevity.
(tty_list): New variable.
(TERMINAL_PTR): Removed.
(FRAME_TTY): New function.
(TTY_NAME, TTY_TYPE): New macros.

src/term.c (current_terminal): Removed.  (_current_terminal): Removed.  (tty_list):
New variable.  (OUTPUT, OUTPUT1, OUTPUTL, OUTPUT_IF, OUTPUT1_IF): Added tty
parameter.  (set_terminal_modes): Added tty parameter.  (reset_terminal_modes):
Added tty parameter.  (cursor_to, raw_cursor_to): Updated cmgoto() calls.
(clear_end_of_line, write_glyphs): Add indirection to terminal output, updated
cmcheckmagic() calls.  (get_named_tty): New function.  (term_dummy_init): New
function.  (term_init): Added name parameter, added tty_output return value.
Changed algorithm to update tty_list.  Call init_sys_modes() to set up tty
mode on the newly opened terminal device.
(get_current_tty): New function, intended for debugging.

src/termhooks.h (termscript): Removed.


src/window.c (init_window_once): Call make_terminal_frame with two zero parameters.

src/cm.h (emacs_tputs): New macro to set current_tty, and then call tputs().
(current_tty): New variable, for cmputc().
(cmcheckmagic, cmputc, cmgoto): Added prototypes.

src/cm.c (current_tty): New variable, for cmputc().
(cmputc): Use it.
(cmcheckmagic): Added tty parameter, look up terminal streams there.
(calccost): Added tty parameter.  Use emacs_tputs() instead of tputs().
(cmgoto): Added tty parameter.  Pass it on to calccost().  Use emacs_tputs()
instead of tputs().

src/dispextern.h (set_terminal_modes, reset_terminal_modes): Added tty parameter.
(term_init): Added name parameter (the filename of the terminal device). Added
return value (struct tty_output).

src/dispnew.c: Replace CURTTY() with local variables throughout the file (where applicable).
(termscript): Moved to struct tty_output.
(terminal_type): Removed.

src/emacs.c (main): Don't call init_sys_modes(), the new term_init() already does that
during init_display().
(shut_down_emacs): Call reset_all_sys_modes() instead of reset_sys_modes().

src/frame.c (Qtty, Qtty_type): New variables.
(syms_of_frame): Initialize them.
(tty_display): Removed.
(make_terminal_frame): New parameters (tty filename and type).
Initialize output_data.tty field instead of output_data.x.  Use term_init() to
find the right tty_output.  (Use term_dummy_init() during bootstrap.)
(Fmake_terminal_frame): Get device filename and type from frame parameters.

if the frame is a tty.
(struct frame): New member in output_data: tty.
(make_terminal_frame): Updated of prototype.

src/keyboard.c (Fset_input_mode): Call reset_all_sys_modes(), not
reset_sys_modes().  Ditto with init_sys_modes().

src/lisp.h (tty_output): Added forward declaration.
(init_sys_modes, reset_sys_modes): Updated prototype.
(init_all_sys_modes, reset_all_sys_modes): New prototypes.

src/scroll.c: Replace CURTTY() with local variables throughout the file (where applicable).

src/sysdep.c (old_tty, term_initted, old_tty_valid): Moved to struct tty_output.(
(init_all_sys_modes): New function.
(init_sys_modes): Added tty_output parameter.  Use it.
(reset_all_sys_modes): New function.
(reset_sys_modes): Added tty_output parameter.  Use it.

src/ Update dependencies.

parent 8a56675d
-*- coding: utf-8; -*-
The ultimate goal of this branch is to implement support for opening
multiple, different tty devices and simultaneous X and tty frames from
a single Emacs session.
I'm Károly Lőrentey. My address:
Patches or suggestions are welcome!
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:
(make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
(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.
X, Mac, Windows and DOS support is broken.
For the NEWS file:
** Support for multiple terminal devices has been added. You can
specify a terminal device (`tty' parameter) and a terminal type
(`tty-type' parameter) to `make-terminal-frame'.
See arch logs.
-- Introduce a new abstraction for terminal devices.
(Done, see struct tty_output. The abstraction is not yet
-- Change the bootstrap procedure to initialize tty_list.
(Done, but needs review.)
-- Change make-terminal-frame to support specifying another tty.
(Done, new frame parameters: `tty' and `tty-type'.)
** 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.
** 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.
** Implement automatic deletion of terminals, when the last frame on
that terminal is closed.
** Put all cached terminal escape sequences into struct tty_output.
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
** 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.
** 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.
** Fix X support.
** Allow simultaneous X and tty frames.
** Fix Mac support (I can't do this myself).
** Fix W32 support (I can't do this myself).
** Fix DOS support (I can't do this myself).
;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d
......@@ -1047,7 +1047,7 @@ ccl.o: ccl.c ccl.h charset.h coding.h $(config_h)
charset.o: charset.c charset.h buffer.h coding.h composite.h disptab.h \
coding.o: coding.c coding.h ccl.h buffer.h charset.h intervals.h composite.h window.h $(config_h)
cm.o: cm.c cm.h termhooks.h $(config_h)
cm.o: cm.c frame.h cm.h termhooks.h systty.h termchar.h $(config_h)
cmds.o: cmds.c syntax.h buffer.h charset.h commands.h window.h $(config_h) \
msdos.h dispextern.h
pre-crt0.o: pre-crt0.c
......@@ -1055,7 +1055,7 @@ ecrt0.o: ecrt0.c $(config_h)
CRT0_COMPILE ${srcdir}/ecrt0.c
dired.o: dired.c commands.h buffer.h $(config_h) charset.h coding.h regex.h \
dispnew.o: dispnew.c systty.h systime.h commands.h process.h frame.h \
dispnew.o: dispnew.c systty.h systime.h commands.h process.h frame.h \
window.h buffer.h dispextern.h termchar.h termopts.h termhooks.h cm.h \
disptab.h \
xterm.h blockinput.h atimer.h charset.h msdos.h composite.h keyboard.h \
......@@ -1073,12 +1073,12 @@ fileio.o: fileio.c window.h buffer.h systime.h $(INTERVAL_SRC) charset.h \
filelock.o: filelock.c buffer.h systime.h epaths.h $(config_h)
filemode.o: filemode.c $(config_h)
frame.o: frame.c xterm.h window.h frame.h termhooks.h commands.h keyboard.h \
blockinput.h atimer.h systime.h buffer.h charset.h fontset.h \
blockinput.h systty.h atimer.h systime.h buffer.h charset.h fontset.h \
msdos.h dosfns.h dispextern.h $(config_h)
fontset.o: dispextern.h fontset.h fontset.c ccl.h buffer.h charset.h frame.h \
keyboard.h $(config_h)
getloadavg.o: getloadavg.c $(config_h)
indent.o: indent.c frame.h window.h indent.h buffer.h $(config_h) termchar.h \
indent.o: indent.c frame.h window.h systty.h indent.h buffer.h $(config_h) termchar.h \
termopts.h disptab.h region-cache.h charset.h composite.h dispextern.h \
insdel.o: insdel.c window.h buffer.h $(INTERVAL_SRC) blockinput.h charset.h \
......@@ -1110,7 +1110,7 @@ process.o: process.c process.h buffer.h window.h termhooks.h termopts.h \
keyboard.h $(config_h)
regex.o: regex.c syntax.h buffer.h $(config_h) regex.h category.h charset.h
region-cache.o: region-cache.c buffer.h region-cache.h
scroll.o: scroll.c termchar.h dispextern.h frame.h msdos.h keyboard.h \
scroll.o: scroll.c systty.h termchar.h dispextern.h frame.h msdos.h keyboard.h \
search.o: search.c regex.h commands.h buffer.h region-cache.h syntax.h \
blockinput.h atimer.h systime.h category.h charset.h composite.h $(config_h)
......@@ -1120,7 +1120,7 @@ syntax.o: syntax.c syntax.h buffer.h commands.h category.h charset.h \
sysdep.o: sysdep.c syssignal.h systty.h systime.h syswait.h blockinput.h \
process.h dispextern.h termhooks.h termchar.h termopts.h \
frame.h atimer.h window.h msdos.h dosfns.h keyboard.h $(config_h)
term.o: term.c termchar.h termhooks.h termopts.h $(config_h) cm.h frame.h \
term.o: term.c systty.h termchar.h termhooks.h termopts.h $(config_h) cm.h frame.h \
disptab.h dispextern.h keyboard.h charset.h coding.h ccl.h msdos.h
termcap.o: termcap.c $(config_h)
terminfo.o: terminfo.c $(config_h)
......@@ -1134,17 +1134,18 @@ w16select.o: w16select.c dispextern.h frame.h blockinput.h atimer.h systime.h \
msdos.h $(config_h)
widget.o: widget.c xterm.h frame.h dispextern.h widgetprv.h \
$(srcdir)/../lwlib/lwlib.h $(config_h)
window.o: window.c indent.h commands.h frame.h window.h buffer.h termchar.h \
window.o: window.c indent.h commands.h frame.h window.h buffer.h systty.h termchar.h \
termhooks.h disptab.h keyboard.h dispextern.h msdos.h composite.h \
xdisp.o: xdisp.c macros.h commands.h process.h indent.h buffer.h dispextern.h coding.h \
termchar.h frame.h window.h disptab.h termhooks.h charset.h $(config_h) \
systty.h termchar.h frame.h window.h disptab.h termhooks.h charset.h $(config_h) \
msdos.h composite.h fontset.h blockinput.h atimer.h systime.h keymap.h
xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \
window.h charset.h msdos.h dosfns.h composite.h atimer.h systime.h $(config_h)
window.h charset.h msdos.h dosfns.h composite.h atimer.h systime.h \
systty.h termchar.h $(config_h)
xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \
$(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \
charset.h gtkutil.h $(config_h)
charset.h gtkutil.h systty.h termchar.h $(config_h)
xmenu.o: xmenu.c xterm.h termhooks.h window.h dispextern.h frame.h buffer.h \
keyboard.h $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h \
gtkutil.h msdos.h coding.h $(config_h)
......@@ -1176,7 +1177,7 @@ floatfns.o: floatfns.c $(config_h)
fns.o: fns.c commands.h $(config_h) frame.h buffer.h charset.h keyboard.h \
frame.h window.h dispextern.h $(INTERVAL_SRC) coding.h md5.h
print.o: print.c process.h frame.h window.h buffer.h keyboard.h charset.h \
$(config_h) dispextern.h msdos.h composite.h
$(config_h) dispextern.h msdos.h composite.h systty.h termchar.h intervals.h
lread.o: lread.c commands.h keyboard.h buffer.h epaths.h charset.h $(config_h) \
termhooks.h coding.h msdos.h
......@@ -22,8 +22,16 @@ Boston, MA 02111-1307, USA. */
#include <config.h>
#include <stdio.h>
/* For CURTTY */
#include "lisp.h"
#include "frame.h"
#include "cm.h"
#include "termhooks.h"
#include "systty.h" /* For emacs_tty in termchar.h */
#include "termchar.h"
/* For now, don't try to include termcap.h. On some systems,
configure finds a non-standard termcap.h that the main build
......@@ -41,6 +49,7 @@ extern char *tgoto P_ ((const char *, int, int));
extern char *BC, *UP;
int cost; /* sums up costs */
......@@ -52,13 +61,16 @@ evalcost (c)
return c;
/* The terminal to use for low-level output. */
struct tty_output * current_tty;
cmputc (c)
char c;
if (termscript)
fputc (c & 0177, termscript);
putchar (c & 0177);
if (TTY_TERMSCRIPT (current_tty))
putc (c & 0177, TTY_TERMSCRIPT (current_tty));
putc (c & 0177, TTY_OUTPUT (current_tty));
return c;
......@@ -122,18 +134,19 @@ addcol (n) {
* after we reach the last column; this takes us to a known state.
cmcheckmagic ()
cmcheckmagic (tty)
struct tty_output *tty;
if (curX == FrameCols)
if (!MagicWrap || curY >= FrameRows - 1)
abort ();
if (termscript)
putc ('\r', termscript);
putchar ('\r');
if (termscript)
putc ('\n', termscript);
putchar ('\n');
putc ('\r', TTY_TERMSCRIPT (tty));
putc ('\r', TTY_OUTPUT (tty));
putc ('\n', TTY_TERMSCRIPT (tty));
putc ('\n', TTY_OUTPUT (tty));
curX = 0;
......@@ -187,8 +200,7 @@ cmcostinit ()
static int
calccost (srcy, srcx, dsty, dstx, doit)
int srcy, srcx, dsty, dstx, doit;
calccost (struct tty_output *tty, int srcy, int srcx, int dsty, int dstx, int doit)
register int deltay,
......@@ -223,7 +235,7 @@ calccost (srcy, srcx, dsty, dstx, doit)
totalcost = c * deltay;
if (doit)
while (--deltay >= 0)
tputs (p, 1, cmputc);
emacs_tputs (tty, p, 1, cmputc);
if ((deltax = dstx - srcx) == 0)
goto done;
......@@ -278,7 +290,7 @@ calccost (srcy, srcx, dsty, dstx, doit)
totalcost += tabcost; /* use the tabs */
if (doit)
while (--ntabs >= 0)
tputs (Wcm.cm_tab, 1, cmputc);
emacs_tputs (tty, Wcm.cm_tab, 1, cmputc);
srcx = tabx;
......@@ -305,7 +317,7 @@ calccost (srcy, srcx, dsty, dstx, doit)
totalcost += c * deltax;
if (doit)
while (--deltax >= 0)
tputs (p, 1, cmputc);
emacs_tputs (tty, p, 1, cmputc);
return totalcost;
......@@ -323,7 +335,8 @@ losecursor ()
#define USECR 3
cmgoto (row, col)
cmgoto (tty, row, col)
struct tty_output *tty;
int row, col;
int homecost,
......@@ -346,24 +359,24 @@ cmgoto (row, col)
* start where we are. Examine the options, and pick the cheapest.
relcost = calccost (curY, curX, row, col, 0);
relcost = calccost (tty, curY, curX, row, col, 0);
use = USEREL;
if ((homecost = Wcm.cc_home) < BIG)
homecost += calccost (0, 0, row, col, 0);
homecost += calccost (tty, 0, 0, row, col, 0);
if (homecost < relcost)
relcost = homecost, use = USEHOME;
relcost = homecost, use = USEHOME;
if ((llcost = Wcm.cc_ll) < BIG)
llcost += calccost (Wcm.cm_rows - 1, 0, row, col, 0);
llcost += calccost (tty, Wcm.cm_rows - 1, 0, row, col, 0);
if (llcost < relcost)
relcost = llcost, use = USELL;
relcost = llcost, use = USELL;
if ((crcost = Wcm.cc_cr) < BIG) {
if (Wcm.cm_autolf)
if (curY + 1 >= Wcm.cm_rows)
crcost = BIG;
crcost += calccost (curY + 1, 0, row, col, 0);
crcost += calccost (tty, curY + 1, 0, row, col, 0);
crcost += calccost (curY, 0, row, col, 0);
crcost += calccost (tty, curY, 0, row, col, 0);
if (crcost < relcost)
relcost = crcost, use = USECR;
......@@ -389,10 +402,10 @@ cmgoto (row, col)
cost = 0;
p = dcm == Wcm.cm_habs ? tgoto (dcm, row, col) :
tgoto (dcm, col, row);
tputs (p, 1, evalcost);
emacs_tputs (tty, p, 1, evalcost);
if (cost <= relcost)
{ /* really is cheaper */
tputs (p, 1, cmputc);
emacs_tputs (tty, p, 1, cmputc);
curY = row, curX = col;
......@@ -401,24 +414,24 @@ cmgoto (row, col)
switch (use)
tputs (Wcm.cm_home, 1, cmputc);
emacs_tputs (tty, Wcm.cm_home, 1, cmputc);
curY = 0, curX = 0;
case USELL:
tputs (Wcm.cm_ll, 1, cmputc);
emacs_tputs (tty, Wcm.cm_ll, 1, cmputc);
curY = Wcm.cm_rows - 1, curX = 0;
case USECR:
tputs (Wcm.cm_cr, 1, cmputc);
emacs_tputs (tty, Wcm.cm_cr, 1, cmputc);
if (Wcm.cm_autolf)
curX = 0;
(void) calccost (curY, curX, row, col, 1);
(void) calccost (tty, curY, curX, row, col, 1);
curY = row, curX = col;
......@@ -162,10 +162,13 @@ extern char PC; /* Pad character */
extern int cost;
extern int evalcost ();
extern void cmcheckmagic ();
extern int cmputc ();
#define emacs_tputs(tty, str, affcnt, putc) (current_tty = (tty), tputs (str, affcnt, putc))
extern struct tty_output *current_tty;
extern void cmcheckmagic P_ ((struct tty_output *));
extern int cmputc P_ ((int));
extern void cmcostinit ();
extern void cmgoto ();
extern void cmgoto P_ ((struct tty_output *, int, int));
extern void Wcm_clear ();
extern int Wcm_init ();
......@@ -2724,8 +2724,8 @@ extern Lisp_Object Qredisplay_dont_pause;
/* Defined in term.c */
extern void ring_bell P_ ((void));
extern void set_terminal_modes P_ ((void));
extern void reset_terminal_modes P_ ((void));
extern void set_terminal_modes P_ ((struct tty_output *));
extern void reset_terminal_modes P_ ((struct tty_output *));
extern void update_begin P_ ((struct frame *));
extern void update_end P_ ((struct frame *));
extern void set_terminal_window P_ ((int));
......@@ -2743,7 +2743,8 @@ extern int per_line_cost P_ ((char *));
extern void calculate_costs P_ ((struct frame *));
extern void set_tty_color_mode P_ ((struct frame *, Lisp_Object));
extern void tty_setup_colors P_ ((int));
extern void term_init P_ ((char *));
extern struct tty_output *term_init P_ ((char *, char *));
extern struct tty_output *term_dummy_init P_ ((void));
extern void fatal P_ ((/* char *, ... */));
void cursor_to P_ ((int, int));
extern int tty_capable_p P_ ((struct frame *, unsigned, unsigned long, unsigned long));
......@@ -29,6 +29,7 @@ Boston, MA 02111-1307, USA. */
#include "lisp.h"
#include "systty.h" /* For emacs_tty in termchar.h */
#include "termchar.h"
#include "termopts.h"
#include "termhooks.h"
......@@ -258,10 +259,6 @@ Lisp_Object selected_frame;
struct frame *last_nonminibuf_frame;
/* Stdio stream being used for copy of all output. */
FILE *termscript;
/* Structure for info on cursor positioning. */
struct cm Wcm;
......@@ -1397,7 +1394,7 @@ line_hash_code (row)
int c = glyph->;
int face_id = glyph->face_id;
hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c;
hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id;
......@@ -1429,7 +1426,7 @@ line_draw_cost (matrix, vpos)
int glyph_table_len = GLYPH_TABLE_LENGTH;
/* Ignore trailing and leading spaces if we can. */
/* Skip from the end over trailing spaces. */
while (end > beg && CHAR_GLYPH_SPACE_P (*(end - 1)))
......@@ -1643,8 +1640,10 @@ realloc_glyph_pool (pool, matrix_dim)
/* Flush standard output. This is sometimes useful to call from
the debugger. */
/* Flush standard output. This is sometimes useful to call from the debugger.
XXX Maybe this should be changed to flush the current terminal instead of
flush_stdout ()
......@@ -3318,7 +3317,7 @@ DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0,
update_begin (f);
if (FRAME_MSDOS_P (f))
set_terminal_modes ();
set_terminal_modes (0);
clear_frame ();
clear_current_matrices (f);
update_end (f);
......@@ -3462,7 +3461,7 @@ direct_output_for_insert (g)
/* If we can't insert glyphs, we can use this method only
at the end of a line. */
if (PT != ZV && FETCH_BYTE (PT_BYTE) != '\n')
return 0;
......@@ -3841,9 +3840,9 @@ update_frame (f, force_p, inhibit_hairy_id_p)
paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p);
update_end (f);
if (termscript)
fflush (termscript);
fflush (stdout);
fflush (TTY_OUTPUT (FRAME_TTY (f)));
/* Check window matrices for lost pointers. */
......@@ -5075,7 +5074,7 @@ update_frame_1 (f, force_p, inhibit_id_p)
/* If we cannot insert/delete lines, it's no use trying it. */
inhibit_id_p = 1;
/* See if any of the desired lines are enabled; don't compute for
......@@ -5293,7 +5292,7 @@ scrolling (frame)
/* If changed lines are few, don't allow preemption, don't scroll. */
&& changed_lines < baud_rate / 2400)
|| unchanged_at_bottom == FRAME_LINES (frame))
return 1;
......@@ -5301,14 +5300,14 @@ scrolling (frame)
window_size = (FRAME_LINES (frame) - unchanged_at_top
- unchanged_at_bottom);
free_at_end_vpos -= unchanged_at_bottom;
free_at_end_vpos = -1;
/* If large window, fast terminal and few lines in common between
current frame and desired frame, don't bother with i/d calc. */
&& window_size >= 18 && baud_rate > 2400
&& (window_size >=
10 * scrolling_max_lines_saved (unchanged_at_top,
......@@ -5389,7 +5388,7 @@ update_frame_line (f, vpos)
struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos);
struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos);
int must_write_whole_line_p;
int write_spaces_p = TTY_MUST_WRITE_SPACES (FRAME_TTY (f));
int colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background
......@@ -5468,7 +5467,7 @@ update_frame_line (f, vpos)
/* If there's no i/d char, quickly do the best we can without it. */
int i, j;
......@@ -5571,7 +5570,7 @@ update_frame_line (f, vpos)
tem = (nlen - nsp) - (olen - osp);
if (endmatch && tem
|| endmatch <= char_ins_del_cost (f)[tem]))
endmatch = 0;
......@@ -5581,7 +5580,7 @@ update_frame_line (f, vpos)
Is it worth it? */
if (nsp != osp
|| begmatch + endmatch <= char_ins_del_cost (f)[nsp - osp]))
begmatch = 0;
......@@ -6113,14 +6112,15 @@ FILE = nil means just close any termscript file currently open. */)
Lisp_Object file;
if (termscript != 0) fclose (termscript);
termscript = 0;
if (! NILP (file))
file = Fexpand_file_name (file, Qnil);
termscript = fopen (SDATA (file), "w");
if (termscript == 0)
TTY_TERMSCRIPT (CURTTY ()) = fopen (SDATA (file), "w");
report_file_error ("Opening termscript", Fcons (file, Qnil));
return Qnil;
......@@ -6136,14 +6136,15 @@ Control characters in STRING will have terminal-dependent effects. */)
/* ??? Perhaps we should do something special for multibyte strings here. */
CHECK_STRING (string);
fwrite (SDATA (string), 1, SBYTES (string), stdout);
fflush (stdout);
if (termscript)
fwrite (SDATA (string), 1, SBYTES (string),
fflush (termscript);
fwrite (SDATA (string), 1, SBYTES (string),
fflush (TTY_OUTPUT (CURTTY ()));
return Qnil;
......@@ -6463,8 +6464,6 @@ the current state. */)
char *terminal_type;
/* Initialization done when Emacs fork is started, before doing stty.
Determine terminal type and set terminal_driver. Then invoke its
decoding routine to set up variables in the terminal package. */
......@@ -6472,6 +6471,8 @@ char *terminal_type;
init_display ()