/* Window creation, deletion and examination for GNU Emacs.
Does not include redisplay.
- Copyright (C) 1985,86,87,93,94,95,96,97,1998,2000, 2001, 2002, 2003
+ Copyright (C) 1985,86,87, 1993,94,95,96,97,98, 2000,01,02,03,04
Free Software Foundation, Inc.
This file is part of GNU Emacs.
bzero (&p->last_cursor, sizeof (p->last_cursor));
bzero (&p->phys_cursor, sizeof (p->phys_cursor));
p->desired_matrix = p->current_matrix = 0;
+ p->nrows_scale_factor = p->ncols_scale_factor = 1;
p->phys_cursor_type = -1;
p->phys_cursor_width = -1;
p->must_be_updated_p = 0;
p->fringes_outside_margins = Qnil;
p->scroll_bar_width = Qnil;
p->vertical_scroll_bar_type = Qt;
+ p->overlay_arrow_bitmap = 0;
Vwindow_list = Qnil;
return val;
}
DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, Swindow_minibuffer_p, 0, 1, 0,
- doc: /* Returns non-nil if WINDOW is a minibuffer window. */)
+ doc: /* Returns non-nil if WINDOW is a minibuffer window.
+WINDOW defaults to the selected window. */)
(window)
Lisp_Object window;
{
DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p,
Spos_visible_in_window_p, 0, 3, 0,
- doc: /* Return t if position POS is currently on the frame in WINDOW.
+ doc: /* Return non-nil if position POS is currently on the frame in WINDOW.
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.
-POS defaults to point in WINDOW; WINDOW defaults to the selected window. */)
+If POS is only out of view because of horizontal scrolling, return non-nil.
+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 FULLY) where X and Y are the pixel coordinates
+relative to the top left corner of the window, and FULLY is t if the
+character after POS is fully visible and nil otherwise. */)
(pos, window, partially)
Lisp_Object pos, window, partially;
{
register int posint;
register struct buffer *buf;
struct text_pos top;
- Lisp_Object in_window;
- int fully_p;
+ Lisp_Object in_window = Qnil;
+ int fully_p = 1;
+ int x, y;
w = decode_window (window);
buf = XBUFFER (w->buffer);
else
posint = XMARKER (w->pointm)->charpos;
- /* If position is above window start, it's not visible. */
- if (posint < CHARPOS (top))
- in_window = Qnil;
- else if (XFASTINT (w->last_modified) >= BUF_MODIFF (buf)
- && XFASTINT (w->last_overlay_modified) >= BUF_OVERLAY_MODIFF (buf)
- && posint < BUF_Z (buf) - XFASTINT (w->window_end_pos))
- {
- /* If frame is up-to-date, and POSINT is < window end pos, use
- that info. This doesn't work for POSINT == end pos, because
- the window end pos is actually the position _after_ the last
- char in the window. */
- if (NILP (partially))
- {
- pos_visible_p (w, posint, &fully_p, NILP (partially));
- in_window = fully_p ? Qt : Qnil;
- }
- else
- in_window = Qt;
- }
- else if (posint > BUF_ZV (buf))
- in_window = Qnil;
- else if (CHARPOS (top) < BUF_BEGV (buf) || CHARPOS (top) > BUF_ZV (buf))
- /* If window start is out of range, do something reasonable. */
- in_window = Qnil;
- else
- {
- if (pos_visible_p (w, posint, &fully_p, NILP (partially)))
- in_window = !NILP (partially) || fully_p ? Qt : Qnil;
- else
- in_window = Qnil;
- }
-
+ /* 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)
+ && CHARPOS (top) >= BUF_BEGV (buf)
+ && CHARPOS (top) <= BUF_ZV (buf)
+ && pos_visible_p (w, posint, &fully_p, &x, &y, NILP (partially))
+ && (!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 ? Qt : Qnil, Qnil)));
return in_window;
}
return XWINDOW (window);
}
+static struct window *
+decode_any_window (window)
+ register Lisp_Object window;
+{
+ if (NILP (window))
+ return XWINDOW (selected_window);
+
+ CHECK_WINDOW (window);
+ return XWINDOW (window);
+}
+
DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0,
- doc: /* Return the buffer that WINDOW is displaying. */)
+ doc: /* Return the buffer that WINDOW is displaying.
+WINDOW defaults to the selected window. */)
(window)
Lisp_Object window;
{
(window)
Lisp_Object window;
{
- return decode_window (window)->total_lines;
+ return decode_any_window (window)->total_lines;
}
DEFUN ("window-width", Fwindow_width, Swindow_width, 0, 1, 0,
(window)
Lisp_Object window;
{
- return make_number (window_box_text_cols (decode_window (window)));
+ return make_number (window_box_text_cols (decode_any_window (window)));
}
DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0,
doc: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
-NCOL should be zero or positive.
+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)
Lisp_Object window;
{
- register struct window *w = decode_window (window);
+ register struct window *w = decode_any_window (window);
return Fcons (make_number (WINDOW_LEFT_EDGE_COL (w)),
Fcons (make_number (WINDOW_TOP_EDGE_LINE (w)),
(window)
Lisp_Object window;
{
- register struct window *w = decode_window (window);
+ register struct window *w = decode_any_window (window);
return Fcons (make_number (WINDOW_LEFT_EDGE_X (w)),
Fcons (make_number (WINDOW_TOP_EDGE_Y (w)),
(window)
Lisp_Object window;
{
- register struct window *w = decode_window (window);
+ register struct window *w = decode_any_window (window);
return list4 (make_number (WINDOW_BOX_LEFT_EDGE_COL (w)
+ WINDOW_LEFT_MARGIN_COLS (w)
}
DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges, Swindow_inside_pixel_edges, 0, 1, 0,
- doc: /* Return a list of the edge coordinates of WINDOW.
+ doc: /* Return a list of the edge pixel coordinates of WINDOW.
\(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.
RIGHT is one more than the rightmost x position used by text in WINDOW,
and BOTTOM is one more than the bottommost y position used by text in WINDOW.
(window)
Lisp_Object window;
{
- register struct window *w = decode_window (window);
+ register struct window *w = decode_any_window (window);
return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w)
+ WINDOW_LEFT_MARGIN_WIDTH (w)
if it is on the window's modeline, return ON_MODE_LINE;
if it is on the border between the window and its right sibling,
return ON_VERTICAL_BORDER.
+ if it is on a scroll bar,
+ return ON_SCROLL_BAR.
if it is on the window's top line, return ON_HEADER_LINE;
if it is in left or right fringe of the window,
return ON_LEFT_FRINGE or ON_RIGHT_FRINGE, and convert *X and *Y
scroll bars. */
if (WINDOW_WANTS_MODELINE_P (w)
- && *y >= bottom_y - CURRENT_MODE_LINE_HEIGHT (w)
- && *y < bottom_y)
+ && *y >= bottom_y - CURRENT_MODE_LINE_HEIGHT (w))
{
part = ON_MODE_LINE;
}
if (WINDOW_WANTS_HEADER_LINE_P (w)
- && *y >= top_y
&& *y < top_y + CURRENT_HEADER_LINE_HEIGHT (w))
{
part = ON_HEADER_LINE;
/* Outside any interesting column? */
if (*x < left_x || *x > right_x)
- return ON_NOTHING;
+ return ON_SCROLL_BAR;
lmargin_width = window_box_width (w, LEFT_MARGIN_AREA);
rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA);
? (*x >= left_x + WINDOW_LEFT_FRINGE_WIDTH (w))
: (*x < left_x + lmargin_width)))
{
- *x -= x0;
+ *x -= left_x;
if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
*x -= WINDOW_LEFT_FRINGE_WIDTH (w);
*y -= top_y;
int x, y;
Lisp_Object lx, ly;
- CHECK_LIVE_WINDOW (window);
+ CHECK_WINDOW (window);
w = XWINDOW (window);
f = XFRAME (w->frame);
CHECK_CONS (coordinates);
ly = Fcdr (coordinates);
CHECK_NUMBER_OR_FLOAT (lx);
CHECK_NUMBER_OR_FLOAT (ly);
- x = FRAME_PIXEL_X_FROM_CANON_X (f, lx);
- y = FRAME_PIXEL_Y_FROM_CANON_Y (f, ly);
+ x = FRAME_PIXEL_X_FROM_CANON_X (f, lx) + FRAME_INTERNAL_BORDER_WIDTH (f);
+ y = FRAME_PIXEL_Y_FROM_CANON_Y (f, ly) + FRAME_INTERNAL_BORDER_WIDTH (f);
switch (coordinates_in_window (w, &x, &y))
{
case ON_RIGHT_MARGIN:
return Qright_margin;
+ case ON_SCROLL_BAR:
+ /* Historically we are supposed to return nil in this case. */
+ return Qnil;
+
default:
abort ();
}
CHECK_NUMBER_OR_FLOAT (y);
return window_from_coordinates (f,
- FRAME_PIXEL_X_FROM_CANON_X (f, x),
- FRAME_PIXEL_Y_FROM_CANON_Y (f, y),
+ (FRAME_PIXEL_X_FROM_CANON_X (f, x)
+ + FRAME_INTERNAL_BORDER_WIDTH (f)),
+ (FRAME_PIXEL_Y_FROM_CANON_Y (f, y)
+ + FRAME_INTERNAL_BORDER_WIDTH (f)),
0, 0, 0, 0);
}
This is updated by redisplay, when it runs to completion.
Simply changing the buffer text or setting `window-start'
does not update this value.
+Return nil if there is no recorded value. \(This can happen if the
+last redisplay of WINDOW was preempted, and did not finish.)
If UPDATE is non-nil, compute the up-to-date position
if it isn't already recorded. */)
(window, update)
}
DEFUN ("set-window-point", Fset_window_point, Sset_window_point, 2, 2, 0,
- doc: /* Make point value in WINDOW be at position POS in WINDOW's buffer. */)
+ doc: /* Make point value in WINDOW be at position POS in WINDOW's buffer.
+Return POS. */)
(window, pos)
Lisp_Object window, pos;
{
DEFUN ("set-window-start", Fset_window_start, Sset_window_start, 2, 3, 0,
doc: /* Make display in WINDOW start at position POS in WINDOW's buffer.
+Return POS.
Optional third arg NOFORCE non-nil inhibits next redisplay
from overriding motion of point in order to display at this exact start. */)
(window, pos, noforce)
doc: /* Select the ARG'th different window on this frame.
All windows on current frame are arranged in a cyclic order.
This command selects the window ARG steps away in that order.
-A negative ARG moves in the opposite order. If the optional second
-argument ALL_FRAMES is non-nil, cycle through all frames. */)
+A negative ARG moves in the opposite order. The optional second
+argument ALL_FRAMES has the same meaning as in `next-window', which see. */)
(arg, all_frames)
Lisp_Object arg, all_frames;
{
window_list_1 (window, minibuf, all_frames)
Lisp_Object window, minibuf, all_frames;
{
- Lisp_Object tail, list;
+ Lisp_Object tail, list, rest;
decode_next_window_args (&window, &minibuf, &all_frames);
list = Qnil;
if (candidate_window_p (XCAR (tail), window, minibuf, all_frames))
list = Fcons (XCAR (tail), list);
- return Fnreverse (list);
+ /* Rotate the list to start with WINDOW. */
+ list = Fnreverse (list);
+ rest = Fmemq (window, list);
+ if (!NILP (rest) && !EQ (rest, list))
+ {
+ for (tail = list; !EQ (XCDR (tail), rest); tail = XCDR (tail))
+ ;
+ XSETCDR (tail, Qnil);
+ list = nconc2 (rest, list);
+ }
+ return list;
}
DELETE_BUFFER_WINDOWS, /* Arg is buffer */
GET_LARGEST_WINDOW,
UNSHOW_BUFFER, /* Arg is buffer */
+ REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
CHECK_ALL_WINDOWS
};
}
break;
+ case REDISPLAY_BUFFER_WINDOWS:
+ if (EQ (w->buffer, obj))
+ {
+ mark_window_display_accurate (window, 0);
+ w->update_mode_line = Qt;
+ XBUFFER (obj)->prevent_redisplay_optimizations_p = 1;
+ ++update_mode_lines;
+ best_window = window;
+ }
+ break;
+
/* Check for a window that has a killed buffer. */
case CHECK_ALL_WINDOWS:
if (! NILP (w->buffer)
DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 1, 0,
doc: /* Return the window least recently selected or used for display.
+Return a full-width window if possible.
+A minibuffer window is never a candidate.
If optional argument FRAME is `visible', search all visible frames.
If FRAME is 0, search all visible and iconified frames.
If FRAME is t, search all frames.
DEFUN ("get-largest-window", Fget_largest_window, Sget_largest_window, 0, 1, 0,
doc: /* Return the largest window in area.
+A minibuffer window is never a candidate.
If optional argument FRAME is `visible', search all visible frames.
If FRAME is 0, search all visible and iconified frames.
If FRAME is t, search all frames.
DEFUN ("get-buffer-window", Fget_buffer_window, Sget_buffer_window, 1, 2, 0,
doc: /* Return a window currently displaying BUFFER, or nil if none.
+BUFFER can be a buffer or a buffer name.
If optional argument FRAME is `visible', search all visible frames.
If optional argument FRAME is 0, search all visible and iconified frames.
If FRAME is t, search all frames.
DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on,
1, 2, "bDelete windows on (buffer): ",
doc: /* Delete all windows showing BUFFER.
+BUFFER must be a buffer or the name of an existing buffer.
Optional second argument FRAME controls which frames are affected.
If optional argument FRAME is `visible', search all visible frames.
If FRAME is 0, search all visible and iconified frames.
DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows,
Sreplace_buffer_in_windows,
1, 1, "bReplace buffer in windows: ",
- doc: /* Replace BUFFER with some other buffer in all windows showing it. */)
+ doc: /* Replace BUFFER with some other buffer in all windows showing it.
+BUFFER may be a buffer or the name of an existing buffer. */)
(buffer)
Lisp_Object buffer;
{
return 1;
}
+/* Calculate new sizes for windows in the list FORWARD when the window size
+ goes from TOTAL to SIZE. TOTAL must be greater than SIZE.
+ The number of windows in FORWARD is NCHILDREN, and the number that
+ can shrink is SHRINKABLE.
+ The minimum size a window can have is MIN_SIZE.
+ If we are shrinking fixed windows, RESIZE_FIXED_P is non-zero.
+ If we are shrinking columns, WIDTH_P is non-zero, otherwise we are
+ shrinking rows.
+
+ This function returns an allocated array of new sizes that the caller
+ must free. The size -1 means the window is fixed and RESIZE_FIXED_P
+ is zero. Array index 0 refers to the first window in FORWARD, 1 to
+ the second, and so on.
+
+ This function tries to keep windows at least at the minimum size
+ and resize other windows before it resizes any window to zero (i.e.
+ delete that window).
+
+ Windows are resized proportional to their size, so bigger windows
+ shrink more than smaller windows. */
+static int *
+shrink_windows (total, size, nchildren, shrinkable,
+ min_size, resize_fixed_p, forward, width_p)
+ int total, size, nchildren, shrinkable, min_size;
+ int resize_fixed_p, width_p;
+ Lisp_Object forward;
+{
+ int available_resize = 0;
+ int *new_sizes;
+ struct window *c;
+ Lisp_Object child;
+ int smallest = total;
+ int total_removed = 0;
+ int total_shrink = total - size;
+ int i;
+
+ new_sizes = xmalloc (sizeof (*new_sizes) * nchildren);
+
+ for (i = 0, child = forward; !NILP (child); child = c->next, ++i)
+ {
+ int child_size;
+
+ c = XWINDOW (child);
+ child_size = width_p ? XINT (c->total_cols) : XINT (c->total_lines);
+
+ if (! resize_fixed_p && window_fixed_size_p (c, width_p, 0))
+ new_sizes[i] = -1;
+ else
+ {
+ new_sizes[i] = child_size;
+ if (child_size > min_size)
+ available_resize += child_size - min_size;
+ }
+ }
+ /* We might need to shrink some windows to zero. Find the smallest
+ windows and set them to 0 until we can fulfil the new size. */
+
+ while (shrinkable > 1 && size + available_resize < total)
+ {
+ for (i = 0; i < nchildren; ++i)
+ if (new_sizes[i] > 0 && smallest > new_sizes[i])
+ smallest = new_sizes[i];
+
+ for (i = 0; i < nchildren; ++i)
+ if (new_sizes[i] == smallest)
+ {
+ /* Resize this window down to zero. */
+ new_sizes[i] = 0;
+ if (smallest > min_size)
+ available_resize -= smallest - min_size;
+ available_resize += smallest;
+ --shrinkable;
+ total_removed += smallest;
+
+ /* Out of for, just remove one window at the time and
+ check again if we have enough space. */
+ break;
+ }
+ }
+
+ /* Now, calculate the new sizes. Try to shrink each window
+ proportional to its size. */
+ for (i = 0; i < nchildren; ++i)
+ {
+ if (new_sizes[i] > min_size)
+ {
+ int to_shrink = total_shrink*new_sizes[i]/total;
+ if (new_sizes[i] - to_shrink < min_size)
+ to_shrink = new_sizes[i] - min_size;
+ new_sizes[i] -= to_shrink;
+ total_removed += to_shrink;
+ }
+ }
+
+ /* Any reminder due to rounding, we just subtract from windows
+ that are left and still can be shrunk. */
+ while (total_shrink > total_removed)
+ {
+ for (i = 0; i < nchildren; ++i)
+ if (new_sizes[i] > min_size)
+ {
+ --new_sizes[i];
+ ++total_removed;
+
+ /* Out of for, just shrink one window at the time and
+ check again if we have enough space. */
+ break;
+ }
+ }
+
+ return new_sizes;
+}
/* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
WINDOW's width. Resize WINDOW's children, if any, so that they
int fixed_size, each, extra, n;
int resize_fixed_p, nfixed;
int last_pos, first_pos, nchildren, total;
+ int *new_sizes = NULL;
/* Determine the fixed-size portion of the this window, and the
number of child windows. */
windows. */
resize_fixed_p = nfixed == nchildren || size < fixed_size;
- /* Compute how many lines/columns to add to each child. The
+ /* Compute how many lines/columns to add/remove to each child. The
value of extra takes care of rounding errors. */
n = resize_fixed_p ? nchildren : nchildren - nfixed;
- each = (size - total) / n;
- extra = (size - total) - n * each;
+ if (size < total && n > 1)
+ new_sizes = shrink_windows (total, size, nchildren, n, min_size,
+ resize_fixed_p, *forward, width_p);
+ else
+ {
+ each = (size - total) / n;
+ extra = (size - total) - n * each;
+ }
/* Compute new children heights and edge positions. */
first_pos = width_p ? XINT (w->left_col) : XINT (w->top_line);
last_pos = first_pos;
- for (child = *forward; !NILP (child); child = c->next)
+ for (n = 0, child = *forward; !NILP (child); child = c->next, ++n)
{
int new_size, old_size;
/* If this child can be resized, do it. */
if (resize_fixed_p || !window_fixed_size_p (c, width_p, 0))
{
- new_size = old_size + each + extra;
+ new_size = new_sizes ? new_sizes[n] : old_size + each + extra;
extra = 0;
}
/* Remember the bottom/right edge position of this child; it
will be used to set the top/left edge of the next child. */
- last_pos += new_size;
+ last_pos += new_size;
}
+ if (new_sizes) xfree (new_sizes);
+
/* We should have covered the parent exactly with child windows. */
xassert (size == last_pos - first_pos);
/* This may call adjust_window_margins three times, so
temporarily disable window margins. */
+ Lisp_Object save_left = w->left_margin_cols;
+ Lisp_Object save_right = w->right_margin_cols;
+
w->left_margin_cols = w->right_margin_cols = Qnil;
Fset_window_fringes (window,
b->scroll_bar_width,
b->vertical_scroll_bar_type, Qnil);
+ w->left_margin_cols = save_left;
+ w->right_margin_cols = save_right;
+
Fset_window_margins (window,
b->left_margin_cols, b->right_margin_cols);
}
DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0,
doc: /* Make WINDOW display BUFFER as its contents.
-BUFFER can be a buffer or buffer name.
-Optional third arg KEEP_MARGINS non-nil means that WINDOW's current
+BUFFER can be a buffer or the name of an existing buffer.
+Optional third arg KEEP-MARGINS non-nil means that WINDOW's current
display margins, fringe widths, and scroll bar settings are maintained;
the default is to reset these from BUFFER's local settings or the frame
defaults. */)
DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
doc: /* Select WINDOW. Most editing will apply to WINDOW's buffer.
-If WINDOW is not already selected, also make WINDOW's buffer current.
-Also make WINDOW the frame's selected window.
+If WINDOW is not already selected, make WINDOW's buffer current
+and make WINDOW the frame's selected window. Return WINDOW.
Optional second arg NORECORD non-nil means
do not put this buffer at the front of the list of recently selected ones.
DEFUN ("display-buffer", Fdisplay_buffer, Sdisplay_buffer, 1, 3,
"BDisplay buffer: \nP",
doc: /* Make BUFFER appear in some window but don't select it.
-BUFFER can be a buffer or a buffer name.
+BUFFER must be the name of an existing buffer, or, when called from Lisp,
+a buffer.
If BUFFER is shown already in some window, just use that one,
unless the window is the selected window and the optional second
argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).
If `display-buffer-reuse-frames' is non-nil, and another frame is currently
displaying BUFFER, then simply raise that frame.
-The variables `special-display-buffer-names', `special-display-regexps',
-`same-window-buffer-names', and `same-window-regexps' customize how certain
-buffer names are handled.
+The variables `special-display-buffer-names',
+`special-display-regexps', `same-window-buffer-names', and
+`same-window-regexps' customize how certain buffer names are handled.
+The latter two take effect only if NOT-THIS-WINDOW is t.
If optional argument FRAME is `visible', search all visible frames.
If FRAME is 0, search all visible and iconified frames.
unless `pop-up-frames' or `display-buffer-reuse-frames' is non-nil,
which means search visible and iconified frames.
+If a full-width window on a splittable frame is available to display
+the buffer, it may be split, subject to the value of the variable
+`split-height-threshold'.
+
If `even-window-heights' is non-nil, window heights will be evened out
if displaying the buffer causes two vertically adjacent windows to be
displayed. */)
return display_buffer_1 (window);
}
+
+DEFUN ("force-window-update", Fforce_window_update, Sforce_window_update,
+ 0, 1, 0,
+ doc: /* Force redisplay of all windows.
+If optional arg OBJECT is a window, force redisplay of that window only.
+If OBJECT is a buffer or buffer name, force redisplay of all windows
+displaying that buffer. */)
+ (object)
+ Lisp_Object object;
+{
+ if (NILP (object))
+ {
+ windows_or_buffers_changed++;
+ update_mode_lines++;
+ return Qt;
+ }
+
+ if (WINDOWP (object))
+ {
+ struct window *w = XWINDOW (object);
+ mark_window_display_accurate (object, 0);
+ w->update_mode_line = Qt;
+ if (BUFFERP (w->buffer))
+ XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+ ++update_mode_lines;
+ return Qt;
+ }
+
+ if (STRINGP (object))
+ object = Fget_buffer (object);
+ if (BUFFERP (object) && !NILP (XBUFFER (object)->name))
+ {
+ /* Walk all windows looking for buffer, and force update
+ of each of those windows. */
+
+ object = window_loop (REDISPLAY_BUFFER_WINDOWS, object, 0, Qvisible);
+ return NILP (object) ? Qnil : Qt;
+ }
+
+ /* If nothing suitable was found, just return.
+ We could signal an error, but this feature will typically be used
+ asynchronously in timers or process sentinels, so we don't. */
+ return Qnil;
+}
+
+
void
temp_output_buffer_show (buf)
register Lisp_Object buf;
Lisp_Object prev_window, prev_buffer;
prev_window = selected_window;
XSETBUFFER (prev_buffer, old);
-
+
/* Select the window that was chosen, for running the hook.
Note: Both Fselect_window and select_window_norecord may
set-buffer to the buffer displayed in the window,
WINDOW defaults to selected one and SIZE to half its size.
If optional third arg HORFLAG is non-nil, split side by side
and put SIZE columns in the first of the pair. In that case,
-SIZE includes that window's scroll bar, or the divider column to its right. */)
+SIZE includes that window's scroll bar, or the divider column to its right.
+Interactively, all arguments are nil.
+
+Returns the newly created window (which is the lower or rightmost one).
+The upper or leftmost window is the original one and remains selected.
+See Info node `(elisp)Splitting Windows' for more details and examples.*/)
(window, size, horflag)
Lisp_Object window, size, horflag;
{
posit = *compute_motion (startpos, 0, 0, 0,
PT, ht, 0,
- window_box_text_cols (w), XINT (w->hscroll),
+ -1, XINT (w->hscroll),
0, w);
original_vpos = posit.vpos;
}
DEFUN ("scroll-up", Fscroll_up, Sscroll_up, 0, 1, "P",
- doc: /* Scroll text of current window upward ARG lines; or near full screen if no ARG.
+ doc: /* Scroll text of current window upward ARG lines.
+If ARG is omitted or nil, scroll upward by a near full screen.
A near full screen is `next-screen-context-lines' less than a full screen.
Negative ARG means scroll downward.
If ARG is the atom `-', scroll downward by nearly full screen.
}
DEFUN ("scroll-down", Fscroll_down, Sscroll_down, 0, 1, "P",
- doc: /* Scroll text of current window down ARG lines; or near full screen if no ARG.
+ doc: /* Scroll text of current window down ARG lines.
+If ARG is omitted or nil, scroll down by a near full screen.
A near full screen is `next-screen-context-lines' less than a full screen.
Negative ARG means scroll upward.
If ARG is the atom `-', scroll upward by nearly full screen.
\f
DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling, Sother_window_for_scrolling, 0, 0, 0,
doc: /* Return the other window for \"other window scroll\" commands.
-If in the minibuffer, `minibuffer-scroll-window' if non-nil
-specifies the window.
If `other-window-scroll-buffer' is non-nil, a window
-showing that buffer is used. */)
+showing that buffer is used.
+If in the minibuffer, `minibuffer-scroll-window' if non-nil
+specifies the window. This takes precedence over
+`other-window-scroll-buffer'. */)
()
{
Lisp_Object window;
If ARG is the atom `-', scroll downward by nearly full screen.
When calling from a program, supply as argument a number, nil, or `-'.
-If in the minibuffer, `minibuffer-scroll-window' if non-nil
-specifies the window to scroll.
If `other-window-scroll-buffer' is non-nil, scroll the window
-showing that buffer, popping the buffer up if necessary. */)
+showing that buffer, popping the buffer up if necessary.
+If in the minibuffer, `minibuffer-scroll-window' if non-nil
+specifies the window to scroll. This takes precedence over
+`other-window-scroll-buffer'. */)
(arg)
Lisp_Object arg;
{
DEFUN ("save-window-excursion", Fsave_window_excursion, Ssave_window_excursion,
0, UNEVALLED, 0,
- doc: /* Execute body, preserving window sizes and contents.
+ doc: /* Execute BODY, preserving window sizes and contents.
+Return the value of the last form in BODY.
Restore which buffer appears in which window, where display starts,
and the value of point and mark for each window.
Also restore the choice of selected window.
DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins,
2, 3, 0,
doc: /* Set width of marginal areas of window WINDOW.
-If window is nil, set margins of the currently selected window.
-First parameter LEFT-WIDTH specifies the number of character
-cells to reserve for the left marginal area. Second parameter
-RIGHT-WIDTH does the same for the right marginal area.
-A nil width parameter means no margin. */)
+If WINDOW is nil, set margins of the currently selected window.
+Second arg LEFT-WIDTH specifies the number of character cells to
+reserve for the left marginal area. Optional third arg RIGHT-WIDTH
+does the same for the right marginal area. A nil width parameter
+means no margin. */)
(window, left, right)
Lisp_Object window, left, right;
{
struct window *w = decode_window (window);
- /* TODO: It doesn't make sense to use FLOATs here, since
- the rest of the code assumes they are integers.
- So don't allow floats! ++KFS */
+ /* Translate negative or zero widths to nil.
+ Margins that are too wide have to be checked elsewhere. */
if (!NILP (left))
- CHECK_NUMBER_OR_FLOAT (left);
- if (!NILP (right))
- CHECK_NUMBER_OR_FLOAT (right);
+ {
+ CHECK_NUMBER (left);
+ if (XINT (left) <= 0)
+ left = Qnil;
+ }
- /* Check widths < 0 and translate a zero width to nil.
- Margins that are too wide have to be checked elsewhere. */
- if ((INTEGERP (left) && XINT (left) < 0)
- || (FLOATP (left) && XFLOAT_DATA (left) <= 0))
- XSETFASTINT (left, 0);
- if (INTEGERP (left) && XFASTINT (left) == 0)
- left = Qnil;
-
- if ((INTEGERP (right) && XINT (right) < 0)
- || (FLOATP (right) && XFLOAT_DATA (right) <= 0))
- XSETFASTINT (right, 0);
- if (INTEGERP (right) && XFASTINT (right) == 0)
- right = Qnil;
+ if (!NILP (right))
+ {
+ CHECK_NUMBER (right);
+ if (XINT (right) <= 0)
+ right = Qnil;
+ }
if (!EQ (w->left_margin_cols, left)
|| !EQ (w->right_margin_cols, right))
DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes,
2, 4, 0,
- doc: /* Set width of fringes of window WINDOW.
-
-If window is nil, set fringes of the currently selected window.
-Second parameter LEFT-WIDTH specifies the number of pixels to reserve
-for the left fringe. Third parameter RIGHT-WIDTH does the same for
-the right fringe. Fourth parameter OUTSIDE-MARGINS non-nil specifies
-that fringes are drawn outside of the display margins; by default, fringes
-are drawn between display marginal areas and the text area.
-A nil width parameter means to use the frame's corresponding fringe width. */)
+ doc: /* Set the fringe widths of window WINDOW.
+If WINDOW is nil, set the fringe widths of the currently selected
+window.
+Second arg LEFT-WIDTH specifies the number of pixels to reserve for
+the left fringe. Optional third arg RIGHT-WIDTH specifies the right
+fringe width. If a fringe width arg is nil, that means to use the
+frame's default fringe width. Default fringe widths can be set with
+the command `set-fringe-style'.
+If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes
+outside of the display margins. By default, fringes are drawn between
+display marginal areas and the text area. */)
(window, left, right, outside_margins)
Lisp_Object window, left, right, outside_margins;
{
0, 1, 0,
doc: /* Get width of fringes of window WINDOW.
If WINDOW is omitted or nil, use the currently selected window.
-Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS).
-If a window specific fringe width is not set, its width will be returned
-as nil. */)
+Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
(window)
Lisp_Object window;
{
this is automatically adjusted to a multiple of the frame column width.
Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
bar: left, right, or nil.
-A width of nil and type of t means to use the frame's corresponding value. */)
+If WIDTH is nil, use the frame's scroll-bar width.
+If TYPE is t, use the frame's scroll-bar type. */)
(window, width, vertical_type, horizontal_type)
Lisp_Object window, width, vertical_type, horizontal_type;
{
if (XINT (width) == 0)
vertical_type = Qnil;
+ if (!(EQ (vertical_type, Qnil)
+ || EQ (vertical_type, Qleft)
+ || EQ (vertical_type, Qright)
+ || EQ (vertical_type, Qt)))
+ error ("Invalid type of vertical scroll bar");
+
if (!EQ (w->scroll_bar_width, width)
|| !EQ (w->vertical_scroll_bar_type, vertical_type))
{
0, 1, 0,
doc: /* Get width and type of scroll bars of window WINDOW.
If WINDOW is omitted or nil, use the currently selected window.
-Value is a list of the form (WIDTH COLS VERTICAL-TYPE HORIZONTAL-TYPE). */)
+Value is a list of the form (WIDTH COLS VERTICAL-TYPE HORIZONTAL-TYPE).
+If WIDTH is nil or TYPE is t, the window is using the frame's corresponding
+value. */)
(window)
Lisp_Object window;
{
Smooth scrolling
***********************************************************************/
-DEFUN ("window-vscroll", Fwindow_vscroll, Swindow_vscroll, 0, 1, 0,
+DEFUN ("window-vscroll", Fwindow_vscroll, Swindow_vscroll, 0, 2, 0,
doc: /* Return the amount by which WINDOW is scrolled vertically.
Use the selected window if WINDOW is nil or omitted.
-Value is a multiple of the canonical character height of WINDOW. */)
- (window)
- Lisp_Object window;
+Normally, value is a multiple of the canonical character height of WINDOW;
+optional second arg PIXELS_P means value is measured in pixels. */)
+ (window, pixels_p)
+ Lisp_Object window, pixels_p;
{
Lisp_Object result;
struct frame *f;
f = XFRAME (w->frame);
if (FRAME_WINDOW_P (f))
- result = FRAME_CANON_Y_FROM_PIXEL_Y (f, -w->vscroll);
+ result = (NILP (pixels_p)
+ ? FRAME_CANON_Y_FROM_PIXEL_Y (f, -w->vscroll)
+ : make_number (-w->vscroll));
else
result = make_number (0);
return result;
DEFUN ("set-window-vscroll", Fset_window_vscroll, Sset_window_vscroll,
- 2, 2, 0,
+ 2, 3, 0,
doc: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL.
-WINDOW nil means use the selected window. VSCROLL is a non-negative
-multiple of the canonical character height of WINDOW. */)
- (window, vscroll)
- Lisp_Object window, vscroll;
+WINDOW nil means use the selected window. Normally, VSCROLL is a
+non-negative multiple of the canonical character height of WINDOW;
+optional third arg PIXELS_P non-nil means that VSCROLL is in pixels.
+If PIXELS-P is nil, VSCROLL may have to be rounded so that it
+corresponds to an integral number of pixels. The return value is the
+result of this rounding.
+If PIXELS-P is non-nil, the return value is VSCROLL. */)
+ (window, vscroll, pixels_p)
+ Lisp_Object window, vscroll, pixels_p;
{
struct window *w;
struct frame *f;
{
int old_dy = w->vscroll;
- w->vscroll = - FRAME_LINE_HEIGHT (f) * XFLOATINT (vscroll);
+ w->vscroll = - (NILP (pixels_p)
+ ? FRAME_LINE_HEIGHT (f) * XFLOATINT (vscroll)
+ : XFLOATINT (vscroll));
w->vscroll = min (w->vscroll, 0);
/* Adjust glyph matrix of the frame if the virtual display
XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
}
- return Fwindow_vscroll (window);
+ return Fwindow_vscroll (window, pixels_p);
}
\f
DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function,
doc: /* If non-nil, function to call to handle `display-buffer'.
It will receive two args, the buffer and a flag which if non-nil means
- that the currently selected window is not acceptable.
+that the currently selected window is not acceptable.
+It should choose or create a window, display the specified buffer in it,
+and return the window.
Commands such as `switch-to-buffer-other-window' and `find-file-other-window'
work using this function. */);
Vdisplay_buffer_function = Qnil;
An element of the list can be a list instead of just a string.
There are two ways to use a list as an element:
(BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)
-In the first case, FRAME-PARAMETERS are used to create the frame.
-In the latter case, FUNCTION is called with BUFFER as the first argument,
-followed by OTHER-ARGS--it can display BUFFER in any way it likes.
+In the first case, the FRAME-PARAMETERS are pairs of the form
+\(PARAMETER . VALUE); these parameter values are used to create the frame.
+In the second case, FUNCTION is called with BUFFER as the first argument,
+followed by the OTHER-ARGS--it can display BUFFER in any way it likes.
All this is done by the function found in `special-display-function'.
+If the specified frame parameters include (same-buffer . t), the
+buffer is displayed in the currently selected window. Otherwise, if
+they include (same-frame . t), the buffer is displayed in a new window
+in the currently selected frame.
+
If this variable appears \"not to work\", because you add a name to it
but that buffer still appears in the selected window, look at the
values of `same-window-buffer-names' and `same-window-regexps'.
An element of the list can be a list instead of just a string.
There are two ways to use a list as an element:
(REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)
-In the first case, FRAME-PARAMETERS are used to create the frame.
-In the latter case, FUNCTION is called with the buffer as first argument,
-followed by OTHER-ARGS--it can display the buffer in any way it likes.
+In the first case, the FRAME-PARAMETERS are pairs of the form
+\(PARAMETER . VALUE); these parameter values are used to create the frame.
+In the second case, FUNCTION is called with BUFFER as the first argument,
+followed by the OTHER-ARGS--it can display the buffer in any way it likes.
All this is done by the function found in `special-display-function'.
+If the specified frame parameters include (same-buffer . t), the
+buffer is displayed in the currently selected window. Otherwise, if
+they include (same-frame . t), the buffer is displayed in a new window
+in the currently selected frame.
+
If this variable appears \"not to work\", because you add a regexp to it
but the matching buffers still appear in the selected window, look at the
values of `same-window-buffer-names' and `same-window-regexps'.
next_screen_context_lines = 2;
DEFVAR_INT ("split-height-threshold", &split_height_threshold,
- doc: /* *display-buffer would prefer to split the largest window if this large.
+ doc: /* *A window must be at least this tall to be eligible for splitting by `display-buffer'.
If there is only one window, it is split regardless of this value. */);
split_height_threshold = 500;
DEFVAR_BOOL ("window-size-fixed", &window_size_fixed,
doc: /* Non-nil in a buffer means windows displaying the buffer are fixed-size.
+If the value is`height', then only the window's height is fixed.
+If the value is `width', then only the window's width is fixed.
+Any other non-nil value fixes both the width and the height.
Emacs won't change the size of any window displaying that buffer,
-unless you explicitly change the size, or Emacs has no other choice.
-This variable automatically becomes buffer-local when set. */);
+unless you explicitly change the size, or Emacs has no other choice. */);
Fmake_variable_buffer_local (Qwindow_size_fixed);
window_size_fixed = 0;
defsubr (&Sspecial_display_p);
defsubr (&Ssame_window_p);
defsubr (&Sdisplay_buffer);
+ defsubr (&Sforce_window_update);
defsubr (&Ssplit_window);
defsubr (&Senlarge_window);
defsubr (&Sshrink_window);