/* Window creation, deletion and examination for GNU Emacs.
Does not include redisplay.
- Copyright (C) 1985-1987, 1993-1998, 2000-2011
+ Copyright (C) 1985-1987, 1993-1998, 2000-2012
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#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;
+static Lisp_Object Qauto_buffer_name, Qclone_of;
static int displayed_window_lines (struct window *);
static struct window *decode_window (Lisp_Object);
static struct window *
decode_any_window (register Lisp_Object window)
{
+ struct window *w;
+
if (NILP (window))
return XWINDOW (selected_window);
CHECK_WINDOW (window);
- return XWINDOW (window);
+ w = XWINDOW (window);
+ /* The following test throws up every time a tooltip frame is displayed. */
+ /* CHECK_LIVE_FRAME (w->frame); */
+ return w;
}
DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
Lisp_Object window;
if (NILP (frame_or_window))
- window = SELECTED_FRAME ()->root_window;
+ window = FVAR (SELECTED_FRAME (), root_window);
else if (WINDOWP (frame_or_window))
- window = XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window)))->root_window;
+ window = FVAR (XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window))), root_window);
else
{
CHECK_LIVE_FRAME (frame_or_window);
- window = XFRAME (frame_or_window)->root_window;
+ window = FVAR (XFRAME (frame_or_window), root_window);
}
return window;
Lisp_Object window;
if (NILP (frame_or_window))
- window = SELECTED_FRAME ()->root_window;
+ window = FVAR (SELECTED_FRAME (), root_window);
else if (WINDOWP (frame_or_window))
- window = XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window)))->root_window;
+ window = FVAR (XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window))), root_window);
else
{
CHECK_LIVE_FRAME (frame_or_window);
- window = XFRAME (frame_or_window)->root_window;
+ window = FVAR (XFRAME (frame_or_window), root_window);
}
while (NILP (XWINDOW (window)->buffer))
Lisp_Object window;
if (NILP (frame_or_window))
- window = SELECTED_FRAME ()->selected_window;
+ window = FVAR (SELECTED_FRAME (), selected_window);
else if (WINDOWP (frame_or_window))
- window = XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window)))->selected_window;
+ window = FVAR (XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window))),
+ selected_window);
else
{
CHECK_LIVE_FRAME (frame_or_window);
- window = XFRAME (frame_or_window)->selected_window;
+ window = FVAR (XFRAME (frame_or_window), selected_window);
}
return window;
if (EQ (frame, selected_frame))
return Fselect_window (window, norecord);
else
- return XFRAME (frame)->selected_window = window;
+ return FVAR (XFRAME (frame), selected_window) = window;
}
DEFUN ("selected-window", Fselected_window, Sselected_window, 0, 0, 0,
if (NILP (norecord))
{
- ++window_select_count;
- XSETFASTINT (w->use_time, window_select_count);
+ w->use_time = ++window_select_count;
record_buffer (w->buffer);
}
sf = SELECTED_FRAME ();
if (XFRAME (WINDOW_FRAME (w)) != sf)
{
- XFRAME (WINDOW_FRAME (w))->selected_window = window;
+ FVAR (XFRAME (WINDOW_FRAME (w)), selected_window) = window;
/* Use this rather than Fhandle_switch_frame
so that FRAME_FOCUS_FRAME is moved appropriately as we
move around in the state where a minibuffer in a separate
return window;
}
else
- sf->selected_window = window;
+ FVAR (sf, selected_window) = window;
/* Store the current buffer's actual point into the
old selected window. It belongs to that window,
(Lisp_Object window, Lisp_Object limit)
{
register struct window *w = decode_any_window (window);
-
w->combination_limit = limit;
-
return w->combination_limit;
}
selected one. */)
(Lisp_Object window)
{
- return decode_window (window)->use_time;
+ return make_number (decode_window (window)->use_time);
}
\f
DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 1, 0,
WINDOW must be a live window and defaults to the selected one. */)
(Lisp_Object window)
{
- return decode_window (window)->hscroll;
+ return make_number (decode_window (window)->hscroll);
+}
+
+/* Set W's horizontal scroll amount to HSCROLL clipped to a reasonable
+ range, returning the new amount as a fixnum. */
+static Lisp_Object
+set_window_hscroll (struct window *w, EMACS_INT hscroll)
+{
+ /* Horizontal scrolling has problems with large scroll amounts.
+ It's too slow with long lines, and even with small lines the
+ display can be messed up. For now, though, impose only the limits
+ required by the internal representation: horizontal scrolling must
+ fit in fixnum (since it's visible to Elisp) and into ptrdiff_t
+ (since it's stored in a ptrdiff_t). */
+ ptrdiff_t hscroll_max = min (MOST_POSITIVE_FIXNUM, PTRDIFF_MAX);
+ ptrdiff_t new_hscroll = clip_to_bounds (0, hscroll, hscroll_max);
+
+ /* Prevent redisplay shortcuts when changing the hscroll. */
+ if (w->hscroll != new_hscroll)
+ XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
+
+ w->hscroll = new_hscroll;
+ return make_number (new_hscroll);
}
DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0,
doc: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
If WINDOW is nil, the selected window is used.
-Return NCOL. NCOL should be zero or positive.
+Clip the number to a reasonable value if out of range.
+Return the new number. NCOL should be zero or positive.
Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
window so that the location of point moves off-window. */)
(Lisp_Object window, Lisp_Object ncol)
{
struct window *w = decode_window (window);
- ptrdiff_t hscroll;
CHECK_NUMBER (ncol);
- hscroll = clip_to_bounds (0, XINT (ncol), PTRDIFF_MAX);
-
- /* Prevent redisplay shortcuts when changing the hscroll. */
- if (XINT (w->hscroll) != hscroll)
- XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
-
- w->hscroll = make_number (hscroll);
- return ncol;
+ return set_window_hscroll (w, XINT (ncol));
}
DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger,
bar exists. */
if (NILP (window)
&& tool_bar_p
- && WINDOWP (f->tool_bar_window)
- && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0
- && (coordinates_in_window (XWINDOW (f->tool_bar_window), x, y)
+ && WINDOWP (FVAR (f, tool_bar_window))
+ && WINDOW_TOTAL_LINES (XWINDOW (FVAR (f, tool_bar_window))) > 0
+ && (coordinates_in_window (XWINDOW (FVAR (f, tool_bar_window)), x, y)
!= ON_NOTHING))
{
*part = ON_TEXT;
- window = f->tool_bar_window;
+ window = FVAR (f, tool_bar_window);
}
return window;
if (! NILP (update)
&& ! (! NILP (w->window_end_valid)
- && XFASTINT (w->last_modified) >= BUF_MODIFF (b)
- && XFASTINT (w->last_overlay_modified) >= BUF_OVERLAY_MODIFF (b))
+ && w->last_modified >= BUF_MODIFF (b)
+ && w->last_overlay_modified >= BUF_OVERLAY_MODIFF (b))
&& !noninteractive)
{
struct text_pos startp;
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;
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
+ w->force_start = 1;
+ w->update_mode_line = 1;
+ w->last_modified = 0;
+ w->last_overlay_modified = 0;
if (!EQ (window, selected_window))
windows_or_buffers_changed++;
if (NILP (w->window_end_valid)
|| current_buffer->clip_changed
|| current_buffer->prevent_redisplay_optimizations_p
- || XFASTINT (w->last_modified) < BUF_MODIFF (b)
- || XFASTINT (w->last_overlay_modified) < BUF_OVERLAY_MODIFF (b))
+ || w->last_modified < BUF_MODIFF (b)
+ || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b))
return Qnil;
if (NILP (line))
candidate_p = 1;
else if (NILP (all_frames))
{
- xassert (WINDOWP (owindow));
+ eassert (WINDOWP (owindow));
candidate_p = EQ (w->frame, XWINDOW (owindow)->frame);
}
else if (EQ (all_frames, Qvisible))
(Lisp_Object frame, Lisp_Object minibuf, Lisp_Object window)
{
if (NILP (window))
- window = FRAMEP (frame) ? XFRAME (frame)->selected_window : selected_window;
+ window = FRAMEP (frame) ? FVAR (XFRAME (frame), selected_window) : selected_window;
CHECK_WINDOW (window);
if (NILP (frame))
frame = selected_frame;
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;
}
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);
}
return 1;
}
\f
-static Lisp_Object Fset_window_margins (Lisp_Object, Lisp_Object, Lisp_Object);
-static Lisp_Object Fset_window_fringes (Lisp_Object, Lisp_Object, Lisp_Object,
- Lisp_Object);
-static Lisp_Object Fset_window_scroll_bars (Lisp_Object, Lisp_Object,
- Lisp_Object, Lisp_Object);
-static Lisp_Object Fset_window_vscroll (Lisp_Object, Lisp_Object, Lisp_Object);
-
/* The following three routines are needed for running a window's
configuration change hook. */
static void
= 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. */
Resetting hscroll and vscroll here is problematic for things like
image-mode and doc-view-mode since it resets the image's position
whenever we resize the frame. */
- w->hscroll = w->min_hscroll = make_number (0);
+ w->hscroll = w->min_hscroll = 0;
w->vscroll = 0;
set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
set_marker_restricted (w->start,
make_number (b->last_window_start),
buffer);
- w->start_at_line_beg = Qnil;
- w->force_start = Qnil;
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
+ 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. */
{
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;
Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
Vminibuf_scroll_window = window;
w = XWINDOW (window);
- XSETFASTINT (w->hscroll, 0);
- XSETFASTINT (w->min_hscroll, 0);
+ w->hscroll = 0;
+ w->min_hscroll = 0;
set_marker_restricted_both (w->start, buf, BEG, BEG);
set_marker_restricted_both (w->pointm, buf, BEG, BEG);
{
Lisp_Object parent;
register struct window *o, *p;
- int i;
o = XWINDOW (window);
p = allocate_window ();
- for (i = 0; i < VECSIZE (struct window); ++i)
- ((struct Lisp_Vector *) p)->contents[i]
- = ((struct Lisp_Vector *) o)->contents[i];
+ memcpy ((char *) p + sizeof (struct vectorlike_header),
+ (char *) o + sizeof (struct vectorlike_header),
+ sizeof (Lisp_Object) * VECSIZE (struct window));
XSETWINDOW (parent, p);
- ++sequence_number;
- XSETFASTINT (p->sequence_number, sequence_number);
+ p->sequence_number = ++sequence_number;
replace_window (window, parent, 1);
register struct window *w;
w = allocate_window ();
- /* Initialize all Lisp data. */
- w->frame = w->mini_p = Qnil;
- w->next = w->prev = w->hchild = w->vchild = w->parent = Qnil;
+ /* Initialize Lisp data. Note that allocate_window initializes all
+ Lisp data to nil, so do it only for slots which should not be nil. */
XSETFASTINT (w->left_col, 0);
XSETFASTINT (w->top_line, 0);
XSETFASTINT (w->total_lines, 0);
w->normal_cols = make_float (1.0);
XSETFASTINT (w->new_total, 0);
XSETFASTINT (w->new_normal, 0);
- w->buffer = Qnil;
w->start = Fmake_marker ();
w->pointm = Fmake_marker ();
- w->force_start = w->optional_new_start = Qnil;
- XSETFASTINT (w->hscroll, 0);
- XSETFASTINT (w->min_hscroll, 0);
- XSETFASTINT (w->use_time, 0);
- ++sequence_number;
- XSETFASTINT (w->sequence_number, sequence_number);
- w->temslot = w->last_modified = w->last_overlay_modified = Qnil;
- XSETFASTINT (w->last_point, 0);
- w->last_had_star = 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->base_line_number = w->base_line_pos = w->region_showing = Qnil;
- w->column_number_displayed = w->redisplay_end_trigger = Qnil;
- w->combination_limit = w->window_parameters = Qnil;
- w->prev_buffers = w->next_buffers = Qnil;
- /* Initialize non-Lisp data. */
- w->desired_matrix = w->current_matrix = 0;
+
+ /* Initialize non-Lisp data. Note that allocate_window zeroes out all
+ non-Lisp data, so do it only for slots which should not be zero. */
w->nrows_scale_factor = w->ncols_scale_factor = 1;
- memset (&w->cursor, 0, sizeof (w->cursor));
- memset (&w->last_cursor, 0, sizeof (w->last_cursor));
- memset (&w->phys_cursor, 0, sizeof (w->phys_cursor));
w->phys_cursor_type = -1;
w->phys_cursor_width = -1;
- w->phys_cursor_on_p = 0;
- w->last_cursor_off_p = w->cursor_off_p = 0;
- w->must_be_updated_p = 0;
- w->pseudo_window_p = 0;
- w->frozen_window_start_p = 0;
- w->vscroll = 0;
+ w->sequence_number = ++sequence_number;
+
/* Reset window_list. */
Vwindow_list = Qnil;
/* Return window. */
}
/* Clear out some redisplay caches. */
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
+ w->last_modified = 0;
+ w->last_overlay_modified = 0;
}
void
resize_frame_windows (struct frame *f, int size, int horflag)
{
- Lisp_Object root = f->root_window;
+ Lisp_Object root = FVAR (f, root_window);
struct window *r = XWINDOW (root);
- Lisp_Object mini = f->minibuffer_window;
+ Lisp_Object mini = FVAR (f, minibuffer_window);
struct window *m;
/* new_size is the new size of the frame's root window. */
int new_size = (horflag
{
/* We lost. Delete all windows but the frame's
selected one. */
- root = f->selected_window;
+ root = FVAR (f, selected_window);
Fdelete_other_windows_internal (root, Qnil);
if (horflag)
XSETFASTINT (XWINDOW (root)->total_cols, new_size);
&& 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;
struct window *r;
Lisp_Object root, value;
- xassert (MINI_WINDOW_P (w));
- xassert (delta >= 0);
+ eassert (MINI_WINDOW_P (w));
+ eassert (delta >= 0);
root = FRAME_ROOT_WINDOW (f);
r = XWINDOW (root);
/* Grow the mini-window. */
XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - XINT (value));
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
+ w->last_modified = 0;
+ w->last_overlay_modified = 0;
adjust_glyphs (f);
UNBLOCK_INPUT;
Lisp_Object root, value;
EMACS_INT size;
- xassert (MINI_WINDOW_P (w));
+ eassert (MINI_WINDOW_P (w));
size = XINT (w->total_lines);
if (size > 1)
XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
XSETFASTINT (w->total_lines, 1);
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
+ w->last_modified = 0;
+ w->last_overlay_modified = 0;
adjust_glyphs (f);
UNBLOCK_INPUT;
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
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;
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
+ 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 = Qt;
+ w->force_start = 1;
return;
}
}
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;
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
+ 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 = Qt;
+ w->force_start = 1;
}
/* The rest of this function uses current_y in a nonstandard way,
struct position posit
= *compute_motion (startpos, 0, 0, 0,
PT, ht, 0,
- -1, XINT (w->hscroll),
+ -1, w->hscroll,
0, w);
window_scroll_preserve_vpos = posit.vpos;
- window_scroll_preserve_hpos = posit.hpos + XINT (w->hscroll);
+ window_scroll_preserve_hpos = posit.hpos + w->hscroll;
}
original_pos = Fcons (make_number (window_scroll_preserve_hpos),
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;
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
+ 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 = Qt;
+ w->force_start = 1;
if (!NILP (Vscroll_preserve_screen_position)
&& (whole || !EQ (Vscroll_preserve_screen_position, Qt)))
{
ptrdiff_t count = SPECPDL_INDEX ();
- xassert (eabs (direction) == 1);
+ eassert (eabs (direction) == 1);
/* If selected window's buffer isn't current, make it current for
the moment. But don't screw up if window_scroll gets an error. */
else
{
if (CONSP (arg))
- arg = Fcar (arg);
+ arg = XCAR (arg);
CHECK_NUMBER (arg);
window_scroll (window, XINT (arg), 0, 1);
}
by this function. This happens in an interactive call. */)
(register Lisp_Object arg, Lisp_Object set_minimum)
{
- Lisp_Object result;
- EMACS_INT hscroll;
struct window *w = XWINDOW (selected_window);
-
- if (NILP (arg))
- XSETFASTINT (arg, window_body_cols (w) - 2);
- else
- arg = Fprefix_numeric_value (arg);
-
- hscroll = XINT (w->hscroll) + XINT (arg);
- result = Fset_window_hscroll (selected_window, make_number (hscroll));
+ EMACS_INT requested_arg = (NILP (arg)
+ ? window_body_cols (w) - 2
+ : XINT (Fprefix_numeric_value (arg)));
+ Lisp_Object result = set_window_hscroll (w, w->hscroll + requested_arg);
if (!NILP (set_minimum))
w->min_hscroll = w->hscroll;
by this function. This happens in an interactive call. */)
(register Lisp_Object arg, Lisp_Object set_minimum)
{
- Lisp_Object result;
- EMACS_INT hscroll;
struct window *w = XWINDOW (selected_window);
-
- if (NILP (arg))
- XSETFASTINT (arg, window_body_cols (w) - 2);
- else
- arg = Fprefix_numeric_value (arg);
-
- hscroll = XINT (w->hscroll) - XINT (arg);
- result = Fset_window_hscroll (selected_window, make_number (hscroll));
+ EMACS_INT requested_arg = (NILP (arg)
+ ? window_body_cols (w) - 2
+ : XINT (Fprefix_numeric_value (arg)));
+ Lisp_Object result = set_window_hscroll (w, w->hscroll - requested_arg);
if (!NILP (set_minimum))
w->min_hscroll = w->hscroll;
also erase the entire frame and redraw it (when `auto-resize-tool-bars'
is set to `grow-only', this resets the tool-bar's height to the minimum
height needed); if `recenter-redisplay' has the special value `tty',
-then only tty frame are redrawn.
+then only tty frames are redrawn.
Just C-u as prefix means put point in the center of the window
and redisplay normally--don't erase and redraw the frame. */)
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 window;
Lisp_Object dead_windows = Qnil;
+ register Lisp_Object tem, par, pers;
register struct window *w;
register struct saved_window *p;
struct window *root_window;
really like to do is to free only those matrices not reused
below. */
root_window = XWINDOW (FRAME_ROOT_WINDOW (f));
- leaf_windows
- = (struct window **) alloca (count_windows (root_window)
- * sizeof (struct window *));
+ leaf_windows = alloca (count_windows (root_window)
+ * sizeof *leaf_windows);
n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
/* Kludge Alert!
w->total_lines = p->total_lines;
w->normal_cols = p->normal_cols;
w->normal_lines = p->normal_lines;
- w->hscroll = p->hscroll;
- w->min_hscroll = p->min_hscroll;
+ w->hscroll = XFASTINT (p->hscroll);
+ w->min_hscroll = XFASTINT (p->min_hscroll);
w->display_table = p->display_table;
w->left_margin_cols = p->left_margin_cols;
w->right_margin_cols = p->right_margin_cols;
w->left_fringe_width = p->left_fringe_width;
w->right_fringe_width = p->right_fringe_width;
- w->fringes_outside_margins = p->fringes_outside_margins;
+ w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
w->scroll_bar_width = p->scroll_bar_width;
w->vertical_scroll_bar_type = p->vertical_scroll_bar_type;
w->dedicated = p->dedicated;
w->combination_limit = p->combination_limit;
- w->window_parameters = p->window_parameters;
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
+ /* Restore any window parameters that have been saved.
+ Parameters that have not been saved are left alone. */
+ for (tem = p->window_parameters; CONSP (tem); tem = XCDR (tem))
+ {
+ pers = XCAR (tem);
+ if (CONSP (pers))
+ {
+ if (NILP (XCDR (pers)))
+ {
+ par = Fassq (XCAR (pers), w->window_parameters);
+ if (CONSP (par) && !NILP (XCDR (par)))
+ /* Reset a parameter to nil if and only if it
+ has a non-nil association. Don't make new
+ associations. */
+ Fsetcdr (par, Qnil);
+ }
+ else
+ /* Always restore a non-nil value. */
+ Fset_window_parameter (window, XCAR (pers), XCDR (pers));
+ }
+ }
+
+ w->last_modified = 0;
+ w->last_overlay_modified = 0;
/* Reinstall the saved buffer and pointers into it. */
if (NILP (p->buffer))
/* 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);
if (NILP (leaf_windows[i]->buffer))
{
/* Assert it's not reused as a combination. */
- xassert (NILP (leaf_windows[i]->hchild)
+ eassert (NILP (leaf_windows[i]->hchild)
&& NILP (leaf_windows[i]->vchild));
free_window_matrices (leaf_windows[i]);
}
if (!row->enabled_p)
return NULL;
- if (XINT (w->hscroll))
+ if (w->hscroll)
{
/* When the window is hscrolled, cursor hpos can legitimately be
out of bounds, but we draw the cursor at the corresponding
{
register struct saved_window *p;
register struct window *w;
- register Lisp_Object tem;
+ register Lisp_Object tem, pers, par;
for (;!NILP (window); window = w->next)
{
p->total_lines = w->total_lines;
p->normal_cols = w->normal_cols;
p->normal_lines = w->normal_lines;
- p->hscroll = w->hscroll;
- p->min_hscroll = w->min_hscroll;
+ XSETFASTINT (p->hscroll, w->hscroll);
+ XSETFASTINT (p->min_hscroll, w->min_hscroll);
p->display_table = w->display_table;
p->left_margin_cols = w->left_margin_cols;
p->right_margin_cols = w->right_margin_cols;
p->left_fringe_width = w->left_fringe_width;
p->right_fringe_width = w->right_fringe_width;
- p->fringes_outside_margins = w->fringes_outside_margins;
+ p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil;
p->scroll_bar_width = w->scroll_bar_width;
p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
p->dedicated = w->dedicated;
p->combination_limit = w->combination_limit;
- p->window_parameters = w->window_parameters;
- if (!NILP (w->buffer))
+ p->window_parameters = Qnil;
+
+ if (!NILP (Vwindow_persistent_parameters))
{
- /* 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))
+ /* Run cycle detection on Vwindow_persistent_parameters. */
+ Lisp_Object tortoise, hare;
+
+ hare = tortoise = Vwindow_persistent_parameters;
+ while (CONSP (hare))
+ {
+ hare = XCDR (hare);
+ if (!CONSP (hare))
+ break;
+
+ hare = XCDR (hare);
+ tortoise = XCDR (tortoise);
+
+ if (EQ (hare, tortoise))
+ /* Reset Vwindow_persistent_parameters to Qnil. */
+ {
+ Vwindow_persistent_parameters = Qnil;
+ break;
+ }
+ }
+
+ for (tem = Vwindow_persistent_parameters; CONSP (tem);
+ tem = XCDR (tem))
{
- p->pointm = Fmake_marker ();
- set_marker_both (p->pointm, w->buffer,
- BUF_PT (XBUFFER (w->buffer)),
- BUF_PT_BYTE (XBUFFER (w->buffer)));
+ pers = XCAR (tem);
+ /* Save values for persistent window parameters. */
+ if (CONSP (pers) && !NILP (XCDR (pers)))
+ {
+ par = Fassq (XCAR (pers), w->window_parameters);
+ if (NILP (par))
+ /* If the window has no value for the parameter,
+ make one. */
+ p->window_parameters = Fcons (Fcons (XCAR (pers), Qnil),
+ p->window_parameters);
+ else
+ /* If the window has a value for the parameter,
+ save it. */
+ p->window_parameters = Fcons (Fcons (XCAR (par),
+ XCDR (par)),
+ p->window_parameters);
+ }
}
+ }
+
+ if (!NILP (w->buffer))
+ {
+ /* 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)));
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);
(Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width, Lisp_Object outside_margins)
{
struct window *w = decode_window (window);
+ int outside = !NILP (outside_margins);
if (!NILP (left_width))
CHECK_NATNUM (left_width);
if (FRAME_WINDOW_P (WINDOW_XFRAME (w))
&& (!EQ (w->left_fringe_width, left_width)
|| !EQ (w->right_fringe_width, right_width)
- || !EQ (w->fringes_outside_margins, outside_margins)))
+ || w->fringes_outside_margins != outside))
{
w->left_fringe_width = left_width;
w->right_fringe_width = right_width;
- w->fringes_outside_margins = outside_margins;
+ w->fringes_outside_margins = outside;
adjust_window_margins (w);
if (!NILP (width))
{
- CHECK_RANGED_INTEGER (0, width, INT_MAX);
+ CHECK_RANGED_INTEGER (width, 0, INT_MAX);
if (XINT (width) == 0)
vertical_type = Qnil;
struct frame *f = make_initial_frame ();
XSETFRAME (selected_frame, f);
Vterminal_frame = selected_frame;
- minibuf_window = f->minibuffer_window;
- selected_window = f->selected_window;
+ minibuf_window = FVAR (f, minibuffer_window);
+ selected_window = FVAR (f, selected_window);
last_nonminibuf_frame = f;
window_initialized = 1;
DEFSYM (Qabove, "above");
DEFSYM (Qbelow, "below");
DEFSYM (Qauto_buffer_name, "auto-buffer-name");
+ DEFSYM (Qclone_of, "clone-of");
staticpro (&Vwindow_list);
Vwindow_configuration_change_hook = Qnil;
DEFVAR_LISP ("recenter-redisplay", Vrecenter_redisplay,
- doc: /* If non-nil, then the `recenter' command with a nil argument
-will redraw the entire frame; the special value `tty' causes the
-frame to be redrawn only if it is a tty frame. */);
+ doc: /* Non-nil means `recenter' redraws entire frame.
+If this option is non-nil, then the `recenter' command with a nil
+argument will redraw the entire frame; the special value `tty' causes
+the frame to be redrawn only if it is a tty frame. */);
Vrecenter_redisplay = Qtty;
DEFVAR_LISP ("window-combination-resize", Vwindow_combination_resize,
- doc: /* Non-nil means resize window combinations proportionally.
+ doc: /* If t, resize window combinations proportionally.
If this variable is nil, splitting a window gets the entire screen space
for displaying the new window from the window to split. Deleting and
resizing a window preferably resizes one adjacent window only.
-If this variable is non-nil, splitting a window tries to get the space
+If this variable is t, splitting a window tries to get the space
proportionally from all windows in the same combination. This also
allows to split a window that is otherwise too small or of fixed size.
Resizing and deleting a window proportionally resize all windows in the
same combination.
+Other values are reserved for future use.
+
This variable takes no effect if `window-combination-limit' is non-nil. */);
Vwindow_combination_resize = Qnil;
DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit,
- doc: /* Non-nil means splitting a window makes a new parent window.
+ doc: /* If t, splitting a window makes a new parent window.
If this variable is nil, splitting a window will create a new parent
window only if the window has no parent window or the window shall
become a combination orthogonal to the one it is part of.
function `set-window-combination-limit'. */);
Vwindow_combination_limit = Qnil;
+ DEFVAR_LISP ("window-persistent-parameters", Vwindow_persistent_parameters,
+ doc: /* Alist of persistent window parameters.
+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:
+
+nil means the parameter is neither saved by `window-state-get' nor by
+`current-window-configuration'.
+
+t means the parameter is saved by `current-window-configuration' and,
+provided its WRITABLE argument is nil, by `window-state-get'.
+
+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, Qt));
+
defsubr (&Sselected_window);
defsubr (&Sminibuffer_window);
defsubr (&Swindow_minibuffer_p);