Mercurial > emacs
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) */ |