diff options
| author | Eli Zaretskii | 2012-07-05 18:04:57 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2012-07-05 18:04:57 +0300 |
| commit | d6e7bf450c0a084927d533cb6913bc5f540a0032 (patch) | |
| tree | 32a92089fbf91bc9f7021a221a9797e0f4e6b8bc /src | |
| parent | 431391ec72c1c6ef324201ee00eabaf5399480dc (diff) | |
| download | emacs-d6e7bf450c0a084927d533cb6913bc5f540a0032.tar.gz emacs-d6e7bf450c0a084927d533cb6913bc5f540a0032.zip | |
Fix bug #11857 with messed up display for insanely large hscroll values.
src/xdisp.c (window_hscroll_limited): New function.
(pos_visible_p, init_iterator): Use it to avoid overflow of pixel
coordinates when window's hscroll is set to insanely large
values.
src/window.h (struct window) <hscroll, min_hscroll>: Change type to 'int'.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/window.h | 4 | ||||
| -rw-r--r-- | src/xdisp.c | 25 |
3 files changed, 34 insertions, 5 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 4519ea2dabf..d14c322cadf 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2012-07-05 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c (window_hscroll_limited): New function. | ||
| 4 | (pos_visible_p, init_iterator): Use it to avoid overflow of pixel | ||
| 5 | coordinates when window's hscroll is set to insanely large | ||
| 6 | values. (Bug#11857) | ||
| 7 | |||
| 8 | * window.h (struct window) <hscroll, min_hscroll>: Change type to | ||
| 9 | 'int'. | ||
| 10 | |||
| 1 | 2012-07-05 Juanma Barranquero <lekktu@gmail.com> | 11 | 2012-07-05 Juanma Barranquero <lekktu@gmail.com> |
| 2 | 12 | ||
| 3 | * makefile.w32-in ($(BLD)/dired.$(O), $(BLD)/fileio.$(O)): Fix typo. | 13 | * makefile.w32-in ($(BLD)/dired.$(O), $(BLD)/fileio.$(O)): Fix typo. |
diff --git a/src/window.h b/src/window.h index 10cabed979b..2684713eb6b 100644 --- a/src/window.h +++ b/src/window.h | |||
| @@ -238,11 +238,11 @@ struct window | |||
| 238 | int sequence_number; | 238 | int sequence_number; |
| 239 | 239 | ||
| 240 | /* Number of columns display within the window is scrolled to the left. */ | 240 | /* Number of columns display within the window is scrolled to the left. */ |
| 241 | ptrdiff_t hscroll; | 241 | int hscroll; |
| 242 | 242 | ||
| 243 | /* Minimum hscroll for automatic hscrolling. This is the value | 243 | /* Minimum hscroll for automatic hscrolling. This is the value |
| 244 | the user has set, by set-window-hscroll for example. */ | 244 | the user has set, by set-window-hscroll for example. */ |
| 245 | ptrdiff_t min_hscroll; | 245 | int min_hscroll; |
| 246 | 246 | ||
| 247 | /* Displayed buffer's text modification events counter as of last time | 247 | /* Displayed buffer's text modification events counter as of last time |
| 248 | display completed. */ | 248 | display completed. */ |
diff --git a/src/xdisp.c b/src/xdisp.c index 8231922056f..e6ad6a0bd78 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -1251,6 +1251,23 @@ string_from_display_spec (Lisp_Object spec) | |||
| 1251 | return spec; | 1251 | return spec; |
| 1252 | } | 1252 | } |
| 1253 | 1253 | ||
| 1254 | |||
| 1255 | /* Limit insanely large values of W->hscroll on frame F to the largest | ||
| 1256 | value that will still prevent first_visible_x and last_visible_x of | ||
| 1257 | 'struct it' from overflowing an int. */ | ||
| 1258 | static inline int | ||
| 1259 | window_hscroll_limited (struct window *w, struct frame *f) | ||
| 1260 | { | ||
| 1261 | int window_hscroll = w->hscroll; | ||
| 1262 | int window_text_width = window_box_width (w, TEXT_AREA); | ||
| 1263 | int colwidth = FRAME_COLUMN_WIDTH (f); | ||
| 1264 | |||
| 1265 | if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1) | ||
| 1266 | window_hscroll = (INT_MAX - window_text_width) / colwidth - 1; | ||
| 1267 | |||
| 1268 | return window_hscroll; | ||
| 1269 | } | ||
| 1270 | |||
| 1254 | /* Return 1 if position CHARPOS is visible in window W. | 1271 | /* Return 1 if position CHARPOS is visible in window W. |
| 1255 | CHARPOS < 0 means return info about WINDOW_END position. | 1272 | CHARPOS < 0 means return info about WINDOW_END position. |
| 1256 | If visible, set *X and *Y to pixel coordinates of top left corner. | 1273 | If visible, set *X and *Y to pixel coordinates of top left corner. |
| @@ -1563,7 +1580,9 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, | |||
| 1563 | current_header_line_height = current_mode_line_height = -1; | 1580 | current_header_line_height = current_mode_line_height = -1; |
| 1564 | 1581 | ||
| 1565 | if (visible_p && w->hscroll > 0) | 1582 | if (visible_p && w->hscroll > 0) |
| 1566 | *x -= w->hscroll * WINDOW_FRAME_COLUMN_WIDTH (w); | 1583 | *x -= |
| 1584 | window_hscroll_limited (w, WINDOW_XFRAME (w)) | ||
| 1585 | * WINDOW_FRAME_COLUMN_WIDTH (w); | ||
| 1567 | 1586 | ||
| 1568 | #if 0 | 1587 | #if 0 |
| 1569 | /* Debugging code. */ | 1588 | /* Debugging code. */ |
| @@ -2759,8 +2778,8 @@ init_iterator (struct it *it, struct window *w, | |||
| 2759 | } | 2778 | } |
| 2760 | else | 2779 | else |
| 2761 | { | 2780 | { |
| 2762 | it->first_visible_x | 2781 | it->first_visible_x = |
| 2763 | = it->w->hscroll * FRAME_COLUMN_WIDTH (it->f); | 2782 | window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f); |
| 2764 | it->last_visible_x = (it->first_visible_x | 2783 | it->last_visible_x = (it->first_visible_x |
| 2765 | + window_box_width (w, TEXT_AREA)); | 2784 | + window_box_width (w, TEXT_AREA)); |
| 2766 | 2785 | ||