1 /* Window creation, deletion and examination for GNU Emacs.
2 Does not include redisplay.
3 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
4 2001, 2002, 2003, 2004, 2005, 2006, 2007 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, or (at your option)
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; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
34 #include "dispextern.h"
35 #include "blockinput.h"
36 #include "intervals.h"
40 #endif /* HAVE_X_WINDOWS */
52 Lisp_Object Qwindowp
, Qwindow_live_p
, Qwindow_configuration_p
;
53 Lisp_Object Qscroll_up
, Qscroll_down
;
54 Lisp_Object Qwindow_size_fixed
;
55 extern Lisp_Object Qleft_margin
, Qright_margin
;
57 static int displayed_window_lines
P_ ((struct window
*));
58 static struct window
*decode_window
P_ ((Lisp_Object
));
59 static int count_windows
P_ ((struct window
*));
60 static int get_leaf_windows
P_ ((struct window
*, struct window
**, int));
61 static void window_scroll
P_ ((Lisp_Object
, int, int, int));
62 static void window_scroll_pixel_based
P_ ((Lisp_Object
, int, int, int));
63 static void window_scroll_line_based
P_ ((Lisp_Object
, int, int, int));
64 static int window_min_size_1
P_ ((struct window
*, int));
65 static int window_min_size_2
P_ ((struct window
*, int));
66 static int window_min_size
P_ ((struct window
*, int, int, int *));
67 static void size_window
P_ ((Lisp_Object
, int, int, int, int, int));
68 static int freeze_window_start
P_ ((struct window
*, void *));
69 static int window_fixed_size_p
P_ ((struct window
*, int, int));
70 static void enlarge_window
P_ ((Lisp_Object
, int, int));
71 static Lisp_Object window_list
P_ ((void));
72 static int add_window_to_list
P_ ((struct window
*, void *));
73 static int candidate_window_p
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
,
75 static Lisp_Object next_window
P_ ((Lisp_Object
, Lisp_Object
,
77 static void decode_next_window_args
P_ ((Lisp_Object
*, Lisp_Object
*,
79 static int foreach_window_1
P_ ((struct window
*,
80 int (* fn
) (struct window
*, void *),
82 static Lisp_Object window_list_1
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
));
84 /* This is the window in which the terminal's cursor should
85 be left when nothing is being done with it. This must
86 always be a leaf window, and its buffer is selected by
87 the top level editing loop at the end of each command.
89 This value is always the same as
90 FRAME_SELECTED_WINDOW (selected_frame). */
92 Lisp_Object selected_window
;
94 /* A list of all windows for use by next_window and Fwindow_list.
95 Functions creating or deleting windows should invalidate this cache
96 by setting it to nil. */
98 Lisp_Object Vwindow_list
;
100 /* The mini-buffer window of the selected frame.
101 Note that you cannot test for mini-bufferness of an arbitrary window
102 by comparing against this; but you can test for mini-bufferness of
103 the selected window. */
105 Lisp_Object minibuf_window
;
107 /* Non-nil means it is the window whose mode line should be
108 shown as the selected window when the minibuffer is selected. */
110 Lisp_Object minibuf_selected_window
;
112 /* Non-nil means it is the window for C-M-v to scroll
113 when the mini-buffer is selected. */
115 Lisp_Object Vminibuf_scroll_window
;
117 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
119 Lisp_Object Vother_window_scroll_buffer
;
121 /* Non-nil means it's function to call to display temp buffers. */
123 Lisp_Object Vtemp_buffer_show_function
;
125 /* Non-zero means line and page scrolling on tall lines (with images)
126 does partial scrolling by modifying window-vscroll. */
128 int auto_window_vscroll_p
;
130 /* Non-zero means to use mode-line-inactive face in all windows but the
131 selected-window and the minibuffer-scroll-window when the
132 minibuffer is active. */
133 int mode_line_in_non_selected_windows
;
135 /* If a window gets smaller than either of these, it is removed. */
137 EMACS_INT window_min_height
;
138 EMACS_INT window_min_width
;
140 /* Nonzero implies Fdisplay_buffer should create windows. */
144 /* Nonzero implies make new frames for Fdisplay_buffer. */
148 /* Nonzero means reuse existing frames for displaying buffers. */
150 int display_buffer_reuse_frames
;
152 /* Non-nil means use this function instead of default */
154 Lisp_Object Vpop_up_frame_function
;
156 /* Function to call to handle Fdisplay_buffer. */
158 Lisp_Object Vdisplay_buffer_function
;
160 /* Non-nil means that Fdisplay_buffer should even the heights of windows. */
162 Lisp_Object Veven_window_heights
;
164 /* List of buffer *names* for buffers that should have their own frames. */
166 Lisp_Object Vspecial_display_buffer_names
;
168 /* List of regexps for buffer names that should have their own frames. */
170 Lisp_Object Vspecial_display_regexps
;
172 /* Function to pop up a special frame. */
174 Lisp_Object Vspecial_display_function
;
176 /* List of buffer *names* for buffers to appear in selected window. */
178 Lisp_Object Vsame_window_buffer_names
;
180 /* List of regexps for buffer names to appear in selected window. */
182 Lisp_Object Vsame_window_regexps
;
184 /* Hook run at end of temp_output_buffer_show. */
186 Lisp_Object Qtemp_buffer_show_hook
;
188 /* Fdisplay_buffer always splits the largest window
189 if that window is more than this high. */
191 EMACS_INT split_height_threshold
;
193 /* Number of lines of continuity in scrolling by screenfuls. */
195 EMACS_INT next_screen_context_lines
;
197 /* Incremented for each window created. */
199 static int sequence_number
;
201 /* Nonzero after init_window_once has finished. */
203 static int window_initialized
;
205 /* Hook to run when window config changes. */
207 Lisp_Object Qwindow_configuration_change_hook
;
208 Lisp_Object Vwindow_configuration_change_hook
;
210 /* Non-nil means scroll commands try to put point
211 at the same screen height as previously. */
213 Lisp_Object Vscroll_preserve_screen_position
;
215 /* Incremented by 1 whenever a window is deleted. */
217 int window_deletion_count
;
219 /* Used by the function window_scroll_pixel_based */
221 static int window_scroll_pixel_based_preserve_y
;
223 #if 0 /* This isn't used anywhere. */
224 /* Nonzero means we can split a frame even if it is "unsplittable". */
225 static int inhibit_frame_unsplittable
;
228 extern EMACS_INT scroll_margin
;
230 extern Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
232 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
233 doc
: /* Returns t if OBJECT is a window. */)
237 return WINDOWP (object
) ? Qt
: Qnil
;
240 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
241 doc
: /* Returns t if OBJECT is a window which is currently visible. */)
245 return WINDOW_LIVE_P (object
) ? Qt
: Qnil
;
252 register struct window
*p
;
254 p
= allocate_window ();
256 XSETFASTINT (p
->sequence_number
, sequence_number
);
257 XSETFASTINT (p
->left_col
, 0);
258 XSETFASTINT (p
->top_line
, 0);
259 XSETFASTINT (p
->total_lines
, 0);
260 XSETFASTINT (p
->total_cols
, 0);
261 XSETFASTINT (p
->hscroll
, 0);
262 XSETFASTINT (p
->min_hscroll
, 0);
263 p
->orig_top_line
= p
->orig_total_lines
= Qnil
;
264 p
->start
= Fmake_marker ();
265 p
->pointm
= Fmake_marker ();
266 XSETFASTINT (p
->use_time
, 0);
268 p
->display_table
= Qnil
;
270 p
->pseudo_window_p
= 0;
271 bzero (&p
->cursor
, sizeof (p
->cursor
));
272 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
273 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
274 p
->desired_matrix
= p
->current_matrix
= 0;
275 p
->nrows_scale_factor
= p
->ncols_scale_factor
= 1;
276 p
->phys_cursor_type
= -1;
277 p
->phys_cursor_width
= -1;
278 p
->must_be_updated_p
= 0;
279 XSETFASTINT (p
->window_end_vpos
, 0);
280 XSETFASTINT (p
->window_end_pos
, 0);
281 p
->window_end_valid
= Qnil
;
284 XSETFASTINT (p
->last_point
, 0);
285 p
->frozen_window_start_p
= 0;
286 p
->last_cursor_off_p
= p
->cursor_off_p
= 0;
287 p
->left_margin_cols
= Qnil
;
288 p
->right_margin_cols
= Qnil
;
289 p
->left_fringe_width
= Qnil
;
290 p
->right_fringe_width
= Qnil
;
291 p
->fringes_outside_margins
= Qnil
;
292 p
->scroll_bar_width
= Qnil
;
293 p
->vertical_scroll_bar_type
= Qt
;
299 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
300 doc
: /* Return the window that the cursor now appears in and commands apply to. */)
303 return selected_window
;
306 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
307 doc
: /* Return the window used now for minibuffers.
308 If the optional argument FRAME is specified, return the minibuffer window
309 used by that frame. */)
314 frame
= selected_frame
;
315 CHECK_LIVE_FRAME (frame
);
316 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
319 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 0, 1, 0,
320 doc
: /* Returns non-nil if WINDOW is a minibuffer window.
321 WINDOW defaults to the selected window. */)
325 struct window
*w
= decode_window (window
);
326 return MINI_WINDOW_P (w
) ? Qt
: Qnil
;
330 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
331 Spos_visible_in_window_p
, 0, 3, 0,
332 doc
: /* Return non-nil if position POS is currently on the frame in WINDOW.
333 Return nil if that position is scrolled vertically out of view.
334 If a character is only partially visible, nil is returned, unless the
335 optional argument PARTIALLY is non-nil.
336 If POS is only out of view because of horizontal scrolling, return non-nil.
337 If POS is t, it specifies the position of the last visible glyph in WINDOW.
338 POS defaults to point in WINDOW; WINDOW defaults to the selected window.
340 If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
341 return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
342 where X and Y are the pixel coordinates relative to the top left corner
343 of the window. The remaining elements are omitted if the character after
344 POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
345 off-window at the top and bottom of the row, ROWH is the height of the
346 display row, and VPOS is the row number (0-based) containing POS. */)
347 (pos
, window
, partially
)
348 Lisp_Object pos
, window
, partially
;
350 register struct window
*w
;
352 register struct buffer
*buf
;
354 Lisp_Object in_window
= Qnil
;
355 int rtop
, rbot
, rowh
, vpos
, fully_p
= 1;
358 w
= decode_window (window
);
359 buf
= XBUFFER (w
->buffer
);
360 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
364 else if (!NILP (pos
))
366 CHECK_NUMBER_COERCE_MARKER (pos
);
369 else if (w
== XWINDOW (selected_window
))
372 posint
= XMARKER (w
->pointm
)->charpos
;
374 /* If position is above window start or outside buffer boundaries,
375 or if window start is out of range, position is not visible. */
377 || (posint
>= CHARPOS (top
) && posint
<= BUF_ZV (buf
)))
378 && CHARPOS (top
) >= BUF_BEGV (buf
)
379 && CHARPOS (top
) <= BUF_ZV (buf
)
380 && pos_visible_p (w
, posint
, &x
, &y
, &rtop
, &rbot
, &rowh
, &vpos
)
381 && (fully_p
= !rtop
&& !rbot
, (!NILP (partially
) || fully_p
)))
384 if (!NILP (in_window
) && !NILP (partially
))
386 Lisp_Object part
= Qnil
;
388 part
= list4 (make_number (rtop
), make_number (rbot
),
389 make_number (rowh
), make_number (vpos
));
390 in_window
= Fcons (make_number (x
),
391 Fcons (make_number (y
), part
));
397 DEFUN ("window-line-height", Fwindow_line_height
,
398 Swindow_line_height
, 0, 2, 0,
399 doc
: /* Return height in pixels of text line LINE in window WINDOW.
400 If WINDOW is nil or omitted, use selected window.
402 Return height of current line if LINE is omitted or nil. Return height of
403 header or mode line if LINE is `header-line' and `mode-line'.
404 Otherwise, LINE is a text line number starting from 0. A negative number
405 counts from the end of the window.
407 Value is a list (HEIGHT VPOS YPOS OFFBOT), where HEIGHT is the height
408 in pixels of the visible part of the line, VPOS and YPOS are the
409 vertical position in lines and pixels of the line, relative to the top
410 of the first text line, and OFFBOT is the number of off-window pixels at
411 the bottom of the text line. If there are off-window pixels at the top
412 of the (first) text line, YPOS is negative.
414 Return nil if window display is not up-to-date. In that case, use
415 `pos-visible-in-window-p' to obtain the information. */)
417 Lisp_Object line
, window
;
419 register struct window
*w
;
420 register struct buffer
*b
;
421 struct glyph_row
*row
, *end_row
;
422 int max_y
, crop
, i
, n
;
424 w
= decode_window (window
);
427 || w
->pseudo_window_p
)
430 CHECK_BUFFER (w
->buffer
);
431 b
= XBUFFER (w
->buffer
);
433 /* Fail if current matrix is not up-to-date. */
434 if (NILP (w
->window_end_valid
)
435 || current_buffer
->clip_changed
436 || current_buffer
->prevent_redisplay_optimizations_p
437 || XFASTINT (w
->last_modified
) < BUF_MODIFF (b
)
438 || XFASTINT (w
->last_overlay_modified
) < BUF_OVERLAY_MODIFF (b
))
444 if (i
< 0 || i
>= w
->current_matrix
->nrows
445 || (row
= MATRIX_ROW (w
->current_matrix
, i
), !row
->enabled_p
))
447 max_y
= window_text_bottom_y (w
);
451 if (EQ (line
, Qheader_line
))
453 if (!WINDOW_WANTS_HEADER_LINE_P (w
))
455 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
458 return list4 (make_number (row
->height
),
459 make_number (0), make_number (0),
463 if (EQ (line
, Qmode_line
))
465 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
468 return list4 (make_number (row
->height
),
469 make_number (0), /* not accurate */
470 make_number (WINDOW_HEADER_LINE_HEIGHT (w
)
471 + window_text_bottom_y (w
)),
478 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
479 end_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
480 max_y
= window_text_bottom_y (w
);
483 while ((n
< 0 || i
< n
)
484 && row
<= end_row
&& row
->enabled_p
485 && row
->y
+ row
->height
< max_y
)
488 if (row
> end_row
|| !row
->enabled_p
)
500 crop
= max (0, (row
->y
+ row
->height
) - max_y
);
501 return list4 (make_number (row
->height
+ min (0, row
->y
) - crop
),
503 make_number (row
->y
),
509 static struct window
*
510 decode_window (window
)
511 register Lisp_Object window
;
514 return XWINDOW (selected_window
);
516 CHECK_LIVE_WINDOW (window
);
517 return XWINDOW (window
);
520 static struct window
*
521 decode_any_window (window
)
522 register Lisp_Object window
;
525 return XWINDOW (selected_window
);
527 CHECK_WINDOW (window
);
528 return XWINDOW (window
);
531 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
532 doc
: /* Return the buffer that WINDOW is displaying.
533 WINDOW defaults to the selected window. */)
537 return decode_window (window
)->buffer
;
540 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
541 doc
: /* Return the number of lines in WINDOW (including its mode line).
542 WINDOW defaults to the selected window. */)
546 return decode_any_window (window
)->total_lines
;
549 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
550 doc
: /* Return the number of display columns in WINDOW.
551 This is the width that is usable columns available for text in WINDOW.
552 If you want to find out how many columns WINDOW takes up,
553 use (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))). */)
557 return make_number (window_box_text_cols (decode_any_window (window
)));
560 DEFUN ("window-full-width-p", Fwindow_full_width_p
, Swindow_full_width_p
, 0, 1, 0,
561 doc
: /* Return t if WINDOW is as wide as its frame.
562 WINDOW defaults to the selected window. */)
566 return WINDOW_FULL_WIDTH_P (decode_any_window (window
)) ? Qt
: Qnil
;
569 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
570 doc
: /* Return the number of columns by which WINDOW is scrolled from left margin.
571 WINDOW defaults to the selected window. */)
575 return decode_window (window
)->hscroll
;
578 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
579 doc
: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
580 Return NCOL. NCOL should be zero or positive.
582 Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
583 window so that the location of point moves off-window. */)
585 Lisp_Object window
, ncol
;
587 struct window
*w
= decode_window (window
);
591 hscroll
= max (0, XINT (ncol
));
593 /* Prevent redisplay shortcuts when changing the hscroll. */
594 if (XINT (w
->hscroll
) != hscroll
)
595 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
597 w
->hscroll
= make_number (hscroll
);
601 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
602 Swindow_redisplay_end_trigger
, 0, 1, 0,
603 doc
: /* Return WINDOW's redisplay end trigger value.
604 WINDOW defaults to the selected window.
605 See `set-window-redisplay-end-trigger' for more information. */)
609 return decode_window (window
)->redisplay_end_trigger
;
612 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
613 Sset_window_redisplay_end_trigger
, 2, 2, 0,
614 doc
: /* Set WINDOW's redisplay end trigger value to VALUE.
615 VALUE should be a buffer position (typically a marker) or nil.
616 If it is a buffer position, then if redisplay in WINDOW reaches a position
617 beyond VALUE, the functions in `redisplay-end-trigger-functions' are called
618 with two arguments: WINDOW, and the end trigger value.
619 Afterwards the end-trigger value is reset to nil. */)
621 register Lisp_Object window
, value
;
623 register struct window
*w
;
625 w
= decode_window (window
);
626 w
->redisplay_end_trigger
= value
;
630 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
631 doc
: /* Return a list of the edge coordinates of WINDOW.
632 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.
633 RIGHT is one more than the rightmost column occupied by WINDOW,
634 and BOTTOM is one more than the bottommost row occupied by WINDOW.
635 The edges include the space used by the window's scroll bar,
636 display margins, fringes, header line, and mode line, if it has them.
637 To get the edges of the actual text area, use `window-inside-edges'. */)
641 register struct window
*w
= decode_any_window (window
);
643 return Fcons (make_number (WINDOW_LEFT_EDGE_COL (w
)),
644 Fcons (make_number (WINDOW_TOP_EDGE_LINE (w
)),
645 Fcons (make_number (WINDOW_RIGHT_EDGE_COL (w
)),
646 Fcons (make_number (WINDOW_BOTTOM_EDGE_LINE (w
)),
650 DEFUN ("window-pixel-edges", Fwindow_pixel_edges
, Swindow_pixel_edges
, 0, 1, 0,
651 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
652 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.
653 RIGHT is one more than the rightmost x position occupied by WINDOW,
654 and BOTTOM is one more than the bottommost y position occupied by WINDOW.
655 The pixel edges include the space used by the window's scroll bar,
656 display margins, fringes, header line, and mode line, if it has them.
657 To get the edges of the actual text area, use `window-inside-pixel-edges'. */)
661 register struct window
*w
= decode_any_window (window
);
663 return Fcons (make_number (WINDOW_LEFT_EDGE_X (w
)),
664 Fcons (make_number (WINDOW_TOP_EDGE_Y (w
)),
665 Fcons (make_number (WINDOW_RIGHT_EDGE_X (w
)),
666 Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w
)),
670 DEFUN ("window-inside-edges", Fwindow_inside_edges
, Swindow_inside_edges
, 0, 1, 0,
671 doc
: /* Return a list of the edge coordinates of WINDOW.
672 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.
673 RIGHT is one more than the rightmost column used by text in WINDOW,
674 and BOTTOM is one more than the bottommost row used by text in WINDOW.
675 The inside edges do not include the space used by the window's scroll bar,
676 display margins, fringes, header line, and/or mode line. */)
680 register struct window
*w
= decode_any_window (window
);
682 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_COL (w
)
683 + WINDOW_LEFT_MARGIN_COLS (w
)
684 + WINDOW_LEFT_FRINGE_COLS (w
)),
685 make_number (WINDOW_TOP_EDGE_LINE (w
)
686 + WINDOW_HEADER_LINE_LINES (w
)),
687 make_number (WINDOW_BOX_RIGHT_EDGE_COL (w
)
688 - WINDOW_RIGHT_MARGIN_COLS (w
)
689 - WINDOW_RIGHT_FRINGE_COLS (w
)),
690 make_number (WINDOW_BOTTOM_EDGE_LINE (w
)
691 - WINDOW_MODE_LINE_LINES (w
)));
694 DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges
, Swindow_inside_pixel_edges
, 0, 1, 0,
695 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
696 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.
697 RIGHT is one more than the rightmost x position used by text in WINDOW,
698 and BOTTOM is one more than the bottommost y position used by text in WINDOW.
699 The inside edges do not include the space used by the window's scroll bar,
700 display margins, fringes, header line, and/or mode line. */)
704 register struct window
*w
= decode_any_window (window
);
706 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w
)
707 + WINDOW_LEFT_MARGIN_WIDTH (w
)
708 + WINDOW_LEFT_FRINGE_WIDTH (w
)),
709 make_number (WINDOW_TOP_EDGE_Y (w
)
710 + WINDOW_HEADER_LINE_HEIGHT (w
)),
711 make_number (WINDOW_BOX_RIGHT_EDGE_X (w
)
712 - WINDOW_RIGHT_MARGIN_WIDTH (w
)
713 - WINDOW_RIGHT_FRINGE_WIDTH (w
)),
714 make_number (WINDOW_BOTTOM_EDGE_Y (w
)
715 - WINDOW_MODE_LINE_HEIGHT (w
)));
718 /* Test if the character at column *X, row *Y is within window W.
719 If it is not, return ON_NOTHING;
720 if it is in the window's text area,
721 set *x and *y to its location relative to the upper left corner
724 if it is on the window's modeline, return ON_MODE_LINE;
725 if it is on the border between the window and its right sibling,
726 return ON_VERTICAL_BORDER.
727 if it is on a scroll bar,
728 return ON_SCROLL_BAR.
729 if it is on the window's top line, return ON_HEADER_LINE;
730 if it is in left or right fringe of the window,
731 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE, and convert *X and *Y
732 to window-relative coordinates;
733 if it is in the marginal area to the left/right of the window,
734 return ON_LEFT_MARGIN or ON_RIGHT_MARGIN, and convert *X and *Y
735 to window-relative coordinates.
737 X and Y are frame relative pixel coordinates. */
739 static enum window_part
740 coordinates_in_window (w
, x
, y
)
741 register struct window
*w
;
744 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
745 int left_x
, right_x
, top_y
, bottom_y
;
746 enum window_part part
;
747 int ux
= FRAME_COLUMN_WIDTH (f
);
748 int x0
= WINDOW_LEFT_EDGE_X (w
);
749 int x1
= WINDOW_RIGHT_EDGE_X (w
);
750 /* The width of the area where the vertical line can be dragged.
751 (Between mode lines for instance. */
752 int grabbable_width
= ux
;
753 int lmargin_width
, rmargin_width
, text_left
, text_right
;
755 /* In what's below, we subtract 1 when computing right_x because we
756 want the rightmost pixel, which is given by left_pixel+width-1. */
757 if (w
->pseudo_window_p
)
760 right_x
= WINDOW_TOTAL_WIDTH (w
) - 1;
761 top_y
= WINDOW_TOP_EDGE_Y (w
);
762 bottom_y
= WINDOW_BOTTOM_EDGE_Y (w
);
766 left_x
= WINDOW_BOX_LEFT_EDGE_X (w
);
767 right_x
= WINDOW_BOX_RIGHT_EDGE_X (w
) - 1;
768 top_y
= WINDOW_TOP_EDGE_Y (w
);
769 bottom_y
= WINDOW_BOTTOM_EDGE_Y (w
);
772 /* Outside any interesting row? */
773 if (*y
< top_y
|| *y
>= bottom_y
)
776 /* On the mode line or header line? If it's near the start of
777 the mode or header line of window that's has a horizontal
778 sibling, say it's on the vertical line. That's to be able
779 to resize windows horizontally in case we're using toolkit
782 if (WINDOW_WANTS_MODELINE_P (w
)
783 && *y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
))
787 header_vertical_border_check
:
788 /* We're somewhere on the mode line. We consider the place
789 between mode lines of horizontally adjacent mode lines
790 as the vertical border. If scroll bars on the left,
791 return the right window. */
792 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
793 || WINDOW_RIGHTMOST_P (w
))
795 if (!WINDOW_LEFTMOST_P (w
) && abs (*x
- x0
) < grabbable_width
)
797 /* Convert X and Y to window relative coordinates.
798 Vertical border is at the left edge of window. */
799 *x
= max (0, *x
- x0
);
801 return ON_VERTICAL_BORDER
;
806 if (abs (*x
- x1
) < grabbable_width
)
808 /* Convert X and Y to window relative coordinates.
809 Vertical border is at the right edge of window. */
810 *x
= min (x1
, *x
) - x0
;
812 return ON_VERTICAL_BORDER
;
816 if (*x
< x0
|| *x
>= x1
)
819 /* Convert X and Y to window relative coordinates.
820 Mode line starts at left edge of window. */
826 if (WINDOW_WANTS_HEADER_LINE_P (w
)
827 && *y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
))
829 part
= ON_HEADER_LINE
;
830 goto header_vertical_border_check
;
833 if (*x
< x0
|| *x
>= x1
)
836 /* Outside any interesting column? */
837 if (*x
< left_x
|| *x
> right_x
)
840 return ON_SCROLL_BAR
;
843 lmargin_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
844 rmargin_width
= window_box_width (w
, RIGHT_MARGIN_AREA
);
846 text_left
= window_box_left (w
, TEXT_AREA
);
847 text_right
= text_left
+ window_box_width (w
, TEXT_AREA
);
849 if (FRAME_WINDOW_P (f
))
851 if (!w
->pseudo_window_p
852 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
)
853 && !WINDOW_RIGHTMOST_P (w
)
854 && (abs (*x
- right_x
) < grabbable_width
))
856 /* Convert X and Y to window relative coordinates.
857 Vertical border is at the right edge of window. */
858 *x
= min (right_x
, *x
) - left_x
;
860 return ON_VERTICAL_BORDER
;
865 /* Need to say "*x > right_x" rather than >=, since on character
866 terminals, the vertical line's x coordinate is right_x. */
867 if (!w
->pseudo_window_p
868 && !WINDOW_RIGHTMOST_P (w
)
869 && *x
> right_x
- ux
)
871 /* On the border on the right side of the window? Assume that
872 this area begins at RIGHT_X minus a canonical char width. */
873 *x
= min (right_x
, *x
) - left_x
;
875 return ON_VERTICAL_BORDER
;
881 if (lmargin_width
> 0
882 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
883 ? (*x
>= left_x
+ WINDOW_LEFT_FRINGE_WIDTH (w
))
884 : (*x
< left_x
+ lmargin_width
)))
887 if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
888 *x
-= WINDOW_LEFT_FRINGE_WIDTH (w
);
890 return ON_LEFT_MARGIN
;
893 /* Convert X and Y to window-relative pixel coordinates. */
896 return ON_LEFT_FRINGE
;
899 if (*x
>= text_right
)
901 if (rmargin_width
> 0
902 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
903 ? (*x
< right_x
- WINDOW_RIGHT_FRINGE_WIDTH (w
))
904 : (*x
>= right_x
- rmargin_width
)))
906 *x
-= right_x
- rmargin_width
;
907 if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
908 *x
+= WINDOW_RIGHT_FRINGE_WIDTH (w
);
910 return ON_RIGHT_MARGIN
;
913 /* Convert X and Y to window-relative pixel coordinates. */
914 *x
-= left_x
+ WINDOW_LEFT_FRINGE_WIDTH (w
);
916 return ON_RIGHT_FRINGE
;
919 /* Everything special ruled out - must be on text area */
926 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
927 Scoordinates_in_window_p
, 2, 2, 0,
928 doc
: /* Return non-nil if COORDINATES are in WINDOW.
929 COORDINATES is a cons of the form (X . Y), X and Y being distances
930 measured in characters from the upper-left corner of the frame.
931 \(0 . 0) denotes the character in the upper left corner of the
933 If COORDINATES are in the text portion of WINDOW,
934 the coordinates relative to the window are returned.
935 If they are in the mode line of WINDOW, `mode-line' is returned.
936 If they are in the top mode line of WINDOW, `header-line' is returned.
937 If they are in the left fringe of WINDOW, `left-fringe' is returned.
938 If they are in the right fringe of WINDOW, `right-fringe' is returned.
939 If they are on the border between WINDOW and its right sibling,
940 `vertical-line' is returned.
941 If they are in the windows's left or right marginal areas, `left-margin'\n\
942 or `right-margin' is returned. */)
943 (coordinates
, window
)
944 register Lisp_Object coordinates
, window
;
951 CHECK_WINDOW (window
);
952 w
= XWINDOW (window
);
953 f
= XFRAME (w
->frame
);
954 CHECK_CONS (coordinates
);
955 lx
= Fcar (coordinates
);
956 ly
= Fcdr (coordinates
);
957 CHECK_NUMBER_OR_FLOAT (lx
);
958 CHECK_NUMBER_OR_FLOAT (ly
);
959 x
= FRAME_PIXEL_X_FROM_CANON_X (f
, lx
) + FRAME_INTERNAL_BORDER_WIDTH (f
);
960 y
= FRAME_PIXEL_Y_FROM_CANON_Y (f
, ly
) + FRAME_INTERNAL_BORDER_WIDTH (f
);
962 switch (coordinates_in_window (w
, &x
, &y
))
968 /* X and Y are now window relative pixel coordinates. Convert
969 them to canonical char units before returning them. */
970 return Fcons (FRAME_CANON_X_FROM_PIXEL_X (f
, x
),
971 FRAME_CANON_Y_FROM_PIXEL_Y (f
, y
));
976 case ON_VERTICAL_BORDER
:
977 return Qvertical_line
;
985 case ON_RIGHT_FRINGE
:
986 return Qright_fringe
;
991 case ON_RIGHT_MARGIN
:
992 return Qright_margin
;
995 /* Historically we are supposed to return nil in this case. */
1004 /* Callback for foreach_window, used in window_from_coordinates.
1005 Check if window W contains coordinates specified by USER_DATA which
1006 is actually a pointer to a struct check_window_data CW.
1008 Check if window W contains coordinates *CW->x and *CW->y. If it
1009 does, return W in *CW->window, as Lisp_Object, and return in
1010 *CW->part the part of the window under coordinates *X,*Y. Return
1011 zero from this function to stop iterating over windows. */
1013 struct check_window_data
1015 Lisp_Object
*window
;
1017 enum window_part
*part
;
1021 check_window_containing (w
, user_data
)
1025 struct check_window_data
*cw
= (struct check_window_data
*) user_data
;
1026 enum window_part found
;
1029 found
= coordinates_in_window (w
, cw
->x
, cw
->y
);
1030 if (found
!= ON_NOTHING
)
1033 XSETWINDOW (*cw
->window
, w
);
1041 /* Find the window containing frame-relative pixel position X/Y and
1042 return it as a Lisp_Object.
1044 If X, Y is on one of the window's special `window_part' elements,
1045 set *PART to the id of that element, and return X and Y converted
1046 to window relative coordinates in WX and WY.
1048 If there is no window under X, Y return nil and leave *PART
1049 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows.
1051 This function was previously implemented with a loop cycling over
1052 windows with Fnext_window, and starting with the frame's selected
1053 window. It turned out that this doesn't work with an
1054 implementation of next_window using Vwindow_list, because
1055 FRAME_SELECTED_WINDOW (F) is not always contained in the window
1056 tree of F when this function is called asynchronously from
1057 note_mouse_highlight. The original loop didn't terminate in this
1061 window_from_coordinates (f
, x
, y
, part
, wx
, wy
, tool_bar_p
)
1064 enum window_part
*part
;
1069 struct check_window_data cw
;
1070 enum window_part dummy
;
1076 cw
.window
= &window
, cw
.x
= &x
, cw
.y
= &y
; cw
.part
= part
;
1077 foreach_window (f
, check_window_containing
, &cw
);
1079 /* If not found above, see if it's in the tool bar window, if a tool
1083 && WINDOWP (f
->tool_bar_window
)
1084 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0
1085 && (coordinates_in_window (XWINDOW (f
->tool_bar_window
), &x
, &y
)
1089 window
= f
->tool_bar_window
;
1098 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
1099 doc
: /* Return window containing coordinates X and Y on FRAME.
1100 If omitted, FRAME defaults to the currently selected frame.
1101 The top left corner of the frame is considered to be row 0,
1104 Lisp_Object x
, y
, frame
;
1109 frame
= selected_frame
;
1110 CHECK_LIVE_FRAME (frame
);
1113 /* Check that arguments are integers or floats. */
1114 CHECK_NUMBER_OR_FLOAT (x
);
1115 CHECK_NUMBER_OR_FLOAT (y
);
1117 return window_from_coordinates (f
,
1118 (FRAME_PIXEL_X_FROM_CANON_X (f
, x
)
1119 + FRAME_INTERNAL_BORDER_WIDTH (f
)),
1120 (FRAME_PIXEL_Y_FROM_CANON_Y (f
, y
)
1121 + FRAME_INTERNAL_BORDER_WIDTH (f
)),
1125 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
1126 doc
: /* Return current value of point in WINDOW.
1127 WINDOW defaults to the selected window.
1129 For a nonselected window, this is the value point would have
1130 if that window were selected.
1132 Note that, when WINDOW is the selected window and its buffer
1133 is also currently selected, the value returned is the same as (point).
1134 It would be more strictly correct to return the `top-level' value
1135 of point, outside of any save-excursion forms.
1136 But that is hard to define. */)
1140 register struct window
*w
= decode_window (window
);
1142 if (w
== XWINDOW (selected_window
)
1143 && current_buffer
== XBUFFER (w
->buffer
))
1145 return Fmarker_position (w
->pointm
);
1148 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
1149 doc
: /* Return position at which display currently starts in WINDOW.
1150 WINDOW defaults to the selected window.
1151 This is updated by redisplay or by calling `set-window-start'. */)
1155 return Fmarker_position (decode_window (window
)->start
);
1158 /* This is text temporarily removed from the doc string below.
1160 This function returns nil if the position is not currently known.
1161 That happens when redisplay is preempted and doesn't finish.
1162 If in that case you want to compute where the end of the window would
1163 have been if redisplay had finished, do this:
1165 (goto-char (window-start window))
1166 (vertical-motion (1- (window-height window)) window)
1169 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
1170 doc
: /* Return position at which display currently ends in WINDOW.
1171 WINDOW defaults to the selected window.
1172 This is updated by redisplay, when it runs to completion.
1173 Simply changing the buffer text or setting `window-start'
1174 does not update this value.
1175 Return nil if there is no recorded value. \(This can happen if the
1176 last redisplay of WINDOW was preempted, and did not finish.)
1177 If UPDATE is non-nil, compute the up-to-date position
1178 if it isn't already recorded. */)
1180 Lisp_Object window
, update
;
1183 struct window
*w
= decode_window (window
);
1191 #if 0 /* This change broke some things. We should make it later. */
1192 /* If we don't know the end position, return nil.
1193 The user can compute it with vertical-motion if he wants to.
1194 It would be nicer to do it automatically,
1195 but that's so slow that it would probably bother people. */
1196 if (NILP (w
->window_end_valid
))
1201 && ! (! NILP (w
->window_end_valid
)
1202 && XFASTINT (w
->last_modified
) >= BUF_MODIFF (b
)
1203 && XFASTINT (w
->last_overlay_modified
) >= BUF_OVERLAY_MODIFF (b
))
1206 struct text_pos startp
;
1208 struct buffer
*old_buffer
= NULL
;
1210 /* Cannot use Fvertical_motion because that function doesn't
1211 cope with variable-height lines. */
1212 if (b
!= current_buffer
)
1214 old_buffer
= current_buffer
;
1215 set_buffer_internal (b
);
1218 /* In case W->start is out of the range, use something
1219 reasonable. This situation occurred when loading a file with
1220 `-l' containing a call to `rmail' with subsequent other
1221 commands. At the end, W->start happened to be BEG, while
1222 rmail had already narrowed the buffer. */
1223 if (XMARKER (w
->start
)->charpos
< BEGV
)
1224 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
1225 else if (XMARKER (w
->start
)->charpos
> ZV
)
1226 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
1228 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
1230 start_display (&it
, w
, startp
);
1231 move_it_vertically (&it
, window_box_height (w
));
1232 if (it
.current_y
< it
.last_visible_y
)
1233 move_it_past_eol (&it
);
1234 value
= make_number (IT_CHARPOS (it
));
1237 set_buffer_internal (old_buffer
);
1240 XSETINT (value
, BUF_Z (b
) - XFASTINT (w
->window_end_pos
));
1245 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
1246 doc
: /* Make point value in WINDOW be at position POS in WINDOW's buffer.
1249 Lisp_Object window
, pos
;
1251 register struct window
*w
= decode_window (window
);
1253 CHECK_NUMBER_COERCE_MARKER (pos
);
1254 if (w
== XWINDOW (selected_window
)
1255 && XBUFFER (w
->buffer
) == current_buffer
)
1258 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
1260 /* We have to make sure that redisplay updates the window to show
1261 the new value of point. */
1262 if (!EQ (window
, selected_window
))
1263 ++windows_or_buffers_changed
;
1268 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
1269 doc
: /* Make display in WINDOW start at position POS in WINDOW's buffer.
1271 Optional third arg NOFORCE non-nil inhibits next redisplay
1272 from overriding motion of point in order to display at this exact start. */)
1273 (window
, pos
, noforce
)
1274 Lisp_Object window
, pos
, noforce
;
1276 register struct window
*w
= decode_window (window
);
1278 CHECK_NUMBER_COERCE_MARKER (pos
);
1279 set_marker_restricted (w
->start
, pos
, w
->buffer
);
1280 /* this is not right, but much easier than doing what is right. */
1281 w
->start_at_line_beg
= Qnil
;
1283 w
->force_start
= Qt
;
1284 w
->update_mode_line
= Qt
;
1285 XSETFASTINT (w
->last_modified
, 0);
1286 XSETFASTINT (w
->last_overlay_modified
, 0);
1287 if (!EQ (window
, selected_window
))
1288 windows_or_buffers_changed
++;
1293 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
1295 doc
: /* Return WINDOW's dedicated object, usually t or nil.
1296 See also `set-window-dedicated-p'. */)
1300 return decode_window (window
)->dedicated
;
1303 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
1304 Sset_window_dedicated_p
, 2, 2, 0,
1305 doc
: /* Control whether WINDOW is dedicated to the buffer it displays.
1306 If it is dedicated, Emacs will not automatically change
1307 which buffer appears in it.
1308 The second argument is the new value for the dedication flag;
1309 non-nil means yes. */)
1311 Lisp_Object window
, arg
;
1313 register struct window
*w
= decode_window (window
);
1317 return w
->dedicated
;
1320 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
1322 doc
: /* Return the display-table that WINDOW is using.
1323 WINDOW defaults to the selected window. */)
1327 return decode_window (window
)->display_table
;
1330 /* Get the display table for use on window W. This is either W's
1331 display table or W's buffer's display table. Ignore the specified
1332 tables if they are not valid; if no valid table is specified,
1335 struct Lisp_Char_Table
*
1336 window_display_table (w
)
1339 struct Lisp_Char_Table
*dp
= NULL
;
1341 if (DISP_TABLE_P (w
->display_table
))
1342 dp
= XCHAR_TABLE (w
->display_table
);
1343 else if (BUFFERP (w
->buffer
))
1345 struct buffer
*b
= XBUFFER (w
->buffer
);
1347 if (DISP_TABLE_P (b
->display_table
))
1348 dp
= XCHAR_TABLE (b
->display_table
);
1349 else if (DISP_TABLE_P (Vstandard_display_table
))
1350 dp
= XCHAR_TABLE (Vstandard_display_table
);
1356 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
1357 doc
: /* Set WINDOW's display-table to TABLE. */)
1359 register Lisp_Object window
, table
;
1361 register struct window
*w
;
1363 w
= decode_window (window
);
1364 w
->display_table
= table
;
1368 /* Record info on buffer window w is displaying
1369 when it is about to cease to display that buffer. */
1372 register struct window
*w
;
1379 if (b
!= XMARKER (w
->pointm
)->buffer
)
1383 if (w
== XWINDOW (selected_window
)
1384 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
1385 /* Do this except when the selected window's buffer
1386 is being removed from some other window. */
1388 /* last_window_start records the start position that this buffer
1389 had in the last window to be disconnected from it.
1390 Now that this statement is unconditional,
1391 it is possible for the buffer to be displayed in the
1392 selected window, while last_window_start reflects another
1393 window which was recently showing the same buffer.
1394 Some people might say that might be a good thing. Let's see. */
1395 b
->last_window_start
= marker_position (w
->start
);
1397 /* Point in the selected window's buffer
1398 is actually stored in that buffer, and the window's pointm isn't used.
1399 So don't clobber point in that buffer. */
1400 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
)
1401 /* This line helps to fix Horsley's testbug.el bug. */
1402 && !(WINDOWP (b
->last_selected_window
)
1403 && w
!= XWINDOW (b
->last_selected_window
)
1404 && EQ (buf
, XWINDOW (b
->last_selected_window
)->buffer
)))
1405 temp_set_point_both (b
,
1406 clip_to_bounds (BUF_BEGV (b
),
1407 XMARKER (w
->pointm
)->charpos
,
1409 clip_to_bounds (BUF_BEGV_BYTE (b
),
1410 marker_byte_position (w
->pointm
),
1413 if (WINDOWP (b
->last_selected_window
)
1414 && w
== XWINDOW (b
->last_selected_window
))
1415 b
->last_selected_window
= Qnil
;
1418 /* Put replacement into the window structure in place of old. */
1420 replace_window (old
, replacement
)
1421 Lisp_Object old
, replacement
;
1423 register Lisp_Object tem
;
1424 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
1426 /* If OLD is its frame's root_window, then replacement is the new
1427 root_window for that frame. */
1429 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
1430 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
1432 p
->left_col
= o
->left_col
;
1433 p
->top_line
= o
->top_line
;
1434 p
->total_cols
= o
->total_cols
;
1435 p
->total_lines
= o
->total_lines
;
1436 p
->desired_matrix
= p
->current_matrix
= 0;
1438 bzero (&p
->cursor
, sizeof (p
->cursor
));
1439 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
1440 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
1441 p
->phys_cursor_type
= -1;
1442 p
->phys_cursor_width
= -1;
1443 p
->must_be_updated_p
= 0;
1444 p
->pseudo_window_p
= 0;
1445 XSETFASTINT (p
->window_end_vpos
, 0);
1446 XSETFASTINT (p
->window_end_pos
, 0);
1447 p
->window_end_valid
= Qnil
;
1448 p
->frozen_window_start_p
= 0;
1449 p
->orig_top_line
= p
->orig_total_lines
= Qnil
;
1451 p
->next
= tem
= o
->next
;
1453 XWINDOW (tem
)->prev
= replacement
;
1455 p
->prev
= tem
= o
->prev
;
1457 XWINDOW (tem
)->next
= replacement
;
1459 p
->parent
= tem
= o
->parent
;
1462 if (EQ (XWINDOW (tem
)->vchild
, old
))
1463 XWINDOW (tem
)->vchild
= replacement
;
1464 if (EQ (XWINDOW (tem
)->hchild
, old
))
1465 XWINDOW (tem
)->hchild
= replacement
;
1468 /*** Here, if replacement is a vertical combination
1469 and so is its new parent, we should make replacement's
1470 children be children of that parent instead. ***/
1473 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
1474 doc
: /* Remove WINDOW from the display. Default is selected window. */)
1476 register Lisp_Object window
;
1478 delete_window (window
);
1480 if (! NILP (Vwindow_configuration_change_hook
)
1481 && ! NILP (Vrun_hooks
))
1482 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
1488 delete_window (window
)
1489 register Lisp_Object window
;
1491 register Lisp_Object tem
, parent
, sib
;
1492 register struct window
*p
;
1493 register struct window
*par
;
1496 /* Because this function is called by other C code on non-leaf
1497 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1498 so we can't decode_window here. */
1500 window
= selected_window
;
1502 CHECK_WINDOW (window
);
1503 p
= XWINDOW (window
);
1505 /* It's a no-op to delete an already-deleted window. */
1506 if (NILP (p
->buffer
)
1508 && NILP (p
->vchild
))
1513 error ("Attempt to delete minibuffer or sole ordinary window");
1514 par
= XWINDOW (parent
);
1516 windows_or_buffers_changed
++;
1517 Vwindow_list
= Qnil
;
1518 f
= XFRAME (WINDOW_FRAME (p
));
1519 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
1521 /* Are we trying to delete any frame's selected window? */
1523 Lisp_Object swindow
, pwindow
;
1525 /* See if the frame's selected window is either WINDOW
1526 or any subwindow of it, by finding all that window's parents
1527 and comparing each one with WINDOW. */
1528 swindow
= FRAME_SELECTED_WINDOW (f
);
1533 while (!NILP (pwindow
))
1535 if (EQ (window
, pwindow
))
1537 pwindow
= XWINDOW (pwindow
)->parent
;
1540 /* If the window being deleted is not a parent of SWINDOW,
1541 then SWINDOW is ok as the new selected window. */
1542 if (!EQ (window
, pwindow
))
1544 /* Otherwise, try another window for SWINDOW. */
1545 swindow
= Fnext_window (swindow
, Qlambda
, Qnil
);
1547 /* If we get back to the frame's selected window,
1548 it means there was no acceptable alternative,
1549 so we cannot delete. */
1550 if (EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
1551 error ("Cannot delete window");
1554 /* If we need to change SWINDOW, do it. */
1555 if (! EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
1557 /* If we're about to delete the selected window on the
1558 selected frame, then we should use Fselect_window to select
1559 the new window. On the other hand, if we're about to
1560 delete the selected window on any other frame, we shouldn't do
1561 anything but set the frame's selected_window slot. */
1562 if (EQ (FRAME_SELECTED_WINDOW (f
), selected_window
))
1563 Fselect_window (swindow
, Qnil
);
1565 FRAME_SELECTED_WINDOW (f
) = swindow
;
1569 /* Now we know we can delete this one. */
1570 window_deletion_count
++;
1573 /* tem is null for dummy parent windows
1574 (which have inferiors but not any contents themselves) */
1578 unchain_marker (XMARKER (p
->pointm
));
1579 unchain_marker (XMARKER (p
->start
));
1582 /* Free window glyph matrices. It is sure that they are allocated
1583 again when ADJUST_GLYPHS is called. Block input so that expose
1584 events and other events that access glyph matrices are not
1585 processed while we are changing them. */
1587 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f
)));
1591 XWINDOW (tem
)->prev
= p
->prev
;
1595 XWINDOW (tem
)->next
= p
->next
;
1597 if (EQ (window
, par
->hchild
))
1598 par
->hchild
= p
->next
;
1599 if (EQ (window
, par
->vchild
))
1600 par
->vchild
= p
->next
;
1602 /* Find one of our siblings to give our space to. */
1606 /* If p gives its space to its next sibling, that sibling needs
1607 to have its top/left side pulled back to where p's is.
1608 set_window_{height,width} will re-position the sibling's
1611 XWINDOW (sib
)->top_line
= p
->top_line
;
1612 XWINDOW (sib
)->left_col
= p
->left_col
;
1615 /* Stretch that sibling. */
1616 if (!NILP (par
->vchild
))
1617 set_window_height (sib
,
1618 XFASTINT (XWINDOW (sib
)->total_lines
) + XFASTINT (p
->total_lines
),
1620 if (!NILP (par
->hchild
))
1621 set_window_width (sib
,
1622 XFASTINT (XWINDOW (sib
)->total_cols
) + XFASTINT (p
->total_cols
),
1625 /* If parent now has only one child,
1626 put the child into the parent's place. */
1630 if (NILP (XWINDOW (tem
)->next
)) {
1631 replace_window (parent
, tem
);
1632 par
= XWINDOW (tem
);
1635 /* Since we may be deleting combination windows, we must make sure that
1636 not only p but all its children have been marked as deleted. */
1637 if (! NILP (p
->hchild
))
1638 delete_all_subwindows (XWINDOW (p
->hchild
));
1639 else if (! NILP (p
->vchild
))
1640 delete_all_subwindows (XWINDOW (p
->vchild
));
1642 /* Mark this window as deleted. */
1643 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
1645 if (! NILP (par
->parent
))
1646 par
= XWINDOW (par
->parent
);
1648 /* Check if we have a v/hchild with a v/hchild. In that case remove
1651 if (! NILP (par
->vchild
) && ! NILP (XWINDOW (par
->vchild
)->vchild
))
1653 p
= XWINDOW (par
->vchild
);
1654 par
->vchild
= p
->vchild
;
1657 else if (! NILP (par
->hchild
) && ! NILP (XWINDOW (par
->hchild
)->hchild
))
1659 p
= XWINDOW (par
->hchild
);
1660 par
->hchild
= p
->hchild
;
1668 while (! NILP (tem
)) {
1669 XWINDOW (tem
)->parent
= p
->parent
;
1670 if (NILP (XWINDOW (tem
)->next
))
1672 tem
= XWINDOW (tem
)->next
;
1675 /* The next of the v/hchild we are removing is now the next of the
1676 last child for the v/hchild:
1677 Before v/hchild -> v/hchild -> next1 -> next2
1680 After: v/hchild -> next1 -> next2 -> next3
1682 XWINDOW (tem
)->next
= p
->next
;
1683 if (! NILP (p
->next
))
1684 XWINDOW (p
->next
)->prev
= tem
;
1686 p
->next
= p
->prev
= p
->vchild
= p
->hchild
= p
->buffer
= Qnil
;
1690 /* Adjust glyph matrices. */
1697 /***********************************************************************
1699 ***********************************************************************/
1701 /* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object
1702 pointer. This is a callback function for foreach_window, used in
1703 function window_list. */
1706 add_window_to_list (w
, user_data
)
1710 Lisp_Object
*list
= (Lisp_Object
*) user_data
;
1712 XSETWINDOW (window
, w
);
1713 *list
= Fcons (window
, *list
);
1718 /* Return a list of all windows, for use by next_window. If
1719 Vwindow_list is a list, return that list. Otherwise, build a new
1720 list, cache it in Vwindow_list, and return that. */
1725 if (!CONSP (Vwindow_list
))
1729 Vwindow_list
= Qnil
;
1730 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
1732 Lisp_Object args
[2];
1734 /* We are visiting windows in canonical order, and add
1735 new windows at the front of args[1], which means we
1736 have to reverse this list at the end. */
1738 foreach_window (XFRAME (XCAR (tail
)), add_window_to_list
, &args
[1]);
1739 args
[0] = Vwindow_list
;
1740 args
[1] = Fnreverse (args
[1]);
1741 Vwindow_list
= Fnconc (2, args
);
1745 return Vwindow_list
;
1749 /* Value is non-zero if WINDOW satisfies the constraints given by
1750 OWINDOW, MINIBUF and ALL_FRAMES.
1752 MINIBUF t means WINDOW may be minibuffer windows.
1753 `lambda' means WINDOW may not be a minibuffer window.
1754 a window means a specific minibuffer window
1756 ALL_FRAMES t means search all frames,
1757 nil means search just current frame,
1758 `visible' means search just visible frames,
1759 0 means search visible and iconified frames,
1760 a window means search the frame that window belongs to,
1761 a frame means consider windows on that frame, only. */
1764 candidate_window_p (window
, owindow
, minibuf
, all_frames
)
1765 Lisp_Object window
, owindow
, minibuf
, all_frames
;
1767 struct window
*w
= XWINDOW (window
);
1768 struct frame
*f
= XFRAME (w
->frame
);
1769 int candidate_p
= 1;
1771 if (!BUFFERP (w
->buffer
))
1773 else if (MINI_WINDOW_P (w
)
1774 && (EQ (minibuf
, Qlambda
)
1775 || (WINDOWP (minibuf
) && !EQ (minibuf
, window
))))
1777 /* If MINIBUF is `lambda' don't consider any mini-windows.
1778 If it is a window, consider only that one. */
1781 else if (EQ (all_frames
, Qt
))
1783 else if (NILP (all_frames
))
1785 xassert (WINDOWP (owindow
));
1786 candidate_p
= EQ (w
->frame
, XWINDOW (owindow
)->frame
);
1788 else if (EQ (all_frames
, Qvisible
))
1790 FRAME_SAMPLE_VISIBILITY (f
);
1791 candidate_p
= FRAME_VISIBLE_P (f
);
1793 else if (INTEGERP (all_frames
) && XINT (all_frames
) == 0)
1795 FRAME_SAMPLE_VISIBILITY (f
);
1796 candidate_p
= FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
);
1798 else if (WINDOWP (all_frames
))
1799 candidate_p
= (EQ (FRAME_MINIBUF_WINDOW (f
), all_frames
)
1800 || EQ (XWINDOW (all_frames
)->frame
, w
->frame
)
1801 || EQ (XWINDOW (all_frames
)->frame
, FRAME_FOCUS_FRAME (f
)));
1802 else if (FRAMEP (all_frames
))
1803 candidate_p
= EQ (all_frames
, w
->frame
);
1809 /* Decode arguments as allowed by Fnext_window, Fprevious_window, and
1810 Fwindow_list. See there for the meaning of WINDOW, MINIBUF, and
1814 decode_next_window_args (window
, minibuf
, all_frames
)
1815 Lisp_Object
*window
, *minibuf
, *all_frames
;
1818 *window
= selected_window
;
1820 CHECK_LIVE_WINDOW (*window
);
1822 /* MINIBUF nil may or may not include minibuffers. Decide if it
1824 if (NILP (*minibuf
))
1825 *minibuf
= minibuf_level
? minibuf_window
: Qlambda
;
1826 else if (!EQ (*minibuf
, Qt
))
1829 /* Now *MINIBUF can be t => count all minibuffer windows, `lambda'
1830 => count none of them, or a specific minibuffer window (the
1831 active one) to count. */
1833 /* ALL_FRAMES nil doesn't specify which frames to include. */
1834 if (NILP (*all_frames
))
1835 *all_frames
= (!EQ (*minibuf
, Qlambda
)
1836 ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window
)->frame
))
1838 else if (EQ (*all_frames
, Qvisible
))
1840 else if (EQ (*all_frames
, make_number (0)))
1842 else if (FRAMEP (*all_frames
))
1844 else if (!EQ (*all_frames
, Qt
))
1847 /* Now *ALL_FRAMES is t meaning search all frames, nil meaning
1848 search just current frame, `visible' meaning search just visible
1849 frames, 0 meaning search visible and iconified frames, or a
1850 window, meaning search the frame that window belongs to, or a
1851 frame, meaning consider windows on that frame, only. */
1855 /* Return the next or previous window of WINDOW in canonical ordering
1856 of windows. NEXT_P non-zero means return the next window. See the
1857 documentation string of next-window for the meaning of MINIBUF and
1861 next_window (window
, minibuf
, all_frames
, next_p
)
1862 Lisp_Object window
, minibuf
, all_frames
;
1865 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1867 /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just
1868 return the first window on the frame. */
1869 if (FRAMEP (all_frames
)
1870 && !EQ (all_frames
, XWINDOW (window
)->frame
))
1871 return Fframe_first_window (all_frames
);
1877 /* Find WINDOW in the list of all windows. */
1878 list
= Fmemq (window
, window_list ());
1880 /* Scan forward from WINDOW to the end of the window list. */
1882 for (list
= XCDR (list
); CONSP (list
); list
= XCDR (list
))
1883 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1886 /* Scan from the start of the window list up to WINDOW. */
1888 for (list
= Vwindow_list
;
1889 CONSP (list
) && !EQ (XCAR (list
), window
);
1891 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1895 window
= XCAR (list
);
1899 Lisp_Object candidate
, list
;
1901 /* Scan through the list of windows for candidates. If there are
1902 candidate windows in front of WINDOW, the last one of these
1903 is the one we want. If there are candidates following WINDOW
1904 in the list, again the last one of these is the one we want. */
1906 for (list
= window_list (); CONSP (list
); list
= XCDR (list
))
1908 if (EQ (XCAR (list
), window
))
1910 if (WINDOWP (candidate
))
1913 else if (candidate_window_p (XCAR (list
), window
, minibuf
,
1915 candidate
= XCAR (list
);
1918 if (WINDOWP (candidate
))
1926 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
1927 doc
: /* Return next window after WINDOW in canonical ordering of windows.
1928 If omitted, WINDOW defaults to the selected window.
1930 Optional second arg MINIBUF t means count the minibuffer window even
1931 if not active. MINIBUF nil or omitted means count the minibuffer iff
1932 it is active. MINIBUF neither t nor nil means not to count the
1933 minibuffer even if it is active.
1935 Several frames may share a single minibuffer; if the minibuffer
1936 counts, all windows on all frames that share that minibuffer count
1937 too. Therefore, `next-window' can be used to iterate through the
1938 set of windows even when the minibuffer is on another frame. If the
1939 minibuffer does not count, only windows from WINDOW's frame count.
1941 Optional third arg ALL-FRAMES t means include windows on all frames.
1942 ALL-FRAMES nil or omitted means cycle within the frames as specified
1943 above. ALL-FRAMES = `visible' means include windows on all visible frames.
1944 ALL-FRAMES = 0 means include windows on all visible and iconified frames.
1945 If ALL-FRAMES is a frame, restrict search to windows on that frame.
1946 Anything else means restrict to WINDOW's frame.
1948 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
1949 `next-window' to iterate through the entire cycle of acceptable
1950 windows, eventually ending up back at the window you started with.
1951 `previous-window' traverses the same cycle, in the reverse order. */)
1952 (window
, minibuf
, all_frames
)
1953 Lisp_Object window
, minibuf
, all_frames
;
1955 return next_window (window
, minibuf
, all_frames
, 1);
1959 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
1960 doc
: /* Return the window preceding WINDOW in canonical ordering of windows.
1961 If omitted, WINDOW defaults to the selected window.
1963 Optional second arg MINIBUF t means count the minibuffer window even
1964 if not active. MINIBUF nil or omitted means count the minibuffer iff
1965 it is active. MINIBUF neither t nor nil means not to count the
1966 minibuffer even if it is active.
1968 Several frames may share a single minibuffer; if the minibuffer
1969 counts, all windows on all frames that share that minibuffer count
1970 too. Therefore, `previous-window' can be used to iterate through
1971 the set of windows even when the minibuffer is on another frame. If
1972 the minibuffer does not count, only windows from WINDOW's frame count
1974 Optional third arg ALL-FRAMES t means include windows on all frames.
1975 ALL-FRAMES nil or omitted means cycle within the frames as specified
1976 above. ALL-FRAMES = `visible' means include windows on all visible frames.
1977 ALL-FRAMES = 0 means include windows on all visible and iconified frames.
1978 If ALL-FRAMES is a frame, restrict search to windows on that frame.
1979 Anything else means restrict to WINDOW's frame.
1981 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
1982 `previous-window' to iterate through the entire cycle of acceptable
1983 windows, eventually ending up back at the window you started with.
1984 `next-window' traverses the same cycle, in the reverse order. */)
1985 (window
, minibuf
, all_frames
)
1986 Lisp_Object window
, minibuf
, all_frames
;
1988 return next_window (window
, minibuf
, all_frames
, 0);
1992 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1993 doc
: /* Select the ARG'th different window on this frame.
1994 All windows on current frame are arranged in a cyclic order.
1995 This command selects the window ARG steps away in that order.
1996 A negative ARG moves in the opposite order. The optional second
1997 argument ALL-FRAMES has the same meaning as in `next-window', which see. */)
1999 Lisp_Object arg
, all_frames
;
2005 window
= selected_window
;
2007 for (i
= XINT (arg
); i
> 0; --i
)
2008 window
= Fnext_window (window
, Qnil
, all_frames
);
2010 window
= Fprevious_window (window
, Qnil
, all_frames
);
2012 Fselect_window (window
, Qnil
);
2017 DEFUN ("window-list", Fwindow_list
, Swindow_list
, 0, 3, 0,
2018 doc
: /* Return a list of windows on FRAME, starting with WINDOW.
2019 FRAME nil or omitted means use the selected frame.
2020 WINDOW nil or omitted means use the selected window.
2021 MINIBUF t means include the minibuffer window, even if it isn't active.
2022 MINIBUF nil or omitted means include the minibuffer window only
2024 MINIBUF neither nil nor t means never include the minibuffer window. */)
2025 (frame
, minibuf
, window
)
2026 Lisp_Object frame
, minibuf
, window
;
2029 window
= FRAMEP (frame
) ? XFRAME (frame
)->selected_window
: selected_window
;
2030 CHECK_WINDOW (window
);
2032 frame
= selected_frame
;
2034 if (!EQ (frame
, XWINDOW (window
)->frame
))
2035 error ("Window is on a different frame");
2037 return window_list_1 (window
, minibuf
, frame
);
2041 /* Return a list of windows in canonical ordering. Arguments are like
2042 for `next-window'. */
2045 window_list_1 (window
, minibuf
, all_frames
)
2046 Lisp_Object window
, minibuf
, all_frames
;
2048 Lisp_Object tail
, list
, rest
;
2050 decode_next_window_args (&window
, &minibuf
, &all_frames
);
2053 for (tail
= window_list (); CONSP (tail
); tail
= XCDR (tail
))
2054 if (candidate_window_p (XCAR (tail
), window
, minibuf
, all_frames
))
2055 list
= Fcons (XCAR (tail
), list
);
2057 /* Rotate the list to start with WINDOW. */
2058 list
= Fnreverse (list
);
2059 rest
= Fmemq (window
, list
);
2060 if (!NILP (rest
) && !EQ (rest
, list
))
2062 for (tail
= list
; !EQ (XCDR (tail
), rest
); tail
= XCDR (tail
))
2064 XSETCDR (tail
, Qnil
);
2065 list
= nconc2 (rest
, list
);
2072 /* Look at all windows, performing an operation specified by TYPE
2074 If FRAMES is Qt, look at all frames;
2075 Qnil, look at just the selected frame;
2076 Qvisible, look at visible frames;
2077 a frame, just look at windows on that frame.
2078 If MINI is non-zero, perform the operation on minibuffer windows too. */
2083 GET_BUFFER_WINDOW
, /* Arg is buffer */
2084 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
2085 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
2086 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
2088 UNSHOW_BUFFER
, /* Arg is buffer */
2089 REDISPLAY_BUFFER_WINDOWS
, /* Arg is buffer */
2094 window_loop (type
, obj
, mini
, frames
)
2095 enum window_loop type
;
2096 Lisp_Object obj
, frames
;
2099 Lisp_Object window
, windows
, best_window
, frame_arg
;
2101 struct gcpro gcpro1
;
2103 /* If we're only looping through windows on a particular frame,
2104 frame points to that frame. If we're looping through windows
2105 on all frames, frame is 0. */
2106 if (FRAMEP (frames
))
2107 f
= XFRAME (frames
);
2108 else if (NILP (frames
))
2109 f
= SELECTED_FRAME ();
2114 frame_arg
= Qlambda
;
2115 else if (EQ (frames
, make_number (0)))
2117 else if (EQ (frames
, Qvisible
))
2122 /* frame_arg is Qlambda to stick to one frame,
2123 Qvisible to consider all visible frames,
2126 /* Pick a window to start with. */
2130 window
= FRAME_SELECTED_WINDOW (f
);
2132 window
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
2134 windows
= window_list_1 (window
, mini
? Qt
: Qnil
, frame_arg
);
2138 for (; CONSP (windows
); windows
= XCDR (windows
))
2142 window
= XCAR (windows
);
2143 w
= XWINDOW (window
);
2145 /* Note that we do not pay attention here to whether the frame
2146 is visible, since Fwindow_list skips non-visible frames if
2147 that is desired, under the control of frame_arg. */
2148 if (!MINI_WINDOW_P (w
)
2149 /* For UNSHOW_BUFFER, we must always consider all windows. */
2150 || type
== UNSHOW_BUFFER
2151 || (mini
&& minibuf_level
> 0))
2154 case GET_BUFFER_WINDOW
:
2155 if (EQ (w
->buffer
, obj
)
2156 /* Don't find any minibuffer window
2157 except the one that is currently in use. */
2158 && (MINI_WINDOW_P (w
)
2159 ? EQ (window
, minibuf_window
)
2162 if (NILP (best_window
))
2163 best_window
= window
;
2164 else if (EQ (window
, selected_window
))
2165 /* For compatibility with 20.x, prefer to return
2167 best_window
= window
;
2171 case GET_LRU_WINDOW
:
2172 /* `obj' is an integer encoding a bitvector.
2173 `obj & 1' means consider only full-width windows.
2174 `obj & 2' means consider also dedicated windows. */
2175 if (((XINT (obj
) & 1) && !WINDOW_FULL_WIDTH_P (w
))
2176 || (!(XINT (obj
) & 2) && !NILP (w
->dedicated
))
2177 /* Minibuffer windows are always ignored. */
2178 || MINI_WINDOW_P (w
))
2180 if (NILP (best_window
)
2181 || (XFASTINT (XWINDOW (best_window
)->use_time
)
2182 > XFASTINT (w
->use_time
)))
2183 best_window
= window
;
2186 case DELETE_OTHER_WINDOWS
:
2187 if (!EQ (window
, obj
))
2188 Fdelete_window (window
);
2191 case DELETE_BUFFER_WINDOWS
:
2192 if (EQ (w
->buffer
, obj
))
2194 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2196 /* If this window is dedicated, and in a frame of its own,
2198 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
2199 && !NILP (w
->dedicated
)
2200 && other_visible_frames (f
))
2202 /* Skip the other windows on this frame.
2203 There might be one, the minibuffer! */
2204 while (CONSP (XCDR (windows
))
2205 && EQ (XWINDOW (XCAR (windows
))->frame
,
2206 XWINDOW (XCAR (XCDR (windows
)))->frame
))
2207 windows
= XCDR (windows
);
2209 /* Now we can safely delete the frame. */
2210 Fdelete_frame (w
->frame
, Qnil
);
2212 else if (NILP (w
->parent
))
2214 /* If we're deleting the buffer displayed in the
2215 only window on the frame, find a new buffer to
2218 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
2219 Fset_window_buffer (window
, buffer
, Qnil
);
2220 if (EQ (window
, selected_window
))
2221 Fset_buffer (w
->buffer
);
2224 Fdelete_window (window
);
2228 case GET_LARGEST_WINDOW
:
2229 { /* nil `obj' means to ignore dedicated windows. */
2230 /* Ignore dedicated windows and minibuffers. */
2231 if (MINI_WINDOW_P (w
) || (NILP (obj
) && !NILP (w
->dedicated
)))
2234 if (NILP (best_window
))
2235 best_window
= window
;
2238 struct window
*b
= XWINDOW (best_window
);
2239 if (XFASTINT (w
->total_lines
) * XFASTINT (w
->total_cols
)
2240 > XFASTINT (b
->total_lines
) * XFASTINT (b
->total_cols
))
2241 best_window
= window
;
2247 if (EQ (w
->buffer
, obj
))
2250 struct frame
*f
= XFRAME (w
->frame
);
2252 /* Find another buffer to show in this window. */
2253 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
2255 /* If this window is dedicated, and in a frame of its own,
2257 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
2258 && !NILP (w
->dedicated
)
2259 && other_visible_frames (f
))
2261 /* Skip the other windows on this frame.
2262 There might be one, the minibuffer! */
2263 while (CONSP (XCDR (windows
))
2264 && EQ (XWINDOW (XCAR (windows
))->frame
,
2265 XWINDOW (XCAR (XCDR (windows
)))->frame
))
2266 windows
= XCDR (windows
);
2268 /* Now we can safely delete the frame. */
2269 Fdelete_frame (w
->frame
, Qnil
);
2271 else if (!NILP (w
->dedicated
) && !NILP (w
->parent
))
2274 XSETWINDOW (window
, w
);
2275 /* If this window is dedicated and not the only window
2276 in its frame, then kill it. */
2277 Fdelete_window (window
);
2281 /* Otherwise show a different buffer in the window. */
2282 w
->dedicated
= Qnil
;
2283 Fset_window_buffer (window
, buffer
, Qnil
);
2284 if (EQ (window
, selected_window
))
2285 Fset_buffer (w
->buffer
);
2290 case REDISPLAY_BUFFER_WINDOWS
:
2291 if (EQ (w
->buffer
, obj
))
2293 mark_window_display_accurate (window
, 0);
2294 w
->update_mode_line
= Qt
;
2295 XBUFFER (obj
)->prevent_redisplay_optimizations_p
= 1;
2296 ++update_mode_lines
;
2297 best_window
= window
;
2301 /* Check for a window that has a killed buffer. */
2302 case CHECK_ALL_WINDOWS
:
2303 if (! NILP (w
->buffer
)
2304 && NILP (XBUFFER (w
->buffer
)->name
))
2308 case WINDOW_LOOP_UNUSED
:
2317 /* Used for debugging. Abort if any window has a dead buffer. */
2320 check_all_windows ()
2322 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
2325 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 2, 0,
2326 doc
: /* Return the window least recently selected or used for display.
2327 \(LRU means Least Recently Used.)
2329 Return a full-width window if possible.
2330 A minibuffer window is never a candidate.
2331 A dedicated window is never a candidate, unless DEDICATED is non-nil,
2332 so if all windows are dedicated, the value is nil.
2333 If optional argument FRAME is `visible', search all visible frames.
2334 If FRAME is 0, search all visible and iconified frames.
2335 If FRAME is t, search all frames.
2336 If FRAME is nil, search only the selected frame.
2337 If FRAME is a frame, search only that frame. */)
2339 Lisp_Object frame
, dedicated
;
2341 register Lisp_Object w
;
2342 /* First try for a window that is full-width */
2343 w
= window_loop (GET_LRU_WINDOW
,
2344 NILP (dedicated
) ? make_number (1) : make_number (3),
2346 if (!NILP (w
) && !EQ (w
, selected_window
))
2348 /* If none of them, try the rest */
2349 return window_loop (GET_LRU_WINDOW
,
2350 NILP (dedicated
) ? make_number (0) : make_number (2),
2354 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 2, 0,
2355 doc
: /* Return the largest window in area.
2356 A minibuffer window is never a candidate.
2357 A dedicated window is never a candidate unless DEDICATED is non-nil,
2358 so if all windows are dedicated, the value is nil.
2359 If optional argument FRAME is `visible', search all visible frames.
2360 If FRAME is 0, search all visible and iconified frames.
2361 If FRAME is t, search all frames.
2362 If FRAME is nil, search only the selected frame.
2363 If FRAME is a frame, search only that frame. */)
2365 Lisp_Object frame
, dedicated
;
2367 return window_loop (GET_LARGEST_WINDOW
, dedicated
, 0,
2371 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
2372 doc
: /* Return a window currently displaying BUFFER, or nil if none.
2373 BUFFER can be a buffer or a buffer name.
2374 If optional argument FRAME is `visible', search all visible frames.
2375 If optional argument FRAME is 0, search all visible and iconified frames.
2376 If FRAME is t, search all frames.
2377 If FRAME is nil, search only the selected frame.
2378 If FRAME is a frame, search only that frame. */)
2380 Lisp_Object buffer
, frame
;
2382 buffer
= Fget_buffer (buffer
);
2383 if (BUFFERP (buffer
))
2384 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
2389 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
2391 doc
: /* Make WINDOW (or the selected window) fill its frame.
2392 Only the frame WINDOW is on is affected.
2393 This function tries to reduce display jumps
2394 by keeping the text previously visible in WINDOW
2395 in the same place on the frame. Doing this depends on
2396 the value of (window-start WINDOW), so if calling this function
2397 in a program gives strange scrolling, make sure the window-start
2398 value is reasonable when this function is called. */)
2407 window
= selected_window
;
2409 CHECK_LIVE_WINDOW (window
);
2410 w
= XWINDOW (window
);
2412 startpos
= marker_position (w
->start
);
2413 top
= WINDOW_TOP_EDGE_LINE (w
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2415 if (MINI_WINDOW_P (w
) && top
> 0)
2416 error ("Can't expand minibuffer to full frame");
2418 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
2420 /* Try to minimize scrolling, by setting the window start to the point
2421 will cause the text at the old window start to be at the same place
2422 on the frame. But don't try to do this if the window start is
2423 outside the visible portion (as might happen when the display is
2424 not current, due to typeahead). */
2425 new_top
= WINDOW_TOP_EDGE_LINE (w
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2427 && startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
2428 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
2430 struct position pos
;
2431 struct buffer
*obuf
= current_buffer
;
2433 Fset_buffer (w
->buffer
);
2434 /* This computation used to temporarily move point, but that can
2435 have unwanted side effects due to text properties. */
2436 pos
= *vmotion (startpos
, -top
, w
);
2438 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
2439 w
->window_end_valid
= Qnil
;
2440 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
2441 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
2443 /* We need to do this, so that the window-scroll-functions
2445 w
->optional_new_start
= Qt
;
2447 set_buffer_internal (obuf
);
2453 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
2454 1, 2, "bDelete windows on (buffer): ",
2455 doc
: /* Delete all windows showing BUFFER.
2456 BUFFER must be a buffer or the name of an existing buffer.
2457 Optional second argument FRAME controls which frames are affected.
2458 If optional argument FRAME is `visible', search all visible frames.
2459 If FRAME is 0, search all visible and iconified frames.
2460 If FRAME is nil, search all frames.
2461 If FRAME is t, search only the selected frame.
2462 If FRAME is a frame, search only that frame. */)
2464 Lisp_Object buffer
, frame
;
2466 /* FRAME uses t and nil to mean the opposite of what window_loop
2470 else if (EQ (frame
, Qt
))
2475 buffer
= Fget_buffer (buffer
);
2476 CHECK_BUFFER (buffer
);
2477 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
2483 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
2484 Sreplace_buffer_in_windows
,
2485 1, 1, "bReplace buffer in windows: ",
2486 doc
: /* Replace BUFFER with some other buffer in all windows showing it.
2487 BUFFER may be a buffer or the name of an existing buffer. */)
2493 buffer
= Fget_buffer (buffer
);
2494 CHECK_BUFFER (buffer
);
2495 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
2500 /* Replace BUFFER with some other buffer in all windows
2501 of all frames, even those on other keyboards. */
2504 replace_buffer_in_all_windows (buffer
)
2508 Lisp_Object tail
, frame
;
2510 /* A single call to window_loop won't do the job
2511 because it only considers frames on the current keyboard.
2512 So loop manually over frames, and handle each one. */
2513 FOR_EACH_FRAME (tail
, frame
)
2514 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
2516 window_loop (UNSHOW_BUFFER
, buffer
, 1, Qt
);
2520 /* Set the height of WINDOW and all its inferiors. */
2522 /* The smallest acceptable dimensions for a window. Anything smaller
2523 might crash Emacs. */
2525 #define MIN_SAFE_WINDOW_WIDTH (2)
2526 #define MIN_SAFE_WINDOW_HEIGHT (1)
2528 /* Make sure that window_min_height and window_min_width are
2529 not too small; if they are, set them to safe minima. */
2532 check_min_window_sizes ()
2534 /* Smaller values might permit a crash. */
2535 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
2536 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
2537 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
2538 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
2541 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
2542 minimum allowable size. */
2545 check_frame_size (frame
, rows
, cols
)
2549 /* For height, we have to see:
2550 how many windows the frame has at minimum (one or two),
2551 and whether it has a menu bar or other special stuff at the top. */
2553 = ((FRAME_MINIBUF_ONLY_P (frame
) || ! FRAME_HAS_MINIBUF_P (frame
))
2554 ? MIN_SAFE_WINDOW_HEIGHT
2555 : 2 * MIN_SAFE_WINDOW_HEIGHT
);
2557 if (FRAME_TOP_MARGIN (frame
) > 0)
2558 min_height
+= FRAME_TOP_MARGIN (frame
);
2560 if (*rows
< min_height
)
2562 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
2563 *cols
= MIN_SAFE_WINDOW_WIDTH
;
2566 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
2567 check if W's width can be changed, otherwise check W's height.
2568 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
2569 siblings, too. If none of the siblings is resizable, WINDOW isn't
2573 window_fixed_size_p (w
, width_p
, check_siblings_p
)
2575 int width_p
, check_siblings_p
;
2580 if (!NILP (w
->hchild
))
2582 c
= XWINDOW (w
->hchild
);
2586 /* A horiz. combination is fixed-width if all of if its
2588 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2589 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2590 fixed_p
= c
== NULL
;
2594 /* A horiz. combination is fixed-height if one of if its
2596 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2597 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2598 fixed_p
= c
!= NULL
;
2601 else if (!NILP (w
->vchild
))
2603 c
= XWINDOW (w
->vchild
);
2607 /* A vert. combination is fixed-width if one of if its
2609 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2610 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2611 fixed_p
= c
!= NULL
;
2615 /* A vert. combination is fixed-height if all of if its
2617 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2618 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2619 fixed_p
= c
== NULL
;
2622 else if (BUFFERP (w
->buffer
))
2624 struct buffer
*old
= current_buffer
;
2627 current_buffer
= XBUFFER (w
->buffer
);
2628 val
= find_symbol_value (Qwindow_size_fixed
);
2629 current_buffer
= old
;
2632 if (!EQ (val
, Qunbound
))
2634 fixed_p
= !NILP (val
);
2637 && ((EQ (val
, Qheight
) && width_p
)
2638 || (EQ (val
, Qwidth
) && !width_p
)))
2642 /* Can't tell if this one is resizable without looking at
2643 siblings. If all siblings are fixed-size this one is too. */
2644 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
2648 for (child
= w
->prev
; !NILP (child
); child
= XWINDOW (child
)->prev
)
2649 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2653 for (child
= w
->next
; !NILP (child
); child
= XWINDOW (child
)->next
)
2654 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2667 /* Return the minimum size for leaf window W. WIDTH_P non-zero means
2668 take into account fringes and the scrollbar of W. WIDTH_P zero means
2669 take into account mode-line of W. Return 1 for the minibuffer. */
2672 window_min_size_2 (w
, width_p
)
2679 size
= max (window_min_width
,
2680 (MIN_SAFE_WINDOW_WIDTH
2681 + WINDOW_FRINGE_COLS (w
)
2682 + WINDOW_SCROLL_BAR_COLS (w
)));
2683 else if (MINI_WINDOW_P (w
))
2686 size
= max (window_min_height
,
2687 (MIN_SAFE_WINDOW_HEIGHT
2688 /* Don't count the header-line here. It would break
2689 splitting a window with a header-line when the new
2690 window shall have a height of two (calculator does
2692 + (WINDOW_WANTS_MODELINE_P (w
) ? 1 : 0)));
2697 /* Return the minimum size of window W, not taking fixed-width windows
2698 into account. WIDTH_P non-zero means return the minimum width,
2699 otherwise return the minimum height. If W is a combination window,
2700 compute the minimum size from the minimum sizes of W's children. */
2703 window_min_size_1 (w
, width_p
)
2710 if (!NILP (w
->hchild
))
2712 c
= XWINDOW (w
->hchild
);
2717 /* The min width of a horizontal combination is
2718 the sum of the min widths of its children. */
2721 size
+= window_min_size_1 (c
, width_p
);
2722 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2727 /* The min height a horizontal combination equals
2728 the maximum of all min height of its children. */
2731 int min_size
= window_min_size_1 (c
, width_p
);
2732 size
= max (min_size
, size
);
2733 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2737 else if (!NILP (w
->vchild
))
2739 c
= XWINDOW (w
->vchild
);
2744 /* The min width of a vertical combination is
2745 the maximum of the min widths of its children. */
2748 int min_size
= window_min_size_1 (c
, width_p
);
2749 size
= max (min_size
, size
);
2750 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2755 /* The min height of a vertical combination equals
2756 the sum of the min height of its children. */
2759 size
+= window_min_size_1 (c
, width_p
);
2760 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2765 size
= window_min_size_2 (w
, width_p
);
2771 /* Return the minimum size of window W, taking fixed-size windows into
2772 account. WIDTH_P non-zero means return the minimum width,
2773 otherwise return the minimum height. IGNORE_FIXED_P non-zero means
2774 ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size
2775 unless FIXED is null. */
2778 window_min_size (w
, width_p
, ignore_fixed_p
, fixed
)
2780 int width_p
, ignore_fixed_p
, *fixed
;
2787 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
2793 size
= width_p
? XFASTINT (w
->total_cols
) : XFASTINT (w
->total_lines
);
2795 size
= window_min_size_1 (w
, width_p
);
2801 /* Adjust the margins of window W if text area is too small.
2802 Return 1 if window width is ok after adjustment; 0 if window
2803 is still too narrow. */
2806 adjust_window_margins (w
)
2809 int box_cols
= (WINDOW_TOTAL_COLS (w
)
2810 - WINDOW_FRINGE_COLS (w
)
2811 - WINDOW_SCROLL_BAR_COLS (w
));
2812 int margin_cols
= (WINDOW_LEFT_MARGIN_COLS (w
)
2813 + WINDOW_RIGHT_MARGIN_COLS (w
));
2815 if (box_cols
- margin_cols
>= MIN_SAFE_WINDOW_WIDTH
)
2818 if (margin_cols
< 0 || box_cols
< MIN_SAFE_WINDOW_WIDTH
)
2821 /* Window's text area is too narrow, but reducing the window
2822 margins will fix that. */
2823 margin_cols
= box_cols
- MIN_SAFE_WINDOW_WIDTH
;
2824 if (WINDOW_RIGHT_MARGIN_COLS (w
) > 0)
2826 if (WINDOW_LEFT_MARGIN_COLS (w
) > 0)
2827 w
->left_margin_cols
= w
->right_margin_cols
2828 = make_number (margin_cols
/2);
2830 w
->right_margin_cols
= make_number (margin_cols
);
2833 w
->left_margin_cols
= make_number (margin_cols
);
2837 /* Calculate new sizes for windows in the list FORWARD when the window size
2838 goes from TOTAL to SIZE. TOTAL must be greater than SIZE.
2839 The number of windows in FORWARD is NCHILDREN, and the number that
2840 can shrink is SHRINKABLE.
2841 The minimum size a window can have is MIN_SIZE.
2842 If we are shrinking fixed windows, RESIZE_FIXED_P is non-zero.
2843 If we are shrinking columns, WIDTH_P is non-zero, otherwise we are
2846 This function returns an allocated array of new sizes that the caller
2847 must free. The size -1 means the window is fixed and RESIZE_FIXED_P
2848 is zero. Array index 0 refers to the first window in FORWARD, 1 to
2849 the second, and so on.
2851 This function tries to keep windows at least at the minimum size
2852 and resize other windows before it resizes any window to zero (i.e.
2853 delete that window).
2855 Windows are resized proportional to their size, so bigger windows
2856 shrink more than smaller windows. */
2858 shrink_windows (total
, size
, nchildren
, shrinkable
,
2859 min_size
, resize_fixed_p
, forward
, width_p
)
2860 int total
, size
, nchildren
, shrinkable
, min_size
;
2861 int resize_fixed_p
, width_p
;
2862 Lisp_Object forward
;
2864 int available_resize
= 0;
2868 int smallest
= total
;
2869 int total_removed
= 0;
2870 int total_shrink
= total
- size
;
2873 new_sizes
= xmalloc (sizeof (*new_sizes
) * nchildren
);
2875 for (i
= 0, child
= forward
; !NILP (child
); child
= c
->next
, ++i
)
2879 c
= XWINDOW (child
);
2880 child_size
= width_p
? XINT (c
->total_cols
) : XINT (c
->total_lines
);
2882 if (! resize_fixed_p
&& window_fixed_size_p (c
, width_p
, 0))
2886 new_sizes
[i
] = child_size
;
2887 if (child_size
> min_size
)
2888 available_resize
+= child_size
- min_size
;
2891 /* We might need to shrink some windows to zero. Find the smallest
2892 windows and set them to 0 until we can fulfil the new size. */
2894 while (shrinkable
> 1 && size
+ available_resize
< total
)
2896 for (i
= 0; i
< nchildren
; ++i
)
2897 if (new_sizes
[i
] > 0 && smallest
> new_sizes
[i
])
2898 smallest
= new_sizes
[i
];
2900 for (i
= 0; i
< nchildren
; ++i
)
2901 if (new_sizes
[i
] == smallest
)
2903 /* Resize this window down to zero. */
2905 if (smallest
> min_size
)
2906 available_resize
-= smallest
- min_size
;
2907 available_resize
+= smallest
;
2909 total_removed
+= smallest
;
2911 /* We don't know what the smallest is now. */
2914 /* Out of for, just remove one window at the time and
2915 check again if we have enough space. */
2920 /* Now, calculate the new sizes. Try to shrink each window
2921 proportional to its size. */
2922 for (i
= 0; i
< nchildren
; ++i
)
2924 if (new_sizes
[i
] > min_size
)
2926 int to_shrink
= total_shrink
*new_sizes
[i
]/total
;
2927 if (new_sizes
[i
] - to_shrink
< min_size
)
2928 to_shrink
= new_sizes
[i
] - min_size
;
2929 new_sizes
[i
] -= to_shrink
;
2930 total_removed
+= to_shrink
;
2934 /* Any reminder due to rounding, we just subtract from windows
2935 that are left and still can be shrunk. */
2936 while (total_shrink
> total_removed
)
2938 int nonzero_sizes
= 0;
2939 int nonzero_idx
= -1;
2941 for (i
= 0; i
< nchildren
; ++i
)
2942 if (new_sizes
[i
] > 0)
2948 for (i
= 0; i
< nchildren
; ++i
)
2949 if (new_sizes
[i
] > min_size
)
2954 /* Out of for, just shrink one window at the time and
2955 check again if we have enough space. */
2960 /* Special case, only one window left. */
2961 if (nonzero_sizes
== 1)
2965 /* Any surplus due to rounding, we add to windows that are left. */
2966 while (total_shrink
< total_removed
)
2968 for (i
= 0; i
< nchildren
; ++i
)
2970 if (new_sizes
[i
] != 0 && total_shrink
< total_removed
)
2982 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
2983 WINDOW's width. Resize WINDOW's children, if any, so that they
2984 keep their proportionate size relative to WINDOW.
2986 If FIRST_ONLY is 1, change only the first of WINDOW's children when
2987 they are in series. If LAST_ONLY is 1, change only the last of
2988 WINDOW's children when they are in series.
2990 Propagate WINDOW's top or left edge position to children. Delete
2991 windows that become too small unless NODELETE_P is non-zero.
2993 If NODELETE_P is 2, that means we do delete windows that are
2994 too small, even if they were too small before! */
2997 size_window (window
, size
, width_p
, nodelete_p
, first_only
, last_only
)
2999 int size
, width_p
, nodelete_p
;
3000 int first_only
, last_only
;
3002 struct window
*w
= XWINDOW (window
);
3004 Lisp_Object child
, *forward
, *sideward
;
3005 int old_size
, min_size
, safe_min_size
;
3007 check_min_window_sizes ();
3008 size
= max (0, size
);
3010 /* If the window has been "too small" at one point,
3011 don't delete it for being "too small" in the future.
3012 Preserve it as long as that is at all possible. */
3015 old_size
= WINDOW_TOTAL_COLS (w
);
3016 min_size
= window_min_width
;
3017 safe_min_size
= window_min_size_2 (w
, 1);
3021 old_size
= XINT (w
->total_lines
);
3022 min_size
= window_min_height
;
3023 safe_min_size
= window_min_size_2 (w
, 0);
3026 if (old_size
< min_size
&& nodelete_p
!= 2)
3027 w
->too_small_ok
= Qt
;
3029 /* Move the following test here since otherwise the
3030 preceding test doesn't make sense. martin. */
3031 if (nodelete_p
== 2)
3034 /* Maybe delete WINDOW if it's too small. */
3035 if (nodelete_p
!= 1 && !NILP (w
->parent
))
3037 if (!MINI_WINDOW_P (w
) && !NILP (w
->too_small_ok
))
3038 min_size
= width_p
? MIN_SAFE_WINDOW_WIDTH
: MIN_SAFE_WINDOW_HEIGHT
;
3039 if (min_size
< safe_min_size
)
3040 min_size
= safe_min_size
;
3041 if (size
< min_size
)
3043 delete_window (window
);
3048 /* Set redisplay hints. */
3049 w
->last_modified
= make_number (0);
3050 w
->last_overlay_modified
= make_number (0);
3051 windows_or_buffers_changed
++;
3052 FRAME_WINDOW_SIZES_CHANGED (XFRAME (w
->frame
)) = 1;
3056 sideward
= &w
->vchild
;
3057 forward
= &w
->hchild
;
3058 w
->total_cols
= make_number (size
);
3059 adjust_window_margins (w
);
3063 sideward
= &w
->hchild
;
3064 forward
= &w
->vchild
;
3065 w
->total_lines
= make_number (size
);
3066 w
->orig_total_lines
= Qnil
;
3069 if (!NILP (*sideward
))
3071 /* We have a chain of parallel siblings whose size should all change. */
3072 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
3074 c
= XWINDOW (child
);
3076 c
->left_col
= w
->left_col
;
3078 c
->top_line
= w
->top_line
;
3079 size_window (child
, size
, width_p
, nodelete_p
,
3080 first_only
, last_only
);
3083 else if (!NILP (*forward
) && last_only
)
3085 /* Change the last in a series of siblings. */
3086 Lisp_Object last_child
;
3089 for (child
= *forward
; !NILP (child
); child
= c
->next
)
3091 c
= XWINDOW (child
);
3095 child_size
= XINT (width_p
? c
->total_cols
: c
->total_lines
);
3096 size_window (last_child
,
3097 size
- old_size
+ child_size
,
3098 width_p
, nodelete_p
, first_only
, last_only
);
3100 else if (!NILP (*forward
) && first_only
)
3102 /* Change the first in a series of siblings. */
3106 c
= XWINDOW (child
);
3109 c
->left_col
= w
->left_col
;
3111 c
->top_line
= w
->top_line
;
3113 child_size
= XINT (width_p
? c
->total_cols
: c
->total_lines
);
3115 size
- old_size
+ child_size
,
3116 width_p
, nodelete_p
, first_only
, last_only
);
3118 else if (!NILP (*forward
))
3120 int fixed_size
, each
, extra
, n
;
3121 int resize_fixed_p
, nfixed
;
3122 int last_pos
, first_pos
, nchildren
, total
;
3123 int *new_sizes
= NULL
;
3125 /* Determine the fixed-size portion of this window, and the
3126 number of child windows. */
3127 fixed_size
= nchildren
= nfixed
= total
= 0;
3128 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
3132 c
= XWINDOW (child
);
3133 child_size
= width_p
? XINT (c
->total_cols
) : XINT (c
->total_lines
);
3134 total
+= child_size
;
3136 if (window_fixed_size_p (c
, width_p
, 0))
3138 fixed_size
+= child_size
;
3143 /* If the new size is smaller than fixed_size, or if there
3144 aren't any resizable windows, allow resizing fixed-size
3146 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
3148 /* Compute how many lines/columns to add/remove to each child. The
3149 value of extra takes care of rounding errors. */
3150 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
3151 if (size
< total
&& n
> 1)
3152 new_sizes
= shrink_windows (total
, size
, nchildren
, n
, min_size
,
3153 resize_fixed_p
, *forward
, width_p
);
3156 each
= (size
- total
) / n
;
3157 extra
= (size
- total
) - n
* each
;
3160 /* Compute new children heights and edge positions. */
3161 first_pos
= width_p
? XINT (w
->left_col
) : XINT (w
->top_line
);
3162 last_pos
= first_pos
;
3163 for (n
= 0, child
= *forward
; !NILP (child
); child
= c
->next
, ++n
)
3165 int new_size
, old_size
;
3167 c
= XWINDOW (child
);
3168 old_size
= width_p
? XFASTINT (c
->total_cols
) : XFASTINT (c
->total_lines
);
3169 new_size
= old_size
;
3171 /* The top or left edge position of this child equals the
3172 bottom or right edge of its predecessor. */
3174 c
->left_col
= make_number (last_pos
);
3176 c
->top_line
= make_number (last_pos
);
3178 /* If this child can be resized, do it. */
3179 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
3181 new_size
= new_sizes
? new_sizes
[n
] : old_size
+ each
+ extra
;
3185 /* Set new height. Note that size_window also propagates
3186 edge positions to children, so it's not a no-op if we
3187 didn't change the child's size. */
3188 size_window (child
, new_size
, width_p
, 1, first_only
, last_only
);
3190 /* Remember the bottom/right edge position of this child; it
3191 will be used to set the top/left edge of the next child. */
3192 last_pos
+= new_size
;
3195 if (new_sizes
) xfree (new_sizes
);
3197 /* We should have covered the parent exactly with child windows. */
3198 xassert (size
== last_pos
- first_pos
);
3200 /* Now delete any children that became too small. */
3202 for (child
= *forward
; !NILP (child
); child
= c
->next
)
3205 c
= XWINDOW (child
);
3206 child_size
= width_p
? XINT (c
->total_cols
) : XINT (c
->total_lines
);
3207 size_window (child
, child_size
, width_p
, 2, first_only
, last_only
);
3212 /* Set WINDOW's height to HEIGHT, and recursively change the height of
3213 WINDOW's children. NODELETE non-zero means don't delete windows
3214 that become too small in the process. (The caller should check
3215 later and do so if appropriate.) */
3218 set_window_height (window
, height
, nodelete
)
3223 size_window (window
, height
, 0, nodelete
, 0, 0);
3227 /* Set WINDOW's width to WIDTH, and recursively change the width of
3228 WINDOW's children. NODELETE non-zero means don't delete windows
3229 that become too small in the process. (The caller should check
3230 later and do so if appropriate.) */
3233 set_window_width (window
, width
, nodelete
)
3238 size_window (window
, width
, 1, nodelete
, 0, 0);
3241 /* Change window heights in windows rooted in WINDOW by N lines. */
3244 change_window_heights (window
, n
)
3248 struct window
*w
= XWINDOW (window
);
3250 XSETFASTINT (w
->top_line
, XFASTINT (w
->top_line
) + n
);
3251 XSETFASTINT (w
->total_lines
, XFASTINT (w
->total_lines
) - n
);
3253 if (INTEGERP (w
->orig_top_line
))
3254 XSETFASTINT (w
->orig_top_line
, XFASTINT (w
->orig_top_line
) + n
);
3255 if (INTEGERP (w
->orig_total_lines
))
3256 XSETFASTINT (w
->orig_total_lines
, XFASTINT (w
->orig_total_lines
) - n
);
3258 /* Handle just the top child in a vertical split. */
3259 if (!NILP (w
->vchild
))
3260 change_window_heights (w
->vchild
, n
);
3262 /* Adjust all children in a horizontal split. */
3263 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
3265 w
= XWINDOW (window
);
3266 change_window_heights (window
, n
);
3271 int window_select_count
;
3274 Fset_window_buffer_unwind (obuf
)
3281 EXFUN (Fset_window_fringes
, 4);
3282 EXFUN (Fset_window_scroll_bars
, 4);
3284 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
3285 means it's allowed to run hooks. See make_frame for a case where
3286 it's not allowed. KEEP_MARGINS_P non-zero means that the current
3287 margins, fringes, and scroll-bar settings of the window are not
3288 reset from the buffer's local settings. */
3291 set_window_buffer (window
, buffer
, run_hooks_p
, keep_margins_p
)
3292 Lisp_Object window
, buffer
;
3293 int run_hooks_p
, keep_margins_p
;
3295 struct window
*w
= XWINDOW (window
);
3296 struct buffer
*b
= XBUFFER (buffer
);
3297 int count
= SPECPDL_INDEX ();
3301 if (EQ (window
, selected_window
))
3302 b
->last_selected_window
= window
;
3304 /* Let redisplay errors through. */
3305 b
->display_error_modiff
= 0;
3307 /* Update time stamps of buffer display. */
3308 if (INTEGERP (b
->display_count
))
3309 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
3310 b
->display_time
= Fcurrent_time ();
3312 XSETFASTINT (w
->window_end_pos
, 0);
3313 XSETFASTINT (w
->window_end_vpos
, 0);
3314 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
3315 w
->window_end_valid
= Qnil
;
3316 w
->hscroll
= w
->min_hscroll
= make_number (0);
3318 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
3319 set_marker_restricted (w
->start
,
3320 make_number (b
->last_window_start
),
3322 w
->start_at_line_beg
= Qnil
;
3323 w
->force_start
= Qnil
;
3324 XSETFASTINT (w
->last_modified
, 0);
3325 XSETFASTINT (w
->last_overlay_modified
, 0);
3326 windows_or_buffers_changed
++;
3328 /* We must select BUFFER for running the window-scroll-functions.
3329 If WINDOW is selected, switch permanently.
3330 Otherwise, switch but go back to the ambient buffer afterward. */
3331 if (EQ (window
, selected_window
))
3332 Fset_buffer (buffer
);
3333 /* We can't check ! NILP (Vwindow_scroll_functions) here
3334 because that might itself be a local variable. */
3335 else if (window_initialized
)
3337 record_unwind_protect (Fset_window_buffer_unwind
, Fcurrent_buffer ());
3338 Fset_buffer (buffer
);
3341 if (!keep_margins_p
)
3343 /* Set left and right marginal area width etc. from buffer. */
3345 /* This may call adjust_window_margins three times, so
3346 temporarily disable window margins. */
3347 Lisp_Object save_left
= w
->left_margin_cols
;
3348 Lisp_Object save_right
= w
->right_margin_cols
;
3350 w
->left_margin_cols
= w
->right_margin_cols
= Qnil
;
3352 Fset_window_fringes (window
,
3353 b
->left_fringe_width
, b
->right_fringe_width
,
3354 b
->fringes_outside_margins
);
3356 Fset_window_scroll_bars (window
,
3357 b
->scroll_bar_width
,
3358 b
->vertical_scroll_bar_type
, Qnil
);
3360 w
->left_margin_cols
= save_left
;
3361 w
->right_margin_cols
= save_right
;
3363 Fset_window_margins (window
,
3364 b
->left_margin_cols
, b
->right_margin_cols
);
3369 if (! NILP (Vwindow_scroll_functions
))
3370 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
3371 Fmarker_position (w
->start
));
3373 if (! NILP (Vwindow_configuration_change_hook
)
3374 && ! NILP (Vrun_hooks
))
3375 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3378 unbind_to (count
, Qnil
);
3382 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 3, 0,
3383 doc
: /* Make WINDOW display BUFFER as its contents.
3384 BUFFER can be a buffer or the name of an existing buffer.
3385 Optional third arg KEEP-MARGINS non-nil means that WINDOW's current
3386 display margins, fringe widths, and scroll bar settings are maintained;
3387 the default is to reset these from BUFFER's local settings or the frame
3390 This function runs the hook `window-scroll-functions'. */)
3391 (window
, buffer
, keep_margins
)
3392 register Lisp_Object window
, buffer
, keep_margins
;
3394 register Lisp_Object tem
;
3395 register struct window
*w
= decode_window (window
);
3397 XSETWINDOW (window
, w
);
3398 buffer
= Fget_buffer (buffer
);
3399 CHECK_BUFFER (buffer
);
3401 if (NILP (XBUFFER (buffer
)->name
))
3402 error ("Attempt to display deleted buffer");
3406 error ("Window is deleted");
3407 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
3408 is first being set up. */
3410 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
3411 error ("Window is dedicated to `%s'",
3412 SDATA (XBUFFER (tem
)->name
));
3417 set_window_buffer (window
, buffer
, 1, !NILP (keep_margins
));
3421 /* Note that selected_window can be nil
3422 when this is called from Fset_window_configuration. */
3424 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 2, 0,
3425 doc
: /* Select WINDOW. Most editing will apply to WINDOW's buffer.
3426 If WINDOW is not already selected, make WINDOW's buffer current
3427 and make WINDOW the frame's selected window. Return WINDOW.
3428 Optional second arg NORECORD non-nil means
3429 do not put this buffer at the front of the list of recently selected ones.
3431 Note that the main editor command loop
3432 selects the buffer of the selected window before each command. */)
3434 register Lisp_Object window
, norecord
;
3436 register struct window
*w
;
3437 register struct window
*ow
;
3440 CHECK_LIVE_WINDOW (window
);
3442 w
= XWINDOW (window
);
3443 w
->frozen_window_start_p
= 0;
3445 ++window_select_count
;
3446 XSETFASTINT (w
->use_time
, window_select_count
);
3447 if (EQ (window
, selected_window
))
3450 /* Store the current buffer's actual point into the
3451 old selected window. It belongs to that window,
3452 and when the window is not selected, must be in the window. */
3453 if (!NILP (selected_window
))
3455 ow
= XWINDOW (selected_window
);
3456 if (! NILP (ow
->buffer
))
3457 set_marker_both (ow
->pointm
, ow
->buffer
,
3458 BUF_PT (XBUFFER (ow
->buffer
)),
3459 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
3462 selected_window
= window
;
3463 sf
= SELECTED_FRAME ();
3464 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
3466 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
3467 /* Use this rather than Fhandle_switch_frame
3468 so that FRAME_FOCUS_FRAME is moved appropriately as we
3469 move around in the state where a minibuffer in a separate
3471 Fselect_frame (WINDOW_FRAME (w
));
3474 sf
->selected_window
= window
;
3476 if (NILP (norecord
))
3477 record_buffer (w
->buffer
);
3478 Fset_buffer (w
->buffer
);
3480 XBUFFER (w
->buffer
)->last_selected_window
= window
;
3482 /* Go to the point recorded in the window.
3483 This is important when the buffer is in more
3484 than one window. It also matters when
3485 redisplay_window has altered point after scrolling,
3486 because it makes the change only in the window. */
3488 register int new_point
= marker_position (w
->pointm
);
3489 if (new_point
< BEGV
)
3491 else if (new_point
> ZV
)
3497 windows_or_buffers_changed
++;
3502 select_window_norecord (window
)
3505 return Fselect_window (window
, Qt
);
3508 /* Deiconify the frame containing the window WINDOW,
3509 unless it is the selected frame;
3512 The reason for the exception for the selected frame
3513 is that it seems better not to change the selected frames visibility
3514 merely because of displaying a different buffer in it.
3515 The deiconification is useful when a buffer gets shown in
3516 another frame that you were not using lately. */
3519 display_buffer_1 (window
)
3522 Lisp_Object frame
= XWINDOW (window
)->frame
;
3523 FRAME_PTR f
= XFRAME (frame
);
3525 FRAME_SAMPLE_VISIBILITY (f
);
3527 if (EQ (frame
, selected_frame
))
3528 ; /* Assume the selected frame is already visible enough. */
3529 else if (minibuf_level
> 0
3530 && MINI_WINDOW_P (XWINDOW (selected_window
))
3531 && WINDOW_LIVE_P (minibuf_selected_window
)
3532 && EQ (frame
, WINDOW_FRAME (XWINDOW (minibuf_selected_window
))))
3533 ; /* Assume the frame from which we invoked the minibuffer is visible. */
3536 if (FRAME_ICONIFIED_P (f
))
3537 Fmake_frame_visible (frame
);
3538 else if (FRAME_VISIBLE_P (f
))
3539 Fraise_frame (frame
);
3545 DEFUN ("special-display-p", Fspecial_display_p
, Sspecial_display_p
, 1, 1, 0,
3546 doc
: /* Returns non-nil if a buffer named BUFFER-NAME gets a special frame.
3547 If the value is t, `display-buffer' or `pop-to-buffer' would create a
3548 special frame for that buffer using the default frame parameters.
3550 If the value is a list, it is a list of frame parameters that would be used
3551 to make a frame for that buffer.
3552 The variables `special-display-buffer-names'
3553 and `special-display-regexps' control this. */)
3555 Lisp_Object buffer_name
;
3559 CHECK_STRING (buffer_name
);
3561 tem
= Fmember (buffer_name
, Vspecial_display_buffer_names
);
3565 tem
= Fassoc (buffer_name
, Vspecial_display_buffer_names
);
3569 for (tem
= Vspecial_display_regexps
; CONSP (tem
); tem
= XCDR (tem
))
3571 Lisp_Object car
= XCAR (tem
);
3573 && fast_string_match (car
, buffer_name
) >= 0)
3575 else if (CONSP (car
)
3576 && STRINGP (XCAR (car
))
3577 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
3583 DEFUN ("same-window-p", Fsame_window_p
, Ssame_window_p
, 1, 1, 0,
3584 doc
: /* Returns non-nil if a buffer named BUFFER-NAME would use the same window.
3585 More precisely, if `display-buffer' or `pop-to-buffer' would display
3586 that buffer in the selected window rather than (as usual) in some other window.
3587 See `same-window-buffer-names' and `same-window-regexps'. */)
3589 Lisp_Object buffer_name
;
3593 CHECK_STRING (buffer_name
);
3595 tem
= Fmember (buffer_name
, Vsame_window_buffer_names
);
3599 tem
= Fassoc (buffer_name
, Vsame_window_buffer_names
);
3603 for (tem
= Vsame_window_regexps
; CONSP (tem
); tem
= XCDR (tem
))
3605 Lisp_Object car
= XCAR (tem
);
3607 && fast_string_match (car
, buffer_name
) >= 0)
3609 else if (CONSP (car
)
3610 && STRINGP (XCAR (car
))
3611 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
3617 /* Use B so the default is (other-buffer). */
3618 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 3,
3619 "BDisplay buffer: \nP",
3620 doc
: /* Make BUFFER appear in some window but don't select it.
3621 BUFFER must be the name of an existing buffer, or, when called from Lisp,
3623 If BUFFER is shown already in some window, just use that one,
3624 unless the window is the selected window and the optional second
3625 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).
3626 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.
3627 Returns the window displaying BUFFER.
3628 If `display-buffer-reuse-frames' is non-nil, and another frame is currently
3629 displaying BUFFER, then simply raise that frame.
3631 The variables `special-display-buffer-names',
3632 `special-display-regexps', `same-window-buffer-names', and
3633 `same-window-regexps' customize how certain buffer names are handled.
3634 The latter two take effect only if NOT-THIS-WINDOW is nil.
3636 If optional argument FRAME is `visible', check all visible frames
3637 for a window to use.
3638 If FRAME is 0, check all visible and iconified frames.
3639 If FRAME is t, check all frames.
3640 If FRAME is a frame, check only that frame.
3641 If FRAME is nil, check only the selected frame
3642 (actually the last nonminibuffer frame),
3643 unless `pop-up-frames' or `display-buffer-reuse-frames' is non-nil,
3644 which means search visible and iconified frames.
3646 If a full-width window on a splittable frame is available to display
3647 the buffer, it may be split, subject to the value of the variable
3648 `split-height-threshold'.
3650 If `even-window-heights' is non-nil, window heights will be evened out
3651 if displaying the buffer causes two vertically adjacent windows to be
3653 (buffer
, not_this_window
, frame
)
3654 register Lisp_Object buffer
, not_this_window
, frame
;
3656 register Lisp_Object window
, tem
, swp
;
3660 buffer
= Fget_buffer (buffer
);
3661 CHECK_BUFFER (buffer
);
3663 if (!NILP (Vdisplay_buffer_function
))
3664 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
3666 if (NILP (not_this_window
)
3667 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
3668 return display_buffer_1 (selected_window
);
3670 /* See if the user has specified this buffer should appear
3671 in the selected window. */
3672 if (NILP (not_this_window
))
3674 swp
= Fsame_window_p (XBUFFER (buffer
)->name
);
3675 if (!NILP (swp
) && !no_switch_window (selected_window
))
3677 Fswitch_to_buffer (buffer
, Qnil
);
3678 return display_buffer_1 (selected_window
);
3682 /* If the user wants pop-up-frames or display-buffer-reuse-frames,
3683 look for a window showing BUFFER on any visible or iconified frame.
3684 Otherwise search only the current frame. */
3687 else if (pop_up_frames
3688 || display_buffer_reuse_frames
3689 || last_nonminibuf_frame
== 0)
3690 XSETFASTINT (tem
, 0);
3692 XSETFRAME (tem
, last_nonminibuf_frame
);
3694 window
= Fget_buffer_window (buffer
, tem
);
3696 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
3697 return display_buffer_1 (window
);
3699 /* Certain buffer names get special handling. */
3700 if (!NILP (Vspecial_display_function
) && NILP (swp
))
3702 tem
= Fspecial_display_p (XBUFFER (buffer
)->name
);
3704 return call1 (Vspecial_display_function
, buffer
);
3706 return call2 (Vspecial_display_function
, buffer
, tem
);
3709 /* If there are no frames open that have more than a minibuffer,
3710 we need to create a new frame. */
3711 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
3713 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
3714 Fset_window_buffer (window
, buffer
, Qnil
);
3715 return display_buffer_1 (window
);
3718 f
= SELECTED_FRAME ();
3720 || FRAME_MINIBUF_ONLY_P (f
)
3721 /* If the current frame is a special display frame,
3722 don't try to reuse its windows. */
3723 || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f
))->dedicated
))
3728 if (FRAME_MINIBUF_ONLY_P (f
))
3729 XSETFRAME (frames
, last_nonminibuf_frame
);
3731 /* Note that both Fget_largest_window and Fget_lru_window
3732 ignore minibuffers and dedicated windows.
3733 This means they can return nil. */
3735 /* If the frame we would try to split cannot be split,
3736 try other frames. */
3737 if (FRAME_NO_SPLIT_P (NILP (frames
) ? f
: last_nonminibuf_frame
))
3739 /* Try visible frames first. */
3740 window
= Fget_largest_window (Qvisible
, Qt
);
3741 /* If that didn't work, try iconified frames. */
3743 window
= Fget_largest_window (make_number (0), Qt
);
3744 #if 0 /* Don't try windows on other displays. */
3746 window
= Fget_largest_window (Qt
, Qt
);
3750 window
= Fget_largest_window (frames
, Qt
);
3752 /* If the largest window is tall enough, full-width, and either eligible
3753 for splitting or the only window, split it. */
3755 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
3756 && WINDOW_FULL_WIDTH_P (XWINDOW (window
))
3757 && (window_height (window
) >= split_height_threshold
3758 || (NILP (XWINDOW (window
)->parent
)))
3759 && (window_height (window
)
3760 >= (2 * window_min_size_2 (XWINDOW (window
), 0))))
3761 window
= Fsplit_window (window
, Qnil
, Qnil
);
3764 Lisp_Object upper
, lower
, other
;
3766 window
= Fget_lru_window (frames
, Qt
);
3767 /* If the LRU window is tall enough, and either eligible for splitting
3768 and selected or the only window, split it. */
3770 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
3771 && ((EQ (window
, selected_window
)
3772 && window_height (window
) >= split_height_threshold
)
3773 || (NILP (XWINDOW (window
)->parent
)))
3774 && (window_height (window
)
3775 >= (2 * window_min_size_2 (XWINDOW (window
), 0))))
3776 window
= Fsplit_window (window
, Qnil
, Qnil
);
3778 window
= Fget_lru_window (frames
, Qnil
);
3779 /* If Fget_lru_window returned nil, try other approaches. */
3781 /* Try visible frames first. */
3783 window
= Fget_buffer_window (buffer
, Qvisible
);
3785 window
= Fget_largest_window (Qvisible
, Qnil
);
3786 /* If that didn't work, try iconified frames. */
3788 window
= Fget_buffer_window (buffer
, make_number (0));
3790 window
= Fget_largest_window (make_number (0), Qnil
);
3792 #if 0 /* Don't try frames on other displays. */
3794 window
= Fget_buffer_window (buffer
, Qt
);
3796 window
= Fget_largest_window (Qt
, Qnil
);
3798 /* As a last resort, make a new frame. */
3800 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
3801 /* If window appears above or below another,
3802 even out their heights. */
3803 other
= upper
= lower
= Qnil
;
3804 if (!NILP (XWINDOW (window
)->prev
))
3805 other
= upper
= XWINDOW (window
)->prev
, lower
= window
;
3806 if (!NILP (XWINDOW (window
)->next
))
3807 other
= lower
= XWINDOW (window
)->next
, upper
= window
;
3809 && !NILP (Veven_window_heights
)
3810 /* Check that OTHER and WINDOW are vertically arrayed. */
3811 && !EQ (XWINDOW (other
)->top_line
, XWINDOW (window
)->top_line
)
3812 && (XFASTINT (XWINDOW (other
)->total_lines
)
3813 > XFASTINT (XWINDOW (window
)->total_lines
)))
3815 int total
= (XFASTINT (XWINDOW (other
)->total_lines
)
3816 + XFASTINT (XWINDOW (window
)->total_lines
));
3817 enlarge_window (upper
,
3818 total
/ 2 - XFASTINT (XWINDOW (upper
)->total_lines
),
3824 window
= Fget_lru_window (Qnil
, Qnil
);
3826 Fset_window_buffer (window
, buffer
, Qnil
);
3827 return display_buffer_1 (window
);
3831 DEFUN ("force-window-update", Fforce_window_update
, Sforce_window_update
,
3833 doc
: /* Force all windows to be updated on next redisplay.
3834 If optional arg OBJECT is a window, force redisplay of that window only.
3835 If OBJECT is a buffer or buffer name, force redisplay of all windows
3836 displaying that buffer. */)
3842 windows_or_buffers_changed
++;
3843 update_mode_lines
++;
3847 if (WINDOWP (object
))
3849 struct window
*w
= XWINDOW (object
);
3850 mark_window_display_accurate (object
, 0);
3851 w
->update_mode_line
= Qt
;
3852 if (BUFFERP (w
->buffer
))
3853 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
3854 ++update_mode_lines
;
3858 if (STRINGP (object
))
3859 object
= Fget_buffer (object
);
3860 if (BUFFERP (object
) && !NILP (XBUFFER (object
)->name
))
3862 /* Walk all windows looking for buffer, and force update
3863 of each of those windows. */
3865 object
= window_loop (REDISPLAY_BUFFER_WINDOWS
, object
, 0, Qvisible
);
3866 return NILP (object
) ? Qnil
: Qt
;
3869 /* If nothing suitable was found, just return.
3870 We could signal an error, but this feature will typically be used
3871 asynchronously in timers or process sentinels, so we don't. */
3877 temp_output_buffer_show (buf
)
3878 register Lisp_Object buf
;
3880 register struct buffer
*old
= current_buffer
;
3881 register Lisp_Object window
;
3882 register struct window
*w
;
3884 XBUFFER (buf
)->directory
= current_buffer
->directory
;
3887 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
3891 #if 0 /* rms: there should be no reason for this. */
3892 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
3894 set_buffer_internal (old
);
3896 if (!NILP (Vtemp_buffer_show_function
))
3897 call1 (Vtemp_buffer_show_function
, buf
);
3900 window
= Fdisplay_buffer (buf
, Qnil
, Qnil
);
3902 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
3903 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
3904 Vminibuf_scroll_window
= window
;
3905 w
= XWINDOW (window
);
3906 XSETFASTINT (w
->hscroll
, 0);
3907 XSETFASTINT (w
->min_hscroll
, 0);
3908 set_marker_restricted_both (w
->start
, buf
, BEG
, BEG
);
3909 set_marker_restricted_both (w
->pointm
, buf
, BEG
, BEG
);
3911 /* Run temp-buffer-show-hook, with the chosen window selected
3912 and its buffer current. */
3914 if (!NILP (Vrun_hooks
)
3915 && !NILP (Fboundp (Qtemp_buffer_show_hook
))
3916 && !NILP (Fsymbol_value (Qtemp_buffer_show_hook
)))
3918 int count
= SPECPDL_INDEX ();
3919 Lisp_Object prev_window
, prev_buffer
;
3920 prev_window
= selected_window
;
3921 XSETBUFFER (prev_buffer
, old
);
3923 /* Select the window that was chosen, for running the hook.
3924 Note: Both Fselect_window and select_window_norecord may
3925 set-buffer to the buffer displayed in the window,
3926 so we need to save the current buffer. --stef */
3927 record_unwind_protect (Fset_buffer
, prev_buffer
);
3928 record_unwind_protect (select_window_norecord
, prev_window
);
3929 Fselect_window (window
, Qt
);
3930 Fset_buffer (w
->buffer
);
3931 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
3932 unbind_to (count
, Qnil
);
3938 make_dummy_parent (window
)
3942 register struct window
*o
, *p
;
3945 o
= XWINDOW (window
);
3946 p
= allocate_window ();
3947 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
3948 ((struct Lisp_Vector
*) p
)->contents
[i
]
3949 = ((struct Lisp_Vector
*)o
)->contents
[i
];
3950 XSETWINDOW (new, p
);
3953 XSETFASTINT (p
->sequence_number
, sequence_number
);
3955 /* Put new into window structure in place of window */
3956 replace_window (window
, new);
3969 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
3970 doc
: /* Split WINDOW, putting SIZE lines in the first of the pair.
3971 WINDOW defaults to selected one and SIZE to half its size.
3972 If optional third arg HORFLAG is non-nil, split side by side
3973 and put SIZE columns in the first of the pair. In that case,
3974 SIZE includes that window's scroll bar, or the divider column to its right.
3975 Interactively, all arguments are nil.
3977 Returns the newly created window (which is the lower or rightmost one).
3978 The upper or leftmost window is the original one, and remains selected
3979 if it was selected before.
3981 See Info node `(elisp)Splitting Windows' for more details and examples.*/)
3982 (window
, size
, horflag
)
3983 Lisp_Object window
, size
, horflag
;
3985 register Lisp_Object
new;
3986 register struct window
*o
, *p
;
3988 register int size_int
;
3991 window
= selected_window
;
3993 CHECK_LIVE_WINDOW (window
);
3995 o
= XWINDOW (window
);
3996 fo
= XFRAME (WINDOW_FRAME (o
));
4000 if (!NILP (horflag
))
4001 /* Calculate the size of the left-hand window, by dividing
4002 the usable space in columns by two.
4003 We round up, since the left-hand window may include
4004 a dividing line, while the right-hand may not. */
4005 size_int
= (XFASTINT (o
->total_cols
) + 1) >> 1;
4007 size_int
= XFASTINT (o
->total_lines
) >> 1;
4011 CHECK_NUMBER (size
);
4012 size_int
= XINT (size
);
4015 if (MINI_WINDOW_P (o
))
4016 error ("Attempt to split minibuffer window");
4017 else if (window_fixed_size_p (o
, !NILP (horflag
), 0))
4018 error ("Attempt to split fixed-size window");
4020 check_min_window_sizes ();
4024 int window_safe_height
= window_min_size_2 (o
, 0);
4026 if (size_int
< window_safe_height
)
4027 error ("Window height %d too small (after splitting)", size_int
);
4028 if (size_int
+ window_safe_height
> XFASTINT (o
->total_lines
))
4029 error ("Window height %d too small (after splitting)",
4030 XFASTINT (o
->total_lines
) - size_int
);
4031 if (NILP (o
->parent
)
4032 || NILP (XWINDOW (o
->parent
)->vchild
))
4034 make_dummy_parent (window
);
4036 XWINDOW (new)->vchild
= window
;
4041 int window_safe_width
= window_min_size_2 (o
, 1);
4043 if (size_int
< window_safe_width
)
4044 error ("Window width %d too small (after splitting)", size_int
);
4045 if (size_int
+ window_safe_width
> XFASTINT (o
->total_cols
))
4046 error ("Window width %d too small (after splitting)",
4047 XFASTINT (o
->total_cols
) - size_int
);
4048 if (NILP (o
->parent
)
4049 || NILP (XWINDOW (o
->parent
)->hchild
))
4051 make_dummy_parent (window
);
4053 XWINDOW (new)->hchild
= window
;
4057 /* Now we know that window's parent is a vertical combination
4058 if we are dividing vertically, or a horizontal combination
4059 if we are making side-by-side windows */
4061 windows_or_buffers_changed
++;
4062 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
4063 new = make_window ();
4066 p
->frame
= o
->frame
;
4068 if (!NILP (p
->next
))
4069 XWINDOW (p
->next
)->prev
= new;
4072 p
->parent
= o
->parent
;
4074 p
->window_end_valid
= Qnil
;
4075 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
4077 /* Duplicate special geometry settings. */
4079 p
->left_margin_cols
= o
->left_margin_cols
;
4080 p
->right_margin_cols
= o
->right_margin_cols
;
4081 p
->left_fringe_width
= o
->left_fringe_width
;
4082 p
->right_fringe_width
= o
->right_fringe_width
;
4083 p
->fringes_outside_margins
= o
->fringes_outside_margins
;
4084 p
->scroll_bar_width
= o
->scroll_bar_width
;
4085 p
->vertical_scroll_bar_type
= o
->vertical_scroll_bar_type
;
4087 /* Apportion the available frame space among the two new windows */
4089 if (!NILP (horflag
))
4091 p
->total_lines
= o
->total_lines
;
4092 p
->top_line
= o
->top_line
;
4093 XSETFASTINT (p
->total_cols
, XFASTINT (o
->total_cols
) - size_int
);
4094 XSETFASTINT (o
->total_cols
, size_int
);
4095 XSETFASTINT (p
->left_col
, XFASTINT (o
->left_col
) + size_int
);
4096 adjust_window_margins (p
);
4097 adjust_window_margins (o
);
4101 p
->left_col
= o
->left_col
;
4102 p
->total_cols
= o
->total_cols
;
4103 XSETFASTINT (p
->total_lines
, XFASTINT (o
->total_lines
) - size_int
);
4104 XSETFASTINT (o
->total_lines
, size_int
);
4105 XSETFASTINT (p
->top_line
, XFASTINT (o
->top_line
) + size_int
);
4108 /* Adjust glyph matrices. */
4111 Fset_window_buffer (new, o
->buffer
, Qt
);
4115 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
4116 doc
: /* Make current window ARG lines bigger.
4117 From program, optional second arg non-nil means grow sideways ARG columns.
4118 Interactively, if an argument is not given, make the window one line bigger.
4119 If HORIZONTAL is non-nil, enlarge horizontally instead of vertically.
4120 This function can delete windows, even the second window, if they get
4123 Lisp_Object arg
, horizontal
;
4126 enlarge_window (selected_window
, XINT (arg
), !NILP (horizontal
));
4128 if (! NILP (Vwindow_configuration_change_hook
))
4129 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
4134 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
4135 doc
: /* Make current window ARG lines smaller.
4136 From program, optional second arg non-nil means shrink sideways arg columns.
4137 Interactively, if an argument is not given, make the window one line smaller.
4138 Only siblings to the right or below are changed. */)
4140 Lisp_Object arg
, side
;
4143 enlarge_window (selected_window
, -XINT (arg
), !NILP (side
));
4145 if (! NILP (Vwindow_configuration_change_hook
))
4146 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
4152 window_height (window
)
4155 register struct window
*p
= XWINDOW (window
);
4156 return WINDOW_TOTAL_LINES (p
);
4160 window_width (window
)
4163 register struct window
*p
= XWINDOW (window
);
4164 return WINDOW_TOTAL_COLS (p
);
4169 *(horiz_flag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
4171 #define CURSIZE(w) \
4172 *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
4175 /* Enlarge WINDOW by DELTA.
4176 HORIZ_FLAG nonzero means enlarge it horizontally;
4177 zero means do it vertically.
4179 Siblings of the selected window are resized to fulfill the size
4180 request. If they become too small in the process, they will be
4184 enlarge_window (window
, delta
, horiz_flag
)
4186 int delta
, horiz_flag
;
4188 Lisp_Object parent
, next
, prev
;
4192 int (*sizefun
) P_ ((Lisp_Object
))
4193 = horiz_flag
? window_width
: window_height
;
4194 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
4195 = (horiz_flag
? set_window_width
: set_window_height
);
4197 /* Check values of window_min_width and window_min_height for
4199 check_min_window_sizes ();
4201 /* Give up if this window cannot be resized. */
4202 if (window_fixed_size_p (XWINDOW (window
), horiz_flag
, 1))
4203 error ("Window is not resizable");
4205 /* Find the parent of the selected window. */
4208 p
= XWINDOW (window
);
4214 error ("No other window to side of this one");
4219 ? !NILP (XWINDOW (parent
)->hchild
)
4220 : !NILP (XWINDOW (parent
)->vchild
))
4226 sizep
= &CURSIZE (window
);
4229 register int maxdelta
;
4231 /* Compute the maximum size increment this window can have. */
4233 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - XINT (*sizep
)
4234 /* This is a main window followed by a minibuffer. */
4235 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
4236 - window_min_size (XWINDOW (p
->next
),
4238 /* This is a minibuffer following a main window. */
4239 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
4240 - window_min_size (XWINDOW (p
->prev
),
4242 /* This is a frame with only one window, a minibuffer-only
4243 or a minibufferless frame. */
4246 if (delta
> maxdelta
)
4247 /* This case traps trying to make the minibuffer
4248 the full frame, or make the only window aside from the
4249 minibuffer the full frame. */
4253 if (XINT (*sizep
) + delta
< window_min_size (XWINDOW (window
), horiz_flag
, 0, 0))
4255 delete_window (window
);
4262 /* Find the total we can get from other siblings without deleting them. */
4264 for (next
= p
->next
; ! NILP (next
); next
= XWINDOW (next
)->next
)
4265 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
4267 for (prev
= p
->prev
; ! NILP (prev
); prev
= XWINDOW (prev
)->prev
)
4268 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
4271 /* If we can get it all from them without deleting them, do so. */
4272 if (delta
<= maximum
)
4274 Lisp_Object first_unaffected
;
4275 Lisp_Object first_affected
;
4280 first_affected
= window
;
4281 /* Look at one sibling at a time,
4282 moving away from this window in both directions alternately,
4283 and take as much as we can get without deleting that sibling. */
4285 && (!NILP (next
) || !NILP (prev
)))
4289 int this_one
= ((*sizefun
) (next
)
4290 - window_min_size (XWINDOW (next
),
4291 horiz_flag
, 0, &fixed_p
));
4294 if (this_one
> delta
)
4297 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
4298 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
4303 next
= XWINDOW (next
)->next
;
4311 int this_one
= ((*sizefun
) (prev
)
4312 - window_min_size (XWINDOW (prev
),
4313 horiz_flag
, 0, &fixed_p
));
4316 if (this_one
> delta
)
4319 first_affected
= prev
;
4321 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
4322 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
4327 prev
= XWINDOW (prev
)->prev
;
4331 xassert (delta
== 0);
4333 /* Now recalculate the edge positions of all the windows affected,
4334 based on the new sizes. */
4335 first_unaffected
= next
;
4336 prev
= first_affected
;
4337 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
4338 prev
= next
, next
= XWINDOW (next
)->next
)
4340 XSETINT (CURBEG (next
), XINT (CURBEG (prev
)) + (*sizefun
) (prev
));
4341 /* This does not change size of NEXT,
4342 but it propagates the new top edge to its children */
4343 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
4348 register int delta1
;
4349 register int opht
= (*sizefun
) (parent
);
4351 if (opht
<= XINT (*sizep
) + delta
)
4353 /* If trying to grow this window to or beyond size of the parent,
4354 just delete all the sibling windows. */
4355 Lisp_Object start
, tem
, next
;
4357 start
= XWINDOW (parent
)->vchild
;
4359 start
= XWINDOW (parent
)->hchild
;
4361 /* Delete any siblings that come after WINDOW. */
4362 tem
= XWINDOW (window
)->next
;
4363 while (! NILP (tem
))
4365 next
= XWINDOW (tem
)->next
;
4366 delete_window (tem
);
4370 /* Delete any siblings that come after WINDOW.
4371 Note that if START is not WINDOW, then WINDOW still
4372 Fhas siblings, so WINDOW has not yet replaced its parent. */
4374 while (! EQ (tem
, window
))
4376 next
= XWINDOW (tem
)->next
;
4377 delete_window (tem
);
4383 /* Otherwise, make delta1 just right so that if we add
4384 delta1 lines to this window and to the parent, and then
4385 shrink the parent back to its original size, the new
4386 proportional size of this window will increase by delta.
4388 The function size_window will compute the new height h'
4389 of the window from delta1 as:
4392 x = delta1 - delta1/n * n for the 1st resizable child
4395 where n is the number of children that can be resized.
4396 We can ignore x by choosing a delta1 that is a multiple of
4397 n. We want the height of this window to come out as
4407 The number of children n equals the number of resizable
4408 children of this window + 1 because we know window itself
4409 is resizable (otherwise we would have signalled an error). */
4411 struct window
*w
= XWINDOW (window
);
4415 for (s
= w
->next
; !NILP (s
); s
= XWINDOW (s
)->next
)
4416 if (!window_fixed_size_p (XWINDOW (s
), horiz_flag
, 0))
4418 for (s
= w
->prev
; !NILP (s
); s
= XWINDOW (s
)->prev
)
4419 if (!window_fixed_size_p (XWINDOW (s
), horiz_flag
, 0))
4424 /* Add delta1 lines or columns to this window, and to the parent,
4425 keeping things consistent while not affecting siblings. */
4426 XSETINT (CURSIZE (parent
), opht
+ delta1
);
4427 (*setsizefun
) (window
, XINT (*sizep
) + delta1
, 0);
4429 /* Squeeze out delta1 lines or columns from our parent,
4430 shriking this window and siblings proportionately.
4431 This brings parent back to correct size.
4432 Delta1 was calculated so this makes this window the desired size,
4433 taking it all out of the siblings. */
4434 (*setsizefun
) (parent
, opht
, 0);
4439 XSETFASTINT (p
->last_modified
, 0);
4440 XSETFASTINT (p
->last_overlay_modified
, 0);
4442 /* Adjust glyph matrices. */
4443 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
4447 /* Adjust the size of WINDOW by DELTA, moving only its trailing edge.
4448 HORIZ_FLAG nonzero means adjust the width, moving the right edge.
4449 zero means adjust the height, moving the bottom edge.
4451 Following siblings of the selected window are resized to fulfill
4452 the size request. If they become too small in the process, they
4453 are not deleted; instead, we signal an error. */
4456 adjust_window_trailing_edge (window
, delta
, horiz_flag
)
4458 int delta
, horiz_flag
;
4460 Lisp_Object parent
, child
;
4462 Lisp_Object old_config
= Fcurrent_window_configuration (Qnil
);
4463 int delcount
= window_deletion_count
;
4465 /* Check values of window_min_width and window_min_height for
4467 check_min_window_sizes ();
4470 window
= Fselected_window ();
4472 CHECK_WINDOW (window
);
4474 /* Give up if this window cannot be resized. */
4475 if (window_fixed_size_p (XWINDOW (window
), horiz_flag
, 1))
4476 error ("Window is not resizable");
4480 Lisp_Object first_parallel
= Qnil
;
4484 /* This happens if WINDOW on the previous iteration was
4485 at top level of the window tree. */
4486 Fset_window_configuration (old_config
);
4487 error ("Specified window edge is fixed");
4490 p
= XWINDOW (window
);
4493 /* See if this level has windows in parallel in the specified
4494 direction. If so, set FIRST_PARALLEL to the first one. */
4497 if (! NILP (parent
) && !NILP (XWINDOW (parent
)->vchild
))
4498 first_parallel
= XWINDOW (parent
)->vchild
;
4499 else if (NILP (parent
) && !NILP (p
->next
))
4501 /* Handle the vertical chain of main window and minibuffer
4502 which has no parent. */
4503 first_parallel
= window
;
4504 while (! NILP (XWINDOW (first_parallel
)->prev
))
4505 first_parallel
= XWINDOW (first_parallel
)->prev
;
4510 if (! NILP (parent
) && !NILP (XWINDOW (parent
)->hchild
))
4511 first_parallel
= XWINDOW (parent
)->hchild
;
4514 /* If this level's succession is in the desired dimension,
4515 and this window is the last one, and there is no higher level,
4516 its trailing edge is fixed. */
4517 if (NILP (XWINDOW (window
)->next
) && NILP (first_parallel
)
4520 Fset_window_configuration (old_config
);
4521 error ("Specified window edge is fixed");
4524 /* Don't make this window too small. */
4525 if (XINT (CURSIZE (window
)) + delta
4526 < window_min_size_2 (XWINDOW (window
), horiz_flag
))
4528 Fset_window_configuration (old_config
);
4529 error ("Cannot adjust window size as specified");
4532 /* Clear out some redisplay caches. */
4533 XSETFASTINT (p
->last_modified
, 0);
4534 XSETFASTINT (p
->last_overlay_modified
, 0);
4536 /* Adjust this window's edge. */
4537 XSETINT (CURSIZE (window
),
4538 XINT (CURSIZE (window
)) + delta
);
4540 /* If this window has following siblings in the desired dimension,
4541 make them smaller, and exit the loop.
4543 (If we reach the top of the tree and can never do this,
4544 we will fail and report an error, above.) */
4545 if (NILP (first_parallel
))
4547 if (!NILP (p
->next
))
4549 /* This may happen for the minibuffer. In that case
4550 the window_deletion_count check below does not work. */
4551 if (XINT (CURSIZE (p
->next
)) - delta
<= 0)
4553 Fset_window_configuration (old_config
);
4554 error ("Cannot adjust window size as specified");
4557 XSETINT (CURBEG (p
->next
),
4558 XINT (CURBEG (p
->next
)) + delta
);
4559 size_window (p
->next
, XINT (CURSIZE (p
->next
)) - delta
,
4560 horiz_flag
, 0, 1, 0);
4565 /* Here we have a chain of parallel siblings, in the other dimension.
4566 Change the size of the other siblings. */
4567 for (child
= first_parallel
;
4569 child
= XWINDOW (child
)->next
)
4570 if (! EQ (child
, window
))
4571 size_window (child
, XINT (CURSIZE (child
)) + delta
,
4572 horiz_flag
, 0, 0, 1);
4577 /* If we made a window so small it got deleted,
4578 we failed. Report failure. */
4579 if (delcount
!= window_deletion_count
)
4581 Fset_window_configuration (old_config
);
4582 error ("Cannot adjust window size as specified");
4585 /* Adjust glyph matrices. */
4586 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
4592 DEFUN ("adjust-window-trailing-edge", Fadjust_window_trailing_edge
,
4593 Sadjust_window_trailing_edge
, 3, 3, 0,
4594 doc
: /* Adjust the bottom or right edge of WINDOW by DELTA.
4595 If HORIZONTAL is non-nil, that means adjust the width, moving the right edge.
4596 Otherwise, adjust the height, moving the bottom edge.
4598 Following siblings of the selected window are resized to fulfill
4599 the size request. If they become too small in the process, they
4600 are not deleted; instead, we signal an error. */)
4601 (window
, delta
, horizontal
)
4602 Lisp_Object window
, delta
, horizontal
;
4604 CHECK_NUMBER (delta
);
4605 adjust_window_trailing_edge (window
, XINT (delta
), !NILP (horizontal
));
4607 if (! NILP (Vwindow_configuration_change_hook
))
4608 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
4615 /***********************************************************************
4616 Resizing Mini-Windows
4617 ***********************************************************************/
4619 static void shrink_window_lowest_first
P_ ((struct window
*, int));
4621 enum save_restore_action
4628 static int save_restore_orig_size
P_ ((struct window
*,
4629 enum save_restore_action
));
4631 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
4632 from lowest windows first. */
4635 shrink_window_lowest_first (w
, height
)
4643 xassert (!MINI_WINDOW_P (w
));
4645 /* Set redisplay hints. */
4646 XSETFASTINT (w
->last_modified
, 0);
4647 XSETFASTINT (w
->last_overlay_modified
, 0);
4648 windows_or_buffers_changed
++;
4649 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
4651 old_height
= XFASTINT (w
->total_lines
);
4652 XSETFASTINT (w
->total_lines
, height
);
4654 if (!NILP (w
->hchild
))
4656 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
4658 c
= XWINDOW (child
);
4659 c
->top_line
= w
->top_line
;
4660 shrink_window_lowest_first (c
, height
);
4663 else if (!NILP (w
->vchild
))
4665 Lisp_Object last_child
;
4666 int delta
= old_height
- height
;
4671 /* Find the last child. We are taking space from lowest windows
4672 first, so we iterate over children from the last child
4674 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
4677 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
4678 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
4682 c
= XWINDOW (child
);
4683 this_one
= XFASTINT (c
->total_lines
) - MIN_SAFE_WINDOW_HEIGHT
;
4685 if (this_one
> delta
)
4688 shrink_window_lowest_first (c
, XFASTINT (c
->total_lines
) - this_one
);
4692 /* Compute new positions. */
4693 last_top
= XINT (w
->top_line
);
4694 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
4696 c
= XWINDOW (child
);
4697 c
->top_line
= make_number (last_top
);
4698 shrink_window_lowest_first (c
, XFASTINT (c
->total_lines
));
4699 last_top
+= XFASTINT (c
->total_lines
);
4705 /* Save, restore, or check positions and sizes in the window tree
4706 rooted at W. ACTION says what to do.
4708 If ACTION is CHECK_ORIG_SIZES, check if orig_top_line and
4709 orig_total_lines members are valid for all windows in the window
4710 tree. Value is non-zero if they are valid.
4712 If ACTION is SAVE_ORIG_SIZES, save members top and height in
4713 orig_top_line and orig_total_lines for all windows in the tree.
4715 If ACTION is RESTORE_ORIG_SIZES, restore top and height from values
4716 stored in orig_top_line and orig_total_lines for all windows. */
4719 save_restore_orig_size (w
, action
)
4721 enum save_restore_action action
;
4727 if (!NILP (w
->hchild
))
4729 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
4732 else if (!NILP (w
->vchild
))
4734 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
4740 case CHECK_ORIG_SIZES
:
4741 if (!INTEGERP (w
->orig_top_line
) || !INTEGERP (w
->orig_total_lines
))
4745 case SAVE_ORIG_SIZES
:
4746 w
->orig_top_line
= w
->top_line
;
4747 w
->orig_total_lines
= w
->total_lines
;
4748 XSETFASTINT (w
->last_modified
, 0);
4749 XSETFASTINT (w
->last_overlay_modified
, 0);
4752 case RESTORE_ORIG_SIZES
:
4753 xassert (INTEGERP (w
->orig_top_line
) && INTEGERP (w
->orig_total_lines
));
4754 w
->top_line
= w
->orig_top_line
;
4755 w
->total_lines
= w
->orig_total_lines
;
4756 w
->orig_total_lines
= w
->orig_top_line
= Qnil
;
4757 XSETFASTINT (w
->last_modified
, 0);
4758 XSETFASTINT (w
->last_overlay_modified
, 0);
4765 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
4772 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
4773 without deleting other windows. */
4776 grow_mini_window (w
, delta
)
4780 struct frame
*f
= XFRAME (w
->frame
);
4781 struct window
*root
;
4783 xassert (MINI_WINDOW_P (w
));
4784 xassert (delta
>= 0);
4786 /* Check values of window_min_width and window_min_height for
4788 check_min_window_sizes ();
4790 /* Compute how much we can enlarge the mini-window without deleting
4792 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4795 int min_height
= window_min_size (root
, 0, 0, 0);
4796 if (XFASTINT (root
->total_lines
) - delta
< min_height
)
4797 /* Note that the root window may already be smaller than
4799 delta
= max (0, XFASTINT (root
->total_lines
) - min_height
);
4804 /* Save original window sizes and positions, if not already done. */
4805 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
4806 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
4808 /* Shrink other windows. */
4809 shrink_window_lowest_first (root
, XFASTINT (root
->total_lines
) - delta
);
4811 /* Grow the mini-window. */
4812 w
->top_line
= make_number (XFASTINT (root
->top_line
) + XFASTINT (root
->total_lines
));
4813 w
->total_lines
= make_number (XFASTINT (w
->total_lines
) + delta
);
4814 XSETFASTINT (w
->last_modified
, 0);
4815 XSETFASTINT (w
->last_overlay_modified
, 0);
4822 /* Shrink mini-window W. If there is recorded info about window sizes
4823 before a call to grow_mini_window, restore recorded window sizes.
4824 Otherwise, if the mini-window is higher than 1 line, resize it to 1
4828 shrink_mini_window (w
)
4831 struct frame
*f
= XFRAME (w
->frame
);
4832 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4834 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
4836 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
4838 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4839 windows_or_buffers_changed
= 1;
4841 else if (XFASTINT (w
->total_lines
) > 1)
4843 /* Distribute the additional lines of the mini-window
4844 among the other windows. */
4846 XSETWINDOW (window
, w
);
4847 enlarge_window (window
, 1 - XFASTINT (w
->total_lines
), 0);
4853 /* Mark window cursors off for all windows in the window tree rooted
4854 at W by setting their phys_cursor_on_p flag to zero. Called from
4855 xterm.c, e.g. when a frame is cleared and thereby all cursors on
4856 the frame are cleared. */
4859 mark_window_cursors_off (w
)
4864 if (!NILP (w
->hchild
))
4865 mark_window_cursors_off (XWINDOW (w
->hchild
));
4866 else if (!NILP (w
->vchild
))
4867 mark_window_cursors_off (XWINDOW (w
->vchild
));
4869 w
->phys_cursor_on_p
= 0;
4871 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4876 /* Return number of lines of text (not counting mode lines) in W. */
4879 window_internal_height (w
)
4882 int ht
= XFASTINT (w
->total_lines
);
4884 if (!MINI_WINDOW_P (w
))
4886 if (!NILP (w
->parent
)
4887 || !NILP (w
->vchild
)
4888 || !NILP (w
->hchild
)
4891 || WINDOW_WANTS_MODELINE_P (w
))
4894 if (WINDOW_WANTS_HEADER_LINE_P (w
))
4902 /* Return the number of columns in W.
4903 Don't count columns occupied by scroll bars or the vertical bar
4904 separating W from the sibling to its right. */
4907 window_box_text_cols (w
)
4910 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4911 int width
= XINT (w
->total_cols
);
4913 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
4914 /* Scroll bars occupy a few columns. */
4915 width
-= WINDOW_CONFIG_SCROLL_BAR_COLS (w
);
4916 else if (!FRAME_WINDOW_P (f
)
4917 && !WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
4918 /* The column of `|' characters separating side-by-side windows
4919 occupies one column only. */
4922 if (FRAME_WINDOW_P (f
))
4923 /* On window-systems, fringes and display margins cannot be
4924 used for normal text. */
4925 width
-= (WINDOW_FRINGE_COLS (w
)
4926 + WINDOW_LEFT_MARGIN_COLS (w
)
4927 + WINDOW_RIGHT_MARGIN_COLS (w
));
4933 /************************************************************************
4935 ***********************************************************************/
4937 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
4938 N screen-fulls, which is defined as the height of the window minus
4939 next_screen_context_lines. If WHOLE is zero, scroll up N lines
4940 instead. Negative values of N mean scroll down. NOERROR non-zero
4941 means don't signal an error if we try to move over BEGV or ZV,
4945 window_scroll (window
, n
, whole
, noerror
)
4953 /* If we must, use the pixel-based version which is much slower than
4954 the line-based one but can handle varying line heights. */
4955 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
4956 window_scroll_pixel_based (window
, n
, whole
, noerror
);
4958 window_scroll_line_based (window
, n
, whole
, noerror
);
4964 /* Implementation of window_scroll that works based on pixel line
4965 heights. See the comment of window_scroll for parameter
4969 window_scroll_pixel_based (window
, n
, whole
, noerror
)
4976 struct window
*w
= XWINDOW (window
);
4977 struct text_pos start
;
4978 int this_scroll_margin
;
4979 /* True if we fiddled the window vscroll field without really scrolling. */
4981 int x
, y
, rtop
, rbot
, rowh
, vpos
;
4983 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4985 /* If PT is not visible in WINDOW, move back one half of
4986 the screen. Allow PT to be partially visible, otherwise
4987 something like (scroll-down 1) with PT in the line before
4988 the partially visible one would recenter. */
4990 if (!pos_visible_p (w
, PT
, &x
, &y
, &rtop
, &rbot
, &rowh
, &vpos
))
4992 /* Move backward half the height of the window. Performance note:
4993 vmotion used here is about 10% faster, but would give wrong
4994 results for variable height lines. */
4995 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4996 it
.current_y
= it
.last_visible_y
;
4997 move_it_vertically_backward (&it
, window_box_height (w
) / 2);
4999 /* The function move_iterator_vertically may move over more than
5000 the specified y-distance. If it->w is small, e.g. a
5001 mini-buffer window, we may end up in front of the window's
5002 display area. This is the case when Start displaying at the
5003 start of the line containing PT in this case. */
5004 if (it
.current_y
<= 0)
5006 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
5007 move_it_vertically_backward (&it
, 0);
5011 start
= it
.current
.pos
;
5013 else if (auto_window_vscroll_p
)
5015 if (rtop
|| rbot
) /* partially visible */
5018 int dy
= WINDOW_FRAME_LINE_HEIGHT (w
);
5020 dy
= max ((window_box_height (w
)
5021 - next_screen_context_lines
* dy
),
5027 /* Only vscroll backwards if already vscrolled forwards. */
5028 if (w
->vscroll
< 0 && rtop
> 0)
5030 px
= max (0, -w
->vscroll
- min (rtop
, -dy
));
5031 Fset_window_vscroll (window
, make_number (px
), Qt
);
5037 /* Do vscroll if already vscrolled or only display line. */
5038 if (rbot
> 0 && (w
->vscroll
< 0 || vpos
== 0))
5040 px
= max (0, -w
->vscroll
+ min (rbot
, dy
));
5041 Fset_window_vscroll (window
, make_number (px
), Qt
);
5045 /* Maybe modify window start instead of scrolling. */
5046 if (rbot
> 0 || w
->vscroll
< 0)
5050 Fset_window_vscroll (window
, make_number (0), Qt
);
5051 /* If there are other text lines above the current row,
5052 move window start to current row. Else to next row. */
5054 spos
= XINT (Fline_beginning_position (Qnil
));
5056 spos
= min (XINT (Fline_end_position (Qnil
)) + 1, ZV
);
5057 set_marker_restricted (w
->start
, make_number (spos
),
5059 w
->start_at_line_beg
= Qt
;
5060 w
->update_mode_line
= Qt
;
5061 XSETFASTINT (w
->last_modified
, 0);
5062 XSETFASTINT (w
->last_overlay_modified
, 0);
5063 /* Set force_start so that redisplay_window will run the
5064 window-scroll-functions. */
5065 w
->force_start
= Qt
;
5070 /* Cancel previous vscroll. */
5071 Fset_window_vscroll (window
, make_number (0), Qt
);
5074 /* If scroll_preserve_screen_position is non-nil, we try to set
5075 point in the same window line as it is now, so get that line. */
5076 if (!NILP (Vscroll_preserve_screen_position
))
5078 /* We preserve the goal pixel coordinate across consecutive
5079 calls to scroll-up or scroll-down. This avoids the
5080 possibility of point becoming "stuck" on a tall line when
5081 scrolling by one line. */
5082 if (window_scroll_pixel_based_preserve_y
< 0
5083 || (!EQ (current_kboard
->Vlast_command
, Qscroll_up
)
5084 && !EQ (current_kboard
->Vlast_command
, Qscroll_down
)))
5086 start_display (&it
, w
, start
);
5087 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
5088 window_scroll_pixel_based_preserve_y
= it
.current_y
;
5092 window_scroll_pixel_based_preserve_y
= -1;
5094 /* Move iterator it from start the specified distance forward or
5095 backward. The result is the new window start. */
5096 start_display (&it
, w
, start
);
5099 int start_pos
= IT_CHARPOS (it
);
5100 int dy
= WINDOW_FRAME_LINE_HEIGHT (w
);
5101 dy
= max ((window_box_height (w
)
5102 - next_screen_context_lines
* dy
),
5105 /* Note that move_it_vertically always moves the iterator to the
5106 start of a line. So, if the last line doesn't have a newline,
5107 we would end up at the start of the line ending at ZV. */
5110 move_it_vertically_backward (&it
, -dy
);
5111 /* Ensure we actually do move, e.g. in case we are currently
5112 looking at an image that is taller that the window height. */
5113 while (start_pos
== IT_CHARPOS (it
)
5114 && start_pos
> BEGV
)
5115 move_it_by_lines (&it
, -1, 1);
5119 move_it_to (&it
, ZV
, -1, it
.current_y
+ dy
, -1,
5120 MOVE_TO_POS
| MOVE_TO_Y
);
5121 /* Ensure we actually do move, e.g. in case we are currently
5122 looking at an image that is taller that the window height. */
5123 while (start_pos
== IT_CHARPOS (it
)
5125 move_it_by_lines (&it
, 1, 1);
5129 move_it_by_lines (&it
, n
, 1);
5131 /* We failed if we find ZV is already on the screen (scrolling up,
5132 means there's nothing past the end), or if we can't start any
5133 earlier (scrolling down, means there's nothing past the top). */
5134 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
5135 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
5137 if (IT_CHARPOS (it
) == ZV
)
5139 if (it
.current_y
< it
.last_visible_y
5140 && (it
.current_y
+ it
.max_ascent
+ it
.max_descent
5141 > it
.last_visible_y
))
5143 /* The last line was only partially visible, make it fully
5145 w
->vscroll
= (it
.last_visible_y
5146 - it
.current_y
+ it
.max_ascent
+ it
.max_descent
);
5147 adjust_glyphs (it
.f
);
5151 else if (n
< 0) /* could happen with empty buffers */
5152 xsignal0 (Qbeginning_of_buffer
);
5154 xsignal0 (Qend_of_buffer
);
5158 if (w
->vscroll
!= 0)
5159 /* The first line was only partially visible, make it fully
5165 xsignal0 (Qbeginning_of_buffer
);
5168 /* If control gets here, then we vscrolled. */
5170 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
5172 /* Don't try to change the window start below. */
5178 int pos
= IT_CHARPOS (it
);
5181 /* If in the middle of a multi-glyph character move forward to
5182 the next character. */
5183 if (in_display_vector_p (&it
))
5186 move_it_to (&it
, pos
, -1, -1, -1, MOVE_TO_POS
);
5189 /* Set the window start, and set up the window for redisplay. */
5190 set_marker_restricted (w
->start
, make_number (pos
),
5192 bytepos
= XMARKER (w
->start
)->bytepos
;
5193 w
->start_at_line_beg
= ((pos
== BEGV
|| FETCH_BYTE (bytepos
- 1) == '\n')
5195 w
->update_mode_line
= Qt
;
5196 XSETFASTINT (w
->last_modified
, 0);
5197 XSETFASTINT (w
->last_overlay_modified
, 0);
5198 /* Set force_start so that redisplay_window will run the
5199 window-scroll-functions. */
5200 w
->force_start
= Qt
;
5203 /* The rest of this function uses current_y in a nonstandard way,
5204 not including the height of the header line if any. */
5205 it
.current_y
= it
.vpos
= 0;
5207 /* Move PT out of scroll margins.
5208 This code wants current_y to be zero at the window start position
5209 even if there is a header line. */
5210 this_scroll_margin
= max (0, scroll_margin
);
5211 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->total_lines
) / 4);
5212 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
5216 /* We moved the window start towards ZV, so PT may be now
5217 in the scroll margin at the top. */
5218 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
5219 if (IT_CHARPOS (it
) == PT
&& it
.current_y
>= this_scroll_margin
5220 && (NILP (Vscroll_preserve_screen_position
)
5221 || EQ (Vscroll_preserve_screen_position
, Qt
)))
5222 /* We found PT at a legitimate height. Leave it alone. */
5224 else if (window_scroll_pixel_based_preserve_y
>= 0)
5226 /* If we have a header line, take account of it.
5227 This is necessary because we set it.current_y to 0, above. */
5228 move_it_to (&it
, -1, -1,
5229 window_scroll_pixel_based_preserve_y
5230 - (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0 ),
5232 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5236 while (it
.current_y
< this_scroll_margin
)
5238 int prev
= it
.current_y
;
5239 move_it_by_lines (&it
, 1, 1);
5240 if (prev
== it
.current_y
)
5243 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5248 int charpos
, bytepos
;
5251 /* Save our position, for the
5252 window_scroll_pixel_based_preserve_y case. */
5253 charpos
= IT_CHARPOS (it
);
5254 bytepos
= IT_BYTEPOS (it
);
5256 /* We moved the window start towards BEGV, so PT may be now
5257 in the scroll margin at the bottom. */
5258 move_it_to (&it
, PT
, -1,
5259 (it
.last_visible_y
- CURRENT_HEADER_LINE_HEIGHT (w
)
5260 - this_scroll_margin
- 1),
5262 MOVE_TO_POS
| MOVE_TO_Y
);
5264 /* Save our position, in case it's correct. */
5265 charpos
= IT_CHARPOS (it
);
5266 bytepos
= IT_BYTEPOS (it
);
5268 /* See if point is on a partially visible line at the end. */
5269 if (it
.what
== IT_EOB
)
5270 partial_p
= it
.current_y
+ it
.ascent
+ it
.descent
> it
.last_visible_y
;
5273 move_it_by_lines (&it
, 1, 1);
5274 partial_p
= it
.current_y
> it
.last_visible_y
;
5277 if (charpos
== PT
&& !partial_p
5278 && (NILP (Vscroll_preserve_screen_position
)
5279 || EQ (Vscroll_preserve_screen_position
, Qt
)))
5280 /* We found PT before we found the display margin, so PT is ok. */
5282 else if (window_scroll_pixel_based_preserve_y
>= 0)
5284 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
5285 start_display (&it
, w
, start
);
5286 /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT
5287 here because we called start_display again and did not
5288 alter it.current_y this time. */
5289 move_it_to (&it
, -1, -1, window_scroll_pixel_based_preserve_y
, -1,
5291 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5296 /* The last line was only partially visible, so back up two
5297 lines to make sure we're on a fully visible line. */
5299 move_it_by_lines (&it
, -2, 0);
5300 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5303 /* No, the position we saved is OK, so use it. */
5304 SET_PT_BOTH (charpos
, bytepos
);
5310 /* Implementation of window_scroll that works based on screen lines.
5311 See the comment of window_scroll for parameter descriptions. */
5314 window_scroll_line_based (window
, n
, whole
, noerror
)
5320 register struct window
*w
= XWINDOW (window
);
5321 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
5322 register int pos
, pos_byte
;
5323 register int ht
= window_internal_height (w
);
5324 register Lisp_Object tem
;
5328 struct position posit
;
5331 /* If scrolling screen-fulls, compute the number of lines to
5332 scroll from the window's height. */
5334 n
*= max (1, ht
- next_screen_context_lines
);
5336 startpos
= marker_position (w
->start
);
5338 posit
= *compute_motion (startpos
, 0, 0, 0,
5340 -1, XINT (w
->hscroll
),
5342 original_vpos
= posit
.vpos
;
5344 XSETFASTINT (tem
, PT
);
5345 tem
= Fpos_visible_in_window_p (tem
, window
, Qnil
);
5349 Fvertical_motion (make_number (- (ht
/ 2)), window
);
5354 lose
= n
< 0 && PT
== BEGV
;
5355 Fvertical_motion (make_number (n
), window
);
5359 SET_PT_BOTH (opoint
, opoint_byte
);
5366 xsignal0 (Qbeginning_of_buffer
);
5371 int this_scroll_margin
= scroll_margin
;
5373 /* Don't use a scroll margin that is negative or too large. */
5374 if (this_scroll_margin
< 0)
5375 this_scroll_margin
= 0;
5377 if (XINT (w
->total_lines
) < 4 * scroll_margin
)
5378 this_scroll_margin
= XINT (w
->total_lines
) / 4;
5380 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
5381 w
->start_at_line_beg
= bolp
;
5382 w
->update_mode_line
= Qt
;
5383 XSETFASTINT (w
->last_modified
, 0);
5384 XSETFASTINT (w
->last_overlay_modified
, 0);
5385 /* Set force_start so that redisplay_window will run
5386 the window-scroll-functions. */
5387 w
->force_start
= Qt
;
5389 if (!NILP (Vscroll_preserve_screen_position
)
5390 && (whole
|| !EQ (Vscroll_preserve_screen_position
, Qt
)))
5392 SET_PT_BOTH (pos
, pos_byte
);
5393 Fvertical_motion (make_number (original_vpos
), window
);
5395 /* If we scrolled forward, put point enough lines down
5396 that it is outside the scroll margin. */
5401 if (this_scroll_margin
> 0)
5403 SET_PT_BOTH (pos
, pos_byte
);
5404 Fvertical_motion (make_number (this_scroll_margin
), window
);
5410 if (top_margin
<= opoint
)
5411 SET_PT_BOTH (opoint
, opoint_byte
);
5412 else if (!NILP (Vscroll_preserve_screen_position
))
5414 SET_PT_BOTH (pos
, pos_byte
);
5415 Fvertical_motion (make_number (original_vpos
), window
);
5418 SET_PT (top_margin
);
5424 /* If we scrolled backward, put point near the end of the window
5425 but not within the scroll margin. */
5426 SET_PT_BOTH (pos
, pos_byte
);
5427 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
5428 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
5431 bottom_margin
= PT
+ 1;
5433 if (bottom_margin
> opoint
)
5434 SET_PT_BOTH (opoint
, opoint_byte
);
5437 if (!NILP (Vscroll_preserve_screen_position
))
5439 SET_PT_BOTH (pos
, pos_byte
);
5440 Fvertical_motion (make_number (original_vpos
), window
);
5443 Fvertical_motion (make_number (-1), window
);
5452 xsignal0 (Qend_of_buffer
);
5457 /* Scroll selected_window up or down. If N is nil, scroll a
5458 screen-full which is defined as the height of the window minus
5459 next_screen_context_lines. If N is the symbol `-', scroll.
5460 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
5461 up. This is the guts of Fscroll_up and Fscroll_down. */
5464 scroll_command (n
, direction
)
5468 int count
= SPECPDL_INDEX ();
5470 xassert (abs (direction
) == 1);
5472 /* If selected window's buffer isn't current, make it current for
5473 the moment. But don't screw up if window_scroll gets an error. */
5474 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
5476 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
5477 Fset_buffer (XWINDOW (selected_window
)->buffer
);
5479 /* Make redisplay consider other windows than just selected_window. */
5480 ++windows_or_buffers_changed
;
5484 window_scroll (selected_window
, direction
, 1, 0);
5485 else if (EQ (n
, Qminus
))
5486 window_scroll (selected_window
, -direction
, 1, 0);
5489 n
= Fprefix_numeric_value (n
);
5490 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
5493 unbind_to (count
, Qnil
);
5496 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
5497 doc
: /* Scroll text of current window upward ARG lines.
5498 If ARG is omitted or nil, scroll upward by a near full screen.
5499 A near full screen is `next-screen-context-lines' less than a full screen.
5500 Negative ARG means scroll downward.
5501 If ARG is the atom `-', scroll downward by nearly full screen.
5502 When calling from a program, supply as argument a number, nil, or `-'. */)
5506 scroll_command (arg
, 1);
5510 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
5511 doc
: /* Scroll text of current window down ARG lines.
5512 If ARG is omitted or nil, scroll down by a near full screen.
5513 A near full screen is `next-screen-context-lines' less than a full screen.
5514 Negative ARG means scroll upward.
5515 If ARG is the atom `-', scroll upward by nearly full screen.
5516 When calling from a program, supply as argument a number, nil, or `-'. */)
5520 scroll_command (arg
, -1);
5524 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
5525 doc
: /* Return the other window for \"other window scroll\" commands.
5526 If `other-window-scroll-buffer' is non-nil, a window
5527 showing that buffer is used.
5528 If in the minibuffer, `minibuffer-scroll-window' if non-nil
5529 specifies the window. This takes precedence over
5530 `other-window-scroll-buffer'. */)
5535 if (MINI_WINDOW_P (XWINDOW (selected_window
))
5536 && !NILP (Vminibuf_scroll_window
))
5537 window
= Vminibuf_scroll_window
;
5538 /* If buffer is specified, scroll that buffer. */
5539 else if (!NILP (Vother_window_scroll_buffer
))
5541 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
5543 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
5547 /* Nothing specified; look for a neighboring window on the same
5549 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
5551 if (EQ (window
, selected_window
))
5552 /* That didn't get us anywhere; look for a window on another
5555 window
= Fnext_window (window
, Qnil
, Qt
);
5556 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
5557 && ! EQ (window
, selected_window
));
5560 CHECK_LIVE_WINDOW (window
);
5562 if (EQ (window
, selected_window
))
5563 error ("There is no other window");
5568 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
5569 doc
: /* Scroll next window upward ARG lines; or near full screen if no ARG.
5570 A near full screen is `next-screen-context-lines' less than a full screen.
5571 The next window is the one below the current one; or the one at the top
5572 if the current one is at the bottom. Negative ARG means scroll downward.
5573 If ARG is the atom `-', scroll downward by nearly full screen.
5574 When calling from a program, supply as argument a number, nil, or `-'.
5576 If `other-window-scroll-buffer' is non-nil, scroll the window
5577 showing that buffer, popping the buffer up if necessary.
5578 If in the minibuffer, `minibuffer-scroll-window' if non-nil
5579 specifies the window to scroll. This takes precedence over
5580 `other-window-scroll-buffer'. */)
5586 int count
= SPECPDL_INDEX ();
5588 window
= Fother_window_for_scrolling ();
5589 w
= XWINDOW (window
);
5591 /* Don't screw up if window_scroll gets an error. */
5592 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
5593 ++windows_or_buffers_changed
;
5595 Fset_buffer (w
->buffer
);
5596 SET_PT (marker_position (w
->pointm
));
5599 window_scroll (window
, 1, 1, 1);
5600 else if (EQ (arg
, Qminus
))
5601 window_scroll (window
, -1, 1, 1);
5607 window_scroll (window
, XINT (arg
), 0, 1);
5610 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
5611 unbind_to (count
, Qnil
);
5616 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 2, "P\np",
5617 doc
: /* Scroll selected window display ARG columns left.
5618 Default for ARG is window width minus 2.
5619 Value is the total amount of leftward horizontal scrolling in
5620 effect after the change.
5621 If SET_MINIMUM is non-nil, the new scroll amount becomes the
5622 lower bound for automatic scrolling, i.e. automatic scrolling
5623 will not scroll a window to a column less than the value returned
5624 by this function. This happens in an interactive call. */)
5626 register Lisp_Object arg
, set_minimum
;
5630 struct window
*w
= XWINDOW (selected_window
);
5633 XSETFASTINT (arg
, window_box_text_cols (w
) - 2);
5635 arg
= Fprefix_numeric_value (arg
);
5637 hscroll
= XINT (w
->hscroll
) + XINT (arg
);
5638 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
5640 if (!NILP (set_minimum
))
5641 w
->min_hscroll
= w
->hscroll
;
5646 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 2, "P\np",
5647 doc
: /* Scroll selected window display ARG columns right.
5648 Default for ARG is window width minus 2.
5649 Value is the total amount of leftward horizontal scrolling in
5650 effect after the change.
5651 If SET_MINIMUM is non-nil, the new scroll amount becomes the
5652 lower bound for automatic scrolling, i.e. automatic scrolling
5653 will not scroll a window to a column less than the value returned
5654 by this function. This happens in an interactive call. */)
5656 register Lisp_Object arg
, set_minimum
;
5660 struct window
*w
= XWINDOW (selected_window
);
5663 XSETFASTINT (arg
, window_box_text_cols (w
) - 2);
5665 arg
= Fprefix_numeric_value (arg
);
5667 hscroll
= XINT (w
->hscroll
) - XINT (arg
);
5668 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
5670 if (!NILP (set_minimum
))
5671 w
->min_hscroll
= w
->hscroll
;
5676 DEFUN ("minibuffer-selected-window", Fminibuffer_selected_window
, Sminibuffer_selected_window
, 0, 0, 0,
5677 doc
: /* Return the window which was selected when entering the minibuffer.
5678 Returns nil, if current window is not a minibuffer window. */)
5681 if (minibuf_level
> 0
5682 && MINI_WINDOW_P (XWINDOW (selected_window
))
5683 && WINDOW_LIVE_P (minibuf_selected_window
))
5684 return minibuf_selected_window
;
5689 /* Value is the number of lines actually displayed in window W,
5690 as opposed to its height. */
5693 displayed_window_lines (w
)
5697 struct text_pos start
;
5698 int height
= window_box_height (w
);
5699 struct buffer
*old_buffer
;
5702 if (XBUFFER (w
->buffer
) != current_buffer
)
5704 old_buffer
= current_buffer
;
5705 set_buffer_internal (XBUFFER (w
->buffer
));
5710 /* In case W->start is out of the accessible range, do something
5711 reasonable. This happens in Info mode when Info-scroll-down
5712 calls (recenter -1) while W->start is 1. */
5713 if (XMARKER (w
->start
)->charpos
< BEGV
)
5714 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
5715 else if (XMARKER (w
->start
)->charpos
> ZV
)
5716 SET_TEXT_POS (start
, ZV
, ZV_BYTE
);
5718 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
5720 start_display (&it
, w
, start
);
5721 move_it_vertically (&it
, height
);
5722 bottom_y
= line_bottom_y (&it
);
5724 /* rms: On a non-window display,
5725 the value of it.vpos at the bottom of the screen
5726 seems to be 1 larger than window_box_height (w).
5727 This kludge fixes a bug whereby (move-to-window-line -1)
5728 when ZV is on the last screen line
5729 moves to the previous screen line instead of the last one. */
5730 if (! FRAME_WINDOW_P (XFRAME (w
->frame
)))
5733 /* Add in empty lines at the bottom of the window. */
5734 if (bottom_y
< height
)
5736 int uy
= FRAME_LINE_HEIGHT (it
.f
);
5737 it
.vpos
+= (height
- bottom_y
+ uy
- 1) / uy
;
5741 set_buffer_internal (old_buffer
);
5747 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
5748 doc
: /* Center point in window and redisplay frame.
5749 With prefix argument ARG, recenter putting point on screen line ARG
5750 relative to the current window. If ARG is negative, it counts up from the
5751 bottom of the window. (ARG should be less than the height of the window.)
5753 If ARG is omitted or nil, erase the entire frame and then redraw with point
5754 in the center of the current window. If `auto-resize-tool-bars' is set to
5755 `grow-only', this resets the tool-bar's height to the minimum height needed.
5757 Just C-u as prefix means put point in the center of the window
5758 and redisplay normally--don't erase and redraw the frame. */)
5760 register Lisp_Object arg
;
5762 struct window
*w
= XWINDOW (selected_window
);
5763 struct buffer
*buf
= XBUFFER (w
->buffer
);
5764 struct buffer
*obuf
= current_buffer
;
5766 int charpos
, bytepos
;
5768 int this_scroll_margin
;
5770 /* If redisplay is suppressed due to an error, try again. */
5771 obuf
->display_error_modiff
= 0;
5777 /* Invalidate pixel data calculated for all compositions. */
5778 for (i
= 0; i
< n_compositions
; i
++)
5779 composition_table
[i
]->font
= NULL
;
5781 WINDOW_XFRAME (w
)->minimize_tool_bar_window_p
= 1;
5783 Fredraw_frame (WINDOW_FRAME (w
));
5784 SET_FRAME_GARBAGED (WINDOW_XFRAME (w
));
5787 else if (CONSP (arg
)) /* Just C-u. */
5791 arg
= Fprefix_numeric_value (arg
);
5796 set_buffer_internal (buf
);
5798 /* Do this after making BUF current
5799 in case scroll_margin is buffer-local. */
5800 this_scroll_margin
= max (0, scroll_margin
);
5801 this_scroll_margin
= min (this_scroll_margin
,
5802 XFASTINT (w
->total_lines
) / 4);
5804 /* Handle centering on a graphical frame specially. Such frames can
5805 have variable-height lines and centering point on the basis of
5806 line counts would lead to strange effects. */
5807 if (FRAME_WINDOW_P (XFRAME (w
->frame
)))
5814 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
5815 start_display (&it
, w
, pt
);
5816 move_it_vertically_backward (&it
, window_box_height (w
) / 2);
5817 charpos
= IT_CHARPOS (it
);
5818 bytepos
= IT_BYTEPOS (it
);
5825 int extra_line_spacing
;
5826 int h
= window_box_height (w
);
5828 iarg
= - max (-iarg
, this_scroll_margin
);
5830 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
5831 start_display (&it
, w
, pt
);
5833 /* Be sure we have the exact height of the full line containing PT. */
5834 move_it_by_lines (&it
, 0, 1);
5836 /* The amount of pixels we have to move back is the window
5837 height minus what's displayed in the line containing PT,
5838 and the lines below. */
5841 move_it_by_lines (&it
, nlines
, 1);
5843 if (it
.vpos
== nlines
)
5847 /* Last line has no newline */
5848 h
-= line_bottom_y (&it
);
5852 /* Don't reserve space for extra line spacing of last line. */
5853 extra_line_spacing
= it
.max_extra_line_spacing
;
5855 /* If we can't move down NLINES lines because we hit
5856 the end of the buffer, count in some empty lines. */
5857 if (it
.vpos
< nlines
)
5860 extra_line_spacing
= it
.extra_line_spacing
;
5861 h
-= nlines
* (FRAME_LINE_HEIGHT (it
.f
) + extra_line_spacing
);
5866 /* Now find the new top line (starting position) of the window. */
5867 start_display (&it
, w
, pt
);
5869 move_it_vertically_backward (&it
, h
);
5871 /* If extra line spacing is present, we may move too far
5872 back. This causes the last line to be only partially
5873 visible (which triggers redisplay to recenter that line
5874 in the middle), so move forward.
5875 But ignore extra line spacing on last line, as it is not
5876 considered to be part of the visible height of the line.
5878 h
+= extra_line_spacing
;
5879 while (-it
.current_y
> h
)
5880 move_it_by_lines (&it
, 1, 1);
5882 charpos
= IT_CHARPOS (it
);
5883 bytepos
= IT_BYTEPOS (it
);
5887 struct position pos
;
5889 iarg
= max (iarg
, this_scroll_margin
);
5891 pos
= *vmotion (PT
, -iarg
, w
);
5892 charpos
= pos
.bufpos
;
5893 bytepos
= pos
.bytepos
;
5898 struct position pos
;
5899 int ht
= window_internal_height (w
);
5906 /* Don't let it get into the margin at either top or bottom. */
5907 iarg
= max (iarg
, this_scroll_margin
);
5908 iarg
= min (iarg
, ht
- this_scroll_margin
- 1);
5910 pos
= *vmotion (PT
, - iarg
, w
);
5911 charpos
= pos
.bufpos
;
5912 bytepos
= pos
.bytepos
;
5915 /* Set the new window start. */
5916 set_marker_both (w
->start
, w
->buffer
, charpos
, bytepos
);
5917 w
->window_end_valid
= Qnil
;
5919 w
->optional_new_start
= Qt
;
5921 if (bytepos
== BEGV_BYTE
|| FETCH_BYTE (bytepos
- 1) == '\n')
5922 w
->start_at_line_beg
= Qt
;
5924 w
->start_at_line_beg
= Qnil
;
5926 set_buffer_internal (obuf
);
5931 DEFUN ("window-text-height", Fwindow_text_height
, Swindow_text_height
,
5933 doc
: /* Return the height in lines of the text display area of WINDOW.
5934 WINDOW defaults to the selected window.
5935 This doesn't include the mode-line (or header-line if any) or any
5936 partial-height lines in the text display area. */)
5940 struct window
*w
= decode_window (window
);
5941 int pixel_height
= window_box_height (w
);
5942 int line_height
= pixel_height
/ FRAME_LINE_HEIGHT (XFRAME (w
->frame
));
5943 return make_number (line_height
);
5948 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
5950 doc
: /* Position point relative to window.
5951 With no argument, position point at center of window.
5952 An argument specifies vertical position within the window;
5953 zero means top of window, negative means relative to bottom of window. */)
5957 struct window
*w
= XWINDOW (selected_window
);
5961 int this_scroll_margin
;
5964 window
= selected_window
;
5965 start
= marker_position (w
->start
);
5966 if (start
< BEGV
|| start
> ZV
)
5968 int height
= window_internal_height (w
);
5969 Fvertical_motion (make_number (- (height
/ 2)), window
);
5970 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
5971 w
->start_at_line_beg
= Fbolp ();
5972 w
->force_start
= Qt
;
5975 Fgoto_char (w
->start
);
5977 lines
= displayed_window_lines (w
);
5980 this_scroll_margin
= max (0, scroll_margin
);
5981 this_scroll_margin
= min (this_scroll_margin
, lines
/ 4);
5985 XSETFASTINT (arg
, lines
/ 2);
5988 int iarg
= XINT (Fprefix_numeric_value (arg
));
5991 iarg
= iarg
+ lines
;
5993 #if 0 /* This code would prevent move-to-window-line from moving point
5994 to a place inside the scroll margins (which would cause the
5995 next redisplay to scroll). I wrote this code, but then concluded
5996 it is probably better not to install it. However, it is here
5997 inside #if 0 so as not to lose it. -- rms. */
5999 /* Don't let it get into the margin at either top or bottom. */
6000 iarg
= max (iarg
, this_scroll_margin
);
6001 iarg
= min (iarg
, lines
- this_scroll_margin
- 1);
6004 arg
= make_number (iarg
);
6007 /* Skip past a partially visible first line. */
6009 XSETINT (arg
, XINT (arg
) + 1);
6011 return Fvertical_motion (arg
, window
);
6016 /***********************************************************************
6017 Window Configuration
6018 ***********************************************************************/
6020 struct save_window_data
6022 EMACS_INT size_from_Lisp_Vector_struct
;
6023 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
6024 Lisp_Object frame_cols
, frame_lines
, frame_menu_bar_lines
;
6025 Lisp_Object frame_tool_bar_lines
;
6026 Lisp_Object selected_frame
;
6027 Lisp_Object current_window
;
6028 Lisp_Object current_buffer
;
6029 Lisp_Object minibuf_scroll_window
;
6030 Lisp_Object minibuf_selected_window
;
6031 Lisp_Object root_window
;
6032 Lisp_Object focus_frame
;
6033 /* Record the values of window-min-width and window-min-height
6034 so that window sizes remain consistent with them. */
6035 Lisp_Object min_width
, min_height
;
6036 /* A vector, each of whose elements is a struct saved_window
6038 Lisp_Object saved_windows
;
6041 /* This is saved as a Lisp_Vector */
6044 /* these first two must agree with struct Lisp_Vector in lisp.h */
6045 EMACS_INT size_from_Lisp_Vector_struct
;
6046 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
6049 Lisp_Object buffer
, start
, pointm
, mark
;
6050 Lisp_Object left_col
, top_line
, total_cols
, total_lines
;
6051 Lisp_Object hscroll
, min_hscroll
;
6052 Lisp_Object parent
, prev
;
6053 Lisp_Object start_at_line_beg
;
6054 Lisp_Object display_table
;
6055 Lisp_Object orig_top_line
, orig_total_lines
;
6056 Lisp_Object left_margin_cols
, right_margin_cols
;
6057 Lisp_Object left_fringe_width
, right_fringe_width
, fringes_outside_margins
;
6058 Lisp_Object scroll_bar_width
, vertical_scroll_bar_type
;
6059 Lisp_Object dedicated
;
6062 #define SAVED_WINDOW_N(swv,n) \
6063 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
6065 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
6066 doc
: /* Return t if OBJECT is a window-configuration object. */)
6070 return WINDOW_CONFIGURATIONP (object
) ? Qt
: Qnil
;
6073 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
6074 doc
: /* Return the frame that CONFIG, a window-configuration object, is about. */)
6078 register struct save_window_data
*data
;
6079 struct Lisp_Vector
*saved_windows
;
6081 CHECK_WINDOW_CONFIGURATION (config
);
6083 data
= (struct save_window_data
*) XVECTOR (config
);
6084 saved_windows
= XVECTOR (data
->saved_windows
);
6085 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
6088 DEFUN ("set-window-configuration", Fset_window_configuration
,
6089 Sset_window_configuration
, 1, 1, 0,
6090 doc
: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
6091 CONFIGURATION must be a value previously returned
6092 by `current-window-configuration' (which see).
6093 If CONFIGURATION was made from a frame that is now deleted,
6094 only frame-independent values can be restored. In this case,
6095 the return value is nil. Otherwise the value is t. */)
6097 Lisp_Object configuration
;
6099 register struct save_window_data
*data
;
6100 struct Lisp_Vector
*saved_windows
;
6101 Lisp_Object new_current_buffer
;
6106 CHECK_WINDOW_CONFIGURATION (configuration
);
6108 data
= (struct save_window_data
*) XVECTOR (configuration
);
6109 saved_windows
= XVECTOR (data
->saved_windows
);
6111 new_current_buffer
= data
->current_buffer
;
6112 if (NILP (XBUFFER (new_current_buffer
)->name
))
6113 new_current_buffer
= Qnil
;
6116 if (XBUFFER (new_current_buffer
) == current_buffer
)
6117 /* The code further down "preserves point" by saving here PT in
6118 old_point and then setting it later back into PT. When the
6119 current-selected-window and the final-selected-window both show
6120 the current buffer, this suffers from the problem that the
6121 current PT is the window-point of the current-selected-window,
6122 while the final PT is the point of the final-selected-window, so
6123 this copy from one PT to the other would end up moving the
6124 window-point of the final-selected-window to the window-point of
6125 the current-selected-window. So we have to be careful which
6126 point of the current-buffer we copy into old_point. */
6127 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
)
6128 && WINDOWP (selected_window
)
6129 && EQ (XWINDOW (selected_window
)->buffer
, new_current_buffer
)
6130 && !EQ (selected_window
, data
->current_window
))
6131 old_point
= XMARKER (XWINDOW (data
->current_window
)->pointm
)->charpos
;
6135 /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of
6136 point in new_current_buffer as of the last time this buffer was
6137 used. This can be non-deterministic since it can be changed by
6138 things like jit-lock by mere temporary selection of some random
6139 window that happens to show this buffer.
6140 So if possible we want this arbitrary choice of "which point" to
6141 be the one from the to-be-selected-window so as to prevent this
6142 window's cursor from being copied from another window. */
6143 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
)
6144 /* If current_window = selected_window, its point is in BUF_PT. */
6145 && !EQ (selected_window
, data
->current_window
))
6146 old_point
= XMARKER (XWINDOW (data
->current_window
)->pointm
)->charpos
;
6148 old_point
= BUF_PT (XBUFFER (new_current_buffer
));
6151 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
6154 /* If f is a dead frame, don't bother rebuilding its window tree.
6155 However, there is other stuff we should still try to do below. */
6156 if (FRAME_LIVE_P (f
))
6158 register struct window
*w
;
6159 register struct saved_window
*p
;
6160 struct window
*root_window
;
6161 struct window
**leaf_windows
;
6165 /* If the frame has been resized since this window configuration was
6166 made, we change the frame to the size specified in the
6167 configuration, restore the configuration, and then resize it
6168 back. We keep track of the prevailing height in these variables. */
6169 int previous_frame_lines
= FRAME_LINES (f
);
6170 int previous_frame_cols
= FRAME_COLS (f
);
6171 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
6172 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
6174 /* The mouse highlighting code could get screwed up
6175 if it runs during this. */
6178 if (XFASTINT (data
->frame_lines
) != previous_frame_lines
6179 || XFASTINT (data
->frame_cols
) != previous_frame_cols
)
6180 change_frame_size (f
, XFASTINT (data
->frame_lines
),
6181 XFASTINT (data
->frame_cols
), 0, 0, 0);
6182 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
6183 if (XFASTINT (data
->frame_menu_bar_lines
)
6184 != previous_frame_menu_bar_lines
)
6185 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, make_number (0));
6186 #ifdef HAVE_WINDOW_SYSTEM
6187 if (XFASTINT (data
->frame_tool_bar_lines
)
6188 != previous_frame_tool_bar_lines
)
6189 x_set_tool_bar_lines (f
, data
->frame_tool_bar_lines
, make_number (0));
6193 /* "Swap out" point from the selected window's buffer
6194 into the window itself. (Normally the pointm of the selected
6195 window holds garbage.) We do this now, before
6196 restoring the window contents, and prevent it from
6197 being done later on when we select a new window. */
6198 if (! NILP (XWINDOW (selected_window
)->buffer
))
6200 w
= XWINDOW (selected_window
);
6201 set_marker_both (w
->pointm
,
6203 BUF_PT (XBUFFER (w
->buffer
)),
6204 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
6207 windows_or_buffers_changed
++;
6208 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
6210 /* Problem: Freeing all matrices and later allocating them again
6211 is a serious redisplay flickering problem. What we would
6212 really like to do is to free only those matrices not reused
6214 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
6216 = (struct window
**) alloca (count_windows (root_window
)
6217 * sizeof (struct window
*));
6218 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
6220 /* Temporarily avoid any problems with windows that are smaller
6221 than they are supposed to be. */
6222 window_min_height
= 1;
6223 window_min_width
= 1;
6226 Mark all windows now on frame as "deleted".
6227 Restoring the new configuration "undeletes" any that are in it.
6229 Save their current buffers in their height fields, since we may
6230 need it later, if a buffer saved in the configuration is now
6232 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
6234 for (k
= 0; k
< saved_windows
->size
; k
++)
6236 p
= SAVED_WINDOW_N (saved_windows
, k
);
6237 w
= XWINDOW (p
->window
);
6240 if (!NILP (p
->parent
))
6241 w
->parent
= SAVED_WINDOW_N (saved_windows
,
6242 XFASTINT (p
->parent
))->window
;
6246 if (!NILP (p
->prev
))
6248 w
->prev
= SAVED_WINDOW_N (saved_windows
,
6249 XFASTINT (p
->prev
))->window
;
6250 XWINDOW (w
->prev
)->next
= p
->window
;
6255 if (!NILP (w
->parent
))
6257 if (EQ (p
->total_cols
, XWINDOW (w
->parent
)->total_cols
))
6259 XWINDOW (w
->parent
)->vchild
= p
->window
;
6260 XWINDOW (w
->parent
)->hchild
= Qnil
;
6264 XWINDOW (w
->parent
)->hchild
= p
->window
;
6265 XWINDOW (w
->parent
)->vchild
= Qnil
;
6270 /* If we squirreled away the buffer in the window's height,
6272 if (BUFFERP (w
->total_lines
))
6273 w
->buffer
= w
->total_lines
;
6274 w
->left_col
= p
->left_col
;
6275 w
->top_line
= p
->top_line
;
6276 w
->total_cols
= p
->total_cols
;
6277 w
->total_lines
= p
->total_lines
;
6278 w
->hscroll
= p
->hscroll
;
6279 w
->min_hscroll
= p
->min_hscroll
;
6280 w
->display_table
= p
->display_table
;
6281 w
->orig_top_line
= p
->orig_top_line
;
6282 w
->orig_total_lines
= p
->orig_total_lines
;
6283 w
->left_margin_cols
= p
->left_margin_cols
;
6284 w
->right_margin_cols
= p
->right_margin_cols
;
6285 w
->left_fringe_width
= p
->left_fringe_width
;
6286 w
->right_fringe_width
= p
->right_fringe_width
;
6287 w
->fringes_outside_margins
= p
->fringes_outside_margins
;
6288 w
->scroll_bar_width
= p
->scroll_bar_width
;
6289 w
->vertical_scroll_bar_type
= p
->vertical_scroll_bar_type
;
6290 w
->dedicated
= p
->dedicated
;
6291 XSETFASTINT (w
->last_modified
, 0);
6292 XSETFASTINT (w
->last_overlay_modified
, 0);
6294 /* Reinstall the saved buffer and pointers into it. */
6295 if (NILP (p
->buffer
))
6296 w
->buffer
= p
->buffer
;
6299 if (!NILP (XBUFFER (p
->buffer
)->name
))
6300 /* If saved buffer is alive, install it. */
6302 w
->buffer
= p
->buffer
;
6303 w
->start_at_line_beg
= p
->start_at_line_beg
;
6304 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
6305 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
6306 Fset_marker (XBUFFER (w
->buffer
)->mark
,
6307 p
->mark
, w
->buffer
);
6309 /* As documented in Fcurrent_window_configuration, don't
6310 restore the location of point in the buffer which was
6311 current when the window configuration was recorded. */
6312 if (!EQ (p
->buffer
, new_current_buffer
)
6313 && XBUFFER (p
->buffer
) == current_buffer
)
6314 Fgoto_char (w
->pointm
);
6316 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
6317 /* Else unless window has a live buffer, get one. */
6319 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
6320 /* This will set the markers to beginning of visible
6322 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
6323 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
6324 w
->start_at_line_beg
= Qt
;
6327 /* Keeping window's old buffer; make sure the markers
6330 /* Set window markers at start of visible range. */
6331 if (XMARKER (w
->start
)->buffer
== 0)
6332 set_marker_restricted (w
->start
, make_number (0),
6334 if (XMARKER (w
->pointm
)->buffer
== 0)
6335 set_marker_restricted_both (w
->pointm
, w
->buffer
,
6336 BUF_PT (XBUFFER (w
->buffer
)),
6337 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
6338 w
->start_at_line_beg
= Qt
;
6343 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
6344 /* Prevent "swapping out point" in the old selected window
6345 using the buffer that has been restored into it.
6346 We already swapped out point that from that window's old buffer. */
6347 selected_window
= Qnil
;
6349 /* Arrange *not* to restore point in the buffer that was
6350 current when the window configuration was saved. */
6351 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
))
6352 set_marker_restricted (XWINDOW (data
->current_window
)->pointm
,
6353 make_number (old_point
),
6354 XWINDOW (data
->current_window
)->buffer
);
6356 Fselect_window (data
->current_window
, Qnil
);
6357 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
6360 if (NILP (data
->focus_frame
)
6361 || (FRAMEP (data
->focus_frame
)
6362 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
6363 Fredirect_frame_focus (frame
, data
->focus_frame
);
6365 #if 0 /* I don't understand why this is needed, and it causes problems
6366 when the frame's old selected window has been deleted. */
6367 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
6368 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
6372 /* Set the screen height to the value it had before this function. */
6373 if (previous_frame_lines
!= FRAME_LINES (f
)
6374 || previous_frame_cols
!= FRAME_COLS (f
))
6375 change_frame_size (f
, previous_frame_lines
, previous_frame_cols
,
6377 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
6378 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
6379 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
6381 #ifdef HAVE_WINDOW_SYSTEM
6382 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
6383 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
6388 /* Now, free glyph matrices in windows that were not reused. */
6389 for (i
= n
= 0; i
< n_leaf_windows
; ++i
)
6391 if (NILP (leaf_windows
[i
]->buffer
))
6393 /* Assert it's not reused as a combination. */
6394 xassert (NILP (leaf_windows
[i
]->hchild
)
6395 && NILP (leaf_windows
[i
]->vchild
));
6396 free_window_matrices (leaf_windows
[i
]);
6398 else if (EQ (leaf_windows
[i
]->buffer
, new_current_buffer
))
6406 /* Fselect_window will have made f the selected frame, so we
6407 reselect the proper frame here. Fhandle_switch_frame will change the
6408 selected window too, but that doesn't make the call to
6409 Fselect_window above totally superfluous; it still sets f's
6411 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
6412 do_switch_frame (data
->selected_frame
, 0, 0);
6414 if (! NILP (Vwindow_configuration_change_hook
)
6415 && ! NILP (Vrun_hooks
))
6416 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
6419 if (!NILP (new_current_buffer
))
6420 Fset_buffer (new_current_buffer
);
6422 /* Restore the minimum heights recorded in the configuration. */
6423 window_min_height
= XINT (data
->min_height
);
6424 window_min_width
= XINT (data
->min_width
);
6426 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
6427 minibuf_selected_window
= data
->minibuf_selected_window
;
6429 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
6432 /* Mark all windows now on frame as deleted
6433 by setting their buffers to nil. */
6436 delete_all_subwindows (w
)
6437 register struct window
*w
;
6439 if (!NILP (w
->next
))
6440 delete_all_subwindows (XWINDOW (w
->next
));
6441 if (!NILP (w
->vchild
))
6442 delete_all_subwindows (XWINDOW (w
->vchild
));
6443 if (!NILP (w
->hchild
))
6444 delete_all_subwindows (XWINDOW (w
->hchild
));
6446 w
->total_lines
= w
->buffer
; /* See Fset_window_configuration for excuse. */
6448 if (!NILP (w
->buffer
))
6451 /* We set all three of these fields to nil, to make sure that we can
6452 distinguish this dead window from any live window. Live leaf
6453 windows will have buffer set, and combination windows will have
6454 vchild or hchild set. */
6459 Vwindow_list
= Qnil
;
6463 count_windows (window
)
6464 register struct window
*window
;
6466 register int count
= 1;
6467 if (!NILP (window
->next
))
6468 count
+= count_windows (XWINDOW (window
->next
));
6469 if (!NILP (window
->vchild
))
6470 count
+= count_windows (XWINDOW (window
->vchild
));
6471 if (!NILP (window
->hchild
))
6472 count
+= count_windows (XWINDOW (window
->hchild
));
6477 /* Fill vector FLAT with leaf windows under W, starting at index I.
6478 Value is last index + 1. */
6481 get_leaf_windows (w
, flat
, i
)
6483 struct window
**flat
;
6488 if (!NILP (w
->hchild
))
6489 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
6490 else if (!NILP (w
->vchild
))
6491 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
6495 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
6502 /* Return a pointer to the glyph W's physical cursor is on. Value is
6503 null if W's current matrix is invalid, so that no meaningfull glyph
6507 get_phys_cursor_glyph (w
)
6510 struct glyph_row
*row
;
6511 struct glyph
*glyph
;
6513 if (w
->phys_cursor
.vpos
>= 0
6514 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
6515 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
6517 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
6518 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
6527 save_window_save (window
, vector
, i
)
6529 struct Lisp_Vector
*vector
;
6532 register struct saved_window
*p
;
6533 register struct window
*w
;
6534 register Lisp_Object tem
;
6536 for (;!NILP (window
); window
= w
->next
)
6538 p
= SAVED_WINDOW_N (vector
, i
);
6539 w
= XWINDOW (window
);
6541 XSETFASTINT (w
->temslot
, i
); i
++;
6543 p
->buffer
= w
->buffer
;
6544 p
->left_col
= w
->left_col
;
6545 p
->top_line
= w
->top_line
;
6546 p
->total_cols
= w
->total_cols
;
6547 p
->total_lines
= w
->total_lines
;
6548 p
->hscroll
= w
->hscroll
;
6549 p
->min_hscroll
= w
->min_hscroll
;
6550 p
->display_table
= w
->display_table
;
6551 p
->orig_top_line
= w
->orig_top_line
;
6552 p
->orig_total_lines
= w
->orig_total_lines
;
6553 p
->left_margin_cols
= w
->left_margin_cols
;
6554 p
->right_margin_cols
= w
->right_margin_cols
;
6555 p
->left_fringe_width
= w
->left_fringe_width
;
6556 p
->right_fringe_width
= w
->right_fringe_width
;
6557 p
->fringes_outside_margins
= w
->fringes_outside_margins
;
6558 p
->scroll_bar_width
= w
->scroll_bar_width
;
6559 p
->vertical_scroll_bar_type
= w
->vertical_scroll_bar_type
;
6560 p
->dedicated
= w
->dedicated
;
6561 if (!NILP (w
->buffer
))
6563 /* Save w's value of point in the window configuration.
6564 If w is the selected window, then get the value of point
6565 from the buffer; pointm is garbage in the selected window. */
6566 if (EQ (window
, selected_window
))
6568 p
->pointm
= Fmake_marker ();
6569 set_marker_both (p
->pointm
, w
->buffer
,
6570 BUF_PT (XBUFFER (w
->buffer
)),
6571 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
6574 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
6576 p
->start
= Fcopy_marker (w
->start
, Qnil
);
6577 p
->start_at_line_beg
= w
->start_at_line_beg
;
6579 tem
= XBUFFER (w
->buffer
)->mark
;
6580 p
->mark
= Fcopy_marker (tem
, Qnil
);
6587 p
->start_at_line_beg
= Qnil
;
6590 if (NILP (w
->parent
))
6593 p
->parent
= XWINDOW (w
->parent
)->temslot
;
6598 p
->prev
= XWINDOW (w
->prev
)->temslot
;
6600 if (!NILP (w
->vchild
))
6601 i
= save_window_save (w
->vchild
, vector
, i
);
6602 if (!NILP (w
->hchild
))
6603 i
= save_window_save (w
->hchild
, vector
, i
);
6609 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
6610 Scurrent_window_configuration
, 0, 1, 0,
6611 doc
: /* Return an object representing the current window configuration of FRAME.
6612 If FRAME is nil or omitted, use the selected frame.
6613 This describes the number of windows, their sizes and current buffers,
6614 and for each displayed buffer, where display starts, and the positions of
6615 point and mark. An exception is made for point in the current buffer:
6616 its value is -not- saved.
6617 This also records the currently selected frame, and FRAME's focus
6618 redirection (see `redirect-frame-focus'). */)
6622 register Lisp_Object tem
;
6623 register int n_windows
;
6624 register struct save_window_data
*data
;
6625 register struct Lisp_Vector
*vec
;
6630 frame
= selected_frame
;
6631 CHECK_LIVE_FRAME (frame
);
6634 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
6635 vec
= allocate_other_vector (VECSIZE (struct save_window_data
));
6636 data
= (struct save_window_data
*)vec
;
6638 XSETFASTINT (data
->frame_cols
, FRAME_COLS (f
));
6639 XSETFASTINT (data
->frame_lines
, FRAME_LINES (f
));
6640 XSETFASTINT (data
->frame_menu_bar_lines
, FRAME_MENU_BAR_LINES (f
));
6641 XSETFASTINT (data
->frame_tool_bar_lines
, FRAME_TOOL_BAR_LINES (f
));
6642 data
->selected_frame
= selected_frame
;
6643 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
6644 XSETBUFFER (data
->current_buffer
, current_buffer
);
6645 data
->minibuf_scroll_window
= minibuf_level
> 0 ? Vminibuf_scroll_window
: Qnil
;
6646 data
->minibuf_selected_window
= minibuf_level
> 0 ? minibuf_selected_window
: Qnil
;
6647 data
->root_window
= FRAME_ROOT_WINDOW (f
);
6648 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
6649 XSETINT (data
->min_height
, window_min_height
);
6650 XSETINT (data
->min_width
, window_min_width
);
6651 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
6652 data
->saved_windows
= tem
;
6653 for (i
= 0; i
< n_windows
; i
++)
6654 XVECTOR (tem
)->contents
[i
]
6655 = Fmake_vector (make_number (VECSIZE (struct saved_window
)), Qnil
);
6656 save_window_save (FRAME_ROOT_WINDOW (f
), XVECTOR (tem
), 0);
6657 XSETWINDOW_CONFIGURATION (tem
, data
);
6661 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
6663 doc
: /* Execute BODY, preserving window sizes and contents.
6664 Return the value of the last form in BODY.
6665 Restore which buffer appears in which window, where display starts,
6666 and the value of point and mark for each window.
6667 Also restore the choice of selected window.
6668 Also restore which buffer is current.
6669 Does not restore the value of point in current buffer.
6670 usage: (save-window-excursion BODY...) */)
6674 register Lisp_Object val
;
6675 register int count
= SPECPDL_INDEX ();
6677 record_unwind_protect (Fset_window_configuration
,
6678 Fcurrent_window_configuration (Qnil
));
6679 val
= Fprogn (args
);
6680 return unbind_to (count
, val
);
6685 /***********************************************************************
6687 ***********************************************************************/
6693 Lisp_Object tail
= Qnil
;
6694 Lisp_Object result
= Qnil
;
6701 if (!NILP (w
->hchild
))
6702 wn
= Fcons (Qnil
, Fcons (Fwindow_edges (wn
),
6703 window_tree (XWINDOW (w
->hchild
))));
6704 else if (!NILP (w
->vchild
))
6705 wn
= Fcons (Qt
, Fcons (Fwindow_edges (wn
),
6706 window_tree (XWINDOW (w
->vchild
))));
6710 result
= tail
= Fcons (wn
, Qnil
);
6714 XSETCDR (tail
, Fcons (wn
, Qnil
));
6718 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
6726 DEFUN ("window-tree", Fwindow_tree
, Swindow_tree
,
6728 doc
: /* Return the window tree for frame FRAME.
6730 The return value is a list of the form (ROOT MINI), where ROOT
6731 represents the window tree of the frame's root window, and MINI
6732 is the frame's minibuffer window.
6734 If the root window is not split, ROOT is the root window itself.
6735 Otherwise, ROOT is a list (DIR EDGES W1 W2 ...) where DIR is nil for a
6736 horizontal split, and t for a vertical split, EDGES gives the combined
6737 size and position of the subwindows in the split, and the rest of the
6738 elements are the subwindows in the split. Each of the subwindows may
6739 again be a window or a list representing a window split, and so on.
6740 EDGES is a list \(LEFT TOP RIGHT BOTTOM) as returned by `window-edges'.
6742 If FRAME is nil or omitted, return information on the currently
6750 frame
= selected_frame
;
6752 CHECK_FRAME (frame
);
6755 if (!FRAME_LIVE_P (f
))
6758 return window_tree (XWINDOW (FRAME_ROOT_WINDOW (f
)));
6762 /***********************************************************************
6764 ***********************************************************************/
6766 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
6768 doc
: /* Set width of marginal areas of window WINDOW.
6769 If WINDOW is nil, set margins of the currently selected window.
6770 Second arg LEFT-WIDTH specifies the number of character cells to
6771 reserve for the left marginal area. Optional third arg RIGHT-WIDTH
6772 does the same for the right marginal area. A nil width parameter
6773 means no margin. */)
6774 (window
, left_width
, right_width
)
6775 Lisp_Object window
, left_width
, right_width
;
6777 struct window
*w
= decode_window (window
);
6779 /* Translate negative or zero widths to nil.
6780 Margins that are too wide have to be checked elsewhere. */
6782 if (!NILP (left_width
))
6784 CHECK_NUMBER (left_width
);
6785 if (XINT (left_width
) <= 0)
6789 if (!NILP (right_width
))
6791 CHECK_NUMBER (right_width
);
6792 if (XINT (right_width
) <= 0)
6796 if (!EQ (w
->left_margin_cols
, left_width
)
6797 || !EQ (w
->right_margin_cols
, right_width
))
6799 w
->left_margin_cols
= left_width
;
6800 w
->right_margin_cols
= right_width
;
6802 adjust_window_margins (w
);
6804 ++windows_or_buffers_changed
;
6805 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
6812 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
6814 doc
: /* Get width of marginal areas of window WINDOW.
6815 If WINDOW is omitted or nil, use the currently selected window.
6816 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).
6817 If a marginal area does not exist, its width will be returned
6822 struct window
*w
= decode_window (window
);
6823 return Fcons (w
->left_margin_cols
, w
->right_margin_cols
);
6828 /***********************************************************************
6830 ***********************************************************************/
6832 DEFUN ("set-window-fringes", Fset_window_fringes
, Sset_window_fringes
,
6834 doc
: /* Set the fringe widths of window WINDOW.
6835 If WINDOW is nil, set the fringe widths of the currently selected
6837 Second arg LEFT-WIDTH specifies the number of pixels to reserve for
6838 the left fringe. Optional third arg RIGHT-WIDTH specifies the right
6839 fringe width. If a fringe width arg is nil, that means to use the
6840 frame's default fringe width. Default fringe widths can be set with
6841 the command `set-fringe-style'.
6842 If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes
6843 outside of the display margins. By default, fringes are drawn between
6844 display marginal areas and the text area. */)
6845 (window
, left_width
, right_width
, outside_margins
)
6846 Lisp_Object window
, left_width
, right_width
, outside_margins
;
6848 struct window
*w
= decode_window (window
);
6850 if (!NILP (left_width
))
6851 CHECK_NATNUM (left_width
);
6852 if (!NILP (right_width
))
6853 CHECK_NATNUM (right_width
);
6855 /* Do nothing on a tty. */
6856 if (FRAME_WINDOW_P (WINDOW_XFRAME (w
))
6857 && (!EQ (w
->left_fringe_width
, left_width
)
6858 || !EQ (w
->right_fringe_width
, right_width
)
6859 || !EQ (w
->fringes_outside_margins
, outside_margins
)))
6861 w
->left_fringe_width
= left_width
;
6862 w
->right_fringe_width
= right_width
;
6863 w
->fringes_outside_margins
= outside_margins
;
6865 adjust_window_margins (w
);
6867 clear_glyph_matrix (w
->current_matrix
);
6868 w
->window_end_valid
= Qnil
;
6870 ++windows_or_buffers_changed
;
6871 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
6878 DEFUN ("window-fringes", Fwindow_fringes
, Swindow_fringes
,
6880 doc
: /* Get width of fringes of window WINDOW.
6881 If WINDOW is omitted or nil, use the currently selected window.
6882 Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
6886 struct window
*w
= decode_window (window
);
6888 return Fcons (make_number (WINDOW_LEFT_FRINGE_WIDTH (w
)),
6889 Fcons (make_number (WINDOW_RIGHT_FRINGE_WIDTH (w
)),
6890 Fcons ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
6891 ? Qt
: Qnil
), Qnil
)));
6896 /***********************************************************************
6898 ***********************************************************************/
6900 DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars
, Sset_window_scroll_bars
,
6902 doc
: /* Set width and type of scroll bars of window WINDOW.
6903 If window is nil, set scroll bars of the currently selected window.
6904 Second parameter WIDTH specifies the pixel width for the scroll bar;
6905 this is automatically adjusted to a multiple of the frame column width.
6906 Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
6907 bar: left, right, or nil.
6908 If WIDTH is nil, use the frame's scroll-bar width.
6909 If VERTICAL-TYPE is t, use the frame's scroll-bar type.
6910 Fourth parameter HORIZONTAL-TYPE is currently unused. */)
6911 (window
, width
, vertical_type
, horizontal_type
)
6912 Lisp_Object window
, width
, vertical_type
, horizontal_type
;
6914 struct window
*w
= decode_window (window
);
6918 CHECK_NATNUM (width
);
6920 if (XINT (width
) == 0)
6921 vertical_type
= Qnil
;
6924 if (!(NILP (vertical_type
)
6925 || EQ (vertical_type
, Qleft
)
6926 || EQ (vertical_type
, Qright
)
6927 || EQ (vertical_type
, Qt
)))
6928 error ("Invalid type of vertical scroll bar");
6930 if (!EQ (w
->scroll_bar_width
, width
)
6931 || !EQ (w
->vertical_scroll_bar_type
, vertical_type
))
6933 w
->scroll_bar_width
= width
;
6934 w
->vertical_scroll_bar_type
= vertical_type
;
6936 adjust_window_margins (w
);
6938 clear_glyph_matrix (w
->current_matrix
);
6939 w
->window_end_valid
= Qnil
;
6941 ++windows_or_buffers_changed
;
6942 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
6949 DEFUN ("window-scroll-bars", Fwindow_scroll_bars
, Swindow_scroll_bars
,
6951 doc
: /* Get width and type of scroll bars of window WINDOW.
6952 If WINDOW is omitted or nil, use the currently selected window.
6953 Value is a list of the form (WIDTH COLS VERTICAL-TYPE HORIZONTAL-TYPE).
6954 If WIDTH is nil or TYPE is t, the window is using the frame's corresponding
6959 struct window
*w
= decode_window (window
);
6960 return Fcons (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
)
6961 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
)
6962 : WINDOW_SCROLL_BAR_AREA_WIDTH (w
))),
6963 Fcons (make_number (WINDOW_SCROLL_BAR_COLS (w
)),
6964 Fcons (w
->vertical_scroll_bar_type
,
6965 Fcons (Qnil
, Qnil
))));
6970 /***********************************************************************
6972 ***********************************************************************/
6974 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 2, 0,
6975 doc
: /* Return the amount by which WINDOW is scrolled vertically.
6976 Use the selected window if WINDOW is nil or omitted.
6977 Normally, value is a multiple of the canonical character height of WINDOW;
6978 optional second arg PIXELS-P means value is measured in pixels. */)
6980 Lisp_Object window
, pixels_p
;
6987 window
= selected_window
;
6989 CHECK_WINDOW (window
);
6990 w
= XWINDOW (window
);
6991 f
= XFRAME (w
->frame
);
6993 if (FRAME_WINDOW_P (f
))
6994 result
= (NILP (pixels_p
)
6995 ? FRAME_CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
)
6996 : make_number (-w
->vscroll
));
6998 result
= make_number (0);
7003 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
7005 doc
: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL.
7006 WINDOW nil means use the selected window. Normally, VSCROLL is a
7007 non-negative multiple of the canonical character height of WINDOW;
7008 optional third arg PIXELS-P non-nil means that VSCROLL is in pixels.
7009 If PIXELS-P is nil, VSCROLL may have to be rounded so that it
7010 corresponds to an integral number of pixels. The return value is the
7011 result of this rounding.
7012 If PIXELS-P is non-nil, the return value is VSCROLL. */)
7013 (window
, vscroll
, pixels_p
)
7014 Lisp_Object window
, vscroll
, pixels_p
;
7020 window
= selected_window
;
7022 CHECK_WINDOW (window
);
7023 CHECK_NUMBER_OR_FLOAT (vscroll
);
7025 w
= XWINDOW (window
);
7026 f
= XFRAME (w
->frame
);
7028 if (FRAME_WINDOW_P (f
))
7030 int old_dy
= w
->vscroll
;
7032 w
->vscroll
= - (NILP (pixels_p
)
7033 ? FRAME_LINE_HEIGHT (f
) * XFLOATINT (vscroll
)
7034 : XFLOATINT (vscroll
));
7035 w
->vscroll
= min (w
->vscroll
, 0);
7037 if (w
->vscroll
!= old_dy
)
7039 /* Adjust glyph matrix of the frame if the virtual display
7040 area becomes larger than before. */
7041 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
7044 /* Prevent redisplay shortcuts. */
7045 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
7049 return Fwindow_vscroll (window
, pixels_p
);
7053 /* Call FN for all leaf windows on frame F. FN is called with the
7054 first argument being a pointer to the leaf window, and with
7055 additional argument USER_DATA. Stops when FN returns 0. */
7058 foreach_window (f
, fn
, user_data
)
7060 int (* fn
) P_ ((struct window
*, void *));
7063 /* Fdelete_frame may set FRAME_ROOT_WINDOW (f) to Qnil. */
7064 if (WINDOWP (FRAME_ROOT_WINDOW (f
)))
7065 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, user_data
);
7069 /* Helper function for foreach_window. Call FN for all leaf windows
7070 reachable from W. FN is called with the first argument being a
7071 pointer to the leaf window, and with additional argument USER_DATA.
7072 Stop when FN returns 0. Value is 0 if stopped by FN. */
7075 foreach_window_1 (w
, fn
, user_data
)
7077 int (* fn
) P_ ((struct window
*, void *));
7082 for (cont
= 1; w
&& cont
;)
7084 if (!NILP (w
->hchild
))
7085 cont
= foreach_window_1 (XWINDOW (w
->hchild
), fn
, user_data
);
7086 else if (!NILP (w
->vchild
))
7087 cont
= foreach_window_1 (XWINDOW (w
->vchild
), fn
, user_data
);
7089 cont
= fn (w
, user_data
);
7091 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
7098 /* Freeze or unfreeze the window start of W unless it is a
7099 mini-window or the selected window. FREEZE_P non-null means freeze
7100 the window start. */
7103 freeze_window_start (w
, freeze_p
)
7107 if (w
== XWINDOW (selected_window
)
7108 || MINI_WINDOW_P (w
)
7109 || (MINI_WINDOW_P (XWINDOW (selected_window
))
7110 && ! NILP (Vminibuf_scroll_window
)
7111 && w
== XWINDOW (Vminibuf_scroll_window
)))
7114 w
->frozen_window_start_p
= freeze_p
!= NULL
;
7119 /* Freeze or unfreeze the window starts of all leaf windows on frame
7120 F, except the selected window and a mini-window. FREEZE_P non-zero
7121 means freeze the window start. */
7124 freeze_window_starts (f
, freeze_p
)
7128 foreach_window (f
, freeze_window_start
, (void *) (freeze_p
? f
: 0));
7132 /***********************************************************************
7134 ***********************************************************************/
7136 /* Return 1 if window configurations C1 and C2
7137 describe the same state of affairs. This is used by Fequal. */
7140 compare_window_configurations (c1
, c2
, ignore_positions
)
7142 int ignore_positions
;
7144 register struct save_window_data
*d1
, *d2
;
7145 struct Lisp_Vector
*sw1
, *sw2
;
7148 CHECK_WINDOW_CONFIGURATION (c1
);
7149 CHECK_WINDOW_CONFIGURATION (c2
);
7151 d1
= (struct save_window_data
*) XVECTOR (c1
);
7152 d2
= (struct save_window_data
*) XVECTOR (c2
);
7153 sw1
= XVECTOR (d1
->saved_windows
);
7154 sw2
= XVECTOR (d2
->saved_windows
);
7156 if (! EQ (d1
->frame_cols
, d2
->frame_cols
))
7158 if (! EQ (d1
->frame_lines
, d2
->frame_lines
))
7160 if (! EQ (d1
->frame_menu_bar_lines
, d2
->frame_menu_bar_lines
))
7162 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
7164 /* Don't compare the current_window field directly.
7165 Instead see w1_is_current and w2_is_current, below. */
7166 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
7168 if (! ignore_positions
)
7170 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
7172 if (! EQ (d1
->minibuf_selected_window
, d2
->minibuf_selected_window
))
7175 /* Don't compare the root_window field.
7176 We don't require the two configurations
7177 to use the same window object,
7178 and the two root windows must be equivalent
7179 if everything else compares equal. */
7180 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
7182 if (! EQ (d1
->min_width
, d2
->min_width
))
7184 if (! EQ (d1
->min_height
, d2
->min_height
))
7187 /* Verify that the two confis have the same number of windows. */
7188 if (sw1
->size
!= sw2
->size
)
7191 for (i
= 0; i
< sw1
->size
; i
++)
7193 struct saved_window
*p1
, *p2
;
7194 int w1_is_current
, w2_is_current
;
7196 p1
= SAVED_WINDOW_N (sw1
, i
);
7197 p2
= SAVED_WINDOW_N (sw2
, i
);
7199 /* Verify that the current windows in the two
7200 configurations correspond to each other. */
7201 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
7202 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
7204 if (w1_is_current
!= w2_is_current
)
7207 /* Verify that the corresponding windows do match. */
7208 if (! EQ (p1
->buffer
, p2
->buffer
))
7210 if (! EQ (p1
->left_col
, p2
->left_col
))
7212 if (! EQ (p1
->top_line
, p2
->top_line
))
7214 if (! EQ (p1
->total_cols
, p2
->total_cols
))
7216 if (! EQ (p1
->total_lines
, p2
->total_lines
))
7218 if (! EQ (p1
->display_table
, p2
->display_table
))
7220 if (! EQ (p1
->parent
, p2
->parent
))
7222 if (! EQ (p1
->prev
, p2
->prev
))
7224 if (! ignore_positions
)
7226 if (! EQ (p1
->hscroll
, p2
->hscroll
))
7228 if (!EQ (p1
->min_hscroll
, p2
->min_hscroll
))
7230 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
7232 if (NILP (Fequal (p1
->start
, p2
->start
)))
7234 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
7236 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
7239 if (! EQ (p1
->left_margin_cols
, p2
->left_margin_cols
))
7241 if (! EQ (p1
->right_margin_cols
, p2
->right_margin_cols
))
7243 if (! EQ (p1
->left_fringe_width
, p2
->left_fringe_width
))
7245 if (! EQ (p1
->right_fringe_width
, p2
->right_fringe_width
))
7247 if (! EQ (p1
->fringes_outside_margins
, p2
->fringes_outside_margins
))
7249 if (! EQ (p1
->scroll_bar_width
, p2
->scroll_bar_width
))
7251 if (! EQ (p1
->vertical_scroll_bar_type
, p2
->vertical_scroll_bar_type
))
7258 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
7259 Scompare_window_configurations
, 2, 2, 0,
7260 doc
: /* Compare two window configurations as regards the structure of windows.
7261 This function ignores details such as the values of point and mark
7262 and scrolling positions. */)
7266 if (compare_window_configurations (x
, y
, 1))
7274 struct frame
*f
= make_terminal_frame ();
7275 XSETFRAME (selected_frame
, f
);
7276 Vterminal_frame
= selected_frame
;
7277 minibuf_window
= f
->minibuffer_window
;
7278 selected_window
= f
->selected_window
;
7279 last_nonminibuf_frame
= f
;
7281 window_initialized
= 1;
7287 Vwindow_list
= Qnil
;
7293 Qscroll_up
= intern ("scroll-up");
7294 staticpro (&Qscroll_up
);
7296 Qscroll_down
= intern ("scroll-down");
7297 staticpro (&Qscroll_down
);
7299 Qwindow_size_fixed
= intern ("window-size-fixed");
7300 staticpro (&Qwindow_size_fixed
);
7301 Fset (Qwindow_size_fixed
, Qnil
);
7303 staticpro (&Qwindow_configuration_change_hook
);
7304 Qwindow_configuration_change_hook
7305 = intern ("window-configuration-change-hook");
7307 Qwindowp
= intern ("windowp");
7308 staticpro (&Qwindowp
);
7310 Qwindow_configuration_p
= intern ("window-configuration-p");
7311 staticpro (&Qwindow_configuration_p
);
7313 Qwindow_live_p
= intern ("window-live-p");
7314 staticpro (&Qwindow_live_p
);
7316 Qtemp_buffer_show_hook
= intern ("temp-buffer-show-hook");
7317 staticpro (&Qtemp_buffer_show_hook
);
7319 staticpro (&Vwindow_list
);
7321 minibuf_selected_window
= Qnil
;
7322 staticpro (&minibuf_selected_window
);
7324 window_scroll_pixel_based_preserve_y
= -1;
7326 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
7327 doc
: /* Non-nil means call as function to display a help buffer.
7328 The function is called with one argument, the buffer to be displayed.
7329 Used by `with-output-to-temp-buffer'.
7330 If this function is used, then it must do the entire job of showing
7331 the buffer; `temp-buffer-show-hook' is not run unless this function runs it. */);
7332 Vtemp_buffer_show_function
= Qnil
;
7334 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
7335 doc
: /* If non-nil, function to call to handle `display-buffer'.
7336 It will receive two args, the buffer and a flag which if non-nil means
7337 that the currently selected window is not acceptable.
7338 It should choose or create a window, display the specified buffer in it,
7339 and return the window.
7340 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'
7341 work using this function. */);
7342 Vdisplay_buffer_function
= Qnil
;
7344 DEFVAR_LISP ("even-window-heights", &Veven_window_heights
,
7345 doc
: /* *If non-nil, `display-buffer' should even the window heights.
7346 If nil, `display-buffer' will leave the window configuration alone. */);
7347 Veven_window_heights
= Qt
;
7349 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
7350 doc
: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */);
7351 Vminibuf_scroll_window
= Qnil
;
7353 DEFVAR_BOOL ("mode-line-in-non-selected-windows", &mode_line_in_non_selected_windows
,
7354 doc
: /* Non-nil means to use `mode-line-inactive' face in non-selected windows.
7355 If the minibuffer is active, the `minibuffer-scroll-window' mode line
7356 is displayed in the `mode-line' face. */);
7357 mode_line_in_non_selected_windows
= 1;
7359 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
7360 doc
: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. */);
7361 Vother_window_scroll_buffer
= Qnil
;
7363 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
7364 doc
: /* *Non-nil means `display-buffer' should make a separate frame. */);
7367 DEFVAR_BOOL ("auto-window-vscroll", &auto_window_vscroll_p
,
7368 doc
: /* *Non-nil means to automatically adjust `window-vscroll' to view tall lines. */);
7369 auto_window_vscroll_p
= 1;
7371 DEFVAR_BOOL ("display-buffer-reuse-frames", &display_buffer_reuse_frames
,
7372 doc
: /* *Non-nil means `display-buffer' should reuse frames.
7373 If the buffer in question is already displayed in a frame, raise that frame. */);
7374 display_buffer_reuse_frames
= 0;
7376 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
7377 doc
: /* Function to call to handle automatic new frame creation.
7378 It is called with no arguments and should return a newly created frame.
7380 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'
7381 where `pop-up-frame-alist' would hold the default frame parameters. */);
7382 Vpop_up_frame_function
= Qnil
;
7384 DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names
,
7385 doc
: /* *List of buffer names that should have their own special frames.
7386 Displaying a buffer with `display-buffer' or `pop-to-buffer',
7387 if its name is in this list, makes a special frame for it
7388 using `special-display-function'. See also `special-display-regexps'.
7390 An element of the list can be a list instead of just a string.
7391 There are two ways to use a list as an element:
7392 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)
7393 In the first case, the FRAME-PARAMETERS are pairs of the form
7394 \(PARAMETER . VALUE); these parameter values are used to create the frame.
7395 In the second case, FUNCTION is called with BUFFER as the first argument,
7396 followed by the OTHER-ARGS--it can display BUFFER in any way it likes.
7397 All this is done by the function found in `special-display-function'.
7399 If the specified frame parameters include (same-buffer . t), the
7400 buffer is displayed in the currently selected window. Otherwise, if
7401 they include (same-frame . t), the buffer is displayed in a new window
7402 in the currently selected frame.
7404 If this variable appears \"not to work\", because you add a name to it
7405 but that buffer still appears in the selected window, look at the
7406 values of `same-window-buffer-names' and `same-window-regexps'.
7407 Those variables take precedence over this one. */);
7408 Vspecial_display_buffer_names
= Qnil
;
7410 DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps
,
7411 doc
: /* *List of regexps saying which buffers should have their own special frames.
7412 When displaying a buffer with `display-buffer' or `pop-to-buffer',
7413 if any regexp in this list matches the buffer name, it makes a
7414 special frame for the buffer by calling `special-display-function'.
7416 An element of the list can be a list instead of just a string.
7417 There are two ways to use a list as an element:
7418 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)
7419 In the first case, the FRAME-PARAMETERS are pairs of the form
7420 \(PARAMETER . VALUE); these parameter values are used to create the frame.
7421 In the second case, FUNCTION is called with BUFFER as the first argument,
7422 followed by the OTHER-ARGS--it can display the buffer in any way it likes.
7423 All this is done by the function found in `special-display-function'.
7425 If the specified frame parameters include (same-buffer . t), the
7426 buffer is displayed in the currently selected window. Otherwise, if
7427 they include (same-frame . t), the buffer is displayed in a new window
7428 in the currently selected frame.
7430 If this variable appears \"not to work\", because you add a regexp to it
7431 but the matching buffers still appear in the selected window, look at the
7432 values of `same-window-buffer-names' and `same-window-regexps'.
7433 Those variables take precedence over this one. */);
7434 Vspecial_display_regexps
= Qnil
;
7436 DEFVAR_LISP ("special-display-function", &Vspecial_display_function
,
7437 doc
: /* Function to call to make a new frame for a special buffer.
7438 It is called with two arguments, the buffer and optional buffer specific
7439 data, and should return a window displaying that buffer.
7440 The default value normally makes a separate frame for the buffer,
7441 using `special-display-frame-alist' to specify the frame parameters.
7442 But if the buffer specific data includes (same-buffer . t) then the
7443 buffer is displayed in the current selected window.
7444 Otherwise if it includes (same-frame . t) then the buffer is displayed in
7445 a new window in the currently selected frame.
7447 A buffer is special if it is listed in `special-display-buffer-names'
7448 or matches a regexp in `special-display-regexps'. */);
7449 Vspecial_display_function
= Qnil
;
7451 DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names
,
7452 doc
: /* *List of buffer names that should appear in the selected window.
7453 Displaying one of these buffers using `display-buffer' or `pop-to-buffer'
7454 switches to it in the selected window, rather than making it appear
7455 in some other window.
7457 An element of the list can be a cons cell instead of just a string.
7458 Then the car must be a string, which specifies the buffer name.
7459 This is for compatibility with `special-display-buffer-names';
7460 the cdr of the cons cell is ignored.
7462 See also `same-window-regexps'. */);
7463 Vsame_window_buffer_names
= Qnil
;
7465 DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps
,
7466 doc
: /* *List of regexps saying which buffers should appear in the selected window.
7467 If a buffer name matches one of these regexps, then displaying it
7468 using `display-buffer' or `pop-to-buffer' switches to it
7469 in the selected window, rather than making it appear in some other window.
7471 An element of the list can be a cons cell instead of just a string.
7472 Then the car must be a string, which specifies the buffer name.
7473 This is for compatibility with `special-display-buffer-names';
7474 the cdr of the cons cell is ignored.
7476 See also `same-window-buffer-names'. */);
7477 Vsame_window_regexps
= Qnil
;
7479 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
7480 doc
: /* *Non-nil means display-buffer should make new windows. */);
7483 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
7484 doc
: /* *Number of lines of continuity when scrolling by screenfuls. */);
7485 next_screen_context_lines
= 2;
7487 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
7488 doc
: /* *A window must be at least this tall to be eligible for splitting
7489 by `display-buffer'. The value is in line units.
7490 If there is only one window, it is split regardless of this value. */);
7491 split_height_threshold
= 500;
7493 DEFVAR_INT ("window-min-height", &window_min_height
,
7494 doc
: /* *Delete any window less than this tall (including its mode line).
7495 The value is in line units. */);
7496 window_min_height
= 4;
7498 DEFVAR_INT ("window-min-width", &window_min_width
,
7499 doc
: /* *Delete any window less than this wide (measured in characters). */);
7500 window_min_width
= 10;
7502 DEFVAR_LISP ("scroll-preserve-screen-position",
7503 &Vscroll_preserve_screen_position
,
7504 doc
: /* *Controls if scroll commands move point to keep its screen line unchanged.
7505 A value of nil means point does not keep its screen position except
7506 at the scroll margin or window boundary respectively.
7507 A value of t means point keeps its screen position if the scroll
7508 command moved it vertically out of the window, e.g. when scrolling
7510 Any other value means point always keeps its screen position. */);
7511 Vscroll_preserve_screen_position
= Qnil
;
7513 DEFVAR_LISP ("window-configuration-change-hook",
7514 &Vwindow_configuration_change_hook
,
7515 doc
: /* Functions to call when window configuration changes.
7516 The selected frame is the one whose configuration has changed. */);
7517 Vwindow_configuration_change_hook
= Qnil
;
7519 defsubr (&Sselected_window
);
7520 defsubr (&Sminibuffer_window
);
7521 defsubr (&Swindow_minibuffer_p
);
7522 defsubr (&Swindowp
);
7523 defsubr (&Swindow_live_p
);
7524 defsubr (&Spos_visible_in_window_p
);
7525 defsubr (&Swindow_line_height
);
7526 defsubr (&Swindow_buffer
);
7527 defsubr (&Swindow_height
);
7528 defsubr (&Swindow_width
);
7529 defsubr (&Swindow_full_width_p
);
7530 defsubr (&Swindow_hscroll
);
7531 defsubr (&Sset_window_hscroll
);
7532 defsubr (&Swindow_redisplay_end_trigger
);
7533 defsubr (&Sset_window_redisplay_end_trigger
);
7534 defsubr (&Swindow_edges
);
7535 defsubr (&Swindow_pixel_edges
);
7536 defsubr (&Swindow_inside_edges
);
7537 defsubr (&Swindow_inside_pixel_edges
);
7538 defsubr (&Scoordinates_in_window_p
);
7539 defsubr (&Swindow_at
);
7540 defsubr (&Swindow_point
);
7541 defsubr (&Swindow_start
);
7542 defsubr (&Swindow_end
);
7543 defsubr (&Sset_window_point
);
7544 defsubr (&Sset_window_start
);
7545 defsubr (&Swindow_dedicated_p
);
7546 defsubr (&Sset_window_dedicated_p
);
7547 defsubr (&Swindow_display_table
);
7548 defsubr (&Sset_window_display_table
);
7549 defsubr (&Snext_window
);
7550 defsubr (&Sprevious_window
);
7551 defsubr (&Sother_window
);
7552 defsubr (&Sget_lru_window
);
7553 defsubr (&Sget_largest_window
);
7554 defsubr (&Sget_buffer_window
);
7555 defsubr (&Sdelete_other_windows
);
7556 defsubr (&Sdelete_windows_on
);
7557 defsubr (&Sreplace_buffer_in_windows
);
7558 defsubr (&Sdelete_window
);
7559 defsubr (&Sset_window_buffer
);
7560 defsubr (&Sselect_window
);
7561 defsubr (&Sspecial_display_p
);
7562 defsubr (&Ssame_window_p
);
7563 defsubr (&Sdisplay_buffer
);
7564 defsubr (&Sforce_window_update
);
7565 defsubr (&Ssplit_window
);
7566 defsubr (&Senlarge_window
);
7567 defsubr (&Sshrink_window
);
7568 defsubr (&Sadjust_window_trailing_edge
);
7569 defsubr (&Sscroll_up
);
7570 defsubr (&Sscroll_down
);
7571 defsubr (&Sscroll_left
);
7572 defsubr (&Sscroll_right
);
7573 defsubr (&Sother_window_for_scrolling
);
7574 defsubr (&Sscroll_other_window
);
7575 defsubr (&Sminibuffer_selected_window
);
7576 defsubr (&Srecenter
);
7577 defsubr (&Swindow_text_height
);
7578 defsubr (&Smove_to_window_line
);
7579 defsubr (&Swindow_configuration_p
);
7580 defsubr (&Swindow_configuration_frame
);
7581 defsubr (&Sset_window_configuration
);
7582 defsubr (&Scurrent_window_configuration
);
7583 defsubr (&Ssave_window_excursion
);
7584 defsubr (&Swindow_tree
);
7585 defsubr (&Sset_window_margins
);
7586 defsubr (&Swindow_margins
);
7587 defsubr (&Sset_window_fringes
);
7588 defsubr (&Swindow_fringes
);
7589 defsubr (&Sset_window_scroll_bars
);
7590 defsubr (&Swindow_scroll_bars
);
7591 defsubr (&Swindow_vscroll
);
7592 defsubr (&Sset_window_vscroll
);
7593 defsubr (&Scompare_window_configurations
);
7594 defsubr (&Swindow_list
);
7600 initial_define_key (control_x_map
, '1', "delete-other-windows");
7601 initial_define_key (control_x_map
, '2', "split-window");
7602 initial_define_key (control_x_map
, '0', "delete-window");
7603 initial_define_key (control_x_map
, 'o', "other-window");
7604 initial_define_key (control_x_map
, '^', "enlarge-window");
7605 initial_define_key (control_x_map
, '<', "scroll-left");
7606 initial_define_key (control_x_map
, '>', "scroll-right");
7608 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
7609 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
7610 initial_define_key (meta_map
, 'v', "scroll-down");
7612 initial_define_key (global_map
, Ctl('L'), "recenter");
7613 initial_define_key (meta_map
, 'r', "move-to-window-line");
7616 /* arch-tag: 90a9c576-0590-48f1-a5f1-6c96a0452d9f
7617 (do not change this comment) */