comparison src/window.c @ 83542:2d56e13fd23d

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
author Karoly Lorentey <lorentey@elte.hu>
date Sat, 14 Oct 2006 17:36:28 +0000
parents 694bbb62a75d aab836d32a11
children 0912b745fc75
comparison
equal deleted inserted replaced
83541:694bbb62a75d 83542:2d56e13fd23d
333 doc: /* Return non-nil if position POS is currently on the frame in WINDOW. 333 doc: /* Return non-nil if position POS is currently on the frame in WINDOW.
334 Return nil if that position is scrolled vertically out of view. 334 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 {
348 register struct window *w; 351 register struct window *w;
349 register int posint; 352 register int posint;
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);
364 } 369 }
365 else if (w == XWINDOW (selected_window)) 370 else if (w == XWINDOW (selected_window))
367 else 372 else
368 posint = XMARKER (w->pointm)->charpos; 373 posint = XMARKER (w->pointm)->charpos;
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 }
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
389 508
390 509
391 static struct window * 510 static struct window *
392 decode_window (window) 511 decode_window (window)
393 register Lisp_Object window; 512 register Lisp_Object window;
449 DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0, 568 DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0,
450 doc: /* Set number of columns WINDOW is scrolled from left margin to NCOL. 569 doc: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
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 {
458 struct window *w = decode_window (window); 577 struct window *w = decode_window (window);
459 int hscroll; 578 int hscroll;
1046 Lisp_Object window, update; 1165 Lisp_Object window, update;
1047 { 1166 {
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.
1057 The user can compute it with vertical-motion if he wants to. 1178 The user can compute it with vertical-motion if he wants to.
1058 It would be nicer to do it automatically, 1179 It would be nicer to do it automatically,
1061 return Qnil; 1182 return Qnil;
1062 #endif 1183 #endif
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
1075 `-l' containing a call to `rmail' with subsequent other 1204 `-l' containing a call to `rmail' with subsequent other
1076 commands. At the end, W->start happened to be BEG, while 1205 commands. At the end, W->start happened to be BEG, while
1080 else if (XMARKER (w->start)->charpos > ZV) 1209 else if (XMARKER (w->start)->charpos > ZV)
1081 SET_TEXT_POS (startp, ZV, ZV_BYTE); 1210 SET_TEXT_POS (startp, ZV, ZV_BYTE);
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)
1096 move_it_past_eol (&it); 1217 move_it_past_eol (&it);
1097 value = make_number (IT_CHARPOS (it)); 1218 value = make_number (IT_CHARPOS (it));
1098 1219
1099 if (old_buffer) 1220 if (old_buffer)
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 }
1107 1228
1108 DEFUN ("set-window-point", Fset_window_point, Sset_window_point, 2, 2, 0, 1229 DEFUN ("set-window-point", Fset_window_point, Sset_window_point, 2, 2, 0,
4818 int noerror; 4939 int noerror;
4819 { 4940 {
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
4830 /* If PT is not visible in WINDOW, move back one half of 4951 /* If PT is not visible in WINDOW, move back one half of
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
4839 results for variable height lines. */ 4960 results for variable height lines. */
4840 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID); 4961 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
4855 4976
4856 start = it.current.pos; 4977 start = it.current.pos;
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);
4864 if (whole) 4985 if (whole)
4865 dy = max ((window_box_height (w) 4986 dy = max ((window_box_height (w)
4866 - next_screen_context_lines * dy), 4987 - next_screen_context_lines * dy),
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
4886 /* If scroll_preserve_screen_position is non-nil, we try to set 5040 /* If scroll_preserve_screen_position is non-nil, we try to set
4887 point in the same window line as it is now, so get that line. */ 5041 point in the same window line as it is now, so get that line. */
4918 start of a line. So, if the last line doesn't have a newline, 5072 start of a line. So, if the last line doesn't have a newline,
4919 we would end up at the start of the line ending at ZV. */ 5073 we would end up at the start of the line ending at ZV. */
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)
4927 move_it_by_lines (&it, -1, 1); 5081 move_it_by_lines (&it, -1, 1);
4928 } 5082 }
4929 else if (dy > 0) 5083 else if (dy > 0)
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)
4937 move_it_by_lines (&it, 1, 1); 5091 move_it_by_lines (&it, 1, 1);
4938 } 5092 }
6656 6810
6657 if (!NILP (left_width)) 6811 if (!NILP (left_width))
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)
6665 || !EQ (w->right_fringe_width, right_width) 6819 || !EQ (w->right_fringe_width, right_width)
6666 || !EQ (w->fringes_outside_margins, outside_margins))) 6820 || !EQ (w->fringes_outside_margins, outside_margins)))
7290 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines, 7444 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines,
7291 doc: /* *Number of lines of continuity when scrolling by screenfuls. */); 7445 doc: /* *Number of lines of continuity when scrolling by screenfuls. */);
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",
7308 &Vscroll_preserve_screen_position, 7464 &Vscroll_preserve_screen_position,
7309 doc: /* *Controls if scroll commands move point to keep its screen line unchanged. 7465 doc: /* *Controls if scroll commands move point to keep its screen line unchanged.
7325 defsubr (&Sminibuffer_window); 7481 defsubr (&Sminibuffer_window);
7326 defsubr (&Swindow_minibuffer_p); 7482 defsubr (&Swindow_minibuffer_p);
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);
7333 defsubr (&Swindow_hscroll); 7490 defsubr (&Swindow_hscroll);
7334 defsubr (&Sset_window_hscroll); 7491 defsubr (&Sset_window_hscroll);