/* 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.
static int window_resize_check (struct window *, int);
static void window_resize_apply (struct window *, int);
static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
+static void select_window_1 (Lisp_Object, bool);
/* 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;
return XWINDOW (window);
}
-static struct window *
+struct window *
decode_any_window (register Lisp_Object window)
{
struct window *w;
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->buffer))
+ {
+ struct buffer *b = XBUFFER (w->buffer);
+
+ 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);
+ w->buffer = val;
+ adjust_window_count (w, 1);
+}
+
+/* Build a frequently used 4-integer (X Y W H) list. */
+
+static Lisp_Object
+list4i (EMACS_INT x, EMACS_INT y, EMACS_INT w, EMACS_INT h)
+{
+ return list4 (make_number (x), make_number (y),
+ make_number (w), make_number (h));
+}
+
DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
doc: /* Return t if OBJECT is a window and nil otherwise. */)
(Lisp_Object object)
}
\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.
WINDOW must be a valid window and defaults to the selected one. */)
(Lisp_Object 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,
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);
else
fset_selected_window (sf, window);
+ select_window_1 (window, inhibit_point_swap);
+
+ bset_last_selected_window (XBUFFER (w->buffer), window);
+ windows_or_buffers_changed++;
+ return window;
+}
+
+/* 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)
{
- ow = XWINDOW (selected_window);
+ struct window *ow = XWINDOW (selected_window);
if (! NILP (ow->buffer))
set_marker_both (ow->pointm, ow->buffer,
BUF_PT (XBUFFER (ow->buffer)),
}
selected_window = window;
- bset_last_selected_window (XBUFFER (w->buffer), window);
/* Go to the point recorded in the window.
This is important when the buffer is in more
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);
+ register ptrdiff_t new_point = marker_position (XWINDOW (window)->pointm);
if (new_point < BEGV)
SET_PT (BEGV);
else if (new_point > ZV)
else
SET_PT (new_point);
}
-
- windows_or_buffers_changed++;
- return window;
}
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 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).
horizontal combination. */)
(Lisp_Object window)
{
- CHECK_WINDOW (window);
return decode_valid_window (window)->vchild;
}
-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).
vertical combination. */)
(Lisp_Object window)
{
- CHECK_WINDOW (window);
return decode_valid_window (window)->hchild;
}
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 and defaults to the selected one.
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. */)
+WINDOW are never \(re-)combined with WINDOW's siblings.
+
+WINDOW must be a valid window. The return value is meaningful for
+internal windows only. */)
(Lisp_Object window)
{
- return decode_valid_window (window)->combination_limit;
+ CHECK_VALID_WINDOW (window);
+ return XWINDOW (window)->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.
-WINDOW must be a valid window and defaults to the selected one.
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. */)
+future use.
+
+WINDOW must be a valid window. Setting the combination limit is
+meaningful for internal windows only. */)
(Lisp_Object window, Lisp_Object limit)
{
wset_combination_limit (decode_valid_window (window), limit);
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;
}
exclude partially-visible lines, use `window-text-height'. */)
(Lisp_Object window)
{
- struct window *w = decode_live_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,
expressed as an integer multiple of the default character width. */)
(Lisp_Object window)
{
- struct window *w = decode_live_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 so that the location of point moves off-window. */)
(Lisp_Object window, Lisp_Object ncol)
{
- struct window *w = decode_live_window (window);
-
CHECK_NUMBER (ncol);
- return set_window_hscroll (w, XINT (ncol));
+ return set_window_hscroll (decode_live_window (window), XINT (ncol));
}
DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger,
{
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,
{
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
{
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,
{
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,
{
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",
{
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.
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);
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
+correct to return the top-level value of `point', outside of any
`save-excursion' forms. But that is hard to define. */)
(Lisp_Object window)
{
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)
- && (windows_or_buffers_changed || NILP (w->window_end_valid))
+ && (windows_or_buffers_changed || !w->window_end_valid)
&& !noninteractive)
{
struct text_pos startp;
+ ptrdiff_t charpos = marker_position (w->start);
struct it it;
struct buffer *old_buffer = NULL;
void *itdata = NULL;
`-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)
+ if (charpos < BEGV)
SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
- else if (XMARKER (w->start)->charpos > ZV)
+ else if (charpos > ZV)
SET_TEXT_POS (startp, ZV, ZV_BYTE);
else
SET_TEXT_POS_FROM_MARKER (startp, w->start);
{
register struct window *w = decode_live_window (window);
- CHECK_NUMBER_COERCE_MARKER (pos);
+ /* Type of POS is checked by Fgoto_char or set_marker_restricted ... */
if (w == XWINDOW (selected_window))
{
{
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->buffer));
Fgoto_char (pos);
set_buffer_internal (old_buffer);
{
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. */
+ /* 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;
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));
}
b = XBUFFER (w->buffer);
/* Fail if current matrix is not up-to-date. */
- if (NILP (w->window_end_valid)
+ if (!w->window_end_valid
|| current_buffer->clip_changed
|| current_buffer->prevent_redisplay_optimizations_p
|| w->last_modified < BUF_MODIFF (b)
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,
&& EQ (buf, XWINDOW (BVAR (b, last_selected_window))->buffer)))
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),
n->pseudo_window_p = 0;
wset_window_end_vpos (n, make_number (0));
wset_window_end_pos (n, make_number (0));
- wset_window_end_valid (n, Qnil);
+ n->window_end_valid = 0;
n->frozen_window_start_p = 0;
}
{
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);
}
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))
if (NILP (*all_frames))
*all_frames
= (!EQ (*minibuf, Qlambda)
- ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window)->frame))
+ ? FRAME_MINIBUF_WINDOW (XFRAME (w->frame))
: Qnil);
else if (EQ (*all_frames, Qvisible))
;
pos = *vmotion (startpos, -top, w);
set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
- wset_window_end_valid (w, Qnil);
+ 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
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. */
}
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. */)
+ 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;
}
wset_window_end_pos (w, make_number (0));
wset_window_end_vpos (w, make_number (0));
memset (&w->last_cursor, 0, sizeof w->last_cursor);
- wset_window_end_valid (w, 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
tem = w->buffer;
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))
{
if (STRINGP (object))
object = Fget_buffer (object);
- if (BUFFERP (object) && BUFFER_LIVE_P (XBUFFER (object)))
+ 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;
}
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);
- p->sequence_number = ++sequence_number;
-
replace_window (window, parent, 1);
wset_next (o, Qnil);
w->nrows_scale_factor = w->ncols_scale_factor = 1;
w->phys_cursor_type = -1;
w->phys_cursor_width = -1;
- w->sequence_number = ++sequence_number;
+ w->column_number_displayed = -1;
/* Reset window_list. */
Vwindow_list = Qnil;
}
-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;
+ struct frame *f = decode_live_frame (frame);
+ struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
int horflag = !NILP (horizontal);
- if (NILP (frame))
- frame = selected_frame;
- CHECK_LIVE_FRAME (frame);
-
- f = XFRAME (frame);
- r = XWINDOW (FRAME_ROOT_WINDOW (f));
-
if (!window_resize_check (r, horflag)
|| ! EQ (r->new_total,
(horflag ? r->total_cols : r->total_lines)))
make_parent_window (old, horflag);
p = XWINDOW (o->parent);
- /* 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);
+ 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. */
wset_new_total (p, horflag ? o->total_cols : o->total_lines);
wset_new_normal (p, new_normal);
wset_next (o, new);
}
- wset_buffer (n, Qt);
- wset_window_end_valid (n, Qnil);
+ n->window_end_valid = 0;
memset (&n->last_cursor, 0, sizeof n->last_cursor);
/* Get special geometry settings from reference window. */
}
/* 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->buffer, 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;
w->last_modified = 0;
{
struct it it;
struct text_pos start;
+ ptrdiff_t charpos = marker_position (w->start);
int height = window_box_height (w);
struct buffer *old_buffer;
int bottom_y;
/* 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)
+ if (charpos < BEGV)
SET_TEXT_POS (start, BEGV, BEGV_BYTE);
- else if (XMARKER (w->start)->charpos > ZV)
+ else if (charpos > ZV)
SET_TEXT_POS (start, ZV, ZV_BYTE);
else
SET_TEXT_POS_FROM_MARKER (start, w->start);
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);
charpos = pos.bufpos;
/* Set the new window start. */
set_marker_both (w->start, w->buffer, charpos, bytepos);
- wset_window_end_valid (w, Qnil);
+ w->window_end_valid = 0;
w->optional_new_start = 1;
&& WINDOWP (selected_window)
&& EQ (XWINDOW (selected_window)->buffer, 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
if (EQ (XWINDOW (data->current_window)->buffer, 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));
}
{
/* 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->buffer, 0, 0);
if (XMARKER (w->pointm)->buffer == 0)
set_marker_restricted_both
(w->pointm, w->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->buffer, 0, 0);
+ set_marker_restricted_both (w->pointm, w->buffer, 0, 0);
w->start_at_line_beg = 1;
if (!NILP (w->dedicated))
/* Record this window as dead. */
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++)
ASET (tem, i,
- Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil));
+ 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);
adjust_window_margins (w);
clear_glyph_matrix (w->current_matrix);
- wset_window_end_valid (w, Qnil);
+ w->window_end_valid = 0;
++windows_or_buffers_changed;
adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
{
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);
}
adjust_window_margins (w);
clear_glyph_matrix (w->current_matrix);
- wset_window_end_valid (w, Qnil);
+ w->window_end_valid = 0;
++windows_or_buffers_changed;
adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
(Lisp_Object window)
{
struct window *w = decode_live_window (window);
- return Fcons (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w)
+
+ 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);
}
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,