#include <config.h>
-#define WINDOW_INLINE EXTERN_INLINE
-
#include <stdio.h>
#include "lisp.h"
#include "blockinput.h"
#include "intervals.h"
#include "termhooks.h" /* For FRAME_TERMINAL. */
-
-#ifdef HAVE_X_WINDOWS
-#include "xterm.h"
-#endif /* HAVE_X_WINDOWS */
-#ifdef HAVE_NTGUI
-#include "w32term.h"
-#endif
+#ifdef HAVE_WINDOW_SYSTEM
+#include TERM_HEADER
+#endif /* HAVE_WINDOW_SYSTEM */
#ifdef MSDOS
#include "msdos.h"
#endif
-#ifdef HAVE_NS
-#include "nsterm.h"
-#endif
Lisp_Object Qwindowp, Qwindow_live_p;
static Lisp_Object Qwindow_valid_p;
-static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
+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 int displayed_window_lines (struct window *);
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 *,
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
always be a leaf window, and its buffer is selected by
static EMACS_INT window_scroll_preserve_hpos;
static EMACS_INT window_scroll_preserve_vpos;
\f
+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->display_table = val;
}
static void
-wset_hchild (struct window *w, Lisp_Object val)
-{
- w->hchild = val;
-}
-static void
-wset_left_fringe_width (struct window *w, Lisp_Object val)
-{
- w->left_fringe_width = val;
-}
-static void
-wset_left_margin_cols (struct window *w, Lisp_Object val)
-{
- w->left_margin_cols = val;
-}
-static void
wset_new_normal (struct window *w, Lisp_Object val)
{
w->new_normal = val;
w->pointm = val;
}
static void
-wset_right_fringe_width (struct window *w, Lisp_Object val)
-{
- w->right_fringe_width = val;
-}
-static void
-wset_right_margin_cols (struct window *w, Lisp_Object val)
-{
- w->right_margin_cols = val;
-}
-static void
-wset_scroll_bar_width (struct window *w, Lisp_Object val)
-{
- w->scroll_bar_width = val;
-}
-static void
wset_start (struct window *w, Lisp_Object val)
{
w->start = val;
w->temslot = val;
}
static void
-wset_vchild (struct window *w, Lisp_Object val)
-{
- w->vchild = val;
-}
-static void
wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val)
{
w->vertical_scroll_bar_type = 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)
adjust_window_count (struct window *w, int arg)
{
eassert (eabs (arg) == 1);
- if (BUFFERP (w->buffer))
+ if (BUFFERP (w->contents))
{
- struct buffer *b = XBUFFER (w->buffer);
+ struct buffer *b = XBUFFER (w->contents);
if (b->base_buffer)
b = b->base_buffer;
wset_buffer (struct window *w, Lisp_Object val)
{
adjust_window_count (w, -1);
- w->buffer = val;
+ 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);
}
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
- emacs_abort ();
- }
+ while (WINDOWP (XWINDOW (window)->contents))
+ window = XWINDOW (window)->contents;
return window;
}
CHECK_LIVE_WINDOW (window);
w = XWINDOW (window);
- w->frozen_window_start_p = 0;
-
- if (NILP (norecord))
- {
- w->use_time = ++window_select_count;
- record_buffer (w->buffer);
- }
/* Make the selected window's buffer current. */
- Fset_buffer (w->buffer);
+ 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)
fset_selected_window (sf, window);
select_window_1 (window, inhibit_point_swap);
-
- bset_last_selected_window (XBUFFER (w->buffer), window);
+ 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))
+ {
+ w->use_time = ++window_select_count;
+ record_buffer (w->contents);
+ }
+
return window;
}
if (!inhibit_point_swap)
{
struct window *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)));
+ if (BUFFERP (ow->contents))
+ set_marker_both (ow->pointm, ow->contents,
+ BUF_PT (XBUFFER (ow->contents)),
+ BUF_PT_BYTE (XBUFFER (ow->contents)));
}
selected_window = window;
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 (XWINDOW (window)->pointm);
- if (new_point < BEGV)
- SET_PT (BEGV);
- else if (new_point > ZV)
- SET_PT (ZV);
- else
- SET_PT (new_point);
- }
+ set_point_from_marker (XWINDOW (window)->pointm);
}
DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
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,
horizontal combination. */)
(Lisp_Object window)
{
- return decode_valid_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, 0, 1, 0,
vertical combination. */)
(Lisp_Object window)
{
- return decode_valid_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,
CHECK_VALID_WINDOW (window);
w = XWINDOW (window);
- if (!NILP (w->buffer))
+ if (WINDOW_LEAF_P (w))
error ("Combination limit is meaningful for internal windows only");
- return XWINDOW (window)->combination_limit;
+ return w->combination_limit;
}
DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0,
CHECK_VALID_WINDOW (window);
w = XWINDOW (window);
- if (!NILP (w->buffer))
+ if (WINDOW_LEAF_P (w))
error ("Combination limit is meaningful for internal windows only");
wset_combination_limit (w, limit);
return limit;
integer multiple of the default character height. */)
(Lisp_Object window)
{
- return decode_valid_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,
integer multiple of the default character width. */)
(Lisp_Object window)
{
- return decode_valid_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,
WINDOW must be a valid window and defaults to the selected one. */)
(Lisp_Object window)
{
- return decode_valid_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,
WINDOW must be a valid window and defaults to the selected one. */)
(Lisp_Object window)
{
- return decode_valid_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. */
/* Prevent redisplay shortcuts when changing the hscroll. */
if (w->hscroll != new_hscroll)
- XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+ XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
w->hscroll = new_hscroll;
return make_number (new_hscroll);
#endif
#ifdef FRAME_TOOLBAR_TOP_HEIGHT
*add_y += FRAME_TOOLBAR_TOP_HEIGHT (f);
-#elif FRAME_TOOLBAR_HEIGHT
+#elif defined (FRAME_TOOLBAR_HEIGHT)
*add_y += FRAME_TOOLBAR_HEIGHT (f);
#endif
#ifdef FRAME_NS_TITLEBAR_HEIGHT
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;
cw.window = &window, cw.x = x, cw.y = y; cw.part = part;
foreach_window (f, check_window_containing, &cw);
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
/* If not found above, see if it's in the tool bar window, if a tool
bar exists. */
if (NILP (window)
*part = ON_TEXT;
window = f->tool_bar_window;
}
+#endif
return window;
}
register struct window *w = decode_live_window (window);
if (w == XWINDOW (selected_window))
- return make_number (BUF_PT (XBUFFER (w->buffer)));
+ return make_number (BUF_PT (XBUFFER (w->contents)));
else
return Fmarker_position (w->pointm);
}
Lisp_Object buf;
struct buffer *b;
- buf = w->buffer;
+ buf = w->contents;
CHECK_BUFFER (buf);
b = XBUFFER (buf);
if (! NILP (update)
- && (windows_or_buffers_changed || !w->window_end_valid)
+ && (windows_or_buffers_changed
+ || !w->window_end_valid
+ || b->clip_changed
+ || b->prevent_redisplay_optimizations_p
+ || window_outdated (w))
&& !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 (charpos < BEGV)
- SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
- else if (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;
}
if (w == XWINDOW (selected_window))
{
- if (XBUFFER (w->buffer) == current_buffer)
+ if (XBUFFER (w->contents) == current_buffer)
Fgoto_char (pos);
else
{
/* ... but here we want to catch type error before buffer change. */
CHECK_NUMBER_COERCE_MARKER (pos);
- set_buffer_internal (XBUFFER (w->buffer));
+ set_buffer_internal (XBUFFER (w->contents));
Fgoto_char (pos);
set_buffer_internal (old_buffer);
}
}
else
{
- set_marker_restricted (w->pointm, pos, w->buffer);
+ 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;
{
register struct window *w = decode_live_window (window);
- set_marker_restricted (w->start, pos, w->buffer);
+ 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;
- w->last_modified = 0;
- 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;
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 x, y;
w = decode_live_window (window);
- buf = XBUFFER (w->buffer);
+ buf = XBUFFER (w->contents);
SET_TEXT_POS_FROM_MARKER (top, w->start);
if (EQ (pos, Qt))
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 (!w->window_end_valid
- || current_buffer->clip_changed
- || current_buffer->prevent_redisplay_optimizations_p
- || w->last_modified < BUF_MODIFF (b)
- || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b))
+ || windows_or_buffers_changed
+ || b->clip_changed
+ || b->prevent_redisplay_optimizations_p
+ || window_outdated (w))
return Qnil;
if (NILP (line))
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));
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)
- emacs_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),
marker_position (w->pointm),
if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame))))
fset_root_window (XFRAME (o->frame), new);
- if (setflag)
- {
- wset_left_col (n, o->left_col);
- wset_top_line (n, o->top_line);
- wset_total_cols (n, o->total_cols);
- wset_total_lines (n, o->total_lines);
+ if (setflag)
+ {
+ n->left_col = o->left_col;
+ n->top_line = o->top_line;
+ n->total_cols = o->total_cols;
+ n->total_lines = o->total_lines;
wset_normal_cols (n, o->normal_cols);
wset_normal_cols (o, make_float (1.0));
wset_normal_lines (n, o->normal_lines);
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->phys_cursor_type = -1;
+ n->last_cursor_vpos = 0;
+#ifdef HAVE_WINDOW_SYSTEM
+ n->phys_cursor_type = NO_CURSOR;
n->phys_cursor_width = -1;
+#endif
n->must_be_updated_p = 0;
n->pseudo_window_p = 0;
- wset_window_end_vpos (n, make_number (0));
- wset_window_end_pos (n, make_number (0));
+ n->window_end_vpos = 0;
+ n->window_end_pos = 0;
n->window_end_valid = 0;
- n->frozen_window_start_p = 0;
}
tem = o->next;
tem = o->parent;
wset_parent (n, tem);
- if (!NILP (tem))
- {
- if (EQ (XWINDOW (tem)->vchild, old))
- wset_vchild (XWINDOW (tem), new);
- if (EQ (XWINDOW (tem)->hchild, old))
- wset_hchild (XWINDOW (tem), new);
- }
+ 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
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)
- wset_hchild (p, child);
- else
- wset_vchild (p, child);
+ wset_combination (p, horflag, child);
else
{
wset_prev (c, w->prev);
if (horflag)
wset_normal_cols (c,
- make_float (XFLOATINT (c->total_cols)
- / XFLOATINT (p->total_cols)));
+ make_float ((double) c->total_cols
+ / (double) p->total_cols));
else
wset_normal_lines (c,
- make_float (XFLOATINT (c->total_lines)
- / XFLOATINT (p->total_lines)));
+ make_float ((double) c->total_lines
+ / (double) p->total_lines));
if (NILP (c->next))
{
}
/* WINDOW can be deleted now. */
- wset_vchild (w, Qnil);
- wset_hchild (w, 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);
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)
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. */
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)
- && !BUFFER_LIVE_P (XBUFFER (w->buffer)))
- emacs_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:
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);
block_input ();
if (!FRAME_INITIAL_P (f))
{
- Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+ 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
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))
- {
- 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;
- }
+ 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));
- wset_top_line (w, r->top_line);
+ 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))
window_resize_apply (w, 0);
/* Resize child windows horizontally. */
if (!resize_failed)
{
- wset_left_col (w, r->left_col);
- XSETINT (delta,
- XINT (r->total_cols) - XINT (w->total_cols));
- wset_left_col (w, r->left_col);
+ 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->next;
s = XWINDOW (sibling);
wset_prev (s, Qnil);
- if (!NILP (XWINDOW (w->parent)->vchild))
- wset_vchild (XWINDOW (w->parent), sibling);
- else
- wset_hchild (XWINDOW (w->parent), sibling);
+ 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);
- wset_vchild (r, Qnil);
- }
- else if (!NILP (r->hchild))
+ if (WINDOWP (r->contents))
{
- delete_all_child_windows (r->hchild);
- wset_hchild (r, 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, startbyte, -top, w);
- set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
+ 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');
}
}
- adjust_glyphs (f);
+ adjust_frame_glyphs (f);
unblock_input ();
run_window_configuration_change_hook (f);
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)
- {
- wset_left_margin_cols (w, make_number (margin_cols / 2));
- wset_right_margin_cols (w, make_number (margin_cols / 2));
- }
+ w->left_margin_cols = w->right_margin_cols = margin_cols / 2;
else
- wset_right_margin_cols (w, make_number (margin_cols));
+ w->right_margin_cols = margin_cols;
}
else
- wset_left_margin_cols (w, make_number (margin_cols));
+ w->left_margin_cols = margin_cols;
return 1;
}
\f
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
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));
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);
wset_buffer (w, buffer);
bset_display_count (b, make_number (XINT (BVAR (b, display_count)) + 1));
bset_display_time (b, Fcurrent_time ());
- 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);
+ w->window_end_pos = 0;
+ w->window_end_vpos = 0;
+ w->last_cursor_vpos = 0;
if (!(keep_margins_p && samebuf))
{ /* If we're not actually changing the buffer, don't reset hscroll and
buffer);
w->start_at_line_beg = 0;
w->force_start = 0;
- w->last_modified = 0;
- 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. */
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;
-
- wset_left_margin_cols (w, Qnil);
- wset_right_margin_cols (w, 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);
-
- wset_left_margin_cols (w, save_left);
- wset_right_margin_cols (w, 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)
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
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 (!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;
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);
}
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. */
+ /* P's buffer slot may change from nil to a buffer... */
adjust_window_count (p, 1);
XSETWINDOW (parent, p);
wset_next (o, Qnil);
wset_prev (o, Qnil);
wset_parent (o, parent);
-
- wset_hchild (p, horflag ? window : Qnil);
- wset_vchild (p, horflag ? Qnil : window);
+ /* ...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);
}
w = allocate_window ();
/* 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_left_col (w, make_number (0));
- wset_top_line (w, make_number (0));
- wset_total_lines (w, make_number (0));
- wset_total_cols (w, make_number (0));
wset_normal_lines (w, make_float (1.0));
wset_normal_cols (w, make_float (1.0));
wset_new_total (w, make_number (0));
wset_start (w, Fmake_marker ());
wset_pointm (w, Fmake_marker ());
wset_vertical_scroll_bar_type (w, Qt);
- wset_window_end_pos (w, make_number (0));
- wset_window_end_vpos (w, make_number (0));
/* These Lisp fields are marked specially so they're not set to nil by
allocate_window. */
wset_prev_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;
- w->phys_cursor_type = -1;
+ w->left_fringe_width = w->right_fringe_width = -1;
+ w->mode_line_height = w->header_line_height = -1;
+#ifdef HAVE_WINDOW_SYSTEM
+ w->phys_cursor_type = NO_CURSOR;
w->phys_cursor_width = -1;
+#endif
+ w->scroll_bar_width = -1;
w->column_number_displayed = -1;
/* Reset window_list. */
{
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. */
parent window has been set *before*. */
if (horflag)
{
- wset_total_cols (w, w->new_total);
+ w->total_cols = XFASTINT (w->new_total);
if (NUMBERP (w->new_normal))
wset_normal_cols (w, w->new_normal);
- pos = XINT (w->left_col);
+ pos = w->left_col;
}
else
{
- wset_total_lines (w, w->new_total);
+ w->total_lines = XFASTINT (w->new_total);
if (NUMBERP (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)
- wset_left_col (c, make_number (pos));
+ c->left_col = pos;
else
- wset_top_line (c, make_number (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)
- wset_left_col (c, make_number (pos));
+ c->left_col = pos;
else
- wset_top_line (c, make_number (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. */
- w->last_modified = 0;
- w->last_overlay_modified = 0;
}
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 ();
windows_or_buffers_changed++;
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
- adjust_glyphs (f);
+ adjust_frame_glyphs (f);
unblock_input ();
run_window_configuration_change_hook (f);
- ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
? 1 : 0)));
- wset_top_line (r, make_number (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)
- wset_total_cols (r, make_number (new_size));
+ r->total_cols = new_size;
else
- wset_total_lines (r, make_number (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);
root = f->selected_window;
Fdelete_other_windows_internal (root, Qnil);
if (horflag)
- wset_total_cols (XWINDOW (root), make_number (new_size));
+ XWINDOW (root)->total_cols = new_size;
else
- wset_total_lines (XWINDOW (root), make_number (new_size));
+ XWINDOW (root)->total_lines = new_size;
}
}
}
{
m = XWINDOW (mini);
if (horflag)
- wset_total_cols (m, make_number (size));
+ m->total_cols = size;
else
{
/* Are we sure we always want 1 line here? */
- wset_total_lines (m, make_number (1));
- wset_top_line
- (m, make_number (XINT (r->top_line) + XINT (r->total_lines)));
+ m->total_lines = 1;
+ m->top_line = r->top_line + r->total_lines;
}
}
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. */
wset_new_total
- (p, make_number (XINT (horflag ? p->total_cols : p->total_lines)
+ (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. */
- wset_new_total (p, 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");
}
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_total (p, make_number
+ (horflag ? o->total_cols : o->total_lines));
wset_new_normal (p, new_normal);
}
else
n = XWINDOW (new);
wset_frame (n, frame);
wset_parent (n, o->parent);
- wset_vchild (n, Qnil);
- wset_hchild (n, Qnil);
if (EQ (side, Qabove) || EQ (side, Qleft))
{
wset_prev (n, o->prev);
if (NILP (n->prev))
- if (horflag)
- wset_hchild (p, new);
- else
- wset_vchild (p, new);
+ wset_combination (p, horflag, new);
else
wset_next (XWINDOW (n->prev), new);
wset_next (n, old);
}
n->window_end_valid = 0;
- memset (&n->last_cursor, 0, sizeof n->last_cursor);
+ n->last_cursor_vpos = 0;
/* Get special geometry settings from reference window. */
- wset_left_margin_cols (n, r->left_margin_cols);
- wset_right_margin_cols (n, r->right_margin_cols);
- wset_left_fringe_width (n, r->left_fringe_width);
- wset_right_fringe_width (n, r->right_fringe_width);
+ n->left_margin_cols = r->left_margin_cols;
+ n->right_margin_cols = r->right_margin_cols;
+ n->left_fringe_width = r->left_fringe_width;
+ n->right_fringe_width = r->right_fringe_width;
n->fringes_outside_margins = r->fringes_outside_margins;
- wset_scroll_bar_width (n, r->scroll_bar_width);
+ n->scroll_bar_width = r->scroll_bar_width;
wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type);
/* Directly assign orthogonal coordinates and sizes. */
if (horflag)
{
- wset_top_line (n, o->top_line);
- wset_total_lines (n, o->total_lines);
+ n->top_line = o->top_line;
+ n->total_lines = o->total_lines;
}
else
{
- wset_left_col (n, o->left_col);
- wset_total_cols (n, o->total_cols);
+ n->left_col = o->left_col;
+ n->total_cols = o->total_cols;
}
/* Iso-coordinates and sizes are assigned by window_resize_apply,
block_input ();
window_resize_apply (p, horflag);
- adjust_glyphs (f);
+ adjust_frame_glyphs (f);
/* Set buffer of NEW to buffer of reference window. Don't run
any hooks. */
- set_window_buffer (new, r->buffer, 0, 1);
+ set_window_buffer (new, r->contents, 0, 1);
unblock_input ();
/* Maybe we should run the scroll functions in Elisp (which already
register Lisp_Object parent, sibling, frame, root;
struct window *w, *p, *s, *r;
struct frame *f;
- bool 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);
sibling = w->next;
s = XWINDOW (sibling);
wset_prev (s, Qnil);
- if (horflag)
- wset_hchild (p, sibling);
- else
- wset_vchild (p, sibling);
+ wset_combination (p, horflag, sibling);
}
else
/* Get SIBLING above (on the left of) WINDOW. */
}
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. */
{
wset_next (w, Qnil); /* Don't delete w->next too. */
free_window_matrices (w);
- if (!NILP (w->vchild))
- {
- delete_all_child_windows (w->vchild);
- wset_vchild (w, Qnil);
- }
- else if (!NILP (w->hchild))
+ if (WINDOWP (w->contents))
{
- delete_all_child_windows (w->hchild);
- wset_hchild (w, Qnil);
+ delete_all_child_windows (w->contents);
+ wset_combination (w, 0, Qnil);
}
- else if (!NILP (w->buffer))
+ else
{
unshow_buffer (w);
unchain_marker (XMARKER (w->pointm));
wset_normal_cols (s, p->normal_cols);
wset_normal_lines (s, p->normal_lines);
/* Mark PARENT as deleted. */
- wset_vchild (p, Qnil);
- wset_hchild (p, Qnil);
+ wset_combination (p, 0, Qnil);
/* Try to merge SIBLING into its new parent. */
recombine_windows (sibling);
}
- adjust_glyphs (f);
+ adjust_frame_glyphs (f);
if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f)))
/* We deleted the frame's selected window. */
if (before_sibling)
{
wset_prev (s, window);
- if (horflag)
- wset_hchild (p, window);
- else
- wset_vchild (p, window);
+ wset_combination (p, horflag, window);
}
else
{
window_resize_apply (r, 0);
/* Grow the mini-window. */
- wset_top_line
- (w, make_number (XFASTINT (r->top_line) + XFASTINT (r->total_lines)));
- wset_total_lines
- (w, make_number (XFASTINT (w->total_lines) - XINT (value)));
- w->last_modified = 0;
- 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);
+ adjust_frame_glyphs (f);
unblock_input ();
}
}
eassert (MINI_WINDOW_P (w));
- size = XINT (w->total_lines);
+ size = w->total_lines;
if (size > 1)
{
root = FRAME_ROOT_WINDOW (f);
window_resize_apply (r, 0);
/* Shrink the mini-window. */
- wset_top_line (w, make_number (XFASTINT (r->top_line)
- + XFASTINT (r->total_lines)));
- wset_total_lines (w, make_number (1));
-
- w->last_modified = 0;
- 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);
+ adjust_frame_glyphs (f);
unblock_input ();
}
/* If the above failed for whatever strange reason we must make a
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 ();
window_resize_apply (r, 0);
- wset_total_lines (w, w->new_total);
- wset_top_line (w, make_number (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);
+ adjust_frame_glyphs (f);
unblock_input ();
run_window_configuration_change_hook (f);
{
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;
- w->last_modified = 0;
- 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;
visible. */
w->vscroll = (it.last_visible_y
- it.current_y + it.max_ascent + it.max_descent);
- adjust_glyphs (it.f);
+ adjust_frame_glyphs (it.f);
}
else
{
/* 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_both (w->start, w->buffer, IT_CHARPOS (it),
+ 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;
- w->last_modified = 0;
- 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);
+ = 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 = marker_position (w->start);
ptrdiff_t startbyte = marker_byte_position (w->start);
{
/* 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;
- w->last_modified = 0;
- w->last_overlay_modified = 0;
/* Set force_start so that redisplay_window will run
the window-scroll-functions. */
w->force_start = 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);
+ Fset_buffer (w->contents);
SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm));
if (NILP (arg))
{
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;
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 (charpos < BEGV)
- SET_TEXT_POS (start, BEGV, BEGV_BYTE);
- else if (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);
(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;
/* Invalidate pixel data calculated for all compositions. */
for (i = 0; i < n_compositions; i++)
composition_table[i]->font = NULL;
-
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
WINDOW_XFRAME (w)->minimize_tool_bar_window_p = 1;
-
+#endif
Fredraw_frame (WINDOW_FRAME (w));
SET_FRAME_GARBAGED (WINDOW_XFRAME (w));
}
/* 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
}
/* Set the new window start. */
- set_marker_both (w->start, w->buffer, charpos, bytepos);
+ set_marker_both (w->start, w->contents, charpos, bytepos);
w->window_end_valid = 0;
w->optional_new_start = 1;
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;
- FRAME_PTR f;
+ struct frame *f;
ptrdiff_t old_point = -1;
CHECK_WINDOW_CONFIGURATION (configuration);
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 = marker_position (XWINDOW (data->current_window)->pointm);
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 = marker_position (XWINDOW (data->current_window)->pointm);
p = SAVED_WINDOW_N (saved_windows, k);
window = p->window;
w = XWINDOW (window);
- if (!NILP (w->buffer)
- && !EQ (w->buffer, p->buffer)
+ 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. */
|| data->frame_cols != previous_frame_cols)
change_frame_size (f, data->frame_lines,
data->frame_cols, 0, 0, 0);
-#if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
+#ifdef HAVE_MENUS
if (data->frame_menu_bar_lines
!= previous_frame_menu_bar_lines)
- x_set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines),
- make_number (0));
+ {
+#ifdef HAVE_WINDOW_SYSTEM
+ if (FRAME_WINDOW_P (f))
+ x_set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines),
+ make_number (0));
+ else /* TTY or MSDOS */
+#endif
+ set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines),
+ make_number (0));
+ }
+#endif
#ifdef HAVE_WINDOW_SYSTEM
if (data->frame_tool_bar_lines
!= previous_frame_tool_bar_lines)
x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines),
make_number (0));
-#endif
#endif
/* "Swap out" point from the selected window's buffer
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++;
{
wset_prev (w, Qnil);
if (!NILP (w->parent))
- {
- if (EQ (p->total_cols, XWINDOW (w->parent)->total_cols))
- {
- wset_vchild (XWINDOW (w->parent), p->window);
- wset_hchild (XWINDOW (w->parent), Qnil);
- }
- else
- {
- wset_hchild (XWINDOW (w->parent), p->window);
- wset_vchild (XWINDOW (w->parent), Qnil);
- }
- }
+ wset_combination (XWINDOW (w->parent),
+ (XINT (p->total_cols)
+ != XWINDOW (w->parent)->total_cols),
+ p->window);
}
/* If we squirreled away the buffer, restore it now. */
if (BUFFERP (w->combination_limit))
wset_buffer (w, w->combination_limit);
- wset_left_col (w, p->left_col);
- wset_top_line (w, p->top_line);
- wset_total_cols (w, p->total_cols);
- wset_total_lines (w, p->total_lines);
+ 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);
- wset_left_margin_cols (w, p->left_margin_cols);
- wset_right_margin_cols (w, p->right_margin_cols);
- wset_left_fringe_width (w, p->left_fringe_width);
- wset_right_fringe_width (w, p->right_fringe_width);
+ 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);
- wset_scroll_bar_width (w, p->scroll_bar_width);
+ 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);
}
}
- w->last_modified = 0;
- w->last_overlay_modified = 0;
-
- /* Reinstall the saved buffer and pointers into it. */
- if (NILP (p->buffer))
- /* An internal window. */
- wset_buffer (w, p->buffer);
- else if (BUFFER_LIVE_P (XBUFFER (p->buffer)))
+ if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
/* If saved buffer is alive, install it. */
{
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->start, p->start, w->contents);
set_marker_restricted (w->pointm, p->pointm,
- w->buffer);
- Fset_marker (BVAR (XBUFFER (w->buffer), mark),
- p->mark, w->buffer);
+ 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
&& XBUFFER (p->buffer) == current_buffer)
Fgoto_char (w->pointm);
}
- else if (!NILP (w->buffer)
- && BUFFER_LIVE_P (XBUFFER (w->buffer)))
- /* 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_both (w->start, w->buffer, 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)));
- w->start_at_line_beg = 1;
- }
- else
- /* Window has no live buffer, get one. */
+ 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_both (w->start, w->contents, 0, 0);
+ if (XMARKER (w->pointm)->buffer == 0)
+ 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 (!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
wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
/* This will set the markers to beginning of visible
range. */
- set_marker_restricted_both (w->start, w->buffer, 0, 0);
- set_marker_restricted_both (w->pointm, w->buffer, 0, 0);
+ 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. */
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)
|| previous_frame_cols != FRAME_COLS (f))
change_frame_size (f, previous_frame_lines, previous_frame_cols,
0, 0, 0);
-#if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
+#ifdef HAVE_MENUS
if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f))
- x_set_menu_bar_lines (f, make_number (previous_frame_menu_bar_lines),
- make_number (0));
+ {
+#ifdef HAVE_WINDOW_SYSTEM
+ if (FRAME_WINDOW_P (f))
+ x_set_menu_bar_lines (f,
+ make_number (previous_frame_menu_bar_lines),
+ make_number (0));
+ else /* TTY or MSDOS */
+#endif
+ set_menu_bar_lines (f, make_number (previous_frame_menu_bar_lines),
+ make_number (0));
+ }
+#endif
#ifdef HAVE_WINDOW_SYSTEM
if (previous_frame_tool_bar_lines != FRAME_TOOL_BAR_LINES (f))
x_set_tool_bar_lines (f, make_number (previous_frame_tool_bar_lines),
make_number (0));
-#endif
#endif
/* 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. */
- eassert (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);
+ adjust_frame_glyphs (f);
unblock_input ();
/* Scan dead buffer windows. */
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)->buffer, new_current_buffer))
+ if (!EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
Fgoto_char (make_number (old_point));
}
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);
- if (!NILP (w->vchild))
- {
- delete_all_child_windows (w->vchild);
- wset_vchild (w, Qnil);
- }
- else if (!NILP (w->hchild))
+ if (WINDOWP (w->contents))
{
- delete_all_child_windows (w->hchild);
- wset_hchild (w, 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));
/* 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->buffer);
+ wset_combination_limit (w, w->contents);
wset_buffer (w, 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;
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);
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;
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->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 = w->scroll_bar_width;
+ 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 = build_marker (XBUFFER (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;
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_frame_glyphs (XFRAME (WINDOW_FRAME (w)));
+}
+
\f
/***********************************************************************
Marginal Areas
***********************************************************************/
+static struct window *
+set_window_margins (struct window *w, Lisp_Object left_width,
+ Lisp_Object right_width)
+{
+ int left, right;
+
+ /* 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 (w->left_margin_cols != left || w->right_margin_cols != right)
+ {
+ w->left_margin_cols = left;
+ w->right_margin_cols = right;
+ return w;
+ }
+ return NULL;
+}
+
DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins,
2, 3, 0,
doc: /* Set width of marginal areas of window 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. */)
+means no margin.
+
+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 = decode_live_window (window);
-
- /* Translate negative or zero widths to nil.
- Margins that are too wide have to be checked elsewhere. */
-
- if (!NILP (left_width))
- {
- CHECK_NUMBER (left_width);
- if (XINT (left_width) <= 0)
- left_width = Qnil;
- }
-
- 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))
- {
- wset_left_margin_cols (w, left_width);
- wset_right_margin_cols (w, right_width);
-
- adjust_window_margins (w);
-
- ++windows_or_buffers_changed;
- adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
- }
-
- return Qnil;
+ struct window *w = set_window_margins (decode_live_window (window),
+ left_width, right_width);
+ return w ? (apply_window_adjustment (w), Qt) : Qnil;
}
(Lisp_Object window)
{
struct window *w = decode_live_window (window);
- return Fcons (w->left_margin_cols, w->right_margin_cols);
+ 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.
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_live_window (window);
- int outside = !NILP (outside_margins);
-
- 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)
- || w->fringes_outside_margins != outside))
- {
- wset_left_fringe_width (w, left_width);
- wset_right_fringe_width (w, right_width);
- w->fringes_outside_margins = outside;
-
- adjust_window_margins (w);
+display marginal areas and the text area.
- clear_glyph_matrix (w->current_matrix);
- w->window_end_valid = 0;
-
- ++windows_or_buffers_changed;
- adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
- }
-
- 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;
}
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.
-WINDOW must be a live window and defaults to the selected one.
-
-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_live_window (window);
+ int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width)));
- if (!NILP (width))
- {
- CHECK_RANGED_INTEGER (width, 0, INT_MAX);
-
- 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))
{
- wset_scroll_bar_width (w, width);
+ w->scroll_bar_width = iwidth;
wset_vertical_scroll_bar_type (w, vertical_type);
+ return w;
+ }
+ return NULL;
+}
- adjust_window_margins (w);
-
- clear_glyph_matrix (w->current_matrix);
- w->window_end_valid = 0;
+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;
}
/* Adjust glyph matrix of the frame if the virtual display
area becomes larger than before. */
if (w->vscroll < 0 && w->vscroll < old_dy)
- adjust_glyphs (f);
+ adjust_frame_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, bool freeze_p)
-{
- foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0));
-}
-
-\f
/***********************************************************************
Initialization
***********************************************************************/
Vterminal_frame = selected_frame;
minibuf_window = f->minibuffer_window;
selected_window = f->selected_window;
- last_nonminibuf_frame = f;
window_initialized = 1;
}