summaryrefslogtreecommitdiff
path: root/src/window.c
diff options
context:
space:
mode:
authorKaroly Lorentey <lorentey@elte.hu>2006-10-14 17:36:28 +0000
committerKaroly Lorentey <lorentey@elte.hu>2006-10-14 17:36:28 +0000
commit12b6af5c7ed2cfdb9783312bf890cf1e6c80c67a (patch)
tree1775f9fd1c92defd8b61304a08ec00da95bc4539 /src/window.c
parent3f87f67ee215ffeecbd2f53bd7f342cdf03f47df (diff)
parentf763da8d0808af7c80d72bc586bf4fcf50b37ddd (diff)
downloademacs-12b6af5c7ed2cfdb9783312bf890cf1e6c80c67a.tar.gz
emacs-12b6af5c7ed2cfdb9783312bf890cf1e6c80c67a.tar.bz2
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.c247
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.
If a character is only partially visible, nil is returned, unless the
optional argument PARTIALLY is non-nil.
If POS is only out of view because of horizontal scrolling, return non-nil.
+If POS is t, it specifies the position of the last visible glyph in WINDOW.
POS defaults to point in WINDOW; WINDOW defaults to the selected window.
If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
-return value is a list (X Y PARTIAL) where X and Y are the pixel coordinates
-relative to the top left corner of the window. PARTIAL is nil if the character
-after POS is fully visible; otherwise it is a cons (RTOP . RBOT) where RTOP
-and RBOT are the number of pixels invisible at the top and bottom of the row. */)
+return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
+where X and Y are the pixel coordinates relative to the top left corner
+of the window. The remaining elements are omitted if the character after
+POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
+off-window at the top and bottom of the row, ROWH is the height of the
+display row, and VPOS is the row number (0-based) containing POS. */)
(pos, window, partially)
Lisp_Object pos, window, partially;
{
@@ -350,14 +353,16 @@ and RBOT are the number of pixels invisible at the top and bottom of the row. *
register struct buffer *buf;
struct text_pos top;
Lisp_Object in_window = Qnil;
- int rtop, rbot, fully_p = 1;
+ int rtop, rbot, rowh, vpos, fully_p = 1;
int x, y;
w = decode_window (window);
buf = XBUFFER (w->buffer);
SET_TEXT_POS_FROM_MARKER (top, w->start);
- if (!NILP (pos))
+ if (EQ (pos, Qt))
+ posint = -1;
+ else if (!NILP (pos))
{
CHECK_NUMBER_COERCE_MARKER (pos);
posint = XINT (pos);
@@ -369,24 +374,138 @@ and RBOT are the number of pixels invisible at the top and bottom of the row. *
/* If position is above window start or outside buffer boundaries,
or if window start is out of range, position is not visible. */
- if (posint >= CHARPOS (top)
- && posint <= BUF_ZV (buf)
+ if ((EQ (pos, Qt)
+ || (posint >= CHARPOS (top) && posint <= BUF_ZV (buf)))
&& CHARPOS (top) >= BUF_BEGV (buf)
&& CHARPOS (top) <= BUF_ZV (buf)
- && pos_visible_p (w, posint, &x, &y, &rtop, &rbot, NILP (partially))
+ && pos_visible_p (w, posint, &x, &y, &rtop, &rbot, &rowh, &vpos)
&& (fully_p = !rtop && !rbot, (!NILP (partially) || fully_p)))
in_window = Qt;
if (!NILP (in_window) && !NILP (partially))
- in_window = Fcons (make_number (x),
- Fcons (make_number (y),
- Fcons ((fully_p ? Qnil
- : Fcons (make_number (rtop),
- make_number (rbot))),
- Qnil)));
+ {
+ Lisp_Object part = Qnil;
+ if (!fully_p)
+ part = list4 (make_number (rtop), make_number (rbot),
+ make_number (rowh), make_number (vpos));
+ in_window = Fcons (make_number (x),
+ Fcons (make_number (y), part));
+ }
+
return in_window;
}
+DEFUN ("window-line-height", Fwindow_line_height,
+ Swindow_line_height, 0, 2, 0,
+ doc: /* Return height in pixels of text line LINE in window WINDOW.
+If WINDOW is nil or omitted, use selected window.
+
+Return height of current line if LINE is omitted or nil. Return height of
+header or mode line if LINE is `header-line' and `mode-line'.
+Otherwise, LINE is a text line number starting from 0. A negative number
+counts from the end of the window.
+
+Value is a list (HEIGHT VPOS YPOS OFFBOT), where HEIGHT is the height
+in pixels of the visible part of the line, VPOS and YPOS are the
+vertical position in lines and pixels of the line, relative to the top
+of the first text line, and OFFBOT is the number of off-window pixels at
+the bottom of the text line. If there are off-window pixels at the top
+of the (first) text line, YPOS is negative.
+
+Return nil if window display is not up-to-date. In that case, use
+`pos-visible-in-window-p' to obtain the information. */)
+ (line, window)
+ Lisp_Object line, window;
+{
+ register struct window *w;
+ register struct buffer *b;
+ struct glyph_row *row, *end_row;
+ int max_y, crop, i, n;
+
+ w = decode_window (window);
+
+ if (noninteractive
+ || w->pseudo_window_p)
+ return Qnil;
+
+ CHECK_BUFFER (w->buffer);
+ b = XBUFFER (w->buffer);
+
+ /* Fail if current matrix is not up-to-date. */
+ if (NILP (w->window_end_valid)
+ || current_buffer->clip_changed
+ || current_buffer->prevent_redisplay_optimizations_p
+ || XFASTINT (w->last_modified) < BUF_MODIFF (b)
+ || XFASTINT (w->last_overlay_modified) < BUF_OVERLAY_MODIFF (b))
+ return Qnil;
+
+ if (NILP (line))
+ {
+ i = w->cursor.vpos;
+ if (i < 0 || i >= w->current_matrix->nrows
+ || (row = MATRIX_ROW (w->current_matrix, i), !row->enabled_p))
+ return Qnil;
+ max_y = window_text_bottom_y (w);
+ goto found_row;
+ }
+
+ if (EQ (line, Qheader_line))
+ {
+ if (!WINDOW_WANTS_HEADER_LINE_P (w))
+ return Qnil;
+ row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
+ if (!row->enabled_p)
+ return Qnil;
+ return list4 (make_number (row->height),
+ make_number (0), make_number (0),
+ make_number (0));
+ }
+
+ if (EQ (line, Qmode_line))
+ {
+ row = MATRIX_MODE_LINE_ROW (w->current_matrix);
+ if (!row->enabled_p)
+ return Qnil;
+ return list4 (make_number (row->height),
+ make_number (0), /* not accurate */
+ make_number (WINDOW_HEADER_LINE_HEIGHT (w)
+ + window_text_bottom_y (w)),
+ make_number (0));
+ }
+
+ CHECK_NUMBER (line);
+ n = XINT (line);
+
+ row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+ end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
+ max_y = window_text_bottom_y (w);
+ i = 0;
+
+ while ((n < 0 || i < n)
+ && row <= end_row && row->enabled_p
+ && row->y + row->height < max_y)
+ row++, i++;
+
+ if (row > end_row || !row->enabled_p)
+ return Qnil;
+
+ if (++n < 0)
+ {
+ if (-n > i)
+ return Qnil;
+ row += n;
+ i += n;
+ }
+
+ found_row:
+ crop = max (0, (row->y + row->height) - max_y);
+ return list4 (make_number (row->height + min (0, row->y) - crop),
+ make_number (i),
+ make_number (row->y),
+ make_number (crop));
+}
+
+
static struct window *
decode_window (window)
@@ -451,7 +570,7 @@ DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0,
Return NCOL. NCOL should be zero or positive.
Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
-window so that the location of point becomes invisible. */)
+window so that the location of point moves off-window. */)
(window, ncol)
Lisp_Object window, ncol;
{
@@ -1048,9 +1167,11 @@ if it isn't already recorded. */)
Lisp_Object value;
struct window *w = decode_window (window);
Lisp_Object buf;
+ struct buffer *b;
buf = w->buffer;
CHECK_BUFFER (buf);
+ b = XBUFFER (buf);
#if 0 /* This change broke some things. We should make it later. */
/* If we don't know the end position, return nil.
@@ -1063,12 +1184,20 @@ if it isn't already recorded. */)
if (! NILP (update)
&& ! (! NILP (w->window_end_valid)
- && XFASTINT (w->last_modified) >= MODIFF)
+ && XFASTINT (w->last_modified) >= BUF_MODIFF (b))
&& !noninteractive)
{
struct text_pos startp;
struct it it;
- struct buffer *old_buffer = NULL, *b = XBUFFER (buf);
+ struct buffer *old_buffer = NULL;
+
+ /* Cannot use Fvertical_motion because that function doesn't
+ cope with variable-height lines. */
+ if (b != current_buffer)
+ {
+ old_buffer = current_buffer;
+ set_buffer_internal (b);
+ }
/* In case W->start is out of the range, use something
reasonable. This situation occurred when loading a file with
@@ -1082,14 +1211,6 @@ if it isn't already recorded. */)
else
SET_TEXT_POS_FROM_MARKER (startp, w->start);
- /* Cannot use Fvertical_motion because that function doesn't
- cope with variable-height lines. */
- if (b != current_buffer)
- {
- old_buffer = current_buffer;
- set_buffer_internal (b);
- }
-
start_display (&it, w, startp);
move_it_vertically (&it, window_box_height (w));
if (it.current_y < it.last_visible_y)
@@ -1100,7 +1221,7 @@ if it isn't already recorded. */)
set_buffer_internal (old_buffer);
}
else
- XSETINT (value, BUF_Z (XBUFFER (buf)) - XFASTINT (w->window_end_pos));
+ XSETINT (value, BUF_Z (b) - XFASTINT (w->window_end_pos));
return value;
}
@@ -4820,10 +4941,10 @@ window_scroll_pixel_based (window, n, whole, noerror)
struct it it;
struct window *w = XWINDOW (window);
struct text_pos start;
- Lisp_Object tem;
int this_scroll_margin;
/* True if we fiddled the window vscroll field without really scrolling. */
int vscrolled = 0;
+ int x, y, rtop, rbot, rowh, vpos;
SET_TEXT_POS_FROM_MARKER (start, w->start);
@@ -4831,8 +4952,8 @@ window_scroll_pixel_based (window, n, whole, noerror)
the screen. Allow PT to be partially visible, otherwise
something like (scroll-down 1) with PT in the line before
the partially visible one would recenter. */
- tem = Fpos_visible_in_window_p (make_number (PT), window, Qt);
- if (NILP (tem))
+
+ if (!pos_visible_p (w, PT, &x, &y, &rtop, &rbot, &rowh, &vpos))
{
/* Move backward half the height of the window. Performance note:
vmotion used here is about 10% faster, but would give wrong
@@ -4857,7 +4978,7 @@ window_scroll_pixel_based (window, n, whole, noerror)
}
else if (auto_window_vscroll_p)
{
- if (tem = XCAR (XCDR (XCDR (tem))), CONSP (tem))
+ if (rtop || rbot) /* partially visible */
{
int px;
int dy = WINDOW_FRAME_LINE_HEIGHT (w);
@@ -4867,19 +4988,52 @@ window_scroll_pixel_based (window, n, whole, noerror)
dy);
dy *= n;
- if (n < 0 && (px = XINT (XCAR (tem))) > 0)
+ if (n < 0)
{
- px = max (0, -w->vscroll - min (px, -dy));
- Fset_window_vscroll (window, make_number (px), Qt);
- return;
+ /* Only vscroll backwards if already vscrolled forwards. */
+ if (w->vscroll < 0 && rtop > 0)
+ {
+ px = max (0, -w->vscroll - min (rtop, -dy));
+ Fset_window_vscroll (window, make_number (px), Qt);
+ return;
+ }
}
- if (n > 0 && (px = XINT (XCDR (tem))) > 0)
+ if (n > 0)
{
- px = max (0, -w->vscroll + min (px, dy));
- Fset_window_vscroll (window, make_number (px), Qt);
- return;
+ /* Do vscroll if already vscrolled or only display line. */
+ if (rbot > 0 && (w->vscroll < 0 || vpos == 0))
+ {
+ px = max (0, -w->vscroll + min (rbot, dy));
+ Fset_window_vscroll (window, make_number (px), Qt);
+ return;
+ }
+
+ /* Maybe modify window start instead of scrolling. */
+ if (rbot > 0 || w->vscroll < 0)
+ {
+ int spos;
+
+ Fset_window_vscroll (window, make_number (0), Qt);
+ /* If there are other text lines above the current row,
+ move window start to current row. Else to next row. */
+ if (rbot > 0)
+ spos = XINT (Fline_beginning_position (Qnil));
+ else
+ spos = min (XINT (Fline_end_position (Qnil)) + 1, ZV);
+ set_marker_restricted (w->start, make_number (spos),
+ w->buffer);
+ w->start_at_line_beg = Qt;
+ w->update_mode_line = Qt;
+ XSETFASTINT (w->last_modified, 0);
+ XSETFASTINT (w->last_overlay_modified, 0);
+ /* Set force_start so that redisplay_window will run the
+ window-scroll-functions. */
+ w->force_start = Qt;
+ return;
+ }
}
}
+ /* Cancel previous vscroll. */
Fset_window_vscroll (window, make_number (0), Qt);
}
@@ -4920,7 +5074,7 @@ window_scroll_pixel_based (window, n, whole, noerror)
if (dy <= 0)
{
move_it_vertically_backward (&it, -dy);
- /* Ensure we actually does move, e.g. in case we are currently
+ /* Ensure we actually do move, e.g. in case we are currently
looking at an image that is taller that the window height. */
while (start_pos == IT_CHARPOS (it)
&& start_pos > BEGV)
@@ -4930,7 +5084,7 @@ window_scroll_pixel_based (window, n, whole, noerror)
{
move_it_to (&it, ZV, -1, it.current_y + dy, -1,
MOVE_TO_POS | MOVE_TO_Y);
- /* Ensure we actually does move, e.g. in case we are currently
+ /* Ensure we actually do move, e.g. in case we are currently
looking at an image that is taller that the window height. */
while (start_pos == IT_CHARPOS (it)
&& start_pos < ZV)
@@ -6658,7 +6812,7 @@ display marginal areas and the text area. */)
CHECK_NATNUM (left_width);
if (!NILP (right_width))
CHECK_NATNUM (right_width);
-
+
/* Do nothing on a tty. */
if (FRAME_WINDOW_P (WINDOW_XFRAME (w))
&& (!EQ (w->left_fringe_width, left_width)
@@ -7292,16 +7446,18 @@ See also `same-window-buffer-names'. */);
next_screen_context_lines = 2;
DEFVAR_INT ("split-height-threshold", &split_height_threshold,
- doc: /* *A window must be at least this tall to be eligible for splitting by `display-buffer'.
+ doc: /* *A window must be at least this tall to be eligible for splitting
+by `display-buffer'. The value is in line units.
If there is only one window, it is split regardless of this value. */);
split_height_threshold = 500;
DEFVAR_INT ("window-min-height", &window_min_height,
- doc: /* *Delete any window less than this tall (including its mode line). */);
+ doc: /* *Delete any window less than this tall (including its mode line).
+The value is in line units. */);
window_min_height = 4;
DEFVAR_INT ("window-min-width", &window_min_width,
- doc: /* *Delete any window less than this wide. */);
+ doc: /* *Delete any window less than this wide (measured in characters). */);
window_min_width = 10;
DEFVAR_LISP ("scroll-preserve-screen-position",
@@ -7327,6 +7483,7 @@ The selected frame is the one whose configuration has changed. */);
defsubr (&Swindowp);
defsubr (&Swindow_live_p);
defsubr (&Spos_visible_in_window_p);
+ defsubr (&Swindow_line_height);
defsubr (&Swindow_buffer);
defsubr (&Swindow_height);
defsubr (&Swindow_width);