comparison src/dispnew.c @ 88155:d7ddb3e565de

sync with trunk
author Henrik Enberg <henrik.enberg@telia.com>
date Mon, 16 Jan 2006 00:03:54 +0000
parents 23a1cea22d13
children
comparison
equal deleted inserted replaced
88154:8ce476d3ba36 88155:d7ddb3e565de
1 /* Updating of data structures for redisplay. 1 /* Updating of data structures for redisplay.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 97, 98, 1999, 2000, 2001, 2002 2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
3 Free Software Foundation, Inc. 3 1997, 1998, 1999, 2000, 2001, 2002, 2003,
4 2004, 2005 Free Software Foundation, Inc.
4 5
5 This file is part of GNU Emacs. 6 This file is part of GNU Emacs.
6 7
7 GNU Emacs is free software; you can redistribute it and/or modify 8 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 16 GNU General Public License for more details.
16 17
17 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to 19 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02111-1307, USA. */ 21 Boston, MA 02110-1301, USA. */
21 22
22 #include <config.h> 23 #include <config.h>
23 #include <signal.h> 24 #include <signal.h>
24 #include <stdio.h> 25 #include <stdio.h>
25 #include <ctype.h> 26 #include <ctype.h>
426 } 427 }
427 428
428 429
429 #else /* GLYPH_DEBUG == 0 */ 430 #else /* GLYPH_DEBUG == 0 */
430 431
431 #define WINDOW_TO_FRAME_VPOS(W, VPOS) ((VPOS) + XFASTINT ((W)->top)) 432 #define WINDOW_TO_FRAME_VPOS(W, VPOS) ((VPOS) + WINDOW_TOP_EDGE_LINE (W))
432 #define WINDOW_TO_FRAME_HPOS(W, HPOS) ((HPOS) + XFASTINT ((W)->left)) 433 #define WINDOW_TO_FRAME_HPOS(W, HPOS) ((HPOS) + WINDOW_LEFT_EDGE_COL (W))
433 434
434 #endif /* GLYPH_DEBUG == 0 */ 435 #endif /* GLYPH_DEBUG == 0 */
435 436
436 437
437 /* Like bcopy except never gets confused by overlap. Let this be the 438 /* Like bcopy except never gets confused by overlap. Let this be the
574 { 575 {
575 int n; 576 int n;
576 577
577 if (NUMBERP (margin)) 578 if (NUMBERP (margin))
578 { 579 {
579 int width = XFASTINT (w->width); 580 int width = XFASTINT (w->total_cols);
580 double d = max (0, XFLOATINT (margin)); 581 double d = max (0, XFLOATINT (margin));
581 d = min (width / 2 - 1, d); 582 d = min (width / 2 - 1, d);
582 n = (int) ((double) total_glyphs / width * d); 583 n = (int) ((double) total_glyphs / width * d);
583 } 584 }
584 else 585 else
621 int new_rows; 622 int new_rows;
622 int marginal_areas_changed_p = 0; 623 int marginal_areas_changed_p = 0;
623 int header_line_changed_p = 0; 624 int header_line_changed_p = 0;
624 int header_line_p = 0; 625 int header_line_p = 0;
625 int left = -1, right = -1; 626 int left = -1, right = -1;
626 int window_x, window_y, window_width = -1, window_height; 627 int window_width = -1, window_height;
627 628
628 /* See if W had a header line that has disappeared now, or vice versa. */ 629 /* See if W had a header line that has disappeared now, or vice versa.
630 Get W's size. */
629 if (w) 631 if (w)
630 { 632 {
633 window_box (w, -1, 0, 0, &window_width, &window_height);
634
631 header_line_p = WINDOW_WANTS_HEADER_LINE_P (w); 635 header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
632 header_line_changed_p = header_line_p != matrix->header_line_p; 636 header_line_changed_p = header_line_p != matrix->header_line_p;
633 } 637 }
634 matrix->header_line_p = header_line_p; 638 matrix->header_line_p = header_line_p;
635 639
636 /* Do nothing if MATRIX' size, position, vscroll, and marginal areas 640 /* If POOL is null, MATRIX is a window matrix for window-based redisplay.
641 Do nothing if MATRIX' size, position, vscroll, and marginal areas
637 haven't changed. This optimization is important because preserving 642 haven't changed. This optimization is important because preserving
638 the matrix means preventing redisplay. */ 643 the matrix means preventing redisplay. */
639 if (matrix->pool == NULL) 644 if (matrix->pool == NULL)
640 { 645 {
641 window_box (w, -1, &window_x, &window_y, &window_width, &window_height); 646 left = margin_glyphs_to_reserve (w, dim.width, w->left_margin_cols);
642 left = margin_glyphs_to_reserve (w, dim.width, w->left_margin_width); 647 right = margin_glyphs_to_reserve (w, dim.width, w->right_margin_cols);
643 right = margin_glyphs_to_reserve (w, dim.width, w->right_margin_width);
644 xassert (left >= 0 && right >= 0); 648 xassert (left >= 0 && right >= 0);
645 marginal_areas_changed_p = (left != matrix->left_margin_glyphs 649 marginal_areas_changed_p = (left != matrix->left_margin_glyphs
646 || right != matrix->right_margin_glyphs); 650 || right != matrix->right_margin_glyphs);
647 651
648 if (!marginal_areas_changed_p 652 if (!marginal_areas_changed_p
649 && !fonts_changed_p 653 && !fonts_changed_p
650 && !header_line_changed_p 654 && !header_line_changed_p
651 && matrix->window_left_x == XFASTINT (w->left) 655 && matrix->window_left_col == WINDOW_LEFT_EDGE_COL (w)
652 && matrix->window_top_y == XFASTINT (w->top) 656 && matrix->window_top_line == WINDOW_TOP_EDGE_LINE (w)
653 && matrix->window_height == window_height 657 && matrix->window_height == window_height
654 && matrix->window_vscroll == w->vscroll 658 && matrix->window_vscroll == w->vscroll
655 && matrix->window_width == window_width) 659 && matrix->window_width == window_width)
656 return; 660 return;
657 } 661 }
677 xassert (matrix->pool->glyphs); 681 xassert (matrix->pool->glyphs);
678 682
679 if (w) 683 if (w)
680 { 684 {
681 left = margin_glyphs_to_reserve (w, dim.width, 685 left = margin_glyphs_to_reserve (w, dim.width,
682 w->left_margin_width); 686 w->left_margin_cols);
683 right = margin_glyphs_to_reserve (w, dim.width, 687 right = margin_glyphs_to_reserve (w, dim.width,
684 w->right_margin_width); 688 w->right_margin_cols);
685 } 689 }
686 else 690 else
687 left = right = 0; 691 left = right = 0;
688 692
689 for (i = 0; i < dim.height; ++i) 693 for (i = 0; i < dim.height; ++i)
721 matrix->right_margin_glyphs = right; 725 matrix->right_margin_glyphs = right;
722 } 726 }
723 else 727 else
724 { 728 {
725 /* If MATRIX->pool is null, MATRIX is responsible for managing 729 /* If MATRIX->pool is null, MATRIX is responsible for managing
726 its own memory. Allocate glyph memory from the heap. */ 730 its own memory. It is a window matrix for window-based redisplay.
731 Allocate glyph memory from the heap. */
727 if (dim.width > matrix->matrix_w 732 if (dim.width > matrix->matrix_w
728 || new_rows 733 || new_rows
729 || header_line_changed_p 734 || header_line_changed_p
730 || marginal_areas_changed_p) 735 || marginal_areas_changed_p)
731 { 736 {
788 of the window. */ 793 of the window. */
789 if (!marginal_areas_changed_p 794 if (!marginal_areas_changed_p
790 && !header_line_changed_p 795 && !header_line_changed_p
791 && new_rows == 0 796 && new_rows == 0
792 && dim.width == matrix->matrix_w 797 && dim.width == matrix->matrix_w
793 && matrix->window_left_x == XFASTINT (w->left) 798 && matrix->window_left_col == WINDOW_LEFT_EDGE_COL (w)
794 && matrix->window_top_y == XFASTINT (w->top) 799 && matrix->window_top_line == WINDOW_TOP_EDGE_LINE (w)
795 && matrix->window_width == window_width) 800 && matrix->window_width == window_width)
796 { 801 {
797 /* Find the last row in the window. */ 802 /* Find the last row in the window. */
798 for (i = 0; i < matrix->nrows && matrix->rows[i].enabled_p; ++i) 803 for (i = 0; i < matrix->nrows && matrix->rows[i].enabled_p; ++i)
799 if (MATRIX_ROW_BOTTOM_Y (matrix->rows + i) >= window_height) 804 if (MATRIX_ROW_BOTTOM_Y (matrix->rows + i) >= window_height)
837 842
838 /* Record the top y location and height of W at the time the matrix 843 /* Record the top y location and height of W at the time the matrix
839 was last adjusted. This is used to optimize redisplay above. */ 844 was last adjusted. This is used to optimize redisplay above. */
840 if (w) 845 if (w)
841 { 846 {
842 matrix->window_left_x = XFASTINT (w->left); 847 matrix->window_left_col = WINDOW_LEFT_EDGE_COL (w);
843 matrix->window_top_y = XFASTINT (w->top); 848 matrix->window_top_line = WINDOW_TOP_EDGE_LINE (w);
844 matrix->window_height = window_height; 849 matrix->window_height = window_height;
845 matrix->window_width = window_width; 850 matrix->window_width = window_width;
846 matrix->window_vscroll = w->vscroll; 851 matrix->window_vscroll = w->vscroll;
847 } 852 }
848 } 853 }
981 986
982 xassert (start <= end); 987 xassert (start <= end);
983 xassert (start >= 0 && start < matrix->nrows); 988 xassert (start >= 0 && start < matrix->nrows);
984 xassert (end >= 0 && end <= matrix->nrows); 989 xassert (end >= 0 && end <= matrix->nrows);
985 990
986 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w); 991 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
987 max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w); 992 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (w);
988 993
989 for (; start < end; ++start) 994 for (; start < end; ++start)
990 { 995 {
991 struct glyph_row *row = &matrix->rows[start]; 996 struct glyph_row *row = &matrix->rows[start];
992 997
1141 struct glyph_row *row; 1146 struct glyph_row *row;
1142 int y; 1147 int y;
1143 { 1148 {
1144 int min_y, max_y; 1149 int min_y, max_y;
1145 1150
1146 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w); 1151 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
1147 max_y = WINDOW_DISPLAY_HEIGHT_NO_MODE_LINE (w); 1152 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (w);
1148 1153
1149 clear_glyph_row (row); 1154 clear_glyph_row (row);
1150 row->y = y; 1155 row->y = y;
1151 row->ascent = row->phys_ascent = 0; 1156 row->ascent = row->phys_ascent = 0;
1152 row->height = row->phys_height = CANON_Y_UNIT (XFRAME (w->frame)); 1157 row->height = row->phys_height = FRAME_LINE_HEIGHT (XFRAME (w->frame));
1153 row->visible_height = row->height; 1158 row->visible_height = row->height;
1154 1159
1155 if (row->y < min_y) 1160 if (row->y < min_y)
1156 row->visible_height -= min_y - row->y; 1161 row->visible_height -= min_y - row->y;
1157 if (row->y + row->height > max_y) 1162 if (row->y + row->height > max_y)
1177 /* Increment start and end positions. */ 1182 /* Increment start and end positions. */
1178 MATRIX_ROW_START_CHARPOS (row) += delta; 1183 MATRIX_ROW_START_CHARPOS (row) += delta;
1179 MATRIX_ROW_START_BYTEPOS (row) += delta_bytes; 1184 MATRIX_ROW_START_BYTEPOS (row) += delta_bytes;
1180 MATRIX_ROW_END_CHARPOS (row) += delta; 1185 MATRIX_ROW_END_CHARPOS (row) += delta;
1181 MATRIX_ROW_END_BYTEPOS (row) += delta_bytes; 1186 MATRIX_ROW_END_BYTEPOS (row) += delta_bytes;
1187
1188 if (!row->enabled_p)
1189 return;
1182 1190
1183 /* Increment positions in glyphs. */ 1191 /* Increment positions in glyphs. */
1184 for (area = 0; area < LAST_AREA; ++area) 1192 for (area = 0; area < LAST_AREA; ++area)
1185 for (i = 0; i < row->used[area]; ++i) 1193 for (i = 0; i < row->used[area]; ++i)
1186 if (BUFFERP (row->glyphs[area][i].object) 1194 if (BUFFERP (row->glyphs[area][i].object)
1507 1515
1508 if (a_glyph != a_end) 1516 if (a_glyph != a_end)
1509 return 0; 1517 return 0;
1510 } 1518 }
1511 1519
1512 if (a->truncated_on_left_p != b->truncated_on_left_p 1520 if (a->fill_line_p != b->fill_line_p
1513 || a->fill_line_p != b->fill_line_p 1521 || a->cursor_in_fringe_p != b->cursor_in_fringe_p
1514 || a->truncated_on_right_p != b->truncated_on_right_p 1522 || a->left_fringe_bitmap != b->left_fringe_bitmap
1515 || a->overlay_arrow_p != b->overlay_arrow_p 1523 || a->left_fringe_face_id != b->left_fringe_face_id
1516 || a->continued_p != b->continued_p 1524 || a->right_fringe_bitmap != b->right_fringe_bitmap
1517 || a->indicate_empty_line_p != b->indicate_empty_line_p 1525 || a->right_fringe_face_id != b->right_fringe_face_id
1526 || a->overlay_arrow_bitmap != b->overlay_arrow_bitmap
1527 || a->exact_window_width_line_p != b->exact_window_width_line_p
1518 || a->overlapped_p != b->overlapped_p 1528 || a->overlapped_p != b->overlapped_p
1519 || (MATRIX_ROW_CONTINUATION_LINE_P (a) 1529 || (MATRIX_ROW_CONTINUATION_LINE_P (a)
1520 != MATRIX_ROW_CONTINUATION_LINE_P (b)) 1530 != MATRIX_ROW_CONTINUATION_LINE_P (b))
1521 /* Different partially visible characters on left margin. */ 1531 /* Different partially visible characters on left margin. */
1522 || a->x != b->x 1532 || a->x != b->x
1903 if (x != w->desired_matrix->matrix_x 1913 if (x != w->desired_matrix->matrix_x
1904 || y != w->desired_matrix->matrix_y 1914 || y != w->desired_matrix->matrix_y
1905 || dim.width != w->desired_matrix->matrix_w 1915 || dim.width != w->desired_matrix->matrix_w
1906 || dim.height != w->desired_matrix->matrix_h 1916 || dim.height != w->desired_matrix->matrix_h
1907 || (margin_glyphs_to_reserve (w, dim.width, 1917 || (margin_glyphs_to_reserve (w, dim.width,
1908 w->right_margin_width) 1918 w->left_margin_cols)
1909 != w->desired_matrix->left_margin_glyphs) 1919 != w->desired_matrix->left_margin_glyphs)
1910 || (margin_glyphs_to_reserve (w, dim.width, 1920 || (margin_glyphs_to_reserve (w, dim.width,
1911 w->left_margin_width) 1921 w->right_margin_cols)
1912 != w->desired_matrix->right_margin_glyphs)) 1922 != w->desired_matrix->right_margin_glyphs))
1913 *window_change_flags |= CHANGED_LEAF_MATRIX; 1923 *window_change_flags |= CHANGED_LEAF_MATRIX;
1914 1924
1915 /* Actually change matrices, if allowed. Do not consider 1925 /* Actually change matrices, if allowed. Do not consider
1916 CHANGED_LEAF_MATRIX computed above here because the pool 1926 CHANGED_LEAF_MATRIX computed above here because the pool
1974 if (FRAME_WINDOW_P (f)) 1984 if (FRAME_WINDOW_P (f))
1975 { 1985 {
1976 int ch_height = FRAME_SMALLEST_FONT_HEIGHT (f); 1986 int ch_height = FRAME_SMALLEST_FONT_HEIGHT (f);
1977 int window_pixel_height = window_box_height (w) + abs (w->vscroll); 1987 int window_pixel_height = window_box_height (w) + abs (w->vscroll);
1978 return (((window_pixel_height + ch_height - 1) 1988 return (((window_pixel_height + ch_height - 1)
1979 / ch_height) 1989 / ch_height) * w->nrows_scale_factor
1980 /* One partially visible line at the top and 1990 /* One partially visible line at the top and
1981 bottom of the window. */ 1991 bottom of the window. */
1982 + 2 1992 + 2
1983 /* 2 for header and mode line. */ 1993 /* 2 for header and mode line. */
1984 + 2); 1994 + 2);
1985 } 1995 }
1986 #endif /* HAVE_WINDOW_SYSTEM */ 1996 #endif /* HAVE_WINDOW_SYSTEM */
1987 1997
1988 return XINT (w->height); 1998 return WINDOW_TOTAL_LINES (w);
1989 } 1999 }
1990 2000
1991 2001
1992 /* Return the required width of glyph matrices for window W. */ 2002 /* Return the required width of glyph matrices for window W. */
1993 2003
1998 #ifdef HAVE_WINDOW_SYSTEM 2008 #ifdef HAVE_WINDOW_SYSTEM
1999 struct frame *f = XFRAME (w->frame); 2009 struct frame *f = XFRAME (w->frame);
2000 if (FRAME_WINDOW_P (f)) 2010 if (FRAME_WINDOW_P (f))
2001 { 2011 {
2002 int ch_width = FRAME_SMALLEST_CHAR_WIDTH (f); 2012 int ch_width = FRAME_SMALLEST_CHAR_WIDTH (f);
2003 int window_pixel_width = XFLOATINT (w->width) * CANON_X_UNIT (f); 2013 int window_pixel_width = WINDOW_TOTAL_WIDTH (w);
2004 2014
2005 /* Compute number of glyphs needed in a glyph row. */ 2015 /* Compute number of glyphs needed in a glyph row. */
2006 return (((window_pixel_width + ch_width - 1) 2016 return (((window_pixel_width + ch_width - 1)
2007 / ch_width) 2017 / ch_width) * w->ncols_scale_factor
2008 /* 2 partially visible columns in the text area. */ 2018 /* 2 partially visible columns in the text area. */
2009 + 2 2019 + 2
2010 /* One partially visible column at the right 2020 /* One partially visible column at the right
2011 edge of each marginal area. */ 2021 edge of each marginal area. */
2012 + 1 + 1); 2022 + 1 + 1);
2013 } 2023 }
2014 #endif /* HAVE_WINDOW_SYSTEM */ 2024 #endif /* HAVE_WINDOW_SYSTEM */
2015 2025
2016 return XINT (w->width); 2026 return XINT (w->total_cols);
2017 } 2027 }
2018 2028
2019 2029
2020 /* Allocate window matrices for window-based redisplay. W is the 2030 /* Allocate window matrices for window-based redisplay. W is the
2021 window whose matrices must be allocated/reallocated. CH_DIM is the 2031 window whose matrices must be allocated/reallocated. CH_DIM is the
2096 adjust_frame_glyphs_initially () 2106 adjust_frame_glyphs_initially ()
2097 { 2107 {
2098 struct frame *sf = SELECTED_FRAME (); 2108 struct frame *sf = SELECTED_FRAME ();
2099 struct window *root = XWINDOW (sf->root_window); 2109 struct window *root = XWINDOW (sf->root_window);
2100 struct window *mini = XWINDOW (root->next); 2110 struct window *mini = XWINDOW (root->next);
2101 int frame_height = FRAME_HEIGHT (sf); 2111 int frame_lines = FRAME_LINES (sf);
2102 int frame_width = FRAME_WIDTH (sf); 2112 int frame_cols = FRAME_COLS (sf);
2103 int top_margin = FRAME_TOP_MARGIN (sf); 2113 int top_margin = FRAME_TOP_MARGIN (sf);
2104 2114
2105 /* Do it for the root window. */ 2115 /* Do it for the root window. */
2106 XSETFASTINT (root->top, top_margin); 2116 XSETFASTINT (root->top_line, top_margin);
2107 XSETFASTINT (root->width, frame_width); 2117 XSETFASTINT (root->total_cols, frame_cols);
2108 set_window_height (sf->root_window, frame_height - 1 - top_margin, 0); 2118 set_window_height (sf->root_window, frame_lines - 1 - top_margin, 0);
2109 2119
2110 /* Do it for the mini-buffer window. */ 2120 /* Do it for the mini-buffer window. */
2111 XSETFASTINT (mini->top, frame_height - 1); 2121 XSETFASTINT (mini->top_line, frame_lines - 1);
2112 XSETFASTINT (mini->width, frame_width); 2122 XSETFASTINT (mini->total_cols, frame_cols);
2113 set_window_height (root->next, 1, 0); 2123 set_window_height (root->next, 1, 0);
2114 2124
2115 adjust_frame_glyphs (sf); 2125 adjust_frame_glyphs (sf);
2116 glyphs_initialized_initially_p = 1; 2126 glyphs_initialized_initially_p = 1;
2117 } 2127 }
2159 int i; 2169 int i;
2160 struct frame *f = XFRAME (w->frame); 2170 struct frame *f = XFRAME (w->frame);
2161 struct glyph_matrix *m = w->current_matrix; 2171 struct glyph_matrix *m = w->current_matrix;
2162 struct glyph_matrix *fm = f->current_matrix; 2172 struct glyph_matrix *fm = f->current_matrix;
2163 2173
2164 xassert (m->matrix_h == XFASTINT (w->height)); 2174 xassert (m->matrix_h == WINDOW_TOTAL_LINES (w));
2165 xassert (m->matrix_w == XFASTINT (w->width)); 2175 xassert (m->matrix_w == WINDOW_TOTAL_COLS (w));
2166 2176
2167 for (i = 0; i < m->matrix_h; ++i) 2177 for (i = 0; i < m->matrix_h; ++i)
2168 { 2178 {
2169 struct glyph_row *r = m->rows + i; 2179 struct glyph_row *r = m->rows + i;
2170 struct glyph_row *fr = fm->rows + i + XFASTINT (w->top); 2180 struct glyph_row *fr = fm->rows + i + WINDOW_TOP_EDGE_LINE (w);
2171 2181
2172 xassert (r->glyphs[TEXT_AREA] >= fr->glyphs[TEXT_AREA] 2182 xassert (r->glyphs[TEXT_AREA] >= fr->glyphs[TEXT_AREA]
2173 && r->glyphs[LAST_AREA] <= fr->glyphs[LAST_AREA]); 2183 && r->glyphs[LAST_AREA] <= fr->glyphs[LAST_AREA]);
2174 2184
2175 r->enabled_p = fr->enabled_p; 2185 r->enabled_p = fr->enabled_p;
2311 &window_change_flags); 2321 &window_change_flags);
2312 2322
2313 /* Size of frame matrices must equal size of frame. Note 2323 /* Size of frame matrices must equal size of frame. Note
2314 that we are called for X frames with window widths NOT equal 2324 that we are called for X frames with window widths NOT equal
2315 to the frame width (from CHANGE_FRAME_SIZE_1). */ 2325 to the frame width (from CHANGE_FRAME_SIZE_1). */
2316 xassert (matrix_dim.width == FRAME_WIDTH (f) 2326 xassert (matrix_dim.width == FRAME_COLS (f)
2317 && matrix_dim.height == FRAME_HEIGHT (f)); 2327 && matrix_dim.height == FRAME_LINES (f));
2318 2328
2319 /* Pointers to glyph memory in glyph rows are exchanged during 2329 /* Pointers to glyph memory in glyph rows are exchanged during
2320 the update phase of redisplay, which means in general that a 2330 the update phase of redisplay, which means in general that a
2321 frame's current matrix consists of pointers into both the 2331 frame's current matrix consists of pointers into both the
2322 desired and current glyph pool of the frame. Adjusting a 2332 desired and current glyph pool of the frame. Adjusting a
2384 else 2394 else
2385 w = XWINDOW (f->menu_bar_window); 2395 w = XWINDOW (f->menu_bar_window);
2386 2396
2387 /* Set window dimensions to frame dimensions and allocate or 2397 /* Set window dimensions to frame dimensions and allocate or
2388 adjust glyph matrices of W. */ 2398 adjust glyph matrices of W. */
2389 XSETFASTINT (w->top, 0); 2399 XSETFASTINT (w->top_line, 0);
2390 XSETFASTINT (w->left, 0); 2400 XSETFASTINT (w->left_col, 0);
2391 XSETFASTINT (w->height, FRAME_MENU_BAR_LINES (f)); 2401 XSETFASTINT (w->total_lines, FRAME_MENU_BAR_LINES (f));
2392 XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f)); 2402 XSETFASTINT (w->total_cols, FRAME_TOTAL_COLS (f));
2393 allocate_matrices_for_window_redisplay (w); 2403 allocate_matrices_for_window_redisplay (w);
2394 } 2404 }
2395 #endif /* not USE_X_TOOLKIT */ 2405 #endif /* not USE_X_TOOLKIT */
2396 2406
2397 #ifndef USE_GTK 2407 #ifndef USE_GTK
2405 w->pseudo_window_p = 1; 2415 w->pseudo_window_p = 1;
2406 } 2416 }
2407 else 2417 else
2408 w = XWINDOW (f->tool_bar_window); 2418 w = XWINDOW (f->tool_bar_window);
2409 2419
2410 XSETFASTINT (w->top, FRAME_MENU_BAR_LINES (f)); 2420 XSETFASTINT (w->top_line, FRAME_MENU_BAR_LINES (f));
2411 XSETFASTINT (w->left, 0); 2421 XSETFASTINT (w->left_col, 0);
2412 XSETFASTINT (w->height, FRAME_TOOL_BAR_LINES (f)); 2422 XSETFASTINT (w->total_lines, FRAME_TOOL_BAR_LINES (f));
2413 XSETFASTINT (w->width, FRAME_WINDOW_WIDTH (f)); 2423 XSETFASTINT (w->total_cols, FRAME_TOTAL_COLS (f));
2414 allocate_matrices_for_window_redisplay (w); 2424 allocate_matrices_for_window_redisplay (w);
2415 #endif 2425 #endif
2416 } 2426 }
2417 2427
2418 2428
2711 2721
2712 /* Decide whether we want to add a vertical border glyph. */ 2722 /* Decide whether we want to add a vertical border glyph. */
2713 if (!WINDOW_RIGHTMOST_P (w)) 2723 if (!WINDOW_RIGHTMOST_P (w))
2714 { 2724 {
2715 struct Lisp_Char_Table *dp = window_display_table (w); 2725 struct Lisp_Char_Table *dp = window_display_table (w);
2716 right_border_glyph = (dp && INTEGERP (DISP_BORDER_GLYPH (dp)) 2726
2717 ? XINT (DISP_BORDER_GLYPH (dp)) 2727 right_border_glyph
2718 : '|'); 2728 = ((dp && INTEGERP (DISP_BORDER_GLYPH (dp)))
2729 ? spec_glyph_lookup_face (w, XINT (DISP_BORDER_GLYPH (dp)))
2730 : '|');
2731
2732 if (FAST_GLYPH_FACE (right_border_glyph) <= 0)
2733 right_border_glyph
2734 = FAST_MAKE_GLYPH (right_border_glyph, VERTICAL_BORDER_FACE_ID);
2719 } 2735 }
2720 } 2736 }
2721 else 2737 else
2722 window_matrix = w->current_matrix; 2738 window_matrix = w->current_matrix;
2723 2739
2769 { 2785 {
2770 struct glyph *border = window_row->glyphs[LAST_AREA] - 1; 2786 struct glyph *border = window_row->glyphs[LAST_AREA] - 1;
2771 SET_CHAR_GLYPH_FROM_GLYPH (*border, right_border_glyph); 2787 SET_CHAR_GLYPH_FROM_GLYPH (*border, right_border_glyph);
2772 } 2788 }
2773 2789
2790 #if GLYPH_DEBUG
2774 /* Window row window_y must be a slice of frame row 2791 /* Window row window_y must be a slice of frame row
2775 frame_y. */ 2792 frame_y. */
2776 xassert (glyph_row_slice_p (window_row, frame_row)); 2793 xassert (glyph_row_slice_p (window_row, frame_row));
2777 2794
2778 /* If rows are in sync, we don't have to copy glyphs because 2795 /* If rows are in sync, we don't have to copy glyphs because
2779 frame and window share glyphs. */ 2796 frame and window share glyphs. */
2780 2797
2781 #if GLYPH_DEBUG
2782 strcpy (w->current_matrix->method, w->desired_matrix->method); 2798 strcpy (w->current_matrix->method, w->desired_matrix->method);
2783 add_window_display_history (w, w->current_matrix->method, 0); 2799 add_window_display_history (w, w->current_matrix->method, 0);
2784 #endif 2800 #endif
2785 } 2801 }
2786 2802
2794 ++window_y; 2810 ++window_y;
2795 ++frame_y; 2811 ++frame_y;
2796 } 2812 }
2797 } 2813 }
2798 2814
2815 /* Given a user-specified glyph, possibly including a Lisp-level face
2816 ID, return a glyph that has a realized face ID.
2817 This is used for glyphs displayed specially and not part of the text;
2818 for instance, vertical separators, truncation markers, etc. */
2819
2820 GLYPH
2821 spec_glyph_lookup_face (w, glyph)
2822 struct window *w;
2823 GLYPH glyph;
2824 {
2825 int lface_id = FAST_GLYPH_FACE (glyph);
2826 /* Convert the glyph's specified face to a realized (cache) face. */
2827 if (lface_id > 0)
2828 {
2829 int face_id = merge_faces (XFRAME (w->frame),
2830 Qt, lface_id, DEFAULT_FACE_ID);
2831 glyph
2832 = FAST_MAKE_GLYPH (FAST_GLYPH_CHAR (glyph), face_id);
2833 }
2834 return glyph;
2835 }
2799 2836
2800 /* Add spaces to a glyph row ROW in a window matrix. 2837 /* Add spaces to a glyph row ROW in a window matrix.
2801 2838
2802 Each row has the form: 2839 Each row has the form:
2803 2840
3020 3057
3021 /* Preconditions: W must be a leaf window on a tty frame. */ 3058 /* Preconditions: W must be a leaf window on a tty frame. */
3022 xassert (NILP (w->hchild) && NILP (w->vchild)); 3059 xassert (NILP (w->hchild) && NILP (w->vchild));
3023 xassert (!FRAME_WINDOW_P (f)); 3060 xassert (!FRAME_WINDOW_P (f));
3024 3061
3025 left = margin_glyphs_to_reserve (w, 1, w->left_margin_width); 3062 left = margin_glyphs_to_reserve (w, 1, w->left_margin_cols);
3026 right = margin_glyphs_to_reserve (w, 1, w->right_margin_width); 3063 right = margin_glyphs_to_reserve (w, 1, w->right_margin_cols);
3027 x = w->current_matrix->matrix_x; 3064 x = w->current_matrix->matrix_x;
3028 width = w->current_matrix->matrix_w; 3065 width = w->current_matrix->matrix_w;
3029 3066
3030 window_row = w->current_matrix->rows; 3067 window_row = w->current_matrix->rows;
3031 window_row_end = window_row + w->current_matrix->nrows; 3068 window_row_end = window_row + w->current_matrix->nrows;
3032 frame_row = f->current_matrix->rows + XFASTINT (w->top); 3069 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
3033 3070
3034 for (; window_row < window_row_end; ++window_row, ++frame_row) 3071 for (; window_row < window_row_end; ++window_row, ++frame_row)
3035 { 3072 {
3036 window_row->glyphs[LEFT_MARGIN_AREA] 3073 window_row->glyphs[LEFT_MARGIN_AREA]
3037 = frame_row->glyphs[0] + x; 3074 = frame_row->glyphs[0] + x;
3059 { 3096 {
3060 if (!NILP (w->hchild)) 3097 if (!NILP (w->hchild))
3061 found = frame_row_to_window (XWINDOW (w->hchild), row); 3098 found = frame_row_to_window (XWINDOW (w->hchild), row);
3062 else if (!NILP (w->vchild)) 3099 else if (!NILP (w->vchild))
3063 found = frame_row_to_window (XWINDOW (w->vchild), row); 3100 found = frame_row_to_window (XWINDOW (w->vchild), row);
3064 else if (row >= XFASTINT (w->top) 3101 else if (row >= WINDOW_TOP_EDGE_LINE (w)
3065 && row < XFASTINT (w->top) + XFASTINT (w->height)) 3102 && row < WINDOW_BOTTOM_EDGE_LINE (w))
3066 found = w; 3103 found = w;
3067 3104
3068 w = NILP (w->next) ? 0 : XWINDOW (w->next); 3105 w = NILP (w->next) ? 0 : XWINDOW (w->next);
3069 } 3106 }
3070 3107
3156 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f)); 3193 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
3157 struct window *w2; 3194 struct window *w2;
3158 struct glyph_matrix *m2; 3195 struct glyph_matrix *m2;
3159 int m2_from; 3196 int m2_from;
3160 3197
3161 w2 = frame_row_to_window (root, frame_to); 3198 w2 = frame_row_to_window (root, frame_from);
3162 m2 = w2->current_matrix; 3199 /* ttn@surf.glug.org: when enabling menu bar using `emacs
3163 m2_from = frame_from - m2->matrix_y; 3200 -nw', FROM_FRAME sometimes has no associated window.
3164 copy_row_except_pointers (m->rows + window_to, 3201 This check avoids a segfault if W2 is null. */
3165 m2->rows + m2_from); 3202 if (w2)
3166 3203 {
3167 /* If frame line is empty, window line is empty, too. */ 3204 m2 = w2->current_matrix;
3168 if (!retained_p[copy_from[i]]) 3205 m2_from = frame_from - m2->matrix_y;
3169 m->rows[window_to].enabled_p = 0; 3206 copy_row_except_pointers (m->rows + window_to,
3207 m2->rows + m2_from);
3208
3209 /* If frame line is empty, window line is empty, too. */
3210 if (!retained_p[copy_from[i]])
3211 m->rows[window_to].enabled_p = 0;
3212 }
3170 sync_p = 1; 3213 sync_p = 1;
3171 } 3214 }
3172 else if (from_inside_window_p) 3215 else if (from_inside_window_p)
3173 sync_p = 1; 3216 sync_p = 1;
3174 } 3217 }
3265 { 3308 {
3266 struct frame *f = XFRAME (w->frame); 3309 struct frame *f = XFRAME (w->frame);
3267 3310
3268 xassert (!FRAME_WINDOW_P (f)); 3311 xassert (!FRAME_WINDOW_P (f));
3269 xassert (vpos >= 0 && vpos <= w->desired_matrix->nrows); 3312 xassert (vpos >= 0 && vpos <= w->desired_matrix->nrows);
3270 vpos += XFASTINT (w->top); 3313 vpos += WINDOW_TOP_EDGE_LINE (w);
3271 xassert (vpos >= 0 && vpos <= FRAME_HEIGHT (f)); 3314 xassert (vpos >= 0 && vpos <= FRAME_LINES (f));
3272 return vpos; 3315 return vpos;
3273 } 3316 }
3274 3317
3275 3318
3276 /* Translate horizontal position HPOS which is relative to window W to 3319 /* Translate horizontal position HPOS which is relative to window W to
3279 static int 3322 static int
3280 window_to_frame_hpos (w, hpos) 3323 window_to_frame_hpos (w, hpos)
3281 struct window *w; 3324 struct window *w;
3282 int hpos; 3325 int hpos;
3283 { 3326 {
3284 struct frame *f = XFRAME (w->frame); 3327 xassert (!FRAME_WINDOW_P (XFRAME (w->frame)));
3285 3328 hpos += WINDOW_LEFT_EDGE_COL (w);
3286 xassert (!FRAME_WINDOW_P (f));
3287 hpos += XFASTINT (w->left);
3288 return hpos; 3329 return hpos;
3289 } 3330 }
3290 3331
3291 #endif /* GLYPH_DEBUG */ 3332 #endif /* GLYPH_DEBUG */
3292 3333
3444 || !NILP (echo_area_buffer[1]) 3485 || !NILP (echo_area_buffer[1])
3445 || (glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos), 3486 || (glyph_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos),
3446 /* Can't do it in a continued line because continuation 3487 /* Can't do it in a continued line because continuation
3447 lines would change. */ 3488 lines would change. */
3448 (glyph_row->continued_p 3489 (glyph_row->continued_p
3490 || glyph_row->exact_window_width_line_p
3449 /* Can't use this method if the line overlaps others or is 3491 /* Can't use this method if the line overlaps others or is
3450 overlapped by others because these other lines would 3492 overlapped by others because these other lines would
3451 have to be redisplayed. */ 3493 have to be redisplayed. */
3452 || glyph_row->overlapping_p 3494 || glyph_row->overlapping_p
3453 || glyph_row->overlapped_p)) 3495 || glyph_row->overlapped_p))
3642 w->cursor.y, w->cursor.x); 3684 w->cursor.y, w->cursor.x);
3643 else 3685 else
3644 { 3686 {
3645 int x, y; 3687 int x, y;
3646 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos) 3688 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos)
3647 + (INTEGERP (w->left_margin_width) 3689 + (INTEGERP (w->left_margin_cols)
3648 ? XFASTINT (w->left_margin_width) 3690 ? XFASTINT (w->left_margin_cols)
3649 : 0)); 3691 : 0));
3650 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos); 3692 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
3651 cursor_to (y, x); 3693 cursor_to (y, x);
3652 } 3694 }
3695
3696 #ifdef HAVE_WINDOW_SYSTEM
3697 update_window_fringes (w, 0);
3698 #endif
3653 3699
3654 if (rif) 3700 if (rif)
3655 rif->update_window_end_hook (w, 1, 0); 3701 rif->update_window_end_hook (w, 1, 0);
3656 update_end (f); 3702 update_end (f);
3657 updated_row = NULL; 3703 updated_row = NULL;
3737 w->cursor.y, w->cursor.x); 3783 w->cursor.y, w->cursor.x);
3738 else 3784 else
3739 { 3785 {
3740 int x, y; 3786 int x, y;
3741 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos) 3787 x = (WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos)
3742 + (INTEGERP (w->left_margin_width) 3788 + (INTEGERP (w->left_margin_cols)
3743 ? XFASTINT (w->left_margin_width) 3789 ? XFASTINT (w->left_margin_cols)
3744 : 0)); 3790 : 0));
3745 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos); 3791 y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
3746 cursor_to (y, x); 3792 cursor_to (y, x);
3747 } 3793 }
3748 3794
3816 3862
3817 /* Update windows. */ 3863 /* Update windows. */
3818 paused_p = update_window_tree (root_window, force_p); 3864 paused_p = update_window_tree (root_window, force_p);
3819 update_end (f); 3865 update_end (f);
3820 3866
3821 #if 0 /* This flush is a performance bottleneck under X, 3867 /* This flush is a performance bottleneck under X,
3822 and it doesn't seem to be necessary anyway. */ 3868 and it doesn't seem to be necessary anyway (in general).
3823 rif->flush_display (f); 3869 It is necessary when resizing the window with the mouse, or
3824 #endif 3870 at least the fringes are not redrawn in a timely manner. ++kfs */
3871 if (f->force_flush_display_p)
3872 {
3873 rif->flush_display (f);
3874 f->force_flush_display_p = 0;
3875 }
3825 } 3876 }
3826 else 3877 else
3827 { 3878 {
3828 /* We are working on frame matrix basis. Set the frame on whose 3879 /* We are working on frame matrix basis. Set the frame on whose
3829 frame matrix we operate. */ 3880 frame matrix we operate. */
3910 /* Reset flag in W. */ 3961 /* Reset flag in W. */
3911 w->must_be_updated_p = 0; 3962 w->must_be_updated_p = 0;
3912 } 3963 }
3913 } 3964 }
3914 3965
3966 #ifdef HAVE_WINDOW_SYSTEM
3915 3967
3916 /* Redraw lines from the current matrix of window W that are 3968 /* Redraw lines from the current matrix of window W that are
3917 overlapped by other rows. YB is bottom-most y-position in W. */ 3969 overlapped by other rows. YB is bottom-most y-position in W. */
3918 3970
3919 static void 3971 static void
3982 4034
3983 bottom_y = MATRIX_ROW_BOTTOM_Y (row); 4035 bottom_y = MATRIX_ROW_BOTTOM_Y (row);
3984 4036
3985 if (row->overlapping_p && i > 0 && bottom_y < yb) 4037 if (row->overlapping_p && i > 0 && bottom_y < yb)
3986 { 4038 {
3987 if (row->used[LEFT_MARGIN_AREA]) 4039 int overlaps = 0;
3988 rif->fix_overlapping_area (w, row, LEFT_MARGIN_AREA); 4040
3989 4041 if (MATRIX_ROW_OVERLAPS_PRED_P (row)
3990 if (row->used[TEXT_AREA]) 4042 && !MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p)
3991 rif->fix_overlapping_area (w, row, TEXT_AREA); 4043 overlaps |= OVERLAPS_PRED;
3992 4044 if (MATRIX_ROW_OVERLAPS_SUCC_P (row)
3993 if (row->used[RIGHT_MARGIN_AREA]) 4045 && !MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p)
3994 rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA); 4046 overlaps |= OVERLAPS_SUCC;
3995 4047
3996 /* Record in neighbour rows that ROW overwrites part of their 4048 if (overlaps)
3997 display. */ 4049 {
3998 if (row->phys_ascent > row->ascent && i > 0) 4050 if (row->used[LEFT_MARGIN_AREA])
3999 MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1; 4051 rif->fix_overlapping_area (w, row, LEFT_MARGIN_AREA, overlaps);
4000 if ((row->phys_height - row->phys_ascent 4052
4001 > row->height - row->ascent) 4053 if (row->used[TEXT_AREA])
4002 && bottom_y < yb) 4054 rif->fix_overlapping_area (w, row, TEXT_AREA, overlaps);
4003 MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p = 1; 4055
4056 if (row->used[RIGHT_MARGIN_AREA])
4057 rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, overlaps);
4058
4059 /* Record in neighbour rows that ROW overwrites part of
4060 their display. */
4061 if (overlaps & OVERLAPS_PRED)
4062 MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1;
4063 if (overlaps & OVERLAPS_SUCC)
4064 MATRIX_ROW (w->current_matrix, i + 1)->overlapped_p = 1;
4065 }
4004 } 4066 }
4005 4067
4006 if (bottom_y >= yb) 4068 if (bottom_y >= yb)
4007 break; 4069 break;
4008 } 4070 }
4009 } 4071 }
4072
4073 #endif /* HAVE_WINDOW_SYSTEM */
4010 4074
4011 4075
4012 #ifdef GLYPH_DEBUG 4076 #ifdef GLYPH_DEBUG
4013 4077
4014 /* Check that no row in the current matrix of window W is enabled 4078 /* Check that no row in the current matrix of window W is enabled
4046 int paused_p; 4110 int paused_p;
4047 int preempt_count = baud_rate / 2400 + 1; 4111 int preempt_count = baud_rate / 2400 + 1;
4048 extern int input_pending; 4112 extern int input_pending;
4049 extern Lisp_Object do_mouse_tracking; 4113 extern Lisp_Object do_mouse_tracking;
4050 #if GLYPH_DEBUG 4114 #if GLYPH_DEBUG
4051 struct frame *f = XFRAME (WINDOW_FRAME (w)); 4115 /* Check that W's frame doesn't have glyph matrices. */
4052 extern struct frame *updating_frame; 4116 xassert (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))));
4117 xassert (updating_frame != NULL);
4053 #endif 4118 #endif
4054
4055 /* Check that W's frame doesn't have glyph matrices. */
4056 xassert (FRAME_WINDOW_P (f));
4057 xassert (updating_frame != NULL);
4058 4119
4059 /* Check pending input the first time so that we can quickly return. */ 4120 /* Check pending input the first time so that we can quickly return. */
4060 if (redisplay_dont_pause) 4121 if (redisplay_dont_pause)
4061 force_p = 1; 4122 force_p = 1;
4062 else 4123 else
4063 detect_input_pending (); 4124 detect_input_pending_ignore_squeezables ();
4064 4125
4065 /* If forced to complete the update, or if no input is pending, do 4126 /* If forced to complete the update, or if no input is pending, do
4066 the update. */ 4127 the update. */
4067 if (force_p || !input_pending || !NILP (do_mouse_tracking)) 4128 if (force_p || !input_pending || !NILP (do_mouse_tracking))
4068 { 4129 {
4113 /* All rows were found to be equal. */ 4174 /* All rows were found to be equal. */
4114 paused_p = 0; 4175 paused_p = 0;
4115 goto set_cursor; 4176 goto set_cursor;
4116 } 4177 }
4117 else if (rc > 0) 4178 else if (rc > 0)
4118 /* We've scrolled the display. */ 4179 {
4119 force_p = 1; 4180 /* We've scrolled the display. */
4120 changed_p = 1; 4181 force_p = 1;
4121 } 4182 changed_p = 1;
4122 4183 }
4123 /* Update the header line after scrolling because a new header
4124 line would otherwise overwrite lines at the top of the window
4125 that can be scrolled. */
4126 if (header_line_row && header_line_row->enabled_p)
4127 {
4128 header_line_row->y = 0;
4129 update_window_line (w, 0, &mouse_face_overwritten_p);
4130 changed_p = 1;
4131 } 4184 }
4132 4185
4133 /* Update the rest of the lines. */ 4186 /* Update the rest of the lines. */
4134 for (n_updated = 0; row < end && (force_p || !input_pending); ++row) 4187 for (n_updated = 0; row < end && (force_p || !input_pending); ++row)
4135 if (row->enabled_p) 4188 if (row->enabled_p)
4140 /* We'll have to play a little bit with when to 4193 /* We'll have to play a little bit with when to
4141 detect_input_pending. If it's done too often, 4194 detect_input_pending. If it's done too often,
4142 scrolling large windows with repeated scroll-up 4195 scrolling large windows with repeated scroll-up
4143 commands will too quickly pause redisplay. */ 4196 commands will too quickly pause redisplay. */
4144 if (!force_p && ++n_updated % preempt_count == 0) 4197 if (!force_p && ++n_updated % preempt_count == 0)
4145 detect_input_pending (); 4198 detect_input_pending_ignore_squeezables ();
4146 4199
4147 changed_p |= update_window_line (w, vpos, 4200 changed_p |= update_window_line (w, vpos,
4148 &mouse_face_overwritten_p); 4201 &mouse_face_overwritten_p);
4149 4202
4150 /* Mark all rows below the last visible one in the current 4203 /* Mark all rows below the last visible one in the current
4164 /* Was display preempted? */ 4217 /* Was display preempted? */
4165 paused_p = row < end; 4218 paused_p = row < end;
4166 4219
4167 set_cursor: 4220 set_cursor:
4168 4221
4222 /* Update the header line after scrolling because a new header
4223 line would otherwise overwrite lines at the top of the window
4224 that can be scrolled. */
4225 if (header_line_row && header_line_row->enabled_p)
4226 {
4227 header_line_row->y = 0;
4228 update_window_line (w, 0, &mouse_face_overwritten_p);
4229 changed_p = 1;
4230 }
4231
4169 /* Fix the appearance of overlapping/overlapped rows. */ 4232 /* Fix the appearance of overlapping/overlapped rows. */
4170 if (!paused_p && !w->pseudo_window_p) 4233 if (!paused_p && !w->pseudo_window_p)
4171 { 4234 {
4235 #ifdef HAVE_WINDOW_SYSTEM
4172 if (changed_p && rif->fix_overlapping_area) 4236 if (changed_p && rif->fix_overlapping_area)
4173 { 4237 {
4174 redraw_overlapped_rows (w, yb); 4238 redraw_overlapped_rows (w, yb);
4175 redraw_overlapping_rows (w, yb); 4239 redraw_overlapping_rows (w, yb);
4176 } 4240 }
4241 #endif
4177 4242
4178 /* Make cursor visible at cursor position of W. */ 4243 /* Make cursor visible at cursor position of W. */
4179 set_window_cursor_after_update (w); 4244 set_window_cursor_after_update (w);
4180 4245
4181 #if 0 /* Check that current matrix invariants are satisfied. This is 4246 #if 0 /* Check that current matrix invariants are satisfied. This is
4185 } 4250 }
4186 4251
4187 #if GLYPH_DEBUG 4252 #if GLYPH_DEBUG
4188 /* Remember the redisplay method used to display the matrix. */ 4253 /* Remember the redisplay method used to display the matrix. */
4189 strcpy (w->current_matrix->method, w->desired_matrix->method); 4254 strcpy (w->current_matrix->method, w->desired_matrix->method);
4255 #endif
4256
4257 #ifdef HAVE_WINDOW_SYSTEM
4258 update_window_fringes (w, 0);
4190 #endif 4259 #endif
4191 4260
4192 /* End the update of window W. Don't set the cursor if we 4261 /* End the update of window W. Don't set the cursor if we
4193 paused updating the display because in this case, 4262 paused updating the display because in this case,
4194 set_window_cursor_after_update hasn't been called, and 4263 set_window_cursor_after_update hasn't been called, and
4337 is "xxx ggg". The character `p' has lbearing, `g' 4406 is "xxx ggg". The character `p' has lbearing, `g'
4338 has not. The loop above will stop in front of the 4407 has not. The loop above will stop in front of the
4339 first `p' in the current row. If we would start 4408 first `p' in the current row. If we would start
4340 writing glyphs there, we wouldn't erase the lbearing 4409 writing glyphs there, we wouldn't erase the lbearing
4341 of the `p'. The rest of the lbearing problem is then 4410 of the `p'. The rest of the lbearing problem is then
4342 taken care of by x_draw_glyphs. */ 4411 taken care of by draw_glyphs. */
4343 if (overlapping_glyphs_p 4412 if (overlapping_glyphs_p
4344 && i > 0 4413 && i > 0
4345 && i < current_row->used[TEXT_AREA] 4414 && i < current_row->used[TEXT_AREA]
4346 && (current_row->used[TEXT_AREA] 4415 && (current_row->used[TEXT_AREA]
4347 != desired_row->used[TEXT_AREA])) 4416 != desired_row->used[TEXT_AREA]))
4416 else if (MATRIX_ROW_EXTENDS_FACE_P (current_row)) 4485 else if (MATRIX_ROW_EXTENDS_FACE_P (current_row))
4417 { 4486 {
4418 /* If old row extends to the end of the text area, clear. */ 4487 /* If old row extends to the end of the text area, clear. */
4419 if (i >= desired_row->used[TEXT_AREA]) 4488 if (i >= desired_row->used[TEXT_AREA])
4420 rif->cursor_to (vpos, i, desired_row->y, 4489 rif->cursor_to (vpos, i, desired_row->y,
4421 desired_row->x + desired_row->pixel_width); 4490 desired_row->pixel_width);
4422 rif->clear_end_of_line (-1); 4491 rif->clear_end_of_line (-1);
4423 changed_p = 1; 4492 changed_p = 1;
4424 } 4493 }
4425 else if (desired_row->pixel_width < current_row->pixel_width) 4494 else if (desired_row->pixel_width < current_row->pixel_width)
4426 { 4495 {
4428 after that position should be clear already. */ 4497 after that position should be clear already. */
4429 int x; 4498 int x;
4430 4499
4431 if (i >= desired_row->used[TEXT_AREA]) 4500 if (i >= desired_row->used[TEXT_AREA])
4432 rif->cursor_to (vpos, i, desired_row->y, 4501 rif->cursor_to (vpos, i, desired_row->y,
4433 desired_row->x + desired_row->pixel_width); 4502 desired_row->pixel_width);
4434 4503
4435 /* If cursor is displayed at the end of the line, make sure 4504 /* If cursor is displayed at the end of the line, make sure
4436 it's cleared. Nowadays we don't have a phys_cursor_glyph 4505 it's cleared. Nowadays we don't have a phys_cursor_glyph
4437 with which to erase the cursor (because this method 4506 with which to erase the cursor (because this method
4438 doesn't work with lbearing/rbearing), so we must do it 4507 doesn't work with lbearing/rbearing), so we must do it
4442 { 4511 {
4443 w->phys_cursor_on_p = 0; 4512 w->phys_cursor_on_p = 0;
4444 x = -1; 4513 x = -1;
4445 } 4514 }
4446 else 4515 else
4447 x = current_row->x + current_row->pixel_width; 4516 x = current_row->pixel_width;
4448 rif->clear_end_of_line (x); 4517 rif->clear_end_of_line (x);
4449 changed_p = 1; 4518 changed_p = 1;
4450 } 4519 }
4451 } 4520 }
4452 4521
4479 { 4548 {
4480 xassert (desired_row->enabled_p); 4549 xassert (desired_row->enabled_p);
4481 4550
4482 /* Update display of the left margin area, if there is one. */ 4551 /* Update display of the left margin area, if there is one. */
4483 if (!desired_row->full_width_p 4552 if (!desired_row->full_width_p
4484 && !NILP (w->left_margin_width)) 4553 && !NILP (w->left_margin_cols))
4485 { 4554 {
4486 changed_p = 1; 4555 changed_p = 1;
4487 update_marginal_area (w, LEFT_MARGIN_AREA, vpos); 4556 update_marginal_area (w, LEFT_MARGIN_AREA, vpos);
4488 } 4557 }
4489 4558
4495 *mouse_face_overwritten_p = 1; 4564 *mouse_face_overwritten_p = 1;
4496 } 4565 }
4497 4566
4498 /* Update display of the right margin area, if there is one. */ 4567 /* Update display of the right margin area, if there is one. */
4499 if (!desired_row->full_width_p 4568 if (!desired_row->full_width_p
4500 && !NILP (w->right_margin_width)) 4569 && !NILP (w->right_margin_cols))
4501 { 4570 {
4502 changed_p = 1; 4571 changed_p = 1;
4503 update_marginal_area (w, RIGHT_MARGIN_AREA, vpos); 4572 update_marginal_area (w, RIGHT_MARGIN_AREA, vpos);
4504 } 4573 }
4505 4574
4506 /* Draw truncation marks etc. */ 4575 /* Draw truncation marks etc. */
4507 if (!current_row->enabled_p 4576 if (!current_row->enabled_p
4508 || desired_row->y != current_row->y 4577 || desired_row->y != current_row->y
4509 || desired_row->visible_height != current_row->visible_height 4578 || desired_row->visible_height != current_row->visible_height
4510 || desired_row->overlay_arrow_p != current_row->overlay_arrow_p 4579 || desired_row->cursor_in_fringe_p != current_row->cursor_in_fringe_p
4511 || desired_row->truncated_on_left_p != current_row->truncated_on_left_p 4580 || desired_row->overlay_arrow_bitmap != current_row->overlay_arrow_bitmap
4512 || desired_row->truncated_on_right_p != current_row->truncated_on_right_p 4581 || current_row->redraw_fringe_bitmaps_p
4513 || desired_row->continued_p != current_row->continued_p
4514 || desired_row->mode_line_p != current_row->mode_line_p 4582 || desired_row->mode_line_p != current_row->mode_line_p
4515 || (desired_row->indicate_empty_line_p 4583 || desired_row->exact_window_width_line_p != current_row->exact_window_width_line_p
4516 != current_row->indicate_empty_line_p)
4517 || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row) 4584 || (MATRIX_ROW_CONTINUATION_LINE_P (desired_row)
4518 != MATRIX_ROW_CONTINUATION_LINE_P (current_row))) 4585 != MATRIX_ROW_CONTINUATION_LINE_P (current_row)))
4519 rif->after_update_window_line_hook (desired_row); 4586 rif->after_update_window_line_hook (desired_row);
4520 } 4587 }
4521 4588
4764 struct glyph_row *d = MATRIX_ROW (desired_matrix, i); 4831 struct glyph_row *d = MATRIX_ROW (desired_matrix, i);
4765 struct glyph_row *c = MATRIX_ROW (current_matrix, i); 4832 struct glyph_row *c = MATRIX_ROW (current_matrix, i);
4766 4833
4767 if (c->enabled_p 4834 if (c->enabled_p
4768 && d->enabled_p 4835 && d->enabled_p
4836 && !d->redraw_fringe_bitmaps_p
4769 && c->y == d->y 4837 && c->y == d->y
4770 && MATRIX_ROW_BOTTOM_Y (c) <= yb 4838 && MATRIX_ROW_BOTTOM_Y (c) <= yb
4771 && MATRIX_ROW_BOTTOM_Y (d) <= yb 4839 && MATRIX_ROW_BOTTOM_Y (d) <= yb
4772 && row_equal_p (w, c, d, 1)) 4840 && row_equal_p (w, c, d, 1))
4773 { 4841 {
4819 while (i - 1 > first_new 4887 while (i - 1 > first_new
4820 && j - 1 > first_old 4888 && j - 1 > first_old
4821 && MATRIX_ROW (current_matrix, i - 1)->enabled_p 4889 && MATRIX_ROW (current_matrix, i - 1)->enabled_p
4822 && (MATRIX_ROW (current_matrix, i - 1)->y 4890 && (MATRIX_ROW (current_matrix, i - 1)->y
4823 == MATRIX_ROW (desired_matrix, j - 1)->y) 4891 == MATRIX_ROW (desired_matrix, j - 1)->y)
4892 && !MATRIX_ROW (desired_matrix, j - 1)->redraw_fringe_bitmaps_p
4824 && row_equal_p (w, 4893 && row_equal_p (w,
4825 MATRIX_ROW (desired_matrix, i - 1), 4894 MATRIX_ROW (desired_matrix, i - 1),
4826 MATRIX_ROW (current_matrix, j - 1), 1)) 4895 MATRIX_ROW (current_matrix, j - 1), 1))
4827 --i, --j; 4896 --i, --j;
4828 last_new = i; 4897 last_new = i;
5011 int to_overlapped_p; 5080 int to_overlapped_p;
5012 5081
5013 to = MATRIX_ROW (current_matrix, r->desired_vpos + j); 5082 to = MATRIX_ROW (current_matrix, r->desired_vpos + j);
5014 from = MATRIX_ROW (desired_matrix, r->desired_vpos + j); 5083 from = MATRIX_ROW (desired_matrix, r->desired_vpos + j);
5015 to_overlapped_p = to->overlapped_p; 5084 to_overlapped_p = to->overlapped_p;
5085 if (!from->mode_line_p && !w->pseudo_window_p
5086 && (to->left_fringe_bitmap != from->left_fringe_bitmap
5087 || to->right_fringe_bitmap != from->right_fringe_bitmap
5088 || to->left_fringe_face_id != from->left_fringe_face_id
5089 || to->right_fringe_face_id != from->right_fringe_face_id
5090 || to->overlay_arrow_bitmap != from->overlay_arrow_bitmap))
5091 from->redraw_fringe_bitmaps_p = 1;
5016 assign_row (to, from); 5092 assign_row (to, from);
5017 to->enabled_p = 1, from->enabled_p = 0; 5093 to->enabled_p = 1, from->enabled_p = 0;
5018 to->overlapped_p = to_overlapped_p; 5094 to->overlapped_p = to_overlapped_p;
5019 } 5095 }
5020 } 5096 }
5021 5097
5022 /* Clear the hash table, for the next time. */ 5098 /* Clear the hash table, for the next time. */
5023 for (i = 0; i < row_entry_idx; ++i) 5099 for (i = 0; i < row_entry_idx; ++i)
5024 row_table[row_entry_pool[i].bucket] = NULL; 5100 row_table[row_entry_pool[i].bucket] = NULL;
5025 5101
5026 /* Value is non-zero to indicate that we scrolled the display. */ 5102 /* Value is > 0 to indicate that we scrolled the display. */
5027 return 1; 5103 return nruns;
5028 } 5104 }
5029 5105
5030 5106
5031 5107
5032 /************************************************************************ 5108 /************************************************************************
5063 if (preempt_count <= 0) 5139 if (preempt_count <= 0)
5064 preempt_count = 1; 5140 preempt_count = 1;
5065 5141
5066 if (redisplay_dont_pause) 5142 if (redisplay_dont_pause)
5067 force_p = 1; 5143 force_p = 1;
5068 else if (!force_p && detect_input_pending ()) 5144 else if (!force_p && detect_input_pending_ignore_squeezables ())
5069 { 5145 {
5070 pause = 1; 5146 pause = 1;
5071 goto do_pause; 5147 goto do_pause;
5072 } 5148 }
5073 5149
5119 } 5195 }
5120 } 5196 }
5121 } 5197 }
5122 5198
5123 if ((i - 1) % preempt_count == 0) 5199 if ((i - 1) % preempt_count == 0)
5124 detect_input_pending (); 5200 detect_input_pending_ignore_squeezables ();
5125 5201
5126 update_frame_line (f, i); 5202 update_frame_line (f, i);
5127 } 5203 }
5128 } 5204 }
5129 5205
5130 pause = (i < FRAME_HEIGHT (f) - 1) ? i : 0; 5206 pause = (i < FRAME_LINES (f) - 1) ? i : 0;
5131 5207
5132 /* Now just clean up termcap drivers and set cursor, etc. */ 5208 /* Now just clean up termcap drivers and set cursor, etc. */
5133 if (!pause) 5209 if (!pause)
5134 { 5210 {
5135 if ((cursor_in_echo_area 5211 if ((cursor_in_echo_area
5142 /* These cases apply only to the frame that contains 5218 /* These cases apply only to the frame that contains
5143 the active mini-buffer window. */ 5219 the active mini-buffer window. */
5144 && FRAME_HAS_MINIBUF_P (f) 5220 && FRAME_HAS_MINIBUF_P (f)
5145 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window)) 5221 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
5146 { 5222 {
5147 int top = XINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top); 5223 int top = WINDOW_TOP_EDGE_LINE (XWINDOW (FRAME_MINIBUF_WINDOW (f)));
5148 int row, col; 5224 int row, col;
5149 5225
5150 if (cursor_in_echo_area < 0) 5226 if (cursor_in_echo_area < 0)
5151 { 5227 {
5152 /* Negative value of cursor_in_echo_area means put 5228 /* Negative value of cursor_in_echo_area means put
5158 { 5234 {
5159 /* Positive value of cursor_in_echo_area means put 5235 /* Positive value of cursor_in_echo_area means put
5160 cursor at the end of the prompt. If the mini-buffer 5236 cursor at the end of the prompt. If the mini-buffer
5161 is several lines high, find the last line that has 5237 is several lines high, find the last line that has
5162 any text on it. */ 5238 any text on it. */
5163 row = FRAME_HEIGHT (f); 5239 row = FRAME_LINES (f);
5164 do 5240 do
5165 { 5241 {
5166 --row; 5242 --row;
5167 col = 0; 5243 col = 0;
5168 5244
5186 5262
5187 /* Make sure COL is not out of range. */ 5263 /* Make sure COL is not out of range. */
5188 if (col >= FRAME_CURSOR_X_LIMIT (f)) 5264 if (col >= FRAME_CURSOR_X_LIMIT (f))
5189 { 5265 {
5190 /* If we have another row, advance cursor into it. */ 5266 /* If we have another row, advance cursor into it. */
5191 if (row < FRAME_HEIGHT (f) - 1) 5267 if (row < FRAME_LINES (f) - 1)
5192 { 5268 {
5193 col = FRAME_LEFT_SCROLL_BAR_WIDTH (f); 5269 col = FRAME_LEFT_SCROLL_BAR_COLS (f);
5194 row++; 5270 row++;
5195 } 5271 }
5196 /* Otherwise move it back in range. */ 5272 /* Otherwise move it back in range. */
5197 else 5273 else
5198 col = FRAME_CURSOR_X_LIMIT (f) - 1; 5274 col = FRAME_CURSOR_X_LIMIT (f) - 1;
5210 /* The cursor vpos may be temporarily out of bounds 5286 /* The cursor vpos may be temporarily out of bounds
5211 in the following situation: There is one window, 5287 in the following situation: There is one window,
5212 with the cursor in the lower half of it. The window 5288 with the cursor in the lower half of it. The window
5213 is split, and a message causes a redisplay before 5289 is split, and a message causes a redisplay before
5214 a new cursor position has been computed. */ 5290 a new cursor position has been computed. */
5215 && w->cursor.vpos < XFASTINT (w->height)) 5291 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
5216 { 5292 {
5217 int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos); 5293 int x = WINDOW_TO_FRAME_HPOS (w, w->cursor.hpos);
5218 int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos); 5294 int y = WINDOW_TO_FRAME_VPOS (w, w->cursor.vpos);
5219 5295
5220 if (INTEGERP (w->left_margin_width)) 5296 if (INTEGERP (w->left_margin_cols))
5221 x += XFASTINT (w->left_margin_width); 5297 x += XFASTINT (w->left_margin_cols);
5222 5298
5223 /* x = max (min (x, FRAME_WINDOW_WIDTH (f) - 1), 0); */ 5299 /* x = max (min (x, FRAME_TOTAL_COLS (f) - 1), 0); */
5224 cursor_to (y, x); 5300 cursor_to (y, x);
5225 } 5301 }
5226 } 5302 }
5227 } 5303 }
5228 5304
5240 struct frame *frame; 5316 struct frame *frame;
5241 { 5317 {
5242 int unchanged_at_top, unchanged_at_bottom; 5318 int unchanged_at_top, unchanged_at_bottom;
5243 int window_size; 5319 int window_size;
5244 int changed_lines; 5320 int changed_lines;
5245 int *old_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int)); 5321 int *old_hash = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
5246 int *new_hash = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int)); 5322 int *new_hash = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
5247 int *draw_cost = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int)); 5323 int *draw_cost = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
5248 int *old_draw_cost = (int *) alloca (FRAME_HEIGHT (frame) * sizeof (int)); 5324 int *old_draw_cost = (int *) alloca (FRAME_LINES (frame) * sizeof (int));
5249 register int i; 5325 register int i;
5250 int free_at_end_vpos = FRAME_HEIGHT (frame); 5326 int free_at_end_vpos = FRAME_LINES (frame);
5251 struct glyph_matrix *current_matrix = frame->current_matrix; 5327 struct glyph_matrix *current_matrix = frame->current_matrix;
5252 struct glyph_matrix *desired_matrix = frame->desired_matrix; 5328 struct glyph_matrix *desired_matrix = frame->desired_matrix;
5253 5329
5254 if (!current_matrix) 5330 if (!current_matrix)
5255 abort (); 5331 abort ();
5257 /* Compute hash codes of all the lines. Also calculate number of 5333 /* Compute hash codes of all the lines. Also calculate number of
5258 changed lines, number of unchanged lines at the beginning, and 5334 changed lines, number of unchanged lines at the beginning, and
5259 number of unchanged lines at the end. */ 5335 number of unchanged lines at the end. */
5260 changed_lines = 0; 5336 changed_lines = 0;
5261 unchanged_at_top = 0; 5337 unchanged_at_top = 0;
5262 unchanged_at_bottom = FRAME_HEIGHT (frame); 5338 unchanged_at_bottom = FRAME_LINES (frame);
5263 for (i = 0; i < FRAME_HEIGHT (frame); i++) 5339 for (i = 0; i < FRAME_LINES (frame); i++)
5264 { 5340 {
5265 /* Give up on this scrolling if some old lines are not enabled. */ 5341 /* Give up on this scrolling if some old lines are not enabled. */
5266 if (!MATRIX_ROW_ENABLED_P (current_matrix, i)) 5342 if (!MATRIX_ROW_ENABLED_P (current_matrix, i))
5267 return 0; 5343 return 0;
5268 old_hash[i] = line_hash_code (MATRIX_ROW (current_matrix, i)); 5344 old_hash[i] = line_hash_code (MATRIX_ROW (current_matrix, i));
5280 } 5356 }
5281 5357
5282 if (old_hash[i] != new_hash[i]) 5358 if (old_hash[i] != new_hash[i])
5283 { 5359 {
5284 changed_lines++; 5360 changed_lines++;
5285 unchanged_at_bottom = FRAME_HEIGHT (frame) - i - 1; 5361 unchanged_at_bottom = FRAME_LINES (frame) - i - 1;
5286 } 5362 }
5287 else if (i == unchanged_at_top) 5363 else if (i == unchanged_at_top)
5288 unchanged_at_top++; 5364 unchanged_at_top++;
5289 old_draw_cost[i] = line_draw_cost (current_matrix, i); 5365 old_draw_cost[i] = line_draw_cost (current_matrix, i);
5290 } 5366 }
5291 5367
5292 /* If changed lines are few, don't allow preemption, don't scroll. */ 5368 /* If changed lines are few, don't allow preemption, don't scroll. */
5293 if ((!scroll_region_ok && changed_lines < baud_rate / 2400) 5369 if ((!scroll_region_ok && changed_lines < baud_rate / 2400)
5294 || unchanged_at_bottom == FRAME_HEIGHT (frame)) 5370 || unchanged_at_bottom == FRAME_LINES (frame))
5295 return 1; 5371 return 1;
5296 5372
5297 window_size = (FRAME_HEIGHT (frame) - unchanged_at_top 5373 window_size = (FRAME_LINES (frame) - unchanged_at_top
5298 - unchanged_at_bottom); 5374 - unchanged_at_bottom);
5299 5375
5300 if (scroll_region_ok) 5376 if (scroll_region_ok)
5301 free_at_end_vpos -= unchanged_at_bottom; 5377 free_at_end_vpos -= unchanged_at_bottom;
5302 else if (memory_below_frame) 5378 else if (memory_below_frame)
5305 /* If large window, fast terminal and few lines in common between 5381 /* If large window, fast terminal and few lines in common between
5306 current frame and desired frame, don't bother with i/d calc. */ 5382 current frame and desired frame, don't bother with i/d calc. */
5307 if (!scroll_region_ok && window_size >= 18 && baud_rate > 2400 5383 if (!scroll_region_ok && window_size >= 18 && baud_rate > 2400
5308 && (window_size >= 5384 && (window_size >=
5309 10 * scrolling_max_lines_saved (unchanged_at_top, 5385 10 * scrolling_max_lines_saved (unchanged_at_top,
5310 FRAME_HEIGHT (frame) - unchanged_at_bottom, 5386 FRAME_LINES (frame) - unchanged_at_bottom,
5311 old_hash, new_hash, draw_cost))) 5387 old_hash, new_hash, draw_cost)))
5312 return 0; 5388 return 0;
5313 5389
5314 if (window_size < 2) 5390 if (window_size < 2)
5315 return 0; 5391 return 0;
5364 5440
5365 5441
5366 /* Char insertion/deletion cost vector, from term.c */ 5442 /* Char insertion/deletion cost vector, from term.c */
5367 5443
5368 extern int *char_ins_del_vector; 5444 extern int *char_ins_del_vector;
5369 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WINDOW_WIDTH((f))]) 5445 #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_TOTAL_COLS((f))])
5370 5446
5371 5447
5372 /* Perform a frame-based update on line VPOS in frame FRAME. */ 5448 /* Perform a frame-based update on line VPOS in frame FRAME. */
5373 5449
5374 static void 5450 static void
5440 } 5516 }
5441 5517
5442 /* Don't call clear_end_of_line if we already wrote the whole 5518 /* Don't call clear_end_of_line if we already wrote the whole
5443 line. The cursor will not be at the right margin in that 5519 line. The cursor will not be at the right margin in that
5444 case but in the line below. */ 5520 case but in the line below. */
5445 if (nlen < FRAME_WINDOW_WIDTH (f)) 5521 if (nlen < FRAME_TOTAL_COLS (f))
5446 { 5522 {
5447 cursor_to (vpos, nlen); 5523 cursor_to (vpos, nlen);
5448 clear_end_of_line (FRAME_WINDOW_WIDTH (f)); 5524 clear_end_of_line (FRAME_TOTAL_COLS (f));
5449 } 5525 }
5450 else 5526 else
5451 /* Make sure we are in the right row, otherwise cursor movement 5527 /* Make sure we are in the right row, otherwise cursor movement
5452 with cmgoto might use `ch' in the wrong row. */ 5528 with cmgoto might use `ch' in the wrong row. */
5453 cursor_to (vpos, 0); 5529 cursor_to (vpos, 0);
5614 { 5690 {
5615 /* If new text being written reaches right margin, there is 5691 /* If new text being written reaches right margin, there is
5616 no need to do clear-to-eol at the end of this function 5692 no need to do clear-to-eol at the end of this function
5617 (and it would not be safe, since cursor is not going to 5693 (and it would not be safe, since cursor is not going to
5618 be "at the margin" after the text is done). */ 5694 be "at the margin" after the text is done). */
5619 if (nlen == FRAME_WINDOW_WIDTH (f)) 5695 if (nlen == FRAME_TOTAL_COLS (f))
5620 olen = 0; 5696 olen = 0;
5621 5697
5622 /* Function write_glyphs is prepared to do nothing 5698 /* Function write_glyphs is prepared to do nothing
5623 if passed a length <= 0. Check it here to avoid 5699 if passed a length <= 0. Check it here to avoid
5624 unnecessary cursor movement. */ 5700 unnecessary cursor movement. */
5682 /*********************************************************************** 5758 /***********************************************************************
5683 X/Y Position -> Buffer Position 5759 X/Y Position -> Buffer Position
5684 ***********************************************************************/ 5760 ***********************************************************************/
5685 5761
5686 /* Determine what's under window-relative pixel position (*X, *Y). 5762 /* Determine what's under window-relative pixel position (*X, *Y).
5687 Return in *OBJECT the object (string or buffer) that's there. 5763 Return the object (string or buffer) that's there.
5688 Return in *POS the position in that object. Adjust *X and *Y 5764 Return in *POS the position in that object.
5689 to character boundaries. */ 5765 Adjust *X and *Y to character positions. */
5690 5766
5691 void 5767 Lisp_Object
5692 buffer_posn_from_coords (w, x, y, object, pos) 5768 buffer_posn_from_coords (w, x, y, pos, object, dx, dy, width, height)
5693 struct window *w; 5769 struct window *w;
5694 int *x, *y; 5770 int *x, *y;
5771 struct display_pos *pos;
5695 Lisp_Object *object; 5772 Lisp_Object *object;
5696 struct display_pos *pos; 5773 int *dx, *dy;
5774 int *width, *height;
5697 { 5775 {
5698 struct it it; 5776 struct it it;
5699 struct buffer *old_current_buffer = current_buffer; 5777 struct buffer *old_current_buffer = current_buffer;
5700 struct text_pos startp; 5778 struct text_pos startp;
5701 int left_area_width; 5779 Lisp_Object string;
5780 struct glyph_row *row;
5781 #ifdef HAVE_WINDOW_SYSTEM
5782 struct image *img = 0;
5783 #endif
5784 int x0, x1;
5702 5785
5703 current_buffer = XBUFFER (w->buffer); 5786 current_buffer = XBUFFER (w->buffer);
5704 SET_TEXT_POS_FROM_MARKER (startp, w->start); 5787 SET_TEXT_POS_FROM_MARKER (startp, w->start);
5705 CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp))); 5788 CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp)));
5706 BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp))); 5789 BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp)));
5707 start_display (&it, w, startp); 5790 start_display (&it, w, startp);
5708 5791
5709 left_area_width = WINDOW_DISPLAY_LEFT_AREA_PIXEL_WIDTH (w); 5792 x0 = *x - WINDOW_LEFT_MARGIN_WIDTH (w);
5710 move_it_to (&it, -1, *x + it.first_visible_x - left_area_width, *y, -1, 5793 move_it_to (&it, -1, x0 + it.first_visible_x, *y, -1,
5711 MOVE_TO_X | MOVE_TO_Y); 5794 MOVE_TO_X | MOVE_TO_Y);
5712 5795
5713 *x = it.current_x - it.first_visible_x + left_area_width;
5714 *y = it.current_y;
5715 current_buffer = old_current_buffer; 5796 current_buffer = old_current_buffer;
5716 5797
5717 *object = STRINGP (it.string) ? it.string : w->buffer; 5798 *dx = x0 + it.first_visible_x - it.current_x;
5799 *dy = *y - it.current_y;
5800
5801 string = w->buffer;
5802 if (STRINGP (it.string))
5803 string = it.string;
5718 *pos = it.current; 5804 *pos = it.current;
5805
5806 #ifdef HAVE_WINDOW_SYSTEM
5807 if (it.what == IT_IMAGE)
5808 {
5809 if ((img = IMAGE_FROM_ID (it.f, it.image_id)) != NULL
5810 && !NILP (img->spec))
5811 *object = img->spec;
5812 }
5813 #endif
5814
5815 if (it.vpos < w->current_matrix->nrows
5816 && (row = MATRIX_ROW (w->current_matrix, it.vpos),
5817 row->enabled_p))
5818 {
5819 if (it.hpos < row->used[TEXT_AREA])
5820 {
5821 struct glyph *glyph = row->glyphs[TEXT_AREA] + it.hpos;
5822 #ifdef HAVE_WINDOW_SYSTEM
5823 if (img)
5824 {
5825 *dy -= row->ascent - glyph->ascent;
5826 *dx += glyph->slice.x;
5827 *dy += glyph->slice.y;
5828 /* Image slices positions are still relative to the entire image */
5829 *width = img->width;
5830 *height = img->height;
5831 }
5832 else
5833 #endif
5834 {
5835 *width = glyph->pixel_width;
5836 *height = glyph->ascent + glyph->descent;
5837 }
5838 }
5839 else
5840 {
5841 *width = 0;
5842 *height = row->height;
5843 }
5844 }
5845 else
5846 {
5847 *width = *height = 0;
5848 }
5849
5850 /* Add extra (default width) columns if clicked after EOL. */
5851 x1 = max(0, it.current_x + it.pixel_width - it.first_visible_x);
5852 if (x0 > x1)
5853 it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w);
5854
5855 *x = it.hpos;
5856 *y = it.vpos;
5857
5858 return string;
5719 } 5859 }
5720 5860
5721 5861
5722 /* Value is the string under window-relative coordinates X/Y in the 5862 /* Value is the string under window-relative coordinates X/Y in the
5723 mode or header line of window W, or nil if none. MODE_LINE_P non-zero 5863 mode line or header line (PART says which) of window W, or nil if none.
5724 means look at the mode line. *CHARPOS is set to the position in 5864 *CHARPOS is set to the position in the string returned. */
5725 the string returned. */
5726 5865
5727 Lisp_Object 5866 Lisp_Object
5728 mode_line_string (w, x, y, mode_line_p, charpos) 5867 mode_line_string (w, part, x, y, charpos, object, dx, dy, width, height)
5729 struct window *w; 5868 struct window *w;
5730 int x, y, mode_line_p; 5869 enum window_part part;
5870 int *x, *y;
5731 int *charpos; 5871 int *charpos;
5872 Lisp_Object *object;
5873 int *dx, *dy;
5874 int *width, *height;
5732 { 5875 {
5733 struct glyph_row *row; 5876 struct glyph_row *row;
5734 struct glyph *glyph, *end; 5877 struct glyph *glyph, *end;
5735 struct frame *f = XFRAME (w->frame); 5878 int x0, y0;
5736 int x0;
5737 Lisp_Object string = Qnil; 5879 Lisp_Object string = Qnil;
5738 5880
5739 if (mode_line_p) 5881 if (part == ON_MODE_LINE)
5740 row = MATRIX_MODE_LINE_ROW (w->current_matrix); 5882 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
5741 else 5883 else
5742 row = MATRIX_HEADER_LINE_ROW (w->current_matrix); 5884 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
5885 y0 = *y - row->y;
5886 *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix);
5743 5887
5744 if (row->mode_line_p && row->enabled_p) 5888 if (row->mode_line_p && row->enabled_p)
5745 { 5889 {
5746 /* The mode lines are displayed over scroll bars and fringes,
5747 and X is window-relative. Correct X by the scroll bar
5748 and fringe width. */
5749 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
5750 x += FRAME_SCROLL_BAR_COLS (f) * CANON_X_UNIT (f);
5751 x += FRAME_LEFT_FRINGE_WIDTH (f);
5752
5753 /* Find the glyph under X. If we find one with a string object, 5890 /* Find the glyph under X. If we find one with a string object,
5754 it's the one we were looking for. */ 5891 it's the one we were looking for. */
5755 glyph = row->glyphs[TEXT_AREA]; 5892 glyph = row->glyphs[TEXT_AREA];
5756 end = glyph + row->used[TEXT_AREA]; 5893 end = glyph + row->used[TEXT_AREA];
5757 for (x0 = 0; glyph < end; x0 += glyph->pixel_width, ++glyph) 5894 for (x0 = *x; glyph < end && x0 >= glyph->pixel_width; ++glyph)
5758 if (x >= x0 && x < x0 + glyph->pixel_width) 5895 x0 -= glyph->pixel_width;
5759 { 5896 *x = glyph - row->glyphs[TEXT_AREA];
5760 string = glyph->object; 5897 if (glyph < end)
5761 *charpos = glyph->charpos; 5898 {
5762 break; 5899 string = glyph->object;
5763 } 5900 *charpos = glyph->charpos;
5764 } 5901 *width = glyph->pixel_width;
5902 *height = glyph->ascent + glyph->descent;
5903 #ifdef HAVE_WINDOW_SYSTEM
5904 if (glyph->type == IMAGE_GLYPH)
5905 {
5906 struct image *img;
5907 img = IMAGE_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
5908 if (img != NULL)
5909 *object = img->spec;
5910 y0 -= row->ascent - glyph->ascent;
5911 }
5912 #endif
5913 }
5914 else
5915 {
5916 /* Add extra (default width) columns if clicked after EOL. */
5917 *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
5918 *width = 0;
5919 *height = row->height;
5920 }
5921 }
5922 else
5923 {
5924 *x = 0;
5925 x0 = 0;
5926 *width = *height = 0;
5927 }
5928
5929 *dx = x0;
5930 *dy = y0;
5765 5931
5766 return string; 5932 return string;
5767 } 5933 }
5768 5934
5769 5935
5770 /* Value is the string under window-relative coordinates X/Y in either 5936 /* Value is the string under window-relative coordinates X/Y in either
5771 marginal area, or nil if none. *CHARPOS is set to the position in 5937 marginal area, or nil if none. *CHARPOS is set to the position in
5772 the string returned. */ 5938 the string returned. */
5773 5939
5774 Lisp_Object 5940 Lisp_Object
5775 marginal_area_string (w, x, y, area, charpos) 5941 marginal_area_string (w, part, x, y, charpos, object, dx, dy, width, height)
5776 struct window *w; 5942 struct window *w;
5777 int x, y; 5943 enum window_part part;
5778 int area; 5944 int *x, *y;
5779 int *charpos; 5945 int *charpos;
5946 Lisp_Object *object;
5947 int *dx, *dy;
5948 int *width, *height;
5780 { 5949 {
5781 struct glyph_row *row = w->current_matrix->rows; 5950 struct glyph_row *row = w->current_matrix->rows;
5782 struct glyph *glyph, *end; 5951 struct glyph *glyph, *end;
5783 int x0, i, wy = y; 5952 int x0, y0, i, wy = *y;
5953 int area;
5784 Lisp_Object string = Qnil; 5954 Lisp_Object string = Qnil;
5785 5955
5786 if (area == 6) 5956 if (part == ON_LEFT_MARGIN)
5787 area = LEFT_MARGIN_AREA; 5957 area = LEFT_MARGIN_AREA;
5788 else if (area == 7) 5958 else if (part == ON_RIGHT_MARGIN)
5789 area = RIGHT_MARGIN_AREA; 5959 area = RIGHT_MARGIN_AREA;
5790 else 5960 else
5791 abort (); 5961 abort ();
5792 5962
5793 for (i = 0; row->enabled_p && i < w->current_matrix->nrows; ++i, ++row) 5963 for (i = 0; row->enabled_p && i < w->current_matrix->nrows; ++i, ++row)
5794 if (wy >= row->y && wy < MATRIX_ROW_BOTTOM_Y (row)) 5964 if (wy >= row->y && wy < MATRIX_ROW_BOTTOM_Y (row))
5795 break; 5965 break;
5966 y0 = *y - row->y;
5967 *y = row - MATRIX_FIRST_TEXT_ROW (w->current_matrix);
5796 5968
5797 if (row->enabled_p) 5969 if (row->enabled_p)
5798 { 5970 {
5799 /* Find the glyph under X. If we find one with a string object, 5971 /* Find the glyph under X. If we find one with a string object,
5800 it's the one we were looking for. */ 5972 it's the one we were looking for. */
5973 if (area == RIGHT_MARGIN_AREA)
5974 x0 = ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5975 ? WINDOW_LEFT_FRINGE_WIDTH (w)
5976 : WINDOW_TOTAL_FRINGE_WIDTH (w))
5977 + window_box_width (w, LEFT_MARGIN_AREA)
5978 + window_box_width (w, TEXT_AREA));
5979 else
5980 x0 = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5981 ? WINDOW_LEFT_FRINGE_WIDTH (w)
5982 : 0);
5983
5801 glyph = row->glyphs[area]; 5984 glyph = row->glyphs[area];
5802 end = glyph + row->used[area]; 5985 end = glyph + row->used[area];
5803 if (area == RIGHT_MARGIN_AREA) 5986 for (x0 = *x - x0; glyph < end && x0 >= glyph->pixel_width; ++glyph)
5804 x0 = (window_box_width (w, TEXT_AREA) 5987 x0 -= glyph->pixel_width;
5805 + window_box_width (w, LEFT_MARGIN_AREA)); 5988 *x = glyph - row->glyphs[area];
5989 if (glyph < end)
5990 {
5991 string = glyph->object;
5992 *charpos = glyph->charpos;
5993 *width = glyph->pixel_width;
5994 *height = glyph->ascent + glyph->descent;
5995 #ifdef HAVE_WINDOW_SYSTEM
5996 if (glyph->type == IMAGE_GLYPH)
5997 {
5998 struct image *img;
5999 img = IMAGE_FROM_ID (WINDOW_XFRAME (w), glyph->u.img_id);
6000 if (img != NULL)
6001 *object = img->spec;
6002 y0 -= row->ascent - glyph->ascent;
6003 x0 += glyph->slice.x;
6004 y0 += glyph->slice.y;
6005 }
6006 #endif
6007 }
5806 else 6008 else
5807 x0 = 0; 6009 {
5808 for (; glyph < end; x0 += glyph->pixel_width, ++glyph) 6010 /* Add extra (default width) columns if clicked after EOL. */
5809 if (x >= x0 && x < x0 + glyph->pixel_width) 6011 *x += x0 / WINDOW_FRAME_COLUMN_WIDTH (w);
5810 { 6012 *width = 0;
5811 string = glyph->object; 6013 *height = row->height;
5812 *charpos = glyph->charpos; 6014 }
5813 break; 6015 }
5814 } 6016 else
5815 } 6017 {
6018 x0 = 0;
6019 *x = 0;
6020 *width = *height = 0;
6021 }
6022
6023 *dx = x0;
6024 *dy = y0;
5816 6025
5817 return string; 6026 return string;
5818 } 6027 }
5819 6028
5820 6029
5831 int width, height; 6040 int width, height;
5832 #ifndef USE_CRT_DLL 6041 #ifndef USE_CRT_DLL
5833 extern int errno; 6042 extern int errno;
5834 #endif 6043 #endif
5835 int old_errno = errno; 6044 int old_errno = errno;
6045
6046 signal (SIGWINCH, window_change_signal);
6047 SIGNAL_THREAD_CHECK (signalnum);
5836 6048
5837 get_frame_size (&width, &height); 6049 get_frame_size (&width, &height);
5838 6050
5839 /* The frame size change obviously applies to a termcap-controlled 6051 /* The frame size change obviously applies to a termcap-controlled
5840 frame. Find such a frame in the list, and assume it's the only 6052 frame. Find such a frame in the list, and assume it's the only
5854 break; 6066 break;
5855 } 6067 }
5856 } 6068 }
5857 } 6069 }
5858 6070
5859 signal (SIGWINCH, window_change_signal);
5860 errno = old_errno; 6071 errno = old_errno;
5861 } 6072 }
5862 #endif /* SIGWINCH */ 6073 #endif /* SIGWINCH */
5863 6074
5864 6075
5882 6093
5883 FOR_EACH_FRAME (tail, frame) 6094 FOR_EACH_FRAME (tail, frame)
5884 { 6095 {
5885 struct frame *f = XFRAME (frame); 6096 struct frame *f = XFRAME (frame);
5886 6097
5887 int height = FRAME_NEW_HEIGHT (f); 6098 if (f->new_text_lines != 0 || f->new_text_cols != 0)
5888 int width = FRAME_NEW_WIDTH (f); 6099 change_frame_size (f, f->new_text_lines, f->new_text_cols,
5889 6100 0, 0, safe);
5890 if (height != 0 || width != 0)
5891 change_frame_size (f, height, width, 0, 0, safe);
5892 } 6101 }
5893 } 6102 }
5894 } 6103 }
5895 6104
5896 6105
5928 static void 6137 static void
5929 change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe) 6138 change_frame_size_1 (f, newheight, newwidth, pretend, delay, safe)
5930 register struct frame *f; 6139 register struct frame *f;
5931 int newheight, newwidth, pretend, delay, safe; 6140 int newheight, newwidth, pretend, delay, safe;
5932 { 6141 {
5933 int new_frame_window_width; 6142 int new_frame_total_cols;
5934 int count = SPECPDL_INDEX (); 6143 int count = SPECPDL_INDEX ();
5935 6144
5936 /* If we can't deal with the change now, queue it for later. */ 6145 /* If we can't deal with the change now, queue it for later. */
5937 if (delay || (redisplaying_p && !safe)) 6146 if (delay || (redisplaying_p && !safe))
5938 { 6147 {
5939 FRAME_NEW_HEIGHT (f) = newheight; 6148 f->new_text_lines = newheight;
5940 FRAME_NEW_WIDTH (f) = newwidth; 6149 f->new_text_cols = newwidth;
5941 delayed_size_change = 1; 6150 delayed_size_change = 1;
5942 return; 6151 return;
5943 } 6152 }
5944 6153
5945 /* This size-change overrides any pending one for this frame. */ 6154 /* This size-change overrides any pending one for this frame. */
5946 FRAME_NEW_HEIGHT (f) = 0; 6155 f->new_text_lines = 0;
5947 FRAME_NEW_WIDTH (f) = 0; 6156 f->new_text_cols = 0;
5948 6157
5949 /* If an argument is zero, set it to the current value. */ 6158 /* If an argument is zero, set it to the current value. */
5950 if (newheight == 0) 6159 if (newheight == 0)
5951 newheight = FRAME_HEIGHT (f); 6160 newheight = FRAME_LINES (f);
5952 if (newwidth == 0) 6161 if (newwidth == 0)
5953 newwidth = FRAME_WIDTH (f); 6162 newwidth = FRAME_COLS (f);
5954 6163
5955 /* Compute width of windows in F. 6164 /* Compute width of windows in F.
5956 This is the width of the frame without vertical scroll bars. */ 6165 This is the width of the frame without vertical scroll bars. */
5957 new_frame_window_width = FRAME_WINDOW_WIDTH_ARG (f, newwidth); 6166 new_frame_total_cols = FRAME_TOTAL_COLS_ARG (f, newwidth);
5958 6167
5959 /* Round up to the smallest acceptable size. */ 6168 /* Round up to the smallest acceptable size. */
5960 check_frame_size (f, &newheight, &newwidth); 6169 check_frame_size (f, &newheight, &newwidth);
5961 6170
5962 /* If we're not changing the frame size, quit now. */ 6171 /* If we're not changing the frame size, quit now. */
5963 if (newheight == FRAME_HEIGHT (f) 6172 if (newheight == FRAME_LINES (f)
5964 && new_frame_window_width == FRAME_WINDOW_WIDTH (f)) 6173 && new_frame_total_cols == FRAME_TOTAL_COLS (f))
5965 return; 6174 return;
5966 6175
5967 BLOCK_INPUT; 6176 BLOCK_INPUT;
5968 6177
5969 #ifdef MSDOS 6178 #ifdef MSDOS
5971 by our video hardware. Try to find the smallest size greater 6180 by our video hardware. Try to find the smallest size greater
5972 or equal to the requested dimensions. */ 6181 or equal to the requested dimensions. */
5973 dos_set_window_size (&newheight, &newwidth); 6182 dos_set_window_size (&newheight, &newwidth);
5974 #endif 6183 #endif
5975 6184
5976 if (newheight != FRAME_HEIGHT (f)) 6185 if (newheight != FRAME_LINES (f))
5977 { 6186 {
5978 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) 6187 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
5979 { 6188 {
5980 /* Frame has both root and mini-buffer. */ 6189 /* Frame has both root and mini-buffer. */
5981 XSETFASTINT (XWINDOW (FRAME_ROOT_WINDOW (f))->top, 6190 XSETFASTINT (XWINDOW (FRAME_ROOT_WINDOW (f))->top_line,
5982 FRAME_TOP_MARGIN (f)); 6191 FRAME_TOP_MARGIN (f));
5983 set_window_height (FRAME_ROOT_WINDOW (f), 6192 set_window_height (FRAME_ROOT_WINDOW (f),
5984 (newheight 6193 (newheight
5985 - 1 6194 - 1
5986 - FRAME_TOP_MARGIN (f)), 6195 - FRAME_TOP_MARGIN (f)),
5987 0); 6196 0);
5988 XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top, 6197 XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top_line,
5989 newheight - 1); 6198 newheight - 1);
5990 set_window_height (FRAME_MINIBUF_WINDOW (f), 1, 0); 6199 set_window_height (FRAME_MINIBUF_WINDOW (f), 1, 0);
5991 } 6200 }
5992 else 6201 else
5993 /* Frame has just one top-level window. */ 6202 /* Frame has just one top-level window. */
5996 6205
5997 if (FRAME_TERMCAP_P (f) && !pretend) 6206 if (FRAME_TERMCAP_P (f) && !pretend)
5998 FrameRows = newheight; 6207 FrameRows = newheight;
5999 } 6208 }
6000 6209
6001 if (new_frame_window_width != FRAME_WINDOW_WIDTH (f)) 6210 if (new_frame_total_cols != FRAME_TOTAL_COLS (f))
6002 { 6211 {
6003 set_window_width (FRAME_ROOT_WINDOW (f), new_frame_window_width, 0); 6212 set_window_width (FRAME_ROOT_WINDOW (f), new_frame_total_cols, 0);
6004 if (FRAME_HAS_MINIBUF_P (f)) 6213 if (FRAME_HAS_MINIBUF_P (f))
6005 set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_window_width, 0); 6214 set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_total_cols, 0);
6006 6215
6007 if (FRAME_TERMCAP_P (f) && !pretend) 6216 if (FRAME_TERMCAP_P (f) && !pretend)
6008 FrameCols = newwidth; 6217 FrameCols = newwidth;
6009 6218
6010 if (WINDOWP (f->tool_bar_window)) 6219 if (WINDOWP (f->tool_bar_window))
6011 XSETFASTINT (XWINDOW (f->tool_bar_window)->width, newwidth); 6220 XSETFASTINT (XWINDOW (f->tool_bar_window)->total_cols, newwidth);
6012 } 6221 }
6013 6222
6014 FRAME_HEIGHT (f) = newheight; 6223 FRAME_LINES (f) = newheight;
6015 SET_FRAME_WIDTH (f, newwidth); 6224 SET_FRAME_COLS (f, newwidth);
6016 6225
6017 { 6226 {
6018 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f)); 6227 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
6019 int text_area_x, text_area_y, text_area_width, text_area_height; 6228 int text_area_x, text_area_y, text_area_width, text_area_height;
6020 6229
6035 6244
6036 record_unwind_protect (Fset_buffer, Fcurrent_buffer ()); 6245 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
6037 6246
6038 /* This isn't quite a no-op: it runs window-configuration-change-hook. */ 6247 /* This isn't quite a no-op: it runs window-configuration-change-hook. */
6039 Fset_window_buffer (FRAME_SELECTED_WINDOW (f), 6248 Fset_window_buffer (FRAME_SELECTED_WINDOW (f),
6040 XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer); 6249 XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer, Qt);
6041 6250
6042 unbind_to (count, Qnil); 6251 unbind_to (count, Qnil);
6043 } 6252 }
6044 6253
6045 6254
6153 usec += (duration - sec) * 1000000; 6362 usec += (duration - sec) * 1000000;
6154 } 6363 }
6155 6364
6156 #ifndef EMACS_HAS_USECS 6365 #ifndef EMACS_HAS_USECS
6157 if (sec == 0 && usec != 0) 6366 if (sec == 0 && usec != 0)
6158 error ("millisecond `sleep-for' not supported on %s", SYSTEM_TYPE); 6367 error ("Millisecond `sleep-for' not supported on %s", SYSTEM_TYPE);
6159 #endif 6368 #endif
6160 6369
6161 /* Assure that 0 <= usec < 1000000. */ 6370 /* Assure that 0 <= usec < 1000000. */
6162 if (usec < 0) 6371 if (usec < 0)
6163 { 6372 {
6171 sec += usec / 1000000, usec %= 1000000; 6380 sec += usec / 1000000, usec %= 1000000;
6172 6381
6173 if (sec < 0 || (sec == 0 && usec == 0)) 6382 if (sec < 0 || (sec == 0 && usec == 0))
6174 return Qnil; 6383 return Qnil;
6175 6384
6176 { 6385 wait_reading_process_output (sec, usec, 0, 0, Qnil, NULL, 0);
6177 Lisp_Object zero;
6178
6179 XSETFASTINT (zero, 0);
6180 wait_reading_process_input (sec, usec, zero, 0);
6181 }
6182
6183 /* We should always have wait_reading_process_input; we have a dummy
6184 implementation for systems which don't support subprocesses. */
6185 #if 0
6186 /* No wait_reading_process_input */
6187 immediate_quit = 1;
6188 QUIT;
6189
6190 #ifdef VMS
6191 sys_sleep (sec);
6192 #else /* not VMS */
6193 /* The reason this is done this way
6194 (rather than defined (H_S) && defined (H_T))
6195 is because the VMS preprocessor doesn't grok `defined'. */
6196 #ifdef HAVE_SELECT
6197 EMACS_GET_TIME (end_time);
6198 EMACS_SET_SECS_USECS (timeout, sec, usec);
6199 EMACS_ADD_TIME (end_time, end_time, timeout);
6200
6201 while (1)
6202 {
6203 EMACS_GET_TIME (timeout);
6204 EMACS_SUB_TIME (timeout, end_time, timeout);
6205 if (EMACS_TIME_NEG_P (timeout)
6206 || !select (1, 0, 0, 0, &timeout))
6207 break;
6208 }
6209 #else /* not HAVE_SELECT */
6210 sleep (sec);
6211 #endif /* HAVE_SELECT */
6212 #endif /* not VMS */
6213
6214 immediate_quit = 0;
6215 #endif /* no subprocesses */
6216 6386
6217 return Qnil; 6387 return Qnil;
6218 } 6388 }
6219 6389
6220 6390
6221 /* This is just like wait_reading_process_input, except that 6391 /* This is just like wait_reading_process_output, except that
6222 it does the redisplay. 6392 it does the redisplay.
6223 6393
6224 It's also much like Fsit_for, except that it can be used for 6394 It's also much like Fsit_for, except that it can be used for
6225 waiting for input as well. */ 6395 waiting for input as well. */
6226 6396
6227 Lisp_Object 6397 Lisp_Object
6228 sit_for (sec, usec, reading, display, initial_display) 6398 sit_for (sec, usec, reading, display, initial_display)
6229 int sec, usec, reading, display, initial_display; 6399 int sec, usec, reading, display, initial_display;
6230 { 6400 {
6231 Lisp_Object read_kbd;
6232
6233 swallow_events (display); 6401 swallow_events (display);
6234 6402
6235 if (detect_input_pending_run_timers (display) || !NILP (Vexecuting_macro)) 6403 if (detect_input_pending_run_timers (display) || !NILP (Vexecuting_kbd_macro))
6236 return Qnil; 6404 return Qnil;
6237 6405
6238 if (initial_display) 6406 if (initial_display)
6239 redisplay_preserve_echo_area (2); 6407 redisplay_preserve_echo_area (2);
6240 6408
6243 6411
6244 #ifdef SIGIO 6412 #ifdef SIGIO
6245 gobble_input (0); 6413 gobble_input (0);
6246 #endif 6414 #endif
6247 6415
6248 XSETINT (read_kbd, reading ? -1 : 1); 6416 wait_reading_process_output (sec, usec, reading ? -1 : 1, display,
6249 wait_reading_process_input (sec, usec, read_kbd, display); 6417 Qnil, NULL, 0);
6250 6418
6251 return detect_input_pending () ? Qnil : Qt; 6419 return detect_input_pending () ? Qnil : Qt;
6252 } 6420 }
6253 6421
6254 6422
6255 DEFUN ("sit-for", Fsit_for, Ssit_for, 1, 3, 0, 6423 DEFUN ("sit-for", Fsit_for, Ssit_for, 1, 3, 0,
6256 doc: /* Perform redisplay, then wait for SECONDS seconds or until input is available. 6424 doc: /* Perform redisplay, then wait for SECONDS seconds or until input is available.
6257 SECONDS may be a floating-point value, meaning that you can wait for a 6425 SECONDS may be a floating-point value, meaning that you can wait for a
6258 fraction of a second. Optional second arg MILLISECONDS specifies an 6426 fraction of a second.
6259 additional wait period, in milliseconds; this may be useful if your
6260 Emacs was built without floating point support.
6261 \(Not all operating systems support waiting for a fraction of a second.) 6427 \(Not all operating systems support waiting for a fraction of a second.)
6262 Optional third arg NODISP non-nil means don't redisplay, just wait for input. 6428 Optional arg NODISP non-nil means don't redisplay, just wait for input.
6263 Redisplay is preempted as always if input arrives, and does not happen 6429 Redisplay is preempted as always if input arrives, and does not happen
6264 if input is available before it starts. 6430 if input is available before it starts.
6265 Value is t if waited the full time with no input arriving. */) 6431 Value is t if waited the full time with no input arriving.
6432
6433 An obsolete but still supported form is
6434 \(sit-for SECONDS &optional MILLISECONDS NODISP)
6435 Where the optional arg MILLISECONDS specifies an additional wait period,
6436 in milliseconds; this was useful when Emacs was built without
6437 floating point support.
6438 usage: (sit-for SECONDS &optional NODISP OLD-NODISP) */)
6439
6440 /* The `old-nodisp' stuff is there so that the arglist has the correct
6441 length. Otherwise, `defdvice' will redefine it with fewer args. */
6266 (seconds, milliseconds, nodisp) 6442 (seconds, milliseconds, nodisp)
6267 Lisp_Object seconds, milliseconds, nodisp; 6443 Lisp_Object seconds, milliseconds, nodisp;
6268 { 6444 {
6269 int sec, usec; 6445 int sec, usec;
6446
6447 if (NILP (nodisp) && !NUMBERP (milliseconds))
6448 { /* New style. */
6449 nodisp = milliseconds;
6450 milliseconds = Qnil;
6451 }
6270 6452
6271 if (NILP (milliseconds)) 6453 if (NILP (milliseconds))
6272 XSETINT (milliseconds, 0); 6454 XSETINT (milliseconds, 0);
6273 else 6455 else
6274 CHECK_NUMBER (milliseconds); 6456 CHECK_NUMBER (milliseconds);
6280 usec += (duration - sec) * 1000000; 6462 usec += (duration - sec) * 1000000;
6281 } 6463 }
6282 6464
6283 #ifndef EMACS_HAS_USECS 6465 #ifndef EMACS_HAS_USECS
6284 if (usec != 0 && sec == 0) 6466 if (usec != 0 && sec == 0)
6285 error ("millisecond `sit-for' not supported on %s", SYSTEM_TYPE); 6467 error ("Millisecond `sit-for' not supported on %s", SYSTEM_TYPE);
6286 #endif 6468 #endif
6287 6469
6288 return sit_for (sec, usec, 0, NILP (nodisp), NILP (nodisp)); 6470 return sit_for (sec, usec, 0, NILP (nodisp), NILP (nodisp));
6289 } 6471 }
6290 6472
6294 Other Lisp Functions 6476 Other Lisp Functions
6295 ***********************************************************************/ 6477 ***********************************************************************/
6296 6478
6297 /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the 6479 /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
6298 session's frames, frame names, buffers, buffer-read-only flags, and 6480 session's frames, frame names, buffers, buffer-read-only flags, and
6299 buffer-modified-flags, and a trailing sentinel (so we don't need to 6481 buffer-modified-flags. */
6300 add length checks). */
6301 6482
6302 static Lisp_Object frame_and_buffer_state; 6483 static Lisp_Object frame_and_buffer_state;
6303 6484
6304 6485
6305 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p, 6486 DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
6306 Sframe_or_buffer_changed_p, 0, 0, 0, 6487 Sframe_or_buffer_changed_p, 0, 1, 0,
6307 doc: /* Return non-nil if the frame and buffer state appears to have changed. 6488 doc: /* Return non-nil if the frame and buffer state appears to have changed.
6308 The state variable is an internal vector containing all frames and buffers, 6489 VARIABLE is a variable name whose value is either nil or a state vector
6490 that will be updated to contain all frames and buffers,
6309 aside from buffers whose names start with space, 6491 aside from buffers whose names start with space,
6310 along with the buffers' read-only and modified flags, which allows a fast 6492 along with the buffers' read-only and modified flags. This allows a fast
6311 check to see whether the menu bars might need to be recomputed. 6493 check to see whether buffer menus might need to be recomputed.
6312 If this function returns non-nil, it updates the internal vector to reflect 6494 If this function returns non-nil, it updates the internal vector to reflect
6313 the current state. */) 6495 the current state.
6314 () 6496
6315 { 6497 If VARIABLE is nil, an internal variable is used. Users should not
6316 Lisp_Object tail, frame, buf; 6498 pass nil for VARIABLE. */)
6317 Lisp_Object *vecp; 6499 (variable)
6500 Lisp_Object variable;
6501 {
6502 Lisp_Object state, tail, frame, buf;
6503 Lisp_Object *vecp, *end;
6318 int n; 6504 int n;
6319 6505
6320 vecp = XVECTOR (frame_and_buffer_state)->contents; 6506 if (! NILP (variable))
6507 {
6508 CHECK_SYMBOL (variable);
6509 state = Fsymbol_value (variable);
6510 if (! VECTORP (state))
6511 goto changed;
6512 }
6513 else
6514 state = frame_and_buffer_state;
6515
6516 vecp = XVECTOR (state)->contents;
6517 end = vecp + XVECTOR (state)->size;
6518
6321 FOR_EACH_FRAME (tail, frame) 6519 FOR_EACH_FRAME (tail, frame)
6322 { 6520 {
6521 if (vecp == end)
6522 goto changed;
6323 if (!EQ (*vecp++, frame)) 6523 if (!EQ (*vecp++, frame))
6524 goto changed;
6525 if (vecp == end)
6324 goto changed; 6526 goto changed;
6325 if (!EQ (*vecp++, XFRAME (frame)->name)) 6527 if (!EQ (*vecp++, XFRAME (frame)->name))
6326 goto changed; 6528 goto changed;
6327 } 6529 }
6328 /* Check that the buffer info matches. 6530 /* Check that the buffer info matches. */
6329 No need to test for the end of the vector
6330 because the last element of the vector is lambda
6331 and that will always cause a mismatch. */
6332 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) 6531 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
6333 { 6532 {
6334 buf = XCDR (XCAR (tail)); 6533 buf = XCDR (XCAR (tail));
6335 /* Ignore buffers that aren't included in buffer lists. */ 6534 /* Ignore buffers that aren't included in buffer lists. */
6336 if (SREF (XBUFFER (buf)->name, 0) == ' ') 6535 if (SREF (XBUFFER (buf)->name, 0) == ' ')
6337 continue; 6536 continue;
6537 if (vecp == end)
6538 goto changed;
6338 if (!EQ (*vecp++, buf)) 6539 if (!EQ (*vecp++, buf))
6540 goto changed;
6541 if (vecp == end)
6339 goto changed; 6542 goto changed;
6340 if (!EQ (*vecp++, XBUFFER (buf)->read_only)) 6543 if (!EQ (*vecp++, XBUFFER (buf)->read_only))
6341 goto changed; 6544 goto changed;
6545 if (vecp == end)
6546 goto changed;
6342 if (!EQ (*vecp++, Fbuffer_modified_p (buf))) 6547 if (!EQ (*vecp++, Fbuffer_modified_p (buf)))
6343 goto changed; 6548 goto changed;
6344 } 6549 }
6550 if (vecp == end)
6551 goto changed;
6345 /* Detect deletion of a buffer at the end of the list. */ 6552 /* Detect deletion of a buffer at the end of the list. */
6346 if (EQ (*vecp, Qlambda)) 6553 if (EQ (*vecp, Qlambda))
6347 return Qnil; 6554 return Qnil;
6555
6556 /* Come here if we decide the data has changed. */
6348 changed: 6557 changed:
6349 /* Start with 1 so there is room for at least one lambda at the end. */ 6558 /* Count the size we will need.
6559 Start with 1 so there is room for at least one lambda at the end. */
6350 n = 1; 6560 n = 1;
6351 FOR_EACH_FRAME (tail, frame) 6561 FOR_EACH_FRAME (tail, frame)
6352 n += 2; 6562 n += 2;
6353 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail)) 6563 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
6354 n += 3; 6564 n += 3;
6355 /* Reallocate the vector if it's grown, or if it's shrunk a lot. */ 6565 /* Reallocate the vector if data has grown to need it,
6356 if (n > XVECTOR (frame_and_buffer_state)->size 6566 or if it has shrunk a lot. */
6357 || n + 20 < XVECTOR (frame_and_buffer_state)->size / 2) 6567 if (! VECTORP (state)
6568 || n > XVECTOR (state)->size
6569 || n + 20 < XVECTOR (state)->size / 2)
6358 /* Add 20 extra so we grow it less often. */ 6570 /* Add 20 extra so we grow it less often. */
6359 frame_and_buffer_state = Fmake_vector (make_number (n + 20), Qlambda); 6571 {
6360 vecp = XVECTOR (frame_and_buffer_state)->contents; 6572 state = Fmake_vector (make_number (n + 20), Qlambda);
6573 if (! NILP (variable))
6574 Fset (variable, state);
6575 else
6576 frame_and_buffer_state = state;
6577 }
6578
6579 /* Record the new data in the (possibly reallocated) vector. */
6580 vecp = XVECTOR (state)->contents;
6361 FOR_EACH_FRAME (tail, frame) 6581 FOR_EACH_FRAME (tail, frame)
6362 { 6582 {
6363 *vecp++ = frame; 6583 *vecp++ = frame;
6364 *vecp++ = XFRAME (frame)->name; 6584 *vecp++ = XFRAME (frame)->name;
6365 } 6585 }
6373 *vecp++ = XBUFFER (buf)->read_only; 6593 *vecp++ = XBUFFER (buf)->read_only;
6374 *vecp++ = Fbuffer_modified_p (buf); 6594 *vecp++ = Fbuffer_modified_p (buf);
6375 } 6595 }
6376 /* Fill up the vector with lambdas (always at least one). */ 6596 /* Fill up the vector with lambdas (always at least one). */
6377 *vecp++ = Qlambda; 6597 *vecp++ = Qlambda;
6378 while (vecp - XVECTOR (frame_and_buffer_state)->contents 6598 while (vecp - XVECTOR (state)->contents
6379 < XVECTOR (frame_and_buffer_state)->size) 6599 < XVECTOR (state)->size)
6380 *vecp++ = Qlambda; 6600 *vecp++ = Qlambda;
6381 /* Make sure we didn't overflow the vector. */ 6601 /* Make sure we didn't overflow the vector. */
6382 if (vecp - XVECTOR (frame_and_buffer_state)->contents 6602 if (vecp - XVECTOR (state)->contents
6383 > XVECTOR (frame_and_buffer_state)->size) 6603 > XVECTOR (state)->size)
6384 abort (); 6604 abort ();
6385 return Qt; 6605 return Qt;
6386 } 6606 }
6387 6607
6388 6608
6523 6743
6524 term_init (terminal_type); 6744 term_init (terminal_type);
6525 6745
6526 { 6746 {
6527 struct frame *sf = SELECTED_FRAME (); 6747 struct frame *sf = SELECTED_FRAME ();
6528 int width = FRAME_WINDOW_WIDTH (sf); 6748 int width = FRAME_TOTAL_COLS (sf);
6529 int height = FRAME_HEIGHT (sf); 6749 int height = FRAME_LINES (sf);
6530 6750
6531 unsigned int total_glyphs = height * (width + 2) * sizeof (struct glyph); 6751 unsigned int total_glyphs = height * (width + 2) * sizeof (struct glyph);
6532 6752
6533 /* If these sizes are so big they cause overflow, just ignore the 6753 /* If these sizes are so big they cause overflow, just ignore the
6534 change. It's not clear what better we could do. */ 6754 change. It's not clear what better we could do. */
6707 { 6927 {
6708 Vwindow_system = Qnil; 6928 Vwindow_system = Qnil;
6709 Vwindow_system_version = Qnil; 6929 Vwindow_system_version = Qnil;
6710 } 6930 }
6711 } 6931 }
6932
6933 /* arch-tag: 8d812b1f-04a2-4195-a9c4-381f8457a413
6934 (do not change this comment) */