X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/68e7476278a3dc4bd13dab63cc23bc0e671e5525..187bc86f15320f5680552b8bd692a62fb1a4b3ba:/src/term.c diff --git a/src/term.c b/src/term.c index 69936400a1..367040288e 100644 --- a/src/term.c +++ b/src/term.c @@ -5,10 +5,10 @@ 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,100 @@ 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_size == 0) + encode_terminal_src = xmalloc (required); else - encode_terminal_buf = xrealloc (encode_terminal_buf, required); - encode_terminal_bufsize = required; + encode_terminal_src = xrealloc (encode_terminal_src, 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 - 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)) + break; + buf += CHAR_STRING (c, buf); + nchars++; + } + else + for (i = 0; i < cmp->glyph_len; i++) + { + int c = COMPOSITION_GLYPH (cmp, i); + + if (! char_charset (c, charset_list, NULL)) + break; + buf += CHAR_STRING (c, buf); + nchars++; + } + if (i == 0) + { + /* The first character of the composition is not encodable. */ + *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++; + c = src->u.ch; } else { @@ -609,65 +670,90 @@ 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; + encode_terminal_dst = xmalloc (encode_terminal_dst_size); } + 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; - encode_coding (coding, encode_terminal_buf, encode_terminal_buf + nbytes, - nbytes, encode_terminal_bufsize - nbytes); - return encode_terminal_buf + nbytes; + return (encode_terminal_dst); } + /* An implementation of write_glyphs for termcap frames. */ static void @@ -951,7 +1037,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 +1067,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 +1392,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 +1507,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 +1575,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 +1587,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 +1635,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 +1660,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) @@ -1669,6 +1750,79 @@ 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; + } + + 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]; + + c = COMPOSITION_GLYPH (cmp, 0); + it->pixel_width = CHAR_WIDTH (it->c); + } + 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 +1835,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 +1848,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); @@ -1962,7 +2115,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 +2135,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 +2201,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); - - 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; + mode = INTEGERP (color_mode) ? XINT (color_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 +2247,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 +2264,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 +2276,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; @@ -2165,7 +2297,7 @@ frame's 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,7 +2307,7 @@ 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 @@ -2185,7 +2317,8 @@ is not on a tty device. */) { 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; @@ -2236,12 +2369,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 +2390,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. */ @@ -2308,6 +2445,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,8 +2459,11 @@ 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); @@ -2381,7 +2525,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 +2569,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 +2808,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); @@ -2693,7 +2837,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))); @@ -2849,10 +2993,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 +3029,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); @@ -2996,7 +3140,7 @@ 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 */ @@ -3100,7 +3244,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,7 +3262,7 @@ 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_terminal_hook = &delete_tty; } @@ -3127,7 +3271,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 +3299,7 @@ dissociate_if_controlling_tty (int fd) #endif /* ! TIOCNOTTY */ #endif /* ! USG */ } -#endif /* !WINDOWSNT */ +#endif /* !DOS_NT */ } static void maybe_fatal(); @@ -3204,7 +3348,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, 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 +3368,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); { @@ -3266,19 +3418,30 @@ init_tty (char *name, char *terminal_type, int must_succeed) 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_terminal_hook = &delete_tty; @@ -3287,12 +3450,13 @@ init_tty (char *name, char *terminal_type, int must_succeed) 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 +3467,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,13 +3484,17 @@ 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); @@ -3404,12 +3580,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 +3655,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 +3667,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; @@ -3529,15 +3695,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"; @@ -3653,13 +3810,6 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", { maybe_fatal (must_succeed, NULL, 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,7 +3825,6 @@ 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); } @@ -3713,17 +3862,10 @@ 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); @@ -3742,12 +3884,11 @@ maybe_fatal (must_succeed, buffer, terminal, str1, str2, arg1, arg2) struct terminal *terminal; char *str1, *str2, *arg1, *arg2; { - if (buffer) - xfree (buffer); + xfree (buffer); if (terminal) delete_tty (terminal); - + if (must_succeed) fatal (str2, arg1, arg2); else @@ -3778,7 +3919,7 @@ delete_tty (struct terminal *terminal) struct tty_display_info *tty; Lisp_Object tail, frame; int last_terminal; - + /* Protect against recursive calls. Fdelete_frame in delete_terminal calls us back when it deletes our last frame. */ if (!terminal->name) @@ -3788,7 +3929,7 @@ delete_tty (struct terminal *terminal) abort (); tty = terminal->display_info.tty; - + last_terminal = 1; FOR_EACH_FRAME (tail, frame) { @@ -3801,7 +3942,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 +3965,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 +3981,8 @@ 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); bzero (tty, sizeof (struct tty_display_info)); xfree (tty); @@ -3912,6 +4049,12 @@ 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 */ }