#include "nsterm.h"
#endif
-Lisp_Object Qwindowp, Qwindow_live_p, Qdelete_window;
+Lisp_Object Qwindowp, Qwindow_live_p;
static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
-static Lisp_Object Qwindow_deletable_p, Qdisplay_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 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
/* Hook to run when window config changes. */
static Lisp_Object Qwindow_configuration_change_hook;
-/* Incremented by 1 whenever a window is deleted. */
-static int window_deletion_count;
-
/* Used by the function window_scroll_pixel_based */
static int window_scroll_pixel_based_preserve_x;
static int window_scroll_pixel_based_preserve_y;
return selected_window;
}
+int window_select_count;
+
/* If select_window is called with inhibit_point_swap non-zero it will
not store point of the old selected window's buffer back into that
window's pointm slot. This is needed by Fset_window_configuration to
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)
}
/* If WINDOW can be deleted, delete it. */
-Lisp_Object
+static void
delete_deletable_window (Lisp_Object window)
{
if (!NILP (call1 (Qwindow_deletable_p, window)))
DEFUN ("next-window", Fnext_window, Snext_window, 0, 3, 0,
doc: /* Return window following WINDOW in cyclic ordering of windows.
-WINDOW defaults to the selected window. The optional arguments
-MINIBUF and ALL-FRAMES specify the set of windows to consider.
-
-MINIBUF t means consider the minibuffer window even if the
-minibuffer is not active. MINIBUF nil or omitted means consider
-the minibuffer window only if the minibuffer is active. Any
-other value means do not consider the minibuffer window even if
-the minibuffer is active.
-
-Several frames may share a single minibuffer; if the minibuffer
-is active, all windows on all frames that share that minibuffer
-are considered too. Therefore, if you are using a separate
-minibuffer frame and the minibuffer is active and MINIBUF says it
-counts, `next-window' considers the windows in the frame from
-which you entered the minibuffer, as well as the minibuffer
-window.
+WINDOW must be a live window and defaults to the selected one. The
+optional arguments MINIBUF and ALL-FRAMES specify the set of windows to
+consider.
+
+MINIBUF nil or omitted means consider the minibuffer window only if the
+minibuffer is active. MINIBUF t means consider the minibuffer window
+even if the minibuffer is not active. Any other value means do not
+consider the minibuffer window even if the minibuffer is active.
+
+ALL-FRAMES nil or omitted means consider all windows on WINDOW's frame,
+plus the minibuffer window if specified by the MINIBUF argument. If the
+minibuffer counts, consider all windows on all frames that share that
+minibuffer too. The following non-nil values of ALL-FRAMES have special
+meanings:
+
+- t means consider all windows on all existing frames.
+
+- `visible' means consider all windows on all visible frames.
+
+- 0 (the number zero) means consider all windows on all visible and
+ iconified frames.
+
+- A frame means consider all windows on that frame only.
-ALL-FRAMES nil or omitted means consider all windows on WINDOW's
- frame, plus the minibuffer window if specified by the MINIBUF
- argument, see above. If the minibuffer counts, consider all
- windows on all frames that share that minibuffer too.
-ALL-FRAMES t means consider all windows on all existing frames.
-ALL-FRAMES `visible' means consider all windows on all visible
- frames on the current terminal.
-ALL-FRAMES 0 means consider all windows on all visible and
- iconified frames on the current terminal.
-ALL-FRAMES a frame means consider all windows on that frame only.
Anything else means consider all windows on WINDOW's frame and no
- others.
+others.
If you use consistent values for MINIBUF and ALL-FRAMES, you can use
`next-window' to iterate through the entire cycle of acceptable
DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 3, 0,
doc: /* Return window preceding WINDOW in cyclic ordering of windows.
-WINDOW defaults to the selected window. The optional arguments
-MINIBUF and ALL-FRAMES specify the set of windows to consider.
-For the precise meaning of these arguments see `next-window'.
+WINDOW must be a live window and defaults to the selected one. The
+optional arguments MINIBUF and ALL-FRAMES specify the set of windows to
+consider.
+
+MINIBUF nil or omitted means consider the minibuffer window only if the
+minibuffer is active. MINIBUF t means consider the minibuffer window
+even if the minibuffer is not active. Any other value means do not
+consider the minibuffer window even if the minibuffer is active.
+
+ALL-FRAMES nil or omitted means consider all windows on WINDOW's frame,
+plus the minibuffer window if specified by the MINIBUF argument. If the
+minibuffer counts, consider all windows on all frames that share that
+minibuffer too. The following non-nil values of ALL-FRAMES have special
+meanings:
+
+- t means consider all windows on all existing frames.
+
+- `visible' means consider all windows on all visible frames.
+
+- 0 (the number zero) means consider all windows on all visible and
+ iconified frames.
+
+- A frame means consider all windows on that frame only.
+
+Anything else means consider all windows on WINDOW's frame and no
+others.
If you use consistent values for MINIBUF and ALL-FRAMES, you can
use `previous-window' to iterate through the entire cycle of
}
-DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p",
- doc: /* Select another window in cyclic ordering of windows.
-COUNT specifies the number of windows to skip, starting with the
-selected window, before making the selection. If COUNT is
-positive, skip COUNT windows forwards. If COUNT is negative,
-skip -COUNT windows backwards. COUNT zero means do not skip any
-window, so select the selected window. In an interactive call,
-COUNT is the numeric prefix argument. Return nil.
-
-This function uses `next-window' for finding the window to select.
-The argument ALL-FRAMES has the same meaning as in `next-window',
-but the MINIBUF argument of `next-window' is always effectively
-nil. */)
- (Lisp_Object count, Lisp_Object all_frames)
-{
- Lisp_Object window;
- int i;
-
- CHECK_NUMBER (count);
- window = selected_window;
-
- for (i = XINT (count); i > 0; --i)
- window = Fnext_window (window, Qnil, all_frames);
- for (; i < 0; ++i)
- window = Fprevious_window (window, Qnil, all_frames);
-
- Fselect_window (window, Qnil);
- return Qnil;
-}
-
-
/* Return a list of windows in cyclic ordering. Arguments are like
for `next-window'. */
enum window_loop
{
WINDOW_LOOP_UNUSED,
- GET_BUFFER_WINDOW, /* Arg is buffer */
- DELETE_BUFFER_WINDOWS, /* Arg is buffer */
- UNSHOW_BUFFER, /* Arg is buffer */
- REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
+ GET_BUFFER_WINDOW, /* Arg is buffer */
+ REPLACE_BUFFER_IN_WINDOWS_SAFELY, /* Arg is buffer */
+ REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
CHECK_ALL_WINDOWS
};
window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frames)
{
Lisp_Object window, windows, best_window, frame_arg;
+ int frame_best_window_flag = 0;
struct frame *f;
struct gcpro gcpro1;
is visible, since Fwindow_list skips non-visible frames if
that is desired, under the control of frame_arg. */
if (!MINI_WINDOW_P (w)
- /* For UNSHOW_BUFFER, we must always consider all windows. */
- || type == UNSHOW_BUFFER
+ /* For REPLACE_BUFFER_IN_WINDOWS_SAFELY, we must always
+ consider all windows. */
+ || type == REPLACE_BUFFER_IN_WINDOWS_SAFELY
|| (mini && minibuf_level > 0))
switch (type)
{
case GET_BUFFER_WINDOW:
if (EQ (w->buffer, obj)
- /* Don't find any minibuffer window
- except the one that is currently in use. */
- && (MINI_WINDOW_P (w)
- ? EQ (window, minibuf_window)
- : 1))
+ /* Don't find any minibuffer window except the one that
+ is currently in use. */
+ && (MINI_WINDOW_P (w) ? EQ (window, minibuf_window) : 1))
{
- if (NILP (best_window))
- best_window = window;
- else if (EQ (window, selected_window))
- /* Prefer to return selected-window. */
+ if (EQ (window, selected_window))
+ /* Preferably return the selected window. */
RETURN_UNGCPRO (window);
- else if (EQ (Fwindow_frame (window), selected_frame))
- /* Prefer windows on the current frame. */
- best_window = window;
- }
- break;
-
- case DELETE_BUFFER_WINDOWS:
- if (EQ (w->buffer, obj))
- {
- struct frame *fr = XFRAME (WINDOW_FRAME (w));
-
- /* If this window is dedicated, and in a frame of its own,
- kill the frame. */
- if (EQ (window, FRAME_ROOT_WINDOW (fr))
- && !NILP (w->dedicated)
- && other_visible_frames (fr))
- {
- /* Skip the other windows on this frame.
- There might be one, the minibuffer! */
- while (CONSP (XCDR (windows))
- && EQ (XWINDOW (XCAR (windows))->frame,
- XWINDOW (XCAR (XCDR (windows)))->frame))
- windows = XCDR (windows);
-
- /* Now we can safely delete the frame. */
- delete_frame (w->frame, Qnil);
- }
- else if (NILP (w->parent))
+ else if (EQ (XWINDOW (window)->frame, selected_frame)
+ && !frame_best_window_flag)
+ /* Prefer windows on the current frame (but don't
+ choose another one if we have one already). */
{
- /* If we're deleting the buffer displayed in the
- only window on the frame, find a new buffer to
- display there. */
- Lisp_Object buffer;
- buffer = Fother_buffer (obj, Qnil, w->frame);
- /* Reset dedicated state of window. */
- w->dedicated = Qnil;
- Fset_window_buffer (window, buffer, Qnil);
- if (EQ (window, selected_window))
- Fset_buffer (w->buffer);
+ best_window = window;
+ frame_best_window_flag = 1;
}
- else
- call1 (Qdelete_window, window);
+ else if (NILP (best_window))
+ best_window = window;
}
break;
- case UNSHOW_BUFFER:
+ case REPLACE_BUFFER_IN_WINDOWS_SAFELY:
+ /* We could simply check whether the buffer shown by window
+ is live, and show another buffer in case it isn't. */
if (EQ (w->buffer, obj))
{
- Lisp_Object buffer;
- struct frame *fr = XFRAME (w->frame);
-
- /* Find another buffer to show in this window. */
- buffer = Fother_buffer (obj, Qnil, w->frame);
-
- /* If this window is dedicated, and in a frame of its own,
- kill the frame. */
- if (EQ (window, FRAME_ROOT_WINDOW (fr))
- && !NILP (w->dedicated)
- && other_visible_frames (fr))
- {
- /* Skip the other windows on this frame.
- There might be one, the minibuffer! */
- while (CONSP (XCDR (windows))
- && EQ (XWINDOW (XCAR (windows))->frame,
- XWINDOW (XCAR (XCDR (windows)))->frame))
- windows = XCDR (windows);
-
- /* Now we can safely delete the frame. */
- delete_frame (w->frame, Qnil);
- }
- else if (!NILP (w->dedicated) && !NILP (w->parent))
- {
- Lisp_Object window_to_delete;
- XSETWINDOW (window_to_delete, w);
- /* If this window is dedicated and not the only window
- in its frame, then kill it. */
- call1 (Qdelete_window, window_to_delete);
- }
- else
- {
- /* Otherwise show a different buffer in the window. */
- w->dedicated = Qnil;
- Fset_window_buffer (window, buffer, Qnil);
- if (EQ (window, selected_window))
- Fset_buffer (w->buffer);
- }
+ /* Undedicate WINDOW. */
+ w->dedicated = Qnil;
+ /* Make WINDOW show the buffer returned by
+ other_buffer_safely, don't run any hooks. */
+ set_window_buffer
+ (window, other_buffer_safely (w->buffer), 0, 0);
+ /* If WINDOW is the selected window, make its buffer
+ current. But do so only if the window shows the
+ current buffer (Bug#6454). */
+ if (EQ (window, selected_window)
+ && XBUFFER (w->buffer) == current_buffer)
+ Fset_buffer (w->buffer);
}
break;
return Qnil;
}
-Lisp_Object
+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);
}
{
struct window *w, *r, *s;
struct frame *f;
- Lisp_Object sibling, pwindow, swindow, delta;
- EMACS_INT startpos;
- int top, new_top, resize_failed;
+ Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta;
+ EMACS_INT startpos IF_LINT (= 0);
+ int top IF_LINT (= 0), new_top, resize_failed;
w = decode_any_window (window);
XSETWINDOW (window, w);
windows_or_buffers_changed++;
Vwindow_list = Qnil;
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
+ resize_failed = 0;
if (NILP (w->buffer))
{
- resize_failed = 0;
/* Resize subwindows vertically. */
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;
}
}
-DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on,
- 0, 2, "bDelete windows on (buffer): ",
- doc: /* Delete all windows showing BUFFER-OR-NAME.
-BUFFER-OR-NAME may be a buffer or the name of an existing buffer and
-defaults to the current 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.
-If FRAME is nil, search all frames.
-If FRAME is t, search only the selected frame.
-If FRAME is a frame, search only that frame.
-When a window showing BUFFER-OR-NAME is dedicated and the only window of
-its frame, that frame is deleted when there are other frames left. */)
- (Lisp_Object buffer_or_name, Lisp_Object frame)
+void
+replace_buffer_in_windows (Lisp_Object buffer)
{
- Lisp_Object buffer;
-
- /* FRAME uses t and nil to mean the opposite of what window_loop
- expects. */
- if (NILP (frame))
- frame = Qt;
- else if (EQ (frame, Qt))
- frame = Qnil;
-
- if (NILP (buffer_or_name))
- buffer = Fcurrent_buffer ();
- else
- {
- buffer = Fget_buffer (buffer_or_name);
- CHECK_BUFFER (buffer);
- }
-
- window_loop (DELETE_BUFFER_WINDOWS, buffer, 0, frame);
-
- return Qnil;
+ call1 (Qreplace_buffer_in_windows, buffer);
}
-DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows,
- Sreplace_buffer_in_windows,
- 0, 1, "bReplace buffer in windows: ",
- doc: /* Replace BUFFER-OR-NAME with some other buffer in all windows showing it.
-BUFFER-OR-NAME may be a buffer or the name of an existing buffer and
-defaults to the current buffer.
-When a window showing BUFFER-OR-NAME is dedicated that window is
-deleted. If that window is the only window on its frame, that frame is
-deleted too when there are other frames left. If there are no other
-frames left, some other buffer is displayed in that window. */)
- (Lisp_Object buffer_or_name)
-{
- Lisp_Object buffer;
-
- if (NILP (buffer_or_name))
- buffer = Fcurrent_buffer ();
- else
- {
- buffer = Fget_buffer (buffer_or_name);
- CHECK_BUFFER (buffer);
- }
-
- window_loop (UNSHOW_BUFFER, buffer, 0, Qt);
-
- return Qnil;
-}
-
-/* Replace BUFFER with some other buffer in all windows
- of all frames, even those on other keyboards. */
+/* Safely replace BUFFER with some other buffer in all windows of all
+ frames, even those on other keyboards. */
void
-replace_buffer_in_all_windows (Lisp_Object buffer)
+replace_buffer_in_windows_safely (Lisp_Object buffer)
{
Lisp_Object tail, frame;
- /* A single call to window_loop won't do the job
- because it only considers frames on the current keyboard.
- So loop manually over frames, and handle each one. */
+ /* A single call to window_loop won't do the job because it only
+ considers frames on the current keyboard. So loop manually over
+ frames, and handle each one. */
FOR_EACH_FRAME (tail, frame)
- window_loop (UNSHOW_BUFFER, buffer, 1, frame);
+ window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame);
}
\f
/* If *ROWS or *COLS are too small a size for FRAME, set them to the
return 1;
}
\f
-int window_select_count;
-
static Lisp_Object Fset_window_margins (Lisp_Object, Lisp_Object, Lisp_Object);
static Lisp_Object Fset_window_fringes (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object);
Lisp_Object, Lisp_Object);
static Lisp_Object Fset_window_vscroll (Lisp_Object, Lisp_Object, Lisp_Object);
+/* The following three routines are needed for running a window's
+ configuration change hook. */
static void
run_funs (Lisp_Object funs)
{
call0 (XCAR (funs));
}
-static Lisp_Object select_window_norecord (Lisp_Object window);
-static Lisp_Object select_frame_norecord (Lisp_Object frame);
+static Lisp_Object
+select_window_norecord (Lisp_Object window)
+{
+ return WINDOW_LIVE_P (window)
+ ? Fselect_window (window, Qt) : selected_window;
+}
+
+static Lisp_Object
+select_frame_norecord (Lisp_Object frame)
+{
+ return FRAME_LIVE_P (XFRAME (frame))
+ ? Fselect_frame (frame, Qt) : selected_frame;
+}
void
run_window_configuration_change_hook (struct frame *f)
if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook,
buffer)))
{
- int count = SPECPDL_INDEX ();
+ int inner_count = SPECPDL_INDEX ();
record_unwind_protect (select_window_norecord, Fselected_window ());
select_window_norecord (window);
run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
buffer));
- unbind_to (count, Qnil);
+ unbind_to (inner_count, Qnil);
}
}
}
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 defaults to the selected window. BUFFER-OR-NAME must be a buffer
-or the name of an existing buffer. Optional third argument KEEP-MARGINS
-non-nil means that WINDOW's current display margins, fringe widths, and
-scroll bar settings are preserved; the default is to reset these from
-the local settings for BUFFER-OR-NAME or the frame defaults. Return nil.
+WINDOW has to be a live window and defaults to the selected one.
+BUFFER-OR-NAME must be a buffer or the name of an existing buffer.
+
+Optional third argument KEEP-MARGINS non-nil means that WINDOW's current
+display margins, fringe widths, and scroll bar settings are preserved;
+the default is to reset these from the local settings for BUFFER-OR-NAME
+or the frame defaults. Return nil.
This function throws an error when WINDOW is strongly dedicated to its
buffer (that is `window-dedicated-p' returns t for WINDOW) and does not
else if (!EQ (tem, Qt))
/* w->buffer is t when the window is first being set up. */
{
- if (EQ (tem, buffer))
- return Qnil;
- else if (EQ (w->dedicated, Qt))
- error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem), name)));
- else
- w->dedicated = Qnil;
+ if (!EQ (tem, buffer))
+ {
+ if (EQ (w->dedicated, Qt))
+ /* WINDOW is strongly dedicated to its buffer, signal an
+ error. */
+ error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem), name)));
+ else
+ /* WINDOW is weakly dedicated to its buffer, reset
+ dedicatedness. */
+ w->dedicated = Qnil;
+
+ call1 (Qrecord_window_buffer, window);
+ }
unshow_buffer (w);
}
set_window_buffer (window, buffer, 1, !NILP (keep_margins));
- return Qnil;
-}
-static Lisp_Object
-select_window_norecord (Lisp_Object window)
-{
- return WINDOW_LIVE_P (window)
- ? Fselect_window (window, Qt) : selected_window;
-}
-
-static Lisp_Object
-select_frame_norecord (Lisp_Object frame)
-{
- return FRAME_LIVE_P (XFRAME (frame))
- ? Fselect_frame (frame, Qt) : selected_frame;
+ return Qnil;
}
\f
static Lisp_Object
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;
Note: This function does not check any of `window-fixed-size-p',
`window-min-height' or `window-min-width'. It does check that window
sizes do not drop below one line (two columns). */
-int
-resize_window_check (struct window *w, int horflag)
+static int
+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, *p;
+ struct window *c;
int pos;
/* Note: Assigning new_normal requires that the new total size of the
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
DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
doc: /* Split window OLD.
Second argument TOTAL-SIZE specifies the number of lines or columns of the
-new window. In any case TOTAL-SIZE must be a positive integer
+new window. In any case TOTAL-SIZE must be a positive integer.
Third argument SIDE nil (or `below') specifies that the new window shall
be located below WINDOW. SIDE `above' means the new window shall be
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));
else error ("Failed to resize minibuffer window");
}
\f
-\f
/* Mark window cursors off for all windows in the window tree rooted
at W by setting their phys_cursor_on_p flag to zero. Called from
xterm.c, e.g. when a frame is cleared and thereby all cursors on
/* 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);
}
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 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)
{
int nlines = -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
{
return Qnil;
}
-
DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
0, 1, 0,
doc: /* Return the height in lines of the text display area of WINDOW.
{
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;
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;
+ struct Lisp_Vector *sws1, *sws2;
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))
- return 0;
-
- /* Verify that the two confis have the same number of windows. */
- if (sw1->header.size != sw2->header.size)
+ 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;
- 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 (&Sset_window_display_table);
defsubr (&Snext_window);
defsubr (&Sprevious_window);
- defsubr (&Sother_window);
defsubr (&Sget_buffer_window);
- defsubr (&Sdelete_windows_on);
- defsubr (&Sreplace_buffer_in_windows);
defsubr (&Sdelete_other_windows_internal);
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);
void
keys_of_window (void)
{
- initial_define_key (control_x_map, 'o', "other-window");
initial_define_key (control_x_map, '<', "scroll-left");
initial_define_key (control_x_map, '>', "scroll-right");