aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGerd Möllmann2024-12-19 10:14:16 +0100
committerGerd Möllmann2024-12-19 10:14:16 +0100
commit8aef5d224a6fccb675729748836d5ebfdcfa1101 (patch)
tree8738c1748f8b37dbc9683d64be34f1b6bfe927d9 /src
parentea865c98cf3c8a4e0216a81be1b9357a48e7b9a3 (diff)
parent6fa2050ee7663441e4d0aa4fff974cc5d45bffc7 (diff)
downloademacs-8aef5d224a6fccb675729748836d5ebfdcfa1101.tar.gz
emacs-8aef5d224a6fccb675729748836d5ebfdcfa1101.zip
Merge branch 'scratch/tty-child-frames'
Add support for child frames on tty The redisplay part is complete. The frame-handling part supports use-cases like Posframe, Corfu, and child frames acting like tooltips. Other use-cases of child frames are not currently supported. In particular, trying to create minibuffer-only child frames on ttys will signal an error. * src/xfaces.c (free_frame_faces): Change formatting slightly. * src/xdisp.c (redisplay_trace, move_tracxe): Print to stderr because stdout screws up terminal display. (init_iterator): Remove a #ifdef HAVE_WINDOW_SYSTEM. (clear_garbaged_frames): Return a bool telling if we cleared matrix. (echo_area_display): Use combine_updates on tty frames. (redisplay_internal): Changes for redisplay of tty child windows. (deep_copy_glyph_row): Take a frame parameter. (display_tty_menu_item): Changes because of function signature changes. * src/w32term.c (w32_read_socket): Don't use FRAME_OBSCRURED_P, which has been removed. * src/w32inevt.c (do_mouse_event): Workaround for mouse events on child frafmes. * src/w32console.c (w32con_write_glyphs, w32con_update_end): Use glyphs' frame for faces. * src/treesit.c (treesit_load_language): Pacify a warning. * src/w32console.c (w32con_clear_end_of_line): Set glyph's frame. * src/terminal.c (cursor_to, raw_cursor_to): Handle case that frame is a child frame. * src/termhooks.h: Declare formerly static functions. * src/term.c (tty_hide_cursor, tty_show_cursor): Make externally visible. (tty_write_glyphs): Determine faces based on a glyph's frame. (tty_write_glyphs_with_face): Take a struct face argument instead of a face id. Callers changed. (tty_insert_glyphs): Use faces, not face ids. (append_glyph, append_composite_glyph, append_glyphless_glyph): Set glyph's frame. (turn_on_face, turn_off_face): Take face argument instead of face id. Callers adapted. (Fresume_tty): Act on root frame. (tty_draw_row_with_mouse_face): Handle child frames. (restore_desired_matrix): Make sure glyphs' is live. (set_tty_hooks): Set terminal's frame_raise_lower_hook. (tty_frame_geometry, Ftty_frame_geometry, Ftty_frame_edges) (Ftty_frame_list_z_order, Ftty_frame_restack) (tty_display_dimension, Ftty_display_pixel_width) (Ftty_display_pixel_height): New functions. (syms_of_term): Defsubr new Lisp functions. * src/minibuf.c (read_minibuf): Use combine_updates for tty frames. * src/frame.h (struct frame): Always define parent_frame. Change 'visible' to be a boolean. Always define 'undecorated' and 'no_accept_focus'. Add 'z_order'. (FRAME_OBSCURED_P): Removed. (FRAME_PARENT_FRAME): Make it a function. (SET_FRAME_VISIBLE): Take a bool parameter, not an int. (FRAME_INTERNAL_BORDER_WIDTH): Don't special-base HAVE_WINDOW_SYSTEM. * src/frame.c (decode_tty_frame): New function. (set_menu_bar_lines): Set menu bar lines and height to 0 for tty child frames. Compute min height differently. (adjust_frame_size): Set FrameCols/Rows only for root tty frames. Mark tty root frame garbaged if child frame is adjusted. Run some code even if not HAVE_WINDOW_SYSTEM. (make_frame): Run some code even if not HAVE_WINDOW_SYSTEM. (make_terminal_frame): Implement child frame creation. (tty_child_pos_param, tty_child_size_param) (tty_child_frame_rect): New functions. (Fmake_terminal_frame): Parts rewritten for child frames. (do_switch_frame): Add child frame support. (Fframe_ancestor_p): Define if not HAVE_WINDOW_SYSTEM. (Fmake_frame_visible, Fmake_frame_invisible) (Fframe_visible_p, Fraise_frame): Handle tty frames differently. (store_frame_param): Signal error if trying to re-parent a tty child frame. (Fframe_parameters): Report some additional tty frame parameters. (Fmodify_frame_parameters): Handle tty child frames. (Fset_frame_position): Ditto. (frame_parms): Define index for additional frame parameters. (handle_frame_param): New function. (gui_set_frame_parameters_1): Use handle_frame_param. * src/disptab.h (DISP_TABLE_EXTRA_SLOTS): Change to 12. (enum box): New enumeration. * src/dispnew.c (check_rows): New function, #if 0. (frame_matrix_frame): Variable removed. (line_hash_code): Take glyph's frame into account. (build_frame_matrix_from_leaf_window): Do not copy glyphs from rows that aren't enabled. (fill_up_glyph_row_with_spaces): Add frame parameter, uses changed. (fill_up_glyph_row_area_with_spaces): Add frame parameter. Set glyph's frame to it. (fill_up_frame_row_with_spaces): Ditto. (set_frame_matrix_frame): Function removed. (make_current): Change signature. Callers changed. (mirrored_line_dance): Take a frame argument, not a matrix. (redraw_frame): Don't clear_frame a child frame. (struct rect): New. (rect_intersect, frame_pos_abs, frame_rect_abs, root_frame) (max_child_z_order, is_frame_ancestor, frames_with_root) (frames_with_parent, frame_z_order_cmp, Fframe__z_order_lessp) (frames_in_reverse_z_order, tty_raise_lower_frame, is_tty_frame) (is_tty_child_frame, is_tty_root_frame, first_enabled_row) (make_matrix_current, prepare_desired_root_row) (make_glyph_space, neutralize_wide_char, produce_box_glyphs) (produce_box_sides, produce_box_line, copy_child_glyphs) (update_window_frame, update_initial_frame, flush_terminal) (abs_cursor_pos, is_in_matrix, is_cursor_obscured) (terminal_cursor_magic, combine_updates_for_frame) (combine_updates): New functions. (update_frame): Rewritten. (Fdisplay__update_for_mouse_movement): Take a MOUSE_FRAME param. (syms_of_display): New symbol frame--z-order--lessp, tty-non-selected-cursor. New subr Sframe__z_order_lessp. Provide tty-child-frames. * src/dispextern.h (struct glyph): Add member 'frame'. (CHAR_GLYPH_SPACE_P): Add FRAME parameter. All uses changed. (GLYPH_EQUAL_P): Compare glyphs' frame. (SET_CHAR_GLYPH): Add parameter FRAME. (SET_CHAR_GLYPH_FROM_GLYPH): Ditto. * src/chartab.c (Fmake_char_table): Allow more than 10 display table slots. * lisp/xt-mouse.el (xterm-mouse--handle-mouse-movement): Use new terminal parameter xterm-mouse-frame. (xterm-mouse-position-function): Ditto. (xterm-mouse-event): Determine frame under mouse and compute frame-relative coordinates. Set terminal parameter xterm-mouse-frame. * lisp/tty-tip.el: New file implementing tooltip for ttys. * lisp/paren.el (show-paren-function): Don't check if display-graphics-p when using child frames. * lisp/frame.el (frame-at): New function. (tty-frame-geometry, tty-frame-edges, tty-frame-restack) (tty-display-pixel-height, tty-frame-list-z-order) (tty-display-pixel-width): Declare C function. (frame-geometry): Use tty-frame-geometry. (frame-edges): Use tty-frame-edges. (frame-list-z-order): Use tty-frame-list-z-order. (frame-restack): Use tty-frame-restack. (display-pixel-height): Use tty-display-pixel-height. (display-pixel-width): Use tty-display-pixel-width. * lisp/disp-table.el (display-table): Increase size to 12. (box-horizontal, box-vertical, box-down-right, box-down-left) (box-up-right, box-up-left): New display table slot names for box-drawing characters. (display-table-slot, set-display-table-slot): Extend doc string. (describe-display-table): Display new display table slots. (standard-display-unicode-special-glyphs): New function setting up Unicode characters for display table entries. * .gitignore: Don't ignore patch files, they are useful to see in Magit status buffer when applying patches (git am).
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c8
-rw-r--r--src/chartab.c2
-rw-r--r--src/dispextern.h40
-rw-r--r--src/dispnew.c1321
-rw-r--r--src/disptab.h12
-rw-r--r--src/frame.c508
-rw-r--r--src/frame.h83
-rw-r--r--src/keyboard.c2
-rw-r--r--src/minibuf.c6
-rw-r--r--src/nsfns.m4
-rw-r--r--src/nsterm.m4
-rw-r--r--src/scroll.c4
-rw-r--r--src/term.c303
-rw-r--r--src/termhooks.h3
-rw-r--r--src/terminal.c6
-rw-r--r--src/treesit.c2
-rw-r--r--src/w32console.c15
-rw-r--r--src/w32inevt.c11
-rw-r--r--src/w32term.c25
-rw-r--r--src/xdisp.c116
-rw-r--r--src/xfaces.c1
21 files changed, 1827 insertions, 649 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 4fab0d54248..bbabd8c95e8 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -6853,9 +6853,11 @@ mark_glyph_matrix (struct glyph_matrix *matrix)
6853 struct glyph *end_glyph = glyph + row->used[area]; 6853 struct glyph *end_glyph = glyph + row->used[area];
6854 6854
6855 for (; glyph < end_glyph; ++glyph) 6855 for (; glyph < end_glyph; ++glyph)
6856 if (STRINGP (glyph->object) 6856 {
6857 && !string_marked_p (XSTRING (glyph->object))) 6857 if (STRINGP (glyph->object)
6858 mark_object (glyph->object); 6858 && !string_marked_p (XSTRING (glyph->object)))
6859 mark_object (glyph->object);
6860 }
6859 } 6861 }
6860 } 6862 }
6861} 6863}
diff --git a/src/chartab.c b/src/chartab.c
index 58bb1658504..76a40ca7cc4 100644
--- a/src/chartab.c
+++ b/src/chartab.c
@@ -122,8 +122,6 @@ the char-table has no extra slot. */)
122 else 122 else
123 { 123 {
124 CHECK_FIXNAT (n); 124 CHECK_FIXNAT (n);
125 if (XFIXNUM (n) > 10)
126 args_out_of_range (n, Qnil);
127 n_extras = XFIXNUM (n); 125 n_extras = XFIXNUM (n);
128 } 126 }
129 127
diff --git a/src/dispextern.h b/src/dispextern.h
index 9df6eaf623a..1bec5e24c85 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -482,6 +482,11 @@ struct glyph
482 continuation glyphs, or the overlay-arrow glyphs on TTYs. */ 482 continuation glyphs, or the overlay-arrow glyphs on TTYs. */
483 Lisp_Object object; 483 Lisp_Object object;
484 484
485 /* Frame on which the glyph was produced. The face_id of this glyph
486 refers to the face_cache of this frame. This is used on tty
487 frames only. */
488 struct frame *frame;
489
485 /* Width in pixels. */ 490 /* Width in pixels. */
486 short pixel_width; 491 short pixel_width;
487 492
@@ -626,10 +631,12 @@ struct glyph
626 631
627#define FONT_TYPE_UNKNOWN 0 632#define FONT_TYPE_UNKNOWN 0
628 633
629/* Is GLYPH a space? */ 634/* Is GLYPH a space in default face on frame FRAME? */
630 635
631#define CHAR_GLYPH_SPACE_P(GLYPH) \ 636# define CHAR_GLYPH_SPACE_P(FRAME, GLYPH) \
632 ((GLYPH).u.ch == SPACEGLYPH && (GLYPH).face_id == DEFAULT_FACE_ID) 637 ((GLYPH).u.ch == SPACEGLYPH \
638 && (GLYPH).face_id == DEFAULT_FACE_ID \
639 && (GLYPH).frame == (FRAME))
633 640
634/* Are glyph slices of glyphs *X and *Y equal? It assumes that both 641/* Are glyph slices of glyphs *X and *Y equal? It assumes that both
635 glyphs have the same type. 642 glyphs have the same type.
@@ -654,6 +661,7 @@ struct glyph
654 && (X)->u.val == (Y)->u.val \ 661 && (X)->u.val == (Y)->u.val \
655 && GLYPH_SLICE_EQUAL_P (X, Y) \ 662 && GLYPH_SLICE_EQUAL_P (X, Y) \
656 && (X)->face_id == (Y)->face_id \ 663 && (X)->face_id == (Y)->face_id \
664 && (X)->frame == (Y)->frame \
657 && (X)->padding_p == (Y)->padding_p \ 665 && (X)->padding_p == (Y)->padding_p \
658 && (X)->left_box_line_p == (Y)->left_box_line_p \ 666 && (X)->left_box_line_p == (Y)->left_box_line_p \
659 && (X)->right_box_line_p == (Y)->right_box_line_p \ 667 && (X)->right_box_line_p == (Y)->right_box_line_p \
@@ -665,16 +673,18 @@ struct glyph
665#define GLYPH_CHAR_AND_FACE_EQUAL_P(X, Y) \ 673#define GLYPH_CHAR_AND_FACE_EQUAL_P(X, Y) \
666 ((X)->u.ch == (Y)->u.ch \ 674 ((X)->u.ch == (Y)->u.ch \
667 && (X)->face_id == (Y)->face_id \ 675 && (X)->face_id == (Y)->face_id \
676 && (X)->frame == (Y)->frame \
668 && (X)->padding_p == (Y)->padding_p) 677 && (X)->padding_p == (Y)->padding_p)
669 678
670/* Fill a character glyph GLYPH. CODE, FACE_ID, PADDING_P correspond 679/* Fill a character glyph GLYPH. CODE, FACE_ID, PADDING_P correspond
671 to the bits defined for the typedef `GLYPH' in lisp.h. */ 680 to the bits defined for the typedef `GLYPH' in lisp.h. */
672 681
673#define SET_CHAR_GLYPH(GLYPH, CODE, FACE_ID, PADDING_P) \ 682#define SET_CHAR_GLYPH(FRAME, GLYPH, CODE, FACE_ID, PADDING_P) \
674 do \ 683 do \
675 { \ 684 { \
676 (GLYPH).u.ch = (CODE); \ 685 (GLYPH).u.ch = (CODE); \
677 (GLYPH).face_id = (FACE_ID); \ 686 (GLYPH).face_id = (FACE_ID); \
687 (GLYPH).frame = (FRAME); \
678 (GLYPH).padding_p = (PADDING_P); \ 688 (GLYPH).padding_p = (PADDING_P); \
679 } \ 689 } \
680 while (false) 690 while (false)
@@ -682,11 +692,9 @@ struct glyph
682/* Fill a character type glyph GLYPH from a glyph typedef FROM as 692/* Fill a character type glyph GLYPH from a glyph typedef FROM as
683 defined in lisp.h. */ 693 defined in lisp.h. */
684 694
685#define SET_CHAR_GLYPH_FROM_GLYPH(GLYPH, FROM) \ 695#define SET_CHAR_GLYPH_FROM_GLYPH(FRAME, GLYPH, FROM) \
686 SET_CHAR_GLYPH (GLYPH, \ 696 SET_CHAR_GLYPH (FRAME, GLYPH, GLYPH_CHAR (FROM), \
687 GLYPH_CHAR (FROM), \ 697 GLYPH_FACE (FROM), false)
688 GLYPH_FACE (FROM), \
689 false)
690 698
691/* Construct a glyph code from a character glyph GLYPH. If the 699/* Construct a glyph code from a character glyph GLYPH. If the
692 character is multibyte, return -1 as we can't use glyph table for a 700 character is multibyte, return -1 as we can't use glyph table for a
@@ -3835,7 +3843,7 @@ extern void adjust_frame_glyphs (struct frame *);
3835void free_glyphs (struct frame *); 3843void free_glyphs (struct frame *);
3836void free_window_matrices (struct window *); 3844void free_window_matrices (struct window *);
3837void check_glyph_memory (void); 3845void check_glyph_memory (void);
3838void mirrored_line_dance (struct glyph_matrix *, int, int, int *, char *); 3846void mirrored_line_dance (struct frame *f, int, int, int *, char *);
3839void clear_glyph_matrix (struct glyph_matrix *); 3847void clear_glyph_matrix (struct glyph_matrix *);
3840void clear_current_matrices (struct frame *f); 3848void clear_current_matrices (struct frame *f);
3841void clear_desired_matrices (struct frame *); 3849void clear_desired_matrices (struct frame *);
@@ -3859,7 +3867,7 @@ extern bool frame_size_change_delayed (struct frame *);
3859void init_display (void); 3867void init_display (void);
3860void syms_of_display (void); 3868void syms_of_display (void);
3861extern void spec_glyph_lookup_face (struct window *, GLYPH *); 3869extern void spec_glyph_lookup_face (struct window *, GLYPH *);
3862extern void fill_up_frame_row_with_spaces (struct glyph_row *, int); 3870extern void fill_up_frame_row_with_spaces (struct frame *, struct glyph_row *, int);
3863 3871
3864/* Defined in terminal.c. */ 3872/* Defined in terminal.c. */
3865 3873
@@ -3941,6 +3949,16 @@ extern void gui_redo_mouse_highlight (Display_Info *);
3941 3949
3942#endif /* HAVE_WINDOW_SYSTEM */ 3950#endif /* HAVE_WINDOW_SYSTEM */
3943 3951
3952struct frame *root_frame (struct frame *f);
3953Lisp_Object frames_in_reverse_z_order (struct frame *f, bool visible);
3954bool is_tty_frame (struct frame *f);
3955bool is_tty_child_frame (struct frame *f);
3956bool is_tty_root_frame (struct frame *f);
3957bool combine_updates (Lisp_Object root_frames, bool force_p, bool inhibit_id_p);
3958bool combine_updates_for_frame (struct frame *f, bool force_p, bool inhibit_id_p);
3959void tty_raise_lower_frame (struct frame *f, bool raise);
3960int max_child_z_order (struct frame *parent);
3961
3944INLINE_HEADER_END 3962INLINE_HEADER_END
3945 3963
3946#endif /* not DISPEXTERN_H_INCLUDED */ 3964#endif /* not DISPEXTERN_H_INCLUDED */
diff --git a/src/dispnew.c b/src/dispnew.c
index 1a243079e46..d473a77e3ad 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -42,6 +42,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
42#include "tparam.h" 42#include "tparam.h"
43#include "xwidget.h" 43#include "xwidget.h"
44#include "pdumper.h" 44#include "pdumper.h"
45#include "disptab.h"
46#include "cm.h"
45 47
46#ifdef HAVE_ANDROID 48#ifdef HAVE_ANDROID
47#include "android.h" 49#include "android.h"
@@ -71,7 +73,7 @@ struct dim
71 73
72/* Function prototypes. */ 74/* Function prototypes. */
73 75
74static void update_frame_line (struct frame *, int, bool); 76static void write_row (struct frame *f, int vpos, bool updating_menu_p);
75static int required_matrix_height (struct window *); 77static int required_matrix_height (struct window *);
76static int required_matrix_width (struct window *); 78static int required_matrix_width (struct window *);
77static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t); 79static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t);
@@ -80,9 +82,9 @@ static void build_frame_matrix_from_window_tree (struct glyph_matrix *,
80static void build_frame_matrix_from_leaf_window (struct glyph_matrix *, 82static void build_frame_matrix_from_leaf_window (struct glyph_matrix *,
81 struct window *); 83 struct window *);
82static void adjust_decode_mode_spec_buffer (struct frame *); 84static void adjust_decode_mode_spec_buffer (struct frame *);
83static void fill_up_glyph_row_with_spaces (struct glyph_row *); 85static void fill_up_glyph_row_with_spaces (struct frame *, struct glyph_row *);
84static void clear_window_matrices (struct window *, bool); 86static void clear_window_matrices (struct window *, bool);
85static void fill_up_glyph_row_area_with_spaces (struct glyph_row *, int); 87static void fill_up_glyph_row_area_with_spaces (struct frame *, struct glyph_row *, int);
86static int scrolling_window (struct window *, int); 88static int scrolling_window (struct window *, int);
87static bool update_window_line (struct window *, int, bool *); 89static bool update_window_line (struct window *, int, bool *);
88static void mirror_make_current (struct window *, int); 90static void mirror_make_current (struct window *, int);
@@ -93,13 +95,27 @@ static void check_matrix_pointers (struct glyph_matrix *,
93static void mirror_line_dance (struct window *, int, int, int *, char *); 95static void mirror_line_dance (struct window *, int, int, int *, char *);
94static bool update_window_tree (struct window *, bool); 96static bool update_window_tree (struct window *, bool);
95static bool update_window (struct window *, bool); 97static bool update_window (struct window *, bool);
96static bool update_frame_1 (struct frame *, bool, bool, bool, bool); 98static bool write_matrix (struct frame *, bool, bool, bool, bool);
97static bool scrolling (struct frame *); 99static bool scrolling (struct frame *);
98static void set_window_cursor_after_update (struct window *); 100static void set_window_cursor_after_update (struct window *);
99static void adjust_frame_glyphs_for_window_redisplay (struct frame *); 101static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
100static void adjust_frame_glyphs_for_frame_redisplay (struct frame *); 102static void adjust_frame_glyphs_for_frame_redisplay (struct frame *);
101static void set_window_update_flags (struct window *w, bool on_p); 103static void set_window_update_flags (struct window *w, bool on_p);
102 104
105#if 0 /* Please leave this in as a debugging aid. */
106static void
107check_rows (struct frame *f)
108{
109 for (int y = 0; y < f->desired_matrix->nrows; ++y)
110 if (MATRIX_ROW_ENABLED_P (f->desired_matrix, y))
111 {
112 struct glyph_row *row = MATRIX_ROW (f->desired_matrix, y);
113 for (int x = 0; x < row->used[TEXT_AREA]; ++x)
114 eassert (row->glyphs[TEXT_AREA][x].frame != 0);
115 }
116}
117#endif
118
103/* True means last display completed. False means it was preempted. */ 119/* True means last display completed. False means it was preempted. */
104 120
105bool display_completed; 121bool display_completed;
@@ -122,11 +138,6 @@ static int glyph_pool_count;
122 138
123#endif /* GLYPH_DEBUG and ENABLE_CHECKING */ 139#endif /* GLYPH_DEBUG and ENABLE_CHECKING */
124 140
125/* If non-null, the frame whose frame matrices are manipulated. If
126 null, window matrices are worked on. */
127
128static struct frame *frame_matrix_frame;
129
130/* Convert vpos and hpos from frame to window and vice versa. 141/* Convert vpos and hpos from frame to window and vice versa.
131 This may only be used for terminal frames. */ 142 This may only be used for terminal frames. */
132 143
@@ -1178,7 +1189,15 @@ line_hash_code (struct frame *f, struct glyph_row *row)
1178 while (glyph < end) 1189 while (glyph < end)
1179 { 1190 {
1180 int c = glyph->u.ch; 1191 int c = glyph->u.ch;
1181 int face_id = glyph->face_id; 1192 unsigned int face_id = glyph->face_id;
1193 /* A given row of a frame glyph matrix could have glyphs
1194 from more than one frame, if child frames are displayed.
1195 Since face_id of a face depends on the frame (it's an
1196 index into the frame's face cache), we need the hash
1197 value to include something specific to the frame, and we
1198 use the frame cache's address for that purpose. */
1199 if (glyph->frame && glyph->frame != f)
1200 face_id += (uintptr_t) glyph->frame->face_cache;
1182 if (FRAME_MUST_WRITE_SPACES (f)) 1201 if (FRAME_MUST_WRITE_SPACES (f))
1183 c -= SPACEGLYPH; 1202 c -= SPACEGLYPH;
1184 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c; 1203 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c;
@@ -1213,7 +1232,7 @@ line_draw_cost (struct frame *f, struct glyph_matrix *matrix, int vpos)
1213 if (!FRAME_MUST_WRITE_SPACES (f)) 1232 if (!FRAME_MUST_WRITE_SPACES (f))
1214 { 1233 {
1215 /* Skip from the end over trailing spaces. */ 1234 /* Skip from the end over trailing spaces. */
1216 while (end > beg && CHAR_GLYPH_SPACE_P (*(end - 1))) 1235 while (end > beg && CHAR_GLYPH_SPACE_P (f, *(end - 1)))
1217 --end; 1236 --end;
1218 1237
1219 /* All blank line. */ 1238 /* All blank line. */
@@ -1221,7 +1240,7 @@ line_draw_cost (struct frame *f, struct glyph_matrix *matrix, int vpos)
1221 return 0; 1240 return 0;
1222 1241
1223 /* Skip over leading spaces. */ 1242 /* Skip over leading spaces. */
1224 while (CHAR_GLYPH_SPACE_P (*beg)) 1243 while (CHAR_GLYPH_SPACE_P (f, *beg))
1225 ++beg; 1244 ++beg;
1226 } 1245 }
1227 1246
@@ -2558,6 +2577,7 @@ build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct w
2558 int window_y, frame_y; 2577 int window_y, frame_y;
2559 /* If non-zero, a glyph to insert at the right border of W. */ 2578 /* If non-zero, a glyph to insert at the right border of W. */
2560 GLYPH right_border_glyph; 2579 GLYPH right_border_glyph;
2580 struct frame *f = XFRAME (w->frame);
2561 2581
2562 SET_GLYPH_FROM_CHAR (right_border_glyph, 0); 2582 SET_GLYPH_FROM_CHAR (right_border_glyph, 0);
2563 2583
@@ -2599,10 +2619,10 @@ build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct w
2599 2619
2600 /* Fill up the frame row with spaces up to the left margin of the 2620 /* Fill up the frame row with spaces up to the left margin of the
2601 window row. */ 2621 window row. */
2602 fill_up_frame_row_with_spaces (frame_row, window_matrix->matrix_x); 2622 fill_up_frame_row_with_spaces (f, frame_row, window_matrix->matrix_x);
2603 2623
2604 /* Fill up areas in the window matrix row with spaces. */ 2624 /* Fill up areas in the window matrix row with spaces. */
2605 fill_up_glyph_row_with_spaces (window_row); 2625 fill_up_glyph_row_with_spaces (f, window_row);
2606 2626
2607 /* If only part of W's desired matrix has been built, and 2627 /* If only part of W's desired matrix has been built, and
2608 window_row wasn't displayed, use the corresponding current 2628 window_row wasn't displayed, use the corresponding current
@@ -2616,10 +2636,21 @@ build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct w
2616 2636
2617 if (current_row_p) 2637 if (current_row_p)
2618 { 2638 {
2619 /* Copy window row to frame row. */ 2639 /* If the desired glyphs for this row haven't been built,
2620 memcpy (frame_row->glyphs[TEXT_AREA] + window_matrix->matrix_x, 2640 copy from the corresponding current row, but only if it
2621 window_row->glyphs[0], 2641 is enabled, because ottherwise its contents are invalid. */
2622 window_matrix->matrix_w * sizeof (struct glyph)); 2642 struct glyph *to = frame_row->glyphs[TEXT_AREA] + window_matrix->matrix_x;
2643 struct glyph *from = window_row->glyphs[0];
2644 for (int i = 0; i < window_matrix->matrix_w; ++i)
2645 {
2646 if (window_row->enabled_p)
2647 to[i] = from[i];
2648 else
2649 {
2650 to[i] = space_glyph;
2651 to[i].frame = f;
2652 }
2653 }
2623 } 2654 }
2624 else 2655 else
2625 { 2656 {
@@ -2638,7 +2669,7 @@ build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct w
2638 glyph with the vertical border glyph. */ 2669 glyph with the vertical border glyph. */
2639 eassert (border->type == CHAR_GLYPH); 2670 eassert (border->type == CHAR_GLYPH);
2640 border->type = CHAR_GLYPH; 2671 border->type = CHAR_GLYPH;
2641 SET_CHAR_GLYPH_FROM_GLYPH (*border, right_border_glyph); 2672 SET_CHAR_GLYPH_FROM_GLYPH (f, *border, right_border_glyph);
2642 } 2673 }
2643 2674
2644#ifdef GLYPH_DEBUG 2675#ifdef GLYPH_DEBUG
@@ -2701,11 +2732,11 @@ spec_glyph_lookup_face (struct window *w, GLYPH *glyph)
2701 To be called for frame-based redisplay, only. */ 2732 To be called for frame-based redisplay, only. */
2702 2733
2703static void 2734static void
2704fill_up_glyph_row_with_spaces (struct glyph_row *row) 2735fill_up_glyph_row_with_spaces (struct frame *f, struct glyph_row *row)
2705{ 2736{
2706 fill_up_glyph_row_area_with_spaces (row, LEFT_MARGIN_AREA); 2737 fill_up_glyph_row_area_with_spaces (f, row, LEFT_MARGIN_AREA);
2707 fill_up_glyph_row_area_with_spaces (row, TEXT_AREA); 2738 fill_up_glyph_row_area_with_spaces (f, row, TEXT_AREA);
2708 fill_up_glyph_row_area_with_spaces (row, RIGHT_MARGIN_AREA); 2739 fill_up_glyph_row_area_with_spaces (f, row, RIGHT_MARGIN_AREA);
2709} 2740}
2710 2741
2711 2742
@@ -2713,15 +2744,19 @@ fill_up_glyph_row_with_spaces (struct glyph_row *row)
2713 frame-based redisplay only. */ 2744 frame-based redisplay only. */
2714 2745
2715static void 2746static void
2716fill_up_glyph_row_area_with_spaces (struct glyph_row *row, int area) 2747fill_up_glyph_row_area_with_spaces (struct frame *f, struct glyph_row *row,
2748 int area)
2717{ 2749{
2718 if (row->glyphs[area] < row->glyphs[area + 1]) 2750 if (row->glyphs[area] < row->glyphs[area + 1])
2719 { 2751 {
2720 struct glyph *end = row->glyphs[area + 1]; 2752 struct glyph *end = row->glyphs[area + 1];
2721 struct glyph *text = row->glyphs[area] + row->used[area]; 2753 struct glyph *text = row->glyphs[area] + row->used[area];
2722 2754
2723 while (text < end) 2755 for (; text < end; ++text)
2724 *text++ = space_glyph; 2756 {
2757 *text = space_glyph;
2758 text->frame = f;
2759 }
2725 row->used[area] = text - row->glyphs[area]; 2760 row->used[area] = text - row->glyphs[area];
2726 } 2761 }
2727} 2762}
@@ -2731,13 +2766,16 @@ fill_up_glyph_row_area_with_spaces (struct glyph_row *row, int area)
2731 reached. In frame matrices only one area, TEXT_AREA, is used. */ 2766 reached. In frame matrices only one area, TEXT_AREA, is used. */
2732 2767
2733void 2768void
2734fill_up_frame_row_with_spaces (struct glyph_row *row, int upto) 2769fill_up_frame_row_with_spaces (struct frame *f, struct glyph_row *row, int upto)
2735{ 2770{
2736 int i = row->used[TEXT_AREA]; 2771 int i = row->used[TEXT_AREA];
2737 struct glyph *glyph = row->glyphs[TEXT_AREA]; 2772 struct glyph *glyph = row->glyphs[TEXT_AREA];
2738 2773
2739 while (i < upto) 2774 for (; i < upto; ++i)
2740 glyph[i++] = space_glyph; 2775 {
2776 glyph[i] = space_glyph;
2777 glyph[i].frame = f;
2778 }
2741 2779
2742 row->used[TEXT_AREA] = i; 2780 row->used[TEXT_AREA] = i;
2743} 2781}
@@ -2748,17 +2786,6 @@ fill_up_frame_row_with_spaces (struct glyph_row *row, int upto)
2748 Mirroring operations on frame matrices in window matrices 2786 Mirroring operations on frame matrices in window matrices
2749 **********************************************************************/ 2787 **********************************************************************/
2750 2788
2751/* Set frame being updated via frame-based redisplay to F. This
2752 function must be called before updates to make explicit that we are
2753 working on frame matrices or not. */
2754
2755static void
2756set_frame_matrix_frame (struct frame *f)
2757{
2758 frame_matrix_frame = f;
2759}
2760
2761
2762/* Make sure glyph row ROW in CURRENT_MATRIX is up to date. 2789/* Make sure glyph row ROW in CURRENT_MATRIX is up to date.
2763 DESIRED_MATRIX is the desired matrix corresponding to 2790 DESIRED_MATRIX is the desired matrix corresponding to
2764 CURRENT_MATRIX. The update is done by exchanging glyph pointers 2791 CURRENT_MATRIX. The update is done by exchanging glyph pointers
@@ -2768,9 +2795,10 @@ set_frame_matrix_frame (struct frame *f)
2768 operations in window matrices of frame_matrix_frame. */ 2795 operations in window matrices of frame_matrix_frame. */
2769 2796
2770static void 2797static void
2771make_current (struct glyph_matrix *desired_matrix, 2798make_current (struct frame *f, struct window *w, int row)
2772 struct glyph_matrix *current_matrix, int row)
2773{ 2799{
2800 struct glyph_matrix *desired_matrix = f ? f->desired_matrix : w->desired_matrix;
2801 struct glyph_matrix *current_matrix = f ? f->current_matrix : w->current_matrix;
2774 struct glyph_row *current_row = MATRIX_ROW (current_matrix, row); 2802 struct glyph_row *current_row = MATRIX_ROW (current_matrix, row);
2775 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row); 2803 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row);
2776 bool mouse_face_p = current_row->mouse_face_p; 2804 bool mouse_face_p = current_row->mouse_face_p;
@@ -2797,8 +2825,8 @@ make_current (struct glyph_matrix *desired_matrix,
2797 2825
2798 /* If we are called on frame matrices, perform analogous operations 2826 /* If we are called on frame matrices, perform analogous operations
2799 for window matrices. */ 2827 for window matrices. */
2800 if (frame_matrix_frame) 2828 if (f)
2801 mirror_make_current (XWINDOW (frame_matrix_frame->root_window), row); 2829 mirror_make_current (XWINDOW (f->root_window), row);
2802} 2830}
2803 2831
2804 2832
@@ -2862,9 +2890,11 @@ mirror_make_current (struct window *w, int frame_row)
2862 This function is called from do_scrolling and do_direct_scrolling. */ 2890 This function is called from do_scrolling and do_direct_scrolling. */
2863 2891
2864void 2892void
2865mirrored_line_dance (struct glyph_matrix *matrix, int unchanged_at_top, int nlines, 2893mirrored_line_dance (struct frame *f, int unchanged_at_top, int nlines,
2866 int *copy_from, char *retained_p) 2894 int *copy_from, char *retained_p)
2867{ 2895{
2896 struct glyph_matrix *matrix = f->current_matrix;
2897
2868 /* A copy of original rows. */ 2898 /* A copy of original rows. */
2869 struct glyph_row *old_rows; 2899 struct glyph_row *old_rows;
2870 2900
@@ -2894,9 +2924,8 @@ mirrored_line_dance (struct glyph_matrix *matrix, int unchanged_at_top, int nlin
2894 } 2924 }
2895 2925
2896 /* Do the same for window matrices, if MATRIX is a frame matrix. */ 2926 /* Do the same for window matrices, if MATRIX is a frame matrix. */
2897 if (frame_matrix_frame) 2927 mirror_line_dance (XWINDOW (f->root_window),
2898 mirror_line_dance (XWINDOW (frame_matrix_frame->root_window), 2928 unchanged_at_top, nlines, copy_from, retained_p);
2899 unchanged_at_top, nlines, copy_from, retained_p);
2900 2929
2901 SAFE_FREE (); 2930 SAFE_FREE ();
2902} 2931}
@@ -3194,7 +3223,10 @@ redraw_frame (struct frame *f)
3194 future. */ 3223 future. */
3195 SET_FRAME_GARBAGED (f); 3224 SET_FRAME_GARBAGED (f);
3196 3225
3197 clear_frame (f); 3226 /* clear_frame is actually a "clear_terminal", i.e.
3227 it clears the entire screen. */
3228 if (!FRAME_PARENT_FRAME (f))
3229 clear_frame (f);
3198 clear_current_matrices (f); 3230 clear_current_matrices (f);
3199 update_end (f); 3231 update_end (f);
3200 fset_redisplay (f); 3232 fset_redisplay (f);
@@ -3229,145 +3261,797 @@ DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
3229 return Qnil; 3261 return Qnil;
3230} 3262}
3231 3263
3232
3233 3264
3234/*********************************************************************** 3265/**********************************************************************
3235 Frame Update 3266 TTY Child Frames
3236 ***********************************************************************/ 3267 **********************************************************************/
3237 3268
3238/* Update frame F based on the data in desired matrices. 3269/* Child frames on ttys break the assumption that frames on a tty
3270 always occupy the whole terminal. They can overlap instead.
3239 3271
3240 If FORCE_P, don't let redisplay be stopped by detecting pending input. 3272 Let a "root" frame be a frame that has no parent frame. Such root
3241 If INHIBIT_HAIRY_ID_P, don't try scrolling. 3273 frames are required to be the size of the terminal screen. The
3274 current glyph matrix of a root frame of a termimnal represents what
3275 is on the screen. The desired matrix of a root frame represents
3276 what should be one the screen.
3242 3277
3243 Value is true if redisplay was stopped due to pending input. */ 3278 Building the desired matrix of root frame proceeds by
3279
3280 - building the desired matrix of the root frame itself which is
3281 the bottommost frame in z-order;
3282 - building desired matrices of child frames in z-order, topmost last;
3283 - copying the desired glyphs from child frames to the desired glyphs
3284 of the root frame
3285
3286 Updating the screen is then done using root frame matrices as it
3287 was before child frames were introduced. Child frame's current
3288 matrices are updated by copying glyph contents of the current
3289 matrix of the root frames to the current matrices of child
3290 frames. This implicitly also updates the glyph contents of their
3291 windows' current matrices. */
3292
3293struct rect
3294{
3295 int x, y, w, h;
3296};
3297
3298/* Compute the intersection of R1 and R2 in R. Value is true if R1 and
3299 R2 intersect, false otherwise. */
3300
3301static bool
3302rect_intersect (struct rect *r, struct rect r1, struct rect r2)
3303{
3304 int x1 = max (r1.x, r2.x);
3305 int x2 = min (r1.x + r1.w, r2.x + r2.w);
3306 if (x2 < x1)
3307 return false;
3308 int y1 = max (r1.y, r2.y);
3309 int y2 = min (r1.y + r1.h, r2.y + r2.h);
3310 if (y2 < y1)
3311 return false;
3312 *r = (struct rect) { .x = x1, .y = y1, .w = x2 - x1, .h = y2 - y1 };
3313 return true;
3314}
3315
3316/* Return the absolute position of frame F in *X and *Y. */
3317
3318static void
3319frame_pos_abs (struct frame *f, int *x, int *y)
3320{
3321 *x = *y = 0;
3322 for (; f; f = FRAME_PARENT_FRAME (f))
3323 {
3324 *x += f->left_pos;
3325 *y += f->top_pos;
3326 }
3327}
3328
3329/* Return the rectangle frame F occupies. X and Y are in absolute
3330 coordinates. */
3331
3332static struct rect
3333frame_rect_abs (struct frame *f)
3334{
3335 int x, y;
3336 frame_pos_abs (f, &x, &y);
3337 return (struct rect) { x, y, f->total_cols, f->total_lines };
3338}
3339
3340/* Return the root frame of frame F. Follow the parent_frame chain
3341 until we reach a frame that has no parent. That is the root frame.
3342 Note that the root of a root frame is itself. */
3343
3344struct frame *
3345root_frame (struct frame *f)
3346{
3347 while (FRAME_PARENT_FRAME (f))
3348 f = FRAME_PARENT_FRAME (f);
3349 return f;
3350}
3351
3352int
3353max_child_z_order (struct frame *parent)
3354{
3355 Lisp_Object tail, frame;
3356 int z_order = 0;
3357 FOR_EACH_FRAME (tail, frame)
3358 {
3359 struct frame *f = XFRAME (frame);
3360 if (FRAME_PARENT_FRAME (f) == parent)
3361 z_order = max (z_order, f->z_order);
3362 }
3363 return z_order;
3364}
3365
3366/* Return true if F1 is an ancestor of F2. */
3367
3368static bool
3369is_frame_ancestor (struct frame *f1, struct frame *f2)
3370{
3371 for (struct frame *f = FRAME_PARENT_FRAME (f2); f; f = FRAME_PARENT_FRAME (f))
3372 if (f == f1)
3373 return true;
3374 return false;
3375}
3376
3377/* Return a list of all frames having root frame ROOT.
3378 If VISIBLE_ONLY is true, return only visible frames. */
3379
3380static Lisp_Object
3381frames_with_root (struct frame *root, bool visible_only)
3382{
3383 Lisp_Object list = Qnil;
3384 Lisp_Object tail, frame;
3385 FOR_EACH_FRAME (tail, frame)
3386 {
3387 struct frame *f = XFRAME (frame);
3388 if (root_frame (f) == root
3389 && (!visible_only || FRAME_VISIBLE_P (f)))
3390 list = Fcons (frame, list);
3391 }
3392 return list;
3393}
3394
3395/* Return a list of frames having parent frame PARENT.
3396 If VISIBLE_ONLY is true, return only visible frames. */
3397
3398static Lisp_Object
3399frames_with_parent (struct frame *parent, bool visible_only)
3400{
3401 Lisp_Object list = Qnil;
3402 Lisp_Object tail, frame;
3403 FOR_EACH_FRAME (tail, frame)
3404 {
3405 struct frame *f = XFRAME (frame);
3406 if (FRAME_PARENT_FRAME (f) == parent
3407 && (!visible_only || FRAME_VISIBLE_P (f)))
3408 list = Fcons (frame, list);
3409 }
3410 return list;
3411}
3412
3413/* Compare frames F1 and F2 for z-order. Value is like strcmp. */
3414
3415static int
3416frame_z_order_cmp (struct frame *f1, struct frame *f2)
3417{
3418 if (f1 == f2)
3419 return 0;
3420 if (is_frame_ancestor (f1, f2))
3421 return -1;
3422 if (is_frame_ancestor (f2, f1))
3423 return 1;
3424 return f1->z_order - f2->z_order;
3425}
3426
3427DEFUN ("frame--z-order-lessp", Fframe__z_order_lessp, Sframe__z_order_lessp,
3428 2, 2, 0, doc: /* Internal frame sorting function A < B. */)
3429 (Lisp_Object a, Lisp_Object b)
3430{
3431 eassert (FRAMEP (a) && FRAMEP (b));
3432 return frame_z_order_cmp (XFRAME (a), XFRAME (b)) < 0 ? Qt : Qnil;
3433}
3434
3435/* Return a z-order list of frames with the same root as F. The list
3436 is ordered topmost frame last. Note that this list contains
3437 the root frame of F itself as first element. */
3438
3439Lisp_Object
3440frames_in_reverse_z_order (struct frame *f, bool visible_only)
3441{
3442 struct frame *root = root_frame (f);
3443 Lisp_Object frames = frames_with_root (root, visible_only);
3444 frames = CALLN (Fsort, frames, QClessp, Qframe__z_order_lessp);
3445 eassert (FRAMEP (XCAR (frames)));
3446 eassert (XFRAME (XCAR (frames)) == root);
3447 return frames;
3448}
3449
3450/* Raise of lower frame F in z-order. If RAISE is true, raise F, else
3451 lower f. */
3452
3453void
3454tty_raise_lower_frame (struct frame *f, bool raise)
3455{
3456 struct frame *parent = FRAME_PARENT_FRAME (f);
3457 if (parent == NULL)
3458 return;
3459
3460 Lisp_Object siblings = frames_with_parent (parent, false);
3461 siblings = CALLN (Fsort, siblings, QClessp, Qframe__z_order_lessp);
3462
3463 int i = 0;
3464 for (Lisp_Object tail = siblings; CONSP (tail); tail = XCDR (tail))
3465 {
3466 struct frame *child = XFRAME (XCAR (tail));
3467 if (child != f)
3468 child->z_order = i++;
3469 }
3470 f->z_order = raise ? i : 0;
3471}
3472
3473/* Return true if frame F is a tty frame. */
3244 3474
3245bool 3475bool
3246update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p) 3476is_tty_frame (struct frame *f)
3247{ 3477{
3248 /* True means display has been paused because of pending input. */ 3478 return FRAME_TERMCAP_P (f);
3249 bool paused_p; 3479}
3250 struct window *root_window = XWINDOW (f->root_window);
3251 3480
3252 if (redisplay_dont_pause) 3481/* Return true if frame F is a tty child frame. */
3253 force_p = true; 3482
3254 else if (!force_p && detect_input_pending_ignore_squeezables ()) 3483bool
3484is_tty_child_frame (struct frame *f)
3485{
3486 return FRAME_PARENT_FRAME (f) && is_tty_frame (f);
3487}
3488
3489/* Return true if frame F is a tty root frame. */
3490
3491bool
3492is_tty_root_frame (struct frame *f)
3493{
3494 return !FRAME_PARENT_FRAME (f) && is_tty_frame (f);
3495}
3496
3497/* Return the index of the first enabled row in MATRIX, or -1 if there
3498 is none. */
3499
3500static int
3501first_enabled_row (struct glyph_matrix *matrix)
3502{
3503 for (int i = 0; i < matrix->nrows; ++i)
3504 if (MATRIX_ROW_ENABLED_P (matrix, i))
3505 return i;
3506 return -1;
3507}
3508
3509/* On tty frame F, make desired matrix current, without writing
3510 to the terminal. */
3511
3512static void
3513make_matrix_current (struct frame *f)
3514{
3515 int first_row = first_enabled_row (f->desired_matrix);
3516 if (first_row >= 0)
3517 for (int i = first_row; i < f->desired_matrix->nrows; ++i)
3518 if (MATRIX_ROW_ENABLED_P (f->desired_matrix, i))
3519 make_current (f, NULL, i);
3520}
3521
3522/* Prepare ROOT's desired row at index Y for copying child frame
3523 contents to it. Value is the prepared desired row or NULL if we
3524 don't have, and can't contruct a desired row. */
3525
3526static struct glyph_row *
3527prepare_desired_root_row (struct frame *root, int y)
3528{
3529 /* If we have a desired row that has been displayed, use that. */
3530 struct glyph_row *desired_row = MATRIX_ROW (root->desired_matrix, y);
3531 if (desired_row->enabled_p)
3532 return desired_row;
3533
3534 /* If we have a current row that is up to date, copy that to the
3535 desired row and use that. */
3536 /* Don't copy rows that aren't enabled, in particuler because they
3537 might not have the 'frame' member of glyphs set. */
3538 struct glyph_row *current_row = MATRIX_ROW (root->current_matrix, y);
3539 if (current_row->enabled_p)
3255 { 3540 {
3256 paused_p = true; 3541 memcpy (desired_row->glyphs[0], current_row->glyphs[0],
3257 goto do_pause; 3542 root->current_matrix->matrix_w * sizeof (struct glyph));
3543 desired_row->enabled_p = true;
3544 return desired_row;
3258 } 3545 }
3259 3546
3260 if (FRAME_WINDOW_P (f)) 3547 return NULL;
3548}
3549
3550/* Change GLYPH to be a space glyph. */
3551
3552static void
3553make_glyph_space (struct glyph *glyph)
3554{
3555 glyph->u.ch = ' ';
3556 glyph->pixel_width = 1;
3557 glyph->padding_p = 0;
3558}
3559
3560/* On root frame ROOT, if the glyph in ROW at position X is part of a
3561 sequence of glyphs for a wide character, change every glyph belonging
3562 to the sequence to a space. If X is outside of ROOT, do nothing. */
3563
3564static void
3565neutralize_wide_char (struct frame *root, struct glyph_row *row, int x)
3566{
3567 if (x < 0 || x >= root->desired_matrix->matrix_w)
3568 return;
3569
3570 struct glyph *glyph = row->glyphs[TEXT_AREA] + x;
3571 if (glyph->type == CHAR_GLYPH && CHARACTER_WIDTH (glyph->u.ch) > 1)
3261 { 3572 {
3262 /* We are working on window matrix basis. All windows whose 3573 /* Glyph is somewhere in a sequence of glyphs for a wide
3263 flag must_be_updated_p is set have to be updated. */ 3574 character, find the start. */
3575 struct glyph *row_start = row->glyphs[TEXT_AREA];
3576 while (glyph > row_start && glyph->padding_p)
3577 --glyph;
3264 3578
3265 /* Record that we are not working on frame matrices. */ 3579 /* Make everything in the sequence a space glyph. */
3266 set_frame_matrix_frame (NULL); 3580 eassert (!glyph->padding_p);
3581 make_glyph_space (glyph);
3582 struct glyph *row_limit = row_start + row->used[TEXT_AREA];
3583 for (++glyph; glyph < row_limit && glyph->padding_p; ++glyph)
3584 make_glyph_space (glyph);
3585 }
3586}
3267 3587
3268 /* Update all windows in the window tree of F, maybe stopping 3588/* Produce glyphs for box character BOX in ROW. X is the position in
3269 when pending input is detected. */ 3589 ROW where to start producing glyphs. N is the number of glyphs to
3270 update_begin (f); 3590 produce. CHILD is the frame to use for the face of the glyphs. */
3271 3591
3272#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR 3592static void
3273 /* Update the menu bar on X frames that don't have toolkit 3593produce_box_glyphs (enum box box, struct glyph_row *row, int x, int n,
3274 support. */ 3594 struct frame *child)
3275 if (WINDOWP (f->menu_bar_window)) 3595{
3276 update_window (XWINDOW (f->menu_bar_window), true); 3596 int dflt;
3277#endif 3597 switch (box)
3598 {
3599 case BOX_VERTICAL:
3600 dflt = '|';
3601 break;
3602 case BOX_HORIZONTAL:
3603 dflt = '-';
3604 break;
3605 case BOX_DOWN_RIGHT:
3606 case BOX_DOWN_LEFT:
3607 case BOX_UP_RIGHT:
3608 case BOX_UP_LEFT:
3609 dflt = '+';
3610 break;
3611 }
3278 3612
3279#if defined (HAVE_WINDOW_SYSTEM) 3613 /* FIXME/tty: some face for the border. */
3280 /* Update the tab-bar window, if present. */ 3614 int face_id = BORDER_FACE_ID;
3281 if (WINDOWP (f->tab_bar_window)) 3615 GLYPH g;
3616 SET_GLYPH (g, dflt, face_id);
3617
3618 if (DISP_TABLE_P (Vstandard_display_table))
3619 {
3620 struct Lisp_Char_Table *dp = XCHAR_TABLE (Vstandard_display_table);
3621 Lisp_Object gc = dp->extras[box];
3622 if (GLYPH_CODE_P (gc))
3282 { 3623 {
3283 struct window *w = XWINDOW (f->tab_bar_window); 3624 SET_GLYPH_FROM_GLYPH_CODE (g, gc);
3625 /* Sorry, but I really don't care if the glyph has a face :-). */
3626 }
3627 }
3284 3628
3285 /* Update tab-bar window. */ 3629 struct glyph *glyph = row->glyphs[0] + x;
3286 if (w->must_be_updated_p) 3630 for (int i = 0; i < n; ++i, ++glyph)
3287 { 3631 {
3288 Lisp_Object tem; 3632 glyph->type = CHAR_GLYPH;
3633 glyph->u.ch = GLYPH_CHAR (g);
3634 glyph->charpos = -1;
3635 glyph->pixel_width = 1;
3636 glyph->multibyte_p = 1;
3637 glyph->face_id = GLYPH_FACE (g);
3638 glyph->frame = child;
3639 glyph->padding_p = 0;
3640 glyph->object = Qnil;
3641 glyph->padding_p = 0;
3642 }
3643}
3289 3644
3290 update_window (w, true); 3645/* Produce box glyphs LEFT and RIGHT in ROOT_ROW. X and W are the start
3291 w->must_be_updated_p = false; 3646 and width of a range in ROOT_ROW before and after which to put the
3647 box glyphs, if they fit. ROOT and CHILD are root and child frame we
3648 are working on. ROOT is the root frame whose matrix dimensions
3649 determines if the box glyphs fit. CHILD is the frame whose faces to
3650 use for the box glyphs. */
3292 3651
3293 /* Swap tab-bar strings. We swap because we want to 3652static void
3294 reuse strings. */ 3653produce_box_sides (enum box left, enum box right, struct glyph_row *root_row, int x,
3295 tem = f->current_tab_bar_string; 3654 int w, struct frame *root, struct frame *child)
3296 fset_current_tab_bar_string (f, f->desired_tab_bar_string); 3655{
3297 fset_desired_tab_bar_string (f, tem); 3656 if (x > 0)
3298 } 3657 {
3658 neutralize_wide_char (root, root_row, x - 1);
3659 produce_box_glyphs (left, root_row, x - 1, 1, child);
3660 }
3661
3662 if (x + w < root->desired_matrix->matrix_w)
3663 {
3664 neutralize_wide_char (root, root_row, x + w);
3665 produce_box_glyphs (right, root_row, x + w, 1, child);
3666 }
3667}
3668
3669static void
3670produce_box_line (struct frame *root, struct frame *child, int x, int y, int w,
3671 bool first)
3672{
3673 struct glyph_row *root_row = prepare_desired_root_row (root, y);
3674 if (root_row == NULL)
3675 return;
3676 if (first)
3677 produce_box_sides (BOX_DOWN_RIGHT, BOX_DOWN_LEFT, root_row, x, w, root, child);
3678 else
3679 produce_box_sides (BOX_UP_RIGHT, BOX_UP_LEFT, root_row, x, w, root, child);
3680 produce_box_glyphs (BOX_HORIZONTAL, root_row, x, w, child);
3681 root_row->hash = row_hash (root_row);
3682}
3683
3684/* Copy to ROOT's desired matrix what we need from CHILD. */
3685
3686static void
3687copy_child_glyphs (struct frame *root, struct frame *child)
3688{
3689 eassert (!FRAME_PARENT_FRAME (root));
3690 eassert (is_frame_ancestor (root, child));
3691
3692 /* Determine the intersection of the child frame rectangle with the
3693 root frame. This is basically clipping the child frame to the
3694 root frame rectangle. */
3695 struct rect r;
3696 if (!rect_intersect (&r, frame_rect_abs (root), frame_rect_abs (child)))
3697 return;
3698
3699 /* Build CHILD's current matrix which we need to copy from it. */
3700 make_matrix_current (child);
3701
3702 /* Draw borders around the child frame. */
3703 if (!FRAME_UNDECORATED (child))
3704 {
3705 /* Horizontal line above. */
3706 if (r.y > 0)
3707 produce_box_line (root, child, r.x, r.y - 1, r.w, true);
3708
3709 for (int y = r.y; y < r.y + r.h; ++y)
3710 {
3711 struct glyph_row *root_row = prepare_desired_root_row (root, y);
3712 if (root_row)
3713 produce_box_sides (BOX_VERTICAL, BOX_VERTICAL, root_row, r.x, r.w,
3714 root, child);
3299 } 3715 }
3300#endif
3301 3716
3302#if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR) 3717 /* Horizontal line below. */
3303 /* Update the tool-bar window, if present. */ 3718 if (r.y + r.h < root->desired_matrix->matrix_h)
3304 if (WINDOWP (f->tool_bar_window)) 3719 produce_box_line (root, child, r.x, r.y + r.h, r.w, false);
3720 }
3721
3722 /* First visible row/col, relative to the child frame. */
3723 int child_x = child->left_pos < 0 ? - child->left_pos : 0;
3724 int child_y = child->top_pos < 0 ? - child->top_pos : 0;
3725
3726 /* For all rows in the intersection, copy glyphs from the child's
3727 current matrix to the root's desired matrix, enabling those rows
3728 if they aren't already. */
3729 for (int y = r.y; y < r.y + r.h; ++y, ++child_y)
3730 {
3731 struct glyph_row *root_row = prepare_desired_root_row (root, y);
3732 if (root_row == NULL)
3733 continue;
3734
3735 /* Deal with wide characters unless already done as part of
3736 drawing a box around the child frame. */
3737 if (FRAME_UNDECORATED (child))
3305 { 3738 {
3306 struct window *w = XWINDOW (f->tool_bar_window); 3739 neutralize_wide_char (root, root_row, r.x - 1);
3740 neutralize_wide_char (root, root_row, r.x + r.w);
3741 }
3307 3742
3308 /* Update tool-bar window. */ 3743 /* Copy what's visible from the child's current row. If that row
3309 if (w->must_be_updated_p) 3744 is not enabled_p, we can't copy anything that makes sense. */
3310 { 3745 struct glyph_row *child_row = MATRIX_ROW (child->current_matrix, child_y);
3311 Lisp_Object tem; 3746 if (child_row->enabled_p)
3747 memcpy (root_row->glyphs[0] + r.x, child_row->glyphs[0] + child_x,
3748 r.w * sizeof (struct glyph));
3312 3749
3313 update_window (w, true); 3750 /* Compute a new hash since we changed glyphs. */
3314 w->must_be_updated_p = false; 3751 root_row->hash = row_hash (root_row);
3752 }
3753}
3315 3754
3316 /* Swap tool-bar strings. We swap because we want to 3755/***********************************************************************
3317 reuse strings. */ 3756 Frame Update
3318 tem = f->current_tool_bar_string; 3757 ***********************************************************************/
3319 fset_current_tool_bar_string (f, f->desired_tool_bar_string); 3758
3320 fset_desired_tool_bar_string (f, tem); 3759/* Update the menu bar on X frames that don't have toolkit
3321 } 3760 support. */
3761
3762static void
3763update_menu_bar (struct frame *f)
3764{
3765#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
3766 if (WINDOWP (f->menu_bar_window))
3767 update_window (XWINDOW (f->menu_bar_window), true);
3768#endif
3769}
3770
3771#ifdef HAVE_WINDOW_SYSTEM
3772static void
3773update_bar_window (Lisp_Object window, Lisp_Object *current,
3774 Lisp_Object *desired)
3775{
3776 if (WINDOWP (window))
3777 {
3778 struct window *w = XWINDOW (window);
3779 if (w->must_be_updated_p)
3780 {
3781 update_window (w, true);
3782 w->must_be_updated_p = false;
3783 Lisp_Object tem = *current;
3784 *current = *desired;
3785 *desired = tem;
3322 } 3786 }
3787 }
3788}
3323#endif 3789#endif
3324 3790
3325 /* Update windows. */ 3791/* Update the tab-bar window of frame F, if present. */
3326 paused_p = update_window_tree (root_window, force_p); 3792
3327 update_end (f); 3793static void
3794update_tab_bar (struct frame *f)
3795{
3796#if defined(HAVE_WINDOW_SYSTEM)
3797 update_bar_window (f->tab_bar_window, &f->current_tab_bar_string,
3798 &f->desired_tab_bar_string);
3799#endif
3800}
3801
3802static void
3803update_tool_bar (struct frame *f)
3804{
3805#if defined(HAVE_WINDOW_SYSTEM) && !defined(HAVE_EXT_TOOL_BAR)
3806 update_bar_window (f->tool_bar_window, &f->current_tool_bar_string,
3807 &f->desired_tool_bar_string);
3808#endif
3809}
3810
3811static bool
3812update_window_frame (struct frame *f, bool force_p)
3813{
3814 eassert (FRAME_WINDOW_P (f));
3815 update_begin (f);
3816 update_menu_bar (f);
3817 update_tab_bar (f);
3818 update_tool_bar (f);
3819 struct window *root_window = XWINDOW (f->root_window);
3820 bool paused_p = update_window_tree (root_window, force_p);
3821 update_end (f);
3822 set_window_update_flags (root_window, false);
3823 return paused_p;
3824}
3825
3826static bool
3827update_initial_frame (struct frame *f, bool force_p)
3828{
3829 build_frame_matrix (f);
3830 struct window *root_window = XWINDOW (f->root_window);
3831 set_window_update_flags (root_window, false);
3832 return false;
3833}
3834
3835static void
3836flush_terminal (struct frame *f)
3837{
3838 if (FRAME_TTY (f)->termscript)
3839 fflush (FRAME_TTY (f)->termscript);
3840 fflush (FRAME_TTY (f)->output);
3841}
3842
3843static bool
3844update_tty_frame (struct frame *f, bool force_p)
3845{
3846 build_frame_matrix (f);
3847 return false;
3848}
3849
3850/* Return the cursor position of the selected window of frame F, in
3851 absolute coordinates in *X and *Y. Note that if F is a child frame,
3852 its cursor may be clipped, i.e. outside of the bounds of the terminal
3853 window. Value is false if the selected window of F doesn't have
3854 valid cursor position info. */
3855
3856static bool
3857abs_cursor_pos (struct frame *f, int *x, int *y)
3858{
3859 struct window *w = XWINDOW (f->selected_window);
3860 if (w->cursor.vpos >= 0
3861 /* The cursor vpos may be temporarily out of bounds
3862 in the following situation: There is one window,
3863 with the cursor in the lower half of it. The window
3864 is split, and a message causes a redisplay before
3865 a new cursor position has been computed. */
3866 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
3867 {
3868 int wx = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
3869 int wy = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
3870
3871 wx += max (0, w->left_margin_cols);
3872
3873 int fx, fy;
3874 frame_pos_abs (f, &fx, &fy);
3875 *x = fx + wx;
3876 *y = fy + wy;
3877 return true;
3328 } 3878 }
3329 else 3879
3880 *x = *y = 0;
3881 return false;
3882}
3883
3884static bool
3885is_in_matrix (struct frame *f, int x, int y)
3886{
3887 struct frame *root = root_frame (f);
3888 if (x < 0 || x >= root->current_matrix->matrix_w || y < 0
3889 || y >= root->current_matrix->matrix_h)
3890 return false;
3891 return true;
3892}
3893
3894/* Is the terminal cursor of the selected frame obscured by a child
3895 frame? */
3896
3897static bool
3898is_cursor_obscured (void)
3899{
3900 /* Give up if we can't tell where the cursor currently is. */
3901 int x, y;
3902 if (!abs_cursor_pos (SELECTED_FRAME (), &x, &y))
3903 return false;
3904
3905 /* (x, y) may be outside of the root frame in case the selected frame is a
3906 child frame which is clipped. */
3907 struct frame *root = root_frame (SELECTED_FRAME ());
3908 if (!is_in_matrix (root, x, y))
3909 return true;
3910
3911 struct glyph_row *cursor_row = MATRIX_ROW (root->current_matrix, y);
3912 struct glyph *cursor_glyph = cursor_row->glyphs[0] + x;
3913 return cursor_glyph->frame != SELECTED_FRAME ();
3914}
3915
3916/* Decide where to show the cursor, and whether to hide it.
3917
3918 This works very well for Vertico-Posframe, Transient-Posframe and
3919 Corfu, but it's debatable if it's the right thing for a general use
3920 of child frames of all sorts, nested and so on. But it is also
3921 debatable if that's a realistic use case from my POV. */
3922
3923static void
3924terminal_cursor_magic (struct frame *root, struct frame *topmost_child)
3925{
3926 /* By default, prevent the cursor "shining through" child frames. */
3927 if (is_cursor_obscured ())
3928 tty_hide_cursor (FRAME_TTY (root));
3929
3930 /* If the terminal cursor is not in the topmost child, the topmost
3931 child's tty-cursor-if-topmost determines what to do. If it is
3932 non-nil, display the cursor in this "non-selected" topmost child
3933 frame to compensate for the fact that we can't display a
3934 non-selected cursor like on a window system frame. */
3935 if (topmost_child != SELECTED_FRAME ())
3330 { 3936 {
3331 /* We are working on frame matrix basis. Set the frame on whose 3937 Lisp_Object frame;
3332 frame matrix we operate. */ 3938 XSETFRAME (frame, topmost_child);
3333 set_frame_matrix_frame (f);
3334 3939
3335 /* Build F's desired matrix from window matrices. */ 3940 int x, y;
3336 build_frame_matrix (f); 3941 Lisp_Object cursor = Fframe_parameter (frame, Qtty_non_selected_cursor);
3942 if (!NILP (cursor) && abs_cursor_pos (topmost_child, &x, &y))
3943 {
3944 if (is_in_matrix (root, x, y))
3945 {
3946 cursor_to (root, y, x);
3947 tty_show_cursor (FRAME_TTY (topmost_child));
3948 }
3949 else
3950 tty_hide_cursor (FRAME_TTY (root));
3951 }
3952 }
3953}
3337 3954
3338 /* Update the display. */ 3955bool
3339 if (FRAME_INITIAL_P (f)) 3956combine_updates_for_frame (struct frame *f, bool force_p, bool inhibit_scrolling)
3340 /* No actual display to update so the "update" is a nop and 3957{
3341 obviously isn't interrupted by pending input. */ 3958 struct frame *root = root_frame (f);
3342 paused_p = false; 3959 eassert (FRAME_VISIBLE_P (root));
3343 else 3960
3344 { 3961 /* Process child frames in reverse z-order, topmost last. For each
3345 update_begin (f); 3962 child, copy what we need to the root's desired matrix. */
3346 paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p, 1, false); 3963 Lisp_Object z_order = frames_in_reverse_z_order (root, true);
3347 update_end (f); 3964 struct frame *topmost_child = NULL;
3348 } 3965 for (Lisp_Object tail = XCDR (z_order); CONSP (tail); tail = XCDR (tail))
3349 3966 {
3350 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)) 3967 topmost_child = XFRAME (XCAR (tail));
3351 { 3968 copy_child_glyphs (root, topmost_child);
3352 if (FRAME_TTY (f)->termscript) 3969 }
3353 fflush (FRAME_TTY (f)->termscript); 3970
3354 if (FRAME_TERMCAP_P (f)) 3971 update_begin (root);
3355 fflush (FRAME_TTY (f)->output); 3972 bool paused = write_matrix (root, force_p, inhibit_scrolling, 1, false);
3356 } 3973 if (!paused)
3357 3974 make_matrix_current (root);
3358 /* Check window matrices for lost pointers. */ 3975 update_end (root);
3976
3977 /* If a child is displayed, and the cursor is displayed in another
3978 frame, the child might lay above the cursor, so that it appers to
3979 "shine through" the child. Avoid that because it's confusing. */
3980 if (topmost_child)
3981 terminal_cursor_magic (root, topmost_child);
3982 flush_terminal (root);
3983
3984 for (Lisp_Object tail = z_order; CONSP (tail); tail = XCDR (tail))
3985 {
3986 struct frame *f = XFRAME (XCAR (tail));
3987 struct window *root_window = XWINDOW (f->root_window);
3988 set_window_update_flags (root_window, false);
3989 clear_desired_matrices (f);
3359#ifdef GLYPH_DEBUG 3990#ifdef GLYPH_DEBUG
3360 check_window_matrix_pointers (root_window); 3991 check_window_matrix_pointers (root_window);
3361 add_frame_display_history (f, paused_p); 3992 add_frame_display_history (f, false);
3362#endif 3993#endif
3363 } 3994 }
3364 3995
3365 do_pause: 3996 return paused;
3366 /* Reset flags indicating that a window should be updated. */ 3997}
3367 set_window_update_flags (root_window, false);
3368 3998
3369 display_completed = !paused_p; 3999/* Update on the screen all root frames ROOTS. Called from
3370 return paused_p; 4000 redisplay_internal as the last step of redisplaying. */
4001
4002bool
4003combine_updates (Lisp_Object roots, bool force_p, bool inhibit_scrolling)
4004{
4005 if (redisplay_dont_pause)
4006 force_p = true;
4007
4008 for (; CONSP (roots); roots = XCDR (roots))
4009 {
4010 struct frame *root = XFRAME (XCAR (roots));
4011 if (combine_updates_for_frame (root, force_p, inhibit_scrolling))
4012 {
4013 display_completed = false;
4014 return true;
4015 }
4016 }
4017
4018 display_completed = true;
4019 return false;
4020}
4021
4022/* Update frame F based on the data in desired matrices.
4023
4024 If FORCE_P, don't let redisplay be stopped by detecting pending input.
4025 If INHIBIT_SCROLLING, don't try scrolling.
4026
4027 Value is true if redisplay was stopped due to pending input. */
4028
4029bool
4030update_frame (struct frame *f, bool force_p, bool inhibit_scrolling)
4031{
4032 struct window *root_window = XWINDOW (f->root_window);
4033
4034 if (redisplay_dont_pause)
4035 force_p = true;
4036 else if (!force_p && detect_input_pending_ignore_squeezables ())
4037 {
4038 /* Reset flags indicating that a window should be updated. */
4039 set_window_update_flags (root_window, false);
4040 display_completed = false;
4041 return true;
4042 }
4043
4044 bool paused;
4045 if (FRAME_WINDOW_P (f))
4046 paused = update_window_frame (f, force_p);
4047 else if (FRAME_INITIAL_P (f))
4048 paused = update_initial_frame (f, force_p);
4049 else
4050 paused = update_tty_frame (f, force_p);
4051
4052 if (paused)
4053 display_completed = false;
4054 return paused;
3371} 4055}
3372 4056
3373/* Update a TTY frame F that has a menu dropped down over some of its 4057/* Update a TTY frame F that has a menu dropped down over some of its
@@ -3384,29 +4068,25 @@ void
3384update_frame_with_menu (struct frame *f, int row, int col) 4068update_frame_with_menu (struct frame *f, int row, int col)
3385{ 4069{
3386 struct window *root_window = XWINDOW (f->root_window); 4070 struct window *root_window = XWINDOW (f->root_window);
3387 bool paused_p, cursor_at_point_p; 4071 bool cursor_at_point_p;
3388 4072
3389 eassert (FRAME_TERMCAP_P (f)); 4073 eassert (FRAME_TERMCAP_P (f));
3390 4074
3391 /* We are working on frame matrix basis. Set the frame on whose
3392 frame matrix we operate. */
3393 set_frame_matrix_frame (f);
3394
3395 /* Update the display. */ 4075 /* Update the display. */
3396 update_begin (f); 4076 update_begin (f);
3397 cursor_at_point_p = !(row >= 0 && col >= 0); 4077 cursor_at_point_p = !(row >= 0 && col >= 0);
3398 /* Force update_frame_1 not to stop due to pending input, and not 4078 /* Do not stop due to pending input, and do not try scrolling. This
3399 try scrolling. */ 4079 means that write_glyphs will always return false. */
3400 paused_p = update_frame_1 (f, 1, 1, cursor_at_point_p, true); 4080 write_matrix (f, 1, 1, cursor_at_point_p, true);
4081 make_matrix_current (f);
4082 clear_desired_matrices (f);
3401 /* ROW and COL tell us where in the menu to position the cursor, so 4083 /* ROW and COL tell us where in the menu to position the cursor, so
3402 that screen readers know the active region on the screen. */ 4084 that screen readers know the active region on the screen. */
3403 if (!cursor_at_point_p) 4085 if (!cursor_at_point_p)
3404 cursor_to (f, row, col); 4086 cursor_to (f, row, col);
3405 update_end (f); 4087 update_end (f);
4088 flush_terminal (f);
3406 4089
3407 if (FRAME_TTY (f)->termscript)
3408 fflush (FRAME_TTY (f)->termscript);
3409 fflush (FRAME_TTY (f)->output);
3410 /* Check window matrices for lost pointers. */ 4090 /* Check window matrices for lost pointers. */
3411#if GLYPH_DEBUG 4091#if GLYPH_DEBUG
3412#if 0 4092#if 0
@@ -3415,12 +4095,12 @@ update_frame_with_menu (struct frame *f, int row, int col)
3415 making any updates to the window matrices. */ 4095 making any updates to the window matrices. */
3416 check_window_matrix_pointers (root_window); 4096 check_window_matrix_pointers (root_window);
3417#endif 4097#endif
3418 add_frame_display_history (f, paused_p); 4098 add_frame_display_history (f, false);
3419#endif 4099#endif
3420 4100
3421 /* Reset flags indicating that a window should be updated. */ 4101 /* Reset flags indicating that a window should be updated. */
3422 set_window_update_flags (root_window, false); 4102 set_window_update_flags (root_window, false);
3423 display_completed = !paused_p; 4103 display_completed = true;
3424} 4104}
3425 4105
3426/* Update the mouse position for a frame F. This handles both 4106/* Update the mouse position for a frame F. This handles both
@@ -3453,19 +4133,20 @@ update_mouse_position (struct frame *f, int x, int y)
3453} 4133}
3454 4134
3455DEFUN ("display--update-for-mouse-movement", Fdisplay__update_for_mouse_movement, 4135DEFUN ("display--update-for-mouse-movement", Fdisplay__update_for_mouse_movement,
3456 Sdisplay__update_for_mouse_movement, 2, 2, 0, 4136 Sdisplay__update_for_mouse_movement, 3, 3, 0,
3457 doc: /* Handle mouse movement detected by Lisp code. 4137 doc: /* Handle mouse movement detected by Lisp code.
3458 4138
3459This function should be called when Lisp code detects the mouse has 4139This function should be called when Lisp code detects the mouse has
3460moved, even if `track-mouse' is nil. This handles updates that do not 4140moved, even if `track-mouse' is nil. This handles updates that do not
3461rely on input events such as updating display for mouse-face 4141rely on input events such as updating display for mouse-face
3462properties or updating the help echo text. */) 4142properties or updating the help echo text. */)
3463 (Lisp_Object mouse_x, Lisp_Object mouse_y) 4143 (Lisp_Object mouse_frame, Lisp_Object mouse_x, Lisp_Object mouse_y)
3464{ 4144{
4145 CHECK_FRAME (mouse_frame);
3465 CHECK_FIXNUM (mouse_x); 4146 CHECK_FIXNUM (mouse_x);
3466 CHECK_FIXNUM (mouse_y); 4147 CHECK_FIXNUM (mouse_y);
3467 4148
3468 update_mouse_position (SELECTED_FRAME (), XFIXNUM (mouse_x), 4149 update_mouse_position (XFRAME (mouse_frame), XFIXNUM (mouse_x),
3469 XFIXNUM (mouse_y)); 4150 XFIXNUM (mouse_y));
3470 return Qnil; 4151 return Qnil;
3471} 4152}
@@ -3507,9 +4188,6 @@ update_single_window (struct window *w)
3507 { 4188 {
3508 struct frame *f = XFRAME (WINDOW_FRAME (w)); 4189 struct frame *f = XFRAME (WINDOW_FRAME (w));
3509 4190
3510 /* Record that this is not a frame-based redisplay. */
3511 set_frame_matrix_frame (NULL);
3512
3513 /* Update W. */ 4191 /* Update W. */
3514 update_begin (f); 4192 update_begin (f);
3515 update_window (w, true); 4193 update_window (w, true);
@@ -3688,6 +4366,8 @@ update_window (struct window *w, bool force_p)
3688 4366
3689#ifdef HAVE_WINDOW_SYSTEM 4367#ifdef HAVE_WINDOW_SYSTEM
3690 gui_update_window_begin (w); 4368 gui_update_window_begin (w);
4369#else
4370 (void) changed_p;
3691#endif 4371#endif
3692 yb = window_text_bottom_y (w); 4372 yb = window_text_bottom_y (w);
3693 row = MATRIX_ROW (desired_matrix, 0); 4373 row = MATRIX_ROW (desired_matrix, 0);
@@ -4321,7 +5001,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
4321 5001
4322 /* Update current_row from desired_row. */ 5002 /* Update current_row from desired_row. */
4323 was_stipple = current_row->stipple_p; 5003 was_stipple = current_row->stipple_p;
4324 make_current (w->desired_matrix, w->current_matrix, vpos); 5004 make_current (NULL, w, vpos);
4325 5005
4326 /* If only a partial update was performed, any stipple already 5006 /* If only a partial update was performed, any stipple already
4327 displayed in MATRIX_ROW (w->current_matrix, vpos) might still be 5007 displayed in MATRIX_ROW (w->current_matrix, vpos) might still be
@@ -4931,7 +5611,92 @@ scrolling_window (struct window *w, int tab_line_p)
4931 Frame-Based Updates 5611 Frame-Based Updates
4932 ************************************************************************/ 5612 ************************************************************************/
4933 5613
4934/* Update the desired frame matrix of frame F. 5614static void
5615tty_set_cursor (void)
5616{
5617 struct frame *f = SELECTED_FRAME ();
5618
5619 if ((cursor_in_echo_area
5620 /* If we are showing a message instead of the mini-buffer,
5621 show the cursor for the message instead of for the
5622 (now hidden) mini-buffer contents. */
5623 || (BASE_EQ (minibuf_window, selected_window)
5624 && BASE_EQ (minibuf_window, echo_area_window)
5625 && !NILP (echo_area_buffer[0])))
5626 /* These cases apply only to the frame that contains
5627 the active mini-buffer window. */
5628 && FRAME_HAS_MINIBUF_P (f)
5629 && BASE_EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
5630 {
5631 int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f)));
5632 int col;
5633
5634 /* Put cursor at the end of the prompt. If the mini-buffer
5635 is several lines high, find the last line that has
5636 any text on it. */
5637 int row = FRAME_TOTAL_LINES (f);
5638 do
5639 {
5640 row--;
5641 col = 0;
5642
5643 if (MATRIX_ROW_ENABLED_P (f->current_matrix, row))
5644 {
5645 /* Frame rows are filled up with spaces that
5646 must be ignored here. */
5647 struct glyph_row *r = MATRIX_ROW (f->current_matrix, row);
5648 struct glyph *start = r->glyphs[TEXT_AREA];
5649
5650 col = r->used[TEXT_AREA];
5651 while (0 < col && start[col - 1].charpos < 0)
5652 col--;
5653 }
5654 }
5655 while (row > top && col == 0);
5656
5657 /* We exit the loop with COL at the glyph _after_ the last one. */
5658 if (col > 0)
5659 col--;
5660
5661 /* Make sure COL is not out of range. */
5662 if (col >= FRAME_CURSOR_X_LIMIT (f))
5663 {
5664 /* If we have another row, advance cursor into it. */
5665 if (row < FRAME_TOTAL_LINES (f) - 1)
5666 {
5667 col = FRAME_LEFT_SCROLL_BAR_COLS (f);
5668 row++;
5669 }
5670 /* Otherwise move it back in range. */
5671 else
5672 col = FRAME_CURSOR_X_LIMIT (f) - 1;
5673 }
5674
5675 cursor_to (f, row, col);
5676 }
5677 else
5678 {
5679 /* We have only one cursor on terminal frames. Use it to
5680 display the cursor of the selected window. */
5681 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
5682 if (w->cursor.vpos >= 0
5683 /* The cursor vpos may be temporarily out of bounds
5684 in the following situation: There is one window,
5685 with the cursor in the lower half of it. The window
5686 is split, and a message causes a redisplay before
5687 a new cursor position has been computed. */
5688 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
5689 {
5690 int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
5691 int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
5692
5693 x += max (0, w->left_margin_cols);
5694 cursor_to (f, y, x);
5695 }
5696 }
5697}
5698
5699/* Write desired matix of tty frame F and make it current.
4935 5700
4936 FORCE_P means that the update should not be stopped by pending input. 5701 FORCE_P means that the update should not be stopped by pending input.
4937 INHIBIT_ID_P means that scrolling by insert/delete should not be tried. 5702 INHIBIT_ID_P means that scrolling by insert/delete should not be tried.
@@ -4940,167 +5705,58 @@ scrolling_window (struct window *w, int tab_line_p)
4940 Value is true if update was stopped due to pending input. */ 5705 Value is true if update was stopped due to pending input. */
4941 5706
4942static bool 5707static bool
4943update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p, 5708write_matrix (struct frame *f, bool force_p, bool inhibit_id_p,
4944 bool set_cursor_p, bool updating_menu_p) 5709 bool set_cursor_p, bool updating_menu_p)
4945{ 5710{
4946 /* Frame matrices to work on. */
4947 struct glyph_matrix *current_matrix = f->current_matrix;
4948 struct glyph_matrix *desired_matrix = f->desired_matrix;
4949 int i;
4950 bool pause_p;
4951 int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
4952
4953 eassert (current_matrix && desired_matrix);
4954
4955 if (baud_rate != FRAME_COST_BAUD_RATE (f))
4956 calculate_costs (f);
4957
4958 if (!force_p && detect_input_pending_ignore_squeezables ()) 5711 if (!force_p && detect_input_pending_ignore_squeezables ())
4959 { 5712 return true;
4960 pause_p = 1;
4961 goto do_pause;
4962 }
4963 5713
4964 /* If we cannot insert/delete lines, it's no use trying it. */ 5714 /* If we cannot insert/delete lines, it's no use trying it. */
4965 if (!FRAME_LINE_INS_DEL_OK (f)) 5715 if (!FRAME_LINE_INS_DEL_OK (f))
4966 inhibit_id_p = 1; 5716 inhibit_id_p = true;
4967 5717
4968 /* See if any of the desired lines are enabled; don't compute for 5718 if (baud_rate != FRAME_COST_BAUD_RATE (f))
4969 i/d line if just want cursor motion. */ 5719 calculate_costs (f);
4970 for (i = 0; i < desired_matrix->nrows; i++)
4971 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4972 break;
4973 5720
4974 /* Try doing i/d line, if not yet inhibited. */ 5721 /* See if any of the desired lines are enabled; don't compute for
4975 if (!inhibit_id_p && i < desired_matrix->nrows) 5722 i/d line if just want cursor motion. */
5723 int first_row = first_enabled_row (f->desired_matrix);
5724 if (!inhibit_id_p && first_row >= 0)
4976 force_p |= scrolling (f); 5725 force_p |= scrolling (f);
4977 5726
4978 /* Update the individual lines as needed. Do bottom line first. */ 5727 /* Update the individual lines as needed. Do bottom line first. This
4979 if (MATRIX_ROW_ENABLED_P (desired_matrix, desired_matrix->nrows - 1)) 5728 is done so that messages are made visible when pausing. */
4980 update_frame_line (f, desired_matrix->nrows - 1, updating_menu_p); 5729 int last_row = f->desired_matrix->nrows - 1;
5730 if (MATRIX_ROW_ENABLED_P (f->desired_matrix, last_row))
5731 write_row (f, last_row, updating_menu_p);
4981 5732
4982 /* Now update the rest of the lines. */ 5733 bool pause_p = false;
4983 for (i = 0; i < desired_matrix->nrows - 1 && (force_p || !input_pending); i++) 5734 if (first_row >= 0)
4984 { 5735 {
4985 if (MATRIX_ROW_ENABLED_P (desired_matrix, i)) 5736 const int preempt_count = clip_to_bounds (1, baud_rate / 2400 + 1, INT_MAX);
4986 {
4987 /* Note that output_buffer_size being 0 means that we want the
4988 old default behavior of flushing output every now and then. */
4989 if (FRAME_TERMCAP_P (f) && FRAME_TTY (f)->output_buffer_size == 0)
4990 {
4991 /* Flush out every so many lines.
4992 Also flush out if likely to have more than 1k buffered
4993 otherwise. I'm told that some telnet connections get
4994 really screwed by more than 1k output at once. */
4995 FILE *display_output = FRAME_TTY (f)->output;
4996 if (display_output)
4997 {
4998 ptrdiff_t outq = __fpending (display_output);
4999 if (outq > 900
5000 || (outq > 20 && ((i - 1) % preempt_count == 0)))
5001 fflush (display_output);
5002 }
5003 }
5004 5737
5005 if (!force_p && (i - 1) % preempt_count == 0) 5738 for (int i = first_row, n = 0; i < last_row; ++i)
5006 detect_input_pending_ignore_squeezables (); 5739 if (MATRIX_ROW_ENABLED_P (f->desired_matrix, i))
5740 {
5741 if (!force_p && n % preempt_count == 0
5742 && detect_input_pending_ignore_squeezables ())
5743 {
5744 pause_p = true;
5745 break;
5746 }
5007 5747
5008 update_frame_line (f, i, updating_menu_p); 5748 write_row (f, i, updating_menu_p);
5009 } 5749 ++n;
5750 }
5010 } 5751 }
5011 5752
5012 pause_p = 0 < i && i < FRAME_TOTAL_LINES (f) - 1;
5013
5014 /* Now just clean up termcap drivers and set cursor, etc. */ 5753 /* Now just clean up termcap drivers and set cursor, etc. */
5015 if (!pause_p && set_cursor_p) 5754 if (!pause_p && set_cursor_p)
5016 { 5755 tty_set_cursor ();
5017 if ((cursor_in_echo_area
5018 /* If we are showing a message instead of the mini-buffer,
5019 show the cursor for the message instead of for the
5020 (now hidden) mini-buffer contents. */
5021 || (BASE_EQ (minibuf_window, selected_window)
5022 && BASE_EQ (minibuf_window, echo_area_window)
5023 && !NILP (echo_area_buffer[0])))
5024 /* These cases apply only to the frame that contains
5025 the active mini-buffer window. */
5026 && FRAME_HAS_MINIBUF_P (f)
5027 && BASE_EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
5028 {
5029 int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f)));
5030 int col;
5031
5032 /* Put cursor at the end of the prompt. If the mini-buffer
5033 is several lines high, find the last line that has
5034 any text on it. */
5035 int row = FRAME_TOTAL_LINES (f);
5036 do
5037 {
5038 row--;
5039 col = 0;
5040
5041 if (MATRIX_ROW_ENABLED_P (current_matrix, row))
5042 {
5043 /* Frame rows are filled up with spaces that
5044 must be ignored here. */
5045 struct glyph_row *r = MATRIX_ROW (current_matrix, row);
5046 struct glyph *start = r->glyphs[TEXT_AREA];
5047
5048 col = r->used[TEXT_AREA];
5049 while (0 < col && start[col - 1].charpos < 0)
5050 col--;
5051 }
5052 }
5053 while (row > top && col == 0);
5054
5055 /* We exit the loop with COL at the glyph _after_ the last one. */
5056 if (col > 0)
5057 col--;
5058
5059 /* Make sure COL is not out of range. */
5060 if (col >= FRAME_CURSOR_X_LIMIT (f))
5061 {
5062 /* If we have another row, advance cursor into it. */
5063 if (row < FRAME_TOTAL_LINES (f) - 1)
5064 {
5065 col = FRAME_LEFT_SCROLL_BAR_COLS (f);
5066 row++;
5067 }
5068 /* Otherwise move it back in range. */
5069 else
5070 col = FRAME_CURSOR_X_LIMIT (f) - 1;
5071 }
5072
5073 cursor_to (f, row, col);
5074 }
5075 else
5076 {
5077 /* We have only one cursor on terminal frames. Use it to
5078 display the cursor of the selected window. */
5079 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
5080 if (w->cursor.vpos >= 0
5081 /* The cursor vpos may be temporarily out of bounds
5082 in the following situation: There is one window,
5083 with the cursor in the lower half of it. The window
5084 is split, and a message causes a redisplay before
5085 a new cursor position has been computed. */
5086 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
5087 {
5088 int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
5089 int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
5090 5756
5091 x += max (0, w->left_margin_cols);
5092 cursor_to (f, y, x);
5093 }
5094 }
5095 }
5096
5097 do_pause:
5098
5099 clear_desired_matrices (f);
5100 return pause_p; 5757 return pause_p;
5101} 5758}
5102 5759
5103
5104/* Do line insertions/deletions on frame F for frame-based redisplay. */ 5760/* Do line insertions/deletions on frame F for frame-based redisplay. */
5105 5761
5106static bool 5762static bool
@@ -5209,12 +5865,12 @@ scrolling (struct frame *frame)
5209 which is LEN glyphs long. */ 5865 which is LEN glyphs long. */
5210 5866
5211static int 5867static int
5212count_blanks (struct glyph *r, int len) 5868count_blanks (struct frame *f, struct glyph *r, int len)
5213{ 5869{
5214 int i; 5870 int i;
5215 5871
5216 for (i = 0; i < len; ++i) 5872 for (i = 0; i < len; ++i)
5217 if (!CHAR_GLYPH_SPACE_P (r[i])) 5873 if (!CHAR_GLYPH_SPACE_P (f, r[i]))
5218 break; 5874 break;
5219 5875
5220 return i; 5876 return i;
@@ -5250,7 +5906,7 @@ count_match (struct glyph *str1, struct glyph *end1, struct glyph *str2, struct
5250/* Perform a frame-based update on line VPOS in frame FRAME. */ 5906/* Perform a frame-based update on line VPOS in frame FRAME. */
5251 5907
5252static void 5908static void
5253update_frame_line (struct frame *f, int vpos, bool updating_menu_p) 5909write_row (struct frame *f, int vpos, bool updating_menu_p)
5254{ 5910{
5255 struct glyph *obody, *nbody, *op1, *op2, *np1, *nend; 5911 struct glyph *obody, *nbody, *op1, *op2, *np1, *nend;
5256 int tem; 5912 int tem;
@@ -5264,11 +5920,6 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5264 bool colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background 5920 bool colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background
5265 != FACE_TTY_DEFAULT_BG_COLOR); 5921 != FACE_TTY_DEFAULT_BG_COLOR);
5266 5922
5267 /* This should never happen, but evidently sometimes does if one
5268 resizes the frame quickly enough. Prevent aborts in cmcheckmagic. */
5269 if (vpos >= FRAME_TOTAL_LINES (f))
5270 return;
5271
5272 if (colored_spaces_p) 5923 if (colored_spaces_p)
5273 write_spaces_p = 1; 5924 write_spaces_p = 1;
5274 5925
@@ -5287,7 +5938,7 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5287 5938
5288 /* Ignore trailing spaces, if we can. */ 5939 /* Ignore trailing spaces, if we can. */
5289 if (!write_spaces_p) 5940 if (!write_spaces_p)
5290 while (olen > 0 && CHAR_GLYPH_SPACE_P (obody[olen-1])) 5941 while (olen > 0 && CHAR_GLYPH_SPACE_P (f, obody[olen-1]))
5291 olen--; 5942 olen--;
5292 } 5943 }
5293 5944
@@ -5316,7 +5967,7 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5316 { 5967 {
5317 /* Ignore spaces at the end, if we can. */ 5968 /* Ignore spaces at the end, if we can. */
5318 if (!write_spaces_p) 5969 if (!write_spaces_p)
5319 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1])) 5970 while (nlen > 0 && CHAR_GLYPH_SPACE_P (f, nbody[nlen - 1]))
5320 --nlen; 5971 --nlen;
5321 5972
5322 /* Write the contents of the desired line. */ 5973 /* Write the contents of the desired line. */
@@ -5338,15 +5989,13 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5338 /* Make sure we are in the right row, otherwise cursor movement 5989 /* Make sure we are in the right row, otherwise cursor movement
5339 with cmgoto might use `ch' in the wrong row. */ 5990 with cmgoto might use `ch' in the wrong row. */
5340 cursor_to (f, vpos, 0); 5991 cursor_to (f, vpos, 0);
5341
5342 make_current (desired_matrix, current_matrix, vpos);
5343 return; 5992 return;
5344 } 5993 }
5345 5994
5346 /* Pretend trailing spaces are not there at all, 5995 /* Pretend trailing spaces are not there at all,
5347 unless for one reason or another we must write all spaces. */ 5996 unless for one reason or another we must write all spaces. */
5348 if (!write_spaces_p) 5997 if (!write_spaces_p)
5349 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1])) 5998 while (nlen > 0 && CHAR_GLYPH_SPACE_P (f, nbody[nlen - 1]))
5350 nlen--; 5999 nlen--;
5351 6000
5352 /* If there's no i/d char, quickly do the best we can without it. */ 6001 /* If there's no i/d char, quickly do the best we can without it. */
@@ -5383,9 +6032,6 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5383 cursor_to (f, vpos, nlen); 6032 cursor_to (f, vpos, nlen);
5384 clear_end_of_line (f, olen); 6033 clear_end_of_line (f, olen);
5385 } 6034 }
5386
5387 /* Make current row = desired row. */
5388 make_current (desired_matrix, current_matrix, vpos);
5389 return; 6035 return;
5390 } 6036 }
5391 6037
@@ -5399,7 +6045,7 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5399 if (write_spaces_p) 6045 if (write_spaces_p)
5400 nsp = 0; 6046 nsp = 0;
5401 else 6047 else
5402 nsp = count_blanks (nbody, nlen); 6048 nsp = count_blanks (f, nbody, nlen);
5403 6049
5404 if (nlen > nsp) 6050 if (nlen > nsp)
5405 { 6051 {
@@ -5407,14 +6053,12 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5407 write_glyphs (f, nbody + nsp, nlen - nsp); 6053 write_glyphs (f, nbody + nsp, nlen - nsp);
5408 } 6054 }
5409 6055
5410 /* Exchange contents between current_frame and new_frame. */
5411 make_current (desired_matrix, current_matrix, vpos);
5412 return; 6056 return;
5413 } 6057 }
5414 6058
5415 /* Compute number of leading blanks in old and new contents. */ 6059 /* Compute number of leading blanks in old and new contents. */
5416 osp = count_blanks (obody, olen); 6060 osp = count_blanks (f, obody, olen);
5417 nsp = (colored_spaces_p ? 0 : count_blanks (nbody, nlen)); 6061 nsp = (colored_spaces_p ? 0 : count_blanks (f, nbody, nlen));
5418 6062
5419 /* Compute number of matching chars starting with first non-blank. */ 6063 /* Compute number of matching chars starting with first non-blank. */
5420 begmatch = count_match (obody + osp, obody + olen, 6064 begmatch = count_match (obody + osp, obody + olen,
@@ -5425,7 +6069,7 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5425 if (!write_spaces_p && osp + begmatch == olen) 6069 if (!write_spaces_p && osp + begmatch == olen)
5426 { 6070 {
5427 np1 = nbody + nsp; 6071 np1 = nbody + nsp;
5428 while (np1 + begmatch < nend && CHAR_GLYPH_SPACE_P (np1[begmatch])) 6072 while (np1 + begmatch < nend && CHAR_GLYPH_SPACE_P (f, np1[begmatch]))
5429 ++begmatch; 6073 ++begmatch;
5430 } 6074 }
5431 6075
@@ -5566,9 +6210,6 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5566 cursor_to (f, vpos, nlen); 6210 cursor_to (f, vpos, nlen);
5567 clear_end_of_line (f, olen); 6211 clear_end_of_line (f, olen);
5568 } 6212 }
5569
5570 /* Exchange contents between current_frame and new_frame. */
5571 make_current (desired_matrix, current_matrix, vpos);
5572} 6213}
5573 6214
5574 6215
@@ -5967,7 +6608,8 @@ handle_window_change_signal (int sig)
5967 { 6608 {
5968 struct frame *f = XFRAME (frame); 6609 struct frame *f = XFRAME (frame);
5969 6610
5970 if (FRAME_TERMCAP_P (f) && FRAME_TTY (f) == tty) 6611 if (FRAME_TERMCAP_P (f) && FRAME_TTY (f) == tty
6612 && !FRAME_PARENT_FRAME (f))
5971 /* Record the new sizes, but don't reallocate the data 6613 /* Record the new sizes, but don't reallocate the data
5972 structures now. Let that be done later outside of the 6614 structures now. Let that be done later outside of the
5973 signal handler. */ 6615 signal handler. */
@@ -6534,7 +7176,7 @@ init_display_interactive (void)
6534 7176
6535 /* Construct the space glyph. */ 7177 /* Construct the space glyph. */
6536 space_glyph.type = CHAR_GLYPH; 7178 space_glyph.type = CHAR_GLYPH;
6537 SET_CHAR_GLYPH (space_glyph, ' ', DEFAULT_FACE_ID, 0); 7179 SET_CHAR_GLYPH (NULL, space_glyph, ' ', DEFAULT_FACE_ID, 0);
6538 space_glyph.charpos = -1; 7180 space_glyph.charpos = -1;
6539 7181
6540 inverse_video = 0; 7182 inverse_video = 0;
@@ -6808,6 +7450,7 @@ syms_of_display (void)
6808 defsubr (&Ssend_string_to_terminal); 7450 defsubr (&Ssend_string_to_terminal);
6809 defsubr (&Sinternal_show_cursor); 7451 defsubr (&Sinternal_show_cursor);
6810 defsubr (&Sinternal_show_cursor_p); 7452 defsubr (&Sinternal_show_cursor_p);
7453 defsubr (&Sframe__z_order_lessp);
6811 7454
6812#ifdef GLYPH_DEBUG 7455#ifdef GLYPH_DEBUG
6813 defsubr (&Sdump_redisplay_history); 7456 defsubr (&Sdump_redisplay_history);
@@ -6818,8 +7461,10 @@ syms_of_display (void)
6818 7461
6819 /* This is the "purpose" slot of a display table. */ 7462 /* This is the "purpose" slot of a display table. */
6820 DEFSYM (Qdisplay_table, "display-table"); 7463 DEFSYM (Qdisplay_table, "display-table");
7464 DEFSYM (Qframe__z_order_lessp, "frame--z-order-lessp");
6821 7465
6822 DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause"); 7466 DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause");
7467 DEFSYM (Qtty_non_selected_cursor, "tty-non-selected-cursor");
6823 7468
6824 DEFVAR_INT ("baud-rate", baud_rate, 7469 DEFVAR_INT ("baud-rate", baud_rate,
6825 doc: /* The output baud rate of the terminal. 7470 doc: /* The output baud rate of the terminal.
@@ -6921,6 +7566,8 @@ Possible values are t (below the tool bar), nil (above the tool bar).
6921This option affects only builds where the tool bar is not external. */); 7566This option affects only builds where the tool bar is not external. */);
6922 7567
6923 pdumper_do_now_and_after_load (syms_of_display_for_pdumper); 7568 pdumper_do_now_and_after_load (syms_of_display_for_pdumper);
7569
7570 Fprovide (intern_c_string ("tty-child-frames"), Qnil);
6924} 7571}
6925 7572
6926static void 7573static void
diff --git a/src/disptab.h b/src/disptab.h
index 2080181610a..f51d1d3044b 100644
--- a/src/disptab.h
+++ b/src/disptab.h
@@ -28,7 +28,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
28 && EQ (XCHAR_TABLE (obj)->purpose, Qdisplay_table) \ 28 && EQ (XCHAR_TABLE (obj)->purpose, Qdisplay_table) \
29 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (obj)) == DISP_TABLE_EXTRA_SLOTS) 29 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (obj)) == DISP_TABLE_EXTRA_SLOTS)
30 30
31#define DISP_TABLE_EXTRA_SLOTS 6 31#define DISP_TABLE_EXTRA_SLOTS 12
32#define DISP_TRUNC_GLYPH(dp) ((dp)->extras[0]) 32#define DISP_TRUNC_GLYPH(dp) ((dp)->extras[0])
33#define DISP_CONTINUE_GLYPH(dp) ((dp)->extras[1]) 33#define DISP_CONTINUE_GLYPH(dp) ((dp)->extras[1])
34#define DISP_ESCAPE_GLYPH(dp) ((dp)->extras[2]) 34#define DISP_ESCAPE_GLYPH(dp) ((dp)->extras[2])
@@ -36,6 +36,16 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
36#define DISP_INVIS_VECTOR(dp) ((dp)->extras[4]) 36#define DISP_INVIS_VECTOR(dp) ((dp)->extras[4])
37#define DISP_BORDER_GLYPH(dp) ((dp)->extras[5]) 37#define DISP_BORDER_GLYPH(dp) ((dp)->extras[5])
38 38
39enum box
40{
41 BOX_VERTICAL = 6,
42 BOX_HORIZONTAL,
43 BOX_DOWN_RIGHT,
44 BOX_DOWN_LEFT,
45 BOX_UP_RIGHT,
46 BOX_UP_LEFT
47};
48
39extern Lisp_Object disp_char_vector (struct Lisp_Char_Table *, int); 49extern Lisp_Object disp_char_vector (struct Lisp_Char_Table *, int);
40 50
41#define DISP_CHAR_VECTOR(dp, c) \ 51#define DISP_CHAR_VECTOR(dp, c) \
diff --git a/src/frame.c b/src/frame.c
index f22bd501a8d..547ad0da962 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -130,6 +130,14 @@ decode_window_system_frame (Lisp_Object frame)
130#endif 130#endif
131} 131}
132 132
133struct frame *
134decode_tty_frame (Lisp_Object frame)
135{
136 struct frame *f = decode_live_frame (frame);
137 check_tty (f);
138 return f;
139}
140
133void 141void
134check_window_system (struct frame *f) 142check_window_system (struct frame *f)
135{ 143{
@@ -141,6 +149,13 @@ check_window_system (struct frame *f)
141 : "Window system is not in use or not initialized"); 149 : "Window system is not in use or not initialized");
142} 150}
143 151
152void
153check_tty (struct frame *f)
154{
155 if (!f || !FRAME_TERMCAP_P (f))
156 error ("tty frame should be used");
157}
158
144/* Return the value of frame parameter PROP in frame FRAME. */ 159/* Return the value of frame parameter PROP in frame FRAME. */
145 160
146Lisp_Object 161Lisp_Object
@@ -178,6 +193,17 @@ set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
178 int olines = FRAME_MENU_BAR_LINES (f); 193 int olines = FRAME_MENU_BAR_LINES (f);
179 int nlines = TYPE_RANGED_FIXNUMP (int, value) ? XFIXNUM (value) : 0; 194 int nlines = TYPE_RANGED_FIXNUMP (int, value) ? XFIXNUM (value) : 0;
180 195
196 /* Menu bars on child frames don't work on all platforms, which is
197 the reason why prepare_menu_bar does not update_menu_bar for
198 child frames (info from Martin Rudalics). This could be
199 implemented in ttys, but it's probaly not worth it. */
200 if (is_tty_child_frame (f))
201 {
202 FRAME_MENU_BAR_LINES (f) = 0;
203 FRAME_MENU_BAR_HEIGHT (f) = 0;
204 return;
205 }
206
181 /* Right now, menu bars don't work properly in minibuf-only frames; 207 /* Right now, menu bars don't work properly in minibuf-only frames;
182 most of the commands try to apply themselves to the minibuffer 208 most of the commands try to apply themselves to the minibuffer
183 frame itself, and get an error because you can't switch buffers 209 frame itself, and get an error because you can't switch buffers
@@ -366,17 +392,17 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
366 } 392 }
367 else 393 else
368 retval = XFIXNUM (call4 (Qframe_windows_min_size, frame, horizontal, 394 retval = XFIXNUM (call4 (Qframe_windows_min_size, frame, horizontal,
369 ignore, pixelwise)); 395 ignore, pixelwise));
370 396
371 /* Don't allow too small height of text-mode frames, or else cm.c 397 /* Don't allow too small height of text-mode frames, or else cm.c
372 might abort in cmcheckmagic. */ 398 might abort in cmcheckmagic. */
373 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)) && NILP (horizontal)) 399 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)) && NILP (horizontal))
374 { 400 {
375 int min_height = (FRAME_MENU_BAR_LINES (f) 401 int min_height = (FRAME_MENU_BAR_LINES (f) + FRAME_TAB_BAR_LINES (f)
376 + FRAME_TAB_BAR_LINES (f)
377 + FRAME_WANTS_MODELINE_P (f) 402 + FRAME_WANTS_MODELINE_P (f)
378 + 2); /* one text line and one echo-area line */ 403 + FRAME_HAS_MINIBUF_P (f));
379 404 if (min_height == 0)
405 min_height = 1;
380 if (retval < min_height) 406 if (retval < min_height)
381 retval = min_height; 407 retval = min_height;
382 } 408 }
@@ -385,7 +411,6 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
385} 411}
386 412
387 413
388#ifdef HAVE_WINDOW_SYSTEM
389/** 414/**
390 * keep_ratio: 415 * keep_ratio:
391 * 416 *
@@ -504,7 +529,6 @@ keep_ratio (struct frame *f, struct frame *p, int old_width, int old_height,
504 } 529 }
505 } 530 }
506} 531}
507#endif
508 532
509 533
510static void 534static void
@@ -829,8 +853,9 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
829 853
830 /* MSDOS frames cannot PRETEND, as they change frame size by 854 /* MSDOS frames cannot PRETEND, as they change frame size by
831 manipulating video hardware. */ 855 manipulating video hardware. */
832 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f)) 856 if (is_tty_root_frame (f))
833 FrameCols (FRAME_TTY (f)) = new_text_cols; 857 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
858 FrameCols (FRAME_TTY (f)) = new_text_cols;
834 859
835#if defined (HAVE_WINDOW_SYSTEM) 860#if defined (HAVE_WINDOW_SYSTEM)
836 if (WINDOWP (f->tab_bar_window)) 861 if (WINDOWP (f->tab_bar_window))
@@ -862,9 +887,10 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
862 resize_frame_windows (f, new_inner_height, false); 887 resize_frame_windows (f, new_inner_height, false);
863 888
864 /* MSDOS frames cannot PRETEND, as they change frame size by 889 /* MSDOS frames cannot PRETEND, as they change frame size by
865 manipulating video hardware. */ 890 manipulating video hardware. */
866 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f)) 891 if (is_tty_root_frame (f))
867 FrameRows (FRAME_TTY (f)) = new_text_lines + FRAME_TOP_MARGIN (f); 892 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
893 FrameRows (FRAME_TTY (f)) = new_text_lines + FRAME_TOP_MARGIN (f);
868 } 894 }
869 else if (new_text_lines != old_text_lines) 895 else if (new_text_lines != old_text_lines)
870 call2 (Qwindow__pixel_to_total, frame, Qnil); 896 call2 (Qwindow__pixel_to_total, frame, Qnil);
@@ -894,6 +920,9 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
894 adjust_frame_glyphs (f); 920 adjust_frame_glyphs (f);
895 calculate_costs (f); 921 calculate_costs (f);
896 SET_FRAME_GARBAGED (f); 922 SET_FRAME_GARBAGED (f);
923 if (is_tty_child_frame (f))
924 SET_FRAME_GARBAGED (root_frame (f));
925
897 /* We now say here that F was resized instead of using the old 926 /* We now say here that F was resized instead of using the old
898 condition below. Some resizing must have taken place and if it was 927 condition below. Some resizing must have taken place and if it was
899 only shifting the root window's position (paranoia?). */ 928 only shifting the root window's position (paranoia?). */
@@ -906,7 +935,6 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
906 935
907 unblock_input (); 936 unblock_input ();
908 937
909#ifdef HAVE_WINDOW_SYSTEM
910 { 938 {
911 /* Adjust size of F's child frames. */ 939 /* Adjust size of F's child frames. */
912 Lisp_Object frames, frame1; 940 Lisp_Object frames, frame1;
@@ -916,7 +944,6 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
916 keep_ratio (XFRAME (frame1), f, old_native_width, old_native_height, 944 keep_ratio (XFRAME (frame1), f, old_native_width, old_native_height,
917 new_native_width, new_native_height); 945 new_native_width, new_native_height);
918 } 946 }
919#endif
920} 947}
921 948
922/* Allocate basically initialized frame. */ 949/* Allocate basically initialized frame. */
@@ -961,12 +988,12 @@ make_frame (bool mini_p)
961 f->line_height = 1; /* !FRAME_WINDOW_P value. */ 988 f->line_height = 1; /* !FRAME_WINDOW_P value. */
962 f->new_width = -1; 989 f->new_width = -1;
963 f->new_height = -1; 990 f->new_height = -1;
991 f->no_special_glyphs = false;
964#ifdef HAVE_WINDOW_SYSTEM 992#ifdef HAVE_WINDOW_SYSTEM
965 f->vertical_scroll_bar_type = vertical_scroll_bar_none; 993 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
966 f->horizontal_scroll_bars = false; 994 f->horizontal_scroll_bars = false;
967 f->want_fullscreen = FULLSCREEN_NONE; 995 f->want_fullscreen = FULLSCREEN_NONE;
968 f->undecorated = false; 996 f->undecorated = false;
969 f->no_special_glyphs = false;
970#ifndef HAVE_NTGUI 997#ifndef HAVE_NTGUI
971 f->override_redirect = false; 998 f->override_redirect = false;
972#endif 999#endif
@@ -1083,7 +1110,6 @@ make_frame (bool mini_p)
1083 return f; 1110 return f;
1084} 1111}
1085 1112
1086#ifdef HAVE_WINDOW_SYSTEM
1087/* Make a frame using a separate minibuffer window on another frame. 1113/* Make a frame using a separate minibuffer window on another frame.
1088 MINI_WINDOW is the minibuffer window to use. nil means use the 1114 MINI_WINDOW is the minibuffer window to use. nil means use the
1089 default (the global minibuffer). */ 1115 default (the global minibuffer). */
@@ -1177,7 +1203,7 @@ make_minibuffer_frame (void)
1177 : Fcar (Vminibuffer_list)), 0, 0); 1203 : Fcar (Vminibuffer_list)), 0, 0);
1178 return f; 1204 return f;
1179} 1205}
1180#endif /* HAVE_WINDOW_SYSTEM */ 1206
1181 1207
1182/* Construct a frame that refers to a terminal. */ 1208/* Construct a frame that refers to a terminal. */
1183 1209
@@ -1203,7 +1229,7 @@ make_initial_frame (void)
1203 tty_frame_count = 1; 1229 tty_frame_count = 1;
1204 fset_name (f, build_pure_c_string ("F1")); 1230 fset_name (f, build_pure_c_string ("F1"));
1205 1231
1206 SET_FRAME_VISIBLE (f, 1); 1232 SET_FRAME_VISIBLE (f, true);
1207 1233
1208 f->output_method = terminal->type; 1234 f->output_method = terminal->type;
1209 f->terminal = terminal; 1235 f->terminal = terminal;
@@ -1240,23 +1266,48 @@ make_initial_frame (void)
1240#ifndef HAVE_ANDROID 1266#ifndef HAVE_ANDROID
1241 1267
1242static struct frame * 1268static struct frame *
1243make_terminal_frame (struct terminal *terminal) 1269make_terminal_frame (struct terminal *terminal, Lisp_Object parent,
1270 Lisp_Object params)
1244{ 1271{
1245 register struct frame *f;
1246 Lisp_Object frame;
1247 char name[sizeof "F" + INT_STRLEN_BOUND (tty_frame_count)]; 1272 char name[sizeof "F" + INT_STRLEN_BOUND (tty_frame_count)];
1248 1273
1249 if (!terminal->name) 1274 if (!terminal->name)
1250 error ("Terminal is not live, can't create new frames on it"); 1275 error ("Terminal is not live, can't create new frames on it");
1251 1276
1252 f = make_frame (1); 1277 struct frame *f;
1278 if (NILP (parent))
1279 f = make_frame (true);
1280 else
1281 {
1282 CHECK_LIVE_FRAME (parent);
1283
1284 f = NULL;
1285 Lisp_Object mini = Fassq (Qminibuffer, params);
1286 if (CONSP (mini))
1287 {
1288 mini = Fcdr (mini);
1289 struct kboard *kb = FRAME_KBOARD (XFRAME (parent));
1290 if (EQ (mini, Qnone) || NILP (mini))
1291 f = make_frame_without_minibuffer (Qnil, kb, Qnil);
1292 else if (EQ (mini, Qonly))
1293 error ("minibuffer-only child frames are not implemented");
1294 else if (WINDOWP (mini))
1295 f = make_frame_without_minibuffer (mini, kb, Qnil);
1296 }
1253 1297
1298 if (f == NULL)
1299 f = make_frame (true);
1300 f->parent_frame = parent;
1301 f->z_order = 1 + max_child_z_order (XFRAME (parent));
1302 }
1303
1304 Lisp_Object frame;
1254 XSETFRAME (frame, f); 1305 XSETFRAME (frame, f);
1255 Vframe_list = Fcons (frame, Vframe_list); 1306 Vframe_list = Fcons (frame, Vframe_list);
1256 1307
1257 fset_name (f, make_formatted_string (name, "F%"PRIdMAX, ++tty_frame_count)); 1308 fset_name (f, make_formatted_string (name, "F%"PRIdMAX, ++tty_frame_count));
1258 1309
1259 SET_FRAME_VISIBLE (f, 1); 1310 SET_FRAME_VISIBLE (f, true);
1260 1311
1261 f->terminal = terminal; 1312 f->terminal = terminal;
1262 f->terminal->reference_count++; 1313 f->terminal->reference_count++;
@@ -1281,7 +1332,15 @@ make_terminal_frame (struct terminal *terminal)
1281 f->horizontal_scroll_bars = false; 1332 f->horizontal_scroll_bars = false;
1282#endif 1333#endif
1283 1334
1284 FRAME_MENU_BAR_LINES (f) = NILP (Vmenu_bar_mode) ? 0 : 1; 1335 /* Menu bars on child frames don't work on all platforms, which is
1336 the reason why prepare_menu_bar does not update_menu_bar for
1337 child frames (info from Martin Rudalics). This could be
1338 implemented in ttys, but it's unclear if it is worth it. */
1339 if (NILP (parent))
1340 FRAME_MENU_BAR_LINES (f) = NILP (Vmenu_bar_mode) ? 0 : 1;
1341 else
1342 FRAME_MENU_BAR_LINES (f) = 0;
1343
1285 FRAME_TAB_BAR_LINES (f) = NILP (Vtab_bar_mode) ? 0 : 1; 1344 FRAME_TAB_BAR_LINES (f) = NILP (Vtab_bar_mode) ? 0 : 1;
1286 FRAME_LINES (f) = FRAME_LINES (f) - FRAME_MENU_BAR_LINES (f) 1345 FRAME_LINES (f) = FRAME_LINES (f) - FRAME_MENU_BAR_LINES (f)
1287 - FRAME_TAB_BAR_LINES (f); 1346 - FRAME_TAB_BAR_LINES (f);
@@ -1290,16 +1349,18 @@ make_terminal_frame (struct terminal *terminal)
1290 FRAME_TEXT_HEIGHT (f) = FRAME_TEXT_HEIGHT (f) - FRAME_MENU_BAR_HEIGHT (f) 1349 FRAME_TEXT_HEIGHT (f) = FRAME_TEXT_HEIGHT (f) - FRAME_MENU_BAR_HEIGHT (f)
1291 - FRAME_TAB_BAR_HEIGHT (f); 1350 - FRAME_TAB_BAR_HEIGHT (f);
1292 1351
1293 /* Set the top frame to the newly created frame. */ 1352 /* Mark current topmost frame obscured if we make a new root frame.
1294 if (FRAMEP (FRAME_TTY (f)->top_frame) 1353 Child frames don't completely obscure other frames. */
1295 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame))) 1354 if (NILP (parent) && FRAMEP (FRAME_TTY (f)->top_frame))
1296 SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (f)->top_frame), 2); /* obscured */ 1355 {
1356 struct frame *top = XFRAME (FRAME_TTY (f)->top_frame);
1357 struct frame *root = root_frame (top);
1358 if (FRAME_LIVE_P (root))
1359 SET_FRAME_VISIBLE (root, false);
1360 }
1297 1361
1362 /* Set the top frame to the newly created frame. */
1298 FRAME_TTY (f)->top_frame = frame; 1363 FRAME_TTY (f)->top_frame = frame;
1299
1300 if (!noninteractive)
1301 init_frame_faces (f);
1302
1303 return f; 1364 return f;
1304} 1365}
1305 1366
@@ -1329,6 +1390,68 @@ get_future_frame_param (Lisp_Object parameter,
1329 1390
1330#endif 1391#endif
1331 1392
1393static int
1394tty_child_pos_param (struct frame *child, Lisp_Object key,
1395 Lisp_Object params, int dflt)
1396{
1397 Lisp_Object val = Fassq (key, params);
1398 if (CONSP (val))
1399 {
1400 val = XCDR (val);
1401 if (FIXNUMP (val))
1402 return XFIXNUM (val);
1403 }
1404 return dflt;
1405}
1406
1407static int
1408tty_child_size_param (struct frame *child, Lisp_Object key,
1409 Lisp_Object params, int dflt)
1410{
1411 Lisp_Object val = Fassq (key, params);
1412 if (CONSP (val))
1413 {
1414 val = XCDR (val);
1415 if (CONSP (val))
1416 {
1417 /* Width and height may look like (width text-pixels . PIXELS)
1418 on window systems. Mimic that. */
1419 val = XCDR (val);
1420 if (EQ (val, Qtext_pixels))
1421 val = XCDR (val);
1422 }
1423 else if (FLOATP (val))
1424 {
1425 /* Width and height may be a float, in which case
1426 it's a multiple of the parent's value. */
1427 struct frame *parent = FRAME_PARENT_FRAME (child);
1428 eassert (parent); /* the caller ensures this, but... */
1429 if (parent)
1430 {
1431 int sz = (EQ (key, Qwidth) ? FRAME_TOTAL_COLS (parent)
1432 : FRAME_TOTAL_LINES (parent));
1433 val = make_fixnum (XFLOAT_DATA (val) * sz);
1434 }
1435 else
1436 val = Qnil;
1437 }
1438
1439 if (FIXNATP (val))
1440 return XFIXNUM (val);
1441 }
1442 return dflt;
1443}
1444
1445static void
1446tty_child_frame_rect (struct frame *f, Lisp_Object params,
1447 int *x, int *y, int *w, int *h)
1448{
1449 *x = tty_child_pos_param (f, Qleft, params, 0);
1450 *y = tty_child_pos_param (f, Qtop, params, 0);
1451 *w = tty_child_size_param (f, Qwidth, params, FRAME_TOTAL_COLS (f));
1452 *h = tty_child_size_param (f, Qheight, params, FRAME_TOTAL_LINES (f));
1453}
1454
1332DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame, 1455DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
1333 1, 1, 0, 1456 1, 1, 0,
1334 doc: /* Create an additional terminal frame, possibly on another terminal. 1457 doc: /* Create an additional terminal frame, possibly on another terminal.
@@ -1352,9 +1475,7 @@ affects all frames on the same terminal device. */)
1352 error ("Text terminals are not supported on this platform"); 1475 error ("Text terminals are not supported on this platform");
1353 return Qnil; 1476 return Qnil;
1354#else 1477#else
1355 struct frame *f;
1356 struct terminal *t = NULL; 1478 struct terminal *t = NULL;
1357 Lisp_Object frame;
1358 struct frame *sf = SELECTED_FRAME (); 1479 struct frame *sf = SELECTED_FRAME ();
1359 1480
1360#ifdef MSDOS 1481#ifdef MSDOS
@@ -1384,7 +1505,7 @@ affects all frames on the same terminal device. */)
1384 error ("Multiple terminals are not supported on this platform"); 1505 error ("Multiple terminals are not supported on this platform");
1385 if (!t) 1506 if (!t)
1386 t = the_only_display_info.terminal; 1507 t = the_only_display_info.terminal;
1387#endif 1508# endif
1388 } 1509 }
1389 1510
1390 if (!t) 1511 if (!t)
@@ -1411,19 +1532,64 @@ affects all frames on the same terminal device. */)
1411 SAFE_FREE (); 1532 SAFE_FREE ();
1412 } 1533 }
1413 1534
1414 f = make_terminal_frame (t); 1535 /* Make a new frame. We need to know up front if a parent frame is
1536 specified because we behave differently in this case, e.g., child
1537 frames don't obscure other frames. */
1538 Lisp_Object parent = Fcdr (Fassq (Qparent_frame, parms));
1539 struct frame *f = make_terminal_frame (t, parent, parms);
1415 1540
1416 { 1541 if (!noninteractive)
1417 int width, height; 1542 init_frame_faces (f);
1418 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height); 1543
1419 /* With INHIBIT 5 pass correct text height to adjust_frame_size. */ 1544 /* Visibility of root frames cannot be set with a frame parameter.
1420 adjust_frame_size (f, width, height - FRAME_TOP_MARGIN (f), 1545 Their visibility solely depends on whether or not they are the
1421 5, 0, Qterminal_frame); 1546 top_frame on the terminal. */
1422 } 1547 if (FRAME_PARENT_FRAME (f))
1548 {
1549 Lisp_Object visible = Fassq (Qvisibility, parms);
1550 if (CONSP (visible))
1551 SET_FRAME_VISIBLE (f, !NILP (visible));
1552
1553 /* FIXME/tty: The only way, for now, to get borders on a tty is
1554 to allow decorations. */
1555 Lisp_Object undecorated = Fassq (Qundecorated, parms);
1556 if (CONSP (undecorated) && !NILP (XCDR (undecorated)))
1557 f->undecorated = true;
1558
1559 /* Unused at present. */
1560 Lisp_Object no_focus = Fassq (Qno_accept_focus, parms);
1561 if (CONSP (no_focus) && !NILP (XCDR (no_focus)))
1562 f->no_accept_focus = true;
1563
1564 Lisp_Object no_split = Fassq (Qunsplittable, parms);
1565 if (CONSP (no_split) && !NILP (XCDR (no_split)))
1566 f->no_split = true;
1567 }
1423 1568
1569 /* Determine width and height of the frame. For root frames use the
1570 width/height of the terminal. For child frames, take it from frame
1571 parameters. Note that a default (80x25) has been set in
1572 make_frame. We handle root frames in this way because otherwise we
1573 would end up needing glyph matrices for the terminal, which is both
1574 more work and has its downsides (think of clipping frames to the
1575 terminal size). */
1576 int x = 0, y = 0, width, height;
1577 if (FRAME_PARENT_FRAME (f))
1578 tty_child_frame_rect (f, parms, &x, &y, &width, &height);
1579 else
1580 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
1581 adjust_frame_size (f, width, height - FRAME_TOP_MARGIN (f), 5, 0,
1582 Qterminal_frame);
1424 adjust_frame_glyphs (f); 1583 adjust_frame_glyphs (f);
1584
1425 calculate_costs (f); 1585 calculate_costs (f);
1426 XSETFRAME (frame, f); 1586
1587 f->left_pos = x;
1588 f->top_pos = y;
1589 store_in_alist (&parms, Qleft, make_fixnum (x));
1590 store_in_alist (&parms, Qtop, make_fixnum (y));
1591 store_in_alist (&parms, Qwidth, make_fixnum (width));
1592 store_in_alist (&parms, Qheight, make_fixnum (height));
1427 1593
1428 store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type)); 1594 store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type));
1429 store_in_alist (&parms, Qtty, 1595 store_in_alist (&parms, Qtty,
@@ -1445,7 +1611,11 @@ affects all frames on the same terminal device. */)
1445 /* On terminal frames the `minibuffer' frame parameter is always 1611 /* On terminal frames the `minibuffer' frame parameter is always
1446 virtually t. Avoid that a different value in parms causes 1612 virtually t. Avoid that a different value in parms causes
1447 complaints, see Bug#24758. */ 1613 complaints, see Bug#24758. */
1448 store_in_alist (&parms, Qminibuffer, Qt); 1614 if (!FRAME_PARENT_FRAME (f))
1615 store_in_alist (&parms, Qminibuffer, Qt);
1616
1617 Lisp_Object frame;
1618 XSETFRAME (frame, f);
1449 Fmodify_frame_parameters (frame, parms); 1619 Fmodify_frame_parameters (frame, parms);
1450 1620
1451 f->can_set_window_size = true; 1621 f->can_set_window_size = true;
@@ -1474,8 +1644,6 @@ affects all frames on the same terminal device. */)
1474Lisp_Object 1644Lisp_Object
1475do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object norecord) 1645do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object norecord)
1476{ 1646{
1477 struct frame *sf = SELECTED_FRAME (), *f;
1478
1479 /* If FRAME is a switch-frame event, extract the frame we should 1647 /* If FRAME is a switch-frame event, extract the frame we should
1480 switch to. */ 1648 switch to. */
1481 if (CONSP (frame) 1649 if (CONSP (frame)
@@ -1487,7 +1655,9 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1487 a switch-frame event to arrive after a frame is no longer live, 1655 a switch-frame event to arrive after a frame is no longer live,
1488 especially when deleting the initial frame during startup. */ 1656 especially when deleting the initial frame during startup. */
1489 CHECK_FRAME (frame); 1657 CHECK_FRAME (frame);
1490 f = XFRAME (frame); 1658 struct frame *f = XFRAME (frame);
1659 struct frame *sf = SELECTED_FRAME ();
1660
1491 /* Silently ignore dead and tooltip frames (Bug#47207). */ 1661 /* Silently ignore dead and tooltip frames (Bug#47207). */
1492 if (!FRAME_LIVE_P (f) || FRAME_TOOLTIP_P (f)) 1662 if (!FRAME_LIVE_P (f) || FRAME_TOOLTIP_P (f))
1493 return Qnil; 1663 return Qnil;
@@ -1540,24 +1710,37 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1540 struct tty_display_info *tty = FRAME_TTY (f); 1710 struct tty_display_info *tty = FRAME_TTY (f);
1541 Lisp_Object top_frame = tty->top_frame; 1711 Lisp_Object top_frame = tty->top_frame;
1542 1712
1543 /* Don't mark the frame garbaged and/or obscured if we are 1713 /* Don't mark the frame garbaged if we are switching to the frame
1544 switching to the frame that is already the top frame of that 1714 that is already the top frame of that TTY. */
1545 TTY. */
1546 if (!EQ (frame, top_frame)) 1715 if (!EQ (frame, top_frame))
1547 { 1716 {
1717 struct frame *new_root = root_frame (f);
1718 SET_FRAME_VISIBLE (new_root, true);
1719 SET_FRAME_VISIBLE (f, true);
1720
1721 /* Mark previously displayed frame as no longer visible. */
1548 if (FRAMEP (top_frame)) 1722 if (FRAMEP (top_frame))
1549 /* Mark previously displayed frame as now obscured. */ 1723 {
1550 SET_FRAME_VISIBLE (XFRAME (top_frame), 2); 1724 struct frame *top = XFRAME (top_frame);
1551 SET_FRAME_VISIBLE (f, 1); 1725 struct frame *old_root = root_frame (top);
1552 /* If the new TTY frame changed dimensions, we need to 1726 if (old_root != new_root)
1553 resync term.c's idea of the frame size with the new 1727 SET_FRAME_VISIBLE (old_root, false);
1554 frame's data. */ 1728 }
1555 if (FRAME_COLS (f) != FrameCols (tty)) 1729
1556 FrameCols (tty) = FRAME_COLS (f); 1730 tty->top_frame = frame;
1557 if (FRAME_TOTAL_LINES (f) != FrameRows (tty)) 1731
1558 FrameRows (tty) = FRAME_TOTAL_LINES (f); 1732 /* FIXME: Why is it correct to set FrameCols/Rows? */
1733 if (!FRAME_PARENT_FRAME (f))
1734 {
1735 /* If the new TTY frame changed dimensions, we need to
1736 resync term.c's idea of the frame size with the new
1737 frame's data. */
1738 if (FRAME_COLS (f) != FrameCols (tty))
1739 FrameCols (tty) = FRAME_COLS (f);
1740 if (FRAME_TOTAL_LINES (f) != FrameRows (tty))
1741 FrameRows (tty) = FRAME_TOTAL_LINES (f);
1742 }
1559 } 1743 }
1560 tty->top_frame = frame;
1561 } 1744 }
1562 1745
1563 sf->select_mini_window_flag = MINI_WINDOW_P (XWINDOW (sf->selected_window)); 1746 sf->select_mini_window_flag = MINI_WINDOW_P (XWINDOW (sf->selected_window));
@@ -1599,10 +1782,36 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1599 (select-window (frame-root-window (make-frame))) doesn't end up 1782 (select-window (frame-root-window (make-frame))) doesn't end up
1600 with your typing being interpreted in the new frame instead of 1783 with your typing being interpreted in the new frame instead of
1601 the one you're actually typing in. */ 1784 the one you're actually typing in. */
1602#ifdef HAVE_WINDOW_SYSTEM 1785
1603 if (!frame_ancestor_p (f, sf)) 1786 /* FIXME/tty: I don't understand this. (The comment above is from
1604#endif 1787 Jim BLandy 1993 BTW, and the frame_ancestor_p from 2017.)
1605 internal_last_event_frame = Qnil; 1788
1789 Setting the last event frame to nil leads to switch-frame events
1790 being generated even if they normally wouldn't be because the frame
1791 in question equals selected-frame. See the places in keyboard.c
1792 where make_lispy_switch_frame is called.
1793
1794 This leads to problems at least on ttys.
1795
1796 Imagine that we have functions in post-command-hook that use
1797 select-frame in some way (e.g., with-selected-window). Let these
1798 functions select different frames during the execution of
1799 post-command-hook in command_loop_1. Setting
1800 internal_last_event_frame to nil here makes these select-frame
1801 calls (potentially and in reality) generate switch-frame events.
1802 (But only in one direction (frame_ancestor_p), which I also don't
1803 understand).
1804
1805 These switch-frame events form an endless loop in
1806 command_loop_1. It runs post-command-hook, which generates
1807 switch-frame events, which command_loop_1 finds (bound to '#ignore)
1808 and executes, which again runs post-command-hook etc., ad
1809 infinitum.
1810
1811 Let's not do that for now on ttys. */
1812 if (!is_tty_frame (f))
1813 if (!frame_ancestor_p (f, sf))
1814 internal_last_event_frame = Qnil;
1606 1815
1607 return frame; 1816 return frame;
1608} 1817}
@@ -1719,7 +1928,6 @@ parent window is the window-system's root window) or an embedded window
1719 return Qnil; 1928 return Qnil;
1720} 1929}
1721 1930
1722#ifdef HAVE_WINDOW_SYSTEM
1723bool 1931bool
1724frame_ancestor_p (struct frame *af, struct frame *df) 1932frame_ancestor_p (struct frame *af, struct frame *df)
1725{ 1933{
@@ -1735,7 +1943,6 @@ frame_ancestor_p (struct frame *af, struct frame *df)
1735 1943
1736 return false; 1944 return false;
1737} 1945}
1738#endif
1739 1946
1740DEFUN ("frame-ancestor-p", Fframe_ancestor_p, Sframe_ancestor_p, 1947DEFUN ("frame-ancestor-p", Fframe_ancestor_p, Sframe_ancestor_p,
1741 2, 2, 0, 1948 2, 2, 0,
@@ -1746,15 +1953,10 @@ ANCESTOR and DESCENDANT must be live frames and default to the selected
1746frame. */) 1953frame. */)
1747 (Lisp_Object ancestor, Lisp_Object descendant) 1954 (Lisp_Object ancestor, Lisp_Object descendant)
1748{ 1955{
1749#ifdef HAVE_WINDOW_SYSTEM
1750 struct frame *af = decode_live_frame (ancestor); 1956 struct frame *af = decode_live_frame (ancestor);
1751 struct frame *df = decode_live_frame (descendant); 1957 struct frame *df = decode_live_frame (descendant);
1752
1753 return frame_ancestor_p (af, df) ? Qt : Qnil; 1958 return frame_ancestor_p (af, df) ? Qt : Qnil;
1754#else 1959}
1755 return Qnil;
1756#endif
1757 }
1758 1960
1759/* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the 1961/* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the
1760 same tty (for tty frames) or among frames which uses FRAME's keyboard. 1962 same tty (for tty frames) or among frames which uses FRAME's keyboard.
@@ -2015,7 +2217,9 @@ other_frames (struct frame *f, bool invisible, bool force)
2015 && (invisible || NILP (get_frame_param (f1, Qdelete_before))) 2217 && (invisible || NILP (get_frame_param (f1, Qdelete_before)))
2016 /* For invisibility and normal deletions, at least one 2218 /* For invisibility and normal deletions, at least one
2017 visible or iconified frame must remain (Bug#26682). */ 2219 visible or iconified frame must remain (Bug#26682). */
2018 && (FRAME_VISIBLE_P (f1) || FRAME_ICONIFIED_P (f1) 2220 && (FRAME_VISIBLE_P (f1)
2221 || is_tty_frame (f1)
2222 || FRAME_ICONIFIED_P (f1)
2019 || (!invisible 2223 || (!invisible
2020 && (force 2224 && (force
2021 /* Allow deleting the terminal frame when at 2225 /* Allow deleting the terminal frame when at
@@ -2276,7 +2480,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
2276 fset_root_window (f, Qnil); 2480 fset_root_window (f, Qnil);
2277 2481
2278 Vframe_list = Fdelq (frame, Vframe_list); 2482 Vframe_list = Fdelq (frame, Vframe_list);
2279 SET_FRAME_VISIBLE (f, 0); 2483 SET_FRAME_VISIBLE (f, false);
2280 2484
2281 /* Allow the vector of menu bar contents to be freed in the next 2485 /* Allow the vector of menu bar contents to be freed in the next
2282 garbage collection. The frame object itself may not be garbage 2486 garbage collection. The frame object itself may not be garbage
@@ -2862,6 +3066,12 @@ If omitted, FRAME defaults to the currently selected frame. */)
2862 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook) 3066 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook)
2863 FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, true); 3067 FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, true);
2864 3068
3069 if (is_tty_frame (f))
3070 {
3071 SET_FRAME_VISIBLE (f, true);
3072 tty_raise_lower_frame (f, true);
3073 }
3074
2865 make_frame_visible_1 (f->root_window); 3075 make_frame_visible_1 (f->root_window);
2866 3076
2867 /* Make menu bar update for the Buffers and Frames menus. */ 3077 /* Make menu bar update for the Buffers and Frames menus. */
@@ -2912,6 +3122,12 @@ displayed in the terminal. */)
2912 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook) 3122 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook)
2913 FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, false); 3123 FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, false);
2914 3124
3125 /* The ELisp manual says that this "usually" makes child frames
3126 invisible, too, but without saying when not. Since users can't
3127 rely on this, it's not implemented. */
3128 if (is_tty_frame (f))
3129 SET_FRAME_VISIBLE (f, false);
3130
2915 /* Make menu bar update for the Buffers and Frames menus. */ 3131 /* Make menu bar update for the Buffers and Frames menus. */
2916 windows_or_buffers_changed = 16; 3132 windows_or_buffers_changed = 16;
2917 3133
@@ -2971,10 +3187,13 @@ currently being displayed on the terminal. */)
2971 (Lisp_Object frame) 3187 (Lisp_Object frame)
2972{ 3188{
2973 CHECK_LIVE_FRAME (frame); 3189 CHECK_LIVE_FRAME (frame);
3190 struct frame *f = XFRAME (frame);
2974 3191
2975 if (FRAME_VISIBLE_P (XFRAME (frame))) 3192 if (FRAME_VISIBLE_P (f))
3193 return Qt;
3194 else if (is_tty_root_frame (f))
2976 return Qt; 3195 return Qt;
2977 if (FRAME_ICONIFIED_P (XFRAME (frame))) 3196 if (FRAME_ICONIFIED_P (f))
2978 return Qicon; 3197 return Qicon;
2979 return Qnil; 3198 return Qnil;
2980} 3199}
@@ -3006,12 +3225,7 @@ doesn't support multiple overlapping frames, this function selects FRAME. */)
3006 3225
3007 XSETFRAME (frame, f); 3226 XSETFRAME (frame, f);
3008 3227
3009 if (FRAME_TERMCAP_P (f)) 3228 Fmake_frame_visible (frame);
3010 /* On a text terminal select FRAME. */
3011 Fselect_frame (frame, Qnil);
3012 else
3013 /* Do like the documentation says. */
3014 Fmake_frame_visible (frame);
3015 3229
3016 if (FRAME_TERMINAL (f)->frame_raise_lower_hook) 3230 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
3017 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, true); 3231 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, true);
@@ -3310,6 +3524,15 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
3310 val = old_val; 3524 val = old_val;
3311 } 3525 }
3312 3526
3527 /* Re-parenting is currently not implemented when changing a root
3528 frame to a child frame or vice versa. */
3529 if (is_tty_frame (f) && EQ (prop, Qparent_frame))
3530 {
3531 if (NILP (f->parent_frame) != NILP (val))
3532 error ("Making a root frame a child or vice versa is not supported");
3533 f->parent_frame = val;
3534 }
3535
3313 /* The tty color needed to be set before the frame's parameter 3536 /* The tty color needed to be set before the frame's parameter
3314 alist was updated with the new value. This is not true any more, 3537 alist was updated with the new value. This is not true any more,
3315 but we still do this test early on. */ 3538 but we still do this test early on. */
@@ -3433,13 +3656,10 @@ If FRAME is omitted or nil, return information on the currently selected frame.
3433 else 3656 else
3434#endif 3657#endif
3435 { 3658 {
3436 /* This ought to be correct in f->param_alist for an X frame. */ 3659 store_in_alist (&alist, Qmenu_bar_lines, make_fixnum (FRAME_MENU_BAR_LINES (f)));
3437 Lisp_Object lines; 3660 store_in_alist (&alist, Qtab_bar_lines, make_fixnum (FRAME_TAB_BAR_LINES (f)));
3438 3661 store_in_alist (&alist, Qvisibility, FRAME_VISIBLE_P (f) ? Qt : Qnil);
3439 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f)); 3662 store_in_alist (&alist, Qno_accept_focus, FRAME_NO_ACCEPT_FOCUS (f) ? Qt : Qnil);
3440 store_in_alist (&alist, Qmenu_bar_lines, lines);
3441 XSETFASTINT (lines, FRAME_TAB_BAR_LINES (f));
3442 store_in_alist (&alist, Qtab_bar_lines, lines);
3443 } 3663 }
3444 3664
3445 return alist; 3665 return alist;
@@ -3517,7 +3737,6 @@ If FRAME is nil, describe the currently selected frame. */)
3517 return value; 3737 return value;
3518} 3738}
3519 3739
3520
3521DEFUN ("modify-frame-parameters", Fmodify_frame_parameters, 3740DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
3522 Smodify_frame_parameters, 2, 2, 0, 3741 Smodify_frame_parameters, 2, 2, 0,
3523 doc: /* Modify FRAME according to new values of its parameters in ALIST. 3742 doc: /* Modify FRAME according to new values of its parameters in ALIST.
@@ -3555,6 +3774,7 @@ list, but are otherwise ignored. */)
3555 USE_SAFE_ALLOCA; 3774 USE_SAFE_ALLOCA;
3556 SAFE_ALLOCA_LISP (parms, 2 * length); 3775 SAFE_ALLOCA_LISP (parms, 2 * length);
3557 values = parms + length; 3776 values = parms + length;
3777 Lisp_Object params = alist;
3558 3778
3559 /* Extract parm names and values into those vectors. */ 3779 /* Extract parm names and values into those vectors. */
3560 3780
@@ -3580,6 +3800,31 @@ list, but are otherwise ignored. */)
3580 update_face_from_frame_parameter (f, prop, val); 3800 update_face_from_frame_parameter (f, prop, val);
3581 } 3801 }
3582 3802
3803 if (is_tty_child_frame (f))
3804 {
3805 int x = tty_child_pos_param (f, Qleft, params, f->left_pos);
3806 int y = tty_child_pos_param (f, Qtop, params, f->top_pos);
3807 if (x != f->left_pos || y != f->top_pos)
3808 {
3809 f->left_pos = x;
3810 f->top_pos = y;
3811 SET_FRAME_GARBAGED (root_frame (f));
3812 }
3813
3814 int w = tty_child_size_param (f, Qwidth, params, f->total_cols);
3815 int h = tty_child_size_param (f, Qheight, params, f->total_lines);
3816 if (w != f->total_cols || h != f->total_lines)
3817 change_frame_size (f, w, h, false, false, false);
3818
3819 Lisp_Object visible = Fassq (Qvisibility, params);
3820 if (CONSP (visible))
3821 SET_FRAME_VISIBLE (f, !NILP (Fcdr (visible)));
3822
3823 Lisp_Object no_special = Fassq (Qno_special_glyphs, params);
3824 if (CONSP (no_special))
3825 FRAME_NO_SPECIAL_GLYPHS (f) = !NILP (Fcdr (no_special));
3826 }
3827
3583 SAFE_FREE (); 3828 SAFE_FREE ();
3584 } 3829 }
3585 return Qnil; 3830 return Qnil;
@@ -3927,6 +4172,11 @@ bottom edge of FRAME's display. */)
3927 (void) yval; 4172 (void) yval;
3928#endif 4173#endif
3929 } 4174 }
4175 else if (is_tty_child_frame (f))
4176 {
4177 f->left_pos = xval;
4178 f->top_pos = yval;
4179 }
3930 4180
3931 return Qt; 4181 return Qt;
3932} 4182}
@@ -3984,9 +4234,9 @@ multiplied to find the real number of pixels. */)
3984/* Connect the frame-parameter names for frames to the ways of passing 4234/* Connect the frame-parameter names for frames to the ways of passing
3985 the parameter values to the window system. 4235 the parameter values to the window system.
3986 4236
3987 The name of a parameter, as a Lisp symbol, has a 4237 The name of a parameter, a Lisp symbol, has an `x-frame-parameter'
3988 `frame-parameter-pos' property which is an integer in Lisp that is 4238 property which is its index in this table. This is initialized in
3989 an index in this table. */ 4239 syms_of_frame. */
3990 4240
3991struct frame_parm_table { 4241struct frame_parm_table {
3992 const char *name; 4242 const char *name;
@@ -3997,13 +4247,13 @@ static const struct frame_parm_table frame_parms[] =
3997{ 4247{
3998 {"auto-raise", SYMBOL_INDEX (Qauto_raise)}, 4248 {"auto-raise", SYMBOL_INDEX (Qauto_raise)},
3999 {"auto-lower", SYMBOL_INDEX (Qauto_lower)}, 4249 {"auto-lower", SYMBOL_INDEX (Qauto_lower)},
4000 {"background-color", -1}, 4250 {"background-color", SYMBOL_INDEX (Qbackground_color)},
4001 {"border-color", SYMBOL_INDEX (Qborder_color)}, 4251 {"border-color", SYMBOL_INDEX (Qborder_color)},
4002 {"border-width", SYMBOL_INDEX (Qborder_width)}, 4252 {"border-width", SYMBOL_INDEX (Qborder_width)},
4003 {"cursor-color", SYMBOL_INDEX (Qcursor_color)}, 4253 {"cursor-color", SYMBOL_INDEX (Qcursor_color)},
4004 {"cursor-type", SYMBOL_INDEX (Qcursor_type)}, 4254 {"cursor-type", SYMBOL_INDEX (Qcursor_type)},
4005 {"font", -1}, 4255 {"font", SYMBOL_INDEX (Qfont)},
4006 {"foreground-color", -1}, 4256 {"foreground-color", SYMBOL_INDEX (Qforeground_color)},
4007 {"icon-name", SYMBOL_INDEX (Qicon_name)}, 4257 {"icon-name", SYMBOL_INDEX (Qicon_name)},
4008 {"icon-type", SYMBOL_INDEX (Qicon_type)}, 4258 {"icon-type", SYMBOL_INDEX (Qicon_type)},
4009 {"child-frame-border-width", SYMBOL_INDEX (Qchild_frame_border_width)}, 4259 {"child-frame-border-width", SYMBOL_INDEX (Qchild_frame_border_width)},
@@ -4238,6 +4488,29 @@ frame_float (struct frame *f, Lisp_Object val, enum frame_float_type what,
4238 } 4488 }
4239} 4489}
4240 4490
4491/* Handle frame parameter change with frame parameter handler.
4492 F is the frame whose frame parameter was changed.
4493 PROP is the name of the frame parameter.
4494 VAL and OLD_VALUE are the current and the old value of the
4495 frame parameter. */
4496
4497static void
4498handle_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val,
4499 Lisp_Object old_value)
4500{
4501 Lisp_Object param_index = Fget (prop, Qx_frame_parameter);
4502 if (FIXNATP (param_index) && XFIXNAT (param_index) < ARRAYELTS (frame_parms))
4503 {
4504 if (FRAME_RIF (f))
4505 {
4506 frame_parm_handler handler
4507 = FRAME_RIF (f)->frame_parm_handlers[XFIXNAT (param_index)];
4508 if (handler)
4509 handler (f, val, old_value);
4510 }
4511 }
4512}
4513
4241/* Change the parameters of frame F as specified by ALIST. 4514/* Change the parameters of frame F as specified by ALIST.
4242 If a parameter is not specially recognized, do nothing special; 4515 If a parameter is not specially recognized, do nothing special;
4243 otherwise call the `gui_set_...' function for that parameter. 4516 otherwise call the `gui_set_...' function for that parameter.
@@ -4379,17 +4652,9 @@ gui_set_frame_parameters_1 (struct frame *f, Lisp_Object alist,
4379 } 4652 }
4380 else 4653 else
4381 { 4654 {
4382 Lisp_Object param_index, old_value; 4655 Lisp_Object old_value = get_frame_param (f, prop);
4383
4384 old_value = get_frame_param (f, prop);
4385
4386 store_frame_param (f, prop, val); 4656 store_frame_param (f, prop, val);
4387 4657 handle_frame_param (f, prop, val, old_value);
4388 param_index = Fget (prop, Qx_frame_parameter);
4389 if (FIXNATP (param_index)
4390 && XFIXNAT (param_index) < ARRAYELTS (frame_parms)
4391 && FRAME_RIF (f)->frame_parm_handlers[XFIXNUM (param_index)])
4392 (*(FRAME_RIF (f)->frame_parm_handlers[XFIXNUM (param_index)])) (f, val, old_value);
4393 4658
4394 if (!default_parameter && EQ (prop, Qfont)) 4659 if (!default_parameter && EQ (prop, Qfont))
4395 /* The user manually specified the `font' frame parameter. 4660 /* The user manually specified the `font' frame parameter.
@@ -4708,14 +4973,7 @@ gui_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_va
4708 /* Apply the new gamma value to the frame background. */ 4973 /* Apply the new gamma value to the frame background. */
4709 bgcolor = Fassq (Qbackground_color, f->param_alist); 4974 bgcolor = Fassq (Qbackground_color, f->param_alist);
4710 if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor))) 4975 if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor)))
4711 { 4976 handle_frame_param (f, Qbackground_color, bgcolor, Qnil);
4712 Lisp_Object parm_index = Fget (Qbackground_color, Qx_frame_parameter);
4713 if (FIXNATP (parm_index)
4714 && XFIXNAT (parm_index) < ARRAYELTS (frame_parms)
4715 && FRAME_RIF (f)->frame_parm_handlers[XFIXNAT (parm_index)])
4716 (*FRAME_RIF (f)->frame_parm_handlers[XFIXNAT (parm_index)])
4717 (f, bgcolor, Qnil);
4718 }
4719 4977
4720 clear_face_cache (true); /* FIXME: Why of all frames? */ 4978 clear_face_cache (true); /* FIXME: Why of all frames? */
4721 fset_redisplay (f); 4979 fset_redisplay (f);
@@ -6453,17 +6711,13 @@ syms_of_frame (void)
6453 DEFSYM (Quse_frame_synchronization, "use-frame-synchronization"); 6711 DEFSYM (Quse_frame_synchronization, "use-frame-synchronization");
6454 DEFSYM (Qfont_parameter, "font-parameter"); 6712 DEFSYM (Qfont_parameter, "font-parameter");
6455 6713
6456 { 6714 for (int i = 0; i < ARRAYELTS (frame_parms); i++)
6457 int i; 6715 {
6458 6716 int sym = frame_parms[i].sym;
6459 for (i = 0; i < ARRAYELTS (frame_parms); i++) 6717 eassert (sym >= 0 && sym < ARRAYELTS (lispsym));
6460 { 6718 Lisp_Object v = builtin_lisp_symbol (sym);
6461 Lisp_Object v = (frame_parms[i].sym < 0 6719 Fput (v, Qx_frame_parameter, make_fixnum (i));
6462 ? intern_c_string (frame_parms[i].name) 6720 }
6463 : builtin_lisp_symbol (frame_parms[i].sym));
6464 Fput (v, Qx_frame_parameter, make_fixnum (i));
6465 }
6466 }
6467 6721
6468#ifdef HAVE_WINDOW_SYSTEM 6722#ifdef HAVE_WINDOW_SYSTEM
6469 DEFVAR_LISP ("x-resource-name", Vx_resource_name, 6723 DEFVAR_LISP ("x-resource-name", Vx_resource_name,
diff --git a/src/frame.h b/src/frame.h
index 172eb5eca99..cb03d5550bb 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -161,10 +161,8 @@ struct frame
161 Usually it is nil. */ 161 Usually it is nil. */
162 Lisp_Object title; 162 Lisp_Object title;
163 163
164#if defined (HAVE_WINDOW_SYSTEM)
165 /* This frame's parent frame, if it has one. */ 164 /* This frame's parent frame, if it has one. */
166 Lisp_Object parent_frame; 165 Lisp_Object parent_frame;
167#endif /* HAVE_WINDOW_SYSTEM */
168 166
169 /* Last device to move over this frame. Any value that isn't a 167 /* Last device to move over this frame. Any value that isn't a
170 string means the "Virtual core pointer". */ 168 string means the "Virtual core pointer". */
@@ -385,15 +383,8 @@ struct frame
385 zero if the frame has been made invisible without an icon. */ 383 zero if the frame has been made invisible without an icon. */
386 384
387 /* Nonzero if the frame is currently displayed; we check 385 /* Nonzero if the frame is currently displayed; we check
388 it to see if we should bother updating the frame's contents. 386 it to see if we should bother updating the frame's contents. */
389 387 unsigned visible : 1;
390 On ttys and on Windows NT/9X, to avoid wasting effort updating
391 visible frames that are actually completely obscured by other
392 windows on the display, we bend the meaning of visible slightly:
393 if equal to 2, then the frame is obscured - we still consider
394 it to be "visible" as seen from lisp, but we don't bother
395 updating it. */
396 unsigned visible : 2;
397 388
398 /* True if the frame is currently iconified. Do not 389 /* True if the frame is currently iconified. Do not
399 set this directly, use SET_FRAME_ICONIFIED instead. */ 390 set this directly, use SET_FRAME_ICONIFIED instead. */
@@ -451,6 +442,13 @@ struct frame
451 This must be the same as the terminal->type. */ 442 This must be the same as the terminal->type. */
452 ENUM_BF (output_method) output_method : 4; 443 ENUM_BF (output_method) output_method : 4;
453 444
445 /* True if this is an undecorated frame. */
446 bool_bf undecorated : 1;
447
448 /* Nonzero if this frame's window does not want to receive input focus
449 via mouse clicks or by moving the mouse into it. */
450 bool_bf no_accept_focus : 1;
451
454#ifdef HAVE_WINDOW_SYSTEM 452#ifdef HAVE_WINDOW_SYSTEM
455 /* True if this frame is a tooltip frame. */ 453 /* True if this frame is a tooltip frame. */
456 bool_bf tooltip : 1; 454 bool_bf tooltip : 1;
@@ -465,10 +463,7 @@ struct frame
465 /* Nonzero if we should actually display horizontal scroll bars on this frame. */ 463 /* Nonzero if we should actually display horizontal scroll bars on this frame. */
466 bool_bf horizontal_scroll_bars : 1; 464 bool_bf horizontal_scroll_bars : 1;
467 465
468 /* True if this is an undecorated frame. */ 466# ifndef HAVE_NTGUI
469 bool_bf undecorated : 1;
470
471#ifndef HAVE_NTGUI
472 /* True if this is an override_redirect frame. */ 467 /* True if this is an override_redirect frame. */
473 bool_bf override_redirect : 1; 468 bool_bf override_redirect : 1;
474#endif 469#endif
@@ -480,17 +475,13 @@ struct frame
480 receive input focus when it is mapped. */ 475 receive input focus when it is mapped. */
481 bool_bf no_focus_on_map : 1; 476 bool_bf no_focus_on_map : 1;
482 477
483 /* Nonzero if this frame's window does not want to receive input focus
484 via mouse clicks or by moving the mouse into it. */
485 bool_bf no_accept_focus : 1;
486
487 /* The z-group this frame's window belongs to. */ 478 /* The z-group this frame's window belongs to. */
488 ENUM_BF (z_group) z_group : 2; 479 ENUM_BF (z_group) z_group : 2;
480#endif /* HAVE_WINDOW_SYSTEM */
489 481
490 /* Non-zero if display of truncation and continuation glyphs outside 482 /* Non-zero if display of truncation and continuation glyphs outside
491 the fringes is suppressed. */ 483 the fringes is suppressed. */
492 bool_bf no_special_glyphs : 1; 484 bool_bf no_special_glyphs : 1;
493#endif /* HAVE_WINDOW_SYSTEM */
494 485
495 /* True means set_window_size_hook requests can be processed for 486 /* True means set_window_size_hook requests can be processed for
496 this frame. */ 487 this frame. */
@@ -736,7 +727,10 @@ struct frame
736#ifdef HAVE_TEXT_CONVERSION 727#ifdef HAVE_TEXT_CONVERSION
737 /* Text conversion state used by certain input methods. */ 728 /* Text conversion state used by certain input methods. */
738 struct text_conversion_state conversion; 729 struct text_conversion_state conversion;
739#endif 730# endif
731
732 /* Z-order of child frames. */
733 int z_order;
740} GCALIGNED_STRUCT; 734} GCALIGNED_STRUCT;
741 735
742/* Most code should use these functions to set Lisp fields in struct frame. */ 736/* Most code should use these functions to set Lisp fields in struct frame. */
@@ -1017,9 +1011,9 @@ default_pixels_per_inch_y (void)
1017 does not have FRAME_DISPLAY_INFO. */ 1011 does not have FRAME_DISPLAY_INFO. */
1018#ifdef HAVE_WINDOW_SYSTEM 1012#ifdef HAVE_WINDOW_SYSTEM
1019#ifndef HAVE_ANDROID 1013#ifndef HAVE_ANDROID
1020# define MOUSE_HL_INFO(F) \ 1014# define MOUSE_HL_INFO(F) \
1021 (FRAME_WINDOW_P (F) \ 1015 (FRAME_WINDOW_P (F) \
1022 ? &FRAME_DISPLAY_INFO(F)->mouse_highlight \ 1016 ? &FRAME_DISPLAY_INFO (F)->mouse_highlight \
1023 : &(F)->output_data.tty->display_info->mouse_highlight) 1017 : &(F)->output_data.tty->display_info->mouse_highlight)
1024#else 1018#else
1025/* There is no "struct tty_output" on Android at all. */ 1019/* There is no "struct tty_output" on Android at all. */
@@ -1172,9 +1166,6 @@ default_pixels_per_inch_y (void)
1172 && FRAME_X_VISIBLE (f))) 1166 && FRAME_X_VISIBLE (f)))
1173#endif 1167#endif
1174 1168
1175/* True if frame F is currently visible but hidden. */
1176#define FRAME_OBSCURED_P(f) ((f)->visible > 1)
1177
1178/* True if frame F is currently iconified. */ 1169/* True if frame F is currently iconified. */
1179#define FRAME_ICONIFIED_P(f) (f)->iconified 1170#define FRAME_ICONIFIED_P(f) (f)->iconified
1180 1171
@@ -1239,21 +1230,23 @@ default_pixels_per_inch_y (void)
1239#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) ((void) (f), 0) 1230#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) ((void) (f), 0)
1240#endif /* HAVE_WINDOW_SYSTEM */ 1231#endif /* HAVE_WINDOW_SYSTEM */
1241 1232
1242#if defined (HAVE_WINDOW_SYSTEM) 1233INLINE struct frame *
1234FRAME_PARENT_FRAME (struct frame *f)
1235{
1236 return NILP (f->parent_frame) ? NULL : XFRAME (f->parent_frame);
1237}
1238
1243#define FRAME_UNDECORATED(f) ((f)->undecorated) 1239#define FRAME_UNDECORATED(f) ((f)->undecorated)
1240
1241#if defined (HAVE_WINDOW_SYSTEM)
1244#ifdef HAVE_NTGUI 1242#ifdef HAVE_NTGUI
1245#define FRAME_OVERRIDE_REDIRECT(f) ((void) (f), 0) 1243#define FRAME_OVERRIDE_REDIRECT(f) ((void) (f), 0)
1246#else 1244#else
1247#define FRAME_OVERRIDE_REDIRECT(f) ((f)->override_redirect) 1245#define FRAME_OVERRIDE_REDIRECT(f) ((f)->override_redirect)
1248#endif 1246#endif
1249#define FRAME_PARENT_FRAME(f) \
1250 (NILP ((f)->parent_frame) \
1251 ? NULL \
1252 : XFRAME ((f)->parent_frame))
1253#define FRAME_SKIP_TASKBAR(f) ((f)->skip_taskbar) 1247#define FRAME_SKIP_TASKBAR(f) ((f)->skip_taskbar)
1254#define FRAME_NO_FOCUS_ON_MAP(f) ((f)->no_focus_on_map) 1248#define FRAME_NO_FOCUS_ON_MAP(f) ((f)->no_focus_on_map)
1255#define FRAME_NO_ACCEPT_FOCUS(f) ((f)->no_accept_focus) 1249#define FRAME_NO_ACCEPT_FOCUS(f) ((f)->no_accept_focus)
1256#define FRAME_NO_SPECIAL_GLYPHS(f) ((f)->no_special_glyphs)
1257#define FRAME_Z_GROUP(f) ((f)->z_group) 1250#define FRAME_Z_GROUP(f) ((f)->z_group)
1258#define FRAME_Z_GROUP_NONE(f) ((f)->z_group == z_group_none) 1251#define FRAME_Z_GROUP_NONE(f) ((f)->z_group == z_group_none)
1259#define FRAME_Z_GROUP_ABOVE(f) ((f)->z_group == z_group_above) 1252#define FRAME_Z_GROUP_ABOVE(f) ((f)->z_group == z_group_above)
@@ -1266,13 +1259,10 @@ default_pixels_per_inch_y (void)
1266#define FRAME_NS_TRANSPARENT_TITLEBAR(f) ((f)->ns_transparent_titlebar) 1259#define FRAME_NS_TRANSPARENT_TITLEBAR(f) ((f)->ns_transparent_titlebar)
1267#endif 1260#endif
1268#else /* not HAVE_WINDOW_SYSTEM */ 1261#else /* not HAVE_WINDOW_SYSTEM */
1269#define FRAME_UNDECORATED(f) ((void) (f), 0)
1270#define FRAME_OVERRIDE_REDIRECT(f) ((void) (f), 0) 1262#define FRAME_OVERRIDE_REDIRECT(f) ((void) (f), 0)
1271#define FRAME_PARENT_FRAME(f) ((void) (f), NULL)
1272#define FRAME_SKIP_TASKBAR(f) ((void) (f), 0) 1263#define FRAME_SKIP_TASKBAR(f) ((void) (f), 0)
1273#define FRAME_NO_FOCUS_ON_MAP(f) ((void) (f), 0) 1264#define FRAME_NO_FOCUS_ON_MAP(f) ((void) (f), 0)
1274#define FRAME_NO_ACCEPT_FOCUS(f) ((void) (f), 0) 1265#define FRAME_NO_ACCEPT_FOCUS(f) ((void) (f), 0)
1275#define FRAME_NO_SPECIAL_GLYPHS(f) ((void) (f), 0)
1276#define FRAME_Z_GROUP(f) ((void) (f), z_group_none) 1266#define FRAME_Z_GROUP(f) ((void) (f), z_group_none)
1277#define FRAME_Z_GROUP_NONE(f) ((void) (f), true) 1267#define FRAME_Z_GROUP_NONE(f) ((void) (f), true)
1278#define FRAME_Z_GROUP_ABOVE(f) ((void) (f), false) 1268#define FRAME_Z_GROUP_ABOVE(f) ((void) (f), false)
@@ -1280,6 +1270,8 @@ default_pixels_per_inch_y (void)
1280#define FRAME_TOOLTIP_P(f) ((void) f, false) 1270#define FRAME_TOOLTIP_P(f) ((void) f, false)
1281#endif /* HAVE_WINDOW_SYSTEM */ 1271#endif /* HAVE_WINDOW_SYSTEM */
1282 1272
1273#define FRAME_NO_SPECIAL_GLYPHS(f) ((f)->no_special_glyphs)
1274
1283/* Whether horizontal scroll bars are currently enabled for frame F. */ 1275/* Whether horizontal scroll bars are currently enabled for frame F. */
1284#if USE_HORIZONTAL_SCROLL_BARS 1276#if USE_HORIZONTAL_SCROLL_BARS
1285#define FRAME_HAS_HORIZONTAL_SCROLL_BARS(f) \ 1277#define FRAME_HAS_HORIZONTAL_SCROLL_BARS(f) \
@@ -1441,9 +1433,8 @@ extern bool frame_garbaged;
1441 if some changes were applied to it while it wasn't visible (and hence 1433 if some changes were applied to it while it wasn't visible (and hence
1442 wasn't redisplayed). */ 1434 wasn't redisplayed). */
1443INLINE void 1435INLINE void
1444SET_FRAME_VISIBLE (struct frame *f, int v) 1436SET_FRAME_VISIBLE (struct frame *f, bool v)
1445{ 1437{
1446 eassert (0 <= v && v <= 2);
1447 if (v) 1438 if (v)
1448 { 1439 {
1449 if (v == 1 && f->visible != 1) 1440 if (v == 1 && f->visible != 1)
@@ -1500,13 +1491,14 @@ extern struct frame *decode_any_frame (Lisp_Object);
1500extern struct frame *make_initial_frame (void); 1491extern struct frame *make_initial_frame (void);
1501extern struct frame *make_frame (bool); 1492extern struct frame *make_frame (bool);
1502#ifdef HAVE_WINDOW_SYSTEM 1493#ifdef HAVE_WINDOW_SYSTEM
1503extern struct frame *make_minibuffer_frame (void);
1504extern struct frame *make_frame_without_minibuffer (Lisp_Object,
1505 struct kboard *,
1506 Lisp_Object);
1507extern bool display_available (void); 1494extern bool display_available (void);
1508#endif 1495#endif
1509 1496
1497struct frame *make_minibuffer_frame (void);
1498struct frame *
1499make_frame_without_minibuffer (Lisp_Object mini_window,
1500 KBOARD *kb, Lisp_Object display);
1501
1510INLINE bool 1502INLINE bool
1511window_system_available (struct frame *f) 1503window_system_available (struct frame *f)
1512{ 1504{
@@ -1518,6 +1510,8 @@ window_system_available (struct frame *f)
1518} 1510}
1519 1511
1520extern WINDOW_SYSTEM_RETURN void check_window_system (struct frame *); 1512extern WINDOW_SYSTEM_RETURN void check_window_system (struct frame *);
1513void check_tty (struct frame *f);
1514struct frame *decode_tty_frame (Lisp_Object frame);
1521extern void frame_make_pointer_invisible (struct frame *); 1515extern void frame_make_pointer_invisible (struct frame *);
1522extern void frame_make_pointer_visible (struct frame *); 1516extern void frame_make_pointer_visible (struct frame *);
1523extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object); 1517extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object);
@@ -1613,15 +1607,11 @@ FRAME_CHILD_FRAME_BORDER_WIDTH (struct frame *f)
1613INLINE int 1607INLINE int
1614FRAME_INTERNAL_BORDER_WIDTH (struct frame *f) 1608FRAME_INTERNAL_BORDER_WIDTH (struct frame *f)
1615{ 1609{
1616#ifdef HAVE_WINDOW_SYSTEM
1617 return (FRAME_PARENT_FRAME(f) 1610 return (FRAME_PARENT_FRAME(f)
1618 ? (FRAME_CHILD_FRAME_BORDER_WIDTH(f) >= 0 1611 ? (FRAME_CHILD_FRAME_BORDER_WIDTH(f) >= 0
1619 ? FRAME_CHILD_FRAME_BORDER_WIDTH(f) 1612 ? FRAME_CHILD_FRAME_BORDER_WIDTH(f)
1620 : frame_dimension (f->internal_border_width)) 1613 : frame_dimension (f->internal_border_width))
1621 : frame_dimension (f->internal_border_width)); 1614 : frame_dimension (f->internal_border_width));
1622#else
1623 return frame_dimension (f->internal_border_width);
1624#endif
1625} 1615}
1626 1616
1627/* Pixel-size of window divider lines. */ 1617/* Pixel-size of window divider lines. */
@@ -1876,7 +1866,6 @@ extern Lisp_Object gui_display_get_resource (Display_Info *,
1876extern void set_frame_menubar (struct frame *f, bool deep_p); 1866extern void set_frame_menubar (struct frame *f, bool deep_p);
1877extern void frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y); 1867extern void frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
1878extern void free_frame_menubar (struct frame *); 1868extern void free_frame_menubar (struct frame *);
1879extern bool frame_ancestor_p (struct frame *af, struct frame *df);
1880extern enum internal_border_part frame_internal_border_part (struct frame *f, int x, int y); 1869extern enum internal_border_part frame_internal_border_part (struct frame *f, int x, int y);
1881 1870
1882#if defined HAVE_X_WINDOWS 1871#if defined HAVE_X_WINDOWS
@@ -1903,6 +1892,8 @@ gui_set_bitmap_icon (struct frame *f)
1903#endif /* !HAVE_NS */ 1892#endif /* !HAVE_NS */
1904#endif /* HAVE_WINDOW_SYSTEM */ 1893#endif /* HAVE_WINDOW_SYSTEM */
1905 1894
1895extern bool frame_ancestor_p (struct frame *af, struct frame *df);
1896
1906INLINE void 1897INLINE void
1907flush_frame (struct frame *f) 1898flush_frame (struct frame *f)
1908{ 1899{
diff --git a/src/keyboard.c b/src/keyboard.c
index 6d28dca9aeb..bfb5fd3592b 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5415,7 +5415,7 @@ static const char *const lispy_kana_keys[] =
5415 5415
5416/* You'll notice that this table is arranged to be conveniently 5416/* You'll notice that this table is arranged to be conveniently
5417 indexed by X Windows keysym values. */ 5417 indexed by X Windows keysym values. */
5418#ifdef HAVE_NS 5418#if defined HAVE_NS || !defined HAVE_WINDOW_SYSTEM
5419/* FIXME: Why are we using X11 keysym values for NS? */ 5419/* FIXME: Why are we using X11 keysym values for NS? */
5420static 5420static
5421#endif 5421#endif
diff --git a/src/minibuf.c b/src/minibuf.c
index 9fd5c236f0b..e75ac5e51df 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -913,7 +913,11 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
913 XWINDOW (minibuf_window)->cursor.hpos = 0; 913 XWINDOW (minibuf_window)->cursor.hpos = 0;
914 XWINDOW (minibuf_window)->cursor.x = 0; 914 XWINDOW (minibuf_window)->cursor.x = 0;
915 XWINDOW (minibuf_window)->must_be_updated_p = true; 915 XWINDOW (minibuf_window)->must_be_updated_p = true;
916 update_frame (XFRAME (selected_frame), true, true); 916 struct frame *sf = XFRAME (selected_frame);
917 update_frame (sf, true, true);
918 if (is_tty_frame (sf))
919 combine_updates_for_frame (sf, true, true);
920
917#ifndef HAVE_NTGUI 921#ifndef HAVE_NTGUI
918 flush_frame (XFRAME (XWINDOW (minibuf_window)->frame)); 922 flush_frame (XFRAME (XWINDOW (minibuf_window)->frame));
919#else 923#else
diff --git a/src/nsfns.m b/src/nsfns.m
index 3c012ca8f05..1055a4b37df 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -3351,7 +3351,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
3351 [nswindow orderFront: NSApp]; 3351 [nswindow orderFront: NSApp];
3352 [nswindow display]; 3352 [nswindow display];
3353 3353
3354 SET_FRAME_VISIBLE (tip_f, 1); 3354 SET_FRAME_VISIBLE (tip_f, true);
3355 unblock_input (); 3355 unblock_input ();
3356 3356
3357 goto start_timer; 3357 goto start_timer;
@@ -3534,7 +3534,7 @@ DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
3534 [nswindow orderFront: NSApp]; 3534 [nswindow orderFront: NSApp];
3535 [nswindow display]; 3535 [nswindow display];
3536 3536
3537 SET_FRAME_VISIBLE (tip_f, YES); 3537 SET_FRAME_VISIBLE (tip_f, true);
3538 FRAME_PIXEL_WIDTH (tip_f) = width; 3538 FRAME_PIXEL_WIDTH (tip_f) = width;
3539 FRAME_PIXEL_HEIGHT (tip_f) = height; 3539 FRAME_PIXEL_HEIGHT (tip_f) = height;
3540 unblock_input (); 3540 unblock_input ();
diff --git a/src/nsterm.m b/src/nsterm.m
index dceb3cebb4d..c705a3c78f4 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1505,7 +1505,7 @@ ns_make_frame_visible (struct frame *f)
1505 EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f); 1505 EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f);
1506 EmacsWindow *window = (EmacsWindow *)[view window]; 1506 EmacsWindow *window = (EmacsWindow *)[view window];
1507 1507
1508 SET_FRAME_VISIBLE (f, 1); 1508 SET_FRAME_VISIBLE (f, true);
1509 ns_raise_frame (f, ! FRAME_NO_FOCUS_ON_MAP (f)); 1509 ns_raise_frame (f, ! FRAME_NO_FOCUS_ON_MAP (f));
1510 1510
1511 /* Making a new frame from a fullscreen frame will make the new frame 1511 /* Making a new frame from a fullscreen frame will make the new frame
@@ -1550,7 +1550,7 @@ ns_make_frame_invisible (struct frame *f)
1550 check_window_system (f); 1550 check_window_system (f);
1551 view = FRAME_NS_VIEW (f); 1551 view = FRAME_NS_VIEW (f);
1552 [[view window] orderOut: NSApp]; 1552 [[view window] orderOut: NSApp];
1553 SET_FRAME_VISIBLE (f, 0); 1553 SET_FRAME_VISIBLE (f, false);
1554 SET_FRAME_ICONIFIED (f, 0); 1554 SET_FRAME_ICONIFIED (f, 0);
1555} 1555}
1556 1556
diff --git a/src/scroll.c b/src/scroll.c
index fd2a9e71207..1d01ae90d72 100644
--- a/src/scroll.c
+++ b/src/scroll.c
@@ -366,7 +366,7 @@ do_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
366 eassert (copy_from[k] >= 0 && copy_from[k] < window_size); 366 eassert (copy_from[k] >= 0 && copy_from[k] < window_size);
367 367
368 /* Perform the row swizzling. */ 368 /* Perform the row swizzling. */
369 mirrored_line_dance (current_matrix, unchanged_at_top, window_size, 369 mirrored_line_dance (frame, unchanged_at_top, window_size,
370 copy_from, retained_p); 370 copy_from, retained_p);
371 371
372 /* Some sanity checks if GLYPH_DEBUG is defined. */ 372 /* Some sanity checks if GLYPH_DEBUG is defined. */
@@ -780,7 +780,7 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
780 copy_from[i] gives the original line to copy to I, and 780 copy_from[i] gives the original line to copy to I, and
781 retained_p[copy_from[i]] is zero if line I in the new display is 781 retained_p[copy_from[i]] is zero if line I in the new display is
782 empty. */ 782 empty. */
783 mirrored_line_dance (current_matrix, unchanged_at_top, window_size, 783 mirrored_line_dance (frame, unchanged_at_top, window_size,
784 copy_from, retained_p); 784 copy_from, retained_p);
785 785
786 if (terminal_window_p) 786 if (terminal_window_p)
diff --git a/src/term.c b/src/term.c
index 1f524880054..64df5261e50 100644
--- a/src/term.c
+++ b/src/term.c
@@ -65,11 +65,9 @@ static int been_here = -1;
65#ifndef HAVE_ANDROID 65#ifndef HAVE_ANDROID
66 66
67static void tty_set_scroll_region (struct frame *f, int start, int stop); 67static void tty_set_scroll_region (struct frame *f, int start, int stop);
68static void turn_on_face (struct frame *, int face_id); 68static void turn_on_face (struct frame *f, struct face *face);
69static void turn_off_face (struct frame *, int face_id); 69static void turn_off_face (struct frame *f, struct face *face);
70static void tty_turn_off_highlight (struct tty_display_info *); 70static void tty_turn_off_highlight (struct tty_display_info *);
71static void tty_show_cursor (struct tty_display_info *);
72static void tty_hide_cursor (struct tty_display_info *);
73static void tty_background_highlight (struct tty_display_info *tty); 71static void tty_background_highlight (struct tty_display_info *tty);
74static void clear_tty_hooks (struct terminal *terminal); 72static void clear_tty_hooks (struct terminal *terminal);
75static void set_tty_hooks (struct terminal *terminal); 73static void set_tty_hooks (struct terminal *terminal);
@@ -336,7 +334,7 @@ tty_toggle_highlight (struct tty_display_info *tty)
336 334
337/* Make cursor invisible. */ 335/* Make cursor invisible. */
338 336
339static void 337void
340tty_hide_cursor (struct tty_display_info *tty) 338tty_hide_cursor (struct tty_display_info *tty)
341{ 339{
342 if (tty->cursor_hidden == 0) 340 if (tty->cursor_hidden == 0)
@@ -353,7 +351,7 @@ tty_hide_cursor (struct tty_display_info *tty)
353 351
354/* Ensure that cursor is visible. */ 352/* Ensure that cursor is visible. */
355 353
356static void 354void
357tty_show_cursor (struct tty_display_info *tty) 355tty_show_cursor (struct tty_display_info *tty)
358{ 356{
359 if (tty->cursor_hidden) 357 if (tty->cursor_hidden)
@@ -753,18 +751,12 @@ encode_terminal_code (struct glyph *src, int src_len,
753static void 751static void
754tty_write_glyphs (struct frame *f, struct glyph *string, int len) 752tty_write_glyphs (struct frame *f, struct glyph *string, int len)
755{ 753{
756 unsigned char *conversion_buffer;
757 struct coding_system *coding;
758 int n, stringlen;
759
760 struct tty_display_info *tty = FRAME_TTY (f); 754 struct tty_display_info *tty = FRAME_TTY (f);
761
762 tty_turn_off_insert (tty); 755 tty_turn_off_insert (tty);
763 tty_hide_cursor (tty); 756 tty_hide_cursor (tty);
764 757
765 /* Don't dare write in last column of bottom line, if Auto-Wrap, 758 /* Don't dare write in last column of bottom line, if Auto-Wrap,
766 since that would scroll the whole frame on some terminals. */ 759 since that would scroll the whole frame on some terminals. */
767
768 if (AutoWrap (tty) 760 if (AutoWrap (tty)
769 && curY (tty) + 1 == FRAME_TOTAL_LINES (f) 761 && curY (tty) + 1 == FRAME_TOTAL_LINES (f)
770 && (curX (tty) + len) == FRAME_COLS (f)) 762 && (curX (tty) + len) == FRAME_COLS (f))
@@ -777,29 +769,34 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
777 /* If terminal_coding does any conversion, use it, otherwise use 769 /* If terminal_coding does any conversion, use it, otherwise use
778 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here 770 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
779 because it always return 1 if the member src_multibyte is 1. */ 771 because it always return 1 if the member src_multibyte is 1. */
780 coding = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK 772 struct coding_system *coding
781 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding); 773 = (FRAME_TERMINAL_CODING (f)->common_flags & CODING_REQUIRE_ENCODING_MASK
774 ? FRAME_TERMINAL_CODING (f) : &safe_terminal_coding);
775
782 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at 776 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
783 the tail. */ 777 the tail. */
784 coding->mode &= ~CODING_MODE_LAST_BLOCK; 778 coding->mode &= ~CODING_MODE_LAST_BLOCK;
785 779
786 for (stringlen = len; stringlen != 0; stringlen -= n) 780 for (int stringlen = len, n; stringlen; stringlen -= n, string += n)
787 { 781 {
788 /* Identify a run of glyphs with the same face. */ 782 /* Identify a run of glyphs with the same face. */
789 int face_id = string->face_id; 783 int face_id = string->face_id;
784 struct frame *face_id_frame = string->frame;
790 785
791 for (n = 1; n < stringlen; ++n) 786 for (n = 1; n < stringlen; ++n)
792 if (string[n].face_id != face_id) 787 if (string[n].face_id != face_id || string[n].frame != face_id_frame)
793 break; 788 break;
794 789
795 /* Turn appearance modes of the face of the run on. */ 790 /* Turn appearance modes of the face of the run on. */
796 tty_highlight_if_desired (tty); 791 tty_highlight_if_desired (tty);
797 turn_on_face (f, face_id); 792 struct face *face = FACE_FROM_ID (face_id_frame, face_id);
793 turn_on_face (f, face);
798 794
799 if (n == stringlen) 795 if (n == stringlen)
800 /* This is the last run. */ 796 /* This is the last run. */
801 coding->mode |= CODING_MODE_LAST_BLOCK; 797 coding->mode |= CODING_MODE_LAST_BLOCK;
802 conversion_buffer = encode_terminal_code (string, n, coding); 798 unsigned char *conversion_buffer
799 = encode_terminal_code (string, n, coding);
803 if (coding->produced > 0) 800 if (coding->produced > 0)
804 { 801 {
805 block_input (); 802 block_input ();
@@ -809,10 +806,9 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
809 fwrite (conversion_buffer, 1, coding->produced, tty->termscript); 806 fwrite (conversion_buffer, 1, coding->produced, tty->termscript);
810 unblock_input (); 807 unblock_input ();
811 } 808 }
812 string += n;
813 809
814 /* Turn appearance modes off. */ 810 /* Turn appearance modes off. */
815 turn_off_face (f, face_id); 811 turn_off_face (f, face);
816 tty_turn_off_highlight (tty); 812 tty_turn_off_highlight (tty);
817 } 813 }
818 814
@@ -822,8 +818,8 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
822#ifndef DOS_NT 818#ifndef DOS_NT
823 819
824static void 820static void
825tty_write_glyphs_with_face (register struct frame *f, register struct glyph *string, 821tty_write_glyphs_with_face (struct frame *f, struct glyph *string,
826 register int len, register int face_id) 822 int len, struct face *face)
827{ 823{
828 unsigned char *conversion_buffer; 824 unsigned char *conversion_buffer;
829 struct coding_system *coding; 825 struct coding_system *coding;
@@ -856,7 +852,7 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str
856 852
857 /* Turn appearance modes of the face. */ 853 /* Turn appearance modes of the face. */
858 tty_highlight_if_desired (tty); 854 tty_highlight_if_desired (tty);
859 turn_on_face (f, face_id); 855 turn_on_face (f, face);
860 856
861 coding->mode |= CODING_MODE_LAST_BLOCK; 857 coding->mode |= CODING_MODE_LAST_BLOCK;
862 conversion_buffer = encode_terminal_code (string, len, coding); 858 conversion_buffer = encode_terminal_code (string, len, coding);
@@ -871,7 +867,7 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str
871 } 867 }
872 868
873 /* Turn appearance modes off. */ 869 /* Turn appearance modes off. */
874 turn_off_face (f, face_id); 870 turn_off_face (f, face);
875 tty_turn_off_highlight (tty); 871 tty_turn_off_highlight (tty);
876 872
877 cmcheckmagic (tty); 873 cmcheckmagic (tty);
@@ -919,6 +915,7 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
919 915
920 while (len-- > 0) 916 while (len-- > 0)
921 { 917 {
918 struct face *face = NULL;
922 OUTPUT1_IF (tty, tty->TS_ins_char); 919 OUTPUT1_IF (tty, tty->TS_ins_char);
923 if (!start) 920 if (!start)
924 { 921 {
@@ -928,7 +925,10 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
928 else 925 else
929 { 926 {
930 tty_highlight_if_desired (tty); 927 tty_highlight_if_desired (tty);
931 turn_on_face (f, start->face_id); 928 int face_id = start->face_id;
929 struct frame *face_id_frame = start->frame;
930 face = FACE_FROM_ID (face_id_frame, face_id);
931 turn_on_face (f, face);
932 glyph = start; 932 glyph = start;
933 ++start; 933 ++start;
934 /* We must open sufficient space for a character which 934 /* We must open sufficient space for a character which
@@ -957,9 +957,9 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
957 } 957 }
958 958
959 OUTPUT1_IF (tty, tty->TS_pad_inserted_char); 959 OUTPUT1_IF (tty, tty->TS_pad_inserted_char);
960 if (start) 960 if (face)
961 { 961 {
962 turn_off_face (f, glyph->face_id); 962 turn_off_face (f, face);
963 tty_turn_off_highlight (tty); 963 tty_turn_off_highlight (tty);
964 } 964 }
965 } 965 }
@@ -1542,6 +1542,7 @@ append_glyph (struct it *it)
1542 glyph->type = CHAR_GLYPH; 1542 glyph->type = CHAR_GLYPH;
1543 glyph->pixel_width = 1; 1543 glyph->pixel_width = 1;
1544 glyph->u.ch = it->char_to_display; 1544 glyph->u.ch = it->char_to_display;
1545 glyph->frame = it->f;
1545 glyph->face_id = it->face_id; 1546 glyph->face_id = it->face_id;
1546 glyph->avoid_cursor_p = it->avoid_cursor_p; 1547 glyph->avoid_cursor_p = it->avoid_cursor_p;
1547 glyph->multibyte_p = it->multibyte_p; 1548 glyph->multibyte_p = it->multibyte_p;
@@ -1769,6 +1770,7 @@ append_composite_glyph (struct it *it)
1769 1770
1770 glyph->avoid_cursor_p = it->avoid_cursor_p; 1771 glyph->avoid_cursor_p = it->avoid_cursor_p;
1771 glyph->multibyte_p = it->multibyte_p; 1772 glyph->multibyte_p = it->multibyte_p;
1773 glyph->frame = it->f;
1772 glyph->face_id = it->face_id; 1774 glyph->face_id = it->face_id;
1773 glyph->padding_p = false; 1775 glyph->padding_p = false;
1774 glyph->charpos = CHARPOS (it->position); 1776 glyph->charpos = CHARPOS (it->position);
@@ -1855,6 +1857,7 @@ append_glyphless_glyph (struct it *it, int face_id, const char *str)
1855 glyph->pixel_width = 1; 1857 glyph->pixel_width = 1;
1856 glyph->avoid_cursor_p = it->avoid_cursor_p; 1858 glyph->avoid_cursor_p = it->avoid_cursor_p;
1857 glyph->multibyte_p = it->multibyte_p; 1859 glyph->multibyte_p = it->multibyte_p;
1860 glyph->frame = it->f;
1858 glyph->face_id = face_id; 1861 glyph->face_id = face_id;
1859 glyph->padding_p = false; 1862 glyph->padding_p = false;
1860 glyph->charpos = CHARPOS (it->position); 1863 glyph->charpos = CHARPOS (it->position);
@@ -1981,9 +1984,8 @@ produce_glyphless_glyph (struct it *it, Lisp_Object acronym)
1981 FACE_ID is a realized face ID number, in the face cache. */ 1984 FACE_ID is a realized face ID number, in the face cache. */
1982 1985
1983static void 1986static void
1984turn_on_face (struct frame *f, int face_id) 1987turn_on_face (struct frame *f, struct face *face)
1985{ 1988{
1986 struct face *face = FACE_FROM_ID (f, face_id);
1987 unsigned long fg = face->foreground; 1989 unsigned long fg = face->foreground;
1988 unsigned long bg = face->background; 1990 unsigned long bg = face->background;
1989 struct tty_display_info *tty = FRAME_TTY (f); 1991 struct tty_display_info *tty = FRAME_TTY (f);
@@ -2064,9 +2066,8 @@ turn_on_face (struct frame *f, int face_id)
2064/* Turn off appearances of face FACE_ID on tty frame F. */ 2066/* Turn off appearances of face FACE_ID on tty frame F. */
2065 2067
2066static void 2068static void
2067turn_off_face (struct frame *f, int face_id) 2069turn_off_face (struct frame *f, struct face *face)
2068{ 2070{
2069 struct face *face = FACE_FROM_ID (f, face_id);
2070 struct tty_display_info *tty = FRAME_TTY (f); 2071 struct tty_display_info *tty = FRAME_TTY (f);
2071 2072
2072 if (tty->TS_exit_attribute_mode) 2073 if (tty->TS_exit_attribute_mode)
@@ -2399,8 +2400,10 @@ A suspended tty may be resumed by calling `resume-tty' on it. */)
2399 t->display_info.tty->output = 0; 2400 t->display_info.tty->output = 0;
2400 2401
2401 if (FRAMEP (t->display_info.tty->top_frame)) 2402 if (FRAMEP (t->display_info.tty->top_frame))
2402 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 0); 2403 {
2403 2404 struct frame *top = XFRAME (t->display_info.tty->top_frame);
2405 SET_FRAME_VISIBLE (root_frame (top), false);
2406 }
2404 } 2407 }
2405 2408
2406 /* Clear display hooks to prevent further output. */ 2409 /* Clear display hooks to prevent further output. */
@@ -2472,7 +2475,8 @@ frame's terminal). */)
2472 2475
2473 if (FRAMEP (t->display_info.tty->top_frame)) 2476 if (FRAMEP (t->display_info.tty->top_frame))
2474 { 2477 {
2475 struct frame *f = XFRAME (t->display_info.tty->top_frame); 2478 struct frame *top = XFRAME (t->display_info.tty->top_frame);
2479 struct frame *f = root_frame (top);
2476 int width, height; 2480 int width, height;
2477 int old_height = FRAME_COLS (f); 2481 int old_height = FRAME_COLS (f);
2478 int old_width = FRAME_TOTAL_LINES (f); 2482 int old_width = FRAME_TOTAL_LINES (f);
@@ -2482,7 +2486,7 @@ frame's terminal). */)
2482 get_tty_size (fileno (t->display_info.tty->input), &width, &height); 2486 get_tty_size (fileno (t->display_info.tty->input), &width, &height);
2483 if (width != old_width || height != old_height) 2487 if (width != old_width || height != old_height)
2484 change_frame_size (f, width, height, false, false, false); 2488 change_frame_size (f, width, height, false, false, false);
2485 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1); 2489 SET_FRAME_VISIBLE (f, true);
2486 } 2490 }
2487 2491
2488 set_tty_hooks (t); 2492 set_tty_hooks (t);
@@ -2563,22 +2567,24 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
2563 struct frame *f = XFRAME (WINDOW_FRAME (w)); 2567 struct frame *f = XFRAME (WINDOW_FRAME (w));
2564 struct tty_display_info *tty = FRAME_TTY (f); 2568 struct tty_display_info *tty = FRAME_TTY (f);
2565 int face_id = tty->mouse_highlight.mouse_face_face_id; 2569 int face_id = tty->mouse_highlight.mouse_face_face_id;
2566 int save_x, save_y, pos_x, pos_y;
2567 2570
2568 if (end_hpos >= row->used[TEXT_AREA]) 2571 if (end_hpos >= row->used[TEXT_AREA])
2569 nglyphs = row->used[TEXT_AREA] - start_hpos; 2572 nglyphs = row->used[TEXT_AREA] - start_hpos;
2570 2573
2571 pos_y = row->y + WINDOW_TOP_EDGE_Y (w); 2574 int pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
2572 pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w); 2575 int pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w);
2573 2576
2574 /* Save current cursor coordinates. */ 2577 /* Save current cursor coordinates. */
2575 save_y = curY (tty); 2578 int save_y = curY (tty);
2576 save_x = curX (tty); 2579 int save_x = curX (tty);
2577 cursor_to (f, pos_y, pos_x); 2580 cursor_to (f, pos_y, pos_x);
2578 2581
2579 if (draw == DRAW_MOUSE_FACE) 2582 if (draw == DRAW_MOUSE_FACE)
2580 tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos, 2583 {
2581 nglyphs, face_id); 2584 struct glyph *glyph = row->glyphs[TEXT_AREA] + start_hpos;
2585 struct face *face = FACE_FROM_ID (f, face_id);
2586 tty_write_glyphs_with_face (f, glyph, nglyphs, face);
2587 }
2582 else if (draw == DRAW_NORMAL_TEXT) 2588 else if (draw == DRAW_NORMAL_TEXT)
2583 write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs); 2589 write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
2584 2590
@@ -3115,9 +3121,7 @@ save_and_enable_current_matrix (struct frame *f)
3115static void 3121static void
3116restore_desired_matrix (struct frame *f, struct glyph_matrix *saved) 3122restore_desired_matrix (struct frame *f, struct glyph_matrix *saved)
3117{ 3123{
3118 int i; 3124 for (int i = 0; i < saved->nrows; ++i)
3119
3120 for (i = 0; i < saved->nrows; ++i)
3121 { 3125 {
3122 struct glyph_row *from = saved->rows + i; 3126 struct glyph_row *from = saved->rows + i;
3123 struct glyph_row *to = f->desired_matrix->rows + i; 3127 struct glyph_row *to = f->desired_matrix->rows + i;
@@ -3127,7 +3131,23 @@ restore_desired_matrix (struct frame *f, struct glyph_matrix *saved)
3127 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes); 3131 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
3128 to->used[TEXT_AREA] = from->used[TEXT_AREA]; 3132 to->used[TEXT_AREA] = from->used[TEXT_AREA];
3129 to->enabled_p = from->enabled_p; 3133 to->enabled_p = from->enabled_p;
3130 to->hash = from->hash; 3134
3135 bool need_new_hash = false;
3136 for (int x = 0; x < f->desired_matrix->matrix_w; ++x)
3137 {
3138 struct glyph *glyph = to->glyphs[0] + x;
3139 if (!FRAME_LIVE_P (glyph->frame))
3140 {
3141 glyph->frame = f;
3142 glyph->face_id = DEFAULT_FACE_ID;
3143 need_new_hash = true;
3144 }
3145 }
3146
3147 if (need_new_hash)
3148 to->hash = row_hash (to);
3149 else
3150 to->hash = from->hash;
3131 } 3151 }
3132} 3152}
3133 3153
@@ -3969,7 +3989,7 @@ tty_free_frame_resources (struct frame *f)
3969 3989
3970#endif 3990#endif
3971 3991
3972 3992
3973 3993
3974#ifndef HAVE_ANDROID 3994#ifndef HAVE_ANDROID
3975 3995
@@ -4044,6 +4064,8 @@ set_tty_hooks (struct terminal *terminal)
4044 terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */ 4064 terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */
4045 terminal->delete_frame_hook = &tty_free_frame_resources; 4065 terminal->delete_frame_hook = &tty_free_frame_resources;
4046 terminal->delete_terminal_hook = &delete_tty; 4066 terminal->delete_terminal_hook = &delete_tty;
4067
4068 terminal->frame_raise_lower_hook = tty_raise_lower_frame;
4047 /* Other hooks are NULL by default. */ 4069 /* Other hooks are NULL by default. */
4048} 4070}
4049 4071
@@ -4714,6 +4736,186 @@ delete_tty (struct terminal *terminal)
4714 4736
4715#endif 4737#endif
4716 4738
4739/* Return geometric attributes of FRAME. According to the value of
4740 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the
4741 native edges of FRAME (Qnative_edges), or the inner edges of frame
4742 (Qinner_edges). Any other value means to return the geometry as
4743 returned by Fx_frame_geometry. */
4744
4745static Lisp_Object
4746tty_frame_geometry (Lisp_Object frame, Lisp_Object attribute)
4747{
4748 struct frame *f = decode_live_frame (frame);
4749 if (FRAME_INITIAL_P (f) || !FRAME_TTY (f))
4750 return Qnil;
4751
4752 int native_width = f->pixel_width;
4753 int native_height = f->pixel_height;
4754
4755 eassert (FRAME_PARENT_FRAME (f) || (f->left_pos == 0 && f->top_pos == 0));
4756 int outer_left = f->left_pos;
4757 int outer_top = f->top_pos;
4758 int outer_right = outer_left + native_width;
4759 int outer_bottom = outer_top + native_height;
4760
4761 int native_left = outer_left;
4762 int native_top = outer_top;
4763 int native_right = outer_right;
4764 int native_bottom = outer_bottom;
4765
4766 int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
4767 int inner_left = native_left + internal_border_width;
4768 int inner_top = native_top + internal_border_width;
4769 int inner_right = native_right - internal_border_width;
4770 int inner_bottom = native_bottom - internal_border_width;
4771
4772 int menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
4773 inner_top += menu_bar_height;
4774 int menu_bar_width = menu_bar_height ? native_width : 0;
4775
4776 int tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
4777 int tab_bar_width = (tab_bar_height
4778 ? native_width - 2 * internal_border_width
4779 : 0);
4780 inner_top += tab_bar_height;
4781
4782 int tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
4783 int tool_bar_width = (tool_bar_height
4784 ? native_width - 2 * internal_border_width
4785 : 0);
4786
4787 /* Subtract or add to the inner dimensions based on the tool bar
4788 position. */
4789 if (EQ (FRAME_TOOL_BAR_POSITION (f), Qtop))
4790 inner_top += tool_bar_height;
4791 else
4792 inner_bottom -= tool_bar_height;
4793
4794 /* Construct list. */
4795 if (EQ (attribute, Qouter_edges))
4796 return list4i (outer_left, outer_top, outer_right, outer_bottom);
4797 else if (EQ (attribute, Qnative_edges))
4798 return list4i (native_left, native_top, native_right, native_bottom);
4799 else if (EQ (attribute, Qinner_edges))
4800 return list4i (inner_left, inner_top, inner_right, inner_bottom);
4801 else
4802 return list (Fcons (Qouter_position, Fcons (make_fixnum (outer_left),
4803 make_fixnum (outer_top))),
4804 Fcons (Qouter_size,
4805 Fcons (make_fixnum (outer_right - outer_left),
4806 make_fixnum (outer_bottom - outer_top))),
4807 Fcons (Qouter_border_width, make_fixnum (0)),
4808 Fcons (Qexternal_border_size,
4809 Fcons (make_fixnum (0), make_fixnum (0))),
4810 Fcons (Qtitle_bar_size,
4811 Fcons (make_fixnum (0), make_fixnum (0))),
4812 Fcons (Qmenu_bar_external, Qnil),
4813 Fcons (Qmenu_bar_size,
4814 Fcons (make_fixnum (menu_bar_width),
4815 make_fixnum (menu_bar_height))),
4816 Fcons (Qtab_bar_size,
4817 Fcons (make_fixnum (tab_bar_width),
4818 make_fixnum (tab_bar_height))),
4819 Fcons (Qtool_bar_external, Qnil),
4820 Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
4821 Fcons (Qtool_bar_size,
4822 Fcons (make_fixnum (tool_bar_width),
4823 make_fixnum (tool_bar_height))),
4824 Fcons (Qinternal_border_width,
4825 make_fixnum (internal_border_width)));
4826}
4827
4828DEFUN ("tty-frame-geometry", Ftty_frame_geometry, Stty_frame_geometry, 0, 1, 0,
4829 doc: /* Return geometric attributes of terminal frame FRAME.
4830 See also `frame-geometry'. */)
4831 (Lisp_Object frame)
4832{
4833 return tty_frame_geometry (frame, Qnil);
4834}
4835
4836DEFUN ("tty-frame-edges", Ftty_frame_edges, Stty_frame_edges, 0, 2, 0,
4837 doc: /* Return coordinates of FRAME's edges.
4838 See also `frame-edges'. */)
4839 (Lisp_Object frame, Lisp_Object type)
4840{
4841 if (!EQ (type, Qouter_edges) && !EQ (type, Qinner_edges))
4842 type = Qnative_edges;
4843 return tty_frame_geometry (frame, type);
4844}
4845
4846DEFUN ("tty-frame-list-z-order", Ftty_frame_list_z_order,
4847 Stty_frame_list_z_order, 0, 1, 0,
4848 doc: /* Return list of Emacs's frames, in Z (stacking) order.
4849 See also `frame-list-z-order'. */)
4850 (Lisp_Object frame)
4851{
4852 struct frame *f = decode_tty_frame (frame);
4853 Lisp_Object frames = frames_in_reverse_z_order (f, true);
4854 return Fnreverse (frames);
4855}
4856
4857DEFUN ("tty-frame-restack", Ftty_frame_restack,
4858 Stty_frame_restack, 2, 3, 0,
4859 doc: /* Restack FRAME1 below FRAME2 on terminals.
4860. See also `frame-restack'. */)
4861 (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above)
4862{
4863 /* FIXME/tty: tty-frame-restack implementation. */
4864 error ("tty-frame-restack is not implemented");
4865 return Qnil;
4866}
4867
4868static void
4869tty_display_dimension (Lisp_Object frame, int *width, int *height)
4870{
4871 if (!FRAMEP (frame))
4872 frame = Fselected_frame ();
4873 struct frame *f = XFRAME (frame);
4874 switch (f->output_method)
4875 {
4876 case output_initial:
4877 *width = 80;
4878 *height = 25;
4879 break;
4880 case output_termcap:
4881 *width = FrameCols (FRAME_TTY (f));
4882 *height = FrameRows (FRAME_TTY (f));
4883 break;
4884 case output_x_window:
4885 case output_msdos_raw:
4886 case output_w32:
4887 case output_ns:
4888 case output_pgtk:
4889 case output_haiku:
4890 case output_android:
4891 default:
4892 emacs_abort ();
4893 break;
4894 }
4895}
4896
4897DEFUN ("tty-display-pixel-width", Ftty_display_pixel_width,
4898 Stty_display_pixel_width, 0, 1, 0,
4899 doc: /* Return the width of DISPLAY's screen in pixels.
4900. See also `display-pixel-width'. */)
4901 (Lisp_Object display)
4902{
4903 int width, height;
4904 tty_display_dimension (display, &width, &height);
4905 return make_fixnum (width);
4906}
4907
4908DEFUN ("tty-display-pixel-height", Ftty_display_pixel_height,
4909 Stty_display_pixel_height, 0, 1, 0,
4910 doc: /* Return the height of DISPLAY's screen in pixels.
4911 See also `display-pixel-height'. */)
4912 (Lisp_Object display)
4913{
4914 int width, height;
4915 tty_display_dimension (display, &width, &height);
4916 return make_fixnum (height);
4917}
4918
4717void 4919void
4718syms_of_term (void) 4920syms_of_term (void)
4719{ 4921{
@@ -4770,6 +4972,13 @@ trigger redisplay. */);
4770 defsubr (&Sgpm_mouse_stop); 4972 defsubr (&Sgpm_mouse_stop);
4771#endif /* HAVE_GPM */ 4973#endif /* HAVE_GPM */
4772 4974
4975 defsubr (&Stty_frame_geometry);
4976 defsubr (&Stty_frame_edges);
4977 defsubr (&Stty_frame_list_z_order);
4978 defsubr (&Stty_frame_restack);
4979 defsubr (&Stty_display_pixel_width);
4980 defsubr (&Stty_display_pixel_height);
4981
4773#if !defined DOS_NT && !defined HAVE_ANDROID 4982#if !defined DOS_NT && !defined HAVE_ANDROID
4774 default_orig_pair = NULL; 4983 default_orig_pair = NULL;
4775 default_set_foreground = NULL; 4984 default_set_foreground = NULL;
diff --git a/src/termhooks.h b/src/termhooks.h
index d6a9300bac9..1c2cd46e44e 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -974,6 +974,9 @@ extern int cursorY (struct tty_display_info *);
974#define cursorY(t) curY(t) 974#define cursorY(t) curY(t)
975#endif 975#endif
976 976
977void tty_hide_cursor (struct tty_display_info *tty);
978void tty_show_cursor (struct tty_display_info *tty);
979
977INLINE_HEADER_END 980INLINE_HEADER_END
978 981
979#endif /* EMACS_TERMHOOKS_H */ 982#endif /* EMACS_TERMHOOKS_H */
diff --git a/src/terminal.c b/src/terminal.c
index 5c21341d905..ad488ea3b52 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -111,7 +111,8 @@ void
111cursor_to (struct frame *f, int vpos, int hpos) 111cursor_to (struct frame *f, int vpos, int hpos)
112{ 112{
113 if (FRAME_TERMINAL (f)->cursor_to_hook) 113 if (FRAME_TERMINAL (f)->cursor_to_hook)
114 (*FRAME_TERMINAL (f)->cursor_to_hook) (f, vpos, hpos); 114 (*FRAME_TERMINAL (f)->cursor_to_hook) (f, vpos + f->top_pos,
115 hpos + f->left_pos);
115} 116}
116 117
117/* Similar but don't take any account of the wasted characters. */ 118/* Similar but don't take any account of the wasted characters. */
@@ -120,7 +121,8 @@ void
120raw_cursor_to (struct frame *f, int row, int col) 121raw_cursor_to (struct frame *f, int row, int col)
121{ 122{
122 if (FRAME_TERMINAL (f)->raw_cursor_to_hook) 123 if (FRAME_TERMINAL (f)->raw_cursor_to_hook)
123 (*FRAME_TERMINAL (f)->raw_cursor_to_hook) (f, row, col); 124 (*FRAME_TERMINAL (f)->raw_cursor_to_hook) (f, row + f->top_pos,
125 col + f->left_pos);
124} 126}
125 127
126/* Erase operations. */ 128/* Erase operations. */
diff --git a/src/treesit.c b/src/treesit.c
index 28c94f307c0..b40df71a94c 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -651,7 +651,7 @@ treesit_load_language (Lisp_Object language_symbol,
651 651
652 /* Override the library name and C name, if appropriate. */ 652 /* Override the library name and C name, if appropriate. */
653 Lisp_Object override_name; 653 Lisp_Object override_name;
654 Lisp_Object override_c_name; 654 Lisp_Object override_c_name UNINIT;
655 bool found_override = treesit_find_override_name (language_symbol, 655 bool found_override = treesit_find_override_name (language_symbol,
656 &override_name, 656 &override_name,
657 &override_c_name); 657 &override_c_name);
diff --git a/src/w32console.c b/src/w32console.c
index 7dcbc795cac..cd01fb9de38 100644
--- a/src/w32console.c
+++ b/src/w32console.c
@@ -167,6 +167,7 @@ w32con_clear_end_of_line (struct frame *f, int end)
167 for (i = 0; i < glyphs_len; i++) 167 for (i = 0; i < glyphs_len; i++)
168 { 168 {
169 memcpy (&glyphs[i], &space_glyph, sizeof (struct glyph)); 169 memcpy (&glyphs[i], &space_glyph, sizeof (struct glyph));
170 glyphs[i].frame = f;
170 } 171 }
171 ceol_initialized = TRUE; 172 ceol_initialized = TRUE;
172 } 173 }
@@ -327,14 +328,19 @@ w32con_write_glyphs (struct frame *f, register struct glyph *string,
327 { 328 {
328 /* Identify a run of glyphs with the same face. */ 329 /* Identify a run of glyphs with the same face. */
329 int face_id = string->face_id; 330 int face_id = string->face_id;
331 /* Since this is called to deliver the frame glyph matrix to the
332 glass, some of the glyphs might be from a child frame, which
333 affects the interpretation of face ID. */
334 struct frame *face_id_frame = string->frame;
330 int n; 335 int n;
331 336
332 for (n = 1; n < len; ++n) 337 for (n = 1; n < len; ++n)
333 if (string[n].face_id != face_id) 338 if (!(string[n].face_id == face_id
339 && string[n].frame == face_id_frame))
334 break; 340 break;
335 341
336 /* Turn appearance modes of the face of the run on. */ 342 /* Turn appearance modes of the face of the run on. */
337 char_attr = w32_face_attributes (f, face_id); 343 char_attr = w32_face_attributes (face_id_frame, face_id);
338 344
339 if (n == len) 345 if (n == len)
340 /* This is the last run. */ 346 /* This is the last run. */
@@ -530,6 +536,11 @@ static void
530w32con_update_end (struct frame * f) 536w32con_update_end (struct frame * f)
531{ 537{
532 SetConsoleCursorPosition (cur_screen, cursor_coords); 538 SetConsoleCursorPosition (cur_screen, cursor_coords);
539 if (!XWINDOW (selected_window)->cursor_off_p
540 && cursor_coords.X < FRAME_COLS (f))
541 w32con_show_cursor ();
542 else
543 w32con_hide_cursor ();
533} 544}
534 545
535/*********************************************************************** 546/***********************************************************************
diff --git a/src/w32inevt.c b/src/w32inevt.c
index 35d3420e39f..63d322087bc 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -471,8 +471,13 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
471 DWORD but_change, mask, flags = event->dwEventFlags; 471 DWORD but_change, mask, flags = event->dwEventFlags;
472 int i; 472 int i;
473 473
474 /* Mouse didn't move unless MOUSE_MOVED says it did. */
475 struct frame *f = get_frame (); 474 struct frame *f = get_frame ();
475
476 /* For now, mouse events on child frames are ignored, because the
477 coordinate conversion is not in place; FIXME. */
478 if (FRAMEP (f->parent_frame))
479 return 0;
480 /* Mouse didn't move unless MOUSE_MOVED says it did. */
476 f->mouse_moved = 0; 481 f->mouse_moved = 0;
477 482
478 switch (flags) 483 switch (flags)
@@ -619,6 +624,10 @@ maybe_generate_resize_event (void)
619 CONSOLE_SCREEN_BUFFER_INFO info; 624 CONSOLE_SCREEN_BUFFER_INFO info;
620 struct frame *f = get_frame (); 625 struct frame *f = get_frame ();
621 626
627 /* Only resize the root frame. */
628 if (FRAMEP (f->parent_frame))
629 return;
630
622 GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info); 631 GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info);
623 632
624 /* It is okay to call this unconditionally, since it will do nothing 633 /* It is okay to call this unconditionally, since it will do nothing
diff --git a/src/w32term.c b/src/w32term.c
index e18f39dd2a8..aceb721f92b 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -6405,14 +6405,13 @@ w32_read_socket (struct terminal *terminal,
6405 if (FRAME_TOOLTIP_P (f)) 6405 if (FRAME_TOOLTIP_P (f))
6406 continue; 6406 continue;
6407 6407
6408 /* Check "visible" frames and mark each as obscured or not. 6408 /* Check "visible" frames and mark each as visible or not.
6409 Note that visible is nonzero for unobscured and obscured 6409 Note that visible is nonzero for unobscured and obscured
6410 frames, but zero for hidden and iconified frames. */ 6410 frames, but zero for hidden and iconified frames. */
6411 if (FRAME_W32_P (f) && FRAME_VISIBLE_P (f)) 6411 if (FRAME_W32_P (f) && FRAME_VISIBLE_P (f))
6412 { 6412 {
6413 RECT clipbox; 6413 RECT clipbox;
6414 HDC hdc; 6414 HDC hdc;
6415 bool obscured;
6416 6415
6417 enter_crit (); 6416 enter_crit ();
6418 /* Query clipping rectangle for the entire window area 6417 /* Query clipping rectangle for the entire window area
@@ -6426,29 +6425,11 @@ w32_read_socket (struct terminal *terminal,
6426 ReleaseDC (FRAME_W32_WINDOW (f), hdc); 6425 ReleaseDC (FRAME_W32_WINDOW (f), hdc);
6427 leave_crit (); 6426 leave_crit ();
6428 6427
6429 obscured = FRAME_OBSCURED_P (f); 6428 if (!(clipbox.right == clipbox.left
6430 6429 || clipbox.bottom == clipbox.top))
6431 if (clipbox.right == clipbox.left || clipbox.bottom == clipbox.top)
6432 {
6433 /* Frame has become completely obscured so mark as such (we
6434 do this by setting visible to 2 so that FRAME_VISIBLE_P
6435 is still true, but redisplay will skip it). */
6436 SET_FRAME_VISIBLE (f, 2);
6437
6438 if (!obscured)
6439 DebPrint (("frame %p (%s) obscured\n", f, SDATA (f->name)));
6440 }
6441 else
6442 { 6430 {
6443 /* Frame is not obscured, so mark it as such. */ 6431 /* Frame is not obscured, so mark it as such. */
6444 SET_FRAME_VISIBLE (f, 1); 6432 SET_FRAME_VISIBLE (f, 1);
6445
6446 if (obscured)
6447 {
6448 SET_FRAME_GARBAGED (f);
6449 DebPrint (("obscured frame %p (%s) found to be visible\n",
6450 f, SDATA (f->name)));
6451 }
6452 } 6433 }
6453 } 6434 }
6454 } 6435 }
diff --git a/src/xdisp.c b/src/xdisp.c
index e5fc4a12263..1f6fb438668 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -943,7 +943,7 @@ redisplay_trace (char const *fmt, ...)
943 { 943 {
944 va_list ap; 944 va_list ap;
945 va_start (ap, fmt); 945 va_start (ap, fmt);
946 vprintf (fmt, ap); 946 vfprintf (stderr, fmt, ap);
947 va_end (ap); 947 va_end (ap);
948 } 948 }
949} 949}
@@ -961,7 +961,7 @@ move_trace (char const *fmt, ...)
961 { 961 {
962 va_list ap; 962 va_list ap;
963 va_start (ap, fmt); 963 va_start (ap, fmt);
964 vprintf (fmt, ap); 964 vfprintf (stderr, fmt, ap);
965 va_end (ap); 965 va_end (ap);
966 } 966 }
967} 967}
@@ -3350,9 +3350,7 @@ init_iterator (struct it *it, struct window *w,
3350 of the iterator's frame, when set, suppresses their display - by 3350 of the iterator's frame, when set, suppresses their display - by
3351 default for tooltip frames and when set via the 'no-special-glyphs' 3351 default for tooltip frames and when set via the 'no-special-glyphs'
3352 frame parameter. */ 3352 frame parameter. */
3353#ifdef HAVE_WINDOW_SYSTEM 3353 if (!it->f->no_special_glyphs)
3354 if (!(FRAME_WINDOW_P (it->f) && it->f->no_special_glyphs))
3355#endif
3356 { 3354 {
3357 if (it->line_wrap == TRUNCATE) 3355 if (it->line_wrap == TRUNCATE)
3358 { 3356 {
@@ -13417,18 +13415,22 @@ clear_message (bool current_p, bool last_displayed_p)
13417 message_buf_print = false; 13415 message_buf_print = false;
13418} 13416}
13419 13417
13420/* Clear garbaged frames. 13418/* Clear garbaged frames. Value is true if current matrices have been
13419 cleared on at least one tty frame. This information is needed to
13420 determine if more than one window has to be updated on ttys, whose
13421 update requires building a frame matrix from window matrices.
13421 13422
13422 This function is used where the old redisplay called 13423 This function is used where the old redisplay called
13423 redraw_garbaged_frames which in turn called redraw_frame which in 13424 redraw_garbaged_frames which in turn called redraw_frame which in
13424 turn called clear_frame. The call to clear_frame was a source of 13425 turn called clear_frame. The call to clear_frame was a source of
13425 flickering. I believe a clear_frame is not necessary. It should 13426 flickering. I believe a clear_frame is not necessary. It should
13426 suffice in the new redisplay to invalidate all current matrices, 13427 suffice in the new redisplay to invalidate all current matrices,
13427 and ensure a complete redisplay of all windows. */ 13428 and ensure a complete redisplay of all windows. */
13428 13429
13429static void 13430static bool
13430clear_garbaged_frames (void) 13431clear_garbaged_frames (void)
13431{ 13432{
13433 bool current_matrices_cleared = false;
13432 if (frame_garbaged) 13434 if (frame_garbaged)
13433 { 13435 {
13434 Lisp_Object tail, frame; 13436 Lisp_Object tail, frame;
@@ -13450,6 +13452,8 @@ clear_garbaged_frames (void)
13450 redraw_frame (f); 13452 redraw_frame (f);
13451 else 13453 else
13452 clear_current_matrices (f); 13454 clear_current_matrices (f);
13455 if (is_tty_frame (f))
13456 current_matrices_cleared = true;
13453 13457
13454#ifdef HAVE_WINDOW_SYSTEM 13458#ifdef HAVE_WINDOW_SYSTEM
13455 if (FRAME_WINDOW_P (f) 13459 if (FRAME_WINDOW_P (f)
@@ -13464,6 +13468,8 @@ clear_garbaged_frames (void)
13464 13468
13465 frame_garbaged = false; 13469 frame_garbaged = false;
13466 } 13470 }
13471
13472 return current_matrices_cleared;
13467} 13473}
13468 13474
13469 13475
@@ -13556,7 +13562,11 @@ echo_area_display (bool update_frame_p)
13556 flush_frame (f); 13562 flush_frame (f);
13557 } 13563 }
13558 else 13564 else
13559 update_frame (f, true, true); 13565 {
13566 update_frame (f, true, true);
13567 if (is_tty_frame (f))
13568 combine_updates_for_frame (f, true, true);
13569 }
13560 13570
13561 /* If cursor is in the echo area, make sure that the next 13571 /* If cursor is in the echo area, make sure that the next
13562 redisplay displays the minibuffer, so that the cursor will 13572 redisplay displays the minibuffer, so that the cursor will
@@ -17035,16 +17045,22 @@ redisplay_internal (void)
17035 if (face_change) 17045 if (face_change)
17036 windows_or_buffers_changed = 47; 17046 windows_or_buffers_changed = 47;
17037 17047
17048 struct frame *previous_frame;
17038 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf)) 17049 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
17039 && FRAME_TTY (sf)->previous_frame != sf) 17050 && (previous_frame = FRAME_TTY (sf)->previous_frame,
17051 previous_frame != sf))
17040 { 17052 {
17041 /* Since frames on a single ASCII terminal share the same 17053 if (previous_frame == NULL
17042 display area, displaying a different frame means redisplay 17054 || root_frame (previous_frame) != root_frame (sf))
17043 the whole thing. */ 17055 {
17044 SET_FRAME_GARBAGED (sf); 17056 /* Since frames on a single terminal share the same display
17057 area, displaying a different frame means redisplay the
17058 whole thing. */
17059 SET_FRAME_GARBAGED (sf);
17045#if !defined DOS_NT && !defined HAVE_ANDROID 17060#if !defined DOS_NT && !defined HAVE_ANDROID
17046 set_tty_color_mode (FRAME_TTY (sf), sf); 17061 set_tty_color_mode (FRAME_TTY (sf), sf);
17047#endif 17062#endif
17063 }
17048 FRAME_TTY (sf)->previous_frame = sf; 17064 FRAME_TTY (sf)->previous_frame = sf;
17049 } 17065 }
17050 17066
@@ -17057,6 +17073,7 @@ redisplay_internal (void)
17057 { 17073 {
17058 struct frame *f = XFRAME (frame); 17074 struct frame *f = XFRAME (frame);
17059 17075
17076 /* FRAME_REDISPLAY_P true basically means the frame is visible. */
17060 if (FRAME_REDISPLAY_P (f)) 17077 if (FRAME_REDISPLAY_P (f))
17061 { 17078 {
17062 ++number_of_visible_frames; 17079 ++number_of_visible_frames;
@@ -17085,7 +17102,7 @@ redisplay_internal (void)
17085 do_pending_window_change (true); 17102 do_pending_window_change (true);
17086 17103
17087 /* Clear frames marked as garbaged. */ 17104 /* Clear frames marked as garbaged. */
17088 clear_garbaged_frames (); 17105 bool current_matrices_cleared = clear_garbaged_frames ();
17089 17106
17090 /* Build menubar and tool-bar items. */ 17107 /* Build menubar and tool-bar items. */
17091 if (NILP (Vmemory_full)) 17108 if (NILP (Vmemory_full))
@@ -17176,7 +17193,8 @@ redisplay_internal (void)
17176 overlay_arrows_changed_p (true); 17193 overlay_arrows_changed_p (true);
17177 17194
17178 consider_all_windows_p = (update_mode_lines 17195 consider_all_windows_p = (update_mode_lines
17179 || windows_or_buffers_changed); 17196 || windows_or_buffers_changed
17197 || current_matrices_cleared);
17180 17198
17181#define AINC(a,i) \ 17199#define AINC(a,i) \
17182 { \ 17200 { \
@@ -17200,7 +17218,6 @@ redisplay_internal (void)
17200 && !current_buffer->clip_changed 17218 && !current_buffer->clip_changed
17201 && !current_buffer->prevent_redisplay_optimizations_p 17219 && !current_buffer->prevent_redisplay_optimizations_p
17202 && FRAME_REDISPLAY_P (XFRAME (w->frame)) 17220 && FRAME_REDISPLAY_P (XFRAME (w->frame))
17203 && !FRAME_OBSCURED_P (XFRAME (w->frame))
17204 && !XFRAME (w->frame)->cursor_type_changed 17221 && !XFRAME (w->frame)->cursor_type_changed
17205 && !XFRAME (w->frame)->face_change 17222 && !XFRAME (w->frame)->face_change
17206 /* Make sure recorded data applies to current buffer, etc. */ 17223 /* Make sure recorded data applies to current buffer, etc. */
@@ -17449,22 +17466,28 @@ redisplay_internal (void)
17449 17466
17450 propagate_buffer_redisplay (); 17467 propagate_buffer_redisplay ();
17451 17468
17469 Lisp_Object tty_root_frames = Qnil;
17452 FOR_EACH_FRAME (tail, frame) 17470 FOR_EACH_FRAME (tail, frame)
17453 { 17471 {
17454 struct frame *f = XFRAME (frame); 17472 struct frame *f = XFRAME (frame);
17455 17473
17456 /* We don't have to do anything for unselected terminal 17474 if (is_tty_frame (f))
17457 frames. */ 17475 {
17458 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)) 17476 /* Ignore all invisble tty frames, children or root. */
17459 && !EQ (FRAME_TTY (f)->top_frame, frame)) 17477 if (!FRAME_VISIBLE_P (root_frame (f)))
17460 continue; 17478 continue;
17479
17480 /* Remember tty root frames which we've seen. */
17481 if (!FRAME_PARENT_FRAME (f)
17482 && NILP (assq_no_quit (frame, tty_root_frames)))
17483 tty_root_frames = Fcons (frame, tty_root_frames);
17484 }
17461 17485
17462 retry_frame: 17486 retry_frame:
17463 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf) 17487 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
17464 { 17488 {
17465 bool gcscrollbars 17489 /* Only GC scrollbars when we redisplay the whole frame. */
17466 /* Only GC scrollbars when we redisplay the whole frame. */ 17490 bool gcscrollbars = f->redisplay || !REDISPLAY_SOME_P ();
17467 = f->redisplay || !REDISPLAY_SOME_P ();
17468 bool f_redisplay_flag = f->redisplay; 17491 bool f_redisplay_flag = f->redisplay;
17469 17492
17470 /* The X error handler may have deleted that frame before 17493 /* The X error handler may have deleted that frame before
@@ -17481,7 +17504,7 @@ redisplay_internal (void)
17481 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook) 17504 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
17482 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f); 17505 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
17483 17506
17484 if (FRAME_REDISPLAY_P (f) && !FRAME_OBSCURED_P (f)) 17507 if (FRAME_REDISPLAY_P (f))
17485 { 17508 {
17486 /* Don't allow freeing images and faces for this 17509 /* Don't allow freeing images and faces for this
17487 frame as long as the frame's update wasn't 17510 frame as long as the frame's update wasn't
@@ -17507,7 +17530,7 @@ redisplay_internal (void)
17507 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook) 17530 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
17508 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f); 17531 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
17509 17532
17510 if (FRAME_REDISPLAY_P (f) && !FRAME_OBSCURED_P (f)) 17533 if (FRAME_REDISPLAY_P (f))
17511 { 17534 {
17512 /* If fonts changed on visible frame, display again. */ 17535 /* If fonts changed on visible frame, display again. */
17513 if (f->fonts_changed) 17536 if (f->fonts_changed)
@@ -17592,6 +17615,9 @@ redisplay_internal (void)
17592 } 17615 }
17593 } 17616 }
17594 17617
17618 if (CONSP (tty_root_frames))
17619 pending |= combine_updates (tty_root_frames, false, false);
17620
17595 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window)); 17621 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
17596 17622
17597 if (!pending) 17623 if (!pending)
@@ -17613,7 +17639,7 @@ redisplay_internal (void)
17613 } 17639 }
17614 } 17640 }
17615 } 17641 }
17616 else if (FRAME_REDISPLAY_P (sf) && !FRAME_OBSCURED_P (sf)) 17642 else if (FRAME_REDISPLAY_P (sf))
17617 { 17643 {
17618 sf->inhibit_clear_image_cache = true; 17644 sf->inhibit_clear_image_cache = true;
17619 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents); 17645 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
@@ -17664,7 +17690,7 @@ redisplay_internal (void)
17664 unrequest_sigio (); 17690 unrequest_sigio ();
17665 STOP_POLLING; 17691 STOP_POLLING;
17666 17692
17667 if (FRAME_REDISPLAY_P (sf) && !FRAME_OBSCURED_P (sf)) 17693 if (FRAME_REDISPLAY_P (sf))
17668 { 17694 {
17669 if (hscroll_retries <= MAX_HSCROLL_RETRIES 17695 if (hscroll_retries <= MAX_HSCROLL_RETRIES
17670 && hscroll_windows (selected_window)) 17696 && hscroll_windows (selected_window))
@@ -17675,6 +17701,10 @@ redisplay_internal (void)
17675 17701
17676 XWINDOW (selected_window)->must_be_updated_p = true; 17702 XWINDOW (selected_window)->must_be_updated_p = true;
17677 pending = update_frame (sf, false, false); 17703 pending = update_frame (sf, false, false);
17704
17705 if (is_tty_frame (sf))
17706 pending |= combine_updates_for_frame (sf, false, false);
17707
17678 sf->cursor_type_changed = false; 17708 sf->cursor_type_changed = false;
17679 sf->inhibit_clear_image_cache = false; 17709 sf->inhibit_clear_image_cache = false;
17680 } 17710 }
@@ -17687,10 +17717,12 @@ redisplay_internal (void)
17687 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf); 17717 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
17688 struct frame *mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window))); 17718 struct frame *mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
17689 17719
17690 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame)) 17720 if (mini_frame != sf)
17691 { 17721 {
17692 XWINDOW (mini_window)->must_be_updated_p = true; 17722 XWINDOW (mini_window)->must_be_updated_p = true;
17693 pending |= update_frame (mini_frame, false, false); 17723 pending |= update_frame (mini_frame, false, false);
17724 if (is_tty_frame (mini_frame))
17725 pending |= combine_updates_for_frame (mini_frame, false, false);
17694 mini_frame->cursor_type_changed = false; 17726 mini_frame->cursor_type_changed = false;
17695 if (!pending && hscroll_retries <= MAX_HSCROLL_RETRIES 17727 if (!pending && hscroll_retries <= MAX_HSCROLL_RETRIES
17696 && hscroll_windows (mini_window)) 17728 && hscroll_windows (mini_window))
@@ -23977,6 +24009,7 @@ extend_face_to_end_of_line (struct it *it)
23977 { 24009 {
23978 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph; 24010 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
23979 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id; 24011 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
24012 it->glyph_row->glyphs[TEXT_AREA][0].frame = f;
23980 it->glyph_row->used[TEXT_AREA] = 1; 24013 it->glyph_row->used[TEXT_AREA] = 1;
23981 } 24014 }
23982 /* Mode line and the header line don't have margins, and 24015 /* Mode line and the header line don't have margins, and
@@ -23996,6 +24029,7 @@ extend_face_to_end_of_line (struct it *it)
23996 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph; 24029 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
23997 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id = 24030 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
23998 default_face->id; 24031 default_face->id;
24032 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].frame = f;
23999 it->glyph_row->used[LEFT_MARGIN_AREA] = 1; 24033 it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
24000 } 24034 }
24001 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0 24035 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
@@ -24004,6 +24038,7 @@ extend_face_to_end_of_line (struct it *it)
24004 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph; 24038 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
24005 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id = 24039 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
24006 default_face->id; 24040 default_face->id;
24041 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].frame = f;
24007 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1; 24042 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
24008 } 24043 }
24009 24044
@@ -24368,9 +24403,11 @@ highlight_trailing_whitespace (struct it *it)
24368 while (glyph >= start 24403 while (glyph >= start
24369 && BUFFERP (glyph->object) 24404 && BUFFERP (glyph->object)
24370 && (glyph->type == STRETCH_GLYPH 24405 && (glyph->type == STRETCH_GLYPH
24371 || (glyph->type == CHAR_GLYPH 24406 || (glyph->type == CHAR_GLYPH && glyph->u.ch == ' ')))
24372 && glyph->u.ch == ' '))) 24407 {
24373 (glyph--)->face_id = face_id; 24408 glyph->frame = it->f;
24409 (glyph--)->face_id = face_id;
24410 }
24374 } 24411 }
24375 else 24412 else
24376 { 24413 {
@@ -24379,7 +24416,10 @@ highlight_trailing_whitespace (struct it *it)
24379 && (glyph->type == STRETCH_GLYPH 24416 && (glyph->type == STRETCH_GLYPH
24380 || (glyph->type == CHAR_GLYPH 24417 || (glyph->type == CHAR_GLYPH
24381 && glyph->u.ch == ' '))) 24418 && glyph->u.ch == ' ')))
24382 (glyph++)->face_id = face_id; 24419 {
24420 glyph->frame = it->f;
24421 (glyph++)->face_id = face_id;
24422 }
24383 } 24423 }
24384 } 24424 }
24385 } 24425 }
@@ -27232,7 +27272,7 @@ display_menu_bar (struct window *w)
27232 27272
27233/* Deep copy of a glyph row, including the glyphs. */ 27273/* Deep copy of a glyph row, including the glyphs. */
27234static void 27274static void
27235deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from) 27275deep_copy_glyph_row (struct frame *f, struct glyph_row *to, struct glyph_row *from)
27236{ 27276{
27237 struct glyph *pointers[1 + LAST_AREA]; 27277 struct glyph *pointers[1 + LAST_AREA];
27238 int to_used = to->used[TEXT_AREA]; 27278 int to_used = to->used[TEXT_AREA];
@@ -27253,7 +27293,7 @@ deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
27253 /* If we filled only part of the TO row, fill the rest with 27293 /* If we filled only part of the TO row, fill the rest with
27254 space_glyph (which will display as empty space). */ 27294 space_glyph (which will display as empty space). */
27255 if (to_used > from->used[TEXT_AREA]) 27295 if (to_used > from->used[TEXT_AREA])
27256 fill_up_frame_row_with_spaces (to, to_used); 27296 fill_up_frame_row_with_spaces (f, to, to_used);
27257} 27297}
27258 27298
27259/* Produce glyphs for a menu separator on a tty. 27299/* Produce glyphs for a menu separator on a tty.
@@ -27331,7 +27371,7 @@ display_tty_menu_item (const char *item_text, int width, int face_id,
27331 it.last_visible_x = FRAME_COLS (f) - 1; 27371 it.last_visible_x = FRAME_COLS (f) - 1;
27332 row = it.glyph_row; 27372 row = it.glyph_row;
27333 /* Start with the row contents from the current matrix. */ 27373 /* Start with the row contents from the current matrix. */
27334 deep_copy_glyph_row (row, f->current_matrix->rows + y); 27374 deep_copy_glyph_row (f, row, f->current_matrix->rows + y);
27335 bool saved_width = row->full_width_p; 27375 bool saved_width = row->full_width_p;
27336 row->full_width_p = true; 27376 row->full_width_p = true;
27337 bool saved_reversed = row->reversed_p; 27377 bool saved_reversed = row->reversed_p;
diff --git a/src/xfaces.c b/src/xfaces.c
index f6264802fa4..5f60f387165 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -696,7 +696,6 @@ void
696free_frame_faces (struct frame *f) 696free_frame_faces (struct frame *f)
697{ 697{
698 struct face_cache *face_cache = FRAME_FACE_CACHE (f); 698 struct face_cache *face_cache = FRAME_FACE_CACHE (f);
699
700 if (face_cache) 699 if (face_cache)
701 { 700 {
702 free_face_cache (face_cache); 701 free_face_cache (face_cache);