/* Window creation, deletion and examination for GNU Emacs.
Does not include redisplay.
- Copyright (C) 1985, 86, 87, 93, 94, 95, 96 Free Software Foundation, Inc.
+ Copyright (C) 1985,86,87,93,94,95,96,97,1998 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "termchar.h"
#include "disptab.h"
#include "keyboard.h"
+#include "blockinput.h"
Lisp_Object Qwindowp, Qwindow_live_p;
-Lisp_Object Fnext_window (), Fdelete_window (), Fselect_window ();
-Lisp_Object Fset_window_buffer (), Fsplit_window (), Frecenter ();
-
-void delete_all_subwindows ();
-static struct window *decode_window();
+static struct window *decode_window P_ ((Lisp_Object));
/* This is the window in which the terminal's cursor should
be left when nothing is being done with it. This must
at the same screen height as previously. */
static int scroll_preserve_screen_position;
-/* Non-nil means we can split a frame even if it is "unsplittable". */
-static int frame_override_unsplittable;
+/* Nonzero means we can split a frame even if it is "unsplittable". */
+static int inhibit_frame_unsplittable;
#define min(a, b) ((a) < (b) ? (a) : (b))
return Qnil;
case 1: /* In text part of window. */
- return Fcons (x, y);
+ return Fcons (make_number (x), make_number (y));
case 2: /* In mode line of window. */
return Qmode_line;
(vertical-motion (1- (window-height window)) window)\n\
(point))") */
-DEFUN ("window-end", Fwindow_end, Swindow_end, 0, 1, 0,
+DEFUN ("window-end", Fwindow_end, Swindow_end, 0, 2, 0,
"Return position at which display currently ends in WINDOW.\n\
This is updated by redisplay, when it runs to completion.\n\
Simply changing the buffer text or setting `window-start'\n\
-does not update this value.")
- (window)
- Lisp_Object window;
+does not update this value.\n\
+If UP-TO-DATE is non-nil, compute the up-to-date position\n\
+if it isn't already recorded.")
+ (window, update)
+ Lisp_Object window, update;
{
Lisp_Object value;
struct window *w = decode_window (window);
return Qnil;
#endif
- XSETINT (value,
- BUF_Z (XBUFFER (buf)) - XFASTINT (w->window_end_pos));
+ if (! NILP (update)
+ && ! (! NILP (w->window_end_valid)
+ && XFASTINT (w->last_modified) >= MODIFF))
+ {
+ int opoint = PT, opoint_byte = PT_BYTE;
+ TEMP_SET_PT_BOTH (XMARKER (w->start)->charpos,
+ XMARKER (w->start)->bytepos);
+ Fvertical_motion (make_number (window_internal_height (w)), Qnil);
+ XSETINT (value, PT);
+ TEMP_SET_PT_BOTH (opoint, opoint_byte);
+ }
+ else
+ XSETINT (value,
+ BUF_Z (XBUFFER (buf)) - XFASTINT (w->window_end_pos));
return value;
}
tem = w->display_table;
if (DISP_TABLE_P (tem))
return XCHAR_TABLE (tem);
+ if (NILP (w->buffer))
+ return 0;
+
tem = XBUFFER (w->buffer)->display_table;
if (DISP_TABLE_P (tem))
return XCHAR_TABLE (tem);
register struct window *w;
{
Lisp_Object buf;
+ struct buffer *b;
buf = w->buffer;
- if (XBUFFER (buf) != XMARKER (w->pointm)->buffer)
+ b = XBUFFER (buf);
+ if (b != XMARKER (w->pointm)->buffer)
abort ();
- if (w == XWINDOW (XBUFFER (buf)->last_selected_window))
- XBUFFER (buf)->last_selected_window = Qnil;
+ if (w == XWINDOW (b->last_selected_window))
+ b->last_selected_window = Qnil;
#if 0
if (w == XWINDOW (selected_window)
selected window, while last_window_start reflects another
window which was recently showing the same buffer.
Some people might say that might be a good thing. Let's see. */
- XBUFFER (buf)->last_window_start = marker_position (w->start);
+ b->last_window_start = marker_position (w->start);
/* 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))
- BUF_PT (XBUFFER (buf))
- = clip_to_bounds (BUF_BEGV (XBUFFER (buf)),
- marker_position (w->pointm),
- BUF_ZV (XBUFFER (buf)));
+ temp_set_point_both (b,
+ clip_to_bounds (BUF_BEGV (b),
+ XMARKER (w->pointm)->charpos,
+ BUF_ZV (b)),
+ clip_to_bounds (BUF_BEGV_BYTE (b),
+ marker_byte_position (w->pointm),
+ BUF_ZV_BYTE (b)));
}
/* Put replacement into the window structure in place of old. */
return Qnil;
}
+void
delete_window (window)
register Lisp_Object window;
{
have unwanted side effects due to text properties. */
pos = *vmotion (startpos, -top, w);
- Fset_marker (w->start, make_number (pos.bufpos), w->buffer);
- w->start_at_line_beg = ((pos.bufpos == BEGV
- || FETCH_BYTE (pos.bufpos - 1) == '\n') ? Qt
+ set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
+ w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE
+ || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt
: Qnil);
/* We need to do this, so that the window-scroll-functions
get called. */
because it only considers frames on the current keyboard.
So loop manually over frames, and handle each one. */
FOR_EACH_FRAME (tail, frame)
- window_loop (UNSHOW_BUFFER, buffer, 0, frame);
+ window_loop (UNSHOW_BUFFER, buffer, 1, frame);
#else
- window_loop (UNSHOW_BUFFER, buffer, 0, Qt);
+ window_loop (UNSHOW_BUFFER, buffer, 1, Qt);
#endif
}
\f
nodelete nonzero means do not do this.
(The caller should check later and do so if appropriate) */
+void
set_window_height (window, height, nodelete)
Lisp_Object window;
int height;
if (!nodelete
&& ! NILP (w->parent)
- && height < window_min_height)
+ && (MINI_WINDOW_P (w)
+ ? height < 1
+ : height < window_min_height))
{
delete_window (window);
return;
/* Recursively set width of WINDOW and its inferiors. */
+void
set_window_width (window, width, nodelete)
Lisp_Object window;
int width;
XSETFASTINT (w->window_end_pos, 0);
w->window_end_valid = Qnil;
XSETFASTINT (w->hscroll, 0);
- Fset_marker (w->pointm,
- make_number (BUF_PT (XBUFFER (buffer))),
- buffer);
+ set_marker_both (w->pointm, buffer,
+ BUF_PT (XBUFFER (buffer)), BUF_PT_BYTE (XBUFFER (buffer)));
set_marker_restricted (w->start,
make_number (XBUFFER (buffer)->last_window_start),
buffer);
if (EQ (window, selected_window))
return window;
- Fset_marker (ow->pointm, make_number (BUF_PT (XBUFFER (ow->buffer))),
- ow->buffer);
+ if (! NILP (ow->buffer))
+ set_marker_both (ow->pointm, ow->buffer,
+ BUF_PT (XBUFFER (ow->buffer)),
+ BUF_PT_BYTE (XBUFFER (ow->buffer)));
selected_window = window;
if (XFRAME (WINDOW_FRAME (w)) != selected_frame)
else if (CONSP (car)
&& STRINGP (XCAR (car))
&& fast_string_match (XCAR (car), buffer_name) >= 0)
- return XCDR (tem);
+ return XCDR (car);
}
return Qnil;
}
return Qnil;
}
-DEFUN ("display-buffer", Fdisplay_buffer, Sdisplay_buffer, 1, 2,
- "BDisplay buffer: \nP", /* Use B so the default is (other-buffer). */
+ /* Use B so the default is (other-buffer). */
+DEFUN ("display-buffer", Fdisplay_buffer, Sdisplay_buffer, 1, 3,
+ "BDisplay buffer: \nP",
"Make BUFFER appear in some window but don't select it.\n\
BUFFER can be a buffer or a buffer name.\n\
If BUFFER is shown already in some window, just use that one,\n\
\n\
The variables `special-display-buffer-names', `special-display-regexps',\n\
`same-window-buffer-names', and `same-window-regexps' customize how certain\n\
-buffer names are handled.")
- (buffer, not_this_window)
- register Lisp_Object buffer, not_this_window;
+buffer names are handled.\n\
+\n\
+If optional argument FRAME is `visible', search all visible frames.\n\
+If FRAME is 0, search all visible and iconified frames.\n\
+If FRAME is t, search all frames.\n\
+If FRAME is a frame, search only that frame.\n\
+If FRAME is nil, search only the selected frame\n\
+ (actually the last nonminibuffer frame),\n\
+ unless `pop-up-frames' is non-nil,\n\
+ which means search visible and iconified frames.")
+ (buffer, not_this_window, frame)
+ register Lisp_Object buffer, not_this_window, frame;
{
register Lisp_Object window, tem;
/* If pop_up_frames,
look for a window showing BUFFER on any visible or iconified frame.
Otherwise search only the current frame. */
- if (pop_up_frames || last_nonminibuf_frame == 0)
+ if (! NILP (frame))
+ tem = frame;
+ else if (pop_up_frames || last_nonminibuf_frame == 0)
XSETFASTINT (tem, 0);
else
XSETFRAME (tem, last_nonminibuf_frame);
register Lisp_Object window;
register struct window *w;
+ XBUFFER (buf)->directory = current_buffer->directory;
+
Fset_buffer (buf);
BUF_SAVE_MODIFF (XBUFFER (buf)) = MODIFF;
BEGV = BEG;
call1 (Vtemp_buffer_show_function, buf);
else
{
- window = Fdisplay_buffer (buf, Qnil);
+ window = Fdisplay_buffer (buf, Qnil, Qnil);
if (XFRAME (XWINDOW (window)->frame) != selected_frame)
Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
Vminibuf_scroll_window = window;
w = XWINDOW (window);
XSETFASTINT (w->hscroll, 0);
- set_marker_restricted (w->start, make_number (1), buf);
- set_marker_restricted (w->pointm, make_number (1), buf);
+ set_marker_restricted_both (w->start, buf, 1, 1);
+ set_marker_restricted_both (w->pointm, buf, 1, 1);
/* Run temp-buffer-show-hook, with the chosen window selected. */
if (!NILP (Vrun_hooks))
if (MINI_WINDOW_P (o))
error ("Attempt to split minibuffer window");
- else if (FRAME_NO_SPLIT_P (fo) && ! frame_override_unsplittable)
- error ("Attempt to split unsplittable frame");
check_min_window_sizes ();
also changes the heights of the siblings so as to
keep everything consistent. */
+void
change_window_height (delta, widthflag)
register int delta;
int widthflag;
Lisp_Object window;
register struct window *p;
int *sizep;
- int (*sizefun) () = widthflag ? window_width : window_height;
- register int (*setsizefun) () = (widthflag
- ? set_window_width
- : set_window_height);
+ int (*sizefun) P_ ((Lisp_Object))
+ = widthflag ? window_width : window_height;
+ register void (*setsizefun) P_ ((Lisp_Object, int, int))
+ = (widthflag ? set_window_width : set_window_height);
int maximum;
Lisp_Object next, prev;
maximum += (*sizefun) (prev) - MINSIZE (prev);
/* If we can get it all from them, do so. */
- if (delta < maximum)
+ if (delta <= maximum)
{
Lisp_Object first_unaffected;
Lisp_Object first_affected;
{
register struct window *w = XWINDOW (window);
register int opoint = PT;
- register int pos;
+ register int opoint_byte = PT_BYTE;
+ register int pos, pos_byte;
register int ht = window_internal_height (w);
register Lisp_Object tem;
int lose;
lose = n < 0 && PT == BEGV;
Fvertical_motion (make_number (n), window);
pos = PT;
+ pos_byte = PT_BYTE;
bolp = Fbolp ();
- SET_PT (opoint);
+ SET_PT_BOTH (opoint, opoint_byte);
if (lose)
{
if (XINT (w->height) < 4 * scroll_margin)
this_scroll_margin = XINT (w->height) / 4;
- set_marker_restricted (w->start, make_number (pos), w->buffer);
+ 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);
if (whole && scroll_preserve_screen_position)
{
- SET_PT (pos);
+ SET_PT_BOTH (pos, pos_byte);
Fvertical_motion (make_number (original_vpos), window);
}
/* If we scrolled forward, put point enough lines down
if (this_scroll_margin > 0)
{
- SET_PT (pos);
+ SET_PT_BOTH (pos, pos_byte);
Fvertical_motion (make_number (this_scroll_margin), window);
top_margin = PT;
}
top_margin = pos;
if (top_margin <= opoint)
- SET_PT (opoint);
+ SET_PT_BOTH (opoint, opoint_byte);
else if (scroll_preserve_screen_position)
{
- SET_PT (pos);
+ SET_PT_BOTH (pos, pos_byte);
Fvertical_motion (make_number (original_vpos), window);
}
else
- SET_PT (pos);
+ SET_PT (top_margin);
}
else if (n < 0)
{
/* If we scrolled backward, put point near the end of the window
but not within the scroll margin. */
- SET_PT (pos);
+ SET_PT_BOTH (pos, pos_byte);
tem = Fvertical_motion (make_number (ht - this_scroll_margin), window);
if (XFASTINT (tem) == ht - this_scroll_margin)
bottom_margin = PT;
bottom_margin = PT + 1;
if (bottom_margin > opoint)
- SET_PT (opoint);
+ SET_PT_BOTH (opoint, opoint_byte);
else
{
if (scroll_preserve_screen_position)
{
- SET_PT (pos);
+ SET_PT_BOTH (pos, pos_byte);
Fvertical_motion (make_number (original_vpos), window);
}
else
{
window = Fget_buffer_window (Vother_window_scroll_buffer, Qnil);
if (NILP (window))
- window = Fdisplay_buffer (Vother_window_scroll_buffer, Qt);
+ window = Fdisplay_buffer (Vother_window_scroll_buffer, Qt, Qnil);
}
else
{
window_scroll (window, XINT (arg), 0, 1);
}
- Fset_marker (w->pointm, make_number (PT), Qnil);
+ set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
unbind_to (count, Qnil);
return Qnil;
register struct window *w = XWINDOW (selected_window);
register int ht = window_internal_height (w);
struct position pos;
+ struct buffer *buf = XBUFFER (w->buffer);
+ struct buffer *obuf = current_buffer;
if (NILP (arg))
{
if (XINT (arg) < 0)
XSETINT (arg, XINT (arg) + ht);
+ set_buffer_internal (buf);
pos = *vmotion (PT, - XINT (arg), w);
- Fset_marker (w->start, make_number (pos.bufpos), w->buffer);
- w->start_at_line_beg = ((pos.bufpos == BEGV
- || FETCH_BYTE (pos.bufpos - 1) == '\n')
+ set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
+ w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE
+ || FETCH_BYTE (pos.bytepos - 1) == '\n')
? Qt : Qnil);
w->force_start = Qt;
+ set_buffer_internal (obuf);
return Qnil;
}
if (start < BEGV || start > ZV)
{
Fvertical_motion (make_number (- (height / 2)), window);
- Fset_marker (w->start, make_number (PT), w->buffer);
+ set_marker_both (w->start, w->buffer, PT, PT_BYTE);
w->start_at_line_beg = Fbolp ();
w->force_start = Qt;
}
else
- SET_PT (start);
+ Fgoto_char (w->start);
return Fvertical_motion (arg, window);
}
/* Record the values of window-min-width and window-min-height
so that window sizes remain consistent with them. */
Lisp_Object min_width, min_height;
- /* A vector, interpreted as a struct saved_window */
+ /* A vector, each of whose elements is a struct saved_window
+ for one window. */
Lisp_Object saved_windows;
};
-/* This is saved as a Lisp_Vector */
+/* This is saved as a Lisp_Vector */
struct saved_window
{
/* these first two must agree with struct Lisp_Vector in lisp.h */
((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
DEFUN ("window-configuration-p", Fwindow_configuration_p, Swindow_configuration_p, 1, 1, 0,
- "T if OBJECT is a window-configuration object.")
+ "Return t if OBJECT is a window-configuration object.")
(object)
Lisp_Object object;
{
return Qnil;
}
-
DEFUN ("set-window-configuration", Fset_window_configuration,
Sset_window_configuration, 1, 1, 0,
"Set the configuration of windows and buffers as specified by CONFIGURATION.\n\
Lisp_Object new_current_buffer;
Lisp_Object frame;
FRAME_PTR f;
+ int old_point = -1;
while (!WINDOW_CONFIGURATIONP (configuration))
{
new_current_buffer = data->current_buffer;
if (NILP (XBUFFER (new_current_buffer)->name))
new_current_buffer = Qnil;
+ else
+ {
+ if (XBUFFER (new_current_buffer) == current_buffer)
+ old_point = PT;
+
+ }
frame = XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
f = XFRAME (frame);
int previous_frame_width = FRAME_WIDTH (f);
int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
+ /* The mouse highlighting code could get screwed up
+ if it runs during this. */
+ BLOCK_INPUT;
+
if (XFASTINT (data->frame_height) != previous_frame_height
|| XFASTINT (data->frame_width) != previous_frame_width)
change_frame_size (f, data->frame_height, data->frame_width, 0, 0);
x_set_menu_bar_lines (f, data->frame_menu_bar_lines, 0);
#endif
+ if (! NILP (XWINDOW (selected_window)->buffer))
+ {
+ w = XWINDOW (selected_window);
+ set_marker_both (w->pointm,
+ w->buffer,
+ BUF_PT (XBUFFER (w->buffer)),
+ BUF_PT_BYTE (XBUFFER (w->buffer)));
+ }
+
windows_or_buffers_changed++;
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
{
w->buffer = p->buffer;
w->start_at_line_beg = p->start_at_line_beg;
- set_marker_restricted (w->start,
- Fmarker_position (p->start),
- w->buffer);
- set_marker_restricted (w->pointm,
- Fmarker_position (p->pointm),
- w->buffer);
+ set_marker_restricted (w->start, p->start, w->buffer);
+ set_marker_restricted (w->pointm, p->pointm, w->buffer);
Fset_marker (XBUFFER (w->buffer)->mark,
- Fmarker_position (p->mark), w->buffer);
+ p->mark, w->buffer);
/* As documented in Fcurrent_window_configuration, don't
save the location of point in the buffer which was current
set_marker_restricted (w->start, make_number (0),
w->buffer);
if (XMARKER (w->pointm)->buffer == 0)
- set_marker_restricted (w->pointm,
- (make_number
- (BUF_PT (XBUFFER (w->buffer)))),
- w->buffer);
+ 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;
}
}
if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f))
x_set_menu_bar_lines (f, previous_frame_menu_bar_lines, 0);
#endif
+
+ UNBLOCK_INPUT;
+
+ /* Fselect_window will have made f the selected frame, so we
+ reselect the proper frame here. Fhandle_switch_frame will change the
+ selected window too, but that doesn't make the call to
+ Fselect_window above totally superfluous; it still sets f's
+ selected window. */
+ if (FRAME_LIVE_P (XFRAME (data->selected_frame)))
+ do_switch_frame (data->selected_frame, Qnil, 0);
+
+ if (! NILP (Vwindow_configuration_change_hook)
+ && ! NILP (Vrun_hooks))
+ call1 (Vrun_hooks, Qwindow_configuration_change_hook);
+ }
+
+ if (!NILP (new_current_buffer))
+ {
+ Fset_buffer (new_current_buffer);
+
+ /* If the buffer that is current now is the same
+ that was current before setting the window configuration,
+ don't alter its PT. */
+ if (old_point >= 0)
+ SET_PT (old_point);
}
/* Restore the minimum heights recorded in the configuration. */
window_min_height = XINT (data->min_height);
window_min_width = XINT (data->min_width);
- /* Fselect_window will have made f the selected frame, so we
- reselect the proper frame here. Fhandle_switch_frame will change the
- selected window too, but that doesn't make the call to
- Fselect_window above totally superfluous; it still sets f's
- selected window. */
- if (FRAME_LIVE_P (XFRAME (data->selected_frame)))
- do_switch_frame (data->selected_frame, Qnil, 0);
-
- if (!NILP (new_current_buffer))
- Fset_buffer (new_current_buffer);
-
Vminibuf_scroll_window = data->minibuf_scroll_window;
- if (! NILP (Vwindow_configuration_change_hook)
- && ! NILP (Vrun_hooks))
- call1 (Vrun_hooks, Qwindow_configuration_change_hook);
-
- return (Qnil);
+ return Qnil;
}
/* Mark all windows now on frame as deleted
if (EQ (window, selected_window))
{
p->pointm = Fmake_marker ();
- Fset_marker (p->pointm, BUF_PT (XBUFFER (w->buffer)),
- w->buffer);
+ set_marker_both (p->pointm, w->buffer,
+ BUF_PT (XBUFFER (w->buffer)),
+ BUF_PT_BYTE (XBUFFER (w->buffer)));
}
else
p->pointm = Fcopy_marker (w->pointm, Qnil);
return unbind_to (count, val);
}
\f
+/* Return 1 if window configurations C1 and C2
+ describe the same state of affairs. This is used by Fequal. */
+
+int
+compare_window_configurations (c1, c2, ignore_positions)
+ Lisp_Object c1, c2;
+ int ignore_positions;
+{
+ register struct save_window_data *d1, *d2;
+ struct Lisp_Vector *sw1, *sw2;
+ int i;
+
+ d1 = (struct save_window_data *) XVECTOR (c1);
+ d2 = (struct save_window_data *) XVECTOR (c2);
+ sw1 = XVECTOR (d1->saved_windows);
+ sw2 = XVECTOR (d2->saved_windows);
+
+ if (! EQ (d1->frame_width, d2->frame_width))
+ return 0;
+ if (! EQ (d1->frame_height, d2->frame_height))
+ return 0;
+ if (! EQ (d1->frame_menu_bar_lines, d2->frame_menu_bar_lines))
+ return 0;
+ if (! EQ (d1->selected_frame, d2->selected_frame))
+ return 0;
+ /* Don't compare the current_window field directly.
+ Instead see w1_is_current and w2_is_current, below. */
+ if (! EQ (d1->current_buffer, d2->current_buffer))
+ return 0;
+ if (! ignore_positions)
+ if (! EQ (d1->minibuf_scroll_window, d2->minibuf_scroll_window))
+ return 0;
+ /* Don't compare the root_window field.
+ We don't require the two configurations
+ to use the same window object,
+ and the two root windows must be equivalent
+ if everything else compares equal. */
+ if (! EQ (d1->focus_frame, d2->focus_frame))
+ return 0;
+ if (! EQ (d1->min_width, d2->min_width))
+ return 0;
+ if (! EQ (d1->min_height, d2->min_height))
+ return 0;
+
+ /* Verify that the two confis have the same number of windows. */
+ if (sw1->size != sw2->size)
+ return 0;
+
+ for (i = 0; i < sw1->size; i++)
+ {
+ struct saved_window *p1, *p2;
+ int w1_is_current, w2_is_current;
+
+ p1 = SAVED_WINDOW_N (sw1, i);
+ p2 = SAVED_WINDOW_N (sw2, i);
+
+ /* Verify that the current windows in the two
+ configurations correspond to each other. */
+ w1_is_current = EQ (d1->current_window, p1->window);
+ w2_is_current = EQ (d2->current_window, p2->window);
+
+ if (w1_is_current != w2_is_current)
+ return 0;
+
+ /* Verify that the corresponding windows do match. */
+ if (! EQ (p1->buffer, p2->buffer))
+ return 0;
+ if (! EQ (p1->left, p2->left))
+ return 0;
+ if (! EQ (p1->top, p2->top))
+ return 0;
+ if (! EQ (p1->width, p2->width))
+ return 0;
+ if (! EQ (p1->height, p2->height))
+ return 0;
+ if (! EQ (p1->display_table, p2->display_table))
+ return 0;
+ if (! EQ (p1->parent, p2->parent))
+ return 0;
+ if (! EQ (p1->prev, p2->prev))
+ return 0;
+ if (! ignore_positions)
+ {
+ if (! EQ (p1->hscroll, p2->hscroll))
+ return 0;
+ if (! EQ (p1->start_at_line_beg, p2->start_at_line_beg))
+ return 0;
+ if (NILP (Fequal (p1->start, p2->start)))
+ return 0;
+ if (NILP (Fequal (p1->pointm, p2->pointm)))
+ return 0;
+ if (NILP (Fequal (p1->mark, p2->mark)))
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+DEFUN ("compare-window-configurations", Fcompare_window_configurations,
+ Scompare_window_configurations, 2, 2, 0,
+ "Compare two window configurations as regards the structure of windows.\n\
+This function ignores details such as the values of point and mark\n\
+and scrolling positions.")
+ (x, y)
+ Lisp_Object x, y;
+{
+ if (compare_window_configurations (x, y, 1))
+ return Qt;
+ return Qnil;
+}
+\f
init_window_once ()
{
selected_frame = make_terminal_frame ();
In the first case, FRAME-PARAMETERS are used to create the frame.\n\
In the latter case, FUNCTION is called with BUFFER as the first argument,\n\
followed by OTHER-ARGS--it can display BUFFER in any way it likes.\n\
-All this is done by the function found in `special-display-function'.");
+All this is done by the function found in `special-display-function'.\n\
+\n\
+If this variable appears \"not to work\", because you add a name to it\n\
+but that buffer still appears in the selected window, look at the\n\
+values of `same-window-buffer-names' and `same-window-regexps'.\n\
+Those variables take precedence over this one.");
Vspecial_display_buffer_names = Qnil;
DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps,
In the first case, FRAME-PARAMETERS are used to create the frame.\n\
In the latter case, FUNCTION is called with the buffer as first argument,\n\
followed by OTHER-ARGS--it can display the buffer in any way it likes.\n\
-All this is done by the function found in `special-display-function'.");
+All this is done by the function found in `special-display-function'.\n\
+\n\
+If this variable appears \"not to work\", because you add a regexp to it\n\
+but the matching buffers still appear in the selected window, look at the\n\
+values of `same-window-buffer-names' and `same-window-regexps'.\n\
+Those variables take precedence over this one.");
Vspecial_display_regexps = Qnil;
DEFVAR_LISP ("special-display-function", &Vspecial_display_function,
DEFVAR_LISP ("window-configuration-change-hook",
&Vwindow_configuration_change_hook,
"Functions to call when window configuration changes.\n\
-The selected frae is the one whose configuration has changed.");
+The selected frame is the one whose configuration has changed.");
Vwindow_configuration_change_hook = Qnil;
- DEFVAR_BOOL ("frame-override-unsplittable", &frame_override_unsplittable,
- "Non-nil means allow splitting an `unsplittable' frame.\n\
-\(That means, a frame whise `unsplittable' parameter is non-nil.)\n\
-Packages such as Ispell that work by splitting the selected frame\n\
-can bind this, so that they will work when used in an unsplittable frame.");
-
defsubr (&Sselected_window);
defsubr (&Sminibuffer_window);
defsubr (&Swindow_minibuffer_p);
defsubr (&Sset_window_configuration);
defsubr (&Scurrent_window_configuration);
defsubr (&Ssave_window_excursion);
+ defsubr (&Scompare_window_configurations);
}
keys_of_window ()