aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c5278
1 files changed, 2391 insertions, 2887 deletions
diff --git a/src/window.c b/src/window.c
index 1a02a3b1cbb..a5f95ea7883 100644
--- a/src/window.c
+++ b/src/window.c
@@ -52,10 +52,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
52 52
53#include "xwidget.h" 53#include "xwidget.h"
54 54
55Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p; 55Lisp_Object Qwindowp, Qwindow_live_p;
56Lisp_Object Qdisplay_buffer; 56static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
57Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; 57static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
58Lisp_Object Qwindow_size_fixed; 58static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
59static Lisp_Object Qresize_root_window, Qresize_root_window_vertically;
60static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
61static Lisp_Object Qsafe, Qabove, Qbelow;
62static Lisp_Object Qauto_buffer_name;
59 63
60static int displayed_window_lines (struct window *); 64static int displayed_window_lines (struct window *);
61static struct window *decode_window (Lisp_Object); 65static struct window *decode_window (Lisp_Object);
@@ -64,13 +68,7 @@ static int get_leaf_windows (struct window *, struct window **, int);
64static void window_scroll (Lisp_Object, int, int, int); 68static void window_scroll (Lisp_Object, int, int, int);
65static void window_scroll_pixel_based (Lisp_Object, int, int, int); 69static void window_scroll_pixel_based (Lisp_Object, int, int, int);
66static void window_scroll_line_based (Lisp_Object, int, int, int); 70static void window_scroll_line_based (Lisp_Object, int, int, int);
67static int window_min_size_1 (struct window *, int, int);
68static int window_min_size_2 (struct window *, int, int);
69static int window_min_size (struct window *, int, int, int, int *);
70static void size_window (Lisp_Object, int, int, int, int, int);
71static int freeze_window_start (struct window *, void *); 71static int freeze_window_start (struct window *, void *);
72static int window_fixed_size_p (struct window *, int, int);
73static void enlarge_window (Lisp_Object, int, int);
74static Lisp_Object window_list (void); 72static Lisp_Object window_list (void);
75static int add_window_to_list (struct window *, void *); 73static int add_window_to_list (struct window *, void *);
76static int candidate_window_p (Lisp_Object, Lisp_Object, Lisp_Object, 74static int candidate_window_p (Lisp_Object, Lisp_Object, Lisp_Object,
@@ -86,6 +84,8 @@ static int foreach_window_1 (struct window *,
86 int (* fn) (struct window *, void *), 84 int (* fn) (struct window *, void *),
87 void *); 85 void *);
88static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object); 86static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
87static int resize_window_check (struct window *, int);
88static void resize_window_apply (struct window *, int);
89static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); 89static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
90 90
91/* This is the window in which the terminal's cursor should 91/* This is the window in which the terminal's cursor should
@@ -95,134 +95,108 @@ static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
95 95
96 This value is always the same as 96 This value is always the same as
97 FRAME_SELECTED_WINDOW (selected_frame). */ 97 FRAME_SELECTED_WINDOW (selected_frame). */
98
99Lisp_Object selected_window; 98Lisp_Object selected_window;
100 99
101/* A list of all windows for use by next_window and Fwindow_list. 100/* A list of all windows for use by next_window and Fwindow_list.
102 Functions creating or deleting windows should invalidate this cache 101 Functions creating or deleting windows should invalidate this cache
103 by setting it to nil. */ 102 by setting it to nil. */
104
105Lisp_Object Vwindow_list; 103Lisp_Object Vwindow_list;
106 104
107/* The mini-buffer window of the selected frame. 105/* The mini-buffer window of the selected frame.
108 Note that you cannot test for mini-bufferness of an arbitrary window 106 Note that you cannot test for mini-bufferness of an arbitrary window
109 by comparing against this; but you can test for mini-bufferness of 107 by comparing against this; but you can test for mini-bufferness of
110 the selected window. */ 108 the selected window. */
111
112Lisp_Object minibuf_window; 109Lisp_Object minibuf_window;
113 110
114/* Non-nil means it is the window whose mode line should be 111/* Non-nil means it is the window whose mode line should be
115 shown as the selected window when the minibuffer is selected. */ 112 shown as the selected window when the minibuffer is selected. */
116
117Lisp_Object minibuf_selected_window; 113Lisp_Object minibuf_selected_window;
118 114
119/* Hook run at end of temp_output_buffer_show. */ 115/* Hook run at end of temp_output_buffer_show. */
120 116static Lisp_Object Qtemp_buffer_show_hook;
121Lisp_Object Qtemp_buffer_show_hook;
122 117
123/* Incremented for each window created. */ 118/* Incremented for each window created. */
124
125static int sequence_number; 119static int sequence_number;
126 120
127/* Nonzero after init_window_once has finished. */ 121/* Nonzero after init_window_once has finished. */
128
129static int window_initialized; 122static int window_initialized;
130 123
131/* Hook to run when window config changes. */ 124/* Hook to run when window config changes. */
132
133static Lisp_Object Qwindow_configuration_change_hook; 125static Lisp_Object Qwindow_configuration_change_hook;
134/* Incremented by 1 whenever a window is deleted. */
135
136int window_deletion_count;
137 126
138/* Used by the function window_scroll_pixel_based */ 127/* Used by the function window_scroll_pixel_based */
139
140static int window_scroll_pixel_based_preserve_x; 128static int window_scroll_pixel_based_preserve_x;
141static int window_scroll_pixel_based_preserve_y; 129static int window_scroll_pixel_based_preserve_y;
142 130
143/* Same for window_scroll_line_based. */ 131/* Same for window_scroll_line_based. */
144
145static int window_scroll_preserve_hpos; 132static int window_scroll_preserve_hpos;
146static int window_scroll_preserve_vpos; 133static int window_scroll_preserve_vpos;
134
135static struct window *
136decode_window (register Lisp_Object window)
137{
138 if (NILP (window))
139 return XWINDOW (selected_window);
147 140
148#if 0 /* This isn't used anywhere. */ 141 CHECK_LIVE_WINDOW (window);
149/* Nonzero means we can split a frame even if it is "unsplittable". */ 142 return XWINDOW (window);
150static int inhibit_frame_unsplittable; 143}
151#endif 144
145static struct window *
146decode_any_window (register Lisp_Object window)
147{
148 if (NILP (window))
149 return XWINDOW (selected_window);
150
151 CHECK_WINDOW (window);
152 return XWINDOW (window);
153}
152 154
153
154DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0, 155DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
155 doc: /* Return t if OBJECT is a window. */) 156 doc: /* Return t if OBJECT is a window and nil otherwise. */)
156 (Lisp_Object object) 157 (Lisp_Object object)
157{ 158{
158 return WINDOWP (object) ? Qt : Qnil; 159 return WINDOWP (object) ? Qt : Qnil;
159} 160}
160 161
161DEFUN ("window-live-p", Fwindow_live_p, Swindow_live_p, 1, 1, 0, 162DEFUN ("window-live-p", Fwindow_live_p, Swindow_live_p, 1, 1, 0,
162 doc: /* Return t if OBJECT is a window which is currently visible. */) 163 doc: /* Return t if OBJECT is a live window and nil otherwise.
164A live window is a window that displays a buffer. */)
163 (Lisp_Object object) 165 (Lisp_Object object)
164{ 166{
165 return WINDOW_LIVE_P (object) ? Qt : Qnil; 167 return WINDOW_LIVE_P (object) ? Qt : Qnil;
166} 168}
167 169
168Lisp_Object 170/* Frames and windows. */
169make_window (void) 171DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
172 doc: /* Return the frame that window WINDOW is on.
173WINDOW can be any window and defaults to the selected one. */)
174 (Lisp_Object window)
170{ 175{
171 Lisp_Object val; 176 return decode_any_window (window)->frame;
172 register struct window *p;
173
174 p = allocate_window ();
175 ++sequence_number;
176 XSETFASTINT (p->sequence_number, sequence_number);
177 XSETFASTINT (p->left_col, 0);
178 XSETFASTINT (p->top_line, 0);
179 XSETFASTINT (p->total_lines, 0);
180 XSETFASTINT (p->total_cols, 0);
181 XSETFASTINT (p->hscroll, 0);
182 XSETFASTINT (p->min_hscroll, 0);
183 p->orig_top_line = p->orig_total_lines = Qnil;
184 p->start = Fmake_marker ();
185 p->pointm = Fmake_marker ();
186 XSETFASTINT (p->use_time, 0);
187 p->frame = Qnil;
188 p->display_table = Qnil;
189 p->dedicated = Qnil;
190 p->window_parameters = Qnil;
191 p->pseudo_window_p = 0;
192 memset (&p->cursor, 0, sizeof (p->cursor));
193 memset (&p->last_cursor, 0, sizeof (p->last_cursor));
194 memset (&p->phys_cursor, 0, sizeof (p->phys_cursor));
195 p->desired_matrix = p->current_matrix = 0;
196 p->nrows_scale_factor = p->ncols_scale_factor = 1;
197 p->phys_cursor_type = -1;
198 p->phys_cursor_width = -1;
199 p->must_be_updated_p = 0;
200 XSETFASTINT (p->window_end_vpos, 0);
201 XSETFASTINT (p->window_end_pos, 0);
202 p->window_end_valid = Qnil;
203 p->vscroll = 0;
204 XSETWINDOW (val, p);
205 XSETFASTINT (p->last_point, 0);
206 p->frozen_window_start_p = 0;
207 p->last_cursor_off_p = p->cursor_off_p = 0;
208 p->left_margin_cols = Qnil;
209 p->right_margin_cols = Qnil;
210 p->left_fringe_width = Qnil;
211 p->right_fringe_width = Qnil;
212 p->fringes_outside_margins = Qnil;
213 p->scroll_bar_width = Qnil;
214 p->vertical_scroll_bar_type = Qt;
215 p->resize_proportionally = Qnil;
216
217 Vwindow_list = Qnil;
218 return val;
219} 177}
220 178
221DEFUN ("selected-window", Fselected_window, Sselected_window, 0, 0, 0, 179DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
222 doc: /* Return the window that the cursor now appears in and commands apply to. */) 180 doc: /* Return the root window of FRAME_OR_WINDOW.
223 (void) 181If omitted, FRAME_OR_WINDOW defaults to the currently selected frame.
182Else if FRAME_OR_WINDOW denotes any window, return the root window of
183that window's frame. If FRAME_OR_WINDOW denotes a live frame, return
184the root window of that frame. */)
185 (Lisp_Object frame_or_window)
224{ 186{
225 return selected_window; 187 Lisp_Object window;
188
189 if (NILP (frame_or_window))
190 window = SELECTED_FRAME ()->root_window;
191 else if (WINDOWP (frame_or_window))
192 window = XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window)))->root_window;
193 else
194 {
195 CHECK_LIVE_FRAME (frame_or_window);
196 window = XFRAME (frame_or_window)->root_window;
197 }
198
199 return window;
226} 200}
227 201
228DEFUN ("minibuffer-window", Fminibuffer_window, Sminibuffer_window, 0, 1, 0, 202DEFUN ("minibuffer-window", Fminibuffer_window, Sminibuffer_window, 0, 1, 0,
@@ -237,257 +211,481 @@ used by that frame. */)
237 return FRAME_MINIBUF_WINDOW (XFRAME (frame)); 211 return FRAME_MINIBUF_WINDOW (XFRAME (frame));
238} 212}
239 213
240DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, Swindow_minibuffer_p, 0, 1, 0, 214DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p,
215 Swindow_minibuffer_p, 0, 1, 0,
241 doc: /* Return non-nil if WINDOW is a minibuffer window. 216 doc: /* Return non-nil if WINDOW is a minibuffer window.
242WINDOW defaults to the selected window. */) 217WINDOW can be any window and defaults to the selected one. */)
243 (Lisp_Object window) 218 (Lisp_Object window)
244{ 219{
245 struct window *w = decode_window (window); 220 return MINI_WINDOW_P (decode_any_window (window)) ? Qt : Qnil;
246 return MINI_WINDOW_P (w) ? Qt : Qnil;
247} 221}
248 222
249 223/* Don't move this to window.el - this must be a safe routine. */
250DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p, 224DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
251 Spos_visible_in_window_p, 0, 3, 0, 225 doc: /* Return the topmost, leftmost live window on FRAME_OR_WINDOW.
252 doc: /* Return non-nil if position POS is currently on the frame in WINDOW. 226If omitted, FRAME_OR_WINDOW defaults to the currently selected frame.
253Return nil if that position is scrolled vertically out of view. 227Else if FRAME_OR_WINDOW denotes any window, return the first window of
254If a character is only partially visible, nil is returned, unless the 228that window's frame. If FRAME_OR_WINDOW denotes a live frame, return
255optional argument PARTIALLY is non-nil. 229the first window of that frame. */)
256If POS is only out of view because of horizontal scrolling, return non-nil. 230 (Lisp_Object frame_or_window)
257If POS is t, it specifies the position of the last visible glyph in WINDOW.
258POS defaults to point in WINDOW; WINDOW defaults to the selected window.
259
260If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
261return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
262where X and Y are the pixel coordinates relative to the top left corner
263of the window. The remaining elements are omitted if the character after
264POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
265off-window at the top and bottom of the row, ROWH is the height of the
266display row, and VPOS is the row number (0-based) containing POS. */)
267 (Lisp_Object pos, Lisp_Object window, Lisp_Object partially)
268{ 231{
269 register struct window *w; 232 Lisp_Object window;
270 register EMACS_INT posint;
271 register struct buffer *buf;
272 struct text_pos top;
273 Lisp_Object in_window = Qnil;
274 int rtop, rbot, rowh, vpos, fully_p = 1;
275 int x, y;
276 233
277 w = decode_window (window); 234 if (NILP (frame_or_window))
278 buf = XBUFFER (w->buffer); 235 window = SELECTED_FRAME ()->root_window;
279 SET_TEXT_POS_FROM_MARKER (top, w->start); 236 else if (WINDOWP (frame_or_window))
237 window = XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window)))->root_window;
238 else
239 {
240 CHECK_LIVE_FRAME (frame_or_window);
241 window = XFRAME (frame_or_window)->root_window;
242 }
280 243
281 if (EQ (pos, Qt)) 244 while (NILP (XWINDOW (window)->buffer))
282 posint = -1;
283 else if (!NILP (pos))
284 { 245 {
285 CHECK_NUMBER_COERCE_MARKER (pos); 246 if (! NILP (XWINDOW (window)->hchild))
286 posint = XINT (pos); 247 window = XWINDOW (window)->hchild;
248 else if (! NILP (XWINDOW (window)->vchild))
249 window = XWINDOW (window)->vchild;
250 else
251 abort ();
287 } 252 }
288 else if (w == XWINDOW (selected_window))
289 posint = PT;
290 else
291 posint = XMARKER (w->pointm)->charpos;
292 253
293 /* If position is above window start or outside buffer boundaries, 254 return window;
294 or if window start is out of range, position is not visible. */ 255}
295 if ((EQ (pos, Qt)
296 || (posint >= CHARPOS (top) && posint <= BUF_ZV (buf)))
297 && CHARPOS (top) >= BUF_BEGV (buf)
298 && CHARPOS (top) <= BUF_ZV (buf)
299 && pos_visible_p (w, posint, &x, &y, &rtop, &rbot, &rowh, &vpos)
300 && (fully_p = !rtop && !rbot, (!NILP (partially) || fully_p)))
301 in_window = Qt;
302 256
303 if (!NILP (in_window) && !NILP (partially)) 257DEFUN ("frame-selected-window", Fframe_selected_window,
258 Sframe_selected_window, 0, 1, 0,
259 doc: /* Return the selected window of FRAME_OR_WINDOW.
260If omitted, FRAME_OR_WINDOW defaults to the currently selected frame.
261Else if FRAME_OR_WINDOW denotes any window, return the selected window
262of that window's frame. If FRAME_OR_WINDOW denotes a live frame, return
263the selected window of that frame. */)
264 (Lisp_Object frame_or_window)
265{
266 Lisp_Object window;
267
268 if (NILP (frame_or_window))
269 window = SELECTED_FRAME ()->selected_window;
270 else if (WINDOWP (frame_or_window))
271 window = XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window)))->selected_window;
272 else
304 { 273 {
305 Lisp_Object part = Qnil; 274 CHECK_LIVE_FRAME (frame_or_window);
306 if (!fully_p) 275 window = XFRAME (frame_or_window)->selected_window;
307 part = list4 (make_number (rtop), make_number (rbot),
308 make_number (rowh), make_number (vpos));
309 in_window = Fcons (make_number (x),
310 Fcons (make_number (y), part));
311 } 276 }
312 277
313 return in_window; 278 return window;
314} 279}
315 280
316DEFUN ("window-line-height", Fwindow_line_height, 281DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
317 Swindow_line_height, 0, 2, 0, 282 Sset_frame_selected_window, 2, 3, 0,
318 doc: /* Return height in pixels of text line LINE in window WINDOW. 283 doc: /* Set selected window of FRAME to WINDOW.
319If WINDOW is nil or omitted, use selected window. 284FRAME must be a live frame and defaults to the selected one. If FRAME
285is the selected frame, this makes WINDOW the selected window. Optional
286argument NORECORD non-nil means to neither change the order of recently
287selected windows nor the buffer list. WINDOW must denote a live window.
288Return WINDOW. */)
289 (Lisp_Object frame, Lisp_Object window, Lisp_Object norecord)
290{
291 if (NILP (frame))
292 frame = selected_frame;
320 293
321Return height of current line if LINE is omitted or nil. Return height of 294 CHECK_LIVE_FRAME (frame);
322header or mode line if LINE is `header-line' and `mode-line'. 295 CHECK_LIVE_WINDOW (window);
323Otherwise, LINE is a text line number starting from 0. A negative number
324counts from the end of the window.
325 296
326Value is a list (HEIGHT VPOS YPOS OFFBOT), where HEIGHT is the height 297 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
327in pixels of the visible part of the line, VPOS and YPOS are the 298 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
328vertical position in lines and pixels of the line, relative to the top
329of the first text line, and OFFBOT is the number of off-window pixels at
330the bottom of the text line. If there are off-window pixels at the top
331of the (first) text line, YPOS is negative.
332 299
333Return nil if window display is not up-to-date. In that case, use 300 if (EQ (frame, selected_frame))
334`pos-visible-in-window-p' to obtain the information. */) 301 return Fselect_window (window, norecord);
335 (Lisp_Object line, Lisp_Object window) 302 else
303 return XFRAME (frame)->selected_window = window;
304}
305
306DEFUN ("selected-window", Fselected_window, Sselected_window, 0, 0, 0,
307 doc: /* Return the selected window.
308The selected window is the window in which the standard cursor for
309selected windows appears and to which many commands apply. */)
310 (void)
336{ 311{
337 register struct window *w; 312 return selected_window;
338 register struct buffer *b; 313}
339 struct glyph_row *row, *end_row;
340 int max_y, crop, i, n;
341 314
342 w = decode_window (window); 315int window_select_count;
343 316
344 if (noninteractive 317/* If select_window is called with inhibit_point_swap non-zero it will
345 || w->pseudo_window_p) 318 not store point of the old selected window's buffer back into that
346 return Qnil; 319 window's pointm slot. This is needed by Fset_window_configuration to
320 avoid that the display routine is called with selected_window set to
321 Qnil causing a subsequent crash. */
322static Lisp_Object
323select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
324{
325 register struct window *w;
326 register struct window *ow;
327 struct frame *sf;
347 328
348 CHECK_BUFFER (w->buffer); 329 CHECK_LIVE_WINDOW (window);
349 b = XBUFFER (w->buffer);
350 330
351 /* Fail if current matrix is not up-to-date. */ 331 w = XWINDOW (window);
352 if (NILP (w->window_end_valid) 332 w->frozen_window_start_p = 0;
353 || current_buffer->clip_changed
354 || current_buffer->prevent_redisplay_optimizations_p
355 || XFASTINT (w->last_modified) < BUF_MODIFF (b)
356 || XFASTINT (w->last_overlay_modified) < BUF_OVERLAY_MODIFF (b))
357 return Qnil;
358 333
359 if (NILP (line)) 334 if (NILP (norecord))
360 { 335 {
361 i = w->cursor.vpos; 336 ++window_select_count;
362 if (i < 0 || i >= w->current_matrix->nrows 337 XSETFASTINT (w->use_time, window_select_count);
363 || (row = MATRIX_ROW (w->current_matrix, i), !row->enabled_p)) 338 record_buffer (w->buffer);
364 return Qnil;
365 max_y = window_text_bottom_y (w);
366 goto found_row;
367 } 339 }
368 340
369 if (EQ (line, Qheader_line)) 341 if (EQ (window, selected_window) && !inhibit_point_swap)
342 return window;
343
344 sf = SELECTED_FRAME ();
345 if (XFRAME (WINDOW_FRAME (w)) != sf)
370 { 346 {
371 if (!WINDOW_WANTS_HEADER_LINE_P (w)) 347 XFRAME (WINDOW_FRAME (w))->selected_window = window;
372 return Qnil; 348 /* Use this rather than Fhandle_switch_frame
373 row = MATRIX_HEADER_LINE_ROW (w->current_matrix); 349 so that FRAME_FOCUS_FRAME is moved appropriately as we
374 if (!row->enabled_p) 350 move around in the state where a minibuffer in a separate
375 return Qnil; 351 frame is active. */
376 return list4 (make_number (row->height), 352 Fselect_frame (WINDOW_FRAME (w), norecord);
377 make_number (0), make_number (0), 353 /* Fselect_frame called us back so we've done all the work already. */
378 make_number (0)); 354 eassert (EQ (window, selected_window));
355 return window;
379 } 356 }
357 else
358 sf->selected_window = window;
380 359
381 if (EQ (line, Qmode_line)) 360 /* Store the current buffer's actual point into the
361 old selected window. It belongs to that window,
362 and when the window is not selected, must be in the window. */
363 if (!inhibit_point_swap)
382 { 364 {
383 row = MATRIX_MODE_LINE_ROW (w->current_matrix); 365 ow = XWINDOW (selected_window);
384 if (!row->enabled_p) 366 if (! NILP (ow->buffer))
385 return Qnil; 367 set_marker_both (ow->pointm, ow->buffer,
386 return list4 (make_number (row->height), 368 BUF_PT (XBUFFER (ow->buffer)),
387 make_number (0), /* not accurate */ 369 BUF_PT_BYTE (XBUFFER (ow->buffer)));
388 make_number (WINDOW_HEADER_LINE_HEIGHT (w)
389 + window_text_bottom_y (w)),
390 make_number (0));
391 } 370 }
392 371
393 CHECK_NUMBER (line); 372 selected_window = window;
394 n = XINT (line);
395
396 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
397 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
398 max_y = window_text_bottom_y (w);
399 i = 0;
400 373
401 while ((n < 0 || i < n) 374 Fset_buffer (w->buffer);
402 && row <= end_row && row->enabled_p
403 && row->y + row->height < max_y)
404 row++, i++;
405 375
406 if (row > end_row || !row->enabled_p) 376 BVAR (XBUFFER (w->buffer), last_selected_window) = window;
407 return Qnil;
408 377
409 if (++n < 0) 378 /* Go to the point recorded in the window.
410 { 379 This is important when the buffer is in more
411 if (-n > i) 380 than one window. It also matters when
412 return Qnil; 381 redisplay_window has altered point after scrolling,
413 row += n; 382 because it makes the change only in the window. */
414 i += n; 383 {
415 } 384 register EMACS_INT new_point = marker_position (w->pointm);
385 if (new_point < BEGV)
386 SET_PT (BEGV);
387 else if (new_point > ZV)
388 SET_PT (ZV);
389 else
390 SET_PT (new_point);
391 }
416 392
417 found_row: 393 windows_or_buffers_changed++;
418 crop = max (0, (row->y + row->height) - max_y); 394 return window;
419 return list4 (make_number (row->height + min (0, row->y) - crop),
420 make_number (i),
421 make_number (row->y),
422 make_number (crop));
423} 395}
424 396
397DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
398 doc: /* Select WINDOW. Most editing will apply to WINDOW's buffer.
399Also make WINDOW's buffer current and make WINDOW the frame's selected
400window. Return WINDOW.
401
402Optional second arg NORECORD non-nil means do not put this buffer at the
403front of the buffer list and do not make this window the most recently
404selected one.
425 405
406Note that the main editor command loop sets the current buffer to the
407buffer of the selected window before each command. */)
408 (register Lisp_Object window, Lisp_Object norecord)
409{
410 return select_window (window, norecord, 0);
411}
426 412
427static struct window * 413DEFUN ("window-clone-number", Fwindow_clone_number, Swindow_clone_number, 0, 1, 0,
428decode_window (register Lisp_Object window) 414 doc: /* Return WINDOW's clone number.
415WINDOW can be any window and defaults to the selected one. */)
416 (Lisp_Object window)
429{ 417{
430 if (NILP (window)) 418 return decode_any_window (window)->clone_number;
431 return XWINDOW (selected_window); 419}
432 420
433 CHECK_LIVE_WINDOW (window); 421DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0,
434 return XWINDOW (window); 422 doc: /* Return the buffer that WINDOW is displaying.
423WINDOW can be any window and defaults to the selected one.
424If WINDOW is an internal window return nil. */)
425 (Lisp_Object window)
426{
427 return decode_any_window (window)->buffer;
435} 428}
436 429
437static struct window * 430DEFUN ("window-parent", Fwindow_parent, Swindow_parent, 0, 1, 0,
438decode_any_window (register Lisp_Object window) 431 doc: /* Return WINDOW's parent window.
432WINDOW can be any window and defaults to the selected one.
433Return nil if WINDOW has no parent. */)
434 (Lisp_Object window)
439{ 435{
440 if (NILP (window)) 436 return decode_any_window (window)->parent;
441 return XWINDOW (selected_window); 437}
442 438
443 CHECK_WINDOW (window); 439DEFUN ("window-vchild", Fwindow_vchild, Swindow_vchild, 0, 1, 0,
444 return XWINDOW (window); 440 doc: /* Return WINDOW's first vertical child window.
441WINDOW can be any window and defaults to the selected one.
442Return nil if WINDOW has no vertical child. */)
443 (Lisp_Object window)
444{
445 return decode_any_window (window)->vchild;
445} 446}
446 447
447DEFUN ("window-buffer", Fwindow_buffer, Swindow_buffer, 0, 1, 0, 448DEFUN ("window-hchild", Fwindow_hchild, Swindow_hchild, 0, 1, 0,
448 doc: /* Return the buffer that WINDOW is displaying. 449 doc: /* Return WINDOW's first horizontal child window.
449WINDOW defaults to the selected window. */) 450WINDOW can be any window and defaults to the selected one.
451Return nil if WINDOW has no horizontal child. */)
450 (Lisp_Object window) 452 (Lisp_Object window)
451{ 453{
452 return decode_window (window)->buffer; 454 return decode_any_window (window)->hchild;
453} 455}
454 456
455DEFUN ("window-height", Fwindow_height, Swindow_height, 0, 1, 0, 457DEFUN ("window-next", Fwindow_next, Swindow_next, 0, 1, 0,
456 doc: /* Return the number of lines in WINDOW. 458 doc: /* Return WINDOW's right sibling window.
457WINDOW defaults to the selected window. 459WINDOW can be any window and defaults to the selected one.
460Return nil if WINDOW has no right sibling. */)
461 (Lisp_Object window)
462{
463 return decode_any_window (window)->next;
464}
458 465
459The return value includes WINDOW's mode line and header line, if any. 466DEFUN ("window-prev", Fwindow_prev, Swindow_prev, 0, 1, 0,
467 doc: /* Return WINDOW's left sibling window.
468WINDOW can be any window and defaults to the selected one.
469Return nil if WINDOW has no left sibling. */)
470 (Lisp_Object window)
471{
472 return decode_any_window (window)->prev;
473}
474
475DEFUN ("window-splits", Fwindow_splits, Swindow_splits, 0, 1, 0,
476 doc: /* Return splits status for WINDOW.
477WINDOW can be any window and defaults to the selected one.
460 478
461Note: The function does not take into account the value of `line-spacing' 479If the value returned by this function is nil and WINDOW is resized, the
462when calculating the number of lines in WINDOW. */) 480corresponding space is preferably taken from (or given to) WINDOW's
481right sibling. When WINDOW is deleted, its space is given to its left
482sibling.
483
484If the value returned by this function is non-nil, resizing and deleting
485WINDOW may resize all windows in the same combination. */)
463 (Lisp_Object window) 486 (Lisp_Object window)
464{ 487{
465 return decode_any_window (window)->total_lines; 488 return decode_any_window (window)->splits;
466} 489}
467 490
468DEFUN ("window-width", Fwindow_width, Swindow_width, 0, 1, 0, 491DEFUN ("set-window-splits", Fset_window_splits, Sset_window_splits, 2, 2, 0,
469 doc: /* Return the number of display columns in WINDOW. 492 doc: /* Set splits status of WINDOW to STATUS.
470WINDOW defaults to the selected window. 493WINDOW can be any window and defaults to the selected one. Return
494STATUS.
495
496If STATUS is nil and WINDOW is later resized, the corresponding space is
497preferably taken from (or given to) WINDOW's right sibling. When WINDOW
498is deleted, its space is given to its left sibling.
471 499
472Note: The return value is the number of columns available for text in 500If STATUS is non-nil, resizing and deleting WINDOW may resize all
473WINDOW. If you want to find out how many columns WINDOW takes up, use 501windows in the same combination. */)
474(let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))). */) 502 (Lisp_Object window, Lisp_Object status)
503{
504 register struct window *w = decode_any_window (window);
505
506 w->splits = status;
507
508 return w->splits;
509}
510
511DEFUN ("window-nest", Fwindow_nest, Swindow_nest, 0, 1, 0,
512 doc: /* Return nest status of WINDOW.
513WINDOW can be any window and defaults to the selected one.
514
515If the return value is nil, subwindows of WINDOW can be recombined with
516WINDOW's siblings. A return value of non-nil means that subwindows of
517WINDOW are never \(re-)combined with WINDOW's siblings. */)
475 (Lisp_Object window) 518 (Lisp_Object window)
476{ 519{
477 return make_number (window_box_text_cols (decode_any_window (window))); 520 return decode_any_window (window)->nest;
478} 521}
479 522
480DEFUN ("window-full-width-p", Fwindow_full_width_p, Swindow_full_width_p, 0, 1, 0, 523DEFUN ("set-window-nest", Fset_window_nest, Sset_window_nest, 2, 2, 0,
481 doc: /* Return t if WINDOW is as wide as its frame. 524 doc: /* Set nest status of WINDOW to STATUS.
482WINDOW defaults to the selected window. */) 525WINDOW can be any window and defaults to the selected one. Return
526STATUS.
527
528If STATUS is nil, subwindows of WINDOW can be recombined with WINDOW's
529siblings. STATUS non-nil means that subwindows of WINDOW are never
530\(re-)combined with WINDOW's siblings. */)
531 (Lisp_Object window, Lisp_Object status)
532{
533 register struct window *w = decode_any_window (window);
534
535 w->nest = status;
536
537 return w->nest;
538}
539
540DEFUN ("window-use-time", Fwindow_use_time, Swindow_use_time, 0, 1, 0,
541 doc: /* Return WINDOW's use time.
542WINDOW defaults to the selected window. The window with the highest use
543time is the most recently selected one. The window with the lowest use
544time is the least recently selected one. */)
545 (Lisp_Object window)
546{
547 return decode_window (window)->use_time;
548}
549
550DEFUN ("window-total-size", Fwindow_total_size, Swindow_total_size, 0, 2, 0,
551 doc: /* Return the total number of lines of WINDOW.
552WINDOW can be any window and defaults to the selected one. The return
553value includes WINDOW's mode line and header line, if any. If WINDOW
554is internal, the return value is the sum of the total number of lines
555of WINDOW's child windows if these are vertically combined and the
556height of WINDOW's first child otherwise.
557
558Optional argument HORIZONTAL non-nil means return the total number of
559columns of WINDOW. In this case the return value includes any vertical
560dividers or scrollbars of WINDOW. If WINDOW is internal, the return
561value is the sum of the total number of columns of WINDOW's child
562windows if they are horizontally combined and the width of WINDOW's
563first child otherwise. */)
564 (Lisp_Object window, Lisp_Object horizontal)
565{
566 if (NILP (horizontal))
567 return decode_any_window (window)->total_lines;
568 else
569 return decode_any_window (window)->total_cols;
570}
571
572DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0,
573 doc: /* Return new total size of WINDOW.
574WINDOW defaults to the selected window. */)
575 (Lisp_Object window)
576{
577 return decode_any_window (window)->new_total;
578}
579
580DEFUN ("window-normal-size", Fwindow_normal_size, Swindow_normal_size, 0, 2, 0,
581 doc: /* Return normal height of WINDOW.
582WINDOW can be any window and defaults to the selected one. Optional
583argument HORIZONTAL non-nil means return normal width of WINDOW. */)
584 (Lisp_Object window, Lisp_Object horizontal)
585{
586 if (NILP (horizontal))
587 return decode_any_window (window)->normal_lines;
588 else
589 return decode_any_window (window)->normal_cols;
590}
591
592DEFUN ("window-new-normal", Fwindow_new_normal, Swindow_new_normal, 0, 1, 0,
593 doc: /* Return new normal size of WINDOW.
594WINDOW can be any window and defaults to the selected one. */)
595 (Lisp_Object window)
596{
597 return decode_any_window (window)->new_normal;
598}
599
600DEFUN ("window-left-column", Fwindow_left_column, Swindow_left_column, 0, 1, 0,
601 doc: /* Return left column of WINDOW.
602WINDOW can be any window and defaults to the selected one. */)
483 (Lisp_Object window) 603 (Lisp_Object window)
484{ 604{
485 return WINDOW_FULL_WIDTH_P (decode_any_window (window)) ? Qt : Qnil; 605 return decode_any_window (window)->left_col;
606}
607
608DEFUN ("window-top-line", Fwindow_top_line, Swindow_top_line, 0, 1, 0,
609 doc: /* Return top line of WINDOW.
610WINDOW can be any window and defaults to the selected one. */)
611 (Lisp_Object window)
612{
613 return decode_any_window (window)->top_line;
614}
615
616/* Return the number of lines of W's body. Don't count any mode or
617 header line of W. */
618
619static int
620window_body_lines (struct window *w)
621{
622 int height = XFASTINT (w->total_lines);
623
624 if (!MINI_WINDOW_P (w))
625 {
626 if (WINDOW_WANTS_MODELINE_P (w))
627 --height;
628 if (WINDOW_WANTS_HEADER_LINE_P (w))
629 --height;
630 }
631
632 return height;
633}
634
635/* Return the number of columns of W's body. Don't count columns
636 occupied by the scroll bar or the vertical bar separating W from its
637 right sibling. On window-systems don't count fringes or display
638 margins either. */
639
640int
641window_body_cols (struct window *w)
642{
643 struct frame *f = XFRAME (WINDOW_FRAME (w));
644 int width = XINT (w->total_cols);
645
646 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
647 /* Scroll bars occupy a few columns. */
648 width -= WINDOW_CONFIG_SCROLL_BAR_COLS (w);
649 else if (!FRAME_WINDOW_P (f)
650 && !WINDOW_RIGHTMOST_P (w) && !WINDOW_FULL_WIDTH_P (w))
651 /* The column of `|' characters separating side-by-side windows
652 occupies one column only. */
653 width -= 1;
654
655 if (FRAME_WINDOW_P (f))
656 /* On window-systems, fringes and display margins cannot be
657 used for normal text. */
658 width -= (WINDOW_FRINGE_COLS (w)
659 + WINDOW_LEFT_MARGIN_COLS (w)
660 + WINDOW_RIGHT_MARGIN_COLS (w));
661
662 return width;
663}
664
665DEFUN ("window-body-size", Fwindow_body_size, Swindow_body_size, 0, 2, 0,
666 doc: /* Return the number of lines of WINDOW's body.
667WINDOW must be a live window and defaults to the selected one. The
668return value does not include WINDOW's mode line and header line, if
669any.
670
671Optional argument HORIZONTAL non-nil means return the number of columns
672of WINDOW's body. In this case, the return value does not include any
673vertical dividers or scroll bars owned by WINDOW. On a window-system
674the return value does not include the number of columns used for
675WINDOW's fringes or display margins either. */)
676 (Lisp_Object window, Lisp_Object horizontal)
677{
678 struct window *w = decode_any_window (window);
679
680 if (NILP (horizontal))
681 return make_number (window_body_lines (w));
682 else
683 return make_number (window_body_cols (w));
486} 684}
487 685
488DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0, 686DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
489 doc: /* Return the number of columns by which WINDOW is scrolled from left margin. 687 doc: /* Return the number of columns by which WINDOW is scrolled from left margin.
490WINDOW defaults to the selected window. */) 688WINDOW must be a live window and defaults to the selected one. */)
491 (Lisp_Object window) 689 (Lisp_Object window)
492{ 690{
493 return decode_window (window)->hscroll; 691 return decode_window (window)->hscroll;
@@ -1057,7 +1255,7 @@ window_from_coordinates (struct frame *f, int x, int y,
1057 1255
1058DEFUN ("window-at", Fwindow_at, Swindow_at, 2, 3, 0, 1256DEFUN ("window-at", Fwindow_at, Swindow_at, 2, 3, 0,
1059 doc: /* Return window containing coordinates X and Y on FRAME. 1257 doc: /* Return window containing coordinates X and Y on FRAME.
1060If omitted, FRAME defaults to the currently selected frame. 1258FRAME must be a live frame and defaults to the selected one.
1061The top left corner of the frame is considered to be row 0, 1259The top left corner of the frame is considered to be row 0,
1062column 0. */) 1260column 0. */)
1063 (Lisp_Object x, Lisp_Object y, Lisp_Object frame) 1261 (Lisp_Object x, Lisp_Object y, Lisp_Object frame)
@@ -1083,7 +1281,7 @@ column 0. */)
1083 1281
1084DEFUN ("window-point", Fwindow_point, Swindow_point, 0, 1, 0, 1282DEFUN ("window-point", Fwindow_point, Swindow_point, 0, 1, 0,
1085 doc: /* Return current value of point in WINDOW. 1283 doc: /* Return current value of point in WINDOW.
1086WINDOW defaults to the selected window. 1284WINDOW must be a live window and defaults to the selected one.
1087 1285
1088For a nonselected window, this is the value point would have 1286For a nonselected window, this is the value point would have
1089if that window were selected. 1287if that window were selected.
@@ -1105,7 +1303,7 @@ But that is hard to define. */)
1105 1303
1106DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0, 1304DEFUN ("window-start", Fwindow_start, Swindow_start, 0, 1, 0,
1107 doc: /* Return position at which display currently starts in WINDOW. 1305 doc: /* Return position at which display currently starts in WINDOW.
1108WINDOW defaults to the selected window. 1306WINDOW must be a live window and defaults to the selected one.
1109This is updated by redisplay or by calling `set-window-start'. */) 1307This is updated by redisplay or by calling `set-window-start'. */)
1110 (Lisp_Object window) 1308 (Lisp_Object window)
1111{ 1309{
@@ -1125,7 +1323,7 @@ have been if redisplay had finished, do this:
1125 1323
1126DEFUN ("window-end", Fwindow_end, Swindow_end, 0, 2, 0, 1324DEFUN ("window-end", Fwindow_end, Swindow_end, 0, 2, 0,
1127 doc: /* Return position at which display currently ends in WINDOW. 1325 doc: /* Return position at which display currently ends in WINDOW.
1128WINDOW defaults to the selected window. 1326WINDOW must be a live window and defaults to the selected one.
1129This is updated by redisplay, when it runs to completion. 1327This is updated by redisplay, when it runs to completion.
1130Simply changing the buffer text or setting `window-start' 1328Simply changing the buffer text or setting `window-start'
1131does not update this value. 1329does not update this value.
@@ -1244,6 +1442,179 @@ overriding motion of point in order to display at this exact start. */)
1244 return pos; 1442 return pos;
1245} 1443}
1246 1444
1445DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p,
1446 Spos_visible_in_window_p, 0, 3, 0,
1447 doc: /* Return non-nil if position POS is currently on the frame in WINDOW.
1448Return nil if that position is scrolled vertically out of view.
1449If a character is only partially visible, nil is returned, unless the
1450optional argument PARTIALLY is non-nil.
1451If POS is only out of view because of horizontal scrolling, return non-nil.
1452If POS is t, it specifies the position of the last visible glyph in WINDOW.
1453POS defaults to point in WINDOW; WINDOW defaults to the selected window.
1454
1455If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
1456return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
1457where X and Y are the pixel coordinates relative to the top left corner
1458of the window. The remaining elements are omitted if the character after
1459POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
1460off-window at the top and bottom of the row, ROWH is the height of the
1461display row, and VPOS is the row number (0-based) containing POS. */)
1462 (Lisp_Object pos, Lisp_Object window, Lisp_Object partially)
1463{
1464 register struct window *w;
1465 register EMACS_INT posint;
1466 register struct buffer *buf;
1467 struct text_pos top;
1468 Lisp_Object in_window = Qnil;
1469 int rtop, rbot, rowh, vpos, fully_p = 1;
1470 int x, y;
1471
1472 w = decode_window (window);
1473 buf = XBUFFER (w->buffer);
1474 SET_TEXT_POS_FROM_MARKER (top, w->start);
1475
1476 if (EQ (pos, Qt))
1477 posint = -1;
1478 else if (!NILP (pos))
1479 {
1480 CHECK_NUMBER_COERCE_MARKER (pos);
1481 posint = XINT (pos);
1482 }
1483 else if (w == XWINDOW (selected_window))
1484 posint = PT;
1485 else
1486 posint = XMARKER (w->pointm)->charpos;
1487
1488 /* If position is above window start or outside buffer boundaries,
1489 or if window start is out of range, position is not visible. */
1490 if ((EQ (pos, Qt)
1491 || (posint >= CHARPOS (top) && posint <= BUF_ZV (buf)))
1492 && CHARPOS (top) >= BUF_BEGV (buf)
1493 && CHARPOS (top) <= BUF_ZV (buf)
1494 && pos_visible_p (w, posint, &x, &y, &rtop, &rbot, &rowh, &vpos)
1495 && (fully_p = !rtop && !rbot, (!NILP (partially) || fully_p)))
1496 in_window = Qt;
1497
1498 if (!NILP (in_window) && !NILP (partially))
1499 {
1500 Lisp_Object part = Qnil;
1501 if (!fully_p)
1502 part = list4 (make_number (rtop), make_number (rbot),
1503 make_number (rowh), make_number (vpos));
1504 in_window = Fcons (make_number (x),
1505 Fcons (make_number (y), part));
1506 }
1507
1508 return in_window;
1509}
1510
1511DEFUN ("window-line-height", Fwindow_line_height,
1512 Swindow_line_height, 0, 2, 0,
1513 doc: /* Return height in pixels of text line LINE in window WINDOW.
1514WINDOW defaults to the selected window.
1515
1516Return height of current line if LINE is omitted or nil. Return height of
1517header or mode line if LINE is `header-line' or `mode-line'.
1518Otherwise, LINE is a text line number starting from 0. A negative number
1519counts from the end of the window.
1520
1521Value is a list (HEIGHT VPOS YPOS OFFBOT), where HEIGHT is the height
1522in pixels of the visible part of the line, VPOS and YPOS are the
1523vertical position in lines and pixels of the line, relative to the top
1524of the first text line, and OFFBOT is the number of off-window pixels at
1525the bottom of the text line. If there are off-window pixels at the top
1526of the (first) text line, YPOS is negative.
1527
1528Return nil if window display is not up-to-date. In that case, use
1529`pos-visible-in-window-p' to obtain the information. */)
1530 (Lisp_Object line, Lisp_Object window)
1531{
1532 register struct window *w;
1533 register struct buffer *b;
1534 struct glyph_row *row, *end_row;
1535 int max_y, crop, i, n;
1536
1537 w = decode_window (window);
1538
1539 if (noninteractive || w->pseudo_window_p)
1540 return Qnil;
1541
1542 CHECK_BUFFER (w->buffer);
1543 b = XBUFFER (w->buffer);
1544
1545 /* Fail if current matrix is not up-to-date. */
1546 if (NILP (w->window_end_valid)
1547 || current_buffer->clip_changed
1548 || current_buffer->prevent_redisplay_optimizations_p
1549 || XFASTINT (w->last_modified) < BUF_MODIFF (b)
1550 || XFASTINT (w->last_overlay_modified) < BUF_OVERLAY_MODIFF (b))
1551 return Qnil;
1552
1553 if (NILP (line))
1554 {
1555 i = w->cursor.vpos;
1556 if (i < 0 || i >= w->current_matrix->nrows
1557 || (row = MATRIX_ROW (w->current_matrix, i), !row->enabled_p))
1558 return Qnil;
1559 max_y = window_text_bottom_y (w);
1560 goto found_row;
1561 }
1562
1563 if (EQ (line, Qheader_line))
1564 {
1565 if (!WINDOW_WANTS_HEADER_LINE_P (w))
1566 return Qnil;
1567 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
1568 if (!row->enabled_p)
1569 return Qnil;
1570 return list4 (make_number (row->height),
1571 make_number (0), make_number (0),
1572 make_number (0));
1573 }
1574
1575 if (EQ (line, Qmode_line))
1576 {
1577 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
1578 if (!row->enabled_p)
1579 return Qnil;
1580 return list4 (make_number (row->height),
1581 make_number (0), /* not accurate */
1582 make_number (WINDOW_HEADER_LINE_HEIGHT (w)
1583 + window_text_bottom_y (w)),
1584 make_number (0));
1585 }
1586
1587 CHECK_NUMBER (line);
1588 n = XINT (line);
1589
1590 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1591 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
1592 max_y = window_text_bottom_y (w);
1593 i = 0;
1594
1595 while ((n < 0 || i < n)
1596 && row <= end_row && row->enabled_p
1597 && row->y + row->height < max_y)
1598 row++, i++;
1599
1600 if (row > end_row || !row->enabled_p)
1601 return Qnil;
1602
1603 if (++n < 0)
1604 {
1605 if (-n > i)
1606 return Qnil;
1607 row += n;
1608 i += n;
1609 }
1610
1611 found_row:
1612 crop = max (0, (row->y + row->height) - max_y);
1613 return list4 (make_number (row->height + min (0, row->y) - crop),
1614 make_number (i),
1615 make_number (row->y),
1616 make_number (crop));
1617}
1247 1618
1248DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p, 1619DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p,
1249 0, 1, 0, 1620 0, 1, 0,
@@ -1271,22 +1642,22 @@ is the value returned by `window-dedicated-p' is t. */)
1271DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p, 1642DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p,
1272 Sset_window_dedicated_p, 2, 2, 0, 1643 Sset_window_dedicated_p, 2, 2, 0,
1273 doc: /* Mark WINDOW as dedicated according to FLAG. 1644 doc: /* Mark WINDOW as dedicated according to FLAG.
1274WINDOW defaults to the selected window. FLAG non-nil means mark WINDOW 1645WINDOW must be a live window and defaults to the selected one. FLAG
1275as dedicated to its buffer. FLAG nil means mark WINDOW as non-dedicated. 1646non-nil means mark WINDOW as dedicated to its buffer. FLAG nil means
1276Return FLAG. 1647mark WINDOW as non-dedicated. Return FLAG.
1277 1648
1278When a window is dedicated to its buffer, `display-buffer' will refrain 1649When a window is dedicated to its buffer, `display-buffer' will refrain
1279from displaying another buffer in it. `get-lru-window' and 1650from displaying another buffer in it. `get-lru-window' and
1280`get-largest-window' treat dedicated windows specially. 1651`get-largest-window' treat dedicated windows specially.
1281`delete-windows-on', `replace-buffer-in-windows', `quit-window' and 1652`delete-windows-on', `replace-buffer-in-windows', `quit-window',
1282`kill-buffer' can delete a dedicated window and the containing 1653`quit-restore-window' and `kill-buffer' can delete a dedicated window
1283frame. 1654and the containing frame.
1284 1655
1285As a special case, if FLAG is t, mark WINDOW as "strongly" dedicated to 1656As a special case, if FLAG is t, mark WINDOW as "strongly" dedicated to
1286its buffer. Functions like `set-window-buffer' may change the buffer 1657its buffer. Functions like `set-window-buffer' may change the buffer
1287displayed by a window, unless that window is strongly dedicated to its 1658displayed by a window, unless that window is strongly dedicated to its
1288buffer. If and when `set-window-buffer' displays another buffer in a 1659buffer. If and when `set-window-buffer' displays another buffer in a
1289window, it also makes sure that the window is not marked as dedicated. */) 1660window, it also makes sure that the window is no more dedicated. */)
1290 (Lisp_Object window, Lisp_Object flag) 1661 (Lisp_Object window, Lisp_Object flag)
1291{ 1662{
1292 register struct window *w = decode_window (window); 1663 register struct window *w = decode_window (window);
@@ -1295,6 +1666,52 @@ window, it also makes sure that the window is not marked as dedicated. */)
1295 return w->dedicated; 1666 return w->dedicated;
1296} 1667}
1297 1668
1669DEFUN ("window-prev-buffers", Fwindow_prev_buffers, Swindow_prev_buffers,
1670 0, 1, 0,
1671 doc: /* Return buffers previously shown in WINDOW.
1672WINDOW must be a live window and defaults to the selected one.
1673
1674The return value is either nil or a list of <buffer, window-start,
1675window-point> triples where buffer was previously shown in WINDOW. */)
1676 (Lisp_Object window)
1677{
1678 return decode_window (window)->prev_buffers;
1679}
1680
1681DEFUN ("set-window-prev-buffers", Fset_window_prev_buffers,
1682 Sset_window_prev_buffers, 2, 2, 0,
1683 doc: /* Set WINDOW's previous buffers to PREV-BUFFERS.
1684WINDOW must be a live window and defaults to the selected one. Return
1685PREV-BUFFERS.
1686
1687PREV-BUFFERS should be either nil or a list of <buffer, window-start,
1688window-point> triples where buffer was previously shown in WINDOW. */)
1689 (Lisp_Object window, Lisp_Object prev_buffers)
1690{
1691 return decode_any_window (window)->prev_buffers = prev_buffers;
1692}
1693
1694DEFUN ("window-next-buffers", Fwindow_next_buffers, Swindow_next_buffers,
1695 0, 1, 0,
1696 doc: /* Return list of buffers recently re-shown in WINDOW.
1697WINDOW must be a live window and defaults to the selected one. */)
1698 (Lisp_Object window)
1699{
1700 return decode_window (window)->next_buffers;
1701}
1702
1703DEFUN ("set-window-next-buffers", Fset_window_next_buffers,
1704 Sset_window_next_buffers, 2, 2, 0,
1705 doc: /* Set WINDOW's next buffers to NEXT-BUFFERS.
1706WINDOW must be a live window and defaults to the selected one. Return
1707NEXT-BUFFERS.
1708
1709NEXT-BUFFERS should be either nil or a list of buffers that have been
1710recently re-shown in WINDOW. */)
1711 (Lisp_Object window, Lisp_Object next_buffers)
1712{
1713 return decode_any_window (window)->next_buffers = next_buffers;
1714}
1298 1715
1299DEFUN ("window-parameters", Fwindow_parameters, Swindow_parameters, 1716DEFUN ("window-parameters", Fwindow_parameters, Swindow_parameters,
1300 0, 1, 0, 1717 0, 1, 0,
@@ -1303,7 +1720,7 @@ WINDOW defaults to the selected window. The return value is a list of
1303elements of the form (PARAMETER . VALUE). */) 1720elements of the form (PARAMETER . VALUE). */)
1304 (Lisp_Object window) 1721 (Lisp_Object window)
1305{ 1722{
1306 return Fcopy_alist (decode_window (window)->window_parameters); 1723 return Fcopy_alist (decode_any_window (window)->window_parameters);
1307} 1724}
1308 1725
1309DEFUN ("window-parameter", Fwindow_parameter, Swindow_parameter, 1726DEFUN ("window-parameter", Fwindow_parameter, Swindow_parameter,
@@ -1314,7 +1731,7 @@ WINDOW defaults to the selected window. */)
1314{ 1731{
1315 Lisp_Object result; 1732 Lisp_Object result;
1316 1733
1317 result = Fassq (parameter, decode_window (window)->window_parameters); 1734 result = Fassq (parameter, decode_any_window (window)->window_parameters);
1318 return CDR_SAFE (result); 1735 return CDR_SAFE (result);
1319} 1736}
1320 1737
@@ -1324,7 +1741,7 @@ DEFUN ("set-window-parameter", Fset_window_parameter,
1324WINDOW defaults to the selected window. Return VALUE. */) 1741WINDOW defaults to the selected window. Return VALUE. */)
1325 (Lisp_Object window, Lisp_Object parameter, Lisp_Object value) 1742 (Lisp_Object window, Lisp_Object parameter, Lisp_Object value)
1326{ 1743{
1327 register struct window *w = decode_window (window); 1744 register struct window *w = decode_any_window (window);
1328 Lisp_Object old_alist_elt; 1745 Lisp_Object old_alist_elt;
1329 1746
1330 old_alist_elt = Fassq (parameter, w->window_parameters); 1747 old_alist_elt = Fassq (parameter, w->window_parameters);
@@ -1335,7 +1752,6 @@ WINDOW defaults to the selected window. Return VALUE. */)
1335 return value; 1752 return value;
1336} 1753}
1337 1754
1338
1339DEFUN ("window-display-table", Fwindow_display_table, Swindow_display_table, 1755DEFUN ("window-display-table", Fwindow_display_table, Swindow_display_table,
1340 0, 1, 0, 1756 0, 1, 0,
1341 doc: /* Return the display-table that WINDOW is using. 1757 doc: /* Return the display-table that WINDOW is using.
@@ -1361,8 +1777,8 @@ window_display_table (struct window *w)
1361 { 1777 {
1362 struct buffer *b = XBUFFER (w->buffer); 1778 struct buffer *b = XBUFFER (w->buffer);
1363 1779
1364 if (DISP_TABLE_P (b->display_table)) 1780 if (DISP_TABLE_P (BVAR (b, display_table)))
1365 dp = XCHAR_TABLE (b->display_table); 1781 dp = XCHAR_TABLE (BVAR (b, display_table));
1366 else if (DISP_TABLE_P (Vstandard_display_table)) 1782 else if (DISP_TABLE_P (Vstandard_display_table))
1367 dp = XCHAR_TABLE (Vstandard_display_table); 1783 dp = XCHAR_TABLE (Vstandard_display_table);
1368 } 1784 }
@@ -1381,9 +1797,7 @@ DEFUN ("set-window-display-table", Fset_window_display_table, Sset_window_displa
1381 return table; 1797 return table;
1382} 1798}
1383 1799
1384static void delete_window (Lisp_Object); 1800/* Record info on buffer window W is displaying
1385
1386/* Record info on buffer window w is displaying
1387 when it is about to cease to display that buffer. */ 1801 when it is about to cease to display that buffer. */
1388static void 1802static void
1389unshow_buffer (register struct window *w) 1803unshow_buffer (register struct window *w)
@@ -1416,9 +1830,9 @@ unshow_buffer (register struct window *w)
1416 So don't clobber point in that buffer. */ 1830 So don't clobber point in that buffer. */
1417 if (! EQ (buf, XWINDOW (selected_window)->buffer) 1831 if (! EQ (buf, XWINDOW (selected_window)->buffer)
1418 /* This line helps to fix Horsley's testbug.el bug. */ 1832 /* This line helps to fix Horsley's testbug.el bug. */
1419 && !(WINDOWP (b->last_selected_window) 1833 && !(WINDOWP (BVAR (b, last_selected_window))
1420 && w != XWINDOW (b->last_selected_window) 1834 && w != XWINDOW (BVAR (b, last_selected_window))
1421 && EQ (buf, XWINDOW (b->last_selected_window)->buffer))) 1835 && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->buffer)))
1422 temp_set_point_both (b, 1836 temp_set_point_both (b,
1423 clip_to_bounds (BUF_BEGV (b), 1837 clip_to_bounds (BUF_BEGV (b),
1424 XMARKER (w->pointm)->charpos, 1838 XMARKER (w->pointm)->charpos,
@@ -1427,290 +1841,149 @@ unshow_buffer (register struct window *w)
1427 marker_byte_position (w->pointm), 1841 marker_byte_position (w->pointm),
1428 BUF_ZV_BYTE (b))); 1842 BUF_ZV_BYTE (b)));
1429 1843
1430 if (WINDOWP (b->last_selected_window) 1844 if (WINDOWP (BVAR (b, last_selected_window))
1431 && w == XWINDOW (b->last_selected_window)) 1845 && w == XWINDOW (BVAR (b, last_selected_window)))
1432 b->last_selected_window = Qnil; 1846 BVAR (b, last_selected_window) = Qnil;
1433} 1847}
1434 1848
1435/* Put replacement into the window structure in place of old. */ 1849/* Put NEW into the window structure in place of OLD. SETFLAG zero
1850 means change window structure only. Otherwise store geometry and
1851 other settings as well. */
1436static void 1852static void
1437replace_window (Lisp_Object old, Lisp_Object replacement) 1853replace_window (Lisp_Object old, Lisp_Object new, int setflag)
1438{ 1854{
1439 register Lisp_Object tem; 1855 register Lisp_Object tem;
1440 register struct window *o = XWINDOW (old), *p = XWINDOW (replacement); 1856 register struct window *o = XWINDOW (old), *n = XWINDOW (new);
1441
1442 /* If OLD is its frame's root_window, then replacement is the new
1443 root_window for that frame. */
1444 1857
1858 /* If OLD is its frame's root window, then NEW is the new
1859 root window for that frame. */
1445 if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame)))) 1860 if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame))))
1446 FRAME_ROOT_WINDOW (XFRAME (o->frame)) = replacement; 1861 FRAME_ROOT_WINDOW (XFRAME (o->frame)) = new;
1447 1862
1448 p->left_col = o->left_col; 1863 if (setflag)
1449 p->top_line = o->top_line; 1864 {
1450 p->total_cols = o->total_cols; 1865 n->left_col = o->left_col;
1451 p->total_lines = o->total_lines; 1866 n->top_line = o->top_line;
1452 p->desired_matrix = p->current_matrix = 0; 1867 n->total_cols = o->total_cols;
1453 p->vscroll = 0; 1868 n->total_lines = o->total_lines;
1454 memset (&p->cursor, 0, sizeof (p->cursor)); 1869 n->normal_cols = o->normal_cols;
1455 memset (&p->last_cursor, 0, sizeof (p->last_cursor)); 1870 o->normal_cols = make_float (1.0);
1456 memset (&p->phys_cursor, 0, sizeof (p->phys_cursor)); 1871 n->normal_lines = o->normal_lines;
1457 p->phys_cursor_type = -1; 1872 o->normal_lines = make_float (1.0);
1458 p->phys_cursor_width = -1; 1873 n->desired_matrix = n->current_matrix = 0;
1459 p->must_be_updated_p = 0; 1874 n->vscroll = 0;
1460 p->pseudo_window_p = 0; 1875 memset (&n->cursor, 0, sizeof (n->cursor));
1461 XSETFASTINT (p->window_end_vpos, 0); 1876 memset (&n->last_cursor, 0, sizeof (n->last_cursor));
1462 XSETFASTINT (p->window_end_pos, 0); 1877 memset (&n->phys_cursor, 0, sizeof (n->phys_cursor));
1463 p->window_end_valid = Qnil; 1878 n->phys_cursor_type = -1;
1464 p->frozen_window_start_p = 0; 1879 n->phys_cursor_width = -1;
1465 p->orig_top_line = p->orig_total_lines = Qnil; 1880 n->must_be_updated_p = 0;
1466 1881 n->pseudo_window_p = 0;
1467 p->next = tem = o->next; 1882 XSETFASTINT (n->window_end_vpos, 0);
1883 XSETFASTINT (n->window_end_pos, 0);
1884 n->window_end_valid = Qnil;
1885 n->frozen_window_start_p = 0;
1886 }
1887
1888 n->next = tem = o->next;
1468 if (!NILP (tem)) 1889 if (!NILP (tem))
1469 XWINDOW (tem)->prev = replacement; 1890 XWINDOW (tem)->prev = new;
1470 1891
1471 p->prev = tem = o->prev; 1892 n->prev = tem = o->prev;
1472 if (!NILP (tem)) 1893 if (!NILP (tem))
1473 XWINDOW (tem)->next = replacement; 1894 XWINDOW (tem)->next = new;
1474 1895
1475 p->parent = tem = o->parent; 1896 n->parent = tem = o->parent;
1476 if (!NILP (tem)) 1897 if (!NILP (tem))
1477 { 1898 {
1478 if (EQ (XWINDOW (tem)->vchild, old)) 1899 if (EQ (XWINDOW (tem)->vchild, old))
1479 XWINDOW (tem)->vchild = replacement; 1900 XWINDOW (tem)->vchild = new;
1480 if (EQ (XWINDOW (tem)->hchild, old)) 1901 if (EQ (XWINDOW (tem)->hchild, old))
1481 XWINDOW (tem)->hchild = replacement; 1902 XWINDOW (tem)->hchild = new;
1482 } 1903 }
1483
1484/*** Here, if replacement is a vertical combination
1485and so is its new parent, we should make replacement's
1486children be children of that parent instead. ***/
1487} 1904}
1488 1905
1489DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "", 1906/* If window WINDOW and its parent window are iso-combined, merge
1490 doc: /* Remove WINDOW from its frame. 1907 WINDOW's children into those of its parent window and mark WINDOW as
1491WINDOW defaults to the selected window. Return nil. 1908 deleted. */
1492Signal an error when WINDOW is the only window on its frame. */)
1493 (register Lisp_Object window)
1494{
1495 struct frame *f;
1496 if (NILP (window))
1497 window = selected_window;
1498 else
1499 CHECK_LIVE_WINDOW (window);
1500
1501 f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
1502 delete_window (window);
1503
1504 run_window_configuration_change_hook (f);
1505
1506 return Qnil;
1507}
1508 1909
1509static void 1910static void
1510delete_window (register Lisp_Object window) 1911recombine_windows (Lisp_Object window)
1511{ 1912{
1512 register Lisp_Object tem, parent, sib; 1913 struct window *w, *p, *c;
1513 register struct window *p; 1914 Lisp_Object parent, child;
1514 register struct window *par; 1915 int horflag;
1515 struct frame *f;
1516
1517 /* Because this function is called by other C code on non-leaf
1518 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1519 so we can't decode_window here. */
1520 CHECK_WINDOW (window);
1521 p = XWINDOW (window);
1522
1523 /* It's a no-op to delete an already-deleted window. */
1524 if (NILP (p->buffer)
1525 && NILP (p->hchild)
1526 && NILP (p->vchild))
1527 return;
1528
1529 parent = p->parent;
1530 if (NILP (parent))
1531 error ("Attempt to delete minibuffer or sole ordinary window");
1532 par = XWINDOW (parent);
1533
1534 windows_or_buffers_changed++;
1535 Vwindow_list = Qnil;
1536 f = XFRAME (WINDOW_FRAME (p));
1537 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
1538
1539 /* Are we trying to delete any frame's selected window? */
1540 {
1541 Lisp_Object swindow, pwindow;
1542
1543 /* See if the frame's selected window is either WINDOW
1544 or any subwindow of it, by finding all that window's parents
1545 and comparing each one with WINDOW. */
1546 swindow = FRAME_SELECTED_WINDOW (f);
1547
1548 while (1)
1549 {
1550 pwindow = swindow;
1551 while (!NILP (pwindow))
1552 {
1553 if (EQ (window, pwindow))
1554 break;
1555 pwindow = XWINDOW (pwindow)->parent;
1556 }
1557
1558 /* If the window being deleted is not a parent of SWINDOW,
1559 then SWINDOW is ok as the new selected window. */
1560 if (!EQ (window, pwindow))
1561 break;
1562 /* Otherwise, try another window for SWINDOW. */
1563 swindow = Fnext_window (swindow, Qlambda, Qnil);
1564
1565 /* If we get back to the frame's selected window,
1566 it means there was no acceptable alternative,
1567 so we cannot delete. */
1568 if (EQ (swindow, FRAME_SELECTED_WINDOW (f)))
1569 error ("Cannot delete window");
1570 }
1571
1572 /* If we need to change SWINDOW, do it. */
1573 if (! EQ (swindow, FRAME_SELECTED_WINDOW (f)))
1574 {
1575 /* If we're about to delete the selected window on the
1576 selected frame, then we should use Fselect_window to select
1577 the new window. On the other hand, if we're about to
1578 delete the selected window on any other frame, we shouldn't do
1579 anything but set the frame's selected_window slot. */
1580 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
1581 Fselect_window (swindow, Qnil);
1582 else
1583 FRAME_SELECTED_WINDOW (f) = swindow;
1584 }
1585 }
1586
1587 /* Now we know we can delete this one. */
1588 window_deletion_count++;
1589
1590 tem = p->buffer;
1591 /* tem is null for dummy parent windows
1592 (which have inferiors but not any contents themselves) */
1593 if (!NILP (tem))
1594 {
1595 unshow_buffer (p);
1596 unchain_marker (XMARKER (p->pointm));
1597 unchain_marker (XMARKER (p->start));
1598 }
1599
1600 /* Free window glyph matrices. It is sure that they are allocated
1601 again when ADJUST_GLYPHS is called. Block input so that expose
1602 events and other events that access glyph matrices are not
1603 processed while we are changing them. */
1604 BLOCK_INPUT;
1605 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)));
1606
1607 tem = p->next;
1608 if (!NILP (tem))
1609 XWINDOW (tem)->prev = p->prev;
1610
1611 tem = p->prev;
1612 if (!NILP (tem))
1613 XWINDOW (tem)->next = p->next;
1614
1615 if (EQ (window, par->hchild))
1616 par->hchild = p->next;
1617 if (EQ (window, par->vchild))
1618 par->vchild = p->next;
1619
1620 /* Find one of our siblings to give our space to. */
1621 sib = p->prev;
1622 if (NILP (sib))
1623 {
1624 /* If p gives its space to its next sibling, that sibling needs
1625 to have its top/left side pulled back to where p's is.
1626 set_window_{height,width} will re-position the sibling's
1627 children. */
1628 sib = p->next;
1629 XWINDOW (sib)->top_line = p->top_line;
1630 XWINDOW (sib)->left_col = p->left_col;
1631 }
1632 1916
1633 /* Stretch that sibling. */ 1917 w = XWINDOW (window);
1634 if (!NILP (par->vchild)) 1918 parent = w->parent;
1635 set_window_height (sib, 1919 if (!NILP (parent) && NILP (w->nest))
1636 XFASTINT (XWINDOW (sib)->total_lines) + XFASTINT (p->total_lines), 1920 {
1637 1); 1921 p = XWINDOW (parent);
1638 if (!NILP (par->hchild)) 1922 if (((!NILP (p->vchild) && !NILP (w->vchild))
1639 set_window_width (sib, 1923 || (!NILP (p->hchild) && !NILP (w->hchild))))
1640 XFASTINT (XWINDOW (sib)->total_cols) + XFASTINT (p->total_cols), 1924 /* WINDOW and PARENT are both either a vertical or a horizontal
1641 1); 1925 combination. */
1642 1926 {
1643 /* If parent now has only one child, 1927 horflag = NILP (w->vchild);
1644 put the child into the parent's place. */ 1928 child = horflag ? w->hchild : w->vchild;
1645 tem = par->hchild; 1929 c = XWINDOW (child);
1646 if (NILP (tem))
1647 tem = par->vchild;
1648 if (NILP (XWINDOW (tem)->next)) {
1649 replace_window (parent, tem);
1650 par = XWINDOW (tem);
1651 }
1652 1930
1653 /* Since we may be deleting combination windows, we must make sure that 1931 /* Splice WINDOW's children into its parent's children and
1654 not only p but all its children have been marked as deleted. */ 1932 assign new normal sizes. */
1655 if (! NILP (p->hchild)) 1933 if (NILP (w->prev))
1656 delete_all_subwindows (XWINDOW (p->hchild)); 1934 if (horflag)
1657 else if (! NILP (p->vchild)) 1935 p->hchild = child;
1658 delete_all_subwindows (XWINDOW (p->vchild)); 1936 else
1937 p->vchild = child;
1938 else
1939 {
1940 c->prev = w->prev;
1941 XWINDOW (w->prev)->next = child;
1942 }
1659 1943
1660 /* Mark this window as deleted. */ 1944 while (c)
1661 p->buffer = p->hchild = p->vchild = Qnil; 1945 {
1946 c->parent = parent;
1662 1947
1663 if (! NILP (par->parent)) 1948 if (horflag)
1664 par = XWINDOW (par->parent); 1949 c->normal_cols
1950 = make_float (XFLOATINT (c->total_cols)
1951 / XFLOATINT (p->total_cols));
1952 else
1953 c->normal_lines
1954 = make_float (XFLOATINT (c->total_lines)
1955 / XFLOATINT (p->total_lines));
1665 1956
1666 /* Check if we have a v/hchild with a v/hchild. In that case remove 1957 if (NILP (c->next))
1667 one of them. */ 1958 {
1959 if (!NILP (w->next))
1960 {
1961 c->next = w->next;
1962 XWINDOW (c->next)->prev = child;
1963 }
1668 1964
1669 if (! NILP (par->vchild) && ! NILP (XWINDOW (par->vchild)->vchild)) 1965 c = 0;
1670 { 1966 }
1671 p = XWINDOW (par->vchild); 1967 else
1672 par->vchild = p->vchild; 1968 {
1673 tem = p->vchild; 1969 child = c->next;
1674 } 1970 c = XWINDOW (child);
1675 else if (! NILP (par->hchild) && ! NILP (XWINDOW (par->hchild)->hchild)) 1971 }
1676 { 1972 }
1677 p = XWINDOW (par->hchild);
1678 par->hchild = p->hchild;
1679 tem = p->hchild;
1680 }
1681 else
1682 p = 0;
1683 1973
1684 if (p) 1974 /* WINDOW can be deleted now. */
1685 { 1975 w->vchild = w->hchild = Qnil;
1686 while (! NILP (tem)) { 1976 }
1687 XWINDOW (tem)->parent = p->parent;
1688 if (NILP (XWINDOW (tem)->next))
1689 break;
1690 tem = XWINDOW (tem)->next;
1691 }
1692 if (! NILP (tem)) {
1693 /* The next of the v/hchild we are removing is now the next of the
1694 last child for the v/hchild:
1695 Before v/hchild -> v/hchild -> next1 -> next2
1696 |
1697 -> next3
1698 After: v/hchild -> next1 -> next2 -> next3
1699 */
1700 XWINDOW (tem)->next = p->next;
1701 if (! NILP (p->next))
1702 XWINDOW (p->next)->prev = tem;
1703 }
1704 p->next = p->prev = p->vchild = p->hchild = p->buffer = Qnil;
1705 } 1977 }
1706
1707
1708 /* Adjust glyph matrices. */
1709 adjust_glyphs (f);
1710 UNBLOCK_INPUT;
1711} 1978}
1712 1979
1713 1980/* If WINDOW can be deleted, delete it. */
1981static void
1982delete_deletable_window (Lisp_Object window)
1983{
1984 if (!NILP (call1 (Qwindow_deletable_p, window)))
1985 call1 (Qdelete_window, window);
1986}
1714 1987
1715/*********************************************************************** 1988/***********************************************************************
1716 Window List 1989 Window List
@@ -1718,7 +1991,7 @@ delete_window (register Lisp_Object window)
1718 1991
1719/* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object 1992/* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object
1720 pointer. This is a callback function for foreach_window, used in 1993 pointer. This is a callback function for foreach_window, used in
1721 function window_list. */ 1994 the window_list function. */
1722 1995
1723static int 1996static int
1724add_window_to_list (struct window *w, void *user_data) 1997add_window_to_list (struct window *w, void *user_data)
@@ -1771,8 +2044,10 @@ window_list (void)
1771 2044
1772 ALL_FRAMES t means search all frames, 2045 ALL_FRAMES t means search all frames,
1773 nil means search just current frame, 2046 nil means search just current frame,
1774 `visible' means search just visible frames, 2047 `visible' means search just visible frames on the
1775 0 means search visible and iconified frames, 2048 current terminal,
2049 0 means search visible and iconified frames on the
2050 current terminal,
1776 a window means search the frame that window belongs to, 2051 a window means search the frame that window belongs to,
1777 a frame means consider windows on that frame, only. */ 2052 a frame means consider windows on that frame, only. */
1778 2053
@@ -1838,8 +2113,8 @@ candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf
1838 2113
1839 2114
1840/* Decode arguments as allowed by Fnext_window, Fprevious_window, and 2115/* Decode arguments as allowed by Fnext_window, Fprevious_window, and
1841 Fwindow_list. See there for the meaning of WINDOW, MINIBUF, and 2116 Fwindow_list. See candidate_window_p for the meaning of WINDOW,
1842 ALL_FRAMES. */ 2117 MINIBUF, and ALL_FRAMES. */
1843 2118
1844static void 2119static void
1845decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames) 2120decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object *all_frames)
@@ -1873,12 +2148,6 @@ decode_next_window_args (Lisp_Object *window, Lisp_Object *minibuf, Lisp_Object
1873 ; 2148 ;
1874 else if (!EQ (*all_frames, Qt)) 2149 else if (!EQ (*all_frames, Qt))
1875 *all_frames = Qnil; 2150 *all_frames = Qnil;
1876
1877 /* Now *ALL_FRAMES is t meaning search all frames, nil meaning
1878 search just current frame, `visible' meaning search just visible
1879 frames, 0 meaning search visible and iconified frames, or a
1880 window, meaning search the frame that window belongs to, or a
1881 frame, meaning consider windows on that frame, only. */
1882} 2151}
1883 2152
1884 2153
@@ -1953,35 +2222,32 @@ next_window (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames, in
1953 2222
1954DEFUN ("next-window", Fnext_window, Snext_window, 0, 3, 0, 2223DEFUN ("next-window", Fnext_window, Snext_window, 0, 3, 0,
1955 doc: /* Return window following WINDOW in cyclic ordering of windows. 2224 doc: /* Return window following WINDOW in cyclic ordering of windows.
1956WINDOW defaults to the selected window. The optional arguments 2225WINDOW must be a live window and defaults to the selected one. The
1957MINIBUF and ALL-FRAMES specify the set of windows to consider. 2226optional arguments MINIBUF and ALL-FRAMES specify the set of windows to
1958 2227consider.
1959MINIBUF t means consider the minibuffer window even if the 2228
1960minibuffer is not active. MINIBUF nil or omitted means consider 2229MINIBUF nil or omitted means consider the minibuffer window only if the
1961the minibuffer window only if the minibuffer is active. Any 2230minibuffer is active. MINIBUF t means consider the minibuffer window
1962other value means do not consider the minibuffer window even if 2231even if the minibuffer is not active. Any other value means do not
1963the minibuffer is active. 2232consider the minibuffer window even if the minibuffer is active.
1964 2233
1965Several frames may share a single minibuffer; if the minibuffer 2234ALL-FRAMES nil or omitted means consider all windows on WINDOW's frame,
1966is active, all windows on all frames that share that minibuffer 2235plus the minibuffer window if specified by the MINIBUF argument. If the
1967are considered too. Therefore, if you are using a separate 2236minibuffer counts, consider all windows on all frames that share that
1968minibuffer frame and the minibuffer is active and MINIBUF says it 2237minibuffer too. The following non-nil values of ALL-FRAMES have special
1969counts, `next-window' considers the windows in the frame from 2238meanings:
1970which you entered the minibuffer, as well as the minibuffer 2239
1971window. 2240- t means consider all windows on all existing frames.
2241
2242- `visible' means consider all windows on all visible frames.
2243
2244- 0 (the number zero) means consider all windows on all visible and
2245 iconified frames.
2246
2247- A frame means consider all windows on that frame only.
1972 2248
1973ALL-FRAMES nil or omitted means consider all windows on WINDOW's
1974 frame, plus the minibuffer window if specified by the MINIBUF
1975 argument, see above. If the minibuffer counts, consider all
1976 windows on all frames that share that minibuffer too.
1977ALL-FRAMES t means consider all windows on all existing frames.
1978ALL-FRAMES `visible' means consider all windows on all visible
1979 frames.
1980ALL-FRAMES 0 means consider all windows on all visible and
1981 iconified frames.
1982ALL-FRAMES a frame means consider all windows on that frame only.
1983Anything else means consider all windows on WINDOW's frame and no 2249Anything else means consider all windows on WINDOW's frame and no
1984 others. 2250others.
1985 2251
1986If you use consistent values for MINIBUF and ALL-FRAMES, you can use 2252If you use consistent values for MINIBUF and ALL-FRAMES, you can use
1987`next-window' to iterate through the entire cycle of acceptable 2253`next-window' to iterate through the entire cycle of acceptable
@@ -1995,9 +2261,32 @@ windows, eventually ending up back at the window you started with.
1995 2261
1996DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 3, 0, 2262DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 3, 0,
1997 doc: /* Return window preceding WINDOW in cyclic ordering of windows. 2263 doc: /* Return window preceding WINDOW in cyclic ordering of windows.
1998WINDOW defaults to the selected window. The optional arguments 2264WINDOW must be a live window and defaults to the selected one. The
1999MINIBUF and ALL-FRAMES specify the set of windows to consider. 2265optional arguments MINIBUF and ALL-FRAMES specify the set of windows to
2000For the precise meaning of these arguments see `next-window'. 2266consider.
2267
2268MINIBUF nil or omitted means consider the minibuffer window only if the
2269minibuffer is active. MINIBUF t means consider the minibuffer window
2270even if the minibuffer is not active. Any other value means do not
2271consider the minibuffer window even if the minibuffer is active.
2272
2273ALL-FRAMES nil or omitted means consider all windows on WINDOW's frame,
2274plus the minibuffer window if specified by the MINIBUF argument. If the
2275minibuffer counts, consider all windows on all frames that share that
2276minibuffer too. The following non-nil values of ALL-FRAMES have special
2277meanings:
2278
2279- t means consider all windows on all existing frames.
2280
2281- `visible' means consider all windows on all visible frames.
2282
2283- 0 (the number zero) means consider all windows on all visible and
2284 iconified frames.
2285
2286- A frame means consider all windows on that frame only.
2287
2288Anything else means consider all windows on WINDOW's frame and no
2289others.
2001 2290
2002If you use consistent values for MINIBUF and ALL-FRAMES, you can 2291If you use consistent values for MINIBUF and ALL-FRAMES, you can
2003use `previous-window' to iterate through the entire cycle of 2292use `previous-window' to iterate through the entire cycle of
@@ -2010,34 +2299,32 @@ reverse order. */)
2010} 2299}
2011 2300
2012 2301
2013DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p", 2302/* Return a list of windows in cyclic ordering. Arguments are like
2014 doc: /* Select another window in cyclic ordering of windows. 2303 for `next-window'. */
2015COUNT specifies the number of windows to skip, starting with the
2016selected window, before making the selection. If COUNT is
2017positive, skip COUNT windows forwards. If COUNT is negative,
2018skip -COUNT windows backwards. COUNT zero means do not skip any
2019window, so select the selected window. In an interactive call,
2020COUNT is the numeric prefix argument. Return nil.
2021 2304
2022This function uses `next-window' for finding the window to select. 2305static Lisp_Object
2023The argument ALL-FRAMES has the same meaning as in `next-window', 2306window_list_1 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
2024but the MINIBUF argument of `next-window' is always effectively
2025nil. */)
2026 (Lisp_Object count, Lisp_Object all_frames)
2027{ 2307{
2028 Lisp_Object window; 2308 Lisp_Object tail, list, rest;
2029 int i;
2030 2309
2031 CHECK_NUMBER (count); 2310 decode_next_window_args (&window, &minibuf, &all_frames);
2032 window = selected_window; 2311 list = Qnil;
2033 2312
2034 for (i = XINT (count); i > 0; --i) 2313 for (tail = window_list (); CONSP (tail); tail = XCDR (tail))
2035 window = Fnext_window (window, Qnil, all_frames); 2314 if (candidate_window_p (XCAR (tail), window, minibuf, all_frames))
2036 for (; i < 0; ++i) 2315 list = Fcons (XCAR (tail), list);
2037 window = Fprevious_window (window, Qnil, all_frames);
2038 2316
2039 Fselect_window (window, Qnil); 2317 /* Rotate the list to start with WINDOW. */
2040 return Qnil; 2318 list = Fnreverse (list);
2319 rest = Fmemq (window, list);
2320 if (!NILP (rest) && !EQ (rest, list))
2321 {
2322 for (tail = list; !EQ (XCDR (tail), rest); tail = XCDR (tail))
2323 ;
2324 XSETCDR (tail, Qnil);
2325 list = nconc2 (rest, list);
2326 }
2327 return list;
2041} 2328}
2042 2329
2043 2330
@@ -2064,35 +2351,41 @@ MINIBUF neither nil nor t means never include the minibuffer window. */)
2064} 2351}
2065 2352
2066 2353
2067/* Return a list of windows in cyclic ordering. Arguments are like 2354DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0,
2068 for `next-window'. */ 2355 doc: /* Return a list of all live windows.
2356WINDOW specifies the first window to list and defaults to the selected
2357window.
2069 2358
2070static Lisp_Object 2359Optional argument MINIBUF nil or omitted means consider the minibuffer
2071window_list_1 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames) 2360window only if the minibuffer is active. MINIBUF t means consider the
2072{ 2361minibuffer window even if the minibuffer is not active. Any other value
2073 Lisp_Object tail, list, rest; 2362means do not consider the minibuffer window even if the minibuffer is
2363active.
2074 2364
2075 decode_next_window_args (&window, &minibuf, &all_frames); 2365Optional argument ALL-FRAMES nil or omitted means consider all windows
2076 list = Qnil; 2366on WINDOW's frame, plus the minibuffer window if specified by the
2367MINIBUF argument. If the minibuffer counts, consider all windows on all
2368frames that share that minibuffer too. The following non-nil values of
2369ALL-FRAMES have special meanings:
2077 2370
2078 for (tail = window_list (); CONSP (tail); tail = XCDR (tail)) 2371- t means consider all windows on all existing frames.
2079 if (candidate_window_p (XCAR (tail), window, minibuf, all_frames))
2080 list = Fcons (XCAR (tail), list);
2081 2372
2082 /* Rotate the list to start with WINDOW. */ 2373- `visible' means consider all windows on all visible frames.
2083 list = Fnreverse (list); 2374
2084 rest = Fmemq (window, list); 2375- 0 (the number zero) means consider all windows on all visible and
2085 if (!NILP (rest) && !EQ (rest, list)) 2376 iconified frames.
2086 {
2087 for (tail = list; !EQ (XCDR (tail), rest); tail = XCDR (tail))
2088 ;
2089 XSETCDR (tail, Qnil);
2090 list = nconc2 (rest, list);
2091 }
2092 return list;
2093}
2094 2377
2378- A frame means consider all windows on that frame only.
2095 2379
2380Anything else means consider all windows on WINDOW's frame and no
2381others.
2382
2383If WINDOW is not on the list of windows returned, some other window will
2384be listed first but no error is signalled. */)
2385 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
2386{
2387 return window_list_1 (window, minibuf, all_frames);
2388}
2096 2389
2097/* Look at all windows, performing an operation specified by TYPE 2390/* Look at all windows, performing an operation specified by TYPE
2098 with argument OBJ. 2391 with argument OBJ.
@@ -2105,13 +2398,9 @@ window_list_1 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
2105enum window_loop 2398enum window_loop
2106{ 2399{
2107 WINDOW_LOOP_UNUSED, 2400 WINDOW_LOOP_UNUSED,
2108 GET_BUFFER_WINDOW, /* Arg is buffer */ 2401 GET_BUFFER_WINDOW, /* Arg is buffer */
2109 GET_LRU_WINDOW, /* Arg is t for full-width windows only */ 2402 REPLACE_BUFFER_IN_WINDOWS_SAFELY, /* Arg is buffer */
2110 DELETE_OTHER_WINDOWS, /* Arg is window not to delete */ 2403 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
2111 DELETE_BUFFER_WINDOWS, /* Arg is buffer */
2112 GET_LARGEST_WINDOW,
2113 UNSHOW_BUFFER, /* Arg is buffer */
2114 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
2115 CHECK_ALL_WINDOWS 2404 CHECK_ALL_WINDOWS
2116}; 2405};
2117 2406
@@ -2119,6 +2408,7 @@ static Lisp_Object
2119window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frames) 2408window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frames)
2120{ 2409{
2121 Lisp_Object window, windows, best_window, frame_arg; 2410 Lisp_Object window, windows, best_window, frame_arg;
2411 int frame_best_window_flag = 0;
2122 struct frame *f; 2412 struct frame *f;
2123 struct gcpro gcpro1; 2413 struct gcpro gcpro1;
2124 2414
@@ -2168,148 +2458,51 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2168 is visible, since Fwindow_list skips non-visible frames if 2458 is visible, since Fwindow_list skips non-visible frames if
2169 that is desired, under the control of frame_arg. */ 2459 that is desired, under the control of frame_arg. */
2170 if (!MINI_WINDOW_P (w) 2460 if (!MINI_WINDOW_P (w)
2171 /* For UNSHOW_BUFFER, we must always consider all windows. */ 2461 /* For REPLACE_BUFFER_IN_WINDOWS_SAFELY, we must always
2172 || type == UNSHOW_BUFFER 2462 consider all windows. */
2463 || type == REPLACE_BUFFER_IN_WINDOWS_SAFELY
2173 || (mini && minibuf_level > 0)) 2464 || (mini && minibuf_level > 0))
2174 switch (type) 2465 switch (type)
2175 { 2466 {
2176 case GET_BUFFER_WINDOW: 2467 case GET_BUFFER_WINDOW:
2177 if (EQ (w->buffer, obj) 2468 if (EQ (w->buffer, obj)
2178 /* Don't find any minibuffer window 2469 /* Don't find any minibuffer window except the one that
2179 except the one that is currently in use. */ 2470 is currently in use. */
2180 && (MINI_WINDOW_P (w) 2471 && (MINI_WINDOW_P (w) ? EQ (window, minibuf_window) : 1))
2181 ? EQ (window, minibuf_window)
2182 : 1))
2183 { 2472 {
2184 if (NILP (best_window)) 2473 if (EQ (window, selected_window))
2185 best_window = window; 2474 /* Preferably return the selected window. */
2186 else if (EQ (window, selected_window))
2187 /* Prefer to return selected-window. */
2188 RETURN_UNGCPRO (window); 2475 RETURN_UNGCPRO (window);
2189 else if (EQ (Fwindow_frame (window), selected_frame)) 2476 else if (EQ (XWINDOW (window)->frame, selected_frame)
2190 /* Prefer windows on the current frame. */ 2477 && !frame_best_window_flag)
2191 best_window = window; 2478 /* Prefer windows on the current frame (but don't
2192 } 2479 choose another one if we have one already). */
2193 break;
2194
2195 case GET_LRU_WINDOW:
2196 /* `obj' is an integer encoding a bitvector.
2197 `obj & 1' means consider only full-width windows.
2198 `obj & 2' means consider also dedicated windows. */
2199 if (((XINT (obj) & 1) && !WINDOW_FULL_WIDTH_P (w))
2200 || (!(XINT (obj) & 2) && !NILP (w->dedicated))
2201 /* Minibuffer windows are always ignored. */
2202 || MINI_WINDOW_P (w))
2203 break;
2204 if (NILP (best_window)
2205 || (XFASTINT (XWINDOW (best_window)->use_time)
2206 > XFASTINT (w->use_time)))
2207 best_window = window;
2208 break;
2209
2210 case DELETE_OTHER_WINDOWS:
2211 if (!EQ (window, obj))
2212 Fdelete_window (window);
2213 break;
2214
2215 case DELETE_BUFFER_WINDOWS:
2216 if (EQ (w->buffer, obj))
2217 {
2218 struct frame *f = XFRAME (WINDOW_FRAME (w));
2219
2220 /* If this window is dedicated, and in a frame of its own,
2221 kill the frame. */
2222 if (EQ (window, FRAME_ROOT_WINDOW (f))
2223 && !NILP (w->dedicated)
2224 && other_visible_frames (f))
2225 { 2480 {
2226 /* Skip the other windows on this frame. 2481 best_window = window;
2227 There might be one, the minibuffer! */ 2482 frame_best_window_flag = 1;
2228 while (CONSP (XCDR (windows))
2229 && EQ (XWINDOW (XCAR (windows))->frame,
2230 XWINDOW (XCAR (XCDR (windows)))->frame))
2231 windows = XCDR (windows);
2232
2233 /* Now we can safely delete the frame. */
2234 delete_frame (w->frame, Qnil);
2235 }
2236 else if (NILP (w->parent))
2237 {
2238 /* If we're deleting the buffer displayed in the
2239 only window on the frame, find a new buffer to
2240 display there. */
2241 Lisp_Object buffer;
2242 buffer = Fother_buffer (obj, Qnil, w->frame);
2243 /* Reset dedicated state of window. */
2244 w->dedicated = Qnil;
2245 Fset_window_buffer (window, buffer, Qnil);
2246 if (EQ (window, selected_window))
2247 Fset_buffer (w->buffer);
2248 } 2483 }
2249 else 2484 else if (NILP (best_window))
2250 Fdelete_window (window); 2485 best_window = window;
2251 } 2486 }
2252 break; 2487 break;
2253 2488
2254 case GET_LARGEST_WINDOW: 2489 case REPLACE_BUFFER_IN_WINDOWS_SAFELY:
2255 { /* nil `obj' means to ignore dedicated windows. */ 2490 /* We could simply check whether the buffer shown by window
2256 /* Ignore dedicated windows and minibuffers. */ 2491 is live, and show another buffer in case it isn't. */
2257 if (MINI_WINDOW_P (w) || (NILP (obj) && !NILP (w->dedicated)))
2258 break;
2259
2260 if (NILP (best_window))
2261 best_window = window;
2262 else
2263 {
2264 struct window *b = XWINDOW (best_window);
2265 if (XFASTINT (w->total_lines) * XFASTINT (w->total_cols)
2266 > XFASTINT (b->total_lines) * XFASTINT (b->total_cols))
2267 best_window = window;
2268 }
2269 }
2270 break;
2271
2272 case UNSHOW_BUFFER:
2273 if (EQ (w->buffer, obj)) 2492 if (EQ (w->buffer, obj))
2274 { 2493 {
2275 Lisp_Object buffer; 2494 /* Undedicate WINDOW. */
2276 struct frame *f = XFRAME (w->frame); 2495 w->dedicated = Qnil;
2277 2496 /* Make WINDOW show the buffer returned by
2278 /* Find another buffer to show in this window. */ 2497 other_buffer_safely, don't run any hooks. */
2279 buffer = Fother_buffer (obj, Qnil, w->frame); 2498 set_window_buffer
2280 2499 (window, other_buffer_safely (w->buffer), 0, 0);
2281 /* If this window is dedicated, and in a frame of its own, 2500 /* If WINDOW is the selected window, make its buffer
2282 kill the frame. */ 2501 current. But do so only if the window shows the
2283 if (EQ (window, FRAME_ROOT_WINDOW (f)) 2502 current buffer (Bug#6454). */
2284 && !NILP (w->dedicated) 2503 if (EQ (window, selected_window)
2285 && other_visible_frames (f)) 2504 && XBUFFER (w->buffer) == current_buffer)
2286 { 2505 Fset_buffer (w->buffer);
2287 /* Skip the other windows on this frame.
2288 There might be one, the minibuffer! */
2289 while (CONSP (XCDR (windows))
2290 && EQ (XWINDOW (XCAR (windows))->frame,
2291 XWINDOW (XCAR (XCDR (windows)))->frame))
2292 windows = XCDR (windows);
2293
2294 /* Now we can safely delete the frame. */
2295 delete_frame (w->frame, Qnil);
2296 }
2297 else if (!NILP (w->dedicated) && !NILP (w->parent))
2298 {
2299 Lisp_Object window;
2300 XSETWINDOW (window, w);
2301 /* If this window is dedicated and not the only window
2302 in its frame, then kill it. */
2303 Fdelete_window (window);
2304 }
2305 else
2306 {
2307 /* Otherwise show a different buffer in the window. */
2308 w->dedicated = Qnil;
2309 Fset_window_buffer (window, buffer, Qnil);
2310 if (EQ (window, selected_window))
2311 Fset_buffer (w->buffer);
2312 }
2313 } 2506 }
2314 break; 2507 break;
2315 2508
@@ -2327,7 +2520,7 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2327 /* Check for a window that has a killed buffer. */ 2520 /* Check for a window that has a killed buffer. */
2328 case CHECK_ALL_WINDOWS: 2521 case CHECK_ALL_WINDOWS:
2329 if (! NILP (w->buffer) 2522 if (! NILP (w->buffer)
2330 && NILP (XBUFFER (w->buffer)->name)) 2523 && NILP (BVAR (XBUFFER (w->buffer), name)))
2331 abort (); 2524 abort ();
2332 break; 2525 break;
2333 2526
@@ -2342,76 +2535,32 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2342 2535
2343/* Used for debugging. Abort if any window has a dead buffer. */ 2536/* Used for debugging. Abort if any window has a dead buffer. */
2344 2537
2538extern void check_all_windows (void) EXTERNALLY_VISIBLE;
2345void 2539void
2346check_all_windows (void) 2540check_all_windows (void)
2347{ 2541{
2348 window_loop (CHECK_ALL_WINDOWS, Qnil, 1, Qt); 2542 window_loop (CHECK_ALL_WINDOWS, Qnil, 1, Qt);
2349} 2543}
2350 2544
2351DEFUN ("window-use-time", Fwindow_use_time, Swindow_use_time, 0, 1, 0,
2352 doc: /* Return WINDOW's use time.
2353WINDOW defaults to the selected window. The window with the highest use
2354time is the most recently selected one. The window with the lowest use
2355time is the least recently selected one. */)
2356 (Lisp_Object window)
2357{
2358 return decode_window (window)->use_time;
2359}
2360
2361DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 2, 0,
2362 doc: /* Return the window least recently selected or used for display.
2363\(LRU means Least Recently Used.)
2364
2365Return a full-width window if possible.
2366A minibuffer window is never a candidate.
2367A dedicated window is never a candidate, unless DEDICATED is non-nil,
2368 so if all windows are dedicated, the value is nil.
2369If optional argument FRAME is `visible', search all visible frames.
2370If FRAME is 0, search all visible and iconified frames.
2371If FRAME is t, search all frames.
2372If FRAME is nil, search only the selected frame.
2373If FRAME is a frame, search only that frame. */)
2374 (Lisp_Object frame, Lisp_Object dedicated)
2375{
2376 register Lisp_Object w;
2377 /* First try for a window that is full-width */
2378 w = window_loop (GET_LRU_WINDOW,
2379 NILP (dedicated) ? make_number (1) : make_number (3),
2380 0, frame);
2381 if (!NILP (w) && !EQ (w, selected_window))
2382 return w;
2383 /* If none of them, try the rest */
2384 return window_loop (GET_LRU_WINDOW,
2385 NILP (dedicated) ? make_number (0) : make_number (2),
2386 0, frame);
2387}
2388
2389DEFUN ("get-largest-window", Fget_largest_window, Sget_largest_window, 0, 2, 0,
2390 doc: /* Return the largest window in area.
2391A minibuffer window is never a candidate.
2392A dedicated window is never a candidate unless DEDICATED is non-nil,
2393 so if all windows are dedicated, the value is nil.
2394If optional argument FRAME is `visible', search all visible frames.
2395If FRAME is 0, search all visible and iconified frames.
2396If FRAME is t, search all frames.
2397If FRAME is nil, search only the selected frame.
2398If FRAME is a frame, search only that frame. */)
2399 (Lisp_Object frame, Lisp_Object dedicated)
2400{
2401 return window_loop (GET_LARGEST_WINDOW, dedicated, 0,
2402 frame);
2403}
2404
2405DEFUN ("get-buffer-window", Fget_buffer_window, Sget_buffer_window, 0, 2, 0, 2545DEFUN ("get-buffer-window", Fget_buffer_window, Sget_buffer_window, 0, 2, 0,
2406 doc: /* Return a window currently displaying BUFFER-OR-NAME, or nil if none. 2546 doc: /* Return a window currently displaying BUFFER-OR-NAME, or nil if none.
2407BUFFER-OR-NAME may be a buffer or a buffer name and defaults to the 2547BUFFER-OR-NAME may be a buffer or a buffer name and defaults to
2408current buffer. 2548the current buffer.
2409If optional argument FRAME is `visible', search all visible frames. 2549
2410If optional argument FRAME is 0, search all visible and iconified frames. 2550The optional argument ALL-FRAMES specifies the frames to consider:
2411If FRAME is t, search all frames. 2551
2412If FRAME is nil, search only the selected frame. 2552- t means consider all windows on all existing frames.
2413If FRAME is a frame, search only that frame. */) 2553
2414 (Lisp_Object buffer_or_name, Lisp_Object frame) 2554- `visible' means consider all windows on all visible frames.
2555
2556- 0 (the number zero) means consider all windows on all visible
2557 and iconified frames.
2558
2559- A frame means consider all windows on that frame only.
2560
2561Any other value of ALL-FRAMES means consider all windows on the
2562selected frame and no others. */)
2563 (Lisp_Object buffer_or_name, Lisp_Object all_frames)
2415{ 2564{
2416 Lisp_Object buffer; 2565 Lisp_Object buffer;
2417 2566
@@ -2421,168 +2570,275 @@ If FRAME is a frame, search only that frame. */)
2421 buffer = Fget_buffer (buffer_or_name); 2570 buffer = Fget_buffer (buffer_or_name);
2422 2571
2423 if (BUFFERP (buffer)) 2572 if (BUFFERP (buffer))
2424 return window_loop (GET_BUFFER_WINDOW, buffer, 1, frame); 2573 return window_loop (GET_BUFFER_WINDOW, buffer, 1, all_frames);
2425 else 2574 else
2426 return Qnil; 2575 return Qnil;
2427} 2576}
2428 2577
2429DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows, 2578static Lisp_Object
2430 0, 1, "", 2579resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore)
2431 doc: /* Make WINDOW (or the selected window) fill its frame. 2580{
2432Only the frame WINDOW is on is affected. 2581 return call4 (Qresize_root_window, window, delta, horizontal, ignore);
2433This function tries to reduce display jumps by keeping the text 2582}
2583
2584
2585DEFUN ("delete-other-windows-internal", Fdelete_other_windows_internal,
2586 Sdelete_other_windows_internal, 0, 2, "",
2587 doc: /* Make WINDOW fill its frame.
2588Only the frame WINDOW is on is affected. WINDOW may be any window and
2589defaults to the selected one.
2590
2591Optional argument ROOT, if non-nil, must specify an internal window
2592containing WINDOW as a subwindow. If this is the case, replace ROOT by
2593WINDOW and leave alone any windows not contained in ROOT.
2594
2595When WINDOW is live try to reduce display jumps by keeping the text
2434previously visible in WINDOW in the same place on the frame. Doing this 2596previously visible in WINDOW in the same place on the frame. Doing this
2435depends on the value of (window-start WINDOW), so if calling this 2597depends on the value of (window-start WINDOW), so if calling this
2436function in a program gives strange scrolling, make sure the 2598function in a program gives strange scrolling, make sure the
2437window-start value is reasonable when this function is called. */) 2599window-start value is reasonable when this function is called. */)
2438 (Lisp_Object window) 2600 (Lisp_Object window, Lisp_Object root)
2439{ 2601{
2440 struct window *w; 2602 struct window *w, *r, *s;
2441 EMACS_INT startpos; 2603 struct frame *f;
2442 int top, new_top; 2604 Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta;
2605 EMACS_INT startpos IF_LINT (= 0);
2606 int top IF_LINT (= 0), new_top, resize_failed;
2443 2607
2444 if (NILP (window)) 2608 w = decode_any_window (window);
2445 window = selected_window; 2609 XSETWINDOW (window, w);
2446 else 2610 f = XFRAME (w->frame);
2447 CHECK_LIVE_WINDOW (window);
2448 w = XWINDOW (window);
2449 2611
2450 startpos = marker_position (w->start); 2612 if (NILP (root))
2451 top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); 2613 /* ROOT is the frame's root window. */
2614 {
2615 root = FRAME_ROOT_WINDOW (f);
2616 r = XWINDOW (root);
2617 }
2618 else
2619 /* ROOT must be an ancestor of WINDOW. */
2620 {
2621 r = decode_any_window (root);
2622 pwindow = XWINDOW (window)->parent;
2623 while (!NILP (pwindow))
2624 if (EQ (pwindow, root))
2625 break;
2626 else
2627 pwindow = XWINDOW (pwindow)->parent;
2628 if (!EQ (pwindow, root))
2629 error ("Specified root is not an ancestor of specified window");
2630 }
2452 2631
2453 if (MINI_WINDOW_P (w) && top > 0) 2632 if (EQ (window, root))
2633 /* A noop. */
2634 return Qnil;
2635 /* I don't understand the "top > 0" part below. If we deal with a
2636 standalone minibuffer it would have been caught by the preceding
2637 test. */
2638 else if (MINI_WINDOW_P (w)) /* && top > 0) */
2454 error ("Can't expand minibuffer to full frame"); 2639 error ("Can't expand minibuffer to full frame");
2455 2640
2456 window_loop (DELETE_OTHER_WINDOWS, window, 0, WINDOW_FRAME (w)); 2641 if (!NILP (w->buffer))
2457
2458 /* Try to minimize scrolling, by setting the window start to the point
2459 will cause the text at the old window start to be at the same place
2460 on the frame. But don't try to do this if the window start is
2461 outside the visible portion (as might happen when the display is
2462 not current, due to typeahead). */
2463 new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
2464 if (new_top != top
2465 && startpos >= BUF_BEGV (XBUFFER (w->buffer))
2466 && startpos <= BUF_ZV (XBUFFER (w->buffer)))
2467 { 2642 {
2468 struct position pos; 2643 startpos = marker_position (w->start);
2469 struct buffer *obuf = current_buffer; 2644 top = WINDOW_TOP_EDGE_LINE (w)
2645 - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
2646 /* Make sure WINDOW is the frame's selected window. */
2647 if (!EQ (window, FRAME_SELECTED_WINDOW (f)))
2648 {
2649 if (EQ (selected_frame, w->frame))
2650 Fselect_window (window, Qnil);
2651 else
2652 FRAME_SELECTED_WINDOW (f) = window;
2653 }
2654 }
2655 else
2656 {
2657 /* See if the frame's selected window is a subwindow of WINDOW, by
2658 finding all the selected window's parents and comparing each
2659 one with WINDOW. If it isn't we need a new selected window for
2660 this frame. */
2661 swindow = FRAME_SELECTED_WINDOW (f);
2662 while (1)
2663 {
2664 pwindow = swindow;
2665 while (!NILP (pwindow) && !EQ (window, pwindow))
2666 pwindow = XWINDOW (pwindow)->parent;
2470 2667
2471 Fset_buffer (w->buffer); 2668 if (EQ (window, pwindow))
2472 /* This computation used to temporarily move point, but that can 2669 /* If WINDOW is an ancestor of SWINDOW, then SWINDOW is ok
2473 have unwanted side effects due to text properties. */ 2670 as the new selected window. */
2474 pos = *vmotion (startpos, -top, w); 2671 break;
2672 else
2673 /* Else try the previous window of SWINDOW. */
2674 swindow = Fprevious_window (swindow, Qlambda, Qnil);
2675 }
2475 2676
2476 set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos); 2677 if (!EQ (swindow, FRAME_SELECTED_WINDOW (f)))
2477 w->window_end_valid = Qnil; 2678 {
2478 w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE 2679 if (EQ (selected_frame, w->frame))
2479 || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt 2680 Fselect_window (swindow, Qnil);
2480 : Qnil); 2681 else
2481 /* We need to do this, so that the window-scroll-functions 2682 FRAME_SELECTED_WINDOW (f) = swindow;
2482 get called. */ 2683 }
2483 w->optional_new_start = Qt;
2484
2485 set_buffer_internal (obuf);
2486 } 2684 }
2487 2685
2488 return Qnil; 2686 BLOCK_INPUT;
2489} 2687 free_window_matrices (r);
2490 2688
2491DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on, 2689 windows_or_buffers_changed++;
2492 0, 2, "bDelete windows on (buffer): ", 2690 Vwindow_list = Qnil;
2493 doc: /* Delete all windows showing BUFFER-OR-NAME. 2691 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
2494BUFFER-OR-NAME may be a buffer or the name of an existing buffer and 2692 resize_failed = 0;
2495defaults to the current buffer.
2496 2693
2497Optional second argument FRAME controls which frames are affected. 2694 if (NILP (w->buffer))
2498If optional argument FRAME is `visible', search all visible frames. 2695 {
2499If FRAME is 0, search all visible and iconified frames. 2696 /* Resize subwindows vertically. */
2500If FRAME is nil, search all frames. 2697 XSETINT (delta, XINT (r->total_lines) - XINT (w->total_lines));
2501If FRAME is t, search only the selected frame. 2698 w->top_line = r->top_line;
2502If FRAME is a frame, search only that frame. 2699 resize_root_window (window, delta, Qnil, Qnil);
2503When a window showing BUFFER-OR-NAME is dedicated and the only window of 2700 if (resize_window_check (w, 0))
2504its frame, that frame is deleted when there are other frames left. */) 2701 resize_window_apply (w, 0);
2505 (Lisp_Object buffer_or_name, Lisp_Object frame) 2702 else
2506{ 2703 {
2507 Lisp_Object buffer; 2704 resize_root_window (window, delta, Qnil, Qt);
2705 if (resize_window_check (w, 0))
2706 resize_window_apply (w, 0);
2707 else
2708 resize_failed = 1;
2709 }
2508 2710
2509 /* FRAME uses t and nil to mean the opposite of what window_loop 2711 /* Resize subwindows horizontally. */
2510 expects. */ 2712 if (!resize_failed)
2511 if (NILP (frame)) 2713 {
2512 frame = Qt; 2714 w->left_col = r->left_col;
2513 else if (EQ (frame, Qt)) 2715 XSETINT (delta, XINT (r->total_cols) - XINT (w->total_cols));
2514 frame = Qnil; 2716 w->left_col = r->left_col;
2717 resize_root_window (window, delta, Qt, Qnil);
2718 if (resize_window_check (w, 1))
2719 resize_window_apply (w, 1);
2720 else
2721 {
2722 resize_root_window (window, delta, Qt, Qt);
2723 if (resize_window_check (w, 1))
2724 resize_window_apply (w, 1);
2725 else
2726 resize_failed = 1;
2727 }
2728 }
2515 2729
2516 if (NILP (buffer_or_name)) 2730 if (resize_failed)
2517 buffer = Fcurrent_buffer (); 2731 /* Play safe, if we still can ... */
2732 {
2733 window = swindow;
2734 w = XWINDOW (window);
2735 }
2736 }
2737
2738 /* Cleanly unlink WINDOW from window-tree. */
2739 if (!NILP (w->prev))
2740 /* Get SIBLING above (on the left of) WINDOW. */
2741 {
2742 sibling = w->prev;
2743 s = XWINDOW (sibling);
2744 s->next = w->next;
2745 if (!NILP (s->next))
2746 XWINDOW (s->next)->prev = sibling;
2747 }
2518 else 2748 else
2749 /* Get SIBLING below (on the right of) WINDOW. */
2519 { 2750 {
2520 buffer = Fget_buffer (buffer_or_name); 2751 sibling = w->next;
2521 CHECK_BUFFER (buffer); 2752 s = XWINDOW (sibling);
2753 s->prev = Qnil;
2754 if (!NILP (XWINDOW (w->parent)->vchild))
2755 XWINDOW (w->parent)->vchild = sibling;
2756 else
2757 XWINDOW (w->parent)->hchild = sibling;
2522 } 2758 }
2523 2759
2524 window_loop (DELETE_BUFFER_WINDOWS, buffer, 0, frame); 2760 /* Delete ROOT and all subwindows of ROOT. */
2525 2761 if (!NILP (r->vchild))
2526 return Qnil; 2762 {
2527} 2763 delete_all_subwindows (r->vchild);
2764 r->vchild = Qnil;
2765 }
2766 else if (!NILP (r->hchild))
2767 {
2768 delete_all_subwindows (r->hchild);
2769 r->hchild = Qnil;
2770 }
2528 2771
2529DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows, 2772 replace_window (root, window, 1);
2530 Sreplace_buffer_in_windows,
2531 0, 1, "bReplace buffer in windows: ",
2532 doc: /* Replace BUFFER-OR-NAME with some other buffer in all windows showing it.
2533BUFFER-OR-NAME may be a buffer or the name of an existing buffer and
2534defaults to the current buffer.
2535 2773
2536When a window showing BUFFER-OR-NAME is dedicated that window is 2774 /* Reset WINDOW's splits status. */
2537deleted. If that window is the only window on its frame, that frame is 2775 w->splits = Qnil;
2538deleted too when there are other frames left. If there are no other
2539frames left, some other buffer is displayed in that window. */)
2540 (Lisp_Object buffer_or_name)
2541{
2542 Lisp_Object buffer;
2543 2776
2544 if (NILP (buffer_or_name)) 2777 /* This must become SWINDOW anyway ....... */
2545 buffer = Fcurrent_buffer (); 2778 if (!NILP (w->buffer) && !resize_failed)
2546 else
2547 { 2779 {
2548 buffer = Fget_buffer (buffer_or_name); 2780 /* Try to minimize scrolling, by setting the window start to the
2549 CHECK_BUFFER (buffer); 2781 point will cause the text at the old window start to be at the
2782 same place on the frame. But don't try to do this if the
2783 window start is outside the visible portion (as might happen
2784 when the display is not current, due to typeahead). */
2785 new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
2786 if (new_top != top
2787 && startpos >= BUF_BEGV (XBUFFER (w->buffer))
2788 && startpos <= BUF_ZV (XBUFFER (w->buffer)))
2789 {
2790 struct position pos;
2791 struct buffer *obuf = current_buffer;
2792
2793 Fset_buffer (w->buffer);
2794 /* This computation used to temporarily move point, but that
2795 can have unwanted side effects due to text properties. */
2796 pos = *vmotion (startpos, -top, w);
2797
2798 set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
2799 w->window_end_valid = Qnil;
2800 w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE
2801 || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt
2802 : Qnil);
2803 /* We need to do this, so that the window-scroll-functions
2804 get called. */
2805 w->optional_new_start = Qt;
2806
2807 set_buffer_internal (obuf);
2808 }
2550 } 2809 }
2551 2810
2552 window_loop (UNSHOW_BUFFER, buffer, 0, Qt); 2811 adjust_glyphs (f);
2812 UNBLOCK_INPUT;
2813
2814 run_window_configuration_change_hook (f);
2553 2815
2554 return Qnil; 2816 return Qnil;
2555} 2817}
2556 2818
2557/* Replace BUFFER with some other buffer in all windows
2558 of all frames, even those on other keyboards. */
2559 2819
2560void 2820void
2561replace_buffer_in_all_windows (Lisp_Object buffer) 2821replace_buffer_in_windows (Lisp_Object buffer)
2562{ 2822{
2563 Lisp_Object tail, frame; 2823 call1 (Qreplace_buffer_in_windows, buffer);
2564
2565 /* A single call to window_loop won't do the job
2566 because it only considers frames on the current keyboard.
2567 So loop manually over frames, and handle each one. */
2568 FOR_EACH_FRAME (tail, frame)
2569 window_loop (UNSHOW_BUFFER, buffer, 1, frame);
2570} 2824}
2571
2572/* Set the height of WINDOW and all its inferiors. */
2573 2825
2574/* The smallest acceptable dimensions for a window. Anything smaller
2575 might crash Emacs. */
2576 2826
2577#define MIN_SAFE_WINDOW_WIDTH (2) 2827/* Safely replace BUFFER with some other buffer in all windows of all
2578#define MIN_SAFE_WINDOW_HEIGHT (1) 2828 frames, even those on other keyboards. */
2579 2829
2580/* For wp non-zero the total number of columns of window w. Otherwise 2830void
2581 the total number of lines of w. */ 2831replace_buffer_in_windows_safely (Lisp_Object buffer)
2582 2832{
2583#define WINDOW_TOTAL_SIZE(w, wp) \ 2833 Lisp_Object tail, frame;
2584 (wp ? WINDOW_TOTAL_COLS (w) : WINDOW_TOTAL_LINES (w))
2585 2834
2835 /* A single call to window_loop won't do the job because it only
2836 considers frames on the current keyboard. So loop manually over
2837 frames, and handle each one. */
2838 FOR_EACH_FRAME (tail, frame)
2839 window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame);
2840}
2841
2586/* If *ROWS or *COLS are too small a size for FRAME, set them to the 2842/* If *ROWS or *COLS are too small a size for FRAME, set them to the
2587 minimum allowable size. */ 2843 minimum allowable size. */
2588 2844
@@ -2606,243 +2862,6 @@ check_frame_size (FRAME_PTR frame, int *rows, int *cols)
2606 *cols = MIN_SAFE_WINDOW_WIDTH; 2862 *cols = MIN_SAFE_WINDOW_WIDTH;
2607} 2863}
2608 2864
2609/* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
2610 check if W's width can be changed, otherwise check W's height.
2611 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
2612 siblings, too. If none of the siblings is resizable, WINDOW isn't
2613 either. */
2614
2615static int
2616window_fixed_size_p (struct window *w, int width_p, int check_siblings_p)
2617{
2618 int fixed_p;
2619 struct window *c;
2620
2621 if (!NILP (w->hchild))
2622 {
2623 c = XWINDOW (w->hchild);
2624
2625 if (width_p)
2626 {
2627 /* A horizontal combination is fixed-width if all of if its
2628 children are. */
2629 while (c && window_fixed_size_p (c, width_p, 0))
2630 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
2631 fixed_p = c == NULL;
2632 }
2633 else
2634 {
2635 /* A horizontal combination is fixed-height if one of if its
2636 children is. */
2637 while (c && !window_fixed_size_p (c, width_p, 0))
2638 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
2639 fixed_p = c != NULL;
2640 }
2641 }
2642 else if (!NILP (w->vchild))
2643 {
2644 c = XWINDOW (w->vchild);
2645
2646 if (width_p)
2647 {
2648 /* A vertical combination is fixed-width if one of if its
2649 children is. */
2650 while (c && !window_fixed_size_p (c, width_p, 0))
2651 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
2652 fixed_p = c != NULL;
2653 }
2654 else
2655 {
2656 /* A vertical combination is fixed-height if all of if its
2657 children are. */
2658 while (c && window_fixed_size_p (c, width_p, 0))
2659 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
2660 fixed_p = c == NULL;
2661 }
2662 }
2663 else if (BUFFERP (w->buffer))
2664 {
2665 struct buffer *old = current_buffer;
2666 Lisp_Object val;
2667
2668 current_buffer = XBUFFER (w->buffer);
2669 val = find_symbol_value (Qwindow_size_fixed);
2670 current_buffer = old;
2671
2672 fixed_p = 0;
2673 if (!EQ (val, Qunbound))
2674 {
2675 fixed_p = !NILP (val);
2676
2677 if (fixed_p
2678 && ((EQ (val, Qheight) && width_p)
2679 || (EQ (val, Qwidth) && !width_p)))
2680 fixed_p = 0;
2681 }
2682
2683 /* Can't tell if this one is resizable without looking at
2684 siblings. If all siblings are fixed-size this one is too. */
2685 if (!fixed_p && check_siblings_p && WINDOWP (w->parent))
2686 {
2687 Lisp_Object child;
2688
2689 for (child = w->prev; WINDOWP (child); child = XWINDOW (child)->prev)
2690 if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
2691 break;
2692
2693 if (NILP (child))
2694 for (child = w->next; WINDOWP (child); child = XWINDOW (child)->next)
2695 if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
2696 break;
2697
2698 if (NILP (child))
2699 fixed_p = 1;
2700 }
2701 }
2702 else
2703 fixed_p = 1;
2704
2705 return fixed_p;
2706}
2707
2708/* Return minimum size of leaf window W. WIDTH_P non-zero means return
2709 the minimum width of W, WIDTH_P zero means return the minimum height
2710 of W. SAFE_P non-zero means ignore window-min-height|width but just
2711 return values that won't crash Emacs and don't hide components like
2712 fringes, scrollbars, or modelines. If WIDTH_P is zero and W is the
2713 minibuffer window, always return 1. */
2714
2715static int
2716window_min_size_2 (struct window *w, int width_p, int safe_p)
2717{
2718 /* We should consider buffer-local values of window_min_height and
2719 window_min_width here. */
2720 if (width_p)
2721 {
2722 int safe_size = (MIN_SAFE_WINDOW_WIDTH
2723 + WINDOW_FRINGE_COLS (w)
2724 + WINDOW_SCROLL_BAR_COLS (w));
2725
2726 return safe_p ? safe_size : max (window_min_width, safe_size);
2727 }
2728 else if (MINI_WINDOW_P (w))
2729 return 1;
2730 else
2731 {
2732 int safe_size = (MIN_SAFE_WINDOW_HEIGHT
2733 + ((BUFFERP (w->buffer)
2734 && !NILP (XBUFFER (w->buffer)->mode_line_format))
2735 ? 1 : 0));
2736
2737 return safe_p ? safe_size : max (window_min_height, safe_size);
2738 }
2739}
2740
2741/* Return minimum size of window W, not taking fixed-width windows into
2742 account. WIDTH_P non-zero means return the minimum width, otherwise
2743 return the minimum height. SAFE_P non-zero means ignore
2744 window-min-height|width but just return values that won't crash Emacs
2745 and don't hide components like fringes, scrollbars, or modelines. If
2746 W is a combination window, compute the minimum size from the minimum
2747 sizes of W's children. */
2748
2749static int
2750window_min_size_1 (struct window *w, int width_p, int safe_p)
2751{
2752 struct window *c;
2753 int size;
2754
2755 if (!NILP (w->hchild))
2756 {
2757 /* W is a horizontal combination. */
2758 c = XWINDOW (w->hchild);
2759 size = 0;
2760
2761 if (width_p)
2762 {
2763 /* The minimum width of a horizontal combination is the sum of
2764 the minimum widths of its children. */
2765 while (c)
2766 {
2767 size += window_min_size_1 (c, 1, safe_p);
2768 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
2769 }
2770 }
2771 else
2772 {
2773 /* The minimum height of a horizontal combination is the
2774 maximum of the minimum heights of its children. */
2775 while (c)
2776 {
2777 size = max (window_min_size_1 (c, 0, safe_p), size);
2778 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
2779 }
2780 }
2781 }
2782 else if (!NILP (w->vchild))
2783 {
2784 /* W is a vertical combination. */
2785 c = XWINDOW (w->vchild);
2786 size = 0;
2787
2788 if (width_p)
2789 {
2790 /* The minimum width of a vertical combination is the maximum
2791 of the minimum widths of its children. */
2792 while (c)
2793 {
2794 size = max (window_min_size_1 (c, 1, safe_p), size);
2795 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
2796 }
2797 }
2798 else
2799 {
2800 /* The minimum height of a vertical combination is the sum of
2801 the minimum height of its children. */
2802 while (c)
2803 {
2804 size += window_min_size_1 (c, 0, safe_p);
2805 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
2806 }
2807 }
2808 }
2809 else
2810 /* W is a leaf window. */
2811 size = window_min_size_2 (w, width_p, safe_p);
2812
2813 return size;
2814}
2815
2816/* Return the minimum size of window W, taking fixed-size windows into
2817 account. WIDTH_P non-zero means return the minimum width, otherwise
2818 return the minimum height. SAFE_P non-zero means ignore
2819 window-min-height|width but just return values that won't crash Emacs
2820 and don't hide components like fringes, scrollbars, or modelines.
2821 IGNORE_FIXED_P non-zero means ignore if W is fixed-size. Set *FIXED
2822 to 1 if W is fixed-size unless FIXED is null. */
2823
2824static int
2825window_min_size (struct window *w, int width_p, int safe_p, int ignore_fixed_p, int *fixed)
2826{
2827 int size, fixed_p;
2828
2829 if (ignore_fixed_p)
2830 fixed_p = 0;
2831 else
2832 fixed_p = window_fixed_size_p (w, width_p, 1);
2833
2834 if (fixed)
2835 *fixed = fixed_p;
2836
2837 if (fixed_p)
2838 size = WINDOW_TOTAL_SIZE (w, width_p);
2839 else
2840 size = window_min_size_1 (w, width_p, safe_p);
2841
2842 return size;
2843}
2844
2845
2846/* Adjust the margins of window W if text area is too small. 2865/* Adjust the margins of window W if text area is too small.
2847 Return 1 if window width is ok after adjustment; 0 if window 2866 Return 1 if window width is ok after adjustment; 0 if window
2848 is still too narrow. */ 2867 is still too narrow. */
@@ -2877,415 +2896,16 @@ adjust_window_margins (struct window *w)
2877 w->left_margin_cols = make_number (margin_cols); 2896 w->left_margin_cols = make_number (margin_cols);
2878 return 1; 2897 return 1;
2879} 2898}
2880
2881/* Calculate new sizes for windows in the list FORWARD when their
2882 compound size goes from TOTAL to SIZE. TOTAL must be greater than
2883 SIZE. The number of windows in FORWARD is NCHILDREN, and the number
2884 that can shrink is SHRINKABLE. Fixed-size windows may be shrunk if
2885 and only if RESIZE_FIXED_P is non-zero. WIDTH_P non-zero means
2886 shrink columns, otherwise shrink lines.
2887
2888 SAFE_P zero means windows may be sized down to window-min-height
2889 lines (window-min-window columns for WIDTH_P non-zero). SAFE_P
2890 non-zero means windows may be sized down to their minimum safe sizes
2891 taking into account the space needed to display modelines, fringes,
2892 and scrollbars.
2893
2894 This function returns an allocated array of new sizes that the caller
2895 must free. A size -1 means the window is fixed and RESIZE_FIXED_P is
2896 zero. A size zero means the window shall be deleted. Array index 0
2897 refers to the first window in FORWARD, 1 to the second, and so on.
2898
2899 This function resizes windows proportionally to their size. It also
2900 tries to preserve smaller windows by resizing larger windows before
2901 resizing any window to zero. If resize_proportionally is non-nil for
2902 a specific window, it will attempt to strictly resize that window
2903 proportionally, even at the expense of deleting smaller windows. */
2904static int *
2905shrink_windows (int total, int size, int nchildren, int shrinkable,
2906 int resize_fixed_p, Lisp_Object forward, int width_p, int safe_p)
2907{
2908 int available_resize = 0;
2909 int *new_sizes, *min_sizes;
2910 struct window *c;
2911 Lisp_Object child;
2912 int smallest = total;
2913 int total_removed = 0;
2914 int total_shrink = total - size;
2915 int i;
2916
2917 new_sizes = xmalloc (sizeof (*new_sizes) * nchildren);
2918 min_sizes = xmalloc (sizeof (*min_sizes) * nchildren);
2919
2920 for (i = 0, child = forward; !NILP (child); child = c->next, ++i)
2921 {
2922 int child_size;
2923
2924 c = XWINDOW (child);
2925 child_size = WINDOW_TOTAL_SIZE (c, width_p);
2926
2927 if (!resize_fixed_p && window_fixed_size_p (c, width_p, 0))
2928 new_sizes[i] = -1;
2929 else
2930 {
2931 new_sizes[i] = child_size;
2932 min_sizes[i] = window_min_size_1 (c, width_p, safe_p);
2933 if (child_size > min_sizes[i]
2934 && NILP (c->resize_proportionally))
2935 available_resize += child_size - min_sizes[i];
2936 }
2937 }
2938 /* We might need to shrink some windows to zero. Find the smallest
2939 windows and set them to 0 until we can fulfil the new size. */
2940
2941 while (shrinkable > 1 && size + available_resize < total)
2942 {
2943 for (i = 0; i < nchildren; ++i)
2944 if (new_sizes[i] > 0 && smallest > new_sizes[i])
2945 smallest = new_sizes[i];
2946
2947 for (i = 0; i < nchildren; ++i)
2948 if (new_sizes[i] == smallest)
2949 {
2950 /* Resize this window down to zero. */
2951 new_sizes[i] = 0;
2952 if (smallest > min_sizes[i])
2953 available_resize -= smallest - min_sizes[i];
2954 available_resize += smallest;
2955 --shrinkable;
2956 total_removed += smallest;
2957
2958 /* We don't know what the smallest is now. */
2959 smallest = total;
2960
2961 /* Out of for, just remove one window at the time and
2962 check again if we have enough space. */
2963 break;
2964 }
2965 }
2966
2967 /* Now, calculate the new sizes. Try to shrink each window
2968 proportional to its size. */
2969 for (i = 0; i < nchildren; ++i)
2970 {
2971 if (new_sizes[i] > min_sizes[i])
2972 {
2973 int to_shrink = total_shrink * new_sizes[i] / total;
2974
2975 if (new_sizes[i] - to_shrink < min_sizes[i])
2976 to_shrink = new_sizes[i] - min_sizes[i];
2977 new_sizes[i] -= to_shrink;
2978 total_removed += to_shrink;
2979 }
2980 }
2981
2982 /* Any reminder due to rounding, we just subtract from windows
2983 that are left and still can be shrunk. */
2984 while (total_shrink > total_removed)
2985 {
2986 int nonzero_sizes = 0;
2987 int nonzero_idx = -1;
2988
2989 for (i = 0; i < nchildren; ++i)
2990 if (new_sizes[i] > 0)
2991 {
2992 ++nonzero_sizes;
2993 nonzero_idx = i;
2994 }
2995
2996 for (i = 0; i < nchildren; ++i)
2997 if (new_sizes[i] > min_sizes[i])
2998 {
2999 --new_sizes[i];
3000 ++total_removed;
3001
3002 /* Out of for, just shrink one window at the time and
3003 check again if we have enough space. */
3004 break;
3005 }
3006
3007 /* Special case, only one window left. */
3008 if (nonzero_sizes == 1)
3009 break;
3010 }
3011
3012 /* Any surplus due to rounding, we add to windows that are left. */
3013 while (total_shrink < total_removed)
3014 {
3015 for (i = 0; i < nchildren; ++i)
3016 {
3017 if (new_sizes[i] != 0 && total_shrink < total_removed)
3018 {
3019 ++new_sizes[i];
3020 --total_removed;
3021 break;
3022 }
3023 }
3024 }
3025
3026 xfree (min_sizes);
3027
3028 return new_sizes;
3029}
3030
3031/* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
3032 WINDOW's width. Resize WINDOW's children, if any, so that they keep
3033 their proportionate size relative to WINDOW.
3034
3035 If FIRST_ONLY is 1, change only the first of WINDOW's children when
3036 they are in series. If LAST_ONLY is 1, change only the last of
3037 WINDOW's children when they are in series.
3038
3039 Propagate WINDOW's top or left edge position to children. Delete
3040 windows that become too small unless NODELETE_P is 1. When
3041 NODELETE_P equals 2 do not honor settings for window-min-height and
3042 window-min-width when resizing windows but use safe defaults instead.
3043 This should give better behavior when resizing frames. */
3044
3045static void
3046size_window (Lisp_Object window, int size, int width_p, int nodelete_p, int first_only, int last_only)
3047{
3048 struct window *w = XWINDOW (window);
3049 struct window *c;
3050 Lisp_Object child, *forward, *sideward;
3051 int old_size = WINDOW_TOTAL_SIZE (w, width_p);
3052
3053 size = max (0, size);
3054
3055 /* Delete WINDOW if it's too small. */
3056 if (nodelete_p != 1 && !NILP (w->parent)
3057 && size < window_min_size_1 (w, width_p, nodelete_p == 2))
3058 {
3059 delete_window (window);
3060 return;
3061 }
3062
3063 /* Set redisplay hints. */
3064 w->last_modified = make_number (0);
3065 w->last_overlay_modified = make_number (0);
3066 windows_or_buffers_changed++;
3067 FRAME_WINDOW_SIZES_CHANGED (XFRAME (w->frame)) = 1;
3068
3069 if (width_p)
3070 {
3071 sideward = &w->vchild;
3072 forward = &w->hchild;
3073 w->total_cols = make_number (size);
3074 adjust_window_margins (w);
3075 }
3076 else
3077 {
3078 sideward = &w->hchild;
3079 forward = &w->vchild;
3080 w->total_lines = make_number (size);
3081 w->orig_total_lines = Qnil;
3082 }
3083
3084 if (!NILP (*sideward))
3085 {
3086 /* We have a chain of parallel siblings whose size should all change. */
3087 for (child = *sideward; !NILP (child); child = c->next)
3088 {
3089 c = XWINDOW (child);
3090 if (width_p)
3091 c->left_col = w->left_col;
3092 else
3093 c->top_line = w->top_line;
3094 size_window (child, size, width_p, nodelete_p,
3095 first_only, last_only);
3096 }
3097 }
3098 else if (!NILP (*forward) && last_only)
3099 {
3100 /* Change the last in a series of siblings. */
3101 Lisp_Object last_child;
3102 int child_size;
3103
3104 for (child = *forward; !NILP (child); child = c->next)
3105 {
3106 c = XWINDOW (child);
3107 last_child = child;
3108 }
3109
3110 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3111 size_window (last_child, size - old_size + child_size,
3112 width_p, nodelete_p, first_only, last_only);
3113 }
3114 else if (!NILP (*forward) && first_only)
3115 {
3116 /* Change the first in a series of siblings. */
3117 int child_size;
3118
3119 child = *forward;
3120 c = XWINDOW (child);
3121
3122 if (width_p)
3123 c->left_col = w->left_col;
3124 else
3125 c->top_line = w->top_line;
3126
3127 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3128 size_window (child, size - old_size + child_size,
3129 width_p, nodelete_p, first_only, last_only);
3130 }
3131 else if (!NILP (*forward))
3132 {
3133 int fixed_size, each, extra, n;
3134 int resize_fixed_p, nfixed;
3135 int last_pos, first_pos, nchildren, total;
3136 int *new_sizes = NULL;
3137
3138 /* Determine the fixed-size portion of this window, and the
3139 number of child windows. */
3140 fixed_size = nchildren = nfixed = total = 0;
3141 for (child = *forward; !NILP (child); child = c->next, ++nchildren)
3142 {
3143 int child_size;
3144
3145 c = XWINDOW (child);
3146 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3147 total += child_size;
3148
3149 if (window_fixed_size_p (c, width_p, 0))
3150 {
3151 fixed_size += child_size;
3152 ++nfixed;
3153 }
3154 }
3155
3156 /* If the new size is smaller than fixed_size, or if there
3157 aren't any resizable windows, allow resizing fixed-size
3158 windows. */
3159 resize_fixed_p = nfixed == nchildren || size < fixed_size;
3160
3161 /* Compute how many lines/columns to add/remove to each child. The
3162 value of extra takes care of rounding errors. */
3163 n = resize_fixed_p ? nchildren : nchildren - nfixed;
3164 if (size < total && n > 1)
3165 new_sizes = shrink_windows (total, size, nchildren, n,
3166 resize_fixed_p, *forward, width_p,
3167 nodelete_p == 2);
3168 else
3169 {
3170 each = (size - total) / n;
3171 extra = (size - total) - n * each;
3172 }
3173
3174 /* Compute new children heights and edge positions. */
3175 first_pos = width_p ? XINT (w->left_col) : XINT (w->top_line);
3176 last_pos = first_pos;
3177 for (n = 0, child = *forward; !NILP (child); child = c->next, ++n)
3178 {
3179 int new_size, old_size;
3180
3181 c = XWINDOW (child);
3182 old_size = WINDOW_TOTAL_SIZE (c, width_p);
3183 new_size = old_size;
3184
3185 /* The top or left edge position of this child equals the
3186 bottom or right edge of its predecessor. */
3187 if (width_p)
3188 c->left_col = make_number (last_pos);
3189 else
3190 c->top_line = make_number (last_pos);
3191
3192 /* If this child can be resized, do it. */
3193 if (resize_fixed_p || !window_fixed_size_p (c, width_p, 0))
3194 {
3195 new_size = new_sizes ? new_sizes[n] : old_size + each + extra;
3196 extra = 0;
3197 }
3198
3199 /* Set new size. Note that size_window also propagates
3200 edge positions to children, so it's not a no-op if we
3201 didn't change the child's size. */
3202 size_window (child, new_size, width_p, 1, first_only, last_only);
3203
3204 /* Remember the bottom/right edge position of this child; it
3205 will be used to set the top/left edge of the next child. */
3206 last_pos += new_size;
3207 }
3208
3209 xfree (new_sizes);
3210
3211 /* We should have covered the parent exactly with child windows. */
3212 xassert (size == last_pos - first_pos);
3213
3214 /* Now delete any children that became too small. */
3215 if (nodelete_p != 1)
3216 for (child = *forward; !NILP (child); child = c->next)
3217 {
3218 int child_size;
3219
3220 c = XWINDOW (child);
3221 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3222 size_window (child, child_size, width_p, nodelete_p,
3223 first_only, last_only);
3224 }
3225 }
3226}
3227
3228/* Set WINDOW's height to HEIGHT, and recursively change the height of
3229 WINDOW's children. NODELETE zero means windows that have become
3230 smaller than window-min-height in the process may be deleted.
3231 NODELETE 1 means never delete windows that become too small in the
3232 process. (The caller should check later and do so if appropriate.)
3233 NODELETE 2 means delete only windows that have become too small to be
3234 displayed correctly. */
3235
3236void
3237set_window_height (Lisp_Object window, int height, int nodelete)
3238{
3239 size_window (window, height, 0, nodelete, 0, 0);
3240}
3241
3242/* Set WINDOW's width to WIDTH, and recursively change the width of
3243 WINDOW's children. NODELETE zero means windows that have become
3244 smaller than window-min-width in the process may be deleted.
3245 NODELETE 1 means never delete windows that become too small in the
3246 process. (The caller should check later and do so if appropriate.)
3247 NODELETE 2 means delete only windows that have become too small to be
3248 displayed correctly. */
3249
3250void
3251set_window_width (Lisp_Object window, int width, int nodelete)
3252{
3253 size_window (window, width, 1, nodelete, 0, 0);
3254}
3255
3256/* Change window heights in windows rooted in WINDOW by N lines. */
3257
3258void
3259change_window_heights (Lisp_Object window, int n)
3260{
3261 struct window *w = XWINDOW (window);
3262
3263 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
3264 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
3265
3266 if (INTEGERP (w->orig_top_line))
3267 XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n);
3268 if (INTEGERP (w->orig_total_lines))
3269 XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n);
3270
3271 /* Handle just the top child in a vertical split. */
3272 if (!NILP (w->vchild))
3273 change_window_heights (w->vchild, n);
3274
3275 /* Adjust all children in a horizontal split. */
3276 for (window = w->hchild; !NILP (window); window = w->next)
3277 {
3278 w = XWINDOW (window);
3279 change_window_heights (window, n);
3280 }
3281}
3282
3283 2899
3284int window_select_count; 2900static Lisp_Object Fset_window_margins (Lisp_Object, Lisp_Object, Lisp_Object);
3285 2901static Lisp_Object Fset_window_fringes (Lisp_Object, Lisp_Object, Lisp_Object,
3286EXFUN (Fset_window_fringes, 4); 2902 Lisp_Object);
3287EXFUN (Fset_window_scroll_bars, 4); 2903static Lisp_Object Fset_window_scroll_bars (Lisp_Object, Lisp_Object,
3288 2904 Lisp_Object, Lisp_Object);
2905static Lisp_Object Fset_window_vscroll (Lisp_Object, Lisp_Object, Lisp_Object);
2906
2907/* The following three routines are needed for running a window's
2908 configuration change hook. */
3289static void 2909static void
3290run_funs (Lisp_Object funs) 2910run_funs (Lisp_Object funs)
3291{ 2911{
@@ -3294,8 +2914,19 @@ run_funs (Lisp_Object funs)
3294 call0 (XCAR (funs)); 2914 call0 (XCAR (funs));
3295} 2915}
3296 2916
3297static Lisp_Object select_window_norecord (Lisp_Object window); 2917static Lisp_Object
3298static Lisp_Object select_frame_norecord (Lisp_Object frame); 2918select_window_norecord (Lisp_Object window)
2919{
2920 return WINDOW_LIVE_P (window)
2921 ? Fselect_window (window, Qt) : selected_window;
2922}
2923
2924static Lisp_Object
2925select_frame_norecord (Lisp_Object frame)
2926{
2927 return FRAME_LIVE_P (XFRAME (frame))
2928 ? Fselect_frame (frame, Qt) : selected_frame;
2929}
3299 2930
3300void 2931void
3301run_window_configuration_change_hook (struct frame *f) 2932run_window_configuration_change_hook (struct frame *f)
@@ -3308,12 +2939,6 @@ run_window_configuration_change_hook (struct frame *f)
3308 if (NILP (Vrun_hooks)) 2939 if (NILP (Vrun_hooks))
3309 return; 2940 return;
3310 2941
3311 if (SELECTED_FRAME () != f)
3312 {
3313 record_unwind_protect (select_frame_norecord, Fselected_frame ());
3314 Fselect_frame (frame, Qt);
3315 }
3316
3317 /* Use the right buffer. Matters when running the local hooks. */ 2942 /* Use the right buffer. Matters when running the local hooks. */
3318 if (current_buffer != XBUFFER (Fwindow_buffer (Qnil))) 2943 if (current_buffer != XBUFFER (Fwindow_buffer (Qnil)))
3319 { 2944 {
@@ -3321,6 +2946,12 @@ run_window_configuration_change_hook (struct frame *f)
3321 Fset_buffer (Fwindow_buffer (Qnil)); 2946 Fset_buffer (Fwindow_buffer (Qnil));
3322 } 2947 }
3323 2948
2949 if (SELECTED_FRAME () != f)
2950 {
2951 record_unwind_protect (select_frame_norecord, Fselected_frame ());
2952 select_frame_norecord (frame);
2953 }
2954
3324 /* Look for buffer-local values. */ 2955 /* Look for buffer-local values. */
3325 { 2956 {
3326 Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil); 2957 Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil);
@@ -3331,12 +2962,12 @@ run_window_configuration_change_hook (struct frame *f)
3331 if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook, 2962 if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook,
3332 buffer))) 2963 buffer)))
3333 { 2964 {
3334 int count = SPECPDL_INDEX (); 2965 int inner_count = SPECPDL_INDEX ();
3335 record_unwind_protect (select_window_norecord, Fselected_window ()); 2966 record_unwind_protect (select_window_norecord, Fselected_window ());
3336 select_window_norecord (window); 2967 select_window_norecord (window);
3337 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook, 2968 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
3338 buffer)); 2969 buffer));
3339 unbind_to (count, Qnil); 2970 unbind_to (inner_count, Qnil);
3340 } 2971 }
3341 } 2972 }
3342 } 2973 }
@@ -3345,6 +2976,16 @@ run_window_configuration_change_hook (struct frame *f)
3345 unbind_to (count, Qnil); 2976 unbind_to (count, Qnil);
3346} 2977}
3347 2978
2979DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook,
2980 Srun_window_configuration_change_hook, 1, 1, 0,
2981 doc: /* Run `window-configuration-change-hook' for FRAME. */)
2982 (Lisp_Object frame)
2983{
2984 CHECK_LIVE_FRAME (frame);
2985 run_window_configuration_change_hook (XFRAME (frame));
2986 return Qnil;
2987}
2988
3348/* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero 2989/* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
3349 means it's allowed to run hooks. See make_frame for a case where 2990 means it's allowed to run hooks. See make_frame for a case where
3350 it's not allowed. KEEP_MARGINS_P non-zero means that the current 2991 it's not allowed. KEEP_MARGINS_P non-zero means that the current
@@ -3362,15 +3003,15 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
3362 w->buffer = buffer; 3003 w->buffer = buffer;
3363 3004
3364 if (EQ (window, selected_window)) 3005 if (EQ (window, selected_window))
3365 b->last_selected_window = window; 3006 BVAR (b, last_selected_window) = window;
3366 3007
3367 /* Let redisplay errors through. */ 3008 /* Let redisplay errors through. */
3368 b->display_error_modiff = 0; 3009 b->display_error_modiff = 0;
3369 3010
3370 /* Update time stamps of buffer display. */ 3011 /* Update time stamps of buffer display. */
3371 if (INTEGERP (b->display_count)) 3012 if (INTEGERP (BVAR (b, display_count)))
3372 XSETINT (b->display_count, XINT (b->display_count) + 1); 3013 XSETINT (BVAR (b, display_count), XINT (BVAR (b, display_count)) + 1);
3373 b->display_time = Fcurrent_time (); 3014 BVAR (b, display_time) = Fcurrent_time ();
3374 3015
3375 XSETFASTINT (w->window_end_pos, 0); 3016 XSETFASTINT (w->window_end_pos, 0);
3376 XSETFASTINT (w->window_end_vpos, 0); 3017 XSETFASTINT (w->window_end_vpos, 0);
@@ -3423,18 +3064,18 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
3423 w->left_margin_cols = w->right_margin_cols = Qnil; 3064 w->left_margin_cols = w->right_margin_cols = Qnil;
3424 3065
3425 Fset_window_fringes (window, 3066 Fset_window_fringes (window,
3426 b->left_fringe_width, b->right_fringe_width, 3067 BVAR (b, left_fringe_width), BVAR (b, right_fringe_width),
3427 b->fringes_outside_margins); 3068 BVAR (b, fringes_outside_margins));
3428 3069
3429 Fset_window_scroll_bars (window, 3070 Fset_window_scroll_bars (window,
3430 b->scroll_bar_width, 3071 BVAR (b, scroll_bar_width),
3431 b->vertical_scroll_bar_type, Qnil); 3072 BVAR (b, vertical_scroll_bar_type), Qnil);
3432 3073
3433 w->left_margin_cols = save_left; 3074 w->left_margin_cols = save_left;
3434 w->right_margin_cols = save_right; 3075 w->right_margin_cols = save_right;
3435 3076
3436 Fset_window_margins (window, 3077 Fset_window_margins (window,
3437 b->left_margin_cols, b->right_margin_cols); 3078 BVAR (b, left_margin_cols), BVAR (b, right_margin_cols));
3438 } 3079 }
3439 3080
3440 if (run_hooks_p) 3081 if (run_hooks_p)
@@ -3448,14 +3089,27 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
3448 unbind_to (count, Qnil); 3089 unbind_to (count, Qnil);
3449} 3090}
3450 3091
3092DEFUN ("set-window-clone-number", Fset_window_clone_number, Sset_window_clone_number, 2, 2, 0,
3093 doc: /* Set WINDOW's clone number to CLONE-NUMBER.
3094WINDOW can be any window and defaults to the selected one. */)
3095 (Lisp_Object window, Lisp_Object clone_number)
3096{
3097 register struct window *w = decode_any_window (window);
3098
3099 CHECK_NUMBER (clone_number);
3100 w->clone_number = clone_number;
3101 return w->clone_number;
3102}
3451 3103
3452DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0, 3104DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0,
3453 doc: /* Make WINDOW display BUFFER-OR-NAME as its contents. 3105 doc: /* Make WINDOW display BUFFER-OR-NAME as its contents.
3454WINDOW defaults to the selected window. BUFFER-OR-NAME must be a buffer 3106WINDOW has to be a live window and defaults to the selected one.
3455or the name of an existing buffer. Optional third argument KEEP-MARGINS 3107BUFFER-OR-NAME must be a buffer or the name of an existing buffer.
3456non-nil means that WINDOW's current display margins, fringe widths, and 3108
3457scroll bar settings are preserved; the default is to reset these from 3109Optional third argument KEEP-MARGINS non-nil means that WINDOW's current
3458the local settings for BUFFER-OR-NAME or the frame defaults. Return nil. 3110display margins, fringe widths, and scroll bar settings are preserved;
3111the default is to reset these from the local settings for BUFFER-OR-NAME
3112or the frame defaults. Return nil.
3459 3113
3460This function throws an error when WINDOW is strongly dedicated to its 3114This function throws an error when WINDOW is strongly dedicated to its
3461buffer (that is `window-dedicated-p' returns t for WINDOW) and does not 3115buffer (that is `window-dedicated-p' returns t for WINDOW) and does not
@@ -3471,7 +3125,7 @@ This function runs `window-scroll-functions' before running
3471 XSETWINDOW (window, w); 3125 XSETWINDOW (window, w);
3472 buffer = Fget_buffer (buffer_or_name); 3126 buffer = Fget_buffer (buffer_or_name);
3473 CHECK_BUFFER (buffer); 3127 CHECK_BUFFER (buffer);
3474 if (NILP (XBUFFER (buffer)->name)) 3128 if (NILP (BVAR (XBUFFER (buffer), name)))
3475 error ("Attempt to display deleted buffer"); 3129 error ("Attempt to display deleted buffer");
3476 3130
3477 tem = w->buffer; 3131 tem = w->buffer;
@@ -3480,136 +3134,29 @@ This function runs `window-scroll-functions' before running
3480 else if (!EQ (tem, Qt)) 3134 else if (!EQ (tem, Qt))
3481 /* w->buffer is t when the window is first being set up. */ 3135 /* w->buffer is t when the window is first being set up. */
3482 { 3136 {
3483 if (EQ (tem, buffer)) 3137 if (!EQ (tem, buffer))
3484 return Qnil; 3138 {
3485 else if (EQ (w->dedicated, Qt)) 3139 if (EQ (w->dedicated, Qt))
3486 error ("Window is dedicated to `%s'", SDATA (XBUFFER (tem)->name)); 3140 /* WINDOW is strongly dedicated to its buffer, signal an
3487 else 3141 error. */
3488 w->dedicated = Qnil; 3142 error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem), name)));
3143 else
3144 /* WINDOW is weakly dedicated to its buffer, reset
3145 dedicatedness. */
3146 w->dedicated = Qnil;
3147
3148 call1 (Qrecord_window_buffer, window);
3149 }
3489 3150
3490 unshow_buffer (w); 3151 unshow_buffer (w);
3491 } 3152 }
3492 3153
3493 set_window_buffer (window, buffer, 1, !NILP (keep_margins)); 3154 set_window_buffer (window, buffer, 1, !NILP (keep_margins));
3494 return Qnil;
3495}
3496
3497/* If select_window is called with inhibit_point_swap non-zero it will
3498 not store point of the old selected window's buffer back into that
3499 window's pointm slot. This is needed by Fset_window_configuration to
3500 avoid that the display routine is called with selected_window set to
3501 Qnil causing a subsequent crash. */
3502 3155
3503static Lisp_Object 3156 return Qnil;
3504select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
3505{
3506 register struct window *w;
3507 register struct window *ow;
3508 struct frame *sf;
3509
3510 CHECK_LIVE_WINDOW (window);
3511
3512 w = XWINDOW (window);
3513 w->frozen_window_start_p = 0;
3514
3515 if (NILP (norecord))
3516 {
3517 ++window_select_count;
3518 XSETFASTINT (w->use_time, window_select_count);
3519 record_buffer (w->buffer);
3520 }
3521
3522 if (EQ (window, selected_window))
3523 return window;
3524
3525 sf = SELECTED_FRAME ();
3526 if (XFRAME (WINDOW_FRAME (w)) != sf)
3527 {
3528 XFRAME (WINDOW_FRAME (w))->selected_window = window;
3529 /* Use this rather than Fhandle_switch_frame
3530 so that FRAME_FOCUS_FRAME is moved appropriately as we
3531 move around in the state where a minibuffer in a separate
3532 frame is active. */
3533 Fselect_frame (WINDOW_FRAME (w), norecord);
3534 /* Fselect_frame called us back so we've done all the work already. */
3535 eassert (EQ (window, selected_window));
3536 return window;
3537 }
3538 else
3539 sf->selected_window = window;
3540
3541 /* Store the current buffer's actual point into the
3542 old selected window. It belongs to that window,
3543 and when the window is not selected, must be in the window. */
3544 if (!inhibit_point_swap)
3545 {
3546 ow = XWINDOW (selected_window);
3547 if (! NILP (ow->buffer))
3548 set_marker_both (ow->pointm, ow->buffer,
3549 BUF_PT (XBUFFER (ow->buffer)),
3550 BUF_PT_BYTE (XBUFFER (ow->buffer)));
3551 }
3552
3553 selected_window = window;
3554
3555 Fset_buffer (w->buffer);
3556
3557 XBUFFER (w->buffer)->last_selected_window = window;
3558
3559 /* Go to the point recorded in the window.
3560 This is important when the buffer is in more
3561 than one window. It also matters when
3562 redisplay_window has altered point after scrolling,
3563 because it makes the change only in the window. */
3564 {
3565 register EMACS_INT new_point = marker_position (w->pointm);
3566 if (new_point < BEGV)
3567 SET_PT (BEGV);
3568 else if (new_point > ZV)
3569 SET_PT (ZV);
3570 else
3571 SET_PT (new_point);
3572 }
3573
3574 xwidget_invalidate();
3575 windows_or_buffers_changed++;
3576 return window;
3577}
3578
3579
3580/* Note that selected_window can be nil when this is called from
3581 Fset_window_configuration. */
3582
3583DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
3584 doc: /* Select WINDOW. Most editing will apply to WINDOW's buffer.
3585If WINDOW is not already selected, make WINDOW's buffer current
3586and make WINDOW the frame's selected window. Return WINDOW.
3587Optional second arg NORECORD non-nil means do not put this buffer
3588at the front of the list of recently selected ones and do not
3589make this window the most recently selected one.
3590
3591Note that the main editor command loop selects the buffer of the
3592selected window before each command. */)
3593 (register Lisp_Object window, Lisp_Object norecord)
3594{
3595 select_window (window, norecord, 0);
3596}
3597
3598static Lisp_Object
3599select_window_norecord (Lisp_Object window)
3600{
3601 return WINDOW_LIVE_P (window)
3602 ? Fselect_window (window, Qt) : selected_window;
3603}
3604
3605static Lisp_Object
3606select_frame_norecord (Lisp_Object frame)
3607{
3608 return FRAME_LIVE_P (XFRAME (frame))
3609 ? Fselect_frame (frame, Qt) : selected_frame;
3610} 3157}
3611 3158
3612Lisp_Object 3159static Lisp_Object
3613display_buffer (Lisp_Object buffer, Lisp_Object not_this_window_p, Lisp_Object override_frame) 3160display_buffer (Lisp_Object buffer, Lisp_Object not_this_window_p, Lisp_Object override_frame)
3614{ 3161{
3615 return call3 (Qdisplay_buffer, buffer, not_this_window_p, override_frame); 3162 return call3 (Qdisplay_buffer, buffer, not_this_window_p, override_frame);
@@ -3643,7 +3190,7 @@ displaying that buffer. */)
3643 3190
3644 if (STRINGP (object)) 3191 if (STRINGP (object))
3645 object = Fget_buffer (object); 3192 object = Fget_buffer (object);
3646 if (BUFFERP (object) && !NILP (XBUFFER (object)->name)) 3193 if (BUFFERP (object) && !NILP (BVAR (XBUFFER (object), name)))
3647 { 3194 {
3648 /* Walk all windows looking for buffer, and force update 3195 /* Walk all windows looking for buffer, and force update
3649 of each of those windows. */ 3196 of each of those windows. */
@@ -3666,23 +3213,23 @@ temp_output_buffer_show (register Lisp_Object buf)
3666 register Lisp_Object window; 3213 register Lisp_Object window;
3667 register struct window *w; 3214 register struct window *w;
3668 3215
3669 XBUFFER (buf)->directory = current_buffer->directory; 3216 BVAR (XBUFFER (buf), directory) = BVAR (current_buffer, directory);
3670 3217
3671 Fset_buffer (buf); 3218 Fset_buffer (buf);
3672 BUF_SAVE_MODIFF (XBUFFER (buf)) = MODIFF; 3219 BUF_SAVE_MODIFF (XBUFFER (buf)) = MODIFF;
3673 BEGV = BEG; 3220 BEGV = BEG;
3674 ZV = Z; 3221 ZV = Z;
3675 SET_PT (BEG); 3222 SET_PT (BEG);
3676#if 0 /* rms: there should be no reason for this. */
3677 XBUFFER (buf)->prevent_redisplay_optimizations_p = 1;
3678#endif
3679 set_buffer_internal (old); 3223 set_buffer_internal (old);
3680 3224
3681 if (!NILP (Vtemp_buffer_show_function)) 3225 if (!NILP (Vtemp_buffer_show_function))
3682 call1 (Vtemp_buffer_show_function, buf); 3226 call1 (Vtemp_buffer_show_function, buf);
3683 else 3227 else
3684 { 3228 {
3685 window = display_buffer (buf, Qnil, Qnil); 3229 window = display_buffer (buf, Vtemp_buffer_show_specifiers, Qnil);
3230 /* Reset Vtemp_buffer_show_specifiers immediately so it won't
3231 affect subsequent calls. */
3232 Vtemp_buffer_show_specifiers = Qnil;
3686 3233
3687 if (!EQ (XWINDOW (window)->frame, selected_frame)) 3234 if (!EQ (XWINDOW (window)->frame, selected_frame))
3688 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window))); 3235 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
@@ -3695,34 +3242,43 @@ temp_output_buffer_show (register Lisp_Object buf)
3695 3242
3696 /* Run temp-buffer-show-hook, with the chosen window selected 3243 /* Run temp-buffer-show-hook, with the chosen window selected
3697 and its buffer current. */ 3244 and its buffer current. */
3698 3245 {
3699 if (!NILP (Vrun_hooks) 3246 int count = SPECPDL_INDEX ();
3700 && !NILP (Fboundp (Qtemp_buffer_show_hook)) 3247 Lisp_Object prev_window, prev_buffer;
3701 && !NILP (Fsymbol_value (Qtemp_buffer_show_hook))) 3248 prev_window = selected_window;
3702 { 3249 XSETBUFFER (prev_buffer, old);
3703 int count = SPECPDL_INDEX (); 3250
3704 Lisp_Object prev_window, prev_buffer; 3251 /* Select the window that was chosen, for running the hook.
3705 prev_window = selected_window; 3252 Note: Both Fselect_window and select_window_norecord may
3706 XSETBUFFER (prev_buffer, old); 3253 set-buffer to the buffer displayed in the window,
3707 3254 so we need to save the current buffer. --stef */
3708 /* Select the window that was chosen, for running the hook. 3255 record_unwind_protect (Fset_buffer, prev_buffer);
3709 Note: Both Fselect_window and select_window_norecord may 3256 record_unwind_protect (select_window_norecord, prev_window);
3710 set-buffer to the buffer displayed in the window, 3257 Fselect_window (window, Qt);
3711 so we need to save the current buffer. --stef */ 3258 Fset_buffer (w->buffer);
3712 record_unwind_protect (Fset_buffer, prev_buffer); 3259 Frun_hooks (1, &Qtemp_buffer_show_hook);
3713 record_unwind_protect (select_window_norecord, prev_window); 3260 unbind_to (count, Qnil);
3714 Fselect_window (window, Qt); 3261 }
3715 Fset_buffer (w->buffer);
3716 call1 (Vrun_hooks, Qtemp_buffer_show_hook);
3717 unbind_to (count, Qnil);
3718 }
3719 } 3262 }
3720} 3263}
3264
3265DEFUN ("internal-temp-output-buffer-show",
3266 Ftemp_output_buffer_show, Stemp_output_buffer_show,
3267 1, 1, 0,
3268 doc: /* Internal function for `with-output-to-temp-buffer''. */)
3269 (Lisp_Object buf)
3270{
3271 temp_output_buffer_show (buf);
3272 return Qnil;
3273}
3721 3274
3275/* Make new window, have it replace WINDOW in window-tree, and make
3276 WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only
3277 horizontal child). */
3722static void 3278static void
3723make_dummy_parent (Lisp_Object window) 3279make_parent_window (Lisp_Object window, int horflag)
3724{ 3280{
3725 Lisp_Object new; 3281 Lisp_Object parent;
3726 register struct window *o, *p; 3282 register struct window *o, *p;
3727 int i; 3283 int i;
3728 3284
@@ -3730,892 +3286,892 @@ make_dummy_parent (Lisp_Object window)
3730 p = allocate_window (); 3286 p = allocate_window ();
3731 for (i = 0; i < VECSIZE (struct window); ++i) 3287 for (i = 0; i < VECSIZE (struct window); ++i)
3732 ((struct Lisp_Vector *) p)->contents[i] 3288 ((struct Lisp_Vector *) p)->contents[i]
3733 = ((struct Lisp_Vector *)o)->contents[i]; 3289 = ((struct Lisp_Vector *) o)->contents[i];
3734 XSETWINDOW (new, p); 3290 XSETWINDOW (parent, p);
3735 3291
3736 ++sequence_number; 3292 ++sequence_number;
3737 XSETFASTINT (p->sequence_number, sequence_number); 3293 XSETFASTINT (p->sequence_number, sequence_number);
3294 XSETFASTINT (p->clone_number, sequence_number);
3738 3295
3739 /* Put new into window structure in place of window */ 3296 replace_window (window, parent, 1);
3740 replace_window (window, new);
3741 3297
3742 o->next = Qnil; 3298 o->next = Qnil;
3743 o->prev = Qnil; 3299 o->prev = Qnil;
3744 o->vchild = Qnil; 3300 o->parent = parent;
3745 o->hchild = Qnil;
3746 o->parent = new;
3747 3301
3302 p->hchild = horflag ? window : Qnil;
3303 p->vchild = horflag ? Qnil : window;
3748 p->start = Qnil; 3304 p->start = Qnil;
3749 p->pointm = Qnil; 3305 p->pointm = Qnil;
3750 p->buffer = Qnil; 3306 p->buffer = Qnil;
3307 p->splits = Qnil;
3308 p->nest = Qnil;
3309 p->window_parameters = Qnil;
3751} 3310}
3752 3311
3753DEFUN ("split-window", Fsplit_window, Ssplit_window, 0, 3, "", 3312/* Make new window from scratch. */
3754 doc: /* Split WINDOW, putting SIZE lines in the first of the pair. 3313Lisp_Object
3755WINDOW defaults to selected one and SIZE to half its size. 3314make_window (void)
3756If optional third arg HORIZONTAL is non-nil, split side by side and put
3757SIZE columns in the first of the pair. In that case, SIZE includes that
3758window's scroll bar, or the divider column to its right.
3759Interactively, all arguments are nil.
3760Returns the newly created window (which is the lower or rightmost one).
3761The upper or leftmost window is the original one, and remains selected
3762if it was selected before.
3763
3764See Info node `(elisp)Splitting Windows' for more details and examples. */)
3765 (Lisp_Object window, Lisp_Object size, Lisp_Object horizontal)
3766{ 3315{
3767 register Lisp_Object new; 3316 Lisp_Object window;
3768 register struct window *o, *p; 3317 register struct window *w;
3769 FRAME_PTR fo;
3770 register int size_int;
3771
3772 if (NILP (window))
3773 window = selected_window;
3774 else
3775 CHECK_LIVE_WINDOW (window);
3776
3777 o = XWINDOW (window);
3778 fo = XFRAME (WINDOW_FRAME (o));
3779
3780 if (NILP (size))
3781 {
3782 if (!NILP (horizontal))
3783 /* Calculate the size of the left-hand window, by dividing
3784 the usable space in columns by two.
3785 We round up, since the left-hand window may include
3786 a dividing line, while the right-hand may not. */
3787 size_int = (XFASTINT (o->total_cols) + 1) >> 1;
3788 else
3789 size_int = XFASTINT (o->total_lines) >> 1;
3790 }
3791 else
3792 {
3793 CHECK_NUMBER (size);
3794 size_int = XINT (size);
3795 }
3796
3797 if (MINI_WINDOW_P (o))
3798 error ("Attempt to split minibuffer window");
3799 else if (window_fixed_size_p (o, !NILP (horizontal), 0))
3800 error ("Attempt to split fixed-size window");
3801
3802 if (NILP (horizontal))
3803 {
3804 int window_safe_height = window_min_size_2 (o, 0, 0);
3805
3806 if (size_int < window_safe_height)
3807 error ("Window height %d too small (after splitting)", size_int);
3808 if (size_int + window_safe_height > XFASTINT (o->total_lines))
3809 error ("Window height %d too small (after splitting)",
3810 XFASTINT (o->total_lines) - size_int);
3811 if (NILP (o->parent)
3812 || NILP (XWINDOW (o->parent)->vchild))
3813 {
3814 make_dummy_parent (window);
3815 new = o->parent;
3816 XWINDOW (new)->vchild = window;
3817 }
3818 }
3819 else
3820 {
3821 int window_safe_width = window_min_size_2 (o, 1, 0);
3822
3823 if (size_int < window_safe_width)
3824 error ("Window width %d too small (after splitting)", size_int);
3825 if (size_int + window_safe_width > XFASTINT (o->total_cols))
3826 error ("Window width %d too small (after splitting)",
3827 XFASTINT (o->total_cols) - size_int);
3828 if (NILP (o->parent)
3829 || NILP (XWINDOW (o->parent)->hchild))
3830 {
3831 make_dummy_parent (window);
3832 new = o->parent;
3833 XWINDOW (new)->hchild = window;
3834 }
3835 }
3836
3837 /* Now we know that window's parent is a vertical combination
3838 if we are dividing vertically, or a horizontal combination
3839 if we are making side-by-side windows */
3840
3841 windows_or_buffers_changed++;
3842 FRAME_WINDOW_SIZES_CHANGED (fo) = 1;
3843 new = make_window ();
3844 p = XWINDOW (new);
3845
3846 p->frame = o->frame;
3847 p->next = o->next;
3848 if (!NILP (p->next))
3849 XWINDOW (p->next)->prev = new;
3850 p->prev = window;
3851 o->next = new;
3852 p->parent = o->parent;
3853 p->buffer = Qt;
3854 p->window_end_valid = Qnil;
3855 memset (&p->last_cursor, 0, sizeof p->last_cursor);
3856
3857 /* Duplicate special geometry settings. */
3858
3859 p->left_margin_cols = o->left_margin_cols;
3860 p->right_margin_cols = o->right_margin_cols;
3861 p->left_fringe_width = o->left_fringe_width;
3862 p->right_fringe_width = o->right_fringe_width;
3863 p->fringes_outside_margins = o->fringes_outside_margins;
3864 p->scroll_bar_width = o->scroll_bar_width;
3865 p->vertical_scroll_bar_type = o->vertical_scroll_bar_type;
3866
3867 /* Apportion the available frame space among the two new windows */
3868
3869 if (!NILP (horizontal))
3870 {
3871 p->total_lines = o->total_lines;
3872 p->top_line = o->top_line;
3873 XSETFASTINT (p->total_cols, XFASTINT (o->total_cols) - size_int);
3874 XSETFASTINT (o->total_cols, size_int);
3875 XSETFASTINT (p->left_col, XFASTINT (o->left_col) + size_int);
3876 adjust_window_margins (p);
3877 adjust_window_margins (o);
3878 }
3879 else
3880 {
3881 p->left_col = o->left_col;
3882 p->total_cols = o->total_cols;
3883 XSETFASTINT (p->total_lines, XFASTINT (o->total_lines) - size_int);
3884 XSETFASTINT (o->total_lines, size_int);
3885 XSETFASTINT (p->top_line, XFASTINT (o->top_line) + size_int);
3886 }
3887
3888 /* Adjust glyph matrices. */
3889 adjust_glyphs (fo);
3890 3318
3891 Fset_window_buffer (new, o->buffer, Qt); 3319 w = allocate_window ();
3892 return new; 3320 /* Initialize all Lisp data. */
3321 w->frame = w->mini_p = Qnil;
3322 w->next = w->prev = w->hchild = w->vchild = w->parent = Qnil;
3323 XSETFASTINT (w->left_col, 0);
3324 XSETFASTINT (w->top_line, 0);
3325 XSETFASTINT (w->total_lines, 0);
3326 XSETFASTINT (w->total_cols, 0);
3327 w->normal_lines = make_float (1.0);
3328 w->normal_cols = make_float (1.0);
3329 XSETFASTINT (w->new_total, 0);
3330 XSETFASTINT (w->new_normal, 0);
3331 w->buffer = Qnil;
3332 w->start = Fmake_marker ();
3333 w->pointm = Fmake_marker ();
3334 w->force_start = w->optional_new_start = Qnil;
3335 XSETFASTINT (w->hscroll, 0);
3336 XSETFASTINT (w->min_hscroll, 0);
3337 XSETFASTINT (w->use_time, 0);
3338 ++sequence_number;
3339 XSETFASTINT (w->sequence_number, sequence_number);
3340 XSETFASTINT (w->clone_number, sequence_number);
3341 w->temslot = w->last_modified = w->last_overlay_modified = Qnil;
3342 XSETFASTINT (w->last_point, 0);
3343 w->last_had_star = w->vertical_scroll_bar = Qnil;
3344 w->left_margin_cols = w->right_margin_cols = Qnil;
3345 w->left_fringe_width = w->right_fringe_width = Qnil;
3346 w->fringes_outside_margins = Qnil;
3347 w->scroll_bar_width = Qnil;
3348 w->vertical_scroll_bar_type = Qt;
3349 w->last_mark_x = w->last_mark_y = Qnil;
3350 XSETFASTINT (w->window_end_pos, 0);
3351 XSETFASTINT (w->window_end_vpos, 0);
3352 w->window_end_valid = w->update_mode_line = Qnil;
3353 w->start_at_line_beg = w->display_table = w->dedicated = Qnil;
3354 w->base_line_number = w->base_line_pos = w->region_showing = Qnil;
3355 w->column_number_displayed = w->redisplay_end_trigger = Qnil;
3356 w->splits = w->nest = w->window_parameters = Qnil;
3357 w->prev_buffers = w->next_buffers = Qnil;
3358 /* Initialize non-Lisp data. */
3359 w->desired_matrix = w->current_matrix = 0;
3360 w->nrows_scale_factor = w->ncols_scale_factor = 1;
3361 memset (&w->cursor, 0, sizeof (w->cursor));
3362 memset (&w->last_cursor, 0, sizeof (w->last_cursor));
3363 memset (&w->phys_cursor, 0, sizeof (w->phys_cursor));
3364 w->phys_cursor_type = -1;
3365 w->phys_cursor_width = -1;
3366 w->last_cursor_off_p = w->cursor_off_p = 0;
3367 w->must_be_updated_p = 0;
3368 w->pseudo_window_p = 0;
3369 w->frozen_window_start_p = 0;
3370 w->vscroll = 0;
3371 /* Reset window_list. */
3372 Vwindow_list = Qnil;
3373 /* Return window. */
3374 XSETWINDOW (window, w);
3375 return window;
3893} 3376}
3894 3377
3895DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p", 3378DEFUN ("set-window-new-total", Fset_window_new_total, Sset_window_new_total, 2, 3, 0,
3896 doc: /* Make selected window SIZE lines taller. 3379 doc: /* Set new total size of WINDOW to SIZE.
3897Interactively, if no argument is given, make the selected window one 3380Return SIZE.
3898line taller. If optional argument HORIZONTAL is non-nil, make selected 3381
3899window wider by SIZE columns. If SIZE is negative, shrink the window by 3382Optional argument ADD non-nil means add SIZE to the new total size of
3900-SIZE lines or columns. Return nil. 3383WINDOW and return the sum.
3901 3384
3902This function can delete windows if they get too small. The size of 3385Note: This function does not operate on any subwindows of WINDOW. */)
3903fixed size windows is not altered by this function. */) 3386 (Lisp_Object window, Lisp_Object size, Lisp_Object add)
3904 (Lisp_Object size, Lisp_Object horizontal)
3905{ 3387{
3906 CHECK_NUMBER (size); 3388 struct window *w = decode_any_window (window);
3907 enlarge_window (selected_window, XINT (size), !NILP (horizontal));
3908 3389
3909 run_window_configuration_change_hook (SELECTED_FRAME ()); 3390 CHECK_NUMBER (size);
3391 if (NILP (add))
3392 XSETINT (w->new_total, XINT (size));
3393 else
3394 XSETINT (w->new_total, XINT (w->new_total) + XINT (size));
3910 3395
3911 return Qnil; 3396 return w->new_total;
3912} 3397}
3913 3398
3914DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p", 3399DEFUN ("set-window-new-normal", Fset_window_new_normal, Sset_window_new_normal, 1, 2, 0,
3915 doc: /* Make selected window SIZE lines smaller. 3400 doc: /* Set new normal size of WINDOW to SIZE.
3916Interactively, if no argument is given, make the selected window one 3401Return SIZE.
3917line smaller. If optional argument HORIZONTAL is non-nil, make the
3918window narrower by SIZE columns. If SIZE is negative, enlarge selected
3919window by -SIZE lines or columns. Return nil.
3920 3402
3921This function can delete windows if they get too small. The size of 3403Note: This function does not operate on any subwindows of WINDOW. */)
3922fixed size windows is not altered by this function. */) 3404 (Lisp_Object window, Lisp_Object size)
3923 (Lisp_Object size, Lisp_Object horizontal)
3924{ 3405{
3925 CHECK_NUMBER (size); 3406 struct window *w = decode_any_window (window);
3926 enlarge_window (selected_window, -XINT (size), !NILP (horizontal));
3927 3407
3928 run_window_configuration_change_hook (SELECTED_FRAME ()); 3408 w->new_normal = size;
3929 3409 return w->new_normal;
3930 return Qnil;
3931} 3410}
3932 3411
3933static int 3412/* Return 1 if setting w->total_lines (w->total_cols if HORFLAG is
3934window_height (Lisp_Object window) 3413 non-zero) to w->new_total would result in correct heights (widths)
3935{ 3414 for window W and recursively all subwindows of W.
3936 register struct window *p = XWINDOW (window);
3937 return WINDOW_TOTAL_LINES (p);
3938}
3939 3415
3416 Note: This function does not check any of `window-fixed-size-p',
3417 `window-min-height' or `window-min-width'. It does check that window
3418 sizes do not drop below one line (two columns). */
3940static int 3419static int
3941window_width (Lisp_Object window) 3420resize_window_check (struct window *w, int horflag)
3942{ 3421{
3943 register struct window *p = XWINDOW (window); 3422 struct window *c;
3944 return WINDOW_TOTAL_COLS (p);
3945}
3946
3947
3948#define CURBEG(w) \
3949 *(horiz_flag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
3950
3951#define CURSIZE(w) \
3952 *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
3953
3954
3955/* Enlarge WINDOW by DELTA. HORIZ_FLAG nonzero means enlarge it
3956 horizontally; zero means do it vertically.
3957
3958 Siblings of the selected window are resized to fulfill the size
3959 request. If they become too small in the process, they may be
3960 deleted. */
3961 3423
3962static void 3424 if (!NILP (w->vchild))
3963enlarge_window (Lisp_Object window, int delta, int horiz_flag) 3425 /* W is a vertical combination. */
3964{
3965 Lisp_Object parent, next, prev;
3966 struct window *p;
3967 Lisp_Object *sizep;
3968 int maximum;
3969 int (*sizefun) (Lisp_Object)
3970 = horiz_flag ? window_width : window_height;
3971 void (*setsizefun) (Lisp_Object, int, int)
3972 = (horiz_flag ? set_window_width : set_window_height);
3973
3974 /* Give up if this window cannot be resized. */
3975 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
3976 error ("Window is not resizable");
3977
3978 /* Find the parent of the selected window. */
3979 while (1)
3980 { 3426 {
3981 p = XWINDOW (window); 3427 c = XWINDOW (w->vchild);
3982 parent = p->parent; 3428 if (horflag)
3983 3429 /* All subwindows of W must have the same width as W. */
3984 if (NILP (parent))
3985 { 3430 {
3986 if (horiz_flag) 3431 while (c)
3987 error ("No other window to side of this one"); 3432 {
3988 break; 3433 if ((XINT (c->new_total) != XINT (w->new_total))
3434 || !resize_window_check (c, horflag))
3435 return 0;
3436 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3437 }
3438 return 1;
3439 }
3440 else
3441 /* The sum of the heights of the subwindows of W must equal W's
3442 height. */
3443 {
3444 int sum_of_sizes = 0;
3445 while (c)
3446 {
3447 if (!resize_window_check (c, horflag))
3448 return 0;
3449 sum_of_sizes = sum_of_sizes + XINT (c->new_total);
3450 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3451 }
3452 return (sum_of_sizes == XINT (w->new_total));
3989 } 3453 }
3990
3991 if (horiz_flag
3992 ? !NILP (XWINDOW (parent)->hchild)
3993 : !NILP (XWINDOW (parent)->vchild))
3994 break;
3995
3996 window = parent;
3997 }
3998
3999 sizep = &CURSIZE (window);
4000
4001 {
4002 register int maxdelta;
4003
4004 /* Compute the maximum size increment this window can have. */
4005
4006 maxdelta = (!NILP (parent) ? (*sizefun) (parent) - XINT (*sizep)
4007 /* This is a main window followed by a minibuffer. */
4008 : !NILP (p->next) ? ((*sizefun) (p->next)
4009 - window_min_size (XWINDOW (p->next),
4010 horiz_flag, 0, 0, 0))
4011 /* This is a minibuffer following a main window. */
4012 : !NILP (p->prev) ? ((*sizefun) (p->prev)
4013 - window_min_size (XWINDOW (p->prev),
4014 horiz_flag, 0, 0, 0))
4015 /* This is a frame with only one window, a minibuffer-only
4016 or a minibufferless frame. */
4017 : (delta = 0));
4018
4019 if (delta > maxdelta)
4020 /* This case traps trying to make the minibuffer
4021 the full frame, or make the only window aside from the
4022 minibuffer the full frame. */
4023 delta = maxdelta;
4024 }
4025
4026 if (XINT (*sizep) + delta < window_min_size (XWINDOW (window),
4027 horiz_flag, 0, 0, 0))
4028 {
4029 delete_window (window);
4030 return;
4031 } 3454 }
4032 3455 else if (!NILP (w->hchild))
4033 if (delta == 0) 3456 /* W is a horizontal combination. */
4034 return;
4035
4036 /* Find the total we can get from other siblings without deleting them. */
4037 maximum = 0;
4038 for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next)
4039 maximum += (*sizefun) (next) - window_min_size (XWINDOW (next),
4040 horiz_flag, 0, 0, 0);
4041 for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev)
4042 maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
4043 horiz_flag, 0, 0, 0);
4044
4045 /* If we can get it all from them without deleting them, do so. */
4046 if (delta <= maximum)
4047 { 3457 {
4048 Lisp_Object first_unaffected; 3458 c = XWINDOW (w->hchild);
4049 Lisp_Object first_affected; 3459 if (horflag)
4050 int fixed_p; 3460 /* The sum of the widths of the subwindows of W must equal W's
4051 3461 width. */
4052 next = p->next;
4053 prev = p->prev;
4054 first_affected = window;
4055 /* Look at one sibling at a time,
4056 moving away from this window in both directions alternately,
4057 and take as much as we can get without deleting that sibling. */
4058 while (delta != 0
4059 && (!NILP (next) || !NILP (prev)))
4060 { 3462 {
4061 if (! NILP (next)) 3463 int sum_of_sizes = 0;
3464 while (c)
4062 { 3465 {
4063 int this_one = ((*sizefun) (next) 3466 if (!resize_window_check (c, horflag))
4064 - window_min_size (XWINDOW (next), horiz_flag, 3467 return 0;
4065 0, 0, &fixed_p)); 3468 sum_of_sizes = sum_of_sizes + XINT (c->new_total);
4066 if (!fixed_p) 3469 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4067 {
4068 if (this_one > delta)
4069 this_one = delta;
4070
4071 (*setsizefun) (next, (*sizefun) (next) - this_one, 0);
4072 (*setsizefun) (window, XINT (*sizep) + this_one, 0);
4073
4074 delta -= this_one;
4075 }
4076
4077 next = XWINDOW (next)->next;
4078 } 3470 }
4079 3471 return (sum_of_sizes == XINT (w->new_total));
4080 if (delta == 0) 3472 }
4081 break; 3473 else
4082 3474 /* All subwindows of W must have the same height as W. */
4083 if (! NILP (prev)) 3475 {
3476 while (c)
4084 { 3477 {
4085 int this_one = ((*sizefun) (prev) 3478 if ((XINT (c->new_total) != XINT (w->new_total))
4086 - window_min_size (XWINDOW (prev), horiz_flag, 3479 || !resize_window_check (c, horflag))
4087 0, 0, &fixed_p)); 3480 return 0;
4088 if (!fixed_p) 3481 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4089 {
4090 if (this_one > delta)
4091 this_one = delta;
4092
4093 first_affected = prev;
4094
4095 (*setsizefun) (prev, (*sizefun) (prev) - this_one, 0);
4096 (*setsizefun) (window, XINT (*sizep) + this_one, 0);
4097
4098 delta -= this_one;
4099 }
4100
4101 prev = XWINDOW (prev)->prev;
4102 } 3482 }
3483 return 1;
4103 } 3484 }
3485 }
3486 else
3487 /* A leaf window. Make sure it's not too small. The following
3488 hardcodes the values of `window-safe-min-width' (2) and
3489 `window-safe-min-height' (1) which are defined in window.el. */
3490 return XINT (w->new_total) >= (horflag ? 2 : 1);
3491}
4104 3492
4105 xassert (delta == 0); 3493/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to
3494 w->new_total for window W and recursively all subwindows of W. Also
3495 calculate and assign the new vertical (horizontal) start positions of
3496 each of these windows.
4106 3497
4107 /* Now recalculate the edge positions of all the windows affected, 3498 This function does not perform any error checks. Make sure you have
4108 based on the new sizes. */ 3499 run resize_window_check on W before applying this function. */
4109 first_unaffected = next; 3500static void
4110 prev = first_affected; 3501resize_window_apply (struct window *w, int horflag)
4111 for (next = XWINDOW (prev)->next; ! EQ (next, first_unaffected); 3502{
4112 prev = next, next = XWINDOW (next)->next) 3503 struct window *c;
4113 { 3504 int pos;
4114 XSETINT (CURBEG (next), XINT (CURBEG (prev)) + (*sizefun) (prev)); 3505
4115 /* This does not change size of NEXT, 3506 /* Note: Assigning new_normal requires that the new total size of the
4116 but it propagates the new top edge to its children */ 3507 parent window has been set *before*. */
4117 (*setsizefun) (next, (*sizefun) (next), 0); 3508 if (horflag)
4118 } 3509 {
3510 w->total_cols = w->new_total;
3511 if (NUMBERP (w->new_normal))
3512 w->normal_cols = w->new_normal;
3513
3514 pos = XINT (w->left_col);
4119 } 3515 }
4120 else 3516 else
4121 { 3517 {
4122 register int delta1; 3518 w->total_lines = w->new_total;
4123 register int opht = (*sizefun) (parent); 3519 if (NUMBERP (w->new_normal))
4124 3520 w->normal_lines = w->new_normal;
4125 if (opht <= XINT (*sizep) + delta)
4126 {
4127 /* If trying to grow this window to or beyond size of the parent,
4128 just delete all the sibling windows. */
4129 Lisp_Object start, tem, next;
4130 3521
4131 start = XWINDOW (parent)->vchild; 3522 pos = XINT (w->top_line);
4132 if (NILP (start)) 3523 }
4133 start = XWINDOW (parent)->hchild;
4134
4135 /* Delete any siblings that come after WINDOW. */
4136 tem = XWINDOW (window)->next;
4137 while (! NILP (tem))
4138 {
4139 next = XWINDOW (tem)->next;
4140 delete_window (tem);
4141 tem = next;
4142 }
4143 3524
4144 /* Delete any siblings that come after WINDOW. 3525 if (!NILP (w->vchild))
4145 Note that if START is not WINDOW, then WINDOW still 3526 /* W is a vertical combination. */
4146 has siblings, so WINDOW has not yet replaced its parent. */ 3527 {
4147 tem = start; 3528 c = XWINDOW (w->vchild);
4148 while (! EQ (tem, window)) 3529 while (c)
4149 { 3530 {
4150 next = XWINDOW (tem)->next; 3531 if (horflag)
4151 delete_window (tem); 3532 XSETFASTINT (c->left_col, pos);
4152 tem = next; 3533 else
4153 } 3534 XSETFASTINT (c->top_line, pos);
3535 resize_window_apply (c, horflag);
3536 if (!horflag)
3537 pos = pos + XINT (c->total_lines);
3538 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4154 } 3539 }
4155 else 3540 }
3541 else if (!NILP (w->hchild))
3542 /* W is a horizontal combination. */
3543 {
3544 c = XWINDOW (w->hchild);
3545 while (c)
4156 { 3546 {
4157 /* Otherwise, make delta1 just right so that if we add 3547 if (horflag)
4158 delta1 lines to this window and to the parent, and then 3548 XSETFASTINT (c->left_col, pos);
4159 shrink the parent back to its original size, the new 3549 else
4160 proportional size of this window will increase by delta. 3550 XSETFASTINT (c->top_line, pos);
4161 3551 resize_window_apply (c, horflag);
4162 The function size_window will compute the new height h' 3552 if (horflag)
4163 of the window from delta1 as: 3553 pos = pos + XINT (c->total_cols);
4164 3554 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4165 e = delta1/n
4166 x = delta1 - delta1/n * n for the 1st resizable child
4167 h' = h + e + x
4168
4169 where n is the number of children that can be resized.
4170 We can ignore x by choosing a delta1 that is a multiple of
4171 n. We want the height of this window to come out as
4172
4173 h' = h + delta
4174
4175 So, delta1 must be
4176
4177 h + e = h + delta
4178 delta1/n = delta
4179 delta1 = n * delta.
4180
4181 The number of children n equals the number of resizable
4182 children of this window + 1 because we know window itself
4183 is resizable (otherwise we would have signaled an error).
4184
4185 This reasoning is not correct when other windows become too
4186 small and shrink_windows refuses to delete them. Below we
4187 use resize_proportionally to work around this problem. */
4188
4189 struct window *w = XWINDOW (window);
4190 Lisp_Object s;
4191 int n = 1;
4192
4193 for (s = w->next; WINDOWP (s); s = XWINDOW (s)->next)
4194 if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
4195 ++n;
4196 for (s = w->prev; WINDOWP (s); s = XWINDOW (s)->prev)
4197 if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
4198 ++n;
4199
4200 delta1 = n * delta;
4201
4202 /* Add delta1 lines or columns to this window, and to the parent,
4203 keeping things consistent while not affecting siblings. */
4204 XSETINT (CURSIZE (parent), opht + delta1);
4205 (*setsizefun) (window, XINT (*sizep) + delta1, 0);
4206
4207 /* Squeeze out delta1 lines or columns from our parent,
4208 shrinking this window and siblings proportionately. This
4209 brings parent back to correct size. Delta1 was calculated
4210 so this makes this window the desired size, taking it all
4211 out of the siblings.
4212
4213 Temporarily set resize_proportionally to Qt to assure that,
4214 if necessary, shrink_windows deletes smaller windows rather
4215 than shrink this window. */
4216 w->resize_proportionally = Qt;
4217 (*setsizefun) (parent, opht, 0);
4218 w->resize_proportionally = Qnil;
4219 } 3555 }
4220 } 3556 }
4221 3557
4222 XSETFASTINT (p->last_modified, 0); 3558 /* Clear out some redisplay caches. */
4223 XSETFASTINT (p->last_overlay_modified, 0); 3559 XSETFASTINT (w->last_modified, 0);
4224 3560 XSETFASTINT (w->last_overlay_modified, 0);
4225 /* Adjust glyph matrices. */
4226 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window))));
4227} 3561}
4228 3562
4229 3563
4230/* Adjust the size of WINDOW by DELTA, moving only its trailing edge. 3564DEFUN ("resize-window-apply", Fresize_window_apply, Sresize_window_apply, 1, 2, 0,
4231 HORIZ_FLAG nonzero means adjust the width, moving the right edge. 3565 doc: /* Apply requested size values for window-tree of FRAME.
4232 zero means adjust the height, moving the bottom edge. 3566Optional argument HORIZONTAL omitted or nil means apply requested height
3567values. HORIZONTAL non-nil means apply requested width values.
4233 3568
4234 Following siblings of the selected window are resized to fulfill 3569This function checks whether the requested values sum up to a valid
4235 the size request. If they become too small in the process, they 3570window layout, recursively assigns the new sizes of all subwindows and
4236 are not deleted; instead, we signal an error. */ 3571calculates and assigns the new start positions of these windows.
4237 3572
4238static void 3573Note: This function does not check any of `window-fixed-size-p',
4239adjust_window_trailing_edge (Lisp_Object window, int delta, int horiz_flag) 3574`window-min-height' or `window-min-width'. All these checks have to
3575be applied on the Elisp level. */)
3576 (Lisp_Object frame, Lisp_Object horizontal)
4240{ 3577{
4241 Lisp_Object parent, child; 3578 struct frame *f;
4242 struct window *p; 3579 struct window *r;
4243 Lisp_Object old_config = Fcurrent_window_configuration (Qnil); 3580 int horflag = !NILP (horizontal);
4244 int delcount = window_deletion_count;
4245 3581
4246 CHECK_WINDOW (window); 3582 if (NILP (frame))
3583 frame = selected_frame;
3584 CHECK_LIVE_FRAME (frame);
4247 3585
4248 /* Give up if this window cannot be resized. */ 3586 f = XFRAME (frame);
4249 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1)) 3587 r = XWINDOW (FRAME_ROOT_WINDOW (f));
4250 error ("Window is not resizable");
4251 3588
4252 while (1) 3589 if (!resize_window_check (r, horflag)
4253 { 3590 || ! EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
4254 Lisp_Object first_parallel = Qnil; 3591 return Qnil;
4255 3592
4256 if (NILP (window)) 3593 BLOCK_INPUT;
4257 { 3594 resize_window_apply (r, horflag);
4258 /* This happens if WINDOW on the previous iteration was
4259 at top level of the window tree. */
4260 Fset_window_configuration (old_config);
4261 error ("Specified window edge is fixed");
4262 }
4263 3595
4264 p = XWINDOW (window); 3596 windows_or_buffers_changed++;
4265 parent = p->parent; 3597 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4266 3598
4267 /* See if this level has windows in parallel in the specified 3599 adjust_glyphs (f);
4268 direction. If so, set FIRST_PARALLEL to the first one. */ 3600 UNBLOCK_INPUT;
4269 if (horiz_flag)
4270 {
4271 if (! NILP (parent) && !NILP (XWINDOW (parent)->vchild))
4272 first_parallel = XWINDOW (parent)->vchild;
4273 else if (NILP (parent) && !NILP (p->next))
4274 {
4275 /* Handle the vertical chain of main window and minibuffer
4276 which has no parent. */
4277 first_parallel = window;
4278 while (! NILP (XWINDOW (first_parallel)->prev))
4279 first_parallel = XWINDOW (first_parallel)->prev;
4280 }
4281 }
4282 else
4283 {
4284 if (! NILP (parent) && !NILP (XWINDOW (parent)->hchild))
4285 first_parallel = XWINDOW (parent)->hchild;
4286 }
4287 3601
4288 /* If this level's succession is in the desired dimension, 3602 run_window_configuration_change_hook (f);
4289 and this window is the last one, and there is no higher level,
4290 its trailing edge is fixed. */
4291 if (NILP (XWINDOW (window)->next) && NILP (first_parallel)
4292 && NILP (parent))
4293 {
4294 Fset_window_configuration (old_config);
4295 error ("Specified window edge is fixed");
4296 }
4297 3603
4298 /* Don't make this window too small. */ 3604 return Qt;
4299 if (XINT (CURSIZE (window)) + delta 3605}
4300 < window_min_size_2 (XWINDOW (window), horiz_flag, 0))
4301 {
4302 Fset_window_configuration (old_config);
4303 error ("Cannot adjust window size as specified");
4304 }
4305 3606
4306 /* Clear out some redisplay caches. */
4307 XSETFASTINT (p->last_modified, 0);
4308 XSETFASTINT (p->last_overlay_modified, 0);
4309 3607
4310 /* Adjust this window's edge. */ 3608/* Resize frame F's windows when number of lines of F is set to SIZE.
4311 XSETINT (CURSIZE (window), 3609 HORFLAG 1 means resize windows when number of columns of F is set to
4312 XINT (CURSIZE (window)) + delta); 3610 SIZE.
4313 3611
4314 /* If this window has following siblings in the desired dimension, 3612 This function can delete all windows but the selected one in order to
4315 make them smaller, and exit the loop. 3613 satisfy the request. The result will be meaningful if and only if
3614 F's windows have meaningful sizes when you call this. */
3615void
3616resize_frame_windows (struct frame *f, int size, int horflag)
3617{
3618 Lisp_Object root = f->root_window;
3619 struct window *r = XWINDOW (root);
3620 Lisp_Object mini = f->minibuffer_window;
3621 struct window *m;
3622 /* new_size is the new size of the frame's root window. */
3623 int new_size = (horflag
3624 ? size
3625 : (size
3626 - FRAME_TOP_MARGIN (f)
3627 - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
3628 ? 1 : 0)));
3629
3630 XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
3631 if (NILP (r->vchild) && NILP (r->hchild))
3632 /* For a leaf root window just set the size. */
3633 if (horflag)
3634 XSETFASTINT (r->total_cols, new_size);
3635 else
3636 XSETFASTINT (r->total_lines, new_size);
3637 else
3638 {
3639 /* old_size is the old size of the frame's root window. */
3640 int old_size = XFASTINT (horflag ? r->total_cols : r->total_lines);
3641 Lisp_Object delta;
4316 3642
4317 (If we reach the top of the tree and can never do this, 3643 XSETINT (delta, new_size - old_size);
4318 we will fail and report an error, above.) */ 3644 /* Try a "normal" resize first. */
4319 if (NILP (first_parallel)) 3645 resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil);
3646 if (resize_window_check (r, horflag) && new_size == XINT (r->new_total))
3647 resize_window_apply (r, horflag);
3648 else
4320 { 3649 {
4321 if (!NILP (p->next)) 3650 /* Try with "reasonable" minimum sizes next. */
3651 resize_root_window (root, delta, horflag ? Qt : Qnil, Qt);
3652 if (resize_window_check (r, horflag)
3653 && new_size == XINT (r->new_total))
3654 resize_window_apply (r, horflag);
3655 else
4322 { 3656 {
4323 /* This may happen for the minibuffer. In that case 3657 /* Finally, try with "safe" minimum sizes. */
4324 the window_deletion_count check below does not work. */ 3658 resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe);
4325 if (XINT (CURSIZE (p->next)) - delta <= 0) 3659 if (resize_window_check (r, horflag)
4326 { 3660 && new_size == XINT (r->new_total))
4327 Fset_window_configuration (old_config); 3661 resize_window_apply (r, horflag);
4328 error ("Cannot adjust window size as specified"); 3662 else
4329 } 3663 {
4330 3664 /* We lost. Delete all windows but the frame's
4331 XSETINT (CURBEG (p->next), 3665 selected one. */
4332 XINT (CURBEG (p->next)) + delta); 3666 root = f->selected_window;
4333 size_window (p->next, XINT (CURSIZE (p->next)) - delta, 3667 Fdelete_other_windows_internal (root, Qnil);
4334 horiz_flag, 0, 1, 0); 3668 if (horflag)
4335 break; 3669 XSETFASTINT (XWINDOW (root)->total_cols, new_size);
3670 else
3671 XSETFASTINT (XWINDOW (root)->total_lines, new_size);
3672 }
4336 } 3673 }
4337 } 3674 }
4338 else
4339 /* Here we have a chain of parallel siblings, in the other dimension.
4340 Change the size of the other siblings. */
4341 for (child = first_parallel;
4342 ! NILP (child);
4343 child = XWINDOW (child)->next)
4344 if (! EQ (child, window))
4345 size_window (child, XINT (CURSIZE (child)) + delta,
4346 horiz_flag, 0, 0, 1);
4347
4348 window = parent;
4349 } 3675 }
4350 3676
4351 /* If we made a window so small it got deleted, 3677 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4352 we failed. Report failure. */
4353 if (delcount != window_deletion_count)
4354 { 3678 {
4355 Fset_window_configuration (old_config); 3679 m = XWINDOW (mini);
4356 error ("Cannot adjust window size as specified"); 3680 if (horflag)
3681 XSETFASTINT (m->total_cols, size);
3682 else
3683 {
3684 /* Are we sure we always want 1 line here? */
3685 XSETFASTINT (m->total_lines, 1);
3686 XSETFASTINT (m->top_line, XINT (r->top_line) + XINT (r->total_lines));
3687 }
4357 } 3688 }
4358
4359 /* Adjust glyph matrices. */
4360 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window))));
4361} 3689}
4362 3690
4363#undef CURBEG
4364#undef CURSIZE
4365
4366DEFUN ("adjust-window-trailing-edge", Fadjust_window_trailing_edge,
4367 Sadjust_window_trailing_edge, 3, 3, 0,
4368 doc: /* Adjust the bottom or right edge of WINDOW by DELTA.
4369If HORIZONTAL is non-nil, that means adjust the width, moving the right edge.
4370Otherwise, adjust the height, moving the bottom edge.
4371
4372Following siblings of the selected window are resized to fulfill
4373the size request. If they become too small in the process, they
4374are not deleted; instead, we signal an error. */)
4375 (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal)
4376{
4377 CHECK_NUMBER (delta);
4378 if (NILP (window))
4379 window = selected_window;
4380 adjust_window_trailing_edge (window, XINT (delta), !NILP (horizontal));
4381
4382 run_window_configuration_change_hook
4383 (XFRAME (WINDOW_FRAME (XWINDOW (window))));
4384 3691
4385 return Qnil; 3692DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
4386} 3693 doc: /* Split window OLD.
3694Second argument TOTAL-SIZE specifies the number of lines or columns of the
3695new window. In any case TOTAL-SIZE must be a positive integer.
4387 3696
3697Third argument SIDE nil (or `below') specifies that the new window shall
3698be located below WINDOW. SIDE `above' means the new window shall be
3699located above WINDOW. In both cases TOTAL-SIZE specifies the number of
3700lines of the new window including space reserved for the mode and/or
3701header line.
4388 3702
4389 3703SIDE t (or `right') specifies that the new window shall be located on
4390/*********************************************************************** 3704the right side of WINDOW. SIDE `left' means the new window shall be
4391 Resizing Mini-Windows 3705located on the left of WINDOW. In both cases TOTAL-SIZE specifies the
4392 ***********************************************************************/ 3706number of columns of the new window including space reserved for fringes
3707and the scrollbar or a divider column.
4393 3708
4394static void shrink_window_lowest_first (struct window *, int); 3709Fourth argument NORMAL-SIZE specifies the normal size of the new window
3710according to the SIDE argument.
4395 3711
4396enum save_restore_action 3712The new total and normal sizes of all involved windows must have been
3713set correctly. See the code of `split-window' for how this is done. */)
3714 (Lisp_Object old, Lisp_Object total_size, Lisp_Object side, Lisp_Object normal_size)
4397{ 3715{
4398 CHECK_ORIG_SIZES, 3716 /* OLD (*o) is the window we have to split. (*p) is either OLD's
4399 SAVE_ORIG_SIZES, 3717 parent window or an internal window we have to install as OLD's new
4400 RESTORE_ORIG_SIZES 3718 parent. REFERENCE (*r) must denote a live window, or is set to OLD
4401}; 3719 provided OLD is a leaf window, or to the frame's selected window.
4402 3720 NEW (*n) is the new window created with some parameters taken from
4403static int save_restore_orig_size (struct window *, 3721 REFERENCE (*r). */
4404 enum save_restore_action); 3722 register Lisp_Object new, frame, reference;
4405 3723 register struct window *o, *p, *n, *r;
4406/* Shrink windows rooted in window W to HEIGHT. Take the space needed 3724 struct frame *f;
4407 from lowest windows first. */ 3725 int horflag
3726 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */
3727 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
3728 int do_nest = 0;
3729
3730 CHECK_WINDOW (old);
3731 o = XWINDOW (old);
3732 frame = WINDOW_FRAME (o);
3733 f = XFRAME (frame);
4408 3734
4409static void 3735 CHECK_NUMBER (total_size);
4410shrink_window_lowest_first (struct window *w, int height) 3736
4411{ 3737 /* Set do_nest to 1 if we have to make a new parent window. We do
4412 struct window *c; 3738 that if either `window-nest' is non-nil, or OLD has no parent, or
4413 Lisp_Object child; 3739 OLD is ortho-combined. */
4414 int old_height; 3740 do_nest =
3741 !NILP (Vwindow_nest)
3742 || NILP (o->parent)
3743 || NILP (horflag
3744 ? (XWINDOW (o->parent)->hchild)
3745 : (XWINDOW (o->parent)->vchild));
3746
3747 /* We need a live reference window to initialize some parameters. */
3748 if (WINDOW_LIVE_P (old))
3749 /* OLD is live, use it as reference window. */
3750 reference = old;
3751 else
3752 /* Use the frame's selected window as reference window. */
3753 reference = FRAME_SELECTED_WINDOW (f);
3754 r = XWINDOW (reference);
4415 3755
4416 xassert (!MINI_WINDOW_P (w)); 3756 /* The following bugs are caught by `split-window'. */
3757 if (MINI_WINDOW_P (o))
3758 error ("Attempt to split minibuffer window");
3759 else if (XINT (total_size) < (horflag ? 2 : 1))
3760 error ("Size of new window too small (after split)");
3761 else if (!do_nest && !NILP (Vwindow_splits))
3762 /* `window-splits' non-nil means try to resize OLD's siblings
3763 proportionally. */
3764 {
3765 p = XWINDOW (o->parent);
3766 /* Temporarily pretend we split the parent window. */
3767 XSETINT (p->new_total,
3768 XINT (horflag ? p->total_cols : p->total_lines)
3769 - XINT (total_size));
3770 if (!resize_window_check (p, horflag))
3771 error ("Window sizes don't fit");
3772 else
3773 /* Undo the temporary pretension. */
3774 p->new_total = horflag ? p->total_cols : p->total_lines;
3775 }
3776 else
3777 {
3778 if (!resize_window_check (o, horflag))
3779 error ("Resizing old window failed");
3780 else if (XINT (total_size) + XINT (o->new_total)
3781 != XINT (horflag ? o->total_cols : o->total_lines))
3782 error ("Sum of sizes of old and new window don't fit");
3783 }
3784
3785 /* This is our point of no return. */
3786 if (do_nest)
3787 {
3788 /* Save the old value of o->normal_cols/lines. It gets corrupted
3789 by make_parent_window and we need it below for assigning it to
3790 p->new_normal. */
3791 Lisp_Object new_normal = horflag ? o->normal_cols : o->normal_lines;
3792
3793 make_parent_window (old, horflag);
3794 p = XWINDOW (o->parent);
3795 /* Store value of `window-nest' in new parent's nest slot. */
3796 p->nest = Vwindow_nest;
3797 /* Have PARENT inherit splits slot value from OLD. */
3798 p->splits = o->splits;
3799 /* Store value of `window-splits' in OLD's splits slot. */
3800 o->splits = Vwindow_splits;
3801 /* These get applied below. */
3802 p->new_total = horflag ? o->total_cols : o->total_lines;
3803 p->new_normal = new_normal;
3804 }
3805 else
3806 p = XWINDOW (o->parent);
4417 3807
4418 /* Set redisplay hints. */
4419 XSETFASTINT (w->last_modified, 0);
4420 XSETFASTINT (w->last_overlay_modified, 0);
4421 windows_or_buffers_changed++; 3808 windows_or_buffers_changed++;
4422 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w))) = 1; 3809 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4423 3810 new = make_window ();
4424 old_height = XFASTINT (w->total_lines); 3811 n = XWINDOW (new);
4425 XSETFASTINT (w->total_lines, height); 3812 n->frame = frame;
3813 n->parent = o->parent;
3814 n->vchild = n->hchild = Qnil;
4426 3815
4427 if (!NILP (w->hchild)) 3816 if (EQ (side, Qabove) || EQ (side, Qleft))
4428 { 3817 {
4429 for (child = w->hchild; !NILP (child); child = c->next) 3818 n->prev = o->prev;
4430 { 3819 if (NILP (n->prev))
4431 c = XWINDOW (child); 3820 if (horflag)
4432 c->top_line = w->top_line; 3821 p->hchild = new;
4433 shrink_window_lowest_first (c, height); 3822 else
4434 } 3823 p->vchild = new;
3824 else
3825 XWINDOW (n->prev)->next = new;
3826 n->next = old;
3827 o->prev = new;
4435 } 3828 }
4436 else if (!NILP (w->vchild)) 3829 else
4437 { 3830 {
4438 Lisp_Object last_child; 3831 n->next = o->next;
4439 int delta = old_height - height; 3832 if (!NILP (n->next))
4440 int last_top; 3833 XWINDOW (n->next)->prev = new;
3834 n->prev = old;
3835 o->next = new;
3836 }
4441 3837
4442 last_child = Qnil; 3838 n->buffer = Qt;
3839 n->window_end_valid = Qnil;
3840 memset (&n->last_cursor, 0, sizeof n->last_cursor);
4443 3841
4444 /* Find the last child. We are taking space from lowest windows 3842 /* Get special geometry settings from reference window. */
4445 first, so we iterate over children from the last child 3843 n->left_margin_cols = r->left_margin_cols;
4446 backwards. */ 3844 n->right_margin_cols = r->right_margin_cols;
4447 for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next) 3845 n->left_fringe_width = r->left_fringe_width;
4448 last_child = child; 3846 n->right_fringe_width = r->right_fringe_width;
3847 n->fringes_outside_margins = r->fringes_outside_margins;
3848 n->scroll_bar_width = r->scroll_bar_width;
3849 n->vertical_scroll_bar_type = r->vertical_scroll_bar_type;
4449 3850
4450 /* Size children down to their safe heights. */ 3851 /* Store `window-splits' in NEW's splits slot. */
4451 for (child = last_child; delta && !NILP (child); child = c->prev) 3852 n->splits = Vwindow_splits;
4452 {
4453 int this_one;
4454 3853
4455 c = XWINDOW (child); 3854 /* Directly assign orthogonal coordinates and sizes. */
4456 this_one = XFASTINT (c->total_lines) - window_min_size_1 (c, 0, 1); 3855 if (horflag)
3856 {
3857 n->top_line = o->top_line;
3858 n->total_lines = o->total_lines;
3859 }
3860 else
3861 {
3862 n->left_col = o->left_col;
3863 n->total_cols = o->total_cols;
3864 }
4457 3865
4458 if (this_one > delta) 3866 /* Iso-coordinates and sizes are assigned by resize_window_apply,
4459 this_one = delta; 3867 get them ready here. */
3868 n->new_total = total_size;
3869 n->new_normal = normal_size;
4460 3870
4461 shrink_window_lowest_first (c, XFASTINT (c->total_lines) - this_one); 3871 BLOCK_INPUT;
4462 delta -= this_one; 3872 resize_window_apply (p, horflag);
4463 } 3873 adjust_glyphs (f);
3874 /* Set buffer of NEW to buffer of reference window. Don't run
3875 any hooks. */
3876 set_window_buffer (new, r->buffer, 0, 1);
3877 UNBLOCK_INPUT;
4464 3878
4465 /* Compute new positions. */ 3879 /* Maybe we should run the scroll functions in Elisp (which already
4466 last_top = XINT (w->top_line); 3880 runs the configuration change hook). */
4467 for (child = w->vchild; !NILP (child); child = c->next) 3881 if (! NILP (Vwindow_scroll_functions))
4468 { 3882 run_hook_with_args_2 (Qwindow_scroll_functions, new,
4469 c = XWINDOW (child); 3883 Fmarker_position (n->start));
4470 c->top_line = make_number (last_top); 3884 /* Return NEW. */
4471 shrink_window_lowest_first (c, XFASTINT (c->total_lines)); 3885 return new;
4472 last_top += XFASTINT (c->total_lines);
4473 }
4474 }
4475} 3886}
4476 3887
4477 3888
4478/* Save, restore, or check positions and sizes in the window tree 3889DEFUN ("delete-window-internal", Fdelete_window_internal, Sdelete_window_internal, 1, 1, 0,
4479 rooted at W. ACTION says what to do. 3890 doc: /* Remove WINDOW from its frame.
3891WINDOW defaults to the selected window. Return nil. Signal an error
3892when WINDOW is the only window on its frame. */)
3893 (register Lisp_Object window)
3894{
3895 register Lisp_Object parent, sibling, frame, root;
3896 struct window *w, *p, *s, *r;
3897 struct frame *f;
3898 int horflag;
3899 int before_sibling = 0;
4480 3900
4481 If ACTION is CHECK_ORIG_SIZES, check if orig_top_line and 3901 w = decode_any_window (window);
4482 orig_total_lines members are valid for all windows in the window 3902 XSETWINDOW (window, w);
4483 tree. Value is non-zero if they are valid. 3903 if (NILP (w->buffer) && NILP (w->hchild) && NILP (w->vchild))
3904 /* It's a no-op to delete an already deleted window. */
3905 return Qnil;
4484 3906
4485 If ACTION is SAVE_ORIG_SIZES, save members top and height in 3907 parent = w->parent;
4486 orig_top_line and orig_total_lines for all windows in the tree. 3908 if (NILP (parent))
3909 /* Never delete a minibuffer or frame root window. */
3910 error ("Attempt to delete minibuffer or sole ordinary window");
3911 else if (NILP (w->prev) && NILP (w->next))
3912 /* Rather bow out here, this case should be handled on the Elisp
3913 level. */
3914 error ("Attempt to delete sole window of parent");
4487 3915
4488 If ACTION is RESTORE_ORIG_SIZES, restore top and height from values 3916 p = XWINDOW (parent);
4489 stored in orig_top_line and orig_total_lines for all windows. */ 3917 horflag = NILP (p->vchild);
4490 3918
4491static int 3919 frame = WINDOW_FRAME (w);
4492save_restore_orig_size (struct window *w, enum save_restore_action action) 3920 f = XFRAME (frame);
4493{
4494 int success_p = 1;
4495 3921
4496 while (w) 3922 root = FRAME_ROOT_WINDOW (f);
3923 r = XWINDOW (root);
3924
3925 /* Unlink WINDOW from window tree. */
3926 if (NILP (w->prev))
3927 /* Get SIBLING below (on the right of) WINDOW. */
3928 {
3929 /* before_sibling 1 means WINDOW is the first child of its
3930 parent and thus before the sibling. */
3931 before_sibling = 1;
3932 sibling = w->next;
3933 s = XWINDOW (sibling);
3934 s->prev = Qnil;
3935 if (horflag)
3936 p->hchild = sibling;
3937 else
3938 p->vchild = sibling;
3939 }
3940 else
3941 /* Get SIBLING above (on the left of) WINDOW. */
4497 { 3942 {
4498 if (!NILP (w->hchild)) 3943 sibling = w->prev;
3944 s = XWINDOW (sibling);
3945 s->next = w->next;
3946 if (!NILP (s->next))
3947 XWINDOW (s->next)->prev = sibling;
3948 }
3949
3950 if (resize_window_check (r, horflag)
3951 && EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
3952 /* We can delete WINDOW now. */
3953 {
3954 /* Block input. */
3955 BLOCK_INPUT;
3956 resize_window_apply (p, horflag);
3957
3958 windows_or_buffers_changed++;
3959 Vwindow_list = Qnil;
3960 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
3961
3962 w->next = Qnil; /* Don't delete w->next too. */
3963 free_window_matrices (w);
3964
3965 if (!NILP (w->vchild))
4499 { 3966 {
4500 if (!save_restore_orig_size (XWINDOW (w->hchild), action)) 3967 delete_all_subwindows (w->vchild);
4501 success_p = 0; 3968 w->vchild = Qnil;
4502 } 3969 }
4503 else if (!NILP (w->vchild)) 3970 else if (!NILP (w->hchild))
3971 {
3972 delete_all_subwindows (w->hchild);
3973 w->hchild = Qnil;
3974 }
3975 else if (!NILP (w->buffer))
4504 { 3976 {
4505 if (!save_restore_orig_size (XWINDOW (w->vchild), action)) 3977 unshow_buffer (w);
4506 success_p = 0; 3978 unchain_marker (XMARKER (w->pointm));
3979 unchain_marker (XMARKER (w->start));
3980 w->buffer = Qnil;
4507 } 3981 }
4508 3982
4509 switch (action) 3983 if (NILP (s->prev) && NILP (s->next))
3984 /* A matrjoshka where SIBLING has become the only child of
3985 PARENT. */
4510 { 3986 {
4511 case CHECK_ORIG_SIZES: 3987 /* Put SIBLING into PARENT's place. */
4512 if (!INTEGERP (w->orig_top_line) || !INTEGERP (w->orig_total_lines)) 3988 replace_window (parent, sibling, 0);
4513 return 0; 3989 /* Have SIBLING inherit the following three slot values from
4514 break; 3990 PARENT (the nest slot is not inherited). */
3991 s->normal_cols = p->normal_cols;
3992 s->normal_lines = p->normal_lines;
3993 s->splits = p->splits;
3994 /* Mark PARENT as deleted. */
3995 p->vchild = p->hchild = Qnil;
3996 /* Try to merge SIBLING into its new parent. */
3997 recombine_windows (sibling);
3998 }
4515 3999
4516 case SAVE_ORIG_SIZES: 4000 adjust_glyphs (f);
4517 w->orig_top_line = w->top_line;
4518 w->orig_total_lines = w->total_lines;
4519 XSETFASTINT (w->last_modified, 0);
4520 XSETFASTINT (w->last_overlay_modified, 0);
4521 break;
4522 4001
4523 case RESTORE_ORIG_SIZES: 4002 if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f)))
4524 xassert (INTEGERP (w->orig_top_line) && INTEGERP (w->orig_total_lines)); 4003 /* We deleted the frame's selected window. */
4525 w->top_line = w->orig_top_line; 4004 {
4526 w->total_lines = w->orig_total_lines; 4005 /* Use the frame's first window as fallback ... */
4527 w->orig_total_lines = w->orig_top_line = Qnil; 4006 Lisp_Object new_selected_window = Fframe_first_window (frame);
4528 XSETFASTINT (w->last_modified, 0); 4007 /* ... but preferably use its most recently used window. */
4529 XSETFASTINT (w->last_overlay_modified, 0); 4008 Lisp_Object mru_window;
4530 break; 4009
4010 /* `get-mru-window' might fail for some reason so play it safe
4011 - promote the first window _without recording it_ first. */
4012 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
4013 Fselect_window (new_selected_window, Qt);
4014 else
4015 FRAME_SELECTED_WINDOW (f) = new_selected_window;
4016
4017 UNBLOCK_INPUT;
4531 4018
4532 default: 4019 /* Now look whether `get-mru-window' gets us something. */
4533 abort (); 4020 mru_window = call1 (Qget_mru_window, frame);
4021 if (WINDOW_LIVE_P (mru_window)
4022 && EQ (XWINDOW (mru_window)->frame, frame))
4023 new_selected_window = mru_window;
4024
4025 /* If all ended up well, we now promote the mru window. */
4026 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
4027 Fselect_window (new_selected_window, Qnil);
4028 else
4029 FRAME_SELECTED_WINDOW (f) = new_selected_window;
4534 } 4030 }
4031 else
4032 UNBLOCK_INPUT;
4535 4033
4536 w = NILP (w->next) ? NULL : XWINDOW (w->next); 4034 /* Must be run by the caller:
4035 run_window_configuration_change_hook (f); */
4036 }
4037 else
4038 /* We failed: Relink WINDOW into window tree. */
4039 {
4040 if (before_sibling)
4041 {
4042 s->prev = window;
4043 if (horflag)
4044 p->hchild = window;
4045 else
4046 p->vchild = window;
4047 }
4048 else
4049 {
4050 s->next = window;
4051 if (!NILP (w->next))
4052 XWINDOW (w->next)->prev = window;
4053 }
4054 error ("Deletion failed");
4537 } 4055 }
4538 4056
4539 return success_p; 4057 return Qnil;
4540} 4058}
4059
4060/***********************************************************************
4061 Resizing Mini-Windows
4062 ***********************************************************************/
4541 4063
4542 4064/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we
4543/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can 4065 can. */
4544 without deleting other windows. */
4545
4546void 4066void
4547grow_mini_window (struct window *w, int delta) 4067grow_mini_window (struct window *w, int delta)
4548{ 4068{
4549 struct frame *f = XFRAME (w->frame); 4069 struct frame *f = XFRAME (w->frame);
4550 struct window *root; 4070 struct window *r;
4071 Lisp_Object root, value;
4551 4072
4552 xassert (MINI_WINDOW_P (w)); 4073 xassert (MINI_WINDOW_P (w));
4553 /* Commenting out the following assertion goes against the stated interface 4074 xassert (delta >= 0);
4554 of the function, but it currently does not seem to do anything useful.
4555 See discussion of this issue in the thread for bug#4534.
4556 xassert (delta >= 0); */
4557
4558 /* Compute how much we can enlarge the mini-window without deleting
4559 other windows. */
4560 root = XWINDOW (FRAME_ROOT_WINDOW (f));
4561 if (delta > 0)
4562 {
4563 int min_height = window_min_size (root, 0, 0, 0, 0);
4564 if (XFASTINT (root->total_lines) - delta < min_height)
4565 /* Note that the root window may already be smaller than
4566 min_height. */
4567 delta = max (0, XFASTINT (root->total_lines) - min_height);
4568 }
4569 4075
4570 if (delta) 4076 root = FRAME_ROOT_WINDOW (f);
4077 r = XWINDOW (root);
4078 value = call2 (Qresize_root_window_vertically, root, make_number (- delta));
4079 if (INTEGERP (value) && resize_window_check (r, 0))
4571 { 4080 {
4572 /* Save original window sizes and positions, if not already done. */ 4081 BLOCK_INPUT;
4573 if (!save_restore_orig_size (root, CHECK_ORIG_SIZES)) 4082 resize_window_apply (r, 0);
4574 save_restore_orig_size (root, SAVE_ORIG_SIZES);
4575
4576 /* Shrink other windows. */
4577 shrink_window_lowest_first (root, XFASTINT (root->total_lines) - delta);
4578 4083
4579 /* Grow the mini-window. */ 4084 /* Grow the mini-window. */
4580 w->top_line = make_number (XFASTINT (root->top_line) + XFASTINT (root->total_lines)); 4085 XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
4581 w->total_lines = make_number (XFASTINT (w->total_lines) + delta); 4086 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - XINT (value));
4582 XSETFASTINT (w->last_modified, 0); 4087 XSETFASTINT (w->last_modified, 0);
4583 XSETFASTINT (w->last_overlay_modified, 0); 4088 XSETFASTINT (w->last_overlay_modified, 0);
4584 4089
4585 adjust_glyphs (f); 4090 adjust_glyphs (f);
4091 UNBLOCK_INPUT;
4586 } 4092 }
4587} 4093}
4588 4094
4589 4095
4590/* Shrink mini-window W. If there is recorded info about window sizes 4096/* Shrink mini-window W. */
4591 before a call to grow_mini_window, restore recorded window sizes.
4592 Otherwise, if the mini-window is higher than 1 line, resize it to 1
4593 line. */
4594
4595void 4097void
4596shrink_mini_window (struct window *w) 4098shrink_mini_window (struct window *w)
4597{ 4099{
4598 struct frame *f = XFRAME (w->frame); 4100 struct frame *f = XFRAME (w->frame);
4599 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f)); 4101 struct window *r;
4102 Lisp_Object root, value;
4103 EMACS_INT size;
4600 4104
4601 if (save_restore_orig_size (root, CHECK_ORIG_SIZES)) 4105 xassert (MINI_WINDOW_P (w));
4602 { 4106
4603 save_restore_orig_size (root, RESTORE_ORIG_SIZES); 4107 size = XINT (w->total_lines);
4604 adjust_glyphs (f); 4108 if (size > 1)
4605 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4606 windows_or_buffers_changed = 1;
4607 }
4608 else if (XFASTINT (w->total_lines) > 1)
4609 { 4109 {
4610 /* Distribute the additional lines of the mini-window 4110 root = FRAME_ROOT_WINDOW (f);
4611 among the other windows. */ 4111 r = XWINDOW (root);
4612 Lisp_Object window; 4112 value = call2 (Qresize_root_window_vertically,
4613 XSETWINDOW (window, w); 4113 root, make_number (size - 1));
4614 enlarge_window (window, 1 - XFASTINT (w->total_lines), 0); 4114 if (INTEGERP (value) && resize_window_check (r, 0))
4115 {
4116 BLOCK_INPUT;
4117 resize_window_apply (r, 0);
4118
4119 /* Shrink the mini-window. */
4120 XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
4121 XSETFASTINT (w->total_lines, 1);
4122
4123 XSETFASTINT (w->last_modified, 0);
4124 XSETFASTINT (w->last_overlay_modified, 0);
4125
4126 adjust_glyphs (f);
4127 UNBLOCK_INPUT;
4128 }
4129 /* If the above failed for whatever strange reason we must make a
4130 one window frame here. The same routine will be needed when
4131 shrinking the frame (and probably when making the initial
4132 *scratch* window). For the moment leave things as they are. */
4615 } 4133 }
4616} 4134}
4617 4135
4136DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini_window_internal, 1, 1, 0,
4137 doc: /* Resize minibuffer window WINDOW. */)
4138 (Lisp_Object window)
4139{
4140 struct window *w = XWINDOW (window);
4141 struct window *r;
4142 struct frame *f;
4143 int height;
4144
4145 CHECK_WINDOW (window);
4146 f = XFRAME (w->frame);
4147
4148 if (!EQ (FRAME_MINIBUF_WINDOW (XFRAME (w->frame)), window))
4149 error ("Not a valid minibuffer window");
4150 else if (FRAME_MINIBUF_ONLY_P (f))
4151 error ("Cannot resize a minibuffer-only frame");
4152
4153 r = XWINDOW (FRAME_ROOT_WINDOW (f));
4154 height = XINT (r->total_lines) + XINT (w->total_lines);
4155 if (resize_window_check (r, 0)
4156 && XINT (w->new_total) > 0
4157 && height == XINT (r->new_total) + XINT (w->new_total))
4158 {
4159 BLOCK_INPUT;
4160 resize_window_apply (r, 0);
4618 4161
4162 w->total_lines = w->new_total;
4163 XSETFASTINT (w->top_line, XINT (r->top_line) + XINT (r->total_lines));
4164
4165 windows_or_buffers_changed++;
4166 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4167 adjust_glyphs (f);
4168 UNBLOCK_INPUT;
4169
4170 run_window_configuration_change_hook (f);
4171 return Qt;
4172 }
4173 else error ("Failed to resize minibuffer window");
4174}
4619 4175
4620/* Mark window cursors off for all windows in the window tree rooted 4176/* Mark window cursors off for all windows in the window tree rooted
4621 at W by setting their phys_cursor_on_p flag to zero. Called from 4177 at W by setting their phys_cursor_on_p flag to zero. Called from
@@ -4662,37 +4218,6 @@ window_internal_height (struct window *w)
4662 4218
4663 return ht; 4219 return ht;
4664} 4220}
4665
4666
4667/* Return the number of columns in W.
4668 Don't count columns occupied by scroll bars or the vertical bar
4669 separating W from the sibling to its right. */
4670
4671int
4672window_box_text_cols (struct window *w)
4673{
4674 struct frame *f = XFRAME (WINDOW_FRAME (w));
4675 int width = XINT (w->total_cols);
4676
4677 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
4678 /* Scroll bars occupy a few columns. */
4679 width -= WINDOW_CONFIG_SCROLL_BAR_COLS (w);
4680 else if (!FRAME_WINDOW_P (f)
4681 && !WINDOW_RIGHTMOST_P (w) && !WINDOW_FULL_WIDTH_P (w))
4682 /* The column of `|' characters separating side-by-side windows
4683 occupies one column only. */
4684 width -= 1;
4685
4686 if (FRAME_WINDOW_P (f))
4687 /* On window-systems, fringes and display margins cannot be
4688 used for normal text. */
4689 width -= (WINDOW_FRINGE_COLS (w)
4690 + WINDOW_LEFT_MARGIN_COLS (w)
4691 + WINDOW_RIGHT_MARGIN_COLS (w));
4692
4693 return width;
4694}
4695
4696 4221
4697/************************************************************************ 4222/************************************************************************
4698 Window Scrolling 4223 Window Scrolling
@@ -4837,8 +4362,8 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4837 possibility of point becoming "stuck" on a tall line when 4362 possibility of point becoming "stuck" on a tall line when
4838 scrolling by one line. */ 4363 scrolling by one line. */
4839 if (window_scroll_pixel_based_preserve_y < 0 4364 if (window_scroll_pixel_based_preserve_y < 0
4840 || !SYMBOLP (current_kboard->Vlast_command) 4365 || !SYMBOLP (KVAR (current_kboard, Vlast_command))
4841 || NILP (Fget (current_kboard->Vlast_command, Qscroll_command))) 4366 || NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command)))
4842 { 4367 {
4843 start_display (&it, w, start); 4368 start_display (&it, w, start);
4844 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); 4369 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
@@ -4871,7 +4396,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4871 looking at an image that is taller that the window height. */ 4396 looking at an image that is taller that the window height. */
4872 while (start_pos == IT_CHARPOS (it) 4397 while (start_pos == IT_CHARPOS (it)
4873 && start_pos > BEGV) 4398 && start_pos > BEGV)
4874 move_it_by_lines (&it, -1, 1); 4399 move_it_by_lines (&it, -1);
4875 } 4400 }
4876 else if (dy > 0) 4401 else if (dy > 0)
4877 { 4402 {
@@ -4881,11 +4406,11 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4881 looking at an image that is taller that the window height. */ 4406 looking at an image that is taller that the window height. */
4882 while (start_pos == IT_CHARPOS (it) 4407 while (start_pos == IT_CHARPOS (it)
4883 && start_pos < ZV) 4408 && start_pos < ZV)
4884 move_it_by_lines (&it, 1, 1); 4409 move_it_by_lines (&it, 1);
4885 } 4410 }
4886 } 4411 }
4887 else 4412 else
4888 move_it_by_lines (&it, n, 1); 4413 move_it_by_lines (&it, n);
4889 4414
4890 /* We failed if we find ZV is already on the screen (scrolling up, 4415 /* We failed if we find ZV is already on the screen (scrolling up,
4891 means there's nothing past the end), or if we can't start any 4416 means there's nothing past the end), or if we can't start any
@@ -4996,7 +4521,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4996 while (it.current_y < this_scroll_margin) 4521 while (it.current_y < this_scroll_margin)
4997 { 4522 {
4998 int prev = it.current_y; 4523 int prev = it.current_y;
4999 move_it_by_lines (&it, 1, 1); 4524 move_it_by_lines (&it, 1);
5000 if (prev == it.current_y) 4525 if (prev == it.current_y)
5001 break; 4526 break;
5002 } 4527 }
@@ -5030,7 +4555,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
5030 partial_p = it.current_y + it.ascent + it.descent > it.last_visible_y; 4555 partial_p = it.current_y + it.ascent + it.descent > it.last_visible_y;
5031 else 4556 else
5032 { 4557 {
5033 move_it_by_lines (&it, 1, 1); 4558 move_it_by_lines (&it, 1);
5034 partial_p = it.current_y > it.last_visible_y; 4559 partial_p = it.current_y > it.last_visible_y;
5035 } 4560 }
5036 4561
@@ -5057,7 +4582,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
5057 /* The last line was only partially visible, so back up two 4582 /* The last line was only partially visible, so back up two
5058 lines to make sure we're on a fully visible line. */ 4583 lines to make sure we're on a fully visible line. */
5059 { 4584 {
5060 move_it_by_lines (&it, -2, 0); 4585 move_it_by_lines (&it, -2);
5061 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); 4586 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
5062 } 4587 }
5063 else 4588 else
@@ -5075,7 +4600,12 @@ static void
5075window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror) 4600window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
5076{ 4601{
5077 register struct window *w = XWINDOW (window); 4602 register struct window *w = XWINDOW (window);
5078 register EMACS_INT opoint = PT, opoint_byte = PT_BYTE; 4603 /* Fvertical_motion enters redisplay, which can trigger
4604 fontification, which in turn can modify buffer text (e.g., if the
4605 fontification functions replace escape sequences with faces, as
4606 in `grep-mode-font-lock-keywords'). So we use a marker to record
4607 the old point position, to prevent crashes in SET_PT_BOTH. */
4608 Lisp_Object opoint_marker = Fpoint_marker ();
5079 register EMACS_INT pos, pos_byte; 4609 register EMACS_INT pos, pos_byte;
5080 register int ht = window_internal_height (w); 4610 register int ht = window_internal_height (w);
5081 register Lisp_Object tem; 4611 register Lisp_Object tem;
@@ -5094,8 +4624,8 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
5094 if (!NILP (Vscroll_preserve_screen_position)) 4624 if (!NILP (Vscroll_preserve_screen_position))
5095 { 4625 {
5096 if (window_scroll_preserve_vpos <= 0 4626 if (window_scroll_preserve_vpos <= 0
5097 || !SYMBOLP (current_kboard->Vlast_command) 4627 || !SYMBOLP (KVAR (current_kboard, Vlast_command))
5098 || NILP (Fget (current_kboard->Vlast_command, Qscroll_command))) 4628 || NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command)))
5099 { 4629 {
5100 struct position posit 4630 struct position posit
5101 = *compute_motion (startpos, 0, 0, 0, 4631 = *compute_motion (startpos, 0, 0, 0,
@@ -5125,7 +4655,8 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
5125 pos = PT; 4655 pos = PT;
5126 pos_byte = PT_BYTE; 4656 pos_byte = PT_BYTE;
5127 bolp = Fbolp (); 4657 bolp = Fbolp ();
5128 SET_PT_BOTH (opoint, opoint_byte); 4658 SET_PT_BOTH (marker_position (opoint_marker),
4659 marker_byte_position (opoint_marker));
5129 4660
5130 if (lose) 4661 if (lose)
5131 { 4662 {
@@ -5176,8 +4707,9 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
5176 else 4707 else
5177 top_margin = pos; 4708 top_margin = pos;
5178 4709
5179 if (top_margin <= opoint) 4710 if (top_margin <= marker_position (opoint_marker))
5180 SET_PT_BOTH (opoint, opoint_byte); 4711 SET_PT_BOTH (marker_position (opoint_marker),
4712 marker_byte_position (opoint_marker));
5181 else if (!NILP (Vscroll_preserve_screen_position)) 4713 else if (!NILP (Vscroll_preserve_screen_position))
5182 { 4714 {
5183 SET_PT_BOTH (pos, pos_byte); 4715 SET_PT_BOTH (pos, pos_byte);
@@ -5199,8 +4731,9 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
5199 else 4731 else
5200 bottom_margin = PT + 1; 4732 bottom_margin = PT + 1;
5201 4733
5202 if (bottom_margin > opoint) 4734 if (bottom_margin > marker_position (opoint_marker))
5203 SET_PT_BOTH (opoint, opoint_byte); 4735 SET_PT_BOTH (marker_position (opoint_marker),
4736 marker_byte_position (opoint_marker));
5204 else 4737 else
5205 { 4738 {
5206 if (!NILP (Vscroll_preserve_screen_position)) 4739 if (!NILP (Vscroll_preserve_screen_position))
@@ -5393,7 +4926,7 @@ by this function. This happens in an interactive call. */)
5393 struct window *w = XWINDOW (selected_window); 4926 struct window *w = XWINDOW (selected_window);
5394 4927
5395 if (NILP (arg)) 4928 if (NILP (arg))
5396 XSETFASTINT (arg, window_box_text_cols (w) - 2); 4929 XSETFASTINT (arg, window_body_cols (w) - 2);
5397 else 4930 else
5398 arg = Fprefix_numeric_value (arg); 4931 arg = Fprefix_numeric_value (arg);
5399 4932
@@ -5422,7 +4955,7 @@ by this function. This happens in an interactive call. */)
5422 struct window *w = XWINDOW (selected_window); 4955 struct window *w = XWINDOW (selected_window);
5423 4956
5424 if (NILP (arg)) 4957 if (NILP (arg))
5425 XSETFASTINT (arg, window_box_text_cols (w) - 2); 4958 XSETFASTINT (arg, window_body_cols (w) - 2);
5426 else 4959 else
5427 arg = Fprefix_numeric_value (arg); 4960 arg = Fprefix_numeric_value (arg);
5428 4961
@@ -5527,7 +5060,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5527 struct buffer *obuf = current_buffer; 5060 struct buffer *obuf = current_buffer;
5528 int center_p = 0; 5061 int center_p = 0;
5529 EMACS_INT charpos, bytepos; 5062 EMACS_INT charpos, bytepos;
5530 int iarg; 5063 int iarg IF_LINT (= 0);
5531 int this_scroll_margin; 5064 int this_scroll_margin;
5532 5065
5533 /* If redisplay is suppressed due to an error, try again. */ 5066 /* If redisplay is suppressed due to an error, try again. */
@@ -5600,14 +5133,14 @@ and redisplay normally--don't erase and redraw the frame. */)
5600 start_display (&it, w, pt); 5133 start_display (&it, w, pt);
5601 5134
5602 /* Be sure we have the exact height of the full line containing PT. */ 5135 /* Be sure we have the exact height of the full line containing PT. */
5603 move_it_by_lines (&it, 0, 1); 5136 move_it_by_lines (&it, 0);
5604 5137
5605 /* The amount of pixels we have to move back is the window 5138 /* The amount of pixels we have to move back is the window
5606 height minus what's displayed in the line containing PT, 5139 height minus what's displayed in the line containing PT,
5607 and the lines below. */ 5140 and the lines below. */
5608 it.current_y = 0; 5141 it.current_y = 0;
5609 it.vpos = 0; 5142 it.vpos = 0;
5610 move_it_by_lines (&it, nlines, 1); 5143 move_it_by_lines (&it, nlines);
5611 5144
5612 if (it.vpos == nlines) 5145 if (it.vpos == nlines)
5613 h -= it.current_y; 5146 h -= it.current_y;
@@ -5646,7 +5179,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5646 */ 5179 */
5647 h += extra_line_spacing; 5180 h += extra_line_spacing;
5648 while (-it.current_y > h) 5181 while (-it.current_y > h)
5649 move_it_by_lines (&it, 1, 1); 5182 move_it_by_lines (&it, 1);
5650 5183
5651 charpos = IT_CHARPOS (it); 5184 charpos = IT_CHARPOS (it);
5652 bytepos = IT_BYTEPOS (it); 5185 bytepos = IT_BYTEPOS (it);
@@ -5696,7 +5229,6 @@ and redisplay normally--don't erase and redraw the frame. */)
5696 return Qnil; 5229 return Qnil;
5697} 5230}
5698 5231
5699
5700DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height, 5232DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
5701 0, 1, 0, 5233 0, 1, 0,
5702 doc: /* Return the height in lines of the text display area of WINDOW. 5234 doc: /* Return the height in lines of the text display area of WINDOW.
@@ -5793,8 +5325,7 @@ zero means top of window, negative means relative to bottom of window. */)
5793 5325
5794struct save_window_data 5326struct save_window_data
5795 { 5327 {
5796 EMACS_UINT size; 5328 struct vectorlike_header header;
5797 struct Lisp_Vector *next_from_Lisp_Vector_struct;
5798 Lisp_Object selected_frame; 5329 Lisp_Object selected_frame;
5799 Lisp_Object current_window; 5330 Lisp_Object current_window;
5800 Lisp_Object current_buffer; 5331 Lisp_Object current_buffer;
@@ -5816,22 +5347,20 @@ struct save_window_data
5816/* This is saved as a Lisp_Vector */ 5347/* This is saved as a Lisp_Vector */
5817struct saved_window 5348struct saved_window
5818{ 5349{
5819 /* these first two must agree with struct Lisp_Vector in lisp.h */ 5350 struct vectorlike_header header;
5820 EMACS_UINT size;
5821 struct Lisp_Vector *next_from_Lisp_Vector_struct;
5822 5351
5823 Lisp_Object window; 5352 Lisp_Object window, clone_number;
5824 Lisp_Object buffer, start, pointm, mark; 5353 Lisp_Object buffer, start, pointm, mark;
5825 Lisp_Object left_col, top_line, total_cols, total_lines; 5354 Lisp_Object left_col, top_line, total_cols, total_lines;
5355 Lisp_Object normal_cols, normal_lines;
5826 Lisp_Object hscroll, min_hscroll; 5356 Lisp_Object hscroll, min_hscroll;
5827 Lisp_Object parent, prev; 5357 Lisp_Object parent, prev;
5828 Lisp_Object start_at_line_beg; 5358 Lisp_Object start_at_line_beg;
5829 Lisp_Object display_table; 5359 Lisp_Object display_table;
5830 Lisp_Object orig_top_line, orig_total_lines;
5831 Lisp_Object left_margin_cols, right_margin_cols; 5360 Lisp_Object left_margin_cols, right_margin_cols;
5832 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins; 5361 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
5833 Lisp_Object scroll_bar_width, vertical_scroll_bar_type; 5362 Lisp_Object scroll_bar_width, vertical_scroll_bar_type, dedicated;
5834 Lisp_Object dedicated, resize_proportionally; 5363 Lisp_Object splits, nest, window_parameters;
5835}; 5364};
5836 5365
5837#define SAVED_WINDOW_N(swv,n) \ 5366#define SAVED_WINDOW_N(swv,n) \
@@ -5872,6 +5401,7 @@ the return value is nil. Otherwise the value is t. */)
5872 struct Lisp_Vector *saved_windows; 5401 struct Lisp_Vector *saved_windows;
5873 Lisp_Object new_current_buffer; 5402 Lisp_Object new_current_buffer;
5874 Lisp_Object frame; 5403 Lisp_Object frame;
5404 Lisp_Object auto_buffer_name;
5875 FRAME_PTR f; 5405 FRAME_PTR f;
5876 EMACS_INT old_point = -1; 5406 EMACS_INT old_point = -1;
5877 5407
@@ -5881,7 +5411,7 @@ the return value is nil. Otherwise the value is t. */)
5881 saved_windows = XVECTOR (data->saved_windows); 5411 saved_windows = XVECTOR (data->saved_windows);
5882 5412
5883 new_current_buffer = data->current_buffer; 5413 new_current_buffer = data->current_buffer;
5884 if (NILP (XBUFFER (new_current_buffer)->name)) 5414 if (NILP (BVAR (XBUFFER (new_current_buffer), name)))
5885 new_current_buffer = Qnil; 5415 new_current_buffer = Qnil;
5886 else 5416 else
5887 { 5417 {
@@ -5927,6 +5457,8 @@ the return value is nil. Otherwise the value is t. */)
5927 However, there is other stuff we should still try to do below. */ 5457 However, there is other stuff we should still try to do below. */
5928 if (FRAME_LIVE_P (f)) 5458 if (FRAME_LIVE_P (f))
5929 { 5459 {
5460 Lisp_Object window;
5461 Lisp_Object dead_windows = Qnil;
5930 register struct window *w; 5462 register struct window *w;
5931 register struct saved_window *p; 5463 register struct saved_window *p;
5932 struct window *root_window; 5464 struct window *root_window;
@@ -5998,12 +5530,13 @@ the return value is nil. Otherwise the value is t. */)
5998 Save their current buffers in their height fields, since we may 5530 Save their current buffers in their height fields, since we may
5999 need it later, if a buffer saved in the configuration is now 5531 need it later, if a buffer saved in the configuration is now
6000 dead. */ 5532 dead. */
6001 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f))); 5533 delete_all_subwindows (FRAME_ROOT_WINDOW (f));
6002 5534
6003 for (k = 0; k < saved_windows->size; k++) 5535 for (k = 0; k < saved_windows->header.size; k++)
6004 { 5536 {
6005 p = SAVED_WINDOW_N (saved_windows, k); 5537 p = SAVED_WINDOW_N (saved_windows, k);
6006 w = XWINDOW (p->window); 5538 window = p->window;
5539 w = XWINDOW (window);
6007 w->next = Qnil; 5540 w->next = Qnil;
6008 5541
6009 if (!NILP (p->parent)) 5542 if (!NILP (p->parent))
@@ -6036,6 +5569,7 @@ the return value is nil. Otherwise the value is t. */)
6036 } 5569 }
6037 } 5570 }
6038 5571
5572 w->clone_number = p->clone_number;
6039 /* If we squirreled away the buffer in the window's height, 5573 /* If we squirreled away the buffer in the window's height,
6040 restore it now. */ 5574 restore it now. */
6041 if (BUFFERP (w->total_lines)) 5575 if (BUFFERP (w->total_lines))
@@ -6044,11 +5578,11 @@ the return value is nil. Otherwise the value is t. */)
6044 w->top_line = p->top_line; 5578 w->top_line = p->top_line;
6045 w->total_cols = p->total_cols; 5579 w->total_cols = p->total_cols;
6046 w->total_lines = p->total_lines; 5580 w->total_lines = p->total_lines;
5581 w->normal_cols = p->normal_cols;
5582 w->normal_lines = p->normal_lines;
6047 w->hscroll = p->hscroll; 5583 w->hscroll = p->hscroll;
6048 w->min_hscroll = p->min_hscroll; 5584 w->min_hscroll = p->min_hscroll;
6049 w->display_table = p->display_table; 5585 w->display_table = p->display_table;
6050 w->orig_top_line = p->orig_top_line;
6051 w->orig_total_lines = p->orig_total_lines;
6052 w->left_margin_cols = p->left_margin_cols; 5586 w->left_margin_cols = p->left_margin_cols;
6053 w->right_margin_cols = p->right_margin_cols; 5587 w->right_margin_cols = p->right_margin_cols;
6054 w->left_fringe_width = p->left_fringe_width; 5588 w->left_fringe_width = p->left_fringe_width;
@@ -6057,61 +5591,78 @@ the return value is nil. Otherwise the value is t. */)
6057 w->scroll_bar_width = p->scroll_bar_width; 5591 w->scroll_bar_width = p->scroll_bar_width;
6058 w->vertical_scroll_bar_type = p->vertical_scroll_bar_type; 5592 w->vertical_scroll_bar_type = p->vertical_scroll_bar_type;
6059 w->dedicated = p->dedicated; 5593 w->dedicated = p->dedicated;
6060 w->resize_proportionally = p->resize_proportionally; 5594 w->splits = p->splits;
5595 w->nest = p->nest;
5596 w->window_parameters = p->window_parameters;
6061 XSETFASTINT (w->last_modified, 0); 5597 XSETFASTINT (w->last_modified, 0);
6062 XSETFASTINT (w->last_overlay_modified, 0); 5598 XSETFASTINT (w->last_overlay_modified, 0);
6063 5599
6064 /* Reinstall the saved buffer and pointers into it. */ 5600 /* Reinstall the saved buffer and pointers into it. */
6065 if (NILP (p->buffer)) 5601 if (NILP (p->buffer))
5602 /* An internal window. */
6066 w->buffer = p->buffer; 5603 w->buffer = p->buffer;
5604 else if (!NILP (BVAR (XBUFFER (p->buffer), name)))
5605 /* If saved buffer is alive, install it. */
5606 {
5607 w->buffer = p->buffer;
5608 w->start_at_line_beg = p->start_at_line_beg;
5609 set_marker_restricted (w->start, p->start, w->buffer);
5610 set_marker_restricted (w->pointm, p->pointm, w->buffer);
5611 Fset_marker (BVAR (XBUFFER (w->buffer), mark),
5612 p->mark, w->buffer);
5613
5614 /* As documented in Fcurrent_window_configuration, don't
5615 restore the location of point in the buffer which was
5616 current when the window configuration was recorded. */
5617 if (!EQ (p->buffer, new_current_buffer)
5618 && XBUFFER (p->buffer) == current_buffer)
5619 Fgoto_char (w->pointm);
5620 }
5621 else if (!NILP (w->buffer) && !NILP (BVAR (XBUFFER (w->buffer), name)))
5622 /* Keep window's old buffer; make sure the markers are
5623 real. */
5624 {
5625 /* Set window markers at start of visible range. */
5626 if (XMARKER (w->start)->buffer == 0)
5627 set_marker_restricted (w->start, make_number (0),
5628 w->buffer);
5629 if (XMARKER (w->pointm)->buffer == 0)
5630 set_marker_restricted_both (w->pointm, w->buffer,
5631 BUF_PT (XBUFFER (w->buffer)),
5632 BUF_PT_BYTE (XBUFFER (w->buffer)));
5633 w->start_at_line_beg = Qt;
5634 }
5635 else if (STRINGP (auto_buffer_name =
5636 Fwindow_parameter (window, Qauto_buffer_name))
5637 && SCHARS (auto_buffer_name) != 0
5638 && !NILP (w->buffer = Fget_buffer_create (auto_buffer_name)))
5639 {
5640 set_marker_restricted (w->start, make_number (0), w->buffer);
5641 set_marker_restricted (w->pointm, make_number (0), w->buffer);
5642 w->start_at_line_beg = Qt;
5643 }
6067 else 5644 else
5645 /* Window has no live buffer, get one. */
6068 { 5646 {
6069 if (!NILP (XBUFFER (p->buffer)->name)) 5647 /* Get the buffer via other_buffer_safely in order to
6070 /* If saved buffer is alive, install it. */ 5648 avoid showing an unimportant buffer and, if necessary, to
6071 { 5649 recreate *scratch* in the course (part of Juanma's bs-show
6072 w->buffer = p->buffer; 5650 scenario from March 2011). */
6073 w->start_at_line_beg = p->start_at_line_beg; 5651 w->buffer = other_buffer_safely (Fcurrent_buffer ());
6074 set_marker_restricted (w->start, p->start, w->buffer); 5652 /* This will set the markers to beginning of visible
6075 set_marker_restricted (w->pointm, p->pointm, w->buffer); 5653 range. */
6076 Fset_marker (XBUFFER (w->buffer)->mark, 5654 set_marker_restricted (w->start, make_number (0), w->buffer);
6077 p->mark, w->buffer); 5655 set_marker_restricted (w->pointm, make_number (0), w->buffer);
6078 5656 w->start_at_line_beg = Qt;
6079 /* As documented in Fcurrent_window_configuration, don't 5657 if (!NILP (w->dedicated))
6080 restore the location of point in the buffer which was 5658 /* Record this window as dead. */
6081 current when the window configuration was recorded. */ 5659 dead_windows = Fcons (window, dead_windows);
6082 if (!EQ (p->buffer, new_current_buffer) 5660 /* Make sure window is no more dedicated. */
6083 && XBUFFER (p->buffer) == current_buffer) 5661 w->dedicated = Qnil;
6084 Fgoto_char (w->pointm);
6085 }
6086 else if (NILP (w->buffer) || NILP (XBUFFER (w->buffer)->name))
6087 /* Else unless window has a live buffer, get one. */
6088 {
6089 w->buffer = Fcdr (Fcar (Vbuffer_alist));
6090 /* This will set the markers to beginning of visible
6091 range. */
6092 set_marker_restricted (w->start, make_number (0), w->buffer);
6093 set_marker_restricted (w->pointm, make_number (0),w->buffer);
6094 w->start_at_line_beg = Qt;
6095 }
6096 else
6097 /* Keeping window's old buffer; make sure the markers
6098 are real. */
6099 {
6100 /* Set window markers at start of visible range. */
6101 if (XMARKER (w->start)->buffer == 0)
6102 set_marker_restricted (w->start, make_number (0),
6103 w->buffer);
6104 if (XMARKER (w->pointm)->buffer == 0)
6105 set_marker_restricted_both (w->pointm, w->buffer,
6106 BUF_PT (XBUFFER (w->buffer)),
6107 BUF_PT_BYTE (XBUFFER (w->buffer)));
6108 w->start_at_line_beg = Qt;
6109 }
6110 } 5662 }
6111 } 5663 }
6112 5664
6113 FRAME_ROOT_WINDOW (f) = data->root_window; 5665 FRAME_ROOT_WINDOW (f) = data->root_window;
6114
6115 /* Arrange *not* to restore point in the buffer that was 5666 /* Arrange *not* to restore point in the buffer that was
6116 current when the window configuration was saved. */ 5667 current when the window configuration was saved. */
6117 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)) 5668 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer))
@@ -6119,12 +5670,12 @@ the return value is nil. Otherwise the value is t. */)
6119 make_number (old_point), 5670 make_number (old_point),
6120 XWINDOW (data->current_window)->buffer); 5671 XWINDOW (data->current_window)->buffer);
6121 5672
6122 /* In the following call to `select-window, prevent "swapping 5673 /* In the following call to `select-window', prevent "swapping out
6123 out point" in the old selected window using the buffer that 5674 point" in the old selected window using the buffer that has
6124 has been restored into it. We already swapped out that point 5675 been restored into it. We already swapped out that point from
6125 from that window's old buffer. */ 5676 that window's old buffer. */
6126 select_window (data->current_window, Qnil, 1); 5677 select_window (data->current_window, Qnil, 1);
6127 XBUFFER (XWINDOW (selected_window)->buffer)->last_selected_window 5678 BVAR (XBUFFER (XWINDOW (selected_window)->buffer), last_selected_window)
6128 = selected_window; 5679 = selected_window;
6129 5680
6130 if (NILP (data->focus_frame) 5681 if (NILP (data->focus_frame)
@@ -6163,9 +5714,16 @@ the return value is nil. Otherwise the value is t. */)
6163 } 5714 }
6164 5715
6165 adjust_glyphs (f); 5716 adjust_glyphs (f);
6166
6167 UNBLOCK_INPUT; 5717 UNBLOCK_INPUT;
6168 5718
5719 /* Scan dead buffer windows. */
5720 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
5721 {
5722 window = XCAR (dead_windows);
5723 if (WINDOW_LIVE_P (window) && !EQ (window, FRAME_ROOT_WINDOW (f)))
5724 delete_deletable_window (window);
5725 }
5726
6169 /* Fselect_window will have made f the selected frame, so we 5727 /* Fselect_window will have made f the selected frame, so we
6170 reselect the proper frame here. Fhandle_switch_frame will change the 5728 reselect the proper frame here. Fhandle_switch_frame will change the
6171 selected window too, but that doesn't make the call to 5729 selected window too, but that doesn't make the call to
@@ -6186,31 +5744,39 @@ the return value is nil. Otherwise the value is t. */)
6186 return (FRAME_LIVE_P (f) ? Qt : Qnil); 5744 return (FRAME_LIVE_P (f) ? Qt : Qnil);
6187} 5745}
6188 5746
6189/* Mark all windows now on frame as deleted
6190 by setting their buffers to nil. */
6191 5747
5748/* Delete all subwindows reachable via the next, vchild, and hchild
5749 slots of WINDOW. */
6192void 5750void
6193delete_all_subwindows (register struct window *w) 5751delete_all_subwindows (Lisp_Object window)
6194{ 5752{
5753 register struct window *w;
5754
5755 w = XWINDOW (window);
5756
6195 if (!NILP (w->next)) 5757 if (!NILP (w->next))
6196 delete_all_subwindows (XWINDOW (w->next)); 5758 /* Delete WINDOW's siblings (we traverse postorderly). */
6197 if (!NILP (w->vchild)) 5759 delete_all_subwindows (w->next);
6198 delete_all_subwindows (XWINDOW (w->vchild));
6199 if (!NILP (w->hchild))
6200 delete_all_subwindows (XWINDOW (w->hchild));
6201 5760
6202 w->total_lines = w->buffer; /* See Fset_window_configuration for excuse. */ 5761 w->total_lines = w->buffer; /* See Fset_window_configuration for excuse. */
6203 5762
6204 if (!NILP (w->buffer)) 5763 if (!NILP (w->vchild))
6205 unshow_buffer (w); 5764 {
6206 5765 delete_all_subwindows (w->vchild);
6207 /* We set all three of these fields to nil, to make sure that we can 5766 w->vchild = Qnil;
6208 distinguish this dead window from any live window. Live leaf 5767 }
6209 windows will have buffer set, and combination windows will have 5768 else if (!NILP (w->hchild))
6210 vchild or hchild set. */ 5769 {
6211 w->buffer = Qnil; 5770 delete_all_subwindows (w->hchild);
6212 w->vchild = Qnil; 5771 w->hchild = Qnil;
6213 w->hchild = Qnil; 5772 }
5773 else if (!NILP (w->buffer))
5774 {
5775 unshow_buffer (w);
5776 unchain_marker (XMARKER (w->pointm));
5777 unchain_marker (XMARKER (w->start));
5778 w->buffer = Qnil;
5779 }
6214 5780
6215 Vwindow_list = Qnil; 5781 Vwindow_list = Qnil;
6216} 5782}
@@ -6231,7 +5797,6 @@ count_windows (register struct window *window)
6231 5797
6232/* Fill vector FLAT with leaf windows under W, starting at index I. 5798/* Fill vector FLAT with leaf windows under W, starting at index I.
6233 Value is last index + 1. */ 5799 Value is last index + 1. */
6234
6235static int 5800static int
6236get_leaf_windows (struct window *w, struct window **flat, int i) 5801get_leaf_windows (struct window *w, struct window **flat, int i)
6237{ 5802{
@@ -6254,7 +5819,6 @@ get_leaf_windows (struct window *w, struct window **flat, int i)
6254/* Return a pointer to the glyph W's physical cursor is on. Value is 5819/* Return a pointer to the glyph W's physical cursor is on. Value is
6255 null if W's current matrix is invalid, so that no meaningfull glyph 5820 null if W's current matrix is invalid, so that no meaningfull glyph
6256 can be returned. */ 5821 can be returned. */
6257
6258struct glyph * 5822struct glyph *
6259get_phys_cursor_glyph (struct window *w) 5823get_phys_cursor_glyph (struct window *w)
6260{ 5824{
@@ -6288,16 +5852,17 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6288 5852
6289 XSETFASTINT (w->temslot, i); i++; 5853 XSETFASTINT (w->temslot, i); i++;
6290 p->window = window; 5854 p->window = window;
5855 p->clone_number = w->clone_number;
6291 p->buffer = w->buffer; 5856 p->buffer = w->buffer;
6292 p->left_col = w->left_col; 5857 p->left_col = w->left_col;
6293 p->top_line = w->top_line; 5858 p->top_line = w->top_line;
6294 p->total_cols = w->total_cols; 5859 p->total_cols = w->total_cols;
6295 p->total_lines = w->total_lines; 5860 p->total_lines = w->total_lines;
5861 p->normal_cols = w->normal_cols;
5862 p->normal_lines = w->normal_lines;
6296 p->hscroll = w->hscroll; 5863 p->hscroll = w->hscroll;
6297 p->min_hscroll = w->min_hscroll; 5864 p->min_hscroll = w->min_hscroll;
6298 p->display_table = w->display_table; 5865 p->display_table = w->display_table;
6299 p->orig_top_line = w->orig_top_line;
6300 p->orig_total_lines = w->orig_total_lines;
6301 p->left_margin_cols = w->left_margin_cols; 5866 p->left_margin_cols = w->left_margin_cols;
6302 p->right_margin_cols = w->right_margin_cols; 5867 p->right_margin_cols = w->right_margin_cols;
6303 p->left_fringe_width = w->left_fringe_width; 5868 p->left_fringe_width = w->left_fringe_width;
@@ -6306,7 +5871,9 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6306 p->scroll_bar_width = w->scroll_bar_width; 5871 p->scroll_bar_width = w->scroll_bar_width;
6307 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type; 5872 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
6308 p->dedicated = w->dedicated; 5873 p->dedicated = w->dedicated;
6309 p->resize_proportionally = w->resize_proportionally; 5874 p->splits = w->splits;
5875 p->nest = w->nest;
5876 p->window_parameters = w->window_parameters;
6310 if (!NILP (w->buffer)) 5877 if (!NILP (w->buffer))
6311 { 5878 {
6312 /* Save w's value of point in the window configuration. 5879 /* Save w's value of point in the window configuration.
@@ -6325,7 +5892,7 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6325 p->start = Fcopy_marker (w->start, Qnil); 5892 p->start = Fcopy_marker (w->start, Qnil);
6326 p->start_at_line_beg = w->start_at_line_beg; 5893 p->start_at_line_beg = w->start_at_line_beg;
6327 5894
6328 tem = XBUFFER (w->buffer)->mark; 5895 tem = BVAR (XBUFFER (w->buffer), mark);
6329 p->mark = Fcopy_marker (tem, Qnil); 5896 p->mark = Fcopy_marker (tem, Qnil);
6330 } 5897 }
6331 else 5898 else
@@ -6402,104 +5969,6 @@ redirection (see `redirect-frame-focus'). */)
6402 XSETWINDOW_CONFIGURATION (tem, data); 5969 XSETWINDOW_CONFIGURATION (tem, data);
6403 return (tem); 5970 return (tem);
6404} 5971}
6405
6406DEFUN ("save-window-excursion", Fsave_window_excursion, Ssave_window_excursion,
6407 0, UNEVALLED, 0,
6408 doc: /* Execute BODY, preserving window sizes and contents.
6409Return the value of the last form in BODY.
6410Restore which buffer appears in which window, where display starts,
6411and the value of point and mark for each window.
6412Also restore the choice of selected window.
6413Also restore which buffer is current.
6414Does not restore the value of point in current buffer.
6415usage: (save-window-excursion BODY...) */)
6416 (Lisp_Object args)
6417{
6418 register Lisp_Object val;
6419 register int count = SPECPDL_INDEX ();
6420
6421 record_unwind_protect (Fset_window_configuration,
6422 Fcurrent_window_configuration (Qnil));
6423 val = Fprogn (args);
6424 return unbind_to (count, val);
6425}
6426
6427
6428
6429/***********************************************************************
6430 Window Split Tree
6431 ***********************************************************************/
6432
6433static Lisp_Object
6434window_tree (struct window *w)
6435{
6436 Lisp_Object tail = Qnil;
6437 Lisp_Object result = Qnil;
6438
6439 while (w)
6440 {
6441 Lisp_Object wn;
6442
6443 XSETWINDOW (wn, w);
6444 if (!NILP (w->hchild))
6445 wn = Fcons (Qnil, Fcons (Fwindow_edges (wn),
6446 window_tree (XWINDOW (w->hchild))));
6447 else if (!NILP (w->vchild))
6448 wn = Fcons (Qt, Fcons (Fwindow_edges (wn),
6449 window_tree (XWINDOW (w->vchild))));
6450
6451 if (NILP (result))
6452 {
6453 result = tail = Fcons (wn, Qnil);
6454 }
6455 else
6456 {
6457 XSETCDR (tail, Fcons (wn, Qnil));
6458 tail = XCDR (tail);
6459 }
6460
6461 w = NILP (w->next) ? 0 : XWINDOW (w->next);
6462 }
6463
6464 return result;
6465}
6466
6467
6468
6469DEFUN ("window-tree", Fwindow_tree, Swindow_tree,
6470 0, 1, 0,
6471 doc: /* Return the window tree for frame FRAME.
6472
6473The return value is a list of the form (ROOT MINI), where ROOT
6474represents the window tree of the frame's root window, and MINI
6475is the frame's minibuffer window.
6476
6477If the root window is not split, ROOT is the root window itself.
6478Otherwise, ROOT is a list (DIR EDGES W1 W2 ...) where DIR is nil for a
6479horizontal split, and t for a vertical split, EDGES gives the combined
6480size and position of the subwindows in the split, and the rest of the
6481elements are the subwindows in the split. Each of the subwindows may
6482again be a window or a list representing a window split, and so on.
6483EDGES is a list \(LEFT TOP RIGHT BOTTOM) as returned by `window-edges'.
6484
6485If FRAME is nil or omitted, return information on the currently
6486selected frame. */)
6487 (Lisp_Object frame)
6488{
6489 FRAME_PTR f;
6490
6491 if (NILP (frame))
6492 frame = selected_frame;
6493
6494 CHECK_FRAME (frame);
6495 f = XFRAME (frame);
6496
6497 if (!FRAME_LIVE_P (f))
6498 return Qnil;
6499
6500 return window_tree (XWINDOW (FRAME_ROOT_WINDOW (f)));
6501}
6502
6503 5972
6504/*********************************************************************** 5973/***********************************************************************
6505 Marginal Areas 5974 Marginal Areas
@@ -6635,8 +6104,8 @@ Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
6635 Scroll bars 6104 Scroll bars
6636 ***********************************************************************/ 6105 ***********************************************************************/
6637 6106
6638DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars, Sset_window_scroll_bars, 6107DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
6639 2, 4, 0, 6108 Sset_window_scroll_bars, 2, 4, 0,
6640 doc: /* Set width and type of scroll bars of window WINDOW. 6109 doc: /* Set width and type of scroll bars of window WINDOW.
6641If window is nil, set scroll bars of the currently selected window. 6110If window is nil, set scroll bars of the currently selected window.
6642Second parameter WIDTH specifies the pixel width for the scroll bar; 6111Second parameter WIDTH specifies the pixel width for the scroll bar;
@@ -6859,116 +6328,81 @@ freeze_window_starts (struct frame *f, int freeze_p)
6859 Initialization 6328 Initialization
6860 ***********************************************************************/ 6329 ***********************************************************************/
6861 6330
6862/* Return 1 if window configurations C1 and C2 6331/* Return 1 if window configurations CONFIGURATION1 and CONFIGURATION2
6863 describe the same state of affairs. This is used by Fequal. */ 6332 describe the same state of affairs. This is used by Fequal.
6333
6334 ignore_positions non-zero means ignore non-matching scroll positions
6335 and the like.
6336
6337 This ignores a couple of things like the dedicatedness status of
6338 window, splits, nest and the like. This might have to be fixed. */
6864 6339
6865int 6340int
6866compare_window_configurations (Lisp_Object c1, Lisp_Object c2, int ignore_positions) 6341compare_window_configurations (Lisp_Object configuration1, Lisp_Object configuration2, int ignore_positions)
6867{ 6342{
6868 register struct save_window_data *d1, *d2; 6343 register struct save_window_data *d1, *d2;
6869 struct Lisp_Vector *sw1, *sw2; 6344 struct Lisp_Vector *sws1, *sws2;
6870 int i; 6345 int i;
6871 6346
6872 CHECK_WINDOW_CONFIGURATION (c1); 6347 CHECK_WINDOW_CONFIGURATION (configuration1);
6873 CHECK_WINDOW_CONFIGURATION (c2); 6348 CHECK_WINDOW_CONFIGURATION (configuration2);
6874 6349
6875 d1 = (struct save_window_data *) XVECTOR (c1); 6350 d1 = (struct save_window_data *) XVECTOR (configuration1);
6876 d2 = (struct save_window_data *) XVECTOR (c2); 6351 d2 = (struct save_window_data *) XVECTOR (configuration2);
6877 sw1 = XVECTOR (d1->saved_windows); 6352 sws1 = XVECTOR (d1->saved_windows);
6878 sw2 = XVECTOR (d2->saved_windows); 6353 sws2 = XVECTOR (d2->saved_windows);
6879 6354
6880 if (d1->frame_cols != d2->frame_cols) 6355 /* Frame settings must match. */
6881 return 0; 6356 if (d1->frame_cols != d2->frame_cols
6882 if (d1->frame_lines != d2->frame_lines) 6357 || d1->frame_lines != d2->frame_lines
6883 return 0; 6358 || d1->frame_menu_bar_lines != d2->frame_menu_bar_lines
6884 if (d1->frame_menu_bar_lines != d2->frame_menu_bar_lines) 6359 || !EQ (d1->selected_frame, d2->selected_frame)
6360 || !EQ (d1->current_buffer, d2->current_buffer)
6361 || (!ignore_positions
6362 && (!EQ (d1->minibuf_scroll_window, d2->minibuf_scroll_window)
6363 || !EQ (d1->minibuf_selected_window, d2->minibuf_selected_window)))
6364 || !EQ (d1->focus_frame, d2->focus_frame)
6365 /* Verify that the two configurations have the same number of windows. */
6366 || sws1->header.size != sws2->header.size)
6885 return 0; 6367 return 0;
6886 if (! EQ (d1->selected_frame, d2->selected_frame))
6887 return 0;
6888 /* Don't compare the current_window field directly.
6889 Instead see w1_is_current and w2_is_current, below. */
6890 if (! EQ (d1->current_buffer, d2->current_buffer))
6891 return 0;
6892 if (! ignore_positions)
6893 {
6894 if (! EQ (d1->minibuf_scroll_window, d2->minibuf_scroll_window))
6895 return 0;
6896 if (! EQ (d1->minibuf_selected_window, d2->minibuf_selected_window))
6897 return 0;
6898 }
6899 /* Don't compare the root_window field.
6900 We don't require the two configurations
6901 to use the same window object,
6902 and the two root windows must be equivalent
6903 if everything else compares equal. */
6904 if (! EQ (d1->focus_frame, d2->focus_frame))
6905 return 0;
6906
6907 /* Verify that the two confis have the same number of windows. */
6908 if (sw1->size != sw2->size)
6909 return 0;
6910
6911 for (i = 0; i < sw1->size; i++)
6912 {
6913 struct saved_window *p1, *p2;
6914 int w1_is_current, w2_is_current;
6915 6368
6916 p1 = SAVED_WINDOW_N (sw1, i); 6369 for (i = 0; i < sws1->header.size; i++)
6917 p2 = SAVED_WINDOW_N (sw2, i); 6370 {
6918 6371 struct saved_window *sw1, *sw2;
6919 /* Verify that the current windows in the two 6372
6920 configurations correspond to each other. */ 6373 sw1 = SAVED_WINDOW_N (sws1, i);
6921 w1_is_current = EQ (d1->current_window, p1->window); 6374 sw2 = SAVED_WINDOW_N (sws2, i);
6922 w2_is_current = EQ (d2->current_window, p2->window); 6375
6923 6376 if (
6924 if (w1_is_current != w2_is_current) 6377 /* The "current" windows in the two configurations must
6925 return 0; 6378 correspond to each other. */
6926 6379 EQ (d1->current_window, sw1->window)
6927 /* Verify that the corresponding windows do match. */ 6380 != EQ (d2->current_window, sw2->window)
6928 if (! EQ (p1->buffer, p2->buffer)) 6381 /* Windows' buffers must match. */
6929 return 0; 6382 || !EQ (sw1->buffer, sw2->buffer)
6930 if (! EQ (p1->left_col, p2->left_col)) 6383 || !EQ (sw1->left_col, sw2->left_col)
6931 return 0; 6384 || !EQ (sw1->top_line, sw2->top_line)
6932 if (! EQ (p1->top_line, p2->top_line)) 6385 || !EQ (sw1->total_cols, sw2->total_cols)
6933 return 0; 6386 || !EQ (sw1->total_lines, sw2->total_lines)
6934 if (! EQ (p1->total_cols, p2->total_cols)) 6387 || !EQ (sw1->display_table, sw2->display_table)
6935 return 0; 6388 /* The next two disjuncts check the window structure for
6936 if (! EQ (p1->total_lines, p2->total_lines)) 6389 equality. */
6937 return 0; 6390 || !EQ (sw1->parent, sw2->parent)
6938 if (! EQ (p1->display_table, p2->display_table)) 6391 || !EQ (sw1->prev, sw2->prev)
6939 return 0; 6392 || (!ignore_positions
6940 if (! EQ (p1->parent, p2->parent)) 6393 && (!EQ (sw1->hscroll, sw2->hscroll)
6941 return 0; 6394 || !EQ (sw1->min_hscroll, sw2->min_hscroll)
6942 if (! EQ (p1->prev, p2->prev)) 6395 || !EQ (sw1->start_at_line_beg, sw2->start_at_line_beg)
6943 return 0; 6396 || NILP (Fequal (sw1->start, sw2->start))
6944 if (! ignore_positions) 6397 || NILP (Fequal (sw1->pointm, sw2->pointm))
6945 { 6398 || NILP (Fequal (sw1->mark, sw2->mark))))
6946 if (! EQ (p1->hscroll, p2->hscroll)) 6399 || !EQ (sw1->left_margin_cols, sw2->left_margin_cols)
6947 return 0; 6400 || !EQ (sw1->right_margin_cols, sw2->right_margin_cols)
6948 if (!EQ (p1->min_hscroll, p2->min_hscroll)) 6401 || !EQ (sw1->left_fringe_width, sw2->left_fringe_width)
6949 return 0; 6402 || !EQ (sw1->right_fringe_width, sw2->right_fringe_width)
6950 if (! EQ (p1->start_at_line_beg, p2->start_at_line_beg)) 6403 || !EQ (sw1->fringes_outside_margins, sw2->fringes_outside_margins)
6951 return 0; 6404 || !EQ (sw1->scroll_bar_width, sw2->scroll_bar_width)
6952 if (NILP (Fequal (p1->start, p2->start))) 6405 || !EQ (sw1->vertical_scroll_bar_type, sw2->vertical_scroll_bar_type))
6953 return 0;
6954 if (NILP (Fequal (p1->pointm, p2->pointm)))
6955 return 0;
6956 if (NILP (Fequal (p1->mark, p2->mark)))
6957 return 0;
6958 }
6959 if (! EQ (p1->left_margin_cols, p2->left_margin_cols))
6960 return 0;
6961 if (! EQ (p1->right_margin_cols, p2->right_margin_cols))
6962 return 0;
6963 if (! EQ (p1->left_fringe_width, p2->left_fringe_width))
6964 return 0;
6965 if (! EQ (p1->right_fringe_width, p2->right_fringe_width))
6966 return 0;
6967 if (! EQ (p1->fringes_outside_margins, p2->fringes_outside_margins))
6968 return 0;
6969 if (! EQ (p1->scroll_bar_width, p2->scroll_bar_width))
6970 return 0;
6971 if (! EQ (p1->vertical_scroll_bar_type, p2->vertical_scroll_bar_type))
6972 return 0; 6406 return 0;
6973 } 6407 }
6974 6408
@@ -7021,10 +6455,6 @@ syms_of_window (void)
7021 Fput (Qscroll_up, Qscroll_command, Qt); 6455 Fput (Qscroll_up, Qscroll_command, Qt);
7022 Fput (Qscroll_down, Qscroll_command, Qt); 6456 Fput (Qscroll_down, Qscroll_command, Qt);
7023 6457
7024 Qwindow_size_fixed = intern_c_string ("window-size-fixed");
7025 staticpro (&Qwindow_size_fixed);
7026 Fset (Qwindow_size_fixed, Qnil);
7027
7028 staticpro (&Qwindow_configuration_change_hook); 6458 staticpro (&Qwindow_configuration_change_hook);
7029 Qwindow_configuration_change_hook 6459 Qwindow_configuration_change_hook
7030 = intern_c_string ("window-configuration-change-hook"); 6460 = intern_c_string ("window-configuration-change-hook");
@@ -7038,12 +6468,45 @@ syms_of_window (void)
7038 Qwindow_live_p = intern_c_string ("window-live-p"); 6468 Qwindow_live_p = intern_c_string ("window-live-p");
7039 staticpro (&Qwindow_live_p); 6469 staticpro (&Qwindow_live_p);
7040 6470
6471 Qwindow_deletable_p = intern_c_string ("window-deletable-p");
6472 staticpro (&Qwindow_deletable_p);
6473
6474 Qdelete_window = intern_c_string ("delete-window");
6475 staticpro (&Qdelete_window);
6476
6477 Qresize_root_window = intern_c_string ("resize-root-window");
6478 staticpro (&Qresize_root_window);
6479
6480 Qresize_root_window_vertically = intern_c_string ("resize-root-window-vertically");
6481 staticpro (&Qresize_root_window_vertically);
6482
6483 Qsafe = intern_c_string ("safe");
6484 staticpro (&Qsafe);
6485
7041 Qdisplay_buffer = intern_c_string ("display-buffer"); 6486 Qdisplay_buffer = intern_c_string ("display-buffer");
7042 staticpro (&Qdisplay_buffer); 6487 staticpro (&Qdisplay_buffer);
7043 6488
6489 Qreplace_buffer_in_windows = intern_c_string ("replace-buffer-in-windows");
6490 staticpro (&Qreplace_buffer_in_windows);
6491
6492 Qrecord_window_buffer = intern_c_string ("record-window-buffer");
6493 staticpro (&Qrecord_window_buffer);
6494
6495 Qget_mru_window = intern_c_string ("get-mru-window");
6496 staticpro (&Qget_mru_window);
6497
7044 Qtemp_buffer_show_hook = intern_c_string ("temp-buffer-show-hook"); 6498 Qtemp_buffer_show_hook = intern_c_string ("temp-buffer-show-hook");
7045 staticpro (&Qtemp_buffer_show_hook); 6499 staticpro (&Qtemp_buffer_show_hook);
7046 6500
6501 Qabove = intern_c_string ("above");
6502 staticpro (&Qabove);
6503
6504 Qbelow = intern_c_string ("below");
6505 staticpro (&Qbelow);
6506
6507 Qauto_buffer_name = intern_c_string ("auto-buffer-name");
6508 staticpro (&Qauto_buffer_name);
6509
7047 staticpro (&Vwindow_list); 6510 staticpro (&Vwindow_list);
7048 6511
7049 minibuf_selected_window = Qnil; 6512 minibuf_selected_window = Qnil;
@@ -7062,6 +6525,16 @@ If this function is used, then it must do the entire job of showing
7062the buffer; `temp-buffer-show-hook' is not run unless this function runs it. */); 6525the buffer; `temp-buffer-show-hook' is not run unless this function runs it. */);
7063 Vtemp_buffer_show_function = Qnil; 6526 Vtemp_buffer_show_function = Qnil;
7064 6527
6528 DEFVAR_LISP ("temp-buffer-show-specifiers", Vtemp_buffer_show_specifiers,
6529 doc: /* Buffer display specifiers used by `with-output-to-temp-buffer'.
6530These specifiers are passed by `with-output-to-temp-buffer' as second
6531argument to `display-buffer'. Applications should only let-bind this
6532around a call to `with-output-to-temp-buffer'.
6533
6534For a description of buffer display specifiers see the variable
6535`display-buffer-alist'. */);
6536 Vtemp_buffer_show_specifiers = Qnil;
6537
7065 DEFVAR_LISP ("minibuffer-scroll-window", Vminibuf_scroll_window, 6538 DEFVAR_LISP ("minibuffer-scroll-window", Vminibuf_scroll_window,
7066 doc: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */); 6539 doc: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */);
7067 Vminibuf_scroll_window = Qnil; 6540 Vminibuf_scroll_window = Qnil;
@@ -7077,34 +6550,16 @@ is displayed in the `mode-line' face. */);
7077 Vother_window_scroll_buffer = Qnil; 6550 Vother_window_scroll_buffer = Qnil;
7078 6551
7079 DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p, 6552 DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p,
7080 doc: /* *Non-nil means to automatically adjust `window-vscroll' to view tall lines. */); 6553 doc: /* Non-nil means to automatically adjust `window-vscroll' to view tall lines. */);
7081 auto_window_vscroll_p = 1; 6554 auto_window_vscroll_p = 1;
7082 6555
7083 DEFVAR_INT ("next-screen-context-lines", next_screen_context_lines, 6556 DEFVAR_INT ("next-screen-context-lines", next_screen_context_lines,
7084 doc: /* *Number of lines of continuity when scrolling by screenfuls. */); 6557 doc: /* Number of lines of continuity when scrolling by screenfuls. */);
7085 next_screen_context_lines = 2; 6558 next_screen_context_lines = 2;
7086 6559
7087 DEFVAR_INT ("window-min-height", window_min_height,
7088 doc: /* Allow deleting windows less than this tall.
7089The value is measured in line units. If a window wants a modeline it
7090is counted as one line.
7091
7092Emacs honors settings of this variable when enlarging or shrinking
7093windows vertically. A value less than 1 is invalid. */);
7094 window_min_height = 4;
7095
7096 DEFVAR_INT ("window-min-width", window_min_width,
7097 doc: /* Allow deleting windows less than this wide.
7098The value is measured in characters and includes any fringes or
7099the scrollbar.
7100
7101Emacs honors settings of this variable when enlarging or shrinking
7102windows horizontally. A value less than 2 is invalid. */);
7103 window_min_width = 10;
7104
7105 DEFVAR_LISP ("scroll-preserve-screen-position", 6560 DEFVAR_LISP ("scroll-preserve-screen-position",
7106 Vscroll_preserve_screen_position, 6561 Vscroll_preserve_screen_position,
7107 doc: /* *Controls if scroll commands move point to keep its screen position unchanged. 6562 doc: /* Controls if scroll commands move point to keep its screen position unchanged.
7108A value of nil means point does not keep its screen position except 6563A value of nil means point does not keep its screen position except
7109at the scroll margin or window boundary respectively. 6564at the scroll margin or window boundary respectively.
7110A value of t means point keeps its screen position if the scroll 6565A value of t means point keeps its screen position if the scroll
@@ -7133,18 +6588,76 @@ will redraw the entire frame; the special value `tty' causes the
7133frame to be redrawn only if it is a tty frame. */); 6588frame to be redrawn only if it is a tty frame. */);
7134 Vrecenter_redisplay = Qtty; 6589 Vrecenter_redisplay = Qtty;
7135 6590
6591 DEFVAR_LISP ("window-splits", Vwindow_splits,
6592 doc: /* Non-nil means splitting windows is handled specially.
6593If this variable is nil, splitting a window gets the entire screen space
6594for displaying the new window from the window to split. If this
6595variable is non-nil, splitting a window may resize all windows in the
6596same combination. This also allows to split a window that is otherwise
6597too small or of fixed size.
6598
6599The value of this variable is also assigned to the split status of the
6600new window and, provided the old and new window form a new combination,
6601to the window that was split as well. The split status of a window can
6602be retrieved with the function `window-splits' and altered by the
6603function `set-window-splits'.
6604
6605If the value of the variable `window-nest' is non-nil, the space for the
6606new window is exclusively taken from the window that shall be split, but
6607the split status of the window that is split as well as that of the new
6608window are still set to the value of this variable. */);
6609 Vwindow_splits = Qnil;
6610
6611 DEFVAR_LISP ("window-nest", Vwindow_nest,
6612 doc: /* Non-nil means splitting a window makes a new parent window.
6613If this variable is nil, splitting a window will create a new parent
6614window only if the window has no parent window or the window shall
6615become a combination orthogonal to the one it it is part of.
6616
6617If this variable is non-nil, splitting a window always creates a new
6618parent window. If all splits behave this way, each frame's window tree
6619is a binary tree and every window but the frame's root window has
6620exactly one sibling.
6621
6622The value of this variable is also assigned to the nest status of the
6623new parent window. The nest status of a window can be retrieved via the
6624function `window-nest' and altered by the function `set-window-nest'. */);
6625 Vwindow_nest = Qnil;
7136 6626
7137 defsubr (&Sselected_window); 6627 defsubr (&Sselected_window);
7138 defsubr (&Sminibuffer_window); 6628 defsubr (&Sminibuffer_window);
7139 defsubr (&Swindow_minibuffer_p); 6629 defsubr (&Swindow_minibuffer_p);
7140 defsubr (&Swindowp); 6630 defsubr (&Swindowp);
7141 defsubr (&Swindow_live_p); 6631 defsubr (&Swindow_live_p);
6632 defsubr (&Swindow_frame);
6633 defsubr (&Sframe_root_window);
6634 defsubr (&Sframe_first_window);
6635 defsubr (&Sframe_selected_window);
6636 defsubr (&Sset_frame_selected_window);
7142 defsubr (&Spos_visible_in_window_p); 6637 defsubr (&Spos_visible_in_window_p);
7143 defsubr (&Swindow_line_height); 6638 defsubr (&Swindow_line_height);
6639 defsubr (&Swindow_clone_number);
7144 defsubr (&Swindow_buffer); 6640 defsubr (&Swindow_buffer);
7145 defsubr (&Swindow_height); 6641 defsubr (&Swindow_parent);
7146 defsubr (&Swindow_width); 6642 defsubr (&Swindow_vchild);
7147 defsubr (&Swindow_full_width_p); 6643 defsubr (&Swindow_hchild);
6644 defsubr (&Swindow_next);
6645 defsubr (&Swindow_prev);
6646 defsubr (&Swindow_splits);
6647 defsubr (&Sset_window_splits);
6648 defsubr (&Swindow_nest);
6649 defsubr (&Sset_window_nest);
6650 defsubr (&Swindow_use_time);
6651 defsubr (&Swindow_top_line);
6652 defsubr (&Swindow_left_column);
6653 defsubr (&Swindow_total_size);
6654 defsubr (&Swindow_normal_size);
6655 defsubr (&Swindow_new_total);
6656 defsubr (&Swindow_new_normal);
6657 defsubr (&Sset_window_new_total);
6658 defsubr (&Sset_window_new_normal);
6659 defsubr (&Sresize_window_apply);
6660 defsubr (&Swindow_body_size);
7148 defsubr (&Swindow_hscroll); 6661 defsubr (&Swindow_hscroll);
7149 defsubr (&Sset_window_hscroll); 6662 defsubr (&Sset_window_hscroll);
7150 defsubr (&Swindow_redisplay_end_trigger); 6663 defsubr (&Swindow_redisplay_end_trigger);
@@ -7168,22 +6681,17 @@ frame to be redrawn only if it is a tty frame. */);
7168 defsubr (&Sset_window_display_table); 6681 defsubr (&Sset_window_display_table);
7169 defsubr (&Snext_window); 6682 defsubr (&Snext_window);
7170 defsubr (&Sprevious_window); 6683 defsubr (&Sprevious_window);
7171 defsubr (&Sother_window);
7172 defsubr (&Sget_lru_window);
7173 defsubr (&Swindow_use_time);
7174 defsubr (&Sget_largest_window);
7175 defsubr (&Sget_buffer_window); 6684 defsubr (&Sget_buffer_window);
7176 defsubr (&Sdelete_other_windows); 6685 defsubr (&Sdelete_other_windows_internal);
7177 defsubr (&Sdelete_windows_on); 6686 defsubr (&Sdelete_window_internal);
7178 defsubr (&Sreplace_buffer_in_windows); 6687 defsubr (&Sresize_mini_window_internal);
7179 defsubr (&Sdelete_window);
7180 defsubr (&Sset_window_buffer); 6688 defsubr (&Sset_window_buffer);
6689 defsubr (&Sset_window_clone_number);
6690 defsubr (&Srun_window_configuration_change_hook);
7181 defsubr (&Sselect_window); 6691 defsubr (&Sselect_window);
7182 defsubr (&Sforce_window_update); 6692 defsubr (&Sforce_window_update);
7183 defsubr (&Ssplit_window); 6693 defsubr (&Stemp_output_buffer_show);
7184 defsubr (&Senlarge_window); 6694 defsubr (&Ssplit_window_internal);
7185 defsubr (&Sshrink_window);
7186 defsubr (&Sadjust_window_trailing_edge);
7187 defsubr (&Sscroll_up); 6695 defsubr (&Sscroll_up);
7188 defsubr (&Sscroll_down); 6696 defsubr (&Sscroll_down);
7189 defsubr (&Sscroll_left); 6697 defsubr (&Sscroll_left);
@@ -7198,8 +6706,6 @@ frame to be redrawn only if it is a tty frame. */);
7198 defsubr (&Swindow_configuration_frame); 6706 defsubr (&Swindow_configuration_frame);
7199 defsubr (&Sset_window_configuration); 6707 defsubr (&Sset_window_configuration);
7200 defsubr (&Scurrent_window_configuration); 6708 defsubr (&Scurrent_window_configuration);
7201 defsubr (&Ssave_window_excursion);
7202 defsubr (&Swindow_tree);
7203 defsubr (&Sset_window_margins); 6709 defsubr (&Sset_window_margins);
7204 defsubr (&Swindow_margins); 6710 defsubr (&Swindow_margins);
7205 defsubr (&Sset_window_fringes); 6711 defsubr (&Sset_window_fringes);
@@ -7210,20 +6716,19 @@ frame to be redrawn only if it is a tty frame. */);
7210 defsubr (&Sset_window_vscroll); 6716 defsubr (&Sset_window_vscroll);
7211 defsubr (&Scompare_window_configurations); 6717 defsubr (&Scompare_window_configurations);
7212 defsubr (&Swindow_list); 6718 defsubr (&Swindow_list);
6719 defsubr (&Swindow_list_1);
6720 defsubr (&Swindow_prev_buffers);
6721 defsubr (&Sset_window_prev_buffers);
6722 defsubr (&Swindow_next_buffers);
6723 defsubr (&Sset_window_next_buffers);
7213 defsubr (&Swindow_parameters); 6724 defsubr (&Swindow_parameters);
7214 defsubr (&Swindow_parameter); 6725 defsubr (&Swindow_parameter);
7215 defsubr (&Sset_window_parameter); 6726 defsubr (&Sset_window_parameter);
7216
7217} 6727}
7218 6728
7219void 6729void
7220keys_of_window (void) 6730keys_of_window (void)
7221{ 6731{
7222 initial_define_key (control_x_map, '1', "delete-other-windows");
7223 initial_define_key (control_x_map, '2', "split-window");
7224 initial_define_key (control_x_map, '0', "delete-window");
7225 initial_define_key (control_x_map, 'o', "other-window");
7226 initial_define_key (control_x_map, '^', "enlarge-window");
7227 initial_define_key (control_x_map, '<', "scroll-left"); 6732 initial_define_key (control_x_map, '<', "scroll-left");
7228 initial_define_key (control_x_map, '>', "scroll-right"); 6733 initial_define_key (control_x_map, '>', "scroll-right");
7229 6734
@@ -7231,4 +6736,3 @@ keys_of_window (void)
7231 initial_define_key (meta_map, Ctl ('V'), "scroll-other-window"); 6736 initial_define_key (meta_map, Ctl ('V'), "scroll-other-window");
7232 initial_define_key (meta_map, 'v', "scroll-down-command"); 6737 initial_define_key (meta_map, 'v', "scroll-down-command");
7233} 6738}
7234