1 /* Window creation, deletion and examination for GNU Emacs.
2 Does not include redisplay.
3 Copyright (C) 1985-1987, 1993-1998, 2000-2011
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
35 #include "dispextern.h"
36 #include "blockinput.h"
37 #include "intervals.h"
38 #include "termhooks.h" /* For FRAME_TERMINAL. */
42 #endif /* HAVE_X_WINDOWS */
53 Lisp_Object Qwindowp
, Qwindow_live_p
;
54 static Lisp_Object Qwindow_configuration_p
, Qrecord_window_buffer
;
55 static Lisp_Object Qwindow_deletable_p
, Qdelete_window
, Qdisplay_buffer
;
56 static Lisp_Object Qreplace_buffer_in_windows
, Qget_mru_window
;
57 static Lisp_Object Qresize_root_window
, Qresize_root_window_vertically
;
58 static Lisp_Object Qscroll_up
, Qscroll_down
, Qscroll_command
;
59 static Lisp_Object Qsafe
, Qabove
, Qbelow
;
60 static Lisp_Object Qauto_buffer_name
;
62 static Lisp_Object Qwindow_size_fixed
;
64 static int displayed_window_lines (struct window
*);
65 static struct window
*decode_window (Lisp_Object
);
66 static int count_windows (struct window
*);
67 static int get_leaf_windows (struct window
*, struct window
**, int);
68 static void window_scroll (Lisp_Object
, int, int, int);
69 static void window_scroll_pixel_based (Lisp_Object
, int, int, int);
70 static void window_scroll_line_based (Lisp_Object
, int, int, int);
71 static int window_min_size_1 (struct window
*, int, int);
72 static int window_min_size_2 (struct window
*, int, int);
73 static int window_min_size (struct window
*, int, int, int, int *);
74 static void size_window (Lisp_Object
, int, int, int, int, int);
75 static int freeze_window_start (struct window
*, void *);
76 static int window_fixed_size_p (struct window
*, int, int);
77 static void enlarge_window (Lisp_Object
, int, int);
78 static Lisp_Object
window_list (void);
79 static int add_window_to_list (struct window
*, void *);
80 static int candidate_window_p (Lisp_Object
, Lisp_Object
, Lisp_Object
,
82 static Lisp_Object
next_window (Lisp_Object
, Lisp_Object
,
84 static void decode_next_window_args (Lisp_Object
*, Lisp_Object
*,
86 static void foreach_window (struct frame
*,
87 int (* fn
) (struct window
*, void *),
89 static int foreach_window_1 (struct window
*,
90 int (* fn
) (struct window
*, void *),
92 static Lisp_Object
window_list_1 (Lisp_Object
, Lisp_Object
, Lisp_Object
);
93 static Lisp_Object
select_window (Lisp_Object
, Lisp_Object
, int);
95 /* This is the window in which the terminal's cursor should
96 be left when nothing is being done with it. This must
97 always be a leaf window, and its buffer is selected by
98 the top level editing loop at the end of each command.
100 This value is always the same as
101 FRAME_SELECTED_WINDOW (selected_frame). */
102 Lisp_Object selected_window
;
104 /* A list of all windows for use by next_window and Fwindow_list.
105 Functions creating or deleting windows should invalidate this cache
106 by setting it to nil. */
107 Lisp_Object Vwindow_list
;
109 /* The mini-buffer window of the selected frame.
110 Note that you cannot test for mini-bufferness of an arbitrary window
111 by comparing against this; but you can test for mini-bufferness of
112 the selected window. */
113 Lisp_Object minibuf_window
;
115 /* Non-nil means it is the window whose mode line should be
116 shown as the selected window when the minibuffer is selected. */
117 Lisp_Object minibuf_selected_window
;
119 /* Hook run at end of temp_output_buffer_show. */
120 static Lisp_Object Qtemp_buffer_show_hook
;
122 /* Incremented for each window created. */
123 static int sequence_number
;
125 /* Nonzero after init_window_once has finished. */
126 static int window_initialized
;
128 /* Hook to run when window config changes. */
129 static Lisp_Object Qwindow_configuration_change_hook
;
131 /* Incremented by 1 whenever a window is deleted. */
132 static int window_deletion_count
;
134 /* Used by the function window_scroll_pixel_based */
135 static int window_scroll_pixel_based_preserve_x
;
136 static int window_scroll_pixel_based_preserve_y
;
138 /* Same for window_scroll_line_based. */
139 static int window_scroll_preserve_hpos
;
140 static int window_scroll_preserve_vpos
;
142 static struct window
*
143 decode_window (register Lisp_Object window
)
146 return XWINDOW (selected_window
);
148 CHECK_LIVE_WINDOW (window
);
149 return XWINDOW (window
);
152 static struct window
*
153 decode_any_window (register Lisp_Object window
)
156 return XWINDOW (selected_window
);
158 CHECK_WINDOW (window
);
159 return XWINDOW (window
);
162 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
163 doc
: /* Return t if OBJECT is a window and nil otherwise. */)
166 return WINDOWP (object
) ? Qt
: Qnil
;
169 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
170 doc
: /* Return t if OBJECT is a live window and nil otherwise.
171 A live window is a window that displays a buffer. */)
174 return WINDOW_LIVE_P (object
) ? Qt
: Qnil
;
177 /* Frames and windows. */
178 DEFUN ("window-frame", Fwindow_frame
, Swindow_frame
, 1, 1, 0,
179 doc
: /* Return the frame that window WINDOW is on.
180 WINDOW can be any window and defaults to the selected one. */)
183 return decode_any_window (window
)->frame
;
186 DEFUN ("frame-root-window", Fframe_root_window
, Sframe_root_window
, 0, 1, 0,
187 doc
: /* Return the root window of FRAME_OR_WINDOW.
188 If omitted, FRAME_OR_WINDOW defaults to the currently selected frame.
189 Else if FRAME_OR_WINDOW denotes any window, return the root window of
190 that window's frame. If FRAME_OR_WINDOW denotes a live frame, return
191 the root window of that frame. */)
192 (Lisp_Object frame_or_window
)
196 if (NILP (frame_or_window
))
197 window
= SELECTED_FRAME ()->root_window
;
198 else if (WINDOWP (frame_or_window
))
199 window
= XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window
)))->root_window
;
202 CHECK_LIVE_FRAME (frame_or_window
);
203 window
= XFRAME (frame_or_window
)->root_window
;
209 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
210 doc
: /* Return the window used now for minibuffers.
211 If the optional argument FRAME is specified, return the minibuffer window
212 used by that frame. */)
216 frame
= selected_frame
;
217 CHECK_LIVE_FRAME (frame
);
218 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
221 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
,
222 Swindow_minibuffer_p
, 0, 1, 0,
223 doc
: /* Return non-nil if WINDOW is a minibuffer window.
224 WINDOW can be any window and defaults to the selected one. */)
227 return MINI_WINDOW_P (decode_any_window (window
)) ? Qt
: Qnil
;
230 /* Don't move this to window.el - this must be a safe routine. */
231 DEFUN ("frame-first-window", Fframe_first_window
, Sframe_first_window
, 0, 1, 0,
232 doc
: /* Return the topmost, leftmost live window on FRAME_OR_WINDOW.
233 If omitted, FRAME_OR_WINDOW defaults to the currently selected frame.
234 Else if FRAME_OR_WINDOW denotes any window, return the first window of
235 that window's frame. If FRAME_OR_WINDOW denotes a live frame, return
236 the first window of that frame. */)
237 (Lisp_Object frame_or_window
)
241 if (NILP (frame_or_window
))
242 window
= SELECTED_FRAME ()->root_window
;
243 else if (WINDOWP (frame_or_window
))
244 window
= XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window
)))->root_window
;
247 CHECK_LIVE_FRAME (frame_or_window
);
248 window
= XFRAME (frame_or_window
)->root_window
;
251 while (NILP (XWINDOW (window
)->buffer
))
253 if (! NILP (XWINDOW (window
)->hchild
))
254 window
= XWINDOW (window
)->hchild
;
255 else if (! NILP (XWINDOW (window
)->vchild
))
256 window
= XWINDOW (window
)->vchild
;
264 DEFUN ("frame-selected-window", Fframe_selected_window
,
265 Sframe_selected_window
, 0, 1, 0,
266 doc
: /* Return the selected window of FRAME_OR_WINDOW.
267 If omitted, FRAME_OR_WINDOW defaults to the currently selected frame.
268 Else if FRAME_OR_WINDOW denotes any window, return the selected window
269 of that window's frame. If FRAME_OR_WINDOW denotes a live frame, return
270 the selected window of that frame. */)
271 (Lisp_Object frame_or_window
)
275 if (NILP (frame_or_window
))
276 window
= SELECTED_FRAME ()->selected_window
;
277 else if (WINDOWP (frame_or_window
))
278 window
= XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window
)))->selected_window
;
281 CHECK_LIVE_FRAME (frame_or_window
);
282 window
= XFRAME (frame_or_window
)->selected_window
;
288 DEFUN ("set-frame-selected-window", Fset_frame_selected_window
,
289 Sset_frame_selected_window
, 2, 3, 0,
290 doc
: /* Set selected window of FRAME to WINDOW.
291 FRAME must be a live frame and defaults to the selected one. If FRAME
292 is the selected frame, this makes WINDOW the selected window. Optional
293 argument NORECORD non-nil means to neither change the order of recently
294 selected windows nor the buffer list. WINDOW must denote a live window.
296 (Lisp_Object frame
, Lisp_Object window
, Lisp_Object norecord
)
299 frame
= selected_frame
;
301 CHECK_LIVE_FRAME (frame
);
302 CHECK_LIVE_WINDOW (window
);
304 if (! EQ (frame
, WINDOW_FRAME (XWINDOW (window
))))
305 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
307 if (EQ (frame
, selected_frame
))
308 return Fselect_window (window
, norecord
);
310 return XFRAME (frame
)->selected_window
= window
;
313 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
314 doc
: /* Return the selected window.
315 The selected window is the window in which the standard cursor for
316 selected windows appears and to which many commands apply. */)
319 return selected_window
;
322 /* If select_window is called with inhibit_point_swap non-zero it will
323 not store point of the old selected window's buffer back into that
324 window's pointm slot. This is needed by Fset_window_configuration to
325 avoid that the display routine is called with selected_window set to
326 Qnil causing a subsequent crash. */
328 select_window (Lisp_Object window
, Lisp_Object norecord
, int inhibit_point_swap
)
330 register struct window
*w
;
331 register struct window
*ow
;
334 CHECK_LIVE_WINDOW (window
);
336 w
= XWINDOW (window
);
337 w
->frozen_window_start_p
= 0;
341 ++window_select_count
;
342 XSETFASTINT (w
->use_time
, window_select_count
);
343 record_buffer (w
->buffer
);
346 if (EQ (window
, selected_window
) && !inhibit_point_swap
)
349 sf
= SELECTED_FRAME ();
350 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
352 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
353 /* Use this rather than Fhandle_switch_frame
354 so that FRAME_FOCUS_FRAME is moved appropriately as we
355 move around in the state where a minibuffer in a separate
357 Fselect_frame (WINDOW_FRAME (w
), norecord
);
358 /* Fselect_frame called us back so we've done all the work already. */
359 eassert (EQ (window
, selected_window
));
363 sf
->selected_window
= window
;
365 /* Store the current buffer's actual point into the
366 old selected window. It belongs to that window,
367 and when the window is not selected, must be in the window. */
368 if (!inhibit_point_swap
)
370 ow
= XWINDOW (selected_window
);
371 if (! NILP (ow
->buffer
))
372 set_marker_both (ow
->pointm
, ow
->buffer
,
373 BUF_PT (XBUFFER (ow
->buffer
)),
374 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
377 selected_window
= window
;
379 Fset_buffer (w
->buffer
);
381 BVAR (XBUFFER (w
->buffer
), last_selected_window
) = window
;
383 /* Go to the point recorded in the window.
384 This is important when the buffer is in more
385 than one window. It also matters when
386 redisplay_window has altered point after scrolling,
387 because it makes the change only in the window. */
389 register EMACS_INT new_point
= marker_position (w
->pointm
);
390 if (new_point
< BEGV
)
392 else if (new_point
> ZV
)
398 windows_or_buffers_changed
++;
402 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 2, 0,
403 doc
: /* Select WINDOW. Most editing will apply to WINDOW's buffer.
404 Also make WINDOW's buffer current and make WINDOW the frame's selected
405 window. Return WINDOW.
407 Optional second arg NORECORD non-nil means do not put this buffer at the
408 front of the buffer list and do not make this window the most recently
411 Note that the main editor command loop sets the current buffer to the
412 buffer of the selected window before each command. */)
413 (register Lisp_Object window
, Lisp_Object norecord
)
415 return select_window (window
, norecord
, 0);
418 DEFUN ("window-clone-number", Fwindow_clone_number
, Swindow_clone_number
, 0, 1, 0,
419 doc
: /* Return WINDOW's clone number.
420 WINDOW can be any window and defaults to the selected one. */)
423 return decode_any_window (window
)->clone_number
;
426 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
427 doc
: /* Return the buffer that WINDOW is displaying.
428 WINDOW can be any window and defaults to the selected one.
429 If WINDOW is an internal window return nil. */)
432 return decode_any_window (window
)->buffer
;
435 DEFUN ("window-parent", Fwindow_parent
, Swindow_parent
, 0, 1, 0,
436 doc
: /* Return WINDOW's parent window.
437 WINDOW can be any window and defaults to the selected one.
438 Return nil if WINDOW has no parent. */)
441 return decode_any_window (window
)->parent
;
444 DEFUN ("window-vchild", Fwindow_vchild
, Swindow_vchild
, 0, 1, 0,
445 doc
: /* Return WINDOW's first vertical child window.
446 WINDOW can be any window and defaults to the selected one.
447 Return nil if WINDOW has no vertical child. */)
450 return decode_any_window (window
)->vchild
;
453 DEFUN ("window-hchild", Fwindow_hchild
, Swindow_hchild
, 0, 1, 0,
454 doc
: /* Return WINDOW's first horizontal child window.
455 WINDOW can be any window and defaults to the selected one.
456 Return nil if WINDOW has no horizontal child. */)
459 return decode_any_window (window
)->hchild
;
462 DEFUN ("window-next", Fwindow_next
, Swindow_next
, 0, 1, 0,
463 doc
: /* Return WINDOW's right sibling window.
464 WINDOW can be any window and defaults to the selected one.
465 Return nil if WINDOW has no right sibling. */)
468 return decode_any_window (window
)->next
;
471 DEFUN ("window-prev", Fwindow_prev
, Swindow_prev
, 0, 1, 0,
472 doc
: /* Return WINDOW's left sibling window.
473 WINDOW can be any window and defaults to the selected one.
474 Return nil if WINDOW has no left sibling. */)
477 return decode_any_window (window
)->prev
;
480 DEFUN ("window-splits", Fwindow_splits
, Swindow_splits
, 0, 1, 0,
481 doc
: /* Return splits status for WINDOW.
482 WINDOW can be any window and defaults to the selected one.
484 If the value returned by this function is nil and WINDOW is resized, the
485 corresponding space is preferably taken from (or given to) WINDOW's
486 right sibling. When WINDOW is deleted, its space is given to its left
489 If the value returned by this function is non-nil, resizing and deleting
490 WINDOW may resize all windows in the same combination. */)
493 return decode_any_window (window
)->splits
;
496 DEFUN ("set-window-splits", Fset_window_splits
, Sset_window_splits
, 2, 2, 0,
497 doc
: /* Set splits status of WINDOW to STATUS.
498 WINDOW can be any window and defaults to the selected one. Return
501 If STATUS is nil and WINDOW is later resized, the corresponding space is
502 preferably taken from (or given to) WINDOW's right sibling. When WINDOW
503 is deleted, its space is given to its left sibling.
505 If STATUS is non-nil, resizing and deleting WINDOW may resize all
506 windows in the same combination. */)
507 (Lisp_Object window
, Lisp_Object status
)
509 register struct window
*w
= decode_any_window (window
);
516 DEFUN ("window-nest", Fwindow_nest
, Swindow_nest
, 0, 1, 0,
517 doc
: /* Return nest status of WINDOW.
518 WINDOW can be any window and defaults to the selected one.
520 If the return value is nil, subwindows of WINDOW can be recombined with
521 WINDOW's siblings. A return value of non-nil means that subwindows of
522 WINDOW are never \(re-)combined with WINDOW's siblings. */)
525 return decode_any_window (window
)->nest
;
528 DEFUN ("set-window-nest", Fset_window_nest
, Sset_window_nest
, 2, 2, 0,
529 doc
: /* Set nest status of WINDOW to STATUS.
530 WINDOW can be any window and defaults to the selected one. Return
533 If STATUS is nil, subwindows of WINDOW can be recombined with WINDOW's
534 siblings. STATUS non-nil means that subwindows of WINDOW are never
535 \(re-)combined with WINDOW's siblings. */)
536 (Lisp_Object window
, Lisp_Object status
)
538 register struct window
*w
= decode_any_window (window
);
545 DEFUN ("window-use-time", Fwindow_use_time
, Swindow_use_time
, 0, 1, 0,
546 doc
: /* Return WINDOW's use time.
547 WINDOW defaults to the selected window. The window with the highest use
548 time is the most recently selected one. The window with the lowest use
549 time is the least recently selected one. */)
552 return decode_window (window
)->use_time
;
555 DEFUN ("window-total-size", Fwindow_total_size
, Swindow_total_size
, 0, 2, 0,
556 doc
: /* Return the total number of lines of WINDOW.
557 WINDOW can be any window and defaults to the selected one. The return
558 value includes WINDOW's mode line and header line, if any. If WINDOW
559 is internal, the return value is the sum of the total number of lines
560 of WINDOW's child windows if these are vertically combined and the
561 height of WINDOW's first child otherwise.
563 Optional argument HORIZONTAL non-nil means return the total number of
564 columns of WINDOW. In this case the return value includes any vertical
565 dividers or scrollbars of WINDOW. If WINDOW is internal, the return
566 value is the sum of the total number of columns of WINDOW's child
567 windows if they are horizontally combined and the width of WINDOW's
568 first child otherwise. */)
569 (Lisp_Object window
, Lisp_Object horizontal
)
571 if (NILP (horizontal
))
572 return decode_any_window (window
)->total_lines
;
574 return decode_any_window (window
)->total_cols
;
577 DEFUN ("window-new-total", Fwindow_new_total
, Swindow_new_total
, 0, 1, 0,
578 doc
: /* Return new total size of WINDOW.
579 WINDOW defaults to the selected window. */)
582 return decode_any_window (window
)->new_total
;
585 DEFUN ("window-normal-size", Fwindow_normal_size
, Swindow_normal_size
, 0, 2, 0,
586 doc
: /* Return normal height of WINDOW.
587 WINDOW can be any window and defaults to the selected one. Optional
588 argument HORIZONTAL non-nil means return normal width of WINDOW. */)
589 (Lisp_Object window
, Lisp_Object horizontal
)
591 if (NILP (horizontal
))
592 return decode_any_window (window
)->normal_lines
;
594 return decode_any_window (window
)->normal_cols
;
597 DEFUN ("window-new-normal", Fwindow_new_normal
, Swindow_new_normal
, 0, 1, 0,
598 doc
: /* Return new normal size of WINDOW.
599 WINDOW can be any window and defaults to the selected one. */)
602 return decode_any_window (window
)->new_normal
;
605 DEFUN ("window-left-column", Fwindow_left_column
, Swindow_left_column
, 0, 1, 0,
606 doc
: /* Return left column of WINDOW.
607 WINDOW can be any window and defaults to the selected one. */)
610 return decode_any_window (window
)->left_col
;
613 DEFUN ("window-top-line", Fwindow_top_line
, Swindow_top_line
, 0, 1, 0,
614 doc
: /* Return top line of WINDOW.
615 WINDOW can be any window and defaults to the selected one. */)
618 return decode_any_window (window
)->top_line
;
621 /* Return the number of lines of W's body. Don't count any mode or
625 window_body_lines (struct window
*w
)
627 int height
= XFASTINT (w
->total_lines
);
629 if (!MINI_WINDOW_P (w
))
631 if (WINDOW_WANTS_MODELINE_P (w
))
633 if (WINDOW_WANTS_HEADER_LINE_P (w
))
640 /* Return the number of columns of W's body. Don't count columns
641 occupied by the scroll bar or the vertical bar separating W from its
642 right sibling. On window-systems don't count fringes or display
646 window_body_cols (struct window
*w
)
648 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
649 int width
= XINT (w
->total_cols
);
651 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
652 /* Scroll bars occupy a few columns. */
653 width
-= WINDOW_CONFIG_SCROLL_BAR_COLS (w
);
654 else if (!FRAME_WINDOW_P (f
)
655 && !WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
656 /* The column of `|' characters separating side-by-side windows
657 occupies one column only. */
660 if (FRAME_WINDOW_P (f
))
661 /* On window-systems, fringes and display margins cannot be
662 used for normal text. */
663 width
-= (WINDOW_FRINGE_COLS (w
)
664 + WINDOW_LEFT_MARGIN_COLS (w
)
665 + WINDOW_RIGHT_MARGIN_COLS (w
));
670 DEFUN ("window-body-size", Fwindow_body_size
, Swindow_body_size
, 0, 2, 0,
671 doc
: /* Return the number of lines of WINDOW's body.
672 WINDOW must be a live window and defaults to the selected one. The
673 return value does not include WINDOW's mode line and header line, if
676 Optional argument HORIZONTAL non-nil means return the number of columns
677 of WINDOW's body. In this case, the return value does not include any
678 vertical dividers or scroll bars owned by WINDOW. On a window-system
679 the return value does not include the number of columns used for
680 WINDOW's fringes or display margins either. */)
681 (Lisp_Object window
, Lisp_Object horizontal
)
683 struct window
*w
= decode_any_window (window
);
685 if (NILP (horizontal
))
686 return make_number (window_body_lines (w
));
688 return make_number (window_body_cols (w
));
691 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
692 doc
: /* Return the number of columns by which WINDOW is scrolled from left margin.
693 WINDOW must be a live window and defaults to the selected one. */)
696 return decode_window (window
)->hscroll
;
699 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
700 doc
: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
701 Return NCOL. NCOL should be zero or positive.
703 Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
704 window so that the location of point moves off-window. */)
705 (Lisp_Object window
, Lisp_Object ncol
)
707 struct window
*w
= decode_window (window
);
711 hscroll
= max (0, XINT (ncol
));
713 /* Prevent redisplay shortcuts when changing the hscroll. */
714 if (XINT (w
->hscroll
) != hscroll
)
715 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
717 w
->hscroll
= make_number (hscroll
);
721 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
722 Swindow_redisplay_end_trigger
, 0, 1, 0,
723 doc
: /* Return WINDOW's redisplay end trigger value.
724 WINDOW defaults to the selected window.
725 See `set-window-redisplay-end-trigger' for more information. */)
728 return decode_window (window
)->redisplay_end_trigger
;
731 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
732 Sset_window_redisplay_end_trigger
, 2, 2, 0,
733 doc
: /* Set WINDOW's redisplay end trigger value to VALUE.
734 VALUE should be a buffer position (typically a marker) or nil.
735 If it is a buffer position, then if redisplay in WINDOW reaches a position
736 beyond VALUE, the functions in `redisplay-end-trigger-functions' are called
737 with two arguments: WINDOW, and the end trigger value.
738 Afterwards the end-trigger value is reset to nil. */)
739 (register Lisp_Object window
, Lisp_Object value
)
741 register struct window
*w
;
743 w
= decode_window (window
);
744 w
->redisplay_end_trigger
= value
;
748 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
749 doc
: /* Return a list of the edge coordinates of WINDOW.
750 The list has the form (LEFT TOP RIGHT BOTTOM).
751 TOP and BOTTOM count by lines, and LEFT and RIGHT count by columns,
752 all relative to 0, 0 at top left corner of frame.
754 RIGHT is one more than the rightmost column occupied by WINDOW.
755 BOTTOM is one more than the bottommost row occupied by WINDOW.
756 The edges include the space used by WINDOW's scroll bar, display
757 margins, fringes, header line, and/or mode line. For the edges of
758 just the text area, use `window-inside-edges'. */)
761 register struct window
*w
= decode_any_window (window
);
763 return Fcons (make_number (WINDOW_LEFT_EDGE_COL (w
)),
764 Fcons (make_number (WINDOW_TOP_EDGE_LINE (w
)),
765 Fcons (make_number (WINDOW_RIGHT_EDGE_COL (w
)),
766 Fcons (make_number (WINDOW_BOTTOM_EDGE_LINE (w
)),
770 DEFUN ("window-pixel-edges", Fwindow_pixel_edges
, Swindow_pixel_edges
, 0, 1, 0,
771 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
772 The list has the form (LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at
773 the top left corner of the frame.
775 RIGHT is one more than the rightmost x position occupied by WINDOW.
776 BOTTOM is one more than the bottommost y position occupied by WINDOW.
777 The pixel edges include the space used by WINDOW's scroll bar, display
778 margins, fringes, header line, and/or mode line. For the pixel edges
779 of just the text area, use `window-inside-pixel-edges'. */)
782 register struct window
*w
= decode_any_window (window
);
784 return Fcons (make_number (WINDOW_LEFT_EDGE_X (w
)),
785 Fcons (make_number (WINDOW_TOP_EDGE_Y (w
)),
786 Fcons (make_number (WINDOW_RIGHT_EDGE_X (w
)),
787 Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w
)),
792 calc_absolute_offset(struct window
*w
, int *add_x
, int *add_y
)
794 struct frame
*f
= XFRAME (w
->frame
);
796 #ifdef FRAME_MENUBAR_HEIGHT
797 *add_y
+= FRAME_MENUBAR_HEIGHT (f
);
799 #ifdef FRAME_TOOLBAR_TOP_HEIGHT
800 *add_y
+= FRAME_TOOLBAR_TOP_HEIGHT (f
);
801 #elif FRAME_TOOLBAR_HEIGHT
802 *add_y
+= FRAME_TOOLBAR_HEIGHT (f
);
804 #ifdef FRAME_NS_TITLEBAR_HEIGHT
805 *add_y
+= FRAME_NS_TITLEBAR_HEIGHT (f
);
807 *add_x
= f
->left_pos
;
808 #ifdef FRAME_TOOLBAR_LEFT_WIDTH
809 *add_x
+= FRAME_TOOLBAR_LEFT_WIDTH (f
);
813 DEFUN ("window-absolute-pixel-edges", Fwindow_absolute_pixel_edges
,
814 Swindow_absolute_pixel_edges
, 0, 1, 0,
815 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
816 The list has the form (LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at
817 the top left corner of the display.
819 RIGHT is one more than the rightmost x position occupied by WINDOW.
820 BOTTOM is one more than the bottommost y position occupied by WINDOW.
821 The pixel edges include the space used by WINDOW's scroll bar, display
822 margins, fringes, header line, and/or mode line. For the pixel edges
823 of just the text area, use `window-inside-absolute-pixel-edges'. */)
826 register struct window
*w
= decode_any_window (window
);
828 calc_absolute_offset (w
, &add_x
, &add_y
);
830 return Fcons (make_number (WINDOW_LEFT_EDGE_X (w
) + add_x
),
831 Fcons (make_number (WINDOW_TOP_EDGE_Y (w
) + add_y
),
832 Fcons (make_number (WINDOW_RIGHT_EDGE_X (w
) + add_x
),
833 Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w
) + add_y
),
837 DEFUN ("window-inside-edges", Fwindow_inside_edges
, Swindow_inside_edges
, 0, 1, 0,
838 doc
: /* Return a list of the edge coordinates of WINDOW.
839 The list has the form (LEFT TOP RIGHT BOTTOM).
840 TOP and BOTTOM count by lines, and LEFT and RIGHT count by columns,
841 all relative to 0, 0 at top left corner of frame.
843 RIGHT is one more than the rightmost column of WINDOW's text area.
844 BOTTOM is one more than the bottommost row of WINDOW's text area.
845 The inside edges do not include the space used by the WINDOW's scroll
846 bar, display margins, fringes, header line, and/or mode line. */)
849 register struct window
*w
= decode_any_window (window
);
851 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_COL (w
)
852 + WINDOW_LEFT_MARGIN_COLS (w
)
853 + WINDOW_LEFT_FRINGE_COLS (w
)),
854 make_number (WINDOW_TOP_EDGE_LINE (w
)
855 + WINDOW_HEADER_LINE_LINES (w
)),
856 make_number (WINDOW_BOX_RIGHT_EDGE_COL (w
)
857 - WINDOW_RIGHT_MARGIN_COLS (w
)
858 - WINDOW_RIGHT_FRINGE_COLS (w
)),
859 make_number (WINDOW_BOTTOM_EDGE_LINE (w
)
860 - WINDOW_MODE_LINE_LINES (w
)));
863 DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges
, Swindow_inside_pixel_edges
, 0, 1, 0,
864 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
865 The list has the form (LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at
866 the top left corner of the frame.
868 RIGHT is one more than the rightmost x position of WINDOW's text area.
869 BOTTOM is one more than the bottommost y position of WINDOW's text area.
870 The inside edges do not include the space used by WINDOW's scroll bar,
871 display margins, fringes, header line, and/or mode line. */)
874 register struct window
*w
= decode_any_window (window
);
876 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w
)
877 + WINDOW_LEFT_MARGIN_WIDTH (w
)
878 + WINDOW_LEFT_FRINGE_WIDTH (w
)),
879 make_number (WINDOW_TOP_EDGE_Y (w
)
880 + WINDOW_HEADER_LINE_HEIGHT (w
)),
881 make_number (WINDOW_BOX_RIGHT_EDGE_X (w
)
882 - WINDOW_RIGHT_MARGIN_WIDTH (w
)
883 - WINDOW_RIGHT_FRINGE_WIDTH (w
)),
884 make_number (WINDOW_BOTTOM_EDGE_Y (w
)
885 - WINDOW_MODE_LINE_HEIGHT (w
)));
888 DEFUN ("window-inside-absolute-pixel-edges",
889 Fwindow_inside_absolute_pixel_edges
,
890 Swindow_inside_absolute_pixel_edges
, 0, 1, 0,
891 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
892 The list has the form (LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at
893 the top left corner of the display.
895 RIGHT is one more than the rightmost x position of WINDOW's text area.
896 BOTTOM is one more than the bottommost y position of WINDOW's text area.
897 The inside edges do not include the space used by WINDOW's scroll bar,
898 display margins, fringes, header line, and/or mode line. */)
901 register struct window
*w
= decode_any_window (window
);
903 calc_absolute_offset (w
, &add_x
, &add_y
);
905 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w
)
906 + WINDOW_LEFT_MARGIN_WIDTH (w
)
907 + WINDOW_LEFT_FRINGE_WIDTH (w
) + add_x
),
908 make_number (WINDOW_TOP_EDGE_Y (w
)
909 + WINDOW_HEADER_LINE_HEIGHT (w
) + add_y
),
910 make_number (WINDOW_BOX_RIGHT_EDGE_X (w
)
911 - WINDOW_RIGHT_MARGIN_WIDTH (w
)
912 - WINDOW_RIGHT_FRINGE_WIDTH (w
) + add_x
),
913 make_number (WINDOW_BOTTOM_EDGE_Y (w
)
914 - WINDOW_MODE_LINE_HEIGHT (w
) + add_y
));
917 /* Test if the character at column X, row Y is within window W.
918 If it is not, return ON_NOTHING;
919 if it is in the window's text area, return ON_TEXT;
920 if it is on the window's modeline, return ON_MODE_LINE;
921 if it is on the border between the window and its right sibling,
922 return ON_VERTICAL_BORDER.
923 if it is on a scroll bar, return ON_SCROLL_BAR.
924 if it is on the window's top line, return ON_HEADER_LINE;
925 if it is in left or right fringe of the window,
926 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE;
927 if it is in the marginal area to the left/right of the window,
928 return ON_LEFT_MARGIN or ON_RIGHT_MARGIN.
930 X and Y are frame relative pixel coordinates. */
932 static enum window_part
933 coordinates_in_window (register struct window
*w
, int x
, int y
)
935 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
937 enum window_part part
;
938 int ux
= FRAME_COLUMN_WIDTH (f
);
939 int x0
= WINDOW_LEFT_EDGE_X (w
);
940 int x1
= WINDOW_RIGHT_EDGE_X (w
);
941 /* The width of the area where the vertical line can be dragged.
942 (Between mode lines for instance. */
943 int grabbable_width
= ux
;
944 int lmargin_width
, rmargin_width
, text_left
, text_right
;
945 int top_y
= WINDOW_TOP_EDGE_Y (w
);
946 int bottom_y
= WINDOW_BOTTOM_EDGE_Y (w
);
948 /* Outside any interesting row? */
949 if (y
< top_y
|| y
>= bottom_y
)
952 /* In what's below, we subtract 1 when computing right_x because we
953 want the rightmost pixel, which is given by left_pixel+width-1. */
954 if (w
->pseudo_window_p
)
957 right_x
= WINDOW_TOTAL_WIDTH (w
) - 1;
961 left_x
= WINDOW_BOX_LEFT_EDGE_X (w
);
962 right_x
= WINDOW_BOX_RIGHT_EDGE_X (w
) - 1;
965 /* On the mode line or header line? If it's near the start of
966 the mode or header line of window that's has a horizontal
967 sibling, say it's on the vertical line. That's to be able
968 to resize windows horizontally in case we're using toolkit
971 if (WINDOW_WANTS_MODELINE_P (w
)
972 && y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
))
976 header_vertical_border_check
:
977 /* We're somewhere on the mode line. We consider the place
978 between mode lines of horizontally adjacent mode lines
979 as the vertical border. If scroll bars on the left,
980 return the right window. */
981 if ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
982 || WINDOW_RIGHTMOST_P (w
))
983 && !WINDOW_LEFTMOST_P (w
)
984 && eabs (x
- x0
) < grabbable_width
)
985 return ON_VERTICAL_BORDER
;
987 /* Make sure we're not at the rightmost position of a
988 mode-/header-line and there's yet another window on the
990 else if ((WINDOW_RIGHTMOST_P (w
) || x
< x1
)
991 && eabs (x
- x1
) < grabbable_width
)
992 return ON_VERTICAL_BORDER
;
994 if (x
< x0
|| x
>= x1
)
1000 if (WINDOW_WANTS_HEADER_LINE_P (w
)
1001 && y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
))
1003 part
= ON_HEADER_LINE
;
1004 goto header_vertical_border_check
;
1007 if (x
< x0
|| x
>= x1
) return ON_NOTHING
;
1009 /* Outside any interesting column? */
1010 if (x
< left_x
|| x
> right_x
)
1011 return ON_SCROLL_BAR
;
1013 lmargin_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
1014 rmargin_width
= window_box_width (w
, RIGHT_MARGIN_AREA
);
1016 text_left
= window_box_left (w
, TEXT_AREA
);
1017 text_right
= text_left
+ window_box_width (w
, TEXT_AREA
);
1019 if (FRAME_WINDOW_P (f
))
1021 if (!w
->pseudo_window_p
1022 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
)
1023 && !WINDOW_RIGHTMOST_P (w
)
1024 && (eabs (x
- right_x
) < grabbable_width
))
1025 return ON_VERTICAL_BORDER
;
1027 /* Need to say "x > right_x" rather than >=, since on character
1028 terminals, the vertical line's x coordinate is right_x. */
1029 else if (!w
->pseudo_window_p
1030 && !WINDOW_RIGHTMOST_P (w
)
1031 && x
> right_x
- ux
)
1032 return ON_VERTICAL_BORDER
;
1036 if (lmargin_width
> 0
1037 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1038 ? (x
>= left_x
+ WINDOW_LEFT_FRINGE_WIDTH (w
))
1039 : (x
< left_x
+ lmargin_width
)))
1040 return ON_LEFT_MARGIN
;
1042 return ON_LEFT_FRINGE
;
1045 if (x
>= text_right
)
1047 if (rmargin_width
> 0
1048 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1049 ? (x
< right_x
- WINDOW_RIGHT_FRINGE_WIDTH (w
))
1050 : (x
>= right_x
- rmargin_width
)))
1051 return ON_RIGHT_MARGIN
;
1053 return ON_RIGHT_FRINGE
;
1056 /* Everything special ruled out - must be on text area */
1060 /* Take X is the frame-relative pixel x-coordinate, and return the
1061 x-coordinate relative to part PART of window W. */
1063 window_relative_x_coord (struct window
*w
, enum window_part part
, int x
)
1065 int left_x
= (w
->pseudo_window_p
) ? 0 : WINDOW_BOX_LEFT_EDGE_X (w
);
1070 return x
- window_box_left (w
, TEXT_AREA
);
1072 case ON_LEFT_FRINGE
:
1075 case ON_RIGHT_FRINGE
:
1076 return x
- left_x
- WINDOW_LEFT_FRINGE_WIDTH (w
);
1078 case ON_LEFT_MARGIN
:
1080 - ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1081 ? WINDOW_LEFT_FRINGE_WIDTH (w
) : 0));
1083 case ON_RIGHT_MARGIN
:
1085 - ((w
->pseudo_window_p
)
1086 ? WINDOW_TOTAL_WIDTH (w
)
1087 : WINDOW_BOX_RIGHT_EDGE_X (w
))
1088 + window_box_width (w
, RIGHT_MARGIN_AREA
)
1089 + ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1090 ? WINDOW_RIGHT_FRINGE_WIDTH (w
) : 0));
1093 /* ON_SCROLL_BAR, ON_NOTHING, and ON_VERTICAL_BORDER: */
1098 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
1099 Scoordinates_in_window_p
, 2, 2, 0,
1100 doc
: /* Return non-nil if COORDINATES are in WINDOW.
1101 COORDINATES is a cons of the form (X . Y), X and Y being distances
1102 measured in characters from the upper-left corner of the frame.
1103 \(0 . 0) denotes the character in the upper left corner of the
1105 If COORDINATES are in the text portion of WINDOW,
1106 the coordinates relative to the window are returned.
1107 If they are in the mode line of WINDOW, `mode-line' is returned.
1108 If they are in the top mode line of WINDOW, `header-line' is returned.
1109 If they are in the left fringe of WINDOW, `left-fringe' is returned.
1110 If they are in the right fringe of WINDOW, `right-fringe' is returned.
1111 If they are on the border between WINDOW and its right sibling,
1112 `vertical-line' is returned.
1113 If they are in the windows's left or right marginal areas, `left-margin'\n\
1114 or `right-margin' is returned. */)
1115 (register Lisp_Object coordinates
, Lisp_Object window
)
1122 CHECK_WINDOW (window
);
1123 w
= XWINDOW (window
);
1124 f
= XFRAME (w
->frame
);
1125 CHECK_CONS (coordinates
);
1126 lx
= Fcar (coordinates
);
1127 ly
= Fcdr (coordinates
);
1128 CHECK_NUMBER_OR_FLOAT (lx
);
1129 CHECK_NUMBER_OR_FLOAT (ly
);
1130 x
= FRAME_PIXEL_X_FROM_CANON_X (f
, lx
) + FRAME_INTERNAL_BORDER_WIDTH (f
);
1131 y
= FRAME_PIXEL_Y_FROM_CANON_Y (f
, ly
) + FRAME_INTERNAL_BORDER_WIDTH (f
);
1133 switch (coordinates_in_window (w
, x
, y
))
1139 /* Convert X and Y to window relative pixel coordinates, and
1140 return the canonical char units. */
1141 x
-= window_box_left (w
, TEXT_AREA
);
1142 y
-= WINDOW_TOP_EDGE_Y (w
);
1143 return Fcons (FRAME_CANON_X_FROM_PIXEL_X (f
, x
),
1144 FRAME_CANON_Y_FROM_PIXEL_Y (f
, y
));
1149 case ON_VERTICAL_BORDER
:
1150 return Qvertical_line
;
1152 case ON_HEADER_LINE
:
1153 return Qheader_line
;
1155 case ON_LEFT_FRINGE
:
1156 return Qleft_fringe
;
1158 case ON_RIGHT_FRINGE
:
1159 return Qright_fringe
;
1161 case ON_LEFT_MARGIN
:
1162 return Qleft_margin
;
1164 case ON_RIGHT_MARGIN
:
1165 return Qright_margin
;
1168 /* Historically we are supposed to return nil in this case. */
1177 /* Callback for foreach_window, used in window_from_coordinates.
1178 Check if window W contains coordinates specified by USER_DATA which
1179 is actually a pointer to a struct check_window_data CW.
1181 Check if window W contains coordinates *CW->x and *CW->y. If it
1182 does, return W in *CW->window, as Lisp_Object, and return in
1183 *CW->part the part of the window under coordinates *X,*Y. Return
1184 zero from this function to stop iterating over windows. */
1186 struct check_window_data
1188 Lisp_Object
*window
;
1190 enum window_part
*part
;
1194 check_window_containing (struct window
*w
, void *user_data
)
1196 struct check_window_data
*cw
= (struct check_window_data
*) user_data
;
1197 enum window_part found
;
1200 found
= coordinates_in_window (w
, cw
->x
, cw
->y
);
1201 if (found
!= ON_NOTHING
)
1204 XSETWINDOW (*cw
->window
, w
);
1212 /* Find the window containing frame-relative pixel position X/Y and
1213 return it as a Lisp_Object.
1215 If X, Y is on one of the window's special `window_part' elements,
1216 set *PART to the id of that element.
1218 If there is no window under X, Y return nil and leave *PART
1219 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows.
1221 This function was previously implemented with a loop cycling over
1222 windows with Fnext_window, and starting with the frame's selected
1223 window. It turned out that this doesn't work with an
1224 implementation of next_window using Vwindow_list, because
1225 FRAME_SELECTED_WINDOW (F) is not always contained in the window
1226 tree of F when this function is called asynchronously from
1227 note_mouse_highlight. The original loop didn't terminate in this
1231 window_from_coordinates (struct frame
*f
, int x
, int y
,
1232 enum window_part
*part
, int tool_bar_p
)
1235 struct check_window_data cw
;
1236 enum window_part dummy
;
1242 cw
.window
= &window
, cw
.x
= x
, cw
.y
= y
; cw
.part
= part
;
1243 foreach_window (f
, check_window_containing
, &cw
);
1245 /* If not found above, see if it's in the tool bar window, if a tool
1249 && WINDOWP (f
->tool_bar_window
)
1250 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0
1251 && (coordinates_in_window (XWINDOW (f
->tool_bar_window
), x
, y
)
1255 window
= f
->tool_bar_window
;
1261 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
1262 doc
: /* Return window containing coordinates X and Y on FRAME.
1263 FRAME must be a live frame and defaults to the selected one.
1264 The top left corner of the frame is considered to be row 0,
1266 (Lisp_Object x
, Lisp_Object y
, Lisp_Object frame
)
1271 frame
= selected_frame
;
1272 CHECK_LIVE_FRAME (frame
);
1275 /* Check that arguments are integers or floats. */
1276 CHECK_NUMBER_OR_FLOAT (x
);
1277 CHECK_NUMBER_OR_FLOAT (y
);
1279 return window_from_coordinates (f
,
1280 (FRAME_PIXEL_X_FROM_CANON_X (f
, x
)
1281 + FRAME_INTERNAL_BORDER_WIDTH (f
)),
1282 (FRAME_PIXEL_Y_FROM_CANON_Y (f
, y
)
1283 + FRAME_INTERNAL_BORDER_WIDTH (f
)),
1287 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
1288 doc
: /* Return current value of point in WINDOW.
1289 WINDOW must be a live window and defaults to the selected one.
1291 For a nonselected window, this is the value point would have
1292 if that window were selected.
1294 Note that, when WINDOW is the selected window and its buffer
1295 is also currently selected, the value returned is the same as (point).
1296 It would be more strictly correct to return the `top-level' value
1297 of point, outside of any save-excursion forms.
1298 But that is hard to define. */)
1299 (Lisp_Object window
)
1301 register struct window
*w
= decode_window (window
);
1303 if (w
== XWINDOW (selected_window
)
1304 && current_buffer
== XBUFFER (w
->buffer
))
1306 return Fmarker_position (w
->pointm
);
1309 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
1310 doc
: /* Return position at which display currently starts in WINDOW.
1311 WINDOW must be a live window and defaults to the selected one.
1312 This is updated by redisplay or by calling `set-window-start'. */)
1313 (Lisp_Object window
)
1315 return Fmarker_position (decode_window (window
)->start
);
1318 /* This is text temporarily removed from the doc string below.
1320 This function returns nil if the position is not currently known.
1321 That happens when redisplay is preempted and doesn't finish.
1322 If in that case you want to compute where the end of the window would
1323 have been if redisplay had finished, do this:
1325 (goto-char (window-start window))
1326 (vertical-motion (1- (window-height window)) window)
1329 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
1330 doc
: /* Return position at which display currently ends in WINDOW.
1331 WINDOW must be a live window and defaults to the selected one.
1332 This is updated by redisplay, when it runs to completion.
1333 Simply changing the buffer text or setting `window-start'
1334 does not update this value.
1335 Return nil if there is no recorded value. \(This can happen if the
1336 last redisplay of WINDOW was preempted, and did not finish.)
1337 If UPDATE is non-nil, compute the up-to-date position
1338 if it isn't already recorded. */)
1339 (Lisp_Object window
, Lisp_Object update
)
1342 struct window
*w
= decode_window (window
);
1350 #if 0 /* This change broke some things. We should make it later. */
1351 /* If we don't know the end position, return nil.
1352 The user can compute it with vertical-motion if he wants to.
1353 It would be nicer to do it automatically,
1354 but that's so slow that it would probably bother people. */
1355 if (NILP (w
->window_end_valid
))
1360 && ! (! NILP (w
->window_end_valid
)
1361 && XFASTINT (w
->last_modified
) >= BUF_MODIFF (b
)
1362 && XFASTINT (w
->last_overlay_modified
) >= BUF_OVERLAY_MODIFF (b
))
1365 struct text_pos startp
;
1367 struct buffer
*old_buffer
= NULL
;
1369 /* Cannot use Fvertical_motion because that function doesn't
1370 cope with variable-height lines. */
1371 if (b
!= current_buffer
)
1373 old_buffer
= current_buffer
;
1374 set_buffer_internal (b
);
1377 /* In case W->start is out of the range, use something
1378 reasonable. This situation occurred when loading a file with
1379 `-l' containing a call to `rmail' with subsequent other
1380 commands. At the end, W->start happened to be BEG, while
1381 rmail had already narrowed the buffer. */
1382 if (XMARKER (w
->start
)->charpos
< BEGV
)
1383 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
1384 else if (XMARKER (w
->start
)->charpos
> ZV
)
1385 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
1387 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
1389 start_display (&it
, w
, startp
);
1390 move_it_vertically (&it
, window_box_height (w
));
1391 if (it
.current_y
< it
.last_visible_y
)
1392 move_it_past_eol (&it
);
1393 value
= make_number (IT_CHARPOS (it
));
1396 set_buffer_internal (old_buffer
);
1399 XSETINT (value
, BUF_Z (b
) - XFASTINT (w
->window_end_pos
));
1404 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
1405 doc
: /* Make point value in WINDOW be at position POS in WINDOW's buffer.
1407 (Lisp_Object window
, Lisp_Object pos
)
1409 register struct window
*w
= decode_window (window
);
1411 CHECK_NUMBER_COERCE_MARKER (pos
);
1412 if (w
== XWINDOW (selected_window
)
1413 && XBUFFER (w
->buffer
) == current_buffer
)
1416 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
1418 /* We have to make sure that redisplay updates the window to show
1419 the new value of point. */
1420 if (!EQ (window
, selected_window
))
1421 ++windows_or_buffers_changed
;
1426 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
1427 doc
: /* Make display in WINDOW start at position POS in WINDOW's buffer.
1428 WINDOW defaults to the selected window. Return POS.
1429 Optional third arg NOFORCE non-nil inhibits next redisplay from
1430 overriding motion of point in order to display at this exact start. */)
1431 (Lisp_Object window
, Lisp_Object pos
, Lisp_Object noforce
)
1433 register struct window
*w
= decode_window (window
);
1435 CHECK_NUMBER_COERCE_MARKER (pos
);
1436 set_marker_restricted (w
->start
, pos
, w
->buffer
);
1437 /* this is not right, but much easier than doing what is right. */
1438 w
->start_at_line_beg
= Qnil
;
1440 w
->force_start
= Qt
;
1441 w
->update_mode_line
= Qt
;
1442 XSETFASTINT (w
->last_modified
, 0);
1443 XSETFASTINT (w
->last_overlay_modified
, 0);
1444 if (!EQ (window
, selected_window
))
1445 windows_or_buffers_changed
++;
1450 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
1451 Spos_visible_in_window_p
, 0, 3, 0,
1452 doc
: /* Return non-nil if position POS is currently on the frame in WINDOW.
1453 Return nil if that position is scrolled vertically out of view.
1454 If a character is only partially visible, nil is returned, unless the
1455 optional argument PARTIALLY is non-nil.
1456 If POS is only out of view because of horizontal scrolling, return non-nil.
1457 If POS is t, it specifies the position of the last visible glyph in WINDOW.
1458 POS defaults to point in WINDOW; WINDOW defaults to the selected window.
1460 If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
1461 return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
1462 where X and Y are the pixel coordinates relative to the top left corner
1463 of the window. The remaining elements are omitted if the character after
1464 POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
1465 off-window at the top and bottom of the row, ROWH is the height of the
1466 display row, and VPOS is the row number (0-based) containing POS. */)
1467 (Lisp_Object pos
, Lisp_Object window
, Lisp_Object partially
)
1469 register struct window
*w
;
1470 register EMACS_INT posint
;
1471 register struct buffer
*buf
;
1472 struct text_pos top
;
1473 Lisp_Object in_window
= Qnil
;
1474 int rtop
, rbot
, rowh
, vpos
, fully_p
= 1;
1477 w
= decode_window (window
);
1478 buf
= XBUFFER (w
->buffer
);
1479 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1483 else if (!NILP (pos
))
1485 CHECK_NUMBER_COERCE_MARKER (pos
);
1486 posint
= XINT (pos
);
1488 else if (w
== XWINDOW (selected_window
))
1491 posint
= XMARKER (w
->pointm
)->charpos
;
1493 /* If position is above window start or outside buffer boundaries,
1494 or if window start is out of range, position is not visible. */
1496 || (posint
>= CHARPOS (top
) && posint
<= BUF_ZV (buf
)))
1497 && CHARPOS (top
) >= BUF_BEGV (buf
)
1498 && CHARPOS (top
) <= BUF_ZV (buf
)
1499 && pos_visible_p (w
, posint
, &x
, &y
, &rtop
, &rbot
, &rowh
, &vpos
)
1500 && (fully_p
= !rtop
&& !rbot
, (!NILP (partially
) || fully_p
)))
1503 if (!NILP (in_window
) && !NILP (partially
))
1505 Lisp_Object part
= Qnil
;
1507 part
= list4 (make_number (rtop
), make_number (rbot
),
1508 make_number (rowh
), make_number (vpos
));
1509 in_window
= Fcons (make_number (x
),
1510 Fcons (make_number (y
), part
));
1516 DEFUN ("window-line-height", Fwindow_line_height
,
1517 Swindow_line_height
, 0, 2, 0,
1518 doc
: /* Return height in pixels of text line LINE in window WINDOW.
1519 WINDOW defaults to the selected window.
1521 Return height of current line if LINE is omitted or nil. Return height of
1522 header or mode line if LINE is `header-line' or `mode-line'.
1523 Otherwise, LINE is a text line number starting from 0. A negative number
1524 counts from the end of the window.
1526 Value is a list (HEIGHT VPOS YPOS OFFBOT), where HEIGHT is the height
1527 in pixels of the visible part of the line, VPOS and YPOS are the
1528 vertical position in lines and pixels of the line, relative to the top
1529 of the first text line, and OFFBOT is the number of off-window pixels at
1530 the bottom of the text line. If there are off-window pixels at the top
1531 of the (first) text line, YPOS is negative.
1533 Return nil if window display is not up-to-date. In that case, use
1534 `pos-visible-in-window-p' to obtain the information. */)
1535 (Lisp_Object line
, Lisp_Object window
)
1537 register struct window
*w
;
1538 register struct buffer
*b
;
1539 struct glyph_row
*row
, *end_row
;
1540 int max_y
, crop
, i
, n
;
1542 w
= decode_window (window
);
1544 if (noninteractive
|| w
->pseudo_window_p
)
1547 CHECK_BUFFER (w
->buffer
);
1548 b
= XBUFFER (w
->buffer
);
1550 /* Fail if current matrix is not up-to-date. */
1551 if (NILP (w
->window_end_valid
)
1552 || current_buffer
->clip_changed
1553 || current_buffer
->prevent_redisplay_optimizations_p
1554 || XFASTINT (w
->last_modified
) < BUF_MODIFF (b
)
1555 || XFASTINT (w
->last_overlay_modified
) < BUF_OVERLAY_MODIFF (b
))
1561 if (i
< 0 || i
>= w
->current_matrix
->nrows
1562 || (row
= MATRIX_ROW (w
->current_matrix
, i
), !row
->enabled_p
))
1564 max_y
= window_text_bottom_y (w
);
1568 if (EQ (line
, Qheader_line
))
1570 if (!WINDOW_WANTS_HEADER_LINE_P (w
))
1572 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
1573 if (!row
->enabled_p
)
1575 return list4 (make_number (row
->height
),
1576 make_number (0), make_number (0),
1580 if (EQ (line
, Qmode_line
))
1582 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
1583 if (!row
->enabled_p
)
1585 return list4 (make_number (row
->height
),
1586 make_number (0), /* not accurate */
1587 make_number (WINDOW_HEADER_LINE_HEIGHT (w
)
1588 + window_text_bottom_y (w
)),
1592 CHECK_NUMBER (line
);
1595 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
1596 end_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
1597 max_y
= window_text_bottom_y (w
);
1600 while ((n
< 0 || i
< n
)
1601 && row
<= end_row
&& row
->enabled_p
1602 && row
->y
+ row
->height
< max_y
)
1605 if (row
> end_row
|| !row
->enabled_p
)
1617 crop
= max (0, (row
->y
+ row
->height
) - max_y
);
1618 return list4 (make_number (row
->height
+ min (0, row
->y
) - crop
),
1620 make_number (row
->y
),
1621 make_number (crop
));
1624 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
1626 doc
: /* Return non-nil when WINDOW is dedicated to its buffer.
1627 More precisely, return the value assigned by the last call of
1628 `set-window-dedicated-p' for WINDOW. Return nil if that function was
1629 never called with WINDOW as its argument, or the value set by that
1630 function was internally reset since its last call. WINDOW defaults to
1631 the selected window.
1633 When a window is dedicated to its buffer, `display-buffer' will refrain
1634 from displaying another buffer in it. `get-lru-window' and
1635 `get-largest-window' treat dedicated windows specially.
1636 `delete-windows-on', `replace-buffer-in-windows', `quit-window' and
1637 `kill-buffer' can delete a dedicated window and the containing frame.
1639 Functions like `set-window-buffer' may change the buffer displayed by a
1640 window, unless that window is "strongly" dedicated to its buffer, that
1641 is the value returned by `window-dedicated-p' is t. */)
1642 (Lisp_Object window
)
1644 return decode_window (window
)->dedicated
;
1647 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
1648 Sset_window_dedicated_p
, 2, 2, 0,
1649 doc
: /* Mark WINDOW as dedicated according to FLAG.
1650 WINDOW must be a live window and defaults to the selected one. FLAG
1651 non-nil means mark WINDOW as dedicated to its buffer. FLAG nil means
1652 mark WINDOW as non-dedicated. Return FLAG.
1654 When a window is dedicated to its buffer, `display-buffer' will refrain
1655 from displaying another buffer in it. `get-lru-window' and
1656 `get-largest-window' treat dedicated windows specially.
1657 `delete-windows-on', `replace-buffer-in-windows', `quit-window',
1658 `quit-restore-window' and `kill-buffer' can delete a dedicated window
1659 and the containing frame.
1661 As a special case, if FLAG is t, mark WINDOW as "strongly" dedicated to
1662 its buffer. Functions like `set-window-buffer' may change the buffer
1663 displayed by a window, unless that window is strongly dedicated to its
1664 buffer. If and when `set-window-buffer' displays another buffer in a
1665 window, it also makes sure that the window is no more dedicated. */)
1666 (Lisp_Object window
, Lisp_Object flag
)
1668 register struct window
*w
= decode_window (window
);
1670 w
->dedicated
= flag
;
1671 return w
->dedicated
;
1674 DEFUN ("window-prev-buffers", Fwindow_prev_buffers
, Swindow_prev_buffers
,
1676 doc
: /* Return buffers previously shown in WINDOW.
1677 WINDOW must be a live window and defaults to the selected one.
1679 The return value is either nil or a list of <buffer, window-start,
1680 window-point> triples where buffer was previously shown in WINDOW. */)
1681 (Lisp_Object window
)
1683 return decode_window (window
)->prev_buffers
;
1686 DEFUN ("set-window-prev-buffers", Fset_window_prev_buffers
,
1687 Sset_window_prev_buffers
, 2, 2, 0,
1688 doc
: /* Set WINDOW's previous buffers to PREV-BUFFERS.
1689 WINDOW must be a live window and defaults to the selected one. Return
1692 PREV-BUFFERS should be either nil or a list of <buffer, window-start,
1693 window-point> triples where buffer was previously shown in WINDOW. */)
1694 (Lisp_Object window
, Lisp_Object prev_buffers
)
1696 return decode_any_window (window
)->prev_buffers
= prev_buffers
;
1699 DEFUN ("window-next-buffers", Fwindow_next_buffers
, Swindow_next_buffers
,
1701 doc
: /* Return list of buffers recently re-shown in WINDOW.
1702 WINDOW must be a live window and defaults to the selected one. */)
1703 (Lisp_Object window
)
1705 return decode_window (window
)->next_buffers
;
1708 DEFUN ("set-window-next-buffers", Fset_window_next_buffers
,
1709 Sset_window_next_buffers
, 2, 2, 0,
1710 doc
: /* Set WINDOW's next buffers to NEXT-BUFFERS.
1711 WINDOW must be a live window and defaults to the selected one. Return
1714 NEXT-BUFFERS should be either nil or a list of buffers that have been
1715 recently re-shown in WINDOW. */)
1716 (Lisp_Object window
, Lisp_Object next_buffers
)
1718 return decode_any_window (window
)->next_buffers
= next_buffers
;
1721 DEFUN ("window-parameters", Fwindow_parameters
, Swindow_parameters
,
1723 doc
: /* Return the parameters of WINDOW and their values.
1724 WINDOW defaults to the selected window. The return value is a list of
1725 elements of the form (PARAMETER . VALUE). */)
1726 (Lisp_Object window
)
1728 return Fcopy_alist (decode_any_window (window
)->window_parameters
);
1731 DEFUN ("window-parameter", Fwindow_parameter
, Swindow_parameter
,
1733 doc
: /* Return WINDOW's value for PARAMETER.
1734 WINDOW defaults to the selected window. */)
1735 (Lisp_Object window
, Lisp_Object parameter
)
1739 result
= Fassq (parameter
, decode_any_window (window
)->window_parameters
);
1740 return CDR_SAFE (result
);
1743 DEFUN ("set-window-parameter", Fset_window_parameter
,
1744 Sset_window_parameter
, 3, 3, 0,
1745 doc
: /* Set WINDOW's value of PARAMETER to VALUE.
1746 WINDOW defaults to the selected window. Return VALUE. */)
1747 (Lisp_Object window
, Lisp_Object parameter
, Lisp_Object value
)
1749 register struct window
*w
= decode_any_window (window
);
1750 Lisp_Object old_alist_elt
;
1752 old_alist_elt
= Fassq (parameter
, w
->window_parameters
);
1753 if (NILP (old_alist_elt
))
1754 w
->window_parameters
= Fcons (Fcons (parameter
, value
), w
->window_parameters
);
1756 Fsetcdr (old_alist_elt
, value
);
1760 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
1762 doc
: /* Return the display-table that WINDOW is using.
1763 WINDOW defaults to the selected window. */)
1764 (Lisp_Object window
)
1766 return decode_window (window
)->display_table
;
1769 /* Get the display table for use on window W. This is either W's
1770 display table or W's buffer's display table. Ignore the specified
1771 tables if they are not valid; if no valid table is specified,
1774 struct Lisp_Char_Table
*
1775 window_display_table (struct window
*w
)
1777 struct Lisp_Char_Table
*dp
= NULL
;
1779 if (DISP_TABLE_P (w
->display_table
))
1780 dp
= XCHAR_TABLE (w
->display_table
);
1781 else if (BUFFERP (w
->buffer
))
1783 struct buffer
*b
= XBUFFER (w
->buffer
);
1785 if (DISP_TABLE_P (BVAR (b
, display_table
)))
1786 dp
= XCHAR_TABLE (BVAR (b
, display_table
));
1787 else if (DISP_TABLE_P (Vstandard_display_table
))
1788 dp
= XCHAR_TABLE (Vstandard_display_table
);
1794 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
1795 doc
: /* Set WINDOW's display-table to TABLE. */)
1796 (register Lisp_Object window
, Lisp_Object table
)
1798 register struct window
*w
;
1800 w
= decode_window (window
);
1801 w
->display_table
= table
;
1805 static void delete_window (Lisp_Object
);
1807 /* Record info on buffer window w is displaying
1808 when it is about to cease to display that buffer. */
1810 unshow_buffer (register struct window
*w
)
1817 if (b
!= XMARKER (w
->pointm
)->buffer
)
1821 if (w
== XWINDOW (selected_window
)
1822 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
1823 /* Do this except when the selected window's buffer
1824 is being removed from some other window. */
1826 /* last_window_start records the start position that this buffer
1827 had in the last window to be disconnected from it.
1828 Now that this statement is unconditional,
1829 it is possible for the buffer to be displayed in the
1830 selected window, while last_window_start reflects another
1831 window which was recently showing the same buffer.
1832 Some people might say that might be a good thing. Let's see. */
1833 b
->last_window_start
= marker_position (w
->start
);
1835 /* Point in the selected window's buffer
1836 is actually stored in that buffer, and the window's pointm isn't used.
1837 So don't clobber point in that buffer. */
1838 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
)
1839 /* This line helps to fix Horsley's testbug.el bug. */
1840 && !(WINDOWP (BVAR (b
, last_selected_window
))
1841 && w
!= XWINDOW (BVAR (b
, last_selected_window
))
1842 && EQ (buf
, XWINDOW (BVAR (b
, last_selected_window
))->buffer
)))
1843 temp_set_point_both (b
,
1844 clip_to_bounds (BUF_BEGV (b
),
1845 XMARKER (w
->pointm
)->charpos
,
1847 clip_to_bounds (BUF_BEGV_BYTE (b
),
1848 marker_byte_position (w
->pointm
),
1851 if (WINDOWP (BVAR (b
, last_selected_window
))
1852 && w
== XWINDOW (BVAR (b
, last_selected_window
)))
1853 BVAR (b
, last_selected_window
) = Qnil
;
1856 /* Put replacement into the window structure in place of old. */
1858 replace_window (Lisp_Object old
, Lisp_Object replacement
)
1860 register Lisp_Object tem
;
1861 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
1863 /* If OLD is its frame's root_window, then replacement is the new
1864 root_window for that frame. */
1866 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
1867 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
1869 p
->left_col
= o
->left_col
;
1870 p
->top_line
= o
->top_line
;
1871 p
->total_cols
= o
->total_cols
;
1872 p
->total_lines
= o
->total_lines
;
1873 p
->desired_matrix
= p
->current_matrix
= 0;
1875 memset (&p
->cursor
, 0, sizeof (p
->cursor
));
1876 memset (&p
->last_cursor
, 0, sizeof (p
->last_cursor
));
1877 memset (&p
->phys_cursor
, 0, sizeof (p
->phys_cursor
));
1878 p
->phys_cursor_type
= -1;
1879 p
->phys_cursor_width
= -1;
1880 p
->must_be_updated_p
= 0;
1881 p
->pseudo_window_p
= 0;
1882 XSETFASTINT (p
->window_end_vpos
, 0);
1883 XSETFASTINT (p
->window_end_pos
, 0);
1884 p
->window_end_valid
= Qnil
;
1885 p
->frozen_window_start_p
= 0;
1886 p
->orig_top_line
= p
->orig_total_lines
= Qnil
;
1888 p
->next
= tem
= o
->next
;
1890 XWINDOW (tem
)->prev
= replacement
;
1892 p
->prev
= tem
= o
->prev
;
1894 XWINDOW (tem
)->next
= replacement
;
1896 p
->parent
= tem
= o
->parent
;
1899 if (EQ (XWINDOW (tem
)->vchild
, old
))
1900 XWINDOW (tem
)->vchild
= replacement
;
1901 if (EQ (XWINDOW (tem
)->hchild
, old
))
1902 XWINDOW (tem
)->hchild
= replacement
;
1905 /*** Here, if replacement is a vertical combination
1906 and so is its new parent, we should make replacement's
1907 children be children of that parent instead. ***/
1910 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
1911 doc
: /* Remove WINDOW from its frame.
1912 WINDOW defaults to the selected window. Return nil.
1913 Signal an error when WINDOW is the only window on its frame. */)
1914 (register Lisp_Object window
)
1918 window
= selected_window
;
1920 CHECK_LIVE_WINDOW (window
);
1922 f
= XFRAME (WINDOW_FRAME (XWINDOW (window
)));
1923 delete_window (window
);
1925 run_window_configuration_change_hook (f
);
1931 delete_window (register Lisp_Object window
)
1933 register Lisp_Object tem
, parent
, sib
;
1934 register struct window
*p
;
1935 register struct window
*par
;
1938 /* Because this function is called by other C code on non-leaf
1939 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1940 so we can't decode_window here. */
1941 CHECK_WINDOW (window
);
1942 p
= XWINDOW (window
);
1944 /* It's a no-op to delete an already-deleted window. */
1945 if (NILP (p
->buffer
)
1947 && NILP (p
->vchild
))
1952 error ("Attempt to delete minibuffer or sole ordinary window");
1953 par
= XWINDOW (parent
);
1955 windows_or_buffers_changed
++;
1956 Vwindow_list
= Qnil
;
1957 f
= XFRAME (WINDOW_FRAME (p
));
1958 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
1960 /* Are we trying to delete any frame's selected window? */
1962 Lisp_Object swindow
, pwindow
;
1964 /* See if the frame's selected window is either WINDOW
1965 or any subwindow of it, by finding all that window's parents
1966 and comparing each one with WINDOW. */
1967 swindow
= FRAME_SELECTED_WINDOW (f
);
1972 while (!NILP (pwindow
))
1974 if (EQ (window
, pwindow
))
1976 pwindow
= XWINDOW (pwindow
)->parent
;
1979 /* If the window being deleted is not a parent of SWINDOW,
1980 then SWINDOW is ok as the new selected window. */
1981 if (!EQ (window
, pwindow
))
1983 /* Otherwise, try another window for SWINDOW. */
1984 swindow
= Fnext_window (swindow
, Qlambda
, Qnil
);
1986 /* If we get back to the frame's selected window,
1987 it means there was no acceptable alternative,
1988 so we cannot delete. */
1989 if (EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
1990 error ("Cannot delete window");
1993 /* If we need to change SWINDOW, do it. */
1994 if (! EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
1996 /* If we're about to delete the selected window on the
1997 selected frame, then we should use Fselect_window to select
1998 the new window. On the other hand, if we're about to
1999 delete the selected window on any other frame, we shouldn't do
2000 anything but set the frame's selected_window slot. */
2001 if (EQ (FRAME_SELECTED_WINDOW (f
), selected_window
))
2002 Fselect_window (swindow
, Qnil
);
2004 FRAME_SELECTED_WINDOW (f
) = swindow
;
2008 /* Now we know we can delete this one. */
2009 window_deletion_count
++;
2012 /* tem is null for dummy parent windows
2013 (which have inferiors but not any contents themselves) */
2017 unchain_marker (XMARKER (p
->pointm
));
2018 unchain_marker (XMARKER (p
->start
));
2021 /* Free window glyph matrices. It is sure that they are allocated
2022 again when ADJUST_GLYPHS is called. Block input so that expose
2023 events and other events that access glyph matrices are not
2024 processed while we are changing them. */
2026 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f
)));
2030 XWINDOW (tem
)->prev
= p
->prev
;
2034 XWINDOW (tem
)->next
= p
->next
;
2036 if (EQ (window
, par
->hchild
))
2037 par
->hchild
= p
->next
;
2038 if (EQ (window
, par
->vchild
))
2039 par
->vchild
= p
->next
;
2041 /* Find one of our siblings to give our space to. */
2045 /* If p gives its space to its next sibling, that sibling needs
2046 to have its top/left side pulled back to where p's is.
2047 set_window_{height,width} will re-position the sibling's
2050 XWINDOW (sib
)->top_line
= p
->top_line
;
2051 XWINDOW (sib
)->left_col
= p
->left_col
;
2054 /* Stretch that sibling. */
2055 if (!NILP (par
->vchild
))
2056 set_window_height (sib
,
2057 XFASTINT (XWINDOW (sib
)->total_lines
) + XFASTINT (p
->total_lines
),
2059 if (!NILP (par
->hchild
))
2060 set_window_width (sib
,
2061 XFASTINT (XWINDOW (sib
)->total_cols
) + XFASTINT (p
->total_cols
),
2064 /* If parent now has only one child,
2065 put the child into the parent's place. */
2069 if (NILP (XWINDOW (tem
)->next
)) {
2070 replace_window (parent
, tem
);
2071 par
= XWINDOW (tem
);
2074 /* Since we may be deleting combination windows, we must make sure that
2075 not only p but all its children have been marked as deleted. */
2076 if (! NILP (p
->hchild
))
2077 delete_all_subwindows (p
->hchild
);
2078 else if (! NILP (p
->vchild
))
2079 delete_all_subwindows (p
->vchild
);
2081 /* Mark this window as deleted. */
2082 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
2084 if (! NILP (par
->parent
))
2085 par
= XWINDOW (par
->parent
);
2087 /* Check if we have a v/hchild with a v/hchild. In that case remove
2090 if (! NILP (par
->vchild
) && ! NILP (XWINDOW (par
->vchild
)->vchild
))
2092 p
= XWINDOW (par
->vchild
);
2093 par
->vchild
= p
->vchild
;
2096 else if (! NILP (par
->hchild
) && ! NILP (XWINDOW (par
->hchild
)->hchild
))
2098 p
= XWINDOW (par
->hchild
);
2099 par
->hchild
= p
->hchild
;
2107 while (! NILP (tem
)) {
2108 XWINDOW (tem
)->parent
= p
->parent
;
2109 if (NILP (XWINDOW (tem
)->next
))
2111 tem
= XWINDOW (tem
)->next
;
2114 /* The next of the v/hchild we are removing is now the next of the
2115 last child for the v/hchild:
2116 Before v/hchild -> v/hchild -> next1 -> next2
2119 After: v/hchild -> next1 -> next2 -> next3
2121 XWINDOW (tem
)->next
= p
->next
;
2122 if (! NILP (p
->next
))
2123 XWINDOW (p
->next
)->prev
= tem
;
2125 p
->next
= p
->prev
= p
->vchild
= p
->hchild
= p
->buffer
= Qnil
;
2129 /* Adjust glyph matrices. */
2136 /***********************************************************************
2138 ***********************************************************************/
2140 /* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object
2141 pointer. This is a callback function for foreach_window, used in
2142 the window_list function. */
2145 add_window_to_list (struct window
*w
, void *user_data
)
2147 Lisp_Object
*list
= (Lisp_Object
*) user_data
;
2149 XSETWINDOW (window
, w
);
2150 *list
= Fcons (window
, *list
);
2155 /* Return a list of all windows, for use by next_window. If
2156 Vwindow_list is a list, return that list. Otherwise, build a new
2157 list, cache it in Vwindow_list, and return that. */
2162 if (!CONSP (Vwindow_list
))
2166 Vwindow_list
= Qnil
;
2167 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
2169 Lisp_Object args
[2];
2171 /* We are visiting windows in canonical order, and add
2172 new windows at the front of args[1], which means we
2173 have to reverse this list at the end. */
2175 foreach_window (XFRAME (XCAR (tail
)), add_window_to_list
, &args
[1]);
2176 args
[0] = Vwindow_list
;
2177 args
[1] = Fnreverse (args
[1]);
2178 Vwindow_list
= Fnconc (2, args
);
2182 return Vwindow_list
;
2186 /* Value is non-zero if WINDOW satisfies the constraints given by
2187 OWINDOW, MINIBUF and ALL_FRAMES.
2189 MINIBUF t means WINDOW may be minibuffer windows.
2190 `lambda' means WINDOW may not be a minibuffer window.
2191 a window means a specific minibuffer window
2193 ALL_FRAMES t means search all frames,
2194 nil means search just current frame,
2195 `visible' means search just visible frames on the
2197 0 means search visible and iconified frames on the
2199 a window means search the frame that window belongs to,
2200 a frame means consider windows on that frame, only. */
2203 candidate_window_p (Lisp_Object window
, Lisp_Object owindow
, Lisp_Object minibuf
, Lisp_Object all_frames
)
2205 struct window
*w
= XWINDOW (window
);
2206 struct frame
*f
= XFRAME (w
->frame
);
2207 int candidate_p
= 1;
2209 if (!BUFFERP (w
->buffer
))
2211 else if (MINI_WINDOW_P (w
)
2212 && (EQ (minibuf
, Qlambda
)
2213 || (WINDOWP (minibuf
) && !EQ (minibuf
, window
))))
2215 /* If MINIBUF is `lambda' don't consider any mini-windows.
2216 If it is a window, consider only that one. */
2219 else if (EQ (all_frames
, Qt
))
2221 else if (NILP (all_frames
))
2223 xassert (WINDOWP (owindow
));
2224 candidate_p
= EQ (w
->frame
, XWINDOW (owindow
)->frame
);
2226 else if (EQ (all_frames
, Qvisible
))
2228 FRAME_SAMPLE_VISIBILITY (f
);
2229 candidate_p
= FRAME_VISIBLE_P (f
)
2230 && (FRAME_TERMINAL (XFRAME (w
->frame
))
2231 == FRAME_TERMINAL (XFRAME (selected_frame
)));
2234 else if (INTEGERP (all_frames
) && XINT (all_frames
) == 0)
2236 FRAME_SAMPLE_VISIBILITY (f
);
2237 candidate_p
= (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)
2238 #ifdef HAVE_X_WINDOWS
2239 /* Yuck!! If we've just created the frame and the
2240 window-manager requested the user to place it
2241 manually, the window may still not be considered
2242 `visible'. I'd argue it should be at least
2243 something like `iconified', but don't know how to do
2245 || (FRAME_X_P (f
) && f
->output_data
.x
->asked_for_visible
2246 && !f
->output_data
.x
->has_been_visible
)
2249 && (FRAME_TERMINAL (XFRAME (w
->frame
))
2250 == FRAME_TERMINAL (XFRAME (selected_frame
)));
2252 else if (WINDOWP (all_frames
))
2253 candidate_p
= (EQ (FRAME_MINIBUF_WINDOW (f
), all_frames
)
2254 || EQ (XWINDOW (all_frames
)->frame
, w
->frame
)
2255 || EQ (XWINDOW (all_frames
)->frame
, FRAME_FOCUS_FRAME (f
)));
2256 else if (FRAMEP (all_frames
))
2257 candidate_p
= EQ (all_frames
, w
->frame
);
2263 /* Decode arguments as allowed by Fnext_window, Fprevious_window, and
2264 Fwindow_list. See candidate_window_p for the meaning of WINDOW,
2265 MINIBUF, and ALL_FRAMES. */
2268 decode_next_window_args (Lisp_Object
*window
, Lisp_Object
*minibuf
, Lisp_Object
*all_frames
)
2271 *window
= selected_window
;
2273 CHECK_LIVE_WINDOW (*window
);
2275 /* MINIBUF nil may or may not include minibuffers. Decide if it
2277 if (NILP (*minibuf
))
2278 *minibuf
= minibuf_level
? minibuf_window
: Qlambda
;
2279 else if (!EQ (*minibuf
, Qt
))
2282 /* Now *MINIBUF can be t => count all minibuffer windows, `lambda'
2283 => count none of them, or a specific minibuffer window (the
2284 active one) to count. */
2286 /* ALL_FRAMES nil doesn't specify which frames to include. */
2287 if (NILP (*all_frames
))
2288 *all_frames
= (!EQ (*minibuf
, Qlambda
)
2289 ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window
)->frame
))
2291 else if (EQ (*all_frames
, Qvisible
))
2293 else if (EQ (*all_frames
, make_number (0)))
2295 else if (FRAMEP (*all_frames
))
2297 else if (!EQ (*all_frames
, Qt
))
2302 /* Return the next or previous window of WINDOW in cyclic ordering
2303 of windows. NEXT_P non-zero means return the next window. See the
2304 documentation string of next-window for the meaning of MINIBUF and
2308 next_window (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
, int next_p
)
2310 decode_next_window_args (&window
, &minibuf
, &all_frames
);
2312 /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just
2313 return the first window on the frame. */
2314 if (FRAMEP (all_frames
)
2315 && !EQ (all_frames
, XWINDOW (window
)->frame
))
2316 return Fframe_first_window (all_frames
);
2322 /* Find WINDOW in the list of all windows. */
2323 list
= Fmemq (window
, window_list ());
2325 /* Scan forward from WINDOW to the end of the window list. */
2327 for (list
= XCDR (list
); CONSP (list
); list
= XCDR (list
))
2328 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
2331 /* Scan from the start of the window list up to WINDOW. */
2333 for (list
= Vwindow_list
;
2334 CONSP (list
) && !EQ (XCAR (list
), window
);
2336 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
2340 window
= XCAR (list
);
2344 Lisp_Object candidate
, list
;
2346 /* Scan through the list of windows for candidates. If there are
2347 candidate windows in front of WINDOW, the last one of these
2348 is the one we want. If there are candidates following WINDOW
2349 in the list, again the last one of these is the one we want. */
2351 for (list
= window_list (); CONSP (list
); list
= XCDR (list
))
2353 if (EQ (XCAR (list
), window
))
2355 if (WINDOWP (candidate
))
2358 else if (candidate_window_p (XCAR (list
), window
, minibuf
,
2360 candidate
= XCAR (list
);
2363 if (WINDOWP (candidate
))
2371 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
2372 doc
: /* Return window following WINDOW in cyclic ordering of windows.
2373 WINDOW defaults to the selected window. The optional arguments
2374 MINIBUF and ALL-FRAMES specify the set of windows to consider.
2376 MINIBUF t means consider the minibuffer window even if the
2377 minibuffer is not active. MINIBUF nil or omitted means consider
2378 the minibuffer window only if the minibuffer is active. Any
2379 other value means do not consider the minibuffer window even if
2380 the minibuffer is active.
2382 Several frames may share a single minibuffer; if the minibuffer
2383 is active, all windows on all frames that share that minibuffer
2384 are considered too. Therefore, if you are using a separate
2385 minibuffer frame and the minibuffer is active and MINIBUF says it
2386 counts, `next-window' considers the windows in the frame from
2387 which you entered the minibuffer, as well as the minibuffer
2390 ALL-FRAMES nil or omitted means consider all windows on WINDOW's
2391 frame, plus the minibuffer window if specified by the MINIBUF
2392 argument, see above. If the minibuffer counts, consider all
2393 windows on all frames that share that minibuffer too.
2394 ALL-FRAMES t means consider all windows on all existing frames.
2395 ALL-FRAMES `visible' means consider all windows on all visible
2396 frames on the current terminal.
2397 ALL-FRAMES 0 means consider all windows on all visible and
2398 iconified frames on the current terminal.
2399 ALL-FRAMES a frame means consider all windows on that frame only.
2400 Anything else means consider all windows on WINDOW's frame and no
2403 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
2404 `next-window' to iterate through the entire cycle of acceptable
2405 windows, eventually ending up back at the window you started with.
2406 `previous-window' traverses the same cycle, in the reverse order. */)
2407 (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
)
2409 return next_window (window
, minibuf
, all_frames
, 1);
2413 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
2414 doc
: /* Return window preceding WINDOW in cyclic ordering of windows.
2415 WINDOW defaults to the selected window. The optional arguments
2416 MINIBUF and ALL-FRAMES specify the set of windows to consider.
2417 For the precise meaning of these arguments see `next-window'.
2419 If you use consistent values for MINIBUF and ALL-FRAMES, you can
2420 use `previous-window' to iterate through the entire cycle of
2421 acceptable windows, eventually ending up back at the window you
2422 started with. `next-window' traverses the same cycle, in the
2424 (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
)
2426 return next_window (window
, minibuf
, all_frames
, 0);
2430 DEFUN ("window-list-1", Fwindow_list_1
, Swindow_list_1
, 0, 3, 0,
2431 doc
: /* Return a list of all live windows.
2432 WINDOW specifies the first window to list and defaults to the selected
2435 Optional argument MINIBUF nil or omitted means consider the minibuffer
2436 window only if the minibuffer is active. MINIBUF t means consider the
2437 minibuffer window even if the minibuffer is not active. Any other value
2438 means do not consider the minibuffer window even if the minibuffer is
2441 Optional argument ALL-FRAMES nil or omitted means consider all windows
2442 on WINDOW's frame, plus the minibuffer window if specified by the
2443 MINIBUF argument. If the minibuffer counts, consider all windows on all
2444 frames that share that minibuffer too. The following non-nil values of
2445 ALL-FRAMES have special meanings:
2447 - t means consider all windows on all existing frames.
2449 - `visible' means consider all windows on all visible frames.
2451 - 0 (the number zero) means consider all windows on all visible and
2454 - A frame means consider all windows on that frame only.
2456 Anything else means consider all windows on WINDOW's frame and no
2459 If WINDOW is not on the list of windows returned, some other window will
2460 be listed first but no error is signalled. */)
2461 (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
)
2463 return window_list_1 (window
, minibuf
, all_frames
);
2467 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
2468 doc
: /* Select another window in cyclic ordering of windows.
2469 COUNT specifies the number of windows to skip, starting with the
2470 selected window, before making the selection. If COUNT is
2471 positive, skip COUNT windows forwards. If COUNT is negative,
2472 skip -COUNT windows backwards. COUNT zero means do not skip any
2473 window, so select the selected window. In an interactive call,
2474 COUNT is the numeric prefix argument. Return nil.
2476 This function uses `next-window' for finding the window to select.
2477 The argument ALL-FRAMES has the same meaning as in `next-window',
2478 but the MINIBUF argument of `next-window' is always effectively
2480 (Lisp_Object count
, Lisp_Object all_frames
)
2485 CHECK_NUMBER (count
);
2486 window
= selected_window
;
2488 for (i
= XINT (count
); i
> 0; --i
)
2489 window
= Fnext_window (window
, Qnil
, all_frames
);
2491 window
= Fprevious_window (window
, Qnil
, all_frames
);
2493 Fselect_window (window
, Qnil
);
2498 /* Return a list of windows in cyclic ordering. Arguments are like
2499 for `next-window'. */
2502 window_list_1 (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
)
2504 Lisp_Object tail
, list
, rest
;
2506 decode_next_window_args (&window
, &minibuf
, &all_frames
);
2509 for (tail
= window_list (); CONSP (tail
); tail
= XCDR (tail
))
2510 if (candidate_window_p (XCAR (tail
), window
, minibuf
, all_frames
))
2511 list
= Fcons (XCAR (tail
), list
);
2513 /* Rotate the list to start with WINDOW. */
2514 list
= Fnreverse (list
);
2515 rest
= Fmemq (window
, list
);
2516 if (!NILP (rest
) && !EQ (rest
, list
))
2518 for (tail
= list
; !EQ (XCDR (tail
), rest
); tail
= XCDR (tail
))
2520 XSETCDR (tail
, Qnil
);
2521 list
= nconc2 (rest
, list
);
2527 DEFUN ("window-list", Fwindow_list
, Swindow_list
, 0, 3, 0,
2528 doc
: /* Return a list of windows on FRAME, starting with WINDOW.
2529 FRAME nil or omitted means use the selected frame.
2530 WINDOW nil or omitted means use the selected window.
2531 MINIBUF t means include the minibuffer window, even if it isn't active.
2532 MINIBUF nil or omitted means include the minibuffer window only
2534 MINIBUF neither nil nor t means never include the minibuffer window. */)
2535 (Lisp_Object frame
, Lisp_Object minibuf
, Lisp_Object window
)
2538 window
= FRAMEP (frame
) ? XFRAME (frame
)->selected_window
: selected_window
;
2539 CHECK_WINDOW (window
);
2541 frame
= selected_frame
;
2543 if (!EQ (frame
, XWINDOW (window
)->frame
))
2544 error ("Window is on a different frame");
2546 return window_list_1 (window
, minibuf
, frame
);
2551 /* Look at all windows, performing an operation specified by TYPE
2553 If FRAMES is Qt, look at all frames;
2554 Qnil, look at just the selected frame;
2555 Qvisible, look at visible frames;
2556 a frame, just look at windows on that frame.
2557 If MINI is non-zero, perform the operation on minibuffer windows too. */
2562 GET_BUFFER_WINDOW
, /* Arg is buffer */
2563 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
2564 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
2565 UNSHOW_BUFFER
, /* Arg is buffer */
2566 REDISPLAY_BUFFER_WINDOWS
, /* Arg is buffer */
2571 window_loop (enum window_loop type
, Lisp_Object obj
, int mini
, Lisp_Object frames
)
2573 Lisp_Object window
, windows
, best_window
, frame_arg
;
2575 struct gcpro gcpro1
;
2577 /* If we're only looping through windows on a particular frame,
2578 frame points to that frame. If we're looping through windows
2579 on all frames, frame is 0. */
2580 if (FRAMEP (frames
))
2581 f
= XFRAME (frames
);
2582 else if (NILP (frames
))
2583 f
= SELECTED_FRAME ();
2588 frame_arg
= Qlambda
;
2589 else if (EQ (frames
, make_number (0)))
2591 else if (EQ (frames
, Qvisible
))
2596 /* frame_arg is Qlambda to stick to one frame,
2597 Qvisible to consider all visible frames,
2600 /* Pick a window to start with. */
2604 window
= FRAME_SELECTED_WINDOW (f
);
2606 window
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
2608 windows
= window_list_1 (window
, mini
? Qt
: Qnil
, frame_arg
);
2612 for (; CONSP (windows
); windows
= XCDR (windows
))
2616 window
= XCAR (windows
);
2617 w
= XWINDOW (window
);
2619 /* Note that we do not pay attention here to whether the frame
2620 is visible, since Fwindow_list skips non-visible frames if
2621 that is desired, under the control of frame_arg. */
2622 if (!MINI_WINDOW_P (w
)
2623 /* For UNSHOW_BUFFER, we must always consider all windows. */
2624 || type
== UNSHOW_BUFFER
2625 || (mini
&& minibuf_level
> 0))
2628 case GET_BUFFER_WINDOW
:
2629 if (EQ (w
->buffer
, obj
)
2630 /* Don't find any minibuffer window
2631 except the one that is currently in use. */
2632 && (MINI_WINDOW_P (w
)
2633 ? EQ (window
, minibuf_window
)
2636 if (NILP (best_window
))
2637 best_window
= window
;
2638 else if (EQ (window
, selected_window
))
2639 /* Prefer to return selected-window. */
2640 RETURN_UNGCPRO (window
);
2641 else if (EQ (Fwindow_frame (window
), selected_frame
))
2642 /* Prefer windows on the current frame. */
2643 best_window
= window
;
2647 case DELETE_OTHER_WINDOWS
:
2648 if (!EQ (window
, obj
))
2649 Fdelete_window (window
);
2652 case DELETE_BUFFER_WINDOWS
:
2653 if (EQ (w
->buffer
, obj
))
2655 struct frame
*fr
= XFRAME (WINDOW_FRAME (w
));
2657 /* If this window is dedicated, and in a frame of its own,
2659 if (EQ (window
, FRAME_ROOT_WINDOW (fr
))
2660 && !NILP (w
->dedicated
)
2661 && other_visible_frames (fr
))
2663 /* Skip the other windows on this frame.
2664 There might be one, the minibuffer! */
2665 while (CONSP (XCDR (windows
))
2666 && EQ (XWINDOW (XCAR (windows
))->frame
,
2667 XWINDOW (XCAR (XCDR (windows
)))->frame
))
2668 windows
= XCDR (windows
);
2670 /* Now we can safely delete the frame. */
2671 delete_frame (w
->frame
, Qnil
);
2673 else if (NILP (w
->parent
))
2675 /* If we're deleting the buffer displayed in the
2676 only window on the frame, find a new buffer to
2679 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
2680 /* Reset dedicated state of window. */
2681 w
->dedicated
= Qnil
;
2682 Fset_window_buffer (window
, buffer
, Qnil
);
2683 if (EQ (window
, selected_window
))
2684 Fset_buffer (w
->buffer
);
2687 Fdelete_window (window
);
2692 if (EQ (w
->buffer
, obj
))
2695 struct frame
*fr
= XFRAME (w
->frame
);
2697 /* Find another buffer to show in this window. */
2698 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
2700 /* If this window is dedicated, and in a frame of its own,
2702 if (EQ (window
, FRAME_ROOT_WINDOW (fr
))
2703 && !NILP (w
->dedicated
)
2704 && other_visible_frames (fr
))
2706 /* Skip the other windows on this frame.
2707 There might be one, the minibuffer! */
2708 while (CONSP (XCDR (windows
))
2709 && EQ (XWINDOW (XCAR (windows
))->frame
,
2710 XWINDOW (XCAR (XCDR (windows
)))->frame
))
2711 windows
= XCDR (windows
);
2713 /* Now we can safely delete the frame. */
2714 delete_frame (w
->frame
, Qnil
);
2716 else if (!NILP (w
->dedicated
) && !NILP (w
->parent
))
2718 Lisp_Object window_to_delete
;
2719 XSETWINDOW (window_to_delete
, w
);
2720 /* If this window is dedicated and not the only window
2721 in its frame, then kill it. */
2722 Fdelete_window (window_to_delete
);
2726 /* Otherwise show a different buffer in the window. */
2727 w
->dedicated
= Qnil
;
2728 Fset_window_buffer (window
, buffer
, Qnil
);
2729 if (EQ (window
, selected_window
))
2730 Fset_buffer (w
->buffer
);
2735 case REDISPLAY_BUFFER_WINDOWS
:
2736 if (EQ (w
->buffer
, obj
))
2738 mark_window_display_accurate (window
, 0);
2739 w
->update_mode_line
= Qt
;
2740 XBUFFER (obj
)->prevent_redisplay_optimizations_p
= 1;
2741 ++update_mode_lines
;
2742 best_window
= window
;
2746 /* Check for a window that has a killed buffer. */
2747 case CHECK_ALL_WINDOWS
:
2748 if (! NILP (w
->buffer
)
2749 && NILP (BVAR (XBUFFER (w
->buffer
), name
)))
2753 case WINDOW_LOOP_UNUSED
:
2762 /* Used for debugging. Abort if any window has a dead buffer. */
2764 extern void check_all_windows (void) EXTERNALLY_VISIBLE
;
2766 check_all_windows (void)
2768 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
2771 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 0, 2, 0,
2772 doc
: /* Return a window currently displaying BUFFER-OR-NAME, or nil if none.
2773 BUFFER-OR-NAME may be a buffer or a buffer name and defaults to
2776 The optional argument ALL-FRAMES specifies the frames to consider:
2778 - t means consider all windows on all existing frames.
2780 - `visible' means consider all windows on all visible frames.
2782 - 0 (the number zero) means consider all windows on all visible
2783 and iconified frames.
2785 - A frame means consider all windows on that frame only.
2787 Any other value of ALL-FRAMES means consider all windows on the
2788 selected frame and no others. */)
2789 (Lisp_Object buffer_or_name
, Lisp_Object all_frames
)
2793 if (NILP (buffer_or_name
))
2794 buffer
= Fcurrent_buffer ();
2796 buffer
= Fget_buffer (buffer_or_name
);
2798 if (BUFFERP (buffer
))
2799 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, all_frames
);
2804 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
2806 doc
: /* Make WINDOW (or the selected window) fill its frame.
2807 Only the frame WINDOW is on is affected.
2808 This function tries to reduce display jumps by keeping the text
2809 previously visible in WINDOW in the same place on the frame. Doing this
2810 depends on the value of (window-start WINDOW), so if calling this
2811 function in a program gives strange scrolling, make sure the
2812 window-start value is reasonable when this function is called. */)
2813 (Lisp_Object window
)
2820 window
= selected_window
;
2822 CHECK_LIVE_WINDOW (window
);
2823 w
= XWINDOW (window
);
2825 startpos
= marker_position (w
->start
);
2826 top
= WINDOW_TOP_EDGE_LINE (w
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2828 if (MINI_WINDOW_P (w
) && top
> 0)
2829 error ("Can't expand minibuffer to full frame");
2831 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
2833 /* Try to minimize scrolling, by setting the window start to the point
2834 will cause the text at the old window start to be at the same place
2835 on the frame. But don't try to do this if the window start is
2836 outside the visible portion (as might happen when the display is
2837 not current, due to typeahead). */
2838 new_top
= WINDOW_TOP_EDGE_LINE (w
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2840 && startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
2841 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
2843 struct position pos
;
2844 struct buffer
*obuf
= current_buffer
;
2846 Fset_buffer (w
->buffer
);
2847 /* This computation used to temporarily move point, but that can
2848 have unwanted side effects due to text properties. */
2849 pos
= *vmotion (startpos
, -top
, w
);
2851 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
2852 w
->window_end_valid
= Qnil
;
2853 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
2854 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
2856 /* We need to do this, so that the window-scroll-functions
2858 w
->optional_new_start
= Qt
;
2860 set_buffer_internal (obuf
);
2866 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
2867 0, 2, "bDelete windows on (buffer): ",
2868 doc
: /* Delete all windows showing BUFFER-OR-NAME.
2869 BUFFER-OR-NAME may be a buffer or the name of an existing buffer and
2870 defaults to the current buffer.
2872 Optional second argument FRAME controls which frames are affected.
2873 If optional argument FRAME is `visible', search all visible frames.
2874 If FRAME is 0, search all visible and iconified frames.
2875 If FRAME is nil, search all frames.
2876 If FRAME is t, search only the selected frame.
2877 If FRAME is a frame, search only that frame.
2878 When a window showing BUFFER-OR-NAME is dedicated and the only window of
2879 its frame, that frame is deleted when there are other frames left. */)
2880 (Lisp_Object buffer_or_name
, Lisp_Object frame
)
2884 /* FRAME uses t and nil to mean the opposite of what window_loop
2888 else if (EQ (frame
, Qt
))
2891 if (NILP (buffer_or_name
))
2892 buffer
= Fcurrent_buffer ();
2895 buffer
= Fget_buffer (buffer_or_name
);
2896 CHECK_BUFFER (buffer
);
2899 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
2904 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
2905 Sreplace_buffer_in_windows
,
2906 0, 1, "bReplace buffer in windows: ",
2907 doc
: /* Replace BUFFER-OR-NAME with some other buffer in all windows showing it.
2908 BUFFER-OR-NAME may be a buffer or the name of an existing buffer and
2909 defaults to the current buffer.
2911 When a window showing BUFFER-OR-NAME is dedicated that window is
2912 deleted. If that window is the only window on its frame, that frame is
2913 deleted too when there are other frames left. If there are no other
2914 frames left, some other buffer is displayed in that window. */)
2915 (Lisp_Object buffer_or_name
)
2919 if (NILP (buffer_or_name
))
2920 buffer
= Fcurrent_buffer ();
2923 buffer
= Fget_buffer (buffer_or_name
);
2924 CHECK_BUFFER (buffer
);
2927 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
2932 /* Replace BUFFER with some other buffer in all windows
2933 of all frames, even those on other keyboards. */
2936 replace_buffer_in_all_windows (Lisp_Object buffer
)
2938 Lisp_Object tail
, frame
;
2940 /* A single call to window_loop won't do the job
2941 because it only considers frames on the current keyboard.
2942 So loop manually over frames, and handle each one. */
2943 FOR_EACH_FRAME (tail
, frame
)
2944 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
2947 /* Set the height of WINDOW and all its inferiors. */
2949 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
2950 minimum allowable size. */
2953 check_frame_size (FRAME_PTR frame
, int *rows
, int *cols
)
2955 /* For height, we have to see:
2956 how many windows the frame has at minimum (one or two),
2957 and whether it has a menu bar or other special stuff at the top. */
2959 = ((FRAME_MINIBUF_ONLY_P (frame
) || ! FRAME_HAS_MINIBUF_P (frame
))
2960 ? MIN_SAFE_WINDOW_HEIGHT
2961 : 2 * MIN_SAFE_WINDOW_HEIGHT
);
2963 if (FRAME_TOP_MARGIN (frame
) > 0)
2964 min_height
+= FRAME_TOP_MARGIN (frame
);
2966 if (*rows
< min_height
)
2968 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
2969 *cols
= MIN_SAFE_WINDOW_WIDTH
;
2972 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
2973 check if W's width can be changed, otherwise check W's height.
2974 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
2975 siblings, too. If none of the siblings is resizable, WINDOW isn't
2979 window_fixed_size_p (struct window
*w
, int width_p
, int check_siblings_p
)
2984 if (!NILP (w
->hchild
))
2986 c
= XWINDOW (w
->hchild
);
2990 /* A horizontal combination is fixed-width if all of if its
2992 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2993 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2994 fixed_p
= c
== NULL
;
2998 /* A horizontal combination is fixed-height if one of if its
3000 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
3001 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
3002 fixed_p
= c
!= NULL
;
3005 else if (!NILP (w
->vchild
))
3007 c
= XWINDOW (w
->vchild
);
3011 /* A vertical combination is fixed-width if one of if its
3013 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
3014 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
3015 fixed_p
= c
!= NULL
;
3019 /* A vertical combination is fixed-height if all of if its
3021 while (c
&& window_fixed_size_p (c
, width_p
, 0))
3022 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
3023 fixed_p
= c
== NULL
;
3026 else if (BUFFERP (w
->buffer
))
3028 struct buffer
*old
= current_buffer
;
3031 current_buffer
= XBUFFER (w
->buffer
);
3032 val
= find_symbol_value (Qwindow_size_fixed
);
3033 current_buffer
= old
;
3036 if (!EQ (val
, Qunbound
))
3038 fixed_p
= !NILP (val
);
3041 && ((EQ (val
, Qheight
) && width_p
)
3042 || (EQ (val
, Qwidth
) && !width_p
)))
3046 /* Can't tell if this one is resizable without looking at
3047 siblings. If all siblings are fixed-size this one is too. */
3048 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
3052 for (child
= w
->prev
; WINDOWP (child
); child
= XWINDOW (child
)->prev
)
3053 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
3057 for (child
= w
->next
; WINDOWP (child
); child
= XWINDOW (child
)->next
)
3058 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
3071 /* Return minimum size of leaf window W. WIDTH_P non-zero means return
3072 the minimum width of W, WIDTH_P zero means return the minimum height
3073 of W. SAFE_P non-zero means ignore window-min-height|width but just
3074 return values that won't crash Emacs and don't hide components like
3075 fringes, scrollbars, or modelines. If WIDTH_P is zero and W is the
3076 minibuffer window, always return 1. */
3079 window_min_size_2 (struct window
*w
, int width_p
, int safe_p
)
3081 /* We should consider buffer-local values of window_min_height and
3082 window_min_width here. */
3085 int safe_size
= (MIN_SAFE_WINDOW_WIDTH
3086 + WINDOW_FRINGE_COLS (w
)
3087 + WINDOW_SCROLL_BAR_COLS (w
));
3089 return safe_p
? safe_size
: max (window_min_width
, safe_size
);
3091 else if (MINI_WINDOW_P (w
))
3095 int safe_size
= (MIN_SAFE_WINDOW_HEIGHT
3096 + ((BUFFERP (w
->buffer
)
3097 && !NILP (BVAR (XBUFFER (w
->buffer
), mode_line_format
)))
3100 return safe_p
? safe_size
: max (window_min_height
, safe_size
);
3104 /* Return minimum size of window W, not taking fixed-width windows into
3105 account. WIDTH_P non-zero means return the minimum width, otherwise
3106 return the minimum height. SAFE_P non-zero means ignore
3107 window-min-height|width but just return values that won't crash Emacs
3108 and don't hide components like fringes, scrollbars, or modelines. If
3109 W is a combination window, compute the minimum size from the minimum
3110 sizes of W's children. */
3113 window_min_size_1 (struct window
*w
, int width_p
, int safe_p
)
3118 if (!NILP (w
->hchild
))
3120 /* W is a horizontal combination. */
3121 c
= XWINDOW (w
->hchild
);
3126 /* The minimum width of a horizontal combination is the sum of
3127 the minimum widths of its children. */
3130 size
+= window_min_size_1 (c
, 1, safe_p
);
3131 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
3136 /* The minimum height of a horizontal combination is the
3137 maximum of the minimum heights of its children. */
3140 size
= max (window_min_size_1 (c
, 0, safe_p
), size
);
3141 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
3145 else if (!NILP (w
->vchild
))
3147 /* W is a vertical combination. */
3148 c
= XWINDOW (w
->vchild
);
3153 /* The minimum width of a vertical combination is the maximum
3154 of the minimum widths of its children. */
3157 size
= max (window_min_size_1 (c
, 1, safe_p
), size
);
3158 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
3163 /* The minimum height of a vertical combination is the sum of
3164 the minimum height of its children. */
3167 size
+= window_min_size_1 (c
, 0, safe_p
);
3168 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
3173 /* W is a leaf window. */
3174 size
= window_min_size_2 (w
, width_p
, safe_p
);
3179 /* Return the minimum size of window W, taking fixed-size windows into
3180 account. WIDTH_P non-zero means return the minimum width, otherwise
3181 return the minimum height. SAFE_P non-zero means ignore
3182 window-min-height|width but just return values that won't crash Emacs
3183 and don't hide components like fringes, scrollbars, or modelines.
3184 IGNORE_FIXED_P non-zero means ignore if W is fixed-size. Set *FIXED
3185 to 1 if W is fixed-size unless FIXED is null. */
3188 window_min_size (struct window
*w
, int width_p
, int safe_p
, int ignore_fixed_p
, int *fixed
)
3195 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
3201 size
= WINDOW_TOTAL_SIZE (w
, width_p
);
3203 size
= window_min_size_1 (w
, width_p
, safe_p
);
3209 /* Adjust the margins of window W if text area is too small.
3210 Return 1 if window width is ok after adjustment; 0 if window
3211 is still too narrow. */
3214 adjust_window_margins (struct window
*w
)
3216 int box_cols
= (WINDOW_TOTAL_COLS (w
)
3217 - WINDOW_FRINGE_COLS (w
)
3218 - WINDOW_SCROLL_BAR_COLS (w
));
3219 int margin_cols
= (WINDOW_LEFT_MARGIN_COLS (w
)
3220 + WINDOW_RIGHT_MARGIN_COLS (w
));
3222 if (box_cols
- margin_cols
>= MIN_SAFE_WINDOW_WIDTH
)
3225 if (margin_cols
< 0 || box_cols
< MIN_SAFE_WINDOW_WIDTH
)
3228 /* Window's text area is too narrow, but reducing the window
3229 margins will fix that. */
3230 margin_cols
= box_cols
- MIN_SAFE_WINDOW_WIDTH
;
3231 if (WINDOW_RIGHT_MARGIN_COLS (w
) > 0)
3233 if (WINDOW_LEFT_MARGIN_COLS (w
) > 0)
3234 w
->left_margin_cols
= w
->right_margin_cols
3235 = make_number (margin_cols
/2);
3237 w
->right_margin_cols
= make_number (margin_cols
);
3240 w
->left_margin_cols
= make_number (margin_cols
);
3244 /* Calculate new sizes for windows in the list FORWARD when their
3245 compound size goes from TOTAL to SIZE. TOTAL must be greater than
3246 SIZE. The number of windows in FORWARD is NCHILDREN, and the number
3247 that can shrink is SHRINKABLE. Fixed-size windows may be shrunk if
3248 and only if RESIZE_FIXED_P is non-zero. WIDTH_P non-zero means
3249 shrink columns, otherwise shrink lines.
3251 SAFE_P zero means windows may be sized down to window-min-height
3252 lines (window-min-window columns for WIDTH_P non-zero). SAFE_P
3253 non-zero means windows may be sized down to their minimum safe sizes
3254 taking into account the space needed to display modelines, fringes,
3257 This function returns an allocated array of new sizes that the caller
3258 must free. A size -1 means the window is fixed and RESIZE_FIXED_P is
3259 zero. A size zero means the window shall be deleted. Array index 0
3260 refers to the first window in FORWARD, 1 to the second, and so on.
3262 This function resizes windows proportionally to their size. It also
3263 tries to preserve smaller windows by resizing larger windows before
3264 resizing any window to zero. If resize_proportionally is non-nil for
3265 a specific window, it will attempt to strictly resize that window
3266 proportionally, even at the expense of deleting smaller windows. */
3268 shrink_windows (int total
, int size
, int nchildren
, int shrinkable
,
3269 int resize_fixed_p
, Lisp_Object forward
, int width_p
, int safe_p
)
3271 int available_resize
= 0;
3272 int *new_sizes
, *min_sizes
;
3275 int smallest
= total
;
3276 int total_removed
= 0;
3277 int total_shrink
= total
- size
;
3280 new_sizes
= xmalloc (sizeof (*new_sizes
) * nchildren
);
3281 min_sizes
= xmalloc (sizeof (*min_sizes
) * nchildren
);
3283 for (i
= 0, child
= forward
; !NILP (child
); child
= c
->next
, ++i
)
3287 c
= XWINDOW (child
);
3288 child_size
= WINDOW_TOTAL_SIZE (c
, width_p
);
3290 if (!resize_fixed_p
&& window_fixed_size_p (c
, width_p
, 0))
3294 new_sizes
[i
] = child_size
;
3295 min_sizes
[i
] = window_min_size_1 (c
, width_p
, safe_p
);
3296 if (child_size
> min_sizes
[i
]
3297 && NILP (c
->resize_proportionally
))
3298 available_resize
+= child_size
- min_sizes
[i
];
3301 /* We might need to shrink some windows to zero. Find the smallest
3302 windows and set them to 0 until we can fulfil the new size. */
3304 while (shrinkable
> 1 && size
+ available_resize
< total
)
3306 for (i
= 0; i
< nchildren
; ++i
)
3307 if (new_sizes
[i
] > 0 && smallest
> new_sizes
[i
])
3308 smallest
= new_sizes
[i
];
3310 for (i
= 0; i
< nchildren
; ++i
)
3311 if (new_sizes
[i
] == smallest
)
3313 /* Resize this window down to zero. */
3315 if (smallest
> min_sizes
[i
])
3316 available_resize
-= smallest
- min_sizes
[i
];
3317 available_resize
+= smallest
;
3319 total_removed
+= smallest
;
3321 /* We don't know what the smallest is now. */
3324 /* Out of for, just remove one window at the time and
3325 check again if we have enough space. */
3330 /* Now, calculate the new sizes. Try to shrink each window
3331 proportional to its size. */
3332 for (i
= 0; i
< nchildren
; ++i
)
3334 if (new_sizes
[i
] > min_sizes
[i
])
3336 int to_shrink
= total_shrink
* new_sizes
[i
] / total
;
3338 if (new_sizes
[i
] - to_shrink
< min_sizes
[i
])
3339 to_shrink
= new_sizes
[i
] - min_sizes
[i
];
3340 new_sizes
[i
] -= to_shrink
;
3341 total_removed
+= to_shrink
;
3345 /* Any reminder due to rounding, we just subtract from windows
3346 that are left and still can be shrunk. */
3347 while (total_shrink
> total_removed
)
3349 int nonzero_sizes
= 0;
3351 for (i
= 0; i
< nchildren
; ++i
)
3352 if (new_sizes
[i
] > 0)
3355 for (i
= 0; i
< nchildren
; ++i
)
3356 if (new_sizes
[i
] > min_sizes
[i
])
3361 /* Out of for, just shrink one window at the time and
3362 check again if we have enough space. */
3366 /* Special case, only one window left. */
3367 if (nonzero_sizes
== 1)
3371 /* Any surplus due to rounding, we add to windows that are left. */
3372 while (total_shrink
< total_removed
)
3374 for (i
= 0; i
< nchildren
; ++i
)
3376 if (new_sizes
[i
] != 0 && total_shrink
< total_removed
)
3390 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
3391 WINDOW's width. Resize WINDOW's children, if any, so that they keep
3392 their proportionate size relative to WINDOW.
3394 If FIRST_ONLY is 1, change only the first of WINDOW's children when
3395 they are in series. If LAST_ONLY is 1, change only the last of
3396 WINDOW's children when they are in series.
3398 Propagate WINDOW's top or left edge position to children. Delete
3399 windows that become too small unless NODELETE_P is 1. When
3400 NODELETE_P equals 2 do not honor settings for window-min-height and
3401 window-min-width when resizing windows but use safe defaults instead.
3402 This should give better behavior when resizing frames. */
3405 size_window (Lisp_Object window
, int size
, int width_p
, int nodelete_p
, int first_only
, int last_only
)
3407 struct window
*w
= XWINDOW (window
);
3409 Lisp_Object child
, *forward
, *sideward
;
3410 int old_size
= WINDOW_TOTAL_SIZE (w
, width_p
);
3412 size
= max (0, size
);
3414 /* Delete WINDOW if it's too small. */
3415 if (nodelete_p
!= 1 && !NILP (w
->parent
)
3416 && size
< window_min_size_1 (w
, width_p
, nodelete_p
== 2))
3418 delete_window (window
);
3422 /* Set redisplay hints. */
3423 w
->last_modified
= make_number (0);
3424 w
->last_overlay_modified
= make_number (0);
3425 windows_or_buffers_changed
++;
3426 FRAME_WINDOW_SIZES_CHANGED (XFRAME (w
->frame
)) = 1;
3430 sideward
= &w
->vchild
;
3431 forward
= &w
->hchild
;
3432 w
->total_cols
= make_number (size
);
3433 adjust_window_margins (w
);
3437 sideward
= &w
->hchild
;
3438 forward
= &w
->vchild
;
3439 w
->total_lines
= make_number (size
);
3440 w
->orig_total_lines
= Qnil
;
3443 if (!NILP (*sideward
))
3445 /* We have a chain of parallel siblings whose size should all change. */
3446 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
3448 c
= XWINDOW (child
);
3450 c
->left_col
= w
->left_col
;
3452 c
->top_line
= w
->top_line
;
3453 size_window (child
, size
, width_p
, nodelete_p
,
3454 first_only
, last_only
);
3457 else if (!NILP (*forward
) && last_only
)
3459 /* Change the last in a series of siblings. */
3460 Lisp_Object last_child
;
3466 c
= XWINDOW (child
);
3470 while (!NILP (child
));
3472 child_size
= WINDOW_TOTAL_SIZE (c
, width_p
);
3473 size_window (last_child
, size
- old_size
+ child_size
,
3474 width_p
, nodelete_p
, first_only
, last_only
);
3476 else if (!NILP (*forward
) && first_only
)
3478 /* Change the first in a series of siblings. */
3482 c
= XWINDOW (child
);
3485 c
->left_col
= w
->left_col
;
3487 c
->top_line
= w
->top_line
;
3489 child_size
= WINDOW_TOTAL_SIZE (c
, width_p
);
3490 size_window (child
, size
- old_size
+ child_size
,
3491 width_p
, nodelete_p
, first_only
, last_only
);
3493 else if (!NILP (*forward
))
3495 int fixed_size
, each
IF_LINT (= 0), extra
IF_LINT (= 0), n
;
3496 int resize_fixed_p
, nfixed
;
3497 int last_pos
, first_pos
, nchildren
, total
;
3498 int *new_sizes
= NULL
;
3500 /* Determine the fixed-size portion of this window, and the
3501 number of child windows. */
3502 fixed_size
= nchildren
= nfixed
= total
= 0;
3503 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
3507 c
= XWINDOW (child
);
3508 child_size
= WINDOW_TOTAL_SIZE (c
, width_p
);
3509 total
+= child_size
;
3511 if (window_fixed_size_p (c
, width_p
, 0))
3513 fixed_size
+= child_size
;
3518 /* If the new size is smaller than fixed_size, or if there
3519 aren't any resizable windows, allow resizing fixed-size
3521 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
3523 /* Compute how many lines/columns to add/remove to each child. The
3524 value of extra takes care of rounding errors. */
3525 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
3526 if (size
< total
&& n
> 1)
3527 new_sizes
= shrink_windows (total
, size
, nchildren
, n
,
3528 resize_fixed_p
, *forward
, width_p
,
3532 each
= (size
- total
) / n
;
3533 extra
= (size
- total
) - n
* each
;
3536 /* Compute new children heights and edge positions. */
3537 first_pos
= width_p
? XINT (w
->left_col
) : XINT (w
->top_line
);
3538 last_pos
= first_pos
;
3539 for (n
= 0, child
= *forward
; !NILP (child
); child
= c
->next
, ++n
)
3541 int new_child_size
, old_child_size
;
3543 c
= XWINDOW (child
);
3544 old_child_size
= WINDOW_TOTAL_SIZE (c
, width_p
);
3545 new_child_size
= old_child_size
;
3547 /* The top or left edge position of this child equals the
3548 bottom or right edge of its predecessor. */
3550 c
->left_col
= make_number (last_pos
);
3552 c
->top_line
= make_number (last_pos
);
3554 /* If this child can be resized, do it. */
3555 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
3558 new_sizes
? new_sizes
[n
] : old_child_size
+ each
+ extra
;
3562 /* Set new size. Note that size_window also propagates
3563 edge positions to children, so it's not a no-op if we
3564 didn't change the child's size. */
3565 size_window (child
, new_child_size
, width_p
, 1,
3566 first_only
, last_only
);
3568 /* Remember the bottom/right edge position of this child; it
3569 will be used to set the top/left edge of the next child. */
3570 last_pos
+= new_child_size
;
3575 /* We should have covered the parent exactly with child windows. */
3576 xassert (size
== last_pos
- first_pos
);
3578 /* Now delete any children that became too small. */
3579 if (nodelete_p
!= 1)
3580 for (child
= *forward
; !NILP (child
); child
= c
->next
)
3584 c
= XWINDOW (child
);
3585 child_size
= WINDOW_TOTAL_SIZE (c
, width_p
);
3586 size_window (child
, child_size
, width_p
, nodelete_p
,
3587 first_only
, last_only
);
3592 /* Set WINDOW's height to HEIGHT, and recursively change the height of
3593 WINDOW's children. NODELETE zero means windows that have become
3594 smaller than window-min-height in the process may be deleted.
3595 NODELETE 1 means never delete windows that become too small in the
3596 process. (The caller should check later and do so if appropriate.)
3597 NODELETE 2 means delete only windows that have become too small to be
3598 displayed correctly. */
3601 set_window_height (Lisp_Object window
, int height
, int nodelete
)
3603 size_window (window
, height
, 0, nodelete
, 0, 0);
3606 /* Set WINDOW's width to WIDTH, and recursively change the width of
3607 WINDOW's children. NODELETE zero means windows that have become
3608 smaller than window-min-width in the process may be deleted.
3609 NODELETE 1 means never delete windows that become too small in the
3610 process. (The caller should check later and do so if appropriate.)
3611 NODELETE 2 means delete only windows that have become too small to be
3612 displayed correctly. */
3615 set_window_width (Lisp_Object window
, int width
, int nodelete
)
3617 size_window (window
, width
, 1, nodelete
, 0, 0);
3620 /* Change window heights in windows rooted in WINDOW by N lines. */
3623 change_window_heights (Lisp_Object window
, int n
)
3625 struct window
*w
= XWINDOW (window
);
3627 XSETFASTINT (w
->top_line
, XFASTINT (w
->top_line
) + n
);
3628 XSETFASTINT (w
->total_lines
, XFASTINT (w
->total_lines
) - n
);
3630 if (INTEGERP (w
->orig_top_line
))
3631 XSETFASTINT (w
->orig_top_line
, XFASTINT (w
->orig_top_line
) + n
);
3632 if (INTEGERP (w
->orig_total_lines
))
3633 XSETFASTINT (w
->orig_total_lines
, XFASTINT (w
->orig_total_lines
) - n
);
3635 /* Handle just the top child in a vertical split. */
3636 if (!NILP (w
->vchild
))
3637 change_window_heights (w
->vchild
, n
);
3639 /* Adjust all children in a horizontal split. */
3640 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
3642 w
= XWINDOW (window
);
3643 change_window_heights (window
, n
);
3648 int window_select_count
;
3650 static Lisp_Object
Fset_window_margins (Lisp_Object
, Lisp_Object
, Lisp_Object
);
3651 static Lisp_Object
Fset_window_fringes (Lisp_Object
, Lisp_Object
, Lisp_Object
,
3653 static Lisp_Object
Fset_window_scroll_bars (Lisp_Object
, Lisp_Object
,
3654 Lisp_Object
, Lisp_Object
);
3655 static Lisp_Object
Fset_window_vscroll (Lisp_Object
, Lisp_Object
, Lisp_Object
);
3658 run_funs (Lisp_Object funs
)
3660 for (; CONSP (funs
); funs
= XCDR (funs
))
3661 if (!EQ (XCAR (funs
), Qt
))
3662 call0 (XCAR (funs
));
3665 static Lisp_Object
select_window_norecord (Lisp_Object window
);
3666 static Lisp_Object
select_frame_norecord (Lisp_Object frame
);
3669 run_window_configuration_change_hook (struct frame
*f
)
3671 int count
= SPECPDL_INDEX ();
3672 Lisp_Object frame
, global_wcch
3673 = Fdefault_value (Qwindow_configuration_change_hook
);
3674 XSETFRAME (frame
, f
);
3676 if (NILP (Vrun_hooks
))
3679 if (SELECTED_FRAME () != f
)
3681 record_unwind_protect (select_frame_norecord
, Fselected_frame ());
3682 Fselect_frame (frame
, Qt
);
3685 /* Use the right buffer. Matters when running the local hooks. */
3686 if (current_buffer
!= XBUFFER (Fwindow_buffer (Qnil
)))
3688 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
3689 Fset_buffer (Fwindow_buffer (Qnil
));
3692 /* Look for buffer-local values. */
3694 Lisp_Object windows
= Fwindow_list (frame
, Qlambda
, Qnil
);
3695 for (; CONSP (windows
); windows
= XCDR (windows
))
3697 Lisp_Object window
= XCAR (windows
);
3698 Lisp_Object buffer
= Fwindow_buffer (window
);
3699 if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook
,
3702 int count1
= SPECPDL_INDEX ();
3703 record_unwind_protect (select_window_norecord
, Fselected_window ());
3704 select_window_norecord (window
);
3705 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook
,
3707 unbind_to (count1
, Qnil
);
3712 run_funs (global_wcch
);
3713 unbind_to (count
, Qnil
);
3716 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
3717 means it's allowed to run hooks. See make_frame for a case where
3718 it's not allowed. KEEP_MARGINS_P non-zero means that the current
3719 margins, fringes, and scroll-bar settings of the window are not
3720 reset from the buffer's local settings. */
3723 set_window_buffer (Lisp_Object window
, Lisp_Object buffer
, int run_hooks_p
, int keep_margins_p
)
3725 struct window
*w
= XWINDOW (window
);
3726 struct buffer
*b
= XBUFFER (buffer
);
3727 int count
= SPECPDL_INDEX ();
3728 int samebuf
= EQ (buffer
, w
->buffer
);
3732 if (EQ (window
, selected_window
))
3733 BVAR (b
, last_selected_window
) = window
;
3735 /* Let redisplay errors through. */
3736 b
->display_error_modiff
= 0;
3738 /* Update time stamps of buffer display. */
3739 if (INTEGERP (BVAR (b
, display_count
)))
3740 XSETINT (BVAR (b
, display_count
), XINT (BVAR (b
, display_count
)) + 1);
3741 BVAR (b
, display_time
) = Fcurrent_time ();
3743 XSETFASTINT (w
->window_end_pos
, 0);
3744 XSETFASTINT (w
->window_end_vpos
, 0);
3745 memset (&w
->last_cursor
, 0, sizeof w
->last_cursor
);
3746 w
->window_end_valid
= Qnil
;
3747 if (!(keep_margins_p
&& samebuf
))
3748 { /* If we're not actually changing the buffer, don't reset hscroll and
3749 vscroll. This case happens for example when called from
3750 change_frame_size_1, where we use a dummy call to
3751 Fset_window_buffer on the frame's selected window (and no other)
3752 just in order to run window-configuration-change-hook.
3753 Resetting hscroll and vscroll here is problematic for things like
3754 image-mode and doc-view-mode since it resets the image's position
3755 whenever we resize the frame. */
3756 w
->hscroll
= w
->min_hscroll
= make_number (0);
3758 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
3759 set_marker_restricted (w
->start
,
3760 make_number (b
->last_window_start
),
3762 w
->start_at_line_beg
= Qnil
;
3763 w
->force_start
= Qnil
;
3764 XSETFASTINT (w
->last_modified
, 0);
3765 XSETFASTINT (w
->last_overlay_modified
, 0);
3767 /* Maybe we could move this into the `if' but it's not obviously safe and
3768 I doubt it's worth the trouble. */
3769 windows_or_buffers_changed
++;
3771 /* We must select BUFFER for running the window-scroll-functions. */
3772 /* We can't check ! NILP (Vwindow_scroll_functions) here
3773 because that might itself be a local variable. */
3774 if (window_initialized
)
3776 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
3777 Fset_buffer (buffer
);
3780 XMARKER (w
->pointm
)->insertion_type
= !NILP (Vwindow_point_insertion_type
);
3782 if (!keep_margins_p
)
3784 /* Set left and right marginal area width etc. from buffer. */
3786 /* This may call adjust_window_margins three times, so
3787 temporarily disable window margins. */
3788 Lisp_Object save_left
= w
->left_margin_cols
;
3789 Lisp_Object save_right
= w
->right_margin_cols
;
3791 w
->left_margin_cols
= w
->right_margin_cols
= Qnil
;
3793 Fset_window_fringes (window
,
3794 BVAR (b
, left_fringe_width
), BVAR (b
, right_fringe_width
),
3795 BVAR (b
, fringes_outside_margins
));
3797 Fset_window_scroll_bars (window
,
3798 BVAR (b
, scroll_bar_width
),
3799 BVAR (b
, vertical_scroll_bar_type
), Qnil
);
3801 w
->left_margin_cols
= save_left
;
3802 w
->right_margin_cols
= save_right
;
3804 Fset_window_margins (window
,
3805 BVAR (b
, left_margin_cols
), BVAR (b
, right_margin_cols
));
3810 if (! NILP (Vwindow_scroll_functions
))
3811 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
3812 Fmarker_position (w
->start
));
3813 run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w
)));
3816 unbind_to (count
, Qnil
);
3819 DEFUN ("set-window-clone-number", Fset_window_clone_number
, Sset_window_clone_number
, 2, 2, 0,
3820 doc
: /* Set WINDOW's clone number to CLONE-NUMBER.
3821 WINDOW can be any window and defaults to the selected one. */)
3822 (Lisp_Object window
, Lisp_Object clone_number
)
3824 register struct window
*w
= decode_any_window (window
);
3826 CHECK_NUMBER (clone_number
);
3827 w
->clone_number
= clone_number
;
3828 return w
->clone_number
;
3831 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 3, 0,
3832 doc
: /* Make WINDOW display BUFFER-OR-NAME as its contents.
3833 WINDOW defaults to the selected window. BUFFER-OR-NAME must be a buffer
3834 or the name of an existing buffer. Optional third argument KEEP-MARGINS
3835 non-nil means that WINDOW's current display margins, fringe widths, and
3836 scroll bar settings are preserved; the default is to reset these from
3837 the local settings for BUFFER-OR-NAME or the frame defaults. Return nil.
3839 This function throws an error when WINDOW is strongly dedicated to its
3840 buffer (that is `window-dedicated-p' returns t for WINDOW) and does not
3841 already display BUFFER-OR-NAME.
3843 This function runs `window-scroll-functions' before running
3844 `window-configuration-change-hook'. */)
3845 (register Lisp_Object window
, Lisp_Object buffer_or_name
, Lisp_Object keep_margins
)
3847 register Lisp_Object tem
, buffer
;
3848 register struct window
*w
= decode_window (window
);
3850 XSETWINDOW (window
, w
);
3851 buffer
= Fget_buffer (buffer_or_name
);
3852 CHECK_BUFFER (buffer
);
3853 if (NILP (BVAR (XBUFFER (buffer
), name
)))
3854 error ("Attempt to display deleted buffer");
3858 error ("Window is deleted");
3859 else if (!EQ (tem
, Qt
))
3860 /* w->buffer is t when the window is first being set up. */
3862 if (EQ (tem
, buffer
))
3864 else if (EQ (w
->dedicated
, Qt
))
3865 error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem
), name
)));
3867 w
->dedicated
= Qnil
;
3872 set_window_buffer (window
, buffer
, 1, !NILP (keep_margins
));
3877 select_window_norecord (Lisp_Object window
)
3879 return WINDOW_LIVE_P (window
)
3880 ? Fselect_window (window
, Qt
) : selected_window
;
3884 select_frame_norecord (Lisp_Object frame
)
3886 return FRAME_LIVE_P (XFRAME (frame
))
3887 ? Fselect_frame (frame
, Qt
) : selected_frame
;
3891 display_buffer (Lisp_Object buffer
, Lisp_Object not_this_window_p
, Lisp_Object override_frame
)
3893 return call3 (Qdisplay_buffer
, buffer
, not_this_window_p
, override_frame
);
3896 DEFUN ("force-window-update", Fforce_window_update
, Sforce_window_update
,
3898 doc
: /* Force all windows to be updated on next redisplay.
3899 If optional arg OBJECT is a window, force redisplay of that window only.
3900 If OBJECT is a buffer or buffer name, force redisplay of all windows
3901 displaying that buffer. */)
3902 (Lisp_Object object
)
3906 windows_or_buffers_changed
++;
3907 update_mode_lines
++;
3911 if (WINDOWP (object
))
3913 struct window
*w
= XWINDOW (object
);
3914 mark_window_display_accurate (object
, 0);
3915 w
->update_mode_line
= Qt
;
3916 if (BUFFERP (w
->buffer
))
3917 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
3918 ++update_mode_lines
;
3922 if (STRINGP (object
))
3923 object
= Fget_buffer (object
);
3924 if (BUFFERP (object
) && !NILP (BVAR (XBUFFER (object
), name
)))
3926 /* Walk all windows looking for buffer, and force update
3927 of each of those windows. */
3929 object
= window_loop (REDISPLAY_BUFFER_WINDOWS
, object
, 0, Qvisible
);
3930 return NILP (object
) ? Qnil
: Qt
;
3933 /* If nothing suitable was found, just return.
3934 We could signal an error, but this feature will typically be used
3935 asynchronously in timers or process sentinels, so we don't. */
3941 temp_output_buffer_show (register Lisp_Object buf
)
3943 register struct buffer
*old
= current_buffer
;
3944 register Lisp_Object window
;
3945 register struct window
*w
;
3947 BVAR (XBUFFER (buf
), directory
) = BVAR (current_buffer
, directory
);
3950 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
3954 set_buffer_internal (old
);
3956 if (!NILP (Vtemp_buffer_show_function
))
3957 call1 (Vtemp_buffer_show_function
, buf
);
3960 window
= display_buffer (buf
, Qnil
, Qnil
);
3962 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
3963 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
3964 Vminibuf_scroll_window
= window
;
3965 w
= XWINDOW (window
);
3966 XSETFASTINT (w
->hscroll
, 0);
3967 XSETFASTINT (w
->min_hscroll
, 0);
3968 set_marker_restricted_both (w
->start
, buf
, BEG
, BEG
);
3969 set_marker_restricted_both (w
->pointm
, buf
, BEG
, BEG
);
3971 /* Run temp-buffer-show-hook, with the chosen window selected
3972 and its buffer current. */
3974 int count
= SPECPDL_INDEX ();
3975 Lisp_Object prev_window
, prev_buffer
;
3976 prev_window
= selected_window
;
3977 XSETBUFFER (prev_buffer
, old
);
3979 /* Select the window that was chosen, for running the hook.
3980 Note: Both Fselect_window and select_window_norecord may
3981 set-buffer to the buffer displayed in the window,
3982 so we need to save the current buffer. --stef */
3983 record_unwind_protect (Fset_buffer
, prev_buffer
);
3984 record_unwind_protect (select_window_norecord
, prev_window
);
3985 Fselect_window (window
, Qt
);
3986 Fset_buffer (w
->buffer
);
3987 Frun_hooks (1, &Qtemp_buffer_show_hook
);
3988 unbind_to (count
, Qnil
);
3993 DEFUN ("internal-temp-output-buffer-show",
3994 Ftemp_output_buffer_show
, Stemp_output_buffer_show
,
3996 doc
: /* Internal function for `with-output-to-temp-buffer''. */)
3999 temp_output_buffer_show (buf
);
4004 make_dummy_parent (Lisp_Object window
)
4007 register struct window
*o
, *p
;
4010 o
= XWINDOW (window
);
4011 p
= allocate_window ();
4012 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
4013 ((struct Lisp_Vector
*) p
)->contents
[i
]
4014 = ((struct Lisp_Vector
*)o
)->contents
[i
];
4015 XSETWINDOW (new, p
);
4018 XSETFASTINT (p
->sequence_number
, sequence_number
);
4019 XSETFASTINT (p
->clone_number
, sequence_number
);
4021 /* Put new into window structure in place of window */
4022 replace_window (window
, new);
4036 p
->window_parameters
= Qnil
;
4040 /* Make new window from scratch. */
4045 register struct window
*w
;
4047 w
= allocate_window ();
4048 /* Initialize all Lisp data. */
4049 w
->frame
= w
->mini_p
= Qnil
;
4050 w
->next
= w
->prev
= w
->hchild
= w
->vchild
= w
->parent
= Qnil
;
4051 XSETFASTINT (w
->left_col
, 0);
4052 XSETFASTINT (w
->top_line
, 0);
4053 XSETFASTINT (w
->total_lines
, 0);
4054 XSETFASTINT (w
->total_cols
, 0);
4055 w
->normal_lines
= make_float (1.0);
4056 w
->normal_cols
= make_float (1.0);
4057 XSETFASTINT (w
->new_total
, 0);
4058 XSETFASTINT (w
->new_normal
, 0);
4060 w
->start
= Fmake_marker ();
4061 w
->pointm
= Fmake_marker ();
4062 w
->force_start
= w
->optional_new_start
= Qnil
;
4063 XSETFASTINT (w
->hscroll
, 0);
4064 XSETFASTINT (w
->min_hscroll
, 0);
4065 XSETFASTINT (w
->use_time
, 0);
4067 XSETFASTINT (w
->sequence_number
, sequence_number
);
4068 XSETFASTINT (w
->clone_number
, sequence_number
);
4069 w
->temslot
= w
->last_modified
= w
->last_overlay_modified
= Qnil
;
4070 XSETFASTINT (w
->last_point
, 0);
4071 w
->last_had_star
= w
->vertical_scroll_bar
= Qnil
;
4072 w
->left_margin_cols
= w
->right_margin_cols
= Qnil
;
4073 w
->left_fringe_width
= w
->right_fringe_width
= Qnil
;
4074 w
->fringes_outside_margins
= Qnil
;
4075 w
->scroll_bar_width
= Qnil
;
4076 w
->vertical_scroll_bar_type
= Qt
;
4077 w
->last_mark_x
= w
->last_mark_y
= Qnil
;
4078 XSETFASTINT (w
->window_end_pos
, 0);
4079 XSETFASTINT (w
->window_end_vpos
, 0);
4080 w
->window_end_valid
= w
->update_mode_line
= Qnil
;
4081 w
->start_at_line_beg
= w
->display_table
= w
->dedicated
= Qnil
;
4082 w
->base_line_number
= w
->base_line_pos
= w
->region_showing
= Qnil
;
4083 w
->column_number_displayed
= w
->redisplay_end_trigger
= Qnil
;
4084 w
->splits
= w
->nest
= w
->window_parameters
= Qnil
;
4085 w
->prev_buffers
= w
->next_buffers
= Qnil
;
4086 /* Initialize non-Lisp data. */
4087 w
->desired_matrix
= w
->current_matrix
= 0;
4088 w
->nrows_scale_factor
= w
->ncols_scale_factor
= 1;
4089 memset (&w
->cursor
, 0, sizeof (w
->cursor
));
4090 memset (&w
->last_cursor
, 0, sizeof (w
->last_cursor
));
4091 memset (&w
->phys_cursor
, 0, sizeof (w
->phys_cursor
));
4092 w
->phys_cursor_type
= -1;
4093 w
->phys_cursor_width
= -1;
4094 w
->last_cursor_off_p
= w
->cursor_off_p
= 0;
4095 w
->must_be_updated_p
= 0;
4096 w
->pseudo_window_p
= 0;
4097 w
->frozen_window_start_p
= 0;
4099 w
->resize_proportionally
= Qnil
;
4100 /* Reset window_list. */
4101 Vwindow_list
= Qnil
;
4102 /* Return window. */
4103 XSETWINDOW (window
, w
);
4107 DEFUN ("set-window-new-total", Fset_window_new_total
, Sset_window_new_total
, 2, 3, 0,
4108 doc
: /* Set new total size of WINDOW to SIZE.
4111 Optional argument ADD non-nil means add SIZE to the new total size of
4112 WINDOW and return the sum.
4114 Note: This function does not operate on any subwindows of WINDOW. */)
4115 (Lisp_Object window
, Lisp_Object size
, Lisp_Object add
)
4117 struct window
*w
= decode_any_window (window
);
4119 CHECK_NUMBER (size
);
4121 XSETINT (w
->new_total
, XINT (size
));
4123 XSETINT (w
->new_total
, XINT (w
->new_total
) + XINT (size
));
4125 return w
->new_total
;
4128 DEFUN ("set-window-new-normal", Fset_window_new_normal
, Sset_window_new_normal
, 1, 2, 0,
4129 doc
: /* Set new normal size of WINDOW to SIZE.
4132 Note: This function does not operate on any subwindows of WINDOW. */)
4133 (Lisp_Object window
, Lisp_Object size
)
4135 struct window
*w
= decode_any_window (window
);
4137 w
->new_normal
= size
;
4138 return w
->new_normal
;
4141 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
4142 doc
: /* Split WINDOW, putting SIZE lines in the first of the pair.
4143 WINDOW defaults to selected one and SIZE to half its size.
4144 If optional third arg HORIZONTAL is non-nil, split side by side and put
4145 SIZE columns in the first of the pair. In that case, SIZE includes that
4146 window's scroll bar, or the divider column to its right.
4147 Interactively, all arguments are nil.
4148 Returns the newly created window (which is the lower or rightmost one).
4149 The upper or leftmost window is the original one, and remains selected
4150 if it was selected before.
4152 See Info node `(elisp)Splitting Windows' for more details and examples. */)
4153 (Lisp_Object window
, Lisp_Object size
, Lisp_Object horizontal
)
4155 register Lisp_Object
new;
4156 register struct window
*o
, *p
;
4158 register int size_int
;
4161 window
= selected_window
;
4163 CHECK_LIVE_WINDOW (window
);
4165 o
= XWINDOW (window
);
4166 fo
= XFRAME (WINDOW_FRAME (o
));
4170 if (!NILP (horizontal
))
4171 /* Calculate the size of the left-hand window, by dividing
4172 the usable space in columns by two.
4173 We round up, since the left-hand window may include
4174 a dividing line, while the right-hand may not. */
4175 size_int
= (XFASTINT (o
->total_cols
) + 1) >> 1;
4177 size_int
= XFASTINT (o
->total_lines
) >> 1;
4181 CHECK_NUMBER (size
);
4182 size_int
= XINT (size
);
4185 if (MINI_WINDOW_P (o
))
4186 error ("Attempt to split minibuffer window");
4187 else if (window_fixed_size_p (o
, !NILP (horizontal
), 0))
4188 error ("Attempt to split fixed-size window");
4190 if (NILP (horizontal
))
4192 int window_safe_height
= window_min_size_2 (o
, 0, 0);
4194 if (size_int
< window_safe_height
)
4195 error ("Window height %d too small (after splitting)", size_int
);
4196 if (size_int
+ window_safe_height
> XFASTINT (o
->total_lines
))
4197 error ("Window height %d too small (after splitting)",
4198 (int) (XFASTINT (o
->total_lines
) - size_int
));
4199 if (NILP (o
->parent
)
4200 || NILP (XWINDOW (o
->parent
)->vchild
))
4202 make_dummy_parent (window
);
4204 XWINDOW (new)->vchild
= window
;
4209 int window_safe_width
= window_min_size_2 (o
, 1, 0);
4211 if (size_int
< window_safe_width
)
4212 error ("Window width %d too small (after splitting)", size_int
);
4213 if (size_int
+ window_safe_width
> XFASTINT (o
->total_cols
))
4214 error ("Window width %d too small (after splitting)",
4215 (int) (XFASTINT (o
->total_cols
) - size_int
));
4216 if (NILP (o
->parent
)
4217 || NILP (XWINDOW (o
->parent
)->hchild
))
4219 make_dummy_parent (window
);
4221 XWINDOW (new)->hchild
= window
;
4225 /* Now we know that window's parent is a vertical combination
4226 if we are dividing vertically, or a horizontal combination
4227 if we are making side-by-side windows */
4229 windows_or_buffers_changed
++;
4230 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
4231 new = make_window ();
4234 p
->frame
= o
->frame
;
4236 if (!NILP (p
->next
))
4237 XWINDOW (p
->next
)->prev
= new;
4240 p
->parent
= o
->parent
;
4242 p
->window_end_valid
= Qnil
;
4243 memset (&p
->last_cursor
, 0, sizeof p
->last_cursor
);
4245 /* Duplicate special geometry settings. */
4247 p
->left_margin_cols
= o
->left_margin_cols
;
4248 p
->right_margin_cols
= o
->right_margin_cols
;
4249 p
->left_fringe_width
= o
->left_fringe_width
;
4250 p
->right_fringe_width
= o
->right_fringe_width
;
4251 p
->fringes_outside_margins
= o
->fringes_outside_margins
;
4252 p
->scroll_bar_width
= o
->scroll_bar_width
;
4253 p
->vertical_scroll_bar_type
= o
->vertical_scroll_bar_type
;
4255 /* Apportion the available frame space among the two new windows */
4257 if (!NILP (horizontal
))
4259 p
->total_lines
= o
->total_lines
;
4260 p
->top_line
= o
->top_line
;
4261 XSETFASTINT (p
->total_cols
, XFASTINT (o
->total_cols
) - size_int
);
4262 XSETFASTINT (o
->total_cols
, size_int
);
4263 XSETFASTINT (p
->left_col
, XFASTINT (o
->left_col
) + size_int
);
4264 adjust_window_margins (p
);
4265 adjust_window_margins (o
);
4269 p
->left_col
= o
->left_col
;
4270 p
->total_cols
= o
->total_cols
;
4271 XSETFASTINT (p
->total_lines
, XFASTINT (o
->total_lines
) - size_int
);
4272 XSETFASTINT (o
->total_lines
, size_int
);
4273 XSETFASTINT (p
->top_line
, XFASTINT (o
->top_line
) + size_int
);
4276 /* Adjust glyph matrices. */
4279 Fset_window_buffer (new, o
->buffer
, Qt
);
4283 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
4284 doc
: /* Make selected window SIZE lines taller.
4285 Interactively, if no argument is given, make the selected window one
4286 line taller. If optional argument HORIZONTAL is non-nil, make selected
4287 window wider by SIZE columns. If SIZE is negative, shrink the window by
4288 -SIZE lines or columns. Return nil.
4290 This function can delete windows if they get too small. The size of
4291 fixed size windows is not altered by this function. */)
4292 (Lisp_Object size
, Lisp_Object horizontal
)
4294 CHECK_NUMBER (size
);
4295 enlarge_window (selected_window
, XINT (size
), !NILP (horizontal
));
4297 run_window_configuration_change_hook (SELECTED_FRAME ());
4302 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
4303 doc
: /* Make selected window SIZE lines smaller.
4304 Interactively, if no argument is given, make the selected window one
4305 line smaller. If optional argument HORIZONTAL is non-nil, make the
4306 window narrower by SIZE columns. If SIZE is negative, enlarge selected
4307 window by -SIZE lines or columns. Return nil.
4309 This function can delete windows if they get too small. The size of
4310 fixed size windows is not altered by this function. */)
4311 (Lisp_Object size
, Lisp_Object horizontal
)
4313 CHECK_NUMBER (size
);
4314 enlarge_window (selected_window
, -XINT (size
), !NILP (horizontal
));
4316 run_window_configuration_change_hook (SELECTED_FRAME ());
4322 window_height (Lisp_Object window
)
4324 register struct window
*p
= XWINDOW (window
);
4325 return WINDOW_TOTAL_LINES (p
);
4329 window_width (Lisp_Object window
)
4331 register struct window
*p
= XWINDOW (window
);
4332 return WINDOW_TOTAL_COLS (p
);
4337 *(horiz_flag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
4339 #define CURSIZE(w) \
4340 *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
4343 /* Enlarge WINDOW by DELTA. HORIZ_FLAG nonzero means enlarge it
4344 horizontally; zero means do it vertically.
4346 Siblings of the selected window are resized to fulfill the size
4347 request. If they become too small in the process, they may be
4351 enlarge_window (Lisp_Object window
, int delta
, int horiz_flag
)
4353 Lisp_Object parent
, next
, prev
;
4357 int (*sizefun
) (Lisp_Object
)
4358 = horiz_flag
? window_width
: window_height
;
4359 void (*setsizefun
) (Lisp_Object
, int, int)
4360 = (horiz_flag
? set_window_width
: set_window_height
);
4362 /* Give up if this window cannot be resized. */
4363 if (window_fixed_size_p (XWINDOW (window
), horiz_flag
, 1))
4364 error ("Window is not resizable");
4366 /* Find the parent of the selected window. */
4369 p
= XWINDOW (window
);
4375 error ("No other window to side of this one");
4380 ? !NILP (XWINDOW (parent
)->hchild
)
4381 : !NILP (XWINDOW (parent
)->vchild
))
4387 sizep
= &CURSIZE (window
);
4390 register int maxdelta
;
4392 /* Compute the maximum size increment this window can have. */
4394 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - XINT (*sizep
)
4395 /* This is a main window followed by a minibuffer. */
4396 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
4397 - window_min_size (XWINDOW (p
->next
),
4398 horiz_flag
, 0, 0, 0))
4399 /* This is a minibuffer following a main window. */
4400 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
4401 - window_min_size (XWINDOW (p
->prev
),
4402 horiz_flag
, 0, 0, 0))
4403 /* This is a frame with only one window, a minibuffer-only
4404 or a minibufferless frame. */
4407 if (delta
> maxdelta
)
4408 /* This case traps trying to make the minibuffer
4409 the full frame, or make the only window aside from the
4410 minibuffer the full frame. */
4414 if (XINT (*sizep
) + delta
< window_min_size (XWINDOW (window
),
4415 horiz_flag
, 0, 0, 0))
4417 delete_window (window
);
4424 /* Find the total we can get from other siblings without deleting them. */
4426 for (next
= p
->next
; WINDOWP (next
); next
= XWINDOW (next
)->next
)
4427 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
4428 horiz_flag
, 0, 0, 0);
4429 for (prev
= p
->prev
; WINDOWP (prev
); prev
= XWINDOW (prev
)->prev
)
4430 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
4431 horiz_flag
, 0, 0, 0);
4433 /* If we can get it all from them without deleting them, do so. */
4434 if (delta
<= maximum
)
4436 Lisp_Object first_unaffected
;
4437 Lisp_Object first_affected
;
4442 first_affected
= window
;
4443 /* Look at one sibling at a time,
4444 moving away from this window in both directions alternately,
4445 and take as much as we can get without deleting that sibling. */
4447 && (!NILP (next
) || !NILP (prev
)))
4451 int this_one
= ((*sizefun
) (next
)
4452 - window_min_size (XWINDOW (next
), horiz_flag
,
4456 if (this_one
> delta
)
4459 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
4460 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
4465 next
= XWINDOW (next
)->next
;
4473 int this_one
= ((*sizefun
) (prev
)
4474 - window_min_size (XWINDOW (prev
), horiz_flag
,
4478 if (this_one
> delta
)
4481 first_affected
= prev
;
4483 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
4484 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
4489 prev
= XWINDOW (prev
)->prev
;
4493 xassert (delta
== 0);
4495 /* Now recalculate the edge positions of all the windows affected,
4496 based on the new sizes. */
4497 first_unaffected
= next
;
4498 prev
= first_affected
;
4499 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
4500 prev
= next
, next
= XWINDOW (next
)->next
)
4502 XSETINT (CURBEG (next
), XINT (CURBEG (prev
)) + (*sizefun
) (prev
));
4503 /* This does not change size of NEXT,
4504 but it propagates the new top edge to its children */
4505 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
4510 register int delta1
;
4511 register int opht
= (*sizefun
) (parent
);
4513 if (opht
<= XINT (*sizep
) + delta
)
4515 /* If trying to grow this window to or beyond size of the parent,
4516 just delete all the sibling windows. */
4517 Lisp_Object start
, tem
;
4519 start
= XWINDOW (parent
)->vchild
;
4521 start
= XWINDOW (parent
)->hchild
;
4523 /* Delete any siblings that come after WINDOW. */
4524 tem
= XWINDOW (window
)->next
;
4525 while (! NILP (tem
))
4527 Lisp_Object next1
= XWINDOW (tem
)->next
;
4528 delete_window (tem
);
4532 /* Delete any siblings that come after WINDOW.
4533 Note that if START is not WINDOW, then WINDOW still
4534 has siblings, so WINDOW has not yet replaced its parent. */
4536 while (! EQ (tem
, window
))
4538 Lisp_Object next1
= XWINDOW (tem
)->next
;
4539 delete_window (tem
);
4545 /* Otherwise, make delta1 just right so that if we add
4546 delta1 lines to this window and to the parent, and then
4547 shrink the parent back to its original size, the new
4548 proportional size of this window will increase by delta.
4550 The function size_window will compute the new height h'
4551 of the window from delta1 as:
4554 x = delta1 - delta1/n * n for the 1st resizable child
4557 where n is the number of children that can be resized.
4558 We can ignore x by choosing a delta1 that is a multiple of
4559 n. We want the height of this window to come out as
4569 The number of children n equals the number of resizable
4570 children of this window + 1 because we know window itself
4571 is resizable (otherwise we would have signaled an error).
4573 This reasoning is not correct when other windows become too
4574 small and shrink_windows refuses to delete them. Below we
4575 use resize_proportionally to work around this problem. */
4577 struct window
*w
= XWINDOW (window
);
4581 for (s
= w
->next
; WINDOWP (s
); s
= XWINDOW (s
)->next
)
4582 if (!window_fixed_size_p (XWINDOW (s
), horiz_flag
, 0))
4584 for (s
= w
->prev
; WINDOWP (s
); s
= XWINDOW (s
)->prev
)
4585 if (!window_fixed_size_p (XWINDOW (s
), horiz_flag
, 0))
4590 /* Add delta1 lines or columns to this window, and to the parent,
4591 keeping things consistent while not affecting siblings. */
4592 XSETINT (CURSIZE (parent
), opht
+ delta1
);
4593 (*setsizefun
) (window
, XINT (*sizep
) + delta1
, 0);
4595 /* Squeeze out delta1 lines or columns from our parent,
4596 shrinking this window and siblings proportionately. This
4597 brings parent back to correct size. Delta1 was calculated
4598 so this makes this window the desired size, taking it all
4599 out of the siblings.
4601 Temporarily set resize_proportionally to Qt to assure that,
4602 if necessary, shrink_windows deletes smaller windows rather
4603 than shrink this window. */
4604 w
->resize_proportionally
= Qt
;
4605 (*setsizefun
) (parent
, opht
, 0);
4606 w
->resize_proportionally
= Qnil
;
4610 XSETFASTINT (p
->last_modified
, 0);
4611 XSETFASTINT (p
->last_overlay_modified
, 0);
4613 /* Adjust glyph matrices. */
4614 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
4618 /* Adjust the size of WINDOW by DELTA, moving only its trailing edge.
4619 HORIZ_FLAG nonzero means adjust the width, moving the right edge.
4620 zero means adjust the height, moving the bottom edge.
4622 Following siblings of the selected window are resized to fulfill
4623 the size request. If they become too small in the process, they
4624 are not deleted; instead, we signal an error. */
4627 adjust_window_trailing_edge (Lisp_Object window
, int delta
, int horiz_flag
)
4629 Lisp_Object parent
, child
;
4631 Lisp_Object old_config
= Fcurrent_window_configuration (Qnil
);
4632 int delcount
= window_deletion_count
;
4634 CHECK_WINDOW (window
);
4636 /* Give up if this window cannot be resized. */
4637 if (window_fixed_size_p (XWINDOW (window
), horiz_flag
, 1))
4638 error ("Window is not resizable");
4642 Lisp_Object first_parallel
= Qnil
;
4646 /* This happens if WINDOW on the previous iteration was
4647 at top level of the window tree. */
4648 Fset_window_configuration (old_config
);
4649 error ("Specified window edge is fixed");
4652 p
= XWINDOW (window
);
4655 /* See if this level has windows in parallel in the specified
4656 direction. If so, set FIRST_PARALLEL to the first one. */
4659 if (! NILP (parent
) && !NILP (XWINDOW (parent
)->vchild
))
4660 first_parallel
= XWINDOW (parent
)->vchild
;
4661 else if (NILP (parent
) && !NILP (p
->next
))
4663 /* Handle the vertical chain of main window and minibuffer
4664 which has no parent. */
4665 first_parallel
= window
;
4666 while (! NILP (XWINDOW (first_parallel
)->prev
))
4667 first_parallel
= XWINDOW (first_parallel
)->prev
;
4672 if (! NILP (parent
) && !NILP (XWINDOW (parent
)->hchild
))
4673 first_parallel
= XWINDOW (parent
)->hchild
;
4676 /* If this level's succession is in the desired dimension,
4677 and this window is the last one, and there is no higher level,
4678 its trailing edge is fixed. */
4679 if (NILP (XWINDOW (window
)->next
) && NILP (first_parallel
)
4682 Fset_window_configuration (old_config
);
4683 error ("Specified window edge is fixed");
4686 /* Don't make this window too small. */
4687 if (XINT (CURSIZE (window
)) + delta
4688 < window_min_size_2 (XWINDOW (window
), horiz_flag
, 0))
4690 Fset_window_configuration (old_config
);
4691 error ("Cannot adjust window size as specified");
4694 /* Clear out some redisplay caches. */
4695 XSETFASTINT (p
->last_modified
, 0);
4696 XSETFASTINT (p
->last_overlay_modified
, 0);
4698 /* Adjust this window's edge. */
4699 XSETINT (CURSIZE (window
),
4700 XINT (CURSIZE (window
)) + delta
);
4702 /* If this window has following siblings in the desired dimension,
4703 make them smaller, and exit the loop.
4705 (If we reach the top of the tree and can never do this,
4706 we will fail and report an error, above.) */
4707 if (NILP (first_parallel
))
4709 if (!NILP (p
->next
))
4711 /* This may happen for the minibuffer. In that case
4712 the window_deletion_count check below does not work. */
4713 if (XINT (CURSIZE (p
->next
)) - delta
<= 0)
4715 Fset_window_configuration (old_config
);
4716 error ("Cannot adjust window size as specified");
4719 XSETINT (CURBEG (p
->next
),
4720 XINT (CURBEG (p
->next
)) + delta
);
4721 size_window (p
->next
, XINT (CURSIZE (p
->next
)) - delta
,
4722 horiz_flag
, 0, 1, 0);
4727 /* Here we have a chain of parallel siblings, in the other dimension.
4728 Change the size of the other siblings. */
4729 for (child
= first_parallel
;
4731 child
= XWINDOW (child
)->next
)
4732 if (! EQ (child
, window
))
4733 size_window (child
, XINT (CURSIZE (child
)) + delta
,
4734 horiz_flag
, 0, 0, 1);
4739 /* If we made a window so small it got deleted,
4740 we failed. Report failure. */
4741 if (delcount
!= window_deletion_count
)
4743 Fset_window_configuration (old_config
);
4744 error ("Cannot adjust window size as specified");
4747 /* Adjust glyph matrices. */
4748 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
4754 DEFUN ("adjust-window-trailing-edge", Fadjust_window_trailing_edge
,
4755 Sadjust_window_trailing_edge
, 3, 3, 0,
4756 doc
: /* Adjust the bottom or right edge of WINDOW by DELTA.
4757 If HORIZONTAL is non-nil, that means adjust the width, moving the right edge.
4758 Otherwise, adjust the height, moving the bottom edge.
4760 Following siblings of the selected window are resized to fulfill
4761 the size request. If they become too small in the process, they
4762 are not deleted; instead, we signal an error. */)
4763 (Lisp_Object window
, Lisp_Object delta
, Lisp_Object horizontal
)
4765 CHECK_NUMBER (delta
);
4767 window
= selected_window
;
4768 adjust_window_trailing_edge (window
, XINT (delta
), !NILP (horizontal
));
4770 run_window_configuration_change_hook
4771 (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
4778 /***********************************************************************
4779 Resizing Mini-Windows
4780 ***********************************************************************/
4782 static void shrink_window_lowest_first (struct window
*, int);
4784 enum save_restore_action
4791 static int save_restore_orig_size (struct window
*,
4792 enum save_restore_action
);
4794 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
4795 from lowest windows first. */
4798 shrink_window_lowest_first (struct window
*w
, int height
)
4804 xassert (!MINI_WINDOW_P (w
));
4806 /* Set redisplay hints. */
4807 XSETFASTINT (w
->last_modified
, 0);
4808 XSETFASTINT (w
->last_overlay_modified
, 0);
4809 windows_or_buffers_changed
++;
4810 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
4812 old_height
= XFASTINT (w
->total_lines
);
4813 XSETFASTINT (w
->total_lines
, height
);
4815 if (!NILP (w
->hchild
))
4817 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
4819 c
= XWINDOW (child
);
4820 c
->top_line
= w
->top_line
;
4821 shrink_window_lowest_first (c
, height
);
4824 else if (!NILP (w
->vchild
))
4826 Lisp_Object last_child
;
4827 int delta
= old_height
- height
;
4832 /* Find the last child. We are taking space from lowest windows
4833 first, so we iterate over children from the last child
4835 for (child
= w
->vchild
; WINDOWP (child
); child
= XWINDOW (child
)->next
)
4838 /* Size children down to their safe heights. */
4839 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
4843 c
= XWINDOW (child
);
4844 this_one
= XFASTINT (c
->total_lines
) - window_min_size_1 (c
, 0, 1);
4846 if (this_one
> delta
)
4849 shrink_window_lowest_first (c
, XFASTINT (c
->total_lines
) - this_one
);
4853 /* Compute new positions. */
4854 last_top
= XINT (w
->top_line
);
4855 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
4857 c
= XWINDOW (child
);
4858 c
->top_line
= make_number (last_top
);
4859 shrink_window_lowest_first (c
, XFASTINT (c
->total_lines
));
4860 last_top
+= XFASTINT (c
->total_lines
);
4866 /* Save, restore, or check positions and sizes in the window tree
4867 rooted at W. ACTION says what to do.
4869 If ACTION is CHECK_ORIG_SIZES, check if orig_top_line and
4870 orig_total_lines members are valid for all windows in the window
4871 tree. Value is non-zero if they are valid.
4873 If ACTION is SAVE_ORIG_SIZES, save members top and height in
4874 orig_top_line and orig_total_lines for all windows in the tree.
4876 If ACTION is RESTORE_ORIG_SIZES, restore top and height from values
4877 stored in orig_top_line and orig_total_lines for all windows. */
4880 save_restore_orig_size (struct window
*w
, enum save_restore_action action
)
4886 if (!NILP (w
->hchild
))
4888 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
4891 else if (!NILP (w
->vchild
))
4893 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
4899 case CHECK_ORIG_SIZES
:
4900 if (!INTEGERP (w
->orig_top_line
) || !INTEGERP (w
->orig_total_lines
))
4904 case SAVE_ORIG_SIZES
:
4905 w
->orig_top_line
= w
->top_line
;
4906 w
->orig_total_lines
= w
->total_lines
;
4907 XSETFASTINT (w
->last_modified
, 0);
4908 XSETFASTINT (w
->last_overlay_modified
, 0);
4911 case RESTORE_ORIG_SIZES
:
4912 xassert (INTEGERP (w
->orig_top_line
) && INTEGERP (w
->orig_total_lines
));
4913 w
->top_line
= w
->orig_top_line
;
4914 w
->total_lines
= w
->orig_total_lines
;
4915 w
->orig_total_lines
= w
->orig_top_line
= Qnil
;
4916 XSETFASTINT (w
->last_modified
, 0);
4917 XSETFASTINT (w
->last_overlay_modified
, 0);
4924 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
4931 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
4932 without deleting other windows. */
4935 grow_mini_window (struct window
*w
, int delta
)
4937 struct frame
*f
= XFRAME (w
->frame
);
4938 struct window
*root
;
4940 xassert (MINI_WINDOW_P (w
));
4941 /* Commenting out the following assertion goes against the stated interface
4942 of the function, but it currently does not seem to do anything useful.
4943 See discussion of this issue in the thread for bug#4534.
4944 xassert (delta >= 0); */
4946 /* Compute how much we can enlarge the mini-window without deleting
4948 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4951 int min_height
= window_min_size (root
, 0, 0, 0, 0);
4952 if (XFASTINT (root
->total_lines
) - delta
< min_height
)
4953 /* Note that the root window may already be smaller than
4955 delta
= max (0, XFASTINT (root
->total_lines
) - min_height
);
4960 /* Save original window sizes and positions, if not already done. */
4961 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
4962 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
4964 /* Shrink other windows. */
4965 shrink_window_lowest_first (root
, XFASTINT (root
->total_lines
) - delta
);
4967 /* Grow the mini-window. */
4968 w
->top_line
= make_number (XFASTINT (root
->top_line
) + XFASTINT (root
->total_lines
));
4969 w
->total_lines
= make_number (XFASTINT (w
->total_lines
) + delta
);
4970 XSETFASTINT (w
->last_modified
, 0);
4971 XSETFASTINT (w
->last_overlay_modified
, 0);
4978 /* Shrink mini-window W. If there is recorded info about window sizes
4979 before a call to grow_mini_window, restore recorded window sizes.
4980 Otherwise, if the mini-window is higher than 1 line, resize it to 1
4984 shrink_mini_window (struct window
*w
)
4986 struct frame
*f
= XFRAME (w
->frame
);
4987 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4989 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
4991 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
4993 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4994 windows_or_buffers_changed
= 1;
4996 else if (XFASTINT (w
->total_lines
) > 1)
4998 /* Distribute the additional lines of the mini-window
4999 among the other windows. */
5001 XSETWINDOW (window
, w
);
5002 enlarge_window (window
, 1 - XFASTINT (w
->total_lines
), 0);
5008 /* Mark window cursors off for all windows in the window tree rooted
5009 at W by setting their phys_cursor_on_p flag to zero. Called from
5010 xterm.c, e.g. when a frame is cleared and thereby all cursors on
5011 the frame are cleared. */
5014 mark_window_cursors_off (struct window
*w
)
5018 if (!NILP (w
->hchild
))
5019 mark_window_cursors_off (XWINDOW (w
->hchild
));
5020 else if (!NILP (w
->vchild
))
5021 mark_window_cursors_off (XWINDOW (w
->vchild
));
5023 w
->phys_cursor_on_p
= 0;
5025 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5030 /* Return number of lines of text (not counting mode lines) in W. */
5033 window_internal_height (struct window
*w
)
5035 int ht
= XFASTINT (w
->total_lines
);
5037 if (!MINI_WINDOW_P (w
))
5039 if (!NILP (w
->parent
)
5040 || !NILP (w
->vchild
)
5041 || !NILP (w
->hchild
)
5044 || WINDOW_WANTS_MODELINE_P (w
))
5047 if (WINDOW_WANTS_HEADER_LINE_P (w
))
5054 /************************************************************************
5056 ***********************************************************************/
5058 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
5059 N screen-fulls, which is defined as the height of the window minus
5060 next_screen_context_lines. If WHOLE is zero, scroll up N lines
5061 instead. Negative values of N mean scroll down. NOERROR non-zero
5062 means don't signal an error if we try to move over BEGV or ZV,
5066 window_scroll (Lisp_Object window
, int n
, int whole
, int noerror
)
5070 /* If we must, use the pixel-based version which is much slower than
5071 the line-based one but can handle varying line heights. */
5072 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
5073 window_scroll_pixel_based (window
, n
, whole
, noerror
);
5075 window_scroll_line_based (window
, n
, whole
, noerror
);
5081 /* Implementation of window_scroll that works based on pixel line
5082 heights. See the comment of window_scroll for parameter
5086 window_scroll_pixel_based (Lisp_Object window
, int n
, int whole
, int noerror
)
5089 struct window
*w
= XWINDOW (window
);
5090 struct text_pos start
;
5091 int this_scroll_margin
;
5092 /* True if we fiddled the window vscroll field without really scrolling. */
5094 int x
, y
, rtop
, rbot
, rowh
, vpos
;
5096 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
5098 /* If PT is not visible in WINDOW, move back one half of
5099 the screen. Allow PT to be partially visible, otherwise
5100 something like (scroll-down 1) with PT in the line before
5101 the partially visible one would recenter. */
5103 if (!pos_visible_p (w
, PT
, &x
, &y
, &rtop
, &rbot
, &rowh
, &vpos
))
5105 /* Move backward half the height of the window. Performance note:
5106 vmotion used here is about 10% faster, but would give wrong
5107 results for variable height lines. */
5108 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
5109 it
.current_y
= it
.last_visible_y
;
5110 move_it_vertically_backward (&it
, window_box_height (w
) / 2);
5112 /* The function move_iterator_vertically may move over more than
5113 the specified y-distance. If it->w is small, e.g. a
5114 mini-buffer window, we may end up in front of the window's
5115 display area. This is the case when Start displaying at the
5116 start of the line containing PT in this case. */
5117 if (it
.current_y
<= 0)
5119 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
5120 move_it_vertically_backward (&it
, 0);
5124 start
= it
.current
.pos
;
5126 else if (auto_window_vscroll_p
)
5128 if (rtop
|| rbot
) /* partially visible */
5131 int dy
= WINDOW_FRAME_LINE_HEIGHT (w
);
5133 dy
= max ((window_box_height (w
)
5134 - next_screen_context_lines
* dy
),
5140 /* Only vscroll backwards if already vscrolled forwards. */
5141 if (w
->vscroll
< 0 && rtop
> 0)
5143 px
= max (0, -w
->vscroll
- min (rtop
, -dy
));
5144 Fset_window_vscroll (window
, make_number (px
), Qt
);
5150 /* Do vscroll if already vscrolled or only display line. */
5151 if (rbot
> 0 && (w
->vscroll
< 0 || vpos
== 0))
5153 px
= max (0, -w
->vscroll
+ min (rbot
, dy
));
5154 Fset_window_vscroll (window
, make_number (px
), Qt
);
5158 /* Maybe modify window start instead of scrolling. */
5159 if (rbot
> 0 || w
->vscroll
< 0)
5163 Fset_window_vscroll (window
, make_number (0), Qt
);
5164 /* If there are other text lines above the current row,
5165 move window start to current row. Else to next row. */
5167 spos
= XINT (Fline_beginning_position (Qnil
));
5169 spos
= min (XINT (Fline_end_position (Qnil
)) + 1, ZV
);
5170 set_marker_restricted (w
->start
, make_number (spos
),
5172 w
->start_at_line_beg
= Qt
;
5173 w
->update_mode_line
= Qt
;
5174 XSETFASTINT (w
->last_modified
, 0);
5175 XSETFASTINT (w
->last_overlay_modified
, 0);
5176 /* Set force_start so that redisplay_window will run the
5177 window-scroll-functions. */
5178 w
->force_start
= Qt
;
5183 /* Cancel previous vscroll. */
5184 Fset_window_vscroll (window
, make_number (0), Qt
);
5187 /* If scroll_preserve_screen_position is non-nil, we try to set
5188 point in the same window line as it is now, so get that line. */
5189 if (!NILP (Vscroll_preserve_screen_position
))
5191 /* We preserve the goal pixel coordinate across consecutive
5192 calls to scroll-up, scroll-down and other commands that
5193 have the `scroll-command' property. This avoids the
5194 possibility of point becoming "stuck" on a tall line when
5195 scrolling by one line. */
5196 if (window_scroll_pixel_based_preserve_y
< 0
5197 || !SYMBOLP (KVAR (current_kboard
, Vlast_command
))
5198 || NILP (Fget (KVAR (current_kboard
, Vlast_command
), Qscroll_command
)))
5200 start_display (&it
, w
, start
);
5201 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
5202 window_scroll_pixel_based_preserve_y
= it
.current_y
;
5203 window_scroll_pixel_based_preserve_x
= it
.current_x
;
5207 window_scroll_pixel_based_preserve_y
5208 = window_scroll_pixel_based_preserve_x
= -1;
5210 /* Move iterator it from start the specified distance forward or
5211 backward. The result is the new window start. */
5212 start_display (&it
, w
, start
);
5215 EMACS_INT start_pos
= IT_CHARPOS (it
);
5216 int dy
= WINDOW_FRAME_LINE_HEIGHT (w
);
5217 dy
= max ((window_box_height (w
)
5218 - next_screen_context_lines
* dy
),
5221 /* Note that move_it_vertically always moves the iterator to the
5222 start of a line. So, if the last line doesn't have a newline,
5223 we would end up at the start of the line ending at ZV. */
5226 move_it_vertically_backward (&it
, -dy
);
5227 /* Ensure we actually do move, e.g. in case we are currently
5228 looking at an image that is taller that the window height. */
5229 while (start_pos
== IT_CHARPOS (it
)
5230 && start_pos
> BEGV
)
5231 move_it_by_lines (&it
, -1);
5235 move_it_to (&it
, ZV
, -1, it
.current_y
+ dy
, -1,
5236 MOVE_TO_POS
| MOVE_TO_Y
);
5237 /* Ensure we actually do move, e.g. in case we are currently
5238 looking at an image that is taller that the window height. */
5239 while (start_pos
== IT_CHARPOS (it
)
5241 move_it_by_lines (&it
, 1);
5245 move_it_by_lines (&it
, n
);
5247 /* We failed if we find ZV is already on the screen (scrolling up,
5248 means there's nothing past the end), or if we can't start any
5249 earlier (scrolling down, means there's nothing past the top). */
5250 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
5251 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
5253 if (IT_CHARPOS (it
) == ZV
)
5255 if (it
.current_y
< it
.last_visible_y
5256 && (it
.current_y
+ it
.max_ascent
+ it
.max_descent
5257 > it
.last_visible_y
))
5259 /* The last line was only partially visible, make it fully
5261 w
->vscroll
= (it
.last_visible_y
5262 - it
.current_y
+ it
.max_ascent
+ it
.max_descent
);
5263 adjust_glyphs (it
.f
);
5267 else if (n
< 0) /* could happen with empty buffers */
5268 xsignal0 (Qbeginning_of_buffer
);
5270 xsignal0 (Qend_of_buffer
);
5274 if (w
->vscroll
!= 0)
5275 /* The first line was only partially visible, make it fully
5281 xsignal0 (Qbeginning_of_buffer
);
5284 /* If control gets here, then we vscrolled. */
5286 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
5288 /* Don't try to change the window start below. */
5294 EMACS_INT pos
= IT_CHARPOS (it
);
5297 /* If in the middle of a multi-glyph character move forward to
5298 the next character. */
5299 if (in_display_vector_p (&it
))
5302 move_it_to (&it
, pos
, -1, -1, -1, MOVE_TO_POS
);
5305 /* Set the window start, and set up the window for redisplay. */
5306 set_marker_restricted (w
->start
, make_number (pos
),
5308 bytepos
= XMARKER (w
->start
)->bytepos
;
5309 w
->start_at_line_beg
= ((pos
== BEGV
|| FETCH_BYTE (bytepos
- 1) == '\n')
5311 w
->update_mode_line
= Qt
;
5312 XSETFASTINT (w
->last_modified
, 0);
5313 XSETFASTINT (w
->last_overlay_modified
, 0);
5314 /* Set force_start so that redisplay_window will run the
5315 window-scroll-functions. */
5316 w
->force_start
= Qt
;
5319 /* The rest of this function uses current_y in a nonstandard way,
5320 not including the height of the header line if any. */
5321 it
.current_y
= it
.vpos
= 0;
5323 /* Move PT out of scroll margins.
5324 This code wants current_y to be zero at the window start position
5325 even if there is a header line. */
5326 this_scroll_margin
= max (0, scroll_margin
);
5327 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->total_lines
) / 4);
5328 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
5332 /* We moved the window start towards ZV, so PT may be now
5333 in the scroll margin at the top. */
5334 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
5335 if (IT_CHARPOS (it
) == PT
&& it
.current_y
>= this_scroll_margin
5336 && (NILP (Vscroll_preserve_screen_position
)
5337 || EQ (Vscroll_preserve_screen_position
, Qt
)))
5338 /* We found PT at a legitimate height. Leave it alone. */
5340 else if (window_scroll_pixel_based_preserve_y
>= 0)
5342 /* If we have a header line, take account of it.
5343 This is necessary because we set it.current_y to 0, above. */
5344 move_it_to (&it
, -1,
5345 window_scroll_pixel_based_preserve_x
,
5346 window_scroll_pixel_based_preserve_y
5347 - (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0 ),
5348 -1, MOVE_TO_Y
| MOVE_TO_X
);
5349 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5353 while (it
.current_y
< this_scroll_margin
)
5355 int prev
= it
.current_y
;
5356 move_it_by_lines (&it
, 1);
5357 if (prev
== it
.current_y
)
5360 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5365 EMACS_INT charpos
, bytepos
;
5368 /* Save our position, for the
5369 window_scroll_pixel_based_preserve_y case. */
5370 charpos
= IT_CHARPOS (it
);
5371 bytepos
= IT_BYTEPOS (it
);
5373 /* We moved the window start towards BEGV, so PT may be now
5374 in the scroll margin at the bottom. */
5375 move_it_to (&it
, PT
, -1,
5376 (it
.last_visible_y
- CURRENT_HEADER_LINE_HEIGHT (w
)
5377 - this_scroll_margin
- 1),
5379 MOVE_TO_POS
| MOVE_TO_Y
);
5381 /* Save our position, in case it's correct. */
5382 charpos
= IT_CHARPOS (it
);
5383 bytepos
= IT_BYTEPOS (it
);
5385 /* See if point is on a partially visible line at the end. */
5386 if (it
.what
== IT_EOB
)
5387 partial_p
= it
.current_y
+ it
.ascent
+ it
.descent
> it
.last_visible_y
;
5390 move_it_by_lines (&it
, 1);
5391 partial_p
= it
.current_y
> it
.last_visible_y
;
5394 if (charpos
== PT
&& !partial_p
5395 && (NILP (Vscroll_preserve_screen_position
)
5396 || EQ (Vscroll_preserve_screen_position
, Qt
)))
5397 /* We found PT before we found the display margin, so PT is ok. */
5399 else if (window_scroll_pixel_based_preserve_y
>= 0)
5401 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
5402 start_display (&it
, w
, start
);
5403 /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT
5404 here because we called start_display again and did not
5405 alter it.current_y this time. */
5406 move_it_to (&it
, -1, window_scroll_pixel_based_preserve_x
,
5407 window_scroll_pixel_based_preserve_y
, -1,
5408 MOVE_TO_Y
| MOVE_TO_X
);
5409 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5414 /* The last line was only partially visible, so back up two
5415 lines to make sure we're on a fully visible line. */
5417 move_it_by_lines (&it
, -2);
5418 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5421 /* No, the position we saved is OK, so use it. */
5422 SET_PT_BOTH (charpos
, bytepos
);
5428 /* Implementation of window_scroll that works based on screen lines.
5429 See the comment of window_scroll for parameter descriptions. */
5432 window_scroll_line_based (Lisp_Object window
, int n
, int whole
, int noerror
)
5434 register struct window
*w
= XWINDOW (window
);
5435 /* Fvertical_motion enters redisplay, which can trigger
5436 fontification, which in turn can modify buffer text (e.g., if the
5437 fontification functions replace escape sequences with faces, as
5438 in `grep-mode-font-lock-keywords'). So we use a marker to record
5439 the old point position, to prevent crashes in SET_PT_BOTH. */
5440 Lisp_Object opoint_marker
= Fpoint_marker ();
5441 register EMACS_INT pos
, pos_byte
;
5442 register int ht
= window_internal_height (w
);
5443 register Lisp_Object tem
;
5447 Lisp_Object original_pos
= Qnil
;
5449 /* If scrolling screen-fulls, compute the number of lines to
5450 scroll from the window's height. */
5452 n
*= max (1, ht
- next_screen_context_lines
);
5454 startpos
= marker_position (w
->start
);
5456 if (!NILP (Vscroll_preserve_screen_position
))
5458 if (window_scroll_preserve_vpos
<= 0
5459 || !SYMBOLP (KVAR (current_kboard
, Vlast_command
))
5460 || NILP (Fget (KVAR (current_kboard
, Vlast_command
), Qscroll_command
)))
5462 struct position posit
5463 = *compute_motion (startpos
, 0, 0, 0,
5465 -1, XINT (w
->hscroll
),
5467 window_scroll_preserve_vpos
= posit
.vpos
;
5468 window_scroll_preserve_hpos
= posit
.hpos
+ XINT (w
->hscroll
);
5471 original_pos
= Fcons (make_number (window_scroll_preserve_hpos
),
5472 make_number (window_scroll_preserve_vpos
));
5475 XSETFASTINT (tem
, PT
);
5476 tem
= Fpos_visible_in_window_p (tem
, window
, Qnil
);
5480 Fvertical_motion (make_number (- (ht
/ 2)), window
);
5485 lose
= n
< 0 && PT
== BEGV
;
5486 Fvertical_motion (make_number (n
), window
);
5490 SET_PT_BOTH (marker_position (opoint_marker
),
5491 marker_byte_position (opoint_marker
));
5498 xsignal0 (Qbeginning_of_buffer
);
5503 int this_scroll_margin
= scroll_margin
;
5505 /* Don't use a scroll margin that is negative or too large. */
5506 if (this_scroll_margin
< 0)
5507 this_scroll_margin
= 0;
5509 if (XINT (w
->total_lines
) < 4 * scroll_margin
)
5510 this_scroll_margin
= XINT (w
->total_lines
) / 4;
5512 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
5513 w
->start_at_line_beg
= bolp
;
5514 w
->update_mode_line
= Qt
;
5515 XSETFASTINT (w
->last_modified
, 0);
5516 XSETFASTINT (w
->last_overlay_modified
, 0);
5517 /* Set force_start so that redisplay_window will run
5518 the window-scroll-functions. */
5519 w
->force_start
= Qt
;
5521 if (!NILP (Vscroll_preserve_screen_position
)
5522 && (whole
|| !EQ (Vscroll_preserve_screen_position
, Qt
)))
5524 SET_PT_BOTH (pos
, pos_byte
);
5525 Fvertical_motion (original_pos
, window
);
5527 /* If we scrolled forward, put point enough lines down
5528 that it is outside the scroll margin. */
5533 if (this_scroll_margin
> 0)
5535 SET_PT_BOTH (pos
, pos_byte
);
5536 Fvertical_motion (make_number (this_scroll_margin
), window
);
5542 if (top_margin
<= marker_position (opoint_marker
))
5543 SET_PT_BOTH (marker_position (opoint_marker
),
5544 marker_byte_position (opoint_marker
));
5545 else if (!NILP (Vscroll_preserve_screen_position
))
5547 SET_PT_BOTH (pos
, pos_byte
);
5548 Fvertical_motion (original_pos
, window
);
5551 SET_PT (top_margin
);
5557 /* If we scrolled backward, put point near the end of the window
5558 but not within the scroll margin. */
5559 SET_PT_BOTH (pos
, pos_byte
);
5560 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
5561 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
5564 bottom_margin
= PT
+ 1;
5566 if (bottom_margin
> marker_position (opoint_marker
))
5567 SET_PT_BOTH (marker_position (opoint_marker
),
5568 marker_byte_position (opoint_marker
));
5571 if (!NILP (Vscroll_preserve_screen_position
))
5573 SET_PT_BOTH (pos
, pos_byte
);
5574 Fvertical_motion (original_pos
, window
);
5577 Fvertical_motion (make_number (-1), window
);
5586 xsignal0 (Qend_of_buffer
);
5591 /* Scroll selected_window up or down. If N is nil, scroll a
5592 screen-full which is defined as the height of the window minus
5593 next_screen_context_lines. If N is the symbol `-', scroll.
5594 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
5595 up. This is the guts of Fscroll_up and Fscroll_down. */
5598 scroll_command (Lisp_Object n
, int direction
)
5600 int count
= SPECPDL_INDEX ();
5602 xassert (eabs (direction
) == 1);
5604 /* If selected window's buffer isn't current, make it current for
5605 the moment. But don't screw up if window_scroll gets an error. */
5606 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
5608 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
5609 Fset_buffer (XWINDOW (selected_window
)->buffer
);
5611 /* Make redisplay consider other windows than just selected_window. */
5612 ++windows_or_buffers_changed
;
5616 window_scroll (selected_window
, direction
, 1, 0);
5617 else if (EQ (n
, Qminus
))
5618 window_scroll (selected_window
, -direction
, 1, 0);
5621 n
= Fprefix_numeric_value (n
);
5622 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
5625 unbind_to (count
, Qnil
);
5628 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "^P",
5629 doc
: /* Scroll text of selected window upward ARG lines.
5630 If ARG is omitted or nil, scroll upward by a near full screen.
5631 A near full screen is `next-screen-context-lines' less than a full screen.
5632 Negative ARG means scroll downward.
5633 If ARG is the atom `-', scroll downward by nearly full screen.
5634 When calling from a program, supply as argument a number, nil, or `-'. */)
5637 scroll_command (arg
, 1);
5641 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "^P",
5642 doc
: /* Scroll text of selected window down ARG lines.
5643 If ARG is omitted or nil, scroll down by a near full screen.
5644 A near full screen is `next-screen-context-lines' less than a full screen.
5645 Negative ARG means scroll upward.
5646 If ARG is the atom `-', scroll upward by nearly full screen.
5647 When calling from a program, supply as argument a number, nil, or `-'. */)
5650 scroll_command (arg
, -1);
5654 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
5655 doc
: /* Return the other window for \"other window scroll\" commands.
5656 If `other-window-scroll-buffer' is non-nil, a window
5657 showing that buffer is used.
5658 If in the minibuffer, `minibuffer-scroll-window' if non-nil
5659 specifies the window. This takes precedence over
5660 `other-window-scroll-buffer'. */)
5665 if (MINI_WINDOW_P (XWINDOW (selected_window
))
5666 && !NILP (Vminibuf_scroll_window
))
5667 window
= Vminibuf_scroll_window
;
5668 /* If buffer is specified, scroll that buffer. */
5669 else if (!NILP (Vother_window_scroll_buffer
))
5671 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
5673 window
= display_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
5677 /* Nothing specified; look for a neighboring window on the same
5679 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
5681 if (EQ (window
, selected_window
))
5682 /* That didn't get us anywhere; look for a window on another
5685 window
= Fnext_window (window
, Qnil
, Qt
);
5686 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
5687 && ! EQ (window
, selected_window
));
5690 CHECK_LIVE_WINDOW (window
);
5692 if (EQ (window
, selected_window
))
5693 error ("There is no other window");
5698 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
5699 doc
: /* Scroll next window upward ARG lines; or near full screen if no ARG.
5700 A near full screen is `next-screen-context-lines' less than a full screen.
5701 The next window is the one below the current one; or the one at the top
5702 if the current one is at the bottom. Negative ARG means scroll downward.
5703 If ARG is the atom `-', scroll downward by nearly full screen.
5704 When calling from a program, supply as argument a number, nil, or `-'.
5706 If `other-window-scroll-buffer' is non-nil, scroll the window
5707 showing that buffer, popping the buffer up if necessary.
5708 If in the minibuffer, `minibuffer-scroll-window' if non-nil
5709 specifies the window to scroll. This takes precedence over
5710 `other-window-scroll-buffer'. */)
5715 int count
= SPECPDL_INDEX ();
5717 window
= Fother_window_for_scrolling ();
5718 w
= XWINDOW (window
);
5720 /* Don't screw up if window_scroll gets an error. */
5721 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
5722 ++windows_or_buffers_changed
;
5724 Fset_buffer (w
->buffer
);
5725 SET_PT (marker_position (w
->pointm
));
5728 window_scroll (window
, 1, 1, 1);
5729 else if (EQ (arg
, Qminus
))
5730 window_scroll (window
, -1, 1, 1);
5736 window_scroll (window
, XINT (arg
), 0, 1);
5739 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
5740 unbind_to (count
, Qnil
);
5745 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 2, "^P\np",
5746 doc
: /* Scroll selected window display ARG columns left.
5747 Default for ARG is window width minus 2.
5748 Value is the total amount of leftward horizontal scrolling in
5749 effect after the change.
5750 If SET-MINIMUM is non-nil, the new scroll amount becomes the
5751 lower bound for automatic scrolling, i.e. automatic scrolling
5752 will not scroll a window to a column less than the value returned
5753 by this function. This happens in an interactive call. */)
5754 (register Lisp_Object arg
, Lisp_Object set_minimum
)
5758 struct window
*w
= XWINDOW (selected_window
);
5761 XSETFASTINT (arg
, window_body_cols (w
) - 2);
5763 arg
= Fprefix_numeric_value (arg
);
5765 hscroll
= XINT (w
->hscroll
) + XINT (arg
);
5766 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
5768 if (!NILP (set_minimum
))
5769 w
->min_hscroll
= w
->hscroll
;
5774 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 2, "^P\np",
5775 doc
: /* Scroll selected window display ARG columns right.
5776 Default for ARG is window width minus 2.
5777 Value is the total amount of leftward horizontal scrolling in
5778 effect after the change.
5779 If SET-MINIMUM is non-nil, the new scroll amount becomes the
5780 lower bound for automatic scrolling, i.e. automatic scrolling
5781 will not scroll a window to a column less than the value returned
5782 by this function. This happens in an interactive call. */)
5783 (register Lisp_Object arg
, Lisp_Object set_minimum
)
5787 struct window
*w
= XWINDOW (selected_window
);
5790 XSETFASTINT (arg
, window_body_cols (w
) - 2);
5792 arg
= Fprefix_numeric_value (arg
);
5794 hscroll
= XINT (w
->hscroll
) - XINT (arg
);
5795 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
5797 if (!NILP (set_minimum
))
5798 w
->min_hscroll
= w
->hscroll
;
5803 DEFUN ("minibuffer-selected-window", Fminibuffer_selected_window
, Sminibuffer_selected_window
, 0, 0, 0,
5804 doc
: /* Return the window which was selected when entering the minibuffer.
5805 Returns nil, if selected window is not a minibuffer window. */)
5808 if (minibuf_level
> 0
5809 && MINI_WINDOW_P (XWINDOW (selected_window
))
5810 && WINDOW_LIVE_P (minibuf_selected_window
))
5811 return minibuf_selected_window
;
5816 /* Value is the number of lines actually displayed in window W,
5817 as opposed to its height. */
5820 displayed_window_lines (struct window
*w
)
5823 struct text_pos start
;
5824 int height
= window_box_height (w
);
5825 struct buffer
*old_buffer
;
5828 if (XBUFFER (w
->buffer
) != current_buffer
)
5830 old_buffer
= current_buffer
;
5831 set_buffer_internal (XBUFFER (w
->buffer
));
5836 /* In case W->start is out of the accessible range, do something
5837 reasonable. This happens in Info mode when Info-scroll-down
5838 calls (recenter -1) while W->start is 1. */
5839 if (XMARKER (w
->start
)->charpos
< BEGV
)
5840 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
5841 else if (XMARKER (w
->start
)->charpos
> ZV
)
5842 SET_TEXT_POS (start
, ZV
, ZV_BYTE
);
5844 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
5846 start_display (&it
, w
, start
);
5847 move_it_vertically (&it
, height
);
5848 bottom_y
= line_bottom_y (&it
);
5850 /* rms: On a non-window display,
5851 the value of it.vpos at the bottom of the screen
5852 seems to be 1 larger than window_box_height (w).
5853 This kludge fixes a bug whereby (move-to-window-line -1)
5854 when ZV is on the last screen line
5855 moves to the previous screen line instead of the last one. */
5856 if (! FRAME_WINDOW_P (XFRAME (w
->frame
)))
5859 /* Add in empty lines at the bottom of the window. */
5860 if (bottom_y
< height
)
5862 int uy
= FRAME_LINE_HEIGHT (it
.f
);
5863 it
.vpos
+= (height
- bottom_y
+ uy
- 1) / uy
;
5867 set_buffer_internal (old_buffer
);
5873 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
5874 doc
: /* Center point in selected window and maybe redisplay frame.
5875 With prefix argument ARG, recenter putting point on screen line ARG
5876 relative to the selected window. If ARG is negative, it counts up from the
5877 bottom of the window. (ARG should be less than the height of the window.)
5879 If ARG is omitted or nil, then recenter with point on the middle line of
5880 the selected window; if the variable `recenter-redisplay' is non-nil,
5881 also erase the entire frame and redraw it (when `auto-resize-tool-bars'
5882 is set to `grow-only', this resets the tool-bar's height to the minimum
5883 height needed); if `recenter-redisplay' has the special value `tty',
5884 then only tty frame are redrawn.
5886 Just C-u as prefix means put point in the center of the window
5887 and redisplay normally--don't erase and redraw the frame. */)
5888 (register Lisp_Object arg
)
5890 struct window
*w
= XWINDOW (selected_window
);
5891 struct buffer
*buf
= XBUFFER (w
->buffer
);
5892 struct buffer
*obuf
= current_buffer
;
5894 EMACS_INT charpos
, bytepos
;
5895 int iarg
IF_LINT (= 0);
5896 int this_scroll_margin
;
5898 /* If redisplay is suppressed due to an error, try again. */
5899 obuf
->display_error_modiff
= 0;
5903 if (!NILP (Vrecenter_redisplay
)
5904 && (!EQ (Vrecenter_redisplay
, Qtty
)
5905 || !NILP (Ftty_type (selected_frame
))))
5909 /* Invalidate pixel data calculated for all compositions. */
5910 for (i
= 0; i
< n_compositions
; i
++)
5911 composition_table
[i
]->font
= NULL
;
5913 WINDOW_XFRAME (w
)->minimize_tool_bar_window_p
= 1;
5915 Fredraw_frame (WINDOW_FRAME (w
));
5916 SET_FRAME_GARBAGED (WINDOW_XFRAME (w
));
5921 else if (CONSP (arg
)) /* Just C-u. */
5925 arg
= Fprefix_numeric_value (arg
);
5930 set_buffer_internal (buf
);
5932 /* Do this after making BUF current
5933 in case scroll_margin is buffer-local. */
5934 this_scroll_margin
= max (0, scroll_margin
);
5935 this_scroll_margin
= min (this_scroll_margin
,
5936 XFASTINT (w
->total_lines
) / 4);
5938 /* Handle centering on a graphical frame specially. Such frames can
5939 have variable-height lines and centering point on the basis of
5940 line counts would lead to strange effects. */
5941 if (FRAME_WINDOW_P (XFRAME (w
->frame
)))
5948 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
5949 start_display (&it
, w
, pt
);
5950 move_it_vertically_backward (&it
, window_box_height (w
) / 2);
5951 charpos
= IT_CHARPOS (it
);
5952 bytepos
= IT_BYTEPOS (it
);
5959 int extra_line_spacing
;
5960 int h
= window_box_height (w
);
5962 iarg
= - max (-iarg
, this_scroll_margin
);
5964 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
5965 start_display (&it
, w
, pt
);
5967 /* Be sure we have the exact height of the full line containing PT. */
5968 move_it_by_lines (&it
, 0);
5970 /* The amount of pixels we have to move back is the window
5971 height minus what's displayed in the line containing PT,
5972 and the lines below. */
5975 move_it_by_lines (&it
, nlines
);
5977 if (it
.vpos
== nlines
)
5981 /* Last line has no newline */
5982 h
-= line_bottom_y (&it
);
5986 /* Don't reserve space for extra line spacing of last line. */
5987 extra_line_spacing
= it
.max_extra_line_spacing
;
5989 /* If we can't move down NLINES lines because we hit
5990 the end of the buffer, count in some empty lines. */
5991 if (it
.vpos
< nlines
)
5994 extra_line_spacing
= it
.extra_line_spacing
;
5995 h
-= nlines
* (FRAME_LINE_HEIGHT (it
.f
) + extra_line_spacing
);
6000 /* Now find the new top line (starting position) of the window. */
6001 start_display (&it
, w
, pt
);
6003 move_it_vertically_backward (&it
, h
);
6005 /* If extra line spacing is present, we may move too far
6006 back. This causes the last line to be only partially
6007 visible (which triggers redisplay to recenter that line
6008 in the middle), so move forward.
6009 But ignore extra line spacing on last line, as it is not
6010 considered to be part of the visible height of the line.
6012 h
+= extra_line_spacing
;
6013 while (-it
.current_y
> h
)
6014 move_it_by_lines (&it
, 1);
6016 charpos
= IT_CHARPOS (it
);
6017 bytepos
= IT_BYTEPOS (it
);
6021 struct position pos
;
6023 iarg
= max (iarg
, this_scroll_margin
);
6025 pos
= *vmotion (PT
, -iarg
, w
);
6026 charpos
= pos
.bufpos
;
6027 bytepos
= pos
.bytepos
;
6032 struct position pos
;
6033 int ht
= window_internal_height (w
);
6040 /* Don't let it get into the margin at either top or bottom. */
6041 iarg
= max (iarg
, this_scroll_margin
);
6042 iarg
= min (iarg
, ht
- this_scroll_margin
- 1);
6044 pos
= *vmotion (PT
, - iarg
, w
);
6045 charpos
= pos
.bufpos
;
6046 bytepos
= pos
.bytepos
;
6049 /* Set the new window start. */
6050 set_marker_both (w
->start
, w
->buffer
, charpos
, bytepos
);
6051 w
->window_end_valid
= Qnil
;
6053 w
->optional_new_start
= Qt
;
6055 if (bytepos
== BEGV_BYTE
|| FETCH_BYTE (bytepos
- 1) == '\n')
6056 w
->start_at_line_beg
= Qt
;
6058 w
->start_at_line_beg
= Qnil
;
6060 set_buffer_internal (obuf
);
6065 DEFUN ("window-text-height", Fwindow_text_height
, Swindow_text_height
,
6067 doc
: /* Return the height in lines of the text display area of WINDOW.
6068 WINDOW defaults to the selected window.
6070 The return value does not include the mode line, any header line, nor
6071 any partial-height lines in the text display area. */)
6072 (Lisp_Object window
)
6074 struct window
*w
= decode_window (window
);
6075 int pixel_height
= window_box_height (w
);
6076 int line_height
= pixel_height
/ FRAME_LINE_HEIGHT (XFRAME (w
->frame
));
6077 return make_number (line_height
);
6082 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
6084 doc
: /* Position point relative to window.
6085 With no argument, position point at center of window.
6086 An argument specifies vertical position within the window;
6087 zero means top of window, negative means relative to bottom of window. */)
6090 struct window
*w
= XWINDOW (selected_window
);
6094 int this_scroll_margin
;
6097 if (!(BUFFERP (w
->buffer
)
6098 && XBUFFER (w
->buffer
) == current_buffer
))
6099 /* This test is needed to make sure PT/PT_BYTE make sense in w->buffer
6100 when passed below to set_marker_both. */
6101 error ("move-to-window-line called from unrelated buffer");
6103 window
= selected_window
;
6104 start
= marker_position (w
->start
);
6105 if (start
< BEGV
|| start
> ZV
)
6107 int height
= window_internal_height (w
);
6108 Fvertical_motion (make_number (- (height
/ 2)), window
);
6109 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
6110 w
->start_at_line_beg
= Fbolp ();
6111 w
->force_start
= Qt
;
6114 Fgoto_char (w
->start
);
6116 lines
= displayed_window_lines (w
);
6119 this_scroll_margin
= max (0, scroll_margin
);
6120 this_scroll_margin
= min (this_scroll_margin
, lines
/ 4);
6124 XSETFASTINT (arg
, lines
/ 2);
6127 int iarg
= XINT (Fprefix_numeric_value (arg
));
6130 iarg
= iarg
+ lines
;
6132 #if 0 /* This code would prevent move-to-window-line from moving point
6133 to a place inside the scroll margins (which would cause the
6134 next redisplay to scroll). I wrote this code, but then concluded
6135 it is probably better not to install it. However, it is here
6136 inside #if 0 so as not to lose it. -- rms. */
6138 /* Don't let it get into the margin at either top or bottom. */
6139 iarg
= max (iarg
, this_scroll_margin
);
6140 iarg
= min (iarg
, lines
- this_scroll_margin
- 1);
6143 arg
= make_number (iarg
);
6146 /* Skip past a partially visible first line. */
6148 XSETINT (arg
, XINT (arg
) + 1);
6150 return Fvertical_motion (arg
, window
);
6155 /***********************************************************************
6156 Window Configuration
6157 ***********************************************************************/
6159 struct save_window_data
6161 struct vectorlike_header header
;
6162 Lisp_Object selected_frame
;
6163 Lisp_Object current_window
;
6164 Lisp_Object current_buffer
;
6165 Lisp_Object minibuf_scroll_window
;
6166 Lisp_Object minibuf_selected_window
;
6167 Lisp_Object root_window
;
6168 Lisp_Object focus_frame
;
6169 /* A vector, each of whose elements is a struct saved_window
6171 Lisp_Object saved_windows
;
6173 /* All fields above are traced by the GC.
6174 From `fame-cols' down, the fields are ignored by the GC. */
6176 int frame_cols
, frame_lines
, frame_menu_bar_lines
;
6177 int frame_tool_bar_lines
;
6180 /* This is saved as a Lisp_Vector */
6183 struct vectorlike_header header
;
6185 Lisp_Object window
, clone_number
;
6186 Lisp_Object buffer
, start
, pointm
, mark
;
6187 Lisp_Object left_col
, top_line
, total_cols
, total_lines
;
6188 Lisp_Object normal_cols
, normal_lines
;
6189 Lisp_Object hscroll
, min_hscroll
;
6190 Lisp_Object parent
, prev
;
6191 Lisp_Object start_at_line_beg
;
6192 Lisp_Object display_table
;
6193 Lisp_Object orig_top_line
, orig_total_lines
;
6194 Lisp_Object left_margin_cols
, right_margin_cols
;
6195 Lisp_Object left_fringe_width
, right_fringe_width
, fringes_outside_margins
;
6196 Lisp_Object scroll_bar_width
, vertical_scroll_bar_type
;
6197 Lisp_Object dedicated
, resize_proportionally
;
6198 Lisp_Object splits
, nest
, window_parameters
;
6201 #define SAVED_WINDOW_N(swv,n) \
6202 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
6204 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
6205 doc
: /* Return t if OBJECT is a window-configuration object. */)
6206 (Lisp_Object object
)
6208 return WINDOW_CONFIGURATIONP (object
) ? Qt
: Qnil
;
6211 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
6212 doc
: /* Return the frame that CONFIG, a window-configuration object, is about. */)
6213 (Lisp_Object config
)
6215 register struct save_window_data
*data
;
6216 struct Lisp_Vector
*saved_windows
;
6218 CHECK_WINDOW_CONFIGURATION (config
);
6220 data
= (struct save_window_data
*) XVECTOR (config
);
6221 saved_windows
= XVECTOR (data
->saved_windows
);
6222 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
6225 DEFUN ("set-window-configuration", Fset_window_configuration
,
6226 Sset_window_configuration
, 1, 1, 0,
6227 doc
: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
6228 CONFIGURATION must be a value previously returned
6229 by `current-window-configuration' (which see).
6230 If CONFIGURATION was made from a frame that is now deleted,
6231 only frame-independent values can be restored. In this case,
6232 the return value is nil. Otherwise the value is t. */)
6233 (Lisp_Object configuration
)
6235 register struct save_window_data
*data
;
6236 struct Lisp_Vector
*saved_windows
;
6237 Lisp_Object new_current_buffer
;
6240 EMACS_INT old_point
= -1;
6242 CHECK_WINDOW_CONFIGURATION (configuration
);
6244 data
= (struct save_window_data
*) XVECTOR (configuration
);
6245 saved_windows
= XVECTOR (data
->saved_windows
);
6247 new_current_buffer
= data
->current_buffer
;
6248 if (NILP (BVAR (XBUFFER (new_current_buffer
), name
)))
6249 new_current_buffer
= Qnil
;
6252 if (XBUFFER (new_current_buffer
) == current_buffer
)
6253 /* The code further down "preserves point" by saving here PT in
6254 old_point and then setting it later back into PT. When the
6255 current-selected-window and the final-selected-window both show
6256 the current buffer, this suffers from the problem that the
6257 current PT is the window-point of the current-selected-window,
6258 while the final PT is the point of the final-selected-window, so
6259 this copy from one PT to the other would end up moving the
6260 window-point of the final-selected-window to the window-point of
6261 the current-selected-window. So we have to be careful which
6262 point of the current-buffer we copy into old_point. */
6263 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
)
6264 && WINDOWP (selected_window
)
6265 && EQ (XWINDOW (selected_window
)->buffer
, new_current_buffer
)
6266 && !EQ (selected_window
, data
->current_window
))
6267 old_point
= XMARKER (XWINDOW (data
->current_window
)->pointm
)->charpos
;
6271 /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of
6272 point in new_current_buffer as of the last time this buffer was
6273 used. This can be non-deterministic since it can be changed by
6274 things like jit-lock by mere temporary selection of some random
6275 window that happens to show this buffer.
6276 So if possible we want this arbitrary choice of "which point" to
6277 be the one from the to-be-selected-window so as to prevent this
6278 window's cursor from being copied from another window. */
6279 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
)
6280 /* If current_window = selected_window, its point is in BUF_PT. */
6281 && !EQ (selected_window
, data
->current_window
))
6282 old_point
= XMARKER (XWINDOW (data
->current_window
)->pointm
)->charpos
;
6284 old_point
= BUF_PT (XBUFFER (new_current_buffer
));
6287 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
6290 /* If f is a dead frame, don't bother rebuilding its window tree.
6291 However, there is other stuff we should still try to do below. */
6292 if (FRAME_LIVE_P (f
))
6294 register struct window
*w
;
6295 register struct saved_window
*p
;
6296 struct window
*root_window
;
6297 struct window
**leaf_windows
;
6301 /* If the frame has been resized since this window configuration was
6302 made, we change the frame to the size specified in the
6303 configuration, restore the configuration, and then resize it
6304 back. We keep track of the prevailing height in these variables. */
6305 int previous_frame_lines
= FRAME_LINES (f
);
6306 int previous_frame_cols
= FRAME_COLS (f
);
6307 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
6308 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
6310 /* The mouse highlighting code could get screwed up
6311 if it runs during this. */
6314 if (data
->frame_lines
!= previous_frame_lines
6315 || data
->frame_cols
!= previous_frame_cols
)
6316 change_frame_size (f
, data
->frame_lines
,
6317 data
->frame_cols
, 0, 0, 0);
6318 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
6319 if (data
->frame_menu_bar_lines
6320 != previous_frame_menu_bar_lines
)
6321 x_set_menu_bar_lines (f
, make_number (data
->frame_menu_bar_lines
),
6323 #ifdef HAVE_WINDOW_SYSTEM
6324 if (data
->frame_tool_bar_lines
6325 != previous_frame_tool_bar_lines
)
6326 x_set_tool_bar_lines (f
, make_number (data
->frame_tool_bar_lines
),
6331 /* "Swap out" point from the selected window's buffer
6332 into the window itself. (Normally the pointm of the selected
6333 window holds garbage.) We do this now, before
6334 restoring the window contents, and prevent it from
6335 being done later on when we select a new window. */
6336 if (! NILP (XWINDOW (selected_window
)->buffer
))
6338 w
= XWINDOW (selected_window
);
6339 set_marker_both (w
->pointm
,
6341 BUF_PT (XBUFFER (w
->buffer
)),
6342 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
6345 windows_or_buffers_changed
++;
6346 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
6348 /* Problem: Freeing all matrices and later allocating them again
6349 is a serious redisplay flickering problem. What we would
6350 really like to do is to free only those matrices not reused
6352 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
6354 = (struct window
**) alloca (count_windows (root_window
)
6355 * sizeof (struct window
*));
6356 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
6359 Mark all windows now on frame as "deleted".
6360 Restoring the new configuration "undeletes" any that are in it.
6362 Save their current buffers in their height fields, since we may
6363 need it later, if a buffer saved in the configuration is now
6365 delete_all_subwindows (FRAME_ROOT_WINDOW (f
));
6367 for (k
= 0; k
< saved_windows
->header
.size
; k
++)
6369 p
= SAVED_WINDOW_N (saved_windows
, k
);
6370 w
= XWINDOW (p
->window
);
6373 if (!NILP (p
->parent
))
6374 w
->parent
= SAVED_WINDOW_N (saved_windows
,
6375 XFASTINT (p
->parent
))->window
;
6379 if (!NILP (p
->prev
))
6381 w
->prev
= SAVED_WINDOW_N (saved_windows
,
6382 XFASTINT (p
->prev
))->window
;
6383 XWINDOW (w
->prev
)->next
= p
->window
;
6388 if (!NILP (w
->parent
))
6390 if (EQ (p
->total_cols
, XWINDOW (w
->parent
)->total_cols
))
6392 XWINDOW (w
->parent
)->vchild
= p
->window
;
6393 XWINDOW (w
->parent
)->hchild
= Qnil
;
6397 XWINDOW (w
->parent
)->hchild
= p
->window
;
6398 XWINDOW (w
->parent
)->vchild
= Qnil
;
6403 w
->clone_number
= p
->clone_number
;
6404 /* If we squirreled away the buffer in the window's height,
6406 if (BUFFERP (w
->total_lines
))
6407 w
->buffer
= w
->total_lines
;
6408 w
->left_col
= p
->left_col
;
6409 w
->top_line
= p
->top_line
;
6410 w
->total_cols
= p
->total_cols
;
6411 w
->total_lines
= p
->total_lines
;
6412 w
->normal_cols
= p
->normal_cols
;
6413 w
->normal_lines
= p
->normal_lines
;
6414 w
->hscroll
= p
->hscroll
;
6415 w
->min_hscroll
= p
->min_hscroll
;
6416 w
->display_table
= p
->display_table
;
6417 w
->orig_top_line
= p
->orig_top_line
;
6418 w
->orig_total_lines
= p
->orig_total_lines
;
6419 w
->left_margin_cols
= p
->left_margin_cols
;
6420 w
->right_margin_cols
= p
->right_margin_cols
;
6421 w
->left_fringe_width
= p
->left_fringe_width
;
6422 w
->right_fringe_width
= p
->right_fringe_width
;
6423 w
->fringes_outside_margins
= p
->fringes_outside_margins
;
6424 w
->scroll_bar_width
= p
->scroll_bar_width
;
6425 w
->vertical_scroll_bar_type
= p
->vertical_scroll_bar_type
;
6426 w
->dedicated
= p
->dedicated
;
6427 w
->splits
= p
->splits
;
6429 w
->window_parameters
= p
->window_parameters
;
6430 w
->resize_proportionally
= p
->resize_proportionally
;
6431 XSETFASTINT (w
->last_modified
, 0);
6432 XSETFASTINT (w
->last_overlay_modified
, 0);
6434 /* Reinstall the saved buffer and pointers into it. */
6435 if (NILP (p
->buffer
))
6436 w
->buffer
= p
->buffer
;
6439 if (!NILP (BVAR (XBUFFER (p
->buffer
), name
)))
6440 /* If saved buffer is alive, install it. */
6442 w
->buffer
= p
->buffer
;
6443 w
->start_at_line_beg
= p
->start_at_line_beg
;
6444 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
6445 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
6446 Fset_marker (BVAR (XBUFFER (w
->buffer
), mark
),
6447 p
->mark
, w
->buffer
);
6449 /* As documented in Fcurrent_window_configuration, don't
6450 restore the location of point in the buffer which was
6451 current when the window configuration was recorded. */
6452 if (!EQ (p
->buffer
, new_current_buffer
)
6453 && XBUFFER (p
->buffer
) == current_buffer
)
6454 Fgoto_char (w
->pointm
);
6456 else if (NILP (w
->buffer
) || NILP (BVAR (XBUFFER (w
->buffer
), name
)))
6457 /* Else unless window has a live buffer, get one. */
6459 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
6460 /* This will set the markers to beginning of visible
6462 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
6463 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
6464 w
->start_at_line_beg
= Qt
;
6467 /* Keeping window's old buffer; make sure the markers
6470 /* Set window markers at start of visible range. */
6471 if (XMARKER (w
->start
)->buffer
== 0)
6472 set_marker_restricted (w
->start
, make_number (0),
6474 if (XMARKER (w
->pointm
)->buffer
== 0)
6475 set_marker_restricted_both (w
->pointm
, w
->buffer
,
6476 BUF_PT (XBUFFER (w
->buffer
)),
6477 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
6478 w
->start_at_line_beg
= Qt
;
6483 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
6485 /* Arrange *not* to restore point in the buffer that was
6486 current when the window configuration was saved. */
6487 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
))
6488 set_marker_restricted (XWINDOW (data
->current_window
)->pointm
,
6489 make_number (old_point
),
6490 XWINDOW (data
->current_window
)->buffer
);
6492 /* In the following call to `select-window, prevent "swapping
6493 out point" in the old selected window using the buffer that
6494 has been restored into it. We already swapped out that point
6495 from that window's old buffer. */
6496 select_window (data
->current_window
, Qnil
, 1);
6497 BVAR (XBUFFER (XWINDOW (selected_window
)->buffer
), last_selected_window
)
6500 if (NILP (data
->focus_frame
)
6501 || (FRAMEP (data
->focus_frame
)
6502 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
6503 Fredirect_frame_focus (frame
, data
->focus_frame
);
6505 /* Set the screen height to the value it had before this function. */
6506 if (previous_frame_lines
!= FRAME_LINES (f
)
6507 || previous_frame_cols
!= FRAME_COLS (f
))
6508 change_frame_size (f
, previous_frame_lines
, previous_frame_cols
,
6510 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
6511 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
6512 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
6514 #ifdef HAVE_WINDOW_SYSTEM
6515 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
6516 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
6521 /* Now, free glyph matrices in windows that were not reused. */
6522 for (i
= n
= 0; i
< n_leaf_windows
; ++i
)
6524 if (NILP (leaf_windows
[i
]->buffer
))
6526 /* Assert it's not reused as a combination. */
6527 xassert (NILP (leaf_windows
[i
]->hchild
)
6528 && NILP (leaf_windows
[i
]->vchild
));
6529 free_window_matrices (leaf_windows
[i
]);
6531 else if (EQ (leaf_windows
[i
]->buffer
, new_current_buffer
))
6539 /* Fselect_window will have made f the selected frame, so we
6540 reselect the proper frame here. Fhandle_switch_frame will change the
6541 selected window too, but that doesn't make the call to
6542 Fselect_window above totally superfluous; it still sets f's
6544 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
6545 do_switch_frame (data
->selected_frame
, 0, 0, Qnil
);
6547 run_window_configuration_change_hook (f
);
6550 if (!NILP (new_current_buffer
))
6551 Fset_buffer (new_current_buffer
);
6553 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
6554 minibuf_selected_window
= data
->minibuf_selected_window
;
6556 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
6559 /* Delete all subwindows reachable via the next, vchild, and hchild
6562 delete_all_subwindows (Lisp_Object window
)
6564 register struct window
*w
;
6566 w
= XWINDOW (window
);
6568 if (!NILP (w
->next
))
6569 /* Delete WINDOW's siblings (we traverse postorderly). */
6570 delete_all_subwindows (w
->next
);
6572 w
->total_lines
= w
->buffer
; /* See Fset_window_configuration for excuse. */
6574 if (!NILP (w
->vchild
))
6576 delete_all_subwindows (w
->vchild
);
6579 else if (!NILP (w
->hchild
))
6581 delete_all_subwindows (w
->hchild
);
6584 else if (!NILP (w
->buffer
))
6587 unchain_marker (XMARKER (w
->pointm
));
6588 unchain_marker (XMARKER (w
->start
));
6592 Vwindow_list
= Qnil
;
6596 count_windows (register struct window
*window
)
6598 register int count
= 1;
6599 if (!NILP (window
->next
))
6600 count
+= count_windows (XWINDOW (window
->next
));
6601 if (!NILP (window
->vchild
))
6602 count
+= count_windows (XWINDOW (window
->vchild
));
6603 if (!NILP (window
->hchild
))
6604 count
+= count_windows (XWINDOW (window
->hchild
));
6609 /* Fill vector FLAT with leaf windows under W, starting at index I.
6610 Value is last index + 1. */
6613 get_leaf_windows (struct window
*w
, struct window
**flat
, int i
)
6617 if (!NILP (w
->hchild
))
6618 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
6619 else if (!NILP (w
->vchild
))
6620 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
6624 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
6631 /* Return a pointer to the glyph W's physical cursor is on. Value is
6632 null if W's current matrix is invalid, so that no meaningfull glyph
6636 get_phys_cursor_glyph (struct window
*w
)
6638 struct glyph_row
*row
;
6639 struct glyph
*glyph
;
6641 if (w
->phys_cursor
.vpos
>= 0
6642 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
6643 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
6645 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
6646 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
6655 save_window_save (Lisp_Object window
, struct Lisp_Vector
*vector
, int i
)
6657 register struct saved_window
*p
;
6658 register struct window
*w
;
6659 register Lisp_Object tem
;
6661 for (;!NILP (window
); window
= w
->next
)
6663 p
= SAVED_WINDOW_N (vector
, i
);
6664 w
= XWINDOW (window
);
6666 XSETFASTINT (w
->temslot
, i
); i
++;
6668 p
->clone_number
= w
->clone_number
;
6669 p
->buffer
= w
->buffer
;
6670 p
->left_col
= w
->left_col
;
6671 p
->top_line
= w
->top_line
;
6672 p
->total_cols
= w
->total_cols
;
6673 p
->total_lines
= w
->total_lines
;
6674 p
->normal_cols
= w
->normal_cols
;
6675 p
->normal_lines
= w
->normal_lines
;
6676 p
->hscroll
= w
->hscroll
;
6677 p
->min_hscroll
= w
->min_hscroll
;
6678 p
->display_table
= w
->display_table
;
6679 p
->orig_top_line
= w
->orig_top_line
;
6680 p
->orig_total_lines
= w
->orig_total_lines
;
6681 p
->left_margin_cols
= w
->left_margin_cols
;
6682 p
->right_margin_cols
= w
->right_margin_cols
;
6683 p
->left_fringe_width
= w
->left_fringe_width
;
6684 p
->right_fringe_width
= w
->right_fringe_width
;
6685 p
->fringes_outside_margins
= w
->fringes_outside_margins
;
6686 p
->scroll_bar_width
= w
->scroll_bar_width
;
6687 p
->vertical_scroll_bar_type
= w
->vertical_scroll_bar_type
;
6688 p
->dedicated
= w
->dedicated
;
6689 p
->splits
= w
->splits
;
6691 p
->resize_proportionally
= w
->resize_proportionally
;
6692 p
->window_parameters
= w
->window_parameters
;
6693 if (!NILP (w
->buffer
))
6695 /* Save w's value of point in the window configuration.
6696 If w is the selected window, then get the value of point
6697 from the buffer; pointm is garbage in the selected window. */
6698 if (EQ (window
, selected_window
))
6700 p
->pointm
= Fmake_marker ();
6701 set_marker_both (p
->pointm
, w
->buffer
,
6702 BUF_PT (XBUFFER (w
->buffer
)),
6703 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
6706 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
6708 p
->start
= Fcopy_marker (w
->start
, Qnil
);
6709 p
->start_at_line_beg
= w
->start_at_line_beg
;
6711 tem
= BVAR (XBUFFER (w
->buffer
), mark
);
6712 p
->mark
= Fcopy_marker (tem
, Qnil
);
6719 p
->start_at_line_beg
= Qnil
;
6722 if (NILP (w
->parent
))
6725 p
->parent
= XWINDOW (w
->parent
)->temslot
;
6730 p
->prev
= XWINDOW (w
->prev
)->temslot
;
6732 if (!NILP (w
->vchild
))
6733 i
= save_window_save (w
->vchild
, vector
, i
);
6734 if (!NILP (w
->hchild
))
6735 i
= save_window_save (w
->hchild
, vector
, i
);
6741 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
6742 Scurrent_window_configuration
, 0, 1, 0,
6743 doc
: /* Return an object representing the current window configuration of FRAME.
6744 If FRAME is nil or omitted, use the selected frame.
6745 This describes the number of windows, their sizes and current buffers,
6746 and for each displayed buffer, where display starts, and the positions of
6747 point and mark. An exception is made for point in the current buffer:
6748 its value is -not- saved.
6749 This also records the currently selected frame, and FRAME's focus
6750 redirection (see `redirect-frame-focus'). */)
6753 register Lisp_Object tem
;
6754 register int n_windows
;
6755 register struct save_window_data
*data
;
6760 frame
= selected_frame
;
6761 CHECK_LIVE_FRAME (frame
);
6764 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
6765 data
= ALLOCATE_PSEUDOVECTOR (struct save_window_data
, frame_cols
,
6766 PVEC_WINDOW_CONFIGURATION
);
6768 data
->frame_cols
= FRAME_COLS (f
);
6769 data
->frame_lines
= FRAME_LINES (f
);
6770 data
->frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
6771 data
->frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
6772 data
->selected_frame
= selected_frame
;
6773 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
6774 XSETBUFFER (data
->current_buffer
, current_buffer
);
6775 data
->minibuf_scroll_window
= minibuf_level
> 0 ? Vminibuf_scroll_window
: Qnil
;
6776 data
->minibuf_selected_window
= minibuf_level
> 0 ? minibuf_selected_window
: Qnil
;
6777 data
->root_window
= FRAME_ROOT_WINDOW (f
);
6778 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
6779 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
6780 data
->saved_windows
= tem
;
6781 for (i
= 0; i
< n_windows
; i
++)
6782 XVECTOR (tem
)->contents
[i
]
6783 = Fmake_vector (make_number (VECSIZE (struct saved_window
)), Qnil
);
6784 save_window_save (FRAME_ROOT_WINDOW (f
), XVECTOR (tem
), 0);
6785 XSETWINDOW_CONFIGURATION (tem
, data
);
6790 /***********************************************************************
6792 ***********************************************************************/
6795 window_tree (struct window
*w
)
6797 Lisp_Object tail
= Qnil
;
6798 Lisp_Object result
= Qnil
;
6805 if (!NILP (w
->hchild
))
6806 wn
= Fcons (Qnil
, Fcons (Fwindow_edges (wn
),
6807 window_tree (XWINDOW (w
->hchild
))));
6808 else if (!NILP (w
->vchild
))
6809 wn
= Fcons (Qt
, Fcons (Fwindow_edges (wn
),
6810 window_tree (XWINDOW (w
->vchild
))));
6814 result
= tail
= Fcons (wn
, Qnil
);
6818 XSETCDR (tail
, Fcons (wn
, Qnil
));
6822 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
6830 DEFUN ("window-tree", Fwindow_tree
, Swindow_tree
,
6832 doc
: /* Return the window tree for frame FRAME.
6834 The return value is a list of the form (ROOT MINI), where ROOT
6835 represents the window tree of the frame's root window, and MINI
6836 is the frame's minibuffer window.
6838 If the root window is not split, ROOT is the root window itself.
6839 Otherwise, ROOT is a list (DIR EDGES W1 W2 ...) where DIR is nil for a
6840 horizontal split, and t for a vertical split, EDGES gives the combined
6841 size and position of the subwindows in the split, and the rest of the
6842 elements are the subwindows in the split. Each of the subwindows may
6843 again be a window or a list representing a window split, and so on.
6844 EDGES is a list \(LEFT TOP RIGHT BOTTOM) as returned by `window-edges'.
6846 If FRAME is nil or omitted, return information on the currently
6853 frame
= selected_frame
;
6855 CHECK_FRAME (frame
);
6858 if (!FRAME_LIVE_P (f
))
6861 return window_tree (XWINDOW (FRAME_ROOT_WINDOW (f
)));
6865 /***********************************************************************
6867 ***********************************************************************/
6869 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
6871 doc
: /* Set width of marginal areas of window WINDOW.
6872 If WINDOW is nil, set margins of the currently selected window.
6873 Second arg LEFT-WIDTH specifies the number of character cells to
6874 reserve for the left marginal area. Optional third arg RIGHT-WIDTH
6875 does the same for the right marginal area. A nil width parameter
6876 means no margin. */)
6877 (Lisp_Object window
, Lisp_Object left_width
, Lisp_Object right_width
)
6879 struct window
*w
= decode_window (window
);
6881 /* Translate negative or zero widths to nil.
6882 Margins that are too wide have to be checked elsewhere. */
6884 if (!NILP (left_width
))
6886 CHECK_NUMBER (left_width
);
6887 if (XINT (left_width
) <= 0)
6891 if (!NILP (right_width
))
6893 CHECK_NUMBER (right_width
);
6894 if (XINT (right_width
) <= 0)
6898 if (!EQ (w
->left_margin_cols
, left_width
)
6899 || !EQ (w
->right_margin_cols
, right_width
))
6901 w
->left_margin_cols
= left_width
;
6902 w
->right_margin_cols
= right_width
;
6904 adjust_window_margins (w
);
6906 ++windows_or_buffers_changed
;
6907 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
6914 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
6916 doc
: /* Get width of marginal areas of window WINDOW.
6917 If WINDOW is omitted or nil, use the currently selected window.
6918 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).
6919 If a marginal area does not exist, its width will be returned
6921 (Lisp_Object window
)
6923 struct window
*w
= decode_window (window
);
6924 return Fcons (w
->left_margin_cols
, w
->right_margin_cols
);
6929 /***********************************************************************
6931 ***********************************************************************/
6933 DEFUN ("set-window-fringes", Fset_window_fringes
, Sset_window_fringes
,
6935 doc
: /* Set the fringe widths of window WINDOW.
6936 If WINDOW is nil, set the fringe widths of the currently selected
6938 Second arg LEFT-WIDTH specifies the number of pixels to reserve for
6939 the left fringe. Optional third arg RIGHT-WIDTH specifies the right
6940 fringe width. If a fringe width arg is nil, that means to use the
6941 frame's default fringe width. Default fringe widths can be set with
6942 the command `set-fringe-style'.
6943 If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes
6944 outside of the display margins. By default, fringes are drawn between
6945 display marginal areas and the text area. */)
6946 (Lisp_Object window
, Lisp_Object left_width
, Lisp_Object right_width
, Lisp_Object outside_margins
)
6948 struct window
*w
= decode_window (window
);
6950 if (!NILP (left_width
))
6951 CHECK_NATNUM (left_width
);
6952 if (!NILP (right_width
))
6953 CHECK_NATNUM (right_width
);
6955 /* Do nothing on a tty. */
6956 if (FRAME_WINDOW_P (WINDOW_XFRAME (w
))
6957 && (!EQ (w
->left_fringe_width
, left_width
)
6958 || !EQ (w
->right_fringe_width
, right_width
)
6959 || !EQ (w
->fringes_outside_margins
, outside_margins
)))
6961 w
->left_fringe_width
= left_width
;
6962 w
->right_fringe_width
= right_width
;
6963 w
->fringes_outside_margins
= outside_margins
;
6965 adjust_window_margins (w
);
6967 clear_glyph_matrix (w
->current_matrix
);
6968 w
->window_end_valid
= Qnil
;
6970 ++windows_or_buffers_changed
;
6971 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
6978 DEFUN ("window-fringes", Fwindow_fringes
, Swindow_fringes
,
6980 doc
: /* Get width of fringes of window WINDOW.
6981 If WINDOW is omitted or nil, use the currently selected window.
6982 Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
6983 (Lisp_Object window
)
6985 struct window
*w
= decode_window (window
);
6987 return Fcons (make_number (WINDOW_LEFT_FRINGE_WIDTH (w
)),
6988 Fcons (make_number (WINDOW_RIGHT_FRINGE_WIDTH (w
)),
6989 Fcons ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
6990 ? Qt
: Qnil
), Qnil
)));
6995 /***********************************************************************
6997 ***********************************************************************/
6999 DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars
,
7000 Sset_window_scroll_bars
, 2, 4, 0,
7001 doc
: /* Set width and type of scroll bars of window WINDOW.
7002 If window is nil, set scroll bars of the currently selected window.
7003 Second parameter WIDTH specifies the pixel width for the scroll bar;
7004 this is automatically adjusted to a multiple of the frame column width.
7005 Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
7006 bar: left, right, or nil.
7007 If WIDTH is nil, use the frame's scroll-bar width.
7008 If VERTICAL-TYPE is t, use the frame's scroll-bar type.
7009 Fourth parameter HORIZONTAL-TYPE is currently unused. */)
7010 (Lisp_Object window
, Lisp_Object width
, Lisp_Object vertical_type
, Lisp_Object horizontal_type
)
7012 struct window
*w
= decode_window (window
);
7016 CHECK_NATNUM (width
);
7018 if (XINT (width
) == 0)
7019 vertical_type
= Qnil
;
7022 if (!(NILP (vertical_type
)
7023 || EQ (vertical_type
, Qleft
)
7024 || EQ (vertical_type
, Qright
)
7025 || EQ (vertical_type
, Qt
)))
7026 error ("Invalid type of vertical scroll bar");
7028 if (!EQ (w
->scroll_bar_width
, width
)
7029 || !EQ (w
->vertical_scroll_bar_type
, vertical_type
))
7031 w
->scroll_bar_width
= width
;
7032 w
->vertical_scroll_bar_type
= vertical_type
;
7034 adjust_window_margins (w
);
7036 clear_glyph_matrix (w
->current_matrix
);
7037 w
->window_end_valid
= Qnil
;
7039 ++windows_or_buffers_changed
;
7040 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
7047 DEFUN ("window-scroll-bars", Fwindow_scroll_bars
, Swindow_scroll_bars
,
7049 doc
: /* Get width and type of scroll bars of window WINDOW.
7050 If WINDOW is omitted or nil, use the currently selected window.
7051 Value is a list of the form (WIDTH COLS VERTICAL-TYPE HORIZONTAL-TYPE).
7052 If WIDTH is nil or TYPE is t, the window is using the frame's corresponding
7054 (Lisp_Object window
)
7056 struct window
*w
= decode_window (window
);
7057 return Fcons (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
)
7058 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
)
7059 : WINDOW_SCROLL_BAR_AREA_WIDTH (w
))),
7060 Fcons (make_number (WINDOW_SCROLL_BAR_COLS (w
)),
7061 Fcons (w
->vertical_scroll_bar_type
,
7062 Fcons (Qnil
, Qnil
))));
7067 /***********************************************************************
7069 ***********************************************************************/
7071 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 2, 0,
7072 doc
: /* Return the amount by which WINDOW is scrolled vertically.
7073 Use the selected window if WINDOW is nil or omitted.
7074 Normally, value is a multiple of the canonical character height of WINDOW;
7075 optional second arg PIXELS-P means value is measured in pixels. */)
7076 (Lisp_Object window
, Lisp_Object pixels_p
)
7083 window
= selected_window
;
7085 CHECK_WINDOW (window
);
7086 w
= XWINDOW (window
);
7087 f
= XFRAME (w
->frame
);
7089 if (FRAME_WINDOW_P (f
))
7090 result
= (NILP (pixels_p
)
7091 ? FRAME_CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
)
7092 : make_number (-w
->vscroll
));
7094 result
= make_number (0);
7099 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
7101 doc
: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL.
7102 WINDOW nil means use the selected window. Normally, VSCROLL is a
7103 non-negative multiple of the canonical character height of WINDOW;
7104 optional third arg PIXELS-P non-nil means that VSCROLL is in pixels.
7105 If PIXELS-P is nil, VSCROLL may have to be rounded so that it
7106 corresponds to an integral number of pixels. The return value is the
7107 result of this rounding.
7108 If PIXELS-P is non-nil, the return value is VSCROLL. */)
7109 (Lisp_Object window
, Lisp_Object vscroll
, Lisp_Object pixels_p
)
7115 window
= selected_window
;
7117 CHECK_WINDOW (window
);
7118 CHECK_NUMBER_OR_FLOAT (vscroll
);
7120 w
= XWINDOW (window
);
7121 f
= XFRAME (w
->frame
);
7123 if (FRAME_WINDOW_P (f
))
7125 int old_dy
= w
->vscroll
;
7127 w
->vscroll
= - (NILP (pixels_p
)
7128 ? FRAME_LINE_HEIGHT (f
) * XFLOATINT (vscroll
)
7129 : XFLOATINT (vscroll
));
7130 w
->vscroll
= min (w
->vscroll
, 0);
7132 if (w
->vscroll
!= old_dy
)
7134 /* Adjust glyph matrix of the frame if the virtual display
7135 area becomes larger than before. */
7136 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
7139 /* Prevent redisplay shortcuts. */
7140 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
7144 return Fwindow_vscroll (window
, pixels_p
);
7148 /* Call FN for all leaf windows on frame F. FN is called with the
7149 first argument being a pointer to the leaf window, and with
7150 additional argument USER_DATA. Stops when FN returns 0. */
7153 foreach_window (struct frame
*f
, int (*fn
) (struct window
*, void *),
7156 /* delete_frame may set FRAME_ROOT_WINDOW (f) to Qnil. */
7157 if (WINDOWP (FRAME_ROOT_WINDOW (f
)))
7158 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, user_data
);
7162 /* Helper function for foreach_window. Call FN for all leaf windows
7163 reachable from W. FN is called with the first argument being a
7164 pointer to the leaf window, and with additional argument USER_DATA.
7165 Stop when FN returns 0. Value is 0 if stopped by FN. */
7168 foreach_window_1 (struct window
*w
, int (*fn
) (struct window
*, void *), void *user_data
)
7172 for (cont
= 1; w
&& cont
;)
7174 if (!NILP (w
->hchild
))
7175 cont
= foreach_window_1 (XWINDOW (w
->hchild
), fn
, user_data
);
7176 else if (!NILP (w
->vchild
))
7177 cont
= foreach_window_1 (XWINDOW (w
->vchild
), fn
, user_data
);
7179 cont
= fn (w
, user_data
);
7181 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
7188 /* Freeze or unfreeze the window start of W unless it is a
7189 mini-window or the selected window. FREEZE_P non-null means freeze
7190 the window start. */
7193 freeze_window_start (struct window
*w
, void *freeze_p
)
7195 if (MINI_WINDOW_P (w
)
7196 || (WINDOWP (selected_window
) /* Can be nil in corner cases. */
7197 && (w
== XWINDOW (selected_window
)
7198 || (MINI_WINDOW_P (XWINDOW (selected_window
))
7199 && ! NILP (Vminibuf_scroll_window
)
7200 && w
== XWINDOW (Vminibuf_scroll_window
)))))
7203 w
->frozen_window_start_p
= freeze_p
!= NULL
;
7208 /* Freeze or unfreeze the window starts of all leaf windows on frame
7209 F, except the selected window and a mini-window. FREEZE_P non-zero
7210 means freeze the window start. */
7213 freeze_window_starts (struct frame
*f
, int freeze_p
)
7215 foreach_window (f
, freeze_window_start
, (void *) (freeze_p
? f
: 0));
7219 /***********************************************************************
7221 ***********************************************************************/
7223 /* Return 1 if window configurations C1 and C2
7224 describe the same state of affairs. This is used by Fequal. */
7227 compare_window_configurations (Lisp_Object c1
, Lisp_Object c2
, int ignore_positions
)
7229 register struct save_window_data
*d1
, *d2
;
7230 struct Lisp_Vector
*sw1
, *sw2
;
7233 CHECK_WINDOW_CONFIGURATION (c1
);
7234 CHECK_WINDOW_CONFIGURATION (c2
);
7236 d1
= (struct save_window_data
*) XVECTOR (c1
);
7237 d2
= (struct save_window_data
*) XVECTOR (c2
);
7238 sw1
= XVECTOR (d1
->saved_windows
);
7239 sw2
= XVECTOR (d2
->saved_windows
);
7241 if (d1
->frame_cols
!= d2
->frame_cols
)
7243 if (d1
->frame_lines
!= d2
->frame_lines
)
7245 if (d1
->frame_menu_bar_lines
!= d2
->frame_menu_bar_lines
)
7247 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
7249 /* Don't compare the current_window field directly.
7250 Instead see w1_is_current and w2_is_current, below. */
7251 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
7253 if (! ignore_positions
)
7255 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
7257 if (! EQ (d1
->minibuf_selected_window
, d2
->minibuf_selected_window
))
7260 /* Don't compare the root_window field.
7261 We don't require the two configurations
7262 to use the same window object,
7263 and the two root windows must be equivalent
7264 if everything else compares equal. */
7265 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
7268 /* Verify that the two confis have the same number of windows. */
7269 if (sw1
->header
.size
!= sw2
->header
.size
)
7272 for (i
= 0; i
< sw1
->header
.size
; i
++)
7274 struct saved_window
*p1
, *p2
;
7275 int w1_is_current
, w2_is_current
;
7277 p1
= SAVED_WINDOW_N (sw1
, i
);
7278 p2
= SAVED_WINDOW_N (sw2
, i
);
7280 /* Verify that the current windows in the two
7281 configurations correspond to each other. */
7282 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
7283 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
7285 if (w1_is_current
!= w2_is_current
)
7288 /* Verify that the corresponding windows do match. */
7289 if (! EQ (p1
->buffer
, p2
->buffer
))
7291 if (! EQ (p1
->left_col
, p2
->left_col
))
7293 if (! EQ (p1
->top_line
, p2
->top_line
))
7295 if (! EQ (p1
->total_cols
, p2
->total_cols
))
7297 if (! EQ (p1
->total_lines
, p2
->total_lines
))
7299 if (! EQ (p1
->display_table
, p2
->display_table
))
7301 if (! EQ (p1
->parent
, p2
->parent
))
7303 if (! EQ (p1
->prev
, p2
->prev
))
7305 if (! ignore_positions
)
7307 if (! EQ (p1
->hscroll
, p2
->hscroll
))
7309 if (!EQ (p1
->min_hscroll
, p2
->min_hscroll
))
7311 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
7313 if (NILP (Fequal (p1
->start
, p2
->start
)))
7315 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
7317 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
7320 if (! EQ (p1
->left_margin_cols
, p2
->left_margin_cols
))
7322 if (! EQ (p1
->right_margin_cols
, p2
->right_margin_cols
))
7324 if (! EQ (p1
->left_fringe_width
, p2
->left_fringe_width
))
7326 if (! EQ (p1
->right_fringe_width
, p2
->right_fringe_width
))
7328 if (! EQ (p1
->fringes_outside_margins
, p2
->fringes_outside_margins
))
7330 if (! EQ (p1
->scroll_bar_width
, p2
->scroll_bar_width
))
7332 if (! EQ (p1
->vertical_scroll_bar_type
, p2
->vertical_scroll_bar_type
))
7339 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
7340 Scompare_window_configurations
, 2, 2, 0,
7341 doc
: /* Compare two window configurations as regards the structure of windows.
7342 This function ignores details such as the values of point and mark
7343 and scrolling positions. */)
7344 (Lisp_Object x
, Lisp_Object y
)
7346 if (compare_window_configurations (x
, y
, 1))
7352 init_window_once (void)
7354 struct frame
*f
= make_initial_frame ();
7355 XSETFRAME (selected_frame
, f
);
7356 Vterminal_frame
= selected_frame
;
7357 minibuf_window
= f
->minibuffer_window
;
7358 selected_window
= f
->selected_window
;
7359 last_nonminibuf_frame
= f
;
7361 window_initialized
= 1;
7367 Vwindow_list
= Qnil
;
7371 syms_of_window (void)
7373 Qscroll_up
= intern_c_string ("scroll-up");
7374 staticpro (&Qscroll_up
);
7376 Qscroll_down
= intern_c_string ("scroll-down");
7377 staticpro (&Qscroll_down
);
7379 Qscroll_command
= intern_c_string ("scroll-command");
7380 staticpro (&Qscroll_command
);
7382 Fput (Qscroll_up
, Qscroll_command
, Qt
);
7383 Fput (Qscroll_down
, Qscroll_command
, Qt
);
7385 Qwindow_size_fixed
= intern_c_string ("window-size-fixed");
7386 staticpro (&Qwindow_size_fixed
);
7387 Fset (Qwindow_size_fixed
, Qnil
);
7389 staticpro (&Qwindow_configuration_change_hook
);
7390 Qwindow_configuration_change_hook
7391 = intern_c_string ("window-configuration-change-hook");
7393 Qwindowp
= intern_c_string ("windowp");
7394 staticpro (&Qwindowp
);
7396 Qwindow_configuration_p
= intern_c_string ("window-configuration-p");
7397 staticpro (&Qwindow_configuration_p
);
7399 Qwindow_live_p
= intern_c_string ("window-live-p");
7400 staticpro (&Qwindow_live_p
);
7402 Qwindow_deletable_p
= intern_c_string ("window-deletable-p");
7403 staticpro (&Qwindow_deletable_p
);
7405 Qdelete_window
= intern_c_string ("delete-window");
7406 staticpro (&Qdelete_window
);
7408 Qresize_root_window
= intern_c_string ("resize-root-window");
7409 staticpro (&Qresize_root_window
);
7411 Qresize_root_window_vertically
= intern_c_string ("resize-root-window-vertically");
7412 staticpro (&Qresize_root_window_vertically
);
7414 Qsafe
= intern_c_string ("safe");
7417 Qdisplay_buffer
= intern_c_string ("display-buffer");
7418 staticpro (&Qdisplay_buffer
);
7420 Qreplace_buffer_in_windows
= intern_c_string ("replace-buffer-in-windows");
7421 staticpro (&Qreplace_buffer_in_windows
);
7423 Qrecord_window_buffer
= intern_c_string ("record-window-buffer");
7424 staticpro (&Qrecord_window_buffer
);
7426 Qget_mru_window
= intern_c_string ("get-mru-window");
7427 staticpro (&Qget_mru_window
);
7429 Qtemp_buffer_show_hook
= intern_c_string ("temp-buffer-show-hook");
7430 staticpro (&Qtemp_buffer_show_hook
);
7432 Qabove
= intern_c_string ("above");
7433 staticpro (&Qabove
);
7435 Qbelow
= intern_c_string ("below");
7436 staticpro (&Qbelow
);
7438 Qauto_buffer_name
= intern_c_string ("auto-buffer-name");
7439 staticpro (&Qauto_buffer_name
);
7441 staticpro (&Vwindow_list
);
7443 minibuf_selected_window
= Qnil
;
7444 staticpro (&minibuf_selected_window
);
7446 window_scroll_pixel_based_preserve_x
= -1;
7447 window_scroll_pixel_based_preserve_y
= -1;
7448 window_scroll_preserve_hpos
= -1;
7449 window_scroll_preserve_vpos
= -1;
7451 DEFVAR_LISP ("temp-buffer-show-function", Vtemp_buffer_show_function
,
7452 doc
: /* Non-nil means call as function to display a help buffer.
7453 The function is called with one argument, the buffer to be displayed.
7454 Used by `with-output-to-temp-buffer'.
7455 If this function is used, then it must do the entire job of showing
7456 the buffer; `temp-buffer-show-hook' is not run unless this function runs it. */);
7457 Vtemp_buffer_show_function
= Qnil
;
7459 DEFVAR_LISP ("minibuffer-scroll-window", Vminibuf_scroll_window
,
7460 doc
: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */);
7461 Vminibuf_scroll_window
= Qnil
;
7463 DEFVAR_BOOL ("mode-line-in-non-selected-windows", mode_line_in_non_selected_windows
,
7464 doc
: /* Non-nil means to use `mode-line-inactive' face in non-selected windows.
7465 If the minibuffer is active, the `minibuffer-scroll-window' mode line
7466 is displayed in the `mode-line' face. */);
7467 mode_line_in_non_selected_windows
= 1;
7469 DEFVAR_LISP ("other-window-scroll-buffer", Vother_window_scroll_buffer
,
7470 doc
: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. */);
7471 Vother_window_scroll_buffer
= Qnil
;
7473 DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p
,
7474 doc
: /* *Non-nil means to automatically adjust `window-vscroll' to view tall lines. */);
7475 auto_window_vscroll_p
= 1;
7477 DEFVAR_INT ("next-screen-context-lines", next_screen_context_lines
,
7478 doc
: /* *Number of lines of continuity when scrolling by screenfuls. */);
7479 next_screen_context_lines
= 2;
7481 DEFVAR_INT ("window-min-height", window_min_height
,
7482 doc
: /* Allow deleting windows less than this tall.
7483 The value is measured in line units. If a window wants a modeline it
7484 is counted as one line.
7486 Emacs honors settings of this variable when enlarging or shrinking
7487 windows vertically. A value less than 1 is invalid. */);
7488 window_min_height
= 4;
7490 DEFVAR_INT ("window-min-width", window_min_width
,
7491 doc
: /* Allow deleting windows less than this wide.
7492 The value is measured in characters and includes any fringes or
7495 Emacs honors settings of this variable when enlarging or shrinking
7496 windows horizontally. A value less than 2 is invalid. */);
7497 window_min_width
= 10;
7499 DEFVAR_LISP ("scroll-preserve-screen-position",
7500 Vscroll_preserve_screen_position
,
7501 doc
: /* *Controls if scroll commands move point to keep its screen position unchanged.
7502 A value of nil means point does not keep its screen position except
7503 at the scroll margin or window boundary respectively.
7504 A value of t means point keeps its screen position if the scroll
7505 command moved it vertically out of the window, e.g. when scrolling
7507 Any other value means point always keeps its screen position.
7508 Scroll commands should have the `scroll-command' property
7509 on their symbols to be controlled by this variable. */);
7510 Vscroll_preserve_screen_position
= Qnil
;
7512 DEFVAR_LISP ("window-point-insertion-type", Vwindow_point_insertion_type
,
7513 doc
: /* Type of marker to use for `window-point'. */);
7514 Vwindow_point_insertion_type
= Qnil
;
7516 DEFVAR_LISP ("window-configuration-change-hook",
7517 Vwindow_configuration_change_hook
,
7518 doc
: /* Functions to call when window configuration changes.
7519 The buffer-local part is run once per window, with the relevant window
7520 selected; while the global part is run only once for the modified frame,
7521 with the relevant frame selected. */);
7522 Vwindow_configuration_change_hook
= Qnil
;
7524 DEFVAR_LISP ("recenter-redisplay", Vrecenter_redisplay
,
7525 doc
: /* If non-nil, then the `recenter' command with a nil argument
7526 will redraw the entire frame; the special value `tty' causes the
7527 frame to be redrawn only if it is a tty frame. */);
7528 Vrecenter_redisplay
= Qtty
;
7531 defsubr (&Sselected_window
);
7532 defsubr (&Sminibuffer_window
);
7533 defsubr (&Swindow_minibuffer_p
);
7534 defsubr (&Swindowp
);
7535 defsubr (&Swindow_live_p
);
7536 defsubr (&Swindow_frame
);
7537 defsubr (&Sframe_root_window
);
7538 defsubr (&Sframe_first_window
);
7539 defsubr (&Sframe_selected_window
);
7540 defsubr (&Sset_frame_selected_window
);
7541 defsubr (&Spos_visible_in_window_p
);
7542 defsubr (&Swindow_line_height
);
7543 defsubr (&Swindow_clone_number
);
7544 defsubr (&Swindow_buffer
);
7545 defsubr (&Swindow_parent
);
7546 defsubr (&Swindow_vchild
);
7547 defsubr (&Swindow_hchild
);
7548 defsubr (&Swindow_next
);
7549 defsubr (&Swindow_prev
);
7550 defsubr (&Swindow_splits
);
7551 defsubr (&Sset_window_splits
);
7552 defsubr (&Swindow_nest
);
7553 defsubr (&Sset_window_nest
);
7554 defsubr (&Swindow_use_time
);
7555 defsubr (&Swindow_top_line
);
7556 defsubr (&Swindow_left_column
);
7557 defsubr (&Swindow_total_size
);
7558 defsubr (&Swindow_normal_size
);
7559 defsubr (&Swindow_new_total
);
7560 defsubr (&Swindow_new_normal
);
7561 defsubr (&Sset_window_new_total
);
7562 defsubr (&Sset_window_new_normal
);
7563 defsubr (&Swindow_body_size
);
7564 defsubr (&Swindow_hscroll
);
7565 defsubr (&Sset_window_hscroll
);
7566 defsubr (&Swindow_redisplay_end_trigger
);
7567 defsubr (&Sset_window_redisplay_end_trigger
);
7568 defsubr (&Swindow_edges
);
7569 defsubr (&Swindow_pixel_edges
);
7570 defsubr (&Swindow_absolute_pixel_edges
);
7571 defsubr (&Swindow_inside_edges
);
7572 defsubr (&Swindow_inside_pixel_edges
);
7573 defsubr (&Swindow_inside_absolute_pixel_edges
);
7574 defsubr (&Scoordinates_in_window_p
);
7575 defsubr (&Swindow_at
);
7576 defsubr (&Swindow_point
);
7577 defsubr (&Swindow_start
);
7578 defsubr (&Swindow_end
);
7579 defsubr (&Sset_window_point
);
7580 defsubr (&Sset_window_start
);
7581 defsubr (&Swindow_dedicated_p
);
7582 defsubr (&Sset_window_dedicated_p
);
7583 defsubr (&Swindow_display_table
);
7584 defsubr (&Sset_window_display_table
);
7585 defsubr (&Snext_window
);
7586 defsubr (&Sprevious_window
);
7587 defsubr (&Sother_window
);
7588 defsubr (&Sget_buffer_window
);
7589 defsubr (&Sdelete_other_windows
);
7590 defsubr (&Sdelete_windows_on
);
7591 defsubr (&Sreplace_buffer_in_windows
);
7592 defsubr (&Sdelete_window
);
7593 defsubr (&Sset_window_buffer
);
7594 defsubr (&Sset_window_clone_number
);
7595 defsubr (&Sselect_window
);
7596 defsubr (&Sforce_window_update
);
7597 defsubr (&Stemp_output_buffer_show
);
7598 defsubr (&Ssplit_window
);
7599 defsubr (&Senlarge_window
);
7600 defsubr (&Sshrink_window
);
7601 defsubr (&Sadjust_window_trailing_edge
);
7602 defsubr (&Sscroll_up
);
7603 defsubr (&Sscroll_down
);
7604 defsubr (&Sscroll_left
);
7605 defsubr (&Sscroll_right
);
7606 defsubr (&Sother_window_for_scrolling
);
7607 defsubr (&Sscroll_other_window
);
7608 defsubr (&Sminibuffer_selected_window
);
7609 defsubr (&Srecenter
);
7610 defsubr (&Swindow_text_height
);
7611 defsubr (&Smove_to_window_line
);
7612 defsubr (&Swindow_configuration_p
);
7613 defsubr (&Swindow_configuration_frame
);
7614 defsubr (&Sset_window_configuration
);
7615 defsubr (&Scurrent_window_configuration
);
7616 defsubr (&Swindow_tree
);
7617 defsubr (&Sset_window_margins
);
7618 defsubr (&Swindow_margins
);
7619 defsubr (&Sset_window_fringes
);
7620 defsubr (&Swindow_fringes
);
7621 defsubr (&Sset_window_scroll_bars
);
7622 defsubr (&Swindow_scroll_bars
);
7623 defsubr (&Swindow_vscroll
);
7624 defsubr (&Sset_window_vscroll
);
7625 defsubr (&Scompare_window_configurations
);
7626 defsubr (&Swindow_list
);
7627 defsubr (&Swindow_list_1
);
7628 defsubr (&Swindow_prev_buffers
);
7629 defsubr (&Sset_window_prev_buffers
);
7630 defsubr (&Swindow_next_buffers
);
7631 defsubr (&Sset_window_next_buffers
);
7632 defsubr (&Swindow_parameters
);
7633 defsubr (&Swindow_parameter
);
7634 defsubr (&Sset_window_parameter
);
7638 keys_of_window (void)
7640 initial_define_key (control_x_map
, '1', "delete-other-windows");
7641 initial_define_key (control_x_map
, '2', "split-window");
7642 initial_define_key (control_x_map
, '0', "delete-window");
7643 initial_define_key (control_x_map
, 'o', "other-window");
7644 initial_define_key (control_x_map
, '^', "enlarge-window");
7645 initial_define_key (control_x_map
, '<', "scroll-left");
7646 initial_define_key (control_x_map
, '>', "scroll-right");
7648 initial_define_key (global_map
, Ctl ('V'), "scroll-up-command");
7649 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
7650 initial_define_key (meta_map
, 'v', "scroll-down-command");