diff options
Diffstat (limited to 'src/dispnew.c')
| -rw-r--r-- | src/dispnew.c | 407 |
1 files changed, 245 insertions, 162 deletions
diff --git a/src/dispnew.c b/src/dispnew.c index 8691c921853..02d6de53bbf 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Updating of data structures for redisplay. | 1 | /* Updating of data structures for redisplay. |
| 2 | Copyright (C) 1985-1988, 1993-1995, 1997-2011 Free Software Foundation, Inc. | 2 | Copyright (C) 1985-1988, 1993-1995, 1997-2012 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -62,7 +62,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 62 | #include <errno.h> | 62 | #include <errno.h> |
| 63 | 63 | ||
| 64 | /* Get number of chars of output now in the buffer of a stdio stream. | 64 | /* Get number of chars of output now in the buffer of a stdio stream. |
| 65 | This ought to be built in in stdio, but it isn't. Some s- files | 65 | This ought to be built in stdio, but it isn't. Some s- files |
| 66 | override this because their stdio internals differ. */ | 66 | override this because their stdio internals differ. */ |
| 67 | 67 | ||
| 68 | #ifdef __GNU_LIBRARY__ | 68 | #ifdef __GNU_LIBRARY__ |
| @@ -87,7 +87,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 87 | #endif | 87 | #endif |
| 88 | #endif /* not __GNU_LIBRARY__ */ | 88 | #endif /* not __GNU_LIBRARY__ */ |
| 89 | 89 | ||
| 90 | #if defined(HAVE_TERM_H) && defined (GNU_LINUX) && defined (HAVE_LIBNCURSES) | 90 | #if defined (HAVE_TERM_H) && defined (GNU_LINUX) && defined (HAVE_LIBNCURSES) |
| 91 | #include <term.h> /* for tgetent */ | 91 | #include <term.h> /* for tgetent */ |
| 92 | #endif | 92 | #endif |
| 93 | 93 | ||
| @@ -103,57 +103,24 @@ struct dim | |||
| 103 | 103 | ||
| 104 | /* Function prototypes. */ | 104 | /* Function prototypes. */ |
| 105 | 105 | ||
| 106 | static struct glyph_matrix *save_current_matrix (struct frame *); | ||
| 107 | static void restore_current_matrix (struct frame *, struct glyph_matrix *); | ||
| 108 | static int showing_window_margins_p (struct window *); | ||
| 109 | static void fake_current_matrices (Lisp_Object); | ||
| 110 | static void redraw_overlapping_rows (struct window *, int); | ||
| 111 | static void redraw_overlapped_rows (struct window *, int); | ||
| 112 | static int count_blanks (struct glyph *, int); | ||
| 113 | static int count_match (struct glyph *, struct glyph *, | ||
| 114 | struct glyph *, struct glyph *); | ||
| 115 | static unsigned line_draw_cost (struct glyph_matrix *, int); | ||
| 116 | static void update_frame_line (struct frame *, int); | 106 | static void update_frame_line (struct frame *, int); |
| 117 | static struct dim allocate_matrices_for_frame_redisplay | ||
| 118 | (Lisp_Object, int, int, int, int *); | ||
| 119 | static int required_matrix_height (struct window *); | 107 | static int required_matrix_height (struct window *); |
| 120 | static int required_matrix_width (struct window *); | 108 | static int required_matrix_width (struct window *); |
| 121 | static void allocate_matrices_for_window_redisplay (struct window *); | ||
| 122 | static int realloc_glyph_pool (struct glyph_pool *, struct dim); | ||
| 123 | static void adjust_frame_glyphs (struct frame *); | 109 | static void adjust_frame_glyphs (struct frame *); |
| 124 | static struct glyph_matrix *new_glyph_matrix (struct glyph_pool *); | ||
| 125 | static void free_glyph_matrix (struct glyph_matrix *); | ||
| 126 | static void adjust_glyph_matrix (struct window *, struct glyph_matrix *, | ||
| 127 | int, int, struct dim); | ||
| 128 | static void change_frame_size_1 (struct frame *, int, int, int, int, int); | 110 | static void change_frame_size_1 (struct frame *, int, int, int, int, int); |
| 129 | static void increment_row_positions (struct glyph_row *, EMACS_INT, EMACS_INT); | 111 | static void increment_row_positions (struct glyph_row *, EMACS_INT, EMACS_INT); |
| 130 | static void swap_glyph_pointers (struct glyph_row *, struct glyph_row *); | ||
| 131 | #if GLYPH_DEBUG | ||
| 132 | static int glyph_row_slice_p (struct glyph_row *, struct glyph_row *); | ||
| 133 | #endif | ||
| 134 | static void fill_up_frame_row_with_spaces (struct glyph_row *, int); | 112 | static void fill_up_frame_row_with_spaces (struct glyph_row *, int); |
| 135 | static void build_frame_matrix_from_window_tree (struct glyph_matrix *, | 113 | static void build_frame_matrix_from_window_tree (struct glyph_matrix *, |
| 136 | struct window *); | 114 | struct window *); |
| 137 | static void build_frame_matrix_from_leaf_window (struct glyph_matrix *, | 115 | static void build_frame_matrix_from_leaf_window (struct glyph_matrix *, |
| 138 | struct window *); | 116 | struct window *); |
| 139 | static struct glyph_pool *new_glyph_pool (void); | ||
| 140 | static void free_glyph_pool (struct glyph_pool *); | ||
| 141 | static void adjust_frame_glyphs_initially (void); | ||
| 142 | static void adjust_frame_message_buffer (struct frame *); | 117 | static void adjust_frame_message_buffer (struct frame *); |
| 143 | static void adjust_decode_mode_spec_buffer (struct frame *); | 118 | static void adjust_decode_mode_spec_buffer (struct frame *); |
| 144 | static void fill_up_glyph_row_with_spaces (struct glyph_row *); | 119 | static void fill_up_glyph_row_with_spaces (struct glyph_row *); |
| 145 | static void build_frame_matrix (struct frame *); | ||
| 146 | void clear_current_matrices (struct frame *); | ||
| 147 | void scroll_glyph_matrix_range (struct glyph_matrix *, int, int, | ||
| 148 | int, int); | ||
| 149 | static void clear_window_matrices (struct window *, int); | 120 | static void clear_window_matrices (struct window *, int); |
| 150 | static void fill_up_glyph_row_area_with_spaces (struct glyph_row *, int); | 121 | static void fill_up_glyph_row_area_with_spaces (struct glyph_row *, int); |
| 151 | static int scrolling_window (struct window *, int); | 122 | static int scrolling_window (struct window *, int); |
| 152 | static int update_window_line (struct window *, int, int *); | 123 | static int update_window_line (struct window *, int, int *); |
| 153 | static void update_marginal_area (struct window *, int, int); | ||
| 154 | static int update_text_area (struct window *, int); | ||
| 155 | static void make_current (struct glyph_matrix *, struct glyph_matrix *, | ||
| 156 | int); | ||
| 157 | static void mirror_make_current (struct window *, int); | 124 | static void mirror_make_current (struct window *, int); |
| 158 | #if GLYPH_DEBUG | 125 | #if GLYPH_DEBUG |
| 159 | static void check_matrix_pointers (struct glyph_matrix *, | 126 | static void check_matrix_pointers (struct glyph_matrix *, |
| @@ -286,7 +253,7 @@ static int history_idx; | |||
| 286 | /* A tick that's incremented each time something is added to the | 253 | /* A tick that's incremented each time something is added to the |
| 287 | history. */ | 254 | history. */ |
| 288 | 255 | ||
| 289 | static unsigned history_tick; | 256 | static uprintmax_t history_tick; |
| 290 | 257 | ||
| 291 | static void add_frame_display_history (struct frame *, int); | 258 | static void add_frame_display_history (struct frame *, int); |
| 292 | 259 | ||
| @@ -305,15 +272,16 @@ add_window_display_history (struct window *w, const char *msg, int paused_p) | |||
| 305 | buf = redisplay_history[history_idx].trace; | 272 | buf = redisplay_history[history_idx].trace; |
| 306 | ++history_idx; | 273 | ++history_idx; |
| 307 | 274 | ||
| 308 | sprintf (buf, "%d: window %p (`%s')%s\n", | 275 | snprintf (buf, sizeof redisplay_history[0].trace, |
| 309 | history_tick++, | 276 | "%"pMu": window %p (`%s')%s\n%s", |
| 310 | w, | 277 | history_tick++, |
| 311 | ((BUFFERP (w->buffer) | 278 | w, |
| 312 | && STRINGP (BVAR (XBUFFER (w->buffer), name))) | 279 | ((BUFFERP (w->buffer) |
| 313 | ? SSDATA (BVAR (XBUFFER (w->buffer), name)) | 280 | && STRINGP (BVAR (XBUFFER (w->buffer), name))) |
| 314 | : "???"), | 281 | ? SSDATA (BVAR (XBUFFER (w->buffer), name)) |
| 315 | paused_p ? " ***paused***" : ""); | 282 | : "???"), |
| 316 | strcat (buf, msg); | 283 | paused_p ? " ***paused***" : "", |
| 284 | msg); | ||
| 317 | } | 285 | } |
| 318 | 286 | ||
| 319 | 287 | ||
| @@ -331,7 +299,7 @@ add_frame_display_history (struct frame *f, int paused_p) | |||
| 331 | buf = redisplay_history[history_idx].trace; | 299 | buf = redisplay_history[history_idx].trace; |
| 332 | ++history_idx; | 300 | ++history_idx; |
| 333 | 301 | ||
| 334 | sprintf (buf, "%d: update frame %p%s", | 302 | sprintf (buf, "%"pMu": update frame %p%s", |
| 335 | history_tick++, | 303 | history_tick++, |
| 336 | f, paused_p ? " ***paused***" : ""); | 304 | f, paused_p ? " ***paused***" : ""); |
| 337 | } | 305 | } |
| @@ -461,6 +429,14 @@ margin_glyphs_to_reserve (struct window *w, int total_glyphs, Lisp_Object margin | |||
| 461 | return n; | 429 | return n; |
| 462 | } | 430 | } |
| 463 | 431 | ||
| 432 | #if XASSERTS | ||
| 433 | /* Return non-zero if ROW's hash value is correct, zero if not. */ | ||
| 434 | int | ||
| 435 | verify_row_hash (struct glyph_row *row) | ||
| 436 | { | ||
| 437 | return row->hash == row_hash (row); | ||
| 438 | } | ||
| 439 | #endif | ||
| 464 | 440 | ||
| 465 | /* Adjust glyph matrix MATRIX on window W or on a frame to changed | 441 | /* Adjust glyph matrix MATRIX on window W or on a frame to changed |
| 466 | window sizes. | 442 | window sizes. |
| @@ -532,12 +508,12 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y | |||
| 532 | /* Enlarge MATRIX->rows if necessary. New rows are cleared. */ | 508 | /* Enlarge MATRIX->rows if necessary. New rows are cleared. */ |
| 533 | if (matrix->rows_allocated < dim.height) | 509 | if (matrix->rows_allocated < dim.height) |
| 534 | { | 510 | { |
| 535 | int size = dim.height * sizeof (struct glyph_row); | 511 | int old_alloc = matrix->rows_allocated; |
| 536 | new_rows = dim.height - matrix->rows_allocated; | 512 | new_rows = dim.height - matrix->rows_allocated; |
| 537 | matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size); | 513 | matrix->rows = xpalloc (matrix->rows, &matrix->rows_allocated, |
| 538 | memset (matrix->rows + matrix->rows_allocated, 0, | 514 | new_rows, INT_MAX, sizeof *matrix->rows); |
| 539 | new_rows * sizeof *matrix->rows); | 515 | memset (matrix->rows + old_alloc, 0, |
| 540 | matrix->rows_allocated = dim.height; | 516 | (matrix->rows_allocated - old_alloc) * sizeof *matrix->rows); |
| 541 | } | 517 | } |
| 542 | else | 518 | else |
| 543 | new_rows = 0; | 519 | new_rows = 0; |
| @@ -609,9 +585,8 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y | |||
| 609 | while (row < end) | 585 | while (row < end) |
| 610 | { | 586 | { |
| 611 | row->glyphs[LEFT_MARGIN_AREA] | 587 | row->glyphs[LEFT_MARGIN_AREA] |
| 612 | = (struct glyph *) xrealloc (row->glyphs[LEFT_MARGIN_AREA], | 588 | = xnrealloc (row->glyphs[LEFT_MARGIN_AREA], |
| 613 | (dim.width | 589 | dim.width, sizeof (struct glyph)); |
| 614 | * sizeof (struct glyph))); | ||
| 615 | 590 | ||
| 616 | /* The mode line never has marginal areas. */ | 591 | /* The mode line never has marginal areas. */ |
| 617 | if (row == matrix->rows + dim.height - 1 | 592 | if (row == matrix->rows + dim.height - 1 |
| @@ -1062,8 +1037,7 @@ increment_row_positions (struct glyph_row *row, | |||
| 1062 | B without changing glyph pointers in A and B. */ | 1037 | B without changing glyph pointers in A and B. */ |
| 1063 | 1038 | ||
| 1064 | static void | 1039 | static void |
| 1065 | swap_glyphs_in_rows (a, b) | 1040 | swap_glyphs_in_rows (struct glyph_row *a, struct glyph_row *b) |
| 1066 | struct glyph_row *a, *b; | ||
| 1067 | { | 1041 | { |
| 1068 | int area; | 1042 | int area; |
| 1069 | 1043 | ||
| @@ -1097,37 +1071,55 @@ swap_glyphs_in_rows (a, b) | |||
| 1097 | 1071 | ||
| 1098 | #endif /* 0 */ | 1072 | #endif /* 0 */ |
| 1099 | 1073 | ||
| 1100 | /* Exchange pointers to glyph memory between glyph rows A and B. */ | 1074 | /* Exchange pointers to glyph memory between glyph rows A and B. Also |
| 1075 | exchange the used[] array and the hash values of the rows, because | ||
| 1076 | these should all go together for the row's hash value to be | ||
| 1077 | correct. */ | ||
| 1101 | 1078 | ||
| 1102 | static inline void | 1079 | static inline void |
| 1103 | swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b) | 1080 | swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b) |
| 1104 | { | 1081 | { |
| 1105 | int i; | 1082 | int i; |
| 1083 | unsigned hash_tem = a->hash; | ||
| 1084 | |||
| 1106 | for (i = 0; i < LAST_AREA + 1; ++i) | 1085 | for (i = 0; i < LAST_AREA + 1; ++i) |
| 1107 | { | 1086 | { |
| 1108 | struct glyph *temp = a->glyphs[i]; | 1087 | struct glyph *temp = a->glyphs[i]; |
| 1088 | short used_tem = a->used[i]; | ||
| 1089 | |||
| 1109 | a->glyphs[i] = b->glyphs[i]; | 1090 | a->glyphs[i] = b->glyphs[i]; |
| 1110 | b->glyphs[i] = temp; | 1091 | b->glyphs[i] = temp; |
| 1092 | a->used[i] = b->used[i]; | ||
| 1093 | b->used[i] = used_tem; | ||
| 1111 | } | 1094 | } |
| 1095 | a->hash = b->hash; | ||
| 1096 | b->hash = hash_tem; | ||
| 1112 | } | 1097 | } |
| 1113 | 1098 | ||
| 1114 | 1099 | ||
| 1115 | /* Copy glyph row structure FROM to glyph row structure TO, except | 1100 | /* Copy glyph row structure FROM to glyph row structure TO, except |
| 1116 | that glyph pointers in the structures are left unchanged. */ | 1101 | that glyph pointers, the `used' counts, and the hash values in the |
| 1102 | structures are left unchanged. */ | ||
| 1117 | 1103 | ||
| 1118 | static inline void | 1104 | static inline void |
| 1119 | copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from) | 1105 | copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from) |
| 1120 | { | 1106 | { |
| 1121 | struct glyph *pointers[1 + LAST_AREA]; | 1107 | struct glyph *pointers[1 + LAST_AREA]; |
| 1108 | short used[1 + LAST_AREA]; | ||
| 1109 | unsigned hashval; | ||
| 1122 | 1110 | ||
| 1123 | /* Save glyph pointers of TO. */ | 1111 | /* Save glyph pointers of TO. */ |
| 1124 | memcpy (pointers, to->glyphs, sizeof to->glyphs); | 1112 | memcpy (pointers, to->glyphs, sizeof to->glyphs); |
| 1113 | memcpy (used, to->used, sizeof to->used); | ||
| 1114 | hashval = to->hash; | ||
| 1125 | 1115 | ||
| 1126 | /* Do a structure assignment. */ | 1116 | /* Do a structure assignment. */ |
| 1127 | *to = *from; | 1117 | *to = *from; |
| 1128 | 1118 | ||
| 1129 | /* Restore original pointers of TO. */ | 1119 | /* Restore original pointers of TO. */ |
| 1130 | memcpy (to->glyphs, pointers, sizeof to->glyphs); | 1120 | memcpy (to->glyphs, pointers, sizeof to->glyphs); |
| 1121 | memcpy (to->used, used, sizeof to->used); | ||
| 1122 | to->hash = hashval; | ||
| 1131 | } | 1123 | } |
| 1132 | 1124 | ||
| 1133 | 1125 | ||
| @@ -1199,7 +1191,7 @@ prepare_desired_row (struct glyph_row *row) | |||
| 1199 | { | 1191 | { |
| 1200 | if (!row->enabled_p) | 1192 | if (!row->enabled_p) |
| 1201 | { | 1193 | { |
| 1202 | unsigned rp = row->reversed_p; | 1194 | int rp = row->reversed_p; |
| 1203 | 1195 | ||
| 1204 | clear_glyph_row (row); | 1196 | clear_glyph_row (row); |
| 1205 | row->enabled_p = 1; | 1197 | row->enabled_p = 1; |
| @@ -1243,7 +1235,7 @@ line_hash_code (struct glyph_row *row) | |||
| 1243 | the number of characters in the line. If must_write_spaces is | 1235 | the number of characters in the line. If must_write_spaces is |
| 1244 | zero, leading and trailing spaces are ignored. */ | 1236 | zero, leading and trailing spaces are ignored. */ |
| 1245 | 1237 | ||
| 1246 | static unsigned int | 1238 | static int |
| 1247 | line_draw_cost (struct glyph_matrix *matrix, int vpos) | 1239 | line_draw_cost (struct glyph_matrix *matrix, int vpos) |
| 1248 | { | 1240 | { |
| 1249 | struct glyph_row *row = matrix->rows + vpos; | 1241 | struct glyph_row *row = matrix->rows + vpos; |
| @@ -1251,7 +1243,7 @@ line_draw_cost (struct glyph_matrix *matrix, int vpos) | |||
| 1251 | struct glyph *end = beg + row->used[TEXT_AREA]; | 1243 | struct glyph *end = beg + row->used[TEXT_AREA]; |
| 1252 | int len; | 1244 | int len; |
| 1253 | Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE; | 1245 | Lisp_Object *glyph_table_base = GLYPH_TABLE_BASE; |
| 1254 | int glyph_table_len = GLYPH_TABLE_LENGTH; | 1246 | ptrdiff_t glyph_table_len = GLYPH_TABLE_LENGTH; |
| 1255 | 1247 | ||
| 1256 | /* Ignore trailing and leading spaces if we can. */ | 1248 | /* Ignore trailing and leading spaces if we can. */ |
| 1257 | if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */ | 1249 | if (!FRAME_MUST_WRITE_SPACES (SELECTED_FRAME ())) /* XXX Is SELECTED_FRAME OK here? */ |
| @@ -1305,6 +1297,9 @@ line_draw_cost (struct glyph_matrix *matrix, int vpos) | |||
| 1305 | static inline int | 1297 | static inline int |
| 1306 | row_equal_p (struct glyph_row *a, struct glyph_row *b, int mouse_face_p) | 1298 | row_equal_p (struct glyph_row *a, struct glyph_row *b, int mouse_face_p) |
| 1307 | { | 1299 | { |
| 1300 | xassert (verify_row_hash (a)); | ||
| 1301 | xassert (verify_row_hash (b)); | ||
| 1302 | |||
| 1308 | if (a == b) | 1303 | if (a == b) |
| 1309 | return 1; | 1304 | return 1; |
| 1310 | else if (a->hash != b->hash) | 1305 | else if (a->hash != b->hash) |
| @@ -1425,7 +1420,7 @@ free_glyph_pool (struct glyph_pool *pool) | |||
| 1425 | static int | 1420 | static int |
| 1426 | realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim) | 1421 | realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim) |
| 1427 | { | 1422 | { |
| 1428 | int needed; | 1423 | ptrdiff_t needed; |
| 1429 | int changed_p; | 1424 | int changed_p; |
| 1430 | 1425 | ||
| 1431 | changed_p = (pool->glyphs == 0 | 1426 | changed_p = (pool->glyphs == 0 |
| @@ -1433,24 +1428,17 @@ realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim) | |||
| 1433 | || matrix_dim.width != pool->ncolumns); | 1428 | || matrix_dim.width != pool->ncolumns); |
| 1434 | 1429 | ||
| 1435 | /* Enlarge the glyph pool. */ | 1430 | /* Enlarge the glyph pool. */ |
| 1436 | needed = matrix_dim.width * matrix_dim.height; | 1431 | needed = matrix_dim.width; |
| 1432 | if (INT_MULTIPLY_OVERFLOW (needed, matrix_dim.height)) | ||
| 1433 | memory_full (SIZE_MAX); | ||
| 1434 | needed *= matrix_dim.height; | ||
| 1437 | if (needed > pool->nglyphs) | 1435 | if (needed > pool->nglyphs) |
| 1438 | { | 1436 | { |
| 1439 | int size = needed * sizeof (struct glyph); | 1437 | ptrdiff_t old_nglyphs = pool->nglyphs; |
| 1440 | 1438 | pool->glyphs = xpalloc (pool->glyphs, &pool->nglyphs, | |
| 1441 | if (pool->glyphs) | 1439 | needed - old_nglyphs, -1, sizeof *pool->glyphs); |
| 1442 | { | 1440 | memset (pool->glyphs + old_nglyphs, 0, |
| 1443 | pool->glyphs = (struct glyph *) xrealloc (pool->glyphs, size); | 1441 | (pool->nglyphs - old_nglyphs) * sizeof *pool->glyphs); |
| 1444 | memset (pool->glyphs + pool->nglyphs, 0, | ||
| 1445 | size - pool->nglyphs * sizeof (struct glyph)); | ||
| 1446 | } | ||
| 1447 | else | ||
| 1448 | { | ||
| 1449 | pool->glyphs = (struct glyph *) xmalloc (size); | ||
| 1450 | memset (pool->glyphs, 0, size); | ||
| 1451 | } | ||
| 1452 | |||
| 1453 | pool->nglyphs = needed; | ||
| 1454 | } | 1442 | } |
| 1455 | 1443 | ||
| 1456 | /* Remember the number of rows and columns because (a) we use them | 1444 | /* Remember the number of rows and columns because (a) we use them |
| @@ -2062,7 +2050,7 @@ save_current_matrix (struct frame *f) | |||
| 2062 | { | 2050 | { |
| 2063 | struct glyph_row *from = f->current_matrix->rows + i; | 2051 | struct glyph_row *from = f->current_matrix->rows + i; |
| 2064 | struct glyph_row *to = saved->rows + i; | 2052 | struct glyph_row *to = saved->rows + i; |
| 2065 | size_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph); | 2053 | ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph); |
| 2066 | to->glyphs[TEXT_AREA] = (struct glyph *) xmalloc (nbytes); | 2054 | to->glyphs[TEXT_AREA] = (struct glyph *) xmalloc (nbytes); |
| 2067 | memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes); | 2055 | memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes); |
| 2068 | to->used[TEXT_AREA] = from->used[TEXT_AREA]; | 2056 | to->used[TEXT_AREA] = from->used[TEXT_AREA]; |
| @@ -2084,7 +2072,7 @@ restore_current_matrix (struct frame *f, struct glyph_matrix *saved) | |||
| 2084 | { | 2072 | { |
| 2085 | struct glyph_row *from = saved->rows + i; | 2073 | struct glyph_row *from = saved->rows + i; |
| 2086 | struct glyph_row *to = f->current_matrix->rows + i; | 2074 | struct glyph_row *to = f->current_matrix->rows + i; |
| 2087 | size_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph); | 2075 | ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph); |
| 2088 | memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes); | 2076 | memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes); |
| 2089 | to->used[TEXT_AREA] = from->used[TEXT_AREA]; | 2077 | to->used[TEXT_AREA] = from->used[TEXT_AREA]; |
| 2090 | xfree (from->glyphs[TEXT_AREA]); | 2078 | xfree (from->glyphs[TEXT_AREA]); |
| @@ -2272,7 +2260,7 @@ adjust_frame_glyphs_for_window_redisplay (struct frame *f) | |||
| 2272 | static void | 2260 | static void |
| 2273 | adjust_frame_message_buffer (struct frame *f) | 2261 | adjust_frame_message_buffer (struct frame *f) |
| 2274 | { | 2262 | { |
| 2275 | int size = FRAME_MESSAGE_BUF_SIZE (f) + 1; | 2263 | ptrdiff_t size = FRAME_MESSAGE_BUF_SIZE (f) + 1; |
| 2276 | 2264 | ||
| 2277 | if (FRAME_MESSAGE_BUF (f)) | 2265 | if (FRAME_MESSAGE_BUF (f)) |
| 2278 | { | 2266 | { |
| @@ -3509,7 +3497,7 @@ redraw_overlapping_rows (struct window *w, int yb) | |||
| 3509 | if (row->used[RIGHT_MARGIN_AREA]) | 3497 | if (row->used[RIGHT_MARGIN_AREA]) |
| 3510 | rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, overlaps); | 3498 | rif->fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, overlaps); |
| 3511 | 3499 | ||
| 3512 | /* Record in neighbour rows that ROW overwrites part of | 3500 | /* Record in neighbor rows that ROW overwrites part of |
| 3513 | their display. */ | 3501 | their display. */ |
| 3514 | if (overlaps & OVERLAPS_PRED) | 3502 | if (overlaps & OVERLAPS_PRED) |
| 3515 | MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1; | 3503 | MATRIX_ROW (w->current_matrix, i - 1)->overlapped_p = 1; |
| @@ -3587,12 +3575,11 @@ update_window (struct window *w, int force_p) | |||
| 3587 | 3575 | ||
| 3588 | rif->update_window_begin_hook (w); | 3576 | rif->update_window_begin_hook (w); |
| 3589 | yb = window_text_bottom_y (w); | 3577 | yb = window_text_bottom_y (w); |
| 3590 | |||
| 3591 | /* If window has a header line, update it before everything else. | ||
| 3592 | Adjust y-positions of other rows by the header line height. */ | ||
| 3593 | row = desired_matrix->rows; | 3578 | row = desired_matrix->rows; |
| 3594 | end = row + desired_matrix->nrows - 1; | 3579 | end = row + desired_matrix->nrows - 1; |
| 3595 | 3580 | ||
| 3581 | /* Take note of the header line, if there is one. We will | ||
| 3582 | update it below, after updating all of the window's lines. */ | ||
| 3596 | if (row->mode_line_p) | 3583 | if (row->mode_line_p) |
| 3597 | { | 3584 | { |
| 3598 | header_line_row = row; | 3585 | header_line_row = row; |
| @@ -3637,6 +3624,8 @@ update_window (struct window *w, int force_p) | |||
| 3637 | 3624 | ||
| 3638 | /* Update the rest of the lines. */ | 3625 | /* Update the rest of the lines. */ |
| 3639 | for (; row < end && (force_p || !input_pending); ++row) | 3626 | for (; row < end && (force_p || !input_pending); ++row) |
| 3627 | /* scrolling_window resets the enabled_p flag of the rows it | ||
| 3628 | reuses from current_matrix. */ | ||
| 3640 | if (row->enabled_p) | 3629 | if (row->enabled_p) |
| 3641 | { | 3630 | { |
| 3642 | int vpos = MATRIX_ROW_VPOS (row, desired_matrix); | 3631 | int vpos = MATRIX_ROW_VPOS (row, desired_matrix); |
| @@ -4200,7 +4189,7 @@ struct row_entry | |||
| 4200 | int new_line_number; | 4189 | int new_line_number; |
| 4201 | 4190 | ||
| 4202 | /* Bucket index of this row_entry in the hash table row_table. */ | 4191 | /* Bucket index of this row_entry in the hash table row_table. */ |
| 4203 | int bucket; | 4192 | ptrdiff_t bucket; |
| 4204 | 4193 | ||
| 4205 | /* The row described by this entry. */ | 4194 | /* The row described by this entry. */ |
| 4206 | struct glyph_row *row; | 4195 | struct glyph_row *row; |
| @@ -4214,29 +4203,29 @@ struct row_entry | |||
| 4214 | that we need a larger one. */ | 4203 | that we need a larger one. */ |
| 4215 | 4204 | ||
| 4216 | static struct row_entry *row_entry_pool; | 4205 | static struct row_entry *row_entry_pool; |
| 4217 | static int row_entry_pool_size; | 4206 | static ptrdiff_t row_entry_pool_size; |
| 4218 | 4207 | ||
| 4219 | /* Index of next free entry in row_entry_pool. */ | 4208 | /* Index of next free entry in row_entry_pool. */ |
| 4220 | 4209 | ||
| 4221 | static int row_entry_idx; | 4210 | static ptrdiff_t row_entry_idx; |
| 4222 | 4211 | ||
| 4223 | /* The hash table used during scrolling, and the table's size. This | 4212 | /* The hash table used during scrolling, and the table's size. This |
| 4224 | table is used to quickly identify equal rows in the desired and | 4213 | table is used to quickly identify equal rows in the desired and |
| 4225 | current matrix. */ | 4214 | current matrix. */ |
| 4226 | 4215 | ||
| 4227 | static struct row_entry **row_table; | 4216 | static struct row_entry **row_table; |
| 4228 | static int row_table_size; | 4217 | static ptrdiff_t row_table_size; |
| 4229 | 4218 | ||
| 4230 | /* Vectors of pointers to row_entry structures belonging to the | 4219 | /* Vectors of pointers to row_entry structures belonging to the |
| 4231 | current and desired matrix, and the size of the vectors. */ | 4220 | current and desired matrix, and the size of the vectors. */ |
| 4232 | 4221 | ||
| 4233 | static struct row_entry **old_lines, **new_lines; | 4222 | static struct row_entry **old_lines, **new_lines; |
| 4234 | static int old_lines_size, new_lines_size; | 4223 | static ptrdiff_t old_lines_size, new_lines_size; |
| 4235 | 4224 | ||
| 4236 | /* A pool to allocate run structures from, and its size. */ | 4225 | /* A pool to allocate run structures from, and its size. */ |
| 4237 | 4226 | ||
| 4238 | static struct run *run_pool; | 4227 | static struct run *run_pool; |
| 4239 | static int runs_size; | 4228 | static ptrdiff_t runs_size; |
| 4240 | 4229 | ||
| 4241 | /* A vector of runs of lines found during scrolling. */ | 4230 | /* A vector of runs of lines found during scrolling. */ |
| 4242 | 4231 | ||
| @@ -4248,9 +4237,10 @@ static inline struct row_entry * | |||
| 4248 | add_row_entry (struct glyph_row *row) | 4237 | add_row_entry (struct glyph_row *row) |
| 4249 | { | 4238 | { |
| 4250 | struct row_entry *entry; | 4239 | struct row_entry *entry; |
| 4251 | int i = row->hash % row_table_size; | 4240 | ptrdiff_t i = row->hash % row_table_size; |
| 4252 | 4241 | ||
| 4253 | entry = row_table[i]; | 4242 | entry = row_table[i]; |
| 4243 | xassert (entry || verify_row_hash (row)); | ||
| 4254 | while (entry && !row_equal_p (entry->row, row, 1)) | 4244 | while (entry && !row_equal_p (entry->row, row, 1)) |
| 4255 | entry = entry->next; | 4245 | entry = entry->next; |
| 4256 | 4246 | ||
| @@ -4301,8 +4291,10 @@ scrolling_window (struct window *w, int header_line_p) | |||
| 4301 | struct glyph_matrix *desired_matrix = w->desired_matrix; | 4291 | struct glyph_matrix *desired_matrix = w->desired_matrix; |
| 4302 | struct glyph_matrix *current_matrix = w->current_matrix; | 4292 | struct glyph_matrix *current_matrix = w->current_matrix; |
| 4303 | int yb = window_text_bottom_y (w); | 4293 | int yb = window_text_bottom_y (w); |
| 4304 | int i, j, first_old, first_new, last_old, last_new; | 4294 | ptrdiff_t i; |
| 4305 | int nruns, nbytes, n, run_idx; | 4295 | int j, first_old, first_new, last_old, last_new; |
| 4296 | int nruns, run_idx; | ||
| 4297 | ptrdiff_t n; | ||
| 4306 | struct row_entry *entry; | 4298 | struct row_entry *entry; |
| 4307 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); | 4299 | struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w))); |
| 4308 | 4300 | ||
| @@ -4373,10 +4365,10 @@ scrolling_window (struct window *w, int header_line_p) | |||
| 4373 | j = last_old; | 4365 | j = last_old; |
| 4374 | while (i - 1 > first_new | 4366 | while (i - 1 > first_new |
| 4375 | && j - 1 > first_old | 4367 | && j - 1 > first_old |
| 4376 | && MATRIX_ROW (current_matrix, i - 1)->enabled_p | 4368 | && MATRIX_ROW (current_matrix, j - 1)->enabled_p |
| 4377 | && (MATRIX_ROW (current_matrix, i - 1)->y | 4369 | && (MATRIX_ROW (current_matrix, j - 1)->y |
| 4378 | == MATRIX_ROW (desired_matrix, j - 1)->y) | 4370 | == MATRIX_ROW (desired_matrix, i - 1)->y) |
| 4379 | && !MATRIX_ROW (desired_matrix, j - 1)->redraw_fringe_bitmaps_p | 4371 | && !MATRIX_ROW (desired_matrix, i - 1)->redraw_fringe_bitmaps_p |
| 4380 | && row_equal_p (MATRIX_ROW (desired_matrix, i - 1), | 4372 | && row_equal_p (MATRIX_ROW (desired_matrix, i - 1), |
| 4381 | MATRIX_ROW (current_matrix, j - 1), 1)) | 4373 | MATRIX_ROW (current_matrix, j - 1), 1)) |
| 4382 | --i, --j; | 4374 | --i, --j; |
| @@ -4387,45 +4379,59 @@ scrolling_window (struct window *w, int header_line_p) | |||
| 4387 | if (last_new == first_new) | 4379 | if (last_new == first_new) |
| 4388 | return 0; | 4380 | return 0; |
| 4389 | 4381 | ||
| 4382 | /* Check for integer overflow in size calculation. | ||
| 4383 | |||
| 4384 | If next_almost_prime checks (N) for divisibility by 2..10, then | ||
| 4385 | it can return at most N + 10, e.g., next_almost_prime (1) == 11. | ||
| 4386 | So, set next_almost_prime_increment_max to 10. | ||
| 4387 | |||
| 4388 | It's just a coincidence that next_almost_prime_increment_max == | ||
| 4389 | NEXT_ALMOST_PRIME_LIMIT - 1. If NEXT_ALMOST_PRIME_LIMIT were | ||
| 4390 | 13, then next_almost_prime_increment_max would be 14, e.g., | ||
| 4391 | because next_almost_prime (113) would be 127. */ | ||
| 4392 | { | ||
| 4393 | verify (NEXT_ALMOST_PRIME_LIMIT == 11); | ||
| 4394 | enum { next_almost_prime_increment_max = 10 }; | ||
| 4395 | ptrdiff_t row_table_max = | ||
| 4396 | (min (PTRDIFF_MAX, SIZE_MAX) / (3 * sizeof *row_table) | ||
| 4397 | - next_almost_prime_increment_max); | ||
| 4398 | ptrdiff_t current_nrows_max = row_table_max - desired_matrix->nrows; | ||
| 4399 | if (current_nrows_max < current_matrix->nrows) | ||
| 4400 | memory_full (SIZE_MAX); | ||
| 4401 | } | ||
| 4402 | |||
| 4390 | /* Reallocate vectors, tables etc. if necessary. */ | 4403 | /* Reallocate vectors, tables etc. if necessary. */ |
| 4391 | 4404 | ||
| 4392 | if (current_matrix->nrows > old_lines_size) | 4405 | if (current_matrix->nrows > old_lines_size) |
| 4393 | { | 4406 | old_lines = xpalloc (old_lines, &old_lines_size, |
| 4394 | old_lines_size = current_matrix->nrows; | 4407 | current_matrix->nrows - old_lines_size, |
| 4395 | nbytes = old_lines_size * sizeof *old_lines; | 4408 | INT_MAX, sizeof *old_lines); |
| 4396 | old_lines = (struct row_entry **) xrealloc (old_lines, nbytes); | ||
| 4397 | } | ||
| 4398 | 4409 | ||
| 4399 | if (desired_matrix->nrows > new_lines_size) | 4410 | if (desired_matrix->nrows > new_lines_size) |
| 4400 | { | 4411 | new_lines = xpalloc (new_lines, &new_lines_size, |
| 4401 | new_lines_size = desired_matrix->nrows; | 4412 | desired_matrix->nrows - new_lines_size, |
| 4402 | nbytes = new_lines_size * sizeof *new_lines; | 4413 | INT_MAX, sizeof *new_lines); |
| 4403 | new_lines = (struct row_entry **) xrealloc (new_lines, nbytes); | ||
| 4404 | } | ||
| 4405 | 4414 | ||
| 4406 | n = desired_matrix->nrows + current_matrix->nrows; | 4415 | n = desired_matrix->nrows; |
| 4407 | if (3 * n > row_table_size) | 4416 | n += current_matrix->nrows; |
| 4417 | if (row_table_size < 3 * n) | ||
| 4408 | { | 4418 | { |
| 4409 | row_table_size = next_almost_prime (3 * n); | 4419 | ptrdiff_t size = next_almost_prime (3 * n); |
| 4410 | nbytes = row_table_size * sizeof *row_table; | 4420 | row_table = xnrealloc (row_table, size, sizeof *row_table); |
| 4411 | row_table = (struct row_entry **) xrealloc (row_table, nbytes); | 4421 | row_table_size = size; |
| 4412 | memset (row_table, 0, nbytes); | 4422 | memset (row_table, 0, size * sizeof *row_table); |
| 4413 | } | 4423 | } |
| 4414 | 4424 | ||
| 4415 | if (n > row_entry_pool_size) | 4425 | if (n > row_entry_pool_size) |
| 4416 | { | 4426 | row_entry_pool = xpalloc (row_entry_pool, &row_entry_pool_size, |
| 4417 | row_entry_pool_size = n; | 4427 | n - row_entry_pool_size, |
| 4418 | nbytes = row_entry_pool_size * sizeof *row_entry_pool; | 4428 | -1, sizeof *row_entry_pool); |
| 4419 | row_entry_pool = (struct row_entry *) xrealloc (row_entry_pool, nbytes); | ||
| 4420 | } | ||
| 4421 | 4429 | ||
| 4422 | if (desired_matrix->nrows > runs_size) | 4430 | if (desired_matrix->nrows > runs_size) |
| 4423 | { | 4431 | { |
| 4432 | runs = xnrealloc (runs, desired_matrix->nrows, sizeof *runs); | ||
| 4433 | run_pool = xnrealloc (run_pool, desired_matrix->nrows, sizeof *run_pool); | ||
| 4424 | runs_size = desired_matrix->nrows; | 4434 | runs_size = desired_matrix->nrows; |
| 4425 | nbytes = runs_size * sizeof *runs; | ||
| 4426 | runs = (struct run **) xrealloc (runs, nbytes); | ||
| 4427 | nbytes = runs_size * sizeof *run_pool; | ||
| 4428 | run_pool = (struct run *) xrealloc (run_pool, nbytes); | ||
| 4429 | } | 4435 | } |
| 4430 | 4436 | ||
| 4431 | nruns = run_idx = 0; | 4437 | nruns = run_idx = 0; |
| @@ -4545,18 +4551,69 @@ scrolling_window (struct window *w, int header_line_p) | |||
| 4545 | { | 4551 | { |
| 4546 | rif->clear_window_mouse_face (w); | 4552 | rif->clear_window_mouse_face (w); |
| 4547 | rif->scroll_run_hook (w, r); | 4553 | rif->scroll_run_hook (w, r); |
| 4554 | } | ||
| 4548 | 4555 | ||
| 4549 | /* Invalidate runs that copy from where we copied to. */ | 4556 | /* Truncate runs that copy to where we copied to, and |
| 4550 | for (j = i + 1; j < nruns; ++j) | 4557 | invalidate runs that copy from where we copied to. */ |
| 4558 | for (j = nruns - 1; j > i; --j) | ||
| 4559 | { | ||
| 4560 | struct run *p = runs[j]; | ||
| 4561 | int truncated_p = 0; | ||
| 4562 | |||
| 4563 | if (p->nrows > 0 | ||
| 4564 | && p->desired_y < r->desired_y + r->height | ||
| 4565 | && p->desired_y + p->height > r->desired_y) | ||
| 4551 | { | 4566 | { |
| 4552 | struct run *p = runs[j]; | 4567 | if (p->desired_y < r->desired_y) |
| 4568 | { | ||
| 4569 | p->nrows = r->desired_vpos - p->desired_vpos; | ||
| 4570 | p->height = r->desired_y - p->desired_y; | ||
| 4571 | truncated_p = 1; | ||
| 4572 | } | ||
| 4573 | else | ||
| 4574 | { | ||
| 4575 | int nrows_copied = (r->desired_vpos + r->nrows | ||
| 4576 | - p->desired_vpos); | ||
| 4577 | |||
| 4578 | if (p->nrows <= nrows_copied) | ||
| 4579 | p->nrows = 0; | ||
| 4580 | else | ||
| 4581 | { | ||
| 4582 | int height_copied = (r->desired_y + r->height | ||
| 4583 | - p->desired_y); | ||
| 4584 | |||
| 4585 | p->current_vpos += nrows_copied; | ||
| 4586 | p->desired_vpos += nrows_copied; | ||
| 4587 | p->nrows -= nrows_copied; | ||
| 4588 | p->current_y += height_copied; | ||
| 4589 | p->desired_y += height_copied; | ||
| 4590 | p->height -= height_copied; | ||
| 4591 | truncated_p = 1; | ||
| 4592 | } | ||
| 4593 | } | ||
| 4594 | } | ||
| 4553 | 4595 | ||
| 4554 | if ((p->current_y >= r->desired_y | 4596 | if (r->current_y != r->desired_y |
| 4597 | /* The condition below is equivalent to | ||
| 4598 | ((p->current_y >= r->desired_y | ||
| 4555 | && p->current_y < r->desired_y + r->height) | 4599 | && p->current_y < r->desired_y + r->height) |
| 4556 | || (p->current_y + p->height >= r->desired_y | 4600 | || (p->current_y + p->height > r->desired_y |
| 4557 | && (p->current_y + p->height | 4601 | && (p->current_y + p->height |
| 4558 | < r->desired_y + r->height))) | 4602 | <= r->desired_y + r->height))) |
| 4559 | p->nrows = 0; | 4603 | because we have 0 < p->height <= r->height. */ |
| 4604 | && p->current_y < r->desired_y + r->height | ||
| 4605 | && p->current_y + p->height > r->desired_y) | ||
| 4606 | p->nrows = 0; | ||
| 4607 | |||
| 4608 | /* Reorder runs by copied pixel lines if truncated. */ | ||
| 4609 | if (truncated_p && p->nrows > 0) | ||
| 4610 | { | ||
| 4611 | int k = nruns - 1; | ||
| 4612 | |||
| 4613 | while (runs[k]->nrows == 0 || runs[k]->height < p->height) | ||
| 4614 | k--; | ||
| 4615 | memmove (runs + j, runs + j + 1, (k - j) * sizeof (*runs)); | ||
| 4616 | runs[k] = p; | ||
| 4560 | } | 4617 | } |
| 4561 | } | 4618 | } |
| 4562 | 4619 | ||
| @@ -4571,7 +4628,14 @@ scrolling_window (struct window *w, int header_line_p) | |||
| 4571 | to_overlapped_p = to->overlapped_p; | 4628 | to_overlapped_p = to->overlapped_p; |
| 4572 | from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p; | 4629 | from->redraw_fringe_bitmaps_p = from->fringe_bitmap_periodic_p; |
| 4573 | assign_row (to, from); | 4630 | assign_row (to, from); |
| 4574 | to->enabled_p = 1, from->enabled_p = 0; | 4631 | /* The above `assign_row' actually does swap, so if we had |
| 4632 | an overlap in the copy destination of two runs, then | ||
| 4633 | the second run would assign a previously disabled bogus | ||
| 4634 | row. But thanks to the truncation code in the | ||
| 4635 | preceding for-loop, we no longer have such an overlap, | ||
| 4636 | and thus the assigned row should always be enabled. */ | ||
| 4637 | xassert (to->enabled_p); | ||
| 4638 | from->enabled_p = 0; | ||
| 4575 | to->overlapped_p = to_overlapped_p; | 4639 | to->overlapped_p = to_overlapped_p; |
| 4576 | } | 4640 | } |
| 4577 | } | 4641 | } |
| @@ -4937,7 +5001,7 @@ count_match (struct glyph *str1, struct glyph *end1, struct glyph *str2, struct | |||
| 4937 | 5001 | ||
| 4938 | /* Char insertion/deletion cost vector, from term.c */ | 5002 | /* Char insertion/deletion cost vector, from term.c */ |
| 4939 | 5003 | ||
| 4940 | #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_TOTAL_COLS((f))]) | 5004 | #define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_TOTAL_COLS ((f))]) |
| 4941 | 5005 | ||
| 4942 | 5006 | ||
| 4943 | /* Perform a frame-based update on line VPOS in frame FRAME. */ | 5007 | /* Perform a frame-based update on line VPOS in frame FRAME. */ |
| @@ -5276,14 +5340,20 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p | |||
| 5276 | struct image *img = 0; | 5340 | struct image *img = 0; |
| 5277 | #endif | 5341 | #endif |
| 5278 | int x0, x1, to_x; | 5342 | int x0, x1, to_x; |
| 5343 | void *itdata = NULL; | ||
| 5279 | 5344 | ||
| 5280 | /* We used to set current_buffer directly here, but that does the | 5345 | /* We used to set current_buffer directly here, but that does the |
| 5281 | wrong thing with `face-remapping-alist' (bug#2044). */ | 5346 | wrong thing with `face-remapping-alist' (bug#2044). */ |
| 5282 | Fset_buffer (w->buffer); | 5347 | Fset_buffer (w->buffer); |
| 5348 | itdata = bidi_shelve_cache (); | ||
| 5283 | SET_TEXT_POS_FROM_MARKER (startp, w->start); | 5349 | SET_TEXT_POS_FROM_MARKER (startp, w->start); |
| 5284 | CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp))); | 5350 | CHARPOS (startp) = min (ZV, max (BEGV, CHARPOS (startp))); |
| 5285 | BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp))); | 5351 | BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp))); |
| 5286 | start_display (&it, w, startp); | 5352 | start_display (&it, w, startp); |
| 5353 | /* start_display takes into account the header-line row, but IT's | ||
| 5354 | vpos still counts from the glyph row that includes the window's | ||
| 5355 | start position. Adjust for a possible header-line row. */ | ||
| 5356 | it.vpos += WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0; | ||
| 5287 | 5357 | ||
| 5288 | x0 = *x; | 5358 | x0 = *x; |
| 5289 | 5359 | ||
| @@ -5313,6 +5383,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p | |||
| 5313 | argument is ZV to prevent move_it_in_display_line from matching | 5383 | argument is ZV to prevent move_it_in_display_line from matching |
| 5314 | based on buffer positions. */ | 5384 | based on buffer positions. */ |
| 5315 | move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X); | 5385 | move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X); |
| 5386 | bidi_unshelve_cache (itdata, 0); | ||
| 5316 | 5387 | ||
| 5317 | Fset_buffer (old_current_buffer); | 5388 | Fset_buffer (old_current_buffer); |
| 5318 | 5389 | ||
| @@ -5337,7 +5408,8 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p | |||
| 5337 | if (STRINGP (it.string)) | 5408 | if (STRINGP (it.string)) |
| 5338 | BYTEPOS (pos->pos) = string_char_to_byte (string, CHARPOS (pos->pos)); | 5409 | BYTEPOS (pos->pos) = string_char_to_byte (string, CHARPOS (pos->pos)); |
| 5339 | else | 5410 | else |
| 5340 | BYTEPOS (pos->pos) = CHAR_TO_BYTE (CHARPOS (pos->pos)); | 5411 | BYTEPOS (pos->pos) = buf_charpos_to_bytepos (XBUFFER (w->buffer), |
| 5412 | CHARPOS (pos->pos)); | ||
| 5341 | } | 5413 | } |
| 5342 | 5414 | ||
| 5343 | #ifdef HAVE_WINDOW_SYSTEM | 5415 | #ifdef HAVE_WINDOW_SYSTEM |
| @@ -5385,7 +5457,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p | |||
| 5385 | } | 5457 | } |
| 5386 | 5458 | ||
| 5387 | /* Add extra (default width) columns if clicked after EOL. */ | 5459 | /* Add extra (default width) columns if clicked after EOL. */ |
| 5388 | x1 = max(0, it.current_x + it.pixel_width - it.first_visible_x); | 5460 | x1 = max (0, it.current_x + it.pixel_width - it.first_visible_x); |
| 5389 | if (x0 > x1) | 5461 | if (x0 > x1) |
| 5390 | it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w); | 5462 | it.hpos += (x0 - x1) / WINDOW_FRAME_COLUMN_WIDTH (w); |
| 5391 | 5463 | ||
| @@ -5689,19 +5761,22 @@ change_frame_size_1 (register struct frame *f, int newheight, int newwidth, int | |||
| 5689 | if (newwidth == 0) | 5761 | if (newwidth == 0) |
| 5690 | newwidth = FRAME_COLS (f); | 5762 | newwidth = FRAME_COLS (f); |
| 5691 | 5763 | ||
| 5692 | /* Compute width of windows in F. | 5764 | /* Compute width of windows in F. */ |
| 5693 | This is the width of the frame without vertical scroll bars. */ | ||
| 5694 | new_frame_total_cols = FRAME_TOTAL_COLS_ARG (f, newwidth); | ||
| 5695 | |||
| 5696 | /* Round up to the smallest acceptable size. */ | 5765 | /* Round up to the smallest acceptable size. */ |
| 5697 | check_frame_size (f, &newheight, &newwidth); | 5766 | check_frame_size (f, &newheight, &newwidth); |
| 5698 | 5767 | ||
| 5768 | /* This is the width of the frame with vertical scroll bars and fringe | ||
| 5769 | columns. Do this after rounding - see discussion of bug#9723. */ | ||
| 5770 | new_frame_total_cols = FRAME_TOTAL_COLS_ARG (f, newwidth); | ||
| 5771 | |||
| 5699 | /* If we're not changing the frame size, quit now. */ | 5772 | /* If we're not changing the frame size, quit now. */ |
| 5700 | /* Frame width may be unchanged but the text portion may change, for example, | 5773 | /* Frame width may be unchanged but the text portion may change, for |
| 5701 | fullscreen and remove/add scroll bar. */ | 5774 | example, fullscreen and remove/add scroll bar. */ |
| 5702 | if (newheight == FRAME_LINES (f) | 5775 | if (newheight == FRAME_LINES (f) |
| 5703 | && newwidth == FRAME_COLS (f) // text portion unchanged | 5776 | /* Text portion unchanged? */ |
| 5704 | && new_frame_total_cols == FRAME_TOTAL_COLS (f)) // frame width unchanged | 5777 | && newwidth == FRAME_COLS (f) |
| 5778 | /* Frame width unchanged? */ | ||
| 5779 | && new_frame_total_cols == FRAME_TOTAL_COLS (f)) | ||
| 5705 | return; | 5780 | return; |
| 5706 | 5781 | ||
| 5707 | BLOCK_INPUT; | 5782 | BLOCK_INPUT; |
| @@ -5993,10 +6068,14 @@ sit_for (Lisp_Object timeout, int reading, int do_display) | |||
| 5993 | 6068 | ||
| 5994 | 6069 | ||
| 5995 | DEFUN ("redisplay", Fredisplay, Sredisplay, 0, 1, 0, | 6070 | DEFUN ("redisplay", Fredisplay, Sredisplay, 0, 1, 0, |
| 5996 | doc: /* Perform redisplay if no input is available. | 6071 | doc: /* Perform redisplay. |
| 5997 | If optional arg FORCE is non-nil or `redisplay-dont-pause' is non-nil, | 6072 | Optional arg FORCE, if non-nil, prevents redisplay from being |
| 5998 | perform a full redisplay even if input is available. | 6073 | preempted by arriving input, even if `redisplay-dont-pause' is nil. |
| 5999 | Return t if redisplay was performed, nil otherwise. */) | 6074 | If `redisplay-dont-pause' is non-nil (the default), redisplay is never |
| 6075 | preempted by arriving input, so FORCE does nothing. | ||
| 6076 | |||
| 6077 | Return t if redisplay was performed, nil if redisplay was preempted | ||
| 6078 | immediately by pending input. */) | ||
| 6000 | (Lisp_Object force) | 6079 | (Lisp_Object force) |
| 6001 | { | 6080 | { |
| 6002 | int count; | 6081 | int count; |
| @@ -6249,7 +6328,7 @@ init_display (void) | |||
| 6249 | ) | 6328 | ) |
| 6250 | { | 6329 | { |
| 6251 | Vinitial_window_system = Qns; | 6330 | Vinitial_window_system = Qns; |
| 6252 | Vwindow_system_version = make_number(10); | 6331 | Vwindow_system_version = make_number (10); |
| 6253 | adjust_frame_glyphs_initially (); | 6332 | adjust_frame_glyphs_initially (); |
| 6254 | return; | 6333 | return; |
| 6255 | } | 6334 | } |
| @@ -6327,11 +6406,14 @@ init_display (void) | |||
| 6327 | int width = FRAME_TOTAL_COLS (sf); | 6406 | int width = FRAME_TOTAL_COLS (sf); |
| 6328 | int height = FRAME_LINES (sf); | 6407 | int height = FRAME_LINES (sf); |
| 6329 | 6408 | ||
| 6330 | unsigned int total_glyphs = height * (width + 2) * sizeof (struct glyph); | ||
| 6331 | |||
| 6332 | /* If these sizes are so big they cause overflow, just ignore the | 6409 | /* If these sizes are so big they cause overflow, just ignore the |
| 6333 | change. It's not clear what better we could do. */ | 6410 | change. It's not clear what better we could do. The rest of |
| 6334 | if (total_glyphs / sizeof (struct glyph) / height != width + 2) | 6411 | the code assumes that (width + 2) * height * sizeof (struct glyph) |
| 6412 | does not overflow and does not exceed PTRDIFF_MAX or SIZE_MAX. */ | ||
| 6413 | if (INT_ADD_RANGE_OVERFLOW (width, 2, INT_MIN, INT_MAX) | ||
| 6414 | || INT_MULTIPLY_RANGE_OVERFLOW (width + 2, height, INT_MIN, INT_MAX) | ||
| 6415 | || (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph) | ||
| 6416 | < (width + 2) * height)) | ||
| 6335 | fatal ("screen size %dx%d too big", width, height); | 6417 | fatal ("screen size %dx%d too big", width, height); |
| 6336 | } | 6418 | } |
| 6337 | 6419 | ||
| @@ -6345,7 +6427,7 @@ init_display (void) | |||
| 6345 | { | 6427 | { |
| 6346 | /* For the initial frame, we don't have any way of knowing what | 6428 | /* For the initial frame, we don't have any way of knowing what |
| 6347 | are the foreground and background colors of the terminal. */ | 6429 | are the foreground and background colors of the terminal. */ |
| 6348 | struct frame *sf = SELECTED_FRAME(); | 6430 | struct frame *sf = SELECTED_FRAME (); |
| 6349 | 6431 | ||
| 6350 | FRAME_FOREGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_FG_COLOR; | 6432 | FRAME_FOREGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_FG_COLOR; |
| 6351 | FRAME_BACKGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_BG_COLOR; | 6433 | FRAME_BACKGROUND_PIXEL (sf) = FACE_TTY_DEFAULT_BG_COLOR; |
| @@ -6443,21 +6525,21 @@ syms_of_display (void) | |||
| 6443 | DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause"); | 6525 | DEFSYM (Qredisplay_dont_pause, "redisplay-dont-pause"); |
| 6444 | 6526 | ||
| 6445 | DEFVAR_INT ("baud-rate", baud_rate, | 6527 | DEFVAR_INT ("baud-rate", baud_rate, |
| 6446 | doc: /* *The output baud rate of the terminal. | 6528 | doc: /* The output baud rate of the terminal. |
| 6447 | On most systems, changing this value will affect the amount of padding | 6529 | On most systems, changing this value will affect the amount of padding |
| 6448 | and the other strategic decisions made during redisplay. */); | 6530 | and the other strategic decisions made during redisplay. */); |
| 6449 | 6531 | ||
| 6450 | DEFVAR_BOOL ("inverse-video", inverse_video, | 6532 | DEFVAR_BOOL ("inverse-video", inverse_video, |
| 6451 | doc: /* *Non-nil means invert the entire frame display. | 6533 | doc: /* Non-nil means invert the entire frame display. |
| 6452 | This means everything is in inverse video which otherwise would not be. */); | 6534 | This means everything is in inverse video which otherwise would not be. */); |
| 6453 | 6535 | ||
| 6454 | DEFVAR_BOOL ("visible-bell", visible_bell, | 6536 | DEFVAR_BOOL ("visible-bell", visible_bell, |
| 6455 | doc: /* *Non-nil means try to flash the frame to represent a bell. | 6537 | doc: /* Non-nil means try to flash the frame to represent a bell. |
| 6456 | 6538 | ||
| 6457 | See also `ring-bell-function'. */); | 6539 | See also `ring-bell-function'. */); |
| 6458 | 6540 | ||
| 6459 | DEFVAR_BOOL ("no-redraw-on-reenter", no_redraw_on_reenter, | 6541 | DEFVAR_BOOL ("no-redraw-on-reenter", no_redraw_on_reenter, |
| 6460 | doc: /* *Non-nil means no need to redraw entire frame after suspending. | 6542 | doc: /* Non-nil means no need to redraw entire frame after suspending. |
| 6461 | A non-nil value is useful if the terminal can automatically preserve | 6543 | A non-nil value is useful if the terminal can automatically preserve |
| 6462 | Emacs's frame display when you reenter Emacs. | 6544 | Emacs's frame display when you reenter Emacs. |
| 6463 | It is up to you to set this variable if your terminal can do that. */); | 6545 | It is up to you to set this variable if your terminal can do that. */); |
| @@ -6512,14 +6594,15 @@ See `buffer-display-table' for more information. */); | |||
| 6512 | Vstandard_display_table = Qnil; | 6594 | Vstandard_display_table = Qnil; |
| 6513 | 6595 | ||
| 6514 | DEFVAR_BOOL ("redisplay-dont-pause", redisplay_dont_pause, | 6596 | DEFVAR_BOOL ("redisplay-dont-pause", redisplay_dont_pause, |
| 6515 | doc: /* *Non-nil means update isn't paused when input is detected. */); | 6597 | doc: /* Non-nil means display update isn't paused when input is detected. */); |
| 6516 | redisplay_dont_pause = 0; | 6598 | redisplay_dont_pause = 1; |
| 6517 | 6599 | ||
| 6518 | #if PERIODIC_PREEMPTION_CHECKING | 6600 | #if PERIODIC_PREEMPTION_CHECKING |
| 6519 | DEFVAR_LISP ("redisplay-preemption-period", Vredisplay_preemption_period, | 6601 | DEFVAR_LISP ("redisplay-preemption-period", Vredisplay_preemption_period, |
| 6520 | doc: /* *The period in seconds between checking for input during redisplay. | 6602 | doc: /* Period in seconds between checking for input during redisplay. |
| 6521 | If input is detected, redisplay is pre-empted, and the input is processed. | 6603 | This has an effect only if `redisplay-dont-pause' is nil; in that |
| 6522 | If nil, never pre-empt redisplay. */); | 6604 | case, arriving input preempts redisplay until the input is processed. |
| 6605 | If the value is nil, redisplay is never preempted. */); | ||
| 6523 | Vredisplay_preemption_period = make_float (0.10); | 6606 | Vredisplay_preemption_period = make_float (0.10); |
| 6524 | #endif | 6607 | #endif |
| 6525 | 6608 | ||