diff options
| author | Karoly Lorentey | 2006-10-14 17:36:28 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2006-10-14 17:36:28 +0000 |
| commit | 12b6af5c7ed2cfdb9783312bf890cf1e6c80c67a (patch) | |
| tree | 1775f9fd1c92defd8b61304a08ec00da95bc4539 /src/window.c | |
| parent | 3f87f67ee215ffeecbd2f53bd7f342cdf03f47df (diff) | |
| parent | f763da8d0808af7c80d72bc586bf4fcf50b37ddd (diff) | |
| download | emacs-12b6af5c7ed2cfdb9783312bf890cf1e6c80c67a.tar.gz emacs-12b6af5c7ed2cfdb9783312bf890cf1e6c80c67a.zip | |
Merged from emacs@sv.gnu.org
Patches applied:
* emacs@sv.gnu.org/emacs--devo--0--patch-413
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-414
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-415
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-416
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-417
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-418
Merge from gnus--rel--5.10
* emacs@sv.gnu.org/emacs--devo--0--patch-419
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-420
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-421
Merge from gnus--rel--5.10
* emacs@sv.gnu.org/emacs--devo--0--patch-422
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-423
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-424
Merge from gnus--rel--5.10
* emacs@sv.gnu.org/emacs--devo--0--patch-425
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-426
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-427
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-428
Merge from gnus--rel--5.10
* emacs@sv.gnu.org/emacs--devo--0--patch-429
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-430
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-431
Merge from gnus--rel--5.10
* emacs@sv.gnu.org/emacs--devo--0--patch-432
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-433
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-434
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-435
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-436
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-437
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-438
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-439
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-440
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-441
lisp/url/url-methods.el: Fix format error when http_proxy is empty string
* emacs@sv.gnu.org/emacs--devo--0--patch-442
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-443
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-444
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-445
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-446
Merge from gnus--rel--5.10
* emacs@sv.gnu.org/emacs--devo--0--patch-447
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-448
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-449
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-450
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-451
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-452
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-453
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-454
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-455
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-456
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-457
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-458
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-459
Merge from gnus--rel--5.10
* emacs@sv.gnu.org/emacs--devo--0--patch-460
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-461
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-462
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-463
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-464
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-465
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-466
Merge from gnus--rel--5.10
* emacs@sv.gnu.org/emacs--devo--0--patch-467
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-468
Merge from gnus--rel--5.10
* emacs@sv.gnu.org/emacs--devo--0--patch-469
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-470
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-471
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-472
Update from CVS
* emacs@sv.gnu.org/emacs--devo--0--patch-473
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-128
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-129
Merge from emacs--devo--0
* emacs@sv.gnu.org/gnus--rel--5.10--patch-130
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-131
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-132
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-133
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-134
Merge from emacs--devo--0
* emacs@sv.gnu.org/gnus--rel--5.10--patch-135
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-136
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-137
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-138
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-139
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-140
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-141
Merge from emacs--devo--0
* emacs@sv.gnu.org/gnus--rel--5.10--patch-142
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-143
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-144
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-145
Merge from emacs--devo--0
* emacs@sv.gnu.org/gnus--rel--5.10--patch-146
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-147
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-148
Update from CVS
* emacs@sv.gnu.org/gnus--rel--5.10--patch-149
Update from CVS
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-582
Diffstat (limited to 'src/window.c')
| -rw-r--r-- | src/window.c | 247 |
1 files changed, 202 insertions, 45 deletions
diff --git a/src/window.c b/src/window.c index a3e7b93e878..0233c6bf79e 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -335,13 +335,16 @@ Return nil if that position is scrolled vertically out of view. | |||
| 335 | If a character is only partially visible, nil is returned, unless the | 335 | If a character is only partially visible, nil is returned, unless the |
| 336 | optional argument PARTIALLY is non-nil. | 336 | optional argument PARTIALLY is non-nil. |
| 337 | If POS is only out of view because of horizontal scrolling, return non-nil. | 337 | If POS is only out of view because of horizontal scrolling, return non-nil. |
| 338 | If POS is t, it specifies the position of the last visible glyph in WINDOW. | ||
| 338 | POS defaults to point in WINDOW; WINDOW defaults to the selected window. | 339 | POS defaults to point in WINDOW; WINDOW defaults to the selected window. |
| 339 | 340 | ||
| 340 | If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil, | 341 | If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil, |
| 341 | return value is a list (X Y PARTIAL) where X and Y are the pixel coordinates | 342 | return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]), |
| 342 | relative to the top left corner of the window. PARTIAL is nil if the character | 343 | where X and Y are the pixel coordinates relative to the top left corner |
| 343 | after POS is fully visible; otherwise it is a cons (RTOP . RBOT) where RTOP | 344 | of the window. The remaining elements are omitted if the character after |
| 344 | and RBOT are the number of pixels invisible at the top and bottom of the row. */) | 345 | POS is fully visible; otherwise, RTOP and RBOT are the number of pixels |
| 346 | off-window at the top and bottom of the row, ROWH is the height of the | ||
| 347 | display row, and VPOS is the row number (0-based) containing POS. */) | ||
| 345 | (pos, window, partially) | 348 | (pos, window, partially) |
| 346 | Lisp_Object pos, window, partially; | 349 | Lisp_Object pos, window, partially; |
| 347 | { | 350 | { |
| @@ -350,14 +353,16 @@ and RBOT are the number of pixels invisible at the top and bottom of the row. * | |||
| 350 | register struct buffer *buf; | 353 | register struct buffer *buf; |
| 351 | struct text_pos top; | 354 | struct text_pos top; |
| 352 | Lisp_Object in_window = Qnil; | 355 | Lisp_Object in_window = Qnil; |
| 353 | int rtop, rbot, fully_p = 1; | 356 | int rtop, rbot, rowh, vpos, fully_p = 1; |
| 354 | int x, y; | 357 | int x, y; |
| 355 | 358 | ||
| 356 | w = decode_window (window); | 359 | w = decode_window (window); |
| 357 | buf = XBUFFER (w->buffer); | 360 | buf = XBUFFER (w->buffer); |
| 358 | SET_TEXT_POS_FROM_MARKER (top, w->start); | 361 | SET_TEXT_POS_FROM_MARKER (top, w->start); |
| 359 | 362 | ||
| 360 | if (!NILP (pos)) | 363 | if (EQ (pos, Qt)) |
| 364 | posint = -1; | ||
| 365 | else if (!NILP (pos)) | ||
| 361 | { | 366 | { |
| 362 | CHECK_NUMBER_COERCE_MARKER (pos); | 367 | CHECK_NUMBER_COERCE_MARKER (pos); |
| 363 | posint = XINT (pos); | 368 | posint = XINT (pos); |
| @@ -369,24 +374,138 @@ and RBOT are the number of pixels invisible at the top and bottom of the row. * | |||
| 369 | 374 | ||
| 370 | /* If position is above window start or outside buffer boundaries, | 375 | /* If position is above window start or outside buffer boundaries, |
| 371 | or if window start is out of range, position is not visible. */ | 376 | or if window start is out of range, position is not visible. */ |
| 372 | if (posint >= CHARPOS (top) | 377 | if ((EQ (pos, Qt) |
| 373 | && posint <= BUF_ZV (buf) | 378 | || (posint >= CHARPOS (top) && posint <= BUF_ZV (buf))) |
| 374 | && CHARPOS (top) >= BUF_BEGV (buf) | 379 | && CHARPOS (top) >= BUF_BEGV (buf) |
| 375 | && CHARPOS (top) <= BUF_ZV (buf) | 380 | && CHARPOS (top) <= BUF_ZV (buf) |
| 376 | && pos_visible_p (w, posint, &x, &y, &rtop, &rbot, NILP (partially)) | 381 | && pos_visible_p (w, posint, &x, &y, &rtop, &rbot, &rowh, &vpos) |
| 377 | && (fully_p = !rtop && !rbot, (!NILP (partially) || fully_p))) | 382 | && (fully_p = !rtop && !rbot, (!NILP (partially) || fully_p))) |
| 378 | in_window = Qt; | 383 | in_window = Qt; |
| 379 | 384 | ||
| 380 | if (!NILP (in_window) && !NILP (partially)) | 385 | if (!NILP (in_window) && !NILP (partially)) |
| 381 | in_window = Fcons (make_number (x), | 386 | { |
| 382 | Fcons (make_number (y), | 387 | Lisp_Object part = Qnil; |
| 383 | Fcons ((fully_p ? Qnil | 388 | if (!fully_p) |
| 384 | : Fcons (make_number (rtop), | 389 | part = list4 (make_number (rtop), make_number (rbot), |
| 385 | make_number (rbot))), | 390 | make_number (rowh), make_number (vpos)); |
| 386 | Qnil))); | 391 | in_window = Fcons (make_number (x), |
| 392 | Fcons (make_number (y), part)); | ||
| 393 | } | ||
| 394 | |||
| 387 | return in_window; | 395 | return in_window; |
| 388 | } | 396 | } |
| 389 | 397 | ||
| 398 | DEFUN ("window-line-height", Fwindow_line_height, | ||
| 399 | Swindow_line_height, 0, 2, 0, | ||
| 400 | doc: /* Return height in pixels of text line LINE in window WINDOW. | ||
| 401 | If WINDOW is nil or omitted, use selected window. | ||
| 402 | |||
| 403 | Return height of current line if LINE is omitted or nil. Return height of | ||
| 404 | header or mode line if LINE is `header-line' and `mode-line'. | ||
| 405 | Otherwise, LINE is a text line number starting from 0. A negative number | ||
| 406 | counts from the end of the window. | ||
| 407 | |||
| 408 | Value is a list (HEIGHT VPOS YPOS OFFBOT), where HEIGHT is the height | ||
| 409 | in pixels of the visible part of the line, VPOS and YPOS are the | ||
| 410 | vertical position in lines and pixels of the line, relative to the top | ||
| 411 | of the first text line, and OFFBOT is the number of off-window pixels at | ||
| 412 | the bottom of the text line. If there are off-window pixels at the top | ||
| 413 | of the (first) text line, YPOS is negative. | ||
| 414 | |||
| 415 | Return nil if window display is not up-to-date. In that case, use | ||
| 416 | `pos-visible-in-window-p' to obtain the information. */) | ||
| 417 | (line, window) | ||
| 418 | Lisp_Object line, window; | ||
| 419 | { | ||
| 420 | register struct window *w; | ||
| 421 | register struct buffer *b; | ||
| 422 | struct glyph_row *row, *end_row; | ||
| 423 | int max_y, crop, i, n; | ||
| 424 | |||
| 425 | w = decode_window (window); | ||
| 426 | |||
| 427 | if (noninteractive | ||
| 428 | || w->pseudo_window_p) | ||
| 429 | return Qnil; | ||
| 430 | |||
| 431 | CHECK_BUFFER (w->buffer); | ||
| 432 | b = XBUFFER (w->buffer); | ||
| 433 | |||
| 434 | /* Fail if current matrix is not up-to-date. */ | ||
| 435 | if (NILP (w->window_end_valid) | ||
| 436 | || current_buffer->clip_changed | ||
| 437 | || current_buffer->prevent_redisplay_optimizations_p | ||
| 438 | || XFASTINT (w->last_modified) < BUF_MODIFF (b) | ||
| 439 | || XFASTINT (w->last_overlay_modified) < BUF_OVERLAY_MODIFF (b)) | ||
| 440 | return Qnil; | ||
| 441 | |||
| 442 | if (NILP (line)) | ||
| 443 | { | ||
| 444 | i = w->cursor.vpos; | ||
| 445 | if (i < 0 || i >= w->current_matrix->nrows | ||
| 446 | || (row = MATRIX_ROW (w->current_matrix, i), !row->enabled_p)) | ||
| 447 | return Qnil; | ||
| 448 | max_y = window_text_bottom_y (w); | ||
| 449 | goto found_row; | ||
| 450 | } | ||
| 451 | |||
| 452 | if (EQ (line, Qheader_line)) | ||
| 453 | { | ||
| 454 | if (!WINDOW_WANTS_HEADER_LINE_P (w)) | ||
| 455 | return Qnil; | ||
| 456 | row = MATRIX_HEADER_LINE_ROW (w->current_matrix); | ||
| 457 | if (!row->enabled_p) | ||
| 458 | return Qnil; | ||
| 459 | return list4 (make_number (row->height), | ||
| 460 | make_number (0), make_number (0), | ||
| 461 | make_number (0)); | ||
| 462 | } | ||
| 463 | |||
| 464 | if (EQ (line, Qmode_line)) | ||
| 465 | { | ||
| 466 | row = MATRIX_MODE_LINE_ROW (w->current_matrix); | ||
| 467 | if (!row->enabled_p) | ||
| 468 | return Qnil; | ||
| 469 | return list4 (make_number (row->height), | ||
| 470 | make_number (0), /* not accurate */ | ||
| 471 | make_number (WINDOW_HEADER_LINE_HEIGHT (w) | ||
| 472 | + window_text_bottom_y (w)), | ||
| 473 | make_number (0)); | ||
| 474 | } | ||
| 475 | |||
| 476 | CHECK_NUMBER (line); | ||
| 477 | n = XINT (line); | ||
| 478 | |||
| 479 | row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); | ||
| 480 | end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w); | ||
| 481 | max_y = window_text_bottom_y (w); | ||
| 482 | i = 0; | ||
| 483 | |||
| 484 | while ((n < 0 || i < n) | ||
| 485 | && row <= end_row && row->enabled_p | ||
| 486 | && row->y + row->height < max_y) | ||
| 487 | row++, i++; | ||
| 488 | |||
| 489 | if (row > end_row || !row->enabled_p) | ||
| 490 | return Qnil; | ||
| 491 | |||
| 492 | if (++n < 0) | ||
| 493 | { | ||
| 494 | if (-n > i) | ||
| 495 | return Qnil; | ||
| 496 | row += n; | ||
| 497 | i += n; | ||
| 498 | } | ||
| 499 | |||
| 500 | found_row: | ||
| 501 | crop = max (0, (row->y + row->height) - max_y); | ||
| 502 | return list4 (make_number (row->height + min (0, row->y) - crop), | ||
| 503 | make_number (i), | ||
| 504 | make_number (row->y), | ||
| 505 | make_number (crop)); | ||
| 506 | } | ||
| 507 | |||
| 508 | |||
| 390 | 509 | ||
| 391 | static struct window * | 510 | static struct window * |
| 392 | decode_window (window) | 511 | decode_window (window) |
| @@ -451,7 +570,7 @@ DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0, | |||
| 451 | Return NCOL. NCOL should be zero or positive. | 570 | Return NCOL. NCOL should be zero or positive. |
| 452 | 571 | ||
| 453 | Note that if `automatic-hscrolling' is non-nil, you cannot scroll the | 572 | Note that if `automatic-hscrolling' is non-nil, you cannot scroll the |
| 454 | window so that the location of point becomes invisible. */) | 573 | window so that the location of point moves off-window. */) |
| 455 | (window, ncol) | 574 | (window, ncol) |
| 456 | Lisp_Object window, ncol; | 575 | Lisp_Object window, ncol; |
| 457 | { | 576 | { |
| @@ -1048,9 +1167,11 @@ if it isn't already recorded. */) | |||
| 1048 | Lisp_Object value; | 1167 | Lisp_Object value; |
| 1049 | struct window *w = decode_window (window); | 1168 | struct window *w = decode_window (window); |
| 1050 | Lisp_Object buf; | 1169 | Lisp_Object buf; |
| 1170 | struct buffer *b; | ||
| 1051 | 1171 | ||
| 1052 | buf = w->buffer; | 1172 | buf = w->buffer; |
| 1053 | CHECK_BUFFER (buf); | 1173 | CHECK_BUFFER (buf); |
| 1174 | b = XBUFFER (buf); | ||
| 1054 | 1175 | ||
| 1055 | #if 0 /* This change broke some things. We should make it later. */ | 1176 | #if 0 /* This change broke some things. We should make it later. */ |
| 1056 | /* If we don't know the end position, return nil. | 1177 | /* If we don't know the end position, return nil. |
| @@ -1063,12 +1184,20 @@ if it isn't already recorded. */) | |||
| 1063 | 1184 | ||
| 1064 | if (! NILP (update) | 1185 | if (! NILP (update) |
| 1065 | && ! (! NILP (w->window_end_valid) | 1186 | && ! (! NILP (w->window_end_valid) |
| 1066 | && XFASTINT (w->last_modified) >= MODIFF) | 1187 | && XFASTINT (w->last_modified) >= BUF_MODIFF (b)) |
| 1067 | && !noninteractive) | 1188 | && !noninteractive) |
| 1068 | { | 1189 | { |
| 1069 | struct text_pos startp; | 1190 | struct text_pos startp; |
| 1070 | struct it it; | 1191 | struct it it; |
| 1071 | struct buffer *old_buffer = NULL, *b = XBUFFER (buf); | 1192 | struct buffer *old_buffer = NULL; |
| 1193 | |||
| 1194 | /* Cannot use Fvertical_motion because that function doesn't | ||
| 1195 | cope with variable-height lines. */ | ||
| 1196 | if (b != current_buffer) | ||
| 1197 | { | ||
| 1198 | old_buffer = current_buffer; | ||
| 1199 | set_buffer_internal (b); | ||
| 1200 | } | ||
| 1072 | 1201 | ||
| 1073 | /* In case W->start is out of the range, use something | 1202 | /* In case W->start is out of the range, use something |
| 1074 | reasonable. This situation occurred when loading a file with | 1203 | reasonable. This situation occurred when loading a file with |
| @@ -1082,14 +1211,6 @@ if it isn't already recorded. */) | |||
| 1082 | else | 1211 | else |
| 1083 | SET_TEXT_POS_FROM_MARKER (startp, w->start); | 1212 | SET_TEXT_POS_FROM_MARKER (startp, w->start); |
| 1084 | 1213 | ||
| 1085 | /* Cannot use Fvertical_motion because that function doesn't | ||
| 1086 | cope with variable-height lines. */ | ||
| 1087 | if (b != current_buffer) | ||
| 1088 | { | ||
| 1089 | old_buffer = current_buffer; | ||
| 1090 | set_buffer_internal (b); | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | start_display (&it, w, startp); | 1214 | start_display (&it, w, startp); |
| 1094 | move_it_vertically (&it, window_box_height (w)); | 1215 | move_it_vertically (&it, window_box_height (w)); |
| 1095 | if (it.current_y < it.last_visible_y) | 1216 | if (it.current_y < it.last_visible_y) |
| @@ -1100,7 +1221,7 @@ if it isn't already recorded. */) | |||
| 1100 | set_buffer_internal (old_buffer); | 1221 | set_buffer_internal (old_buffer); |
| 1101 | } | 1222 | } |
| 1102 | else | 1223 | else |
| 1103 | XSETINT (value, BUF_Z (XBUFFER (buf)) - XFASTINT (w->window_end_pos)); | 1224 | XSETINT (value, BUF_Z (b) - XFASTINT (w->window_end_pos)); |
| 1104 | 1225 | ||
| 1105 | return value; | 1226 | return value; |
| 1106 | } | 1227 | } |
| @@ -4820,10 +4941,10 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4820 | struct it it; | 4941 | struct it it; |
| 4821 | struct window *w = XWINDOW (window); | 4942 | struct window *w = XWINDOW (window); |
| 4822 | struct text_pos start; | 4943 | struct text_pos start; |
| 4823 | Lisp_Object tem; | ||
| 4824 | int this_scroll_margin; | 4944 | int this_scroll_margin; |
| 4825 | /* True if we fiddled the window vscroll field without really scrolling. */ | 4945 | /* True if we fiddled the window vscroll field without really scrolling. */ |
| 4826 | int vscrolled = 0; | 4946 | int vscrolled = 0; |
| 4947 | int x, y, rtop, rbot, rowh, vpos; | ||
| 4827 | 4948 | ||
| 4828 | SET_TEXT_POS_FROM_MARKER (start, w->start); | 4949 | SET_TEXT_POS_FROM_MARKER (start, w->start); |
| 4829 | 4950 | ||
| @@ -4831,8 +4952,8 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4831 | the screen. Allow PT to be partially visible, otherwise | 4952 | the screen. Allow PT to be partially visible, otherwise |
| 4832 | something like (scroll-down 1) with PT in the line before | 4953 | something like (scroll-down 1) with PT in the line before |
| 4833 | the partially visible one would recenter. */ | 4954 | the partially visible one would recenter. */ |
| 4834 | tem = Fpos_visible_in_window_p (make_number (PT), window, Qt); | 4955 | |
| 4835 | if (NILP (tem)) | 4956 | if (!pos_visible_p (w, PT, &x, &y, &rtop, &rbot, &rowh, &vpos)) |
| 4836 | { | 4957 | { |
| 4837 | /* Move backward half the height of the window. Performance note: | 4958 | /* Move backward half the height of the window. Performance note: |
| 4838 | vmotion used here is about 10% faster, but would give wrong | 4959 | vmotion used here is about 10% faster, but would give wrong |
| @@ -4857,7 +4978,7 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4857 | } | 4978 | } |
| 4858 | else if (auto_window_vscroll_p) | 4979 | else if (auto_window_vscroll_p) |
| 4859 | { | 4980 | { |
| 4860 | if (tem = XCAR (XCDR (XCDR (tem))), CONSP (tem)) | 4981 | if (rtop || rbot) /* partially visible */ |
| 4861 | { | 4982 | { |
| 4862 | int px; | 4983 | int px; |
| 4863 | int dy = WINDOW_FRAME_LINE_HEIGHT (w); | 4984 | int dy = WINDOW_FRAME_LINE_HEIGHT (w); |
| @@ -4867,19 +4988,52 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4867 | dy); | 4988 | dy); |
| 4868 | dy *= n; | 4989 | dy *= n; |
| 4869 | 4990 | ||
| 4870 | if (n < 0 && (px = XINT (XCAR (tem))) > 0) | 4991 | if (n < 0) |
| 4871 | { | 4992 | { |
| 4872 | px = max (0, -w->vscroll - min (px, -dy)); | 4993 | /* Only vscroll backwards if already vscrolled forwards. */ |
| 4873 | Fset_window_vscroll (window, make_number (px), Qt); | 4994 | if (w->vscroll < 0 && rtop > 0) |
| 4874 | return; | 4995 | { |
| 4996 | px = max (0, -w->vscroll - min (rtop, -dy)); | ||
| 4997 | Fset_window_vscroll (window, make_number (px), Qt); | ||
| 4998 | return; | ||
| 4999 | } | ||
| 4875 | } | 5000 | } |
| 4876 | if (n > 0 && (px = XINT (XCDR (tem))) > 0) | 5001 | if (n > 0) |
| 4877 | { | 5002 | { |
| 4878 | px = max (0, -w->vscroll + min (px, dy)); | 5003 | /* Do vscroll if already vscrolled or only display line. */ |
| 4879 | Fset_window_vscroll (window, make_number (px), Qt); | 5004 | if (rbot > 0 && (w->vscroll < 0 || vpos == 0)) |
| 4880 | return; | 5005 | { |
| 5006 | px = max (0, -w->vscroll + min (rbot, dy)); | ||
| 5007 | Fset_window_vscroll (window, make_number (px), Qt); | ||
| 5008 | return; | ||
| 5009 | } | ||
| 5010 | |||
| 5011 | /* Maybe modify window start instead of scrolling. */ | ||
| 5012 | if (rbot > 0 || w->vscroll < 0) | ||
| 5013 | { | ||
| 5014 | int spos; | ||
| 5015 | |||
| 5016 | Fset_window_vscroll (window, make_number (0), Qt); | ||
| 5017 | /* If there are other text lines above the current row, | ||
| 5018 | move window start to current row. Else to next row. */ | ||
| 5019 | if (rbot > 0) | ||
| 5020 | spos = XINT (Fline_beginning_position (Qnil)); | ||
| 5021 | else | ||
| 5022 | spos = min (XINT (Fline_end_position (Qnil)) + 1, ZV); | ||
| 5023 | set_marker_restricted (w->start, make_number (spos), | ||
| 5024 | w->buffer); | ||
| 5025 | w->start_at_line_beg = Qt; | ||
| 5026 | w->update_mode_line = Qt; | ||
| 5027 | XSETFASTINT (w->last_modified, 0); | ||
| 5028 | XSETFASTINT (w->last_overlay_modified, 0); | ||
| 5029 | /* Set force_start so that redisplay_window will run the | ||
| 5030 | window-scroll-functions. */ | ||
| 5031 | w->force_start = Qt; | ||
| 5032 | return; | ||
| 5033 | } | ||
| 4881 | } | 5034 | } |
| 4882 | } | 5035 | } |
| 5036 | /* Cancel previous vscroll. */ | ||
| 4883 | Fset_window_vscroll (window, make_number (0), Qt); | 5037 | Fset_window_vscroll (window, make_number (0), Qt); |
| 4884 | } | 5038 | } |
| 4885 | 5039 | ||
| @@ -4920,7 +5074,7 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4920 | if (dy <= 0) | 5074 | if (dy <= 0) |
| 4921 | { | 5075 | { |
| 4922 | move_it_vertically_backward (&it, -dy); | 5076 | move_it_vertically_backward (&it, -dy); |
| 4923 | /* Ensure we actually does move, e.g. in case we are currently | 5077 | /* Ensure we actually do move, e.g. in case we are currently |
| 4924 | looking at an image that is taller that the window height. */ | 5078 | looking at an image that is taller that the window height. */ |
| 4925 | while (start_pos == IT_CHARPOS (it) | 5079 | while (start_pos == IT_CHARPOS (it) |
| 4926 | && start_pos > BEGV) | 5080 | && start_pos > BEGV) |
| @@ -4930,7 +5084,7 @@ window_scroll_pixel_based (window, n, whole, noerror) | |||
| 4930 | { | 5084 | { |
| 4931 | move_it_to (&it, ZV, -1, it.current_y + dy, -1, | 5085 | move_it_to (&it, ZV, -1, it.current_y + dy, -1, |
| 4932 | MOVE_TO_POS | MOVE_TO_Y); | 5086 | MOVE_TO_POS | MOVE_TO_Y); |
| 4933 | /* Ensure we actually does move, e.g. in case we are currently | 5087 | /* Ensure we actually do move, e.g. in case we are currently |
| 4934 | looking at an image that is taller that the window height. */ | 5088 | looking at an image that is taller that the window height. */ |
| 4935 | while (start_pos == IT_CHARPOS (it) | 5089 | while (start_pos == IT_CHARPOS (it) |
| 4936 | && start_pos < ZV) | 5090 | && start_pos < ZV) |
| @@ -6658,7 +6812,7 @@ display marginal areas and the text area. */) | |||
| 6658 | CHECK_NATNUM (left_width); | 6812 | CHECK_NATNUM (left_width); |
| 6659 | if (!NILP (right_width)) | 6813 | if (!NILP (right_width)) |
| 6660 | CHECK_NATNUM (right_width); | 6814 | CHECK_NATNUM (right_width); |
| 6661 | 6815 | ||
| 6662 | /* Do nothing on a tty. */ | 6816 | /* Do nothing on a tty. */ |
| 6663 | if (FRAME_WINDOW_P (WINDOW_XFRAME (w)) | 6817 | if (FRAME_WINDOW_P (WINDOW_XFRAME (w)) |
| 6664 | && (!EQ (w->left_fringe_width, left_width) | 6818 | && (!EQ (w->left_fringe_width, left_width) |
| @@ -7292,16 +7446,18 @@ See also `same-window-buffer-names'. */); | |||
| 7292 | next_screen_context_lines = 2; | 7446 | next_screen_context_lines = 2; |
| 7293 | 7447 | ||
| 7294 | DEFVAR_INT ("split-height-threshold", &split_height_threshold, | 7448 | DEFVAR_INT ("split-height-threshold", &split_height_threshold, |
| 7295 | doc: /* *A window must be at least this tall to be eligible for splitting by `display-buffer'. | 7449 | doc: /* *A window must be at least this tall to be eligible for splitting |
| 7450 | by `display-buffer'. The value is in line units. | ||
| 7296 | If there is only one window, it is split regardless of this value. */); | 7451 | If there is only one window, it is split regardless of this value. */); |
| 7297 | split_height_threshold = 500; | 7452 | split_height_threshold = 500; |
| 7298 | 7453 | ||
| 7299 | DEFVAR_INT ("window-min-height", &window_min_height, | 7454 | DEFVAR_INT ("window-min-height", &window_min_height, |
| 7300 | doc: /* *Delete any window less than this tall (including its mode line). */); | 7455 | doc: /* *Delete any window less than this tall (including its mode line). |
| 7456 | The value is in line units. */); | ||
| 7301 | window_min_height = 4; | 7457 | window_min_height = 4; |
| 7302 | 7458 | ||
| 7303 | DEFVAR_INT ("window-min-width", &window_min_width, | 7459 | DEFVAR_INT ("window-min-width", &window_min_width, |
| 7304 | doc: /* *Delete any window less than this wide. */); | 7460 | doc: /* *Delete any window less than this wide (measured in characters). */); |
| 7305 | window_min_width = 10; | 7461 | window_min_width = 10; |
| 7306 | 7462 | ||
| 7307 | DEFVAR_LISP ("scroll-preserve-screen-position", | 7463 | DEFVAR_LISP ("scroll-preserve-screen-position", |
| @@ -7327,6 +7483,7 @@ The selected frame is the one whose configuration has changed. */); | |||
| 7327 | defsubr (&Swindowp); | 7483 | defsubr (&Swindowp); |
| 7328 | defsubr (&Swindow_live_p); | 7484 | defsubr (&Swindow_live_p); |
| 7329 | defsubr (&Spos_visible_in_window_p); | 7485 | defsubr (&Spos_visible_in_window_p); |
| 7486 | defsubr (&Swindow_line_height); | ||
| 7330 | defsubr (&Swindow_buffer); | 7487 | defsubr (&Swindow_buffer); |
| 7331 | defsubr (&Swindow_height); | 7488 | defsubr (&Swindow_height); |
| 7332 | defsubr (&Swindow_width); | 7489 | defsubr (&Swindow_width); |