From 428a555ec5d5736a3eede739e9b42bd9d33b4364 Mon Sep 17 00:00:00 2001 From: Karoly Lorentey Date: Mon, 5 Jan 2004 05:54:35 +0000 Subject: [PATCH] Converted display hooks to be display-local. Plus many bugfixes. lib-src/emacsclient.c (window_change_signal): Renamed to pass_signal_to_emacs. (init_signal): Pass SIGINT and SIGQUIT to the emacs process. lisp/faces.el (face-valid-attribute-values): Use the window-system function, not the variable. (read-face-attribute, face-spec-set-match-display, frame-set-background-mode) (face-set-after-frame-default): Ditto. lisp/frame.el (make-frame-on-tty): Added interactive declaration (suggested by Robert J. Chassell). Use tty-create-frame-with-faces, not make-terminal-frame. src/termhooks.h (struct display_method): Renamed to display for brevity. (struct display): Added all display hook variables as members of this structure. Added next_display, reference_count, type and display_info components. (FRAME_MUST_WRITE_SPACES, FRAME_FAST_CLEAR_END_OF_LINE, FRAME_LINE_INS_DEL_OK) (FRAME_CHAR_INS_DEL_OK, FRAME_SCROLL_REGION_OK, FRAME_SCROLL_REGION_COST) (FRAME_MEMORY_BELOW_FRAME, FRAME_RIF): Updated for struct display. (FRAME_DISPLAY): New macro. (create_display, delete_display): New prototypes. src/frame.h (struct frame): Added `display' member, removed display_method. (FRAME_LIVE_P): Look at f->display, not f->output_data. src/termchar.h (struct tty_display_info): Removed display_method component. (FRAME_TTY): Use the display structure, not output_data. src/term.c (display_list): New variable. (cursor_to_hook, raw_cursor_to_hook, clear_to_end_hook, clear_frame_hook) (clear_end_of_line_hook, ins_del_lines_hook, delete_glyphs_hook) (ring_bell_hook, reset_terminal_modes_hook, set_terminal_modes_hook) (update_begin_hook, update_end_hook, set_terminal_window_hook) (insert_glyphs_hook, write_glyphs_hook, delete_glyphs_hoo, read_socket_hook) (frame_up_to_date_hook, mouse_position_hook, frame_rehighlight_hook) (frame_raise_lower_hook, set_vertical_scroll_bar_hook, condemn_scroll_bars_hook) (redeem_scroll_bar_hook, judge_scroll_bars_hook): Moved to struct display. (tty_display_method_template): Removed. (syms_of_term): Don't initialize tty_display_method_template. (ring_bell, set_terminal_modes, reset_terminal_modes, update_begin) (update_end, set_terminal_window, cursor_to, raw_cursor_to, clear_to_end) (clear_frame, clear_end_of_line, write_glyphs, insert_glyphs) (delete_glyphs, ins_del_lines): Access display hooks through the frame pointer. (Ftty_display_color_p): Use the frame given as a parameter, or else return nil. (Ftty_display_color_cells): Ditto. (get_named_tty): Renamed to get_named_tty_display, changed return type to struct display. (term_dummy_init): Renamed to initial_term_init. Create and return an initial display. (term_init): Initialize a new struct display and return a pointer to it instead of tty_display_info. Removed frame initialization kludge. (Fdelete_tty): Updated for struct display. (delete_tty): The parameter type is now struct display, not tty_display_info. Delete the display, too. (create_tty_output): New function for creating tty_output structures. (delete_tty_output): New function for deleting tty_output structures. (create_display): New function for creating and registering display structures. (delete_display): New function for deleting and unregistering display structures. src/dispextern.h: Updated prototypes. src/dispnew.c: Include frame.h before termhooks.h. (init_display): Updated term_init call to new signature. src/emacs.c: Include frame.h (for termhooks.h). src/keymap.c: Ditto. src/lread.c: Ditto. src/xsmfns.c: Ditto. src/process.c: Include frame.h before termhooks.h. src/frame.c (Fwindow_system): New function. (syms_of_frame): Initialize it. (make_terminal_frame): Open the terminal device before creating the new frame. Disable scrollbars here, term_init cannot do that anymore. (Fdelete_frame): Use the new delete_frame_hook, don't do display-specific frame deletion here. Ditto for delete_display_hook. (Fmouse_position, Fmouse_pixel_position, Fraise_frame, Flower_frame) (Fredirect_frame_focus): Access display hooks through the frame pointer. src/keyboard.c: Include frame.h before termhooks.h. (start_polling, input_polling_used, stop_polling, gobble_input): Ignore read_socket_hook. (kbd_buffer_get_event, Fset_input_mode): Access display hooks through the frame pointer. (read_avail_input): Loop through all display devices for and call all read_socket_hook functions. Check ttys even if read_socket_hook returned an error. src/sysdep.c (discard_tty_input): Ignore read_socket_hook. (stuff_char): Don't do anything if the current frame is not on a termcap display. (request_sigio, unrequest_sigio): Ignore read_socket_hook. (init_sys_modes): Always call narrow_foreground_group. Set up terminal modes and sigio even under X. src/xdisp.c (message2_nolog, message3_nolog, redisplay_internal) (set_vertical_scroll_bar, redisplay_window): Access display hooks through the frame pointer. (echo_area_display): Don't be afraid of termcap frames during an X+tty combo session. src/xfaces.c: Include termhooks.h. (Ftty_supports_face_attributes_p): Use the given frame, not selected_frame. src/xfns.c (x_set_scroll_bar_foreground, x_set_scroll_bar_background): Access display hooks through the frame pointer. (Fx_create_frame, x_create_tip_frame): Initialize the frame's display structure. src/xmenu.c: Include termhooks.h after frame.h. src/xselect.c (x_own_selection, some_frame_on_display, x_get_foreign_selection) (Fx_disown_selection_internal, Fx_get_cut_buffer_internal) (Fx_store_cut_buffer_internal, Fx_rotate_cut_buffers_internal): Don't do anything if the selected frame is not an X frame. src/xterm.c (x_display_method): Removed. (x_create_frame_display, x_delete_frame_display): New functions for handling struct display objects. (x_term_init): Set up a new struct display object, too. (x_delete_display): Delete the struct display corresponding to the X display. (x_initialize): Moved hook initialization to x_create_frame_display. src/xterm.h (x_display_method): Removed. (struct x_display_info): Added frame_display component. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-44 --- README.multi-tty | 80 +++++--- lib-src/emacsclient.c | 10 +- lisp/faces.el | 20 +- lisp/frame.el | 3 +- src/Makefile.in | 22 +- src/cm.c | 1 - src/dispextern.h | 6 +- src/dispnew.c | 10 +- src/emacs.c | 1 + src/frame.c | 151 ++++++++------ src/frame.h | 39 ++-- src/indent.c | 1 - src/keyboard.c | 51 +++-- src/keymap.c | 1 + src/lread.c | 1 + src/print.c | 1 - src/process.c | 2 +- src/scroll.c | 1 - src/sysdep.c | 30 +-- src/term.c | 462 ++++++++++++++++++------------------------ src/termchar.h | 6 +- src/termhooks.h | 451 +++++++++++++++++++++++------------------ src/window.c | 1 - src/xdisp.c | 42 ++-- src/xfaces.c | 3 +- src/xfns.c | 24 ++- src/xmenu.c | 2 +- src/xselect.c | 52 ++++- src/xsmfns.c | 1 + src/xterm.c | 103 +++++++--- src/xterm.h | 6 +- 31 files changed, 870 insertions(+), 714 deletions(-) diff --git a/README.multi-tty b/README.multi-tty index 20dac233d9..deb56789a7 100644 --- a/README.multi-tty +++ b/README.multi-tty @@ -127,15 +127,13 @@ See arch logs. THINGS TO DO ------------ -** Something with (maybe) multi-keyboard support broke function keys - and arrows on ttys during X+tty combo sessions. Debug this. - -** Fix faces on tty frames during X-tty combo sessions. There is an - init_frame_faces call in init_sys_modes, see if there is a problem - with it. +** Fix color handling during X+tty combo sessions. (It seems that tty + sessions automatically convert the face colors to terminal colors + when the face is loaded. This conversion must happen instead on + the fly in write_glyphs, which might be problematic, as color + approximation is done in lisp (term/tty-colors.el).) -** During an X-tty combo session, a (message "Hello") from a tty frame - goes to the X frame. Fix this. +** The command `emacsclient -t -e '(delete-frame)'' fails to exit. ** Find out the best way to support suspending Emacs with multiple ttys. My guess: disable it on the controlling tty, but from other @@ -143,16 +141,17 @@ THINGS TO DO extend emacsclient to handle suspend/resume. A `kill -STOP' almost works right now.) -** Move baud_rate to tty_output. +** During an X session, Emacs seems to read from stdin. + +** Move baud_rate to struct display. -** Do tty output through term_hooks, like graphical display backends. +** Do tty output through struct display, like graphical display + backends. ** 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). @@ -162,15 +161,14 @@ THINGS TO DO ** Do a grep on XXX and ?? for more issues. ** Understand Emacs's low-level input system (it seems complicated) :-) - -** What does interrupt_input do? I tried to disable it for raw + 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. :-( +** Make sure C-g goes to the right frame with ttys. This is hard, as + SIGINT doesn't have a tty parameter. :-( ** I have seen a case when Emacs with multiple ttys fell into a loop eating 100% of CPU time. Strace showed this loop: @@ -191,19 +189,19 @@ THINGS TO DO I have seen something similar with a single X frame, but have not been able to reproduce it for debugging. -** Define a output_initial value for output_method for the initial + Update: This may have been caused by checking for nread != 0 + instead of nread > 0 after calling read_socket_hook in + read_avail_input. + +** Define an output_initial value for output_method for the initial frame that is dumped with Emacs. Checking for this frame (e.g. in cmd_error_internal) is ugly. ** emacsclient -t from an Emacs term buffer does not work, complains about face problems. This can even lock up Emacs (if the recursive - frame sets single_kboard). - -** Clean up the source of emacsclient. It is a mess. - -** C-x 5 2, C-x 5 o, C-x 5 0 on an emacsclient frame unexpectedly - exits emacsclient. This is a result of trying to be clever with - delete-frame-functions. + frame sets single_kboard). Update: the face problems are caused by + bugs in term.el, not in multi-tty. The lockup is caused by + single_kboard mode. DIARY OF CHANGES ---------------- @@ -449,4 +447,38 @@ DIARY OF CHANGES (Done.) +-- Clean up the source of emacsclient. It is a mess. + + (Done, eliminated stupid proxy-pty kludge.) + +-- Fix faces on tty frames during X-tty combo sessions. There is an + init_frame_faces call in init_sys_modes, see if there is a problem + with it. + + (Done, there was a stupid mistake in + Ftty_supports_face_attributes_p. Colors are broken, though.) + +-- C-x 5 2, C-x 5 o, C-x 5 0 on an emacsclient frame unexpectedly + exits emacsclient. This is a result of trying to be clever with + delete-frame-functions. + + (Fixed, added delete-tty-after-functions, and changed server.el to + use it.) + +-- Something with (maybe) multi-keyboard support broke function keys + and arrows on ttys during X+tty combo sessions. Debug this. + + (I can't reproduce it, maybe the terminal type was wrong.) + +-- Fix input from raw ttys (again). + + (Now it seems to work all right.) + +-- During an X-tty combo session, a (message "Hello") from a tty frame + goes to the X frame. Fix this. + + (Done. There was a safeguard against writing to the initial + terminal frame during bootstrap which prevented echo_area_display + from working correctly on a tty frame during a combo session.) + ;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index 563a8ba9db..f45ca56c0d 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c @@ -283,14 +283,14 @@ char _sobuf[BUFSIZ]; #endif SIGTYPE -window_change_signal (int signalnum) +pass_signal_to_emacs (int signalnum) { int old_errno = errno; if (emacs_pid) - kill (emacs_pid, SIGWINCH); + kill (emacs_pid, signalnum); - signal (SIGWINCH, window_change_signal); + signal (signalnum, pass_signal_to_emacs); errno = old_errno; } @@ -298,7 +298,9 @@ void init_signals (void) { /* Set up signal handlers. */ - signal (SIGWINCH, window_change_signal); + signal (SIGWINCH, pass_signal_to_emacs); + signal (SIGINT, pass_signal_to_emacs); + signal (SIGQUIT, pass_signal_to_emacs); } diff --git a/lisp/faces.el b/lisp/faces.el index 49652175f4..1e80cb4409 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -905,7 +905,7 @@ an integer value." (let ((valid (case attribute (:family - (if window-system + (if (window-system frame) (mapcar #'(lambda (x) (cons (car x) (car x))) (x-font-family-list)) ;; Only one font on TTYs. @@ -914,7 +914,7 @@ an integer value." (mapcar #'(lambda (x) (cons (symbol-name x) x)) (internal-lisp-face-attribute-values attribute))) ((:underline :overline :strike-through :box) - (if window-system + (if (window-system frame) (nconc (mapcar #'(lambda (x) (cons (symbol-name x) x)) (internal-lisp-face-attribute-values attribute)) (mapcar #'(lambda (c) (cons c c)) @@ -927,7 +927,7 @@ an integer value." ((:height) 'integerp) (:stipple - (and (memq window-system '(x w32 mac)) + (and (memq (window-system frame) '(x w32 mac)) (mapcar #'list (apply #'nconc (mapcar (lambda (dir) @@ -1045,7 +1045,7 @@ of a global face. Value is the new attribute value." ;; explicitly in VALID, using color approximation code ;; in tty-colors.el. (when (and (memq attribute '(:foreground :background)) - (not (memq window-system '(x w32 mac))) + (not (memq (window-system frame) '(x w32 mac))) (not (member new-value '("unspecified" "unspecified-fg" "unspecified-bg")))) @@ -1298,14 +1298,14 @@ If FRAME is nil, the current FRAME is used." req (car conjunct) options (cdr conjunct) match (cond ((eq req 'type) - (or (memq window-system options) + (or (memq (window-system frame) options) ;; FIXME: This should be revisited to use ;; display-graphic-p, provided that the ;; color selection depends on the number ;; of supported colors, and all defface's ;; are changed to look at number of colors ;; instead of (type graphic) etc. - (and (null window-system) + (and (null (window-system frame)) (memq 'tty options)) (and (memq 'motif options) (featurep 'motif)) @@ -1537,14 +1537,14 @@ this won't have the expected effect." Display-dependent faces are those which have different definitions according to the `background-mode' and `display-type' frame parameters." (let* ((bg-resource - (and window-system + (and (window-system frame) (x-get-resource "backgroundMode" "BackgroundMode"))) (bg-color (frame-parameter frame 'background-color)) (bg-mode (cond (frame-background-mode) (bg-resource (intern (downcase bg-resource))) - ((and (null window-system) (null bg-color)) + ((and (null (window-system frame)) (null bg-color)) ;; No way to determine this automatically (?). 'dark) ;; Unspecified frame background color can only happen @@ -1561,7 +1561,7 @@ according to the `background-mode' and `display-type' frame parameters." 'light) (t 'dark))) (display-type - (cond ((null window-system) + (cond ((null (window-system frame)) (if (tty-display-color-p frame) 'color 'mono)) ((x-display-color-p frame) 'color) @@ -1696,7 +1696,7 @@ Initialize colors of certain faces from frame parameters." (when (not (equal face 'default)) (face-spec-set face (face-user-default-spec face) frame) (internal-merge-in-global-face face frame) - (when (and (memq window-system '(x w32 mac)) + (when (and (memq (window-system frame) '(x w32 mac)) (or (not (boundp 'inhibit-default-face-x-resources)) (not (eq face 'default)))) (make-face-x-resource-internal face frame))) diff --git a/lisp/frame.el b/lisp/frame.el index 45716fde22..b6130e2a66 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -583,11 +583,12 @@ terminal resizes only on the controlling terminal, so we need emacsclient to sit on the real terminal device, create SIGIO signals upon terminal input, and forward SIGWINCH signals to us.)" + (interactive "fOpen frame on tty device: \nsTerminal type of %s: ") (unless device (error "Invalid terminal device")) (unless type (error "Invalid terminal type")) - (make-terminal-frame (append (list (cons 'tty device) (cons 'tty-type type)) parameters))) + (tty-create-frame-with-faces (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 --git a/src/Makefile.in b/src/Makefile.in index 32215899a4..94579aed47 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1047,7 +1047,7 @@ ccl.o: ccl.c ccl.h charset.h coding.h $(config_h) charset.o: charset.c charset.h buffer.h coding.h composite.h disptab.h \ $(config_h) coding.o: coding.c coding.h ccl.h buffer.h charset.h intervals.h composite.h window.h $(config_h) -cm.o: cm.c frame.h cm.h termhooks.h systty.h termchar.h $(config_h) +cm.o: cm.c frame.h cm.h termhooks.h termchar.h $(config_h) cmds.o: cmds.c syntax.h buffer.h charset.h commands.h window.h $(config_h) \ msdos.h dispextern.h pre-crt0.o: pre-crt0.c @@ -1055,7 +1055,7 @@ ecrt0.o: ecrt0.c $(config_h) CRT0_COMPILE ${srcdir}/ecrt0.c dired.o: dired.c commands.h buffer.h $(config_h) charset.h coding.h regex.h \ systime.h -dispnew.o: dispnew.c systty.h systime.h commands.h process.h frame.h \ +dispnew.o: dispnew.c systime.h commands.h process.h frame.h \ window.h buffer.h dispextern.h termchar.h termopts.h termhooks.h cm.h \ disptab.h \ xterm.h blockinput.h atimer.h charset.h msdos.h composite.h keyboard.h \ @@ -1073,19 +1073,19 @@ fileio.o: fileio.c window.h buffer.h systime.h $(INTERVAL_SRC) charset.h \ filelock.o: filelock.c buffer.h systime.h epaths.h $(config_h) filemode.o: filemode.c $(config_h) frame.o: frame.c xterm.h window.h frame.h termhooks.h commands.h keyboard.h \ - blockinput.h systty.h atimer.h systime.h buffer.h charset.h fontset.h \ + blockinput.h atimer.h systime.h buffer.h charset.h fontset.h \ msdos.h dosfns.h dispextern.h $(config_h) fontset.o: dispextern.h fontset.h fontset.c ccl.h buffer.h charset.h frame.h \ keyboard.h termhooks.h $(config_h) getloadavg.o: getloadavg.c $(config_h) -indent.o: indent.c frame.h window.h systty.h indent.h buffer.h $(config_h) termchar.h \ +indent.o: indent.c frame.h window.h indent.h buffer.h $(config_h) termchar.h \ termopts.h disptab.h region-cache.h charset.h composite.h dispextern.h \ keyboard.h insdel.o: insdel.c window.h buffer.h $(INTERVAL_SRC) blockinput.h charset.h \ dispextern.h atimer.h systime.h $(config_h) keyboard.o: keyboard.c termchar.h termhooks.h termopts.h buffer.h charset.h \ commands.h frame.h window.h macros.h disptab.h keyboard.h syssignal.h \ - systty.h systime.h dispextern.h syntax.h $(INTERVAL_SRC) blockinput.h \ + systime.h dispextern.h syntax.h $(INTERVAL_SRC) blockinput.h \ atimer.h xterm.h puresize.h msdos.h $(config_h) keymap.o: keymap.c buffer.h commands.h keyboard.h termhooks.h blockinput.h \ atimer.h systime.h puresize.h charset.h intervals.h $(config_h) @@ -1110,7 +1110,7 @@ process.o: process.c process.h buffer.h window.h termhooks.h termopts.h \ keyboard.h $(config_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 \ +scroll.o: scroll.c termchar.h dispextern.h frame.h msdos.h keyboard.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) @@ -1120,7 +1120,7 @@ syntax.o: syntax.c syntax.h buffer.h commands.h category.h charset.h \ sysdep.o: sysdep.c syssignal.h systty.h systime.h syswait.h blockinput.h \ process.h dispextern.h termhooks.h termchar.h termopts.h \ frame.h atimer.h window.h msdos.h dosfns.h keyboard.h cm.h $(config_h) -term.o: term.c systty.h termchar.h termhooks.h termopts.h $(config_h) cm.h frame.h \ +term.o: term.c termchar.h termhooks.h termopts.h $(config_h) cm.h frame.h \ disptab.h dispextern.h keyboard.h charset.h coding.h ccl.h msdos.h termcap.o: termcap.c $(config_h) terminfo.o: terminfo.c $(config_h) @@ -1134,18 +1134,18 @@ w16select.o: w16select.c dispextern.h frame.h blockinput.h atimer.h systime.h \ msdos.h $(config_h) widget.o: widget.c xterm.h frame.h dispextern.h widgetprv.h \ $(srcdir)/../lwlib/lwlib.h $(config_h) -window.o: window.c indent.h commands.h frame.h window.h buffer.h systty.h termchar.h \ +window.o: window.c indent.h commands.h frame.h window.h buffer.h termchar.h \ termhooks.h disptab.h keyboard.h dispextern.h msdos.h composite.h \ $(config_h) xdisp.o: xdisp.c macros.h commands.h process.h indent.h buffer.h dispextern.h coding.h \ - systty.h termchar.h frame.h window.h disptab.h termhooks.h charset.h $(config_h) \ + termchar.h frame.h window.h disptab.h termhooks.h charset.h $(config_h) \ msdos.h composite.h fontset.h blockinput.h atimer.h systime.h keymap.h xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \ window.h charset.h msdos.h dosfns.h composite.h atimer.h systime.h \ termchar.h $(config_h) xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \ $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \ - charset.h gtkutil.h systty.h termchar.h $(config_h) + charset.h gtkutil.h termchar.h $(config_h) xmenu.o: xmenu.c xterm.h termhooks.h window.h dispextern.h frame.h buffer.h \ keyboard.h $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h \ gtkutil.h msdos.h coding.h $(config_h) @@ -1177,7 +1177,7 @@ floatfns.o: floatfns.c $(config_h) fns.o: fns.c commands.h $(config_h) frame.h buffer.h charset.h keyboard.h \ frame.h window.h dispextern.h $(INTERVAL_SRC) coding.h md5.h print.o: print.c process.h frame.h window.h buffer.h keyboard.h charset.h \ - $(config_h) dispextern.h msdos.h composite.h systty.h termchar.h intervals.h + $(config_h) dispextern.h msdos.h composite.h termchar.h intervals.h lread.o: lread.c commands.h keyboard.h buffer.h epaths.h charset.h $(config_h) \ termhooks.h coding.h msdos.h diff --git a/src/cm.c b/src/cm.c index 1f165e90f4..9073813dd7 100644 --- a/src/cm.c +++ b/src/cm.c @@ -29,7 +29,6 @@ Boston, MA 02111-1307, USA. */ #include "cm.h" #include "termhooks.h" -#include "systty.h" /* For emacs_tty in termchar.h */ #include "termchar.h" diff --git a/src/dispextern.h b/src/dispextern.h index 52ea29b8d6..a6c14da3f6 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1249,7 +1249,7 @@ struct glyph_string DESCENT = FONT->descent HEIGHT = FONT_HEIGHT (FONT) F_DESCENT = (FRAME_FONT (F)->descent - - F->output_data.x->baseline_offset) + - F->device->output_data.x->baseline_offset) F_HEIGHT = FRAME_LINE_HEIGHT (F) */ @@ -2748,8 +2748,8 @@ extern int per_line_cost P_ ((char *)); extern void calculate_costs P_ ((struct frame *)); extern void set_tty_color_mode P_ ((struct frame *, Lisp_Object)); extern void tty_setup_colors P_ ((struct tty_display_info *, int)); -extern struct tty_display_info *term_init P_ ((Lisp_Object, char *, char *)); -extern struct tty_display_info *term_dummy_init P_ ((void)); +extern struct display *term_init P_ ((char *, char *)); +extern struct display *initial_term_init P_ ((void)); extern void fatal P_ ((/* char *, ... */)); void cursor_to P_ ((int, int)); extern int tty_capable_p P_ ((struct tty_display_info *, unsigned, unsigned long, unsigned long)); diff --git a/src/dispnew.c b/src/dispnew.c index be6e6330e3..3fbd830536 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -29,10 +29,8 @@ Boston, MA 02111-1307, USA. */ #endif #include "lisp.h" -#include "systty.h" /* For emacs_tty in termchar.h */ #include "termchar.h" #include "termopts.h" -#include "termhooks.h" /* cm.h must come after dispextern.h on Windows. */ #include "dispextern.h" #include "cm.h" @@ -40,6 +38,7 @@ Boston, MA 02111-1307, USA. */ #include "charset.h" #include "keyboard.h" #include "frame.h" +#include "termhooks.h" #include "window.h" #include "commands.h" #include "disptab.h" @@ -6634,10 +6633,11 @@ For types not defined in VMS, use define emacs_term \"TYPE\".\n\ #endif /* VMS */ { - struct tty_display_info *tty; + struct display *d; - tty = term_init (selected_frame, 0, terminal_type); - change_frame_size (XFRAME (selected_frame), FrameRows (tty), FrameCols (tty), 0, 0, 1); + d = term_init (0, terminal_type); + d->display_info.tty->top_frame = selected_frame; + change_frame_size (XFRAME (selected_frame), FrameRows (d->display_info.tty), FrameCols (d->display_info.tty), 0, 0, 1); } { diff --git a/src/emacs.c b/src/emacs.c index d6f040f3f5..25a421cb30 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -54,6 +54,7 @@ Boston, MA 02111-1307, USA. */ #include "blockinput.h" #include "syssignal.h" #include "process.h" +#include "frame.h" #include "termhooks.h" #include "keyboard.h" #include "keymap.h" diff --git a/src/frame.c b/src/frame.c index cc971edefc..86c26b9d86 100644 --- a/src/frame.c +++ b/src/frame.c @@ -42,7 +42,6 @@ Boston, MA 02111-1307, USA. */ #include "fontset.h" #endif #include "blockinput.h" -#include "systty.h" /* For emacs_tty in termchar.h */ #include "termchar.h" #include "termhooks.h" #include "dispextern.h" @@ -233,6 +232,30 @@ return values. */) : Qnil); } +DEFUN ("window-system", Fwindow_system, Swindow_system, 0, 1, 0, + doc: /* The name of the window system that FRAME is displaying through. +The value is a symbol---for instance, 'x' for X windows. +The value is nil if Emacs is using a text-only terminal. + +FRAME defaults to the currently selected frame. */) + (frame) + Lisp_Object frame; +{ + Lisp_Object type; + if (NILP (frame)) + frame = selected_frame; + + type = Fframep (frame); + + if (NILP (type)) + wrong_type_argument (Qframep, frame); + + if (EQ (type, Qt)) + return Qnil; + else + return type; +} + struct frame * make_frame (mini_p) int mini_p; @@ -484,6 +507,7 @@ make_terminal_frame (tty_name, tty_type) char *tty_type; { register struct frame *f; + struct display *display; Lisp_Object frame; char name[20]; @@ -502,6 +526,13 @@ make_terminal_frame (tty_name, tty_type) if (! (NILP (Vframe_list) || CONSP (Vframe_list))) Vframe_list = Qnil; + /* Open the display before creating the new frame, because + create_tty_display might throw an error. */ + if (initialized) + display = term_init (tty_name, tty_type); + else + display = initial_term_init (); + f = make_frame (1); XSETFRAME (frame, f); @@ -540,37 +571,29 @@ make_terminal_frame (tty_name, tty_type) #else #ifdef WINDOWSNT f->output_method = output_termcap; - f->output_data.x = &tty_display; /* XXX */ + f->output_data.x = &tty_display; /* XXX ??? */ #else #ifdef MAC_OS8 make_mac_terminal_frame (f); #else { - struct tty_display_info *tty; f->output_method = output_termcap; - - f->output_data.tty = (struct tty_output *) xmalloc (sizeof (struct tty_output)); - bzero (f->output_data.tty, sizeof (struct tty_output)); - + f->display = display; + f->display->reference_count++; + create_tty_output (f); + FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR; FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR; - if (initialized) - { - /* Note that term_init may signal an error, but then it is its - responsibility to make sure this frame is deleted. */ - f->output_data.tty->display_info = term_init (frame, tty_name, tty_type); - } - else - { - /* init_display() will reinitialize the terminal with correct values after dump. */ - f->output_data.tty->display_info = term_dummy_init (); - } - FRAME_TTY (f)->reference_count++; - f->display_method = FRAME_TTY (f)->display_method; + FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; + FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; + #ifdef MULTI_KBOARD f->kboard = FRAME_TTY (f)->kboard; #endif + + /* Set the top frame to the newly created frame. */ + FRAME_TTY (f)->top_frame = frame; } #ifdef CANNOT_DUMP @@ -1397,30 +1420,26 @@ The functions are run with one arg, the frame to be deleted. */) promise that the display of the frame must be valid until we have called the window-system-dependent frame destruction routine. */ - /* I think this should be done with a hook. */ -#ifdef HAVE_WINDOW_SYSTEM - if (FRAME_WINDOW_P (f)) - x_destroy_window (f); -#endif + if (FRAME_DISPLAY (f)->delete_frame_hook) + (*FRAME_DISPLAY (f)->delete_frame_hook) (f); + + { + struct display *display = FRAME_DISPLAY (f); - if (FRAME_TERMCAP_P (f)) - { - int delete = 1; - struct tty_display_info *tty = FRAME_TTY (f); - - if (! --tty->reference_count) - { - /* delete_tty would call us recursively if we don't kill the - frame now. */ - xfree (f->output_data.tty); - f->output_data.nothing = 0; - delete_tty (tty); - } - } - else + f->output_data.nothing = 0; + f->display = 0; /* Now the frame is dead. */ + + /* If needed, delete the device that this frame was on. + (This must be done after the frame is killed.) */ + display->reference_count--; + if (display->reference_count == 0) { - f->output_data.nothing = 0; + if (display->delete_display_hook) + (*display->delete_display_hook) (display); + else + delete_display (display); } + } /* If we've deleted the last_nonminibuf_frame, then try to find another one. */ @@ -1535,11 +1554,11 @@ and returns whatever that function returns. */) #ifdef HAVE_MOUSE /* It's okay for the hook to refrain from storing anything. */ - if (!FRAME_TERMCAP_P (f) && mouse_position_hook) - (*mouse_position_hook) (&f, -1, - &lispy_dummy, &party_dummy, - &x, &y, - &long_dummy); + if (FRAME_DISPLAY (f)->mouse_position_hook) + (*FRAME_DISPLAY (f)->mouse_position_hook) (&f, -1, + &lispy_dummy, &party_dummy, + &x, &y, + &long_dummy); if (! NILP (x)) { col = XINT (x); @@ -1578,12 +1597,11 @@ and nil for X and Y. */) #ifdef HAVE_MOUSE /* It's okay for the hook to refrain from storing anything. */ - if (FRAME_TERMCAP_P (f) - && mouse_position_hook) - (*mouse_position_hook) (&f, -1, - &lispy_dummy, &party_dummy, - &x, &y, - &long_dummy); + if (FRAME_DISPLAY (f)->mouse_position_hook) + (*FRAME_DISPLAY (f)->mouse_position_hook) (&f, -1, + &lispy_dummy, &party_dummy, + &x, &y, + &long_dummy); #endif XSETFRAME (lispy_dummy, f); return Fcons (lispy_dummy, Fcons (x, y)); @@ -1845,17 +1863,19 @@ doesn't support multiple overlapping frames, this function does nothing. */) (frame) Lisp_Object frame; { + struct frame *f; if (NILP (frame)) frame = selected_frame; CHECK_LIVE_FRAME (frame); + f = XFRAME (frame); + /* Do like the documentation says. */ Fmake_frame_visible (frame); - if (FRAME_TERMCAP_P (XFRAME (frame)) - && frame_raise_lower_hook) - (*frame_raise_lower_hook) (XFRAME (frame), 1); + if (FRAME_DISPLAY (f)->frame_raise_lower_hook) + (*FRAME_DISPLAY (f)->frame_raise_lower_hook) (f, 1); return Qnil; } @@ -1869,14 +1889,17 @@ doesn't support multiple overlapping frames, this function does nothing. */) (frame) Lisp_Object frame; { + struct frame *f; + if (NILP (frame)) frame = selected_frame; CHECK_LIVE_FRAME (frame); - if (FRAME_TERMCAP_P (XFRAME (frame)) - && frame_raise_lower_hook) - (*frame_raise_lower_hook) (XFRAME (frame), 0); + f = XFRAME (frame); + + if (FRAME_DISPLAY (f)->frame_raise_lower_hook) + (*FRAME_DISPLAY (f)->frame_raise_lower_hook) (f, 0); return Qnil; } @@ -1910,6 +1933,8 @@ The redirection lasts until `redirect-frame-focus' is called to change it. */) (frame, focus_frame) Lisp_Object frame, focus_frame; { + struct frame *f; + /* Note that we don't check for a live frame here. It's reasonable to redirect the focus of a frame you're about to delete, if you know what other frame should receive those keystrokes. */ @@ -1918,11 +1943,12 @@ The redirection lasts until `redirect-frame-focus' is called to change it. */) if (! NILP (focus_frame)) CHECK_LIVE_FRAME (focus_frame); - XFRAME (frame)->focus_frame = focus_frame; + f = XFRAME (frame); + + f->focus_frame = focus_frame; - if (!FRAME_TERMCAP_P (XFRAME (frame)) - && frame_rehighlight_hook) - (*frame_rehighlight_hook) (XFRAME (frame)); + if (FRAME_DISPLAY (f)->frame_rehighlight_hook) + (*FRAME_DISPLAY (f)->frame_rehighlight_hook) (f); return Qnil; } @@ -4198,6 +4224,7 @@ This variable is local to the current terminal and cannot be buffer-local. */); defsubr (&Sactive_minibuffer_window); defsubr (&Sframep); defsubr (&Sframe_live_p); + defsubr (&Swindow_system); defsubr (&Smake_terminal_frame); defsubr (&Shandle_switch_frame); defsubr (&Signore_event); diff --git a/src/frame.h b/src/frame.h index 4bd5220488..9b6d6afa1e 100644 --- a/src/frame.h +++ b/src/frame.h @@ -68,7 +68,7 @@ enum text_cursor_kinds #define FRAME_FOREGROUND_PIXEL(f) ((f)->foreground_pixel) #define FRAME_BACKGROUND_PIXEL(f) ((f)->background_pixel) -struct device; +struct display; struct frame { @@ -256,26 +256,24 @@ struct frame /* Canonical Y unit. Height of a line, in pixels. */ int line_height; - /* The display hooks to use with this frame. */ - 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. */ + /* The output method says how the contents of this frame are + displayed. It could be using termcap, or using an X window. + This must be the same as the display->type. */ enum output_method output_method; - /* A structure of auxiliary data used for displaying the contents. - struct tty_output is used for termcap frames; - it is defined in term.h. - struct x_output is used for X window frames; - it is defined in xterm.h. - struct w32_output is used for W32 window frames; - it is defined in w32term.h. */ + /* The display that this frame uses. If this is NULL, then the + frame is deleted. */ + struct display *display; + + /* Display-dependent, frame-local auxiliary data used for displaying + the contents. When the frame is deleted, this data is deleted as + well. */ union output_data { - struct tty_output *tty; - struct x_output *x; - struct w32_output *w32; - struct mac_output *mac; + struct tty_output *tty; /* termchar.h */ + struct x_output *x; /* xterm.h */ + struct w32_output *w32; /* w32term.h */ + struct mac_output *mac; /* macterm.h */ EMACS_INT nothing; } output_data; @@ -291,11 +289,12 @@ struct frame int left_fringe_width, right_fringe_width; #ifdef MULTI_KBOARD + /* XXX Maybe this should be moved to struct display, too. */ /* A pointer to the kboard structure associated with this frame. For termcap frames, it will be the same as - output_data.tty->display_info->kboard. + display->display_info.tty->kboard. For X frames, it will be the same as - output_data.x->display_info->kboard. */ + display->display_info.x->kboard. */ struct kboard *kboard; #endif @@ -486,7 +485,7 @@ typedef struct frame *FRAME_PTR; #endif /* Nonzero if frame F is still alive (not deleted). */ -#define FRAME_LIVE_P(f) ((f)->output_data.nothing != 0) +#define FRAME_LIVE_P(f) ((f)->display != 0) /* Nonzero if frame F is a minibuffer-only frame. */ #define FRAME_MINIBUF_ONLY_P(f) \ diff --git a/src/indent.c b/src/indent.c index 0eca2f3410..1b3e584751 100644 --- a/src/indent.c +++ b/src/indent.c @@ -30,7 +30,6 @@ Boston, MA 02111-1307, USA. */ #include "keyboard.h" #include "frame.h" #include "window.h" -#include "systty.h" /* For emacs_tty in termchar.h */ #include "termchar.h" #include "termopts.h" #include "disptab.h" diff --git a/src/keyboard.c b/src/keyboard.c index df5c65c334..ff62a07c25 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -23,13 +23,12 @@ Boston, MA 02111-1307, USA. */ #include #include #include "lisp.h" -#include "systty.h" /* This must be included befor termchar.h. */ #include "termchar.h" #include "termopts.h" +#include "frame.h" #include "termhooks.h" #include "macros.h" #include "keyboard.h" -#include "frame.h" #include "window.h" #include "commands.h" #include "buffer.h" @@ -2065,7 +2064,10 @@ void start_polling () { #ifdef POLL_FOR_INPUT - if (read_socket_hook && !interrupt_input) + /* XXX This condition was (read_socket_hook && !interrupt_input), + but read_socket_hook is not global anymore. Let's pretend that + it's always set. */ + if (!interrupt_input) { /* Turn alarm handling on unconditionally. It might have been turned off in process.c. */ @@ -2099,7 +2101,10 @@ int input_polling_used () { #ifdef POLL_FOR_INPUT - return read_socket_hook && !interrupt_input; + /* XXX This condition was (read_socket_hook && !interrupt_input), + but read_socket_hook is not global anymore. Let's pretend that + it's always set. */ + return !interrupt_input; #else return 0; #endif @@ -2111,7 +2116,10 @@ void stop_polling () { #ifdef POLL_FOR_INPUT - if (read_socket_hook && !interrupt_input) + /* XXX This condition was (read_socket_hook && !interrupt_input), + but read_socket_hook is not global anymore. Let's pretend that + it's always set. */ + if (!interrupt_input) ++poll_suppress_count; #endif } @@ -4081,7 +4089,8 @@ kbd_buffer_get_event (kbp, used_mouse_menu) If there is no valid info, it does not store anything so x remains nil. */ x = Qnil; - (*mouse_position_hook) (&f, 0, &bar_window, &part, &x, &y, &time); + if (f && FRAME_DISPLAY (f)->mouse_position_hook) /* XXX Can f or mouse_position_hook be NULL here? */ + (*FRAME_DISPLAY (f)->mouse_position_hook) (&f, 0, &bar_window, &part, &x, &y, &time); obj = Qnil; @@ -6516,7 +6525,10 @@ gobble_input (expected) } else #ifdef POLL_FOR_INPUT - if (read_socket_hook && !interrupt_input && poll_suppress_count == 0) + /* XXX This condition was (read_socket_hook && !interrupt_input), + but read_socket_hook is not global anymore. Let's pretend that + it's always set. */ + if (!interrupt_input && poll_suppress_count == 0) { SIGMASKTYPE mask; mask = sigblock (sigmask (SIGALRM)); @@ -6600,11 +6612,21 @@ read_avail_input (expected) for (i = 0; i < KBD_BUFFER_SIZE; i++) EVENT_INIT (buf[i]); - if (read_socket_hook) - /* No need for FIONREAD or fcntl; just say don't wait. */ - nread = (*read_socket_hook) (buf, KBD_BUFFER_SIZE, expected); + { + struct display *d; - if (!nread && tty_list) + for (d = display_list; d; d = d->next_display) + { + if (d->read_socket_hook) + /* No need for FIONREAD or fcntl; just say don't wait. */ + nread = (*d->read_socket_hook) (buf, KBD_BUFFER_SIZE, expected); + + if (nread > 0) + break; + } + } + + if (nread <= 0 && tty_list) { /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than the kbd_buffer can really hold. That may prevent loss @@ -10426,6 +10448,11 @@ See also `current-input-mode'. */) (interrupt, flow, meta, quit) Lisp_Object interrupt, flow, meta, quit; { + /* XXX This function needs to be revised for multi-device support. + Currently it compiles fine, but its semantics are wrong. It sets + global parameters (e.g. interrupt_input) based on only the + current frame's device. */ + if (!NILP (quit) && (!INTEGERP (quit) || XINT (quit) < 0 || XINT (quit) > 0400)) error ("set-input-mode: QUIT must be an ASCII character"); @@ -10442,7 +10469,7 @@ See also `current-input-mode'. */) #ifdef SIGIO /* Note SIGIO has been undef'd if FIONREAD is missing. */ - if (read_socket_hook) + if (FRAME_DISPLAY (SELECTED_FRAME ())->read_socket_hook) { /* When using X, don't give the user a real choice, because we haven't implemented the mechanisms to support it. */ diff --git a/src/keymap.c b/src/keymap.c index 5f1f2a3f3a..d03c84aa69 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. */ #include "buffer.h" #include "charset.h" #include "keyboard.h" +#include "frame.h" #include "termhooks.h" #include "blockinput.h" #include "puresize.h" diff --git a/src/lread.c b/src/lread.c index 603c871c4d..fae47300bd 100644 --- a/src/lread.c +++ b/src/lread.c @@ -33,6 +33,7 @@ Boston, MA 02111-1307, USA. */ #include #include "commands.h" #include "keyboard.h" +#include "frame.h" #include "termhooks.h" #include "coding.h" diff --git a/src/print.c b/src/print.c index 2560f5f3e2..3069f73282 100644 --- a/src/print.c +++ b/src/print.c @@ -30,7 +30,6 @@ Boston, MA 02111-1307, USA. */ #include "window.h" #include "process.h" #include "dispextern.h" -#include "systty.h" /* For emacs_tty in termchar.h */ #include "termchar.h" #include "intervals.h" diff --git a/src/process.c b/src/process.c index 906497f14e..70c3efa1dd 100644 --- a/src/process.c +++ b/src/process.c @@ -126,11 +126,11 @@ Boston, MA 02111-1307, USA. */ #include "charset.h" #include "coding.h" #include "process.h" +#include "frame.h" #include "termhooks.h" #include "termopts.h" #include "commands.h" #include "keyboard.h" -#include "frame.h" #include "blockinput.h" #include "dispextern.h" #include "composite.h" diff --git a/src/scroll.c b/src/scroll.c index 915b60ab4c..8f83851a2e 100644 --- a/src/scroll.c +++ b/src/scroll.c @@ -23,7 +23,6 @@ Boston, MA 02111-1307, USA. */ #include #include #include "lisp.h" -#include "systty.h" /* For emacs_tty in termchar.h */ #include "termchar.h" #include "dispextern.h" #include "keyboard.h" diff --git a/src/sysdep.c b/src/sysdep.c index a84a6d5c1f..d5c72c52dd 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -272,11 +272,6 @@ discard_tty_input () if (noninteractive) return; - /* Discarding input is not safe when the input could contain - replies from the X server. So don't do it. */ - if (read_socket_hook) - return; - #ifdef VMS end_kbd_input (); SYS$QIOW (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0, @@ -322,7 +317,7 @@ discard_tty_input () void stuff_char (char c) { - if (read_socket_hook) + if (! FRAME_TERMCAP_P (SELECTED_FRAME ())) return; /* Should perhaps error if in batch mode */ @@ -961,13 +956,17 @@ reset_sigio (fd) } #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */ -/* XXX Uhm, this FASYNC is not used anymore here. */ +/* XXX Uhm, FASYNC is not used anymore here. */ void request_sigio () { + /* XXX read_socket_hook is not global anymore. Is blocking SIGIO + bad under X? */ +#if 0 if (read_socket_hook) return; +#endif #ifdef SIGWINCH sigunblock (sigmask (SIGWINCH)); @@ -979,10 +978,14 @@ request_sigio () void unrequest_sigio (void) -{ +{ + /* XXX read_socket_hook is not global anymore. Is blocking SIGIO + bad under X? */ +#if 0 if (read_socket_hook) return; - +#endif + #ifdef SIGWINCH sigblock (sigmask (SIGWINCH)); #endif @@ -1388,15 +1391,18 @@ nil means don't delete them until `list-processes' is run. */); #endif /* VMS */ #ifdef BSD_PGRPS +#if 0 + /* read_socket_hook is not global anymore. I think doing this + unconditionally will not cause any problems. */ if (! read_socket_hook && EQ (Vwindow_system, Qnil)) +#endif narrow_foreground_group (fileno (TTY_INPUT (tty_out))); #endif #ifdef HAVE_WINDOW_SYSTEM /* Emacs' window system on MSDOG uses the `internal terminal' and therefore needs the initialization code below. */ - /* XXX This need to be revised for X+tty session support. */ - if (tty_out->input != stdin || (!read_socket_hook && EQ (Vwindow_system, Qnil))) + if (tty_out->input != stdin || EQ (Vwindow_system, Qnil)) #endif { if (! tty_out->old_tty) @@ -1642,7 +1648,7 @@ nil means don't delete them until `list-processes' is run. */); #ifndef F_SETOWN_BUG #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */ if (interrupt_input - && ! read_socket_hook && EQ (Vwindow_system, Qnil)) + && (tty_out->input != stdin || EQ (Vwindow_system, Qnil))) { old_fcntl_owner[fileno (TTY_INPUT (tty_out))] = fcntl (fileno (TTY_INPUT (tty_out)), F_GETOWN, 0); diff --git a/src/term.c b/src/term.c index 96fa9badda..178ded7fc8 100644 --- a/src/term.c +++ b/src/term.c @@ -29,7 +29,6 @@ Boston, MA 02111-1307, USA. */ #include #include "lisp.h" -#include "systty.h" /* For emacs_tty in termchar.h */ #include "termchar.h" #include "termopts.h" #include "charset.h" @@ -72,9 +71,9 @@ static void turn_off_face P_ ((struct frame *, int face_id)); static void tty_show_cursor P_ ((struct tty_display_info *)); static void tty_hide_cursor P_ ((struct tty_display_info *)); -void delete_tty P_ ((struct tty_display_info *)); -static void delete_tty_1 P_ ((struct tty_display_info *)); - +void delete_tty P_ ((struct display *)); +void create_tty_output P_ ((struct frame *)); +void delete_tty_output P_ ((struct frame *)); #define OUTPUT(tty, a) \ emacs_tputs ((tty), a, \ @@ -103,8 +102,10 @@ Lisp_Object Vring_bell_function; /* Functions to call after a tty was deleted. */ Lisp_Object Vdelete_tty_after_functions; -/* Terminal characteristics that higher levels want to look at. */ +/* Chain of all displays currently in use. */ +struct display *display_list; +/* Chain of all tty device parameters. */ struct tty_display_info *tty_list; /* Nonzero means no need to redraw the entire frame on resuming a @@ -115,133 +116,6 @@ int no_redraw_on_reenter; Lisp_Object Qframe_tty_name, Qframe_tty_type; -/* Hook functions that you can set to snap out the functions in this file. - These are all extern'd in termhooks.h */ - -void (*cursor_to_hook) P_ ((int, int)); -void (*raw_cursor_to_hook) P_ ((int, int)); -void (*clear_to_end_hook) P_ ((void)); -void (*clear_frame_hook) P_ ((void)); -void (*clear_end_of_line_hook) P_ ((int)); - -void (*ins_del_lines_hook) P_ ((int, int)); - -void (*delete_glyphs_hook) P_ ((int)); - -void (*ring_bell_hook) P_ ((void)); - -void (*reset_terminal_modes_hook) P_ ((void)); -void (*set_terminal_modes_hook) P_ ((void)); -void (*update_begin_hook) P_ ((struct frame *)); -void (*update_end_hook) P_ ((struct frame *)); -void (*set_terminal_window_hook) P_ ((int)); -void (*insert_glyphs_hook) P_ ((struct glyph *, int)); -void (*write_glyphs_hook) P_ ((struct glyph *, int)); -void (*delete_glyphs_hook) P_ ((int)); - -int (*read_socket_hook) P_ ((struct input_event *, int, int)); - -void (*frame_up_to_date_hook) P_ ((struct frame *)); - -/* Return the current position of the mouse. - - Set *f to the frame the mouse is in, or zero if the mouse is in no - Emacs frame. If it is set to zero, all the other arguments are - garbage. - - If the motion started in a scroll bar, set *bar_window to the - scroll bar's window, *part to the part the mouse is currently over, - *x to the position of the mouse along the scroll bar, and *y to the - overall length of the scroll bar. - - Otherwise, set *bar_window to Qnil, and *x and *y to the column and - row of the character cell the mouse is over. - - Set *time to the time the mouse was at the returned position. - - This should clear mouse_moved until the next motion - event arrives. */ - -void (*mouse_position_hook) P_ ((FRAME_PTR *f, int insist, - Lisp_Object *bar_window, - enum scroll_bar_part *part, - Lisp_Object *x, - Lisp_Object *y, - unsigned long *time)); - -/* When reading from a minibuffer in a different frame, Emacs wants - to shift the highlight from the selected frame to the mini-buffer's - frame; under X, this means it lies about where the focus is. - This hook tells the window system code to re-decide where to put - the highlight. */ - -void (*frame_rehighlight_hook) P_ ((FRAME_PTR f)); - -/* If we're displaying frames using a window system that can stack - frames on top of each other, this hook allows you to bring a frame - to the front, or bury it behind all the other windows. If this - hook is zero, that means the device we're displaying on doesn't - support overlapping frames, so there's no need to raise or lower - anything. - - If RAISE is non-zero, F is brought to the front, before all other - windows. If RAISE is zero, F is sent to the back, behind all other - windows. */ - -void (*frame_raise_lower_hook) P_ ((FRAME_PTR f, int raise)); - -/* Set the vertical scroll bar for WINDOW to have its upper left corner - at (TOP, LEFT), and be LENGTH rows high. Set its handle to - indicate that we are displaying PORTION characters out of a total - of WHOLE characters, starting at POSITION. If WINDOW doesn't yet - have a scroll bar, create one for it. */ - -void (*set_vertical_scroll_bar_hook) - P_ ((struct window *window, - int portion, int whole, int position)); - - -/* The following three hooks are used when we're doing a thorough - redisplay of the frame. We don't explicitly know which scroll bars - are going to be deleted, because keeping track of when windows go - away is a real pain - can you say set-window-configuration? - Instead, we just assert at the beginning of redisplay that *all* - scroll bars are to be removed, and then save scroll bars from the - fiery pit when we actually redisplay their window. */ - -/* Arrange for all scroll bars on FRAME to be removed at the next call - to `*judge_scroll_bars_hook'. A scroll bar may be spared if - `*redeem_scroll_bar_hook' is applied to its window before the judgment. - - This should be applied to each frame each time its window tree is - redisplayed, even if it is not displaying scroll bars at the moment; - if the HAS_SCROLL_BARS flag has just been turned off, only calling - this and the judge_scroll_bars_hook will get rid of them. - - If non-zero, this hook should be safe to apply to any frame, - whether or not it can support scroll bars, and whether or not it is - currently displaying them. */ - -void (*condemn_scroll_bars_hook) P_ ((FRAME_PTR frame)); - -/* Unmark WINDOW's scroll bar for deletion in this judgement cycle. - Note that it's okay to redeem a scroll bar that is not condemned. */ - -void (*redeem_scroll_bar_hook) P_ ((struct window *window)); - -/* Remove all scroll bars on FRAME that haven't been saved since the - last call to `*condemn_scroll_bars_hook'. - - This should be applied to each frame after each time its window - tree is redisplayed, even if it is not displaying scroll bars at the - moment; if the HAS_SCROLL_BARS flag has just been turned off, only - calling this and condemn_scroll_bars_hook will get rid of them. - - If non-zero, this hook should be safe to apply to any frame, - whether or not it can support scroll bars, and whether or not it is - currently displaying them. */ - -void (*judge_scroll_bars_hook) P_ ((FRAME_PTR FRAME)); /* Meaning of bits in no_color_video. Each bit set means that the @@ -270,10 +144,6 @@ 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). */ @@ -323,8 +193,8 @@ ring_bell () Vring_bell_function = function; } - else if (!FRAME_TERMCAP_P (f)) - (*ring_bell_hook) (); + else if (FRAME_DISPLAY (f)->ring_bell_hook) + (*FRAME_DISPLAY (f)->ring_bell_hook) (); else { struct tty_display_info *tty = FRAME_TTY (f); OUTPUT (tty, tty->TS_visible_bell && visible_bell ? tty->TS_visible_bell : tty->TS_bell); @@ -343,10 +213,10 @@ void set_terminal_modes () { struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); - if (FRAME_TERMCAP_P (f)) + if (FRAME_DISPLAY (f)->set_terminal_modes_hook) + (*FRAME_DISPLAY (f)->set_terminal_modes_hook) (); + else tty_set_terminal_modes (FRAME_TTY (f)); - else - (*set_terminal_modes_hook) (); } void tty_reset_terminal_modes (struct tty_display_info *tty) @@ -366,10 +236,10 @@ void reset_terminal_modes () { struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); - if (FRAME_TERMCAP_P (f)) + if (FRAME_DISPLAY (f)->reset_terminal_modes_hook) + (*FRAME_DISPLAY (f)->reset_terminal_modes_hook) (); + else tty_reset_terminal_modes (FRAME_TTY (f)); - else if (reset_terminal_modes_hook) - (*reset_terminal_modes_hook) (); } void @@ -377,15 +247,17 @@ update_begin (f) struct frame *f; { updating_frame = f; - if (!FRAME_TERMCAP_P (f)) - update_begin_hook (f); + if (FRAME_DISPLAY (f)->update_begin_hook) + (*FRAME_DISPLAY (f)->update_begin_hook) (f); } void update_end (f) struct frame *f; { - if (FRAME_TERMCAP_P (f)) + if (FRAME_DISPLAY (f)->update_end_hook) + (*FRAME_DISPLAY (f)->update_end_hook) (f); + else if (FRAME_TERMCAP_P (f)) { struct tty_display_info *tty = FRAME_TTY (f); if (!XWINDOW (selected_window)->cursor_off_p) @@ -393,8 +265,6 @@ update_end (f) turn_off_insert (tty); background_highlight (tty); } - else - update_end_hook (f); updating_frame = NULL; } @@ -404,15 +274,15 @@ set_terminal_window (size) int size; { struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); - if (FRAME_TERMCAP_P (f)) + if (FRAME_DISPLAY (f)->set_terminal_window_hook) + (*FRAME_DISPLAY (f)->set_terminal_window_hook) (size); + else if (FRAME_TERMCAP_P (f)) { struct tty_display_info *tty = FRAME_TTY (f); tty->specified_window = size ? size : FRAME_LINES (f); if (FRAME_SCROLL_REGION_OK (f)) set_scroll_region (0, tty->specified_window); } - else - set_terminal_window_hook (size); } void @@ -545,9 +415,9 @@ 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) + if (FRAME_DISPLAY (f)->cursor_to_hook) { - (*cursor_to_hook) (vpos, hpos); + (*FRAME_DISPLAY (f)->cursor_to_hook) (vpos, hpos); return; } @@ -576,9 +446,9 @@ raw_cursor_to (row, col) { struct frame *f = updating_frame ? updating_frame : XFRAME (selected_frame); struct tty_display_info *tty; - if (! FRAME_TERMCAP_P (f)) + if (FRAME_DISPLAY (f)->raw_cursor_to_hook) { - (*raw_cursor_to_hook) (row, col); + (*FRAME_DISPLAY (f)->raw_cursor_to_hook) (row, col); return; } tty = FRAME_TTY (f); @@ -603,9 +473,9 @@ 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)) + if (FRAME_DISPLAY (f)->clear_to_end_hook) { - (*clear_to_end_hook) (); + (*FRAME_DISPLAY (f)->clear_to_end_hook) (); return; } tty = FRAME_TTY (f); @@ -632,9 +502,9 @@ 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)) + if (FRAME_DISPLAY (f)->clear_frame_hook) { - (*clear_frame_hook) (); + (*FRAME_DISPLAY (f)->clear_frame_hook) (); return; } tty = FRAME_TTY (f); @@ -663,9 +533,9 @@ 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 (FRAME_DISPLAY (f)->clear_end_of_line_hook) { - (*clear_end_of_line_hook) (first_unused_hpos); + (*FRAME_DISPLAY (f)->clear_end_of_line_hook) (first_unused_hpos); return; } @@ -828,9 +698,9 @@ 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 (FRAME_DISPLAY (f)->write_glyphs_hook) { - (*write_glyphs_hook) (string, len); + (*FRAME_DISPLAY (f)->write_glyphs_hook) (string, len); return; } @@ -935,9 +805,9 @@ insert_glyphs (start, len) f = (updating_frame ? updating_frame : XFRAME (selected_frame)); - if (insert_glyphs_hook && ! FRAME_TERMCAP_P (f)) + if (FRAME_DISPLAY (f)->insert_glyphs_hook) { - (*insert_glyphs_hook) (start, len); + (*FRAME_DISPLAY (f)->insert_glyphs_hook) (start, len); return; } @@ -1024,9 +894,9 @@ delete_glyphs (n) struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); struct tty_display_info *tty = FRAME_TTY (f); - if (delete_glyphs_hook && ! FRAME_TERMCAP_P (f)) + if (FRAME_DISPLAY (f)->delete_glyphs_hook) { - (*delete_glyphs_hook) (n); + (*FRAME_DISPLAY (f)->delete_glyphs_hook) (n); return; } @@ -1061,9 +931,9 @@ ins_del_lines (vpos, n) int vpos, n; { struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame)); - if (ins_del_lines_hook && ! FRAME_TERMCAP_P (f)) + if (FRAME_DISPLAY (f)->ins_del_lines_hook) { - (*ins_del_lines_hook) (vpos, n); + (*FRAME_DISPLAY (f)->ins_del_lines_hook) (vpos, n); return; } else @@ -1948,7 +1818,12 @@ DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p, (display) Lisp_Object display; { - struct tty_display_info *tty = FRAME_TTY (SELECTED_FRAME ()); + struct tty_display_info *tty; + + if (! FRAMEP (display)) + return Qnil; + + tty = FRAME_TTY (XFRAME (display)); return tty->TN_max_colors > 0 ? Qt : Qnil; } @@ -1959,7 +1834,12 @@ DEFUN ("tty-display-color-cells", Ftty_display_color_cells, (display) Lisp_Object display; { - struct tty_display_info *tty = FRAME_TTY (SELECTED_FRAME ()); + struct tty_display_info *tty; + + if (! FRAMEP (display)) + return Qnil; + + tty = FRAME_TTY (XFRAME (display)); return make_number (tty->TN_max_colors); } @@ -2102,17 +1982,18 @@ set_tty_color_mode (f, val) -struct tty_display_info * -get_named_tty (name) +static struct display * +get_named_tty_display (name) char *name; { - struct tty_display_info *tty = tty_list; - - while (tty) { - if ((tty->name == 0 && name == 0) - || (name && tty->name && !strcmp (tty->name, name))) - return tty; - tty = tty->next; + struct display *d; + + for (d = display_list; d; d = d->next_display) { + if (d->type == output_termcap + && ((d->display_info.tty->name == 0 && name == 0) + || (name && d->display_info.tty->name + && !strcmp (d->display_info.tty->name, name)))) + return d; }; return 0; @@ -2177,11 +2058,13 @@ DEFUN ("frame-tty-type", Fframe_tty_type, Sframe_tty_type, 0, 1, 0, Initialization ***********************************************************************/ -struct tty_display_info * -term_dummy_init (void) +struct display * +initial_term_init (void) { - if (initialized || tty_list) - error ("tty already initialized"); + if (initialized || display_list || tty_list) + abort (); + + display_list = create_display (); tty_list = xmalloc (sizeof (struct tty_display_info)); bzero (tty_list, sizeof (struct tty_display_info)); @@ -2189,14 +2072,19 @@ term_dummy_init (void) tty_list->input = stdin; 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)); +#ifdef MULTI_KBOARD tty_list->kboard = initial_kboard; - return tty_list; +#endif + + display_list->type = output_termcap; + display_list->display_info.tty = tty_list; + + return display_list; } -struct tty_display_info * -term_init (Lisp_Object frame, char *name, char *terminal_type) +struct display * +term_init (char *name, char *terminal_type) { char *area; char **address = &area; @@ -2204,52 +2092,45 @@ term_init (Lisp_Object frame, char *name, char *terminal_type) int buffer_size = 4096; register char *p; int status; - struct frame *f = XFRAME (frame); struct tty_display_info *tty; + struct display *display; - tty = get_named_tty (name); - if (tty) + display = get_named_tty_display (name); + if (display) { + tty = display->display_info.tty; + /* Return the previously initialized terminal, except if it is the dummy terminal created for the initial frame. */ if (tty->type) - return tty; + return display; /* Free up temporary structures. */ if (tty->Wcm) xfree (tty->Wcm); - if (tty->display_method) - xfree (tty->display_method); if (tty->kboard != initial_kboard) abort (); tty->kboard = 0; } else { + display = create_display (); tty = (struct tty_display_info *) xmalloc (sizeof (struct tty_display_info)); bzero (tty, sizeof (struct tty_display_info)); tty->next = tty_list; tty_list = tty; + + display->type = output_termcap; + display->display_info.tty = tty; } tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm)); Wcm_clear (tty); - /* Each termcap frame has its own display method. */ - tty->display_method = (struct display_method *) xmalloc (sizeof (struct display_method)); - bzero (tty->display_method, 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; - - /* Make sure the frame is live; if an error happens, it must be - deleted. */ - f->output_method = output_termcap; - if (! f->output_data.tty) - abort (); - f->output_data.tty->display_info = tty; + display->rif = 0; /* ttys don't support window-based redisplay. */ + display->delete_frame_hook = &delete_tty_output; + display->delete_display_hook = &delete_tty; + if (name) { int fd; @@ -2257,7 +2138,7 @@ term_init (Lisp_Object frame, char *name, char *terminal_type) fd = emacs_open (name, O_RDWR, 0); if (fd < 0) { - delete_tty (tty); + delete_tty (display); error ("Could not open file: %s", name); } file = fdopen (fd, "w+"); @@ -2283,29 +2164,29 @@ term_init (Lisp_Object frame, char *name, char *terminal_type) area = (char *) xmalloc (2044); - FrameRows (tty) = FRAME_LINES (f); - FrameCols (tty) = FRAME_COLS (f); - tty->specified_window = FRAME_LINES (f); + FrameRows (tty) = FRAME_LINES (f); /* XXX */ + FrameCols (tty) = FRAME_COLS (f); /* XXX */ + tty->specified_window = FRAME_LINES (f); /* XXX */ - tty->display_method->delete_in_insert_mode = 1; + tty->display->delete_in_insert_mode = 1; UseTabs (tty) = 0; - FRAME_SCROLL_REGION_OK (f) = 0; + display->scroll_region_ok = 0; /* Seems to insert lines when it's not supposed to, messing up the display. In doing a trace, it didn't seem to be called much, so I don't think we're losing anything by turning it off. */ - FRAME_LINE_INS_DEL_OK (f) = 0; - FRAME_CHAR_INS_DEL_OK (f) = 1; + display->line_ins_del_ok = 0; + display->char_ins_del_ok = 1; baud_rate = 19200; - FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; - FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; + FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; /* XXX */ + FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; /* XXX */ TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */ - return tty; + return display; #else /* not WINDOWSNT */ Wcm_clear (tty); @@ -2318,7 +2199,7 @@ term_init (Lisp_Object frame, char *name, char *terminal_type) if (name) { xfree (buffer); - delete_tty (tty); + delete_tty (display); error ("Cannot open terminfo database file"); } else @@ -2327,7 +2208,7 @@ term_init (Lisp_Object frame, char *name, char *terminal_type) if (name) { xfree (buffer); - delete_tty (tty); + delete_tty (display); error ("Cannot open termcap database file"); } else @@ -2340,7 +2221,7 @@ term_init (Lisp_Object frame, char *name, char *terminal_type) if (name) { xfree (buffer); - delete_tty (tty); + delete_tty (display); error ("Terminal type %s is not defined", terminal_type); } else @@ -2354,7 +2235,7 @@ to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.", if (name) { xfree (buffer); - delete_tty (tty); + delete_tty (display); error ("Terminal type %s is not defined", terminal_type); } else @@ -2478,9 +2359,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"); - FRAME_MEMORY_BELOW_FRAME (f) = tgetflag ("db"); + display->memory_below_frame = tgetflag ("db"); tty->TF_hazeltine = tgetflag ("hz"); - FRAME_MUST_WRITE_SPACES (f) = tgetflag ("in"); + display->must_write_spaces = tgetflag ("in"); tty->meta_key = tgetflag ("km") || tgetflag ("MT"); tty->TF_insmode_motion = tgetflag ("mi"); tty->TF_standout_motion = tgetflag ("ms"); @@ -2506,7 +2387,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", { if (initialized) { - delete_tty (tty); + delete_tty (display); error ("Screen size %dx%d is too small", FrameCols (tty), FrameRows (tty)); } @@ -2518,7 +2399,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", } #if 0 /* This is not used anywhere. */ - tty->display_method->min_padding_speed = tgetnum ("pb"); + tty->display->min_padding_speed = tgetnum ("pb"); #endif TabWidth (tty) = tgetnum ("tw"); @@ -2596,7 +2477,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", if (!strcmp (terminal_type, "supdup")) { - FRAME_MEMORY_BELOW_FRAME (f) = 1; + display->memory_below_frame = 1; tty->Wcm->cm_losewrap = 1; } if (!strncmp (terminal_type, "c10", 3) @@ -2623,7 +2504,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 */ - FRAME_MUST_WRITE_SPACES (f) = 1; + display->must_write_spaces = 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); @@ -2646,7 +2527,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", if (Wcm_init (tty) == -1) /* can't do cursor motion */ if (name) { - delete_tty (tty); + delete_tty (display); error ("Terminal type \"%s\" is not powerful enough to run Emacs", terminal_type); } @@ -2683,7 +2564,7 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", { if (name) { - delete_tty (tty); + delete_tty (display); error ("The frame size has not been specified"); } else @@ -2700,36 +2581,35 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", UseTabs (tty) = tabs_safe_p (fileno (TTY_INPUT (tty))) && TabWidth (tty) == 8; - FRAME_SCROLL_REGION_OK (f) + display->scroll_region_ok = (tty->Wcm->cm_abs && (tty->TS_set_window || tty->TS_set_scroll_region || tty->TS_set_scroll_region_1)); - FRAME_LINE_INS_DEL_OK (f) + display->line_ins_del_ok = (((tty->TS_ins_line || tty->TS_ins_multi_lines) && (tty->TS_del_line || tty->TS_del_multi_lines)) - || (FRAME_SCROLL_REGION_OK (f) + || (display->scroll_region_ok && tty->TS_fwd_scroll && tty->TS_rev_scroll)); - FRAME_CHAR_INS_DEL_OK (f) + display->char_ins_del_ok = ((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)); - FRAME_FAST_CLEAR_END_OF_LINE (f) = tty->TS_clr_line != 0; + display->fast_clear_end_of_line = tty->TS_clr_line != 0; init_baud_rate (fileno (TTY_INPUT (tty))); - if (read_socket_hook) /* Baudrate is somewhat - meaningless in this case */ - baud_rate = 9600; - FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; - FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; + /* XXX This condition sounds bogus. */ + if (display->read_socket_hook) /* Baudrate is somewhat + meaningless in this case */ + baud_rate = 9600; #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; + display->line_ins_del_ok = 0; + display->char_ins_del_ok = 0; #endif #ifdef MULTI_KBOARD @@ -2748,13 +2628,10 @@ to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.", /* 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); - return tty; + return display; #endif /* not WINDOWSNT */ } @@ -2781,7 +2658,7 @@ tty. The functions are run with one arg, the frame to be deleted. */) (tty) Lisp_Object tty; { - struct tty_display_info *t; + struct display *d; char *name = 0; CHECK_STRING (tty); @@ -2793,29 +2670,35 @@ tty. The functions are run with one arg, the frame to be deleted. */) name[SBYTES (tty)] = 0; } - t = get_named_tty (name); + d = get_named_tty_display (name); - if (! t) - error ("No such tty device: %s", name); + if (! d) + error ("No such terminal device: %s", name); - delete_tty (t); + delete_tty (d); } static int deleting_tty = 0; void -delete_tty (struct tty_display_info *tty) +delete_tty (struct display *display) { + struct tty_display_info *tty; Lisp_Object tail, frame; char *tty_name; if (deleting_tty) /* We get a recursive call when we delete the last frame on this - tty. */ + display. */ return; deleting_tty = 1; + if (display->type != output_termcap) + abort (); + + tty = display->display_info.tty; + if (tty == tty_list) tty_list = tty->next; else @@ -2842,6 +2725,8 @@ delete_tty (struct tty_display_info *tty) } } + delete_display (display); + reset_sys_modes (tty); tty_name = tty->name; @@ -2865,9 +2750,6 @@ delete_tty (struct tty_display_info *tty) if (tty->Wcm) xfree (tty->Wcm); - if (tty->display_method) - xfree (tty->display_method); - #ifdef MULTI_KBOARD if (tty->kboard && --tty->kboard->reference_count > 0) abort (); @@ -2895,6 +2777,34 @@ delete_tty (struct tty_display_info *tty) } } + + +/* Initialize the tty-dependent part of frame F. The frame must + already have its display initialized. */ +void +create_tty_output (struct frame *f) +{ + if (! FRAME_TERMCAP_P (f)) + abort (); + + struct tty_output *t = xmalloc (sizeof (struct tty_output)); + bzero (t, sizeof (struct tty_output)); + + t->display_info = FRAME_DISPLAY (f)->display_info.tty; + + f->output_data.tty = t; +} + +/* Delete the tty-dependent part of frame F. */ +void +delete_tty_output (struct frame *f) +{ + if (! FRAME_TERMCAP_P (f)) + abort (); + + xfree (f->output_data.tty); +} + @@ -2912,6 +2822,35 @@ mark_ttys () } } + + +/* Create a new display object and add it to the display list. */ +struct display * +create_display (void) +{ + struct display *dev = (struct display *) xmalloc (sizeof (struct display)); + + bzero (dev, sizeof (struct display)); + dev->next_display = display_list; + display_list = dev; + + return dev; +} + +/* Remove a display from the display list and free its memory. */ +void +delete_display (struct display *dev) +{ + struct display **dp; + for (dp = &display_list; *dp != dev; dp = &(*dp)->next_display) + if (! *dp) + abort (); + *dp = dev->next_display; + + bzero (dev, sizeof (struct display)); + xfree (dev); +} + void @@ -2951,11 +2890,6 @@ See `delete-tty'. */); Fprovide (intern ("multi-tty"), Qnil); - /* Initialize the display method template. */ - - /* Termcap-based displays don't support window-based redisplay. */ - tty_display_method_template.rif = 0; - } diff --git a/src/termchar.h b/src/termchar.h index 5b9082917f..fe9cd4b27d 100644 --- a/src/termchar.h +++ b/src/termchar.h @@ -179,10 +179,6 @@ struct tty_display_info /* 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; - #ifdef MULTI_KBOARD /* The terminal's keyboard object. */ struct kboard *kboard; @@ -195,7 +191,7 @@ extern struct tty_display_info *tty_list; #define FRAME_TTY(f) \ ((f)->output_method == output_termcap \ - ? (f)->output_data.tty->display_info \ + ? (f)->display->display_info.tty \ : (abort(), (struct tty_display_info *) 0)) #define CURTTY() FRAME_TTY (SELECTED_FRAME()) diff --git a/src/termhooks.h b/src/termhooks.h index 35a8763425..36a31ff4f6 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -1,5 +1,4 @@ -/* Hooks by which low level terminal operations - can be made to call other routines. +/* Parameters and display hooks for output devices Copyright (C) 1985,86,93,94,2003 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -30,75 +29,6 @@ struct frame; #define P_(X) () #endif -/* Device-local parameters. */ -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) - -#define FRAME_RIF(f) ((f)->display_method->rif) - -/* Text display hooks. */ - -extern void (*cursor_to_hook) P_ ((int vpos, int hpos)); -extern void (*raw_cursor_to_hook) P_ ((int, int)); - -extern void (*clear_to_end_hook) P_ ((void)); -extern void (*clear_frame_hook) P_ ((void)); -extern void (*clear_end_of_line_hook) P_ ((int)); - -extern void (*ins_del_lines_hook) P_ ((int, int)); - -extern void (*insert_glyphs_hook) P_ ((struct glyph *s, int n)); -extern void (*write_glyphs_hook) P_ ((struct glyph *s, int n)); -extern void (*delete_glyphs_hook) P_ ((int)); - -extern void (*ring_bell_hook) P_ ((void)); - -extern void (*reset_terminal_modes_hook) P_ ((void)); -extern void (*set_terminal_modes_hook) P_ ((void)); -extern void (*update_begin_hook) P_ ((struct frame *)); -extern void (*update_end_hook) P_ ((struct frame *)); -extern void (*set_terminal_window_hook) P_ ((int)); - - - -/* Multi-frame and mouse support hooks. */ enum scroll_bar_part { scroll_bar_above_handle, @@ -112,125 +42,6 @@ enum scroll_bar_part { scroll_bar_move_ratio }; -/* Return the current position of the mouse. - - Set *f to the frame the mouse is in, or zero if the mouse is in no - Emacs frame. If it is set to zero, all the other arguments are - garbage. - - If the motion started in a scroll bar, set *bar_window to the - scroll bar's window, *part to the part the mouse is currently over, - *x to the position of the mouse along the scroll bar, and *y to the - overall length of the scroll bar. - - Otherwise, set *bar_window to Qnil, and *x and *y to the column and - row of the character cell the mouse is over. - - Set *time to the time the mouse was at the returned position. - - This should clear mouse_moved until the next motion - event arrives. */ -extern void (*mouse_position_hook) P_ ((struct frame **f, int, - Lisp_Object *bar_window, - enum scroll_bar_part *part, - Lisp_Object *x, - Lisp_Object *y, - unsigned long *time)); - -/* The window system handling code should set this if the mouse has - moved since the last call to the mouse_position_hook. Calling that - hook should clear this. */ -extern int mouse_moved; - -/* When a frame's focus redirection is changed, this hook tells the - window system code to re-decide where to put the highlight. Under - X, this means that Emacs lies about where the focus is. */ -extern void (*frame_rehighlight_hook) P_ ((struct frame *)); - -/* If we're displaying frames using a window system that can stack - frames on top of each other, this hook allows you to bring a frame - to the front, or bury it behind all the other windows. If this - hook is zero, that means the device we're displaying on doesn't - support overlapping frames, so there's no need to raise or lower - anything. - - If RAISE is non-zero, F is brought to the front, before all other - windows. If RAISE is zero, F is sent to the back, behind all other - windows. */ -extern void (*frame_raise_lower_hook) P_ ((struct frame *f, int raise)); - - -/* Scroll bar hooks. */ - -/* The representation of scroll bars is determined by the code which - implements them, except for one thing: they must be represented by - lisp objects. This allows us to place references to them in - Lisp_Windows without worrying about those references becoming - dangling references when the scroll bar is destroyed. - - The window-system-independent portion of Emacs just refers to - scroll bars via their windows, and never looks inside the scroll bar - representation; it always uses hook functions to do all the - scroll bar manipulation it needs. - - The `vertical_scroll_bar' field of a Lisp_Window refers to that - window's scroll bar, or is nil if the window doesn't have a - scroll bar. - - The `scroll_bars' and `condemned_scroll_bars' fields of a Lisp_Frame - are free for use by the scroll bar implementation in any way it sees - fit. They are marked by the garbage collector. */ - - -/* Set the vertical scroll bar for WINDOW to have its upper left corner - at (TOP, LEFT), and be LENGTH rows high. Set its handle to - indicate that we are displaying PORTION characters out of a total - of WHOLE characters, starting at POSITION. If WINDOW doesn't yet - have a scroll bar, create one for it. */ -extern void (*set_vertical_scroll_bar_hook) - P_ ((struct window *window, - int portion, int whole, int position)); - - -/* The following three hooks are used when we're doing a thorough - redisplay of the frame. We don't explicitly know which scroll bars - are going to be deleted, because keeping track of when windows go - away is a real pain - can you say set-window-configuration? - Instead, we just assert at the beginning of redisplay that *all* - scroll bars are to be removed, and then save scroll bars from the - fiery pit when we actually redisplay their window. */ - -/* Arrange for all scroll bars on FRAME to be removed at the next call - to `*judge_scroll_bars_hook'. A scroll bar may be spared if - `*redeem_scroll_bar_hook' is applied to its window before the judgement. - - This should be applied to each frame each time its window tree is - redisplayed, even if it is not displaying scroll bars at the moment; - if the HAS_SCROLL_BARS flag has just been turned off, only calling - this and the judge_scroll_bars_hook will get rid of them. - - If non-zero, this hook should be safe to apply to any frame, - whether or not it can support scroll bars, and whether or not it is - currently displaying them. */ -extern void (*condemn_scroll_bars_hook) P_ ((struct frame *frame)); - -/* Unmark WINDOW's scroll bar for deletion in this judgement cycle. - Note that it's okay to redeem a scroll bar that is not condemned. */ -extern void (*redeem_scroll_bar_hook) P_ ((struct window *window)); - -/* Remove all scroll bars on FRAME that haven't been saved since the - last call to `*condemn_scroll_bars_hook'. - - This should be applied to each frame after each time its window - tree is redisplayed, even if it is not displaying scroll bars at the - moment; if the HAS_SCROLL_BARS flag has just been turned off, only - calling this and condemn_scroll_bars_hook will get rid of them. - - If non-zero, this hook should be safe to apply to any frame, - whether or not it can support scroll bars, and whether or not it is - currently displaying them. */ -extern void (*judge_scroll_bars_hook) P_ ((struct frame *FRAME)); - /* Input queue declarations and hooks. */ @@ -413,13 +224,6 @@ struct input_event #define EVENT_INIT(event) bzero (&(event), sizeof (struct input_event)) -/* Called to read input events. */ -extern int (*read_socket_hook) P_ ((struct input_event *, int, int)); - -/* Called when a frame's display becomes entirely up to date. */ -extern void (*frame_up_to_date_hook) P_ ((struct frame *)); - - /* Bits in the modifiers member of the input_event structure. Note that reorder_modifiers assumes that the bits are in canonical order. @@ -471,5 +275,258 @@ enum { #endif /* CONSP */ + +/* Display-local parameters. */ +struct display +{ + /* Chain of all displays. */ + struct display *next_display; + + /* The number of frames that are on this display. */ + int reference_count; + + /* The type of the display. */ + enum output_method type; + + /* Display-type dependent data shared amongst all frames on this display. */ + union display_info + { + struct tty_display_info *tty; /* termchar.h */ + struct x_display_info *x; /* xterm.h */ + } display_info; + + + /* Terminal characteristics. */ + /* XXX Are these really used on non-termcap displays? */ + + 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 device (0 for tty + devices). */ + struct redisplay_interface *rif; + + /* Frame-based redisplay interface. */ + + /* Text display hooks. */ + + void (*cursor_to_hook) P_ ((int vpos, int hpos)); + void (*raw_cursor_to_hook) P_ ((int, int)); + + void (*clear_to_end_hook) P_ ((void)); + void (*clear_frame_hook) P_ ((void)); + void (*clear_end_of_line_hook) P_ ((int)); + + void (*ins_del_lines_hook) P_ ((int, int)); + + void (*insert_glyphs_hook) P_ ((struct glyph *s, int n)); + void (*write_glyphs_hook) P_ ((struct glyph *s, int n)); + void (*delete_glyphs_hook) P_ ((int)); + + void (*ring_bell_hook) P_ ((void)); + + void (*reset_terminal_modes_hook) P_ ((void)); + void (*set_terminal_modes_hook) P_ ((void)); + void (*update_begin_hook) P_ ((struct frame *)); + void (*update_end_hook) P_ ((struct frame *)); + void (*set_terminal_window_hook) P_ ((int)); + + /* Multi-frame and mouse support hooks. */ + + /* Return the current position of the mouse. + + Set *f to the frame the mouse is in, or zero if the mouse is in no + Emacs frame. If it is set to zero, all the other arguments are + garbage. + + If the motion started in a scroll bar, set *bar_window to the + scroll bar's window, *part to the part the mouse is currently over, + *x to the position of the mouse along the scroll bar, and *y to the + overall length of the scroll bar. + + Otherwise, set *bar_window to Qnil, and *x and *y to the column and + row of the character cell the mouse is over. + + Set *time to the time the mouse was at the returned position. + + This should clear mouse_moved until the next motion + event arrives. */ + void (*mouse_position_hook) P_ ((struct frame **f, int, + Lisp_Object *bar_window, + enum scroll_bar_part *part, + Lisp_Object *x, + Lisp_Object *y, + unsigned long *time)); + + /* The window system handling code should set this if the mouse has + moved since the last call to the mouse_position_hook. Calling that + hook should clear this. */ + int mouse_moved; + + /* When a frame's focus redirection is changed, this hook tells the + window system code to re-decide where to put the highlight. Under + X, this means that Emacs lies about where the focus is. */ + void (*frame_rehighlight_hook) P_ ((struct frame *)); + + /* If we're displaying frames using a window system that can stack + frames on top of each other, this hook allows you to bring a frame + to the front, or bury it behind all the other windows. If this + hook is zero, that means the device we're displaying on doesn't + support overlapping frames, so there's no need to raise or lower + anything. + + If RAISE is non-zero, F is brought to the front, before all other + windows. If RAISE is zero, F is sent to the back, behind all other + windows. */ + void (*frame_raise_lower_hook) P_ ((struct frame *f, int raise)); + + + /* Scroll bar hooks. */ + + /* The representation of scroll bars is determined by the code which + implements them, except for one thing: they must be represented by + lisp objects. This allows us to place references to them in + Lisp_Windows without worrying about those references becoming + dangling references when the scroll bar is destroyed. + + The window-system-independent portion of Emacs just refers to + scroll bars via their windows, and never looks inside the scroll bar + representation; it always uses hook functions to do all the + scroll bar manipulation it needs. + + The `vertical_scroll_bar' field of a Lisp_Window refers to that + window's scroll bar, or is nil if the window doesn't have a + scroll bar. + + The `scroll_bars' and `condemned_scroll_bars' fields of a Lisp_Frame + are free for use by the scroll bar implementation in any way it sees + fit. They are marked by the garbage collector. */ + + + /* Set the vertical scroll bar for WINDOW to have its upper left corner + at (TOP, LEFT), and be LENGTH rows high. Set its handle to + indicate that we are displaying PORTION characters out of a total + of WHOLE characters, starting at POSITION. If WINDOW doesn't yet + have a scroll bar, create one for it. */ + void (*set_vertical_scroll_bar_hook) P_ ((struct window *window, + int portion, int whole, + int position)); + + + /* The following three hooks are used when we're doing a thorough + redisplay of the frame. We don't explicitly know which scroll bars + are going to be deleted, because keeping track of when windows go + away is a real pain - can you say set-window-configuration? + Instead, we just assert at the beginning of redisplay that *all* + scroll bars are to be removed, and then save scroll bars from the + fiery pit when we actually redisplay their window. */ + + /* Arrange for all scroll bars on FRAME to be removed at the next call + to `*judge_scroll_bars_hook'. A scroll bar may be spared if + `*redeem_scroll_bar_hook' is applied to its window before the judgement. + + This should be applied to each frame each time its window tree is + redisplayed, even if it is not displaying scroll bars at the moment; + if the HAS_SCROLL_BARS flag has just been turned off, only calling + this and the judge_scroll_bars_hook will get rid of them. + + If non-zero, this hook should be safe to apply to any frame, + whether or not it can support scroll bars, and whether or not it is + currently displaying them. */ + void (*condemn_scroll_bars_hook) P_ ((struct frame *frame)); + + /* Unmark WINDOW's scroll bar for deletion in this judgement cycle. + Note that it's okay to redeem a scroll bar that is not condemned. */ + void (*redeem_scroll_bar_hook) P_ ((struct window *window)); + + /* Remove all scroll bars on FRAME that haven't been saved since the + last call to `*condemn_scroll_bars_hook'. + + This should be applied to each frame after each time its window + tree is redisplayed, even if it is not displaying scroll bars at the + moment; if the HAS_SCROLL_BARS flag has just been turned off, only + calling this and condemn_scroll_bars_hook will get rid of them. + + If non-zero, this hook should be safe to apply to any frame, + whether or not it can support scroll bars, and whether or not it is + currently displaying them. */ + void (*judge_scroll_bars_hook) P_ ((struct frame *FRAME)); + + + /* Called to read input events. */ + int (*read_socket_hook) P_ ((struct input_event *, int, int)); + + /* Called when a frame's display becomes entirely up to date. */ + void (*frame_up_to_date_hook) P_ ((struct frame *)); + + + /* Called to delete the device-specific portions of a frame that is + on this display. */ + void (*delete_frame_hook) P_ ((struct frame *)); + + /* Called after the last frame on this display is deleted. + If this is NULL, then the generic delete_frame() is called. + + Fdelete_frame ensures that there are no live frames on the + display when it calls this hook. */ + void (*delete_display_hook) P_ ((struct display *)); + +}; + + +/* Chain of all displays currently in use. */ +extern struct display *display_list; + +#define FRAME_MUST_WRITE_SPACES(f) ((f)->display->must_write_spaces) +#define FRAME_FAST_CLEAR_END_OF_LINE(f) ((f)->display->fast_clear_end_of_line) +#define FRAME_LINE_INS_DEL_OK(f) ((f)->display->line_ins_del_ok) +#define FRAME_CHAR_INS_DEL_OK(f) ((f)->display->char_ins_del_ok) +#define FRAME_SCROLL_REGION_OK(f) ((f)->display->scroll_region_ok) +#define FRAME_SCROLL_REGION_COST(f) ((f)->display->scroll_region_cost) +#define FRAME_MEMORY_BELOW_FRAME(f) ((f)->display->memory_below_frame) + +#define FRAME_RIF(f) ((f)->display->rif) + +#define FRAME_DISPLAY(f) ((f)->display) + +/* FRAME_WINDOW_P tests whether the frame is a window, and is + defined to be the predicate for the window system being used. */ + +#ifdef HAVE_X_WINDOWS +#define FRAME_WINDOW_P(f) FRAME_X_P (f) +#endif +#ifdef HAVE_NTGUI +#define FRAME_WINDOW_P(f) FRAME_W32_P (f) +#endif +#ifdef MAC_OS +#define FRAME_WINDOW_P(f) FRAME_MAC_P (f) +#endif +#ifndef FRAME_WINDOW_P +#define FRAME_WINDOW_P(f) (0) +#endif + + +extern struct display *create_display P_ ((void)); +extern void delete_display P_ ((struct display *)); + /* arch-tag: 33a00ecc-52b5-4186-a410-8801ac9f087d (do not change this comment) */ diff --git a/src/window.c b/src/window.c index 854fb712a2..c4d896532b 100644 --- a/src/window.c +++ b/src/window.c @@ -31,7 +31,6 @@ Boston, MA 02111-1307, USA. */ #include "window.h" #include "commands.h" #include "indent.h" -#include "systty.h" /* For emacs_tty in termchar.h */ #include "termchar.h" #include "disptab.h" #include "dispextern.h" diff --git a/src/xdisp.c b/src/xdisp.c index dcddeeb903..65c914d65f 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -173,7 +173,6 @@ Boston, MA 02111-1307, USA. */ #include "keyboard.h" #include "frame.h" #include "window.h" -#include "systty.h" /* For emacs_tty in termchar.h */ #include "termchar.h" #include "dispextern.h" #include "buffer.h" @@ -6458,8 +6457,8 @@ message2_nolog (m, nbytes, multibyte) do_pending_window_change (0); echo_area_display (1); do_pending_window_change (0); - if (frame_up_to_date_hook != 0 && ! gc_in_progress) - (*frame_up_to_date_hook) (f); + if (FRAME_DISPLAY (f)->frame_up_to_date_hook != 0 && ! gc_in_progress) + (*FRAME_DISPLAY (f)->frame_up_to_date_hook) (f); } } @@ -6544,8 +6543,8 @@ message3_nolog (m, nbytes, multibyte) do_pending_window_change (0); echo_area_display (1); do_pending_window_change (0); - if (frame_up_to_date_hook != 0 && ! gc_in_progress) - (*frame_up_to_date_hook) (f); + if (FRAME_DISPLAY (f)->frame_up_to_date_hook != 0 && ! gc_in_progress) + (*FRAME_DISPLAY (f)->frame_up_to_date_hook) (f); } } @@ -7616,11 +7615,11 @@ echo_area_display (update_frame_p) /* The terminal frame is used as the first Emacs frame on the Mac OS. */ #ifndef MAC_OS8 #ifdef HAVE_WINDOW_SYSTEM - /* When Emacs starts, selected_frame may be a visible terminal - frame, even if we run under a window system. If we let this - through, a message would be displayed on the terminal. */ - if (!FRAME_WINDOW_P (XFRAME (selected_frame)) - && !NILP (Vwindow_system)) + /* When Emacs starts, selected_frame may be the initial terminal + frame. If we let this through, a message would be displayed on + the terminal. */ + if (FRAME_TERMCAP_P (XFRAME (selected_frame)) + && FRAME_TTY (XFRAME (selected_frame))->type == NULL) return 0; #endif /* HAVE_WINDOW_SYSTEM */ #endif @@ -10100,16 +10099,16 @@ redisplay_internal (preserve_echo_area) /* Mark all the scroll bars to be removed; we'll redeem the ones we want when we redisplay their windows. */ - if (condemn_scroll_bars_hook) - condemn_scroll_bars_hook (f); + if (FRAME_DISPLAY (f)->condemn_scroll_bars_hook) + FRAME_DISPLAY (f)->condemn_scroll_bars_hook (f); if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f)) redisplay_windows (FRAME_ROOT_WINDOW (f)); /* Any scroll bars which redisplay_windows should have nuked should now go away. */ - if (judge_scroll_bars_hook) - judge_scroll_bars_hook (f); + if (FRAME_DISPLAY (f)->judge_scroll_bars_hook) + FRAME_DISPLAY (f)->judge_scroll_bars_hook (f); /* If fonts changed, display again. */ /* ??? rms: I suspect it is a mistake to jump all the way @@ -10161,8 +10160,8 @@ redisplay_internal (preserve_echo_area) { struct frame *f = updated[i]; mark_window_display_accurate (f->root_window, 1); - if (frame_up_to_date_hook) - frame_up_to_date_hook (f); + if (FRAME_DISPLAY (f)->frame_up_to_date_hook) + FRAME_DISPLAY (f)->frame_up_to_date_hook (f); } } } @@ -10251,8 +10250,8 @@ redisplay_internal (preserve_echo_area) last_arrow_position = COERCE_MARKER (Voverlay_arrow_position); last_arrow_string = Voverlay_arrow_string; - if (frame_up_to_date_hook != 0) - frame_up_to_date_hook (sf); + if (FRAME_DISPLAY (sf)->frame_up_to_date_hook != 0) + FRAME_DISPLAY (sf)->frame_up_to_date_hook (sf); } update_mode_lines = 0; @@ -11390,7 +11389,9 @@ set_vertical_scroll_bar (w) start = end = whole = 0; /* Indicate what this scroll bar ought to be displaying now. */ - set_vertical_scroll_bar_hook (w, end - start, whole, start); + if (FRAME_DISPLAY (XFRAME (w->frame))->set_vertical_scroll_bar_hook) + (*FRAME_DISPLAY (XFRAME (w->frame))->set_vertical_scroll_bar_hook) + (w, end - start, whole, start); } /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only @@ -12091,7 +12092,8 @@ redisplay_window (window, just_this_one_p) /* Note that we actually used the scroll bar attached to this window, so it shouldn't be deleted at the end of redisplay. */ - redeem_scroll_bar_hook (w); + if (FRAME_DISPLAY (f)->redeem_scroll_bar_hook) + (*FRAME_DISPLAY (f)->redeem_scroll_bar_hook) (w); } /* Restore current_buffer and value of point in it. */ diff --git a/src/xfaces.c b/src/xfaces.c index 9f51f118f3..77a2663a2c 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -200,6 +200,7 @@ Boston, MA 02111-1307, USA. */ #include "charset.h" #include "keyboard.h" #include "frame.h" +#include "termhooks.h" #ifdef HAVE_WINDOW_SYSTEM #include "fontset.h" @@ -5407,7 +5408,7 @@ substitution of a `dim' face for italic. */) /* See if the capabilities we selected above are supported, with the given colors. */ if (test_caps != 0 && - ! tty_capable_p (FRAME_TTY (SELECTED_FRAME ()), test_caps, fg_tty_color.pixel, bg_tty_color.pixel)) + ! tty_capable_p (FRAME_TTY (f), test_caps, fg_tty_color.pixel, bg_tty_color.pixel)) return Qnil; diff --git a/src/xfns.c b/src/xfns.c index bfb4140f8d..3a1c861686 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -48,7 +48,6 @@ Boston, MA 02111-1307, USA. */ #include "systime.h" #include "termhooks.h" #include "atimer.h" -#include "systty.h" #include "termchar.h" #ifdef HAVE_X_WINDOWS @@ -1762,10 +1761,10 @@ x_set_scroll_bar_foreground (f, value, oldval) if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f)) { /* Remove all scroll bars because they have wrong colors. */ - if (condemn_scroll_bars_hook) - (*condemn_scroll_bars_hook) (f); - if (judge_scroll_bars_hook) - (*judge_scroll_bars_hook) (f); + if (FRAME_DISPLAY (f)->condemn_scroll_bars_hook) + (*FRAME_DISPLAY (f)->condemn_scroll_bars_hook) (f); + if (FRAME_DISPLAY (f)->judge_scroll_bars_hook) + (*FRAME_DISPLAY (f)->judge_scroll_bars_hook) (f); update_face_from_frame_parameter (f, Qscroll_bar_foreground, value); redraw_frame (f); @@ -1811,10 +1810,10 @@ x_set_scroll_bar_background (f, value, oldval) if (FRAME_X_WINDOW (f) && FRAME_VISIBLE_P (f)) { /* Remove all scroll bars because they have wrong colors. */ - if (condemn_scroll_bars_hook) - (*condemn_scroll_bars_hook) (f); - if (judge_scroll_bars_hook) - (*judge_scroll_bars_hook) (f); + if (FRAME_DISPLAY (f)->condemn_scroll_bars_hook) + (*FRAME_DISPLAY (f)->condemn_scroll_bars_hook) (f); + if (FRAME_DISPLAY (f)->judge_scroll_bars_hook) + (*FRAME_DISPLAY (f)->judge_scroll_bars_hook) (f); update_face_from_frame_parameter (f, Qscroll_bar_background, value); redraw_frame (f); @@ -3245,7 +3244,9 @@ 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->display = dpyinfo->frame_display; + f->display->reference_count++; + 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)); @@ -9981,7 +9982,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; + f->display = dpyinfo->frame_display; + f->display->reference_count++; /* By setting the output method, we're essentially saying that the frame is live, as per FRAME_LIVE_P. If we get a signal diff --git a/src/xmenu.c b/src/xmenu.c index 669d8177c1..7c3aa8002b 100644 --- a/src/xmenu.c +++ b/src/xmenu.c @@ -39,10 +39,10 @@ Boston, MA 02111-1307, USA. */ #include #include "lisp.h" -#include "termhooks.h" #include "keyboard.h" #include "keymap.h" #include "frame.h" +#include "termhooks.h" #include "window.h" #include "blockinput.h" #include "buffer.h" diff --git a/src/xselect.c b/src/xselect.c index 8eda4b7846..e1dbb4601d 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -302,13 +302,20 @@ x_own_selection (selection_name, selection_value) Lisp_Object selection_name, selection_value; { struct frame *sf = SELECTED_FRAME (); - Window selecting_window = FRAME_X_WINDOW (sf); - Display *display = FRAME_X_DISPLAY (sf); + Window selecting_window; + Display *display; Time time = last_event_timestamp; Atom selection_atom; - struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (sf); + struct x_display_info *dpyinfo; int count; + if (! FRAME_X_P (sf)) + return; + + selecting_window = FRAME_X_WINDOW (sf); + display = FRAME_X_DISPLAY (sf); + dpyinfo = FRAME_X_DISPLAY_INFO (sf); + CHECK_SYMBOL (selection_name); selection_atom = symbol_to_x_atom (dpyinfo, display, selection_name); @@ -572,7 +579,8 @@ some_frame_on_display (dpyinfo) FOR_EACH_FRAME (list, frame) { - if (FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo) + if (FRAME_X_P (XFRAME (frame)) + && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo) return frame; } @@ -1219,17 +1227,26 @@ x_get_foreign_selection (selection_symbol, target_type) Lisp_Object selection_symbol, target_type; { struct frame *sf = SELECTED_FRAME (); - Window requestor_window = FRAME_X_WINDOW (sf); - Display *display = FRAME_X_DISPLAY (sf); - struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (sf); + Window requestor_window; + Display *display; + struct x_display_info *dpyinfo; Time requestor_time = last_event_timestamp; - Atom target_property = dpyinfo->Xatom_EMACS_TMP; - Atom selection_atom = symbol_to_x_atom (dpyinfo, display, selection_symbol); + Atom target_property; + Atom selection_atom; Atom type_atom; int secs, usecs; int count; Lisp_Object frame; + if (! FRAME_X_P (sf)) + return Qnil; + + requestor_window = FRAME_X_WINDOW (sf); + display = FRAME_X_DISPLAY (sf); + dpyinfo = FRAME_X_DISPLAY_INFO (sf); + target_property = dpyinfo->Xatom_EMACS_TMP; + selection_atom = symbol_to_x_atom (dpyinfo, display, selection_symbol); + if (CONSP (target_type)) type_atom = symbol_to_x_atom (dpyinfo, display, XCAR (target_type)); else @@ -1989,6 +2006,9 @@ Disowning it means there is no such selection. */) struct frame *sf = SELECTED_FRAME (); check_x (); + if (! FRAME_X_P (sf)) + return Qnil; + display = FRAME_X_DISPLAY (sf); dpyinfo = FRAME_X_DISPLAY_INFO (sf); CHECK_SYMBOL (selection); @@ -2152,6 +2172,10 @@ DEFUN ("x-get-cut-buffer-internal", Fx_get_cut_buffer_internal, struct frame *sf = SELECTED_FRAME (); check_x (); + + if (! FRAME_X_P (sf)) + return Qnil; + display = FRAME_X_DISPLAY (sf); dpyinfo = FRAME_X_DISPLAY_INFO (sf); window = RootWindow (display, 0); /* Cut buffers are on screen 0 */ @@ -2193,6 +2217,10 @@ DEFUN ("x-store-cut-buffer-internal", Fx_store_cut_buffer_internal, struct frame *sf = SELECTED_FRAME (); check_x (); + + if (! FRAME_X_P (sf)) + return Qnil; + display = FRAME_X_DISPLAY (sf); window = RootWindow (display, 0); /* Cut buffers are on screen 0 */ @@ -2249,8 +2277,12 @@ Positive means shift the values forward, negative means backward. */) Atom props[8]; Display *display; struct frame *sf = SELECTED_FRAME (); - + check_x (); + + if (! FRAME_X_P (sf)) + return Qnil; + display = FRAME_X_DISPLAY (sf); window = RootWindow (display, 0); /* Cut buffers are on screen 0 */ CHECK_NUMBER (n); diff --git a/src/xsmfns.c b/src/xsmfns.c index 091d21327a..88ee0a7818 100644 --- a/src/xsmfns.c +++ b/src/xsmfns.c @@ -48,6 +48,7 @@ Boston, MA 02111-1307, USA. */ #include "systime.h" #include "sysselect.h" #include "lisp.h" +#include "frame.h" #include "termhooks.h" #include "termopts.h" #include "xterm.h" diff --git a/src/xterm.c b/src/xterm.c index b850139de4..fcb431a472 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -54,7 +54,6 @@ Boston, MA 02111-1307, USA. */ #include #endif /* ! defined (BSD_SYSTEM) */ -#include "systty.h" #include "systime.h" #ifndef INCLUDED_FCNTL @@ -184,10 +183,6 @@ 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. */ @@ -329,6 +324,8 @@ void x_raise_frame P_ ((struct frame *)); void x_set_window_size P_ ((struct frame *, int, int, int)); void x_wm_set_window_state P_ ((struct frame *, int)); void x_wm_set_icon_pixmap P_ ((struct frame *, int)); +struct display *x_create_frame_display P_ ((struct x_display_info *)); +void x_delete_frame_display P_ ((struct display *)); void x_initialize P_ ((void)); static void x_font_min_bounds P_ ((XFontStruct *, int *, int *)); static int x_compute_min_glyph_bounds P_ ((struct frame *)); @@ -10232,6 +10229,7 @@ x_term_init (display_name, xrm_option, resource_name) { int connection; Display *dpy; + struct display *display; struct x_display_info *dpyinfo; XrmDatabase xrdb; @@ -10366,6 +10364,8 @@ x_term_init (display_name, xrm_option, resource_name) dpyinfo = (struct x_display_info *) xmalloc (sizeof (struct x_display_info)); bzero (dpyinfo, sizeof *dpyinfo); + display = x_create_frame_display (dpyinfo); + #ifdef MULTI_KBOARD { struct x_display_info *share; @@ -10716,7 +10716,18 @@ x_delete_display (dpyinfo) struct x_display_info *dpyinfo; { int i; - + + { + /* Delete the generic struct display for this X display. */ + struct display *d; + for (d = display_list; d; d = d->next_display) + if (d->type == output_x_window && d->display_info.x != dpyinfo) + { + delete_display (d); + break; + } + } + delete_keyboard_wait_descriptor (dpyinfo->connection); /* Discard this display from x_display_name_list and x_display_list. @@ -10846,35 +10857,63 @@ static struct redisplay_interface x_redisplay_interface = x_shift_glyphs_for_insert }; + +/* This function is called when the last frame on a display is deleted. */ +void +x_delete_frame_display (struct display *display) +{ + /* We don't do anything, the connection to the X server must remain + open. */ +} + + +struct display * +x_create_frame_display (struct x_display_info *dpyinfo) +{ + struct display *display; + + display = create_display (); + + display->type = output_x_window; + display->display_info.x = dpyinfo; + dpyinfo->frame_display = display; + + display->clear_frame_hook = x_clear_frame; + display->ins_del_lines_hook = x_ins_del_lines; + display->delete_glyphs_hook = x_delete_glyphs; + display->ring_bell_hook = XTring_bell; + display->reset_terminal_modes_hook = XTreset_terminal_modes; + display->set_terminal_modes_hook = XTset_terminal_modes; + display->update_begin_hook = x_update_begin; + display->update_end_hook = x_update_end; + display->set_terminal_window_hook = XTset_terminal_window; + display->read_socket_hook = XTread_socket; + display->frame_up_to_date_hook = XTframe_up_to_date; + display->mouse_position_hook = XTmouse_position; + display->frame_rehighlight_hook = XTframe_rehighlight; + display->frame_raise_lower_hook = XTframe_raise_lower; + display->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar; + display->condemn_scroll_bars_hook = XTcondemn_scroll_bars; + display->redeem_scroll_bar_hook = XTredeem_scroll_bar; + display->judge_scroll_bars_hook = XTjudge_scroll_bars; + + display->delete_frame_hook = x_destroy_window; + display->delete_display_hook = x_delete_frame_display; + + display->rif = &x_redisplay_interface; + display->scroll_region_ok = 1; /* We'll scroll partial frames. */ + display->char_ins_del_ok = 1; + display->line_ins_del_ok = 1; /* We'll just blt 'em. */ + display->fast_clear_end_of_line = 1; /* X does this well. */ + display->memory_below_frame = 0; /* We don't remember what scrolls + off the bottom. */ + + return display; +} + void x_initialize () { - clear_frame_hook = x_clear_frame; - ins_del_lines_hook = x_ins_del_lines; - delete_glyphs_hook = x_delete_glyphs; - ring_bell_hook = XTring_bell; - reset_terminal_modes_hook = XTreset_terminal_modes; - set_terminal_modes_hook = XTset_terminal_modes; - update_begin_hook = x_update_begin; - update_end_hook = x_update_end; - set_terminal_window_hook = XTset_terminal_window; - read_socket_hook = XTread_socket; - frame_up_to_date_hook = XTframe_up_to_date; - mouse_position_hook = XTmouse_position; - frame_rehighlight_hook = XTframe_rehighlight; - frame_raise_lower_hook = XTframe_raise_lower; - set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar; - condemn_scroll_bars_hook = XTcondemn_scroll_bars; - redeem_scroll_bar_hook = XTredeem_scroll_bar; - judge_scroll_bars_hook = XTjudge_scroll_bars; - - 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 3f629a7695..8eb8604ae7 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -134,9 +134,6 @@ 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. */ @@ -385,6 +382,9 @@ struct x_display_info X_WMTYPE_A, X_WMTYPE_B } wm_type; + + /* The generic display parameters corresponding to this X display. */ + struct display *frame_display; }; #ifdef HAVE_X_I18N -- 2.20.1