X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/03c19041455f679a452b2803106ab8c739c5de3b..8510724d46951d651a78424e12b93ccee100c665:/src/term.c diff --git a/src/term.c b/src/term.c index fca99bc6c7..c425337fe7 100644 --- a/src/term.c +++ b/src/term.c @@ -1,13 +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 Free Software Foundation, Inc. + 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 @@ -15,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 . */ @@ -37,6 +36,7 @@ Boston, MA 02110-1301, USA. */ #endif #include +#include #include "lisp.h" #include "termchar.h" @@ -57,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 @@ -75,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 @@ -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) @@ -567,7 +568,6 @@ 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; @@ -581,10 +581,10 @@ encode_terminal_code (src, src_len, coding) required = MAX_MULTIBYTE_LENGTH * src_len; if (encode_terminal_src_size < required) { - if (encode_terminal_src_size == 0) - encode_terminal_src = xmalloc (required); - else + if (encode_terminal_src) encode_terminal_src = xrealloc (encode_terminal_src, required); + else + encode_terminal_src = xmalloc (required); encode_terminal_src_size = required; } @@ -596,11 +596,21 @@ encode_terminal_code (src, src_len, coding) { if (src->type == COMPOSITE_GLYPH) { - struct composition *cmp = composition_table[src->u.cmp_id]; + struct composition *cmp; + Lisp_Object gstring; int i; nbytes = buf - encode_terminal_src; - required = MAX_MULTIBYTE_LENGTH * cmp->glyph_len; + 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) { @@ -610,34 +620,53 @@ encode_terminal_code (src, src_len, coding) buf = encode_terminal_src + nbytes; } - 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++; - } + 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. */ else if (! CHAR_GLYPH_PADDING_P (*src)) { + GLYPH g; int c; Lisp_Object string; string = Qnil; - g = GLYPH_FROM_CHAR_GLYPH (src[0]); + 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. */ + /* This glyph doesn't have an entry in Vglyph_table. */ c = src->u.ch; } else @@ -649,10 +678,10 @@ encode_terminal_code (src, src_len, coding) if (GLYPH_SIMPLE_P (tbase, tlen, g)) /* We set the multi-byte form of a character in G (that should be an ASCII character) at WORKBUF. */ - c = FAST_GLYPH_CHAR (g); + c = GLYPH_CHAR (g); else /* We have a string in Vglyph_table. */ - string = tbase[g]; + string = tbase[GLYPH_CHAR (g)]; } if (NILP (string)) @@ -717,7 +746,11 @@ encode_terminal_code (src, src_len, coding) if (encode_terminal_dst_size == 0) { encode_terminal_dst_size = encode_terminal_src_size; - encode_terminal_dst = xmalloc (encode_terminal_dst_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); } coding->destination = encode_terminal_dst; coding->dst_bytes = encode_terminal_dst_size; @@ -1014,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); @@ -1044,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) @@ -1369,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); @@ -1744,7 +1777,20 @@ append_composite_glyph (it) { glyph->type = COMPOSITE_GLYPH; glyph->pixel_width = it->pixel_width; - glyph->u.cmp_id = it->cmp_id; + 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); @@ -1765,14 +1811,22 @@ static void produce_composite_glyph (it) struct it *it; { - struct composition *cmp = composition_table[it->cmp_id]; int c; - xassert (cmp->glyph_len > 0); - c = COMPOSITION_GLYPH (cmp, 0); - it->pixel_width = CHAR_WIDTH (it->c); - it->nglyphs = 1; + 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); } @@ -1790,6 +1844,7 @@ produce_special_glyphs (it, what) enum display_element_type what; { struct it temp_it; + Lisp_Object gc; GLYPH glyph; temp_it = *it; @@ -1802,34 +1857,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); @@ -2071,7 +2124,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 @@ -2091,17 +2144,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; @@ -2160,60 +2210,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 */ @@ -2224,7 +2256,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); @@ -2241,7 +2273,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; @@ -2253,7 +2285,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; @@ -2274,7 +2306,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) @@ -2284,7 +2316,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 @@ -2294,7 +2326,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; @@ -2345,12 +2378,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 @@ -2366,18 +2399,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. */ @@ -2417,6 +2454,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) @@ -2427,11 +2468,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); @@ -2490,7 +2546,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); @@ -2534,7 +2590,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) @@ -2773,7 +2829,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); @@ -2802,7 +2858,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))); @@ -2958,10 +3014,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; @@ -2994,7 +3050,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); @@ -3093,6 +3149,15 @@ Gpm-mouse can only be activated for one tty at a time. */) } } +void +close_gpm () +{ + if (gpm_fd >= 0) + delete_gpm_wait_descriptor (gpm_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. */) @@ -3105,11 +3170,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 (); return Qnil; } #endif /* HAVE_GPM */ @@ -3138,14 +3200,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); } @@ -3184,7 +3249,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; } @@ -3209,7 +3274,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. */ @@ -3227,8 +3292,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; } @@ -3236,7 +3301,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) @@ -3264,7 +3329,7 @@ dissociate_if_controlling_tty (int fd) #endif /* ! TIOCNOTTY */ #endif /* ! USG */ } -#endif /* !WINDOWSNT */ +#endif /* !DOS_NT */ } static void maybe_fatal(); @@ -3285,7 +3350,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; @@ -3294,7 +3358,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"); @@ -3313,7 +3377,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; @@ -3325,7 +3397,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); { @@ -3347,15 +3419,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); @@ -3367,18 +3442,18 @@ 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 +#endif /* !DOS_NT */ + encode_terminal_src_size = 0; encode_terminal_dst_size = 0; @@ -3387,22 +3462,31 @@ init_tty (char *name, char *terminal_type, int must_succeed) 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); @@ -3413,6 +3497,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; @@ -3422,32 +3514,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 @@ -3455,7 +3551,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\ @@ -3464,7 +3560,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\ @@ -3476,12 +3572,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); @@ -3514,12 +3609,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...) */ @@ -3595,10 +3684,10 @@ 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; terminal->kboard->next_kboard = all_kboards; all_kboards = terminal->kboard; terminal->kboard->reference_count++; @@ -3607,12 +3696,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; @@ -3627,7 +3713,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)); @@ -3638,15 +3724,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"; @@ -3760,15 +3837,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\ @@ -3784,12 +3854,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"); @@ -3822,17 +3891,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); @@ -3841,22 +3900,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 @@ -3865,14 +3920,14 @@ maybe_fatal (must_succeed, buffer, terminal, str1, str2, arg1, arg2) abort (); } -/* VARARGS 1 */ void -fatal (str, arg1, arg2) - char *str, *arg1, *arg2; +fatal (const char *str, ...) { + va_list ap; + va_start (ap, str); fprintf (stderr, "emacs: "); - fprintf (stderr, str, arg1, arg2); - fprintf (stderr, "\n"); + vfprintf (stderr, str, ap); + va_end (ap); fflush (stderr); exit (1); } @@ -3887,8 +3942,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; @@ -3897,7 +3952,7 @@ delete_tty (struct terminal *terminal) abort (); tty = terminal->display_info.tty; - + last_terminal = 1; FOR_EACH_FRAME (tail, frame) { @@ -3910,7 +3965,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 @@ -3933,15 +3988,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); } @@ -3950,11 +4004,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); @@ -4021,6 +4076,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; }