#include <setjmp.h>
#include "lisp.h"
+#include "character.h"
#include "buffer.h"
#include "keyboard.h"
#include "keymap.h"
static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically;
static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
static Lisp_Object Qsafe, Qabove, Qbelow;
-static Lisp_Object Qauto_buffer_name, Qclone_of, Qstate;
+static Lisp_Object Qauto_buffer_name, Qclone_of;
static int displayed_window_lines (struct window *);
static struct window *decode_window (Lisp_Object);
static int count_windows (struct window *);
static int get_leaf_windows (struct window *, struct window **, int);
-static void window_scroll (Lisp_Object, int, int, 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 int window_scroll_pixel_based_preserve_y;
/* Same for window_scroll_line_based. */
-static int window_scroll_preserve_hpos;
-static int window_scroll_preserve_vpos;
+static EMACS_INT window_scroll_preserve_hpos;
+static EMACS_INT window_scroll_preserve_vpos;
\f
static struct window *
decode_window (register Lisp_Object window)
redisplay_window has altered point after scrolling,
because it makes the change only in the window. */
{
- register EMACS_INT new_point = marker_position (w->pointm);
+ register ptrdiff_t new_point = marker_position (w->pointm);
if (new_point < BEGV)
SET_PT (BEGV);
else if (new_point > ZV)
(Lisp_Object window, Lisp_Object ncol)
{
struct window *w = decode_window (window);
- int hscroll;
+ ptrdiff_t hscroll;
CHECK_NUMBER (ncol);
- hscroll = max (0, XINT (ncol));
+ hscroll = clip_to_bounds (0, XINT (ncol), PTRDIFF_MAX);
/* Prevent redisplay shortcuts when changing the hscroll. */
if (XINT (w->hscroll) != hscroll)
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. */
- w->start_at_line_beg = Qnil;
+ w->start_at_line_beg = 0;
if (NILP (noforce))
- w->force_start = Qt;
- w->update_mode_line = Qt;
+ w->force_start = 1;
+ w->update_mode_line = 1;
XSETFASTINT (w->last_modified, 0);
XSETFASTINT (w->last_overlay_modified, 0);
if (!EQ (window, selected_window))
register struct window *w;
register struct buffer *b;
struct glyph_row *row, *end_row;
- int max_y, crop, i, n;
+ int max_y, crop, i;
+ EMACS_INT n;
w = decode_window (window);
if (EQ (w->buffer, obj))
{
mark_window_display_accurate (window, 0);
- w->update_mode_line = Qt;
+ w->update_mode_line = 1;
XBUFFER (obj)->prevent_redisplay_optimizations_p = 1;
++update_mode_lines;
best_window = window;
struct window *w, *r, *s;
struct frame *f;
Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta;
- EMACS_INT startpos IF_LINT (= 0);
+ ptrdiff_t startpos IF_LINT (= 0);
int top IF_LINT (= 0), new_top, resize_failed;
w = decode_any_window (window);
}
BLOCK_INPUT;
+ if (!FRAME_INITIAL_P (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
+ some of their glyphs highlighted in mouse face. (These rows
+ are marked with a non-zero mouse_face_p flag.) If WINDOW
+ indeed has some glyphs highlighted in mouse face, signal to
+ frame's up-to-date hook that mouse highlight was overwritten,
+ so that it will arrange for redisplaying the highlight. */
+ if (EQ (hlinfo->mouse_face_window, window))
+ {
+ 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;
+ }
+ }
free_window_matrices (r);
windows_or_buffers_changed++;
set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
w->window_end_valid = Qnil;
- w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE
- || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt
- : Qnil);
+ 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
get called. */
- w->optional_new_start = Qt;
+ w->optional_new_start = 1;
set_buffer_internal (obuf);
}
void
run_window_configuration_change_hook (struct frame *f)
{
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object frame, global_wcch
= Fdefault_value (Qwindow_configuration_change_hook);
XSETFRAME (frame, f);
- if (NILP (Vrun_hooks))
+ if (NILP (Vrun_hooks) || !NILP (inhibit_lisp_code))
return;
/* Use the right buffer. Matters when running the local hooks. */
if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook,
buffer)))
{
- int inner_count = SPECPDL_INDEX ();
+ ptrdiff_t inner_count = SPECPDL_INDEX ();
record_unwind_protect (select_window_norecord, Fselected_window ());
select_window_norecord (window);
run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
{
struct window *w = XWINDOW (window);
struct buffer *b = XBUFFER (buffer);
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
int samebuf = EQ (buffer, w->buffer);
w->buffer = buffer;
set_marker_restricted (w->start,
make_number (b->last_window_start),
buffer);
- w->start_at_line_beg = Qnil;
- w->force_start = Qnil;
+ w->start_at_line_beg = 0;
+ w->force_start = 0;
XSETFASTINT (w->last_modified, 0);
XSETFASTINT (w->last_overlay_modified, 0);
}
{
struct window *w = XWINDOW (object);
mark_window_display_accurate (object, 0);
- w->update_mode_line = Qt;
+ w->update_mode_line = 1;
if (BUFFERP (w->buffer))
XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
++update_mode_lines;
/* Run temp-buffer-show-hook, with the chosen window selected
and its buffer current. */
{
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object prev_window, prev_buffer;
prev_window = selected_window;
XSETBUFFER (prev_buffer, old);
w = allocate_window ();
/* Initialize all Lisp data. */
- w->frame = w->mini_p = Qnil;
+ w->frame = Qnil;
+ w->mini = 0;
w->next = w->prev = w->hchild = w->vchild = w->parent = Qnil;
XSETFASTINT (w->left_col, 0);
XSETFASTINT (w->top_line, 0);
w->buffer = Qnil;
w->start = Fmake_marker ();
w->pointm = Fmake_marker ();
- w->force_start = w->optional_new_start = Qnil;
+ w->force_start = w->optional_new_start = 0;
XSETFASTINT (w->hscroll, 0);
XSETFASTINT (w->min_hscroll, 0);
XSETFASTINT (w->use_time, 0);
XSETFASTINT (w->sequence_number, sequence_number);
w->temslot = w->last_modified = w->last_overlay_modified = Qnil;
XSETFASTINT (w->last_point, 0);
- w->last_had_star = w->vertical_scroll_bar = Qnil;
+ w->last_had_star = 0;
+ w->vertical_scroll_bar = Qnil;
w->left_margin_cols = w->right_margin_cols = Qnil;
w->left_fringe_width = w->right_fringe_width = Qnil;
w->fringes_outside_margins = Qnil;
w->scroll_bar_width = Qnil;
w->vertical_scroll_bar_type = Qt;
- w->last_mark_x = w->last_mark_y = Qnil;
XSETFASTINT (w->window_end_pos, 0);
XSETFASTINT (w->window_end_vpos, 0);
- w->window_end_valid = w->update_mode_line = Qnil;
- w->start_at_line_beg = w->display_table = w->dedicated = Qnil;
+ w->window_end_valid = w->display_table = Qnil;
+ w->update_mode_line = w->start_at_line_beg = 0;
+ w->dedicated = Qnil;
w->base_line_number = w->base_line_pos = w->region_showing = Qnil;
w->column_number_displayed = w->redisplay_end_trigger = Qnil;
w->combination_limit = w->window_parameters = Qnil;
&& EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
/* We can delete WINDOW now. */
{
+
/* Block input. */
BLOCK_INPUT;
window_resize_apply (p, horflag);
+ /* If this window is referred to by the dpyinfo's mouse
+ highlight, invalidate that slot to be safe (Bug#9904). */
+ if (!FRAME_INITIAL_P (f))
+ {
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
+
+ if (EQ (hlinfo->mouse_face_window, window))
+ hlinfo->mouse_face_window = Qnil;
+ }
+
windows_or_buffers_changed++;
Vwindow_list = Qnil;
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
respectively. */
static void
-window_scroll (Lisp_Object window, int n, int whole, int noerror)
+window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror)
{
immediate_quit = 1;
+ n = clip_to_bounds (INT_MIN, n, INT_MAX);
/* If we must, use the pixel-based version which is much slower than
the line-based one but can handle varying line heights. */
void *itdata = NULL;
SET_TEXT_POS_FROM_MARKER (start, w->start);
+ /* Scrolling a minibuffer window via scroll bar when the echo area
+ shows long text sometimes resets the minibuffer contents behind
+ our backs. */
+ if (CHARPOS (start) > ZV)
+ SET_TEXT_POS (start, BEGV, BEGV_BYTE);
/* If PT is not visible in WINDOW, move back one half of
the screen. Allow PT to be partially visible, otherwise
/* Maybe modify window start instead of scrolling. */
if (rbot > 0 || w->vscroll < 0)
{
- EMACS_INT spos;
+ ptrdiff_t spos;
Fset_window_vscroll (window, make_number (0), Qt);
/* If there are other text lines above the current row,
spos = min (XINT (Fline_end_position (Qnil)) + 1, ZV);
set_marker_restricted (w->start, make_number (spos),
w->buffer);
- w->start_at_line_beg = Qt;
- w->update_mode_line = Qt;
+ w->start_at_line_beg = 1;
+ w->update_mode_line = 1;
XSETFASTINT (w->last_modified, 0);
XSETFASTINT (w->last_overlay_modified, 0);
/* Set force_start so that redisplay_window will run the
window-scroll-functions. */
- w->force_start = Qt;
+ w->force_start = 1;
return;
}
}
start_display (&it, w, start);
if (whole)
{
- EMACS_INT start_pos = IT_CHARPOS (it);
+ ptrdiff_t start_pos = IT_CHARPOS (it);
int dy = WINDOW_FRAME_LINE_HEIGHT (w);
dy = max ((window_box_height (w)
- next_screen_context_lines * dy),
if (! vscrolled)
{
- EMACS_INT pos = IT_CHARPOS (it);
- EMACS_INT bytepos;
+ ptrdiff_t pos = IT_CHARPOS (it);
+ ptrdiff_t bytepos;
/* If in the middle of a multi-glyph character move forward to
the next character. */
set_marker_restricted (w->start, make_number (pos),
w->buffer);
bytepos = XMARKER (w->start)->bytepos;
- w->start_at_line_beg = ((pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n')
- ? Qt : Qnil);
- w->update_mode_line = Qt;
+ w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n');
+ w->update_mode_line = 1;
XSETFASTINT (w->last_modified, 0);
XSETFASTINT (w->last_overlay_modified, 0);
/* Set force_start so that redisplay_window will run the
window-scroll-functions. */
- w->force_start = Qt;
+ w->force_start = 1;
}
/* The rest of this function uses current_y in a nonstandard way,
}
else if (n < 0)
{
- EMACS_INT charpos, bytepos;
+ ptrdiff_t charpos, bytepos;
int partial_p;
/* Save our position, for the
in `grep-mode-font-lock-keywords'). So we use a marker to record
the old point position, to prevent crashes in SET_PT_BOTH. */
Lisp_Object opoint_marker = Fpoint_marker ();
- register EMACS_INT pos, pos_byte;
+ register ptrdiff_t pos, pos_byte;
register int ht = window_internal_height (w);
register Lisp_Object tem;
int lose;
Lisp_Object bolp;
- EMACS_INT startpos;
+ ptrdiff_t startpos;
Lisp_Object original_pos = Qnil;
/* If scrolling screen-fulls, compute the number of lines to
max (0, min (scroll_margin, XINT (w->total_lines) / 4));
set_marker_restricted_both (w->start, w->buffer, pos, pos_byte);
- w->start_at_line_beg = bolp;
- w->update_mode_line = Qt;
+ w->start_at_line_beg = !NILP (bolp);
+ w->update_mode_line = 1;
XSETFASTINT (w->last_modified, 0);
XSETFASTINT (w->last_overlay_modified, 0);
/* Set force_start so that redisplay_window will run
the window-scroll-functions. */
- w->force_start = Qt;
+ w->force_start = 1;
if (!NILP (Vscroll_preserve_screen_position)
&& (whole || !EQ (Vscroll_preserve_screen_position, Qt)))
static void
scroll_command (Lisp_Object n, int direction)
{
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
xassert (eabs (direction) == 1);
{
Lisp_Object window;
struct window *w;
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
window = Fother_window_for_scrolling ();
w = XWINDOW (window);
(register Lisp_Object arg, Lisp_Object set_minimum)
{
Lisp_Object result;
- int hscroll;
+ EMACS_INT hscroll;
struct window *w = XWINDOW (selected_window);
if (NILP (arg))
(register Lisp_Object arg, Lisp_Object set_minimum)
{
Lisp_Object result;
- int hscroll;
+ EMACS_INT hscroll;
struct window *w = XWINDOW (selected_window);
if (NILP (arg))
struct buffer *buf = XBUFFER (w->buffer);
struct buffer *obuf = current_buffer;
int center_p = 0;
- EMACS_INT charpos, bytepos;
+ ptrdiff_t charpos, bytepos;
EMACS_INT iarg IF_LINT (= 0);
int this_scroll_margin;
{
struct it it;
struct text_pos pt;
- int nlines = min (INT_MAX, -iarg);
+ ptrdiff_t nlines = min (PTRDIFF_MAX, -iarg);
int extra_line_spacing;
int h = window_box_height (w);
void *itdata = bidi_shelve_cache ();
set_marker_both (w->start, w->buffer, charpos, bytepos);
w->window_end_valid = Qnil;
- w->optional_new_start = Qt;
+ w->optional_new_start = 1;
- if (bytepos == BEGV_BYTE || FETCH_BYTE (bytepos - 1) == '\n')
- w->start_at_line_beg = Qt;
- else
- w->start_at_line_beg = Qnil;
+ w->start_at_line_beg = (bytepos == BEGV_BYTE ||
+ FETCH_BYTE (bytepos - 1) == '\n');
set_buffer_internal (obuf);
return Qnil;
int height = window_internal_height (w);
Fvertical_motion (make_number (- (height / 2)), window);
set_marker_both (w->start, w->buffer, PT, PT_BYTE);
- w->start_at_line_beg = Fbolp ();
- w->force_start = Qt;
+ w->start_at_line_beg = !NILP (Fbolp ());
+ w->force_start = 1;
}
else
Fgoto_char (w->start);
Lisp_Object frame;
Lisp_Object auto_buffer_name;
FRAME_PTR f;
- EMACS_INT old_point = -1;
+ ptrdiff_t old_point = -1;
CHECK_WINDOW_CONFIGURATION (configuration);
/* If saved buffer is alive, install it. */
{
w->buffer = p->buffer;
- w->start_at_line_beg = p->start_at_line_beg;
+ w->start_at_line_beg = !NILP (p->start_at_line_beg);
set_marker_restricted (w->start, p->start, w->buffer);
set_marker_restricted (w->pointm, p->pointm, w->buffer);
Fset_marker (BVAR (XBUFFER (w->buffer), mark),
set_marker_restricted_both (w->pointm, w->buffer,
BUF_PT (XBUFFER (w->buffer)),
BUF_PT_BYTE (XBUFFER (w->buffer)));
- w->start_at_line_beg = Qt;
+ w->start_at_line_beg = 1;
}
else if (STRINGP (auto_buffer_name =
Fwindow_parameter (window, Qauto_buffer_name))
{
set_marker_restricted (w->start, make_number (0), w->buffer);
set_marker_restricted (w->pointm, make_number (0), w->buffer);
- w->start_at_line_beg = Qt;
+ w->start_at_line_beg = 1;
}
else
/* Window has no live buffer, get one. */
range. */
set_marker_restricted (w->start, make_number (0), w->buffer);
set_marker_restricted (w->pointm, make_number (0), w->buffer);
- w->start_at_line_beg = Qt;
+ w->start_at_line_beg = 1;
if (!NILP (w->dedicated))
/* Record this window as dead. */
dead_windows = Fcons (window, dead_windows);
tem = XCDR (tem))
{
pers = XCAR (tem);
- /* Save values for persistent window parameters whose cdr
- is either nil or t. */
- if (CONSP (pers) && (NILP (XCDR (pers)) || EQ (XCDR (pers), Qt)))
+ /* Save values for persistent window parameters. */
+ if (CONSP (pers) && !NILP (XCDR (pers)))
{
par = Fassq (XCAR (pers), w->window_parameters);
if (NILP (par))
}
else
p->pointm = Fcopy_marker (w->pointm, Qnil);
+ XMARKER (p->pointm)->insertion_type
+ = !NILP (Vwindow_point_insertion_type);
p->start = Fcopy_marker (w->start, Qnil);
- p->start_at_line_beg = w->start_at_line_beg;
+ p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
tem = BVAR (XBUFFER (w->buffer), mark);
p->mark = Fcopy_marker (tem, Qnil);
point and mark. An exception is made for point in the current buffer:
its value is -not- saved.
This also records the currently selected frame, and FRAME's focus
-redirection (see `redirect-frame-focus'). */)
+redirection (see `redirect-frame-focus'). The variable
+`window-persistent-parameters' specifies which window parameters are
+saved by this function. */)
(Lisp_Object frame)
{
register Lisp_Object tem;
tem = Fmake_vector (make_number (n_windows), Qnil);
data->saved_windows = tem;
for (i = 0; i < n_windows; i++)
- XVECTOR (tem)->contents[i]
- = Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil);
+ ASET (tem, i,
+ Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil));
save_window_save (FRAME_ROOT_WINDOW (f), XVECTOR (tem), 0);
XSETWINDOW_CONFIGURATION (tem, data);
return (tem);
if (!NILP (width))
{
- CHECK_NATNUM (width);
+ CHECK_RANGED_INTEGER (0, width, INT_MAX);
if (XINT (width) == 0)
vertical_type = Qnil;
DEFSYM (Qbelow, "below");
DEFSYM (Qauto_buffer_name, "auto-buffer-name");
DEFSYM (Qclone_of, "clone-of");
- DEFSYM (Qstate, "state");
staticpro (&Vwindow_list);
DEFVAR_LISP ("window-persistent-parameters", Vwindow_persistent_parameters,
doc: /* Alist of persistent window parameters.
-Parameters in this list are saved by `current-window-configuration' and
-`window-state-get' and subsequently restored to their previous values by
-`set-window-configuration' and `window-state-put'.
+This alist specifies which window parameters shall get saved by
+`current-window-configuration' and `window-state-get' and subsequently
+restored to their previous values by `set-window-configuration' and
+`window-state-put'.
The car of each entry of this alist is the symbol specifying the
parameter. The cdr is one of the following:
-The symbol `state' means the parameter is saved by `window-state-get'
-provided its IGNORE argument is nil. `current-window-configuration'
-does not save this parameter.
+nil means the parameter is neither saved by `window-state-get' nor by
+`current-window-configuration'.
-nil means the parameter is saved by `current-window-configuration' and,
-provided its IGNORE argument is nil, by `window-state-get'.
+t means the parameter is saved by `current-window-configuration' and,
+provided its WRITABLE argument is nil, by `window-state-get'.
-t means the parameter is saved unconditionally by both
-`current-window-configuration' and `window-state-get'. Parameters
-without read syntax (like windows or frames) should not use that.
+The symbol `writable' means the parameter is saved unconditionally by
+both `current-window-configuration' and `window-state-get'. Do not use
+this value for parameters without read syntax (like windows or frames).
Parameters not saved by `current-window-configuration' or
`window-state-get' are left alone by `set-window-configuration'
respectively are not installed by `window-state-put'. */);
- Vwindow_persistent_parameters = list1 (Fcons (Qclone_of, Qstate));
+ Vwindow_persistent_parameters = list1 (Fcons (Qclone_of, Qt));
defsubr (&Sselected_window);
defsubr (&Sminibuffer_window);