X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/bf120ed1b9f1fa5a2422465e7ca825080b7b0c65..7d72bb827da6e6a1a4df8752ace4513349adc28d:/src/term.c diff --git a/src/term.c b/src/term.c index 69936400a1..f9875f8bc0 100644 --- a/src/term.c +++ b/src/term.c @@ -1,14 +1,14 @@ /* Terminal control module for terminals described by TERMCAP Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008 + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GNU Emacs. -GNU Emacs is free software; you can redistribute it and/or modify +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 3, or (at your option) -any later version. +the Free Software Foundation, either version 3 of the License, 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 @@ -16,9 +16,7 @@ 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., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ +along with GNU Emacs. If not, see . */ /* New redisplay, TTY faces by Gerd Moellmann . */ @@ -43,8 +41,11 @@ Boston, MA 02110-1301, USA. */ #include "lisp.h" #include "termchar.h" #include "termopts.h" +#include "buffer.h" +#include "character.h" #include "charset.h" #include "coding.h" +#include "composite.h" #include "keyboard.h" #include "frame.h" #include "disptab.h" @@ -56,6 +57,10 @@ Boston, MA 02110-1301, USA. */ #include "syssignal.h" #include "systty.h" #include "intervals.h" +#ifdef MSDOS +#include "msdos.h" +static int been_here = -1; +#endif /* For now, don't try to include termcap.h. On some systems, configure finds a non-standard termcap.h that the main build @@ -74,9 +79,6 @@ extern int tgetnum P_ ((char *id)); #ifdef HAVE_X_WINDOWS #include "xterm.h" #endif -#ifdef MAC_OS -#include "macterm.h" -#endif #ifndef O_RDWR #define O_RDWR 2 @@ -188,7 +190,6 @@ extern char *tgetstr (); #ifdef HAVE_GPM #include -#include "buffer.h" static void term_clear_mouse_face (); static void term_mouse_highlight (struct frame *f, int x, int y); @@ -233,7 +234,7 @@ void tty_set_terminal_modes (struct terminal *terminal) { struct tty_display_info *tty = terminal->display_info.tty; - + if (tty->output) { if (tty->TS_termcap_modes) @@ -549,10 +550,12 @@ tty_clear_end_of_line (struct frame *f, int first_unused_hpos) } } -/* Buffer to store the source and result of code conversion for terminal. */ -static unsigned char *encode_terminal_buf; -/* Allocated size of the above buffer. */ -static int encode_terminal_bufsize; +/* Buffers to store the source and result of code conversion for terminal. */ +static unsigned char *encode_terminal_src; +static unsigned char *encode_terminal_dst; +/* Allocated sizes of the above buffers. */ +static int encode_terminal_src_size; +static int encode_terminal_dst_size; /* Encode SRC_LEN glyphs starting at SRC to terminal output codes. Set CODING->produced to the byte-length of the resulting byte @@ -565,42 +568,106 @@ encode_terminal_code (src, src_len, coding) struct coding_system *coding; { struct glyph *src_end = src + src_len; - register GLYPH g; unsigned char *buf; int nchars, nbytes, required; register int tlen = GLYPH_TABLE_LENGTH; register Lisp_Object *tbase = GLYPH_TABLE_BASE; + Lisp_Object charset_list; /* Allocate sufficient size of buffer to store all characters in multibyte-form. But, it may be enlarged on demand if - Vglyph_table contains a string. */ + Vglyph_table contains a string or a composite glyph is + encountered. */ required = MAX_MULTIBYTE_LENGTH * src_len; - if (encode_terminal_bufsize < required) + if (encode_terminal_src_size < required) { - if (encode_terminal_bufsize == 0) - encode_terminal_buf = xmalloc (required); + if (encode_terminal_src) + encode_terminal_src = xrealloc (encode_terminal_src, required); else - encode_terminal_buf = xrealloc (encode_terminal_buf, required); - encode_terminal_bufsize = required; + encode_terminal_src = xmalloc (required); + encode_terminal_src_size = required; } - buf = encode_terminal_buf; + charset_list = coding_charset_list (coding); + + buf = encode_terminal_src; nchars = 0; while (src < src_end) { + if (src->type == COMPOSITE_GLYPH) + { + struct composition *cmp; + Lisp_Object gstring; + int i; + + nbytes = buf - encode_terminal_src; + if (src->u.cmp.automatic) + { + gstring = composition_gstring_from_id (src->u.cmp.id); + required = src->u.cmp.to + 1 - src->u.cmp.from; + } + else + { + cmp = composition_table[src->u.cmp.id]; + required = MAX_MULTIBYTE_LENGTH * cmp->glyph_len; + } + + if (encode_terminal_src_size < nbytes + required) + { + encode_terminal_src_size = nbytes + required; + encode_terminal_src = xrealloc (encode_terminal_src, + encode_terminal_src_size); + buf = encode_terminal_src + nbytes; + } + + if (src->u.cmp.automatic) + for (i = src->u.cmp.from; i <= src->u.cmp.to; i++) + { + Lisp_Object g = LGSTRING_GLYPH (gstring, i); + int c = LGLYPH_CHAR (g); + + if (! char_charset (c, charset_list, NULL)) + c = '?'; + buf += CHAR_STRING (c, buf); + nchars++; + } + else + for (i = 0; i < cmp->glyph_len; i++) + { + int c = COMPOSITION_GLYPH (cmp, i); + + if (c == '\t') + continue; + if (char_charset (c, charset_list, NULL)) + { + if (CHAR_WIDTH (c) == 0 + && i > 0 && COMPOSITION_GLYPH (cmp, i - 1) == '\t') + /* Should be left-padded */ + { + buf += CHAR_STRING (' ', buf); + nchars++; + } + } + else + c = '?'; + buf += CHAR_STRING (c, buf); + nchars++; + } + } /* We must skip glyphs to be padded for a wide character. */ - if (! CHAR_GLYPH_PADDING_P (*src)) + else if (! CHAR_GLYPH_PADDING_P (*src)) { - g = GLYPH_FROM_CHAR_GLYPH (src[0]); + GLYPH g; + int c; + Lisp_Object string; + + string = Qnil; + SET_GLYPH_FROM_CHAR_GLYPH (g, src[0]); - if (g < 0 || g >= tlen) + if (GLYPH_INVALID_P (g) || GLYPH_SIMPLE_P (tbase, tlen, g)) { - /* This glyph doesn't has an entry in Vglyph_table. */ - if (CHAR_VALID_P (src->u.ch, 0)) - buf += CHAR_STRING (src->u.ch, buf); - else - *buf++ = SPACEGLYPH; - nchars++; + /* This glyph doesn't have an entry in Vglyph_table. */ + c = src->u.ch; } else { @@ -609,65 +676,94 @@ encode_terminal_code (src, src_len, coding) GLYPH_FOLLOW_ALIASES (tbase, tlen, g); if (GLYPH_SIMPLE_P (tbase, tlen, g)) - { - int c = FAST_GLYPH_CHAR (g); + /* We set the multi-byte form of a character in G + (that should be an ASCII character) at WORKBUF. */ + c = GLYPH_CHAR (g); + else + /* We have a string in Vglyph_table. */ + string = tbase[GLYPH_CHAR (g)]; + } - if (CHAR_VALID_P (c, 0)) - buf += CHAR_STRING (c, buf); - else - *buf++ = SPACEGLYPH; + if (NILP (string)) + { + nbytes = buf - encode_terminal_src; + if (encode_terminal_src_size < nbytes + MAX_MULTIBYTE_LENGTH) + { + encode_terminal_src_size = nbytes + MAX_MULTIBYTE_LENGTH; + encode_terminal_src = xrealloc (encode_terminal_src, + encode_terminal_src_size); + buf = encode_terminal_src + nbytes; + } + if (char_charset (c, charset_list, NULL)) + { + /* Store the multibyte form of C at BUF. */ + buf += CHAR_STRING (c, buf); nchars++; } else { - /* We have a string in Vglyph_table. */ - Lisp_Object string; - - string = tbase[g]; - if (! STRING_MULTIBYTE (string)) - string = string_to_multibyte (string); - nbytes = buf - encode_terminal_buf; - if (encode_terminal_bufsize < nbytes + SBYTES (string)) + /* C is not encodable. */ + *buf++ = '?'; + nchars++; + while (src + 1 < src_end && CHAR_GLYPH_PADDING_P (src[1])) { - encode_terminal_bufsize = nbytes + SBYTES (string); - encode_terminal_buf = xrealloc (encode_terminal_buf, - encode_terminal_bufsize); - buf = encode_terminal_buf + nbytes; + *buf++ = '?'; + nchars++; + src++; } - bcopy (SDATA (string), buf, SBYTES (string)); - buf += SBYTES (string); - nchars += SCHARS (string); } } + else + { + unsigned char *p = SDATA (string), *pend = p + SBYTES (string); + + if (! STRING_MULTIBYTE (string)) + string = string_to_multibyte (string); + nbytes = buf - encode_terminal_src; + if (encode_terminal_src_size < nbytes + SBYTES (string)) + { + encode_terminal_src_size = nbytes + SBYTES (string); + encode_terminal_src = xrealloc (encode_terminal_src, + encode_terminal_src_size); + buf = encode_terminal_src + nbytes; + } + bcopy (SDATA (string), buf, SBYTES (string)); + buf += SBYTES (string); + nchars += SCHARS (string); + } } src++; } - nbytes = buf - encode_terminal_buf; - coding->src_multibyte = 1; - coding->dst_multibyte = 0; - if (SYMBOLP (coding->pre_write_conversion) - && ! NILP (Ffboundp (coding->pre_write_conversion))) + if (nchars == 0) { - run_pre_write_conversin_on_c_str (&encode_terminal_buf, - &encode_terminal_bufsize, - nchars, nbytes, coding); - nchars = coding->produced_char; - nbytes = coding->produced; + coding->produced = 0; + return NULL; } - required = nbytes + encoding_buffer_size (coding, nbytes); - if (encode_terminal_bufsize < required) + + nbytes = buf - encode_terminal_src; + coding->source = encode_terminal_src; + if (encode_terminal_dst_size == 0) { - encode_terminal_bufsize = required; - encode_terminal_buf = xrealloc (encode_terminal_buf, required); + encode_terminal_dst_size = encode_terminal_src_size; + if (encode_terminal_dst) + encode_terminal_dst = xrealloc (encode_terminal_dst, + encode_terminal_dst_size); + else + encode_terminal_dst = xmalloc (encode_terminal_dst_size); } - - encode_coding (coding, encode_terminal_buf, encode_terminal_buf + nbytes, - nbytes, encode_terminal_bufsize - nbytes); - return encode_terminal_buf + nbytes; + coding->destination = encode_terminal_dst; + coding->dst_bytes = encode_terminal_dst_size; + encode_coding_object (coding, Qnil, 0, 0, nchars, nbytes, Qnil); + /* coding->destination may have been reallocated. */ + encode_terminal_dst = coding->destination; + encode_terminal_dst_size = coding->dst_bytes; + + return (encode_terminal_dst); } + /* An implementation of write_glyphs for termcap frames. */ static void @@ -951,7 +1047,7 @@ tty_ins_del_lines (struct frame *f, int vpos, int n) if (!FRAME_MEMORY_BELOW_FRAME (f) && vpos + i >= FRAME_LINES (f)) return; - + if (multi) { raw_cursor_to (f, vpos, 0); @@ -981,7 +1077,7 @@ tty_ins_del_lines (struct frame *f, int vpos, int n) OUTPUTL (tty, scroll, tty->specified_window - vpos); tty_set_scroll_region (f, 0, tty->specified_window); } - + if (!FRAME_SCROLL_REGION_OK (f) && FRAME_MEMORY_BELOW_FRAME (f) && n < 0) @@ -1306,7 +1402,7 @@ term_get_fkeys_1 () char **address = term_get_fkeys_address; KBOARD *kboard = term_get_fkeys_kboard; - + /* This can happen if CANNOT_DUMP or with strange options. */ if (!KEYMAPP (kboard->Vinput_decode_map)) kboard->Vinput_decode_map = Fmake_sparse_keymap (Qnil); @@ -1421,11 +1517,14 @@ term_get_fkeys_1 () #ifdef static #define append_glyph append_glyph_term #define produce_stretch_glyph produce_stretch_glyph_term +#define append_composite_glyph append_composite_glyph_term +#define produce_composite_glyph produce_composite_glyph_term #endif static void append_glyph P_ ((struct it *)); static void produce_stretch_glyph P_ ((struct it *)); - +static void append_composite_glyph P_ ((struct it *)); +static void produce_composite_glyph P_ ((struct it *)); /* Append glyphs to IT's glyph_row. Called from produce_glyphs for terminal frames if IT->glyph_row != NULL. IT->char_to_display is @@ -1486,6 +1585,8 @@ produce_glyphs (it) struct it *it; { /* If a hook is installed, let it do the work. */ + + /* Nothing but characters are supported on terminal frames. */ xassert (it->what == IT_CHARACTER || it->what == IT_COMPOSITION || it->what == IT_STRETCH); @@ -1496,11 +1597,11 @@ produce_glyphs (it) goto done; } - /* Nothing but characters are supported on terminal frames. For a - composition sequence, it->c is the first character of the - sequence. */ - xassert (it->what == IT_CHARACTER - || it->what == IT_COMPOSITION); + if (it->what == IT_COMPOSITION) + { + produce_composite_glyph (it); + goto done; + } /* Maybe translate single-byte characters to multibyte. */ it->char_to_display = it->c; @@ -1544,28 +1645,24 @@ produce_glyphs (it) it->pixel_width = nspaces; it->nglyphs = nspaces; } - else if (SINGLE_BYTE_CHAR_P (it->c)) + else if (CHAR_BYTE8_P (it->c)) { if (unibyte_display_via_language_environment - && (it->c >= 0240 - || !NILP (Vnonascii_translation_table))) + && (it->c >= 0240)) { - int charset; - it->char_to_display = unibyte_char_to_multibyte (it->c); - charset = CHAR_CHARSET (it->char_to_display); - it->pixel_width = CHARSET_WIDTH (charset); + it->pixel_width = CHAR_WIDTH (it->char_to_display); it->nglyphs = it->pixel_width; if (it->glyph_row) append_glyph (it); } else { - /* Coming here means that it->c is from display table, thus we - must send the code as is to the terminal. Although there's - no way to know how many columns it occupies on a screen, it - is a good assumption that a single byte code has 1-column - width. */ + /* Coming here means that it->c is from display table, thus + we must send the raw 8-bit byte as is to the terminal. + Although there's no way to know how many columns it + occupies on a screen, it is a good assumption that a + single byte code has 1-column width. */ it->pixel_width = it->nglyphs = 1; if (it->glyph_row) append_glyph (it); @@ -1573,13 +1670,7 @@ produce_glyphs (it) } else { - /* A multi-byte character. The display width is fixed for all - characters of the set. Some of the glyphs may have to be - ignored because they are already displayed in a continued - line. */ - int charset = CHAR_CHARSET (it->c); - - it->pixel_width = CHARSET_WIDTH (charset); + it->pixel_width = CHAR_WIDTH (it->c); it->nglyphs = it->pixel_width; if (it->glyph_row) @@ -1649,6 +1740,10 @@ produce_stretch_glyph (it) if (width <= 0 && (width < 0 || !zero_width_ok_p)) width = 1; + if (width > 0 && it->line_wrap != TRUNCATE + && it->current_x + width > it->last_visible_x) + width = it->last_visible_x - it->current_x - 1; + if (width > 0 && it->glyph_row) { Lisp_Object o_object = it->object; @@ -1669,6 +1764,78 @@ produce_stretch_glyph (it) } +/* Append glyphs to IT's glyph_row for the composition IT->cmp_id. + Called from produce_composite_glyph for terminal frames if + IT->glyph_row != NULL. IT->face_id contains the character's + face. */ + +static void +append_composite_glyph (it) + struct it *it; +{ + struct glyph *glyph; + + xassert (it->glyph_row); + glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area]; + if (glyph < it->glyph_row->glyphs[1 + it->area]) + { + glyph->type = COMPOSITE_GLYPH; + glyph->pixel_width = it->pixel_width; + glyph->u.cmp.id = it->cmp_it.id; + if (it->cmp_it.ch < 0) + { + glyph->u.cmp.automatic = 0; + glyph->u.cmp.id = it->cmp_it.id; + } + else + { + glyph->u.cmp.automatic = 1; + glyph->u.cmp.id = it->cmp_it.id; + glyph->u.cmp.from = it->cmp_it.from; + glyph->u.cmp.to = it->cmp_it.to - 1; + } + + glyph->face_id = it->face_id; + glyph->padding_p = 0; + glyph->charpos = CHARPOS (it->position); + glyph->object = it->object; + + ++it->glyph_row->used[it->area]; + ++glyph; + } +} + + +/* Produce a composite glyph for iterator IT. IT->cmp_id is the ID of + the composition. We simply produces components of the composition + assuming that that the terminal has a capability to layout/render + it correctly. */ + +static void +produce_composite_glyph (it) + struct it *it; +{ + int c; + + if (it->cmp_it.ch < 0) + { + struct composition *cmp = composition_table[it->cmp_it.id]; + + it->pixel_width = cmp->width; + } + else + { + Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id); + + it->pixel_width = composition_gstring_width (gstring, it->cmp_it.from, + it->cmp_it.to, NULL); + } + it->nglyphs = 1; + if (it->glyph_row) + append_composite_glyph (it); +} + + /* Get information about special display element WHAT in an environment described by IT. WHAT is one of IT_TRUNCATION or IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a @@ -1681,6 +1848,7 @@ produce_special_glyphs (it, what) enum display_element_type what; { struct it temp_it; + Lisp_Object gc; GLYPH glyph; temp_it = *it; @@ -1693,34 +1861,32 @@ produce_special_glyphs (it, what) if (what == IT_CONTINUATION) { /* Continuation glyph. */ + SET_GLYPH_FROM_CHAR (glyph, '\\'); if (it->dp - && INTEGERP (DISP_CONTINUE_GLYPH (it->dp)) - && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it->dp)))) + && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)) + && GLYPH_CODE_CHAR_VALID_P (gc)) { - glyph = XINT (DISP_CONTINUE_GLYPH (it->dp)); - glyph = spec_glyph_lookup_face (XWINDOW (it->window), glyph); + SET_GLYPH_FROM_GLYPH_CODE (glyph, gc); + spec_glyph_lookup_face (XWINDOW (it->window), &glyph); } - else - glyph = '\\'; } else if (what == IT_TRUNCATION) { /* Truncation glyph. */ + SET_GLYPH_FROM_CHAR (glyph, '$'); if (it->dp - && INTEGERP (DISP_TRUNC_GLYPH (it->dp)) - && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it->dp)))) + && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)) + && GLYPH_CODE_CHAR_VALID_P (gc)) { - glyph = XINT (DISP_TRUNC_GLYPH (it->dp)); - glyph = spec_glyph_lookup_face (XWINDOW (it->window), glyph); + SET_GLYPH_FROM_GLYPH_CODE (glyph, gc); + spec_glyph_lookup_face (XWINDOW (it->window), &glyph); } - else - glyph = '$'; } else abort (); - temp_it.c = FAST_GLYPH_CHAR (glyph); - temp_it.face_id = FAST_GLYPH_FACE (glyph); + temp_it.c = GLYPH_CHAR (glyph); + temp_it.face_id = GLYPH_FACE (glyph); temp_it.len = CHAR_BYTES (temp_it.c); produce_glyphs (&temp_it); @@ -1931,9 +2097,9 @@ DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p, 0, 1, 0, doc: /* Return non-nil if the tty device TERMINAL can display colors. -TERMINAL can be a terminal id, a frame or nil (meaning the selected -frame's terminal). This function always returns nil if TERMINAL -is not on a tty device. */) +TERMINAL can be a terminal object, a frame, or nil (meaning the +selected frame's terminal). This function always returns nil if +TERMINAL does not refer to a text-only terminal. */) (terminal) Lisp_Object terminal; { @@ -1949,9 +2115,9 @@ DEFUN ("tty-display-color-cells", Ftty_display_color_cells, Stty_display_color_cells, 0, 1, 0, doc: /* Return the number of colors supported by the tty device TERMINAL. -TERMINAL can be a terminal id, a frame or nil (meaning the selected -frame's terminal). This function always returns 0 if TERMINAL -is not on a tty device. */) +TERMINAL can be a terminal object, a frame, or nil (meaning the +selected frame's terminal). This function always returns 0 if +TERMINAL does not refer to a text-only terminal. */) (terminal) Lisp_Object terminal; { @@ -1962,7 +2128,7 @@ is not on a tty device. */) return make_number (t->display_info.tty->TN_max_colors); } -#ifndef WINDOWSNT +#ifndef DOS_NT /* Declare here rather than in the function, as in the rest of Emacs, to work around an HPUX compiler bug (?). See @@ -1982,17 +2148,14 @@ tty_default_color_capabilities (struct tty_display_info *tty, int save) if (save) { - if (default_orig_pair) - xfree (default_orig_pair); + xfree (default_orig_pair); default_orig_pair = tty->TS_orig_pair ? xstrdup (tty->TS_orig_pair) : NULL; - if (default_set_foreground) - xfree (default_set_foreground); + xfree (default_set_foreground); default_set_foreground = tty->TS_set_foreground ? xstrdup (tty->TS_set_foreground) : NULL; - if (default_set_background) - xfree (default_set_background); + xfree (default_set_background); default_set_background = tty->TS_set_background ? xstrdup (tty->TS_set_background) : NULL; @@ -2051,60 +2214,42 @@ tty_setup_colors (struct tty_display_info *tty, int mode) } void -set_tty_color_mode (f, val) +set_tty_color_mode (tty, f) + struct tty_display_info *tty; struct frame *f; - Lisp_Object val; { - Lisp_Object color_mode_spec, current_mode_spec; - Lisp_Object color_mode, current_mode; - int mode, old_mode; + Lisp_Object tem, val, color_mode_spec; + Lisp_Object color_mode; + int mode; extern Lisp_Object Qtty_color_mode; - Lisp_Object tty_color_mode_alist; + Lisp_Object tty_color_mode_alist + = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil); - tty_color_mode_alist = Fintern_soft (build_string ("tty-color-mode-alist"), - Qnil); + tem = assq_no_quit (Qtty_color_mode, f->param_alist); + val = CONSP (tem) ? XCDR (tem) : Qnil; if (INTEGERP (val)) color_mode = val; else { - if (NILP (tty_color_mode_alist)) - color_mode_spec = Qnil; - else - color_mode_spec = Fassq (val, XSYMBOL (tty_color_mode_alist)->value); - - if (CONSP (color_mode_spec)) - color_mode = XCDR (color_mode_spec); - else - color_mode = Qnil; + tem = (NILP (tty_color_mode_alist) ? Qnil + : Fassq (val, XSYMBOL (tty_color_mode_alist)->value)); + color_mode = CONSP (tem) ? XCDR (tem) : Qnil; } - current_mode_spec = assq_no_quit (Qtty_color_mode, f->param_alist); + mode = INTEGERP (color_mode) ? XINT (color_mode) : 0; - if (CONSP (current_mode_spec)) - current_mode = XCDR (current_mode_spec); - else - current_mode = Qnil; - if (INTEGERP (color_mode)) - mode = XINT (color_mode); - else - mode = 0; /* meaning default */ - if (INTEGERP (current_mode)) - old_mode = XINT (current_mode); - else - old_mode = 0; - - if (mode != old_mode) + if (mode != tty->previous_color_mode) { - tty_setup_colors (FRAME_TTY (f), mode); - /* This recomputes all the faces given the new color - definitions. */ - call0 (intern ("tty-set-up-initial-frame-faces")); - redraw_frame (f); + Lisp_Object funsym = intern ("tty-set-up-initial-frame-faces"); + tty->previous_color_mode = mode; + tty_setup_colors (tty , mode); + /* This recomputes all the faces given the new color definitions. */ + safe_call (1, &funsym); } } -#endif /* !WINDOWSNT */ +#endif /* !DOS_NT */ @@ -2115,7 +2260,7 @@ get_tty_terminal (Lisp_Object terminal, int throw) { struct terminal *t = get_terminal (terminal, throw); - if (t && t->type != output_termcap) + if (t && t->type != output_termcap && t->type != output_msdos_raw) { if (throw) error ("Device %d is not a termcap terminal device", t->id); @@ -2132,7 +2277,7 @@ get_tty_terminal (Lisp_Object terminal, int throw) This function ignores suspended devices. Returns NULL if the named terminal device is not opened. */ - + struct terminal * get_named_tty (name) char *name; @@ -2144,7 +2289,7 @@ get_named_tty (name) for (t = terminal_list; t; t = t->next_terminal) { - if (t->type == output_termcap + if ((t->type == output_termcap || t->type == output_msdos_raw) && !strcmp (t->display_info.tty->name, name) && TERMINAL_ACTIVE_P (t)) return t; @@ -2158,14 +2303,14 @@ DEFUN ("tty-type", Ftty_type, Stty_type, 0, 1, 0, doc: /* Return the type of the tty device that TERMINAL uses. Returns nil if TERMINAL is not on a tty device. -TERMINAL can be a terminal id, a frame or nil (meaning the selected -frame's terminal). */) +TERMINAL can be a terminal object, a frame, or nil (meaning the +selected frame's terminal). */) (terminal) Lisp_Object terminal; { struct terminal *t = get_terminal (terminal, 1); - if (t->type != output_termcap) + if (t->type != output_termcap && t->type != output_msdos_raw) return Qnil; if (t->display_info.tty->type) @@ -2175,17 +2320,18 @@ frame's terminal). */) } DEFUN ("controlling-tty-p", Fcontrolling_tty_p, Scontrolling_tty_p, 0, 1, 0, - doc: /* Return non-nil if TERMINAL is on the controlling tty of the Emacs process. + doc: /* Return non-nil if TERMINAL is the controlling tty of the Emacs process. -TERMINAL can be a terminal id, a frame or nil (meaning the selected -frame's terminal). This function always returns nil if TERMINAL -is not on a tty device. */) +TERMINAL can be a terminal object, a frame, or nil (meaning the +selected frame's terminal). This function always returns nil if +TERMINAL is not on a tty device. */) (terminal) Lisp_Object terminal; { struct terminal *t = get_terminal (terminal, 1); - if (t->type != output_termcap || strcmp (t->display_info.tty->name, DEV_TTY)) + if ((t->type != output_termcap && t->type != output_msdos_raw) + || strcmp (t->display_info.tty->name, DEV_TTY) != 0) return Qnil; else return Qt; @@ -2197,9 +2343,9 @@ This is used to override the terminfo data, for certain terminals that do not really do underlining, but say that they do. This function has no effect if used on a non-tty terminal. -TERMINAL can be a terminal id, a frame or nil (meaning the selected -frame's terminal). This function always returns nil if TERMINAL -is not on a tty device. */) +TERMINAL can be a terminal object, a frame or nil (meaning the +selected frame's terminal). This function always returns nil if +TERMINAL does not refer to a text-only terminal. */) (terminal) Lisp_Object terminal; { @@ -2220,8 +2366,8 @@ access to the tty device. Frames that use the device are not deleted, but input is not read from them and if they change, their display is not updated. -TTY may be a terminal id, a frame, or nil for the terminal device of -the currently selected frame. +TTY may be a terminal object, a frame, or nil for the terminal device +of the currently selected frame. This function runs `suspend-tty-functions' after suspending the device. The functions are run with one arg, the id of the suspended @@ -2236,12 +2382,12 @@ A suspended tty may be resumed by calling `resume-tty' on it. */) { struct terminal *t = get_tty_terminal (tty, 1); FILE *f; - + if (!t) error ("Unknown tty device"); f = t->display_info.tty->input; - + if (f) { /* First run `suspend-tty-functions' and then clean up the tty @@ -2257,18 +2403,22 @@ A suspended tty may be resumed by calling `resume-tty' on it. */) reset_sys_modes (t->display_info.tty); +#ifdef subprocesses delete_keyboard_wait_descriptor (fileno (f)); - +#endif + +#ifndef MSDOS fclose (f); if (f != t->display_info.tty->output) fclose (t->display_info.tty->output); - +#endif + t->display_info.tty->input = 0; t->display_info.tty->output = 0; if (FRAMEP (t->display_info.tty->top_frame)) FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 0); - + } /* Clear display hooks to prevent further output. */ @@ -2292,8 +2442,8 @@ device. `resume-tty' does nothing if it is called on a device that is not suspended. -TTY may be a terminal id, a frame, or nil for the terminal device of -the currently selected frame. */) +TTY may be a terminal object, a frame, or nil (meaning the selected +frame's terminal). */) (tty) Lisp_Object tty; { @@ -2308,6 +2458,10 @@ the currently selected frame. */) if (get_named_tty (t->display_info.tty->name)) error ("Cannot resume display while another display is active on the same device"); +#ifdef MSDOS + t->display_info.tty->output = stdout; + t->display_info.tty->input = stdin; +#else /* !MSDOS */ fd = emacs_open (t->display_info.tty->name, O_RDWR | O_NOCTTY, 0); if (fd == -1) @@ -2318,11 +2472,26 @@ the currently selected frame. */) t->display_info.tty->output = fdopen (fd, "w+"); t->display_info.tty->input = t->display_info.tty->output; +#endif +#ifdef subprocesses add_keyboard_wait_descriptor (fd); +#endif if (FRAMEP (t->display_info.tty->top_frame)) - FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1); + { + struct frame *f = XFRAME (t->display_info.tty->top_frame); + int width, height; + int old_height = FRAME_COLS (f); + int old_width = FRAME_LINES (f); + + /* Check if terminal/window size has changed while the frame + was suspended. */ + get_tty_size (fileno (t->display_info.tty->input), &width, &height); + if (width != old_width || height != old_height) + change_frame_size (f, height, width, 0, 0, 0); + FRAME_SET_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1); + } init_sys_modes (t->display_info.tty); @@ -2381,7 +2550,7 @@ term_show_mouse_face (enum draw_glyphs_face draw) /* write_glyphs writes at cursor position, so we need to temporarily move cursor coordinates to the beginning of the highlight region. */ - + /* Save current cursor co-ordinates */ save_y = curY (tty); save_x = curX (tty); @@ -2425,7 +2594,7 @@ term_show_mouse_face (enum draw_glyphs_face draw) pos_y = row->y + WINDOW_TOP_EDGE_Y (w); pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w); - + cursor_to (f, pos_y, pos_x); if (draw == DRAW_MOUSE_FACE) @@ -2664,7 +2833,7 @@ term_mouse_highlight (struct frame *f, int x, int y) /* Find the range of text around this char that should be active. */ Lisp_Object before, after; - int ignore; + EMACS_INT ignore; before = Foverlay_start (overlay); @@ -2682,7 +2851,7 @@ term_mouse_highlight (struct frame *f, int x, int y) mouse_face_face_id = face_at_buffer_position (w, pos, 0, 0, - &ignore, pos + 1, 1); + &ignore, pos + 1, 1, -1); /* Display it as active. */ term_show_mouse_face (DRAW_MOUSE_FACE); @@ -2693,7 +2862,7 @@ term_mouse_highlight (struct frame *f, int x, int y) /* Find the range of text around this char that should be active. */ Lisp_Object before, after, beginning, end; - int ignore; + EMACS_INT ignore; beginning = Fmarker_position (w->start); XSETINT (end, (BUF_Z (b) - XFASTINT (w->window_end_pos))); @@ -2717,7 +2886,7 @@ term_mouse_highlight (struct frame *f, int x, int y) mouse_face_face_id = face_at_buffer_position (w, pos, 0, 0, - &ignore, pos + 1, 1); + &ignore, pos + 1, 1, -1); /* Display it as active. */ term_show_mouse_face (DRAW_MOUSE_FACE); @@ -2849,10 +3018,10 @@ term_mouse_click (struct input_event *result, Gpm_Event *event, result->modifiers = down_modifier; else result->modifiers = 0; - + if (event->type & GPM_SINGLE) result->modifiers |= click_modifier; - + if (event->type & GPM_DOUBLE) result->modifiers |= double_modifier; @@ -2885,7 +3054,7 @@ term_mouse_click (struct input_event *result, Gpm_Event *event, return Qnil; } -int +int handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event, struct input_event* hold_quit) { struct frame *f = XFRAME (tty->top_frame); @@ -2984,6 +3153,15 @@ Gpm-mouse can only be activated for one tty at a time. */) } } +void +close_gpm (int fd) +{ + if (fd >= 0) + delete_gpm_wait_descriptor (fd); + while (Gpm_Close()); /* close all the stack */ + gpm_tty = NULL; +} + DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop, Sgpm_mouse_stop, 0, 0, 0, doc: /* Close a connection to Gpm. */) @@ -2996,11 +3174,8 @@ DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop, Sgpm_mouse_stop, if (!tty || gpm_tty != tty) return Qnil; /* Not activated on this terminal, nothing to do. */ - - if (gpm_fd >= 0) - delete_gpm_wait_descriptor (gpm_fd); - while (Gpm_Close()); /* close all the stack */ - gpm_tty = NULL; + + close_gpm (gpm_fd); return Qnil; } #endif /* HAVE_GPM */ @@ -3029,14 +3204,17 @@ create_tty_output (struct frame *f) f->output_data.tty = t; } -/* Delete the tty-dependent part of frame F. */ +/* Delete frame F's face cache, and its tty-dependent part. */ static void -delete_tty_output (struct frame *f) +tty_free_frame_resources (struct frame *f) { if (! FRAME_TERMCAP_P (f)) abort (); + if (FRAME_FACE_CACHE (f)) + free_frame_faces (f); + xfree (f->output_data.tty); } @@ -3075,7 +3253,7 @@ clear_tty_hooks (struct terminal *terminal) /* Leave these two set, or suspended frames are not deleted correctly. */ - terminal->delete_frame_hook = &delete_tty_output; + terminal->delete_frame_hook = &tty_free_frame_resources; terminal->delete_terminal_hook = &delete_tty; } @@ -3100,7 +3278,7 @@ set_tty_hooks (struct terminal *terminal) terminal->delete_glyphs_hook = &tty_delete_glyphs; terminal->ring_bell_hook = &tty_ring_bell; - + terminal->reset_terminal_modes_hook = &tty_reset_terminal_modes; terminal->set_terminal_modes_hook = &tty_set_terminal_modes; terminal->update_begin_hook = 0; /* Not needed. */ @@ -3118,8 +3296,8 @@ set_tty_hooks (struct terminal *terminal) terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */ terminal->frame_up_to_date_hook = 0; /* Not needed. */ - - terminal->delete_frame_hook = &delete_tty_output; + + terminal->delete_frame_hook = &tty_free_frame_resources; terminal->delete_terminal_hook = &delete_tty; } @@ -3127,7 +3305,7 @@ set_tty_hooks (struct terminal *terminal) static void dissociate_if_controlling_tty (int fd) { -#ifndef WINDOWSNT +#ifndef DOS_NT int pgid; EMACS_GET_TTY_PGRP (fd, &pgid); /* If tcgetpgrp succeeds, fd is the ctty. */ if (pgid != -1) @@ -3155,7 +3333,7 @@ dissociate_if_controlling_tty (int fd) #endif /* ! TIOCNOTTY */ #endif /* ! USG */ } -#endif /* !WINDOWSNT */ +#endif /* !DOS_NT */ } static void maybe_fatal(); @@ -3176,7 +3354,6 @@ init_tty (char *name, char *terminal_type, int must_succeed) { char *area = NULL; char **address = &area; - char *buffer = NULL; int buffer_size = 4096; register char *p = NULL; int status; @@ -3185,7 +3362,7 @@ init_tty (char *name, char *terminal_type, int must_succeed) int ctty = 0; /* 1 if asked to open controlling tty. */ if (!terminal_type) - maybe_fatal (must_succeed, 0, 0, + maybe_fatal (must_succeed, 0, "Unknown terminal type", "Unknown terminal type"); @@ -3204,7 +3381,15 @@ init_tty (char *name, char *terminal_type, int must_succeed) return terminal; terminal = create_terminal (); +#ifdef MSDOS + if (been_here > 0) + maybe_fatal (1, 0, "Attempt to create another terminal %s", "", + name, ""); + been_here = 1; + tty = &the_only_display_info; +#else tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info)); +#endif bzero (tty, sizeof (struct tty_display_info)); tty->next = tty_list; tty_list = tty; @@ -3216,7 +3401,7 @@ init_tty (char *name, char *terminal_type, int must_succeed) tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm)); Wcm_clear (tty); -#ifndef WINDOWSNT +#ifndef DOS_NT set_tty_hooks (terminal); { @@ -3238,15 +3423,18 @@ init_tty (char *name, char *terminal_type, int must_succeed) fd = emacs_open (name, O_RDWR | O_NOCTTY, 0); #endif /* O_IGNORE_CTTY */ + tty->name = xstrdup (name); + terminal->name = xstrdup (name); + if (fd < 0) - maybe_fatal (must_succeed, buffer, terminal, + maybe_fatal (must_succeed, terminal, "Could not open file: %s", "Could not open file: %s", name); if (!isatty (fd)) { close (fd); - maybe_fatal (must_succeed, buffer, terminal, + maybe_fatal (must_succeed, terminal, "Not a tty device: %s", "Not a tty device: %s", name); @@ -3258,41 +3446,51 @@ init_tty (char *name, char *terminal_type, int must_succeed) #endif file = fdopen (fd, "w+"); - tty->name = xstrdup (name); - terminal->name = xstrdup (name); tty->input = file; tty->output = file; } tty->type = xstrdup (terminal_type); +#ifdef subprocesses add_keyboard_wait_descriptor (fileno (tty->input)); - #endif - encode_terminal_bufsize = 0; +#endif /* !DOS_NT */ + + encode_terminal_src_size = 0; + encode_terminal_dst_size = 0; #ifdef HAVE_GPM terminal->mouse_position_hook = term_mouse_position; mouse_face_window = Qnil; #endif +#ifdef DOS_NT #ifdef WINDOWSNT initialize_w32_display (terminal); +#else /* MSDOS */ + if (strcmp (terminal_type, "internal") == 0) + terminal->type = output_msdos_raw; + initialize_msdos_display (terminal); +#endif /* MSDOS */ + tty->output = stdout; + tty->input = stdin; /* The following two are inaccessible from w32console.c. */ - terminal->delete_frame_hook = &delete_tty_output; + terminal->delete_frame_hook = &tty_free_frame_resources; terminal->delete_terminal_hook = &delete_tty; tty->name = xstrdup (name); terminal->name = xstrdup (name); tty->type = xstrdup (terminal_type); - tty->output = stdout; - tty->input = stdin; +#ifdef subprocesses add_keyboard_wait_descriptor (0); +#endif Wcm_clear (tty); +#ifdef WINDOWSNT { struct frame *f = XFRAME (selected_frame); @@ -3303,6 +3501,14 @@ init_tty (char *name, char *terminal_type, int must_succeed) FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; } +#else /* MSDOS */ + { + int height, width; + get_tty_size (fileno (tty->input), &width, &height); + FrameCols (tty) = width; + FrameRows (tty) = height; + } +#endif /* MSDOS */ tty->delete_in_insert_mode = 1; UseTabs (tty) = 0; @@ -3312,32 +3518,36 @@ init_tty (char *name, char *terminal_type, int must_succeed) display. In doing a trace, it didn't seem to be called much, so I don't think we're losing anything by turning it off. */ terminal->line_ins_del_ok = 0; +#ifdef WINDOWSNT terminal->char_ins_del_ok = 1; - baud_rate = 19200; +#else /* MSDOS */ + terminal->char_ins_del_ok = 0; + init_baud_rate (fileno (tty->input)); +#endif /* MSDOS */ tty->TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */ -#else /* not WINDOWSNT */ +#else /* not DOS_NT */ Wcm_clear (tty); - buffer = (char *) xmalloc (buffer_size); + tty->termcap_term_buffer = (char *) xmalloc (buffer_size); /* On some systems, tgetent tries to access the controlling terminal. */ sigblock (sigmask (SIGTTOU)); - status = tgetent (buffer, terminal_type); + status = tgetent (tty->termcap_term_buffer, terminal_type); sigunblock (sigmask (SIGTTOU)); if (status < 0) { #ifdef TERMINFO - maybe_fatal (must_succeed, buffer, terminal, + maybe_fatal (must_succeed, terminal, "Cannot open terminfo database file", "Cannot open terminfo database file"); #else - maybe_fatal (must_succeed, buffer, terminal, + maybe_fatal (must_succeed, terminal, "Cannot open termcap database file", "Cannot open termcap database file"); #endif @@ -3345,7 +3555,7 @@ init_tty (char *name, char *terminal_type, int must_succeed) if (status == 0) { #ifdef TERMINFO - maybe_fatal (must_succeed, buffer, terminal, + maybe_fatal (must_succeed, terminal, "Terminal type %s is not defined", "Terminal type %s is not defined.\n\ If that is not the actual type of terminal you have,\n\ @@ -3354,7 +3564,7 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.", terminal_type); #else - maybe_fatal (must_succeed, buffer, terminal, + maybe_fatal (must_succeed, terminal, "Terminal type %s is not defined", "Terminal type %s is not defined.\n\ If that is not the actual type of terminal you have,\n\ @@ -3366,12 +3576,11 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", } #ifndef TERMINFO - if (strlen (buffer) >= buffer_size) + if (strlen (tty->termcap_term_buffer) >= buffer_size) abort (); - buffer_size = strlen (buffer); + buffer_size = strlen (tty->termcap_term_buffer); #endif - area = (char *) xmalloc (buffer_size); - + tty->termcap_strings_buffer = area = (char *) xmalloc (buffer_size); tty->TS_ins_line = tgetstr ("al", address); tty->TS_ins_multi_lines = tgetstr ("AL", address); tty->TS_bell = tgetstr ("bl", address); @@ -3404,12 +3613,6 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", Down (tty) = tgetstr ("do", address); if (!Down (tty)) Down (tty) = tgetstr ("nl", address); /* Obsolete name for "do" */ -#ifdef VMS - /* VMS puts a carriage return before each linefeed, - so it is not safe to use linefeeds. */ - if (Down (tty) && Down (tty)[0] == '\n' && Down (tty)[1] == '\0') - Down (tty) = 0; -#endif /* VMS */ if (tgetflag ("bs")) Left (tty) = "\b"; /* can't possibly be longer! */ else /* (Actually, "bs" is obsolete...) */ @@ -3485,8 +3688,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", tty->TF_underscore = tgetflag ("ul"); tty->TF_teleray = tgetflag ("xt"); -#endif /* !WINDOWSNT */ -#ifdef MULTI_KBOARD +#endif /* !DOS_NT */ terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD)); init_kboard (terminal->kboard); terminal->kboard->Vwindow_system = Qnil; @@ -3498,12 +3700,9 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", prompt in the mini-buffer. */ if (current_kboard == initial_kboard) current_kboard = terminal->kboard; -#ifndef WINDOWSNT +#ifndef DOS_NT term_get_fkeys (address, terminal->kboard); -#endif -#endif -#ifndef WINDOWSNT /* Get frame size from system, or else from termcap. */ { int height, width; @@ -3518,7 +3717,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", FrameRows (tty) = tgetnum ("li"); if (FrameRows (tty) < 3 || FrameCols (tty) < 3) - maybe_fatal (must_succeed, NULL, terminal, + maybe_fatal (must_succeed, terminal, "Screen size %dx%d is too small" "Screen size %dx%d is too small", FrameCols (tty), FrameRows (tty)); @@ -3529,15 +3728,6 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", TabWidth (tty) = tgetnum ("tw"); -#ifdef VMS - /* These capabilities commonly use ^J. - I don't know why, but sending them on VMS does not work; - it causes following spaces to be lost, sometimes. - For now, the simplest fix is to avoid using these capabilities ever. */ - if (Down (tty) && Down (tty)[0] == '\n') - Down (tty) = 0; -#endif /* VMS */ - if (!tty->TS_bell) tty->TS_bell = "\07"; @@ -3651,15 +3841,8 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", if (Wcm_init (tty) == -1) /* can't do cursor motion */ { - maybe_fatal (must_succeed, NULL, terminal, + maybe_fatal (must_succeed, terminal, "Terminal type \"%s\" is not powerful enough to run Emacs", -#ifdef VMS - "Terminal type \"%s\" is not powerful enough to run Emacs.\n\ -It lacks the ability to position the cursor.\n\ -If that is not the actual type of terminal you have, use either the\n\ -DCL command `SET TERMINAL/DEVICE= ...' for DEC-compatible terminals,\n\ -or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.", -#else /* not VMS */ # ifdef TERMINFO "Terminal type \"%s\" is not powerful enough to run Emacs.\n\ It lacks the ability to position the cursor.\n\ @@ -3675,12 +3858,11 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ `setenv TERM ...') to specify the correct type. It may be necessary\n\ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", # endif /* TERMINFO */ -#endif /*VMS */ terminal_type); } if (FrameRows (tty) <= 0 || FrameCols (tty) <= 0) - maybe_fatal (must_succeed, NULL, terminal, + maybe_fatal (must_succeed, terminal, "Could not determine the frame size", "Could not determine the frame size"); @@ -3713,17 +3895,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", init_baud_rate (fileno (tty->input)); -#ifdef AIXHFT - /* The HFT system on AIX doesn't optimize for scrolling, so it's - really ugly at times. */ - terminal->line_ins_del_ok = 0; - terminal->char_ins_del_ok = 0; -#endif - - /* Don't do this. I think termcap may still need the buffer. */ - /* xfree (buffer); */ - -#endif /* not WINDOWSNT */ +#endif /* not DOS_NT */ /* Init system terminal modes (RAW or CBREAK, etc.). */ init_sys_modes (tty); @@ -3732,22 +3904,18 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", } /* Auxiliary error-handling function for init_tty. - Free BUFFER and delete TERMINAL, then call error or fatal - with str1 or str2, respectively, according to MUST_SUCCEED. */ + Delete TERMINAL, then call error or fatal with str1 or str2, + respectively, according to MUST_SUCCEED. */ static void -maybe_fatal (must_succeed, buffer, terminal, str1, str2, arg1, arg2) +maybe_fatal (must_succeed, terminal, str1, str2, arg1, arg2) int must_succeed; - char *buffer; struct terminal *terminal; char *str1, *str2, *arg1, *arg2; { - if (buffer) - xfree (buffer); - if (terminal) delete_tty (terminal); - + if (must_succeed) fatal (str2, arg1, arg2); else @@ -3778,8 +3946,8 @@ delete_tty (struct terminal *terminal) struct tty_display_info *tty; Lisp_Object tail, frame; int last_terminal; - - /* Protect against recursive calls. Fdelete_frame in + + /* Protect against recursive calls. delete_frame in delete_terminal calls us back when it deletes our last frame. */ if (!terminal->name) return; @@ -3788,7 +3956,7 @@ delete_tty (struct terminal *terminal) abort (); tty = terminal->display_info.tty; - + last_terminal = 1; FOR_EACH_FRAME (tail, frame) { @@ -3801,7 +3969,7 @@ delete_tty (struct terminal *terminal) } if (last_terminal) error ("Attempt to delete the sole terminal device with live frames"); - + if (tty == tty_list) tty_list = tty->next; else @@ -3824,15 +3992,14 @@ delete_tty (struct terminal *terminal) delete_terminal (terminal); - if (tty->name) - xfree (tty->name); - - if (tty->type) - xfree (tty->type); + xfree (tty->name); + xfree (tty->type); if (tty->input) { +#ifdef subprocesses delete_keyboard_wait_descriptor (fileno (tty->input)); +#endif if (tty->input != stdin) fclose (tty->input); } @@ -3841,11 +4008,12 @@ delete_tty (struct terminal *terminal) if (tty->termscript) fclose (tty->termscript); - if (tty->old_tty) - xfree (tty->old_tty); - - if (tty->Wcm) - xfree (tty->Wcm); + xfree (tty->old_tty); + xfree (tty->Wcm); + if (tty->termcap_strings_buffer) + xfree (tty->termcap_strings_buffer); + if (tty->termcap_term_buffer) + xfree (tty->termcap_term_buffer); bzero (tty, sizeof (struct tty_display_info)); xfree (tty); @@ -3881,14 +4049,14 @@ This variable can be used by terminal emulator packages. */); DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions, doc: /* Functions to be run after suspending a tty. -The functions are run with one argument, the terminal id to be suspended. +The functions are run with one argument, the terminal object to be suspended. See `suspend-tty'. */); Vsuspend_tty_functions = Qnil; DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions, doc: /* Functions to be run after resuming a tty. -The functions are run with one argument, the terminal id that was revived. +The functions are run with one argument, the terminal object that was revived. See `resume-tty'. */); Vresume_tty_functions = Qnil; @@ -3912,6 +4080,15 @@ bigger, or it may make it blink, or it may do nothing at all. */); staticpro (&mouse_face_window); #endif /* HAVE_GPM */ + +#ifndef DOS_NT + default_orig_pair = NULL; + default_set_foreground = NULL; + default_set_background = NULL; +#endif /* !DOS_NT */ + + encode_terminal_src = NULL; + encode_terminal_dst = NULL; }