aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGerd Möllmann2024-10-05 18:55:18 +0200
committerGerd Möllmann2024-10-05 18:55:18 +0200
commitbeb5b77123619758c1def6b9f227fa7568516775 (patch)
tree809e025df6a48b10f3022558f23840a8def6cbec /src
parent069ecc9c4c3709246a6ff50d09af418444d427c3 (diff)
downloademacs-tty-child-frames.tar.gz
emacs-tty-child-frames.zip
Preview from my branch on githubtty-child-frames
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c12
-rw-r--r--src/dispextern.h45
-rw-r--r--src/dispnew.c979
-rw-r--r--src/frame.c407
-rw-r--r--src/frame.h65
-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.c253
-rw-r--r--src/terminal.c6
-rw-r--r--src/xdisp.c76
-rw-r--r--src/xfaces.c1
14 files changed, 1321 insertions, 543 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 4fab0d54248..ac5cf06805b 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -6853,9 +6853,15 @@ 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 0 /* FIXME/tty: Probably not needed */
6858 mark_object (glyph->object); 6858 if (glyph->frame)
6859 mark_object (glyph->frame);
6860#endif
6861 if (STRINGP (glyph->object)
6862 && !string_marked_p (XSTRING (glyph->object)))
6863 mark_object (glyph->object);
6864 }
6859 } 6865 }
6860 } 6866 }
6861} 6867}
diff --git a/src/dispextern.h b/src/dispextern.h
index cc248a4472e..59785b2d03d 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 frames
487 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
@@ -3805,7 +3813,7 @@ extern void adjust_frame_glyphs (struct frame *);
3805void free_glyphs (struct frame *); 3813void free_glyphs (struct frame *);
3806void free_window_matrices (struct window *); 3814void free_window_matrices (struct window *);
3807void check_glyph_memory (void); 3815void check_glyph_memory (void);
3808void mirrored_line_dance (struct glyph_matrix *, int, int, int *, char *); 3816void mirrored_line_dance (struct frame *f, int, int, int *, char *);
3809void clear_glyph_matrix (struct glyph_matrix *); 3817void clear_glyph_matrix (struct glyph_matrix *);
3810void clear_current_matrices (struct frame *f); 3818void clear_current_matrices (struct frame *f);
3811void clear_desired_matrices (struct frame *); 3819void clear_desired_matrices (struct frame *);
@@ -3829,7 +3837,7 @@ extern bool frame_size_change_delayed (struct frame *);
3829void init_display (void); 3837void init_display (void);
3830void syms_of_display (void); 3838void syms_of_display (void);
3831extern void spec_glyph_lookup_face (struct window *, GLYPH *); 3839extern void spec_glyph_lookup_face (struct window *, GLYPH *);
3832extern void fill_up_frame_row_with_spaces (struct glyph_row *, int); 3840extern void fill_up_frame_row_with_spaces (struct frame *, struct glyph_row *, int);
3833 3841
3834/* Defined in terminal.c. */ 3842/* Defined in terminal.c. */
3835 3843
@@ -3911,6 +3919,21 @@ extern void gui_redo_mouse_highlight (Display_Info *);
3911 3919
3912#endif /* HAVE_WINDOW_SYSTEM */ 3920#endif /* HAVE_WINDOW_SYSTEM */
3913 3921
3922struct frame *root_frame (struct frame *f);
3923Lisp_Object frames_in_reverse_z_order (struct frame *f, bool visible);
3924bool is_tty_frame (struct frame *f);
3925bool is_tty_child_frame (struct frame *f);
3926bool is_tty_root_frame (struct frame *f);
3927Lisp_Object frames_with_root (struct frame *root, bool visible);
3928bool combine_updates (Lisp_Object root_frames, bool force_p, bool inhibit_id_p);
3929bool combine_updates_for_frame (struct frame *f, bool force_p, bool inhibit_id_p);
3930void tty_raise_lower_frame (struct frame *f, bool raise);
3931
3932#ifdef GLYPH_DEBUG
3933bool is_tty_desired_glyph (struct frame *f, struct glyph *g);
3934bool is_tty_current_glyph (struct frame *f, struct glyph *g);
3935#endif
3936
3914INLINE_HEADER_END 3937INLINE_HEADER_END
3915 3938
3916#endif /* not DISPEXTERN_H_INCLUDED */ 3939#endif /* not DISPEXTERN_H_INCLUDED */
diff --git a/src/dispnew.c b/src/dispnew.c
index 1a243079e46..1089ab4c4f8 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -71,7 +71,7 @@ struct dim
71 71
72/* Function prototypes. */ 72/* Function prototypes. */
73 73
74static void update_frame_line (struct frame *, int, bool); 74static void write_row (struct frame *f, int vpos, bool updating_menu_p);
75static int required_matrix_height (struct window *); 75static int required_matrix_height (struct window *);
76static int required_matrix_width (struct window *); 76static int required_matrix_width (struct window *);
77static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t); 77static void increment_row_positions (struct glyph_row *, ptrdiff_t, ptrdiff_t);
@@ -80,9 +80,9 @@ static void build_frame_matrix_from_window_tree (struct glyph_matrix *,
80static void build_frame_matrix_from_leaf_window (struct glyph_matrix *, 80static void build_frame_matrix_from_leaf_window (struct glyph_matrix *,
81 struct window *); 81 struct window *);
82static void adjust_decode_mode_spec_buffer (struct frame *); 82static void adjust_decode_mode_spec_buffer (struct frame *);
83static void fill_up_glyph_row_with_spaces (struct glyph_row *); 83static void fill_up_glyph_row_with_spaces (struct frame *, struct glyph_row *);
84static void clear_window_matrices (struct window *, bool); 84static void clear_window_matrices (struct window *, bool);
85static void fill_up_glyph_row_area_with_spaces (struct glyph_row *, int); 85static void fill_up_glyph_row_area_with_spaces (struct frame *, struct glyph_row *, int);
86static int scrolling_window (struct window *, int); 86static int scrolling_window (struct window *, int);
87static bool update_window_line (struct window *, int, bool *); 87static bool update_window_line (struct window *, int, bool *);
88static void mirror_make_current (struct window *, int); 88static void mirror_make_current (struct window *, int);
@@ -93,7 +93,7 @@ static void check_matrix_pointers (struct glyph_matrix *,
93static void mirror_line_dance (struct window *, int, int, int *, char *); 93static void mirror_line_dance (struct window *, int, int, int *, char *);
94static bool update_window_tree (struct window *, bool); 94static bool update_window_tree (struct window *, bool);
95static bool update_window (struct window *, bool); 95static bool update_window (struct window *, bool);
96static bool update_frame_1 (struct frame *, bool, bool, bool, bool); 96static bool write_matrix (struct frame *, bool, bool, bool, bool);
97static bool scrolling (struct frame *); 97static bool scrolling (struct frame *);
98static void set_window_cursor_after_update (struct window *); 98static void set_window_cursor_after_update (struct window *);
99static void adjust_frame_glyphs_for_window_redisplay (struct frame *); 99static void adjust_frame_glyphs_for_window_redisplay (struct frame *);
@@ -122,11 +122,6 @@ static int glyph_pool_count;
122 122
123#endif /* GLYPH_DEBUG and ENABLE_CHECKING */ 123#endif /* GLYPH_DEBUG and ENABLE_CHECKING */
124 124
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. 125/* Convert vpos and hpos from frame to window and vice versa.
131 This may only be used for terminal frames. */ 126 This may only be used for terminal frames. */
132 127
@@ -1178,7 +1173,12 @@ line_hash_code (struct frame *f, struct glyph_row *row)
1178 while (glyph < end) 1173 while (glyph < end)
1179 { 1174 {
1180 int c = glyph->u.ch; 1175 int c = glyph->u.ch;
1176 /* FIXME/tty: struct frame can move with igc, and so on.
1177 But we need something that takes different frames
1178 into account. */
1181 int face_id = glyph->face_id; 1179 int face_id = glyph->face_id;
1180 if (glyph->frame != f)
1181 face_id += (ptrdiff_t) glyph->frame;
1182 if (FRAME_MUST_WRITE_SPACES (f)) 1182 if (FRAME_MUST_WRITE_SPACES (f))
1183 c -= SPACEGLYPH; 1183 c -= SPACEGLYPH;
1184 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c; 1184 hash = (((hash << 4) + (hash >> 24)) & 0x0fffffff) + c;
@@ -1213,7 +1213,7 @@ line_draw_cost (struct frame *f, struct glyph_matrix *matrix, int vpos)
1213 if (!FRAME_MUST_WRITE_SPACES (f)) 1213 if (!FRAME_MUST_WRITE_SPACES (f))
1214 { 1214 {
1215 /* Skip from the end over trailing spaces. */ 1215 /* Skip from the end over trailing spaces. */
1216 while (end > beg && CHAR_GLYPH_SPACE_P (*(end - 1))) 1216 while (end > beg && CHAR_GLYPH_SPACE_P (f, *(end - 1)))
1217 --end; 1217 --end;
1218 1218
1219 /* All blank line. */ 1219 /* All blank line. */
@@ -1221,7 +1221,7 @@ line_draw_cost (struct frame *f, struct glyph_matrix *matrix, int vpos)
1221 return 0; 1221 return 0;
1222 1222
1223 /* Skip over leading spaces. */ 1223 /* Skip over leading spaces. */
1224 while (CHAR_GLYPH_SPACE_P (*beg)) 1224 while (CHAR_GLYPH_SPACE_P (f, *beg))
1225 ++beg; 1225 ++beg;
1226 } 1226 }
1227 1227
@@ -2558,6 +2558,7 @@ build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct w
2558 int window_y, frame_y; 2558 int window_y, frame_y;
2559 /* If non-zero, a glyph to insert at the right border of W. */ 2559 /* If non-zero, a glyph to insert at the right border of W. */
2560 GLYPH right_border_glyph; 2560 GLYPH right_border_glyph;
2561 struct frame *f = XFRAME (w->frame);
2561 2562
2562 SET_GLYPH_FROM_CHAR (right_border_glyph, 0); 2563 SET_GLYPH_FROM_CHAR (right_border_glyph, 0);
2563 2564
@@ -2599,10 +2600,10 @@ build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct w
2599 2600
2600 /* Fill up the frame row with spaces up to the left margin of the 2601 /* Fill up the frame row with spaces up to the left margin of the
2601 window row. */ 2602 window row. */
2602 fill_up_frame_row_with_spaces (frame_row, window_matrix->matrix_x); 2603 fill_up_frame_row_with_spaces (f, frame_row, window_matrix->matrix_x);
2603 2604
2604 /* Fill up areas in the window matrix row with spaces. */ 2605 /* Fill up areas in the window matrix row with spaces. */
2605 fill_up_glyph_row_with_spaces (window_row); 2606 fill_up_glyph_row_with_spaces (f, window_row);
2606 2607
2607 /* If only part of W's desired matrix has been built, and 2608 /* If only part of W's desired matrix has been built, and
2608 window_row wasn't displayed, use the corresponding current 2609 window_row wasn't displayed, use the corresponding current
@@ -2638,7 +2639,7 @@ build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct w
2638 glyph with the vertical border glyph. */ 2639 glyph with the vertical border glyph. */
2639 eassert (border->type == CHAR_GLYPH); 2640 eassert (border->type == CHAR_GLYPH);
2640 border->type = CHAR_GLYPH; 2641 border->type = CHAR_GLYPH;
2641 SET_CHAR_GLYPH_FROM_GLYPH (*border, right_border_glyph); 2642 SET_CHAR_GLYPH_FROM_GLYPH (f, *border, right_border_glyph);
2642 } 2643 }
2643 2644
2644#ifdef GLYPH_DEBUG 2645#ifdef GLYPH_DEBUG
@@ -2701,11 +2702,11 @@ spec_glyph_lookup_face (struct window *w, GLYPH *glyph)
2701 To be called for frame-based redisplay, only. */ 2702 To be called for frame-based redisplay, only. */
2702 2703
2703static void 2704static void
2704fill_up_glyph_row_with_spaces (struct glyph_row *row) 2705fill_up_glyph_row_with_spaces (struct frame *f, struct glyph_row *row)
2705{ 2706{
2706 fill_up_glyph_row_area_with_spaces (row, LEFT_MARGIN_AREA); 2707 fill_up_glyph_row_area_with_spaces (f, row, LEFT_MARGIN_AREA);
2707 fill_up_glyph_row_area_with_spaces (row, TEXT_AREA); 2708 fill_up_glyph_row_area_with_spaces (f, row, TEXT_AREA);
2708 fill_up_glyph_row_area_with_spaces (row, RIGHT_MARGIN_AREA); 2709 fill_up_glyph_row_area_with_spaces (f, row, RIGHT_MARGIN_AREA);
2709} 2710}
2710 2711
2711 2712
@@ -2713,15 +2714,19 @@ fill_up_glyph_row_with_spaces (struct glyph_row *row)
2713 frame-based redisplay only. */ 2714 frame-based redisplay only. */
2714 2715
2715static void 2716static void
2716fill_up_glyph_row_area_with_spaces (struct glyph_row *row, int area) 2717fill_up_glyph_row_area_with_spaces (struct frame *f, struct glyph_row *row,
2718 int area)
2717{ 2719{
2718 if (row->glyphs[area] < row->glyphs[area + 1]) 2720 if (row->glyphs[area] < row->glyphs[area + 1])
2719 { 2721 {
2720 struct glyph *end = row->glyphs[area + 1]; 2722 struct glyph *end = row->glyphs[area + 1];
2721 struct glyph *text = row->glyphs[area] + row->used[area]; 2723 struct glyph *text = row->glyphs[area] + row->used[area];
2722 2724
2723 while (text < end) 2725 for (; text < end; ++text)
2724 *text++ = space_glyph; 2726 {
2727 *text = space_glyph;
2728 text->frame = f;
2729 }
2725 row->used[area] = text - row->glyphs[area]; 2730 row->used[area] = text - row->glyphs[area];
2726 } 2731 }
2727} 2732}
@@ -2731,13 +2736,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. */ 2736 reached. In frame matrices only one area, TEXT_AREA, is used. */
2732 2737
2733void 2738void
2734fill_up_frame_row_with_spaces (struct glyph_row *row, int upto) 2739fill_up_frame_row_with_spaces (struct frame *f, struct glyph_row *row, int upto)
2735{ 2740{
2736 int i = row->used[TEXT_AREA]; 2741 int i = row->used[TEXT_AREA];
2737 struct glyph *glyph = row->glyphs[TEXT_AREA]; 2742 struct glyph *glyph = row->glyphs[TEXT_AREA];
2738 2743
2739 while (i < upto) 2744 for (; i < upto; ++i)
2740 glyph[i++] = space_glyph; 2745 {
2746 glyph[i] = space_glyph;
2747 glyph[i].frame = f;
2748 }
2741 2749
2742 row->used[TEXT_AREA] = i; 2750 row->used[TEXT_AREA] = i;
2743} 2751}
@@ -2748,17 +2756,6 @@ fill_up_frame_row_with_spaces (struct glyph_row *row, int upto)
2748 Mirroring operations on frame matrices in window matrices 2756 Mirroring operations on frame matrices in window matrices
2749 **********************************************************************/ 2757 **********************************************************************/
2750 2758
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. 2759/* Make sure glyph row ROW in CURRENT_MATRIX is up to date.
2763 DESIRED_MATRIX is the desired matrix corresponding to 2760 DESIRED_MATRIX is the desired matrix corresponding to
2764 CURRENT_MATRIX. The update is done by exchanging glyph pointers 2761 CURRENT_MATRIX. The update is done by exchanging glyph pointers
@@ -2768,9 +2765,10 @@ set_frame_matrix_frame (struct frame *f)
2768 operations in window matrices of frame_matrix_frame. */ 2765 operations in window matrices of frame_matrix_frame. */
2769 2766
2770static void 2767static void
2771make_current (struct glyph_matrix *desired_matrix, 2768make_current (struct frame *f, struct window *w, int row)
2772 struct glyph_matrix *current_matrix, int row)
2773{ 2769{
2770 struct glyph_matrix *desired_matrix = f ? f->desired_matrix : w->desired_matrix;
2771 struct glyph_matrix *current_matrix = f ? f->current_matrix : w->current_matrix;
2774 struct glyph_row *current_row = MATRIX_ROW (current_matrix, row); 2772 struct glyph_row *current_row = MATRIX_ROW (current_matrix, row);
2775 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row); 2773 struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row);
2776 bool mouse_face_p = current_row->mouse_face_p; 2774 bool mouse_face_p = current_row->mouse_face_p;
@@ -2797,8 +2795,8 @@ make_current (struct glyph_matrix *desired_matrix,
2797 2795
2798 /* If we are called on frame matrices, perform analogous operations 2796 /* If we are called on frame matrices, perform analogous operations
2799 for window matrices. */ 2797 for window matrices. */
2800 if (frame_matrix_frame) 2798 if (f)
2801 mirror_make_current (XWINDOW (frame_matrix_frame->root_window), row); 2799 mirror_make_current (XWINDOW (f->root_window), row);
2802} 2800}
2803 2801
2804 2802
@@ -2862,9 +2860,11 @@ mirror_make_current (struct window *w, int frame_row)
2862 This function is called from do_scrolling and do_direct_scrolling. */ 2860 This function is called from do_scrolling and do_direct_scrolling. */
2863 2861
2864void 2862void
2865mirrored_line_dance (struct glyph_matrix *matrix, int unchanged_at_top, int nlines, 2863mirrored_line_dance (struct frame *f, int unchanged_at_top, int nlines,
2866 int *copy_from, char *retained_p) 2864 int *copy_from, char *retained_p)
2867{ 2865{
2866 struct glyph_matrix *matrix = f->current_matrix;
2867
2868 /* A copy of original rows. */ 2868 /* A copy of original rows. */
2869 struct glyph_row *old_rows; 2869 struct glyph_row *old_rows;
2870 2870
@@ -2894,9 +2894,8 @@ mirrored_line_dance (struct glyph_matrix *matrix, int unchanged_at_top, int nlin
2894 } 2894 }
2895 2895
2896 /* Do the same for window matrices, if MATRIX is a frame matrix. */ 2896 /* Do the same for window matrices, if MATRIX is a frame matrix. */
2897 if (frame_matrix_frame) 2897 mirror_line_dance (XWINDOW (f->root_window),
2898 mirror_line_dance (XWINDOW (frame_matrix_frame->root_window), 2898 unchanged_at_top, nlines, copy_from, retained_p);
2899 unchanged_at_top, nlines, copy_from, retained_p);
2900 2899
2901 SAFE_FREE (); 2900 SAFE_FREE ();
2902} 2901}
@@ -3194,7 +3193,10 @@ redraw_frame (struct frame *f)
3194 future. */ 3193 future. */
3195 SET_FRAME_GARBAGED (f); 3194 SET_FRAME_GARBAGED (f);
3196 3195
3197 clear_frame (f); 3196 /* FIXME/tty: clear_frame is actually a "clear_terminal", i.e.
3197 is clears the entire screen. */
3198 if (!FRAME_PARENT_FRAME (f))
3199 clear_frame (f);
3198 clear_current_matrices (f); 3200 clear_current_matrices (f);
3199 update_end (f); 3201 update_end (f);
3200 fset_redisplay (f); 3202 fset_redisplay (f);
@@ -3229,145 +3231,501 @@ DEFUN ("redraw-display", Fredraw_display, Sredraw_display, 0, 0, "",
3229 return Qnil; 3231 return Qnil;
3230} 3232}
3231 3233
3232
3233 3234
3234/*********************************************************************** 3235/**********************************************************************
3235 Frame Update 3236 TTY Child Frames
3236 ***********************************************************************/ 3237 **********************************************************************/
3237 3238
3238/* Update frame F based on the data in desired matrices. 3239/* The new thing that child frames on ttys provide is that frames on a
3240 tty no longer always occupy the whole terminal. They can overlap
3241 instead.
3239 3242
3240 If FORCE_P, don't let redisplay be stopped by detecting pending input. 3243 Let a "root" frame be a frame that has no parent frame. Such root
3241 If INHIBIT_HAIRY_ID_P, don't try scrolling. 3244 frames we require to be the size of the terminal screen. The current
3245 glyph matrix of a root frame of a termimnal represents what is on the
3246 screen. The desired matrix of a root frame represents what should be
3247 one the screen.
3242 3248
3243 Value is true if redisplay was stopped due to pending input. */ 3249 Building the desired matrix of root frame proceeds by
3244 3250
3245bool 3251 - building the desired matrix of the root frame itself which is
3246update_frame (struct frame *f, bool force_p, bool inhibit_hairy_id_p) 3252 the bottommost frame in z-order,
3253 - building desired matrices of child frames in z-order, topmost last,
3254 - copying the desired glyphs from child frames to the desired glyphs
3255 of the root frame
3256
3257 Updating the screen is then done using root frame matrices as it was
3258 before child frames were introduced. Child frame current matrices are
3259 updated by copying glyph contents of the current matrix of the root
3260 frames to the current matrices of child frames. This imnplicitly
3261 also updates the glyph contents of their windows' current matrices. */
3262
3263struct rect
3247{ 3264{
3248 /* True means display has been paused because of pending input. */ 3265 int x, y, w, h;
3249 bool paused_p; 3266};
3250 struct window *root_window = XWINDOW (f->root_window);
3251 3267
3252 if (redisplay_dont_pause) 3268#ifdef GLYPH_DEBUG
3253 force_p = true; 3269static bool
3254 else if (!force_p && detect_input_pending_ignore_squeezables ()) 3270is_glyph_in_matrix (struct glyph_matrix *m, struct glyph *g)
3271{
3272 for (int y = 0; y < m->matrix_h; ++y)
3255 { 3273 {
3256 paused_p = true; 3274 struct glyph_row *r = MATRIX_ROW (m, y);
3257 goto do_pause; 3275 if (g >= r->glyphs[0] && g < r->glyphs[0] + m->matrix_w)
3276 return true;
3258 } 3277 }
3278 return false;
3279}
3259 3280
3260 if (FRAME_WINDOW_P (f)) 3281/* Return true if GLYPH is part of the desired matrix of F. */
3282
3283bool
3284is_tty_desired_glyph (struct frame *f, struct glyph *g)
3285{
3286 eassert (is_tty_frame (f));
3287 return is_glyph_in_matrix (f->desired_matrix, g);
3288}
3289
3290/* Return true if GLYPH is part of the desired matrix of F. */
3291
3292bool
3293is_tty_current_glyph (struct frame *f, struct glyph *g)
3294{
3295 eassert (is_tty_frame (f));
3296 return is_glyph_in_matrix (f->current_matrix, g);
3297}
3298#endif // GLYPH_DEBUG
3299
3300/* Compute the intersection of R1 and R2 in R. Value is true if R1 and
3301 R2 intersect, false otherwise. */
3302
3303static bool
3304rect_intersect (struct rect *r, struct rect r1, struct rect r2)
3305{
3306 int x1 = max (r1.x, r2.x);
3307 int x2 = min (r1.x + r1.w, r2.x + r2.w);
3308 if (x2 < x1)
3309 return false;
3310 int y1 = max (r1.y, r2.y);
3311 int y2 = min (r1.y + r1.h, r2.y + r2.h);
3312 if (y2 < y1)
3313 return false;
3314 *r = (struct rect) { .x = x1, .y = y1, .w = x2 - x1, .h = y2 - y1 };
3315 return true;
3316}
3317
3318/* Return the rectanlge frame F occupies. */
3319
3320static struct rect
3321frame_rect (struct frame *f)
3322{
3323 return (struct rect) {
3324 .x = f->left_pos, .y = f->top_pos, .w = f->total_cols, .h = f->total_lines
3325 };
3326}
3327
3328/* Return the root frame of frame F. Follow the parent_frame chain until
3329 we reach a frame that has no parent. That is the root frame. Note
3330 that the root of a root frame is itself. */
3331
3332struct frame *
3333root_frame (struct frame *f)
3334{
3335 while (FRAME_PARENT_FRAME (f))
3336 f = FRAME_PARENT_FRAME (f);
3337 return f;
3338}
3339
3340/* Return true if F1 is an ancestor of F2. */
3341
3342static bool
3343is_frame_ancestor (struct frame *f1, struct frame *f2)
3344{
3345 for (struct frame *f = FRAME_PARENT_FRAME (f2); f; f = FRAME_PARENT_FRAME (f))
3346 if (f == f1)
3347 return true;
3348 return false;
3349}
3350
3351/* Return a list of all frames having root frame ROOT. */
3352
3353Lisp_Object
3354frames_with_root (struct frame *root, bool visible)
3355{
3356 Lisp_Object list = Qnil;
3357 Lisp_Object tail, frame;
3358 FOR_EACH_FRAME (tail, frame)
3261 { 3359 {
3262 /* We are working on window matrix basis. All windows whose 3360 struct frame *f = XFRAME (frame);
3263 flag must_be_updated_p is set have to be updated. */ 3361 if (FRAME_VISIBLE_P (f) && root_frame (f) == root)
3362 list = Fcons (frame, list);
3363 }
3364 return list;
3365}
3264 3366
3265 /* Record that we are not working on frame matrices. */ 3367/* Compare frames F1 and F2 for z-order. Value is like strcmp. */
3266 set_frame_matrix_frame (NULL);
3267 3368
3268 /* Update all windows in the window tree of F, maybe stopping 3369static bool
3269 when pending input is detected. */ 3370frame_z_order_cmp (struct frame *f1, struct frame *f2)
3270 update_begin (f); 3371{
3372 if (f1 == f2)
3373 return 0;
3374 if (is_frame_ancestor (f1, f2))
3375 return -1;
3376 return f1->z_order - f2->z_order;
3377}
3271 3378
3272#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR 3379DEFUN ("frame--z-order-sort-predicate",
3273 /* Update the menu bar on X frames that don't have toolkit 3380 Fframe__z_order_sort_predicate,
3274 support. */ 3381 Sframe__z_order_sort_predicate,
3275 if (WINDOWP (f->menu_bar_window)) 3382 2, 2, 0,
3276 update_window (XWINDOW (f->menu_bar_window), true); 3383 doc: /* Internal frame sorting function A < B. */)
3277#endif 3384 (Lisp_Object a, Lisp_Object b)
3385{
3386 CHECK_FRAME (a); CHECK_FRAME (b);
3387 return frame_z_order_cmp (XFRAME (a), XFRAME (b)) < 0 ? Qt : Qnil;
3388}
3278 3389
3279#if defined (HAVE_WINDOW_SYSTEM) 3390/* Return a z-order list of frames on the same terminal as F. The list
3280 /* Update the tab-bar window, if present. */ 3391 is ordered topmost frame last. Note that this list may contain
3281 if (WINDOWP (f->tab_bar_window)) 3392 more than one root frame plus their children. */
3393
3394Lisp_Object
3395frames_in_reverse_z_order (struct frame *f, bool visible)
3396{
3397 struct frame *root = root_frame (f);
3398 Lisp_Object frames = frames_with_root (root, visible);
3399 frames = CALLN (Fsort, frames, Qframe__z_order_sort_predicate);
3400 eassert (FRAMEP (XCAR (frames)));
3401 eassert (XFRAME (XCAR (frames)) == root);
3402 return frames;
3403}
3404
3405void
3406tty_raise_lower_frame (struct frame *f, bool raise)
3407{
3408 struct frame *parent = FRAME_PARENT_FRAME (f);
3409 if (parent)
3410 {
3411 Lisp_Object children = frames_in_reverse_z_order (root_frame (f), false);
3412 Lisp_Object siblings = Qnil;
3413 for (Lisp_Object tail = children; CONSP (tail); tail = XCDR (tail))
3282 { 3414 {
3283 struct window *w = XWINDOW (f->tab_bar_window); 3415 struct frame *child = XFRAME (XCAR (tail));
3416 if (FRAME_PARENT_FRAME (child) == parent)
3417 siblings = Fcons (XCAR (tail), siblings);
3418 }
3284 3419
3285 /* Update tab-bar window. */ 3420 int n = list_length (siblings);
3286 if (w->must_be_updated_p) 3421 if (n > 1)
3422 {
3423 int i;
3424 if (raise)
3425 f->z_order = 0, i = 1;
3426 else
3427 f->z_order = n - 1, i = 0;
3428 for (Lisp_Object tail = siblings; CONSP (tail); tail = XCDR (tail))
3287 { 3429 {
3288 Lisp_Object tem; 3430 struct frame *child = XFRAME (XCAR (tail));
3431 if (f != child)
3432 child->z_order = i++;
3433 }
3434 }
3435 }
3436}
3289 3437
3290 update_window (w, true); 3438/* Return true if frame F is a tty frame. */
3291 w->must_be_updated_p = false;
3292 3439
3293 /* Swap tab-bar strings. We swap because we want to 3440bool
3294 reuse strings. */ 3441is_tty_frame (struct frame *f)
3295 tem = f->current_tab_bar_string; 3442{
3296 fset_current_tab_bar_string (f, f->desired_tab_bar_string); 3443 return FRAME_TERMCAP_P (f);
3297 fset_desired_tab_bar_string (f, tem); 3444}
3298 } 3445
3446/* Return true if frame F is a tty child frame. */
3447
3448bool
3449is_tty_child_frame (struct frame *f)
3450{
3451 return FRAME_PARENT_FRAME (f) && is_tty_frame (f);
3452}
3453
3454/* Return true if frame F is a tty root frame. */
3455
3456bool
3457is_tty_root_frame (struct frame *f)
3458{
3459 return !FRAME_PARENT_FRAME (f) && is_tty_frame (f);
3460}
3461
3462/* Return the index of the first enabled row in MATRIX, or -1 if there
3463 is none. */
3464
3465static int
3466first_enabled_row (struct glyph_matrix *matrix)
3467{
3468 for (int i = 0; i < matrix->nrows; ++i)
3469 if (MATRIX_ROW_ENABLED_P (matrix, i))
3470 return i;
3471 return -1;
3472}
3473
3474/* On tty frame F, make desired matrix current, without writing
3475 to the terminal. */
3476
3477static void
3478make_matrix_current (struct frame *f)
3479{
3480 int first_row = first_enabled_row (f->desired_matrix);
3481 if (first_row >= 0)
3482 for (int i = first_row; i < f->desired_matrix->nrows; ++i)
3483 if (MATRIX_ROW_ENABLED_P (f->desired_matrix, i))
3484 make_current (f, NULL, i);
3485}
3486
3487/* Copy to ROOT's desired matrix what we need from CHILD's current frame matrix. */
3488
3489static void
3490copy_child_glyphs (struct frame *root, struct frame *child)
3491{
3492 eassert (!FRAME_PARENT_FRAME (root));
3493 eassert (is_frame_ancestor (root, child));
3494
3495 /* Determine the intersection of the child frame rectangle with
3496 the root frame. This is basically clipping the child frame to
3497 the root frame rectangle. */
3498 struct rect r;
3499 if (!rect_intersect (&r, frame_rect (root), frame_rect (child)))
3500 return;
3501
3502 /* Build CHILD's current matrix which we need to copy from it. */
3503 make_matrix_current (child);
3504
3505 /* The first row of the child's matrix that is visible in the parent
3506 depends on how many child rows are above the parent, which is
3507 abs (child->top_pos) if top_pos is negative. */
3508 int child_y = child->top_pos < 0 ? abs (child->top_pos) : 0;
3509
3510 /* The first column of the child's matrix that is visible in the
3511 parent depends on how many child columns are to the left of the
3512 parent, which is abs (child->left_pos) if left_pos is negative. */
3513 int child_x = child->left_pos < 0 ? abs (child->left_pos) : 0;
3514
3515 /* For all rows in the intersection, copy glyphs from the child's
3516 current matrix to the root's desired matrix, enabling those
3517 rows. */
3518 for (int y = r.y; y < r.y + r.h; ++y, ++child_y)
3519 {
3520 /* Start with the root's desired matrix row. If that hasn't
3521 been redisplayed, copy from the root's current matrix. */
3522 struct glyph_row *root_row = MATRIX_ROW (root->desired_matrix, y);
3523 if (!root_row->enabled_p)
3524 {
3525 struct glyph_row *from = MATRIX_ROW (root->current_matrix, y);
3526 memcpy (root_row->glyphs[0], from->glyphs[0],
3527 root->current_matrix->matrix_w * sizeof (struct glyph));
3528 root_row->enabled_p = true;
3299 } 3529 }
3530
3531 /* Copy the child's current row contents over it. */
3532 struct glyph_row *child_row = MATRIX_ROW (child->current_matrix, child_y);
3533 memcpy (root_row->glyphs[0] + r.x,
3534 child_row->glyphs[0] + child_x,
3535 r.w * sizeof (struct glyph));
3536
3537 /* Compute a new hash since we changed glyphs. */
3538 root_row->hash = row_hash (root_row);
3539 }
3540}
3541
3542/***********************************************************************
3543 Frame Update
3544 ***********************************************************************/
3545
3546/* Update the menu bar on X frames that don't have toolkit
3547 support. */
3548
3549static void
3550update_menu_bar (struct frame *f)
3551{
3552#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
3553 if (WINDOWP (f->menu_bar_window))
3554 update_window (XWINDOW (f->menu_bar_window), true);
3300#endif 3555#endif
3556}
3301 3557
3302#if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR) 3558#ifdef HAVE_WINDOW_SYSTEM
3303 /* Update the tool-bar window, if present. */ 3559static void
3304 if (WINDOWP (f->tool_bar_window)) 3560update_bar_window (Lisp_Object window, Lisp_Object *current,
3561 Lisp_Object *desired)
3562{
3563 if (WINDOWP (window))
3564 {
3565 struct window *w = XWINDOW (window);
3566 if (w->must_be_updated_p)
3305 { 3567 {
3306 struct window *w = XWINDOW (f->tool_bar_window); 3568 update_window (w, true);
3569 w->must_be_updated_p = false;
3570 Lisp_Object tem = *current;
3571 *current = *desired;
3572 *desired = tem;
3573 }
3574 }
3575}
3576#endif
3307 3577
3308 /* Update tool-bar window. */ 3578/* Update the tab-bar window of frame F, if present.
3309 if (w->must_be_updated_p) 3579 FIXME/tty: This is almost identical to the updating
3310 { 3580 of the tab bar. */
3311 Lisp_Object tem;
3312 3581
3313 update_window (w, true); 3582static void
3314 w->must_be_updated_p = false; 3583update_tab_bar (struct frame *f)
3584{
3585#if defined(HAVE_WINDOW_SYSTEM)
3586 update_bar_window (f->tab_bar_window, &f->current_tab_bar_string,
3587 &f->desired_tab_bar_string);
3588#endif
3589}
3315 3590
3316 /* Swap tool-bar strings. We swap because we want to 3591static void
3317 reuse strings. */ 3592update_tool_bar (struct frame *f)
3318 tem = f->current_tool_bar_string; 3593{
3319 fset_current_tool_bar_string (f, f->desired_tool_bar_string); 3594#if defined(HAVE_WINDOW_SYSTEM) && !defined(HAVE_EXT_TOOL_BAR)
3320 fset_desired_tool_bar_string (f, tem); 3595 update_bar_window (f->tool_bar_window, &f->current_tool_bar_string,
3321 } 3596 &f->desired_tool_bar_string);
3322 }
3323#endif 3597#endif
3598}
3324 3599
3325 /* Update windows. */ 3600static bool
3326 paused_p = update_window_tree (root_window, force_p); 3601update_window_frame (struct frame *f, bool force_p)
3327 update_end (f); 3602{
3328 } 3603 eassert (FRAME_WINDOW_P (f));
3329 else 3604 update_begin (f);
3605 update_menu_bar (f);
3606 update_tab_bar (f);
3607 update_tool_bar (f);
3608 struct window *root_window = XWINDOW (f->root_window);
3609 bool paused_p = update_window_tree (root_window, force_p);
3610 update_end (f);
3611 set_window_update_flags (root_window, false);
3612 return paused_p;
3613}
3614
3615static bool
3616update_initial_frame (struct frame *f, bool force_p)
3617{
3618 build_frame_matrix (f);
3619 struct window *root_window = XWINDOW (f->root_window);
3620 set_window_update_flags (root_window, false);
3621 return false;
3622}
3623
3624static void
3625flush_terminal (struct frame *f)
3626{
3627 if (FRAME_TTY (f)->termscript)
3628 fflush (FRAME_TTY (f)->termscript);
3629 fflush (FRAME_TTY (f)->output);
3630}
3631
3632static bool
3633update_tty_frame (struct frame *f, bool force_p)
3634{
3635 build_frame_matrix (f);
3636 return false;
3637}
3638
3639bool
3640combine_updates_for_frame (struct frame *f, bool force_p, bool inhibit_scrolling)
3641{
3642 struct frame *root = root_frame (f);
3643 eassert (FRAME_VISIBLE_P (root));
3644
3645 /* Process child frames in reverse z-order, topmost last. For each
3646 child, copy what we need to the root's desired matrix. */
3647 Lisp_Object z_order = frames_in_reverse_z_order (root, true);
3648 for (Lisp_Object tail = XCDR (z_order); CONSP (tail); tail = XCDR (tail))
3330 { 3649 {
3331 /* We are working on frame matrix basis. Set the frame on whose 3650 struct frame *child = XFRAME (XCAR (tail));
3332 frame matrix we operate. */ 3651 copy_child_glyphs (root, child);
3333 set_frame_matrix_frame (f); 3652 }
3334 3653
3335 /* Build F's desired matrix from window matrices. */ 3654 update_begin (root);
3336 build_frame_matrix (f); 3655 bool paused = write_matrix (root, force_p, inhibit_scrolling, 1, false);
3656 if (!paused)
3657 make_matrix_current (root);
3658 update_end (root);
3659 flush_terminal (root);
3337 3660
3338 /* Update the display. */ 3661 for (Lisp_Object tail = z_order; CONSP (tail); tail = XCDR (tail))
3339 if (FRAME_INITIAL_P (f)) 3662 {
3340 /* No actual display to update so the "update" is a nop and 3663 struct frame *f = XFRAME (XCAR (tail));
3341 obviously isn't interrupted by pending input. */ 3664 struct window *root_window = XWINDOW (f->root_window);
3342 paused_p = false; 3665 set_window_update_flags (root_window, false);
3343 else 3666 clear_desired_matrices (f);
3344 {
3345 update_begin (f);
3346 paused_p = update_frame_1 (f, force_p, inhibit_hairy_id_p, 1, false);
3347 update_end (f);
3348 }
3349
3350 if (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
3351 {
3352 if (FRAME_TTY (f)->termscript)
3353 fflush (FRAME_TTY (f)->termscript);
3354 if (FRAME_TERMCAP_P (f))
3355 fflush (FRAME_TTY (f)->output);
3356 }
3357
3358 /* Check window matrices for lost pointers. */
3359#ifdef GLYPH_DEBUG 3667#ifdef GLYPH_DEBUG
3360 check_window_matrix_pointers (root_window); 3668 check_window_matrix_pointers (root_window);
3361 add_frame_display_history (f, paused_p); 3669 add_frame_display_history (f, false);
3362#endif 3670#endif
3363 } 3671 }
3364 3672
3365 do_pause: 3673 return paused;
3366 /* Reset flags indicating that a window should be updated. */ 3674}
3367 set_window_update_flags (root_window, false);
3368 3675
3369 display_completed = !paused_p; 3676/* Update on the screen all root frames ROOTS. Called from
3370 return paused_p; 3677 redisplay_internal as the last step of redisplaying. */
3678
3679bool
3680combine_updates (Lisp_Object roots, bool force_p, bool inhibit_scrolling)
3681{
3682 for (; CONSP (roots); roots = XCDR (roots))
3683 {
3684 struct frame *root = XFRAME (XCAR (roots));
3685 if (combine_updates_for_frame (root, force_p, inhibit_scrolling))
3686 {
3687 display_completed = false;
3688 return true;
3689 }
3690 }
3691
3692 display_completed = true;
3693 return false;
3694}
3695
3696/* Update frame F based on the data in desired matrices.
3697
3698 If FORCE_P, don't let redisplay be stopped by detecting pending input.
3699 If INHIBIT_SCROLLING, don't try scrolling.
3700
3701 Value is true if redisplay was stopped due to pending input. */
3702
3703bool
3704update_frame (struct frame *f, bool force_p, bool inhibit_scrolling)
3705{
3706 struct window *root_window = XWINDOW (f->root_window);
3707
3708 if (redisplay_dont_pause)
3709 force_p = true;
3710 else if (!force_p && detect_input_pending_ignore_squeezables ())
3711 {
3712 /* Reset flags indicating that a window should be updated. */
3713 set_window_update_flags (root_window, false);
3714 display_completed = false;
3715 return true;
3716 }
3717
3718 bool paused;
3719 if (FRAME_WINDOW_P (f))
3720 paused = update_window_frame (f, force_p);
3721 else if (FRAME_INITIAL_P (f))
3722 paused = update_initial_frame (f, force_p);
3723 else
3724 paused = update_tty_frame (f, force_p);
3725
3726 if (paused)
3727 display_completed = false;
3728 return paused;
3371} 3729}
3372 3730
3373/* Update a TTY frame F that has a menu dropped down over some of its 3731/* Update a TTY frame F that has a menu dropped down over some of its
@@ -3384,29 +3742,25 @@ void
3384update_frame_with_menu (struct frame *f, int row, int col) 3742update_frame_with_menu (struct frame *f, int row, int col)
3385{ 3743{
3386 struct window *root_window = XWINDOW (f->root_window); 3744 struct window *root_window = XWINDOW (f->root_window);
3387 bool paused_p, cursor_at_point_p; 3745 bool cursor_at_point_p;
3388 3746
3389 eassert (FRAME_TERMCAP_P (f)); 3747 eassert (FRAME_TERMCAP_P (f));
3390 3748
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. */ 3749 /* Update the display. */
3396 update_begin (f); 3750 update_begin (f);
3397 cursor_at_point_p = !(row >= 0 && col >= 0); 3751 cursor_at_point_p = !(row >= 0 && col >= 0);
3398 /* Force update_frame_1 not to stop due to pending input, and not 3752 /* Do not stop due to pending input, and do not try scrolling. This
3399 try scrolling. */ 3753 means that write_glyphs will always return false. */
3400 paused_p = update_frame_1 (f, 1, 1, cursor_at_point_p, true); 3754 write_matrix (f, 1, 1, cursor_at_point_p, true);
3755 make_matrix_current (f);
3756 clear_desired_matrices (f);
3401 /* ROW and COL tell us where in the menu to position the cursor, so 3757 /* 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. */ 3758 that screen readers know the active region on the screen. */
3403 if (!cursor_at_point_p) 3759 if (!cursor_at_point_p)
3404 cursor_to (f, row, col); 3760 cursor_to (f, row, col);
3405 update_end (f); 3761 update_end (f);
3762 flush_terminal (f);
3406 3763
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. */ 3764 /* Check window matrices for lost pointers. */
3411#if GLYPH_DEBUG 3765#if GLYPH_DEBUG
3412#if 0 3766#if 0
@@ -3415,12 +3769,12 @@ update_frame_with_menu (struct frame *f, int row, int col)
3415 making any updates to the window matrices. */ 3769 making any updates to the window matrices. */
3416 check_window_matrix_pointers (root_window); 3770 check_window_matrix_pointers (root_window);
3417#endif 3771#endif
3418 add_frame_display_history (f, paused_p); 3772 add_frame_display_history (f, false);
3419#endif 3773#endif
3420 3774
3421 /* Reset flags indicating that a window should be updated. */ 3775 /* Reset flags indicating that a window should be updated. */
3422 set_window_update_flags (root_window, false); 3776 set_window_update_flags (root_window, false);
3423 display_completed = !paused_p; 3777 display_completed = true;
3424} 3778}
3425 3779
3426/* Update the mouse position for a frame F. This handles both 3780/* Update the mouse position for a frame F. This handles both
@@ -3507,9 +3861,6 @@ update_single_window (struct window *w)
3507 { 3861 {
3508 struct frame *f = XFRAME (WINDOW_FRAME (w)); 3862 struct frame *f = XFRAME (WINDOW_FRAME (w));
3509 3863
3510 /* Record that this is not a frame-based redisplay. */
3511 set_frame_matrix_frame (NULL);
3512
3513 /* Update W. */ 3864 /* Update W. */
3514 update_begin (f); 3865 update_begin (f);
3515 update_window (w, true); 3866 update_window (w, true);
@@ -3688,6 +4039,8 @@ update_window (struct window *w, bool force_p)
3688 4039
3689#ifdef HAVE_WINDOW_SYSTEM 4040#ifdef HAVE_WINDOW_SYSTEM
3690 gui_update_window_begin (w); 4041 gui_update_window_begin (w);
4042#else
4043 (void) changed_p;
3691#endif 4044#endif
3692 yb = window_text_bottom_y (w); 4045 yb = window_text_bottom_y (w);
3693 row = MATRIX_ROW (desired_matrix, 0); 4046 row = MATRIX_ROW (desired_matrix, 0);
@@ -4321,7 +4674,7 @@ update_window_line (struct window *w, int vpos, bool *mouse_face_overwritten_p)
4321 4674
4322 /* Update current_row from desired_row. */ 4675 /* Update current_row from desired_row. */
4323 was_stipple = current_row->stipple_p; 4676 was_stipple = current_row->stipple_p;
4324 make_current (w->desired_matrix, w->current_matrix, vpos); 4677 make_current (NULL, w, vpos);
4325 4678
4326 /* If only a partial update was performed, any stipple already 4679 /* If only a partial update was performed, any stipple already
4327 displayed in MATRIX_ROW (w->current_matrix, vpos) might still be 4680 displayed in MATRIX_ROW (w->current_matrix, vpos) might still be
@@ -4931,7 +5284,92 @@ scrolling_window (struct window *w, int tab_line_p)
4931 Frame-Based Updates 5284 Frame-Based Updates
4932 ************************************************************************/ 5285 ************************************************************************/
4933 5286
4934/* Update the desired frame matrix of frame F. 5287static void
5288tty_set_cursor (void)
5289{
5290 struct frame *f = SELECTED_FRAME ();
5291
5292 if ((cursor_in_echo_area
5293 /* If we are showing a message instead of the mini-buffer,
5294 show the cursor for the message instead of for the
5295 (now hidden) mini-buffer contents. */
5296 || (BASE_EQ (minibuf_window, selected_window)
5297 && BASE_EQ (minibuf_window, echo_area_window)
5298 && !NILP (echo_area_buffer[0])))
5299 /* These cases apply only to the frame that contains
5300 the active mini-buffer window. */
5301 && FRAME_HAS_MINIBUF_P (f)
5302 && BASE_EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
5303 {
5304 int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f)));
5305 int col;
5306
5307 /* Put cursor at the end of the prompt. If the mini-buffer
5308 is several lines high, find the last line that has
5309 any text on it. */
5310 int row = FRAME_TOTAL_LINES (f);
5311 do
5312 {
5313 row--;
5314 col = 0;
5315
5316 if (MATRIX_ROW_ENABLED_P (f->current_matrix, row))
5317 {
5318 /* Frame rows are filled up with spaces that
5319 must be ignored here. */
5320 struct glyph_row *r = MATRIX_ROW (f->current_matrix, row);
5321 struct glyph *start = r->glyphs[TEXT_AREA];
5322
5323 col = r->used[TEXT_AREA];
5324 while (0 < col && start[col - 1].charpos < 0)
5325 col--;
5326 }
5327 }
5328 while (row > top && col == 0);
5329
5330 /* We exit the loop with COL at the glyph _after_ the last one. */
5331 if (col > 0)
5332 col--;
5333
5334 /* Make sure COL is not out of range. */
5335 if (col >= FRAME_CURSOR_X_LIMIT (f))
5336 {
5337 /* If we have another row, advance cursor into it. */
5338 if (row < FRAME_TOTAL_LINES (f) - 1)
5339 {
5340 col = FRAME_LEFT_SCROLL_BAR_COLS (f);
5341 row++;
5342 }
5343 /* Otherwise move it back in range. */
5344 else
5345 col = FRAME_CURSOR_X_LIMIT (f) - 1;
5346 }
5347
5348 cursor_to (f, row, col);
5349 }
5350 else
5351 {
5352 /* We have only one cursor on terminal frames. Use it to
5353 display the cursor of the selected window. */
5354 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
5355 if (w->cursor.vpos >= 0
5356 /* The cursor vpos may be temporarily out of bounds
5357 in the following situation: There is one window,
5358 with the cursor in the lower half of it. The window
5359 is split, and a message causes a redisplay before
5360 a new cursor position has been computed. */
5361 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
5362 {
5363 int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
5364 int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
5365
5366 x += max (0, w->left_margin_cols);
5367 cursor_to (f, y, x);
5368 }
5369 }
5370}
5371
5372/* Write desired matix of tty frame F and make it current.
4935 5373
4936 FORCE_P means that the update should not be stopped by pending input. 5374 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. 5375 INHIBIT_ID_P means that scrolling by insert/delete should not be tried.
@@ -4940,167 +5378,58 @@ scrolling_window (struct window *w, int tab_line_p)
4940 Value is true if update was stopped due to pending input. */ 5378 Value is true if update was stopped due to pending input. */
4941 5379
4942static bool 5380static bool
4943update_frame_1 (struct frame *f, bool force_p, bool inhibit_id_p, 5381write_matrix (struct frame *f, bool force_p, bool inhibit_id_p,
4944 bool set_cursor_p, bool updating_menu_p) 5382 bool set_cursor_p, bool updating_menu_p)
4945{ 5383{
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 ()) 5384 if (!force_p && detect_input_pending_ignore_squeezables ())
4959 { 5385 return true;
4960 pause_p = 1;
4961 goto do_pause;
4962 }
4963 5386
4964 /* If we cannot insert/delete lines, it's no use trying it. */ 5387 /* If we cannot insert/delete lines, it's no use trying it. */
4965 if (!FRAME_LINE_INS_DEL_OK (f)) 5388 if (!FRAME_LINE_INS_DEL_OK (f))
4966 inhibit_id_p = 1; 5389 inhibit_id_p = true;
4967 5390
4968 /* See if any of the desired lines are enabled; don't compute for 5391 if (baud_rate != FRAME_COST_BAUD_RATE (f))
4969 i/d line if just want cursor motion. */ 5392 calculate_costs (f);
4970 for (i = 0; i < desired_matrix->nrows; i++)
4971 if (MATRIX_ROW_ENABLED_P (desired_matrix, i))
4972 break;
4973 5393
4974 /* Try doing i/d line, if not yet inhibited. */ 5394 /* See if any of the desired lines are enabled; don't compute for
4975 if (!inhibit_id_p && i < desired_matrix->nrows) 5395 i/d line if just want cursor motion. */
5396 int first_row = first_enabled_row (f->desired_matrix);
5397 if (!inhibit_id_p && first_row >= 0)
4976 force_p |= scrolling (f); 5398 force_p |= scrolling (f);
4977 5399
4978 /* Update the individual lines as needed. Do bottom line first. */ 5400 /* Update the individual lines as needed. Do bottom line first. This
4979 if (MATRIX_ROW_ENABLED_P (desired_matrix, desired_matrix->nrows - 1)) 5401 is done so that messages are made visible when pausing. */
4980 update_frame_line (f, desired_matrix->nrows - 1, updating_menu_p); 5402 int last_row = f->desired_matrix->nrows - 1;
5403 if (MATRIX_ROW_ENABLED_P (f->desired_matrix, last_row))
5404 write_row (f, last_row, updating_menu_p);
4981 5405
4982 /* Now update the rest of the lines. */ 5406 bool pause_p = false;
4983 for (i = 0; i < desired_matrix->nrows - 1 && (force_p || !input_pending); i++) 5407 if (first_row >= 0)
4984 { 5408 {
4985 if (MATRIX_ROW_ENABLED_P (desired_matrix, i)) 5409 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 5410
5005 if (!force_p && (i - 1) % preempt_count == 0) 5411 for (int i = first_row, n = 0; i < last_row; ++i)
5006 detect_input_pending_ignore_squeezables (); 5412 if (MATRIX_ROW_ENABLED_P (f->desired_matrix, i))
5413 {
5414 if (!force_p && n % preempt_count == 0
5415 && detect_input_pending_ignore_squeezables ())
5416 {
5417 pause_p = true;
5418 break;
5419 }
5007 5420
5008 update_frame_line (f, i, updating_menu_p); 5421 write_row (f, i, updating_menu_p);
5009 } 5422 ++n;
5423 }
5010 } 5424 }
5011 5425
5012 pause_p = 0 < i && i < FRAME_TOTAL_LINES (f) - 1;
5013
5014 /* Now just clean up termcap drivers and set cursor, etc. */ 5426 /* Now just clean up termcap drivers and set cursor, etc. */
5015 if (!pause_p && set_cursor_p) 5427 if (!pause_p && set_cursor_p)
5016 { 5428 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 5429
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
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; 5430 return pause_p;
5101} 5431}
5102 5432
5103
5104/* Do line insertions/deletions on frame F for frame-based redisplay. */ 5433/* Do line insertions/deletions on frame F for frame-based redisplay. */
5105 5434
5106static bool 5435static bool
@@ -5209,12 +5538,12 @@ scrolling (struct frame *frame)
5209 which is LEN glyphs long. */ 5538 which is LEN glyphs long. */
5210 5539
5211static int 5540static int
5212count_blanks (struct glyph *r, int len) 5541count_blanks (struct frame *f, struct glyph *r, int len)
5213{ 5542{
5214 int i; 5543 int i;
5215 5544
5216 for (i = 0; i < len; ++i) 5545 for (i = 0; i < len; ++i)
5217 if (!CHAR_GLYPH_SPACE_P (r[i])) 5546 if (!CHAR_GLYPH_SPACE_P (f, r[i]))
5218 break; 5547 break;
5219 5548
5220 return i; 5549 return i;
@@ -5250,7 +5579,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. */ 5579/* Perform a frame-based update on line VPOS in frame FRAME. */
5251 5580
5252static void 5581static void
5253update_frame_line (struct frame *f, int vpos, bool updating_menu_p) 5582write_row (struct frame *f, int vpos, bool updating_menu_p)
5254{ 5583{
5255 struct glyph *obody, *nbody, *op1, *op2, *np1, *nend; 5584 struct glyph *obody, *nbody, *op1, *op2, *np1, *nend;
5256 int tem; 5585 int tem;
@@ -5264,11 +5593,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 5593 bool colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background
5265 != FACE_TTY_DEFAULT_BG_COLOR); 5594 != FACE_TTY_DEFAULT_BG_COLOR);
5266 5595
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) 5596 if (colored_spaces_p)
5273 write_spaces_p = 1; 5597 write_spaces_p = 1;
5274 5598
@@ -5287,7 +5611,7 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5287 5611
5288 /* Ignore trailing spaces, if we can. */ 5612 /* Ignore trailing spaces, if we can. */
5289 if (!write_spaces_p) 5613 if (!write_spaces_p)
5290 while (olen > 0 && CHAR_GLYPH_SPACE_P (obody[olen-1])) 5614 while (olen > 0 && CHAR_GLYPH_SPACE_P (f, obody[olen-1]))
5291 olen--; 5615 olen--;
5292 } 5616 }
5293 5617
@@ -5316,7 +5640,7 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5316 { 5640 {
5317 /* Ignore spaces at the end, if we can. */ 5641 /* Ignore spaces at the end, if we can. */
5318 if (!write_spaces_p) 5642 if (!write_spaces_p)
5319 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1])) 5643 while (nlen > 0 && CHAR_GLYPH_SPACE_P (f, nbody[nlen - 1]))
5320 --nlen; 5644 --nlen;
5321 5645
5322 /* Write the contents of the desired line. */ 5646 /* Write the contents of the desired line. */
@@ -5338,15 +5662,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 5662 /* Make sure we are in the right row, otherwise cursor movement
5339 with cmgoto might use `ch' in the wrong row. */ 5663 with cmgoto might use `ch' in the wrong row. */
5340 cursor_to (f, vpos, 0); 5664 cursor_to (f, vpos, 0);
5341
5342 make_current (desired_matrix, current_matrix, vpos);
5343 return; 5665 return;
5344 } 5666 }
5345 5667
5346 /* Pretend trailing spaces are not there at all, 5668 /* Pretend trailing spaces are not there at all,
5347 unless for one reason or another we must write all spaces. */ 5669 unless for one reason or another we must write all spaces. */
5348 if (!write_spaces_p) 5670 if (!write_spaces_p)
5349 while (nlen > 0 && CHAR_GLYPH_SPACE_P (nbody[nlen - 1])) 5671 while (nlen > 0 && CHAR_GLYPH_SPACE_P (f, nbody[nlen - 1]))
5350 nlen--; 5672 nlen--;
5351 5673
5352 /* If there's no i/d char, quickly do the best we can without it. */ 5674 /* If there's no i/d char, quickly do the best we can without it. */
@@ -5383,9 +5705,6 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5383 cursor_to (f, vpos, nlen); 5705 cursor_to (f, vpos, nlen);
5384 clear_end_of_line (f, olen); 5706 clear_end_of_line (f, olen);
5385 } 5707 }
5386
5387 /* Make current row = desired row. */
5388 make_current (desired_matrix, current_matrix, vpos);
5389 return; 5708 return;
5390 } 5709 }
5391 5710
@@ -5399,7 +5718,7 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5399 if (write_spaces_p) 5718 if (write_spaces_p)
5400 nsp = 0; 5719 nsp = 0;
5401 else 5720 else
5402 nsp = count_blanks (nbody, nlen); 5721 nsp = count_blanks (f, nbody, nlen);
5403 5722
5404 if (nlen > nsp) 5723 if (nlen > nsp)
5405 { 5724 {
@@ -5407,14 +5726,12 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5407 write_glyphs (f, nbody + nsp, nlen - nsp); 5726 write_glyphs (f, nbody + nsp, nlen - nsp);
5408 } 5727 }
5409 5728
5410 /* Exchange contents between current_frame and new_frame. */
5411 make_current (desired_matrix, current_matrix, vpos);
5412 return; 5729 return;
5413 } 5730 }
5414 5731
5415 /* Compute number of leading blanks in old and new contents. */ 5732 /* Compute number of leading blanks in old and new contents. */
5416 osp = count_blanks (obody, olen); 5733 osp = count_blanks (f, obody, olen);
5417 nsp = (colored_spaces_p ? 0 : count_blanks (nbody, nlen)); 5734 nsp = (colored_spaces_p ? 0 : count_blanks (f, nbody, nlen));
5418 5735
5419 /* Compute number of matching chars starting with first non-blank. */ 5736 /* Compute number of matching chars starting with first non-blank. */
5420 begmatch = count_match (obody + osp, obody + olen, 5737 begmatch = count_match (obody + osp, obody + olen,
@@ -5425,7 +5742,7 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5425 if (!write_spaces_p && osp + begmatch == olen) 5742 if (!write_spaces_p && osp + begmatch == olen)
5426 { 5743 {
5427 np1 = nbody + nsp; 5744 np1 = nbody + nsp;
5428 while (np1 + begmatch < nend && CHAR_GLYPH_SPACE_P (np1[begmatch])) 5745 while (np1 + begmatch < nend && CHAR_GLYPH_SPACE_P (f, np1[begmatch]))
5429 ++begmatch; 5746 ++begmatch;
5430 } 5747 }
5431 5748
@@ -5566,9 +5883,6 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p)
5566 cursor_to (f, vpos, nlen); 5883 cursor_to (f, vpos, nlen);
5567 clear_end_of_line (f, olen); 5884 clear_end_of_line (f, olen);
5568 } 5885 }
5569
5570 /* Exchange contents between current_frame and new_frame. */
5571 make_current (desired_matrix, current_matrix, vpos);
5572} 5886}
5573 5887
5574 5888
@@ -5967,7 +6281,8 @@ handle_window_change_signal (int sig)
5967 { 6281 {
5968 struct frame *f = XFRAME (frame); 6282 struct frame *f = XFRAME (frame);
5969 6283
5970 if (FRAME_TERMCAP_P (f) && FRAME_TTY (f) == tty) 6284 if (FRAME_TERMCAP_P (f) && FRAME_TTY (f) == tty
6285 && !FRAME_PARENT_FRAME (f))
5971 /* Record the new sizes, but don't reallocate the data 6286 /* Record the new sizes, but don't reallocate the data
5972 structures now. Let that be done later outside of the 6287 structures now. Let that be done later outside of the
5973 signal handler. */ 6288 signal handler. */
@@ -6534,7 +6849,7 @@ init_display_interactive (void)
6534 6849
6535 /* Construct the space glyph. */ 6850 /* Construct the space glyph. */
6536 space_glyph.type = CHAR_GLYPH; 6851 space_glyph.type = CHAR_GLYPH;
6537 SET_CHAR_GLYPH (space_glyph, ' ', DEFAULT_FACE_ID, 0); 6852 SET_CHAR_GLYPH (NULL, space_glyph, ' ', DEFAULT_FACE_ID, 0);
6538 space_glyph.charpos = -1; 6853 space_glyph.charpos = -1;
6539 6854
6540 inverse_video = 0; 6855 inverse_video = 0;
@@ -6808,6 +7123,7 @@ syms_of_display (void)
6808 defsubr (&Ssend_string_to_terminal); 7123 defsubr (&Ssend_string_to_terminal);
6809 defsubr (&Sinternal_show_cursor); 7124 defsubr (&Sinternal_show_cursor);
6810 defsubr (&Sinternal_show_cursor_p); 7125 defsubr (&Sinternal_show_cursor_p);
7126 defsubr (&Sframe__z_order_sort_predicate);
6811 7127
6812#ifdef GLYPH_DEBUG 7128#ifdef GLYPH_DEBUG
6813 defsubr (&Sdump_redisplay_history); 7129 defsubr (&Sdump_redisplay_history);
@@ -6818,6 +7134,7 @@ syms_of_display (void)
6818 7134
6819 /* This is the "purpose" slot of a display table. */ 7135 /* This is the "purpose" slot of a display table. */
6820 DEFSYM (Qdisplay_table, "display-table"); 7136 DEFSYM (Qdisplay_table, "display-table");
7137 DEFSYM (Qframe__z_order_sort_predicate, "frame--z-order-sort-predicate");
6821 7138
6822 DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause"); 7139 DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause");
6823 7140
@@ -6921,6 +7238,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. */); 7238This option affects only builds where the tool bar is not external. */);
6922 7239
6923 pdumper_do_now_and_after_load (syms_of_display_for_pdumper); 7240 pdumper_do_now_and_after_load (syms_of_display_for_pdumper);
7241
7242 Fprovide (intern_c_string ("tty-child-frames"), Qnil);
6924} 7243}
6925 7244
6926static void 7245static void
diff --git a/src/frame.c b/src/frame.c
index 7f4bf274ad9..f14b29c02ef 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
@@ -182,6 +197,17 @@ set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
182 int olines = FRAME_MENU_BAR_LINES (f); 197 int olines = FRAME_MENU_BAR_LINES (f);
183 int nlines = TYPE_RANGED_FIXNUMP (int, value) ? XFIXNUM (value) : 0; 198 int nlines = TYPE_RANGED_FIXNUMP (int, value) ? XFIXNUM (value) : 0;
184 199
200 /* FIXME/tty: menu bars on child frames don't work on all platforms,
201 which is the reason why prepare_menu_bar does not update_menu_bar
202 for child frames (info from Martin Rudalics). This could be
203 implemented in ttys, but it's unclear if it is worth it. */
204 if (is_tty_child_frame (f))
205 {
206 FRAME_MENU_BAR_LINES (f) = 0;
207 FRAME_MENU_BAR_HEIGHT (f) = 0;
208 return;
209 }
210
185 /* Right now, menu bars don't work properly in minibuf-only frames; 211 /* Right now, menu bars don't work properly in minibuf-only frames;
186 most of the commands try to apply themselves to the minibuffer 212 most of the commands try to apply themselves to the minibuffer
187 frame itself, and get an error because you can't switch buffers 213 frame itself, and get an error because you can't switch buffers
@@ -389,7 +415,6 @@ frame_windows_min_size (Lisp_Object frame, Lisp_Object horizontal,
389} 415}
390 416
391 417
392#ifdef HAVE_WINDOW_SYSTEM
393/** 418/**
394 * keep_ratio: 419 * keep_ratio:
395 * 420 *
@@ -508,7 +533,6 @@ keep_ratio (struct frame *f, struct frame *p, int old_width, int old_height,
508 } 533 }
509 } 534 }
510} 535}
511#endif
512 536
513 537
514static void 538static void
@@ -832,9 +856,11 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
832 resize_frame_windows (f, new_inner_width, true); 856 resize_frame_windows (f, new_inner_width, true);
833 857
834 /* MSDOS frames cannot PRETEND, as they change frame size by 858 /* MSDOS frames cannot PRETEND, as they change frame size by
835 manipulating video hardware. */ 859 manipulating video hardware. FIXME/tty: it looks wrong to set
836 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f)) 860 FrameCols here. See also the comment for FrameRows above. */
837 FrameCols (FRAME_TTY (f)) = new_text_cols; 861 if (is_tty_root_frame (f))
862 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
863 FrameCols (FRAME_TTY (f)) = new_text_cols;
838 864
839#if defined (HAVE_WINDOW_SYSTEM) 865#if defined (HAVE_WINDOW_SYSTEM)
840 if (WINDOWP (f->tab_bar_window)) 866 if (WINDOWP (f->tab_bar_window))
@@ -866,9 +892,15 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
866 resize_frame_windows (f, new_inner_height, false); 892 resize_frame_windows (f, new_inner_height, false);
867 893
868 /* MSDOS frames cannot PRETEND, as they change frame size by 894 /* MSDOS frames cannot PRETEND, as they change frame size by
869 manipulating video hardware. */ 895 manipulating video hardware.
870 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f)) 896
871 FrameRows (FRAME_TTY (f)) = new_text_lines + FRAME_TOP_MARGIN (f); 897 FIXME/tty: ti looks strange to set FrameRows here. The terminal
898 emulator window or console has some physical size, and I wonder
899 how one would change that size from here. Or what it is good for
900 to set it here. */
901 if (is_tty_root_frame (f))
902 if ((FRAME_TERMCAP_P (f) && !pretend) || FRAME_MSDOS_P (f))
903 FrameRows (FRAME_TTY (f)) = new_text_lines + FRAME_TOP_MARGIN (f);
872 } 904 }
873 else if (new_text_lines != old_text_lines) 905 else if (new_text_lines != old_text_lines)
874 call2 (Qwindow__pixel_to_total, frame, Qnil); 906 call2 (Qwindow__pixel_to_total, frame, Qnil);
@@ -910,7 +942,6 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
910 942
911 unblock_input (); 943 unblock_input ();
912 944
913#ifdef HAVE_WINDOW_SYSTEM
914 { 945 {
915 /* Adjust size of F's child frames. */ 946 /* Adjust size of F's child frames. */
916 Lisp_Object frames, frame1; 947 Lisp_Object frames, frame1;
@@ -920,7 +951,6 @@ adjust_frame_size (struct frame *f, int new_text_width, int new_text_height,
920 keep_ratio (XFRAME (frame1), f, old_native_width, old_native_height, 951 keep_ratio (XFRAME (frame1), f, old_native_width, old_native_height,
921 new_native_width, new_native_height); 952 new_native_width, new_native_height);
922 } 953 }
923#endif
924} 954}
925 955
926/* Allocate basically initialized frame. */ 956/* Allocate basically initialized frame. */
@@ -967,12 +997,12 @@ make_frame (bool mini_p)
967 f->line_height = 1; /* !FRAME_WINDOW_P value. */ 997 f->line_height = 1; /* !FRAME_WINDOW_P value. */
968 f->new_width = -1; 998 f->new_width = -1;
969 f->new_height = -1; 999 f->new_height = -1;
1000 f->no_special_glyphs = false;
970#ifdef HAVE_WINDOW_SYSTEM 1001#ifdef HAVE_WINDOW_SYSTEM
971 f->vertical_scroll_bar_type = vertical_scroll_bar_none; 1002 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
972 f->horizontal_scroll_bars = false; 1003 f->horizontal_scroll_bars = false;
973 f->want_fullscreen = FULLSCREEN_NONE; 1004 f->want_fullscreen = FULLSCREEN_NONE;
974 f->undecorated = false; 1005 f->undecorated = false;
975 f->no_special_glyphs = false;
976#ifndef HAVE_NTGUI 1006#ifndef HAVE_NTGUI
977 f->override_redirect = false; 1007 f->override_redirect = false;
978#endif 1008#endif
@@ -1089,7 +1119,6 @@ make_frame (bool mini_p)
1089 return f; 1119 return f;
1090} 1120}
1091 1121
1092#ifdef HAVE_WINDOW_SYSTEM
1093/* Make a frame using a separate minibuffer window on another frame. 1122/* Make a frame using a separate minibuffer window on another frame.
1094 MINI_WINDOW is the minibuffer window to use. nil means use the 1123 MINI_WINDOW is the minibuffer window to use. nil means use the
1095 default (the global minibuffer). */ 1124 default (the global minibuffer). */
@@ -1183,7 +1212,7 @@ make_minibuffer_frame (void)
1183 : Fcar (Vminibuffer_list)), 0, 0); 1212 : Fcar (Vminibuffer_list)), 0, 0);
1184 return f; 1213 return f;
1185} 1214}
1186#endif /* HAVE_WINDOW_SYSTEM */ 1215
1187 1216
1188/* Construct a frame that refers to a terminal. */ 1217/* Construct a frame that refers to a terminal. */
1189 1218
@@ -1209,7 +1238,7 @@ make_initial_frame (void)
1209 tty_frame_count = 1; 1238 tty_frame_count = 1;
1210 fset_name (f, build_pure_c_string ("F1")); 1239 fset_name (f, build_pure_c_string ("F1"));
1211 1240
1212 SET_FRAME_VISIBLE (f, 1); 1241 SET_FRAME_VISIBLE (f, true);
1213 1242
1214 f->output_method = terminal->type; 1243 f->output_method = terminal->type;
1215 f->terminal = terminal; 1244 f->terminal = terminal;
@@ -1246,23 +1275,56 @@ make_initial_frame (void)
1246#ifndef HAVE_ANDROID 1275#ifndef HAVE_ANDROID
1247 1276
1248static struct frame * 1277static struct frame *
1249make_terminal_frame (struct terminal *terminal) 1278make_terminal_frame (struct terminal *terminal, Lisp_Object parent,
1279 Lisp_Object params)
1250{ 1280{
1251 register struct frame *f;
1252 Lisp_Object frame;
1253 char name[sizeof "F" + INT_STRLEN_BOUND (tty_frame_count)]; 1281 char name[sizeof "F" + INT_STRLEN_BOUND (tty_frame_count)];
1254 1282
1255 if (!terminal->name) 1283 if (!terminal->name)
1256 error ("Terminal is not live, can't create new frames on it"); 1284 error ("Terminal is not live, can't create new frames on it");
1257 1285
1258 f = make_frame (1); 1286 struct frame *f;
1287 if (NILP (parent))
1288 f = make_frame (true);
1289 else
1290 {
1291 CHECK_FRAME (parent);
1292
1293 f = NULL;
1294 Lisp_Object mini = Fassq (Qminibuffer, params);
1295 if (CONSP (mini))
1296 {
1297 mini = Fcdr (mini);
1298 struct kboard *kb = FRAME_KBOARD (XFRAME (parent));
1299 if (EQ (mini, Qnone) || NILP (mini))
1300 f = make_frame_without_minibuffer (Qnil, kb, Qnil);
1301 else if (EQ (mini, Qonly))
1302 {
1303 /* FIXME/tty: No interest in this feature at the moment,
1304 unless someone complains. */
1305# if 0
1306 f = make_minibuffer_frame ();
1307 /* Not sure about this plus the unsplittable frame
1308 paran. */
1309 f->no_split = true;
1310# endif
1311 }
1312 else if (WINDOWP (mini))
1313 f = make_frame_without_minibuffer (mini, kb, Qnil);
1314 }
1315
1316 if (f == NULL)
1317 f = make_frame (true);
1318 f->parent_frame = parent;
1319 }
1259 1320
1321 Lisp_Object frame;
1260 XSETFRAME (frame, f); 1322 XSETFRAME (frame, f);
1261 Vframe_list = Fcons (frame, Vframe_list); 1323 Vframe_list = Fcons (frame, Vframe_list);
1262 1324
1263 fset_name (f, make_formatted_string (name, "F%"PRIdMAX, ++tty_frame_count)); 1325 fset_name (f, make_formatted_string (name, "F%"PRIdMAX, ++tty_frame_count));
1264 1326
1265 SET_FRAME_VISIBLE (f, 1); 1327 SET_FRAME_VISIBLE (f, true);
1266 1328
1267 f->terminal = terminal; 1329 f->terminal = terminal;
1268 f->terminal->reference_count++; 1330 f->terminal->reference_count++;
@@ -1287,7 +1349,15 @@ make_terminal_frame (struct terminal *terminal)
1287 f->horizontal_scroll_bars = false; 1349 f->horizontal_scroll_bars = false;
1288#endif 1350#endif
1289 1351
1290 FRAME_MENU_BAR_LINES (f) = NILP (Vmenu_bar_mode) ? 0 : 1; 1352 /* FIXME/tty: menu bars on child frames don't work on all platforms,
1353 which is the reason why prepare_menu_bar does not update_menu_bar
1354 for child frames (info from Martin Rudalics). This could be
1355 implemented in ttys, but it's unclear if it is worth it. */
1356 if (NILP (parent))
1357 FRAME_MENU_BAR_LINES (f) = NILP (Vmenu_bar_mode) ? 0 : 1;
1358 else
1359 FRAME_MENU_BAR_LINES (f) = 0;
1360
1291 FRAME_TAB_BAR_LINES (f) = NILP (Vtab_bar_mode) ? 0 : 1; 1361 FRAME_TAB_BAR_LINES (f) = NILP (Vtab_bar_mode) ? 0 : 1;
1292 FRAME_LINES (f) = FRAME_LINES (f) - FRAME_MENU_BAR_LINES (f) 1362 FRAME_LINES (f) = FRAME_LINES (f) - FRAME_MENU_BAR_LINES (f)
1293 - FRAME_TAB_BAR_LINES (f); 1363 - FRAME_TAB_BAR_LINES (f);
@@ -1296,16 +1366,16 @@ make_terminal_frame (struct terminal *terminal)
1296 FRAME_TEXT_HEIGHT (f) = FRAME_TEXT_HEIGHT (f) - FRAME_MENU_BAR_HEIGHT (f) 1366 FRAME_TEXT_HEIGHT (f) = FRAME_TEXT_HEIGHT (f) - FRAME_MENU_BAR_HEIGHT (f)
1297 - FRAME_TAB_BAR_HEIGHT (f); 1367 - FRAME_TAB_BAR_HEIGHT (f);
1298 1368
1299 /* Set the top frame to the newly created frame. */ 1369 /* Mark current topmost frame obscured if we make a new root frame.
1370 Child frames don't completely obscure other frames. */
1300 if (FRAMEP (FRAME_TTY (f)->top_frame) 1371 if (FRAMEP (FRAME_TTY (f)->top_frame)
1301 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame))) 1372 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame))
1302 SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (f)->top_frame), 2); /* obscured */ 1373 && NILP (parent))
1303 1374 SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (f)->top_frame), false);
1304 FRAME_TTY (f)->top_frame = frame;
1305
1306 if (!noninteractive)
1307 init_frame_faces (f);
1308 1375
1376 /* Set the top frame to the newly created frame. */
1377 if (!FRAME_PARENT_FRAME (f))
1378 FRAME_TTY (f)->top_frame = frame;
1309 return f; 1379 return f;
1310} 1380}
1311 1381
@@ -1335,6 +1405,62 @@ get_future_frame_param (Lisp_Object parameter,
1335 1405
1336#endif 1406#endif
1337 1407
1408static int
1409tty_child_pos_param (struct frame *child, Lisp_Object key,
1410 Lisp_Object params, int dflt)
1411{
1412 Lisp_Object val = Fassq (key, params);
1413 if (CONSP (val))
1414 {
1415 val = XCDR (val);
1416 if (FIXNUMP (val))
1417 return XFIXNUM (val);
1418 }
1419 return dflt;
1420}
1421
1422static int
1423tty_child_size_param (struct frame *child, Lisp_Object key,
1424 Lisp_Object params, int dflt)
1425{
1426 Lisp_Object val = Fassq (key, params);
1427 if (CONSP (val))
1428 {
1429 val = XCDR (val);
1430 if (CONSP (val))
1431 {
1432 /* Width and height may look like (width text-pixels
1433 . PIXELS) on window systems. Mimic that. */
1434 val = XCDR (val);
1435 if (EQ (val, Qtext_pixels))
1436 val = XCDR (val);
1437 }
1438 else if (FLOATP (val))
1439 {
1440 /* Width and height may be a float, in which case
1441 it's a multiple of the parent's value. */
1442 struct frame *parent = FRAME_PARENT_FRAME (child);
1443 int sz = (EQ (key, Qwidth) ? FRAME_TOTAL_COLS (parent)
1444 : FRAME_TOTAL_LINES (parent));
1445 val = make_fixnum (XFLOAT_DATA (val) * sz);
1446 }
1447
1448 if (FIXNUMP (val) && XFIXNUM (val) > 0)
1449 return XFIXNUM (val);
1450 }
1451 return dflt;
1452}
1453
1454static void
1455child_frame_rect (struct frame *f, Lisp_Object params,
1456 int *x, int *y, int *w, int *h)
1457{
1458 *x = tty_child_pos_param (f, Qleft, params, 0);
1459 *y = tty_child_pos_param (f, Qtop, params, 0);
1460 *w = tty_child_size_param (f, Qwidth, params, FRAME_TOTAL_COLS (f));
1461 *h = tty_child_size_param (f, Qheight, params, FRAME_TOTAL_LINES (f));
1462}
1463
1338DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame, 1464DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
1339 1, 1, 0, 1465 1, 1, 0,
1340 doc: /* Create an additional terminal frame, possibly on another terminal. 1466 doc: /* Create an additional terminal frame, possibly on another terminal.
@@ -1358,9 +1484,7 @@ affects all frames on the same terminal device. */)
1358 error ("Text terminals are not supported on this platform"); 1484 error ("Text terminals are not supported on this platform");
1359 return Qnil; 1485 return Qnil;
1360#else 1486#else
1361 struct frame *f;
1362 struct terminal *t = NULL; 1487 struct terminal *t = NULL;
1363 Lisp_Object frame;
1364 struct frame *sf = SELECTED_FRAME (); 1488 struct frame *sf = SELECTED_FRAME ();
1365 1489
1366#ifdef MSDOS 1490#ifdef MSDOS
@@ -1390,7 +1514,7 @@ affects all frames on the same terminal device. */)
1390 error ("Multiple terminals are not supported on this platform"); 1514 error ("Multiple terminals are not supported on this platform");
1391 if (!t) 1515 if (!t)
1392 t = the_only_display_info.terminal; 1516 t = the_only_display_info.terminal;
1393#endif 1517# endif
1394 } 1518 }
1395 1519
1396 if (!t) 1520 if (!t)
@@ -1417,19 +1541,60 @@ affects all frames on the same terminal device. */)
1417 SAFE_FREE (); 1541 SAFE_FREE ();
1418 } 1542 }
1419 1543
1420 f = make_terminal_frame (t); 1544 /* Make a new frame. We need to know upfront if if a parent frame is
1545 specified because we behave differently in this case, e.g. child
1546 frames don't obscure other frames. */
1547 Lisp_Object parent = Fcdr (Fassq (Qparent_frame, parms));
1548 struct frame *f = make_terminal_frame (t, parent, parms);
1421 1549
1422 { 1550 if (!noninteractive)
1423 int width, height; 1551 init_frame_faces (f);
1424 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
1425 /* With INHIBIT 5 pass correct text height to adjust_frame_size. */
1426 adjust_frame_size (f, width, height - FRAME_TOP_MARGIN (f),
1427 5, 0, Qterminal_frame);
1428 }
1429 1552
1553 /* Visibility of root frames cannot be set with a frame parameter.
1554 Their visibility solely depends on whether or not they are the
1555 top_frame on the terminal. */
1556 if (FRAME_PARENT_FRAME (f))
1557 {
1558 Lisp_Object visible = Fassq (Qvisibility, parms);
1559 if (CONSP (visible))
1560 SET_FRAME_VISIBLE (f, !NILP (visible));
1561
1562 /* FIXME/tty: Not having borders is currently deeply
1563 engraved in the code, so we can't naively do it. */
1564#if 0
1565 Lisp_Object border = Fcdr (Fassq (Qborder_width, parms));
1566 if (FIXNUMP (border))
1567 f->border_width = XFIXNUM (border);
1568 border = Fcdr (Fassq (Qchild_frame_border_width, parms));
1569 if (FIXNUMP (border))
1570 f->child_frame_border_width = XFIXNUM (border);
1571# endif
1572 }
1573
1574 /* Determine width and height of the frame. For root frames use the
1575 width/height of the terminal. For child frames, take it from frame
1576 parameters. Note that a default (80x25) has been set in
1577 make_frame. We handle root frames in this way because otherwise we
1578 would end up needing glyph matrices for the terminal, which is both
1579 more work and has its downsides (think of clipping frames to the
1580 terminal size). */
1581 int x = 0, y = 0, width, height;
1582 if (FRAME_PARENT_FRAME (f))
1583 child_frame_rect (f, parms, &x, &y, &width, &height);
1584 else
1585 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
1586 adjust_frame_size (f, width, height - FRAME_TOP_MARGIN (f), 5, 0,
1587 Qterminal_frame);
1430 adjust_frame_glyphs (f); 1588 adjust_frame_glyphs (f);
1589
1431 calculate_costs (f); 1590 calculate_costs (f);
1432 XSETFRAME (frame, f); 1591
1592 f->left_pos = x;
1593 f->top_pos = y;
1594 store_in_alist (&parms, Qleft, make_fixnum (x));
1595 store_in_alist (&parms, Qtop, make_fixnum (y));
1596 store_in_alist (&parms, Qwidth, make_fixnum (width));
1597 store_in_alist (&parms, Qheight, make_fixnum (height));
1433 1598
1434 store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type)); 1599 store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type));
1435 store_in_alist (&parms, Qtty, 1600 store_in_alist (&parms, Qtty,
@@ -1451,7 +1616,11 @@ affects all frames on the same terminal device. */)
1451 /* On terminal frames the `minibuffer' frame parameter is always 1616 /* On terminal frames the `minibuffer' frame parameter is always
1452 virtually t. Avoid that a different value in parms causes 1617 virtually t. Avoid that a different value in parms causes
1453 complaints, see Bug#24758. */ 1618 complaints, see Bug#24758. */
1454 store_in_alist (&parms, Qminibuffer, Qt); 1619 if (!FRAME_PARENT_FRAME (f))
1620 store_in_alist (&parms, Qminibuffer, Qt);
1621
1622 Lisp_Object frame;
1623 XSETFRAME (frame, f);
1455 Fmodify_frame_parameters (frame, parms); 1624 Fmodify_frame_parameters (frame, parms);
1456 1625
1457 f->can_set_window_size = true; 1626 f->can_set_window_size = true;
@@ -1546,24 +1715,32 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1546 struct tty_display_info *tty = FRAME_TTY (f); 1715 struct tty_display_info *tty = FRAME_TTY (f);
1547 Lisp_Object top_frame = tty->top_frame; 1716 Lisp_Object top_frame = tty->top_frame;
1548 1717
1549 /* Don't mark the frame garbaged and/or obscured if we are 1718 /* Don't mark the frame garbaged if we are switching to the frame
1550 switching to the frame that is already the top frame of that 1719 that is already the top frame of that TTY. */
1551 TTY. */
1552 if (!EQ (frame, top_frame)) 1720 if (!EQ (frame, top_frame))
1553 { 1721 {
1554 if (FRAMEP (top_frame)) 1722 SET_FRAME_VISIBLE (f, true);
1555 /* Mark previously displayed frame as now obscured. */ 1723 if (is_tty_root_frame (f))
1556 SET_FRAME_VISIBLE (XFRAME (top_frame), 2); 1724 {
1557 SET_FRAME_VISIBLE (f, 1); 1725 /* Mark previously displayed frame as no longer visible. */
1558 /* If the new TTY frame changed dimensions, we need to 1726 if (FRAMEP (top_frame))
1559 resync term.c's idea of the frame size with the new 1727 SET_FRAME_VISIBLE (XFRAME (top_frame), false);
1560 frame's data. */ 1728
1561 if (FRAME_COLS (f) != FrameCols (tty)) 1729 tty->top_frame = frame;
1562 FrameCols (tty) = FRAME_COLS (f); 1730
1563 if (FRAME_TOTAL_LINES (f) != FrameRows (tty)) 1731 /* If the new TTY frame changed dimensions, we need to
1564 FrameRows (tty) = FRAME_TOTAL_LINES (f); 1732 resync term.c's idea of the frame size with the new
1733 frame's data. */
1734 /* FIXME/tty: another place where we set
1735 FrameRows/FrameCols, which is really a physical
1736 property of the terminal, and nothing we set. That
1737 doesn't look right to me. */
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 }
1565 } 1743 }
1566 tty->top_frame = frame;
1567 } 1744 }
1568 1745
1569 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));
@@ -1605,9 +1782,7 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
1605 (select-window (frame-root-window (make-frame))) doesn't end up 1782 (select-window (frame-root-window (make-frame))) doesn't end up
1606 with your typing being interpreted in the new frame instead of 1783 with your typing being interpreted in the new frame instead of
1607 the one you're actually typing in. */ 1784 the one you're actually typing in. */
1608#ifdef HAVE_WINDOW_SYSTEM
1609 if (!frame_ancestor_p (f, sf)) 1785 if (!frame_ancestor_p (f, sf))
1610#endif
1611 internal_last_event_frame = Qnil; 1786 internal_last_event_frame = Qnil;
1612 1787
1613 return frame; 1788 return frame;
@@ -1725,7 +1900,6 @@ parent window is the window-system's root window) or an embedded window
1725 return Qnil; 1900 return Qnil;
1726} 1901}
1727 1902
1728#ifdef HAVE_WINDOW_SYSTEM
1729bool 1903bool
1730frame_ancestor_p (struct frame *af, struct frame *df) 1904frame_ancestor_p (struct frame *af, struct frame *df)
1731{ 1905{
@@ -1741,7 +1915,6 @@ frame_ancestor_p (struct frame *af, struct frame *df)
1741 1915
1742 return false; 1916 return false;
1743} 1917}
1744#endif
1745 1918
1746DEFUN ("frame-ancestor-p", Fframe_ancestor_p, Sframe_ancestor_p, 1919DEFUN ("frame-ancestor-p", Fframe_ancestor_p, Sframe_ancestor_p,
1747 2, 2, 0, 1920 2, 2, 0,
@@ -1752,15 +1925,10 @@ ANCESTOR and DESCENDANT must be live frames and default to the selected
1752frame. */) 1925frame. */)
1753 (Lisp_Object ancestor, Lisp_Object descendant) 1926 (Lisp_Object ancestor, Lisp_Object descendant)
1754{ 1927{
1755#ifdef HAVE_WINDOW_SYSTEM
1756 struct frame *af = decode_live_frame (ancestor); 1928 struct frame *af = decode_live_frame (ancestor);
1757 struct frame *df = decode_live_frame (descendant); 1929 struct frame *df = decode_live_frame (descendant);
1758
1759 return frame_ancestor_p (af, df) ? Qt : Qnil; 1930 return frame_ancestor_p (af, df) ? Qt : Qnil;
1760#else 1931}
1761 return Qnil;
1762#endif
1763 }
1764 1932
1765/* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the 1933/* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the
1766 same tty (for tty frames) or among frames which uses FRAME's keyboard. 1934 same tty (for tty frames) or among frames which uses FRAME's keyboard.
@@ -2282,7 +2450,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
2282 fset_root_window (f, Qnil); 2450 fset_root_window (f, Qnil);
2283 2451
2284 Vframe_list = Fdelq (frame, Vframe_list); 2452 Vframe_list = Fdelq (frame, Vframe_list);
2285 SET_FRAME_VISIBLE (f, 0); 2453 SET_FRAME_VISIBLE (f, false);
2286 2454
2287 /* Allow the vector of menu bar contents to be freed in the next 2455 /* Allow the vector of menu bar contents to be freed in the next
2288 garbage collection. The frame object itself may not be garbage 2456 garbage collection. The frame object itself may not be garbage
@@ -2868,6 +3036,9 @@ If omitted, FRAME defaults to the currently selected frame. */)
2868 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook) 3036 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook)
2869 FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, true); 3037 FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, true);
2870 3038
3039 if (is_tty_frame (f))
3040 SET_FRAME_VISIBLE (f, true);
3041
2871 make_frame_visible_1 (f->root_window); 3042 make_frame_visible_1 (f->root_window);
2872 3043
2873 /* Make menu bar update for the Buffers and Frames menus. */ 3044 /* Make menu bar update for the Buffers and Frames menus. */
@@ -2918,6 +3089,12 @@ displayed in the terminal. */)
2918 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook) 3089 if (FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->frame_visible_invisible_hook)
2919 FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, false); 3090 FRAME_TERMINAL (f)->frame_visible_invisible_hook (f, false);
2920 3091
3092 /* FIXME/tty: the Elisp info manual says that this "usually" makes
3093 child frames invisible, too, but without saying when not. Since users
3094 can't rely on this, it's not implemented. */
3095 if (is_tty_frame (f))
3096 SET_FRAME_VISIBLE (f, false);
3097
2921 /* Make menu bar update for the Buffers and Frames menus. */ 3098 /* Make menu bar update for the Buffers and Frames menus. */
2922 windows_or_buffers_changed = 16; 3099 windows_or_buffers_changed = 16;
2923 3100
@@ -3012,12 +3189,7 @@ doesn't support multiple overlapping frames, this function selects FRAME. */)
3012 3189
3013 XSETFRAME (frame, f); 3190 XSETFRAME (frame, f);
3014 3191
3015 if (FRAME_TERMCAP_P (f)) 3192 Fmake_frame_visible (frame);
3016 /* On a text terminal select FRAME. */
3017 Fselect_frame (frame, Qnil);
3018 else
3019 /* Do like the documentation says. */
3020 Fmake_frame_visible (frame);
3021 3193
3022 if (FRAME_TERMINAL (f)->frame_raise_lower_hook) 3194 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
3023 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, true); 3195 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, true);
@@ -3318,6 +3490,16 @@ store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
3318 val = old_val; 3490 val = old_val;
3319 } 3491 }
3320 3492
3493 /* FIXME/tty: re-parenting is currently not implemented when changing
3494 a root frame to a child frame or vice versa. Could be done, but
3495 it's unclear if it's worth it. */
3496 if (is_tty_frame (f))
3497 {
3498 if (EQ (prop, Qparent_frame)
3499 && NILP (f->parent_frame) != NILP (val))
3500 error ("Making a root frame a child or vice versa is not supported");
3501 }
3502
3321 /* The tty color needed to be set before the frame's parameter 3503 /* The tty color needed to be set before the frame's parameter
3322 alist was updated with the new value. This is not true any more, 3504 alist was updated with the new value. This is not true any more,
3323 but we still do this test early on. */ 3505 but we still do this test early on. */
@@ -3441,13 +3623,9 @@ If FRAME is omitted or nil, return information on the currently selected frame.
3441 else 3623 else
3442#endif 3624#endif
3443 { 3625 {
3444 /* This ought to be correct in f->param_alist for an X frame. */ 3626 store_in_alist (&alist, Qmenu_bar_lines, make_fixnum (FRAME_MENU_BAR_LINES (f)));
3445 Lisp_Object lines; 3627 store_in_alist (&alist, Qtab_bar_lines, make_fixnum (FRAME_TAB_BAR_LINES (f)));
3446 3628 store_in_alist (&alist, Qvisibility, FRAME_VISIBLE_P (f) ? Qt : Qnil);
3447 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
3448 store_in_alist (&alist, Qmenu_bar_lines, lines);
3449 XSETFASTINT (lines, FRAME_TAB_BAR_LINES (f));
3450 store_in_alist (&alist, Qtab_bar_lines, lines);
3451 } 3629 }
3452 3630
3453 return alist; 3631 return alist;
@@ -3525,7 +3703,6 @@ If FRAME is nil, describe the currently selected frame. */)
3525 return value; 3703 return value;
3526} 3704}
3527 3705
3528
3529DEFUN ("modify-frame-parameters", Fmodify_frame_parameters, 3706DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
3530 Smodify_frame_parameters, 2, 2, 0, 3707 Smodify_frame_parameters, 2, 2, 0,
3531 doc: /* Modify FRAME according to new values of its parameters in ALIST. 3708 doc: /* Modify FRAME according to new values of its parameters in ALIST.
@@ -3563,6 +3740,7 @@ list, but are otherwise ignored. */)
3563 USE_SAFE_ALLOCA; 3740 USE_SAFE_ALLOCA;
3564 SAFE_ALLOCA_LISP (parms, 2 * length); 3741 SAFE_ALLOCA_LISP (parms, 2 * length);
3565 values = parms + length; 3742 values = parms + length;
3743 Lisp_Object params = alist;
3566 3744
3567 /* Extract parm names and values into those vectors. */ 3745 /* Extract parm names and values into those vectors. */
3568 3746
@@ -3588,6 +3766,25 @@ list, but are otherwise ignored. */)
3588 update_face_from_frame_parameter (f, prop, val); 3766 update_face_from_frame_parameter (f, prop, val);
3589 } 3767 }
3590 3768
3769 if (is_tty_child_frame (f))
3770 {
3771 f->left_pos = tty_child_pos_param (f, Qleft, params, f->left_pos);
3772 f->top_pos = tty_child_pos_param (f, Qtop, params, f->top_pos);
3773
3774 int w = tty_child_size_param (f, Qwidth, params, f->total_cols);
3775 int h = tty_child_size_param (f, Qheight, params, f->total_lines);
3776 if (w != f->total_cols || h != f->total_lines)
3777 change_frame_size (f, w, h, false, false, false);
3778
3779 Lisp_Object visible = Fassq (Qvisibility, params);
3780 if (CONSP (visible))
3781 SET_FRAME_VISIBLE (f, !NILP (Fcdr (visible)));
3782
3783 Lisp_Object no_special = Fassq (Qno_special_glyphs, params);
3784 if (CONSP (no_special))
3785 FRAME_NO_SPECIAL_GLYPHS (f) = !NILP (Fcdr (no_special));
3786 }
3787
3591 SAFE_FREE (); 3788 SAFE_FREE ();
3592 } 3789 }
3593 return Qnil; 3790 return Qnil;
@@ -3935,6 +4132,11 @@ bottom edge of FRAME's display. */)
3935 (void) yval; 4132 (void) yval;
3936#endif 4133#endif
3937 } 4134 }
4135 else if (is_tty_child_frame (f))
4136 {
4137 f->left_pos = xval;
4138 f->top_pos = yval;
4139 }
3938 4140
3939 return Qt; 4141 return Qt;
3940} 4142}
@@ -4246,6 +4448,28 @@ frame_float (struct frame *f, Lisp_Object val, enum frame_float_type what,
4246 } 4448 }
4247} 4449}
4248 4450
4451/* Handle frame parameter change with frame parameter handler. F is the
4452 frame whose frame parameter was changed. PROP is the name of the
4453 frame parameter. VAL and OLD_VALUE are the current value and old
4454 value of the frame parameter. */
4455
4456static void
4457handle_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val,
4458 Lisp_Object old_value)
4459{
4460 Lisp_Object param_index = Fget (prop, Qx_frame_parameter);
4461 if (FIXNATP (param_index) && XFIXNAT (param_index) < ARRAYELTS (frame_parms))
4462 {
4463 if (FRAME_RIF (f))
4464 {
4465 frame_parm_handler handler
4466 = FRAME_RIF (f)->frame_parm_handlers[XFIXNAT (param_index)];
4467 if (handler)
4468 handler (f, val, old_value);
4469 }
4470 }
4471}
4472
4249/* Change the parameters of frame F as specified by ALIST. 4473/* Change the parameters of frame F as specified by ALIST.
4250 If a parameter is not specially recognized, do nothing special; 4474 If a parameter is not specially recognized, do nothing special;
4251 otherwise call the `gui_set_...' function for that parameter. 4475 otherwise call the `gui_set_...' function for that parameter.
@@ -4387,17 +4611,9 @@ gui_set_frame_parameters_1 (struct frame *f, Lisp_Object alist,
4387 } 4611 }
4388 else 4612 else
4389 { 4613 {
4390 Lisp_Object param_index, old_value; 4614 Lisp_Object old_value = get_frame_param (f, prop);
4391
4392 old_value = get_frame_param (f, prop);
4393
4394 store_frame_param (f, prop, val); 4615 store_frame_param (f, prop, val);
4395 4616 handle_frame_param (f, prop, val, old_value);
4396 param_index = Fget (prop, Qx_frame_parameter);
4397 if (FIXNATP (param_index)
4398 && XFIXNAT (param_index) < ARRAYELTS (frame_parms)
4399 && FRAME_RIF (f)->frame_parm_handlers[XFIXNUM (param_index)])
4400 (*(FRAME_RIF (f)->frame_parm_handlers[XFIXNUM (param_index)])) (f, val, old_value);
4401 4617
4402 if (!default_parameter && EQ (prop, Qfont)) 4618 if (!default_parameter && EQ (prop, Qfont))
4403 /* The user manually specified the `font' frame parameter. 4619 /* The user manually specified the `font' frame parameter.
@@ -4716,14 +4932,7 @@ gui_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_va
4716 /* Apply the new gamma value to the frame background. */ 4932 /* Apply the new gamma value to the frame background. */
4717 bgcolor = Fassq (Qbackground_color, f->param_alist); 4933 bgcolor = Fassq (Qbackground_color, f->param_alist);
4718 if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor))) 4934 if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor)))
4719 { 4935 handle_frame_param (f, Qbackground_color, bgcolor, Qnil);
4720 Lisp_Object parm_index = Fget (Qbackground_color, Qx_frame_parameter);
4721 if (FIXNATP (parm_index)
4722 && XFIXNAT (parm_index) < ARRAYELTS (frame_parms)
4723 && FRAME_RIF (f)->frame_parm_handlers[XFIXNAT (parm_index)])
4724 (*FRAME_RIF (f)->frame_parm_handlers[XFIXNAT (parm_index)])
4725 (f, bgcolor, Qnil);
4726 }
4727 4936
4728 clear_face_cache (true); /* FIXME: Why of all frames? */ 4937 clear_face_cache (true); /* FIXME: Why of all frames? */
4729 fset_redisplay (f); 4938 fset_redisplay (f);
diff --git a/src/frame.h b/src/frame.h
index 1d920d1a6bc..6a636ecec3f 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. */
@@ -486,11 +477,11 @@ struct frame
486 477
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. */
@@ -740,7 +731,10 @@ struct frame
740#ifdef HAVE_TEXT_CONVERSION 731#ifdef HAVE_TEXT_CONVERSION
741 /* Text conversion state used by certain input methods. */ 732 /* Text conversion state used by certain input methods. */
742 struct text_conversion_state conversion; 733 struct text_conversion_state conversion;
743#endif 734# endif
735
736 /* Z-order of child frames. */
737 int z_order;
744} GCALIGNED_STRUCT; 738} GCALIGNED_STRUCT;
745 739
746/* Most code should use these functions to set Lisp fields in struct frame. */ 740/* Most code should use these functions to set Lisp fields in struct frame. */
@@ -1021,9 +1015,11 @@ default_pixels_per_inch_y (void)
1021 does not have FRAME_DISPLAY_INFO. */ 1015 does not have FRAME_DISPLAY_INFO. */
1022#ifdef HAVE_WINDOW_SYSTEM 1016#ifdef HAVE_WINDOW_SYSTEM
1023#ifndef HAVE_ANDROID 1017#ifndef HAVE_ANDROID
1024# define MOUSE_HL_INFO(F) \ 1018# define MOUSE_HL_INFO(F) \
1025 (FRAME_WINDOW_P (F) \ 1019 (FRAME_WINDOW_P (F) \
1026 ? &FRAME_DISPLAY_INFO(F)->mouse_highlight \ 1020 ? (FRAME_OUTPUT_DATA (F) \
1021 ? &FRAME_DISPLAY_INFO (F)->mouse_highlight \
1022 : NULL) \
1027 : &(F)->output_data.tty->display_info->mouse_highlight) 1023 : &(F)->output_data.tty->display_info->mouse_highlight)
1028#else 1024#else
1029/* There is no "struct tty_output" on Android at all. */ 1025/* There is no "struct tty_output" on Android at all. */
@@ -1176,9 +1172,6 @@ default_pixels_per_inch_y (void)
1176 && FRAME_X_VISIBLE (f))) 1172 && FRAME_X_VISIBLE (f)))
1177#endif 1173#endif
1178 1174
1179/* True if frame F is currently visible but hidden. */
1180#define FRAME_OBSCURED_P(f) ((f)->visible > 1)
1181
1182/* True if frame F is currently iconified. */ 1175/* True if frame F is currently iconified. */
1183#define FRAME_ICONIFIED_P(f) (f)->iconified 1176#define FRAME_ICONIFIED_P(f) (f)->iconified
1184 1177
@@ -1243,6 +1236,12 @@ default_pixels_per_inch_y (void)
1243#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) ((void) (f), 0) 1236#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) ((void) (f), 0)
1244#endif /* HAVE_WINDOW_SYSTEM */ 1237#endif /* HAVE_WINDOW_SYSTEM */
1245 1238
1239INLINE struct frame *
1240FRAME_PARENT_FRAME (struct frame *f)
1241{
1242 return NILP (f->parent_frame) ? NULL : XFRAME (f->parent_frame);
1243}
1244
1246#if defined (HAVE_WINDOW_SYSTEM) 1245#if defined (HAVE_WINDOW_SYSTEM)
1247#define FRAME_UNDECORATED(f) ((f)->undecorated) 1246#define FRAME_UNDECORATED(f) ((f)->undecorated)
1248#ifdef HAVE_NTGUI 1247#ifdef HAVE_NTGUI
@@ -1250,14 +1249,9 @@ default_pixels_per_inch_y (void)
1250#else 1249#else
1251#define FRAME_OVERRIDE_REDIRECT(f) ((f)->override_redirect) 1250#define FRAME_OVERRIDE_REDIRECT(f) ((f)->override_redirect)
1252#endif 1251#endif
1253#define FRAME_PARENT_FRAME(f) \
1254 (NILP ((f)->parent_frame) \
1255 ? NULL \
1256 : XFRAME ((f)->parent_frame))
1257#define FRAME_SKIP_TASKBAR(f) ((f)->skip_taskbar) 1252#define FRAME_SKIP_TASKBAR(f) ((f)->skip_taskbar)
1258#define FRAME_NO_FOCUS_ON_MAP(f) ((f)->no_focus_on_map) 1253#define FRAME_NO_FOCUS_ON_MAP(f) ((f)->no_focus_on_map)
1259#define FRAME_NO_ACCEPT_FOCUS(f) ((f)->no_accept_focus) 1254#define FRAME_NO_ACCEPT_FOCUS(f) ((f)->no_accept_focus)
1260#define FRAME_NO_SPECIAL_GLYPHS(f) ((f)->no_special_glyphs)
1261#define FRAME_Z_GROUP(f) ((f)->z_group) 1255#define FRAME_Z_GROUP(f) ((f)->z_group)
1262#define FRAME_Z_GROUP_NONE(f) ((f)->z_group == z_group_none) 1256#define FRAME_Z_GROUP_NONE(f) ((f)->z_group == z_group_none)
1263#define FRAME_Z_GROUP_ABOVE(f) ((f)->z_group == z_group_above) 1257#define FRAME_Z_GROUP_ABOVE(f) ((f)->z_group == z_group_above)
@@ -1272,11 +1266,9 @@ default_pixels_per_inch_y (void)
1272#else /* not HAVE_WINDOW_SYSTEM */ 1266#else /* not HAVE_WINDOW_SYSTEM */
1273#define FRAME_UNDECORATED(f) ((void) (f), 0) 1267#define FRAME_UNDECORATED(f) ((void) (f), 0)
1274#define FRAME_OVERRIDE_REDIRECT(f) ((void) (f), 0) 1268#define FRAME_OVERRIDE_REDIRECT(f) ((void) (f), 0)
1275#define FRAME_PARENT_FRAME(f) ((void) (f), NULL)
1276#define FRAME_SKIP_TASKBAR(f) ((void) (f), 0) 1269#define FRAME_SKIP_TASKBAR(f) ((void) (f), 0)
1277#define FRAME_NO_FOCUS_ON_MAP(f) ((void) (f), 0) 1270#define FRAME_NO_FOCUS_ON_MAP(f) ((void) (f), 0)
1278#define FRAME_NO_ACCEPT_FOCUS(f) ((void) (f), 0) 1271#define FRAME_NO_ACCEPT_FOCUS(f) ((void) (f), 0)
1279#define FRAME_NO_SPECIAL_GLYPHS(f) ((void) (f), 0)
1280#define FRAME_Z_GROUP(f) ((void) (f), z_group_none) 1272#define FRAME_Z_GROUP(f) ((void) (f), z_group_none)
1281#define FRAME_Z_GROUP_NONE(f) ((void) (f), true) 1273#define FRAME_Z_GROUP_NONE(f) ((void) (f), true)
1282#define FRAME_Z_GROUP_ABOVE(f) ((void) (f), false) 1274#define FRAME_Z_GROUP_ABOVE(f) ((void) (f), false)
@@ -1284,6 +1276,8 @@ default_pixels_per_inch_y (void)
1284#define FRAME_TOOLTIP_P(f) ((void) f, false) 1276#define FRAME_TOOLTIP_P(f) ((void) f, false)
1285#endif /* HAVE_WINDOW_SYSTEM */ 1277#endif /* HAVE_WINDOW_SYSTEM */
1286 1278
1279#define FRAME_NO_SPECIAL_GLYPHS(f) ((f)->no_special_glyphs)
1280
1287/* Whether horizontal scroll bars are currently enabled for frame F. */ 1281/* Whether horizontal scroll bars are currently enabled for frame F. */
1288#if USE_HORIZONTAL_SCROLL_BARS 1282#if USE_HORIZONTAL_SCROLL_BARS
1289#define FRAME_HAS_HORIZONTAL_SCROLL_BARS(f) \ 1283#define FRAME_HAS_HORIZONTAL_SCROLL_BARS(f) \
@@ -1445,9 +1439,8 @@ extern bool frame_garbaged;
1445 if some changes were applied to it while it wasn't visible (and hence 1439 if some changes were applied to it while it wasn't visible (and hence
1446 wasn't redisplayed). */ 1440 wasn't redisplayed). */
1447INLINE void 1441INLINE void
1448SET_FRAME_VISIBLE (struct frame *f, int v) 1442SET_FRAME_VISIBLE (struct frame *f, bool v)
1449{ 1443{
1450 eassert (0 <= v && v <= 2);
1451 if (v) 1444 if (v)
1452 { 1445 {
1453 if (v == 1 && f->visible != 1) 1446 if (v == 1 && f->visible != 1)
@@ -1504,13 +1497,14 @@ extern struct frame *decode_any_frame (Lisp_Object);
1504extern struct frame *make_initial_frame (void); 1497extern struct frame *make_initial_frame (void);
1505extern struct frame *make_frame (bool); 1498extern struct frame *make_frame (bool);
1506#ifdef HAVE_WINDOW_SYSTEM 1499#ifdef HAVE_WINDOW_SYSTEM
1507extern struct frame *make_minibuffer_frame (void);
1508extern struct frame *make_frame_without_minibuffer (Lisp_Object,
1509 struct kboard *,
1510 Lisp_Object);
1511extern bool display_available (void); 1500extern bool display_available (void);
1512#endif 1501#endif
1513 1502
1503struct frame *make_minibuffer_frame (void);
1504struct frame *
1505make_frame_without_minibuffer (Lisp_Object mini_window,
1506 KBOARD *kb, Lisp_Object display);
1507
1514INLINE bool 1508INLINE bool
1515window_system_available (struct frame *f) 1509window_system_available (struct frame *f)
1516{ 1510{
@@ -1522,6 +1516,8 @@ window_system_available (struct frame *f)
1522} 1516}
1523 1517
1524extern WINDOW_SYSTEM_RETURN void check_window_system (struct frame *); 1518extern WINDOW_SYSTEM_RETURN void check_window_system (struct frame *);
1519void check_tty (struct frame *f);
1520struct frame *decode_tty_frame (Lisp_Object frame);
1525extern void frame_make_pointer_invisible (struct frame *); 1521extern void frame_make_pointer_invisible (struct frame *);
1526extern void frame_make_pointer_visible (struct frame *); 1522extern void frame_make_pointer_visible (struct frame *);
1527extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object); 1523extern Lisp_Object delete_frame (Lisp_Object, Lisp_Object);
@@ -1617,15 +1613,11 @@ FRAME_CHILD_FRAME_BORDER_WIDTH (struct frame *f)
1617INLINE int 1613INLINE int
1618FRAME_INTERNAL_BORDER_WIDTH (struct frame *f) 1614FRAME_INTERNAL_BORDER_WIDTH (struct frame *f)
1619{ 1615{
1620#ifdef HAVE_WINDOW_SYSTEM
1621 return (FRAME_PARENT_FRAME(f) 1616 return (FRAME_PARENT_FRAME(f)
1622 ? (FRAME_CHILD_FRAME_BORDER_WIDTH(f) >= 0 1617 ? (FRAME_CHILD_FRAME_BORDER_WIDTH(f) >= 0
1623 ? FRAME_CHILD_FRAME_BORDER_WIDTH(f) 1618 ? FRAME_CHILD_FRAME_BORDER_WIDTH(f)
1624 : frame_dimension (f->internal_border_width)) 1619 : frame_dimension (f->internal_border_width))
1625 : frame_dimension (f->internal_border_width)); 1620 : frame_dimension (f->internal_border_width));
1626#else
1627 return frame_dimension (f->internal_border_width);
1628#endif
1629} 1621}
1630 1622
1631/* Pixel-size of window divider lines. */ 1623/* Pixel-size of window divider lines. */
@@ -1880,7 +1872,6 @@ extern Lisp_Object gui_display_get_resource (Display_Info *,
1880extern void set_frame_menubar (struct frame *f, bool deep_p); 1872extern void set_frame_menubar (struct frame *f, bool deep_p);
1881extern void frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y); 1873extern void frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y);
1882extern void free_frame_menubar (struct frame *); 1874extern void free_frame_menubar (struct frame *);
1883extern bool frame_ancestor_p (struct frame *af, struct frame *df);
1884extern enum internal_border_part frame_internal_border_part (struct frame *f, int x, int y); 1875extern enum internal_border_part frame_internal_border_part (struct frame *f, int x, int y);
1885 1876
1886#if defined HAVE_X_WINDOWS 1877#if defined HAVE_X_WINDOWS
@@ -1907,6 +1898,8 @@ gui_set_bitmap_icon (struct frame *f)
1907#endif /* !HAVE_NS */ 1898#endif /* !HAVE_NS */
1908#endif /* HAVE_WINDOW_SYSTEM */ 1899#endif /* HAVE_WINDOW_SYSTEM */
1909 1900
1901extern bool frame_ancestor_p (struct frame *af, struct frame *df);
1902
1910INLINE void 1903INLINE void
1911flush_frame (struct frame *f) 1904flush_frame (struct frame *f)
1912{ 1905{
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 1f94e0e650e..c8267045397 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 f68a22d9fbc..7ad794b6bdb 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..37c0780b555 100644
--- a/src/term.c
+++ b/src/term.c
@@ -65,8 +65,8 @@ 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 *); 71static void tty_show_cursor (struct tty_display_info *);
72static void tty_hide_cursor (struct tty_display_info *); 72static void tty_hide_cursor (struct tty_display_info *);
@@ -788,13 +788,20 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
788 /* Identify a run of glyphs with the same face. */ 788 /* Identify a run of glyphs with the same face. */
789 int face_id = string->face_id; 789 int face_id = string->face_id;
790 790
791 /* FIXME/tty: it happens that a single glyph's frame is NULL. It
792 might depend on a tab bar line being present, then switching
793 from a buffer without header line to one with header line and
794 opening a child frame. */
795 struct frame *face_id_frame = string->frame ? string->frame : f;
796
791 for (n = 1; n < stringlen; ++n) 797 for (n = 1; n < stringlen; ++n)
792 if (string[n].face_id != face_id) 798 if (string[n].face_id != face_id || string[n].frame != face_id_frame)
793 break; 799 break;
794 800
795 /* Turn appearance modes of the face of the run on. */ 801 /* Turn appearance modes of the face of the run on. */
796 tty_highlight_if_desired (tty); 802 tty_highlight_if_desired (tty);
797 turn_on_face (f, face_id); 803 struct face *face = FACE_FROM_ID (face_id_frame, face_id);
804 turn_on_face (f, face);
798 805
799 if (n == stringlen) 806 if (n == stringlen)
800 /* This is the last run. */ 807 /* This is the last run. */
@@ -812,7 +819,7 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
812 string += n; 819 string += n;
813 820
814 /* Turn appearance modes off. */ 821 /* Turn appearance modes off. */
815 turn_off_face (f, face_id); 822 turn_off_face (f, face);
816 tty_turn_off_highlight (tty); 823 tty_turn_off_highlight (tty);
817 } 824 }
818 825
@@ -822,8 +829,8 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
822#ifndef DOS_NT 829#ifndef DOS_NT
823 830
824static void 831static void
825tty_write_glyphs_with_face (register struct frame *f, register struct glyph *string, 832tty_write_glyphs_with_face (struct frame *f, struct glyph *string,
826 register int len, register int face_id) 833 int len, struct face *face)
827{ 834{
828 unsigned char *conversion_buffer; 835 unsigned char *conversion_buffer;
829 struct coding_system *coding; 836 struct coding_system *coding;
@@ -856,7 +863,7 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str
856 863
857 /* Turn appearance modes of the face. */ 864 /* Turn appearance modes of the face. */
858 tty_highlight_if_desired (tty); 865 tty_highlight_if_desired (tty);
859 turn_on_face (f, face_id); 866 turn_on_face (f, face);
860 867
861 coding->mode |= CODING_MODE_LAST_BLOCK; 868 coding->mode |= CODING_MODE_LAST_BLOCK;
862 conversion_buffer = encode_terminal_code (string, len, coding); 869 conversion_buffer = encode_terminal_code (string, len, coding);
@@ -871,7 +878,7 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str
871 } 878 }
872 879
873 /* Turn appearance modes off. */ 880 /* Turn appearance modes off. */
874 turn_off_face (f, face_id); 881 turn_off_face (f, face);
875 tty_turn_off_highlight (tty); 882 tty_turn_off_highlight (tty);
876 883
877 cmcheckmagic (tty); 884 cmcheckmagic (tty);
@@ -919,6 +926,7 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
919 926
920 while (len-- > 0) 927 while (len-- > 0)
921 { 928 {
929 struct face *face = NULL;
922 OUTPUT1_IF (tty, tty->TS_ins_char); 930 OUTPUT1_IF (tty, tty->TS_ins_char);
923 if (!start) 931 if (!start)
924 { 932 {
@@ -928,7 +936,10 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
928 else 936 else
929 { 937 {
930 tty_highlight_if_desired (tty); 938 tty_highlight_if_desired (tty);
931 turn_on_face (f, start->face_id); 939 int face_id = start->face_id;
940 struct frame *face_id_frame = start->frame;
941 face = FACE_FROM_ID (face_id_frame, face_id);
942 turn_on_face (f, face);
932 glyph = start; 943 glyph = start;
933 ++start; 944 ++start;
934 /* We must open sufficient space for a character which 945 /* We must open sufficient space for a character which
@@ -957,9 +968,9 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
957 } 968 }
958 969
959 OUTPUT1_IF (tty, tty->TS_pad_inserted_char); 970 OUTPUT1_IF (tty, tty->TS_pad_inserted_char);
960 if (start) 971 if (face)
961 { 972 {
962 turn_off_face (f, glyph->face_id); 973 turn_off_face (f, face);
963 tty_turn_off_highlight (tty); 974 tty_turn_off_highlight (tty);
964 } 975 }
965 } 976 }
@@ -1542,6 +1553,7 @@ append_glyph (struct it *it)
1542 glyph->type = CHAR_GLYPH; 1553 glyph->type = CHAR_GLYPH;
1543 glyph->pixel_width = 1; 1554 glyph->pixel_width = 1;
1544 glyph->u.ch = it->char_to_display; 1555 glyph->u.ch = it->char_to_display;
1556 glyph->frame = it->f;
1545 glyph->face_id = it->face_id; 1557 glyph->face_id = it->face_id;
1546 glyph->avoid_cursor_p = it->avoid_cursor_p; 1558 glyph->avoid_cursor_p = it->avoid_cursor_p;
1547 glyph->multibyte_p = it->multibyte_p; 1559 glyph->multibyte_p = it->multibyte_p;
@@ -1769,6 +1781,7 @@ append_composite_glyph (struct it *it)
1769 1781
1770 glyph->avoid_cursor_p = it->avoid_cursor_p; 1782 glyph->avoid_cursor_p = it->avoid_cursor_p;
1771 glyph->multibyte_p = it->multibyte_p; 1783 glyph->multibyte_p = it->multibyte_p;
1784 glyph->frame = it->f;
1772 glyph->face_id = it->face_id; 1785 glyph->face_id = it->face_id;
1773 glyph->padding_p = false; 1786 glyph->padding_p = false;
1774 glyph->charpos = CHARPOS (it->position); 1787 glyph->charpos = CHARPOS (it->position);
@@ -1855,6 +1868,7 @@ append_glyphless_glyph (struct it *it, int face_id, const char *str)
1855 glyph->pixel_width = 1; 1868 glyph->pixel_width = 1;
1856 glyph->avoid_cursor_p = it->avoid_cursor_p; 1869 glyph->avoid_cursor_p = it->avoid_cursor_p;
1857 glyph->multibyte_p = it->multibyte_p; 1870 glyph->multibyte_p = it->multibyte_p;
1871 glyph->frame = it->f;
1858 glyph->face_id = face_id; 1872 glyph->face_id = face_id;
1859 glyph->padding_p = false; 1873 glyph->padding_p = false;
1860 glyph->charpos = CHARPOS (it->position); 1874 glyph->charpos = CHARPOS (it->position);
@@ -1981,9 +1995,8 @@ produce_glyphless_glyph (struct it *it, Lisp_Object acronym)
1981 FACE_ID is a realized face ID number, in the face cache. */ 1995 FACE_ID is a realized face ID number, in the face cache. */
1982 1996
1983static void 1997static void
1984turn_on_face (struct frame *f, int face_id) 1998turn_on_face (struct frame *f, struct face *face)
1985{ 1999{
1986 struct face *face = FACE_FROM_ID (f, face_id);
1987 unsigned long fg = face->foreground; 2000 unsigned long fg = face->foreground;
1988 unsigned long bg = face->background; 2001 unsigned long bg = face->background;
1989 struct tty_display_info *tty = FRAME_TTY (f); 2002 struct tty_display_info *tty = FRAME_TTY (f);
@@ -2064,9 +2077,8 @@ turn_on_face (struct frame *f, int face_id)
2064/* Turn off appearances of face FACE_ID on tty frame F. */ 2077/* Turn off appearances of face FACE_ID on tty frame F. */
2065 2078
2066static void 2079static void
2067turn_off_face (struct frame *f, int face_id) 2080turn_off_face (struct frame *f, struct face *face)
2068{ 2081{
2069 struct face *face = FACE_FROM_ID (f, face_id);
2070 struct tty_display_info *tty = FRAME_TTY (f); 2082 struct tty_display_info *tty = FRAME_TTY (f);
2071 2083
2072 if (tty->TS_exit_attribute_mode) 2084 if (tty->TS_exit_attribute_mode)
@@ -2399,7 +2411,7 @@ A suspended tty may be resumed by calling `resume-tty' on it. */)
2399 t->display_info.tty->output = 0; 2411 t->display_info.tty->output = 0;
2400 2412
2401 if (FRAMEP (t->display_info.tty->top_frame)) 2413 if (FRAMEP (t->display_info.tty->top_frame))
2402 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 0); 2414 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), false);
2403 2415
2404 } 2416 }
2405 2417
@@ -2482,7 +2494,7 @@ frame's terminal). */)
2482 get_tty_size (fileno (t->display_info.tty->input), &width, &height); 2494 get_tty_size (fileno (t->display_info.tty->input), &width, &height);
2483 if (width != old_width || height != old_height) 2495 if (width != old_width || height != old_height)
2484 change_frame_size (f, width, height, false, false, false); 2496 change_frame_size (f, width, height, false, false, false);
2485 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), 1); 2497 SET_FRAME_VISIBLE (XFRAME (t->display_info.tty->top_frame), true);
2486 } 2498 }
2487 2499
2488 set_tty_hooks (t); 2500 set_tty_hooks (t);
@@ -2563,22 +2575,24 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
2563 struct frame *f = XFRAME (WINDOW_FRAME (w)); 2575 struct frame *f = XFRAME (WINDOW_FRAME (w));
2564 struct tty_display_info *tty = FRAME_TTY (f); 2576 struct tty_display_info *tty = FRAME_TTY (f);
2565 int face_id = tty->mouse_highlight.mouse_face_face_id; 2577 int face_id = tty->mouse_highlight.mouse_face_face_id;
2566 int save_x, save_y, pos_x, pos_y;
2567 2578
2568 if (end_hpos >= row->used[TEXT_AREA]) 2579 if (end_hpos >= row->used[TEXT_AREA])
2569 nglyphs = row->used[TEXT_AREA] - start_hpos; 2580 nglyphs = row->used[TEXT_AREA] - start_hpos;
2570 2581
2571 pos_y = row->y + WINDOW_TOP_EDGE_Y (w); 2582 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); 2583 int pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w);
2573 2584
2574 /* Save current cursor coordinates. */ 2585 /* Save current cursor coordinates. */
2575 save_y = curY (tty); 2586 int save_y = curY (tty);
2576 save_x = curX (tty); 2587 int save_x = curX (tty);
2577 cursor_to (f, pos_y, pos_x); 2588 cursor_to (f, pos_y, pos_x);
2578 2589
2579 if (draw == DRAW_MOUSE_FACE) 2590 if (draw == DRAW_MOUSE_FACE)
2580 tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos, 2591 {
2581 nglyphs, face_id); 2592 struct glyph *glyph = row->glyphs[TEXT_AREA] + start_hpos;
2593 struct face *face = FACE_FROM_ID (glyph->frame, face_id);
2594 tty_write_glyphs_with_face (f, glyph, nglyphs, face);
2595 }
2582 else if (draw == DRAW_NORMAL_TEXT) 2596 else if (draw == DRAW_NORMAL_TEXT)
2583 write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs); 2597 write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
2584 2598
@@ -3969,7 +3983,7 @@ tty_free_frame_resources (struct frame *f)
3969 3983
3970#endif 3984#endif
3971 3985
3972 3986
3973 3987
3974#ifndef HAVE_ANDROID 3988#ifndef HAVE_ANDROID
3975 3989
@@ -4044,6 +4058,8 @@ set_tty_hooks (struct terminal *terminal)
4044 terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */ 4058 terminal->read_socket_hook = &tty_read_avail_input; /* keyboard.c */
4045 terminal->delete_frame_hook = &tty_free_frame_resources; 4059 terminal->delete_frame_hook = &tty_free_frame_resources;
4046 terminal->delete_terminal_hook = &delete_tty; 4060 terminal->delete_terminal_hook = &delete_tty;
4061
4062 terminal->frame_raise_lower_hook = tty_raise_lower_frame;
4047 /* Other hooks are NULL by default. */ 4063 /* Other hooks are NULL by default. */
4048} 4064}
4049 4065
@@ -4714,6 +4730,184 @@ delete_tty (struct terminal *terminal)
4714 4730
4715#endif 4731#endif
4716 4732
4733/* Return geometric attributes of FRAME. According to the value of
4734 ATTRIBUTES return the outer edges of FRAME (Qouter_edges), the
4735 native edges of FRAME (Qnative_edges), or the inner edges of frame
4736 (Qinner_edges). Any other value means to return the geometry as
4737 returned by Fx_frame_geometry. */
4738
4739static Lisp_Object
4740tty_frame_geometry (Lisp_Object frame, Lisp_Object attribute)
4741{
4742 struct frame *f = decode_live_frame (frame);
4743 if (FRAME_INITIAL_P (f) || !FRAME_TTY (f))
4744 return Qnil;
4745
4746 int native_width = f->pixel_width;
4747 int native_height = f->pixel_height;
4748
4749 eassert (FRAME_PARENT_FRAME (f) || (f->left_pos == 0 && f->top_pos == 0));
4750 int outer_left = f->left_pos;
4751 int outer_top = f->top_pos;
4752 int outer_right = outer_left + native_width;
4753 int outer_bottom = outer_top + native_height;
4754
4755 int native_left = outer_left;
4756 int native_top = outer_top;
4757 int native_right = outer_right;
4758 int native_bottom = outer_bottom;
4759
4760 int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
4761 int inner_left = native_left + internal_border_width;
4762 int inner_top = native_top + internal_border_width;
4763 int inner_right = native_right - internal_border_width;
4764 int inner_bottom = native_bottom - internal_border_width;
4765
4766 int menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
4767 inner_top += menu_bar_height;
4768 int menu_bar_width = menu_bar_height ? native_width : 0;
4769
4770 int tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
4771 int tab_bar_width = (tab_bar_height
4772 ? native_width - 2 * internal_border_width
4773 : 0);
4774 inner_top += tab_bar_height;
4775
4776 int tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
4777 int tool_bar_width = (tool_bar_height
4778 ? native_width - 2 * internal_border_width
4779 : 0);
4780
4781 /* Subtract or add to the inner dimensions based on the tool bar
4782 position. */
4783 if (EQ (FRAME_TOOL_BAR_POSITION (f), Qtop))
4784 inner_top += tool_bar_height;
4785 else
4786 inner_bottom -= tool_bar_height;
4787
4788 /* Construct list. */
4789 if (EQ (attribute, Qouter_edges))
4790 return list4i (outer_left, outer_top, outer_right, outer_bottom);
4791 else if (EQ (attribute, Qnative_edges))
4792 return list4i (native_left, native_top, native_right, native_bottom);
4793 else if (EQ (attribute, Qinner_edges))
4794 return list4i (inner_left, inner_top, inner_right, inner_bottom);
4795 else
4796 return list (Fcons (Qouter_position, Fcons (make_fixnum (outer_left),
4797 make_fixnum (outer_top))),
4798 Fcons (Qouter_size,
4799 Fcons (make_fixnum (outer_right - outer_left),
4800 make_fixnum (outer_bottom - outer_top))),
4801 Fcons (Qouter_border_width, make_fixnum (0)),
4802 Fcons (Qexternal_border_size,
4803 Fcons (make_fixnum (0), make_fixnum (0))),
4804 Fcons (Qtitle_bar_size,
4805 Fcons (make_fixnum (0), make_fixnum (0))),
4806 Fcons (Qmenu_bar_external, Qnil),
4807 Fcons (Qmenu_bar_size,
4808 Fcons (make_fixnum (menu_bar_width),
4809 make_fixnum (menu_bar_height))),
4810 Fcons (Qtab_bar_size,
4811 Fcons (make_fixnum (tab_bar_width),
4812 make_fixnum (tab_bar_height))),
4813 Fcons (Qtool_bar_external, Qnil),
4814 Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
4815 Fcons (Qtool_bar_size,
4816 Fcons (make_fixnum (tool_bar_width),
4817 make_fixnum (tool_bar_height))),
4818 Fcons (Qinternal_border_width,
4819 make_fixnum (internal_border_width)));
4820}
4821
4822DEFUN ("tty-frame-geometry", Ftty_frame_geometry, Stty_frame_geometry, 0, 1, 0,
4823 doc: /* Return geometric attributes of terminal frame FRAME.
4824 See also `frame-geometry'. */)
4825 (Lisp_Object frame)
4826{
4827 return tty_frame_geometry (frame, Qnil);
4828}
4829
4830DEFUN ("tty-frame-edges", Ftty_frame_edges, Stty_frame_edges, 0, 2, 0,
4831 doc: /* Return coordinates of FRAME's edges.
4832 See also `frame-edges'. */)
4833 (Lisp_Object frame, Lisp_Object type)
4834{
4835 if (!EQ (type, Qouter_edges) && !EQ (type, Qinner_edges))
4836 type = Qnative_edges;
4837 return tty_frame_geometry (frame, type);
4838}
4839
4840DEFUN ("tty-frame-list-z-order", Ftty_frame_list_z_order,
4841 Stty_frame_list_z_order, 0, 1, 0,
4842 doc: /* Return list of Emacs's frames, in Z (stacking) order.
4843 See also `frame-list-z-order'. */)
4844 (Lisp_Object frame)
4845{
4846 struct frame *f = decode_tty_frame (frame);
4847 Lisp_Object frames = frames_in_reverse_z_order (f, true);
4848 return Fnreverse (frames);
4849}
4850
4851DEFUN ("tty-frame-restack", Ftty_frame_restack,
4852 Stty_frame_restack, 2, 3, 0,
4853 doc: /* Restack FRAME1 below FRAME2 on terminals.
4854. See also `frame-restack'. */)
4855 (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above)
4856{
4857 /* FIXME/tty: implementation. */
4858 return Qnil;
4859}
4860
4861static void
4862tty_display_dimension (Lisp_Object frame, int *width, int *height)
4863{
4864 if (!FRAMEP (frame))
4865 frame = Fselected_frame ();
4866 struct frame *f = XFRAME (frame);
4867 switch (f->output_method)
4868 {
4869 case output_initial:
4870 *width = 80;
4871 *height = 25;
4872 break;
4873 case output_termcap:
4874 *width = FrameCols (FRAME_TTY (f));
4875 *height = FrameRows (FRAME_TTY (f));
4876 break;
4877 case output_x_window:
4878 case output_msdos_raw:
4879 case output_w32:
4880 case output_ns:
4881 case output_pgtk:
4882 case output_haiku:
4883 case output_android:
4884 emacs_abort ();
4885 break;
4886 }
4887}
4888
4889DEFUN ("tty-display-pixel-width", Ftty_display_pixel_width,
4890 Stty_display_pixel_width, 0, 1, 0,
4891 doc: /* Return the width of DISPLAY's screen in pixels.
4892. See also `display-pixel-width'. */)
4893 (Lisp_Object display)
4894{
4895 int width, height;
4896 tty_display_dimension (display, &width, &height);
4897 return make_fixnum (width);
4898}
4899
4900DEFUN ("tty-display-pixel-height", Ftty_display_pixel_height,
4901 Stty_display_pixel_height, 0, 1, 0,
4902 doc: /* Return the height of DISPLAY's screen in pixels.
4903 See also `display-pixel-height'. */)
4904 (Lisp_Object display)
4905{
4906 int width, height;
4907 tty_display_dimension (display, &width, &height);
4908 return make_fixnum (height);
4909}
4910
4717void 4911void
4718syms_of_term (void) 4912syms_of_term (void)
4719{ 4913{
@@ -4770,6 +4964,13 @@ trigger redisplay. */);
4770 defsubr (&Sgpm_mouse_stop); 4964 defsubr (&Sgpm_mouse_stop);
4771#endif /* HAVE_GPM */ 4965#endif /* HAVE_GPM */
4772 4966
4967 defsubr (&Stty_frame_geometry);
4968 defsubr (&Stty_frame_edges);
4969 defsubr (&Stty_frame_list_z_order);
4970 defsubr (&Stty_frame_restack);
4971 defsubr (&Stty_display_pixel_width);
4972 defsubr (&Stty_display_pixel_height);
4973
4773#if !defined DOS_NT && !defined HAVE_ANDROID 4974#if !defined DOS_NT && !defined HAVE_ANDROID
4774 default_orig_pair = NULL; 4975 default_orig_pair = NULL;
4775 default_set_foreground = NULL; 4976 default_set_foreground = NULL;
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/xdisp.c b/src/xdisp.c
index c74e81a3933..f19706005ad 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}
@@ -3348,9 +3348,7 @@ init_iterator (struct it *it, struct window *w,
3348 of the iterator's frame, when set, suppresses their display - by 3348 of the iterator's frame, when set, suppresses their display - by
3349 default for tooltip frames and when set via the 'no-special-glyphs' 3349 default for tooltip frames and when set via the 'no-special-glyphs'
3350 frame parameter. */ 3350 frame parameter. */
3351#ifdef HAVE_WINDOW_SYSTEM 3351 if (!it->f->no_special_glyphs)
3352 if (!(FRAME_WINDOW_P (it->f) && it->f->no_special_glyphs))
3353#endif
3354 { 3352 {
3355 if (it->line_wrap == TRUNCATE) 3353 if (it->line_wrap == TRUNCATE)
3356 { 3354 {
@@ -13554,7 +13552,11 @@ echo_area_display (bool update_frame_p)
13554 flush_frame (f); 13552 flush_frame (f);
13555 } 13553 }
13556 else 13554 else
13557 update_frame (f, true, true); 13555 {
13556 update_frame (f, true, true);
13557 if (is_tty_frame (f))
13558 combine_updates_for_frame (f, true, true);
13559 }
13558 13560
13559 /* If cursor is in the echo area, make sure that the next 13561 /* If cursor is in the echo area, make sure that the next
13560 redisplay displays the minibuffer, so that the cursor will 13562 redisplay displays the minibuffer, so that the cursor will
@@ -17033,6 +17035,9 @@ redisplay_internal (void)
17033 if (face_change) 17035 if (face_change)
17034 windows_or_buffers_changed = 47; 17036 windows_or_buffers_changed = 47;
17035 17037
17038 /* FIXME/tty: can we do better for tty child frames? It could be
17039 a bit faster when we switch between child frames of the same
17040 root frame. OTOH, it's probably not a frequent use case. */
17036 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf)) 17041 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
17037 && FRAME_TTY (sf)->previous_frame != sf) 17042 && FRAME_TTY (sf)->previous_frame != sf)
17038 { 17043 {
@@ -17055,6 +17060,7 @@ redisplay_internal (void)
17055 { 17060 {
17056 struct frame *f = XFRAME (frame); 17061 struct frame *f = XFRAME (frame);
17057 17062
17063 /* FRAME_REDISPLAY_P true basically means the frame is visible. */
17058 if (FRAME_REDISPLAY_P (f)) 17064 if (FRAME_REDISPLAY_P (f))
17059 { 17065 {
17060 ++number_of_visible_frames; 17066 ++number_of_visible_frames;
@@ -17198,7 +17204,6 @@ redisplay_internal (void)
17198 && !current_buffer->clip_changed 17204 && !current_buffer->clip_changed
17199 && !current_buffer->prevent_redisplay_optimizations_p 17205 && !current_buffer->prevent_redisplay_optimizations_p
17200 && FRAME_REDISPLAY_P (XFRAME (w->frame)) 17206 && FRAME_REDISPLAY_P (XFRAME (w->frame))
17201 && !FRAME_OBSCURED_P (XFRAME (w->frame))
17202 && !XFRAME (w->frame)->cursor_type_changed 17207 && !XFRAME (w->frame)->cursor_type_changed
17203 && !XFRAME (w->frame)->face_change 17208 && !XFRAME (w->frame)->face_change
17204 /* Make sure recorded data applies to current buffer, etc. */ 17209 /* Make sure recorded data applies to current buffer, etc. */
@@ -17447,22 +17452,19 @@ redisplay_internal (void)
17447 17452
17448 propagate_buffer_redisplay (); 17453 propagate_buffer_redisplay ();
17449 17454
17455 Lisp_Object tty_root_frames = Qnil;
17450 FOR_EACH_FRAME (tail, frame) 17456 FOR_EACH_FRAME (tail, frame)
17451 { 17457 {
17452 struct frame *f = XFRAME (frame); 17458 struct frame *f = XFRAME (frame);
17453 17459
17454 /* We don't have to do anything for unselected terminal 17460 if (is_tty_root_frame (f))
17455 frames. */ 17461 tty_root_frames = Fcons (frame, tty_root_frames);
17456 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
17457 && !EQ (FRAME_TTY (f)->top_frame, frame))
17458 continue;
17459 17462
17460 retry_frame: 17463 retry_frame:
17461 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf) 17464 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
17462 { 17465 {
17463 bool gcscrollbars 17466 /* Only GC scrollbars when we redisplay the whole frame. */
17464 /* Only GC scrollbars when we redisplay the whole frame. */ 17467 bool gcscrollbars = f->redisplay || !REDISPLAY_SOME_P ();
17465 = f->redisplay || !REDISPLAY_SOME_P ();
17466 bool f_redisplay_flag = f->redisplay; 17468 bool f_redisplay_flag = f->redisplay;
17467 17469
17468 /* The X error handler may have deleted that frame before 17470 /* The X error handler may have deleted that frame before
@@ -17479,7 +17481,7 @@ redisplay_internal (void)
17479 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook) 17481 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
17480 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f); 17482 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
17481 17483
17482 if (FRAME_REDISPLAY_P (f) && !FRAME_OBSCURED_P (f)) 17484 if (FRAME_REDISPLAY_P (f))
17483 { 17485 {
17484 /* Don't allow freeing images and faces for this 17486 /* Don't allow freeing images and faces for this
17485 frame as long as the frame's update wasn't 17487 frame as long as the frame's update wasn't
@@ -17505,7 +17507,9 @@ redisplay_internal (void)
17505 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook) 17507 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
17506 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f); 17508 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
17507 17509
17508 if (FRAME_REDISPLAY_P (f) && !FRAME_OBSCURED_P (f)) 17510 /* FIXME/tty: The FRAME_OBSCURE_P (f->visible == 2, :-()
17511 seems to be something for Windows. I'm ignoring it. */
17512 if (FRAME_REDISPLAY_P (f))
17509 { 17513 {
17510 /* If fonts changed on visible frame, display again. */ 17514 /* If fonts changed on visible frame, display again. */
17511 if (f->fonts_changed) 17515 if (f->fonts_changed)
@@ -17590,6 +17594,9 @@ redisplay_internal (void)
17590 } 17594 }
17591 } 17595 }
17592 17596
17597 if (CONSP (tty_root_frames))
17598 pending |= combine_updates (tty_root_frames, false, false);
17599
17593 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window)); 17600 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
17594 17601
17595 if (!pending) 17602 if (!pending)
@@ -17611,7 +17618,7 @@ redisplay_internal (void)
17611 } 17618 }
17612 } 17619 }
17613 } 17620 }
17614 else if (FRAME_REDISPLAY_P (sf) && !FRAME_OBSCURED_P (sf)) 17621 else if (FRAME_REDISPLAY_P (sf))
17615 { 17622 {
17616 sf->inhibit_clear_image_cache = true; 17623 sf->inhibit_clear_image_cache = true;
17617 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents); 17624 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
@@ -17662,7 +17669,7 @@ redisplay_internal (void)
17662 unrequest_sigio (); 17669 unrequest_sigio ();
17663 STOP_POLLING; 17670 STOP_POLLING;
17664 17671
17665 if (FRAME_REDISPLAY_P (sf) && !FRAME_OBSCURED_P (sf)) 17672 if (FRAME_REDISPLAY_P (sf))
17666 { 17673 {
17667 if (hscroll_retries <= MAX_HSCROLL_RETRIES 17674 if (hscroll_retries <= MAX_HSCROLL_RETRIES
17668 && hscroll_windows (selected_window)) 17675 && hscroll_windows (selected_window))
@@ -17673,6 +17680,10 @@ redisplay_internal (void)
17673 17680
17674 XWINDOW (selected_window)->must_be_updated_p = true; 17681 XWINDOW (selected_window)->must_be_updated_p = true;
17675 pending = update_frame (sf, false, false); 17682 pending = update_frame (sf, false, false);
17683
17684 if (is_tty_frame (sf))
17685 pending |= combine_updates_for_frame (sf, false, false);
17686
17676 sf->cursor_type_changed = false; 17687 sf->cursor_type_changed = false;
17677 sf->inhibit_clear_image_cache = false; 17688 sf->inhibit_clear_image_cache = false;
17678 } 17689 }
@@ -17685,10 +17696,13 @@ redisplay_internal (void)
17685 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf); 17696 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
17686 struct frame *mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window))); 17697 struct frame *mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
17687 17698
17688 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame)) 17699 /* FIXME/tty: is removing FRAME_WINDOW_P here right? */
17700 if (mini_frame != sf /*&& FRAME_WINDOW_P (mini_frame)*/)
17689 { 17701 {
17690 XWINDOW (mini_window)->must_be_updated_p = true; 17702 XWINDOW (mini_window)->must_be_updated_p = true;
17691 pending |= update_frame (mini_frame, false, false); 17703 pending |= update_frame (mini_frame, false, false);
17704 if (is_tty_frame (mini_frame))
17705 pending |= combine_updates_for_frame (mini_frame, false, false);
17692 mini_frame->cursor_type_changed = false; 17706 mini_frame->cursor_type_changed = false;
17693 if (!pending && hscroll_retries <= MAX_HSCROLL_RETRIES 17707 if (!pending && hscroll_retries <= MAX_HSCROLL_RETRIES
17694 && hscroll_windows (mini_window)) 17708 && hscroll_windows (mini_window))
@@ -23975,6 +23989,7 @@ extend_face_to_end_of_line (struct it *it)
23975 { 23989 {
23976 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph; 23990 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
23977 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id; 23991 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
23992 it->glyph_row->glyphs[TEXT_AREA][0].frame = f;
23978 it->glyph_row->used[TEXT_AREA] = 1; 23993 it->glyph_row->used[TEXT_AREA] = 1;
23979 } 23994 }
23980 /* Mode line and the header line don't have margins, and 23995 /* Mode line and the header line don't have margins, and
@@ -23994,6 +24009,7 @@ extend_face_to_end_of_line (struct it *it)
23994 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph; 24009 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
23995 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id = 24010 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
23996 default_face->id; 24011 default_face->id;
24012 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].frame = f;
23997 it->glyph_row->used[LEFT_MARGIN_AREA] = 1; 24013 it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
23998 } 24014 }
23999 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0 24015 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
@@ -24002,6 +24018,7 @@ extend_face_to_end_of_line (struct it *it)
24002 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph; 24018 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
24003 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id = 24019 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
24004 default_face->id; 24020 default_face->id;
24021 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].frame = f;
24005 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1; 24022 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
24006 } 24023 }
24007 24024
@@ -24366,9 +24383,11 @@ highlight_trailing_whitespace (struct it *it)
24366 while (glyph >= start 24383 while (glyph >= start
24367 && BUFFERP (glyph->object) 24384 && BUFFERP (glyph->object)
24368 && (glyph->type == STRETCH_GLYPH 24385 && (glyph->type == STRETCH_GLYPH
24369 || (glyph->type == CHAR_GLYPH 24386 || (glyph->type == CHAR_GLYPH && glyph->u.ch == ' ')))
24370 && glyph->u.ch == ' '))) 24387 {
24371 (glyph--)->face_id = face_id; 24388 glyph->frame = it->f;
24389 (glyph--)->face_id = face_id;
24390 }
24372 } 24391 }
24373 else 24392 else
24374 { 24393 {
@@ -24377,7 +24396,10 @@ highlight_trailing_whitespace (struct it *it)
24377 && (glyph->type == STRETCH_GLYPH 24396 && (glyph->type == STRETCH_GLYPH
24378 || (glyph->type == CHAR_GLYPH 24397 || (glyph->type == CHAR_GLYPH
24379 && glyph->u.ch == ' '))) 24398 && glyph->u.ch == ' ')))
24380 (glyph++)->face_id = face_id; 24399 {
24400 glyph->frame = it->f;
24401 (glyph++)->face_id = face_id;
24402 }
24381 } 24403 }
24382 } 24404 }
24383 } 24405 }
@@ -27230,7 +27252,7 @@ display_menu_bar (struct window *w)
27230 27252
27231/* Deep copy of a glyph row, including the glyphs. */ 27253/* Deep copy of a glyph row, including the glyphs. */
27232static void 27254static void
27233deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from) 27255deep_copy_glyph_row (struct frame *f, struct glyph_row *to, struct glyph_row *from)
27234{ 27256{
27235 struct glyph *pointers[1 + LAST_AREA]; 27257 struct glyph *pointers[1 + LAST_AREA];
27236 int to_used = to->used[TEXT_AREA]; 27258 int to_used = to->used[TEXT_AREA];
@@ -27251,7 +27273,7 @@ deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
27251 /* If we filled only part of the TO row, fill the rest with 27273 /* If we filled only part of the TO row, fill the rest with
27252 space_glyph (which will display as empty space). */ 27274 space_glyph (which will display as empty space). */
27253 if (to_used > from->used[TEXT_AREA]) 27275 if (to_used > from->used[TEXT_AREA])
27254 fill_up_frame_row_with_spaces (to, to_used); 27276 fill_up_frame_row_with_spaces (f, to, to_used);
27255} 27277}
27256 27278
27257/* Display one menu item on a TTY, by overwriting the glyphs in the 27279/* Display one menu item on a TTY, by overwriting the glyphs in the
@@ -27300,7 +27322,7 @@ display_tty_menu_item (const char *item_text, int width, int face_id,
27300 it.last_visible_x = FRAME_COLS (f) - 1; 27322 it.last_visible_x = FRAME_COLS (f) - 1;
27301 row = it.glyph_row; 27323 row = it.glyph_row;
27302 /* Start with the row contents from the current matrix. */ 27324 /* Start with the row contents from the current matrix. */
27303 deep_copy_glyph_row (row, f->current_matrix->rows + y); 27325 deep_copy_glyph_row (f, row, f->current_matrix->rows + y);
27304 bool saved_width = row->full_width_p; 27326 bool saved_width = row->full_width_p;
27305 row->full_width_p = true; 27327 row->full_width_p = true;
27306 bool saved_reversed = row->reversed_p; 27328 bool saved_reversed = row->reversed_p;
diff --git a/src/xfaces.c b/src/xfaces.c
index e248279e9b7..fd321734d14 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);