diff options
Diffstat (limited to 'src/term.c')
-rw-r--r-- | src/term.c | 1115 |
1 files changed, 437 insertions, 678 deletions
diff --git a/src/term.c b/src/term.c index 78bf77d9d71..4d452ed3e00 100644 --- a/src/term.c +++ b/src/term.c @@ -23,7 +23,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include <config.h> #include <stdio.h> #include <ctype.h> -#include <string.h> #include <errno.h> #include <sys/file.h> @@ -31,10 +30,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include <unistd.h> #endif -#if HAVE_TERMIOS_H -#include <termios.h> /* For TIOCNOTTY. */ -#endif - #include <signal.h> #include <stdarg.h> #include <setjmp.h> @@ -66,15 +61,10 @@ static int been_here = -1; /* For now, don't try to include termcap.h. On some systems, configure finds a non-standard termcap.h that the main build won't find. */ - -#if defined HAVE_TERMCAP_H && 0 -#include <termcap.h> -#else -extern void tputs P_ ((const char *, int, int (*)(int))); -extern int tgetent P_ ((char *, const char *)); -extern int tgetflag P_ ((char *id)); -extern int tgetnum P_ ((char *id)); -#endif +extern void tputs (const char *, int, int (*)(int)); +extern int tgetent (char *, const char *); +extern int tgetflag (char *id); +extern int tgetnum (char *id); #include "cm.h" #ifdef HAVE_X_WINDOWS @@ -96,16 +86,20 @@ extern int tgetnum P_ ((char *id)); #define DEV_TTY "/dev/tty" #endif -static void tty_set_scroll_region P_ ((struct frame *f, int start, int stop)); -static void turn_on_face P_ ((struct frame *, int face_id)); -static void turn_off_face P_ ((struct frame *, int face_id)); -static void tty_show_cursor P_ ((struct tty_display_info *)); -static void tty_hide_cursor P_ ((struct tty_display_info *)); -static void tty_background_highlight P_ ((struct tty_display_info *tty)); -static void clear_tty_hooks P_ ((struct terminal *terminal)); -static void set_tty_hooks P_ ((struct terminal *terminal)); -static void dissociate_if_controlling_tty P_ ((int fd)); -static void delete_tty P_ ((struct terminal *)); +static void tty_set_scroll_region (struct frame *f, int start, int stop); +static void turn_on_face (struct frame *, int face_id); +static void turn_off_face (struct frame *, int face_id); +static void tty_show_cursor (struct tty_display_info *); +static void tty_hide_cursor (struct tty_display_info *); +static void tty_background_highlight (struct tty_display_info *tty); +static void clear_tty_hooks (struct terminal *terminal); +static void set_tty_hooks (struct terminal *terminal); +static void dissociate_if_controlling_tty (int fd); +static void delete_tty (struct terminal *); +static void maybe_fatal (int must_succeed, struct terminal *terminal, + const char *str1, const char *str2, ...) NO_RETURN; +static void vfatal (const char *str, va_list ap) NO_RETURN; + #define OUTPUT(tty, a) \ emacs_tputs ((tty), a, \ @@ -133,8 +127,6 @@ static int visible_cursor; /* Display space properties */ -extern Lisp_Object Qspace, QCalign_to, QCwidth; - /* Functions to call after suspending a tty. */ Lisp_Object Vsuspend_tty_functions; @@ -184,32 +176,18 @@ static int no_controlling_tty; static int system_uses_terminfo; -char *tparam (); +char *tparam (char *, char *, int, int, ...); -extern char *tgetstr (); +extern char *tgetstr (char *, char **); #ifdef HAVE_GPM #include <sys/fcntl.h> -static void term_clear_mouse_face (); -static void term_mouse_highlight (struct frame *f, int x, int y); - /* The device for which we have enabled gpm support (or NULL). */ struct tty_display_info *gpm_tty = NULL; -/* These variables describe the range of text currently shown in its - mouse-face, together with the window they apply to. As long as - the mouse stays within this range, we need not redraw anything on - its account. Rows and columns are glyph matrix positions in - MOUSE_FACE_WINDOW. */ -static int mouse_face_beg_row, mouse_face_beg_col; -static int mouse_face_end_row, mouse_face_end_col; -static int mouse_face_past_end; -static Lisp_Object mouse_face_window; -static int mouse_face_face_id; - -static int pos_x, pos_y; +/* Last recorded mouse coordinates. */ static int last_mouse_x, last_mouse_y; #endif /* HAVE_GPM */ @@ -562,10 +540,7 @@ static int encode_terminal_dst_size; sequence, and return a pointer to that byte sequence. */ unsigned char * -encode_terminal_code (src, src_len, coding) - struct glyph *src; - int src_len; - struct coding_system *coding; +encode_terminal_code (struct glyph *src, int src_len, struct coding_system *coding) { struct glyph *src_end = src + src_len; unsigned char *buf; @@ -604,7 +579,7 @@ encode_terminal_code (src, src_len, coding) if (src->u.cmp.automatic) { gstring = composition_gstring_from_id (src->u.cmp.id); - required = src->u.cmp.to + 1 - src->u.cmp.from; + required = src->slice.cmp.to + 1 - src->slice.cmp.from; } else { @@ -621,7 +596,7 @@ encode_terminal_code (src, src_len, coding) } if (src->u.cmp.automatic) - for (i = src->u.cmp.from; i <= src->u.cmp.to; i++) + for (i = src->slice.cmp.from; i <= src->slice.cmp.to; i++) { Lisp_Object g = LGSTRING_GLYPH (gstring, i); int c = LGLYPH_CHAR (g); @@ -716,7 +691,7 @@ encode_terminal_code (src, src_len, coding) } else { - unsigned char *p = SDATA (string), *pend = p + SBYTES (string); + unsigned char *p = SDATA (string); if (! STRING_MULTIBYTE (string)) string = string_to_multibyte (string); @@ -728,7 +703,7 @@ encode_terminal_code (src, src_len, coding) encode_terminal_src_size); buf = encode_terminal_src + nbytes; } - bcopy (SDATA (string), buf, SBYTES (string)); + memcpy (buf, SDATA (string), SBYTES (string)); buf += SBYTES (string); nchars += SCHARS (string); } @@ -841,10 +816,8 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len) #ifdef HAVE_GPM /* Only used by GPM code. */ static void -tty_write_glyphs_with_face (f, string, len, face_id) - register struct frame *f; - register struct glyph *string; - register int len, face_id; +tty_write_glyphs_with_face (register struct frame *f, register struct glyph *string, + register int len, register int face_id) { unsigned char *conversion_buffer; struct coding_system *coding; @@ -1092,7 +1065,7 @@ tty_ins_del_lines (struct frame *f, int vpos, int n) not counting any line-dependent padding. */ int -string_cost (char *str) +string_cost (const char *str) { cost = 0; if (str) @@ -1104,7 +1077,7 @@ string_cost (char *str) counting any line-dependent padding at one line. */ static int -string_cost_one_line (char *str) +string_cost_one_line (const char *str) { cost = 0; if (str) @@ -1116,7 +1089,7 @@ string_cost_one_line (char *str) in tenths of characters. */ int -per_line_cost (char *str) +per_line_cost (const char *str) { cost = 0; if (str) @@ -1127,7 +1100,6 @@ per_line_cost (char *str) return cost; } -#ifndef old /* char_ins_del_cost[n] is cost of inserting N characters. char_ins_del_cost[-n] is cost of deleting N characters. The length of this vector is based on max_frame_cols. */ @@ -1135,7 +1107,6 @@ per_line_cost (char *str) int *char_ins_del_vector; #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))]) -#endif /* ARGSUSED */ static void @@ -1235,8 +1206,8 @@ calculate_costs (struct frame *frame) = (int *) xmalloc (sizeof (int) + 2 * max_frame_cols * sizeof (int)); - bzero (char_ins_del_vector, (sizeof (int) - + 2 * max_frame_cols * sizeof (int))); + memset (char_ins_del_vector, 0, + (sizeof (int) + 2 * max_frame_cols * sizeof (int))); if (f && (!tty->TS_ins_line && !tty->TS_del_line)) @@ -1273,7 +1244,7 @@ struct fkey_table { other keys (as on the IBM PC keyboard) they get overridden. */ -static struct fkey_table keys[] = +static const struct fkey_table keys[] = { {"kh", "home"}, /* termcap */ {"kl", "left"}, /* termcap */ @@ -1369,18 +1340,17 @@ static struct fkey_table keys[] = {"!3", "S-undo"} /*shifted undo key*/ }; +#ifndef DOS_NT static char **term_get_fkeys_address; static KBOARD *term_get_fkeys_kboard; -static Lisp_Object term_get_fkeys_1 (); +static Lisp_Object term_get_fkeys_1 (void); /* Find the escape codes sent by the function keys for Vinput_decode_map. This function scans the termcap function key sequence entries, and adds entries to Vinput_decode_map for each function key it finds. */ static void -term_get_fkeys (address, kboard) - char **address; - KBOARD *kboard; +term_get_fkeys (char **address, KBOARD *kboard) { /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp errors during the call. The only errors should be from Fdefine_key @@ -1390,14 +1360,13 @@ term_get_fkeys (address, kboard) function key specification, rather than giving the user an error and refusing to run at all on such a terminal. */ - extern Lisp_Object Fidentity (); term_get_fkeys_address = address; term_get_fkeys_kboard = kboard; internal_condition_case (term_get_fkeys_1, Qerror, Fidentity); } static Lisp_Object -term_get_fkeys_1 () +term_get_fkeys_1 (void) { int i; @@ -1508,24 +1477,18 @@ term_get_fkeys_1 () return Qnil; } +#endif /* not DOS_NT */ /*********************************************************************** Character Display Information ***********************************************************************/ - -/* Avoid name clash with functions defined in xterm.c */ -#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 *)); +static void append_glyph (struct it *); +static void produce_stretch_glyph (struct it *); +static void append_composite_glyph (struct it *); +static void produce_composite_glyph (struct it *); +static void append_glyphless_glyph (struct it *, int, char *); +static void produce_glyphless_glyph (struct it *, int, Lisp_Object); /* Append glyphs to IT's glyph_row. Called from produce_glyphs for terminal frames if IT->glyph_row != NULL. IT->char_to_display is @@ -1534,8 +1497,7 @@ static void produce_composite_glyph P_ ((struct it *)); IT->pixel_width > 1. */ static void -append_glyph (it) - struct it *it; +append_glyph (struct it *it) { struct glyph *glyph, *end; int i; @@ -1545,6 +1507,26 @@ append_glyph (it) + it->glyph_row->used[it->area]); end = it->glyph_row->glyphs[1 + it->area]; + /* If the glyph row is reversed, we need to prepend the glyph rather + than append it. */ + if (it->glyph_row->reversed_p && it->area == TEXT_AREA) + { + struct glyph *g; + int move_by = it->pixel_width; + + /* Make room for the new glyphs. */ + if (move_by > end - glyph) /* don't overstep end of this area */ + move_by = end - glyph; + for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--) + g[move_by] = *g; + glyph = it->glyph_row->glyphs[it->area]; + end = glyph + move_by; + } + + /* BIDI Note: we put the glyphs of a "multi-pixel" character left to + right, even in the REVERSED_P case, since (a) all of its u.ch are + identical, and (b) the PADDING_P flag needs to be set for the + leftmost one, because we write to the terminal left-to-right. */ for (i = 0; i < it->pixel_width && glyph < end; ++i) @@ -1556,13 +1538,24 @@ append_glyph (it) glyph->padding_p = i > 0; glyph->charpos = CHARPOS (it->position); glyph->object = it->object; + if (it->bidi_p) + { + glyph->resolved_level = it->bidi_it.resolved_level; + if ((it->bidi_it.type & 7) != it->bidi_it.type) + abort (); + glyph->bidi_type = it->bidi_it.type; + } + else + { + glyph->resolved_level = 0; + glyph->bidi_type = UNKNOWN_BT; + } ++it->glyph_row->used[it->area]; ++glyph; } } - /* Produce glyphs for the display element described by IT. *IT specifies what we want to produce a glyph for (character, image, ...), and where in the glyph matrix we currently are (glyph row and hpos). @@ -1583,8 +1576,7 @@ append_glyph (it) instead they use the macro PRODUCE_GLYPHS. */ void -produce_glyphs (it) - struct it *it; +produce_glyphs (struct it *it) { /* If a hook is installed, let it do the work. */ @@ -1605,6 +1597,12 @@ produce_glyphs (it) goto done; } + if (it->what == IT_GLYPHLESS) + { + produce_glyphless_glyph (it, 0, Qnil); + goto done; + } + if (it->char_to_display >= 040 && it->char_to_display < 0177) { it->pixel_width = it->nglyphs = 1; @@ -1656,11 +1654,22 @@ produce_glyphs (it) } else { - it->pixel_width = CHAR_WIDTH (it->char_to_display); - it->nglyphs = it->pixel_width; + Lisp_Object charset_list = FRAME_TERMINAL (it->f)->charset_list; - if (it->glyph_row) - append_glyph (it); + if (char_charset (it->char_to_display, charset_list, NULL)) + { + it->pixel_width = CHAR_WIDTH (it->char_to_display); + it->nglyphs = it->pixel_width; + if (it->glyph_row) + append_glyph (it); + } + else + { + Lisp_Object acronym = lookup_glyphless_char_display (-1, it); + + xassert (it->what == IT_GLYPHLESS); + produce_glyphless_glyph (it, 1, acronym); + } } done: @@ -1686,8 +1695,7 @@ produce_glyphs (it) to reach HPOS, a value in canonical character units. */ static void -produce_stretch_glyph (it) - struct it *it; +produce_stretch_glyph (struct it *it) { /* (space :width WIDTH ...) */ Lisp_Object prop, plist; @@ -1756,8 +1764,7 @@ produce_stretch_glyph (it) face. */ static void -append_composite_glyph (it) - struct it *it; +append_composite_glyph (struct it *it) { struct glyph *glyph; @@ -1765,6 +1772,17 @@ append_composite_glyph (it) glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area]; if (glyph < it->glyph_row->glyphs[1 + it->area]) { + /* If the glyph row is reversed, we need to prepend the glyph + rather than append it. */ + if (it->glyph_row->reversed_p && it->area == TEXT_AREA) + { + struct glyph *g; + + /* Make room for the new glyph. */ + for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--) + g[1] = *g; + glyph = it->glyph_row->glyphs[it->area]; + } glyph->type = COMPOSITE_GLYPH; glyph->pixel_width = it->pixel_width; glyph->u.cmp.id = it->cmp_it.id; @@ -1777,14 +1795,26 @@ append_composite_glyph (it) { 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->slice.cmp.from = it->cmp_it.from; + glyph->slice.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; + if (it->bidi_p) + { + glyph->resolved_level = it->bidi_it.resolved_level; + if ((it->bidi_it.type & 7) != it->bidi_it.type) + abort (); + glyph->bidi_type = it->bidi_it.type; + } + else + { + glyph->resolved_level = 0; + glyph->bidi_type = UNKNOWN_BT; + } ++it->glyph_row->used[it->area]; ++glyph; @@ -1798,11 +1828,8 @@ append_composite_glyph (it) correctly. */ static void -produce_composite_glyph (it) - struct it *it; +produce_composite_glyph (struct it *it) { - int c; - if (it->cmp_it.ch < 0) { struct composition *cmp = composition_table[it->cmp_it.id]; @@ -1822,6 +1849,159 @@ produce_composite_glyph (it) } +/* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID + is a face ID to be used for the glyph. What is actually appended + are glyphs of type CHAR_GLYPH whose characters are in STR (which + comes from it->nglyphs bytes). */ + +static void +append_glyphless_glyph (struct it *it, int face_id, char *str) +{ + struct glyph *glyph, *end; + int i; + + xassert (it->glyph_row); + glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area]; + end = it->glyph_row->glyphs[1 + it->area]; + + /* If the glyph row is reversed, we need to prepend the glyph rather + than append it. */ + if (it->glyph_row->reversed_p && it->area == TEXT_AREA) + { + struct glyph *g; + int move_by = it->pixel_width; + + /* Make room for the new glyphs. */ + if (move_by > end - glyph) /* don't overstep end of this area */ + move_by = end - glyph; + for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--) + g[move_by] = *g; + glyph = it->glyph_row->glyphs[it->area]; + end = glyph + move_by; + } + + if (glyph >= end) + return; + glyph->type = CHAR_GLYPH; + glyph->pixel_width = 1; + glyph->face_id = face_id; + glyph->padding_p = 0; + glyph->charpos = CHARPOS (it->position); + glyph->object = it->object; + if (it->bidi_p) + { + glyph->resolved_level = it->bidi_it.resolved_level; + if ((it->bidi_it.type & 7) != it->bidi_it.type) + abort (); + glyph->bidi_type = it->bidi_it.type; + } + else + { + glyph->resolved_level = 0; + glyph->bidi_type = UNKNOWN_BT; + } + + /* BIDI Note: we put the glyphs of characters left to right, even in + the REVERSED_P case because we write to the terminal + left-to-right. */ + for (i = 0; i < it->nglyphs && glyph < end; ++i) + { + if (i > 0) + glyph[0] = glyph[-1]; + glyph->u.ch = str[i]; + ++it->glyph_row->used[it->area]; + ++glyph; + } +} + +/* Declared in xdisp.c */ +extern struct frame *last_glyphless_glyph_frame; +extern unsigned last_glyphless_glyph_face_id; +extern int last_glyphless_glyph_merged_face_id; +extern Lisp_Object Qglyphless_char; + +/* Produce glyphs for a glyphless character for iterator IT. + IT->glyphless_method specifies which method to use for displaying + the character. See the description of enum + glyphless_display_method in dispextern.h for the details. + + FOR_NO_FONT is nonzero if and only if this is for a character that + is not supproted by the coding system of the terminal. ACRONYM, if + non-nil, is an acronym string for the character. + + The glyphs actually produced are of type CHAR_GLYPH. */ + +static void +produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym) +{ + int face_id; + int len; + char buf[11], *str = " "; + + /* Get a face ID for the glyph by utilizing a cache (the same way as + done for `escape-glyph' in get_next_display_element). */ + if (it->f == last_glyphless_glyph_frame + && it->face_id == last_glyphless_glyph_face_id) + { + face_id = last_glyphless_glyph_merged_face_id; + } + else + { + /* Merge the `glyphless-char' face into the current face. */ + face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id); + last_glyphless_glyph_frame = it->f; + last_glyphless_glyph_face_id = it->face_id; + last_glyphless_glyph_merged_face_id = face_id; + } + + if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE) + { + /* As there's no way to produce a thin space, we produce a space + of canonical width. */ + len = 1; + } + else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX) + { + len = CHAR_WIDTH (it->c); + if (len == 0) + len = 1; + else if (len > 4) + len = 4; + sprintf (buf, "[%.*s]", len, str); + len += 2; + str = buf; + } + else + { + if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM) + { + if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display)) + acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c); + buf[0] = '['; + str = STRINGP (acronym) ? (char *) SDATA (acronym) : ""; + for (len = 0; len < 6 && str[len] && ASCII_BYTE_P (str[len]); len++) + buf[1 + len] = str[len]; + buf[1 + len] = ']'; + len += 2; + } + else + { + xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE); + len = (it->c < 0x100 ? sprintf (buf, "[U+%02X]", it->c) + : it->c < 0x10000 ? sprintf (buf, "[U+%04X]", it->c) + : it->c <= MAX_UNICODE_CHAR ? sprintf (buf, "[U+%06X]", it->c) + : sprintf (buf, "[E+%06X]", it->c)); + } + str = buf; + } + + it->pixel_width = len; + it->nglyphs = len; + if (len > 0 && it->glyph_row) + append_glyphless_glyph (it, face_id, str); +} + + /* 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 @@ -1829,9 +2009,7 @@ produce_composite_glyph (it) face_id, c, len of IT are left untouched. */ void -produce_special_glyphs (it, what) - struct it *it; - enum display_element_type what; +produce_special_glyphs (struct it *it, enum display_element_type what) { struct it temp_it; Lisp_Object gc; @@ -1842,16 +2020,20 @@ produce_special_glyphs (it, what) temp_it.what = IT_CHARACTER; temp_it.len = 1; temp_it.object = make_number (0); - bzero (&temp_it.current, sizeof temp_it.current); + memset (&temp_it.current, 0, sizeof temp_it.current); if (what == IT_CONTINUATION) { - /* Continuation glyph. */ - SET_GLYPH_FROM_CHAR (glyph, '\\'); + /* Continuation glyph. For R2L lines, we mirror it by hand. */ + if (it->bidi_it.paragraph_dir == R2L) + SET_GLYPH_FROM_CHAR (glyph, '/'); + else + SET_GLYPH_FROM_CHAR (glyph, '\\'); if (it->dp && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)) && GLYPH_CODE_CHAR_VALID_P (gc)) { + /* FIXME: Should we mirror GC for R2L lines? */ SET_GLYPH_FROM_GLYPH_CODE (glyph, gc); spec_glyph_lookup_face (XWINDOW (it->window), &glyph); } @@ -1864,6 +2046,7 @@ produce_special_glyphs (it, what) && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)) && GLYPH_CODE_CHAR_VALID_P (gc)) { + /* FIXME: Should we mirror GC for R2L lines? */ SET_GLYPH_FROM_GLYPH_CODE (glyph, gc); spec_glyph_lookup_face (XWINDOW (it->window), &glyph); } @@ -1900,9 +2083,7 @@ produce_special_glyphs (it, what) FACE_ID is a realized face ID number, in the face cache. */ static void -turn_on_face (f, face_id) - struct frame *f; - int face_id; +turn_on_face (struct frame *f, int face_id) { struct face *face = FACE_FROM_ID (f, face_id); long fg = face->foreground; @@ -1999,9 +2180,7 @@ turn_on_face (f, face_id) /* Turn off appearances of face FACE_ID on tty frame F. */ static void -turn_off_face (f, face_id) - struct frame *f; - int face_id; +turn_off_face (struct frame *f, int face_id) { struct face *face = FACE_FROM_ID (f, face_id); struct tty_display_info *tty = FRAME_TTY (f); @@ -2054,10 +2233,8 @@ turn_off_face (f, face_id) colors FG and BG. */ int -tty_capable_p (tty, caps, fg, bg) - struct tty_display_info *tty; - unsigned caps; - unsigned long fg, bg; +tty_capable_p (struct tty_display_info *tty, unsigned int caps, + unsigned long fg, unsigned long bg) { #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit) \ if ((caps & (cap)) && (!(TS) || !MAY_USE_WITH_COLORS_P(tty, NC_bit))) \ @@ -2083,8 +2260,7 @@ DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p, 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; + (Lisp_Object terminal) { struct terminal *t = get_tty_terminal (terminal, 0); if (!t) @@ -2101,8 +2277,7 @@ DEFUN ("tty-display-color-cells", Ftty_display_color_cells, 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; + (Lisp_Object terminal) { struct terminal *t = get_tty_terminal (terminal, 0); if (!t) @@ -2197,14 +2372,11 @@ tty_setup_colors (struct tty_display_info *tty, int mode) } void -set_tty_color_mode (tty, f) - struct tty_display_info *tty; - struct frame *f; +set_tty_color_mode (struct tty_display_info *tty, struct frame *f) { - Lisp_Object tem, val, color_mode_spec; + Lisp_Object tem, val; Lisp_Object color_mode; int mode; - extern Lisp_Object Qtty_color_mode; Lisp_Object tty_color_mode_alist = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil); @@ -2213,12 +2385,13 @@ set_tty_color_mode (tty, f) if (INTEGERP (val)) color_mode = val; - else + else if (SYMBOLP (tty_color_mode_alist)) { - tem = (NILP (tty_color_mode_alist) ? Qnil - : Fassq (val, XSYMBOL (tty_color_mode_alist)->value)); + tem = Fassq (val, Fsymbol_value (tty_color_mode_alist)); color_mode = CONSP (tem) ? XCDR (tem) : Qnil; } + else + color_mode = Qnil; mode = INTEGERP (color_mode) ? XINT (color_mode) : 0; @@ -2262,8 +2435,7 @@ get_tty_terminal (Lisp_Object terminal, int throw) Returns NULL if the named terminal device is not opened. */ struct terminal * -get_named_tty (name) - char *name; +get_named_tty (const char *name) { struct terminal *t; @@ -2288,8 +2460,7 @@ 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). */) - (terminal) - Lisp_Object terminal; + (Lisp_Object terminal) { struct terminal *t = get_terminal (terminal, 1); @@ -2308,8 +2479,7 @@ DEFUN ("controlling-tty-p", Fcontrolling_tty_p, Scontrolling_tty_p, 0, 1, 0, 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; + (Lisp_Object terminal) { struct terminal *t = get_terminal (terminal, 1); @@ -2329,8 +2499,7 @@ no effect if used on a non-tty terminal. 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; + (Lisp_Object terminal) { struct terminal *t = get_terminal (terminal, 1); @@ -2360,8 +2529,7 @@ terminal device. suspended. A suspended tty may be resumed by calling `resume-tty' on it. */) - (tty) - Lisp_Object tty; + (Lisp_Object tty) { struct terminal *t = get_tty_terminal (tty, 1); FILE *f; @@ -2385,10 +2553,7 @@ 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); @@ -2427,8 +2592,7 @@ suspended. TTY may be a terminal object, a frame, or nil (meaning the selected frame's terminal). */) - (tty) - Lisp_Object tty; + (Lisp_Object tty) { struct terminal *t = get_tty_terminal (tty, 1); int fd; @@ -2457,9 +2621,7 @@ frame's terminal). */) 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)) { @@ -2513,415 +2675,36 @@ term_mouse_moveto (int x, int y) last_mouse_y = y; */ } -static void -term_show_mouse_face (enum draw_glyphs_face draw) +/* Implementation of draw_row_with_mouse_face for TTY/GPM. */ +void +tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row, + int start_hpos, int end_hpos, + enum draw_glyphs_face draw) { - struct window *w = XWINDOW (mouse_face_window); - int save_x, save_y; - int i; - - struct frame *f = XFRAME (w->frame); + int nglyphs = end_hpos - start_hpos; + struct frame *f = XFRAME (WINDOW_FRAME (w)); struct tty_display_info *tty = FRAME_TTY (f); + int face_id = tty->mouse_highlight.mouse_face_face_id; + int save_x, save_y, pos_x, pos_y; - if (/* If window is in the process of being destroyed, don't bother - to do anything. */ - w->current_matrix != NULL - /* Recognize when we are called to operate on rows that don't exist - anymore. This can happen when a window is split. */ - && mouse_face_end_row < w->current_matrix->nrows) - { - /* 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); - - /* Note that mouse_face_beg_row etc. are window relative. */ - for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++) - { - int start_hpos, end_hpos, nglyphs; - struct glyph_row *row = MATRIX_ROW (w->current_matrix, i); - - /* Don't do anything if row doesn't have valid contents. */ - if (!row->enabled_p) - continue; - - /* For all but the first row, the highlight starts at column 0. */ - if (i == mouse_face_beg_row) - start_hpos = mouse_face_beg_col; - else - start_hpos = 0; - - if (i == mouse_face_end_row) - end_hpos = mouse_face_end_col; - else - { - end_hpos = row->used[TEXT_AREA]; - if (draw == DRAW_NORMAL_TEXT) - row->fill_line_p = 1; /* Clear to end of line */ - } - - if (end_hpos <= start_hpos) - continue; - /* Record that some glyphs of this row are displayed in - mouse-face. */ - row->mouse_face_p = draw > 0; - - nglyphs = end_hpos - start_hpos; - - if (end_hpos >= row->used[TEXT_AREA]) - nglyphs = row->used[TEXT_AREA] - start_hpos; - - 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) - { - tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos, - nglyphs, mouse_face_face_id); - } - else /* draw == DRAW_NORMAL_TEXT */ - write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs); - } - cursor_to (f, save_y, save_x); - } -} - -static void -term_clear_mouse_face () -{ - if (!NILP (mouse_face_window)) - term_show_mouse_face (DRAW_NORMAL_TEXT); - - mouse_face_beg_row = mouse_face_beg_col = -1; - mouse_face_end_row = mouse_face_end_col = -1; - mouse_face_window = Qnil; -} - -/* Find the glyph matrix position of buffer position POS in window W. - *HPOS and *VPOS are set to the positions found. W's current glyphs - must be up to date. If POS is above window start return (0, 0). - If POS is after end of W, return end of last line in W. - - taken from msdos.c */ -static int -fast_find_position (struct window *w, int pos, int *hpos, int *vpos) -{ - int i, lastcol, line_start_position, maybe_next_line_p = 0; - int yb = window_text_bottom_y (w); - struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0), *best_row = row; - - while (row->y < yb) - { - if (row->used[TEXT_AREA]) - line_start_position = row->glyphs[TEXT_AREA]->charpos; - else - line_start_position = 0; - - if (line_start_position > pos) - break; - /* If the position sought is the end of the buffer, - don't include the blank lines at the bottom of the window. */ - else if (line_start_position == pos - && pos == BUF_ZV (XBUFFER (w->buffer))) - { - maybe_next_line_p = 1; - break; - } - else if (line_start_position > 0) - best_row = row; - - /* Don't overstep the last matrix row, lest we get into the - never-never land... */ - if (row->y + 1 >= yb) - break; - - ++row; - } - - /* Find the right column within BEST_ROW. */ - lastcol = 0; - row = best_row; - for (i = 0; i < row->used[TEXT_AREA]; i++) - { - struct glyph *glyph = row->glyphs[TEXT_AREA] + i; - int charpos; - - charpos = glyph->charpos; - if (charpos == pos) - { - *hpos = i; - *vpos = row->y; - return 1; - } - else if (charpos > pos) - break; - else if (charpos > 0) - lastcol = i; - } - - /* If we're looking for the end of the buffer, - and we didn't find it in the line we scanned, - use the start of the following line. */ - if (maybe_next_line_p) - { - ++row; - lastcol = 0; - } - - *vpos = row->y; - *hpos = lastcol + 1; - return 0; -} - -static void -term_mouse_highlight (struct frame *f, int x, int y) -{ - enum window_part part; - Lisp_Object window; - struct window *w; - struct buffer *b; - - if (NILP (Vmouse_highlight) - || !f->glyphs_initialized_p) - return; - - /* Which window is that in? */ - window = window_from_coordinates (f, x, y, &part, &x, &y, 0); - - /* Not on a window -> return. */ - if (!WINDOWP (window)) - return; - - if (!EQ (window, mouse_face_window)) - term_clear_mouse_face (); - - w = XWINDOW (window); - - /* Are we in a window whose display is up to date? - And verify the buffer's text has not changed. */ - b = XBUFFER (w->buffer); - if (part == ON_TEXT - && EQ (w->window_end_valid, w->buffer) - && XFASTINT (w->last_modified) == BUF_MODIFF (b) - && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b)) - { - int pos, i, nrows = w->current_matrix->nrows; - struct glyph_row *row; - struct glyph *glyph; - - /* Find the glyph under X/Y. */ - glyph = NULL; - if (y >= 0 && y < nrows) - { - row = MATRIX_ROW (w->current_matrix, y); - /* Give up if some row before the one we are looking for is - not enabled. */ - for (i = 0; i <= y; i++) - if (!MATRIX_ROW (w->current_matrix, i)->enabled_p) - break; - if (i > y /* all rows upto and including the one at Y are enabled */ - && row->displays_text_p - && x < window_box_width (w, TEXT_AREA)) - { - glyph = row->glyphs[TEXT_AREA]; - if (x >= row->used[TEXT_AREA]) - glyph = NULL; - else - { - glyph += x; - if (!BUFFERP (glyph->object)) - glyph = NULL; - } - } - } - - /* Clear mouse face if X/Y not over text. */ - if (glyph == NULL) - { - term_clear_mouse_face (); - return; - } - - if (!BUFFERP (glyph->object)) - abort (); - pos = glyph->charpos; - - /* Check for mouse-face. */ - { - extern Lisp_Object Qmouse_face; - Lisp_Object mouse_face, overlay, position, *overlay_vec; - int noverlays, obegv, ozv; - struct buffer *obuf; - - /* If we get an out-of-range value, return now; avoid an error. */ - if (pos > BUF_Z (b)) - return; - - /* Make the window's buffer temporarily current for - overlays_at and compute_char_face. */ - obuf = current_buffer; - current_buffer = b; - obegv = BEGV; - ozv = ZV; - BEGV = BEG; - ZV = Z; - - /* Is this char mouse-active? */ - XSETINT (position, pos); - - /* Put all the overlays we want in a vector in overlay_vec. */ - GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0); - /* Sort overlays into increasing priority order. */ - noverlays = sort_overlays (overlay_vec, noverlays, w); - - /* Check mouse-face highlighting. */ - if (!(EQ (window, mouse_face_window) - && y >= mouse_face_beg_row - && y <= mouse_face_end_row - && (y > mouse_face_beg_row - || x >= mouse_face_beg_col) - && (y < mouse_face_end_row - || x < mouse_face_end_col - || mouse_face_past_end))) - { - /* Clear the display of the old active region, if any. */ - term_clear_mouse_face (); - - /* Find the highest priority overlay that has a mouse-face - property. */ - overlay = Qnil; - for (i = noverlays - 1; i >= 0; --i) - { - mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face); - if (!NILP (mouse_face)) - { - overlay = overlay_vec[i]; - break; - } - } - - /* If no overlay applies, get a text property. */ - if (NILP (overlay)) - mouse_face = Fget_text_property (position, Qmouse_face, - w->buffer); + if (end_hpos >= row->used[TEXT_AREA]) + nglyphs = row->used[TEXT_AREA] - start_hpos; - /* Handle the overlay case. */ - if (!NILP (overlay)) - { - /* Find the range of text around this char that - should be active. */ - Lisp_Object before, after; - EMACS_INT ignore; - - - before = Foverlay_start (overlay); - after = Foverlay_end (overlay); - /* Record this as the current active region. */ - fast_find_position (w, XFASTINT (before), - &mouse_face_beg_col, - &mouse_face_beg_row); - - mouse_face_past_end - = !fast_find_position (w, XFASTINT (after), - &mouse_face_end_col, - &mouse_face_end_row); - mouse_face_window = window; - - mouse_face_face_id - = face_at_buffer_position (w, pos, 0, 0, - &ignore, pos + 1, 1, -1); - - /* Display it as active. */ - term_show_mouse_face (DRAW_MOUSE_FACE); - } - /* Handle the text property case. */ - else if (!NILP (mouse_face)) - { - /* Find the range of text around this char that - should be active. */ - Lisp_Object before, after, beginning, end; - EMACS_INT ignore; - - beginning = Fmarker_position (w->start); - XSETINT (end, (BUF_Z (b) - XFASTINT (w->window_end_pos))); - before - = Fprevious_single_property_change (make_number (pos + 1), - Qmouse_face, - w->buffer, beginning); - after - = Fnext_single_property_change (position, Qmouse_face, - w->buffer, end); - - /* Record this as the current active region. */ - fast_find_position (w, XFASTINT (before), - &mouse_face_beg_col, - &mouse_face_beg_row); - mouse_face_past_end - = !fast_find_position (w, XFASTINT (after), - &mouse_face_end_col, - &mouse_face_end_row); - mouse_face_window = window; - - mouse_face_face_id - = face_at_buffer_position (w, pos, 0, 0, - &ignore, pos + 1, 1, -1); - - /* Display it as active. */ - term_show_mouse_face (DRAW_MOUSE_FACE); - } - } + pos_y = row->y + WINDOW_TOP_EDGE_Y (w); + pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w); - /* Look for a `help-echo' property. */ - { - Lisp_Object help; - extern Lisp_Object Qhelp_echo; + /* Save current cursor co-ordinates. */ + save_y = curY (tty); + save_x = curX (tty); + cursor_to (f, pos_y, pos_x); - /* Check overlays first. */ - help = Qnil; - for (i = noverlays - 1; i >= 0 && NILP (help); --i) - { - overlay = overlay_vec[i]; - help = Foverlay_get (overlay, Qhelp_echo); - } + if (draw == DRAW_MOUSE_FACE) + tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos, + nglyphs, face_id); + else if (draw == DRAW_NORMAL_TEXT) + write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs); - if (!NILP (help)) - { - help_echo_string = help; - help_echo_window = window; - help_echo_object = overlay; - help_echo_pos = pos; - } - /* Try text properties. */ - else if (NILP (help) - && ((STRINGP (glyph->object) - && glyph->charpos >= 0 - && glyph->charpos < SCHARS (glyph->object)) - || (BUFFERP (glyph->object) - && glyph->charpos >= BEGV - && glyph->charpos < ZV))) - { - help = Fget_text_property (make_number (glyph->charpos), - Qhelp_echo, glyph->object); - if (!NILP (help)) - { - help_echo_string = help; - help_echo_window = window; - help_echo_object = glyph->object; - help_echo_pos = glyph->charpos; - } - } - } - - BEGV = obegv; - ZV = ozv; - current_buffer = obuf; - } - } + cursor_to (f, save_y, save_x); } static int @@ -2931,7 +2714,7 @@ term_mouse_movement (FRAME_PTR frame, Gpm_Event *event) if (event->x != last_mouse_x || event->y != last_mouse_y) { frame->mouse_moved = 1; - term_mouse_highlight (frame, event->x, event->y); + note_mouse_highlight (frame, event->x, event->y); /* Remember which glyph we're now on. */ last_mouse_x = event->x; last_mouse_y = event->y; @@ -3100,7 +2883,7 @@ DEFUN ("gpm-mouse-start", Fgpm_mouse_start, Sgpm_mouse_start, 0, 0, 0, doc: /* Open a connection to Gpm. Gpm-mouse can only be activated for one tty at a time. */) - () + (void) { struct frame *f = SELECTED_FRAME (); struct tty_display_info *tty @@ -3148,7 +2931,7 @@ close_gpm (int fd) DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop, Sgpm_mouse_stop, 0, 0, 0, doc: /* Close a connection to Gpm. */) - () + (void) { struct frame *f = SELECTED_FRAME (); struct tty_display_info *tty @@ -3181,7 +2964,7 @@ create_tty_output (struct frame *f) abort (); t = xmalloc (sizeof (struct tty_output)); - bzero (t, sizeof (struct tty_output)); + memset (t, 0, sizeof (struct tty_output)); t->display_info = FRAME_TERMINAL (f)->display_info.tty; @@ -3304,11 +3087,10 @@ static void dissociate_if_controlling_tty (int fd) { #ifndef DOS_NT - int pgid; - EMACS_GET_TTY_PGRP (fd, &pgid); /* If tcgetpgrp succeeds, fd is the ctty. */ + int pgid = tcgetpgrp (fd); /* If tcgetpgrp succeeds, fd is the ctty. */ if (pgid != -1) { -#if defined (USG) && !defined (BSD_PGRPS) +#if defined (USG5) setpgrp (); no_controlling_tty = 1; #elif defined (CYGWIN) @@ -3334,8 +3116,6 @@ dissociate_if_controlling_tty (int fd) #endif /* !DOS_NT */ } -static void maybe_fatal(); - /* Create a termcap display on the tty device with the given name and type. @@ -3348,7 +3128,7 @@ static void maybe_fatal(); If MUST_SUCCEED is true, then all errors are fatal. */ struct terminal * -init_tty (char *name, char *terminal_type, int must_succeed) +init_tty (const char *name, const char *terminal_type, int must_succeed) { char *area = NULL; char **address = &area; @@ -3388,7 +3168,7 @@ init_tty (char *name, char *terminal_type, int must_succeed) #else tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info)); #endif - bzero (tty, sizeof (struct tty_display_info)); + memset (tty, 0, sizeof (struct tty_display_info)); tty->next = tty_list; tty_list = tty; @@ -3399,6 +3179,15 @@ init_tty (char *name, char *terminal_type, int must_succeed) tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm)); Wcm_clear (tty); + encode_terminal_src_size = 0; + encode_terminal_dst_size = 0; + +#ifdef HAVE_GPM + terminal->mouse_position_hook = term_mouse_position; + tty->mouse_highlight.mouse_face_window = Qnil; +#endif + + #ifndef DOS_NT set_tty_hooks (terminal); @@ -3452,80 +3241,6 @@ init_tty (char *name, char *terminal_type, int must_succeed) add_keyboard_wait_descriptor (fileno (tty->input)); -#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 = &tty_free_frame_resources; - terminal->delete_terminal_hook = &delete_tty; - - tty->name = xstrdup (name); - terminal->name = xstrdup (name); - tty->type = xstrdup (terminal_type); - -#ifdef subprocesses - add_keyboard_wait_descriptor (0); -#endif - - Wcm_clear (tty); - -#ifdef WINDOWSNT - { - struct frame *f = XFRAME (selected_frame); - - FrameRows (tty) = FRAME_LINES (f); - FrameCols (tty) = FRAME_COLS (f); - tty->specified_window = FRAME_LINES (f); - - 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; - terminal->scroll_region_ok = 0; - - /* Seems to insert lines when it's not supposed to, messing up the - 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 DOS_NT */ - Wcm_clear (tty); tty->termcap_term_buffer = (char *) xmalloc (buffer_size); @@ -3550,25 +3265,18 @@ init_tty (char *name, char *terminal_type, int must_succeed) } if (status == 0) { -#ifdef TERMINFO 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\ 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 TERMINFO' (C-shell: `unsetenv TERMINFO') as well.", - terminal_type); +`setenv TERM ...') to specify the correct type. It may be necessary\n" +#ifdef TERMINFO +"to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.", #else - 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\ -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.", - terminal_type); +"to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", #endif + terminal_type); } #ifndef TERMINFO @@ -3684,7 +3392,61 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", tty->TF_underscore = tgetflag ("ul"); tty->TF_teleray = tgetflag ("xt"); -#endif /* !DOS_NT */ +#else /* DOS_NT */ +#ifdef WINDOWSNT + { + struct frame *f = XFRAME (selected_frame); + + initialize_w32_display (terminal); + + FrameRows (tty) = FRAME_LINES (f); + FrameCols (tty) = FRAME_COLS (f); + tty->specified_window = FRAME_LINES (f); + + FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; + FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; + terminal->char_ins_del_ok = 1; + baud_rate = 19200; + } +#else /* MSDOS */ + { + int height, width; + if (strcmp (terminal_type, "internal") == 0) + terminal->type = output_msdos_raw; + initialize_msdos_display (terminal); + + get_tty_size (fileno (tty->input), &width, &height); + FrameCols (tty) = width; + FrameRows (tty) = height; + terminal->char_ins_del_ok = 0; + init_baud_rate (fileno (tty->input)); + } +#endif /* MSDOS */ + tty->output = stdout; + tty->input = stdin; + /* The following two are inaccessible from w32console.c. */ + 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); + + add_keyboard_wait_descriptor (0); + + tty->delete_in_insert_mode = 1; + + UseTabs (tty) = 0; + terminal->scroll_region_ok = 0; + + /* Seems to insert lines when it's not supposed to, messing up the + 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; + + tty->TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */ +#endif /* DOS_NT */ + terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD)); init_kboard (terminal->kboard); terminal->kboard->Vwindow_system = Qnil; @@ -3714,7 +3476,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", if (FrameRows (tty) < 3 || FrameCols (tty) < 3) maybe_fatal (must_succeed, terminal, - "Screen size %dx%d is too small" + "Screen size %dx%d is too small", "Screen size %dx%d is too small", FrameCols (tty), FrameRows (tty)); @@ -3835,20 +3597,15 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", { maybe_fatal (must_succeed, terminal, "Terminal type \"%s\" is not powerful enough to run Emacs", -# ifdef TERMINFO "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,\n\ 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 TERMINFO' (C-shell: `unsetenv TERMINFO') as well.", +`setenv TERM ...') to specify the correct type. It may be necessary\n" +# ifdef TERMINFO +"to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.", # else /* TERMCAP */ - "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,\n\ -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.", +"to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", # endif /* TERMINFO */ terminal_type); } @@ -3895,24 +3652,39 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", return terminal; } + +static void +vfatal (const char *str, va_list ap) +{ + fprintf (stderr, "emacs: "); + vfprintf (stderr, str, ap); + if (!(strlen (str) > 0 && str[strlen (str) - 1] == '\n')) + fprintf (stderr, "\n"); + va_end (ap); + fflush (stderr); + exit (1); +} + + /* Auxiliary error-handling function for init_tty. Delete TERMINAL, then call error or fatal with str1 or str2, respectively, according to MUST_SUCCEED. */ static void -maybe_fatal (must_succeed, terminal, str1, str2, arg1, arg2) - int must_succeed; - struct terminal *terminal; - char *str1, *str2, *arg1, *arg2; +maybe_fatal (int must_succeed, struct terminal *terminal, + const char *str1, const char *str2, ...) { + va_list ap; + va_start (ap, str2); if (terminal) delete_tty (terminal); if (must_succeed) - fatal (str2, arg1, arg2); + vfatal (str2, ap); else - error (str1, arg1, arg2); + verror (str1, ap); + va_end (ap); abort (); } @@ -3921,13 +3693,8 @@ fatal (const char *str, ...) { va_list ap; va_start (ap, str); - fprintf (stderr, "emacs: "); - vfprintf (stderr, str, ap); - if (!(strlen (str) > 0 && str[strlen (str) - 1] == '\n')) - fprintf (stderr, "\n"); + vfatal (str, ap); va_end (ap); - fflush (stderr); - exit (1); } @@ -3976,9 +3743,7 @@ delete_tty (struct terminal *terminal) if (tty->input) { -#ifdef subprocesses delete_keyboard_wait_descriptor (fileno (tty->input)); -#endif if (tty->input != stdin) fclose (tty->input); } @@ -3992,7 +3757,7 @@ delete_tty (struct terminal *terminal) xfree (tty->termcap_strings_buffer); xfree (tty->termcap_term_buffer); - bzero (tty, sizeof (struct tty_display_info)); + memset (tty, 0, sizeof (struct tty_display_info)); xfree (tty); } @@ -4013,7 +3778,7 @@ mark_ttys (void) void -syms_of_term () +syms_of_term (void) { DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo, doc: /* Non-nil means the system uses terminfo rather than termcap. @@ -4054,8 +3819,6 @@ bigger, or it may make it blink, or it may do nothing at all. */); #ifdef HAVE_GPM defsubr (&Sgpm_mouse_start); defsubr (&Sgpm_mouse_stop); - - staticpro (&mouse_face_window); #endif /* HAVE_GPM */ #ifndef DOS_NT @@ -4068,7 +3831,3 @@ bigger, or it may make it blink, or it may do nothing at all. */); encode_terminal_dst = NULL; } - - -/* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193 - (do not change this comment) */ |