/* Window creation, deletion and examination for GNU Emacs.
Does not include redisplay.
- Copyright (C) 1985-1987, 1993-1998, 2000-2012
- Free Software Foundation, Inc.
+ Copyright (C) 1985-1987, 1993-1998, 2000-2013 Free Software
+ Foundation, Inc.
This file is part of GNU Emacs.
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
+
+#define WINDOW_INLINE EXTERN_INLINE
+
#include <stdio.h>
-#include <setjmp.h>
#include "lisp.h"
+#include "character.h"
#include "buffer.h"
#include "keyboard.h"
#include "keymap.h"
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
#endif /* HAVE_X_WINDOWS */
-#ifdef WINDOWSNT
+#ifdef HAVE_NTGUI
#include "w32term.h"
#endif
#ifdef MSDOS
#endif
Lisp_Object Qwindowp, Qwindow_live_p;
-static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
+static Lisp_Object Qwindow_valid_p;
+static Lisp_Object Qwindow_configuration_p;
+static Lisp_Object 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 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, Qclone_of;
+static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
static int displayed_window_lines (struct window *);
-static struct window *decode_window (Lisp_Object);
static int count_windows (struct window *);
static int get_leaf_windows (struct window *, struct window **, int);
-static void window_scroll (Lisp_Object, EMACS_INT, int, int);
-static void window_scroll_pixel_based (Lisp_Object, int, int, int);
-static void window_scroll_line_based (Lisp_Object, int, int, int);
-static int freeze_window_start (struct window *, void *);
+static void window_scroll (Lisp_Object, EMACS_INT, bool, int);
+static void window_scroll_pixel_based (Lisp_Object, int, bool, int);
+static void window_scroll_line_based (Lisp_Object, int, bool, int);
static Lisp_Object window_list (void);
static int add_window_to_list (struct window *, void *);
-static int candidate_window_p (Lisp_Object, Lisp_Object, Lisp_Object,
- Lisp_Object);
static Lisp_Object next_window (Lisp_Object, Lisp_Object,
Lisp_Object, int);
static void decode_next_window_args (Lisp_Object *, Lisp_Object *,
int (* fn) (struct window *, void *),
void *);
static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
-static int window_resize_check (struct window *, int);
-static void window_resize_apply (struct window *, int);
+static int window_resize_check (struct window *, bool);
+static void window_resize_apply (struct window *, bool);
static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
+static void select_window_1 (Lisp_Object, bool);
+
+static struct window *set_window_fringes (struct window *, Lisp_Object,
+ Lisp_Object, Lisp_Object);
+static struct window *set_window_margins (struct window *, Lisp_Object,
+ Lisp_Object);
+static struct window *set_window_scroll_bars (struct window *, Lisp_Object,
+ Lisp_Object, Lisp_Object);
+static void apply_window_adjustment (struct window *);
/* This is the window in which the terminal's cursor should
be left when nothing is being done with it. This must
/* Hook run at end of temp_output_buffer_show. */
static Lisp_Object Qtemp_buffer_show_hook;
-/* Incremented for each window created. */
-static int sequence_number;
-
/* Nonzero after init_window_once has finished. */
static int window_initialized;
static EMACS_INT window_scroll_preserve_hpos;
static EMACS_INT window_scroll_preserve_vpos;
\f
-static struct window *
-decode_window (register Lisp_Object window)
+static void
+CHECK_WINDOW_CONFIGURATION (Lisp_Object x)
+{
+ CHECK_TYPE (WINDOW_CONFIGURATIONP (x), Qwindow_configuration_p, x);
+}
+
+/* These setters are used only in this file, so they can be private. */
+static void
+wset_combination_limit (struct window *w, Lisp_Object val)
+{
+ w->combination_limit = val;
+}
+static void
+wset_dedicated (struct window *w, Lisp_Object val)
+{
+ w->dedicated = val;
+}
+static void
+wset_display_table (struct window *w, Lisp_Object val)
+{
+ w->display_table = val;
+}
+static void
+wset_new_normal (struct window *w, Lisp_Object val)
+{
+ w->new_normal = val;
+}
+static void
+wset_new_total (struct window *w, Lisp_Object val)
+{
+ w->new_total = val;
+}
+static void
+wset_normal_cols (struct window *w, Lisp_Object val)
+{
+ w->normal_cols = val;
+}
+static void
+wset_normal_lines (struct window *w, Lisp_Object val)
+{
+ w->normal_lines = val;
+}
+static void
+wset_parent (struct window *w, Lisp_Object val)
+{
+ w->parent = val;
+}
+static void
+wset_pointm (struct window *w, Lisp_Object val)
+{
+ w->pointm = val;
+}
+static void
+wset_start (struct window *w, Lisp_Object val)
+{
+ w->start = val;
+}
+static void
+wset_temslot (struct window *w, Lisp_Object val)
+{
+ w->temslot = val;
+}
+static void
+wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val)
+{
+ w->vertical_scroll_bar_type = val;
+}
+static void
+wset_window_parameters (struct window *w, Lisp_Object val)
+{
+ w->window_parameters = val;
+}
+static void
+wset_combination (struct window *w, bool horflag, Lisp_Object val)
+{
+ /* Since leaf windows never becomes non-leaf, there should
+ be no buffer and markers in start and pointm fields of W. */
+ eassert (!BUFFERP (w->contents) && NILP (w->start) && NILP (w->pointm));
+ w->contents = val;
+ /* When an internal window is deleted and VAL is nil, HORFLAG
+ is meaningless. */
+ if (!NILP (val))
+ w->horizontal = horflag;
+}
+
+/* Nonzero if leaf window W doesn't reflect the actual state
+ of displayed buffer due to its text or overlays change. */
+
+bool
+window_outdated (struct window *w)
+{
+ struct buffer *b = XBUFFER (w->contents);
+ return (w->last_modified < BUF_MODIFF (b)
+ || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b));
+}
+
+struct window *
+decode_live_window (register Lisp_Object window)
{
if (NILP (window))
return XWINDOW (selected_window);
return XWINDOW (window);
}
-static struct window *
+struct window *
decode_any_window (register Lisp_Object window)
{
+ struct window *w;
+
if (NILP (window))
return XWINDOW (selected_window);
CHECK_WINDOW (window);
- return XWINDOW (window);
+ w = XWINDOW (window);
+ return w;
+}
+
+static struct window *
+decode_valid_window (register Lisp_Object window)
+{
+ struct window *w;
+
+ if (NILP (window))
+ return XWINDOW (selected_window);
+
+ CHECK_VALID_WINDOW (window);
+ w = XWINDOW (window);
+ return w;
+}
+
+/* Called when W's buffer slot is changed. ARG -1 means that W is about to
+ cease its buffer, and 1 means that W is about to set up the new one. */
+
+static void
+adjust_window_count (struct window *w, int arg)
+{
+ eassert (eabs (arg) == 1);
+ if (BUFFERP (w->contents))
+ {
+ struct buffer *b = XBUFFER (w->contents);
+
+ if (b->base_buffer)
+ b = b->base_buffer;
+ b->window_count += arg;
+ eassert (b->window_count >= 0);
+ /* These should be recalculated by redisplay code. */
+ w->window_end_valid = 0;
+ w->base_line_pos = 0;
+ }
+}
+
+/* Set W's buffer slot to VAL and recompute number
+ of windows showing VAL if it is a buffer. */
+
+void
+wset_buffer (struct window *w, Lisp_Object val)
+{
+ adjust_window_count (w, -1);
+ if (BUFFERP (val))
+ /* Make sure that we do not assign the buffer
+ to an internal window. */
+ eassert (MARKERP (w->start) && MARKERP (w->pointm));
+ w->contents = val;
+ adjust_window_count (w, 1);
}
DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
return WINDOWP (object) ? Qt : Qnil;
}
+DEFUN ("window-valid-p", Fwindow_valid_p, Swindow_valid_p, 1, 1, 0,
+ doc: /* Return t if OBJECT is a valid window and nil otherwise.
+A valid window is either a window that displays a buffer or an internal
+window. Deleted windows are not live. */)
+ (Lisp_Object object)
+{
+ return WINDOW_VALID_P (object) ? Qt : Qnil;
+}
+
DEFUN ("window-live-p", Fwindow_live_p, Swindow_live_p, 1, 1, 0,
doc: /* Return t if OBJECT is a live window and nil otherwise.
A live window is a window that displays a buffer.
}
\f
/* Frames and windows. */
-DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
+DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 0, 1, 0,
doc: /* Return the frame that window WINDOW is on.
-If WINDOW is omitted or nil, it defaults to the selected window. */)
+WINDOW must be a valid window and defaults to the selected one. */)
(Lisp_Object window)
{
- return decode_any_window (window)->frame;
+ return decode_valid_window (window)->frame;
}
DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
if (NILP (frame_or_window))
window = SELECTED_FRAME ()->root_window;
- else if (WINDOWP (frame_or_window))
- window = XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window)))->root_window;
+ else if (WINDOW_VALID_P (frame_or_window))
+ window = XFRAME (XWINDOW (frame_or_window)->frame)->root_window;
else
{
CHECK_LIVE_FRAME (frame_or_window);
If FRAME is omitted or nil, it defaults to the selected frame. */)
(Lisp_Object frame)
{
- if (NILP (frame))
- frame = selected_frame;
- CHECK_LIVE_FRAME (frame);
- return FRAME_MINIBUF_WINDOW (XFRAME (frame));
+ return FRAME_MINIBUF_WINDOW (decode_live_frame (frame));
}
DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p,
Swindow_minibuffer_p, 0, 1, 0,
doc: /* Return non-nil if WINDOW is a minibuffer window.
-If WINDOW is omitted or nil, it defaults to the selected window. */)
+WINDOW must be a valid window and defaults to the selected one. */)
(Lisp_Object window)
{
- return MINI_WINDOW_P (decode_any_window (window)) ? Qt : Qnil;
+ return MINI_WINDOW_P (decode_valid_window (window)) ? Qt : Qnil;
}
/* Don't move this to window.el - this must be a safe routine. */
DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
doc: /* Return the topmost, leftmost live window on FRAME-OR-WINDOW.
If omitted, FRAME-OR-WINDOW defaults to the currently selected frame.
-Else if FRAME-OR-WINDOW denotes any window, return the first window of
-that window's frame. If FRAME-OR-WINDOW denotes a live frame, return
+Else if FRAME-OR-WINDOW denotes a valid window, return the first window
+of that window's frame. If FRAME-OR-WINDOW denotes a live frame, return
the first window of that frame. */)
(Lisp_Object frame_or_window)
{
if (NILP (frame_or_window))
window = SELECTED_FRAME ()->root_window;
- else if (WINDOWP (frame_or_window))
+ else if (WINDOW_VALID_P (frame_or_window))
window = XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window)))->root_window;
else
{
window = XFRAME (frame_or_window)->root_window;
}
- while (NILP (XWINDOW (window)->buffer))
- {
- if (! NILP (XWINDOW (window)->hchild))
- window = XWINDOW (window)->hchild;
- else if (! NILP (XWINDOW (window)->vchild))
- window = XWINDOW (window)->vchild;
- else
- abort ();
- }
+ while (WINDOWP (XWINDOW (window)->contents))
+ window = XWINDOW (window)->contents;
return window;
}
Sframe_selected_window, 0, 1, 0,
doc: /* Return the selected window of FRAME-OR-WINDOW.
If omitted, FRAME-OR-WINDOW defaults to the currently selected frame.
-Else if FRAME-OR-WINDOW denotes any window, return the selected window
-of that window's frame. If FRAME-OR-WINDOW denotes a live frame, return
-the selected window of that frame. */)
+Else if FRAME-OR-WINDOW denotes a valid window, return the selected
+window of that window's frame. If FRAME-OR-WINDOW denotes a live frame,
+return the selected window of that frame. */)
(Lisp_Object frame_or_window)
{
Lisp_Object window;
if (NILP (frame_or_window))
window = SELECTED_FRAME ()->selected_window;
- else if (WINDOWP (frame_or_window))
+ else if (WINDOW_VALID_P (frame_or_window))
window = XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window)))->selected_window;
else
{
if (EQ (frame, selected_frame))
return Fselect_window (window, norecord);
else
- return XFRAME (frame)->selected_window = window;
+ {
+ fset_selected_window (XFRAME (frame), window);
+ return window;
+ }
}
DEFUN ("selected-window", Fselected_window, Sselected_window, 0, 0, 0,
select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
{
register struct window *w;
- register struct window *ow;
struct frame *sf;
CHECK_LIVE_WINDOW (window);
w = XWINDOW (window);
- w->frozen_window_start_p = 0;
- if (NILP (norecord))
- {
- ++window_select_count;
- XSETFASTINT (w->use_time, window_select_count);
- record_buffer (w->buffer);
- }
+ /* Make the selected window's buffer current. */
+ Fset_buffer (w->contents);
if (EQ (window, selected_window) && !inhibit_point_swap)
- return window;
+ /* `switch-to-buffer' uses (select-window (selected-window)) as a "clever"
+ way to call record_buffer from Elisp, so it's important that we call
+ record_buffer before returning here. */
+ goto record_and_return;
sf = SELECTED_FRAME ();
if (XFRAME (WINDOW_FRAME (w)) != sf)
{
- XFRAME (WINDOW_FRAME (w))->selected_window = window;
+ fset_selected_window (XFRAME (WINDOW_FRAME (w)), window);
/* Use this rather than Fhandle_switch_frame
so that FRAME_FOCUS_FRAME is moved appropriately as we
move around in the state where a minibuffer in a separate
return window;
}
else
- sf->selected_window = window;
+ fset_selected_window (sf, window);
- /* Store the current buffer's actual point into the
- old selected window. It belongs to that window,
- and when the window is not selected, must be in the window. */
- if (!inhibit_point_swap)
+ select_window_1 (window, inhibit_point_swap);
+ bset_last_selected_window (XBUFFER (w->contents), window);
+ windows_or_buffers_changed++;
+
+ record_and_return:
+ /* record_buffer can run QUIT, so make sure it is run only after we have
+ re-established the invariant between selected_window and selected_frame,
+ otherwise the temporary broken invariant might "escape" (bug#14161). */
+ if (NILP (norecord))
{
- ow = XWINDOW (selected_window);
- if (! NILP (ow->buffer))
- set_marker_both (ow->pointm, ow->buffer,
- BUF_PT (XBUFFER (ow->buffer)),
- BUF_PT_BYTE (XBUFFER (ow->buffer)));
+ w->use_time = ++window_select_count;
+ record_buffer (w->contents);
}
- selected_window = window;
+ return window;
+}
- Fset_buffer (w->buffer);
+/* Select window with a minimum of fuss, i.e. don't record the change anywhere
+ (not even for redisplay's benefit), and assume that the window's frame is
+ already selected. */
+static void
+select_window_1 (Lisp_Object window, bool inhibit_point_swap)
+{
+ /* Store the old selected window's buffer's point in pointm of the old
+ selected window. It belongs to that window, and when the window is
+ not selected, must be in the window. */
+ if (!inhibit_point_swap)
+ {
+ struct window *ow = XWINDOW (selected_window);
+ if (BUFFERP (ow->contents))
+ set_marker_both (ow->pointm, ow->contents,
+ BUF_PT (XBUFFER (ow->contents)),
+ BUF_PT_BYTE (XBUFFER (ow->contents)));
+ }
- BVAR (XBUFFER (w->buffer), last_selected_window) = window;
+ selected_window = window;
/* Go to the point recorded in the window.
This is important when the buffer is in more
than one window. It also matters when
redisplay_window has altered point after scrolling,
because it makes the change only in the window. */
- {
- register ptrdiff_t new_point = marker_position (w->pointm);
- if (new_point < BEGV)
- SET_PT (BEGV);
- else if (new_point > ZV)
- SET_PT (ZV);
- else
- SET_PT (new_point);
- }
-
- windows_or_buffers_changed++;
- return window;
+ set_point_from_marker (XWINDOW (window)->pointm);
}
DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
- doc: /* Select WINDOW. Most editing will apply to WINDOW's buffer.
-Also make WINDOW's buffer current and make WINDOW the frame's selected
-window. Return WINDOW.
+ doc: /* Select WINDOW which must be a live window.
+Also make WINDOW's frame the selected frame and WINDOW that frame's
+selected window. In addition, make WINDOW's buffer current and set that
+buffer's value of `point' to the value of WINDOW's `window-point'.
+Return WINDOW.
Optional second arg NORECORD non-nil means do not put this buffer at the
front of the buffer list and do not make this window the most recently
Return nil for an internal window or a deleted window. */)
(Lisp_Object window)
{
- return decode_any_window (window)->buffer;
+ struct window *w = decode_any_window (window);
+ return WINDOW_LEAF_P (w) ? w->contents : Qnil;
}
DEFUN ("window-parent", Fwindow_parent, Swindow_parent, 0, 1, 0,
doc: /* Return the parent window of window WINDOW.
-If WINDOW is omitted or nil, it defaults to the selected window.
+WINDOW must be a valid window and defaults to the selected one.
Return nil for a window with no parent (e.g. a root window). */)
(Lisp_Object window)
{
- return decode_any_window (window)->parent;
+ return decode_valid_window (window)->parent;
}
-DEFUN ("window-top-child", Fwindow_top_child, Swindow_top_child, 1, 1, 0,
+DEFUN ("window-top-child", Fwindow_top_child, Swindow_top_child, 0, 1, 0,
doc: /* Return the topmost child window of window WINDOW.
+WINDOW must be a valid window and defaults to the selected one.
Return nil if WINDOW is a live window (live windows have no children).
Return nil if WINDOW is an internal window whose children form a
horizontal combination. */)
(Lisp_Object window)
{
- CHECK_WINDOW (window);
- return decode_any_window (window)->vchild;
+ struct window *w = decode_valid_window (window);
+ return WINDOW_VERTICAL_COMBINATION_P (w) ? w->contents : Qnil;
}
-DEFUN ("window-left-child", Fwindow_left_child, Swindow_left_child, 1, 1, 0,
+DEFUN ("window-left-child", Fwindow_left_child, Swindow_left_child, 0, 1, 0,
doc: /* Return the leftmost child window of window WINDOW.
+WINDOW must be a valid window and defaults to the selected one.
Return nil if WINDOW is a live window (live windows have no children).
Return nil if WINDOW is an internal window whose children form a
vertical combination. */)
(Lisp_Object window)
{
- CHECK_WINDOW (window);
- return decode_any_window (window)->hchild;
+ struct window *w = decode_valid_window (window);
+ return WINDOW_HORIZONTAL_COMBINATION_P (w) ? w->contents : Qnil;
}
DEFUN ("window-next-sibling", Fwindow_next_sibling, Swindow_next_sibling, 0, 1, 0,
doc: /* Return the next sibling window of window WINDOW.
-If WINDOW is omitted or nil, it defaults to the selected window.
+WINDOW must be a valid window and defaults to the selected one.
Return nil if WINDOW has no next sibling. */)
(Lisp_Object window)
{
- return decode_any_window (window)->next;
+ return decode_valid_window (window)->next;
}
DEFUN ("window-prev-sibling", Fwindow_prev_sibling, Swindow_prev_sibling, 0, 1, 0,
doc: /* Return the previous sibling window of window WINDOW.
-If WINDOW is omitted or nil, it defaults to the selected window.
+WINDOW must be a valid window and defaults to the selected one.
Return nil if WINDOW has no previous sibling. */)
(Lisp_Object window)
{
- return decode_any_window (window)->prev;
+ return decode_valid_window (window)->prev;
}
DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combination_limit, 1, 1, 0,
doc: /* Return combination limit of window WINDOW.
+WINDOW must be a valid window used in horizontal or vertical combination.
If the return value is nil, child windows of WINDOW can be recombined with
WINDOW's siblings. A return value of t means that child windows of
WINDOW are never \(re-)combined with WINDOW's siblings. */)
(Lisp_Object window)
{
- return decode_any_window (window)->combination_limit;
+ struct window *w;
+
+ CHECK_VALID_WINDOW (window);
+ w = XWINDOW (window);
+ if (WINDOW_LEAF_P (w))
+ error ("Combination limit is meaningful for internal windows only");
+ return w->combination_limit;
}
DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0,
doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT.
-If LIMIT is nil, child windows of WINDOW can be recombined with
-WINDOW's siblings. LIMIT t means that child windows of WINDOW are
-never \(re-)combined with WINDOW's siblings. Other values are reserved
-for future use. */)
+WINDOW must be a valid window used in horizontal or vertical combination.
+If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's
+siblings. LIMIT t means that child windows of WINDOW are never
+\(re-)combined with WINDOW's siblings. Other values are reserved for
+future use. */)
(Lisp_Object window, Lisp_Object limit)
{
- register struct window *w = decode_any_window (window);
-
- w->combination_limit = limit;
+ struct window *w;
- return w->combination_limit;
+ CHECK_VALID_WINDOW (window);
+ w = XWINDOW (window);
+ if (WINDOW_LEAF_P (w))
+ error ("Combination limit is meaningful for internal windows only");
+ wset_combination_limit (w, limit);
+ return limit;
}
DEFUN ("window-use-time", Fwindow_use_time, Swindow_use_time, 0, 1, 0,
doc: /* Return the use time of window WINDOW.
-If WINDOW is omitted or nil, it defaults to the selected window.
+WINDOW must be a live window and defaults to the selected one.
The window with the highest use time is the most recently selected
one. The window with the lowest use time is the least recently
selected one. */)
(Lisp_Object window)
{
- return decode_window (window)->use_time;
+ return make_number (decode_live_window (window)->use_time);
}
\f
DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 1, 0,
doc: /* Return the total height, in lines, of window WINDOW.
-If WINDOW is omitted or nil, it defaults to the selected window.
+WINDOW must be a valid window and defaults to the selected one.
The return value includes the mode line and header line, if any.
If WINDOW is an internal window, the total height is the height
integer multiple of the default character height. */)
(Lisp_Object window)
{
- return decode_any_window (window)->total_lines;
+ return make_number (decode_valid_window (window)->total_lines);
}
DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 1, 0,
doc: /* Return the total width, in columns, of window WINDOW.
-If WINDOW is omitted or nil, it defaults to the selected window.
+WINDOW must be a valid window and defaults to the selected one.
The return value includes any vertical dividers or scroll bars
belonging to WINDOW. If WINDOW is an internal window, the total width
integer multiple of the default character width. */)
(Lisp_Object window)
{
- return decode_any_window (window)->total_cols;
+ return make_number (decode_valid_window (window)->total_cols);
}
DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0,
doc: /* Return the new total size of window WINDOW.
-If WINDOW is omitted or nil, it defaults to the selected window. */)
+WINDOW must be a valid window and defaults to the selected one. */)
(Lisp_Object window)
{
- return decode_any_window (window)->new_total;
+ return decode_valid_window (window)->new_total;
}
DEFUN ("window-normal-size", Fwindow_normal_size, Swindow_normal_size, 0, 2, 0,
doc: /* Return the normal height of window WINDOW.
-If WINDOW is omitted or nil, it defaults to the selected window.
+WINDOW must be a valid window and defaults to the selected one.
If HORIZONTAL is non-nil, return the normal width of WINDOW. */)
(Lisp_Object window, Lisp_Object horizontal)
{
- if (NILP (horizontal))
- return decode_any_window (window)->normal_lines;
- else
- return decode_any_window (window)->normal_cols;
+ struct window *w = decode_valid_window (window);
+
+ return NILP (horizontal) ? w->normal_lines : w->normal_cols;
}
DEFUN ("window-new-normal", Fwindow_new_normal, Swindow_new_normal, 0, 1, 0,
doc: /* Return new normal size of window WINDOW.
-If WINDOW is omitted or nil, it defaults to the selected window. */)
+WINDOW must be a valid window and defaults to the selected one. */)
(Lisp_Object window)
{
- return decode_any_window (window)->new_normal;
+ return decode_valid_window (window)->new_normal;
}
DEFUN ("window-left-column", Fwindow_left_column, Swindow_left_column, 0, 1, 0,
the left edge of the frame's window area. For instance, the return
value is 0 if there is no window to the left of WINDOW.
-If WINDOW is omitted or nil, it defaults to the selected window. */)
+WINDOW must be a valid window and defaults to the selected one. */)
(Lisp_Object window)
{
- return decode_any_window (window)->left_col;
+ return make_number (decode_valid_window (window)->left_col);
}
DEFUN ("window-top-line", Fwindow_top_line, Swindow_top_line, 0, 1, 0,
of the frame's window area. For instance, the return value is 0 if
there is no window above WINDOW.
-If WINDOW is omitted or nil, it defaults to the selected window. */)
+WINDOW must be a valid window and defaults to the selected one. */)
(Lisp_Object window)
{
- return decode_any_window (window)->top_line;
+ return make_number (decode_valid_window (window)->top_line);
}
/* Return the number of lines of W's body. Don't count any mode or
static int
window_body_lines (struct window *w)
{
- int height = XFASTINT (w->total_lines);
+ int height = w->total_lines;
if (!MINI_WINDOW_P (w))
{
window_body_cols (struct window *w)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
- int width = XINT (w->total_cols);
+ int width = w->total_cols;
if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
/* Scroll bars occupy a few columns. */
occupies one column only. */
width -= 1;
+ /* Display margins cannot be used for normal text. */
+ width -= WINDOW_LEFT_MARGIN_COLS (w) + WINDOW_RIGHT_MARGIN_COLS (w);
+
if (FRAME_WINDOW_P (f))
- /* On window-systems, fringes and display margins cannot be
- used for normal text. */
- width -= (WINDOW_FRINGE_COLS (w)
- + WINDOW_LEFT_MARGIN_COLS (w)
- + WINDOW_RIGHT_MARGIN_COLS (w));
+ /* On window-systems, fringes cannot be used for normal text. */
+ width -= WINDOW_FRINGE_COLS (w);
return width;
}
DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 1, 0,
doc: /* Return the height, in lines, of WINDOW's text area.
-If WINDOW is omitted or nil, it defaults to the selected window.
-Signal an error if the window is not live.
+WINDOW must be a live window and defaults to the selected one.
The returned height does not include the mode line or header line.
On a graphical display, the height is expressed as an integer multiple
exclude partially-visible lines, use `window-text-height'. */)
(Lisp_Object window)
{
- struct window *w = decode_window (window);
- return make_number (window_body_lines (w));
+ return make_number (window_body_lines (decode_live_window (window)));
}
DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 1, 0,
doc: /* Return the width, in columns, of WINDOW's text area.
-If WINDOW is omitted or nil, it defaults to the selected window.
-Signal an error if the window is not live.
+WINDOW must be a live window and defaults to the selected one.
The return value does not include any vertical dividers, fringe or
marginal areas, or scroll bars. On a graphical display, the width is
expressed as an integer multiple of the default character width. */)
(Lisp_Object window)
{
- struct window *w = decode_window (window);
- return make_number (window_body_cols (w));
+ return make_number (window_body_cols (decode_live_window (window)));
}
DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
WINDOW must be a live window and defaults to the selected one. */)
(Lisp_Object window)
{
- return decode_window (window)->hscroll;
+ return make_number (decode_live_window (window)->hscroll);
+}
+
+/* Set W's horizontal scroll amount to HSCROLL clipped to a reasonable
+ range, returning the new amount as a fixnum. */
+static Lisp_Object
+set_window_hscroll (struct window *w, EMACS_INT hscroll)
+{
+ /* Horizontal scrolling has problems with large scroll amounts.
+ It's too slow with long lines, and even with small lines the
+ display can be messed up. For now, though, impose only the limits
+ required by the internal representation: horizontal scrolling must
+ fit in fixnum (since it's visible to Elisp) and into ptrdiff_t
+ (since it's stored in a ptrdiff_t). */
+ ptrdiff_t hscroll_max = min (MOST_POSITIVE_FIXNUM, PTRDIFF_MAX);
+ ptrdiff_t new_hscroll = clip_to_bounds (0, hscroll, hscroll_max);
+
+ /* Prevent redisplay shortcuts when changing the hscroll. */
+ if (w->hscroll != new_hscroll)
+ XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
+
+ w->hscroll = new_hscroll;
+ return make_number (new_hscroll);
}
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.
+WINDOW must be a live window and defaults to the selected one.
+Clip the number to a reasonable value if out of range.
+Return the new number. NCOL should be zero or positive.
Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
window so that the location of point moves off-window. */)
(Lisp_Object window, Lisp_Object ncol)
{
- struct window *w = decode_window (window);
- ptrdiff_t hscroll;
-
CHECK_NUMBER (ncol);
- hscroll = clip_to_bounds (0, XINT (ncol), PTRDIFF_MAX);
-
- /* Prevent redisplay shortcuts when changing the hscroll. */
- if (XINT (w->hscroll) != hscroll)
- XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
-
- w->hscroll = make_number (hscroll);
- return ncol;
+ return set_window_hscroll (decode_live_window (window), XINT (ncol));
}
DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger,
Swindow_redisplay_end_trigger, 0, 1, 0,
doc: /* Return WINDOW's redisplay end trigger value.
-WINDOW defaults to the selected window.
+WINDOW must be a live window and defaults to the selected one.
See `set-window-redisplay-end-trigger' for more information. */)
(Lisp_Object window)
{
- return decode_window (window)->redisplay_end_trigger;
+ return decode_live_window (window)->redisplay_end_trigger;
}
DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger,
Sset_window_redisplay_end_trigger, 2, 2, 0,
doc: /* Set WINDOW's redisplay end trigger value to VALUE.
-VALUE should be a buffer position (typically a marker) or nil.
-If it is a buffer position, then if redisplay in WINDOW reaches a position
-beyond VALUE, the functions in `redisplay-end-trigger-functions' are called
-with two arguments: WINDOW, and the end trigger value.
-Afterwards the end-trigger value is reset to nil. */)
+WINDOW must be a live window and defaults to the selected one. VALUE
+should be a buffer position (typically a marker) or nil. If it is a
+buffer position, then if redisplay in WINDOW reaches a position beyond
+VALUE, the functions in `redisplay-end-trigger-functions' are called
+with two arguments: WINDOW, and the end trigger value. Afterwards the
+end-trigger value is reset to nil. */)
(register Lisp_Object window, Lisp_Object value)
{
- register struct window *w;
-
- w = decode_window (window);
- w->redisplay_end_trigger = value;
+ wset_redisplay_end_trigger (decode_live_window (window), value);
return value;
}
DEFUN ("window-edges", Fwindow_edges, Swindow_edges, 0, 1, 0,
doc: /* Return a list of the edge coordinates of WINDOW.
-The list has the form (LEFT TOP RIGHT BOTTOM).
-TOP and BOTTOM count by lines, and LEFT and RIGHT count by columns,
-all relative to 0, 0 at top left corner of frame.
-
-RIGHT is one more than the rightmost column occupied by WINDOW.
-BOTTOM is one more than the bottommost row occupied by WINDOW.
-The edges include the space used by WINDOW's scroll bar, display
-margins, fringes, header line, and/or mode line. For the edges of
-just the text area, use `window-inside-edges'. */)
+WINDOW must be a valid window and defaults to the selected one.
+
+The returned list has the form (LEFT TOP RIGHT BOTTOM). TOP and BOTTOM
+count by lines, and LEFT and RIGHT count by columns, all relative to 0,
+0 at top left corner of frame.
+
+RIGHT is one more than the rightmost column occupied by WINDOW. BOTTOM
+is one more than the bottommost row occupied by WINDOW. The edges
+include the space used by WINDOW's scroll bar, display margins, fringes,
+header line, and/or mode line. For the edges of just the text area, use
+`window-inside-edges'. */)
(Lisp_Object window)
{
- register struct window *w = decode_any_window (window);
+ register struct window *w = decode_valid_window (window);
- return Fcons (make_number (WINDOW_LEFT_EDGE_COL (w)),
- Fcons (make_number (WINDOW_TOP_EDGE_LINE (w)),
- Fcons (make_number (WINDOW_RIGHT_EDGE_COL (w)),
- Fcons (make_number (WINDOW_BOTTOM_EDGE_LINE (w)),
- Qnil))));
+ return list4i (WINDOW_LEFT_EDGE_COL (w), WINDOW_TOP_EDGE_LINE (w),
+ WINDOW_RIGHT_EDGE_COL (w), WINDOW_BOTTOM_EDGE_LINE (w));
}
DEFUN ("window-pixel-edges", Fwindow_pixel_edges, Swindow_pixel_edges, 0, 1, 0,
doc: /* Return a list of the edge pixel coordinates of WINDOW.
-The list has the form (LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at
-the top left corner of the frame.
+WINDOW must be a valid window and defaults to the selected one.
+
+The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
+0, 0 at the top left corner of the frame.
RIGHT is one more than the rightmost x position occupied by WINDOW.
BOTTOM is one more than the bottommost y position occupied by WINDOW.
of just the text area, use `window-inside-pixel-edges'. */)
(Lisp_Object window)
{
- register struct window *w = decode_any_window (window);
+ register struct window *w = decode_valid_window (window);
- return Fcons (make_number (WINDOW_LEFT_EDGE_X (w)),
- Fcons (make_number (WINDOW_TOP_EDGE_Y (w)),
- Fcons (make_number (WINDOW_RIGHT_EDGE_X (w)),
- Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w)),
- Qnil))));
+ return list4i (WINDOW_LEFT_EDGE_X (w), WINDOW_TOP_EDGE_Y (w),
+ WINDOW_RIGHT_EDGE_X (w), WINDOW_BOTTOM_EDGE_Y (w));
}
static void
DEFUN ("window-absolute-pixel-edges", Fwindow_absolute_pixel_edges,
Swindow_absolute_pixel_edges, 0, 1, 0,
doc: /* Return a list of the edge pixel coordinates of WINDOW.
-The list has the form (LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at
-the top left corner of the display.
+WINDOW must be a valid window and defaults to the selected one.
+
+The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
+0, 0 at the top left corner of the display.
RIGHT is one more than the rightmost x position occupied by WINDOW.
BOTTOM is one more than the bottommost y position occupied by WINDOW.
of just the text area, use `window-inside-absolute-pixel-edges'. */)
(Lisp_Object window)
{
- register struct window *w = decode_any_window (window);
+ register struct window *w = decode_valid_window (window);
int add_x, add_y;
+
calc_absolute_offset (w, &add_x, &add_y);
- return Fcons (make_number (WINDOW_LEFT_EDGE_X (w) + add_x),
- Fcons (make_number (WINDOW_TOP_EDGE_Y (w) + add_y),
- Fcons (make_number (WINDOW_RIGHT_EDGE_X (w) + add_x),
- Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w) + add_y),
- Qnil))));
+ return list4i (WINDOW_LEFT_EDGE_X (w) + add_x,
+ WINDOW_TOP_EDGE_Y (w) + add_y,
+ WINDOW_RIGHT_EDGE_X (w) + add_x,
+ WINDOW_BOTTOM_EDGE_Y (w) + add_y);
}
DEFUN ("window-inside-edges", Fwindow_inside_edges, Swindow_inside_edges, 0, 1, 0,
doc: /* Return a list of the edge coordinates of WINDOW.
-The list has the form (LEFT TOP RIGHT BOTTOM).
-TOP and BOTTOM count by lines, and LEFT and RIGHT count by columns,
-all relative to 0, 0 at top left corner of frame.
+WINDOW must be a live window and defaults to the selected one.
+
+The returned list has the form (LEFT TOP RIGHT BOTTOM). TOP and BOTTOM
+count by lines, and LEFT and RIGHT count by columns, all relative to 0,
+0 at top left corner of frame.
RIGHT is one more than the rightmost column of WINDOW's text area.
-BOTTOM is one more than the bottommost row of WINDOW's text area.
-The inside edges do not include the space used by the WINDOW's scroll
-bar, display margins, fringes, header line, and/or mode line. */)
+BOTTOM is one more than the bottommost row of WINDOW's text area. The
+inside edges do not include the space used by the WINDOW's scroll bar,
+display margins, fringes, header line, and/or mode line. */)
(Lisp_Object window)
{
- register struct window *w = decode_window (window);
+ register struct window *w = decode_live_window (window);
- return list4 (make_number (WINDOW_BOX_LEFT_EDGE_COL (w)
- + WINDOW_LEFT_MARGIN_COLS (w)
- + WINDOW_LEFT_FRINGE_COLS (w)),
- make_number (WINDOW_TOP_EDGE_LINE (w)
- + WINDOW_HEADER_LINE_LINES (w)),
- make_number (WINDOW_BOX_RIGHT_EDGE_COL (w)
- - WINDOW_RIGHT_MARGIN_COLS (w)
- - WINDOW_RIGHT_FRINGE_COLS (w)),
- make_number (WINDOW_BOTTOM_EDGE_LINE (w)
- - WINDOW_MODE_LINE_LINES (w)));
+ return list4i ((WINDOW_BOX_LEFT_EDGE_COL (w)
+ + WINDOW_LEFT_MARGIN_COLS (w)
+ + WINDOW_LEFT_FRINGE_COLS (w)),
+ (WINDOW_TOP_EDGE_LINE (w)
+ + WINDOW_HEADER_LINE_LINES (w)),
+ (WINDOW_BOX_RIGHT_EDGE_COL (w)
+ - WINDOW_RIGHT_MARGIN_COLS (w)
+ - WINDOW_RIGHT_FRINGE_COLS (w)),
+ (WINDOW_BOTTOM_EDGE_LINE (w)
+ - WINDOW_MODE_LINE_LINES (w)));
}
DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges, Swindow_inside_pixel_edges, 0, 1, 0,
doc: /* Return a list of the edge pixel coordinates of WINDOW's text area.
-The list has the form (LEFT TOP RIGHT BOTTOM), all relative to (0,0)
-at the top left corner of the frame's window area.
+WINDOW must be a live window and defaults to the selected one.
+
+The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
+(0,0) at the top left corner of the frame's window area.
RIGHT is one more than the rightmost x position of WINDOW's text area.
BOTTOM is one more than the bottommost y position of WINDOW's text area.
display margins, fringes, header line, and/or mode line. */)
(Lisp_Object window)
{
- register struct window *w = decode_window (window);
+ register struct window *w = decode_live_window (window);
- return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w)
- + WINDOW_LEFT_MARGIN_WIDTH (w)
- + WINDOW_LEFT_FRINGE_WIDTH (w)),
- make_number (WINDOW_TOP_EDGE_Y (w)
- + WINDOW_HEADER_LINE_HEIGHT (w)),
- make_number (WINDOW_BOX_RIGHT_EDGE_X (w)
- - WINDOW_RIGHT_MARGIN_WIDTH (w)
- - WINDOW_RIGHT_FRINGE_WIDTH (w)),
- make_number (WINDOW_BOTTOM_EDGE_Y (w)
- - WINDOW_MODE_LINE_HEIGHT (w)));
+ return list4i ((WINDOW_BOX_LEFT_EDGE_X (w)
+ + WINDOW_LEFT_MARGIN_WIDTH (w)
+ + WINDOW_LEFT_FRINGE_WIDTH (w)),
+ (WINDOW_TOP_EDGE_Y (w)
+ + WINDOW_HEADER_LINE_HEIGHT (w)),
+ (WINDOW_BOX_RIGHT_EDGE_X (w)
+ - WINDOW_RIGHT_MARGIN_WIDTH (w)
+ - WINDOW_RIGHT_FRINGE_WIDTH (w)),
+ (WINDOW_BOTTOM_EDGE_Y (w)
+ - WINDOW_MODE_LINE_HEIGHT (w)));
}
DEFUN ("window-inside-absolute-pixel-edges",
Fwindow_inside_absolute_pixel_edges,
Swindow_inside_absolute_pixel_edges, 0, 1, 0,
doc: /* Return a list of the edge pixel coordinates of WINDOW's text area.
-The list has the form (LEFT TOP RIGHT BOTTOM), all relative to (0,0)
-at the top left corner of the frame's window area.
+WINDOW must be a live window and defaults to the selected one.
+
+The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
+(0,0) at the top left corner of the frame's window area.
RIGHT is one more than the rightmost x position of WINDOW's text area.
BOTTOM is one more than the bottommost y position of WINDOW's text area.
display margins, fringes, header line, and/or mode line. */)
(Lisp_Object window)
{
- register struct window *w = decode_window (window);
+ register struct window *w = decode_live_window (window);
int add_x, add_y;
+
calc_absolute_offset (w, &add_x, &add_y);
- return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w)
- + WINDOW_LEFT_MARGIN_WIDTH (w)
- + WINDOW_LEFT_FRINGE_WIDTH (w) + add_x),
- make_number (WINDOW_TOP_EDGE_Y (w)
- + WINDOW_HEADER_LINE_HEIGHT (w) + add_y),
- make_number (WINDOW_BOX_RIGHT_EDGE_X (w)
- - WINDOW_RIGHT_MARGIN_WIDTH (w)
- - WINDOW_RIGHT_FRINGE_WIDTH (w) + add_x),
- make_number (WINDOW_BOTTOM_EDGE_Y (w)
- - WINDOW_MODE_LINE_HEIGHT (w) + add_y));
+ return list4i ((WINDOW_BOX_LEFT_EDGE_X (w)
+ + WINDOW_LEFT_MARGIN_WIDTH (w)
+ + WINDOW_LEFT_FRINGE_WIDTH (w) + add_x),
+ (WINDOW_TOP_EDGE_Y (w)
+ + WINDOW_HEADER_LINE_HEIGHT (w) + add_y),
+ (WINDOW_BOX_RIGHT_EDGE_X (w)
+ - WINDOW_RIGHT_MARGIN_WIDTH (w)
+ - WINDOW_RIGHT_FRINGE_WIDTH (w) + add_x),
+ (WINDOW_BOTTOM_EDGE_Y (w)
+ - WINDOW_MODE_LINE_HEIGHT (w) + add_y));
}
/* Test if the character at column X, row Y is within window W.
DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p,
Scoordinates_in_window_p, 2, 2, 0,
doc: /* Return non-nil if COORDINATES are in WINDOW.
-WINDOW must be a live window.
+WINDOW must be a live window and defaults to the selected one.
COORDINATES is a cons of the form (X . Y), X and Y being distances
measured in characters from the upper-left corner of the frame.
\(0 . 0) denotes the character in the upper left corner of the
int x, y;
Lisp_Object lx, ly;
- CHECK_LIVE_WINDOW (window);
- w = XWINDOW (window);
+ w = decode_live_window (window);
f = XFRAME (w->frame);
CHECK_CONS (coordinates);
lx = Fcar (coordinates);
return Qnil;
default:
- abort ();
+ emacs_abort ();
}
}
static int
check_window_containing (struct window *w, void *user_data)
{
- struct check_window_data *cw = (struct check_window_data *) user_data;
+ struct check_window_data *cw = user_data;
enum window_part found;
int continue_p = 1;
Lisp_Object
window_from_coordinates (struct frame *f, int x, int y,
- enum window_part *part, int tool_bar_p)
+ enum window_part *part, bool tool_bar_p)
{
Lisp_Object window;
struct check_window_data cw;
column 0. */)
(Lisp_Object x, Lisp_Object y, Lisp_Object frame)
{
- struct frame *f;
-
- if (NILP (frame))
- frame = selected_frame;
- CHECK_LIVE_FRAME (frame);
- f = XFRAME (frame);
+ struct frame *f = decode_live_frame (frame);
/* Check that arguments are integers or floats. */
CHECK_NUMBER_OR_FLOAT (x);
doc: /* Return current value of point in WINDOW.
WINDOW must be a live window and defaults to the selected one.
-For a nonselected window, this is the value point would have
-if that window were selected.
+For a nonselected window, this is the value point would have if that
+window were selected.
-Note that, when WINDOW is the selected window and its buffer
-is also currently selected, the value returned is the same as (point).
-It would be more strictly correct to return the `top-level' value
-of point, outside of any save-excursion forms.
-But that is hard to define. */)
+Note that, when WINDOW is selected, the value returned is the same as
+that returned by `point' for WINDOW's buffer. It would be more strictly
+correct to return the top-level value of `point', outside of any
+`save-excursion' forms. But that is hard to define. */)
(Lisp_Object window)
{
- register struct window *w = decode_window (window);
+ register struct window *w = decode_live_window (window);
- if (w == XWINDOW (selected_window)
- && current_buffer == XBUFFER (w->buffer))
- return Fpoint ();
- return Fmarker_position (w->pointm);
+ if (w == XWINDOW (selected_window))
+ return make_number (BUF_PT (XBUFFER (w->contents)));
+ else
+ return Fmarker_position (w->pointm);
}
DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0,
This is updated by redisplay or by calling `set-window-start'. */)
(Lisp_Object window)
{
- return Fmarker_position (decode_window (window)->start);
+ return Fmarker_position (decode_live_window (window)->start);
}
/* This is text temporarily removed from the doc string below.
(Lisp_Object window, Lisp_Object update)
{
Lisp_Object value;
- struct window *w = decode_window (window);
+ struct window *w = decode_live_window (window);
Lisp_Object buf;
struct buffer *b;
- buf = w->buffer;
+ buf = w->contents;
CHECK_BUFFER (buf);
b = XBUFFER (buf);
-#if 0 /* This change broke some things. We should make it later. */
- /* If we don't know the end position, return nil.
- The user can compute it with vertical-motion if he wants to.
- It would be nicer to do it automatically,
- but that's so slow that it would probably bother people. */
- if (NILP (w->window_end_valid))
- return Qnil;
-#endif
-
if (! NILP (update)
- && ! (! NILP (w->window_end_valid)
- && XFASTINT (w->last_modified) >= BUF_MODIFF (b)
- && XFASTINT (w->last_overlay_modified) >= BUF_OVERLAY_MODIFF (b))
+ && (windows_or_buffers_changed
+ || !w->window_end_valid
+ || b->clip_changed
+ || b->prevent_redisplay_optimizations_p
+ || window_outdated (w))
&& !noninteractive)
{
struct text_pos startp;
`-l' containing a call to `rmail' with subsequent other
commands. At the end, W->start happened to be BEG, while
rmail had already narrowed the buffer. */
- if (XMARKER (w->start)->charpos < BEGV)
- SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
- else if (XMARKER (w->start)->charpos > ZV)
- SET_TEXT_POS (startp, ZV, ZV_BYTE);
- else
- SET_TEXT_POS_FROM_MARKER (startp, w->start);
+ CLIP_TEXT_POS_FROM_MARKER (startp, w->start);
itdata = bidi_shelve_cache ();
start_display (&it, w, startp);
set_buffer_internal (old_buffer);
}
else
- XSETINT (value, BUF_Z (b) - XFASTINT (w->window_end_pos));
+ XSETINT (value, BUF_Z (b) - w->window_end_pos);
return value;
}
DEFUN ("set-window-point", Fset_window_point, Sset_window_point, 2, 2, 0,
doc: /* Make point value in WINDOW be at position POS in WINDOW's buffer.
+WINDOW must be a live window and defaults to the selected one.
Return POS. */)
(Lisp_Object window, Lisp_Object pos)
{
- register struct window *w = decode_window (window);
+ register struct window *w = decode_live_window (window);
- CHECK_NUMBER_COERCE_MARKER (pos);
- if (w == XWINDOW (selected_window)
- && XBUFFER (w->buffer) == current_buffer)
- Fgoto_char (pos);
- else
- set_marker_restricted (w->pointm, pos, w->buffer);
+ /* Type of POS is checked by Fgoto_char or set_marker_restricted ... */
- /* We have to make sure that redisplay updates the window to show
- the new value of point. */
- if (!EQ (window, selected_window))
- ++windows_or_buffers_changed;
+ if (w == XWINDOW (selected_window))
+ {
+ if (XBUFFER (w->contents) == current_buffer)
+ Fgoto_char (pos);
+ else
+ {
+ struct buffer *old_buffer = current_buffer;
+
+ /* ... but here we want to catch type error before buffer change. */
+ CHECK_NUMBER_COERCE_MARKER (pos);
+ set_buffer_internal (XBUFFER (w->contents));
+ Fgoto_char (pos);
+ set_buffer_internal (old_buffer);
+ }
+ }
+ else
+ {
+ set_marker_restricted (w->pointm, pos, w->contents);
+ /* We have to make sure that redisplay updates the window to show
+ the new value of point. */
+ ++windows_or_buffers_changed;
+ }
return pos;
}
DEFUN ("set-window-start", Fset_window_start, Sset_window_start, 2, 3, 0,
doc: /* Make display in WINDOW start at position POS in WINDOW's buffer.
-If WINDOW is nil, the selected window is used. Return POS.
-Optional third arg NOFORCE non-nil inhibits next redisplay from
+WINDOW must be a live window and defaults to the selected one. 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)
{
- register struct window *w = decode_window (window);
+ register struct window *w = decode_live_window (window);
- CHECK_NUMBER_COERCE_MARKER (pos);
- set_marker_restricted (w->start, pos, w->buffer);
- /* this is not right, but much easier than doing what is right. */
+ set_marker_restricted (w->start, pos, w->contents);
+ /* This is not right, but much easier than doing what is right. */
w->start_at_line_beg = 0;
if (NILP (noforce))
w->force_start = 1;
w->update_mode_line = 1;
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
- if (!EQ (window, selected_window))
+ if (w != XWINDOW (selected_window))
+ /* Enforce full redisplay. FIXME: make it more selective. */
windows_or_buffers_changed++;
return pos;
DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p,
Spos_visible_in_window_p, 0, 3, 0,
doc: /* Return non-nil if position POS is currently on the frame in WINDOW.
-Return nil if that position is scrolled vertically out of view.
-If a character is only partially visible, nil is returned, unless the
-optional argument PARTIALLY is non-nil.
-If POS is only out of view because of horizontal scrolling, return non-nil.
-If POS is t, it specifies the position of the last visible glyph in WINDOW.
-POS defaults to point in WINDOW; WINDOW defaults to the selected window.
+WINDOW must be a live window and defaults to the selected one.
+
+Return nil if that position is scrolled vertically out of view. If a
+character is only partially visible, nil is returned, unless the
+optional argument PARTIALLY is non-nil. If POS is only out of view
+because of horizontal scrolling, return non-nil. If POS is t, it
+specifies the position of the last visible glyph in WINDOW. POS
+defaults to point in WINDOW; WINDOW defaults to the selected window.
If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
-return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
+the return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
where X and Y are the pixel coordinates relative to the top left corner
of the window. The remaining elements are omitted if the character after
POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
-off-window at the top and bottom of the row, ROWH is the height of the
-display row, and VPOS is the row number (0-based) containing POS. */)
+off-window at the top and bottom of the screen line ("row") containing
+POS, ROWH is the visible height of that row, and VPOS is the row number
+\(zero-based). */)
(Lisp_Object pos, Lisp_Object window, Lisp_Object partially)
{
register struct window *w;
int rtop, rbot, rowh, vpos, fully_p = 1;
int x, y;
- w = decode_window (window);
- buf = XBUFFER (w->buffer);
+ w = decode_live_window (window);
+ buf = XBUFFER (w->contents);
SET_TEXT_POS_FROM_MARKER (top, w->start);
if (EQ (pos, Qt))
else if (w == XWINDOW (selected_window))
posint = PT;
else
- posint = XMARKER (w->pointm)->charpos;
+ posint = marker_position (w->pointm);
/* If position is above window start or outside buffer boundaries,
or if window start is out of range, position is not visible. */
{
Lisp_Object part = Qnil;
if (!fully_p)
- part = list4 (make_number (rtop), make_number (rbot),
- make_number (rowh), make_number (vpos));
+ part = list4i (rtop, rbot, rowh, vpos);
in_window = Fcons (make_number (x),
Fcons (make_number (y), part));
}
DEFUN ("window-line-height", Fwindow_line_height,
Swindow_line_height, 0, 2, 0,
doc: /* Return height in pixels of text line LINE in window WINDOW.
-WINDOW defaults to the selected window.
+WINDOW must be a live window and defaults to the selected one.
Return height of current line if LINE is omitted or nil. Return height of
header or mode line if LINE is `header-line' or `mode-line'.
int max_y, crop, i;
EMACS_INT n;
- w = decode_window (window);
+ w = decode_live_window (window);
if (noninteractive || w->pseudo_window_p)
return Qnil;
- CHECK_BUFFER (w->buffer);
- b = XBUFFER (w->buffer);
+ CHECK_BUFFER (w->contents);
+ b = XBUFFER (w->contents);
/* Fail if current matrix is not up-to-date. */
- if (NILP (w->window_end_valid)
- || current_buffer->clip_changed
- || current_buffer->prevent_redisplay_optimizations_p
- || XFASTINT (w->last_modified) < BUF_MODIFF (b)
- || XFASTINT (w->last_overlay_modified) < BUF_OVERLAY_MODIFF (b))
+ if (!w->window_end_valid
+ || windows_or_buffers_changed
+ || b->clip_changed
+ || b->prevent_redisplay_optimizations_p
+ || window_outdated (w))
return Qnil;
if (NILP (line))
if (!WINDOW_WANTS_HEADER_LINE_P (w))
return Qnil;
row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
- if (!row->enabled_p)
- return Qnil;
- return list4 (make_number (row->height),
- make_number (0), make_number (0),
- make_number (0));
+ return row->enabled_p ? list4i (row->height, 0, 0, 0) : Qnil;
}
if (EQ (line, Qmode_line))
{
row = MATRIX_MODE_LINE_ROW (w->current_matrix);
- if (!row->enabled_p)
- return Qnil;
- return list4 (make_number (row->height),
- make_number (0), /* not accurate */
- make_number (WINDOW_HEADER_LINE_HEIGHT (w)
- + window_text_bottom_y (w)),
- make_number (0));
+ return (row->enabled_p ?
+ list4i (row->height,
+ 0, /* not accurate */
+ (WINDOW_HEADER_LINE_HEIGHT (w)
+ + window_text_bottom_y (w)),
+ 0)
+ : Qnil);
}
CHECK_NUMBER (line);
found_row:
crop = max (0, (row->y + row->height) - max_y);
- return list4 (make_number (row->height + min (0, row->y) - crop),
- make_number (i),
- make_number (row->y),
- make_number (crop));
+ return list4i (row->height + min (0, row->y) - crop, i, row->y, crop);
}
DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p,
More precisely, return the value assigned by the last call of
`set-window-dedicated-p' for WINDOW. Return nil if that function was
never called with WINDOW as its argument, or the value set by that
-function was internally reset since its last call. WINDOW defaults to
-the selected window.
+function was internally reset since its last call. WINDOW must be a
+live window and defaults to the selected one.
When a window is dedicated to its buffer, `display-buffer' will refrain
from displaying another buffer in it. `get-lru-window' and
is the value returned by `window-dedicated-p' is t. */)
(Lisp_Object window)
{
- return decode_window (window)->dedicated;
+ return decode_live_window (window)->dedicated;
}
DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p,
window, it also makes sure that the window is no more dedicated. */)
(Lisp_Object window, Lisp_Object flag)
{
- register struct window *w = decode_window (window);
-
- w->dedicated = flag;
- return w->dedicated;
+ wset_dedicated (decode_live_window (window), flag);
+ return flag;
}
DEFUN ("window-prev-buffers", Fwindow_prev_buffers, Swindow_prev_buffers,
window for that buffer, and POS is a window-specific point value. */)
(Lisp_Object window)
{
- return decode_window (window)->prev_buffers;
+ return decode_live_window (window)->prev_buffers;
}
DEFUN ("set-window-prev-buffers", Fset_window_prev_buffers,
window for that buffer, and POS is a window-specific point value. */)
(Lisp_Object window, Lisp_Object prev_buffers)
{
- return decode_window (window)->prev_buffers = prev_buffers;
+ wset_prev_buffers (decode_live_window (window), prev_buffers);
+ return prev_buffers;
}
DEFUN ("window-next-buffers", Fwindow_next_buffers, Swindow_next_buffers,
WINDOW must be a live window and defaults to the selected one. */)
(Lisp_Object window)
{
- return decode_window (window)->next_buffers;
+ return decode_live_window (window)->next_buffers;
}
DEFUN ("set-window-next-buffers", Fset_window_next_buffers,
NEXT-BUFFERS should be a list of buffers. */)
(Lisp_Object window, Lisp_Object next_buffers)
{
- return decode_window (window)->next_buffers = next_buffers;
+ wset_next_buffers (decode_live_window (window), next_buffers);
+ return next_buffers;
}
DEFUN ("window-parameters", Fwindow_parameters, Swindow_parameters,
0, 1, 0,
doc: /* Return the parameters of WINDOW and their values.
-WINDOW defaults to the selected window. The return value is a list of
-elements of the form (PARAMETER . VALUE). */)
+WINDOW must be a valid window and defaults to the selected one. The
+return value is a list of elements of the form (PARAMETER . VALUE). */)
(Lisp_Object window)
{
- return Fcopy_alist (decode_any_window (window)->window_parameters);
+ return Fcopy_alist (decode_valid_window (window)->window_parameters);
}
DEFUN ("window-parameter", Fwindow_parameter, Swindow_parameter,
2, 2, 0,
doc: /* Return WINDOW's value for PARAMETER.
-WINDOW defaults to the selected window. */)
+WINDOW can be any window and defaults to the selected one. */)
(Lisp_Object window, Lisp_Object parameter)
{
Lisp_Object result;
DEFUN ("set-window-parameter", Fset_window_parameter,
Sset_window_parameter, 3, 3, 0,
doc: /* Set WINDOW's value of PARAMETER to VALUE.
-WINDOW defaults to the selected window. Return VALUE. */)
+WINDOW can be any window and defaults to the selected one.
+Return VALUE. */)
(Lisp_Object window, Lisp_Object parameter, Lisp_Object value)
{
register struct window *w = decode_any_window (window);
old_alist_elt = Fassq (parameter, w->window_parameters);
if (NILP (old_alist_elt))
- w->window_parameters = Fcons (Fcons (parameter, value), w->window_parameters);
+ wset_window_parameters
+ (w, Fcons (Fcons (parameter, value), w->window_parameters));
else
Fsetcdr (old_alist_elt, value);
return value;
DEFUN ("window-display-table", Fwindow_display_table, Swindow_display_table,
0, 1, 0,
doc: /* Return the display-table that WINDOW is using.
-WINDOW defaults to the selected window. */)
+WINDOW must be a live window and defaults to the selected one. */)
(Lisp_Object window)
{
- return decode_window (window)->display_table;
+ return decode_live_window (window)->display_table;
}
/* Get the display table for use on window W. This is either W's
if (DISP_TABLE_P (w->display_table))
dp = XCHAR_TABLE (w->display_table);
- else if (BUFFERP (w->buffer))
+ else if (BUFFERP (w->contents))
{
- struct buffer *b = XBUFFER (w->buffer);
+ struct buffer *b = XBUFFER (w->contents);
if (DISP_TABLE_P (BVAR (b, display_table)))
dp = XCHAR_TABLE (BVAR (b, display_table));
}
DEFUN ("set-window-display-table", Fset_window_display_table, Sset_window_display_table, 2, 2, 0,
- doc: /* Set WINDOW's display-table to TABLE. */)
+ doc: /* Set WINDOW's display-table to TABLE.
+WINDOW must be a live window and defaults to the selected one. */)
(register Lisp_Object window, Lisp_Object table)
{
- register struct window *w;
-
- w = decode_window (window);
- w->display_table = table;
+ wset_display_table (decode_live_window (window), table);
return table;
}
\f
static void
unshow_buffer (register struct window *w)
{
- Lisp_Object buf;
- struct buffer *b;
+ Lisp_Object buf = w->contents;
+ struct buffer *b = XBUFFER (buf);
- buf = w->buffer;
- b = XBUFFER (buf);
- if (b != XMARKER (w->pointm)->buffer)
- abort ();
+ eassert (b == XMARKER (w->pointm)->buffer);
#if 0
if (w == XWINDOW (selected_window)
- || ! EQ (buf, XWINDOW (selected_window)->buffer))
+ || ! EQ (buf, XWINDOW (selected_window)->contents))
/* Do this except when the selected window's buffer
is being removed from some other window. */
#endif
/* Point in the selected window's buffer
is actually stored in that buffer, and the window's pointm isn't used.
So don't clobber point in that buffer. */
- if (! EQ (buf, XWINDOW (selected_window)->buffer)
+ if (! EQ (buf, XWINDOW (selected_window)->contents)
+ /* Don't clobber point in current buffer either (this could be
+ useful in connection with bug#12208).
+ && XBUFFER (buf) != current_buffer */
/* This line helps to fix Horsley's testbug.el bug. */
&& !(WINDOWP (BVAR (b, last_selected_window))
&& w != XWINDOW (BVAR (b, last_selected_window))
- && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->buffer)))
+ && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->contents)))
temp_set_point_both (b,
clip_to_bounds (BUF_BEGV (b),
- XMARKER (w->pointm)->charpos,
+ marker_position (w->pointm),
BUF_ZV (b)),
clip_to_bounds (BUF_BEGV_BYTE (b),
marker_byte_position (w->pointm),
if (WINDOWP (BVAR (b, last_selected_window))
&& w == XWINDOW (BVAR (b, last_selected_window)))
- BVAR (b, last_selected_window) = Qnil;
+ bset_last_selected_window (b, Qnil);
}
/* Put NEW into the window structure in place of OLD. SETFLAG zero
/* If OLD is its frame's root window, then NEW is the new
root window for that frame. */
if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame))))
- FRAME_ROOT_WINDOW (XFRAME (o->frame)) = new;
+ fset_root_window (XFRAME (o->frame), new);
if (setflag)
{
n->top_line = o->top_line;
n->total_cols = o->total_cols;
n->total_lines = o->total_lines;
- n->normal_cols = o->normal_cols;
- o->normal_cols = make_float (1.0);
- n->normal_lines = o->normal_lines;
- o->normal_lines = make_float (1.0);
+ wset_normal_cols (n, o->normal_cols);
+ wset_normal_cols (o, make_float (1.0));
+ wset_normal_lines (n, o->normal_lines);
+ wset_normal_lines (o, make_float (1.0));
n->desired_matrix = n->current_matrix = 0;
n->vscroll = 0;
memset (&n->cursor, 0, sizeof (n->cursor));
- memset (&n->last_cursor, 0, sizeof (n->last_cursor));
memset (&n->phys_cursor, 0, sizeof (n->phys_cursor));
+ n->last_cursor_vpos = 0;
n->phys_cursor_type = -1;
n->phys_cursor_width = -1;
n->must_be_updated_p = 0;
n->pseudo_window_p = 0;
- XSETFASTINT (n->window_end_vpos, 0);
- XSETFASTINT (n->window_end_pos, 0);
- n->window_end_valid = Qnil;
- n->frozen_window_start_p = 0;
+ n->window_end_vpos = 0;
+ n->window_end_pos = 0;
+ n->window_end_valid = 0;
}
- n->next = tem = o->next;
+ tem = o->next;
+ wset_next (n, tem);
if (!NILP (tem))
- XWINDOW (tem)->prev = new;
+ wset_prev (XWINDOW (tem), new);
- n->prev = tem = o->prev;
+ tem = o->prev;
+ wset_prev (n, tem);
if (!NILP (tem))
- XWINDOW (tem)->next = new;
+ wset_next (XWINDOW (tem), new);
- n->parent = tem = o->parent;
- if (!NILP (tem))
- {
- if (EQ (XWINDOW (tem)->vchild, old))
- XWINDOW (tem)->vchild = new;
- if (EQ (XWINDOW (tem)->hchild, old))
- XWINDOW (tem)->hchild = new;
- }
+ tem = o->parent;
+ wset_parent (n, tem);
+ if (!NILP (tem) && EQ (XWINDOW (tem)->contents, old))
+ wset_combination (XWINDOW (tem), XWINDOW (tem)->horizontal, new);
}
/* If window WINDOW and its parent window are iso-combined, merge
{
struct window *w, *p, *c;
Lisp_Object parent, child;
- int horflag;
+ bool horflag;
w = XWINDOW (window);
parent = w->parent;
if (!NILP (parent) && NILP (w->combination_limit))
{
p = XWINDOW (parent);
- if (((!NILP (p->vchild) && !NILP (w->vchild))
- || (!NILP (p->hchild) && !NILP (w->hchild))))
+ if (WINDOWP (p->contents) && WINDOWP (w->contents)
+ && p->horizontal == w->horizontal)
/* WINDOW and PARENT are both either a vertical or a horizontal
combination. */
{
- horflag = NILP (w->vchild);
- child = horflag ? w->hchild : w->vchild;
+ horflag = WINDOW_HORIZONTAL_COMBINATION_P (w);
+ child = w->contents;
c = XWINDOW (child);
/* Splice WINDOW's children into its parent's children and
assign new normal sizes. */
if (NILP (w->prev))
- if (horflag)
- p->hchild = child;
- else
- p->vchild = child;
+ wset_combination (p, horflag, child);
else
{
- c->prev = w->prev;
- XWINDOW (w->prev)->next = child;
+ wset_prev (c, w->prev);
+ wset_next (XWINDOW (w->prev), child);
}
while (c)
{
- c->parent = parent;
+ wset_parent (c, parent);
if (horflag)
- c->normal_cols
- = make_float (XFLOATINT (c->total_cols)
- / XFLOATINT (p->total_cols));
+ wset_normal_cols (c,
+ make_float ((double) c->total_cols
+ / (double) p->total_cols));
else
- c->normal_lines
- = make_float (XFLOATINT (c->total_lines)
- / XFLOATINT (p->total_lines));
+ wset_normal_lines (c,
+ make_float ((double) c->total_lines
+ / (double) p->total_lines));
if (NILP (c->next))
{
if (!NILP (w->next))
{
- c->next = w->next;
- XWINDOW (c->next)->prev = child;
+ wset_next (c, w->next);
+ wset_prev (XWINDOW (c->next), child);
}
c = 0;
}
/* WINDOW can be deleted now. */
- w->vchild = w->hchild = Qnil;
+ wset_combination (w, 0, Qnil);
}
}
}
static int
add_window_to_list (struct window *w, void *user_data)
{
- Lisp_Object *list = (Lisp_Object *) user_data;
+ Lisp_Object *list = user_data;
Lisp_Object window;
XSETWINDOW (window, w);
*list = Fcons (window, *list);
{
if (!CONSP (Vwindow_list))
{
- Lisp_Object tail;
+ Lisp_Object tail, frame;
Vwindow_list = Qnil;
- for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
+ FOR_EACH_FRAME (tail, frame)
{
Lisp_Object args[2];
new windows at the front of args[1], which means we
have to reverse this list at the end. */
args[1] = Qnil;
- foreach_window (XFRAME (XCAR (tail)), add_window_to_list, &args[1]);
+ foreach_window (XFRAME (frame), add_window_to_list, &args[1]);
args[0] = Vwindow_list;
args[1] = Fnreverse (args[1]);
Vwindow_list = Fnconc (2, args);
a window means search the frame that window belongs to,
a frame means consider windows on that frame, only. */
-static int
-candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf, Lisp_Object all_frames)
+static bool
+candidate_window_p (Lisp_Object window, Lisp_Object owindow,
+ Lisp_Object minibuf, Lisp_Object all_frames)
{
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
- int candidate_p = 1;
+ bool candidate_p = 1;
- if (!BUFFERP (w->buffer))
+ if (!BUFFERP (w->contents))
candidate_p = 0;
else if (MINI_WINDOW_P (w)
&& (EQ (minibuf, Qlambda)
candidate_p = 1;
else if (NILP (all_frames))
{
- xassert (WINDOWP (owindow));
+ eassert (WINDOWP (owindow));
candidate_p = EQ (w->frame, XWINDOW (owindow)->frame);
}
else if (EQ (all_frames, Qvisible))
{
- FRAME_SAMPLE_VISIBILITY (f);
candidate_p = FRAME_VISIBLE_P (f)
&& (FRAME_TERMINAL (XFRAME (w->frame))
== FRAME_TERMINAL (XFRAME (selected_frame)));
}
else if (INTEGERP (all_frames) && XINT (all_frames) == 0)
{
- FRAME_SAMPLE_VISIBILITY (f);
candidate_p = (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)
#ifdef HAVE_X_WINDOWS
/* Yuck!! If we've just created the frame and the
static void
decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames)
{
- if (NILP (*window))
- *window = selected_window;
- else
- CHECK_LIVE_WINDOW (*window);
+ struct window *w = decode_live_window (*window);
+ XSETWINDOW (*window, w);
/* MINIBUF nil may or may not include minibuffers. Decide if it
does. */
if (NILP (*minibuf))
/* ALL_FRAMES nil doesn't specify which frames to include. */
if (NILP (*all_frames))
- *all_frames = (!EQ (*minibuf, Qlambda)
- ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window)->frame))
- : Qnil);
+ *all_frames
+ = (!EQ (*minibuf, Qlambda)
+ ? FRAME_MINIBUF_WINDOW (XFRAME (w->frame))
+ : Qnil);
else if (EQ (*all_frames, Qvisible))
;
else if (EQ (*all_frames, make_number (0)))
GET_BUFFER_WINDOW, /* Arg is buffer */
REPLACE_BUFFER_IN_WINDOWS_SAFELY, /* Arg is buffer */
REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
- CHECK_ALL_WINDOWS
+ CHECK_ALL_WINDOWS /* Arg is ignored */
};
static Lisp_Object
switch (type)
{
case GET_BUFFER_WINDOW:
- if (EQ (w->buffer, obj)
+ if (EQ (w->contents, obj)
/* Don't find any minibuffer window except the one that
is currently in use. */
&& (MINI_WINDOW_P (w) ? EQ (window, minibuf_window) : 1))
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))
+ if (EQ (w->contents, obj))
{
/* Undedicate WINDOW. */
- w->dedicated = Qnil;
+ wset_dedicated (w, 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);
+ (window, other_buffer_safely (w->contents), 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);
+ && XBUFFER (w->contents) == current_buffer)
+ Fset_buffer (w->contents);
}
break;
case REDISPLAY_BUFFER_WINDOWS:
- if (EQ (w->buffer, obj))
+ if (EQ (w->contents, obj))
{
mark_window_display_accurate (window, 0);
w->update_mode_line = 1;
}
break;
- /* Check for a window that has a killed buffer. */
+ /* Check for a leaf window that has a killed buffer
+ or broken markers. */
case CHECK_ALL_WINDOWS:
- if (! NILP (w->buffer)
- && NILP (BVAR (XBUFFER (w->buffer), name)))
- abort ();
+ if (BUFFERP (w->contents))
+ {
+ struct buffer *b = XBUFFER (w->contents);
+
+ if (!BUFFER_LIVE_P (b))
+ emacs_abort ();
+ if (!MARKERP (w->start) || XMARKER (w->start)->buffer != b)
+ emacs_abort ();
+ if (!MARKERP (w->pointm) || XMARKER (w->pointm)->buffer != b)
+ emacs_abort ();
+ }
break;
case WINDOW_LOOP_UNUSED:
DEFUN ("delete-other-windows-internal", Fdelete_other_windows_internal,
Sdelete_other_windows_internal, 0, 2, "",
doc: /* Make WINDOW fill its frame.
-Only the frame WINDOW is on is affected. WINDOW may be any window and
-defaults to the selected one.
+Only the frame WINDOW is on is affected. WINDOW must be a valid window
+and defaults to the selected one.
Optional argument ROOT, if non-nil, must specify an internal window such
that WINDOW is in its window subtree. If this is the case, replace ROOT
struct window *w, *r, *s;
struct frame *f;
Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta;
- ptrdiff_t startpos IF_LINT (= 0);
+ ptrdiff_t startpos IF_LINT (= 0), startbyte IF_LINT (= 0);
int top IF_LINT (= 0), new_top, resize_failed;
- Mouse_HLInfo *hlinfo;
- w = decode_any_window (window);
+ w = decode_valid_window (window);
XSETWINDOW (window, w);
f = XFRAME (w->frame);
else
/* ROOT must be an ancestor of WINDOW. */
{
- r = decode_any_window (root);
+ r = decode_valid_window (root);
pwindow = XWINDOW (window)->parent;
while (!NILP (pwindow))
if (EQ (pwindow, root))
else if (MINI_WINDOW_P (w)) /* && top > 0) */
error ("Can't expand minibuffer to full frame");
- if (!NILP (w->buffer))
+ if (BUFFERP (w->contents))
{
startpos = marker_position (w->start);
+ startbyte = marker_byte_position (w->start);
top = WINDOW_TOP_EDGE_LINE (w)
- FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
/* Make sure WINDOW is the frame's selected window. */
if (EQ (selected_frame, w->frame))
Fselect_window (window, Qnil);
else
- FRAME_SELECTED_WINDOW (f) = window;
+ fset_selected_window (f, window);
}
}
else
if (EQ (selected_frame, w->frame))
Fselect_window (swindow, Qnil);
else
- FRAME_SELECTED_WINDOW (f) = swindow;
+ fset_selected_window (f, swindow);
}
}
- BLOCK_INPUT;
- hlinfo = MOUSE_HL_INFO (f);
- /* We are going to free the glyph matrices of WINDOW, and with that
- we might lose any information about glyph rows that have some of
- their glyphs highlighted in mouse face. (These rows are marked
- with a non-zero mouse_face_p flag.) If WINDOW indeed has some
- glyphs highlighted in mouse face, signal to frame's up-to-date
- hook that mouse highlight was overwritten, so that it will
- arrange for redisplaying the highlight. */
- if (EQ (hlinfo->mouse_face_window, window))
+ block_input ();
+ if (!FRAME_INITIAL_P (f))
{
- hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
- hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
- hlinfo->mouse_face_window = Qnil;
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+
+ /* We are going to free the glyph matrices of WINDOW, and with
+ that we might lose any information about glyph rows that have
+ some of their glyphs highlighted in mouse face. (These rows
+ are marked with a non-zero mouse_face_p flag.) If WINDOW
+ indeed has some glyphs highlighted in mouse face, signal to
+ frame's up-to-date hook that mouse highlight was overwritten,
+ so that it will arrange for redisplaying the highlight. */
+ if (EQ (hlinfo->mouse_face_window, window))
+ reset_mouse_highlight (hlinfo);
}
free_window_matrices (r);
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
resize_failed = 0;
- if (NILP (w->buffer))
+ if (!WINDOW_LEAF_P (w))
{
/* Resize child windows vertically. */
- XSETINT (delta, XINT (r->total_lines) - XINT (w->total_lines));
+ XSETINT (delta, r->total_lines - w->total_lines);
w->top_line = r->top_line;
resize_root_window (window, delta, Qnil, Qnil);
if (window_resize_check (w, 0))
if (!resize_failed)
{
w->left_col = r->left_col;
- XSETINT (delta, XINT (r->total_cols) - XINT (w->total_cols));
- w->left_col = r->left_col;
+ XSETINT (delta, r->total_cols - w->total_cols);
resize_root_window (window, delta, Qt, Qnil);
if (window_resize_check (w, 1))
window_resize_apply (w, 1);
{
sibling = w->prev;
s = XWINDOW (sibling);
- s->next = w->next;
+ wset_next (s, w->next);
if (!NILP (s->next))
- XWINDOW (s->next)->prev = sibling;
+ wset_prev (XWINDOW (s->next), sibling);
}
else
/* Get SIBLING below (on the right of) WINDOW. */
{
sibling = w->next;
s = XWINDOW (sibling);
- s->prev = Qnil;
- if (!NILP (XWINDOW (w->parent)->vchild))
- XWINDOW (w->parent)->vchild = sibling;
- else
- XWINDOW (w->parent)->hchild = sibling;
+ wset_prev (s, Qnil);
+ wset_combination (XWINDOW (w->parent),
+ XWINDOW (w->parent)->horizontal, sibling);
}
/* Delete ROOT and all child windows of ROOT. */
- if (!NILP (r->vchild))
- {
- delete_all_child_windows (r->vchild);
- r->vchild = Qnil;
- }
- else if (!NILP (r->hchild))
+ if (WINDOWP (r->contents))
{
- delete_all_child_windows (r->hchild);
- r->hchild = Qnil;
+ delete_all_child_windows (r->contents);
+ wset_combination (r, 0, Qnil);
}
replace_window (root, window, 1);
- /* This must become SWINDOW anyway ....... */
- if (!NILP (w->buffer) && !resize_failed)
+ /* This must become SWINDOW anyway ....... */
+ if (BUFFERP (w->contents) && !resize_failed)
{
/* Try to minimize scrolling, by setting the window start to the
point will cause the text at the old window start to be at the
when the display is not current, due to typeahead). */
new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
if (new_top != top
- && startpos >= BUF_BEGV (XBUFFER (w->buffer))
- && startpos <= BUF_ZV (XBUFFER (w->buffer)))
+ && startpos >= BUF_BEGV (XBUFFER (w->contents))
+ && startpos <= BUF_ZV (XBUFFER (w->contents)))
{
struct position pos;
struct buffer *obuf = current_buffer;
- Fset_buffer (w->buffer);
+ Fset_buffer (w->contents);
/* This computation used to temporarily move point, but that
can have unwanted side effects due to text properties. */
- pos = *vmotion (startpos, -top, w);
+ pos = *vmotion (startpos, startbyte, -top, w);
- set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
- w->window_end_valid = Qnil;
+ set_marker_both (w->start, w->contents, pos.bufpos, pos.bytepos);
+ w->window_end_valid = 0;
w->start_at_line_beg = (pos.bytepos == BEGV_BYTE
|| FETCH_BYTE (pos.bytepos - 1) == '\n');
/* We need to do this, so that the window-scroll-functions
}
adjust_glyphs (f);
- UNBLOCK_INPUT;
+ unblock_input ();
run_window_configuration_change_hook (f);
call1 (Qreplace_buffer_in_windows, buffer);
}
-
-/* Safely replace BUFFER with some other buffer in all windows of all
- frames, even those on other keyboards. */
+/* If BUFFER is shown in a window, safely replace it with some other
+ buffer in all windows of all frames, even those on other keyboards. */
void
replace_buffer_in_windows_safely (Lisp_Object buffer)
{
- Lisp_Object tail, frame;
+ if (buffer_window_count (XBUFFER (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. */
- FOR_EACH_FRAME (tail, frame)
- window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, 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. */
+ FOR_EACH_FRAME (tail, 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
minimum allowable size. */
void
-check_frame_size (FRAME_PTR frame, int *rows, int *cols)
+check_frame_size (struct frame *frame, int *rows, int *cols)
{
/* For height, we have to see:
how many windows the frame has at minimum (one or two),
if (WINDOW_RIGHT_MARGIN_COLS (w) > 0)
{
if (WINDOW_LEFT_MARGIN_COLS (w) > 0)
- w->left_margin_cols = w->right_margin_cols
- = make_number (margin_cols/2);
+ w->left_margin_cols = w->right_margin_cols = margin_cols / 2;
else
- w->right_margin_cols = make_number (margin_cols);
+ w->right_margin_cols = margin_cols;
}
else
- w->left_margin_cols = make_number (margin_cols);
+ w->left_margin_cols = margin_cols;
return 1;
}
\f
-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);
-static Lisp_Object Fset_window_scroll_bars (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
call0 (XCAR (funs));
}
-static Lisp_Object
+static void
select_window_norecord (Lisp_Object window)
{
- return WINDOW_LIVE_P (window)
- ? Fselect_window (window, Qt) : selected_window;
+ if (WINDOW_LIVE_P (window))
+ Fselect_window (window, Qt);
}
-static Lisp_Object
+static void
select_frame_norecord (Lisp_Object frame)
{
- return FRAME_LIVE_P (XFRAME (frame))
- ? Fselect_frame (frame, Qt) : selected_frame;
+ if (FRAME_LIVE_P (XFRAME (frame)))
+ Fselect_frame (frame, Qt);
}
void
/* Use the right buffer. Matters when running the local hooks. */
if (current_buffer != XBUFFER (Fwindow_buffer (Qnil)))
{
- record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+ record_unwind_current_buffer ();
Fset_buffer (Fwindow_buffer (Qnil));
}
if (SELECTED_FRAME () != f)
{
- record_unwind_protect (select_frame_norecord, Fselected_frame ());
+ record_unwind_protect (select_frame_norecord, selected_frame);
select_frame_norecord (frame);
}
buffer)))
{
ptrdiff_t inner_count = SPECPDL_INDEX ();
- record_unwind_protect (select_window_norecord, Fselected_window ());
+ record_unwind_protect (select_window_norecord, selected_window);
select_window_norecord (window);
run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
buffer));
}
DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook,
- Srun_window_configuration_change_hook, 1, 1, 0,
- doc: /* Run `window-configuration-change-hook' for FRAME. */)
- (Lisp_Object frame)
+ Srun_window_configuration_change_hook, 0, 1, 0,
+ doc: /* Run `window-configuration-change-hook' for FRAME.
+If FRAME is omitted or nil, it defaults to the selected frame. */)
+ (Lisp_Object frame)
{
- CHECK_LIVE_FRAME (frame);
- run_window_configuration_change_hook (XFRAME (frame));
+ run_window_configuration_change_hook (decode_live_frame (frame));
return Qnil;
}
reset from the buffer's local settings. */
void
-set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int keep_margins_p)
+set_window_buffer (Lisp_Object window, Lisp_Object buffer,
+ bool run_hooks_p, bool keep_margins_p)
{
struct window *w = XWINDOW (window);
struct buffer *b = XBUFFER (buffer);
ptrdiff_t count = SPECPDL_INDEX ();
- int samebuf = EQ (buffer, w->buffer);
+ int samebuf = EQ (buffer, w->contents);
- w->buffer = buffer;
+ wset_buffer (w, buffer);
if (EQ (window, selected_window))
- BVAR (b, last_selected_window) = window;
+ bset_last_selected_window (b, window);
/* Let redisplay errors through. */
b->display_error_modiff = 0;
/* Update time stamps of buffer display. */
if (INTEGERP (BVAR (b, display_count)))
- XSETINT (BVAR (b, display_count), XINT (BVAR (b, display_count)) + 1);
- BVAR (b, display_time) = Fcurrent_time ();
+ bset_display_count (b, make_number (XINT (BVAR (b, display_count)) + 1));
+ bset_display_time (b, Fcurrent_time ());
+
+ w->window_end_pos = 0;
+ w->window_end_vpos = 0;
+ w->last_cursor_vpos = 0;
- XSETFASTINT (w->window_end_pos, 0);
- XSETFASTINT (w->window_end_vpos, 0);
- memset (&w->last_cursor, 0, sizeof w->last_cursor);
- w->window_end_valid = Qnil;
if (!(keep_margins_p && samebuf))
{ /* If we're not actually changing the buffer, don't reset hscroll and
vscroll. This case happens for example when called from
Resetting hscroll and vscroll here is problematic for things like
image-mode and doc-view-mode since it resets the image's position
whenever we resize the frame. */
- w->hscroll = w->min_hscroll = make_number (0);
+ w->hscroll = w->min_hscroll = 0;
w->vscroll = 0;
set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
set_marker_restricted (w->start,
buffer);
w->start_at_line_beg = 0;
w->force_start = 0;
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
}
/* Maybe we could move this into the `if' but it's not obviously safe and
I doubt it's worth the trouble. */
because that might itself be a local variable. */
if (window_initialized)
{
- record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+ record_unwind_current_buffer ();
Fset_buffer (buffer);
}
if (!keep_margins_p)
{
/* Set left and right marginal area width etc. from buffer. */
-
- /* This may call adjust_window_margins three times, so
- temporarily disable window margins. */
- Lisp_Object save_left = w->left_margin_cols;
- Lisp_Object save_right = w->right_margin_cols;
-
- w->left_margin_cols = w->right_margin_cols = Qnil;
-
- Fset_window_fringes (window,
- BVAR (b, left_fringe_width), BVAR (b, right_fringe_width),
- BVAR (b, fringes_outside_margins));
-
- Fset_window_scroll_bars (window,
- BVAR (b, scroll_bar_width),
- BVAR (b, vertical_scroll_bar_type), Qnil);
-
- w->left_margin_cols = save_left;
- w->right_margin_cols = save_right;
-
- Fset_window_margins (window,
- BVAR (b, left_margin_cols), BVAR (b, right_margin_cols));
+ set_window_fringes (w, BVAR (b, left_fringe_width),
+ BVAR (b, right_fringe_width),
+ BVAR (b, fringes_outside_margins));
+ set_window_scroll_bars (w, BVAR (b, scroll_bar_width),
+ BVAR (b, vertical_scroll_bar_type), Qnil);
+ set_window_margins (w, BVAR (b, left_margin_cols),
+ BVAR (b, right_margin_cols));
+ apply_window_adjustment (w);
}
if (run_hooks_p)
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.
+WINDOW must 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
(register Lisp_Object window, Lisp_Object buffer_or_name, Lisp_Object keep_margins)
{
register Lisp_Object tem, buffer;
- register struct window *w = decode_window (window);
+ register struct window *w = decode_live_window (window);
XSETWINDOW (window, w);
buffer = Fget_buffer (buffer_or_name);
CHECK_BUFFER (buffer);
- if (NILP (BVAR (XBUFFER (buffer), name)))
+ if (!BUFFER_LIVE_P (XBUFFER (buffer)))
error ("Attempt to display deleted buffer");
- tem = w->buffer;
+ tem = w->contents;
if (NILP (tem))
error ("Window is deleted");
- else if (!EQ (tem, Qt))
- /* w->buffer is t when the window is first being set up. */
+ else
{
if (!EQ (tem, buffer))
{
else
/* WINDOW is weakly dedicated to its buffer, reset
dedication. */
- w->dedicated = Qnil;
+ wset_dedicated (w, Qnil);
call1 (Qrecord_window_buffer, window);
}
struct window *w = XWINDOW (object);
mark_window_display_accurate (object, 0);
w->update_mode_line = 1;
- if (BUFFERP (w->buffer))
- XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+ if (BUFFERP (w->contents))
+ XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
++update_mode_lines;
return Qt;
}
if (STRINGP (object))
object = Fget_buffer (object);
- if (BUFFERP (object) && !NILP (BVAR (XBUFFER (object), name)))
+ if (BUFFERP (object) && BUFFER_LIVE_P (XBUFFER (object))
+ && buffer_window_count (XBUFFER (object)))
{
- /* Walk all windows looking for buffer, and force update
- of each of those windows. */
-
+ /* If buffer is live and shown in at least one window, find
+ all windows showing this buffer and force update of them. */
object = window_loop (REDISPLAY_BUFFER_WINDOWS, object, 0, Qvisible);
return NILP (object) ? Qnil : Qt;
}
return Qnil;
}
-
+/* Obsolete since 24.3. */
void
temp_output_buffer_show (register Lisp_Object buf)
{
register Lisp_Object window;
register struct window *w;
- BVAR (XBUFFER (buf), directory) = BVAR (current_buffer, directory);
+ bset_directory (XBUFFER (buf), BVAR (current_buffer, directory));
Fset_buffer (buf);
BUF_SAVE_MODIFF (XBUFFER (buf)) = MODIFF;
if (!NILP (Vtemp_buffer_show_function))
call1 (Vtemp_buffer_show_function, buf);
- else
+ else if (WINDOW_LIVE_P (window = display_buffer (buf, Qnil, Qnil)))
{
- window = display_buffer (buf, Qnil, Qnil);
-
if (!EQ (XWINDOW (window)->frame, selected_frame))
Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
Vminibuf_scroll_window = window;
w = XWINDOW (window);
- XSETFASTINT (w->hscroll, 0);
- XSETFASTINT (w->min_hscroll, 0);
+ w->hscroll = 0;
+ w->min_hscroll = 0;
set_marker_restricted_both (w->start, buf, BEG, BEG);
set_marker_restricted_both (w->pointm, buf, BEG, BEG);
Note: Both Fselect_window and select_window_norecord may
set-buffer to the buffer displayed in the window,
so we need to save the current buffer. --stef */
- record_unwind_protect (Fset_buffer, prev_buffer);
+ record_unwind_protect (restore_buffer, prev_buffer);
record_unwind_protect (select_window_norecord, prev_window);
Fselect_window (window, Qt);
- Fset_buffer (w->buffer);
+ Fset_buffer (w->contents);
Frun_hooks (1, &Qtemp_buffer_show_hook);
unbind_to (count, Qnil);
}
}
}
-
-DEFUN ("internal-temp-output-buffer-show",
- Ftemp_output_buffer_show, Stemp_output_buffer_show,
- 1, 1, 0,
- doc: /* Internal function for `with-output-to-temp-buffer'. */)
- (Lisp_Object buf)
-{
- temp_output_buffer_show (buf);
- return Qnil;
-}
\f
/* Make new window, have it replace WINDOW in window-tree, and make
WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only
horizontal child). */
static void
-make_parent_window (Lisp_Object window, int horflag)
+make_parent_window (Lisp_Object window, bool horflag)
{
Lisp_Object parent;
register struct window *o, *p;
- int i;
o = XWINDOW (window);
p = allocate_window ();
- for (i = 0; i < VECSIZE (struct window); ++i)
- ((struct Lisp_Vector *) p)->contents[i]
- = ((struct Lisp_Vector *) o)->contents[i];
+ memcpy ((char *) p + sizeof (struct vectorlike_header),
+ (char *) o + sizeof (struct vectorlike_header),
+ word_size * VECSIZE (struct window));
+ /* P's buffer slot may change from nil to a buffer... */
+ adjust_window_count (p, 1);
XSETWINDOW (parent, p);
- ++sequence_number;
- XSETFASTINT (p->sequence_number, sequence_number);
-
replace_window (window, parent, 1);
- o->next = Qnil;
- o->prev = Qnil;
- o->parent = parent;
-
- p->hchild = horflag ? window : Qnil;
- p->vchild = horflag ? Qnil : window;
- p->start = Qnil;
- p->pointm = Qnil;
- p->buffer = Qnil;
- p->combination_limit = Qnil;
- p->window_parameters = Qnil;
+ wset_next (o, Qnil);
+ wset_prev (o, Qnil);
+ wset_parent (o, parent);
+ /* ...but now P becomes an internal window. */
+ wset_start (p, Qnil);
+ wset_pointm (p, Qnil);
+ wset_buffer (p, Qnil);
+ wset_combination (p, horflag, window);
+ wset_combination_limit (p, Qnil);
+ wset_window_parameters (p, Qnil);
}
/* Make new window from scratch. */
register struct window *w;
w = allocate_window ();
- /* Initialize all Lisp data. */
- w->frame = Qnil;
- w->mini = 0;
- w->next = w->prev = w->hchild = w->vchild = w->parent = Qnil;
- XSETFASTINT (w->left_col, 0);
- XSETFASTINT (w->top_line, 0);
- XSETFASTINT (w->total_lines, 0);
- XSETFASTINT (w->total_cols, 0);
- w->normal_lines = make_float (1.0);
- w->normal_cols = make_float (1.0);
- XSETFASTINT (w->new_total, 0);
- XSETFASTINT (w->new_normal, 0);
- w->buffer = Qnil;
- w->start = Fmake_marker ();
- w->pointm = Fmake_marker ();
- w->force_start = w->optional_new_start = 0;
- XSETFASTINT (w->hscroll, 0);
- XSETFASTINT (w->min_hscroll, 0);
- XSETFASTINT (w->use_time, 0);
- ++sequence_number;
- XSETFASTINT (w->sequence_number, sequence_number);
- w->temslot = w->last_modified = w->last_overlay_modified = Qnil;
- XSETFASTINT (w->last_point, 0);
- w->last_had_star = 0;
- w->vertical_scroll_bar = Qnil;
- w->left_margin_cols = w->right_margin_cols = Qnil;
- w->left_fringe_width = w->right_fringe_width = Qnil;
- w->fringes_outside_margins = Qnil;
- w->scroll_bar_width = Qnil;
- w->vertical_scroll_bar_type = Qt;
- XSETFASTINT (w->window_end_pos, 0);
- XSETFASTINT (w->window_end_vpos, 0);
- w->window_end_valid = w->display_table = Qnil;
- w->update_mode_line = w->start_at_line_beg = 0;
- w->dedicated = Qnil;
- w->base_line_number = w->base_line_pos = w->region_showing = Qnil;
- w->column_number_displayed = w->redisplay_end_trigger = Qnil;
- w->combination_limit = w->window_parameters = Qnil;
- w->prev_buffers = w->next_buffers = Qnil;
- /* Initialize non-Lisp data. */
- w->desired_matrix = w->current_matrix = 0;
+ /* Initialize Lisp data. Note that allocate_window initializes all
+ Lisp data to nil, so do it only for slots which should not be nil. */
+ wset_normal_lines (w, make_float (1.0));
+ wset_normal_cols (w, make_float (1.0));
+ wset_new_total (w, make_number (0));
+ wset_new_normal (w, make_number (0));
+ wset_start (w, Fmake_marker ());
+ wset_pointm (w, Fmake_marker ());
+ wset_vertical_scroll_bar_type (w, Qt);
+ /* These Lisp fields are marked specially so they're not set to nil by
+ allocate_window. */
+ wset_prev_buffers (w, Qnil);
+ wset_next_buffers (w, Qnil);
+
+ /* Initialize non-Lisp data. Note that allocate_window zeroes out all
+ non-Lisp data, so do it only for slots which should not be zero. */
w->nrows_scale_factor = w->ncols_scale_factor = 1;
- memset (&w->cursor, 0, sizeof (w->cursor));
- memset (&w->last_cursor, 0, sizeof (w->last_cursor));
- memset (&w->phys_cursor, 0, sizeof (w->phys_cursor));
+ w->left_fringe_width = w->right_fringe_width = -1;
w->phys_cursor_type = -1;
w->phys_cursor_width = -1;
- w->phys_cursor_on_p = 0;
- w->last_cursor_off_p = w->cursor_off_p = 0;
- w->must_be_updated_p = 0;
- w->pseudo_window_p = 0;
- w->frozen_window_start_p = 0;
- w->vscroll = 0;
+ w->scroll_bar_width = -1;
+ w->column_number_displayed = -1;
+
/* Reset window_list. */
Vwindow_list = Qnil;
/* Return window. */
\f
DEFUN ("set-window-new-total", Fset_window_new_total, Sset_window_new_total, 2, 3, 0,
doc: /* Set new total size of WINDOW to SIZE.
+WINDOW must be a valid window and defaults to the selected one.
Return SIZE.
Optional argument ADD non-nil means add SIZE to the new total size of
Note: This function does not operate on any child windows of WINDOW. */)
(Lisp_Object window, Lisp_Object size, Lisp_Object add)
{
- struct window *w = decode_any_window (window);
+ struct window *w = decode_valid_window (window);
CHECK_NUMBER (size);
if (NILP (add))
- XSETINT (w->new_total, XINT (size));
+ wset_new_total (w, size);
else
- XSETINT (w->new_total, XINT (w->new_total) + XINT (size));
+ wset_new_total (w, make_number (XINT (w->new_total) + XINT (size)));
return w->new_total;
}
DEFUN ("set-window-new-normal", Fset_window_new_normal, Sset_window_new_normal, 1, 2, 0,
doc: /* Set new normal size of WINDOW to SIZE.
+WINDOW must be a valid window and defaults to the selected one.
Return SIZE.
Note: This function does not operate on any child windows of WINDOW. */)
(Lisp_Object window, Lisp_Object size)
{
- struct window *w = decode_any_window (window);
-
- w->new_normal = size;
- return w->new_normal;
+ wset_new_normal (decode_valid_window (window), size);
+ return size;
}
/* Return 1 if setting w->total_lines (w->total_cols if HORFLAG is
`window-min-height' or `window-min-width'. It does check that window
sizes do not drop below one line (two columns). */
static int
-window_resize_check (struct window *w, int horflag)
+window_resize_check (struct window *w, bool horflag)
{
struct window *c;
- if (!NILP (w->vchild))
+ if (WINDOW_VERTICAL_COMBINATION_P (w))
/* W is a vertical combination. */
{
- c = XWINDOW (w->vchild);
+ c = XWINDOW (w->contents);
if (horflag)
/* All child windows of W must have the same width as W. */
{
return (sum_of_sizes == XINT (w->new_total));
}
}
- else if (!NILP (w->hchild))
+ else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
/* W is a horizontal combination. */
{
- c = XWINDOW (w->hchild);
+ c = XWINDOW (w->contents);
if (horflag)
/* The sum of the widths of the child windows of W must equal W's
width. */
This function does not perform any error checks. Make sure you have
run window_resize_check on W before applying this function. */
static void
-window_resize_apply (struct window *w, int horflag)
+window_resize_apply (struct window *w, bool horflag)
{
struct window *c;
int pos;
parent window has been set *before*. */
if (horflag)
{
- w->total_cols = w->new_total;
+ w->total_cols = XFASTINT (w->new_total);
if (NUMBERP (w->new_normal))
- w->normal_cols = w->new_normal;
+ wset_normal_cols (w, w->new_normal);
- pos = XINT (w->left_col);
+ pos = w->left_col;
}
else
{
- w->total_lines = w->new_total;
+ w->total_lines = XFASTINT (w->new_total);
if (NUMBERP (w->new_normal))
- w->normal_lines = w->new_normal;
+ wset_normal_lines (w, w->new_normal);
- pos = XINT (w->top_line);
+ pos = w->top_line;
}
- if (!NILP (w->vchild))
+ if (WINDOW_VERTICAL_COMBINATION_P (w))
/* W is a vertical combination. */
{
- c = XWINDOW (w->vchild);
+ c = XWINDOW (w->contents);
while (c)
{
if (horflag)
- XSETFASTINT (c->left_col, pos);
+ c->left_col = pos;
else
- XSETFASTINT (c->top_line, pos);
+ c->top_line = pos;
window_resize_apply (c, horflag);
if (!horflag)
- pos = pos + XINT (c->total_lines);
+ pos = pos + c->total_lines;
c = NILP (c->next) ? 0 : XWINDOW (c->next);
}
}
- else if (!NILP (w->hchild))
+ else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
/* W is a horizontal combination. */
{
- c = XWINDOW (w->hchild);
+ c = XWINDOW (w->contents);
while (c)
{
if (horflag)
- XSETFASTINT (c->left_col, pos);
+ c->left_col = pos;
else
- XSETFASTINT (c->top_line, pos);
+ c->top_line = pos;
window_resize_apply (c, horflag);
if (horflag)
- pos = pos + XINT (c->total_cols);
+ pos = pos + c->total_cols;
c = NILP (c->next) ? 0 : XWINDOW (c->next);
}
}
-
- /* Clear out some redisplay caches. */
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
}
-DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 1, 2, 0,
+DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 0, 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.
+If FRAME is omitted or nil, it defaults to the selected frame.
+
+Optional argument HORIZONTAL omitted or nil means apply requested
+height values. HORIZONTAL non-nil means apply requested width values.
This function checks whether the requested values sum up to a valid
window layout, recursively assigns the new sizes of all child windows
be applied on the Elisp level. */)
(Lisp_Object frame, Lisp_Object horizontal)
{
- struct frame *f;
- struct window *r;
- int horflag = !NILP (horizontal);
-
- if (NILP (frame))
- frame = selected_frame;
- CHECK_LIVE_FRAME (frame);
-
- f = XFRAME (frame);
- r = XWINDOW (FRAME_ROOT_WINDOW (f));
+ struct frame *f = decode_live_frame (frame);
+ struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
+ bool horflag = !NILP (horizontal);
if (!window_resize_check (r, horflag)
- || ! EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
+ || (XINT (r->new_total)
+ != (horflag ? r->total_cols : r->total_lines)))
return Qnil;
- BLOCK_INPUT;
+ block_input ();
window_resize_apply (r, horflag);
windows_or_buffers_changed++;
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
adjust_glyphs (f);
- UNBLOCK_INPUT;
+ unblock_input ();
run_window_configuration_change_hook (f);
satisfy the request. The result will be meaningful if and only if
F's windows have meaningful sizes when you call this. */
void
-resize_frame_windows (struct frame *f, int size, int horflag)
+resize_frame_windows (struct frame *f, int size, bool horflag)
{
Lisp_Object root = f->root_window;
struct window *r = XWINDOW (root);
- ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
? 1 : 0)));
- XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
- if (NILP (r->vchild) && NILP (r->hchild))
+ r->top_line = FRAME_TOP_MARGIN (f);
+ if (WINDOW_LEAF_P (r))
/* For a leaf root window just set the size. */
if (horflag)
- XSETFASTINT (r->total_cols, new_size);
+ r->total_cols = new_size;
else
- XSETFASTINT (r->total_lines, new_size);
+ r->total_lines = new_size;
else
{
/* old_size is the old size of the frame's root window. */
- int old_size = XFASTINT (horflag ? r->total_cols : r->total_lines);
+ int old_size = horflag ? r->total_cols : r->total_lines;
Lisp_Object delta;
XSETINT (delta, new_size - old_size);
/* Try a "normal" resize first. */
resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil);
- if (window_resize_check (r, horflag) && new_size == XINT (r->new_total))
+ if (window_resize_check (r, horflag)
+ && new_size == XINT (r->new_total))
window_resize_apply (r, horflag);
else
{
root = f->selected_window;
Fdelete_other_windows_internal (root, Qnil);
if (horflag)
- XSETFASTINT (XWINDOW (root)->total_cols, new_size);
+ XWINDOW (root)->total_cols = new_size;
else
- XSETFASTINT (XWINDOW (root)->total_lines, new_size);
+ XWINDOW (root)->total_lines = new_size;
}
}
}
{
m = XWINDOW (mini);
if (horflag)
- XSETFASTINT (m->total_cols, size);
+ m->total_cols = size;
else
{
/* Are we sure we always want 1 line here? */
- XSETFASTINT (m->total_lines, 1);
- XSETFASTINT (m->top_line, XINT (r->top_line) + XINT (r->total_lines));
+ m->total_lines = 1;
+ m->top_line = r->top_line + r->total_lines;
}
}
+
+ windows_or_buffers_changed++;
}
register Lisp_Object new, frame, reference;
register struct window *o, *p, *n, *r;
struct frame *f;
- int horflag
+ bool horflag
/* HORFLAG is 1 when we split side-by-side, 0 otherwise. */
= EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
int combination_limit = 0;
We do that if either `window-combination-limit' is t, or OLD has no
parent, or OLD is ortho-combined. */
combination_limit =
- !NILP (Vwindow_combination_limit)
+ EQ (Vwindow_combination_limit, Qt)
|| NILP (o->parent)
- || NILP (horflag
- ? (XWINDOW (o->parent)->hchild)
- : (XWINDOW (o->parent)->vchild));
+ || (horflag
+ ? WINDOW_VERTICAL_COMBINATION_P (XWINDOW (o->parent))
+ : WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (o->parent)));
/* We need a live reference window to initialize some parameters. */
if (WINDOW_LIVE_P (old))
{
p = XWINDOW (o->parent);
/* Temporarily pretend we split the parent window. */
- XSETINT (p->new_total,
- XINT (horflag ? p->total_cols : p->total_lines)
- - XINT (total_size));
+ wset_new_total
+ (p, make_number ((horflag ? p->total_cols : p->total_lines)
+ - XINT (total_size)));
if (!window_resize_check (p, horflag))
error ("Window sizes don't fit");
else
/* Undo the temporary pretension. */
- p->new_total = horflag ? p->total_cols : p->total_lines;
+ wset_new_total (p, make_number
+ (horflag ? p->total_cols : p->total_lines));
}
else
{
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))
+ != (horflag ? o->total_cols : o->total_lines))
error ("Sum of sizes of old and new window don't fit");
}
/* Save the old value of o->normal_cols/lines. It gets corrupted
by make_parent_window and we need it below for assigning it to
p->new_normal. */
- Lisp_Object new_normal = horflag ? o->normal_cols : o->normal_lines;
+ Lisp_Object new_normal
+ = horflag ? o->normal_cols : o->normal_lines;
make_parent_window (old, horflag);
p = XWINDOW (o->parent);
- /* Store value of `window-combination-limit' in new parent's
- combination_limit slot. */
- p->combination_limit = Vwindow_combination_limit;
+ if (EQ (Vwindow_combination_limit, Qt))
+ /* Store t in the new parent's combination_limit slot to avoid
+ that its children get merged into another window. */
+ wset_combination_limit (p, Qt);
/* These get applied below. */
- p->new_total = horflag ? o->total_cols : o->total_lines;
- p->new_normal = new_normal;
+ wset_new_total (p, make_number
+ (horflag ? o->total_cols : o->total_lines));
+ wset_new_normal (p, new_normal);
}
else
p = XWINDOW (o->parent);
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
new = make_window ();
n = XWINDOW (new);
- n->frame = frame;
- n->parent = o->parent;
- n->vchild = n->hchild = Qnil;
+ wset_frame (n, frame);
+ wset_parent (n, o->parent);
if (EQ (side, Qabove) || EQ (side, Qleft))
{
- n->prev = o->prev;
+ wset_prev (n, o->prev);
if (NILP (n->prev))
- if (horflag)
- p->hchild = new;
- else
- p->vchild = new;
+ wset_combination (p, horflag, new);
else
- XWINDOW (n->prev)->next = new;
- n->next = old;
- o->prev = new;
+ wset_next (XWINDOW (n->prev), new);
+ wset_next (n, old);
+ wset_prev (o, new);
}
else
{
- n->next = o->next;
+ wset_next (n, o->next);
if (!NILP (n->next))
- XWINDOW (n->next)->prev = new;
- n->prev = old;
- o->next = new;
+ wset_prev (XWINDOW (n->next), new);
+ wset_prev (n, old);
+ wset_next (o, new);
}
- n->buffer = Qt;
- n->window_end_valid = Qnil;
- memset (&n->last_cursor, 0, sizeof n->last_cursor);
+ n->window_end_valid = 0;
+ n->last_cursor_vpos = 0;
/* Get special geometry settings from reference window. */
n->left_margin_cols = r->left_margin_cols;
n->right_fringe_width = r->right_fringe_width;
n->fringes_outside_margins = r->fringes_outside_margins;
n->scroll_bar_width = r->scroll_bar_width;
- n->vertical_scroll_bar_type = r->vertical_scroll_bar_type;
+ wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type);
/* Directly assign orthogonal coordinates and sizes. */
if (horflag)
/* Iso-coordinates and sizes are assigned by window_resize_apply,
get them ready here. */
- n->new_total = total_size;
- n->new_normal = normal_size;
+ wset_new_total (n, total_size);
+ wset_new_normal (n, normal_size);
- BLOCK_INPUT;
+ block_input ();
window_resize_apply (p, horflag);
adjust_glyphs (f);
/* Set buffer of NEW to buffer of reference window. Don't run
any hooks. */
- set_window_buffer (new, r->buffer, 0, 1);
- UNBLOCK_INPUT;
+ set_window_buffer (new, r->contents, 0, 1);
+ unblock_input ();
/* Maybe we should run the scroll functions in Elisp (which already
runs the configuration change hook). */
register Lisp_Object parent, sibling, frame, root;
struct window *w, *p, *s, *r;
struct frame *f;
- int horflag;
- int before_sibling = 0;
+ bool horflag, before_sibling = 0;
w = decode_any_window (window);
XSETWINDOW (window, w);
- if (NILP (w->buffer) && NILP (w->hchild) && NILP (w->vchild))
+ if (NILP (w->contents))
/* It's a no-op to delete an already deleted window. */
return Qnil;
error ("Attempt to delete sole window of parent");
p = XWINDOW (parent);
- horflag = NILP (p->vchild);
+ horflag = WINDOW_HORIZONTAL_COMBINATION_P (p);
frame = WINDOW_FRAME (w);
f = XFRAME (frame);
before_sibling = 1;
sibling = w->next;
s = XWINDOW (sibling);
- s->prev = Qnil;
- if (horflag)
- p->hchild = sibling;
- else
- p->vchild = sibling;
+ wset_prev (s, Qnil);
+ wset_combination (p, horflag, sibling);
}
else
/* Get SIBLING above (on the left of) WINDOW. */
{
sibling = w->prev;
s = XWINDOW (sibling);
- s->next = w->next;
+ wset_next (s, w->next);
if (!NILP (s->next))
- XWINDOW (s->next)->prev = sibling;
+ wset_prev (XWINDOW (s->next), sibling);
}
if (window_resize_check (r, horflag)
- && EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
+ && (XINT (r->new_total)
+ == (horflag ? r->total_cols : r->total_lines)))
/* We can delete WINDOW now. */
{
- Mouse_HLInfo *hlinfo;
/* Block input. */
- BLOCK_INPUT;
+ block_input ();
window_resize_apply (p, horflag);
/* If this window is referred to by the dpyinfo's mouse
highlight, invalidate that slot to be safe (Bug#9904). */
- hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
- if (EQ (hlinfo->mouse_face_window, window))
- hlinfo->mouse_face_window = Qnil;
+ if (!FRAME_INITIAL_P (f))
+ {
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+
+ if (EQ (hlinfo->mouse_face_window, window))
+ hlinfo->mouse_face_window = Qnil;
+ }
windows_or_buffers_changed++;
Vwindow_list = Qnil;
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
- w->next = Qnil; /* Don't delete w->next too. */
+ wset_next (w, Qnil); /* Don't delete w->next too. */
free_window_matrices (w);
- if (!NILP (w->vchild))
+ if (WINDOWP (w->contents))
{
- delete_all_child_windows (w->vchild);
- w->vchild = Qnil;
+ delete_all_child_windows (w->contents);
+ wset_combination (w, 0, Qnil);
}
- else if (!NILP (w->hchild))
- {
- delete_all_child_windows (w->hchild);
- w->hchild = Qnil;
- }
- else if (!NILP (w->buffer))
+ else
{
unshow_buffer (w);
unchain_marker (XMARKER (w->pointm));
unchain_marker (XMARKER (w->start));
- w->buffer = Qnil;
+ wset_buffer (w, Qnil);
}
if (NILP (s->prev) && NILP (s->next))
replace_window (parent, sibling, 0);
/* Have SIBLING inherit the following three slot values from
PARENT (the combination_limit slot is not inherited). */
- s->normal_cols = p->normal_cols;
- s->normal_lines = p->normal_lines;
+ wset_normal_cols (s, p->normal_cols);
+ wset_normal_lines (s, p->normal_lines);
/* Mark PARENT as deleted. */
- p->vchild = p->hchild = Qnil;
+ wset_combination (p, 0, Qnil);
/* Try to merge SIBLING into its new parent. */
recombine_windows (sibling);
}
if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
Fselect_window (new_selected_window, Qt);
else
- FRAME_SELECTED_WINDOW (f) = new_selected_window;
+ fset_selected_window (f, new_selected_window);
- UNBLOCK_INPUT;
+ unblock_input ();
/* Now look whether `get-mru-window' gets us something. */
mru_window = call1 (Qget_mru_window, frame);
if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
Fselect_window (new_selected_window, Qnil);
else
- FRAME_SELECTED_WINDOW (f) = new_selected_window;
+ fset_selected_window (f, new_selected_window);
}
else
- UNBLOCK_INPUT;
+ unblock_input ();
/* Must be run by the caller:
run_window_configuration_change_hook (f); */
{
if (before_sibling)
{
- s->prev = window;
- if (horflag)
- p->hchild = window;
- else
- p->vchild = window;
+ wset_prev (s, window);
+ wset_combination (p, horflag, window);
}
else
{
- s->next = window;
+ wset_next (s, window);
if (!NILP (w->next))
- XWINDOW (w->next)->prev = window;
+ wset_prev (XWINDOW (w->next), window);
}
error ("Deletion failed");
}
struct window *r;
Lisp_Object root, value;
- xassert (MINI_WINDOW_P (w));
- xassert (delta >= 0);
+ eassert (MINI_WINDOW_P (w));
+ eassert (delta >= 0);
root = FRAME_ROOT_WINDOW (f);
r = XWINDOW (root);
root, make_number (- delta));
if (INTEGERP (value) && window_resize_check (r, 0))
{
- BLOCK_INPUT;
+ block_input ();
window_resize_apply (r, 0);
/* Grow the mini-window. */
- XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
- XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - XINT (value));
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
-
+ w->top_line = r->top_line + r->total_lines;
+ w->total_lines -= XINT (value);
+ /* Enforce full redisplay. FIXME: make it more selective. */
+ windows_or_buffers_changed++;
adjust_glyphs (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
Lisp_Object root, value;
EMACS_INT size;
- xassert (MINI_WINDOW_P (w));
+ eassert (MINI_WINDOW_P (w));
- size = XINT (w->total_lines);
+ size = w->total_lines;
if (size > 1)
{
root = FRAME_ROOT_WINDOW (f);
root, make_number (size - 1));
if (INTEGERP (value) && window_resize_check (r, 0))
{
- BLOCK_INPUT;
+ block_input ();
window_resize_apply (r, 0);
/* Shrink the mini-window. */
- XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
- XSETFASTINT (w->total_lines, 1);
-
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
-
+ w->top_line = r->top_line + r->total_lines;
+ w->total_lines = 1;
+ /* Enforce full redisplay. FIXME: make it more selective. */
+ windows_or_buffers_changed++;
adjust_glyphs (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* If the above failed for whatever strange reason we must make a
one window frame here. The same routine will be needed when
error ("Cannot resize a minibuffer-only frame");
r = XWINDOW (FRAME_ROOT_WINDOW (f));
- height = XINT (r->total_lines) + XINT (w->total_lines);
+ height = r->total_lines + w->total_lines;
if (window_resize_check (r, 0)
&& XINT (w->new_total) > 0
&& height == XINT (r->new_total) + XINT (w->new_total))
{
- BLOCK_INPUT;
+ block_input ();
window_resize_apply (r, 0);
- w->total_lines = w->new_total;
- XSETFASTINT (w->top_line, XINT (r->top_line) + XINT (r->total_lines));
+ w->total_lines = XFASTINT (w->new_total);
+ w->top_line = r->top_line + r->total_lines;
windows_or_buffers_changed++;
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
adjust_glyphs (f);
- UNBLOCK_INPUT;
+ unblock_input ();
run_window_configuration_change_hook (f);
return Qt;
{
while (w)
{
- if (!NILP (w->hchild))
- mark_window_cursors_off (XWINDOW (w->hchild));
- else if (!NILP (w->vchild))
- mark_window_cursors_off (XWINDOW (w->vchild));
+ if (WINDOWP (w->contents))
+ mark_window_cursors_off (XWINDOW (w->contents));
else
w->phys_cursor_on_p = 0;
int
window_internal_height (struct window *w)
{
- int ht = XFASTINT (w->total_lines);
+ int ht = w->total_lines;
if (!MINI_WINDOW_P (w))
{
if (!NILP (w->parent)
- || !NILP (w->vchild)
- || !NILP (w->hchild)
+ || WINDOWP (w->contents)
|| !NILP (w->next)
|| !NILP (w->prev)
|| WINDOW_WANTS_MODELINE_P (w))
respectively. */
static void
-window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror)
+window_scroll (Lisp_Object window, EMACS_INT n, bool whole, int noerror)
{
immediate_quit = 1;
n = clip_to_bounds (INT_MIN, n, INT_MAX);
descriptions. */
static void
-window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
+window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
{
struct it it;
struct window *w = XWINDOW (window);
int vscrolled = 0;
int x, y, rtop, rbot, rowh, vpos;
void *itdata = NULL;
+ int window_total_lines;
+ int frame_line_height = default_line_pixel_height (w);
SET_TEXT_POS_FROM_MARKER (start, w->start);
/* Scrolling a minibuffer window via scroll bar when the echo area
if (rtop || rbot) /* partially visible */
{
int px;
- int dy = WINDOW_FRAME_LINE_HEIGHT (w);
+ int dy = frame_line_height;
if (whole)
dy = max ((window_box_height (w)
- next_screen_context_lines * dy),
else
spos = min (XINT (Fline_end_position (Qnil)) + 1, ZV);
set_marker_restricted (w->start, make_number (spos),
- w->buffer);
+ w->contents);
w->start_at_line_beg = 1;
w->update_mode_line = 1;
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
/* Set force_start so that redisplay_window will run the
window-scroll-functions. */
w->force_start = 1;
if (whole)
{
ptrdiff_t start_pos = IT_CHARPOS (it);
- int dy = WINDOW_FRAME_LINE_HEIGHT (w);
+ int dy = frame_line_height;
dy = max ((window_box_height (w)
- next_screen_context_lines * dy),
dy) * n;
/* If control gets here, then we vscrolled. */
- XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+ XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
/* Don't try to change the window start below. */
vscrolled = 1;
}
/* Set the window start, and set up the window for redisplay. */
- set_marker_restricted (w->start, make_number (pos),
- w->buffer);
- bytepos = XMARKER (w->start)->bytepos;
+ set_marker_restricted_both (w->start, w->contents, IT_CHARPOS (it),
+ IT_BYTEPOS (it));
+ bytepos = marker_byte_position (w->start);
w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n');
w->update_mode_line = 1;
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
/* Set force_start so that redisplay_window will run the
window-scroll-functions. */
w->force_start = 1;
/* Move PT out of scroll margins.
This code wants current_y to be zero at the window start position
even if there is a header line. */
+ window_total_lines
+ = w->total_lines * WINDOW_FRAME_LINE_HEIGHT (w) / frame_line_height;
this_scroll_margin = max (0, scroll_margin);
- this_scroll_margin = min (this_scroll_margin, XFASTINT (w->total_lines) / 4);
- this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
+ this_scroll_margin
+ = min (this_scroll_margin, window_total_lines / 4);
+ this_scroll_margin *= frame_line_height;
if (n > 0)
{
See the comment of window_scroll for parameter descriptions. */
static void
-window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
+window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
{
register struct window *w = XWINDOW (window);
/* Fvertical_motion enters redisplay, which can trigger
register ptrdiff_t pos, pos_byte;
register int ht = window_internal_height (w);
register Lisp_Object tem;
- int lose;
+ bool lose;
Lisp_Object bolp;
- ptrdiff_t startpos;
+ ptrdiff_t startpos = marker_position (w->start);
+ ptrdiff_t startbyte = marker_byte_position (w->start);
Lisp_Object original_pos = Qnil;
/* If scrolling screen-fulls, compute the number of lines to
if (whole)
n *= max (1, ht - next_screen_context_lines);
- startpos = marker_position (w->start);
-
if (!NILP (Vscroll_preserve_screen_position))
{
if (window_scroll_preserve_vpos <= 0
|| NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command)))
{
struct position posit
- = *compute_motion (startpos, 0, 0, 0,
- PT, ht, 0,
- -1, XINT (w->hscroll),
- 0, w);
+ = *compute_motion (startpos, startbyte, 0, 0, 0,
+ PT, ht, 0, -1, w->hscroll, 0, w);
window_scroll_preserve_vpos = posit.vpos;
- window_scroll_preserve_hpos = posit.hpos + XINT (w->hscroll);
+ window_scroll_preserve_hpos = posit.hpos + w->hscroll;
}
original_pos = Fcons (make_number (window_scroll_preserve_hpos),
{
Fvertical_motion (make_number (- (ht / 2)), window);
startpos = PT;
+ startbyte = PT_BYTE;
}
- SET_PT (startpos);
+ SET_PT_BOTH (startpos, startbyte);
lose = n < 0 && PT == BEGV;
Fvertical_motion (make_number (n), window);
pos = PT;
{
/* Don't use a scroll margin that is negative or too large. */
int this_scroll_margin =
- max (0, min (scroll_margin, XINT (w->total_lines) / 4));
+ max (0, min (scroll_margin, w->total_lines / 4));
- set_marker_restricted_both (w->start, w->buffer, pos, pos_byte);
+ set_marker_restricted_both (w->start, w->contents, pos, pos_byte);
w->start_at_line_beg = !NILP (bolp);
w->update_mode_line = 1;
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
/* Set force_start so that redisplay_window will run
the window-scroll-functions. */
w->force_start = 1;
{
ptrdiff_t count = SPECPDL_INDEX ();
- xassert (eabs (direction) == 1);
+ eassert (eabs (direction) == 1);
/* If selected window's buffer isn't current, make it current for
the moment. But don't screw up if window_scroll gets an error. */
- if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
+ if (XBUFFER (XWINDOW (selected_window)->contents) != current_buffer)
{
record_unwind_protect (save_excursion_restore, save_excursion_save ());
- Fset_buffer (XWINDOW (selected_window)->buffer);
+ Fset_buffer (XWINDOW (selected_window)->contents);
/* Make redisplay consider other windows than just selected_window. */
++windows_or_buffers_changed;
record_unwind_protect (save_excursion_restore, save_excursion_save ());
++windows_or_buffers_changed;
- Fset_buffer (w->buffer);
- SET_PT (marker_position (w->pointm));
+ Fset_buffer (w->contents);
+ SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm));
if (NILP (arg))
window_scroll (window, 1, 1, 1);
else
{
if (CONSP (arg))
- arg = Fcar (arg);
+ arg = XCAR (arg);
CHECK_NUMBER (arg);
window_scroll (window, XINT (arg), 0, 1);
}
by this function. This happens in an interactive call. */)
(register Lisp_Object arg, Lisp_Object set_minimum)
{
- Lisp_Object result;
- EMACS_INT hscroll;
struct window *w = XWINDOW (selected_window);
-
- if (NILP (arg))
- XSETFASTINT (arg, window_body_cols (w) - 2);
- else
- arg = Fprefix_numeric_value (arg);
-
- hscroll = XINT (w->hscroll) + XINT (arg);
- result = Fset_window_hscroll (selected_window, make_number (hscroll));
+ EMACS_INT requested_arg = (NILP (arg)
+ ? window_body_cols (w) - 2
+ : XINT (Fprefix_numeric_value (arg)));
+ Lisp_Object result = set_window_hscroll (w, w->hscroll + requested_arg);
if (!NILP (set_minimum))
w->min_hscroll = w->hscroll;
by this function. This happens in an interactive call. */)
(register Lisp_Object arg, Lisp_Object set_minimum)
{
- Lisp_Object result;
- EMACS_INT hscroll;
struct window *w = XWINDOW (selected_window);
-
- if (NILP (arg))
- XSETFASTINT (arg, window_body_cols (w) - 2);
- else
- arg = Fprefix_numeric_value (arg);
-
- hscroll = XINT (w->hscroll) - XINT (arg);
- result = Fset_window_hscroll (selected_window, make_number (hscroll));
+ EMACS_INT requested_arg = (NILP (arg)
+ ? window_body_cols (w) - 2
+ : XINT (Fprefix_numeric_value (arg)));
+ Lisp_Object result = set_window_hscroll (w, w->hscroll - requested_arg);
if (!NILP (set_minimum))
w->min_hscroll = w->hscroll;
int bottom_y;
void *itdata = NULL;
- if (XBUFFER (w->buffer) != current_buffer)
+ if (XBUFFER (w->contents) != current_buffer)
{
old_buffer = current_buffer;
- set_buffer_internal (XBUFFER (w->buffer));
+ set_buffer_internal (XBUFFER (w->contents));
}
else
old_buffer = NULL;
/* In case W->start is out of the accessible range, do something
reasonable. This happens in Info mode when Info-scroll-down
calls (recenter -1) while W->start is 1. */
- if (XMARKER (w->start)->charpos < BEGV)
- SET_TEXT_POS (start, BEGV, BEGV_BYTE);
- else if (XMARKER (w->start)->charpos > ZV)
- SET_TEXT_POS (start, ZV, ZV_BYTE);
- else
- SET_TEXT_POS_FROM_MARKER (start, w->start);
+ CLIP_TEXT_POS_FROM_MARKER (start, w->start);
itdata = bidi_shelve_cache ();
start_display (&it, w, start);
DEFUN ("recenter", Frecenter, Srecenter, 0, 1, "P",
doc: /* Center point in selected window and maybe redisplay frame.
-With prefix argument ARG, recenter putting point on screen line ARG
+With a numeric prefix argument ARG, recenter putting point on screen line ARG
relative to the selected window. If ARG is negative, it counts up from the
bottom of the window. (ARG should be less than the height of the window.)
(register Lisp_Object arg)
{
struct window *w = XWINDOW (selected_window);
- struct buffer *buf = XBUFFER (w->buffer);
+ struct buffer *buf = XBUFFER (w->contents);
struct buffer *obuf = current_buffer;
- int center_p = 0;
+ bool center_p = 0;
ptrdiff_t charpos, bytepos;
EMACS_INT iarg IF_LINT (= 0);
int this_scroll_margin;
/* Do this after making BUF current
in case scroll_margin is buffer-local. */
this_scroll_margin =
- max (0, min (scroll_margin, XFASTINT (w->total_lines) / 4));
+ max (0, min (scroll_margin, 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
iarg = max (iarg, this_scroll_margin);
- pos = *vmotion (PT, -iarg, w);
+ pos = *vmotion (PT, PT_BYTE, -iarg, w);
charpos = pos.bufpos;
bytepos = pos.bytepos;
}
iarg += ht;
/* Don't let it get into the margin at either top or bottom. */
- iarg = max (iarg, this_scroll_margin);
- iarg = min (iarg, ht - this_scroll_margin - 1);
+ iarg = clip_to_bounds (this_scroll_margin, iarg,
+ ht - this_scroll_margin - 1);
- pos = *vmotion (PT, - iarg, w);
+ pos = *vmotion (PT, PT_BYTE, - iarg, w);
charpos = pos.bufpos;
bytepos = pos.bytepos;
}
/* Set the new window start. */
- set_marker_both (w->start, w->buffer, charpos, bytepos);
- w->window_end_valid = Qnil;
+ set_marker_both (w->start, w->contents, charpos, bytepos);
+ w->window_end_valid = 0;
w->optional_new_start = 1;
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.
-If WINDOW is omitted or nil, it defaults to the selected window.
+WINDOW must be a live window and defaults to the selected one.
The returned height does not include the mode line, any header line,
nor any partial-height lines at the bottom of the text area. */)
(Lisp_Object window)
{
- struct window *w = decode_window (window);
+ struct window *w = decode_live_window (window);
int pixel_height = window_box_height (w);
int line_height = pixel_height / FRAME_LINE_HEIGHT (XFRAME (w->frame));
return make_number (line_height);
int this_scroll_margin;
#endif
- if (!(BUFFERP (w->buffer)
- && XBUFFER (w->buffer) == current_buffer))
- /* This test is needed to make sure PT/PT_BYTE make sense in w->buffer
+ if (!(BUFFERP (w->contents) && XBUFFER (w->contents) == current_buffer))
+ /* This test is needed to make sure PT/PT_BYTE make sense in w->contents
when passed below to set_marker_both. */
error ("move-to-window-line called from unrelated buffer");
{
int height = window_internal_height (w);
Fvertical_motion (make_number (- (height / 2)), window);
- set_marker_both (w->start, w->buffer, PT, PT_BYTE);
+ set_marker_both (w->start, w->contents, PT, PT_BYTE);
w->start_at_line_beg = !NILP (Fbolp ());
w->force_start = 1;
}
Lisp_Object saved_windows;
/* All fields above are traced by the GC.
- From `fame-cols' down, the fields are ignored by the GC. */
+ From `frame-cols' down, the fields are ignored by the GC. */
int frame_cols, frame_lines, frame_menu_bar_lines;
int frame_tool_bar_lines;
struct Lisp_Vector *saved_windows;
Lisp_Object new_current_buffer;
Lisp_Object frame;
- Lisp_Object auto_buffer_name;
- FRAME_PTR f;
+ struct frame *f;
ptrdiff_t old_point = -1;
CHECK_WINDOW_CONFIGURATION (configuration);
saved_windows = XVECTOR (data->saved_windows);
new_current_buffer = data->current_buffer;
- if (NILP (BVAR (XBUFFER (new_current_buffer), name)))
+ if (!BUFFER_LIVE_P (XBUFFER (new_current_buffer)))
new_current_buffer = Qnil;
else
{
window-point of the final-selected-window to the window-point of
the current-selected-window. So we have to be careful which
point of the current-buffer we copy into old_point. */
- if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)
+ if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
&& WINDOWP (selected_window)
- && EQ (XWINDOW (selected_window)->buffer, new_current_buffer)
+ && EQ (XWINDOW (selected_window)->contents, new_current_buffer)
&& !EQ (selected_window, data->current_window))
- old_point = XMARKER (XWINDOW (data->current_window)->pointm)->charpos;
+ old_point = marker_position (XWINDOW (data->current_window)->pointm);
else
old_point = PT;
else
So if possible we want this arbitrary choice of "which point" to
be the one from the to-be-selected-window so as to prevent this
window's cursor from being copied from another window. */
- if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)
+ if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
/* If current_window = selected_window, its point is in BUF_PT. */
&& !EQ (selected_window, data->current_window))
- old_point = XMARKER (XWINDOW (data->current_window)->pointm)->charpos;
+ old_point = marker_position (XWINDOW (data->current_window)->pointm);
else
old_point = BUF_PT (XBUFFER (new_current_buffer));
}
int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
int previous_frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
+ /* Don't do this within the main loop below: This may call Lisp
+ code and is thus potentially unsafe while input is blocked. */
+ for (k = 0; k < saved_windows->header.size; k++)
+ {
+ p = SAVED_WINDOW_N (saved_windows, k);
+ window = p->window;
+ w = XWINDOW (window);
+ if (BUFFERP (w->contents)
+ && !EQ (w->contents, p->buffer)
+ && BUFFER_LIVE_P (XBUFFER (p->buffer)))
+ /* If a window we restore gets another buffer, record the
+ window's old buffer. */
+ call1 (Qrecord_window_buffer, window);
+ }
+
/* The mouse highlighting code could get screwed up
if it runs during this. */
- BLOCK_INPUT;
+ block_input ();
if (data->frame_lines != previous_frame_lines
|| data->frame_cols != previous_frame_cols)
window holds garbage.) We do this now, before
restoring the window contents, and prevent it from
being done later on when we select a new window. */
- if (! NILP (XWINDOW (selected_window)->buffer))
+ if (! NILP (XWINDOW (selected_window)->contents))
{
w = XWINDOW (selected_window);
set_marker_both (w->pointm,
- w->buffer,
- BUF_PT (XBUFFER (w->buffer)),
- BUF_PT_BYTE (XBUFFER (w->buffer)));
+ w->contents,
+ BUF_PT (XBUFFER (w->contents)),
+ BUF_PT_BYTE (XBUFFER (w->contents)));
}
windows_or_buffers_changed++;
really like to do is to free only those matrices not reused
below. */
root_window = XWINDOW (FRAME_ROOT_WINDOW (f));
- leaf_windows
- = (struct window **) alloca (count_windows (root_window)
- * sizeof (struct window *));
+ leaf_windows = alloca (count_windows (root_window)
+ * sizeof *leaf_windows);
n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
/* Kludge Alert!
p = SAVED_WINDOW_N (saved_windows, k);
window = p->window;
w = XWINDOW (window);
- w->next = Qnil;
+ wset_next (w, Qnil);
if (!NILP (p->parent))
- w->parent = SAVED_WINDOW_N (saved_windows,
- XFASTINT (p->parent))->window;
+ wset_parent
+ (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->parent))->window);
else
- w->parent = Qnil;
+ wset_parent (w, Qnil);
if (!NILP (p->prev))
{
- w->prev = SAVED_WINDOW_N (saved_windows,
- XFASTINT (p->prev))->window;
- XWINDOW (w->prev)->next = p->window;
+ wset_prev
+ (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->prev))->window);
+ wset_next (XWINDOW (w->prev), p->window);
}
else
{
- w->prev = Qnil;
+ wset_prev (w, Qnil);
if (!NILP (w->parent))
- {
- if (EQ (p->total_cols, XWINDOW (w->parent)->total_cols))
- {
- XWINDOW (w->parent)->vchild = p->window;
- XWINDOW (w->parent)->hchild = Qnil;
- }
- else
- {
- XWINDOW (w->parent)->hchild = p->window;
- XWINDOW (w->parent)->vchild = Qnil;
- }
- }
+ wset_combination (XWINDOW (w->parent),
+ (XINT (p->total_cols)
+ != XWINDOW (w->parent)->total_cols),
+ p->window);
}
- /* If we squirreled away the buffer in the window's height,
- restore it now. */
- if (BUFFERP (w->total_lines))
- w->buffer = w->total_lines;
- w->left_col = p->left_col;
- w->top_line = p->top_line;
- w->total_cols = p->total_cols;
- w->total_lines = p->total_lines;
- w->normal_cols = p->normal_cols;
- w->normal_lines = p->normal_lines;
- w->hscroll = p->hscroll;
- w->min_hscroll = p->min_hscroll;
- w->display_table = p->display_table;
- w->left_margin_cols = p->left_margin_cols;
- w->right_margin_cols = p->right_margin_cols;
- w->left_fringe_width = p->left_fringe_width;
- w->right_fringe_width = p->right_fringe_width;
- w->fringes_outside_margins = p->fringes_outside_margins;
- w->scroll_bar_width = p->scroll_bar_width;
- w->vertical_scroll_bar_type = p->vertical_scroll_bar_type;
- w->dedicated = p->dedicated;
- w->combination_limit = p->combination_limit;
+ /* If we squirreled away the buffer, restore it now. */
+ if (BUFFERP (w->combination_limit))
+ wset_buffer (w, w->combination_limit);
+ w->left_col = XFASTINT (p->left_col);
+ w->top_line = XFASTINT (p->top_line);
+ w->total_cols = XFASTINT (p->total_cols);
+ w->total_lines = XFASTINT (p->total_lines);
+ wset_normal_cols (w, p->normal_cols);
+ wset_normal_lines (w, p->normal_lines);
+ w->hscroll = XFASTINT (p->hscroll);
+ w->min_hscroll = XFASTINT (p->min_hscroll);
+ wset_display_table (w, p->display_table);
+ w->left_margin_cols = XINT (p->left_margin_cols);
+ w->right_margin_cols = XINT (p->right_margin_cols);
+ w->left_fringe_width = XINT (p->left_fringe_width);
+ w->right_fringe_width = XINT (p->right_fringe_width);
+ w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
+ w->scroll_bar_width = XINT (p->scroll_bar_width);
+ wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
+ wset_dedicated (w, p->dedicated);
+ wset_combination_limit (w, p->combination_limit);
/* Restore any window parameters that have been saved.
Parameters that have not been saved are left alone. */
for (tem = p->window_parameters; CONSP (tem); tem = XCDR (tem))
}
}
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
-
- /* 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 (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
/* If saved buffer is alive, install it. */
{
- w->buffer = p->buffer;
+ wset_buffer (w, p->buffer);
w->start_at_line_beg = !NILP (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);
+ set_marker_restricted (w->start, p->start, w->contents);
+ set_marker_restricted (w->pointm, p->pointm,
+ w->contents);
+ Fset_marker (BVAR (XBUFFER (w->contents), mark),
+ p->mark, w->contents);
/* As documented in Fcurrent_window_configuration, don't
restore the location of point in the buffer which was
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. */
+ }
+ else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
+ /* 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);
+ set_marker_restricted_both (w->start, w->contents, 0, 0);
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)));
+ set_marker_restricted_both
+ (w->pointm, w->contents,
+ BUF_PT (XBUFFER (w->contents)),
+ BUF_PT_BYTE (XBUFFER (w->contents)));
w->start_at_line_beg = 1;
}
- 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 = 1;
- }
- else
- /* Window has no live buffer, get one. */
+ else if (!NILP (w->start))
+ /* Leaf window has no live buffer, get one. */
{
/* 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 ());
+ wset_buffer (w, 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);
+ set_marker_restricted_both (w->start, w->contents, 0, 0);
+ set_marker_restricted_both (w->pointm, w->contents, 0, 0);
w->start_at_line_beg = 1;
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;
+ wset_dedicated (w, Qnil);
}
}
- FRAME_ROOT_WINDOW (f) = data->root_window;
+ fset_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))
+ if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
set_marker_restricted (XWINDOW (data->current_window)->pointm,
make_number (old_point),
- XWINDOW (data->current_window)->buffer);
+ XWINDOW (data->current_window)->contents);
/* 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)
+ BVAR (XBUFFER (XWINDOW (selected_window)->contents), last_selected_window)
= selected_window;
if (NILP (data->focus_frame)
/* Now, free glyph matrices in windows that were not reused. */
for (i = n = 0; i < n_leaf_windows; ++i)
{
- if (NILP (leaf_windows[i]->buffer))
- {
- /* Assert it's not reused as a combination. */
- xassert (NILP (leaf_windows[i]->hchild)
- && NILP (leaf_windows[i]->vchild));
- free_window_matrices (leaf_windows[i]);
- }
- else if (EQ (leaf_windows[i]->buffer, new_current_buffer))
+ if (NILP (leaf_windows[i]->contents))
+ free_window_matrices (leaf_windows[i]);
+ else if (EQ (leaf_windows[i]->contents, new_current_buffer))
++n;
}
adjust_glyphs (f);
- UNBLOCK_INPUT;
+ unblock_input ();
/* Scan dead buffer windows. */
for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
}
if (!NILP (new_current_buffer))
- Fset_buffer (new_current_buffer);
+ {
+ Fset_buffer (new_current_buffer);
+ /* If the new current buffer doesn't appear in the selected
+ window, go to its old point (see bug#12208). */
+ if (!EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
+ Fgoto_char (make_number (old_point));
+ }
Vminibuf_scroll_window = data->minibuf_scroll_window;
minibuf_selected_window = data->minibuf_selected_window;
return (FRAME_LIVE_P (f) ? Qt : Qnil);
}
+void
+restore_window_configuration (Lisp_Object configuration)
+{
+ Fset_window_configuration (configuration);
+}
+
+
+/* If WINDOW is an internal window, recursively delete all child windows
+ reachable via the next and contents slots of WINDOW. Otherwise setup
+ WINDOW to not show any buffer. */
-/* Recursively delete all child windows reachable via the next, vchild,
- and hchild slots of WINDOW. */
void
delete_all_child_windows (Lisp_Object window)
{
/* Delete WINDOW's siblings (we traverse postorderly). */
delete_all_child_windows (w->next);
- w->total_lines = w->buffer; /* See Fset_window_configuration for excuse. */
-
- if (!NILP (w->vchild))
- {
- delete_all_child_windows (w->vchild);
- w->vchild = Qnil;
- }
- else if (!NILP (w->hchild))
+ if (WINDOWP (w->contents))
{
- delete_all_child_windows (w->hchild);
- w->hchild = Qnil;
+ delete_all_child_windows (w->contents);
+ wset_combination (w, 0, Qnil);
}
- else if (!NILP (w->buffer))
+ else if (BUFFERP (w->contents))
{
unshow_buffer (w);
unchain_marker (XMARKER (w->pointm));
unchain_marker (XMARKER (w->start));
- w->buffer = Qnil;
+ /* Since combination limit makes sense for an internal windows
+ only, we use this slot to save the buffer for the sake of
+ possible resurrection in Fset_window_configuration. */
+ wset_combination_limit (w, w->contents);
+ wset_buffer (w, Qnil);
}
Vwindow_list = Qnil;
register int count = 1;
if (!NILP (window->next))
count += count_windows (XWINDOW (window->next));
- if (!NILP (window->vchild))
- count += count_windows (XWINDOW (window->vchild));
- if (!NILP (window->hchild))
- count += count_windows (XWINDOW (window->hchild));
+ if (WINDOWP (window->contents))
+ count += count_windows (XWINDOW (window->contents));
return count;
}
{
while (w)
{
- if (!NILP (w->hchild))
- i = get_leaf_windows (XWINDOW (w->hchild), flat, i);
- else if (!NILP (w->vchild))
- i = get_leaf_windows (XWINDOW (w->vchild), flat, i);
+ if (WINDOWP (w->contents))
+ i = get_leaf_windows (XWINDOW (w->contents), flat, i);
else
flat[i++] = w;
if (!row->enabled_p)
return NULL;
- if (XINT (w->hscroll))
+ if (w->hscroll)
{
/* When the window is hscrolled, cursor hpos can legitimately be
out of bounds, but we draw the cursor at the corresponding
hpos = row->used[TEXT_AREA] - 1;
}
- if (row->used[TEXT_AREA] > hpos
- && 0 <= hpos)
+ if (0 <= hpos && hpos < row->used[TEXT_AREA])
glyph = row->glyphs[TEXT_AREA] + hpos;
else
glyph = NULL;
register struct window *w;
register Lisp_Object tem, pers, par;
- for (;!NILP (window); window = w->next)
+ for (; !NILP (window); window = w->next)
{
p = SAVED_WINDOW_N (vector, i);
w = XWINDOW (window);
- XSETFASTINT (w->temslot, i); i++;
+ wset_temslot (w, make_number (i)); i++;
p->window = window;
- p->buffer = w->buffer;
- p->left_col = w->left_col;
- p->top_line = w->top_line;
- p->total_cols = w->total_cols;
- p->total_lines = w->total_lines;
+ p->buffer = (WINDOW_LEAF_P (w) ? w->contents : Qnil);
+ p->left_col = make_number (w->left_col);
+ p->top_line = make_number (w->top_line);
+ p->total_cols = make_number (w->total_cols);
+ p->total_lines = make_number (w->total_lines);
p->normal_cols = w->normal_cols;
p->normal_lines = w->normal_lines;
- p->hscroll = w->hscroll;
- p->min_hscroll = w->min_hscroll;
+ XSETFASTINT (p->hscroll, w->hscroll);
+ XSETFASTINT (p->min_hscroll, w->min_hscroll);
p->display_table = w->display_table;
- p->left_margin_cols = w->left_margin_cols;
- p->right_margin_cols = w->right_margin_cols;
- p->left_fringe_width = w->left_fringe_width;
- p->right_fringe_width = w->right_fringe_width;
- p->fringes_outside_margins = w->fringes_outside_margins;
- p->scroll_bar_width = w->scroll_bar_width;
+ p->left_margin_cols = make_number (w->left_margin_cols);
+ p->right_margin_cols = make_number (w->right_margin_cols);
+ p->left_fringe_width = make_number (w->left_fringe_width);
+ p->right_fringe_width = make_number (w->right_fringe_width);
+ p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil;
+ p->scroll_bar_width = make_number (w->scroll_bar_width);
p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
p->dedicated = w->dedicated;
p->combination_limit = w->combination_limit;
}
}
- if (!NILP (w->buffer))
+ if (BUFFERP (w->contents))
{
/* Save w's value of point in the window configuration. If w
is the selected window, then get the value of point from
the buffer; pointm is garbage in the selected window. */
if (EQ (window, selected_window))
- {
- p->pointm = Fmake_marker ();
- set_marker_both (p->pointm, w->buffer,
- BUF_PT (XBUFFER (w->buffer)),
- BUF_PT_BYTE (XBUFFER (w->buffer)));
- }
+ p->pointm = build_marker (XBUFFER (w->contents),
+ BUF_PT (XBUFFER (w->contents)),
+ BUF_PT_BYTE (XBUFFER (w->contents)));
else
p->pointm = Fcopy_marker (w->pointm, Qnil);
XMARKER (p->pointm)->insertion_type
p->start = Fcopy_marker (w->start, Qnil);
p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
- tem = BVAR (XBUFFER (w->buffer), mark);
+ tem = BVAR (XBUFFER (w->contents), mark);
p->mark = Fcopy_marker (tem, Qnil);
}
else
else
p->prev = XWINDOW (w->prev)->temslot;
- if (!NILP (w->vchild))
- i = save_window_save (w->vchild, vector, i);
- if (!NILP (w->hchild))
- i = save_window_save (w->hchild, vector, i);
+ if (WINDOWP (w->contents))
+ i = save_window_save (w->contents, vector, i);
}
return i;
register int n_windows;
register struct save_window_data *data;
register int i;
- FRAME_PTR f;
-
- if (NILP (frame))
- frame = selected_frame;
- CHECK_LIVE_FRAME (frame);
- f = XFRAME (frame);
+ struct frame *f = decode_live_frame (frame);
n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
data = ALLOCATE_PSEUDOVECTOR (struct save_window_data, frame_cols,
data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil;
data->root_window = FRAME_ROOT_WINDOW (f);
data->focus_frame = FRAME_FOCUS_FRAME (f);
- tem = Fmake_vector (make_number (n_windows), Qnil);
+ tem = make_uninit_vector (n_windows);
data->saved_windows = tem;
for (i = 0; i < n_windows; i++)
- XVECTOR (tem)->contents[i]
- = Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil);
+ ASET (tem, i,
+ Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil));
save_window_save (FRAME_ROOT_WINDOW (f), XVECTOR (tem), 0);
XSETWINDOW_CONFIGURATION (tem, data);
return (tem);
}
+
+/* Called after W's margins, fringes or scroll bars was adjusted. */
+
+static void
+apply_window_adjustment (struct window *w)
+{
+ eassert (w);
+ adjust_window_margins (w);
+ clear_glyph_matrix (w->current_matrix);
+ w->window_end_valid = 0;
+ windows_or_buffers_changed++;
+ adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
+}
+
\f
/***********************************************************************
Marginal Areas
***********************************************************************/
-DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins,
- 2, 3, 0,
- doc: /* Set width of marginal areas of window WINDOW.
-If WINDOW is nil, set margins of the currently selected window.
-Second arg LEFT-WIDTH specifies the number of character cells to
-reserve for the left marginal area. Optional third arg RIGHT-WIDTH
-does the same for the right marginal area. A nil width parameter
-means no margin. */)
- (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width)
+static struct window *
+set_window_margins (struct window *w, Lisp_Object left_width,
+ Lisp_Object right_width)
{
- struct window *w = decode_window (window);
+ int left, right;
- /* Translate negative or zero widths to nil.
- Margins that are too wide have to be checked elsewhere. */
+ /* FIXME: what about margins that are too wide? */
+ left = (NILP (left_width) ? 0
+ : (CHECK_NATNUM (left_width), XINT (left_width)));
+ right = (NILP (right_width) ? 0
+ : (CHECK_NATNUM (right_width), XINT (right_width)));
- if (!NILP (left_width))
+ if (w->left_margin_cols != left || w->right_margin_cols != right)
{
- CHECK_NUMBER (left_width);
- if (XINT (left_width) <= 0)
- left_width = Qnil;
+ w->left_margin_cols = left;
+ w->right_margin_cols = right;
+ return w;
}
+ return NULL;
+}
- if (!NILP (right_width))
- {
- CHECK_NUMBER (right_width);
- if (XINT (right_width) <= 0)
- right_width = Qnil;
- }
-
- if (!EQ (w->left_margin_cols, left_width)
- || !EQ (w->right_margin_cols, right_width))
- {
- w->left_margin_cols = left_width;
- w->right_margin_cols = right_width;
-
- adjust_window_margins (w);
+DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins,
+ 2, 3, 0,
+ doc: /* Set width of marginal areas of window WINDOW.
+WINDOW must be a live window and defaults to the selected one.
- ++windows_or_buffers_changed;
- adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
- }
+Second arg LEFT-WIDTH specifies the number of character cells to
+reserve for the left marginal area. Optional third arg RIGHT-WIDTH
+does the same for the right marginal area. A nil width parameter
+means no margin.
- return Qnil;
+Return t if any margin was actually changed and nil otherwise. */)
+ (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width)
+{
+ struct window *w = set_window_margins (decode_live_window (window),
+ left_width, right_width);
+ return w ? (apply_window_adjustment (w), Qt) : Qnil;
}
DEFUN ("window-margins", Fwindow_margins, Swindow_margins,
0, 1, 0,
doc: /* Get width of marginal areas of window WINDOW.
-If WINDOW is omitted or nil, it defaults to the selected window.
+WINDOW must be a live window and defaults to the selected one.
+
Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).
If a marginal area does not exist, its width will be returned
as nil. */)
(Lisp_Object window)
{
- struct window *w = decode_window (window);
- return Fcons (w->left_margin_cols, w->right_margin_cols);
+ struct window *w = decode_live_window (window);
+ return Fcons (w->left_margin_cols ? make_number (w->left_margin_cols) : Qnil,
+ w->right_margin_cols ? make_number (w->right_margin_cols) : Qnil);
}
Fringes
***********************************************************************/
+static struct window *
+set_window_fringes (struct window *w, Lisp_Object left_width,
+ Lisp_Object right_width, Lisp_Object outside_margins)
+{
+ int left, right, outside = !NILP (outside_margins);
+
+ left = (NILP (left_width) ? -1
+ : (CHECK_NATNUM (left_width), XINT (left_width)));
+ right = (NILP (right_width) ? -1
+ : (CHECK_NATNUM (right_width), XINT (right_width)));
+
+ /* Do nothing on a tty or if nothing to actually change. */
+ if (FRAME_WINDOW_P (WINDOW_XFRAME (w))
+ && (w->left_fringe_width != left
+ || w->right_fringe_width != right
+ || w->fringes_outside_margins != outside))
+ {
+ w->left_fringe_width = left;
+ w->right_fringe_width = right;
+ w->fringes_outside_margins = outside;
+ return w;
+ }
+ return NULL;
+}
+
DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes,
2, 4, 0,
doc: /* Set the fringe widths of window WINDOW.
-If WINDOW is nil, set the fringe widths of the currently selected
-window.
+WINDOW must be a live window and defaults to the selected one.
+
Second arg LEFT-WIDTH specifies the number of pixels to reserve for
the left fringe. Optional third arg RIGHT-WIDTH specifies the right
fringe width. If a fringe width arg is nil, that means to use the
the command `set-fringe-style'.
If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes
outside of the display margins. By default, fringes are drawn between
-display marginal areas and the text area. */)
- (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width, Lisp_Object outside_margins)
-{
- struct window *w = decode_window (window);
-
- if (!NILP (left_width))
- CHECK_NATNUM (left_width);
- if (!NILP (right_width))
- CHECK_NATNUM (right_width);
-
- /* Do nothing on a tty. */
- if (FRAME_WINDOW_P (WINDOW_XFRAME (w))
- && (!EQ (w->left_fringe_width, left_width)
- || !EQ (w->right_fringe_width, right_width)
- || !EQ (w->fringes_outside_margins, outside_margins)))
- {
- w->left_fringe_width = left_width;
- w->right_fringe_width = right_width;
- w->fringes_outside_margins = outside_margins;
-
- adjust_window_margins (w);
-
- clear_glyph_matrix (w->current_matrix);
- w->window_end_valid = Qnil;
-
- ++windows_or_buffers_changed;
- adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
- }
+display marginal areas and the text area.
- return Qnil;
+Return t if any fringe was actually changed and nil otherwise. */)
+ (Lisp_Object window, Lisp_Object left_width,
+ Lisp_Object right_width, Lisp_Object outside_margins)
+{
+ struct window *w
+ = set_window_fringes (decode_live_window (window),
+ left_width, right_width, outside_margins);
+ return w ? (apply_window_adjustment (w), Qt) : Qnil;
}
DEFUN ("window-fringes", Fwindow_fringes, Swindow_fringes,
0, 1, 0,
doc: /* Get width of fringes of window WINDOW.
-If WINDOW is omitted or nil, it defaults to the selected window.
+WINDOW must be a live window and defaults to the selected one.
+
Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
(Lisp_Object window)
{
- struct window *w = decode_window (window);
+ struct window *w = decode_live_window (window);
- return Fcons (make_number (WINDOW_LEFT_FRINGE_WIDTH (w)),
- Fcons (make_number (WINDOW_RIGHT_FRINGE_WIDTH (w)),
- Fcons ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
- ? Qt : Qnil), Qnil)));
+ return list3 (make_number (WINDOW_LEFT_FRINGE_WIDTH (w)),
+ make_number (WINDOW_RIGHT_FRINGE_WIDTH (w)),
+ WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) ? Qt : Qnil);
}
Scroll bars
***********************************************************************/
-DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
- Sset_window_scroll_bars, 2, 4, 0,
- doc: /* Set width and type of scroll bars of window WINDOW.
-If window is nil, set scroll bars of the currently selected window.
-Second parameter WIDTH specifies the pixel width for the scroll bar;
-this is automatically adjusted to a multiple of the frame column width.
-Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
-bar: left, right, or nil.
-If WIDTH is nil, use the frame's scroll-bar width.
-If VERTICAL-TYPE is t, use the frame's scroll-bar type.
-Fourth parameter HORIZONTAL-TYPE is currently unused. */)
- (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type, Lisp_Object horizontal_type)
+static struct window *
+set_window_scroll_bars (struct window *w, Lisp_Object width,
+ Lisp_Object vertical_type, Lisp_Object horizontal_type)
{
- struct window *w = decode_window (window);
-
- if (!NILP (width))
- {
- CHECK_RANGED_INTEGER (0, width, INT_MAX);
+ int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width)));
- if (XINT (width) == 0)
- vertical_type = Qnil;
- }
+ if (iwidth == 0)
+ vertical_type = Qnil;
if (!(NILP (vertical_type)
|| EQ (vertical_type, Qleft)
|| EQ (vertical_type, Qt)))
error ("Invalid type of vertical scroll bar");
- if (!EQ (w->scroll_bar_width, width)
+ if (w->scroll_bar_width != iwidth
|| !EQ (w->vertical_scroll_bar_type, vertical_type))
{
- w->scroll_bar_width = width;
- w->vertical_scroll_bar_type = vertical_type;
-
- adjust_window_margins (w);
+ w->scroll_bar_width = iwidth;
+ wset_vertical_scroll_bar_type (w, vertical_type);
+ return w;
+ }
+ return NULL;
+}
- clear_glyph_matrix (w->current_matrix);
- w->window_end_valid = Qnil;
+DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
+ Sset_window_scroll_bars, 2, 4, 0,
+ doc: /* Set width and type of scroll bars of window WINDOW.
+WINDOW must be a live window and defaults to the selected one.
- ++windows_or_buffers_changed;
- adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
- }
+Second parameter WIDTH specifies the pixel width for the scroll bar;
+this is automatically adjusted to a multiple of the frame column width.
+Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
+bar: left, right, or nil.
+If WIDTH is nil, use the frame's scroll-bar width.
+If VERTICAL-TYPE is t, use the frame's scroll-bar type.
+Fourth parameter HORIZONTAL-TYPE is currently unused.
- return Qnil;
+Return t if scroll bars was actually changed and nil otherwise. */)
+ (Lisp_Object window, Lisp_Object width,
+ Lisp_Object vertical_type, Lisp_Object horizontal_type)
+{
+ struct window *w
+ = set_window_scroll_bars (decode_live_window (window),
+ width, vertical_type, horizontal_type);
+ return w ? (apply_window_adjustment (w), Qt) : Qnil;
}
DEFUN ("window-scroll-bars", Fwindow_scroll_bars, Swindow_scroll_bars,
0, 1, 0,
doc: /* Get width and type of scroll bars of window WINDOW.
-If WINDOW is omitted or nil, it defaults to the selected window.
+WINDOW must be a live window and defaults to the selected one.
+
Value is a list of the form (WIDTH COLS VERTICAL-TYPE HORIZONTAL-TYPE).
If WIDTH is nil or TYPE is t, the window is using the frame's corresponding
value. */)
(Lisp_Object window)
{
- struct window *w = decode_window (window);
- return Fcons (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w)
+ struct window *w = decode_live_window (window);
+
+ return list4 (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w)
? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w)
: WINDOW_SCROLL_BAR_AREA_WIDTH (w))),
- Fcons (make_number (WINDOW_SCROLL_BAR_COLS (w)),
- Fcons (w->vertical_scroll_bar_type,
- Fcons (Qnil, Qnil))));
+ make_number (WINDOW_SCROLL_BAR_COLS (w)),
+ w->vertical_scroll_bar_type, Qnil);
}
(Lisp_Object window, Lisp_Object pixels_p)
{
Lisp_Object result;
- struct frame *f;
- struct window *w;
-
- if (NILP (window))
- window = selected_window;
- else
- CHECK_WINDOW (window);
- w = XWINDOW (window);
- f = XFRAME (w->frame);
+ struct window *w = decode_live_window (window);
+ struct frame *f = XFRAME (w->frame);
if (FRAME_WINDOW_P (f))
result = (NILP (pixels_p)
If PIXELS-P is non-nil, the return value is VSCROLL. */)
(Lisp_Object window, Lisp_Object vscroll, Lisp_Object pixels_p)
{
- struct window *w;
- struct frame *f;
+ struct window *w = decode_live_window (window);
+ struct frame *f = XFRAME (w->frame);
- if (NILP (window))
- window = selected_window;
- else
- CHECK_WINDOW (window);
CHECK_NUMBER_OR_FLOAT (vscroll);
- w = XWINDOW (window);
- f = XFRAME (w->frame);
-
if (FRAME_WINDOW_P (f))
{
int old_dy = w->vscroll;
adjust_glyphs (f);
/* Prevent redisplay shortcuts. */
- XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+ XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
}
}
for (cont = 1; w && cont;)
{
- if (!NILP (w->hchild))
- cont = foreach_window_1 (XWINDOW (w->hchild), fn, user_data);
- else if (!NILP (w->vchild))
- cont = foreach_window_1 (XWINDOW (w->vchild), fn, user_data);
+ if (WINDOWP (w->contents))
+ cont = foreach_window_1 (XWINDOW (w->contents), fn, user_data);
else
cont = fn (w, user_data);
return cont;
}
-
-/* Freeze or unfreeze the window start of W unless it is a
- mini-window or the selected window. FREEZE_P non-null means freeze
- the window start. */
-
-static int
-freeze_window_start (struct window *w, void *freeze_p)
-{
- if (MINI_WINDOW_P (w)
- || (WINDOWP (selected_window) /* Can be nil in corner cases. */
- && (w == XWINDOW (selected_window)
- || (MINI_WINDOW_P (XWINDOW (selected_window))
- && ! NILP (Vminibuf_scroll_window)
- && w == XWINDOW (Vminibuf_scroll_window)))))
- freeze_p = NULL;
-
- w->frozen_window_start_p = freeze_p != NULL;
- return 1;
-}
-
-
-/* Freeze or unfreeze the window starts of all leaf windows on frame
- F, except the selected window and a mini-window. FREEZE_P non-zero
- means freeze the window start. */
-
-void
-freeze_window_starts (struct frame *f, int freeze_p)
-{
- foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0));
-}
-
-\f
/***********************************************************************
Initialization
***********************************************************************/
/* 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
+ IGNORE_POSITIONS means ignore non-matching scroll positions
and the like.
This ignores a couple of things like the dedication status of
window, combination_limit and the like. This might have to be
fixed. */
-int
-compare_window_configurations (Lisp_Object configuration1, Lisp_Object configuration2, int ignore_positions)
+bool
+compare_window_configurations (Lisp_Object configuration1,
+ Lisp_Object configuration2,
+ bool ignore_positions)
{
register struct save_window_data *d1, *d2;
struct Lisp_Vector *sws1, *sws2;
DEFSYM (Qwindowp, "windowp");
DEFSYM (Qwindow_configuration_p, "window-configuration-p");
DEFSYM (Qwindow_live_p, "window-live-p");
+ DEFSYM (Qwindow_valid_p, "window-valid-p");
DEFSYM (Qwindow_deletable_p, "window-deletable-p");
DEFSYM (Qdelete_window, "delete-window");
DEFSYM (Qwindow_resize_root_window, "window--resize-root-window");
DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows");
DEFSYM (Qrecord_window_buffer, "record-window-buffer");
DEFSYM (Qget_mru_window, "get-mru-window");
+ DEFSYM (Qwindow_size, "window-size");
DEFSYM (Qtemp_buffer_show_hook, "temp-buffer-show-hook");
DEFSYM (Qabove, "above");
DEFSYM (Qbelow, "below");
- DEFSYM (Qauto_buffer_name, "auto-buffer-name");
DEFSYM (Qclone_of, "clone-of");
staticpro (&Vwindow_list);
Other values are reserved for future use.
-This variable takes no effect if `window-combination-limit' is non-nil. */);
+This variable takes no effect if the variable `window-combination-limit' is
+non-nil. */);
Vwindow_combination_resize = Qnil;
DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit,
- doc: /* If t, splitting a window makes a new parent window.
-If this variable is nil, splitting a window will create a new parent
-window only if the window has no parent window or the window shall
-become a combination orthogonal to the one it is part of.
+ doc: /* If non-nil, splitting a window makes a new parent window.
+The following values are recognized:
-If this variable is t, splitting a window always creates a new parent
-window. If all splits behave this way, each frame's window tree is a
-binary tree and every window but the frame's root window has exactly one
-sibling.
+nil means splitting a window will create a new parent window only if the
+ window has no parent window or the window shall become part of a
+ combination orthogonal to the one it is part of.
-Other values are reserved for future use.
+`window-size' means that splitting a window for displaying a buffer
+ makes a new parent window provided `display-buffer' is supposed to
+ explicitly set the window's size due to the presence of a
+ `window-height' or `window-width' entry in the alist used by
+ `display-buffer'. Otherwise, this value is handled like nil.
+
+`temp-buffer' means that splitting a window for displaying a temporary
+ buffer always makes a new parent window. Otherwise, this value is
+ handled like nil.
+
+`display-buffer' means that splitting a window for displaying a buffer
+ always makes a new parent window. Since temporary buffers are
+ displayed by the function `display-buffer', this value is stronger
+ than `temp-buffer'. Splitting a window for other purpose makes a
+ new parent window only if needed.
+
+t means that splitting a window always creates a new parent window. If
+ all splits behave this way, each frame's window tree is a binary
+ tree and every window but the frame's root window has exactly one
+ sibling.
-The value of this variable is also assigned to the combination limit of
-the new parent window. The combination limit of a window can be
-retrieved via the function `window-combination-limit' and altered by the
-function `set-window-combination-limit'. */);
- Vwindow_combination_limit = Qnil;
+Other values are reserved for future use. */);
+ Vwindow_combination_limit = Qwindow_size;
DEFVAR_LISP ("window-persistent-parameters", Vwindow_persistent_parameters,
doc: /* Alist of persistent window parameters.
defsubr (&Sminibuffer_window);
defsubr (&Swindow_minibuffer_p);
defsubr (&Swindowp);
+ defsubr (&Swindow_valid_p);
defsubr (&Swindow_live_p);
defsubr (&Swindow_frame);
defsubr (&Sframe_root_window);
defsubr (&Srun_window_configuration_change_hook);
defsubr (&Sselect_window);
defsubr (&Sforce_window_update);
- defsubr (&Stemp_output_buffer_show);
defsubr (&Ssplit_window_internal);
defsubr (&Sscroll_up);
defsubr (&Sscroll_down);