diff options
author | Karoly Lorentey <lorentey@elte.hu> | 2004-01-02 01:15:26 +0000 |
---|---|---|
committer | Karoly Lorentey <lorentey@elte.hu> | 2004-01-02 01:15:26 +0000 |
commit | daf0170133e658c41f3ae2fc8558c5ab74227c1d (patch) | |
tree | fa6577e49c4c63a6ad6e672f9e3bd1a018cb61d0 /src | |
parent | 28d7d09f841801cd052bb4ba0df92016b9245870 (diff) | |
download | emacs-daf0170133e658c41f3ae2fc8558c5ab74227c1d.tar.gz emacs-daf0170133e658c41f3ae2fc8558c5ab74227c1d.tar.bz2 emacs-daf0170133e658c41f3ae2fc8558c5ab74227c1d.zip |
Fixed X support, preliminary support for X-tty combo sessions.
lib-src/emacsclient.c (copy_from_to, pty_conversation): Re-added SIGIO
hack. (Sigh.)
lisp/frame.el (make-frame-on-tty): Use make-terminal-frame, not
make-frame.
src/dispnew.c (line_hash_code, line_draw_cost): Updated to use
the new display_method parameters.
(Fredraw_frame): fflush the tty only if f is a termcap frame.
(direct_output_for_insert): Updated to use the new display_method
parameters. fflush the tty only if f is a termcap frame.
(direct_output_forward_char, update_frame_1, scrolling): Ditto.
(update_frame_line, Fding, bitch_at_user): Ditto.
(Fsend_string_to_terminal): Fail if current frame is not on a tty.
(init_display): Frame size change is safe here.
src/frame.c (Vterminal_frame): Restored previously deleted variable.
(syms_of_frame): Initialize it.
(make_terminal_frame): Copy the frame's display_method from tty_display_info.
(Fmake_terminal_frame): Enable simultaneous X and tty frames (buggy).
(Fredirect_frame_focus): Don't call frame_rehighlight_hook if frame
is on a termcap device.
src/frame.h (struct frame): Renamed display to display_method.
(Vterminal_frame): Re-added declaration.
src/keyboard.c (flow_control): Moved to struct tty_display_info.
(read_avail_input): Check ttys even if there is a read_socket_hook.
(Fset_input_mode): Call reset_sys_modes/init_sys_modes and set
flow_control or meta_key only when the frame is a termcap frame.
(Fcurrent_input_mode): Handle flow_control and meta_key right on
non-termcap frames.
src/scroll.c (calculate_scrolling, calculate_direct_scrolling): Update
to use the new display_method parameters.
(scrolling_1, scroll_cost): Ditto.
src/sysdep.c (init_sys_modes, reset_sys_modes): Always set the
terminal parameters if tty_out->input is not stdin. Updated to the
new location of flow_control.
(hft_init): Moved HFT init code to term_init, as it needs the frame.
src/term.c (tty_display_method_template): New variable.
(update_begin): Added rif hack.
(set_terminal_window, ins_del_lines, term_init): Updated to use the
new display_method parameters.
(insert_glyphs, ins_del_lines): Only call insert_glyphs_hook if the
current frame is not on a tty.
(calculate_costs): Don't calculate costs if not on a tty.
(term_dummy_init): Fixed tty->output initialization. Preallocate Wcm
and display_method.
(term_init): Allocate & initialize display_method. Blindly fixed
WINDOWSNT-specific parts. Added HFT-specific initialization
exception from hft_init.
(delete_tty): Only delete termcap frames. Free() the display_method.
src/termchar.h (struct tty_display_info): Moved high-level terminal
characteristics to struct display_method. Added flow_control and
display_method members.
src/termhooks.h (struct display_method): New struct (renamed from
struct device). Added accessor macros.
src/window.c (init_window_once): Initialize Vterminal_frame.
src/xdisp.c (init_iterator, expose_frame): Added rif hack.
(try_window_id): Updated to use the new display_method parameters.
src/xfaces.c (realize_basic_faces): Don't call
x_update_menu_appearance if the frame is a tty frame.
src/xfns.c (Fx_create_frame): Added rif hack. Initialize
display_method.
(x_create_tip_frame): Initialize display_method.
src/xterm.c (x_display_method): New variable.
(x_flush, x_frame_of_widget, XTmouse_position): Ignore non-X frames.
(x_window_to_scroll_bar, x_window_to_menu_bar): Ditto.
(xim_destroy_callback, xim_instantiate_callback): Ditto.
(frame_highlight, frame_unhighlight): Added rif hack.
(x_initialize): Don't initialize rif. Do initialize x_display_method.
src/xterm.h (x_display_method): New declaration.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-30
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.in | 2 | ||||
-rw-r--r-- | src/dispnew.c | 50 | ||||
-rw-r--r-- | src/frame.c | 13 | ||||
-rw-r--r-- | src/frame.h | 4 | ||||
-rw-r--r-- | src/keyboard.c | 50 | ||||
-rw-r--r-- | src/scroll.c | 9 | ||||
-rw-r--r-- | src/sysdep.c | 28 | ||||
-rw-r--r-- | src/term.c | 239 | ||||
-rw-r--r-- | src/termchar.h | 38 | ||||
-rw-r--r-- | src/termhooks.h | 39 | ||||
-rw-r--r-- | src/window.c | 1 | ||||
-rw-r--r-- | src/xdisp.c | 12 | ||||
-rw-r--r-- | src/xfaces.c | 3 | ||||
-rw-r--r-- | src/xfns.c | 6 | ||||
-rw-r--r-- | src/xterm.c | 111 | ||||
-rw-r--r-- | src/xterm.h | 3 |
16 files changed, 359 insertions, 249 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index e42c5099830..8a19441c53a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1111,7 +1111,7 @@ process.o: process.c process.h buffer.h window.h termhooks.h termopts.h \ regex.o: regex.c syntax.h buffer.h $(config_h) regex.h category.h charset.h region-cache.o: region-cache.c buffer.h region-cache.h scroll.o: scroll.c systty.h termchar.h dispextern.h frame.h msdos.h keyboard.h \ - $(config_h) + termhooks.h $(config_h) search.o: search.c regex.h commands.h buffer.h region-cache.h syntax.h \ blockinput.h atimer.h systime.h category.h charset.h composite.h $(config_h) strftime.o: strftime.c $(config_h) diff --git a/src/dispnew.c b/src/dispnew.c index 4401e2d2d56..9ccc87a6020 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -297,8 +297,10 @@ int glyph_pool_count; static struct frame *frame_matrix_frame; -/* Current interface for window-based redisplay. Set from init_xterm. - A null value means we are not using window-based redisplay. */ +/* Current interface for window-based redisplay. Set from + update_begin. A null value means we are not using window-based + redisplay. */ +/* XXX this variable causes frequent coredumps */ struct redisplay_interface *rif; @@ -1390,7 +1392,7 @@ line_hash_code (row) { int c = glyph->u.ch; int face_id = glyph->face_id; - if (TTY_MUST_WRITE_SPACES (CURTTY ())) + if (FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */ c -= SPACEGLYPH; hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c; hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + face_id; @@ -1422,7 +1424,7 @@ line_draw_cost (matrix, vpos) int glyph_table_len = GLYPH_TABLE_LENGTH; /* Ignore trailing and leading spaces if we can. */ - if (!TTY_MUST_WRITE_SPACES (CURTTY ())) + if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */ { /* Skip from the end over trailing spaces. */ while (end > beg && CHAR_GLYPH_SPACE_P (*(end - 1))) @@ -3317,7 +3319,8 @@ DEFUN ("redraw-frame", Fredraw_frame, Sredraw_frame, 1, 1, 0, clear_frame (); clear_current_matrices (f); update_end (f); - fflush (TTY_OUTPUT (FRAME_TTY (f))); + if (FRAME_TERMCAP_P (f)) + fflush (TTY_OUTPUT (FRAME_TTY (f))); windows_or_buffers_changed++; /* Mark all windows as inaccurate, so that every window will have its redisplay done. */ @@ -3457,7 +3460,7 @@ direct_output_for_insert (g) /* If we can't insert glyphs, we can use this method only at the end of a line. */ - if (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f))) + if (!FRAME_CHAR_INS_DEL_OK (f)) if (PT != ZV && FETCH_BYTE (PT_BYTE) != '\n') return 0; @@ -3654,7 +3657,8 @@ direct_output_for_insert (g) rif->update_window_end_hook (w, 1, 0); update_end (f); updated_row = NULL; - fflush (TTY_OUTPUT (CURTTY ())); + if (FRAME_TERMCAP_P (f)) + fflush (TTY_OUTPUT (FRAME_TTY (f))); TRACE ((stderr, "direct output for insert\n")); mark_window_display_accurate (it.window, 1); @@ -3745,7 +3749,8 @@ direct_output_forward_char (n) cursor_to (y, x); } - fflush (TTY_OUTPUT (CURTTY ())); + if (FRAME_TERMCAP_P (f)) + fflush (TTY_OUTPUT (FRAME_TTY (f))); redisplay_performed_directly_p = 1; return 1; } @@ -5070,7 +5075,7 @@ update_frame_1 (f, force_p, inhibit_id_p) } /* If we cannot insert/delete lines, it's no use trying it. */ - if (!TTY_LINE_INS_DEL_OK (FRAME_TTY (f))) + if (!FRAME_LINE_INS_DEL_OK (f)) inhibit_id_p = 1; /* See if any of the desired lines are enabled; don't compute for @@ -5288,7 +5293,7 @@ scrolling (frame) } /* If changed lines are few, don't allow preemption, don't scroll. */ - if ((!TTY_SCROLL_REGION_OK (FRAME_TTY (frame)) + if ((!FRAME_SCROLL_REGION_OK (frame) && changed_lines < baud_rate / 2400) || unchanged_at_bottom == FRAME_LINES (frame)) return 1; @@ -5296,14 +5301,14 @@ scrolling (frame) window_size = (FRAME_LINES (frame) - unchanged_at_top - unchanged_at_bottom); - if (TTY_SCROLL_REGION_OK (FRAME_TTY (frame))) + if (FRAME_SCROLL_REGION_OK (frame)) free_at_end_vpos -= unchanged_at_bottom; - else if (TTY_MEMORY_BELOW_FRAME (FRAME_TTY (frame))) + else if (FRAME_MEMORY_BELOW_FRAME (frame)) free_at_end_vpos = -1; /* If large window, fast terminal and few lines in common between current frame and desired frame, don't bother with i/d calc. */ - if (!TTY_SCROLL_REGION_OK (FRAME_TTY (frame)) + if (!FRAME_SCROLL_REGION_OK (frame) && window_size >= 18 && baud_rate > 2400 && (window_size >= 10 * scrolling_max_lines_saved (unchanged_at_top, @@ -5384,7 +5389,7 @@ update_frame_line (f, vpos) struct glyph_row *current_row = MATRIX_ROW (current_matrix, vpos); struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, vpos); int must_write_whole_line_p; - int write_spaces_p = TTY_MUST_WRITE_SPACES (FRAME_TTY (f)); + int write_spaces_p = FRAME_MUST_WRITE_SPACES (f); int colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background != FACE_TTY_DEFAULT_BG_COLOR); @@ -5463,7 +5468,7 @@ update_frame_line (f, vpos) nlen--; /* If there's no i/d char, quickly do the best we can without it. */ - if (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f))) + if (!FRAME_CHAR_INS_DEL_OK (f)) { int i, j; @@ -5566,7 +5571,7 @@ update_frame_line (f, vpos) tem = (nlen - nsp) - (olen - osp); if (endmatch && tem - && (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f)) + && (!FRAME_CHAR_INS_DEL_OK (f) || endmatch <= char_ins_del_cost (f)[tem])) endmatch = 0; @@ -5576,7 +5581,7 @@ update_frame_line (f, vpos) Is it worth it? */ if (nsp != osp - && (!TTY_CHAR_INS_DEL_OK (FRAME_TTY (f)) + && (!FRAME_CHAR_INS_DEL_OK (f) || begmatch + endmatch <= char_ins_del_cost (f)[nsp - osp])) { begmatch = 0; @@ -6167,6 +6172,9 @@ Control characters in STRING will have terminal-dependent effects. */) { /* ??? Perhaps we should do something special for multibyte strings here. */ CHECK_STRING (string); + if (! FRAME_TERMCAP_P (SELECTED_FRAME ())) + error ("Current frame is not on a tty device"); + if (TTY_TERMSCRIPT (CURTTY ())) { fwrite (SDATA (string), 1, SBYTES (string), @@ -6193,7 +6201,8 @@ terminate any keyboard macro currently executing. */) putchar (07); else ring_bell (); - fflush (TTY_OUTPUT (CURTTY ())); + if (FRAME_TERMCAP_P (XFRAME (selected_frame))) + fflush (TTY_OUTPUT (CURTTY ())); } else bitch_at_user (); @@ -6210,7 +6219,8 @@ bitch_at_user () error ("Keyboard macro terminated by a command ringing the bell"); else ring_bell (); - fflush (TTY_OUTPUT (CURTTY ())); + if (FRAME_TERMCAP_P (XFRAME (selected_frame))) + fflush (TTY_OUTPUT (CURTTY ())); } @@ -6628,7 +6638,7 @@ For types not defined in VMS, use define emacs_term \"TYPE\".\n\ struct tty_display_info *tty; tty = term_init (selected_frame, 0, terminal_type); - change_frame_size (XFRAME (selected_frame), FrameRows (tty), FrameCols (tty), 0, 0, 0); + change_frame_size (XFRAME (selected_frame), FrameRows (tty), FrameCols (tty), 0, 0, 1); } { diff --git a/src/frame.c b/src/frame.c index af2cd20c514..0b407181a6b 100644 --- a/src/frame.c +++ b/src/frame.c @@ -114,6 +114,7 @@ Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth; Lisp_Object Qface_set_after_frame_default; +Lisp_Object Vterminal_frame; Lisp_Object Vdefault_frame_alist; Lisp_Object Vdefault_frame_scroll_bars; Lisp_Object Vmouse_position_function; @@ -122,8 +123,8 @@ Lisp_Object Vdelete_frame_functions; static void set_menu_bar_lines_1 (window, n) - Lisp_Object window; - int n; + Lisp_Object window; + int n; { struct window *w = XWINDOW (window); @@ -565,6 +566,7 @@ make_terminal_frame (tty_name, tty_type) f->output_data.tty->display_info = term_dummy_init (); } FRAME_TTY (f)->reference_count++; + f->display_method = FRAME_TTY (f)->display_method; } #ifdef CANNOT_DUMP @@ -614,9 +616,11 @@ Note that changing the size of one terminal frame automatically affects all. */ if (sf->output_method != output_mac) error ("Not running on a Macintosh screen; cannot make a new Macintosh frame"); #else +#if 0 /* This should work now! */ if (sf->output_method != output_termcap) error ("Not using an ASCII terminal now; cannot make a new ASCII frame"); #endif +#endif #endif /* not MSDOS */ { @@ -1909,7 +1913,7 @@ The redirection lasts until `redirect-frame-focus' is called to change it. */) XFRAME (frame)->focus_frame = focus_frame; - if (frame_rehighlight_hook) + if (!FRAME_TERMCAP_P (XFRAME (frame)) && frame_rehighlight_hook) (*frame_rehighlight_hook) (XFRAME (frame)); return Qnil; @@ -4137,6 +4141,9 @@ Setting this variable does not affect existing frames, only new ones. */); = intern ("inhibit-default-face-x-resources"); staticpro (&Qinhibit_default_face_x_resources); + DEFVAR_LISP ("terminal-frame", &Vterminal_frame, + doc: /* The initial frame-object, which represents Emacs's stdout. */); + DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified, doc: /* Non-nil if all of emacs is iconified and frame updates are not needed. */); Vemacs_iconified = Qnil; diff --git a/src/frame.h b/src/frame.h index 5c4654632e1..4a67744edaa 100644 --- a/src/frame.h +++ b/src/frame.h @@ -257,7 +257,7 @@ struct frame int line_height; /* The display hooks to use with this frame. */ - struct display *display; + struct display_method *display_method; /* The output method says how the contents of this frame are displayed. It could be using termcap, or using an X window. */ @@ -783,6 +783,8 @@ extern int other_visible_frames P_ ((struct frame *)); extern Lisp_Object Vframe_list; extern Lisp_Object Vdefault_frame_alist; +extern Lisp_Object Vterminal_frame; + extern Lisp_Object Vmouse_highlight; /* The currently selected frame. */ diff --git a/src/keyboard.c b/src/keyboard.c index 1751df6a735..532257e797f 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -617,9 +617,6 @@ int interrupt_input; /* Nonzero while interrupts are temporarily deferred during redisplay. */ int interrupts_deferred; -/* Nonzero means use ^S/^Q for flow control. */ -int flow_control; - /* Allow m- file to inhibit use of FIONREAD. */ #ifdef BROKEN_FIONREAD #undef FIONREAD @@ -6605,7 +6602,8 @@ read_avail_input (expected) if (read_socket_hook) /* No need for FIONREAD or fcntl; just say don't wait. */ nread = (*read_socket_hook) (buf, KBD_BUFFER_SIZE, expected); - else + + if (!nread && tty_list) { /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than the kbd_buffer can really hold. That may prevent loss @@ -10433,7 +10431,8 @@ See also `current-input-mode'. */) #ifndef DOS_NT /* this causes startup screen to be restored and messes with the mouse */ - reset_sys_modes (CURTTY ()); + if (FRAME_TERMCAP_P (SELECTED_FRAME ())) + reset_sys_modes (CURTTY ()); #endif #ifdef SIGIO @@ -10459,19 +10458,25 @@ See also `current-input-mode'. */) interrupt_input = 1; #endif - flow_control = !NILP (flow); - if (NILP (meta)) - CURTTY ()->meta_key = 0; - else if (EQ (meta, Qt)) - CURTTY ()->meta_key = 1; - else - CURTTY ()->meta_key = 2; + if (FRAME_TERMCAP_P (XFRAME (selected_frame))) + { + struct tty_display_info *tty = CURTTY (); + tty->flow_control = !NILP (flow); + if (NILP (meta)) + tty->meta_key = 0; + else if (EQ (meta, Qt)) + tty->meta_key = 1; + else + tty->meta_key = 2; + } + if (!NILP (quit)) /* Don't let this value be out of range. */ quit_char = XINT (quit) & (CURTTY ()->meta_key ? 0377 : 0177); #ifndef DOS_NT - init_sys_modes (CURTTY ()); + if (FRAME_TERMCAP_P (XFRAME (selected_frame))) + init_sys_modes (CURTTY ()); #endif #ifdef POLL_FOR_INPUT @@ -10498,12 +10503,21 @@ The elements of this list correspond to the arguments of () { Lisp_Object val[4]; - + struct frame *sf = XFRAME (selected_frame); + val[0] = interrupt_input ? Qt : Qnil; - val[1] = flow_control ? Qt : Qnil; - val[2] = FRAME_TTY (SELECTED_FRAME ())->meta_key == 2 - ? make_number (0) - : FRAME_TTY (SELECTED_FRAME ())->meta_key == 1 ? Qt : Qnil; + if (FRAME_TERMCAP_P (sf)) + { + val[1] = FRAME_TTY (sf)->flow_control ? Qt : Qnil; + val[2] = FRAME_TTY (sf)->meta_key == 2 + ? make_number (0) + : CURTTY ()->meta_key == 1 ? Qt : Qnil; + } + else + { + val[1] = Qnil; + val[2] = Qt; + } XSETFASTINT (val[3], quit_char); return Flist (sizeof (val) / sizeof (val[0]), val); diff --git a/src/scroll.c b/src/scroll.c index c4371377e03..915b60ab4c5 100644 --- a/src/scroll.c +++ b/src/scroll.c @@ -29,6 +29,7 @@ Boston, MA 02111-1307, USA. */ #include "keyboard.h" #include "frame.h" #include "window.h" +#include "termhooks.h" /* All costs measured in characters. So no cost can exceed the area of a frame, measured in characters. @@ -102,7 +103,7 @@ calculate_scrolling (frame, matrix, window_size, lines_below, register int cost, cost1; int lines_moved = window_size - + (TTY_SCROLL_REGION_OK (FRAME_TTY (frame)) ? 0 : lines_below); + + (FRAME_SCROLL_REGION_OK (frame) ? 0 : lines_below); /* first_insert_cost[I] is the cost of doing the first insert-line at the i'th line of the lines we are considering, where I is origin 1 (as it is below). */ @@ -469,7 +470,7 @@ calculate_direct_scrolling (frame, matrix, window_size, lines_below, cost of scrolling by a distance of one. The extra cost is added once for consistency with the cost vectors */ scroll_overhead - = TTY_SCROLL_REGION_COST (FRAME_TTY (frame)) + extra_cost; + = FRAME_SCROLL_REGION_COST (frame) + extra_cost; /* initialize the top left corner of the matrix */ matrix->writecost = 0; @@ -821,7 +822,7 @@ scrolling_1 (frame, window_size, unchanged_at_top, unchanged_at_bottom, matrix = ((struct matrix_elt *) alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix)); - if (TTY_SCROLL_REGION_OK (FRAME_TTY (frame))) + if (FRAME_SCROLL_REGION_OK (frame)) { calculate_direct_scrolling (frame, matrix, window_size, unchanged_at_bottom, @@ -917,7 +918,7 @@ scroll_cost (frame, from, to, amount) if (amount == 0) return 0; - if (! TTY_SCROLL_REGION_OK (FRAME_TTY (frame))) + if (! FRAME_SCROLL_REGION_OK (frame)) limit = height; else if (amount > 0) limit += amount; diff --git a/src/sysdep.c b/src/sysdep.c index 7710c2ad8ce..502671ba0f6 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1368,7 +1368,7 @@ nil means don't delete them until `list-processes' is run. */); #ifdef HAVE_WINDOW_SYSTEM /* Emacs' window system on MSDOG uses the `internal terminal' and therefore needs the initialization code below. */ - if (!read_socket_hook && EQ (Vwindow_system, Qnil)) + if (tty_out->input != stdin || (!read_socket_hook && EQ (Vwindow_system, Qnil))) #endif { if (! tty_out->old_tty) @@ -1400,7 +1400,7 @@ nil means don't delete them until `list-processes' is run. */); tty.main.c_lflag &= ~IEXTEN; /* Disable other editing characters. */ #endif tty.main.c_lflag |= ISIG; /* Enable signals */ - if (flow_control) + if (tty_out->flow_control) { tty.main.c_iflag |= IXON; /* Enable start/stop output control */ #ifdef IXANY @@ -1454,7 +1454,7 @@ nil means don't delete them until `list-processes' is run. */); tty.main.c_cc[VDISCARD] = CDISABLE; #endif /* VDISCARD */ - if (flow_control) + if (tty_out->flow_control) { #ifdef VSTART tty.main.c_cc[VSTART] = '\021'; @@ -1490,7 +1490,7 @@ nil means don't delete them until `list-processes' is run. */); tty.main.c_cc[VSUSP] = 255; tty.main.c_cc[VDSUSP] = 255; #endif /* IBMR2AIX */ - if (flow_control) + if (tty_out->flow_control) { #ifdef VSTART tty.main.c_cc[VSTART] = '\021'; @@ -1511,7 +1511,7 @@ nil means don't delete them until `list-processes' is run. */); tty.main.tt_char |= TT$M_NOECHO; if (meta_key) tty.main.tt_char |= TT$M_EIGHTBIT; - if (flow_control) + if (tty_out->flow_control) tty.main.tt_char |= TT$M_TTSYNC; else tty.main.tt_char &= ~TT$M_TTSYNC; @@ -1538,7 +1538,7 @@ nil means don't delete them until `list-processes' is run. */); set this */ tty.tchars = new_tchars; tty.tchars.t_intrc = quit_char; - if (flow_control) + if (tty_out->flow_control) { tty.tchars.t_startc = '\021'; tty.tchars.t_stopc = '\023'; @@ -1573,17 +1573,17 @@ nil means don't delete them until `list-processes' is run. */); we have an unlocked terminal at the start. */ #ifdef TCXONC - if (!flow_control) ioctl (fileno (TTY_INPUT (tty_out)), TCXONC, 1); + if (!tty_out->flow_control) ioctl (fileno (TTY_INPUT (tty_out)), TCXONC, 1); #endif #ifndef APOLLO #ifdef TIOCSTART - if (!flow_control) ioctl (fileno (TTY_INPUT (tty_out)), TIOCSTART, 0); + if (!tty_out->flow_control) ioctl (fileno (TTY_INPUT (tty_out)), TIOCSTART, 0); #endif #endif #if defined (HAVE_TERMIOS) || defined (HPUX9) #ifdef TCOON - if (!flow_control) tcflow (fileno (TTY_INPUT (tty_out)), TCOON); + if (!tty_out->flow_control) tcflow (fileno (TTY_INPUT (tty_out)), TCOON); #endif #endif @@ -1658,6 +1658,7 @@ nil means don't delete them until `list-processes' is run. */); Lisp_Object tail, frame; FOR_EACH_FRAME (tail, frame) { + /* XXX This needs to be revised. */ if (FRAME_TERMCAP_P (XFRAME (frame)) && FRAME_TTY (XFRAME (frame)) == tty_out) init_frame_faces (XFRAME (frame)); @@ -1817,13 +1818,14 @@ reset_sys_modes (tty_out) #ifdef HAVE_WINDOW_SYSTEM /* Emacs' window system on MSDOG uses the `internal terminal' and therefore needs the clean-up code below. */ - if (!EQ (Vwindow_system, Qnil) + if (tty_out->input != stdin + || (!EQ (Vwindow_system, Qnil) #ifndef WINDOWSNT /* When running in tty mode on NT/Win95, we have a read_socket hook, but still need the rest of the clean-up code below. */ || read_socket_hook #endif - ) + )) return; #endif @@ -5156,10 +5158,6 @@ hft_init (struct tty_display_info *tty_out) keymap.hfkey[1].hf_char = 127; hftctl (0, HFSKBD, &buf); } - /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly - at times. */ - TTY_LINE_INS_DEL_OK (tty_out) = 0; - TTY_CHAR_INS_DEL_OK (tty_out) = 0; } /* Reset the rubout key to backspace. */ diff --git a/src/term.c b/src/term.c index cce411debe7..c8310b5b85b 100644 --- a/src/term.c +++ b/src/term.c @@ -267,6 +267,10 @@ int max_frame_cols; int max_frame_lines; +/* A template for tty display methods, with common values + preinitialized. */ +static struct display_method tty_display_method_template; + /* Frame currently being redisplayed; 0 if not currently redisplaying. (Direct output does not count). */ @@ -370,6 +374,8 @@ update_begin (f) struct frame *f; { updating_frame = f; + /* XXX rif hack */ + rif = f->display_method->rif; if (!FRAME_TERMCAP_P (f)) update_begin_hook (f); } @@ -401,7 +407,7 @@ set_terminal_window (size) { struct tty_display_info *tty = FRAME_TTY (f); tty->specified_window = size ? size : FRAME_LINES (f); - if (TTY_SCROLL_REGION_OK (tty)) + if (FRAME_SCROLL_REGION_OK (f)) set_scroll_region (0, tty->specified_window); } else @@ -537,7 +543,7 @@ cursor_to (vpos, hpos) { struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); struct tty_display_info *tty; - + if (! FRAME_TERMCAP_P (f) && cursor_to_hook) { (*cursor_to_hook) (vpos, hpos); @@ -595,7 +601,7 @@ clear_to_end () struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); struct tty_display_info *tty; - + if (clear_to_end_hook && ! FRAME_TERMCAP_P (f)) { (*clear_to_end_hook) (); @@ -624,7 +630,7 @@ clear_frame () { struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); struct tty_display_info *tty; - + if (clear_frame_hook && ! FRAME_TERMCAP_P (f)) { (*clear_frame_hook) (); @@ -655,9 +661,8 @@ clear_end_of_line (first_unused_hpos) { struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); struct tty_display_info *tty; - - if (clear_end_of_line_hook - && ! FRAME_TERMCAP_P (f)) + + if (clear_end_of_line_hook && ! FRAME_TERMCAP_P (f)) { (*clear_end_of_line_hook) (first_unused_hpos); return; @@ -822,8 +827,7 @@ write_glyphs (string, len) unsigned char conversion_buffer[1024]; int conversion_buffer_size = sizeof conversion_buffer; - if (write_glyphs_hook - && ! FRAME_TERMCAP_P (f)) + if (write_glyphs_hook && ! FRAME_TERMCAP_P (f)) { (*write_glyphs_hook) (string, len); return; @@ -924,17 +928,18 @@ insert_glyphs (start, len) struct glyph *glyph = NULL; struct frame *f; struct tty_display_info *tty; - + if (len <= 0) return; - if (insert_glyphs_hook) + f = (updating_frame ? updating_frame : XFRAME (selected_frame)); + + if (insert_glyphs_hook && ! FRAME_TERMCAP_P (f)) { (*insert_glyphs_hook) (start, len); return; } - f = (updating_frame ? updating_frame : XFRAME (selected_frame)); tty = FRAME_TTY (f); if (tty->TS_ins_multi_chars) @@ -1034,7 +1039,7 @@ delete_glyphs (n) turn_off_insert (tty); OUTPUT_IF (tty, tty->TS_delete_mode); } - + if (tty->TS_del_multi_chars) { buf = tparam (tty->TS_del_multi_chars, 0, 0, n); @@ -1066,10 +1071,10 @@ ins_del_lines (vpos, n) 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 @@ -1077,13 +1082,13 @@ ins_del_lines (vpos, n) /* 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 (TTY_SCROLL_REGION_OK (tty) + if (FRAME_SCROLL_REGION_OK (f) && vpos + i >= tty->specified_window) return; - if (!TTY_MEMORY_BELOW_FRAME (tty) + if (!FRAME_MEMORY_BELOW_FRAME (f) && vpos + i >= FRAME_LINES (f)) return; - + if (multi) { raw_cursor_to (vpos, 0); @@ -1113,9 +1118,9 @@ ins_del_lines (vpos, n) OUTPUTL (tty, scroll, tty->specified_window - vpos); set_scroll_region (0, tty->specified_window); } - - if (!TTY_SCROLL_REGION_OK (tty) - && TTY_MEMORY_BELOW_FRAME (tty) + + if (!FRAME_SCROLL_REGION_OK (f) + && FRAME_MEMORY_BELOW_FRAME (f) && n < 0) { cursor_to (FRAME_LINES (f) + n, 0); @@ -1243,60 +1248,64 @@ void calculate_costs (frame) FRAME_PTR frame; { - struct tty_display_info *tty = FRAME_TTY (frame); - register char *f = (tty->TS_set_scroll_region - ? tty->TS_set_scroll_region - : tty->TS_set_scroll_region_1); - FRAME_COST_BAUD_RATE (frame) = baud_rate; if (FRAME_TERMCAP_P (frame)) - TTY_SCROLL_REGION_COST (FRAME_TTY (frame)) = string_cost (f); + { + struct tty_display_info *tty = FRAME_TTY (frame); + register char *f = (tty->TS_set_scroll_region + ? tty->TS_set_scroll_region + : tty->TS_set_scroll_region_1); - /* These variables are only used for terminal stuff. They are allocated - once for the terminal frame of X-windows emacs, but not used afterwards. + FRAME_SCROLL_REGION_COST (frame) = string_cost (f); - char_ins_del_vector (i.e., char_ins_del_cost) isn't used because - X turns off char_ins_del_ok. */ + tty->costs_set = 1; - max_frame_lines = max (max_frame_lines, FRAME_LINES (frame)); - max_frame_cols = max (max_frame_cols, FRAME_COLS (frame)); + /* These variables are only used for terminal stuff. They are + allocated once for the terminal frame of X-windows emacs, but not + used afterwards. - tty->costs_set = 1; + char_ins_del_vector (i.e., char_ins_del_cost) isn't used because + X turns off char_ins_del_ok. */ - if (char_ins_del_vector != 0) - char_ins_del_vector - = (int *) xrealloc (char_ins_del_vector, - (sizeof (int) - + 2 * max_frame_cols * sizeof (int))); - else - char_ins_del_vector - = (int *) xmalloc (sizeof (int) - + 2 * max_frame_cols * sizeof (int)); - - bzero (char_ins_del_vector, (sizeof (int) - + 2 * max_frame_cols * sizeof (int))); - - if (f && (!tty->TS_ins_line && !tty->TS_del_line)) - do_line_insertion_deletion_costs (frame, - tty->TS_rev_scroll, tty->TS_ins_multi_lines, - tty->TS_fwd_scroll, tty->TS_del_multi_lines, - f, f, 1); - else - do_line_insertion_deletion_costs (frame, - tty->TS_ins_line, tty->TS_ins_multi_lines, - tty->TS_del_line, tty->TS_del_multi_lines, - 0, 0, 1); + max_frame_lines = max (max_frame_lines, FRAME_LINES (frame)); + max_frame_cols = max (max_frame_cols, FRAME_COLS (frame)); - calculate_ins_del_char_costs (frame); + if (char_ins_del_vector != 0) + char_ins_del_vector + = (int *) xrealloc (char_ins_del_vector, + (sizeof (int) + + 2 * max_frame_cols * sizeof (int))); + else + char_ins_del_vector + = (int *) xmalloc (sizeof (int) + + 2 * max_frame_cols * sizeof (int)); - /* Don't use TS_repeat if its padding is worse than sending the chars */ - if (tty->TS_repeat && per_line_cost (tty->TS_repeat) * baud_rate < 9000) - tty->RPov = string_cost (tty->TS_repeat); - else - tty->RPov = FRAME_COLS (frame) * 2; + bzero (char_ins_del_vector, (sizeof (int) + + 2 * max_frame_cols * sizeof (int))); + + + if (f && (!tty->TS_ins_line && !tty->TS_del_line)) + do_line_insertion_deletion_costs (frame, + tty->TS_rev_scroll, tty->TS_ins_multi_lines, + tty->TS_fwd_scroll, tty->TS_del_multi_lines, + f, f, 1); + else + do_line_insertion_deletion_costs (frame, + tty->TS_ins_line, tty->TS_ins_multi_lines, + tty->TS_del_line, tty->TS_del_multi_lines, + 0, 0, 1); + + calculate_ins_del_char_costs (frame); + + /* Don't use TS_repeat if its padding is worse than sending the chars */ + if (tty->TS_repeat && per_line_cost (tty->TS_repeat) * baud_rate < 9000) + tty->RPov = string_cost (tty->TS_repeat); + else + tty->RPov = FRAME_COLS (frame) * 2; - cmcostinit (FRAME_TTY (frame)); /* set up cursor motion costs */ + cmcostinit (FRAME_TTY (frame)); /* set up cursor motion costs */ + } } struct fkey_table { @@ -2142,7 +2151,7 @@ DEFUN ("frame-tty-type", Fframe_tty_type, Sframe_tty_type, 0, 1, 0, Lisp_Object frame; { struct frame *f; - + if (NILP (frame)) { f = XFRAME (selected_frame); @@ -2177,7 +2186,9 @@ term_dummy_init (void) bzero (tty_list, sizeof (struct tty_display_info)); tty_list->name = 0; tty_list->input = stdin; - tty_list->input = stdout; + tty_list->output = stdout; + tty_list->Wcm = (struct cm *) xmalloc (sizeof (struct cm)); + tty_list->display_method = (struct display_method *) xmalloc (sizeof (struct display_method)); return tty_list; } @@ -2211,7 +2222,18 @@ term_init (Lisp_Object frame, char *name, char *terminal_type) } if (! tty->Wcm) - tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm)); + tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm)); + + if (! tty->display_method) + tty->display_method = (struct display_method *) xmalloc (sizeof (struct display_method)); + + /* Initialize the common members in the new display method with our + predefined template. */ + *tty->display_method = tty_display_method_template; + f->display_method = tty->display_method; + + /* Termcap-based displays don't support window-based redisplay. */ + f->display_method->rif = 0; /* Make sure the frame is live; if an error happens, it must be deleted. */ @@ -2219,7 +2241,6 @@ term_init (Lisp_Object frame, char *name, char *terminal_type) if (! f->output_data.tty) abort (); f->output_data.tty->display_info = tty; - if (name) { int fd; @@ -2245,7 +2266,7 @@ term_init (Lisp_Object frame, char *name, char *terminal_type) tty->type = xstrdup (terminal_type); add_keyboard_wait_descriptor (fileno (tty->input)); - + #ifdef WINDOWSNT initialize_w32_display (); @@ -2253,22 +2274,21 @@ term_init (Lisp_Object frame, char *name, char *terminal_type) area = (char *) xmalloc (2044); - FrameRows = FRAME_LINES (f); - FrameCols = FRAME_COLS (f); - specified_window = FRAME_LINES (f); + FrameRows (tty) = FRAME_LINES (f); + FrameCols (tty) = FRAME_COLS (f); + tty->specified_window = FRAME_LINES (f); - delete_in_insert_mode = 1; + f->display_method->delete_in_insert_mode = 1; - UseTabs = 0; - TTY_SCROLL_REGION_OK (tty) = 0; + UseTabs (tty) = 0; + FRAME_SCROLL_REGION_OK (f) = 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. */ - TTY_LINE_INS_DEL_OK (tty) = 0; - - TTY_CHAR_INS_DEL_OK (tty) = 1; + FRAME_LINE_INS_DEL_OK (f) = 0; + FRAME_CHAR_INS_DEL_OK (f) = 1; baud_rate = 19200; @@ -2449,9 +2469,9 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", /* Since we make MagicWrap terminals look like AutoWrap, we need to have the former flag imply the latter. */ AutoWrap (tty) = MagicWrap (tty) || tgetflag ("am"); - TTY_MEMORY_BELOW_FRAME (tty) = tgetflag ("db"); + FRAME_MEMORY_BELOW_FRAME (f) = tgetflag ("db"); tty->TF_hazeltine = tgetflag ("hz"); - TTY_MUST_WRITE_SPACES (tty) = tgetflag ("in"); + FRAME_MUST_WRITE_SPACES (f) = tgetflag ("in"); tty->meta_key = tgetflag ("km") || tgetflag ("MT"); tty->TF_insmode_motion = tgetflag ("mi"); tty->TF_standout_motion = tgetflag ("ms"); @@ -2489,7 +2509,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", } #if 0 /* This is not used anywhere. */ - TTY_MIN_PADDING_SPEED (tty) = tgetnum ("pb"); + f->display_method->min_padding_speed = tgetnum ("pb"); #endif TabWidth (tty) = tgetnum ("tw"); @@ -2567,7 +2587,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", if (!strcmp (terminal_type, "supdup")) { - TTY_MEMORY_BELOW_FRAME (tty) = 1; + FRAME_MEMORY_BELOW_FRAME (f) = 1; tty->Wcm->cm_losewrap = 1; } if (!strncmp (terminal_type, "c10", 3) @@ -2577,7 +2597,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", This string is not valid in general since it works only for windows starting at the upper left corner; but that is all Emacs uses. - + This string works only if the frame is using the top of the video memory, because addressing is memory-relative. So first check the :ti string to see if that is true. @@ -2594,7 +2614,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", tty->TS_set_window = "\033v%C %C %C %C "; } /* Termcap entry often fails to have :in: flag */ - TTY_MUST_WRITE_SPACES (tty) = 1; + FRAME_MUST_WRITE_SPACES (f) = 1; /* :ti string typically fails to have \E^G! in it */ /* This limits scope of insert-char to one line. */ strcpy (area, tty->TS_termcap_modes); @@ -2649,7 +2669,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", # endif /* TERMINFO */ #endif /*VMS */ } - + if (FrameRows (tty) <= 0 || FrameCols (tty) <= 0) { if (name) @@ -2671,22 +2691,22 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", UseTabs (tty) = tabs_safe_p (fileno (TTY_INPUT (tty))) && TabWidth (tty) == 8; - TTY_SCROLL_REGION_OK (tty) + FRAME_SCROLL_REGION_OK (f) = (tty->Wcm->cm_abs && (tty->TS_set_window || tty->TS_set_scroll_region || tty->TS_set_scroll_region_1)); - TTY_LINE_INS_DEL_OK (tty) + FRAME_LINE_INS_DEL_OK (f) = (((tty->TS_ins_line || tty->TS_ins_multi_lines) && (tty->TS_del_line || tty->TS_del_multi_lines)) - || (TTY_SCROLL_REGION_OK (tty) + || (FRAME_SCROLL_REGION_OK (f) && tty->TS_fwd_scroll && tty->TS_rev_scroll)); - TTY_CHAR_INS_DEL_OK (tty) + FRAME_CHAR_INS_DEL_OK (f) = ((tty->TS_ins_char || tty->TS_insert_mode || tty->TS_pad_inserted_char || tty->TS_ins_multi_chars) && (tty->TS_del_char || tty->TS_del_multi_chars)); - TTY_FAST_CLEAR_END_OF_LINE (tty) = tty->TS_clr_line != 0; + FRAME_FAST_CLEAR_END_OF_LINE (f) = tty->TS_clr_line != 0; init_baud_rate (fileno (TTY_INPUT (tty))); if (read_socket_hook) /* Baudrate is somewhat @@ -2696,14 +2716,22 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; +#ifdef AIXHFT + /* The HFT system on AIX doesn't optimize for scrolling, so it's + really ugly at times. */ + FRAME_LINE_INS_DEL_OK (f) = 0; + FRAME_CHAR_INS_DEL_OK (f) = 0; +#endif + /* Don't do this. I think termcap may still need the buffer. */ /* xfree (buffer); */ + /* Set the top frame to the first frame on this display. */ tty->top_frame = frame; - + /* Init system terminal modes (RAW or CBREAK, etc.). */ init_sys_modes (tty); - + tty_set_terminal_modes (tty); return tty; @@ -2733,7 +2761,7 @@ DEFUN ("delete-tty", Fdelete_tty, Sdelete_tty, 0, 1, 0, char *name = 0; CHECK_STRING (tty); - + if (SBYTES (tty) > 0) { name = (char *) alloca (SBYTES (tty) + 1); @@ -2745,7 +2773,7 @@ DEFUN ("delete-tty", Fdelete_tty, Sdelete_tty, 0, 1, 0, if (! t) error ("No such tty device: %s", name); - + delete_tty (t); } @@ -2755,14 +2783,14 @@ void delete_tty (struct tty_display_info *tty) { Lisp_Object tail, frame; - + if (deleting_tty) /* We get a recursive call when we delete the last frame on this tty. */ return; deleting_tty = 1; - + if (tty == tty_list) tty_list = tty->next; else @@ -2782,20 +2810,20 @@ delete_tty (struct tty_display_info *tty) FOR_EACH_FRAME (tail, frame) { struct frame *f = XFRAME (frame); - if (FRAME_LIVE_P (f) && FRAME_TTY (f) == tty) + if (FRAME_TERMCAP_P (f) && FRAME_LIVE_P (f) && FRAME_TTY (f) == tty) { Fdelete_frame (frame, Qt); f->output_data.tty = 0; } } - + reset_sys_modes (tty); if (tty->name) xfree (tty->name); if (tty->type) xfree (tty->type); - + if (tty->input) { delete_keyboard_wait_descriptor (fileno (tty->input)); @@ -2806,13 +2834,16 @@ delete_tty (struct tty_display_info *tty) fclose (tty->output); if (tty->termscript) fclose (tty->termscript); - + if (tty->old_tty) xfree (tty->old_tty); if (tty->Wcm) - xfree (tty->Wcm); - + xfree (tty->Wcm); + + if (tty->display_method) + xfree (tty->display_method); + bzero (tty, sizeof (struct tty_display_info)); xfree (tty); deleting_tty = 0; @@ -2865,7 +2896,9 @@ The function should accept no arguments. */); defsubr (&Sframe_tty_name); defsubr (&Sframe_tty_type); defsubr (&Sdelete_tty); - + + /* XXX tty_display_method_template initialization will go here. */ + Fprovide (intern ("multi-tty"), Qnil); } diff --git a/src/termchar.h b/src/termchar.h index 49b1be87bea..c54c1dde061 100644 --- a/src/termchar.h +++ b/src/termchar.h @@ -64,29 +64,6 @@ struct tty_display_info /* The previous terminal frame we displayed on this tty. */ struct frame *previous_terminal_frame; - /* Terminal characteristics. */ - - int must_write_spaces; /* Nonzero means spaces in the text must - actually be output; can't just skip over - some columns to leave them blank. */ - int fast_clear_end_of_line; /* Nonzero means terminal has a `ce' string */ - - int line_ins_del_ok; /* Terminal can insert and delete lines */ - int char_ins_del_ok; /* Terminal can insert and delete chars */ - int scroll_region_ok; /* Terminal supports setting the scroll - window */ - int scroll_region_cost; /* Cost of setting the scroll window, - measured in characters. */ - int memory_below_frame; /* Terminal remembers lines scrolled - off bottom */ - -#if 0 /* These are not used anywhere. */ - /* EMACS_INT baud_rate; */ /* Output speed in baud */ - int min_padding_speed; /* Speed below which no padding necessary. */ - int dont_calculate_costs; /* Nonzero means don't bother computing - various cost tables; we won't use them. */ -#endif - /* Strings, numbers and flags taken from the termcap entry. */ char *TS_ins_line; /* "al" */ @@ -198,6 +175,13 @@ struct tty_display_info /* Flag used in tty_show/hide_cursor. */ int cursor_hidden; + + /* Nonzero means use ^S/^Q for flow control. */ + int flow_control; + + /* This is a copy of struct frame's display_method value; needed for + freeing up memory when deleting the tty. */ + struct display_method *display_method; }; /* A chain of structures for all tty devices currently in use. */ @@ -215,13 +199,5 @@ extern struct tty_display_info *tty_list; #define TTY_OUTPUT(t) ((t)->output) #define TTY_TERMSCRIPT(t) ((t)->termscript) -#define TTY_MUST_WRITE_SPACES(t) ((t)->must_write_spaces) -#define TTY_FAST_CLEAR_END_OF_LINE(t) ((t)->fast_clear_end_of_line) -#define TTY_LINE_INS_DEL_OK(t) ((t)->line_ins_del_ok) -#define TTY_CHAR_INS_DEL_OK(t) ((t)->char_ins_del_ok) -#define TTY_SCROLL_REGION_OK(t) ((t)->scroll_region_ok) -#define TTY_SCROLL_REGION_COST(t) ((t)->scroll_region_cost) -#define TTY_MEMORY_BELOW_FRAME(t) ((t)->memory_below_frame) - /* arch-tag: bf9f0d49-842b-42fb-9348-ec8759b27193 (do not change this comment) */ diff --git a/src/termhooks.h b/src/termhooks.h index 0802ec50d95..0d7818ab818 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -31,11 +31,46 @@ struct frame; #endif /* Device-local parameters. */ -struct device +struct display_method { + /* Terminal characteristics. */ + + int must_write_spaces; /* Nonzero means spaces in the text must + actually be output; can't just skip over + some columns to leave them blank. */ + int fast_clear_end_of_line; /* Nonzero means terminal has a `ce' string */ + + int line_ins_del_ok; /* Terminal can insert and delete lines */ + int char_ins_del_ok; /* Terminal can insert and delete chars */ + int scroll_region_ok; /* Terminal supports setting the scroll + window */ + int scroll_region_cost; /* Cost of setting the scroll window, + measured in characters. */ + int memory_below_frame; /* Terminal remembers lines scrolled + off bottom */ + +#if 0 /* These are not used anywhere. */ + /* EMACS_INT baud_rate; */ /* Output speed in baud */ + int min_padding_speed; /* Speed below which no padding necessary. */ + int dont_calculate_costs; /* Nonzero means don't bother computing + various cost tables; we won't use them. */ +#endif + + /* Window-based redisplay interface for this frame (0 for termcap + frames). */ + struct redisplay_interface *rif; + /* XXX Display hooks will go here. */ }; +#define FRAME_MUST_WRITE_SPACES(f) ((f)->display_method->must_write_spaces) +#define FRAME_FAST_CLEAR_END_OF_LINE(f) ((f)->display_method->fast_clear_end_of_line) +#define FRAME_LINE_INS_DEL_OK(f) ((f)->display_method->line_ins_del_ok) +#define FRAME_CHAR_INS_DEL_OK(f) ((f)->display_method->char_ins_del_ok) +#define FRAME_SCROLL_REGION_OK(f) ((f)->display_method->scroll_region_ok) +#define FRAME_SCROLL_REGION_COST(f) ((f)->display_method->scroll_region_cost) +#define FRAME_MEMORY_BELOW_FRAME(f) ((f)->display_method->memory_below_frame) + /* Text display hooks. */ extern void (*cursor_to_hook) P_ ((int vpos, int hpos)); @@ -432,7 +467,7 @@ enum { meta_modifier = CHAR_META /* Under X, the XK_Meta_[LR] keysyms. */ }; -#endif +#endif /* CONSP */ /* arch-tag: 33a00ecc-52b5-4186-a410-8801ac9f087d (do not change this comment) */ diff --git a/src/window.c b/src/window.c index 4efc43bb9ce..48e517a68f7 100644 --- a/src/window.c +++ b/src/window.c @@ -6384,6 +6384,7 @@ init_window_once () { struct frame *f = make_terminal_frame (0, 0); XSETFRAME (selected_frame, f); + Vterminal_frame = selected_frame; minibuf_window = f->minibuffer_window; selected_window = f->selected_window; last_nonminibuf_frame = f; diff --git a/src/xdisp.c b/src/xdisp.c index 2c83246b9f4..e2decba9066 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -2008,6 +2008,9 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id) XSETWINDOW (it->window, w); it->w = w; it->f = XFRAME (w->frame); + + /* XXX rif hack: Make sure the redisplay interface is correctly set. */ + rif = it->f->display_method->rif; /* Extra space between lines (on window systems only). */ if (base_face_id == DEFAULT_FACE_ID @@ -12899,7 +12902,7 @@ try_window_id (w) /* Window must either use window-based redisplay or be full width. */ if (!FRAME_WINDOW_P (f) - && (!TTY_LINE_INS_DEL_OK (CURTTY ()) + && (!FRAME_LINE_INS_DEL_OK (f) || !WINDOW_FULL_WIDTH_P (w))) GIVE_UP (4); @@ -13332,7 +13335,7 @@ try_window_id (w) /* On dumb terminals delete dvpos lines at the end before inserting dvpos empty lines. */ - if (!TTY_SCROLL_REGION_OK (FRAME_TTY (f))) + if (!FRAME_SCROLL_REGION_OK (f)) ins_del_lines (end - dvpos, -dvpos); /* Insert dvpos empty lines in front of @@ -13353,7 +13356,7 @@ try_window_id (w) /* On a dumb terminal insert dvpos empty lines at the end. */ - if (!TTY_SCROLL_REGION_OK (FRAME_TTY (f))) + if (!FRAME_SCROLL_REGION_OK (f)) ins_del_lines (end + dvpos, -dvpos); } @@ -21194,6 +21197,9 @@ expose_frame (f, x, y, w, h) TRACE ((stderr, "expose_frame ")); + /* XXX rif hack: Make sure redisplay interface is updated. */ + rif = f->display_method->rif; + /* No need to redraw if frame will be redrawn soon. */ if (FRAME_GARBAGED_P (f)) { diff --git a/src/xfaces.c b/src/xfaces.c index 47f406d7012..7b3637b1a6a 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -6640,7 +6640,8 @@ realize_basic_faces (f) { FRAME_FACE_CACHE (f)->menu_face_changed_p = 0; #ifdef USE_X_TOOLKIT - x_update_menu_appearance (f); + if (FRAME_WINDOW_P (f)) + x_update_menu_appearance (f); #endif } diff --git a/src/xfns.c b/src/xfns.c index 4d9733bdc95..3306173580c 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -3191,6 +3191,9 @@ This function is an internal primitive--use `make-frame' instead. */) check_x (); + /* XXX rif hack:Make sure rif is set to the right value. */ + rif = x_display_method.rif; + /* Use this general default value to start with until we know if this frame has a specified name. */ Vx_resource_name = Vinvocation_name; @@ -3245,6 +3248,7 @@ This function is an internal primitive--use `make-frame' instead. */) /* Note that X Windows does support scroll bars. */ FRAME_CAN_HAVE_SCROLL_BARS (f) = 1; + f->display_method = &x_display_method; f->output_method = output_x_window; f->output_data.x = (struct x_output *) xmalloc (sizeof (struct x_output)); bzero (f->output_data.x, sizeof (struct x_output)); @@ -9980,6 +9984,8 @@ x_create_tip_frame (dpyinfo, parms, text) FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; record_unwind_protect (unwind_create_tip_frame, frame); + f->display_method = &x_display_method; + /* By setting the output method, we're essentially saying that the frame is live, as per FRAME_LIVE_P. If we get a signal from this point on, x_destroy_window might screw up reference diff --git a/src/xterm.c b/src/xterm.c index e01a5e540fd..01b500f1915 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -184,6 +184,10 @@ static Lisp_Object last_window; int x_use_underline_position_properties; +/* Generic display parameters for X displays. */ + +struct display_method x_display_method; + /* This is a chain of structures for all the X displays currently in use. */ @@ -382,7 +386,8 @@ x_flush (f) { Lisp_Object rest, frame; FOR_EACH_FRAME (rest, frame) - x_flush (XFRAME (frame)); + if (FRAME_X_P (XFRAME (frame))) + x_flush (XFRAME (frame)); } else if (FRAME_X_P (f)) XFlush (FRAME_X_DISPLAY (f)); @@ -469,7 +474,6 @@ x_update_begin (f) /* Nothing to do. */ } - /* Start update of window W. Set the global variable updated_window to the window being updated and set output_cursor to the cursor position of W. */ @@ -1365,7 +1369,8 @@ x_frame_of_widget (widget) for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail)) if (GC_FRAMEP (XCAR (tail)) && (f = XFRAME (XCAR (tail)), - (f->output_data.nothing != 1 + (FRAME_X_P (f) + && f->output_data.nothing != 1 && FRAME_X_DISPLAY_INFO (f) == dpyinfo)) && f->output_data.x->widget == widget) return f; @@ -3057,6 +3062,9 @@ static void frame_highlight (f) struct frame *f; { + /* XXX hack: make sure rif is right. */ + rif = f->display_method->rif; + /* We used to only do this if Vx_no_window_manager was non-nil, but the ICCCM (section 4.1.6) says that the window's border pixmap and border pixel are window attributes which are "private to the @@ -3072,6 +3080,9 @@ static void frame_unhighlight (f) struct frame *f; { + /* XXX hack: make sure rif is right. */ + rif = f->display_method->rif; + /* We used to only do this if Vx_no_window_manager was non-nil, but the ICCCM (section 4.1.6) says that the window's border pixmap and border pixel are window attributes which are "private to the @@ -3663,7 +3674,8 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time) /* Clear the mouse-moved flag for every frame on this display. */ FOR_EACH_FRAME (tail, frame) - if (FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp)) + if (FRAME_X_P (XFRAME (frame)) + && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp)) XFRAME (frame)->mouse_moved = 0; last_mouse_scroll_bar = Qnil; @@ -3877,6 +3889,9 @@ x_window_to_scroll_bar (display, window_id) if (! GC_FRAMEP (frame)) abort (); + if (! FRAME_X_P (XFRAME (frame))) + continue; + /* Scan this frame's scroll bar list for a scroll bar with the right window ID. */ condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame)); @@ -3911,11 +3926,14 @@ x_window_to_menu_bar (window) XGCTYPE (tail) == Lisp_Cons; tail = XCDR (tail)) { - Lisp_Object frame = XCAR (tail); - Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget; + if (FRAME_X_P (XFRAME (XCAR (tail)))) + { + Lisp_Object frame = XCAR (tail); + Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget; - if (menu_bar && xlwmenu_window_p (menu_bar, window)) - return menu_bar; + if (menu_bar && xlwmenu_window_p (menu_bar, window)) + return menu_bar; + } } return NULL; @@ -8027,7 +8045,7 @@ xim_destroy_callback (xim, client_data, call_data) FOR_EACH_FRAME (tail, frame) { struct frame *f = XFRAME (frame); - if (FRAME_X_DISPLAY_INFO (f) == dpyinfo) + if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo) { FRAME_XIC (f) = NULL; if (FRAME_XIC_FONTSET (f)) @@ -8130,7 +8148,8 @@ xim_instantiate_callback (display, client_data, call_data) { struct frame *f = XFRAME (frame); - if (FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo) + if (FRAME_X_P (f) + && FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo) if (FRAME_XIC (f) == NULL) { create_frame_xic (f); @@ -10801,43 +10820,41 @@ x_process_timeouts (timer) extern frame_parm_handler x_frame_parm_handlers[]; static struct redisplay_interface x_redisplay_interface = -{ - x_frame_parm_handlers, - x_produce_glyphs, - x_write_glyphs, - x_insert_glyphs, - x_clear_end_of_line, - x_scroll_run, - x_after_update_window_line, - x_update_window_begin, - x_update_window_end, - x_cursor_to, - x_flush, + { + x_frame_parm_handlers, + x_produce_glyphs, + x_write_glyphs, + x_insert_glyphs, + x_clear_end_of_line, + x_scroll_run, + x_after_update_window_line, + x_update_window_begin, + x_update_window_end, + x_cursor_to, + x_flush, #ifndef XFlush - x_flush, + x_flush, #else - 0, /* flush_display_optional */ + 0, /* flush_display_optional */ #endif - x_clear_window_mouse_face, - x_get_glyph_overhangs, - x_fix_overlapping_area, - x_draw_fringe_bitmap, - x_per_char_metric, - x_encode_char, - x_compute_glyph_string_overhangs, - x_draw_glyph_string, - x_define_frame_cursor, - x_clear_frame_area, - x_draw_window_cursor, - x_draw_vertical_window_border, - x_shift_glyphs_for_insert -}; + x_clear_window_mouse_face, + x_get_glyph_overhangs, + x_fix_overlapping_area, + x_draw_fringe_bitmap, + x_per_char_metric, + x_encode_char, + x_compute_glyph_string_overhangs, + x_draw_glyph_string, + x_define_frame_cursor, + x_clear_frame_area, + x_draw_window_cursor, + x_draw_vertical_window_border, + x_shift_glyphs_for_insert + }; void x_initialize () { - rif = &x_redisplay_interface; - clear_frame_hook = x_clear_frame; ins_del_lines_hook = x_ins_del_lines; delete_glyphs_hook = x_delete_glyphs; @@ -10857,13 +10874,13 @@ x_initialize () redeem_scroll_bar_hook = XTredeem_scroll_bar; judge_scroll_bars_hook = XTjudge_scroll_bars; - TERMINAL_SCROLL_REGION_OK (CURRENT_TERMINAL ()) = 1; /* we'll scroll partial frames */ - TERMINAL_CHAR_INS_DEL_OK (CURRENT_TERMINAL ()) = 1; - TERMINAL_LINE_INS_DEL_OK (CURRENT_TERMINAL ()) = 1; /* we'll just blt 'em */ - TERMINAL_FAST_CLEAR_END_OF_LINE (CURRENT_TERMINAL ()) = 1; /* X does this well */ - TERMINAL_MEMORY_BELOW_FRAME (CURRENT_TERMINAL ()) = 0; /* we don't remember what - scrolls off the - bottom */ + x_display_method.rif = &x_redisplay_interface; + x_display_method.scroll_region_ok = 1; /* We'll scroll partial frames. */ + x_display_method.char_ins_del_ok = 1; + x_display_method.line_ins_del_ok = 1; /* We'll just blt 'em. */ + x_display_method.fast_clear_end_of_line = 1; /* X does this well. */ + x_display_method.memory_below_frame = 0; /* We don't remember what scrolls off the + bottom. */ baud_rate = 19200; x_noop_count = 0; diff --git a/src/xterm.h b/src/xterm.h index 104f5f8d76e..3f629a7695a 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -134,6 +134,9 @@ struct x_bitmap_record int height, width, depth; }; +/* Generic parameters for X displays. */ +extern struct display_method x_display_method; + /* For each X display, we have a structure that records information about it. */ |