# HG changeset patch # User Karoly Lorentey # Date 1073006126 0 # Node ID 2ecd1f669db947f0a56594ccfee2e0674c8ff51c # Parent f3845715a5f6ee297b4b983165db3252b5c71443 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 diff -r f3845715a5f6 -r 2ecd1f669db9 README.multi-tty --- a/README.multi-tty Thu Jan 01 17:55:53 2004 +0000 +++ b/README.multi-tty Fri Jan 02 01:15:26 2004 +0000 @@ -16,7 +16,7 @@ Retrieving the latest version of the branch: tla register-archive lorentey@elte.hu--2004 http://lorentey.web.elte.hu/arch/2004/ - tla get lorentey@elte.hu--2004/emacs--multi-tty--0 + tla get lorentey@elte.hu--2004/emacs--multi-tty (I use tla 1.1.) @@ -33,11 +33,11 @@ mkdir +build cd +build - ../configure --with-x-toolkit=no --without-x + ../configure make bootstrap -then start up the emacs server (src/emacs, M-x server-start), and then -(from a shell prompt on another terminal) start emacsclient with +then start up the emacs server (src/emacs -nw, M-x server-start), and +then (from a shell prompt on another terminal) start emacsclient with lib-src/emacsclient -f /optional/file/names... @@ -50,7 +50,10 @@ If you exit emacs, all terminals should be restored to their previous states. -X, Mac, Windows and DOS support is broken, probably doesn't even +X support is (I hope) working, but at the moment there are problems +with simultaneous X and tty devices, so don't do that. + +Mac, Windows and DOS support is broken, probably doesn't even compile -- this will be solved later. Only tested on my GNU/Linux box. @@ -91,9 +94,9 @@ (ex-TODO items with explanations.) --- Introduce a new abstraction for terminal devices. +-- Introduce a new struct for terminal devices. - (Done, see struct tty_output. The abstraction is not yet + (Done, see struct tty_output. The list of members is not yet complete.) -- Change the bootstrap procedure to initialize tty_list. @@ -112,6 +115,8 @@ (Update: They do, now.) + (Update2: After enabling X, they don't.) + -- other-frame should cycle through the frames on the `current' terminal only. @@ -167,6 +172,8 @@ read_input_waiting was not necessary. Secondary ttys do seem to send signals on input.) + (Update^3: Not any more.) + -- Make make-terminal-frame look up the `tty' and `tty-type' frame parameters from the currently selected terminal before the global default. @@ -191,7 +198,7 @@ (Done, but at the moment only called when an error happens during initialization. There is a memory corruption error around this - somewhere.) + somewhere.) (Update: now it is fully enabled.) -- Implement automatic deletion of terminals when the last frame on that terminal is closed. @@ -214,9 +221,10 @@ server-frames may be removed from server.el.) (Done, nothing to do. It seems that Emacs does not receive SIGHUP - from secondary ttys.) + from secondary ttys, which is actually a good thing.) (Update: I + think it would be a bad idea to remove server-frames anyway.) --- Change emacsclient/server.el to support the -h argument better, +-- Change emacsclient/server.el to support the -t argument better, i.e. automatically close the socket when the frame is closed. (Seems to be working OK.) @@ -248,7 +256,7 @@ earlier, but it seems to be fixed (there were several changes around request_sigio, maybe one of them did it). read_input_waiting() is only used in sys_select(), don't change - it.) + it.) (Update: After adding X support, it's broken again.) -- Find out why does Emacs abort when it wants to close its controlling tty. Hint: chan_process[] array. Hey, maybe @@ -262,6 +270,7 @@ fcntl() kernel behaviour could be emulated by emacsclient. (Done. Simply disabled the SIGIO emulation hack in emacsclient.) + (Update: it was added back.) -- server.el: There are issues with saving files in buffers of closed clients. Try editing a file with emacsclient -f, and (without @@ -273,7 +282,7 @@ pending buffers, and modified buffers don't seem to be deleted.) -- emacsclient.el, server.el: Handle eval or file open errors when - doing -f. + doing -t. (Done.) @@ -286,32 +295,52 @@ (Done, see delete-tty.) +-- Get rid of the accessor macros in termchar.h, or define macros for + all members. + + (Done.) + +-- Move device-specific parameters (like costs) commonly used by + device backends to a common, device-dependent structure. + + (Done. See struct display_method in termhooks.h.) + +-- Fix X support. + + (Done. Well, it seems to be working.) + +-- Allow simultaneous X and tty frames. (Handling input could be + tricky. Or maybe not.) + + (Done. Allowed, that is. It is currently extremely unstable, to + the point of being unusable. The rif variable causes constant + core dumps. Handling input is indeed tricky.) THINGS TO DO ------------ +** Fix rif issue with X-tty combo sessions. IMHO the best thing to do + is to get rid of that global variable (and use the value value in + display_method, which is guaranteed to be correct). + +** Fix faces on tty frames during X-tty combo sessions. + ** Find out the best way to support suspending Emacs with multiple - ttys. My guess: disable it on the controlling tty, but other ttys - should pass it on to emacsclient somehow. (It is (I hope) trivial - to extend emacsclient to handle suspend/resume. A `kill -STOP' - almost works right now.) + ttys. My guess: disable it on the controlling tty, but from other + ttys pass it on to emacsclient somehow. (It is (I hope) trivial to + extend emacsclient to handle suspend/resume. A `kill -STOP' almost + works right now.) ** Move baud_rate to tty_output. -** Move device-specific parameters (like costs) commonly used by - device backends to a common, device-dependent structure. - ** Do tty output through term_hooks, like graphical display backends. -** Fix X support. - -** Allow simultaneous X and tty frames. (Handling input could be - tricky. Or maybe not.) - ** Implement support for starting an interactive Emacs session without an initial frame. (The user would connect to it and open frames later, with emacsclient.) Not necessarily a good idea. +** Fix input from raw ttys (again). + ** Fix Mac support (I can't do this myself). ** Fix W32 support (I can't do this myself). @@ -320,14 +349,22 @@ ** Do a grep on XXX and ?? for more issues. -** Get rid of the accessor macros in termchar.h, or define macros for - all members. +** Understand Emacs's low-level input system (it seems complicated) + :-) and maybe rewrite multi-tty input in terms of MULTI_KBOARD. + (Update: This backtrace from a tty-X combo session hints that this + may be necessary.) -** Understand Emacs's low-level input system (it seems complicated) :-) - and maybe rewrite multi-tty input in terms of MULTIKBOARD. + #0 abort () at /home/lorentey/work/emacs/emacs--multi-tty/src/emacs.c:417 + #1 0x081104fb in read_char (commandflag=0, nmaps=0, maps=0x0, prev_event=675499188, used_mouse_menu=0x0) at /home/lorentey/work/emacs/emacs--multi-tty/src/keyboard.c:2581 + #2 0x0819f23e in read_filtered_event (no_switch_frame=1, ascii_required=0, error_nonascii=0, input_method=0) at /home/lorentey/work/emacs/emacs--multi-tty/src/lread.c:468 + #3 0x0819387c in Fy_or_n_p (prompt=1759896324) at /home/lorentey/work/emacs/emacs--multi-tty/src/fns.c:3115 + ... ** What does interrupt_input do? I tried to disable it for raw secondary tty support, but it does not seem to do anything useful. + (Update: Look again. X unconditionally enables this, maybe that's + why raw terminal support is broken again. I really do need to + understand input.) ** Make sure C-g goes to the right frame. This is hard, as SIGINT doesn't have a tty parameter. :-( @@ -335,7 +372,6 @@ ** I have seen a case when Emacs with multiple ttys fell into a loop eating 100% of CPU time. Strace showed this loop: - getpid() = 30284 kill(30284, SIGIO) = 0 --- SIGIO (I/O possible) @ 0 (0) --- diff -r f3845715a5f6 -r 2ecd1f669db9 lib-src/emacsclient.c --- a/lib-src/emacsclient.c Thu Jan 01 17:55:53 2004 +0000 +++ b/lib-src/emacsclient.c Fri Jan 02 01:15:26 2004 +0000 @@ -720,7 +720,7 @@ } int -copy_from_to (int in, int out) +copy_from_to (int in, int out, int sigio) { static char buf[BUFSIZ]; int nread = read (in, &buf, BUFSIZ); @@ -740,6 +740,9 @@ if (r < 0) return 0; + + if (sigio && emacs_pid) + kill (emacs_pid, SIGIO); } return 1; } @@ -774,7 +777,7 @@ if (FD_ISSET (master, &rset)) { /* Copy Emacs output to stdout. */ - if (! copy_from_to (master, 0)) + if (! copy_from_to (master, 0, 0)) { FD_CLR (master, &set); } @@ -782,7 +785,7 @@ if (FD_ISSET (1, &rset)) { /* Forward user input to Emacs. */ - if (! copy_from_to (1, master)) + if (! copy_from_to (1, master, 1)) { FD_CLR (master, &set); } diff -r f3845715a5f6 -r 2ecd1f669db9 lisp/frame.el --- a/lisp/frame.el Thu Jan 01 17:55:53 2004 +0000 +++ b/lisp/frame.el Fri Jan 02 01:15:26 2004 +0000 @@ -587,7 +587,7 @@ (error "Invalid terminal device")) (unless type (error "Invalid terminal type")) - (make-frame `((tty . ,device) (tty-type . ,type) . ,parameters))) + (make-terminal-frame (append (list (cons 'tty device) (cons 'tty-type type)) parameters))) (defun make-frame-command () "Make a new frame, and select it if the terminal displays only one frame." diff -r f3845715a5f6 -r 2ecd1f669db9 src/Makefile.in --- a/src/Makefile.in Thu Jan 01 17:55:53 2004 +0000 +++ b/src/Makefile.in Fri Jan 02 01:15:26 2004 +0000 @@ -1111,7 +1111,7 @@ 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 -r f3845715a5f6 -r 2ecd1f669db9 src/dispnew.c --- a/src/dispnew.c Thu Jan 01 17:55:53 2004 +0000 +++ b/src/dispnew.c Fri Jan 02 01:15:26 2004 +0000 @@ -297,8 +297,10 @@ 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 @@ { 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ } /* 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 @@ } /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { /* ??? 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 @@ 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 @@ 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 @@ 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 -r f3845715a5f6 -r 2ecd1f669db9 src/frame.c --- a/src/frame.c Thu Jan 01 17:55:53 2004 +0000 +++ b/src/frame.c Fri Jan 02 01:15:26 2004 +0000 @@ -114,6 +114,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ = 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 -r f3845715a5f6 -r 2ecd1f669db9 src/frame.h --- a/src/frame.h Thu Jan 01 17:55:53 2004 +0000 +++ b/src/frame.h Fri Jan 02 01:15:26 2004 +0000 @@ -257,7 +257,7 @@ 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 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 -r f3845715a5f6 -r 2ecd1f669db9 src/keyboard.c --- a/src/keyboard.c Thu Jan 01 17:55:53 2004 +0000 +++ b/src/keyboard.c Fri Jan 02 01:15:26 2004 +0000 @@ -617,9 +617,6 @@ /* 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 @@ 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 @@ #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 @@ 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 @@ () { 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 -r f3845715a5f6 -r 2ecd1f669db9 src/scroll.c --- a/src/scroll.c Thu Jan 01 17:55:53 2004 +0000 +++ b/src/scroll.c Fri Jan 02 01:15:26 2004 +0000 @@ -29,6 +29,7 @@ #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 @@ 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 @@ 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 @@ 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 @@ 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 -r f3845715a5f6 -r 2ecd1f669db9 src/sysdep.c --- a/src/sysdep.c Thu Jan 01 17:55:53 2004 +0000 +++ b/src/sysdep.c Fri Jan 02 01:15:26 2004 +0000 @@ -1368,7 +1368,7 @@ #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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ #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 @@ 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 -r f3845715a5f6 -r 2ecd1f669db9 src/term.c --- a/src/term.c Thu Jan 01 17:55:53 2004 +0000 +++ b/src/term.c Fri Jan 02 01:15:26 2004 +0000 @@ -267,6 +267,10 @@ 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 @@ 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 @@ { 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 @@ { 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 @@ 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 @@ { 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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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); - - /* These variables are only used for terminal stuff. They are allocated - once for the terminal frame of X-windows emacs, but not used afterwards. - - char_ins_del_vector (i.e., char_ins_del_cost) isn't used because - X turns off char_ins_del_ok. */ - - max_frame_lines = max (max_frame_lines, FRAME_LINES (frame)); - max_frame_cols = max (max_frame_cols, FRAME_COLS (frame)); - - tty->costs_set = 1; - - 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); - - 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 */ + { + 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_SCROLL_REGION_COST (frame) = string_cost (f); + + tty->costs_set = 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. + + char_ins_del_vector (i.e., char_ins_del_cost) isn't used because + X turns off char_ins_del_ok. */ + + max_frame_lines = max (max_frame_lines, FRAME_LINES (frame)); + max_frame_cols = max (max_frame_cols, FRAME_COLS (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)); + + 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 */ + } } struct fkey_table { @@ -2142,7 +2151,7 @@ Lisp_Object frame; { struct frame *f; - + if (NILP (frame)) { f = XFRAME (selected_frame); @@ -2177,7 +2186,9 @@ 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 @@ } 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 @@ if (! f->output_data.tty) abort (); f->output_data.tty->display_info = tty; - if (name) { int fd; @@ -2245,7 +2266,7 @@ tty->type = xstrdup (terminal_type); add_keyboard_wait_descriptor (fileno (tty->input)); - + #ifdef WINDOWSNT initialize_w32_display (); @@ -2253,22 +2274,21 @@ area = (char *) xmalloc (2044); - FrameRows = FRAME_LINES (f); - FrameCols = FRAME_COLS (f); - specified_window = FRAME_LINES (f); - - delete_in_insert_mode = 1; - - UseTabs = 0; - TTY_SCROLL_REGION_OK (tty) = 0; + FrameRows (tty) = FRAME_LINES (f); + FrameCols (tty) = FRAME_COLS (f); + tty->specified_window = FRAME_LINES (f); + + f->display_method->delete_in_insert_mode = 1; + + 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 @@ /* 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 @@ } #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 @@ 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 @@ 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 @@ 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 @@ # endif /* TERMINFO */ #endif /*VMS */ } - + if (FrameRows (tty) <= 0 || FrameCols (tty) <= 0) { if (name) @@ -2671,22 +2691,22 @@ 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 @@ 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 @@ char *name = 0; CHECK_STRING (tty); - + if (SBYTES (tty) > 0) { name = (char *) alloca (SBYTES (tty) + 1); @@ -2745,7 +2773,7 @@ if (! t) error ("No such tty device: %s", name); - + delete_tty (t); } @@ -2755,14 +2783,14 @@ 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 @@ 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 @@ 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 @@ 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 -r f3845715a5f6 -r 2ecd1f669db9 src/termchar.h --- a/src/termchar.h Thu Jan 01 17:55:53 2004 +0000 +++ b/src/termchar.h Fri Jan 02 01:15:26 2004 +0000 @@ -64,29 +64,6 @@ /* 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 @@ /* 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 @@ #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 -r f3845715a5f6 -r 2ecd1f669db9 src/termhooks.h --- a/src/termhooks.h Thu Jan 01 17:55:53 2004 +0000 +++ b/src/termhooks.h Fri Jan 02 01:15:26 2004 +0000 @@ -31,11 +31,46 @@ #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 @@ 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 -r f3845715a5f6 -r 2ecd1f669db9 src/window.c --- a/src/window.c Thu Jan 01 17:55:53 2004 +0000 +++ b/src/window.c Fri Jan 02 01:15:26 2004 +0000 @@ -6384,6 +6384,7 @@ { 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 -r f3845715a5f6 -r 2ecd1f669db9 src/xdisp.c --- a/src/xdisp.c Thu Jan 01 17:55:53 2004 +0000 +++ b/src/xdisp.c Fri Jan 02 01:15:26 2004 +0000 @@ -2008,6 +2008,9 @@ 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 @@ /* 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 @@ /* 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 @@ /* 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 @@ 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 -r f3845715a5f6 -r 2ecd1f669db9 src/xfaces.c --- a/src/xfaces.c Thu Jan 01 17:55:53 2004 +0000 +++ b/src/xfaces.c Fri Jan 02 01:15:26 2004 +0000 @@ -6640,7 +6640,8 @@ { 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 -r f3845715a5f6 -r 2ecd1f669db9 src/xfns.c --- a/src/xfns.c Thu Jan 01 17:55:53 2004 +0000 +++ b/src/xfns.c Fri Jan 02 01:15:26 2004 +0000 @@ -3191,6 +3191,9 @@ 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 @@ /* 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 @@ 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 -r f3845715a5f6 -r 2ecd1f669db9 src/xterm.c --- a/src/xterm.c Thu Jan 01 17:55:53 2004 +0000 +++ b/src/xterm.c Fri Jan 02 01:15:26 2004 +0000 @@ -184,6 +184,10 @@ 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 @@ { 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ XGCTYPE (tail) == Lisp_Cons; tail = XCDR (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 (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; + } } return NULL; @@ -8027,7 +8045,7 @@ 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 @@ { 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 @@ 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 */ -#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 -}; + 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 + }; 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 @@ 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 -r f3845715a5f6 -r 2ecd1f669db9 src/xterm.h --- a/src/xterm.h Thu Jan 01 17:55:53 2004 +0000 +++ b/src/xterm.h Fri Jan 02 01:15:26 2004 +0000 @@ -134,6 +134,9 @@ 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. */