static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
-static Lisp_Object Qresize_root_window, Qresize_root_window_vertically;
+static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically;
static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
static Lisp_Object Qsafe, Qabove, Qbelow;
static Lisp_Object Qauto_buffer_name;
int (* fn) (struct window *, void *),
void *);
static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
-static int resize_window_check (struct window *, int);
-static void resize_window_apply (struct window *, int);
+static int window_resize_check (struct window *, int);
+static void window_resize_apply (struct window *, int);
static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
/* This is the window in which the terminal's cursor should
return select_window (window, norecord, 0);
}
\f
-DEFUN ("window-clone-number", Fwindow_clone_number, Swindow_clone_number, 0, 1, 0,
- doc: /* Return WINDOW's clone number.
-WINDOW can be any window and defaults to the selected one. */)
- (Lisp_Object window)
-{
- return decode_any_window (window)->clone_number;
-}
-
DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0,
doc: /* Return the buffer that WINDOW is displaying.
WINDOW can be any window and defaults to the selected one.
return decode_any_window (window)->parent;
}
-DEFUN ("window-vchild", Fwindow_vchild, Swindow_vchild, 0, 1, 0,
- doc: /* Return WINDOW's first vertical child window.
+DEFUN ("window-top-child", Fwindow_top_child, Swindow_top_child, 0, 1, 0,
+ doc: /* Return WINDOW's topmost child window.
WINDOW can be any window and defaults to the selected one.
-Return nil if WINDOW has no vertical child. */)
+Return nil if WINDOW is not a vertical combination. */)
(Lisp_Object window)
{
return decode_any_window (window)->vchild;
}
-DEFUN ("window-hchild", Fwindow_hchild, Swindow_hchild, 0, 1, 0,
- doc: /* Return WINDOW's first horizontal child window.
+DEFUN ("window-left-child", Fwindow_left_child, Swindow_left_child, 0, 1, 0,
+ doc: /* Return WINDOW's leftmost child window.
WINDOW can be any window and defaults to the selected one.
-Return nil if WINDOW has no horizontal child. */)
+Return nil if WINDOW is not a horizontal combination. */)
(Lisp_Object window)
{
return decode_any_window (window)->hchild;
}
-DEFUN ("window-next", Fwindow_next, Swindow_next, 0, 1, 0,
- doc: /* Return WINDOW's right sibling window.
+DEFUN ("window-next-sibling", Fwindow_next_sibling, Swindow_next_sibling, 0, 1, 0,
+ doc: /* Return WINDOW's next sibling window.
WINDOW can be any window and defaults to the selected one.
-Return nil if WINDOW has no right sibling. */)
+Return nil if WINDOW has no next sibling. */)
(Lisp_Object window)
{
return decode_any_window (window)->next;
}
-DEFUN ("window-prev", Fwindow_prev, Swindow_prev, 0, 1, 0,
- doc: /* Return WINDOW's left sibling window.
+DEFUN ("window-prev-sibling", Fwindow_prev_sibling, Swindow_prev_sibling, 0, 1, 0,
+ doc: /* Return WINDOW's previous sibling window.
WINDOW can be any window and defaults to the selected one.
-Return nil if WINDOW has no left sibling. */)
+Return nil if WINDOW has no previous sibling. */)
(Lisp_Object window)
{
return decode_any_window (window)->prev;
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.
+If WINDOW is nil, the selected window is used.
Return NCOL. NCOL should be zero or positive.
Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
struct text_pos startp;
struct it it;
struct buffer *old_buffer = NULL;
+ void *itdata = NULL;
/* Cannot use Fvertical_motion because that function doesn't
cope with variable-height lines. */
else
SET_TEXT_POS_FROM_MARKER (startp, w->start);
+ itdata = bidi_shelve_cache ();
start_display (&it, w, startp);
move_it_vertically (&it, window_box_height (w));
if (it.current_y < it.last_visible_y)
move_it_past_eol (&it);
value = make_number (IT_CHARPOS (it));
+ bidi_unshelve_cache (itdata, 0);
if (old_buffer)
set_buffer_internal (old_buffer);
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.
-WINDOW defaults to the selected window. Return POS.
+If WINDOW is nil, the selected window is used. Return POS.
Optional third arg NOFORCE non-nil inhibits next redisplay from
overriding motion of point in order to display at this exact start. */)
(Lisp_Object window, Lisp_Object pos, Lisp_Object noforce)
window-point> triples where buffer was previously shown in WINDOW. */)
(Lisp_Object window, Lisp_Object prev_buffers)
{
- return decode_any_window (window)->prev_buffers = prev_buffers;
+ return decode_window (window)->prev_buffers = prev_buffers;
}
DEFUN ("window-next-buffers", Fwindow_next_buffers, Swindow_next_buffers,
recently re-shown in WINDOW. */)
(Lisp_Object window, Lisp_Object next_buffers)
{
- return decode_any_window (window)->next_buffers = next_buffers;
+ return decode_window (window)->next_buffers = next_buffers;
}
DEFUN ("window-parameters", Fwindow_parameters, Swindow_parameters,
}
}
}
+
+/* If WINDOW can be deleted, delete it. */
+static void
+delete_deletable_window (Lisp_Object window)
+{
+ if (!NILP (call1 (Qwindow_deletable_p, window)))
+ call1 (Qdelete_window, window);
+}
\f
/***********************************************************************
Window List
static Lisp_Object
resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore)
{
- return call4 (Qresize_root_window, window, delta, horizontal, ignore);
+ return call4 (Qwindow_resize_root_window, window, delta, horizontal, ignore);
}
XSETINT (delta, XINT (r->total_lines) - XINT (w->total_lines));
w->top_line = r->top_line;
resize_root_window (window, delta, Qnil, Qnil);
- if (resize_window_check (w, 0))
- resize_window_apply (w, 0);
+ if (window_resize_check (w, 0))
+ window_resize_apply (w, 0);
else
{
resize_root_window (window, delta, Qnil, Qt);
- if (resize_window_check (w, 0))
- resize_window_apply (w, 0);
+ if (window_resize_check (w, 0))
+ window_resize_apply (w, 0);
else
resize_failed = 1;
}
XSETINT (delta, XINT (r->total_cols) - XINT (w->total_cols));
w->left_col = r->left_col;
resize_root_window (window, delta, Qt, Qnil);
- if (resize_window_check (w, 1))
- resize_window_apply (w, 1);
+ if (window_resize_check (w, 1))
+ window_resize_apply (w, 1);
else
{
resize_root_window (window, delta, Qt, Qt);
- if (resize_window_check (w, 1))
- resize_window_apply (w, 1);
+ if (window_resize_check (w, 1))
+ window_resize_apply (w, 1);
else
resize_failed = 1;
}
unbind_to (count, Qnil);
}
-DEFUN ("set-window-clone-number", Fset_window_clone_number, Sset_window_clone_number, 2, 2, 0,
- doc: /* Set WINDOW's clone number to CLONE-NUMBER.
-WINDOW can be any window and defaults to the selected one. */)
- (Lisp_Object window, Lisp_Object clone_number)
-{
- register struct window *w = decode_any_window (window);
-
- CHECK_NUMBER (clone_number);
- w->clone_number = clone_number;
- return w->clone_number;
-}
-
DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0,
doc: /* Make WINDOW display BUFFER-OR-NAME as its contents.
WINDOW has to be a live window and defaults to the selected one.
call1 (Vtemp_buffer_show_function, buf);
else
{
- window = display_buffer (buf, Qnil, Qnil);
+ window = display_buffer (buf, Vtemp_buffer_show_specifiers, Qnil);
+ /* Reset Vtemp_buffer_show_specifiers immediately so it won't
+ affect subsequent calls. */
+ Vtemp_buffer_show_specifiers = Qnil;
if (!EQ (XWINDOW (window)->frame, selected_frame))
Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
++sequence_number;
XSETFASTINT (p->sequence_number, sequence_number);
- XSETFASTINT (p->clone_number, sequence_number);
replace_window (window, parent, 1);
XSETFASTINT (w->use_time, 0);
++sequence_number;
XSETFASTINT (w->sequence_number, sequence_number);
- XSETFASTINT (w->clone_number, sequence_number);
w->temslot = w->last_modified = w->last_overlay_modified = Qnil;
XSETFASTINT (w->last_point, 0);
w->last_had_star = w->vertical_scroll_bar = Qnil;
`window-min-height' or `window-min-width'. It does check that window
sizes do not drop below one line (two columns). */
static int
-resize_window_check (struct window *w, int horflag)
+window_resize_check (struct window *w, int horflag)
{
struct window *c;
while (c)
{
if ((XINT (c->new_total) != XINT (w->new_total))
- || !resize_window_check (c, horflag))
+ || !window_resize_check (c, horflag))
return 0;
c = NILP (c->next) ? 0 : XWINDOW (c->next);
}
int sum_of_sizes = 0;
while (c)
{
- if (!resize_window_check (c, horflag))
+ if (!window_resize_check (c, horflag))
return 0;
sum_of_sizes = sum_of_sizes + XINT (c->new_total);
c = NILP (c->next) ? 0 : XWINDOW (c->next);
int sum_of_sizes = 0;
while (c)
{
- if (!resize_window_check (c, horflag))
+ if (!window_resize_check (c, horflag))
return 0;
sum_of_sizes = sum_of_sizes + XINT (c->new_total);
c = NILP (c->next) ? 0 : XWINDOW (c->next);
while (c)
{
if ((XINT (c->new_total) != XINT (w->new_total))
- || !resize_window_check (c, horflag))
+ || !window_resize_check (c, horflag))
return 0;
c = NILP (c->next) ? 0 : XWINDOW (c->next);
}
each of these windows.
This function does not perform any error checks. Make sure you have
- run resize_window_check on W before applying this function. */
+ run window_resize_check on W before applying this function. */
static void
-resize_window_apply (struct window *w, int horflag)
+window_resize_apply (struct window *w, int horflag)
{
struct window *c;
int pos;
XSETFASTINT (c->left_col, pos);
else
XSETFASTINT (c->top_line, pos);
- resize_window_apply (c, horflag);
+ window_resize_apply (c, horflag);
if (!horflag)
pos = pos + XINT (c->total_lines);
c = NILP (c->next) ? 0 : XWINDOW (c->next);
XSETFASTINT (c->left_col, pos);
else
XSETFASTINT (c->top_line, pos);
- resize_window_apply (c, horflag);
+ window_resize_apply (c, horflag);
if (horflag)
pos = pos + XINT (c->total_cols);
c = NILP (c->next) ? 0 : XWINDOW (c->next);
}
-DEFUN ("resize-window-apply", Fresize_window_apply, Sresize_window_apply, 1, 2, 0,
+DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 1, 2, 0,
doc: /* Apply requested size values for window-tree of FRAME.
Optional argument HORIZONTAL omitted or nil means apply requested height
values. HORIZONTAL non-nil means apply requested width values.
f = XFRAME (frame);
r = XWINDOW (FRAME_ROOT_WINDOW (f));
- if (!resize_window_check (r, horflag)
+ if (!window_resize_check (r, horflag)
|| ! EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
return Qnil;
BLOCK_INPUT;
- resize_window_apply (r, horflag);
+ window_resize_apply (r, horflag);
windows_or_buffers_changed++;
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
XSETINT (delta, new_size - old_size);
/* Try a "normal" resize first. */
resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil);
- if (resize_window_check (r, horflag) && new_size == XINT (r->new_total))
- resize_window_apply (r, horflag);
+ if (window_resize_check (r, horflag) && new_size == XINT (r->new_total))
+ window_resize_apply (r, horflag);
else
{
/* Try with "reasonable" minimum sizes next. */
resize_root_window (root, delta, horflag ? Qt : Qnil, Qt);
- if (resize_window_check (r, horflag)
+ if (window_resize_check (r, horflag)
&& new_size == XINT (r->new_total))
- resize_window_apply (r, horflag);
+ window_resize_apply (r, horflag);
else
{
/* Finally, try with "safe" minimum sizes. */
resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe);
- if (resize_window_check (r, horflag)
+ if (window_resize_check (r, horflag)
&& new_size == XINT (r->new_total))
- resize_window_apply (r, horflag);
+ window_resize_apply (r, horflag);
else
{
/* We lost. Delete all windows but the frame's
XSETINT (p->new_total,
XINT (horflag ? p->total_cols : p->total_lines)
- XINT (total_size));
- if (!resize_window_check (p, horflag))
+ if (!window_resize_check (p, horflag))
error ("Window sizes don't fit");
else
/* Undo the temporary pretension. */
}
else
{
- if (!resize_window_check (o, horflag))
+ if (!window_resize_check (o, horflag))
error ("Resizing old window failed");
else if (XINT (total_size) + XINT (o->new_total)
!= XINT (horflag ? o->total_cols : o->total_lines))
n->total_cols = o->total_cols;
}
- /* Iso-coordinates and sizes are assigned by resize_window_apply,
+ /* Iso-coordinates and sizes are assigned by window_resize_apply,
get them ready here. */
n->new_total = total_size;
n->new_normal = normal_size;
BLOCK_INPUT;
- resize_window_apply (p, horflag);
+ window_resize_apply (p, horflag);
adjust_glyphs (f);
/* Set buffer of NEW to buffer of reference window. Don't run
any hooks. */
XWINDOW (s->next)->prev = sibling;
}
- if (resize_window_check (r, horflag)
+ if (window_resize_check (r, horflag)
&& EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
/* We can delete WINDOW now. */
{
/* Block input. */
BLOCK_INPUT;
- resize_window_apply (p, horflag);
+ window_resize_apply (p, horflag);
windows_or_buffers_changed++;
Vwindow_list = Qnil;
root = FRAME_ROOT_WINDOW (f);
r = XWINDOW (root);
- value = call2 (Qresize_root_window_vertically, root, make_number (- delta));
- if (INTEGERP (value) && resize_window_check (r, 0))
+ value = call2 (Qwindow_resize_root_window_vertically,
+ root, make_number (- delta));
+ if (INTEGERP (value) && window_resize_check (r, 0))
{
BLOCK_INPUT;
- resize_window_apply (r, 0);
+ window_resize_apply (r, 0);
/* Grow the mini-window. */
XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
{
root = FRAME_ROOT_WINDOW (f);
r = XWINDOW (root);
- value = call2 (Qresize_root_window_vertically,
+ value = call2 (Qwindow_resize_root_window_vertically,
root, make_number (size - 1));
- if (INTEGERP (value) && resize_window_check (r, 0))
+ if (INTEGERP (value) && window_resize_check (r, 0))
{
BLOCK_INPUT;
- resize_window_apply (r, 0);
+ window_resize_apply (r, 0);
/* Shrink the mini-window. */
XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
r = XWINDOW (FRAME_ROOT_WINDOW (f));
height = XINT (r->total_lines) + XINT (w->total_lines);
- if (resize_window_check (r, 0)
+ if (window_resize_check (r, 0)
&& XINT (w->new_total) > 0
&& height == XINT (r->new_total) + XINT (w->new_total))
{
BLOCK_INPUT;
- resize_window_apply (r, 0);
+ window_resize_apply (r, 0);
w->total_lines = w->new_total;
XSETFASTINT (w->top_line, XINT (r->top_line) + XINT (r->total_lines));
/* True if we fiddled the window vscroll field without really scrolling. */
int vscrolled = 0;
int x, y, rtop, rbot, rowh, vpos;
+ void *itdata = NULL;
SET_TEXT_POS_FROM_MARKER (start, w->start);
if (!pos_visible_p (w, PT, &x, &y, &rtop, &rbot, &rowh, &vpos))
{
+ itdata = bidi_shelve_cache ();
/* Move backward half the height of the window. Performance note:
vmotion used here is about 10% faster, but would give wrong
results for variable height lines. */
}
start = it.current.pos;
+ bidi_unshelve_cache (itdata, 0);
}
else if (auto_window_vscroll_p)
{
Fset_window_vscroll (window, make_number (0), Qt);
}
+ itdata = bidi_shelve_cache ();
/* If scroll_preserve_screen_position is non-nil, we try to set
point in the same window line as it is now, so get that line. */
if (!NILP (Vscroll_preserve_screen_position))
- it.current_y + it.max_ascent + it.max_descent);
adjust_glyphs (it.f);
}
- else if (noerror)
- return;
- else if (n < 0) /* could happen with empty buffers */
- xsignal0 (Qbeginning_of_buffer);
else
- xsignal0 (Qend_of_buffer);
+ {
+ bidi_unshelve_cache (itdata, 0);
+ if (noerror)
+ return;
+ else if (n < 0) /* could happen with empty buffers */
+ xsignal0 (Qbeginning_of_buffer);
+ else
+ xsignal0 (Qend_of_buffer);
+ }
}
else
{
/* The first line was only partially visible, make it fully
visible. */
w->vscroll = 0;
- else if (noerror)
- return;
else
- xsignal0 (Qbeginning_of_buffer);
+ {
+ bidi_unshelve_cache (itdata, 0);
+ if (noerror)
+ return;
+ else
+ xsignal0 (Qbeginning_of_buffer);
+ }
}
/* If control gets here, then we vscrolled. */
SET_PT_BOTH (charpos, bytepos);
}
}
+ bidi_unshelve_cache (itdata, 0);
}
if (pos < ZV)
{
- int this_scroll_margin = scroll_margin;
-
/* Don't use a scroll margin that is negative or too large. */
- if (this_scroll_margin < 0)
- this_scroll_margin = 0;
-
- if (XINT (w->total_lines) < 4 * scroll_margin)
- this_scroll_margin = XINT (w->total_lines) / 4;
+ int this_scroll_margin =
+ max (0, min (scroll_margin, XINT (w->total_lines) / 4));
set_marker_restricted_both (w->start, w->buffer, pos, pos_byte);
w->start_at_line_beg = bolp;
int height = window_box_height (w);
struct buffer *old_buffer;
int bottom_y;
+ void *itdata = NULL;
if (XBUFFER (w->buffer) != current_buffer)
{
else
SET_TEXT_POS_FROM_MARKER (start, w->start);
+ itdata = bidi_shelve_cache ();
start_display (&it, w, start);
move_it_vertically (&it, height);
bottom_y = line_bottom_y (&it);
+ bidi_unshelve_cache (itdata, 0);
/* rms: On a non-window display,
the value of it.vpos at the bottom of the screen
struct buffer *obuf = current_buffer;
int center_p = 0;
EMACS_INT charpos, bytepos;
- int iarg IF_LINT (= 0);
+ EMACS_INT iarg IF_LINT (= 0);
int this_scroll_margin;
/* If redisplay is suppressed due to an error, try again. */
&& (!EQ (Vrecenter_redisplay, Qtty)
|| !NILP (Ftty_type (selected_frame))))
{
- int i;
+ ptrdiff_t i;
/* Invalidate pixel data calculated for all compositions. */
for (i = 0; i < n_compositions; i++)
/* Do this after making BUF current
in case scroll_margin is buffer-local. */
- this_scroll_margin = max (0, scroll_margin);
- this_scroll_margin = min (this_scroll_margin,
- XFASTINT (w->total_lines) / 4);
+ this_scroll_margin =
+ max (0, min (scroll_margin, XFASTINT (w->total_lines) / 4));
/* Handle centering on a graphical frame specially. Such frames can
have variable-height lines and centering point on the basis of
{
struct it it;
struct text_pos pt;
+ void *itdata = bidi_shelve_cache ();
SET_TEXT_POS (pt, PT, PT_BYTE);
start_display (&it, w, pt);
move_it_vertically_backward (&it, window_box_height (w) / 2);
charpos = IT_CHARPOS (it);
bytepos = IT_BYTEPOS (it);
+ bidi_unshelve_cache (itdata, 0);
}
else if (iarg < 0)
{
struct it it;
struct text_pos pt;
- int nlines = -iarg;
+ int nlines = min (INT_MAX, -iarg);
int extra_line_spacing;
int h = window_box_height (w);
+ void *itdata = bidi_shelve_cache ();
iarg = - max (-iarg, this_scroll_margin);
h -= nlines * (FRAME_LINE_HEIGHT (it.f) + extra_line_spacing);
}
if (h <= 0)
- return Qnil;
+ {
+ bidi_unshelve_cache (itdata, 0);
+ return Qnil;
+ }
/* Now find the new top line (starting position) of the window. */
start_display (&it, w, pt);
charpos = IT_CHARPOS (it);
bytepos = IT_BYTEPOS (it);
+
+ bidi_unshelve_cache (itdata, 0);
}
else
{
lines = displayed_window_lines (w);
#if 0
- this_scroll_margin = max (0, scroll_margin);
- this_scroll_margin = min (this_scroll_margin, lines / 4);
+ this_scroll_margin = max (0, min (scroll_margin, lines / 4));
#endif
if (NILP (arg))
XSETFASTINT (arg, lines / 2);
else
{
- int iarg = XINT (Fprefix_numeric_value (arg));
+ EMACS_INT iarg = XINT (Fprefix_numeric_value (arg));
if (iarg < 0)
iarg = iarg + lines;
{
struct vectorlike_header header;
- Lisp_Object window, clone_number;
- Lisp_Object buffer, start, pointm, mark;
+ Lisp_Object window, buffer, start, pointm, mark;
Lisp_Object left_col, top_line, total_cols, total_lines;
Lisp_Object normal_cols, normal_lines;
Lisp_Object hscroll, min_hscroll;
struct Lisp_Vector *saved_windows;
Lisp_Object new_current_buffer;
Lisp_Object frame;
+ Lisp_Object auto_buffer_name;
FRAME_PTR f;
EMACS_INT old_point = -1;
However, there is other stuff we should still try to do below. */
if (FRAME_LIVE_P (f))
{
+ Lisp_Object window;
+ Lisp_Object dead_windows = Qnil;
register struct window *w;
register struct saved_window *p;
struct window *root_window;
struct window **leaf_windows;
int n_leaf_windows;
- int k, i, n;
+ ptrdiff_t k;
+ int i, n;
/* If the frame has been resized since this window configuration was
made, we change the frame to the size specified in the
for (k = 0; k < saved_windows->header.size; k++)
{
p = SAVED_WINDOW_N (saved_windows, k);
- w = XWINDOW (p->window);
+ window = p->window;
+ w = XWINDOW (window);
w->next = Qnil;
if (!NILP (p->parent))
}
}
- w->clone_number = p->clone_number;
/* If we squirreled away the buffer in the window's height,
restore it now. */
if (BUFFERP (w->total_lines))
/* Reinstall the saved buffer and pointers into it. */
if (NILP (p->buffer))
+ /* An internal window. */
w->buffer = p->buffer;
+ else if (!NILP (BVAR (XBUFFER (p->buffer), name)))
+ /* If saved buffer is alive, install it. */
+ {
+ w->buffer = p->buffer;
+ w->start_at_line_beg = p->start_at_line_beg;
+ set_marker_restricted (w->start, p->start, w->buffer);
+ set_marker_restricted (w->pointm, p->pointm, w->buffer);
+ Fset_marker (BVAR (XBUFFER (w->buffer), mark),
+ p->mark, w->buffer);
+
+ /* As documented in Fcurrent_window_configuration, don't
+ restore the location of point in the buffer which was
+ current when the window configuration was recorded. */
+ if (!EQ (p->buffer, new_current_buffer)
+ && XBUFFER (p->buffer) == current_buffer)
+ Fgoto_char (w->pointm);
+ }
+ else if (!NILP (w->buffer) && !NILP (BVAR (XBUFFER (w->buffer), name)))
+ /* Keep window's old buffer; make sure the markers are
+ real. */
+ {
+ /* Set window markers at start of visible range. */
+ if (XMARKER (w->start)->buffer == 0)
+ set_marker_restricted (w->start, make_number (0),
+ w->buffer);
+ if (XMARKER (w->pointm)->buffer == 0)
+ set_marker_restricted_both (w->pointm, w->buffer,
+ BUF_PT (XBUFFER (w->buffer)),
+ BUF_PT_BYTE (XBUFFER (w->buffer)));
+ w->start_at_line_beg = Qt;
+ }
+ else if (STRINGP (auto_buffer_name =
+ Fwindow_parameter (window, Qauto_buffer_name))
+ && SCHARS (auto_buffer_name) != 0
+ && !NILP (w->buffer = Fget_buffer_create (auto_buffer_name)))
+ {
+ set_marker_restricted (w->start, make_number (0), w->buffer);
+ set_marker_restricted (w->pointm, make_number (0), w->buffer);
+ w->start_at_line_beg = Qt;
+ }
else
+ /* Window has no live buffer, get one. */
{
- if (!NILP (BVAR (XBUFFER (p->buffer), name)))
- /* If saved buffer is alive, install it. */
- {
- w->buffer = p->buffer;
- w->start_at_line_beg = p->start_at_line_beg;
- set_marker_restricted (w->start, p->start, w->buffer);
- set_marker_restricted (w->pointm, p->pointm, w->buffer);
- Fset_marker (BVAR (XBUFFER (w->buffer), mark),
- p->mark, w->buffer);
-
- /* As documented in Fcurrent_window_configuration, don't
- restore the location of point in the buffer which was
- current when the window configuration was recorded. */
- if (!EQ (p->buffer, new_current_buffer)
- && XBUFFER (p->buffer) == current_buffer)
- Fgoto_char (w->pointm);
- }
- else if (NILP (w->buffer) || NILP (BVAR (XBUFFER (w->buffer), name)))
- /* Else unless window has a live buffer, get one. */
- {
- w->buffer = Fcdr (Fcar (Vbuffer_alist));
- /* This will set the markers to beginning of visible
- range. */
- set_marker_restricted (w->start, make_number (0), w->buffer);
- set_marker_restricted (w->pointm, make_number (0),w->buffer);
- w->start_at_line_beg = Qt;
- }
- else
- /* Keeping window's old buffer; make sure the markers
- are real. */
- {
- /* Set window markers at start of visible range. */
- if (XMARKER (w->start)->buffer == 0)
- set_marker_restricted (w->start, make_number (0),
- w->buffer);
- if (XMARKER (w->pointm)->buffer == 0)
- set_marker_restricted_both (w->pointm, w->buffer,
- BUF_PT (XBUFFER (w->buffer)),
- BUF_PT_BYTE (XBUFFER (w->buffer)));
- w->start_at_line_beg = Qt;
- }
+ /* Get the buffer via other_buffer_safely in order to
+ avoid showing an unimportant buffer and, if necessary, to
+ recreate *scratch* in the course (part of Juanma's bs-show
+ scenario from March 2011). */
+ w->buffer = other_buffer_safely (Fcurrent_buffer ());
+ /* This will set the markers to beginning of visible
+ range. */
+ set_marker_restricted (w->start, make_number (0), w->buffer);
+ set_marker_restricted (w->pointm, make_number (0), w->buffer);
+ w->start_at_line_beg = Qt;
+ if (!NILP (w->dedicated))
+ /* Record this window as dead. */
+ dead_windows = Fcons (window, dead_windows);
+ /* Make sure window is no more dedicated. */
+ w->dedicated = Qnil;
}
}
FRAME_ROOT_WINDOW (f) = data->root_window;
-
/* Arrange *not* to restore point in the buffer that was
current when the window configuration was saved. */
if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer))
make_number (old_point),
XWINDOW (data->current_window)->buffer);
- /* In the following call to `select-window, prevent "swapping
- out point" in the old selected window using the buffer that
- has been restored into it. We already swapped out that point
- from that window's old buffer. */
+ /* In the following call to `select-window', prevent "swapping out
+ point" in the old selected window using the buffer that has
+ been restored into it. We already swapped out that point from
+ that window's old buffer. */
select_window (data->current_window, Qnil, 1);
BVAR (XBUFFER (XWINDOW (selected_window)->buffer), last_selected_window)
= selected_window;
}
adjust_glyphs (f);
-
UNBLOCK_INPUT;
+ /* Scan dead buffer windows. */
+ for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
+ {
+ window = XCAR (dead_windows);
+ if (WINDOW_LIVE_P (window) && !EQ (window, FRAME_ROOT_WINDOW (f)))
+ delete_deletable_window (window);
+ }
+
/* Fselect_window will have made f the selected frame, so we
reselect the proper frame here. Fhandle_switch_frame will change the
selected window too, but that doesn't make the call to
XSETFASTINT (w->temslot, i); i++;
p->window = window;
- p->clone_number = w->clone_number;
p->buffer = w->buffer;
p->left_col = w->left_col;
p->top_line = w->top_line;
XSETWINDOW_CONFIGURATION (tem, data);
return (tem);
}
-
-\f
-/***********************************************************************
- Window Split Tree
- ***********************************************************************/
-
-static Lisp_Object
-window_tree (struct window *w)
-{
- Lisp_Object tail = Qnil;
- Lisp_Object result = Qnil;
-
- while (w)
- {
- Lisp_Object wn;
-
- XSETWINDOW (wn, w);
- if (!NILP (w->hchild))
- wn = Fcons (Qnil, Fcons (Fwindow_edges (wn),
- window_tree (XWINDOW (w->hchild))));
- else if (!NILP (w->vchild))
- wn = Fcons (Qt, Fcons (Fwindow_edges (wn),
- window_tree (XWINDOW (w->vchild))));
-
- if (NILP (result))
- {
- result = tail = Fcons (wn, Qnil);
- }
- else
- {
- XSETCDR (tail, Fcons (wn, Qnil));
- tail = XCDR (tail);
- }
-
- w = NILP (w->next) ? 0 : XWINDOW (w->next);
- }
-
- return result;
-}
-
-
-
-DEFUN ("window-tree", Fwindow_tree, Swindow_tree,
- 0, 1, 0,
- doc: /* Return the window tree for frame FRAME.
-
-The return value is a list of the form (ROOT MINI), where ROOT
-represents the window tree of the frame's root window, and MINI
-is the frame's minibuffer window.
-
-If the root window is not split, ROOT is the root window itself.
-Otherwise, ROOT is a list (DIR EDGES W1 W2 ...) where DIR is nil for a
-horizontal split, and t for a vertical split, EDGES gives the combined
-size and position of the subwindows in the split, and the rest of the
-elements are the subwindows in the split. Each of the subwindows may
-again be a window or a list representing a window split, and so on.
-EDGES is a list \(LEFT TOP RIGHT BOTTOM) as returned by `window-edges'.
-
-If FRAME is nil or omitted, return information on the currently
-selected frame. */)
- (Lisp_Object frame)
-{
- FRAME_PTR f;
-
- if (NILP (frame))
- frame = selected_frame;
-
- CHECK_FRAME (frame);
- f = XFRAME (frame);
-
- if (!FRAME_LIVE_P (f))
- return Qnil;
-
- return window_tree (XWINDOW (FRAME_ROOT_WINDOW (f)));
-}
-
\f
/***********************************************************************
Marginal Areas
Initialization
***********************************************************************/
-/* Return 1 if window configurations C1 and C2
- describe the same state of affairs. This is used by Fequal. */
+/* Return 1 if window configurations CONFIGURATION1 and CONFIGURATION2
+ describe the same state of affairs. This is used by Fequal.
+
+ ignore_positions non-zero means ignore non-matching scroll positions
+ and the like.
+
+ This ignores a couple of things like the dedicatedness status of
+ window, splits, nest and the like. This might have to be fixed. */
int
-compare_window_configurations (Lisp_Object c1, Lisp_Object c2, int ignore_positions)
+compare_window_configurations (Lisp_Object configuration1, Lisp_Object configuration2, int ignore_positions)
{
register struct save_window_data *d1, *d2;
- struct Lisp_Vector *sw1, *sw2;
- int i;
-
- CHECK_WINDOW_CONFIGURATION (c1);
- CHECK_WINDOW_CONFIGURATION (c2);
-
- d1 = (struct save_window_data *) XVECTOR (c1);
- d2 = (struct save_window_data *) XVECTOR (c2);
- sw1 = XVECTOR (d1->saved_windows);
- sw2 = XVECTOR (d2->saved_windows);
-
- if (d1->frame_cols != d2->frame_cols)
- return 0;
- if (d1->frame_lines != d2->frame_lines)
- return 0;
- if (d1->frame_menu_bar_lines != d2->frame_menu_bar_lines)
- return 0;
- if (! EQ (d1->selected_frame, d2->selected_frame))
- return 0;
- /* Don't compare the current_window field directly.
- Instead see w1_is_current and w2_is_current, below. */
- if (! EQ (d1->current_buffer, d2->current_buffer))
- return 0;
- if (! ignore_positions)
- {
- if (! EQ (d1->minibuf_scroll_window, d2->minibuf_scroll_window))
- return 0;
- if (! EQ (d1->minibuf_selected_window, d2->minibuf_selected_window))
- return 0;
- }
- /* Don't compare the root_window field.
- We don't require the two configurations
- to use the same window object,
- and the two root windows must be equivalent
- if everything else compares equal. */
- if (! EQ (d1->focus_frame, d2->focus_frame))
+ struct Lisp_Vector *sws1, *sws2;
+ ptrdiff_t i;
+
+ CHECK_WINDOW_CONFIGURATION (configuration1);
+ CHECK_WINDOW_CONFIGURATION (configuration2);
+
+ d1 = (struct save_window_data *) XVECTOR (configuration1);
+ d2 = (struct save_window_data *) XVECTOR (configuration2);
+ sws1 = XVECTOR (d1->saved_windows);
+ sws2 = XVECTOR (d2->saved_windows);
+
+ /* Frame settings must match. */
+ if (d1->frame_cols != d2->frame_cols
+ || d1->frame_lines != d2->frame_lines
+ || d1->frame_menu_bar_lines != d2->frame_menu_bar_lines
+ || !EQ (d1->selected_frame, d2->selected_frame)
+ || !EQ (d1->current_buffer, d2->current_buffer)
+ || (!ignore_positions
+ && (!EQ (d1->minibuf_scroll_window, d2->minibuf_scroll_window)
+ || !EQ (d1->minibuf_selected_window, d2->minibuf_selected_window)))
+ || !EQ (d1->focus_frame, d2->focus_frame)
+ /* Verify that the two configurations have the same number of windows. */
+ || sws1->header.size != sws2->header.size)
return 0;
- /* Verify that the two confis have the same number of windows. */
- if (sw1->header.size != sw2->header.size)
- return 0;
-
- for (i = 0; i < sw1->header.size; i++)
- {
- struct saved_window *p1, *p2;
- int w1_is_current, w2_is_current;
-
- p1 = SAVED_WINDOW_N (sw1, i);
- p2 = SAVED_WINDOW_N (sw2, i);
-
- /* Verify that the current windows in the two
- configurations correspond to each other. */
- w1_is_current = EQ (d1->current_window, p1->window);
- w2_is_current = EQ (d2->current_window, p2->window);
-
- if (w1_is_current != w2_is_current)
- return 0;
-
- /* Verify that the corresponding windows do match. */
- if (! EQ (p1->buffer, p2->buffer))
- return 0;
- if (! EQ (p1->left_col, p2->left_col))
- return 0;
- if (! EQ (p1->top_line, p2->top_line))
- return 0;
- if (! EQ (p1->total_cols, p2->total_cols))
- return 0;
- if (! EQ (p1->total_lines, p2->total_lines))
- return 0;
- if (! EQ (p1->display_table, p2->display_table))
- return 0;
- if (! EQ (p1->parent, p2->parent))
- return 0;
- if (! EQ (p1->prev, p2->prev))
- return 0;
- if (! ignore_positions)
- {
- if (! EQ (p1->hscroll, p2->hscroll))
- return 0;
- if (!EQ (p1->min_hscroll, p2->min_hscroll))
- return 0;
- if (! EQ (p1->start_at_line_beg, p2->start_at_line_beg))
- return 0;
- if (NILP (Fequal (p1->start, p2->start)))
- return 0;
- if (NILP (Fequal (p1->pointm, p2->pointm)))
- return 0;
- if (NILP (Fequal (p1->mark, p2->mark)))
- return 0;
- }
- if (! EQ (p1->left_margin_cols, p2->left_margin_cols))
- return 0;
- if (! EQ (p1->right_margin_cols, p2->right_margin_cols))
- return 0;
- if (! EQ (p1->left_fringe_width, p2->left_fringe_width))
- return 0;
- if (! EQ (p1->right_fringe_width, p2->right_fringe_width))
- return 0;
- if (! EQ (p1->fringes_outside_margins, p2->fringes_outside_margins))
- return 0;
- if (! EQ (p1->scroll_bar_width, p2->scroll_bar_width))
- return 0;
- if (! EQ (p1->vertical_scroll_bar_type, p2->vertical_scroll_bar_type))
+ for (i = 0; i < sws1->header.size; i++)
+ {
+ struct saved_window *sw1, *sw2;
+
+ sw1 = SAVED_WINDOW_N (sws1, i);
+ sw2 = SAVED_WINDOW_N (sws2, i);
+
+ if (
+ /* The "current" windows in the two configurations must
+ correspond to each other. */
+ EQ (d1->current_window, sw1->window)
+ != EQ (d2->current_window, sw2->window)
+ /* Windows' buffers must match. */
+ || !EQ (sw1->buffer, sw2->buffer)
+ || !EQ (sw1->left_col, sw2->left_col)
+ || !EQ (sw1->top_line, sw2->top_line)
+ || !EQ (sw1->total_cols, sw2->total_cols)
+ || !EQ (sw1->total_lines, sw2->total_lines)
+ || !EQ (sw1->display_table, sw2->display_table)
+ /* The next two disjuncts check the window structure for
+ equality. */
+ || !EQ (sw1->parent, sw2->parent)
+ || !EQ (sw1->prev, sw2->prev)
+ || (!ignore_positions
+ && (!EQ (sw1->hscroll, sw2->hscroll)
+ || !EQ (sw1->min_hscroll, sw2->min_hscroll)
+ || !EQ (sw1->start_at_line_beg, sw2->start_at_line_beg)
+ || NILP (Fequal (sw1->start, sw2->start))
+ || NILP (Fequal (sw1->pointm, sw2->pointm))
+ || NILP (Fequal (sw1->mark, sw2->mark))))
+ || !EQ (sw1->left_margin_cols, sw2->left_margin_cols)
+ || !EQ (sw1->right_margin_cols, sw2->right_margin_cols)
+ || !EQ (sw1->left_fringe_width, sw2->left_fringe_width)
+ || !EQ (sw1->right_fringe_width, sw2->right_fringe_width)
+ || !EQ (sw1->fringes_outside_margins, sw2->fringes_outside_margins)
+ || !EQ (sw1->scroll_bar_width, sw2->scroll_bar_width)
+ || !EQ (sw1->vertical_scroll_bar_type, sw2->vertical_scroll_bar_type))
return 0;
}
void
syms_of_window (void)
{
- Qscroll_up = intern_c_string ("scroll-up");
- staticpro (&Qscroll_up);
-
- Qscroll_down = intern_c_string ("scroll-down");
- staticpro (&Qscroll_down);
-
- Qscroll_command = intern_c_string ("scroll-command");
- staticpro (&Qscroll_command);
+ DEFSYM (Qscroll_up, "scroll-up");
+ DEFSYM (Qscroll_down, "scroll-down");
+ DEFSYM (Qscroll_command, "scroll-command");
Fput (Qscroll_up, Qscroll_command, Qt);
Fput (Qscroll_down, Qscroll_command, Qt);
- staticpro (&Qwindow_configuration_change_hook);
- Qwindow_configuration_change_hook
- = intern_c_string ("window-configuration-change-hook");
-
- Qwindowp = intern_c_string ("windowp");
- staticpro (&Qwindowp);
-
- Qwindow_configuration_p = intern_c_string ("window-configuration-p");
- staticpro (&Qwindow_configuration_p);
-
- Qwindow_live_p = intern_c_string ("window-live-p");
- staticpro (&Qwindow_live_p);
-
- Qwindow_deletable_p = intern_c_string ("window-deletable-p");
- staticpro (&Qwindow_deletable_p);
-
- Qdelete_window = intern_c_string ("delete-window");
- staticpro (&Qdelete_window);
-
- Qresize_root_window = intern_c_string ("resize-root-window");
- staticpro (&Qresize_root_window);
-
- Qresize_root_window_vertically = intern_c_string ("resize-root-window-vertically");
- staticpro (&Qresize_root_window_vertically);
-
- Qsafe = intern_c_string ("safe");
- staticpro (&Qsafe);
-
- Qdisplay_buffer = intern_c_string ("display-buffer");
- staticpro (&Qdisplay_buffer);
-
- Qreplace_buffer_in_windows = intern_c_string ("replace-buffer-in-windows");
- staticpro (&Qreplace_buffer_in_windows);
-
- Qrecord_window_buffer = intern_c_string ("record-window-buffer");
- staticpro (&Qrecord_window_buffer);
-
- Qget_mru_window = intern_c_string ("get-mru-window");
- staticpro (&Qget_mru_window);
-
- Qtemp_buffer_show_hook = intern_c_string ("temp-buffer-show-hook");
- staticpro (&Qtemp_buffer_show_hook);
-
- Qabove = intern_c_string ("above");
- staticpro (&Qabove);
-
- Qbelow = intern_c_string ("below");
- staticpro (&Qbelow);
-
- Qauto_buffer_name = intern_c_string ("auto-buffer-name");
- staticpro (&Qauto_buffer_name);
+ DEFSYM (Qwindow_configuration_change_hook, "window-configuration-change-hook");
+ DEFSYM (Qwindowp, "windowp");
+ DEFSYM (Qwindow_configuration_p, "window-configuration-p");
+ DEFSYM (Qwindow_live_p, "window-live-p");
+ DEFSYM (Qwindow_deletable_p, "window-deletable-p");
+ DEFSYM (Qdelete_window, "delete-window");
+ DEFSYM (Qwindow_resize_root_window, "window--resize-root-window");
+ DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically");
+ DEFSYM (Qsafe, "safe");
+ DEFSYM (Qdisplay_buffer, "display-buffer");
+ DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows");
+ DEFSYM (Qrecord_window_buffer, "record-window-buffer");
+ DEFSYM (Qget_mru_window, "get-mru-window");
+ DEFSYM (Qtemp_buffer_show_hook, "temp-buffer-show-hook");
+ DEFSYM (Qabove, "above");
+ DEFSYM (Qbelow, "below");
+ DEFSYM (Qauto_buffer_name, "auto-buffer-name");
staticpro (&Vwindow_list);
the buffer; `temp-buffer-show-hook' is not run unless this function runs it. */);
Vtemp_buffer_show_function = Qnil;
+ DEFVAR_LISP ("temp-buffer-show-specifiers", Vtemp_buffer_show_specifiers,
+ doc: /* Buffer display specifiers used by `with-output-to-temp-buffer'.
+These specifiers are passed by `with-output-to-temp-buffer' as second
+argument to `display-buffer'. Applications should only let-bind this
+around a call to `with-output-to-temp-buffer'.
+
+For a description of buffer display specifiers see the variable
+`display-buffer-alist'. */);
+ Vtemp_buffer_show_specifiers = Qnil;
+
DEFVAR_LISP ("minibuffer-scroll-window", Vminibuf_scroll_window,
doc: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */);
Vminibuf_scroll_window = Qnil;
Vother_window_scroll_buffer = Qnil;
DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p,
- doc: /* *Non-nil means to automatically adjust `window-vscroll' to view tall lines. */);
+ doc: /* Non-nil means to automatically adjust `window-vscroll' to view tall lines. */);
auto_window_vscroll_p = 1;
DEFVAR_INT ("next-screen-context-lines", next_screen_context_lines,
- doc: /* *Number of lines of continuity when scrolling by screenfuls. */);
+ doc: /* Number of lines of continuity when scrolling by screenfuls. */);
next_screen_context_lines = 2;
DEFVAR_LISP ("scroll-preserve-screen-position",
Vscroll_preserve_screen_position,
- doc: /* *Controls if scroll commands move point to keep its screen position unchanged.
+ doc: /* Controls if scroll commands move point to keep its screen position unchanged.
A value of nil means point does not keep its screen position except
at the scroll margin or window boundary respectively.
A value of t means point keeps its screen position if the scroll
defsubr (&Sset_frame_selected_window);
defsubr (&Spos_visible_in_window_p);
defsubr (&Swindow_line_height);
- defsubr (&Swindow_clone_number);
defsubr (&Swindow_buffer);
defsubr (&Swindow_parent);
- defsubr (&Swindow_vchild);
- defsubr (&Swindow_hchild);
- defsubr (&Swindow_next);
- defsubr (&Swindow_prev);
+ defsubr (&Swindow_top_child);
+ defsubr (&Swindow_left_child);
+ defsubr (&Swindow_next_sibling);
+ defsubr (&Swindow_prev_sibling);
defsubr (&Swindow_splits);
defsubr (&Sset_window_splits);
defsubr (&Swindow_nest);
defsubr (&Swindow_new_normal);
defsubr (&Sset_window_new_total);
defsubr (&Sset_window_new_normal);
- defsubr (&Sresize_window_apply);
+ defsubr (&Swindow_resize_apply);
defsubr (&Swindow_body_size);
defsubr (&Swindow_hscroll);
defsubr (&Sset_window_hscroll);
defsubr (&Sdelete_window_internal);
defsubr (&Sresize_mini_window_internal);
defsubr (&Sset_window_buffer);
- defsubr (&Sset_window_clone_number);
defsubr (&Srun_window_configuration_change_hook);
defsubr (&Sselect_window);
defsubr (&Sforce_window_update);
defsubr (&Swindow_configuration_frame);
defsubr (&Sset_window_configuration);
defsubr (&Scurrent_window_configuration);
- defsubr (&Swindow_tree);
defsubr (&Sset_window_margins);
defsubr (&Swindow_margins);
defsubr (&Sset_window_fringes);