Mercurial > emacs
diff src/term.c @ 83008:040dd41ed7d0
Hookified termcap devices, added bootstrap display device, plus many bugfixes.
lisp/frame.el (display-color-cells): Pass display parameter to tty-display-color-cells.
lisp/term/xterm.el (xterm-register-default-colors): Pass the selected-frame to display-color-cells.
src/dispextern.h (set_terminal_modes, reset_terminal_modes): Removed declarations.
(get_named_tty_display): New prototype.
(tty_clear_end_of_line, term_init): Updated to new prototype.
(initial_term_init): Renamed to init_initial_display.
src/dispnew.c (Fredraw_frame): ifdef-out DOS-specific code. Add display parameter to set_terminal_modes call.
(update_frame): Don't flush the tty of there is no tty.
(init_display): Set up a termcap display on the controlling tty and
change the initial frame to use that. Delete the initial display.
src/frame.c (Fframep): Return t for the initial frame.
(make_initial_frame): New function for creating the initial frame during bootstrap. Use init_initial_display, not initial_term_init.
(make_terminal_frame): Removed special cases for creating the initial frame.
src/frame.h (enum output_method): New entry: output_initial for the bootstrap display.
(FRAME_INITIAL_P): New macro.
(make_initial_frame): New prototype.
src/keyboard.c (interrupt_signal): Exit Emacs on SIGINT from the (frameless) controlling tty, if possible. Explain this in a comment.
(init_keyboard): Added comment about exiting on SIGINT.
(Fset_input_mode): A termcap frame is never the initial frame anymore.
src/sysdep.c (init_sys_modes): Update tty_set_terminal_modes call to the new prototype.
(reset_sys_modes): Comment out tty_clear_end_of_line call; it doesn't work anymore. Update tty_reset_terminal_modes call.
src/termchar.h (struct tty_display_info): Added pointer to the display structure, for reset_sys_modes.
src/termhooks.h (struct display): Added display parameter to set_terminal_modes_hook and reset_terminal_modes_hook.
src/term.c (initial_display): New variable.
(tty_ring_bell, tty_update_end, tty_set_terminal_window, tty_cursor_to)
(tty_raw_cursor_to, tty_clear_to_end, tty_clear_frame, tty_clear_end_of_line)
(tty_write_glyphs, tty_insert_glyphs, tty_delete_glyphs, tty_ins_del_lines): New functions.
(ring_bell, update_end, set_terminal_window, cursor_to, raw_cursor_to)
(clear_to_end, clear_frame, clear_end_of_line, write_glyphs, insert_glyphs)
(delete_glyphs, ins_del_lines): Removed special casing of termcap displays.
(get_tty_display): New function.
(Ftty_display_color_p, Ftty_display_color_cells): Use it.
(get_named_tty_display): Removed static.
(tty_set_terminal_modes, tty_reset_terminal_modes): Changed to use a display parameter
instead of tty_display_info for hook compatibility.
(set_terminal_modes, reset_terminal_modes): Removed.
(initial_term_init): Renamed to init_initial_display. Set up an
output_initial device, not a termcap display.
(delete_initial_display): New function.
(maybe_fatal): New function, for private use of term_init.
(term_init): New parameter for choosing between fatal and simple errors.
Removed incomprehensible special casing for the second initialization of the
controlling tty. Use maybe_fatal for error handling.
Initialize termcap display hooks in the new device.
Initialize the display pointer in the tty_display_info structure.
(delete_tty): Replace order of reset_sys_modes and delete_display.
src/window.c (init_window_once): Call make_initial_frame instead of make_terminal_frame.
src/xfaces.c (realize_default_face, realize_face): Don't abort on the bootstrap display device.
src/xterm.c (XTset_terminal_modes, XTreset_terminal_modes): Added display parameter.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-48
author | Karoly Lorentey <lorentey@elte.hu> |
---|---|
date | Fri, 09 Jan 2004 18:57:53 +0000 |
parents | 7900111db01c |
children | c4d4cbf86260 |
line wrap: on
line diff
--- a/src/term.c Fri Jan 09 13:12:28 2004 +0000 +++ b/src/term.c Fri Jan 09 18:57:53 2004 +0000 @@ -71,6 +71,7 @@ static void tty_show_cursor P_ ((struct tty_display_info *)); static void tty_hide_cursor P_ ((struct tty_display_info *)); +void delete_initial_display P_ ((struct display *)); void delete_tty P_ ((struct display *)); void create_tty_output P_ ((struct frame *)); void delete_tty_output P_ ((struct frame *)); @@ -105,6 +106,9 @@ /* Chain of all displays currently in use. */ struct display *display_list; +/* The initial display device, created by initial_term_init. */ +struct display *initial_display; + /* Chain of all tty device parameters. */ struct tty_display_info *tty_list; @@ -172,7 +176,9 @@ void ring_bell () { - struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); if (!NILP (Vring_bell_function)) { @@ -195,32 +201,36 @@ } else if (FRAME_DISPLAY (f)->ring_bell_hook) (*FRAME_DISPLAY (f)->ring_bell_hook) (); - else { - struct tty_display_info *tty = FRAME_TTY (f); - OUTPUT (tty, tty->TS_visible_bell && visible_bell ? tty->TS_visible_bell : tty->TS_bell); - } } -void tty_set_terminal_modes (struct tty_display_info *tty) +void +tty_ring_bell () { + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + + struct tty_display_info *tty = FRAME_TTY (f); + + OUTPUT (tty, (tty->TS_visible_bell && visible_bell + ? tty->TS_visible_bell + : tty->TS_bell)); +} + +void tty_set_terminal_modes (struct display *display) +{ + struct tty_display_info *tty = display->display_info.tty; + OUTPUT_IF (tty, tty->TS_termcap_modes); OUTPUT_IF (tty, tty->TS_cursor_visible); OUTPUT_IF (tty, tty->TS_keypad_mode); losecursor (tty); } -void -set_terminal_modes () +void tty_reset_terminal_modes (struct display *display) { - struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); - if (FRAME_DISPLAY (f)->set_terminal_modes_hook) - (*FRAME_DISPLAY (f)->set_terminal_modes_hook) (); - else - tty_set_terminal_modes (FRAME_TTY (f)); -} - -void tty_reset_terminal_modes (struct tty_display_info *tty) -{ + struct tty_display_info *tty = display->display_info.tty; + turn_off_highlight (tty); turn_off_insert (tty); OUTPUT_IF (tty, tty->TS_end_keypad_mode); @@ -233,16 +243,6 @@ } void -reset_terminal_modes () -{ - struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); - if (FRAME_DISPLAY (f)->reset_terminal_modes_hook) - (*FRAME_DISPLAY (f)->reset_terminal_modes_hook) (); - else - tty_reset_terminal_modes (FRAME_TTY (f)); -} - -void update_begin (f) struct frame *f; { @@ -257,32 +257,44 @@ { if (FRAME_DISPLAY (f)->update_end_hook) (*FRAME_DISPLAY (f)->update_end_hook) (f); - else if (FRAME_TERMCAP_P (f)) - { - struct tty_display_info *tty = FRAME_TTY (f); - if (!XWINDOW (selected_window)->cursor_off_p) - tty_show_cursor (tty); - turn_off_insert (tty); - background_highlight (tty); - } - updating_frame = NULL; } void +tty_update_end (struct frame *f) +{ + struct tty_display_info *tty = FRAME_TTY (f); + + if (!XWINDOW (selected_window)->cursor_off_p) + tty_show_cursor (tty); + turn_off_insert (tty); + background_highlight (tty); +} + +void set_terminal_window (size) int size; { - struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + if (FRAME_DISPLAY (f)->set_terminal_window_hook) (*FRAME_DISPLAY (f)->set_terminal_window_hook) (size); - else if (FRAME_TERMCAP_P (f)) - { - struct tty_display_info *tty = FRAME_TTY (f); - tty->specified_window = size ? size : FRAME_LINES (f); - if (FRAME_SCROLL_REGION_OK (f)) - set_scroll_region (0, tty->specified_window); - } +} + +void +tty_set_terminal_window (int size) +{ + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + + struct tty_display_info *tty = FRAME_TTY (f); + + tty->specified_window = size ? size : FRAME_LINES (f); + if (FRAME_SCROLL_REGION_OK (f)) + set_scroll_region (0, tty->specified_window); } void @@ -290,7 +302,10 @@ int start, stop; { char *buf; - struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + struct tty_display_info *tty = FRAME_TTY (f); if (tty->TS_set_scroll_region) @@ -412,16 +427,22 @@ cursor_to (vpos, hpos) int vpos, hpos; { - struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); - struct tty_display_info *tty; + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); if (FRAME_DISPLAY (f)->cursor_to_hook) - { - (*FRAME_DISPLAY (f)->cursor_to_hook) (vpos, hpos); - return; - } - - tty = FRAME_TTY (f); + (*FRAME_DISPLAY (f)->cursor_to_hook) (vpos, hpos); +} + +void +tty_cursor_to (int vpos, int hpos) +{ + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + + struct tty_display_info *tty = FRAME_TTY (f); /* Detect the case where we are called from reset_sys_modes and the costs have never been calculated. Do nothing. */ @@ -444,14 +465,23 @@ raw_cursor_to (row, col) int row, col; { - struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame); - struct tty_display_info *tty; + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + if (FRAME_DISPLAY (f)->raw_cursor_to_hook) - { - (*FRAME_DISPLAY (f)->raw_cursor_to_hook) (row, col); - return; - } - tty = FRAME_TTY (f); + (*FRAME_DISPLAY (f)->raw_cursor_to_hook) (row, col); +} + +void +tty_raw_cursor_to (int row, int col) +{ + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + + struct tty_display_info *tty = FRAME_TTY (f); + if (curY (tty) == row && curX (tty) == col) return; @@ -468,17 +498,23 @@ void clear_to_end () { - register int i; - - struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); - struct tty_display_info *tty; + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); if (FRAME_DISPLAY (f)->clear_to_end_hook) - { - (*FRAME_DISPLAY (f)->clear_to_end_hook) (); - return; - } - tty = FRAME_TTY (f); + (*FRAME_DISPLAY (f)->clear_to_end_hook) (); +} + +void +tty_clear_to_end (void) +{ + register int i; + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + struct tty_display_info *tty = FRAME_TTY (f); + if (tty->TS_clr_to_bottom) { background_highlight (tty); @@ -500,14 +536,20 @@ clear_frame () { struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); - struct tty_display_info *tty; if (FRAME_DISPLAY (f)->clear_frame_hook) - { - (*FRAME_DISPLAY (f)->clear_frame_hook) (); - return; - } - tty = FRAME_TTY (f); + (*FRAME_DISPLAY (f)->clear_frame_hook) (); +} + +void +tty_clear_frame () +{ + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + + struct tty_display_info *tty = FRAME_TTY (f); + if (tty->TS_clr_frame) { background_highlight (tty); @@ -530,22 +572,23 @@ clear_end_of_line (first_unused_hpos) int first_unused_hpos; { - struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); - struct tty_display_info *tty; + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); if (FRAME_DISPLAY (f)->clear_end_of_line_hook) - { - (*FRAME_DISPLAY (f)->clear_end_of_line_hook) (first_unused_hpos); - return; - } - - tty_clear_end_of_line (FRAME_TTY (f), first_unused_hpos); + (*FRAME_DISPLAY (f)->clear_end_of_line_hook) (first_unused_hpos); } void -tty_clear_end_of_line (struct tty_display_info *tty, int first_unused_hpos) +tty_clear_end_of_line (int first_unused_hpos) { register int i; + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + struct tty_display_info *tty = FRAME_TTY (f); + /* Detect the case where we are called from reset_sys_modes and the costs have never been calculated. Do nothing. */ if (! tty->costs_set) @@ -692,19 +735,26 @@ register struct glyph *string; register int len; { - int produced, consumed; - struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame); - struct tty_display_info *tty; - unsigned char conversion_buffer[1024]; - int conversion_buffer_size = sizeof conversion_buffer; + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); if (FRAME_DISPLAY (f)->write_glyphs_hook) - { - (*FRAME_DISPLAY (f)->write_glyphs_hook) (string, len); - return; - } - - tty = FRAME_TTY (f); + (*FRAME_DISPLAY (f)->write_glyphs_hook) (string, len); +} + +void +tty_write_glyphs (struct glyph *string, int len) +{ + int produced, consumed; + unsigned char conversion_buffer[1024]; + int conversion_buffer_size = sizeof conversion_buffer; + + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + + struct tty_display_info *tty = FRAME_TTY (f); turn_off_insert (tty); tty_hide_cursor (tty); @@ -795,23 +845,27 @@ register struct glyph *start; register int len; { - char *buf; - struct glyph *glyph = NULL; - struct frame *f; - struct tty_display_info *tty; + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); if (len <= 0) return; - f = (updating_frame ? updating_frame : XFRAME (selected_frame)); - if (FRAME_DISPLAY (f)->insert_glyphs_hook) - { - (*FRAME_DISPLAY (f)->insert_glyphs_hook) (start, len); - return; - } - - tty = FRAME_TTY (f); + (*FRAME_DISPLAY (f)->insert_glyphs_hook) (start, len); +} + +void +tty_insert_glyphs (struct glyph *start, int len) +{ + char *buf; + struct glyph *glyph = NULL; + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + + struct tty_display_info *tty = FRAME_TTY (f); if (tty->TS_ins_multi_chars) { @@ -889,17 +943,24 @@ delete_glyphs (n) register int n; { - char *buf; - register int i; - struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); - struct tty_display_info *tty = FRAME_TTY (f); + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); if (FRAME_DISPLAY (f)->delete_glyphs_hook) - { - (*FRAME_DISPLAY (f)->delete_glyphs_hook) (n); - return; - } - + (*FRAME_DISPLAY (f)->delete_glyphs_hook) (n); +} + +void +tty_delete_glyphs (int n) +{ + char *buf; + register int i; + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + + struct tty_display_info *tty = FRAME_TTY (f); if (tty->delete_in_insert_mode) { @@ -930,73 +991,79 @@ ins_del_lines (vpos, n) int vpos, n; { - struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + if (FRAME_DISPLAY (f)->ins_del_lines_hook) + (*FRAME_DISPLAY (f)->ins_del_lines_hook) (vpos, n); +} + +void +tty_ins_del_lines (int vpos, int n) +{ + struct frame *f = (updating_frame + ? updating_frame + : XFRAME (selected_frame)); + + struct tty_display_info *tty = FRAME_TTY (f); + char *multi = n > 0 ? tty->TS_ins_multi_lines : tty->TS_del_multi_lines; + char *single = n > 0 ? tty->TS_ins_line : tty->TS_del_line; + char *scroll = n > 0 ? tty->TS_rev_scroll : tty->TS_fwd_scroll; + + register int i = n > 0 ? n : -n; + register char *buf; + + /* If the lines below the insertion are being pushed + into the end of the window, this is the same as clearing; + and we know the lines are already clear, since the matching + deletion has already been done. So can ignore this. */ + /* If the lines below the deletion are blank lines coming + out of the end of the window, don't bother, + as there will be a matching inslines later that will flush them. */ + if (FRAME_SCROLL_REGION_OK (f) + && vpos + i >= tty->specified_window) + return; + if (!FRAME_MEMORY_BELOW_FRAME (f) + && vpos + i >= FRAME_LINES (f)) + return; + + if (multi) { - (*FRAME_DISPLAY (f)->ins_del_lines_hook) (vpos, n); - return; + raw_cursor_to (vpos, 0); + background_highlight (tty); + buf = tparam (multi, 0, 0, i); + OUTPUT (tty, buf); + xfree (buf); + } + else if (single) + { + raw_cursor_to (vpos, 0); + background_highlight (tty); + while (--i >= 0) + OUTPUT (tty, single); + if (tty->TF_teleray) + curX (tty) = 0; } else { - struct tty_display_info *tty = FRAME_TTY (f); - char *multi = n > 0 ? tty->TS_ins_multi_lines : tty->TS_del_multi_lines; - char *single = n > 0 ? tty->TS_ins_line : tty->TS_del_line; - char *scroll = n > 0 ? tty->TS_rev_scroll : tty->TS_fwd_scroll; - - register int i = n > 0 ? n : -n; - register char *buf; - - /* If the lines below the insertion are being pushed - into the end of the window, this is the same as clearing; - and we know the lines are already clear, since the matching - deletion has already been done. So can ignore this. */ - /* If the lines below the deletion are blank lines coming - out of the end of the window, don't bother, - as there will be a matching inslines later that will flush them. */ - if (FRAME_SCROLL_REGION_OK (f) - && vpos + i >= tty->specified_window) - return; - if (!FRAME_MEMORY_BELOW_FRAME (f) - && vpos + i >= FRAME_LINES (f)) - return; - - if (multi) - { - raw_cursor_to (vpos, 0); - background_highlight (tty); - buf = tparam (multi, 0, 0, i); - OUTPUT (tty, buf); - xfree (buf); - } - else if (single) - { - raw_cursor_to (vpos, 0); - background_highlight (tty); - while (--i >= 0) - OUTPUT (tty, single); - if (tty->TF_teleray) - curX (tty) = 0; - } + set_scroll_region (vpos, tty->specified_window); + if (n < 0) + raw_cursor_to (tty->specified_window - 1, 0); else - { - set_scroll_region (vpos, tty->specified_window); - if (n < 0) - raw_cursor_to (tty->specified_window - 1, 0); - else - raw_cursor_to (vpos, 0); - background_highlight (tty); - while (--i >= 0) - OUTPUTL (tty, scroll, tty->specified_window - vpos); - set_scroll_region (0, tty->specified_window); - } - - if (!FRAME_SCROLL_REGION_OK (f) - && FRAME_MEMORY_BELOW_FRAME (f) - && n < 0) - { - cursor_to (FRAME_LINES (f) + n, 0); - clear_to_end (); - } + raw_cursor_to (vpos, 0); + background_highlight (tty); + while (--i >= 0) + OUTPUTL (tty, scroll, tty->specified_window - vpos); + set_scroll_region (0, tty->specified_window); + } + + if (!FRAME_SCROLL_REGION_OK (f) + && FRAME_MEMORY_BELOW_FRAME (f) + && n < 0) + { + cursor_to (FRAME_LINES (f) + n, 0); + clear_to_end (); } } @@ -1809,6 +1876,48 @@ return 1; } +/* Return the tty display object specified by DISPLAY. + DISPLAY may be a frame or a string. */ + +static struct display * +get_tty_display (Lisp_Object display) +{ + struct display *d; + + if (! FRAMEP (display) && ! STRINGP (display)) + return 0; + + /* The initial frame does not support colors. */ + if (FRAMEP (display) && FRAME_INITIAL_P (XFRAME (display))) + return 0; + + if (FRAMEP (display)) + { + if (! FRAME_TERMCAP_P (XFRAME (display))) +#if 0 /* XXX We need a predicate as the first argument; find one. */ + wrong_type_argument ("Not a termcap frame", display); +#else /* Until we fix the wrong_type_argument call above, simply throw + a dumb error. */ + error ("DISPLAY is not a termcap frame"); +#endif + + d = FRAME_DISPLAY (XFRAME (display)); + } + else if (STRINGP (display)) + { + char *name = (char *) alloca (SBYTES (display) + 1); + strncpy (name, SDATA (display), SBYTES (display)); + name[SBYTES (display)] = 0; + + d = get_named_tty_display (name); + + if (!d) + error ("There is no tty display on %s", name); + } + + return d; +} + /* Return non-zero if the terminal is capable to display colors. */ @@ -1818,13 +1927,11 @@ (display) Lisp_Object display; { - struct tty_display_info *tty; - - if (! FRAMEP (display)) + struct display *d = get_tty_display (display); + if (!d) return Qnil; - - tty = FRAME_TTY (XFRAME (display)); - return tty->TN_max_colors > 0 ? Qt : Qnil; + else + return d->display_info.tty->TN_max_colors > 0 ? Qt : Qnil; } /* Return the number of supported colors. */ @@ -1834,13 +1941,11 @@ (display) Lisp_Object display; { - struct tty_display_info *tty; - - if (! FRAMEP (display)) + struct display *d = get_tty_display (display); + if (!d) return Qnil; - - tty = FRAME_TTY (XFRAME (display)); - return make_number (tty->TN_max_colors); + else + return make_number (d->display_info.tty->TN_max_colors); } #ifndef WINDOWSNT @@ -1982,7 +2087,7 @@ -static struct display * +struct display * get_named_tty_display (name) char *name; { @@ -2058,33 +2163,50 @@ Initialization ***********************************************************************/ +/* Create the bootstrap display device for the initial frame. + +Returns a display of type output_initial. */ struct display * -initial_term_init (void) +init_initial_display (void) { + struct tty_display_info *tty; + if (initialized || display_list || tty_list) abort (); - display_list = create_display (); - - tty_list = xmalloc (sizeof (struct tty_display_info)); - bzero (tty_list, sizeof (struct tty_display_info)); - tty_list->name = 0; - tty_list->input = stdin; - tty_list->output = stdout; - tty_list->Wcm = (struct cm *) xmalloc (sizeof (struct cm)); -#ifdef MULTI_KBOARD - tty_list->kboard = initial_kboard; -#endif + initial_display = create_display (); + initial_display->type = output_initial; + + initial_display->delete_display_hook = &delete_initial_display; + /* All other hooks are NULL. */ - display_list->type = output_termcap; - display_list->display_info.tty = tty_list; - - return display_list; + return initial_display; +} + +/* Deletes the bootstrap display device. + Called through delete_display_hook. */ +void +delete_initial_display (struct display *display) +{ + if (display != initial_display) + abort (); + + delete_display (display); + initial_display = NULL; } - +/* Create a termcap display on the tty device with the given name and + type. + + If NAME is NULL, then use the controlling tty, i.e., stdin/stdout. + Otherwise NAME should be a path to the tty device file, + e.g. "/dev/pts/7". + + TERMINAL_TYPE is the termcap type of the device, e.g. "vt100". + + If MUST_SUCCEED is true, then all errors are fatal. */ struct display * -term_init (char *name, char *terminal_type) +term_init (char *name, char *terminal_type, int must_succeed) { char *area; char **address = &area; @@ -2095,39 +2217,65 @@ struct tty_display_info *tty; struct display *display; + static void maybe_fatal(); + + if (!terminal_type) + maybe_fatal (must_succeed, 0, 0, + "Unknown terminal type", + "Unknown terminal type"); + display = get_named_tty_display (name); if (display) - { - tty = display->display_info.tty; - - /* Return the previously initialized terminal, except if it is - the dummy terminal created for the initial frame. */ - if (tty->type) - return display; - - /* Free up temporary structures. */ - if (tty->Wcm) - xfree (tty->Wcm); - if (tty->kboard != initial_kboard) - abort (); - tty->kboard = 0; - } - else - { - display = create_display (); - tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info)); - bzero (tty, sizeof (struct tty_display_info)); - tty->next = tty_list; - tty_list = tty; - - display->type = output_termcap; - display->display_info.tty = tty; - } + return display; /* We have already opened a display there. */ + + display = create_display (); + tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info)); + bzero (tty, sizeof (struct tty_display_info)); + tty->next = tty_list; + tty_list = tty; + + display->type = output_termcap; + display->display_info.tty = tty; + tty->display = display; tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm)); Wcm_clear (tty); display->rif = 0; /* ttys don't support window-based redisplay. */ + + display->cursor_to_hook = &tty_cursor_to; + display->raw_cursor_to_hook = &tty_raw_cursor_to; + + display->clear_to_end_hook = &tty_clear_to_end; + display->clear_frame_hook = &tty_clear_frame; + display->clear_end_of_line_hook = &tty_clear_end_of_line; + + display->ins_del_lines_hook = &tty_ins_del_lines; + + display->insert_glyphs_hook = &tty_insert_glyphs; + display->write_glyphs_hook = &tty_write_glyphs; + display->delete_glyphs_hook = &tty_delete_glyphs; + + display->ring_bell_hook = &tty_ring_bell; + + display->reset_terminal_modes_hook = &tty_reset_terminal_modes; + display->set_terminal_modes_hook = &tty_set_terminal_modes; + display->update_begin_hook = 0; /* Not needed. */ + display->update_end_hook = &tty_update_end; + display->set_terminal_window_hook = &tty_set_terminal_window; + + display->mouse_position_hook = 0; /* Not needed. */ + display->frame_rehighlight_hook = 0; /* Not needed. */ + display->frame_raise_lower_hook = 0; /* Not needed. */ + + display->set_vertical_scroll_bar_hook = 0; /* Not needed. */ + display->condemn_scroll_bars_hook = 0; /* Not needed. */ + display->redeem_scroll_bar_hook = 0; /* Not needed. */ + display->judge_scroll_bars_hook = 0; /* Not needed. */ + + display->read_socket_hook = 0; /* Not needed. */ + display->frame_up_to_date_hook = 0; /* Not needed. */ + display->delete_frame_hook = &delete_tty_output; display->delete_display_hook = &delete_tty; @@ -2196,55 +2344,35 @@ if (status < 0) { #ifdef TERMINFO - if (name) - { - xfree (buffer); - delete_tty (display); - error ("Cannot open terminfo database file"); - } - else - fatal ("Cannot open terminfo database file"); + maybe_fatal (must_succeed, buffer, display, + "Cannot open terminfo database file", + "Cannot open terminfo database file"); #else - if (name) - { - xfree (buffer); - delete_tty (display); - error ("Cannot open termcap database file"); - } - else - fatal ("Cannot open termcap database file"); + maybe_fatal (must_succeed, buffer, display, + "Cannot open termcap database file", + "Cannot open termcap database file"); #endif } if (status == 0) { #ifdef TERMINFO - if (name) - { - xfree (buffer); - delete_tty (display); - error ("Terminal type %s is not defined", terminal_type); - } - else - fatal ("Terminal type %s is not defined.\n\ + maybe_fatal (must_succeed, buffer, display, + "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); + terminal_type); #else - if (name) - { - xfree (buffer); - delete_tty (display); - error ("Terminal type %s is not defined", terminal_type); - } - else - fatal ("Terminal type %s is not defined.\n\ + maybe_fatal (must_succeed, buffer, display, + "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); + terminal_type); #endif } @@ -2384,19 +2512,10 @@ FrameRows (tty) = tgetnum ("li"); if (FrameRows (tty) < 3 || FrameCols (tty) < 3) - { - if (initialized) - { - delete_tty (display); - error ("Screen size %dx%d is too small", + maybe_fatal (must_succeed, NULL, display, + "Screen size %dx%d is too small" + "Screen size %dx%d is too small", FrameCols (tty), FrameRows (tty)); - } - else - { - fatal ("Screen size %dx%d is too small", - FrameCols (tty), FrameRows (tty)); - } - } #if 0 /* This is not used anywhere. */ tty->display->min_padding_speed = tgetnum ("pb"); @@ -2525,51 +2644,39 @@ tty->specified_window = FrameRows (tty); if (Wcm_init (tty) == -1) /* can't do cursor motion */ - if (name) - { - delete_tty (display); - error ("Terminal type \"%s\" is not powerful enough to run Emacs", - terminal_type); - } - else { + { + maybe_fatal (must_succeed, NULL, display, + "Terminal type \"%s\" is not powerful enough to run Emacs", #ifdef VMS - fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\ + "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.", - terminal_type); #else /* not VMS */ # ifdef TERMINFO - fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\ + "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.", - terminal_type); # else /* TERMCAP */ - fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\ + "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.", - terminal_type); # endif /* TERMINFO */ #endif /*VMS */ + terminal_type); } if (FrameRows (tty) <= 0 || FrameCols (tty) <= 0) - { - if (name) - { - delete_tty (display); - error ("The frame size has not been specified"); - } - else - fatal ("The frame size has not been specified"); - } + maybe_fatal (must_succeed, NULL, display, + "Could not determine the frame size", + "Could not determine the frame size"); tty->delete_in_insert_mode = tty->TS_delete_mode && tty->TS_insert_mode @@ -2635,6 +2742,31 @@ #endif /* not WINDOWSNT */ } +/* Auxiliary error-handling function for term_init. + Free BUFFER and delete DISPLAY, then call error or fatal + with str1 or str2, respectively, according to MUST_SUCCEED. +*/ +static void +maybe_fatal (must_succeed, buffer, display, str1, str2, arg1, arg2) + int must_succeed; + char *buffer; + struct display *display; + char *str1, *str2, *arg1, *arg2; +{ + if (buffer) + xfree (buffer); + + if (display) + delete_tty (display); + + if (must_succeed) + fatal (str2, arg1, arg2); + else + error (str1, arg1, arg2); + + abort (); +} + /* VARARGS 1 */ void fatal (str, arg1, arg2) @@ -2725,10 +2857,12 @@ } } + /* reset_sys_modes needs a valid display, so this call needs to be + before delete_display. */ + reset_sys_modes (tty); + delete_display (display); - reset_sys_modes (tty); - tty_name = tty->name; if (tty->type) xfree (tty->type);