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, 2008, 2009, 2010
5 Free Software Foundation, Inc.
7 This file is part of GNU Emacs.
9 GNU Emacs is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 GNU Emacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
36 #include "dispextern.h"
37 #include "blockinput.h"
38 #include "intervals.h"
39 #include "termhooks.h" /* For FRAME_TERMINAL. */
43 #endif /* HAVE_X_WINDOWS */
55 Lisp_Object Qwindowp
, Qwindow_live_p
, Qwindow_configuration_p
;
56 Lisp_Object Qdisplay_buffer
;
57 Lisp_Object Qscroll_up
, Qscroll_down
, Qscroll_command
;
58 Lisp_Object Qwindow_size_fixed
;
60 extern Lisp_Object Qleft_margin
, Qright_margin
;
62 static int displayed_window_lines
P_ ((struct window
*));
63 static struct window
*decode_window
P_ ((Lisp_Object
));
64 static int count_windows
P_ ((struct window
*));
65 static int get_leaf_windows
P_ ((struct window
*, struct window
**, int));
66 static void window_scroll
P_ ((Lisp_Object
, int, int, int));
67 static void window_scroll_pixel_based
P_ ((Lisp_Object
, int, int, int));
68 static void window_scroll_line_based
P_ ((Lisp_Object
, int, int, int));
69 static int window_min_size_1
P_ ((struct window
*, int, int));
70 static int window_min_size_2
P_ ((struct window
*, int, int));
71 static int window_min_size
P_ ((struct window
*, int, int, int, int *));
72 static void size_window
P_ ((Lisp_Object
, int, int, int, int, int));
73 static int freeze_window_start
P_ ((struct window
*, void *));
74 static int window_fixed_size_p
P_ ((struct window
*, int, int));
75 static void enlarge_window
P_ ((Lisp_Object
, int, int));
76 static Lisp_Object window_list
P_ ((void));
77 static int add_window_to_list
P_ ((struct window
*, void *));
78 static int candidate_window_p
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
,
80 static Lisp_Object next_window
P_ ((Lisp_Object
, Lisp_Object
,
82 static void decode_next_window_args
P_ ((Lisp_Object
*, Lisp_Object
*,
84 static int foreach_window_1
P_ ((struct window
*,
85 int (* fn
) (struct window
*, void *),
87 static Lisp_Object window_list_1
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
));
89 /* This is the window in which the terminal's cursor should
90 be left when nothing is being done with it. This must
91 always be a leaf window, and its buffer is selected by
92 the top level editing loop at the end of each command.
94 This value is always the same as
95 FRAME_SELECTED_WINDOW (selected_frame). */
97 Lisp_Object selected_window
;
99 /* A list of all windows for use by next_window and Fwindow_list.
100 Functions creating or deleting windows should invalidate this cache
101 by setting it to nil. */
103 Lisp_Object Vwindow_list
;
105 /* The mini-buffer window of the selected frame.
106 Note that you cannot test for mini-bufferness of an arbitrary window
107 by comparing against this; but you can test for mini-bufferness of
108 the selected window. */
110 Lisp_Object minibuf_window
;
112 /* Non-nil means it is the window whose mode line should be
113 shown as the selected window when the minibuffer is selected. */
115 Lisp_Object minibuf_selected_window
;
117 /* Non-nil means it is the window for C-M-v to scroll
118 when the mini-buffer is selected. */
120 Lisp_Object Vminibuf_scroll_window
;
122 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
124 Lisp_Object Vother_window_scroll_buffer
;
126 /* Non-nil means it's function to call to display temp buffers. */
128 Lisp_Object Vtemp_buffer_show_function
;
130 /* Non-zero means line and page scrolling on tall lines (with images)
131 does partial scrolling by modifying window-vscroll. */
133 int auto_window_vscroll_p
;
135 /* Non-zero means to use mode-line-inactive face in all windows but the
136 selected-window and the minibuffer-scroll-window when the
137 minibuffer is active. */
138 int mode_line_in_non_selected_windows
;
140 /* If a window gets smaller than either of these, it is removed. */
142 EMACS_INT window_min_height
;
143 EMACS_INT window_min_width
;
145 /* Hook run at end of temp_output_buffer_show. */
147 Lisp_Object Qtemp_buffer_show_hook
;
149 /* Number of lines of continuity in scrolling by screenfuls. */
151 EMACS_INT next_screen_context_lines
;
153 /* Incremented for each window created. */
155 static int sequence_number
;
157 /* Nonzero after init_window_once has finished. */
159 static int window_initialized
;
161 /* Hook to run when window config changes. */
163 static Lisp_Object Qwindow_configuration_change_hook
;
164 static Lisp_Object Vwindow_configuration_change_hook
;
166 /* Non-nil means scroll commands try to put point
167 at the same screen height as previously. */
169 Lisp_Object Vscroll_preserve_screen_position
;
171 /* Non-nil means that text is inserted before window's markers. */
173 Lisp_Object Vwindow_point_insertion_type
;
175 /* Incremented by 1 whenever a window is deleted. */
177 int window_deletion_count
;
179 /* Used by the function window_scroll_pixel_based */
181 static int window_scroll_pixel_based_preserve_x
;
182 static int window_scroll_pixel_based_preserve_y
;
184 /* Same for window_scroll_line_based. */
186 static int window_scroll_preserve_hpos
;
187 static int window_scroll_preserve_vpos
;
189 #if 0 /* This isn't used anywhere. */
190 /* Nonzero means we can split a frame even if it is "unsplittable". */
191 static int inhibit_frame_unsplittable
;
194 extern EMACS_INT scroll_margin
;
196 extern Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
198 /* If non-nil, then the `recenter' command with a nil argument
199 the entire frame to be redrawn; the special value `tty' causes the
200 frame to be redrawn only if it is a tty frame. */
202 static Lisp_Object Vrecenter_redisplay
;
203 extern Lisp_Object Qtty
;
206 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
207 doc
: /* Return t if OBJECT is a window. */)
211 return WINDOWP (object
) ? Qt
: Qnil
;
214 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
215 doc
: /* Return t if OBJECT is a window which is currently visible. */)
219 return WINDOW_LIVE_P (object
) ? Qt
: Qnil
;
226 register struct window
*p
;
228 p
= allocate_window ();
230 XSETFASTINT (p
->sequence_number
, sequence_number
);
231 XSETFASTINT (p
->left_col
, 0);
232 XSETFASTINT (p
->top_line
, 0);
233 XSETFASTINT (p
->total_lines
, 0);
234 XSETFASTINT (p
->total_cols
, 0);
235 XSETFASTINT (p
->hscroll
, 0);
236 XSETFASTINT (p
->min_hscroll
, 0);
237 p
->orig_top_line
= p
->orig_total_lines
= Qnil
;
238 p
->start
= Fmake_marker ();
239 p
->pointm
= Fmake_marker ();
240 XSETFASTINT (p
->use_time
, 0);
242 p
->display_table
= Qnil
;
244 p
->window_parameters
= Qnil
;
245 p
->pseudo_window_p
= 0;
246 bzero (&p
->cursor
, sizeof (p
->cursor
));
247 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
248 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
249 p
->desired_matrix
= p
->current_matrix
= 0;
250 p
->nrows_scale_factor
= p
->ncols_scale_factor
= 1;
251 p
->phys_cursor_type
= -1;
252 p
->phys_cursor_width
= -1;
253 p
->must_be_updated_p
= 0;
254 XSETFASTINT (p
->window_end_vpos
, 0);
255 XSETFASTINT (p
->window_end_pos
, 0);
256 p
->window_end_valid
= Qnil
;
259 XSETFASTINT (p
->last_point
, 0);
260 p
->frozen_window_start_p
= 0;
261 p
->last_cursor_off_p
= p
->cursor_off_p
= 0;
262 p
->left_margin_cols
= Qnil
;
263 p
->right_margin_cols
= Qnil
;
264 p
->left_fringe_width
= Qnil
;
265 p
->right_fringe_width
= Qnil
;
266 p
->fringes_outside_margins
= Qnil
;
267 p
->scroll_bar_width
= Qnil
;
268 p
->vertical_scroll_bar_type
= Qt
;
269 p
->resize_proportionally
= Qnil
;
275 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
276 doc
: /* Return the window that the cursor now appears in and commands apply to. */)
279 return selected_window
;
282 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
283 doc
: /* Return the window used now for minibuffers.
284 If the optional argument FRAME is specified, return the minibuffer window
285 used by that frame. */)
290 frame
= selected_frame
;
291 CHECK_LIVE_FRAME (frame
);
292 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
295 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 0, 1, 0,
296 doc
: /* Return non-nil if WINDOW is a minibuffer window.
297 WINDOW defaults to the selected window. */)
301 struct window
*w
= decode_window (window
);
302 return MINI_WINDOW_P (w
) ? Qt
: Qnil
;
306 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
307 Spos_visible_in_window_p
, 0, 3, 0,
308 doc
: /* Return non-nil if position POS is currently on the frame in WINDOW.
309 Return nil if that position is scrolled vertically out of view.
310 If a character is only partially visible, nil is returned, unless the
311 optional argument PARTIALLY is non-nil.
312 If POS is only out of view because of horizontal scrolling, return non-nil.
313 If POS is t, it specifies the position of the last visible glyph in WINDOW.
314 POS defaults to point in WINDOW; WINDOW defaults to the selected window.
316 If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
317 return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
318 where X and Y are the pixel coordinates relative to the top left corner
319 of the window. The remaining elements are omitted if the character after
320 POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
321 off-window at the top and bottom of the row, ROWH is the height of the
322 display row, and VPOS is the row number (0-based) containing POS. */)
323 (pos
, window
, partially
)
324 Lisp_Object pos
, window
, partially
;
326 register struct window
*w
;
328 register struct buffer
*buf
;
330 Lisp_Object in_window
= Qnil
;
331 int rtop
, rbot
, rowh
, vpos
, fully_p
= 1;
334 w
= decode_window (window
);
335 buf
= XBUFFER (w
->buffer
);
336 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
340 else if (!NILP (pos
))
342 CHECK_NUMBER_COERCE_MARKER (pos
);
345 else if (w
== XWINDOW (selected_window
))
348 posint
= XMARKER (w
->pointm
)->charpos
;
350 /* If position is above window start or outside buffer boundaries,
351 or if window start is out of range, position is not visible. */
353 || (posint
>= CHARPOS (top
) && posint
<= BUF_ZV (buf
)))
354 && CHARPOS (top
) >= BUF_BEGV (buf
)
355 && CHARPOS (top
) <= BUF_ZV (buf
)
356 && pos_visible_p (w
, posint
, &x
, &y
, &rtop
, &rbot
, &rowh
, &vpos
)
357 && (fully_p
= !rtop
&& !rbot
, (!NILP (partially
) || fully_p
)))
360 if (!NILP (in_window
) && !NILP (partially
))
362 Lisp_Object part
= Qnil
;
364 part
= list4 (make_number (rtop
), make_number (rbot
),
365 make_number (rowh
), make_number (vpos
));
366 in_window
= Fcons (make_number (x
),
367 Fcons (make_number (y
), part
));
373 DEFUN ("window-line-height", Fwindow_line_height
,
374 Swindow_line_height
, 0, 2, 0,
375 doc
: /* Return height in pixels of text line LINE in window WINDOW.
376 If WINDOW is nil or omitted, use selected window.
378 Return height of current line if LINE is omitted or nil. Return height of
379 header or mode line if LINE is `header-line' and `mode-line'.
380 Otherwise, LINE is a text line number starting from 0. A negative number
381 counts from the end of the window.
383 Value is a list (HEIGHT VPOS YPOS OFFBOT), where HEIGHT is the height
384 in pixels of the visible part of the line, VPOS and YPOS are the
385 vertical position in lines and pixels of the line, relative to the top
386 of the first text line, and OFFBOT is the number of off-window pixels at
387 the bottom of the text line. If there are off-window pixels at the top
388 of the (first) text line, YPOS is negative.
390 Return nil if window display is not up-to-date. In that case, use
391 `pos-visible-in-window-p' to obtain the information. */)
393 Lisp_Object line
, window
;
395 register struct window
*w
;
396 register struct buffer
*b
;
397 struct glyph_row
*row
, *end_row
;
398 int max_y
, crop
, i
, n
;
400 w
= decode_window (window
);
403 || w
->pseudo_window_p
)
406 CHECK_BUFFER (w
->buffer
);
407 b
= XBUFFER (w
->buffer
);
409 /* Fail if current matrix is not up-to-date. */
410 if (NILP (w
->window_end_valid
)
411 || current_buffer
->clip_changed
412 || current_buffer
->prevent_redisplay_optimizations_p
413 || XFASTINT (w
->last_modified
) < BUF_MODIFF (b
)
414 || XFASTINT (w
->last_overlay_modified
) < BUF_OVERLAY_MODIFF (b
))
420 if (i
< 0 || i
>= w
->current_matrix
->nrows
421 || (row
= MATRIX_ROW (w
->current_matrix
, i
), !row
->enabled_p
))
423 max_y
= window_text_bottom_y (w
);
427 if (EQ (line
, Qheader_line
))
429 if (!WINDOW_WANTS_HEADER_LINE_P (w
))
431 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
434 return list4 (make_number (row
->height
),
435 make_number (0), make_number (0),
439 if (EQ (line
, Qmode_line
))
441 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
444 return list4 (make_number (row
->height
),
445 make_number (0), /* not accurate */
446 make_number (WINDOW_HEADER_LINE_HEIGHT (w
)
447 + window_text_bottom_y (w
)),
454 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
455 end_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
456 max_y
= window_text_bottom_y (w
);
459 while ((n
< 0 || i
< n
)
460 && row
<= end_row
&& row
->enabled_p
461 && row
->y
+ row
->height
< max_y
)
464 if (row
> end_row
|| !row
->enabled_p
)
476 crop
= max (0, (row
->y
+ row
->height
) - max_y
);
477 return list4 (make_number (row
->height
+ min (0, row
->y
) - crop
),
479 make_number (row
->y
),
485 static struct window
*
486 decode_window (window
)
487 register Lisp_Object window
;
490 return XWINDOW (selected_window
);
492 CHECK_LIVE_WINDOW (window
);
493 return XWINDOW (window
);
496 static struct window
*
497 decode_any_window (window
)
498 register Lisp_Object window
;
501 return XWINDOW (selected_window
);
503 CHECK_WINDOW (window
);
504 return XWINDOW (window
);
507 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
508 doc
: /* Return the buffer that WINDOW is displaying.
509 WINDOW defaults to the selected window. */)
513 return decode_window (window
)->buffer
;
516 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
517 doc
: /* Return the number of lines in WINDOW.
518 WINDOW defaults to the selected window.
520 The return value includes WINDOW's mode line and header line, if any. */)
524 return decode_any_window (window
)->total_lines
;
527 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
528 doc
: /* Return the number of display columns in WINDOW.
529 WINDOW defaults to the selected window.
531 Note: The return value is the number of columns available for text in
532 WINDOW. If you want to find out how many columns WINDOW takes up, use
533 (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))). */)
537 return make_number (window_box_text_cols (decode_any_window (window
)));
540 DEFUN ("window-full-width-p", Fwindow_full_width_p
, Swindow_full_width_p
, 0, 1, 0,
541 doc
: /* Return t if WINDOW is as wide as its frame.
542 WINDOW defaults to the selected window. */)
546 return WINDOW_FULL_WIDTH_P (decode_any_window (window
)) ? Qt
: Qnil
;
549 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
550 doc
: /* Return the number of columns by which WINDOW is scrolled from left margin.
551 WINDOW defaults to the selected window. */)
555 return decode_window (window
)->hscroll
;
558 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
559 doc
: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
560 Return NCOL. NCOL should be zero or positive.
562 Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
563 window so that the location of point moves off-window. */)
565 Lisp_Object window
, ncol
;
567 struct window
*w
= decode_window (window
);
571 hscroll
= max (0, XINT (ncol
));
573 /* Prevent redisplay shortcuts when changing the hscroll. */
574 if (XINT (w
->hscroll
) != hscroll
)
575 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
577 w
->hscroll
= make_number (hscroll
);
581 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
582 Swindow_redisplay_end_trigger
, 0, 1, 0,
583 doc
: /* Return WINDOW's redisplay end trigger value.
584 WINDOW defaults to the selected window.
585 See `set-window-redisplay-end-trigger' for more information. */)
589 return decode_window (window
)->redisplay_end_trigger
;
592 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
593 Sset_window_redisplay_end_trigger
, 2, 2, 0,
594 doc
: /* Set WINDOW's redisplay end trigger value to VALUE.
595 VALUE should be a buffer position (typically a marker) or nil.
596 If it is a buffer position, then if redisplay in WINDOW reaches a position
597 beyond VALUE, the functions in `redisplay-end-trigger-functions' are called
598 with two arguments: WINDOW, and the end trigger value.
599 Afterwards the end-trigger value is reset to nil. */)
601 register Lisp_Object window
, value
;
603 register struct window
*w
;
605 w
= decode_window (window
);
606 w
->redisplay_end_trigger
= value
;
610 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
611 doc
: /* Return a list of the edge coordinates of WINDOW.
612 The list has the form (LEFT TOP RIGHT BOTTOM).
613 TOP and BOTTOM count by lines, and LEFT and RIGHT count by columns,
614 all relative to 0, 0 at top left corner of frame.
616 RIGHT is one more than the rightmost column occupied by WINDOW.
617 BOTTOM is one more than the bottommost row occupied by WINDOW.
618 The edges include the space used by WINDOW's scroll bar, display
619 margins, fringes, header line, and/or mode line. For the edges of
620 just the text area, use `window-inside-edges'. */)
624 register struct window
*w
= decode_any_window (window
);
626 return Fcons (make_number (WINDOW_LEFT_EDGE_COL (w
)),
627 Fcons (make_number (WINDOW_TOP_EDGE_LINE (w
)),
628 Fcons (make_number (WINDOW_RIGHT_EDGE_COL (w
)),
629 Fcons (make_number (WINDOW_BOTTOM_EDGE_LINE (w
)),
633 DEFUN ("window-pixel-edges", Fwindow_pixel_edges
, Swindow_pixel_edges
, 0, 1, 0,
634 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
635 The list has the form (LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at
636 the top left corner of the frame.
638 RIGHT is one more than the rightmost x position occupied by WINDOW.
639 BOTTOM is one more than the bottommost y position occupied by WINDOW.
640 The pixel edges include the space used by WINDOW's scroll bar, display
641 margins, fringes, header line, and/or mode line. For the pixel edges
642 of just the text area, use `window-inside-pixel-edges'. */)
646 register struct window
*w
= decode_any_window (window
);
648 return Fcons (make_number (WINDOW_LEFT_EDGE_X (w
)),
649 Fcons (make_number (WINDOW_TOP_EDGE_Y (w
)),
650 Fcons (make_number (WINDOW_RIGHT_EDGE_X (w
)),
651 Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w
)),
656 calc_absolute_offset(struct window
*w
, int *add_x
, int *add_y
)
658 struct frame
*f
= XFRAME (w
->frame
);
660 #ifdef FRAME_MENUBAR_HEIGHT
661 *add_y
+= FRAME_MENUBAR_HEIGHT (f
);
663 #ifdef FRAME_TOOLBAR_HEIGHT
664 *add_y
+= FRAME_TOOLBAR_HEIGHT (f
);
666 #ifdef FRAME_NS_TITLEBAR_HEIGHT
667 *add_y
+= FRAME_NS_TITLEBAR_HEIGHT (f
);
669 *add_x
= f
->left_pos
;
672 DEFUN ("window-absolute-pixel-edges", Fwindow_absolute_pixel_edges
,
673 Swindow_absolute_pixel_edges
, 0, 1, 0,
674 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
675 The list has the form (LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at
676 the top left corner of the display.
678 RIGHT is one more than the rightmost x position occupied by WINDOW.
679 BOTTOM is one more than the bottommost y position occupied by WINDOW.
680 The pixel edges include the space used by WINDOW's scroll bar, display
681 margins, fringes, header line, and/or mode line. For the pixel edges
682 of just the text area, use `window-inside-absolute-pixel-edges'. */)
686 register struct window
*w
= decode_any_window (window
);
688 calc_absolute_offset(w
, &add_x
, &add_y
);
690 return Fcons (make_number (WINDOW_LEFT_EDGE_X (w
) + add_x
),
691 Fcons (make_number (WINDOW_TOP_EDGE_Y (w
) + add_y
),
692 Fcons (make_number (WINDOW_RIGHT_EDGE_X (w
) + add_x
),
693 Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w
) + add_y
),
697 DEFUN ("window-inside-edges", Fwindow_inside_edges
, Swindow_inside_edges
, 0, 1, 0,
698 doc
: /* Return a list of the edge coordinates of WINDOW.
699 The list has the form (LEFT TOP RIGHT BOTTOM).
700 TOP and BOTTOM count by lines, and LEFT and RIGHT count by columns,
701 all relative to 0, 0 at top left corner of frame.
703 RIGHT is one more than the rightmost column of WINDOW's text area.
704 BOTTOM is one more than the bottommost row of WINDOW's text area.
705 The inside edges do not include the space used by the WINDOW's scroll
706 bar, display margins, fringes, header line, and/or mode line. */)
710 register struct window
*w
= decode_any_window (window
);
712 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_COL (w
)
713 + WINDOW_LEFT_MARGIN_COLS (w
)
714 + WINDOW_LEFT_FRINGE_COLS (w
)),
715 make_number (WINDOW_TOP_EDGE_LINE (w
)
716 + WINDOW_HEADER_LINE_LINES (w
)),
717 make_number (WINDOW_BOX_RIGHT_EDGE_COL (w
)
718 - WINDOW_RIGHT_MARGIN_COLS (w
)
719 - WINDOW_RIGHT_FRINGE_COLS (w
)),
720 make_number (WINDOW_BOTTOM_EDGE_LINE (w
)
721 - WINDOW_MODE_LINE_LINES (w
)));
724 DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges
, Swindow_inside_pixel_edges
, 0, 1, 0,
725 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
726 The list has the form (LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at
727 the top left corner of the frame.
729 RIGHT is one more than the rightmost x position of WINDOW's text area.
730 BOTTOM is one more than the bottommost y position of WINDOW's text area.
731 The inside edges do not include the space used by WINDOW's scroll bar,
732 display margins, fringes, header line, and/or mode line. */)
736 register struct window
*w
= decode_any_window (window
);
738 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w
)
739 + WINDOW_LEFT_MARGIN_WIDTH (w
)
740 + WINDOW_LEFT_FRINGE_WIDTH (w
)),
741 make_number (WINDOW_TOP_EDGE_Y (w
)
742 + WINDOW_HEADER_LINE_HEIGHT (w
)),
743 make_number (WINDOW_BOX_RIGHT_EDGE_X (w
)
744 - WINDOW_RIGHT_MARGIN_WIDTH (w
)
745 - WINDOW_RIGHT_FRINGE_WIDTH (w
)),
746 make_number (WINDOW_BOTTOM_EDGE_Y (w
)
747 - WINDOW_MODE_LINE_HEIGHT (w
)));
750 DEFUN ("window-inside-absolute-pixel-edges",
751 Fwindow_inside_absolute_pixel_edges
,
752 Swindow_inside_absolute_pixel_edges
, 0, 1, 0,
753 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
754 The list has the form (LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at
755 the top left corner of the display.
757 RIGHT is one more than the rightmost x position of WINDOW's text area.
758 BOTTOM is one more than the bottommost y position of WINDOW's text area.
759 The inside edges do not include the space used by WINDOW's scroll bar,
760 display margins, fringes, header line, and/or mode line. */)
764 register struct window
*w
= decode_any_window (window
);
766 calc_absolute_offset(w
, &add_x
, &add_y
);
768 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w
)
769 + WINDOW_LEFT_MARGIN_WIDTH (w
)
770 + WINDOW_LEFT_FRINGE_WIDTH (w
) + add_x
),
771 make_number (WINDOW_TOP_EDGE_Y (w
)
772 + WINDOW_HEADER_LINE_HEIGHT (w
) + add_y
),
773 make_number (WINDOW_BOX_RIGHT_EDGE_X (w
)
774 - WINDOW_RIGHT_MARGIN_WIDTH (w
)
775 - WINDOW_RIGHT_FRINGE_WIDTH (w
) + add_x
),
776 make_number (WINDOW_BOTTOM_EDGE_Y (w
)
777 - WINDOW_MODE_LINE_HEIGHT (w
) + add_y
));
780 /* Test if the character at column *X, row *Y is within window W.
781 If it is not, return ON_NOTHING;
782 if it is in the window's text area,
783 set *x and *y to its location relative to the upper left corner
786 if it is on the window's modeline, return ON_MODE_LINE;
787 if it is on the border between the window and its right sibling,
788 return ON_VERTICAL_BORDER.
789 if it is on a scroll bar,
790 return ON_SCROLL_BAR.
791 if it is on the window's top line, return ON_HEADER_LINE;
792 if it is in left or right fringe of the window,
793 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE, and convert *X and *Y
794 to window-relative coordinates;
795 if it is in the marginal area to the left/right of the window,
796 return ON_LEFT_MARGIN or ON_RIGHT_MARGIN, and convert *X and *Y
797 to window-relative coordinates.
799 X and Y are frame relative pixel coordinates. */
801 static enum window_part
802 coordinates_in_window (w
, x
, y
)
803 register struct window
*w
;
806 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
807 int left_x
, right_x
, top_y
, bottom_y
;
808 enum window_part part
;
809 int ux
= FRAME_COLUMN_WIDTH (f
);
810 int x0
= WINDOW_LEFT_EDGE_X (w
);
811 int x1
= WINDOW_RIGHT_EDGE_X (w
);
812 /* The width of the area where the vertical line can be dragged.
813 (Between mode lines for instance. */
814 int grabbable_width
= ux
;
815 int lmargin_width
, rmargin_width
, text_left
, text_right
;
817 /* In what's below, we subtract 1 when computing right_x because we
818 want the rightmost pixel, which is given by left_pixel+width-1. */
819 if (w
->pseudo_window_p
)
822 right_x
= WINDOW_TOTAL_WIDTH (w
) - 1;
823 top_y
= WINDOW_TOP_EDGE_Y (w
);
824 bottom_y
= WINDOW_BOTTOM_EDGE_Y (w
);
828 left_x
= WINDOW_BOX_LEFT_EDGE_X (w
);
829 right_x
= WINDOW_BOX_RIGHT_EDGE_X (w
) - 1;
830 top_y
= WINDOW_TOP_EDGE_Y (w
);
831 bottom_y
= WINDOW_BOTTOM_EDGE_Y (w
);
834 /* Outside any interesting row? */
835 if (*y
< top_y
|| *y
>= bottom_y
)
838 /* On the mode line or header line? If it's near the start of
839 the mode or header line of window that's has a horizontal
840 sibling, say it's on the vertical line. That's to be able
841 to resize windows horizontally in case we're using toolkit
844 if (WINDOW_WANTS_MODELINE_P (w
)
845 && *y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
))
849 header_vertical_border_check
:
850 /* We're somewhere on the mode line. We consider the place
851 between mode lines of horizontally adjacent mode lines
852 as the vertical border. If scroll bars on the left,
853 return the right window. */
854 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
855 || WINDOW_RIGHTMOST_P (w
))
857 if (!WINDOW_LEFTMOST_P (w
) && eabs (*x
- x0
) < grabbable_width
)
859 /* Convert X and Y to window relative coordinates.
860 Vertical border is at the left edge of window. */
861 *x
= max (0, *x
- x0
);
863 return ON_VERTICAL_BORDER
;
868 /* Make sure we're not at the rightmost position of a
869 mode-/header-line and there's yet another window on
870 the right. (Bug#1372) */
871 if ((WINDOW_RIGHTMOST_P (w
) || *x
< x1
)
872 && eabs (*x
- x1
) < grabbable_width
)
874 /* Convert X and Y to window relative coordinates.
875 Vertical border is at the right edge of window. */
876 *x
= min (x1
, *x
) - x0
;
878 return ON_VERTICAL_BORDER
;
882 if (*x
< x0
|| *x
>= x1
)
885 /* Convert X and Y to window relative coordinates.
886 Mode line starts at left edge of window. */
892 if (WINDOW_WANTS_HEADER_LINE_P (w
)
893 && *y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
))
895 part
= ON_HEADER_LINE
;
896 goto header_vertical_border_check
;
899 if (*x
< x0
|| *x
>= x1
)
902 /* Outside any interesting column? */
903 if (*x
< left_x
|| *x
> right_x
)
906 return ON_SCROLL_BAR
;
909 lmargin_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
910 rmargin_width
= window_box_width (w
, RIGHT_MARGIN_AREA
);
912 text_left
= window_box_left (w
, TEXT_AREA
);
913 text_right
= text_left
+ window_box_width (w
, TEXT_AREA
);
915 if (FRAME_WINDOW_P (f
))
917 if (!w
->pseudo_window_p
918 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
)
919 && !WINDOW_RIGHTMOST_P (w
)
920 && (eabs (*x
- right_x
) < grabbable_width
))
922 /* Convert X and Y to window relative coordinates.
923 Vertical border is at the right edge of window. */
924 *x
= min (right_x
, *x
) - left_x
;
926 return ON_VERTICAL_BORDER
;
931 /* Need to say "*x > right_x" rather than >=, since on character
932 terminals, the vertical line's x coordinate is right_x. */
933 if (!w
->pseudo_window_p
934 && !WINDOW_RIGHTMOST_P (w
)
935 && *x
> right_x
- ux
)
937 /* On the border on the right side of the window? Assume that
938 this area begins at RIGHT_X minus a canonical char width. */
939 *x
= min (right_x
, *x
) - left_x
;
941 return ON_VERTICAL_BORDER
;
947 if (lmargin_width
> 0
948 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
949 ? (*x
>= left_x
+ WINDOW_LEFT_FRINGE_WIDTH (w
))
950 : (*x
< left_x
+ lmargin_width
)))
953 if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
954 *x
-= WINDOW_LEFT_FRINGE_WIDTH (w
);
956 return ON_LEFT_MARGIN
;
959 /* Convert X and Y to window-relative pixel coordinates. */
962 return ON_LEFT_FRINGE
;
965 if (*x
>= text_right
)
967 if (rmargin_width
> 0
968 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
969 ? (*x
< right_x
- WINDOW_RIGHT_FRINGE_WIDTH (w
))
970 : (*x
>= right_x
- rmargin_width
)))
972 *x
-= right_x
- rmargin_width
;
973 if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
974 *x
+= WINDOW_RIGHT_FRINGE_WIDTH (w
);
976 return ON_RIGHT_MARGIN
;
979 /* Convert X and Y to window-relative pixel coordinates. */
980 *x
-= left_x
+ WINDOW_LEFT_FRINGE_WIDTH (w
);
982 return ON_RIGHT_FRINGE
;
985 /* Everything special ruled out - must be on text area */
992 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
993 Scoordinates_in_window_p
, 2, 2, 0,
994 doc
: /* Return non-nil if COORDINATES are in WINDOW.
995 COORDINATES is a cons of the form (X . Y), X and Y being distances
996 measured in characters from the upper-left corner of the frame.
997 \(0 . 0) denotes the character in the upper left corner of the
999 If COORDINATES are in the text portion of WINDOW,
1000 the coordinates relative to the window are returned.
1001 If they are in the mode line of WINDOW, `mode-line' is returned.
1002 If they are in the top mode line of WINDOW, `header-line' is returned.
1003 If they are in the left fringe of WINDOW, `left-fringe' is returned.
1004 If they are in the right fringe of WINDOW, `right-fringe' is returned.
1005 If they are on the border between WINDOW and its right sibling,
1006 `vertical-line' is returned.
1007 If they are in the windows's left or right marginal areas, `left-margin'\n\
1008 or `right-margin' is returned. */)
1009 (coordinates
, window
)
1010 register Lisp_Object coordinates
, window
;
1017 CHECK_WINDOW (window
);
1018 w
= XWINDOW (window
);
1019 f
= XFRAME (w
->frame
);
1020 CHECK_CONS (coordinates
);
1021 lx
= Fcar (coordinates
);
1022 ly
= Fcdr (coordinates
);
1023 CHECK_NUMBER_OR_FLOAT (lx
);
1024 CHECK_NUMBER_OR_FLOAT (ly
);
1025 x
= FRAME_PIXEL_X_FROM_CANON_X (f
, lx
) + FRAME_INTERNAL_BORDER_WIDTH (f
);
1026 y
= FRAME_PIXEL_Y_FROM_CANON_Y (f
, ly
) + FRAME_INTERNAL_BORDER_WIDTH (f
);
1028 switch (coordinates_in_window (w
, &x
, &y
))
1034 /* X and Y are now window relative pixel coordinates. Convert
1035 them to canonical char units before returning them. */
1036 return Fcons (FRAME_CANON_X_FROM_PIXEL_X (f
, x
),
1037 FRAME_CANON_Y_FROM_PIXEL_Y (f
, y
));
1042 case ON_VERTICAL_BORDER
:
1043 return Qvertical_line
;
1045 case ON_HEADER_LINE
:
1046 return Qheader_line
;
1048 case ON_LEFT_FRINGE
:
1049 return Qleft_fringe
;
1051 case ON_RIGHT_FRINGE
:
1052 return Qright_fringe
;
1054 case ON_LEFT_MARGIN
:
1055 return Qleft_margin
;
1057 case ON_RIGHT_MARGIN
:
1058 return Qright_margin
;
1061 /* Historically we are supposed to return nil in this case. */
1070 /* Callback for foreach_window, used in window_from_coordinates.
1071 Check if window W contains coordinates specified by USER_DATA which
1072 is actually a pointer to a struct check_window_data CW.
1074 Check if window W contains coordinates *CW->x and *CW->y. If it
1075 does, return W in *CW->window, as Lisp_Object, and return in
1076 *CW->part the part of the window under coordinates *X,*Y. Return
1077 zero from this function to stop iterating over windows. */
1079 struct check_window_data
1081 Lisp_Object
*window
;
1083 enum window_part
*part
;
1087 check_window_containing (w
, user_data
)
1091 struct check_window_data
*cw
= (struct check_window_data
*) user_data
;
1092 enum window_part found
;
1095 found
= coordinates_in_window (w
, cw
->x
, cw
->y
);
1096 if (found
!= ON_NOTHING
)
1099 XSETWINDOW (*cw
->window
, w
);
1107 /* Find the window containing frame-relative pixel position X/Y and
1108 return it as a Lisp_Object.
1110 If X, Y is on one of the window's special `window_part' elements,
1111 set *PART to the id of that element, and return X and Y converted
1112 to window relative coordinates in WX and WY.
1114 If there is no window under X, Y return nil and leave *PART
1115 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows.
1117 This function was previously implemented with a loop cycling over
1118 windows with Fnext_window, and starting with the frame's selected
1119 window. It turned out that this doesn't work with an
1120 implementation of next_window using Vwindow_list, because
1121 FRAME_SELECTED_WINDOW (F) is not always contained in the window
1122 tree of F when this function is called asynchronously from
1123 note_mouse_highlight. The original loop didn't terminate in this
1127 window_from_coordinates (f
, x
, y
, part
, wx
, wy
, tool_bar_p
)
1130 enum window_part
*part
;
1135 struct check_window_data cw
;
1136 enum window_part dummy
;
1142 cw
.window
= &window
, cw
.x
= &x
, cw
.y
= &y
; cw
.part
= part
;
1143 foreach_window (f
, check_window_containing
, &cw
);
1145 /* If not found above, see if it's in the tool bar window, if a tool
1149 && WINDOWP (f
->tool_bar_window
)
1150 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0
1151 && (coordinates_in_window (XWINDOW (f
->tool_bar_window
), &x
, &y
)
1155 window
= f
->tool_bar_window
;
1164 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
1165 doc
: /* Return window containing coordinates X and Y on FRAME.
1166 If omitted, FRAME defaults to the currently selected frame.
1167 The top left corner of the frame is considered to be row 0,
1170 Lisp_Object x
, y
, frame
;
1175 frame
= selected_frame
;
1176 CHECK_LIVE_FRAME (frame
);
1179 /* Check that arguments are integers or floats. */
1180 CHECK_NUMBER_OR_FLOAT (x
);
1181 CHECK_NUMBER_OR_FLOAT (y
);
1183 return window_from_coordinates (f
,
1184 (FRAME_PIXEL_X_FROM_CANON_X (f
, x
)
1185 + FRAME_INTERNAL_BORDER_WIDTH (f
)),
1186 (FRAME_PIXEL_Y_FROM_CANON_Y (f
, y
)
1187 + FRAME_INTERNAL_BORDER_WIDTH (f
)),
1191 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
1192 doc
: /* Return current value of point in WINDOW.
1193 WINDOW defaults to the selected window.
1195 For a nonselected window, this is the value point would have
1196 if that window were selected.
1198 Note that, when WINDOW is the selected window and its buffer
1199 is also currently selected, the value returned is the same as (point).
1200 It would be more strictly correct to return the `top-level' value
1201 of point, outside of any save-excursion forms.
1202 But that is hard to define. */)
1206 register struct window
*w
= decode_window (window
);
1208 if (w
== XWINDOW (selected_window
)
1209 && current_buffer
== XBUFFER (w
->buffer
))
1211 return Fmarker_position (w
->pointm
);
1214 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
1215 doc
: /* Return position at which display currently starts in WINDOW.
1216 WINDOW defaults to the selected window.
1217 This is updated by redisplay or by calling `set-window-start'. */)
1221 return Fmarker_position (decode_window (window
)->start
);
1224 /* This is text temporarily removed from the doc string below.
1226 This function returns nil if the position is not currently known.
1227 That happens when redisplay is preempted and doesn't finish.
1228 If in that case you want to compute where the end of the window would
1229 have been if redisplay had finished, do this:
1231 (goto-char (window-start window))
1232 (vertical-motion (1- (window-height window)) window)
1235 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
1236 doc
: /* Return position at which display currently ends in WINDOW.
1237 WINDOW defaults to the selected window.
1238 This is updated by redisplay, when it runs to completion.
1239 Simply changing the buffer text or setting `window-start'
1240 does not update this value.
1241 Return nil if there is no recorded value. \(This can happen if the
1242 last redisplay of WINDOW was preempted, and did not finish.)
1243 If UPDATE is non-nil, compute the up-to-date position
1244 if it isn't already recorded. */)
1246 Lisp_Object window
, update
;
1249 struct window
*w
= decode_window (window
);
1257 #if 0 /* This change broke some things. We should make it later. */
1258 /* If we don't know the end position, return nil.
1259 The user can compute it with vertical-motion if he wants to.
1260 It would be nicer to do it automatically,
1261 but that's so slow that it would probably bother people. */
1262 if (NILP (w
->window_end_valid
))
1267 && ! (! NILP (w
->window_end_valid
)
1268 && XFASTINT (w
->last_modified
) >= BUF_MODIFF (b
)
1269 && XFASTINT (w
->last_overlay_modified
) >= BUF_OVERLAY_MODIFF (b
))
1272 struct text_pos startp
;
1274 struct buffer
*old_buffer
= NULL
;
1276 /* Cannot use Fvertical_motion because that function doesn't
1277 cope with variable-height lines. */
1278 if (b
!= current_buffer
)
1280 old_buffer
= current_buffer
;
1281 set_buffer_internal (b
);
1284 /* In case W->start is out of the range, use something
1285 reasonable. This situation occurred when loading a file with
1286 `-l' containing a call to `rmail' with subsequent other
1287 commands. At the end, W->start happened to be BEG, while
1288 rmail had already narrowed the buffer. */
1289 if (XMARKER (w
->start
)->charpos
< BEGV
)
1290 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
1291 else if (XMARKER (w
->start
)->charpos
> ZV
)
1292 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
1294 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
1296 start_display (&it
, w
, startp
);
1297 move_it_vertically (&it
, window_box_height (w
));
1298 if (it
.current_y
< it
.last_visible_y
)
1299 move_it_past_eol (&it
);
1300 value
= make_number (IT_CHARPOS (it
));
1303 set_buffer_internal (old_buffer
);
1306 XSETINT (value
, BUF_Z (b
) - XFASTINT (w
->window_end_pos
));
1311 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
1312 doc
: /* Make point value in WINDOW be at position POS in WINDOW's buffer.
1315 Lisp_Object window
, pos
;
1317 register struct window
*w
= decode_window (window
);
1319 CHECK_NUMBER_COERCE_MARKER (pos
);
1320 if (w
== XWINDOW (selected_window
)
1321 && XBUFFER (w
->buffer
) == current_buffer
)
1324 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
1326 /* We have to make sure that redisplay updates the window to show
1327 the new value of point. */
1328 if (!EQ (window
, selected_window
))
1329 ++windows_or_buffers_changed
;
1334 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
1335 doc
: /* Make display in WINDOW start at position POS in WINDOW's buffer.
1336 WINDOW defaults to the selected window. Return POS.
1337 Optional third arg NOFORCE non-nil inhibits next redisplay from
1338 overriding motion of point in order to display at this exact start. */)
1339 (window
, pos
, noforce
)
1340 Lisp_Object window
, pos
, noforce
;
1342 register struct window
*w
= decode_window (window
);
1344 CHECK_NUMBER_COERCE_MARKER (pos
);
1345 set_marker_restricted (w
->start
, pos
, w
->buffer
);
1346 /* this is not right, but much easier than doing what is right. */
1347 w
->start_at_line_beg
= Qnil
;
1349 w
->force_start
= Qt
;
1350 w
->update_mode_line
= Qt
;
1351 XSETFASTINT (w
->last_modified
, 0);
1352 XSETFASTINT (w
->last_overlay_modified
, 0);
1353 if (!EQ (window
, selected_window
))
1354 windows_or_buffers_changed
++;
1360 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
1362 doc
: /* Return non-nil when WINDOW is dedicated to its buffer.
1363 More precisely, return the value assigned by the last call of
1364 `set-window-dedicated-p' for WINDOW. Return nil if that function was
1365 never called with WINDOW as its argument, or the value set by that
1366 function was internally reset since its last call. WINDOW defaults to
1367 the selected window.
1369 When a window is dedicated to its buffer, `display-buffer' will refrain
1370 from displaying another buffer in it. `get-lru-window' and
1371 `get-largest-window' treat dedicated windows specially.
1372 `delete-windows-on', `replace-buffer-in-windows', `quit-window' and
1373 `kill-buffer' can delete a dedicated window and the containing frame.
1375 Functions like `set-window-buffer' may change the buffer displayed by a
1376 window, unless that window is "strongly" dedicated to its buffer, that
1377 is the value returned by `window-dedicated-p' is t. */)
1381 return decode_window (window
)->dedicated
;
1384 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
1385 Sset_window_dedicated_p
, 2, 2, 0,
1386 doc
: /* Mark WINDOW as dedicated according to FLAG.
1387 WINDOW defaults to the selected window. FLAG non-nil means mark WINDOW
1388 as dedicated to its buffer. FLAG nil means mark WINDOW as non-dedicated.
1391 When a window is dedicated to its buffer, `display-buffer' will refrain
1392 from displaying another buffer in it. `get-lru-window' and
1393 `get-largest-window' treat dedicated windows specially.
1394 `delete-windows-on', `replace-buffer-in-windows', `quit-window' and
1395 `kill-buffer' can delete a dedicated window and the containing
1398 As a special case, if FLAG is t, mark WINDOW as "strongly" dedicated to
1399 its buffer. Functions like `set-window-buffer' may change the buffer
1400 displayed by a window, unless that window is strongly dedicated to its
1401 buffer. If and when `set-window-buffer' displays another buffer in a
1402 window, it also makes sure that the window is not marked as dedicated. */)
1404 Lisp_Object window
, flag
;
1406 register struct window
*w
= decode_window (window
);
1408 w
->dedicated
= flag
;
1409 return w
->dedicated
;
1413 DEFUN ("window-parameters", Fwindow_parameters
, Swindow_parameters
,
1415 doc
: /* Return the parameters of WINDOW and their values.
1416 WINDOW defaults to the selected window. The return value is a list of
1417 elements of the form (PARAMETER . VALUE). */)
1421 return Fcopy_alist (decode_window (window
)->window_parameters
);
1424 DEFUN ("window-parameter", Fwindow_parameter
, Swindow_parameter
,
1426 doc
: /* Return WINDOW's value for PARAMETER.
1427 WINDOW defaults to the selected window. */)
1429 Lisp_Object window
, parameter
;
1433 result
= Fassq (parameter
, decode_window (window
)->window_parameters
);
1434 return CDR_SAFE (result
);
1437 DEFUN ("set-window-parameter", Fset_window_parameter
,
1438 Sset_window_parameter
, 3, 3, 0,
1439 doc
: /* Set WINDOW's value of PARAMETER to VALUE.
1440 WINDOW defaults to the selected window. Return VALUE. */)
1441 (window
, parameter
, value
)
1442 Lisp_Object window
, parameter
, value
;
1444 register struct window
*w
= decode_window (window
);
1445 Lisp_Object old_alist_elt
;
1447 old_alist_elt
= Fassq (parameter
, w
->window_parameters
);
1448 if (NILP (old_alist_elt
))
1449 w
->window_parameters
= Fcons (Fcons (parameter
, value
), w
->window_parameters
);
1451 Fsetcdr (old_alist_elt
, value
);
1456 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
1458 doc
: /* Return the display-table that WINDOW is using.
1459 WINDOW defaults to the selected window. */)
1463 return decode_window (window
)->display_table
;
1466 /* Get the display table for use on window W. This is either W's
1467 display table or W's buffer's display table. Ignore the specified
1468 tables if they are not valid; if no valid table is specified,
1471 struct Lisp_Char_Table
*
1472 window_display_table (w
)
1475 struct Lisp_Char_Table
*dp
= NULL
;
1477 if (DISP_TABLE_P (w
->display_table
))
1478 dp
= XCHAR_TABLE (w
->display_table
);
1479 else if (BUFFERP (w
->buffer
))
1481 struct buffer
*b
= XBUFFER (w
->buffer
);
1483 if (DISP_TABLE_P (b
->display_table
))
1484 dp
= XCHAR_TABLE (b
->display_table
);
1485 else if (DISP_TABLE_P (Vstandard_display_table
))
1486 dp
= XCHAR_TABLE (Vstandard_display_table
);
1492 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
1493 doc
: /* Set WINDOW's display-table to TABLE. */)
1495 register Lisp_Object window
, table
;
1497 register struct window
*w
;
1499 w
= decode_window (window
);
1500 w
->display_table
= table
;
1504 /* Record info on buffer window w is displaying
1505 when it is about to cease to display that buffer. */
1508 register struct window
*w
;
1515 if (b
!= XMARKER (w
->pointm
)->buffer
)
1519 if (w
== XWINDOW (selected_window
)
1520 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
1521 /* Do this except when the selected window's buffer
1522 is being removed from some other window. */
1524 /* last_window_start records the start position that this buffer
1525 had in the last window to be disconnected from it.
1526 Now that this statement is unconditional,
1527 it is possible for the buffer to be displayed in the
1528 selected window, while last_window_start reflects another
1529 window which was recently showing the same buffer.
1530 Some people might say that might be a good thing. Let's see. */
1531 b
->last_window_start
= marker_position (w
->start
);
1533 /* Point in the selected window's buffer
1534 is actually stored in that buffer, and the window's pointm isn't used.
1535 So don't clobber point in that buffer. */
1536 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
)
1537 /* This line helps to fix Horsley's testbug.el bug. */
1538 && !(WINDOWP (b
->last_selected_window
)
1539 && w
!= XWINDOW (b
->last_selected_window
)
1540 && EQ (buf
, XWINDOW (b
->last_selected_window
)->buffer
)))
1541 temp_set_point_both (b
,
1542 clip_to_bounds (BUF_BEGV (b
),
1543 XMARKER (w
->pointm
)->charpos
,
1545 clip_to_bounds (BUF_BEGV_BYTE (b
),
1546 marker_byte_position (w
->pointm
),
1549 if (WINDOWP (b
->last_selected_window
)
1550 && w
== XWINDOW (b
->last_selected_window
))
1551 b
->last_selected_window
= Qnil
;
1554 /* Put replacement into the window structure in place of old. */
1556 replace_window (old
, replacement
)
1557 Lisp_Object old
, replacement
;
1559 register Lisp_Object tem
;
1560 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
1562 /* If OLD is its frame's root_window, then replacement is the new
1563 root_window for that frame. */
1565 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
1566 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
1568 p
->left_col
= o
->left_col
;
1569 p
->top_line
= o
->top_line
;
1570 p
->total_cols
= o
->total_cols
;
1571 p
->total_lines
= o
->total_lines
;
1572 p
->desired_matrix
= p
->current_matrix
= 0;
1574 bzero (&p
->cursor
, sizeof (p
->cursor
));
1575 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
1576 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
1577 p
->phys_cursor_type
= -1;
1578 p
->phys_cursor_width
= -1;
1579 p
->must_be_updated_p
= 0;
1580 p
->pseudo_window_p
= 0;
1581 XSETFASTINT (p
->window_end_vpos
, 0);
1582 XSETFASTINT (p
->window_end_pos
, 0);
1583 p
->window_end_valid
= Qnil
;
1584 p
->frozen_window_start_p
= 0;
1585 p
->orig_top_line
= p
->orig_total_lines
= Qnil
;
1587 p
->next
= tem
= o
->next
;
1589 XWINDOW (tem
)->prev
= replacement
;
1591 p
->prev
= tem
= o
->prev
;
1593 XWINDOW (tem
)->next
= replacement
;
1595 p
->parent
= tem
= o
->parent
;
1598 if (EQ (XWINDOW (tem
)->vchild
, old
))
1599 XWINDOW (tem
)->vchild
= replacement
;
1600 if (EQ (XWINDOW (tem
)->hchild
, old
))
1601 XWINDOW (tem
)->hchild
= replacement
;
1604 /*** Here, if replacement is a vertical combination
1605 and so is its new parent, we should make replacement's
1606 children be children of that parent instead. ***/
1609 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
1610 doc
: /* Remove WINDOW from its frame.
1611 WINDOW defaults to the selected window. Return nil.
1612 Signal an error when WINDOW is the only window on its frame. */)
1614 register Lisp_Object window
;
1618 window
= selected_window
;
1620 CHECK_LIVE_WINDOW (window
);
1622 f
= XFRAME (WINDOW_FRAME (XWINDOW (window
)));
1623 delete_window (window
);
1625 run_window_configuration_change_hook (f
);
1631 delete_window (window
)
1632 register Lisp_Object window
;
1634 register Lisp_Object tem
, parent
, sib
;
1635 register struct window
*p
;
1636 register struct window
*par
;
1639 /* Because this function is called by other C code on non-leaf
1640 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1641 so we can't decode_window here. */
1642 CHECK_WINDOW (window
);
1643 p
= XWINDOW (window
);
1645 /* It's a no-op to delete an already-deleted window. */
1646 if (NILP (p
->buffer
)
1648 && NILP (p
->vchild
))
1653 error ("Attempt to delete minibuffer or sole ordinary window");
1654 par
= XWINDOW (parent
);
1656 windows_or_buffers_changed
++;
1657 Vwindow_list
= Qnil
;
1658 f
= XFRAME (WINDOW_FRAME (p
));
1659 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
1661 /* Are we trying to delete any frame's selected window? */
1663 Lisp_Object swindow
, pwindow
;
1665 /* See if the frame's selected window is either WINDOW
1666 or any subwindow of it, by finding all that window's parents
1667 and comparing each one with WINDOW. */
1668 swindow
= FRAME_SELECTED_WINDOW (f
);
1673 while (!NILP (pwindow
))
1675 if (EQ (window
, pwindow
))
1677 pwindow
= XWINDOW (pwindow
)->parent
;
1680 /* If the window being deleted is not a parent of SWINDOW,
1681 then SWINDOW is ok as the new selected window. */
1682 if (!EQ (window
, pwindow
))
1684 /* Otherwise, try another window for SWINDOW. */
1685 swindow
= Fnext_window (swindow
, Qlambda
, Qnil
);
1687 /* If we get back to the frame's selected window,
1688 it means there was no acceptable alternative,
1689 so we cannot delete. */
1690 if (EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
1691 error ("Cannot delete window");
1694 /* If we need to change SWINDOW, do it. */
1695 if (! EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
1697 /* If we're about to delete the selected window on the
1698 selected frame, then we should use Fselect_window to select
1699 the new window. On the other hand, if we're about to
1700 delete the selected window on any other frame, we shouldn't do
1701 anything but set the frame's selected_window slot. */
1702 if (EQ (FRAME_SELECTED_WINDOW (f
), selected_window
))
1703 Fselect_window (swindow
, Qnil
);
1705 FRAME_SELECTED_WINDOW (f
) = swindow
;
1709 /* Now we know we can delete this one. */
1710 window_deletion_count
++;
1713 /* tem is null for dummy parent windows
1714 (which have inferiors but not any contents themselves) */
1718 unchain_marker (XMARKER (p
->pointm
));
1719 unchain_marker (XMARKER (p
->start
));
1722 /* Free window glyph matrices. It is sure that they are allocated
1723 again when ADJUST_GLYPHS is called. Block input so that expose
1724 events and other events that access glyph matrices are not
1725 processed while we are changing them. */
1727 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f
)));
1731 XWINDOW (tem
)->prev
= p
->prev
;
1735 XWINDOW (tem
)->next
= p
->next
;
1737 if (EQ (window
, par
->hchild
))
1738 par
->hchild
= p
->next
;
1739 if (EQ (window
, par
->vchild
))
1740 par
->vchild
= p
->next
;
1742 /* Find one of our siblings to give our space to. */
1746 /* If p gives its space to its next sibling, that sibling needs
1747 to have its top/left side pulled back to where p's is.
1748 set_window_{height,width} will re-position the sibling's
1751 XWINDOW (sib
)->top_line
= p
->top_line
;
1752 XWINDOW (sib
)->left_col
= p
->left_col
;
1755 /* Stretch that sibling. */
1756 if (!NILP (par
->vchild
))
1757 set_window_height (sib
,
1758 XFASTINT (XWINDOW (sib
)->total_lines
) + XFASTINT (p
->total_lines
),
1760 if (!NILP (par
->hchild
))
1761 set_window_width (sib
,
1762 XFASTINT (XWINDOW (sib
)->total_cols
) + XFASTINT (p
->total_cols
),
1765 /* If parent now has only one child,
1766 put the child into the parent's place. */
1770 if (NILP (XWINDOW (tem
)->next
)) {
1771 replace_window (parent
, tem
);
1772 par
= XWINDOW (tem
);
1775 /* Since we may be deleting combination windows, we must make sure that
1776 not only p but all its children have been marked as deleted. */
1777 if (! NILP (p
->hchild
))
1778 delete_all_subwindows (XWINDOW (p
->hchild
));
1779 else if (! NILP (p
->vchild
))
1780 delete_all_subwindows (XWINDOW (p
->vchild
));
1782 /* Mark this window as deleted. */
1783 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
1785 if (! NILP (par
->parent
))
1786 par
= XWINDOW (par
->parent
);
1788 /* Check if we have a v/hchild with a v/hchild. In that case remove
1791 if (! NILP (par
->vchild
) && ! NILP (XWINDOW (par
->vchild
)->vchild
))
1793 p
= XWINDOW (par
->vchild
);
1794 par
->vchild
= p
->vchild
;
1797 else if (! NILP (par
->hchild
) && ! NILP (XWINDOW (par
->hchild
)->hchild
))
1799 p
= XWINDOW (par
->hchild
);
1800 par
->hchild
= p
->hchild
;
1808 while (! NILP (tem
)) {
1809 XWINDOW (tem
)->parent
= p
->parent
;
1810 if (NILP (XWINDOW (tem
)->next
))
1812 tem
= XWINDOW (tem
)->next
;
1815 /* The next of the v/hchild we are removing is now the next of the
1816 last child for the v/hchild:
1817 Before v/hchild -> v/hchild -> next1 -> next2
1820 After: v/hchild -> next1 -> next2 -> next3
1822 XWINDOW (tem
)->next
= p
->next
;
1823 if (! NILP (p
->next
))
1824 XWINDOW (p
->next
)->prev
= tem
;
1826 p
->next
= p
->prev
= p
->vchild
= p
->hchild
= p
->buffer
= Qnil
;
1830 /* Adjust glyph matrices. */
1837 /***********************************************************************
1839 ***********************************************************************/
1841 /* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object
1842 pointer. This is a callback function for foreach_window, used in
1843 function window_list. */
1846 add_window_to_list (w
, user_data
)
1850 Lisp_Object
*list
= (Lisp_Object
*) user_data
;
1852 XSETWINDOW (window
, w
);
1853 *list
= Fcons (window
, *list
);
1858 /* Return a list of all windows, for use by next_window. If
1859 Vwindow_list is a list, return that list. Otherwise, build a new
1860 list, cache it in Vwindow_list, and return that. */
1865 if (!CONSP (Vwindow_list
))
1869 Vwindow_list
= Qnil
;
1870 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
1872 Lisp_Object args
[2];
1874 /* We are visiting windows in canonical order, and add
1875 new windows at the front of args[1], which means we
1876 have to reverse this list at the end. */
1878 foreach_window (XFRAME (XCAR (tail
)), add_window_to_list
, &args
[1]);
1879 args
[0] = Vwindow_list
;
1880 args
[1] = Fnreverse (args
[1]);
1881 Vwindow_list
= Fnconc (2, args
);
1885 return Vwindow_list
;
1889 /* Value is non-zero if WINDOW satisfies the constraints given by
1890 OWINDOW, MINIBUF and ALL_FRAMES.
1892 MINIBUF t means WINDOW may be minibuffer windows.
1893 `lambda' means WINDOW may not be a minibuffer window.
1894 a window means a specific minibuffer window
1896 ALL_FRAMES t means search all frames,
1897 nil means search just current frame,
1898 `visible' means search just visible frames,
1899 0 means search visible and iconified frames,
1900 a window means search the frame that window belongs to,
1901 a frame means consider windows on that frame, only. */
1904 candidate_window_p (window
, owindow
, minibuf
, all_frames
)
1905 Lisp_Object window
, owindow
, minibuf
, all_frames
;
1907 struct window
*w
= XWINDOW (window
);
1908 struct frame
*f
= XFRAME (w
->frame
);
1909 int candidate_p
= 1;
1911 if (!BUFFERP (w
->buffer
))
1913 else if (MINI_WINDOW_P (w
)
1914 && (EQ (minibuf
, Qlambda
)
1915 || (WINDOWP (minibuf
) && !EQ (minibuf
, window
))))
1917 /* If MINIBUF is `lambda' don't consider any mini-windows.
1918 If it is a window, consider only that one. */
1921 else if (EQ (all_frames
, Qt
))
1923 else if (NILP (all_frames
))
1925 xassert (WINDOWP (owindow
));
1926 candidate_p
= EQ (w
->frame
, XWINDOW (owindow
)->frame
);
1928 else if (EQ (all_frames
, Qvisible
))
1930 FRAME_SAMPLE_VISIBILITY (f
);
1931 candidate_p
= FRAME_VISIBLE_P (f
)
1932 && (FRAME_TERMINAL (XFRAME (w
->frame
))
1933 == FRAME_TERMINAL (XFRAME (selected_frame
)));
1936 else if (INTEGERP (all_frames
) && XINT (all_frames
) == 0)
1938 FRAME_SAMPLE_VISIBILITY (f
);
1939 candidate_p
= (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)
1940 #ifdef HAVE_X_WINDOWS
1941 /* Yuck!! If we've just created the frame and the
1942 window-manager requested the user to place it
1943 manually, the window may still not be considered
1944 `visible'. I'd argue it should be at least
1945 something like `iconified', but don't know how to do
1947 || (FRAME_X_P (f
) && f
->output_data
.x
->asked_for_visible
1948 && !f
->output_data
.x
->has_been_visible
)
1951 && (FRAME_TERMINAL (XFRAME (w
->frame
))
1952 == FRAME_TERMINAL (XFRAME (selected_frame
)));
1954 else if (WINDOWP (all_frames
))
1955 candidate_p
= (EQ (FRAME_MINIBUF_WINDOW (f
), all_frames
)
1956 || EQ (XWINDOW (all_frames
)->frame
, w
->frame
)
1957 || EQ (XWINDOW (all_frames
)->frame
, FRAME_FOCUS_FRAME (f
)));
1958 else if (FRAMEP (all_frames
))
1959 candidate_p
= EQ (all_frames
, w
->frame
);
1965 /* Decode arguments as allowed by Fnext_window, Fprevious_window, and
1966 Fwindow_list. See there for the meaning of WINDOW, MINIBUF, and
1970 decode_next_window_args (window
, minibuf
, all_frames
)
1971 Lisp_Object
*window
, *minibuf
, *all_frames
;
1974 *window
= selected_window
;
1976 CHECK_LIVE_WINDOW (*window
);
1978 /* MINIBUF nil may or may not include minibuffers. Decide if it
1980 if (NILP (*minibuf
))
1981 *minibuf
= minibuf_level
? minibuf_window
: Qlambda
;
1982 else if (!EQ (*minibuf
, Qt
))
1985 /* Now *MINIBUF can be t => count all minibuffer windows, `lambda'
1986 => count none of them, or a specific minibuffer window (the
1987 active one) to count. */
1989 /* ALL_FRAMES nil doesn't specify which frames to include. */
1990 if (NILP (*all_frames
))
1991 *all_frames
= (!EQ (*minibuf
, Qlambda
)
1992 ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window
)->frame
))
1994 else if (EQ (*all_frames
, Qvisible
))
1996 else if (EQ (*all_frames
, make_number (0)))
1998 else if (FRAMEP (*all_frames
))
2000 else if (!EQ (*all_frames
, Qt
))
2003 /* Now *ALL_FRAMES is t meaning search all frames, nil meaning
2004 search just current frame, `visible' meaning search just visible
2005 frames, 0 meaning search visible and iconified frames, or a
2006 window, meaning search the frame that window belongs to, or a
2007 frame, meaning consider windows on that frame, only. */
2011 /* Return the next or previous window of WINDOW in cyclic ordering
2012 of windows. NEXT_P non-zero means return the next window. See the
2013 documentation string of next-window for the meaning of MINIBUF and
2017 next_window (window
, minibuf
, all_frames
, next_p
)
2018 Lisp_Object window
, minibuf
, all_frames
;
2021 decode_next_window_args (&window
, &minibuf
, &all_frames
);
2023 /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just
2024 return the first window on the frame. */
2025 if (FRAMEP (all_frames
)
2026 && !EQ (all_frames
, XWINDOW (window
)->frame
))
2027 return Fframe_first_window (all_frames
);
2033 /* Find WINDOW in the list of all windows. */
2034 list
= Fmemq (window
, window_list ());
2036 /* Scan forward from WINDOW to the end of the window list. */
2038 for (list
= XCDR (list
); CONSP (list
); list
= XCDR (list
))
2039 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
2042 /* Scan from the start of the window list up to WINDOW. */
2044 for (list
= Vwindow_list
;
2045 CONSP (list
) && !EQ (XCAR (list
), window
);
2047 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
2051 window
= XCAR (list
);
2055 Lisp_Object candidate
, list
;
2057 /* Scan through the list of windows for candidates. If there are
2058 candidate windows in front of WINDOW, the last one of these
2059 is the one we want. If there are candidates following WINDOW
2060 in the list, again the last one of these is the one we want. */
2062 for (list
= window_list (); CONSP (list
); list
= XCDR (list
))
2064 if (EQ (XCAR (list
), window
))
2066 if (WINDOWP (candidate
))
2069 else if (candidate_window_p (XCAR (list
), window
, minibuf
,
2071 candidate
= XCAR (list
);
2074 if (WINDOWP (candidate
))
2082 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
2083 doc
: /* Return window following WINDOW in cyclic ordering of windows.
2084 WINDOW defaults to the selected window. The optional arguments
2085 MINIBUF and ALL-FRAMES specify the set of windows to consider.
2087 MINIBUF t means consider the minibuffer window even if the
2088 minibuffer is not active. MINIBUF nil or omitted means consider
2089 the minibuffer window only if the minibuffer is active. Any
2090 other value means do not consider the minibuffer window even if
2091 the minibuffer is active.
2093 Several frames may share a single minibuffer; if the minibuffer
2094 is active, all windows on all frames that share that minibuffer
2095 are considered too. Therefore, if you are using a separate
2096 minibuffer frame and the minibuffer is active and MINIBUF says it
2097 counts, `next-window' considers the windows in the frame from
2098 which you entered the minibuffer, as well as the minibuffer
2101 ALL-FRAMES nil or omitted means consider all windows on WINDOW's
2102 frame, plus the minibuffer window if specified by the MINIBUF
2103 argument, see above. If the minibuffer counts, consider all
2104 windows on all frames that share that minibuffer too.
2105 ALL-FRAMES t means consider all windows on all existing frames.
2106 ALL-FRAMES `visible' means consider all windows on all visible
2108 ALL-FRAMES 0 means consider all windows on all visible and
2110 ALL-FRAMES a frame means consider all windows on that frame only.
2111 Anything else means consider all windows on WINDOW's frame and no
2114 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
2115 `next-window' to iterate through the entire cycle of acceptable
2116 windows, eventually ending up back at the window you started with.
2117 `previous-window' traverses the same cycle, in the reverse order. */)
2118 (window
, minibuf
, all_frames
)
2119 Lisp_Object window
, minibuf
, all_frames
;
2121 return next_window (window
, minibuf
, all_frames
, 1);
2125 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
2126 doc
: /* Return window preceding WINDOW in cyclic ordering of windows.
2127 WINDOW defaults to the selected window. The optional arguments
2128 MINIBUF and ALL-FRAMES specify the set of windows to consider.
2129 For the precise meaning of these arguments see `next-window'.
2131 If you use consistent values for MINIBUF and ALL-FRAMES, you can
2132 use `previous-window' to iterate through the entire cycle of
2133 acceptable windows, eventually ending up back at the window you
2134 started with. `next-window' traverses the same cycle, in the
2136 (window
, minibuf
, all_frames
)
2137 Lisp_Object window
, minibuf
, all_frames
;
2139 return next_window (window
, minibuf
, all_frames
, 0);
2143 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
2144 doc
: /* Select another window in cyclic ordering of windows.
2145 COUNT specifies the number of windows to skip, starting with the
2146 selected window, before making the selection. If COUNT is
2147 positive, skip COUNT windows forwards. If COUNT is negative,
2148 skip -COUNT windows backwards. COUNT zero means do not skip any
2149 window, so select the selected window. In an interactive call,
2150 COUNT is the numeric prefix argument. Return nil.
2152 This function uses `next-window' for finding the window to select.
2153 The argument ALL-FRAMES has the same meaning as in `next-window',
2154 but the MINIBUF argument of `next-window' is always effectively
2157 Lisp_Object count
, all_frames
;
2162 CHECK_NUMBER (count
);
2163 window
= selected_window
;
2165 for (i
= XINT (count
); i
> 0; --i
)
2166 window
= Fnext_window (window
, Qnil
, all_frames
);
2168 window
= Fprevious_window (window
, Qnil
, all_frames
);
2170 Fselect_window (window
, Qnil
);
2175 DEFUN ("window-list", Fwindow_list
, Swindow_list
, 0, 3, 0,
2176 doc
: /* Return a list of windows on FRAME, starting with WINDOW.
2177 FRAME nil or omitted means use the selected frame.
2178 WINDOW nil or omitted means use the selected window.
2179 MINIBUF t means include the minibuffer window, even if it isn't active.
2180 MINIBUF nil or omitted means include the minibuffer window only
2182 MINIBUF neither nil nor t means never include the minibuffer window. */)
2183 (frame
, minibuf
, window
)
2184 Lisp_Object frame
, minibuf
, window
;
2187 window
= FRAMEP (frame
) ? XFRAME (frame
)->selected_window
: selected_window
;
2188 CHECK_WINDOW (window
);
2190 frame
= selected_frame
;
2192 if (!EQ (frame
, XWINDOW (window
)->frame
))
2193 error ("Window is on a different frame");
2195 return window_list_1 (window
, minibuf
, frame
);
2199 /* Return a list of windows in cyclic ordering. Arguments are like
2200 for `next-window'. */
2203 window_list_1 (window
, minibuf
, all_frames
)
2204 Lisp_Object window
, minibuf
, all_frames
;
2206 Lisp_Object tail
, list
, rest
;
2208 decode_next_window_args (&window
, &minibuf
, &all_frames
);
2211 for (tail
= window_list (); CONSP (tail
); tail
= XCDR (tail
))
2212 if (candidate_window_p (XCAR (tail
), window
, minibuf
, all_frames
))
2213 list
= Fcons (XCAR (tail
), list
);
2215 /* Rotate the list to start with WINDOW. */
2216 list
= Fnreverse (list
);
2217 rest
= Fmemq (window
, list
);
2218 if (!NILP (rest
) && !EQ (rest
, list
))
2220 for (tail
= list
; !EQ (XCDR (tail
), rest
); tail
= XCDR (tail
))
2222 XSETCDR (tail
, Qnil
);
2223 list
= nconc2 (rest
, list
);
2230 /* Look at all windows, performing an operation specified by TYPE
2232 If FRAMES is Qt, look at all frames;
2233 Qnil, look at just the selected frame;
2234 Qvisible, look at visible frames;
2235 a frame, just look at windows on that frame.
2236 If MINI is non-zero, perform the operation on minibuffer windows too. */
2241 GET_BUFFER_WINDOW
, /* Arg is buffer */
2242 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
2243 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
2244 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
2246 UNSHOW_BUFFER
, /* Arg is buffer */
2247 REDISPLAY_BUFFER_WINDOWS
, /* Arg is buffer */
2252 window_loop (type
, obj
, mini
, frames
)
2253 enum window_loop type
;
2254 Lisp_Object obj
, frames
;
2257 Lisp_Object window
, windows
, best_window
, frame_arg
;
2259 struct gcpro gcpro1
;
2261 /* If we're only looping through windows on a particular frame,
2262 frame points to that frame. If we're looping through windows
2263 on all frames, frame is 0. */
2264 if (FRAMEP (frames
))
2265 f
= XFRAME (frames
);
2266 else if (NILP (frames
))
2267 f
= SELECTED_FRAME ();
2272 frame_arg
= Qlambda
;
2273 else if (EQ (frames
, make_number (0)))
2275 else if (EQ (frames
, Qvisible
))
2280 /* frame_arg is Qlambda to stick to one frame,
2281 Qvisible to consider all visible frames,
2284 /* Pick a window to start with. */
2288 window
= FRAME_SELECTED_WINDOW (f
);
2290 window
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
2292 windows
= window_list_1 (window
, mini
? Qt
: Qnil
, frame_arg
);
2296 for (; CONSP (windows
); windows
= XCDR (windows
))
2300 window
= XCAR (windows
);
2301 w
= XWINDOW (window
);
2303 /* Note that we do not pay attention here to whether the frame
2304 is visible, since Fwindow_list skips non-visible frames if
2305 that is desired, under the control of frame_arg. */
2306 if (!MINI_WINDOW_P (w
)
2307 /* For UNSHOW_BUFFER, we must always consider all windows. */
2308 || type
== UNSHOW_BUFFER
2309 || (mini
&& minibuf_level
> 0))
2312 case GET_BUFFER_WINDOW
:
2313 if (EQ (w
->buffer
, obj
)
2314 /* Don't find any minibuffer window
2315 except the one that is currently in use. */
2316 && (MINI_WINDOW_P (w
)
2317 ? EQ (window
, minibuf_window
)
2320 if (NILP (best_window
))
2321 best_window
= window
;
2322 else if (EQ (window
, selected_window
))
2323 /* Prefer to return selected-window. */
2324 RETURN_UNGCPRO (window
);
2325 else if (EQ (Fwindow_frame (window
), selected_frame
))
2326 /* Prefer windows on the current frame. */
2327 best_window
= window
;
2331 case GET_LRU_WINDOW
:
2332 /* `obj' is an integer encoding a bitvector.
2333 `obj & 1' means consider only full-width windows.
2334 `obj & 2' means consider also dedicated windows. */
2335 if (((XINT (obj
) & 1) && !WINDOW_FULL_WIDTH_P (w
))
2336 || (!(XINT (obj
) & 2) && !NILP (w
->dedicated
))
2337 /* Minibuffer windows are always ignored. */
2338 || MINI_WINDOW_P (w
))
2340 if (NILP (best_window
)
2341 || (XFASTINT (XWINDOW (best_window
)->use_time
)
2342 > XFASTINT (w
->use_time
)))
2343 best_window
= window
;
2346 case DELETE_OTHER_WINDOWS
:
2347 if (!EQ (window
, obj
))
2348 Fdelete_window (window
);
2351 case DELETE_BUFFER_WINDOWS
:
2352 if (EQ (w
->buffer
, obj
))
2354 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2356 /* If this window is dedicated, and in a frame of its own,
2358 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
2359 && !NILP (w
->dedicated
)
2360 && other_visible_frames (f
))
2362 /* Skip the other windows on this frame.
2363 There might be one, the minibuffer! */
2364 while (CONSP (XCDR (windows
))
2365 && EQ (XWINDOW (XCAR (windows
))->frame
,
2366 XWINDOW (XCAR (XCDR (windows
)))->frame
))
2367 windows
= XCDR (windows
);
2369 /* Now we can safely delete the frame. */
2370 delete_frame (w
->frame
, Qnil
);
2372 else if (NILP (w
->parent
))
2374 /* If we're deleting the buffer displayed in the
2375 only window on the frame, find a new buffer to
2378 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
2379 /* Reset dedicated state of window. */
2380 w
->dedicated
= Qnil
;
2381 Fset_window_buffer (window
, buffer
, Qnil
);
2382 if (EQ (window
, selected_window
))
2383 Fset_buffer (w
->buffer
);
2386 Fdelete_window (window
);
2390 case GET_LARGEST_WINDOW
:
2391 { /* nil `obj' means to ignore dedicated windows. */
2392 /* Ignore dedicated windows and minibuffers. */
2393 if (MINI_WINDOW_P (w
) || (NILP (obj
) && !NILP (w
->dedicated
)))
2396 if (NILP (best_window
))
2397 best_window
= window
;
2400 struct window
*b
= XWINDOW (best_window
);
2401 if (XFASTINT (w
->total_lines
) * XFASTINT (w
->total_cols
)
2402 > XFASTINT (b
->total_lines
) * XFASTINT (b
->total_cols
))
2403 best_window
= window
;
2409 if (EQ (w
->buffer
, obj
))
2412 struct frame
*f
= XFRAME (w
->frame
);
2414 /* Find another buffer to show in this window. */
2415 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
2417 /* If this window is dedicated, and in a frame of its own,
2419 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
2420 && !NILP (w
->dedicated
)
2421 && other_visible_frames (f
))
2423 /* Skip the other windows on this frame.
2424 There might be one, the minibuffer! */
2425 while (CONSP (XCDR (windows
))
2426 && EQ (XWINDOW (XCAR (windows
))->frame
,
2427 XWINDOW (XCAR (XCDR (windows
)))->frame
))
2428 windows
= XCDR (windows
);
2430 /* Now we can safely delete the frame. */
2431 delete_frame (w
->frame
, Qnil
);
2433 else if (!NILP (w
->dedicated
) && !NILP (w
->parent
))
2436 XSETWINDOW (window
, w
);
2437 /* If this window is dedicated and not the only window
2438 in its frame, then kill it. */
2439 Fdelete_window (window
);
2443 /* Otherwise show a different buffer in the window. */
2444 w
->dedicated
= Qnil
;
2445 Fset_window_buffer (window
, buffer
, Qnil
);
2446 if (EQ (window
, selected_window
))
2447 Fset_buffer (w
->buffer
);
2452 case REDISPLAY_BUFFER_WINDOWS
:
2453 if (EQ (w
->buffer
, obj
))
2455 mark_window_display_accurate (window
, 0);
2456 w
->update_mode_line
= Qt
;
2457 XBUFFER (obj
)->prevent_redisplay_optimizations_p
= 1;
2458 ++update_mode_lines
;
2459 best_window
= window
;
2463 /* Check for a window that has a killed buffer. */
2464 case CHECK_ALL_WINDOWS
:
2465 if (! NILP (w
->buffer
)
2466 && NILP (XBUFFER (w
->buffer
)->name
))
2470 case WINDOW_LOOP_UNUSED
:
2479 /* Used for debugging. Abort if any window has a dead buffer. */
2482 check_all_windows ()
2484 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
2487 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 2, 0,
2488 doc
: /* Return the window least recently selected or used for display.
2489 \(LRU means Least Recently Used.)
2491 Return a full-width window if possible.
2492 A minibuffer window is never a candidate.
2493 A dedicated window is never a candidate, unless DEDICATED is non-nil,
2494 so if all windows are dedicated, the value is nil.
2495 If optional argument FRAME is `visible', search all visible frames.
2496 If FRAME is 0, search all visible and iconified frames.
2497 If FRAME is t, search all frames.
2498 If FRAME is nil, search only the selected frame.
2499 If FRAME is a frame, search only that frame. */)
2501 Lisp_Object frame
, dedicated
;
2503 register Lisp_Object w
;
2504 /* First try for a window that is full-width */
2505 w
= window_loop (GET_LRU_WINDOW
,
2506 NILP (dedicated
) ? make_number (1) : make_number (3),
2508 if (!NILP (w
) && !EQ (w
, selected_window
))
2510 /* If none of them, try the rest */
2511 return window_loop (GET_LRU_WINDOW
,
2512 NILP (dedicated
) ? make_number (0) : make_number (2),
2516 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 2, 0,
2517 doc
: /* Return the largest window in area.
2518 A minibuffer window is never a candidate.
2519 A dedicated window is never a candidate unless DEDICATED is non-nil,
2520 so if all windows are dedicated, the value is nil.
2521 If optional argument FRAME is `visible', search all visible frames.
2522 If FRAME is 0, search all visible and iconified frames.
2523 If FRAME is t, search all frames.
2524 If FRAME is nil, search only the selected frame.
2525 If FRAME is a frame, search only that frame. */)
2527 Lisp_Object frame
, dedicated
;
2529 return window_loop (GET_LARGEST_WINDOW
, dedicated
, 0,
2533 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 0, 2, 0,
2534 doc
: /* Return a window currently displaying BUFFER-OR-NAME, or nil if none.
2535 BUFFER-OR-NAME may be a buffer or a buffer name and defaults to the
2537 If optional argument FRAME is `visible', search all visible frames.
2538 If optional argument FRAME is 0, search all visible and iconified frames.
2539 If FRAME is t, search all frames.
2540 If FRAME is nil, search only the selected frame.
2541 If FRAME is a frame, search only that frame. */)
2542 (buffer_or_name
, frame
)
2543 Lisp_Object buffer_or_name
, frame
;
2547 if (NILP (buffer_or_name
))
2548 buffer
= Fcurrent_buffer ();
2550 buffer
= Fget_buffer (buffer_or_name
);
2552 if (BUFFERP (buffer
))
2553 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
2558 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
2560 doc
: /* Make WINDOW (or the selected window) fill its frame.
2561 Only the frame WINDOW is on is affected.
2562 This function tries to reduce display jumps by keeping the text
2563 previously visible in WINDOW in the same place on the frame. Doing this
2564 depends on the value of (window-start WINDOW), so if calling this
2565 function in a program gives strange scrolling, make sure the
2566 window-start value is reasonable when this function is called. */)
2575 window
= selected_window
;
2577 CHECK_LIVE_WINDOW (window
);
2578 w
= XWINDOW (window
);
2580 startpos
= marker_position (w
->start
);
2581 top
= WINDOW_TOP_EDGE_LINE (w
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2583 if (MINI_WINDOW_P (w
) && top
> 0)
2584 error ("Can't expand minibuffer to full frame");
2586 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
2588 /* Try to minimize scrolling, by setting the window start to the point
2589 will cause the text at the old window start to be at the same place
2590 on the frame. But don't try to do this if the window start is
2591 outside the visible portion (as might happen when the display is
2592 not current, due to typeahead). */
2593 new_top
= WINDOW_TOP_EDGE_LINE (w
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2595 && startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
2596 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
2598 struct position pos
;
2599 struct buffer
*obuf
= current_buffer
;
2601 Fset_buffer (w
->buffer
);
2602 /* This computation used to temporarily move point, but that can
2603 have unwanted side effects due to text properties. */
2604 pos
= *vmotion (startpos
, -top
, w
);
2606 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
2607 w
->window_end_valid
= Qnil
;
2608 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
2609 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
2611 /* We need to do this, so that the window-scroll-functions
2613 w
->optional_new_start
= Qt
;
2615 set_buffer_internal (obuf
);
2621 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
2622 0, 2, "bDelete windows on (buffer): ",
2623 doc
: /* Delete all windows showing BUFFER-OR-NAME.
2624 BUFFER-OR-NAME may be a buffer or the name of an existing buffer and
2625 defaults to the current buffer.
2627 Optional second argument FRAME controls which frames are affected.
2628 If optional argument FRAME is `visible', search all visible frames.
2629 If FRAME is 0, search all visible and iconified frames.
2630 If FRAME is nil, search all frames.
2631 If FRAME is t, search only the selected frame.
2632 If FRAME is a frame, search only that frame.
2633 When a window showing BUFFER-OR-NAME is dedicated and the only window of
2634 its frame, that frame is deleted when there are other frames left. */)
2635 (buffer_or_name
, frame
)
2636 Lisp_Object buffer_or_name
, frame
;
2640 /* FRAME uses t and nil to mean the opposite of what window_loop
2644 else if (EQ (frame
, Qt
))
2647 if (NILP (buffer_or_name
))
2648 buffer
= Fcurrent_buffer ();
2651 buffer
= Fget_buffer (buffer_or_name
);
2652 CHECK_BUFFER (buffer
);
2655 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
2660 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
2661 Sreplace_buffer_in_windows
,
2662 0, 1, "bReplace buffer in windows: ",
2663 doc
: /* Replace BUFFER-OR-NAME with some other buffer in all windows showing it.
2664 BUFFER-OR-NAME may be a buffer or the name of an existing buffer and
2665 defaults to the current buffer.
2667 When a window showing BUFFER-OR-NAME is dedicated that window is
2668 deleted. If that window is the only window on its frame, that frame is
2669 deleted too when there are other frames left. If there are no other
2670 frames left, some other buffer is displayed in that window. */)
2672 Lisp_Object buffer_or_name
;
2676 if (NILP (buffer_or_name
))
2677 buffer
= Fcurrent_buffer ();
2680 buffer
= Fget_buffer (buffer_or_name
);
2681 CHECK_BUFFER (buffer
);
2684 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
2689 /* Replace BUFFER with some other buffer in all windows
2690 of all frames, even those on other keyboards. */
2693 replace_buffer_in_all_windows (buffer
)
2696 Lisp_Object tail
, frame
;
2698 /* A single call to window_loop won't do the job
2699 because it only considers frames on the current keyboard.
2700 So loop manually over frames, and handle each one. */
2701 FOR_EACH_FRAME (tail
, frame
)
2702 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
2705 /* Set the height of WINDOW and all its inferiors. */
2707 /* The smallest acceptable dimensions for a window. Anything smaller
2708 might crash Emacs. */
2710 #define MIN_SAFE_WINDOW_WIDTH (2)
2711 #define MIN_SAFE_WINDOW_HEIGHT (1)
2713 /* For wp non-zero the total number of columns of window w. Otherwise
2714 the total number of lines of w. */
2716 #define WINDOW_TOTAL_SIZE(w, wp) \
2717 (wp ? WINDOW_TOTAL_COLS (w) : WINDOW_TOTAL_LINES (w))
2719 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
2720 minimum allowable size. */
2723 check_frame_size (frame
, rows
, cols
)
2727 /* For height, we have to see:
2728 how many windows the frame has at minimum (one or two),
2729 and whether it has a menu bar or other special stuff at the top. */
2731 = ((FRAME_MINIBUF_ONLY_P (frame
) || ! FRAME_HAS_MINIBUF_P (frame
))
2732 ? MIN_SAFE_WINDOW_HEIGHT
2733 : 2 * MIN_SAFE_WINDOW_HEIGHT
);
2735 if (FRAME_TOP_MARGIN (frame
) > 0)
2736 min_height
+= FRAME_TOP_MARGIN (frame
);
2738 if (*rows
< min_height
)
2740 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
2741 *cols
= MIN_SAFE_WINDOW_WIDTH
;
2744 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
2745 check if W's width can be changed, otherwise check W's height.
2746 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
2747 siblings, too. If none of the siblings is resizable, WINDOW isn't
2751 window_fixed_size_p (w
, width_p
, check_siblings_p
)
2753 int width_p
, check_siblings_p
;
2758 if (!NILP (w
->hchild
))
2760 c
= XWINDOW (w
->hchild
);
2764 /* A horizontal combination is fixed-width if all of if its
2766 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2767 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2768 fixed_p
= c
== NULL
;
2772 /* A horizontal combination is fixed-height if one of if its
2774 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2775 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2776 fixed_p
= c
!= NULL
;
2779 else if (!NILP (w
->vchild
))
2781 c
= XWINDOW (w
->vchild
);
2785 /* A vertical combination is fixed-width if one of if its
2787 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2788 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2789 fixed_p
= c
!= NULL
;
2793 /* A vertical combination is fixed-height if all of if its
2795 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2796 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2797 fixed_p
= c
== NULL
;
2800 else if (BUFFERP (w
->buffer
))
2802 struct buffer
*old
= current_buffer
;
2805 current_buffer
= XBUFFER (w
->buffer
);
2806 val
= find_symbol_value (Qwindow_size_fixed
);
2807 current_buffer
= old
;
2810 if (!EQ (val
, Qunbound
))
2812 fixed_p
= !NILP (val
);
2815 && ((EQ (val
, Qheight
) && width_p
)
2816 || (EQ (val
, Qwidth
) && !width_p
)))
2820 /* Can't tell if this one is resizable without looking at
2821 siblings. If all siblings are fixed-size this one is too. */
2822 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
2826 for (child
= w
->prev
; WINDOWP (child
); child
= XWINDOW (child
)->prev
)
2827 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2831 for (child
= w
->next
; WINDOWP (child
); child
= XWINDOW (child
)->next
)
2832 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2845 /* Return minimum size of leaf window W. WIDTH_P non-zero means return
2846 the minimum width of W, WIDTH_P zero means return the minimum height
2847 of W. SAFE_P non-zero means ignore window-min-height|width but just
2848 return values that won't crash Emacs and don't hide components like
2849 fringes, scrollbars, or modelines. If WIDTH_P is zero and W is the
2850 minibuffer window, always return 1. */
2853 window_min_size_2 (w
, width_p
, safe_p
)
2855 int width_p
, safe_p
;
2857 /* We should consider buffer-local values of window_min_height and
2858 window_min_width here. */
2861 int safe_size
= (MIN_SAFE_WINDOW_WIDTH
2862 + WINDOW_FRINGE_COLS (w
)
2863 + WINDOW_SCROLL_BAR_COLS (w
));
2865 return safe_p
? safe_size
: max (window_min_width
, safe_size
);
2867 else if (MINI_WINDOW_P (w
))
2871 int safe_size
= (MIN_SAFE_WINDOW_HEIGHT
2872 + ((BUFFERP (w
->buffer
)
2873 && !NILP (XBUFFER (w
->buffer
)->mode_line_format
))
2876 return safe_p
? safe_size
: max (window_min_height
, safe_size
);
2880 /* Return minimum size of window W, not taking fixed-width windows into
2881 account. WIDTH_P non-zero means return the minimum width, otherwise
2882 return the minimum height. SAFE_P non-zero means ignore
2883 window-min-height|width but just return values that won't crash Emacs
2884 and don't hide components like fringes, scrollbars, or modelines. If
2885 W is a combination window, compute the minimum size from the minimum
2886 sizes of W's children. */
2889 window_min_size_1 (w
, width_p
, safe_p
)
2891 int width_p
, safe_p
;
2896 if (!NILP (w
->hchild
))
2898 /* W is a horizontal combination. */
2899 c
= XWINDOW (w
->hchild
);
2904 /* The minimum width of a horizontal combination is the sum of
2905 the minimum widths of its children. */
2908 size
+= window_min_size_1 (c
, 1, safe_p
);
2909 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2914 /* The minimum height of a horizontal combination is the
2915 maximum of the minimum heights of its children. */
2918 size
= max (window_min_size_1 (c
, 0, safe_p
), size
);
2919 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2923 else if (!NILP (w
->vchild
))
2925 /* W is a vertical combination. */
2926 c
= XWINDOW (w
->vchild
);
2931 /* The minimum width of a vertical combination is the maximum
2932 of the minimum widths of its children. */
2935 size
= max (window_min_size_1 (c
, 1, safe_p
), size
);
2936 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2941 /* The minimum height of a vertical combination is the sum of
2942 the minimum height of its children. */
2945 size
+= window_min_size_1 (c
, 0, safe_p
);
2946 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2951 /* W is a leaf window. */
2952 size
= window_min_size_2 (w
, width_p
, safe_p
);
2957 /* Return the minimum size of window W, taking fixed-size windows into
2958 account. WIDTH_P non-zero means return the minimum width, otherwise
2959 return the minimum height. SAFE_P non-zero means ignore
2960 window-min-height|width but just return values that won't crash Emacs
2961 and don't hide components like fringes, scrollbars, or modelines.
2962 IGNORE_FIXED_P non-zero means ignore if W is fixed-size. Set *FIXED
2963 to 1 if W is fixed-size unless FIXED is null. */
2966 window_min_size (w
, width_p
, safe_p
, ignore_fixed_p
, fixed
)
2968 int width_p
, safe_p
, ignore_fixed_p
, *fixed
;
2975 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
2981 size
= WINDOW_TOTAL_SIZE (w
, width_p
);
2983 size
= window_min_size_1 (w
, width_p
, safe_p
);
2989 /* Adjust the margins of window W if text area is too small.
2990 Return 1 if window width is ok after adjustment; 0 if window
2991 is still too narrow. */
2994 adjust_window_margins (w
)
2997 int box_cols
= (WINDOW_TOTAL_COLS (w
)
2998 - WINDOW_FRINGE_COLS (w
)
2999 - WINDOW_SCROLL_BAR_COLS (w
));
3000 int margin_cols
= (WINDOW_LEFT_MARGIN_COLS (w
)
3001 + WINDOW_RIGHT_MARGIN_COLS (w
));
3003 if (box_cols
- margin_cols
>= MIN_SAFE_WINDOW_WIDTH
)
3006 if (margin_cols
< 0 || box_cols
< MIN_SAFE_WINDOW_WIDTH
)
3009 /* Window's text area is too narrow, but reducing the window
3010 margins will fix that. */
3011 margin_cols
= box_cols
- MIN_SAFE_WINDOW_WIDTH
;
3012 if (WINDOW_RIGHT_MARGIN_COLS (w
) > 0)
3014 if (WINDOW_LEFT_MARGIN_COLS (w
) > 0)
3015 w
->left_margin_cols
= w
->right_margin_cols
3016 = make_number (margin_cols
/2);
3018 w
->right_margin_cols
= make_number (margin_cols
);
3021 w
->left_margin_cols
= make_number (margin_cols
);
3025 /* Calculate new sizes for windows in the list FORWARD when their
3026 compound size goes from TOTAL to SIZE. TOTAL must be greater than
3027 SIZE. The number of windows in FORWARD is NCHILDREN, and the number
3028 that can shrink is SHRINKABLE. Fixed-size windows may be shrunk if
3029 and only if RESIZE_FIXED_P is non-zero. WIDTH_P non-zero means
3030 shrink columns, otherwise shrink lines.
3032 SAFE_P zero means windows may be sized down to window-min-height
3033 lines (window-min-window columns for WIDTH_P non-zero). SAFE_P
3034 non-zero means windows may be sized down to their minimum safe sizes
3035 taking into account the space needed to display modelines, fringes,
3038 This function returns an allocated array of new sizes that the caller
3039 must free. A size -1 means the window is fixed and RESIZE_FIXED_P is
3040 zero. A size zero means the window shall be deleted. Array index 0
3041 refers to the first window in FORWARD, 1 to the second, and so on.
3043 This function resizes windows proportionally to their size. It also
3044 tries to preserve smaller windows by resizing larger windows before
3045 resizing any window to zero. If resize_proportionally is non-nil for
3046 a specific window, it will attempt to strictly resize that window
3047 proportionally, even at the expense of deleting smaller windows. */
3049 shrink_windows (total
, size
, nchildren
, shrinkable
, resize_fixed_p
,
3050 forward
, width_p
, safe_p
)
3051 int total
, size
, nchildren
, shrinkable
;
3052 int resize_fixed_p
, width_p
, safe_p
;
3053 Lisp_Object forward
;
3055 int available_resize
= 0;
3056 int *new_sizes
, *min_sizes
;
3059 int smallest
= total
;
3060 int total_removed
= 0;
3061 int total_shrink
= total
- size
;
3064 new_sizes
= xmalloc (sizeof (*new_sizes
) * nchildren
);
3065 min_sizes
= xmalloc (sizeof (*min_sizes
) * nchildren
);
3067 for (i
= 0, child
= forward
; !NILP (child
); child
= c
->next
, ++i
)
3071 c
= XWINDOW (child
);
3072 child_size
= WINDOW_TOTAL_SIZE (c
, width_p
);
3074 if (!resize_fixed_p
&& window_fixed_size_p (c
, width_p
, 0))
3078 new_sizes
[i
] = child_size
;
3079 min_sizes
[i
] = window_min_size_1 (c
, width_p
, safe_p
);
3080 if (child_size
> min_sizes
[i
]
3081 && NILP (c
->resize_proportionally
))
3082 available_resize
+= child_size
- min_sizes
[i
];
3085 /* We might need to shrink some windows to zero. Find the smallest
3086 windows and set them to 0 until we can fulfil the new size. */
3088 while (shrinkable
> 1 && size
+ available_resize
< total
)
3090 for (i
= 0; i
< nchildren
; ++i
)
3091 if (new_sizes
[i
] > 0 && smallest
> new_sizes
[i
])
3092 smallest
= new_sizes
[i
];
3094 for (i
= 0; i
< nchildren
; ++i
)
3095 if (new_sizes
[i
] == smallest
)
3097 /* Resize this window down to zero. */
3099 if (smallest
> min_sizes
[i
])
3100 available_resize
-= smallest
- min_sizes
[i
];
3101 available_resize
+= smallest
;
3103 total_removed
+= smallest
;
3105 /* We don't know what the smallest is now. */
3108 /* Out of for, just remove one window at the time and
3109 check again if we have enough space. */
3114 /* Now, calculate the new sizes. Try to shrink each window
3115 proportional to its size. */
3116 for (i
= 0; i
< nchildren
; ++i
)
3118 if (new_sizes
[i
] > min_sizes
[i
])
3120 int to_shrink
= total_shrink
* new_sizes
[i
] / total
;
3122 if (new_sizes
[i
] - to_shrink
< min_sizes
[i
])
3123 to_shrink
= new_sizes
[i
] - min_sizes
[i
];
3124 new_sizes
[i
] -= to_shrink
;
3125 total_removed
+= to_shrink
;
3129 /* Any reminder due to rounding, we just subtract from windows
3130 that are left and still can be shrunk. */
3131 while (total_shrink
> total_removed
)
3133 int nonzero_sizes
= 0;
3134 int nonzero_idx
= -1;
3136 for (i
= 0; i
< nchildren
; ++i
)
3137 if (new_sizes
[i
] > 0)
3143 for (i
= 0; i
< nchildren
; ++i
)
3144 if (new_sizes
[i
] > min_sizes
[i
])
3149 /* Out of for, just shrink one window at the time and
3150 check again if we have enough space. */
3154 /* Special case, only one window left. */
3155 if (nonzero_sizes
== 1)
3159 /* Any surplus due to rounding, we add to windows that are left. */
3160 while (total_shrink
< total_removed
)
3162 for (i
= 0; i
< nchildren
; ++i
)
3164 if (new_sizes
[i
] != 0 && total_shrink
< total_removed
)
3178 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
3179 WINDOW's width. Resize WINDOW's children, if any, so that they keep
3180 their proportionate size relative to WINDOW.
3182 If FIRST_ONLY is 1, change only the first of WINDOW's children when
3183 they are in series. If LAST_ONLY is 1, change only the last of
3184 WINDOW's children when they are in series.
3186 Propagate WINDOW's top or left edge position to children. Delete
3187 windows that become too small unless NODELETE_P is 1. When
3188 NODELETE_P equals 2 do not honor settings for window-min-height and
3189 window-min-width when resizing windows but use safe defaults instead.
3190 This should give better behavior when resizing frames. */
3193 size_window (window
, size
, width_p
, nodelete_p
, first_only
, last_only
)
3195 int size
, width_p
, nodelete_p
;
3196 int first_only
, last_only
;
3198 struct window
*w
= XWINDOW (window
);
3200 Lisp_Object child
, *forward
, *sideward
;
3201 int old_size
= WINDOW_TOTAL_SIZE (w
, width_p
);
3203 size
= max (0, size
);
3205 /* Delete WINDOW if it's too small. */
3206 if (nodelete_p
!= 1 && !NILP (w
->parent
)
3207 && size
< window_min_size_1 (w
, width_p
, nodelete_p
== 2))
3209 delete_window (window
);
3213 /* Set redisplay hints. */
3214 w
->last_modified
= make_number (0);
3215 w
->last_overlay_modified
= make_number (0);
3216 windows_or_buffers_changed
++;
3217 FRAME_WINDOW_SIZES_CHANGED (XFRAME (w
->frame
)) = 1;
3221 sideward
= &w
->vchild
;
3222 forward
= &w
->hchild
;
3223 w
->total_cols
= make_number (size
);
3224 adjust_window_margins (w
);
3228 sideward
= &w
->hchild
;
3229 forward
= &w
->vchild
;
3230 w
->total_lines
= make_number (size
);
3231 w
->orig_total_lines
= Qnil
;
3234 if (!NILP (*sideward
))
3236 /* We have a chain of parallel siblings whose size should all change. */
3237 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
3239 c
= XWINDOW (child
);
3241 c
->left_col
= w
->left_col
;
3243 c
->top_line
= w
->top_line
;
3244 size_window (child
, size
, width_p
, nodelete_p
,
3245 first_only
, last_only
);
3248 else if (!NILP (*forward
) && last_only
)
3250 /* Change the last in a series of siblings. */
3251 Lisp_Object last_child
;
3254 for (child
= *forward
; !NILP (child
); child
= c
->next
)
3256 c
= XWINDOW (child
);
3260 child_size
= WINDOW_TOTAL_SIZE (c
, width_p
);
3261 size_window (last_child
, size
- old_size
+ child_size
,
3262 width_p
, nodelete_p
, first_only
, last_only
);
3264 else if (!NILP (*forward
) && first_only
)
3266 /* Change the first in a series of siblings. */
3270 c
= XWINDOW (child
);
3273 c
->left_col
= w
->left_col
;
3275 c
->top_line
= w
->top_line
;
3277 child_size
= WINDOW_TOTAL_SIZE (c
, width_p
);
3278 size_window (child
, size
- old_size
+ child_size
,
3279 width_p
, nodelete_p
, first_only
, last_only
);
3281 else if (!NILP (*forward
))
3283 int fixed_size
, each
, extra
, n
;
3284 int resize_fixed_p
, nfixed
;
3285 int last_pos
, first_pos
, nchildren
, total
;
3286 int *new_sizes
= NULL
;
3288 /* Determine the fixed-size portion of this window, and the
3289 number of child windows. */
3290 fixed_size
= nchildren
= nfixed
= total
= 0;
3291 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
3295 c
= XWINDOW (child
);
3296 child_size
= WINDOW_TOTAL_SIZE (c
, width_p
);
3297 total
+= child_size
;
3299 if (window_fixed_size_p (c
, width_p
, 0))
3301 fixed_size
+= child_size
;
3306 /* If the new size is smaller than fixed_size, or if there
3307 aren't any resizable windows, allow resizing fixed-size
3309 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
3311 /* Compute how many lines/columns to add/remove to each child. The
3312 value of extra takes care of rounding errors. */
3313 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
3314 if (size
< total
&& n
> 1)
3315 new_sizes
= shrink_windows (total
, size
, nchildren
, n
,
3316 resize_fixed_p
, *forward
, width_p
,
3320 each
= (size
- total
) / n
;
3321 extra
= (size
- total
) - n
* each
;
3324 /* Compute new children heights and edge positions. */
3325 first_pos
= width_p
? XINT (w
->left_col
) : XINT (w
->top_line
);
3326 last_pos
= first_pos
;
3327 for (n
= 0, child
= *forward
; !NILP (child
); child
= c
->next
, ++n
)
3329 int new_size
, old_size
;
3331 c
= XWINDOW (child
);
3332 old_size
= WINDOW_TOTAL_SIZE (c
, width_p
);
3333 new_size
= old_size
;
3335 /* The top or left edge position of this child equals the
3336 bottom or right edge of its predecessor. */
3338 c
->left_col
= make_number (last_pos
);
3340 c
->top_line
= make_number (last_pos
);
3342 /* If this child can be resized, do it. */
3343 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
3345 new_size
= new_sizes
? new_sizes
[n
] : old_size
+ each
+ extra
;
3349 /* Set new size. Note that size_window also propagates
3350 edge positions to children, so it's not a no-op if we
3351 didn't change the child's size. */
3352 size_window (child
, new_size
, width_p
, 1, first_only
, last_only
);
3354 /* Remember the bottom/right edge position of this child; it
3355 will be used to set the top/left edge of the next child. */
3356 last_pos
+= new_size
;
3361 /* We should have covered the parent exactly with child windows. */
3362 xassert (size
== last_pos
- first_pos
);
3364 /* Now delete any children that became too small. */
3365 if (nodelete_p
!= 1)
3366 for (child
= *forward
; !NILP (child
); child
= c
->next
)
3370 c
= XWINDOW (child
);
3371 child_size
= WINDOW_TOTAL_SIZE (c
, width_p
);
3372 size_window (child
, child_size
, width_p
, nodelete_p
,
3373 first_only
, last_only
);
3378 /* Set WINDOW's height to HEIGHT, and recursively change the height of
3379 WINDOW's children. NODELETE zero means windows that have become
3380 smaller than window-min-height in the process may be deleted.
3381 NODELETE 1 means never delete windows that become too small in the
3382 process. (The caller should check later and do so if appropriate.)
3383 NODELETE 2 means delete only windows that have become too small to be
3384 displayed correctly. */
3387 set_window_height (window
, height
, nodelete
)
3392 size_window (window
, height
, 0, nodelete
, 0, 0);
3395 /* Set WINDOW's width to WIDTH, and recursively change the width of
3396 WINDOW's children. NODELETE zero means windows that have become
3397 smaller than window-min-width in the process may be deleted.
3398 NODELETE 1 means never delete windows that become too small in the
3399 process. (The caller should check later and do so if appropriate.)
3400 NODELETE 2 means delete only windows that have become too small to be
3401 displayed correctly. */
3404 set_window_width (window
, width
, nodelete
)
3409 size_window (window
, width
, 1, nodelete
, 0, 0);
3412 /* Change window heights in windows rooted in WINDOW by N lines. */
3415 change_window_heights (window
, n
)
3419 struct window
*w
= XWINDOW (window
);
3421 XSETFASTINT (w
->top_line
, XFASTINT (w
->top_line
) + n
);
3422 XSETFASTINT (w
->total_lines
, XFASTINT (w
->total_lines
) - n
);
3424 if (INTEGERP (w
->orig_top_line
))
3425 XSETFASTINT (w
->orig_top_line
, XFASTINT (w
->orig_top_line
) + n
);
3426 if (INTEGERP (w
->orig_total_lines
))
3427 XSETFASTINT (w
->orig_total_lines
, XFASTINT (w
->orig_total_lines
) - n
);
3429 /* Handle just the top child in a vertical split. */
3430 if (!NILP (w
->vchild
))
3431 change_window_heights (w
->vchild
, n
);
3433 /* Adjust all children in a horizontal split. */
3434 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
3436 w
= XWINDOW (window
);
3437 change_window_heights (window
, n
);
3442 int window_select_count
;
3444 EXFUN (Fset_window_fringes
, 4);
3445 EXFUN (Fset_window_scroll_bars
, 4);
3448 run_funs (Lisp_Object funs
)
3450 for (; CONSP (funs
); funs
= XCDR (funs
))
3451 if (!EQ (XCAR (funs
), Qt
))
3452 call0 (XCAR (funs
));
3455 static Lisp_Object
select_window_norecord (Lisp_Object window
);
3456 static Lisp_Object
select_frame_norecord (Lisp_Object frame
);
3459 run_window_configuration_change_hook (struct frame
*f
)
3461 int count
= SPECPDL_INDEX ();
3462 Lisp_Object frame
, global_wcch
3463 = Fdefault_value (Qwindow_configuration_change_hook
);
3464 XSETFRAME (frame
, f
);
3466 if (NILP (Vrun_hooks
))
3469 if (SELECTED_FRAME () != f
)
3471 record_unwind_protect (select_frame_norecord
, Fselected_frame ());
3472 Fselect_frame (frame
, Qt
);
3475 /* Use the right buffer. Matters when running the local hooks. */
3476 if (current_buffer
!= XBUFFER (Fwindow_buffer (Qnil
)))
3478 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
3479 Fset_buffer (Fwindow_buffer (Qnil
));
3482 /* Look for buffer-local values. */
3484 Lisp_Object windows
= Fwindow_list (frame
, Qlambda
, Qnil
);
3485 for (; CONSP (windows
); windows
= XCDR (windows
))
3487 Lisp_Object window
= XCAR (windows
);
3488 Lisp_Object buffer
= Fwindow_buffer (window
);
3489 if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook
,
3492 int count
= SPECPDL_INDEX ();
3493 record_unwind_protect (select_window_norecord
, Fselected_window ());
3494 select_window_norecord (window
);
3495 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook
,
3497 unbind_to (count
, Qnil
);
3502 run_funs (global_wcch
);
3503 unbind_to (count
, Qnil
);
3506 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
3507 means it's allowed to run hooks. See make_frame for a case where
3508 it's not allowed. KEEP_MARGINS_P non-zero means that the current
3509 margins, fringes, and scroll-bar settings of the window are not
3510 reset from the buffer's local settings. */
3513 set_window_buffer (window
, buffer
, run_hooks_p
, keep_margins_p
)
3514 Lisp_Object window
, buffer
;
3515 int run_hooks_p
, keep_margins_p
;
3517 struct window
*w
= XWINDOW (window
);
3518 struct buffer
*b
= XBUFFER (buffer
);
3519 int count
= SPECPDL_INDEX ();
3520 int samebuf
= EQ (buffer
, w
->buffer
);
3524 if (EQ (window
, selected_window
))
3525 b
->last_selected_window
= window
;
3527 /* Let redisplay errors through. */
3528 b
->display_error_modiff
= 0;
3530 /* Update time stamps of buffer display. */
3531 if (INTEGERP (b
->display_count
))
3532 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
3533 b
->display_time
= Fcurrent_time ();
3535 XSETFASTINT (w
->window_end_pos
, 0);
3536 XSETFASTINT (w
->window_end_vpos
, 0);
3537 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
3538 w
->window_end_valid
= Qnil
;
3539 if (!(keep_margins_p
&& samebuf
))
3540 { /* If we're not actually changing the buffer, don't reset hscroll and
3541 vscroll. This case happens for example when called from
3542 change_frame_size_1, where we use a dummy call to
3543 Fset_window_buffer on the frame's selected window (and no other)
3544 just in order to run window-configuration-change-hook.
3545 Resetting hscroll and vscroll here is problematic for things like
3546 image-mode and doc-view-mode since it resets the image's position
3547 whenever we resize the frame. */
3548 w
->hscroll
= w
->min_hscroll
= make_number (0);
3550 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
3551 set_marker_restricted (w
->start
,
3552 make_number (b
->last_window_start
),
3554 w
->start_at_line_beg
= Qnil
;
3555 w
->force_start
= Qnil
;
3556 XSETFASTINT (w
->last_modified
, 0);
3557 XSETFASTINT (w
->last_overlay_modified
, 0);
3559 /* Maybe we could move this into the `if' but it's not obviously safe and
3560 I doubt it's worth the trouble. */
3561 windows_or_buffers_changed
++;
3563 /* We must select BUFFER for running the window-scroll-functions. */
3564 /* We can't check ! NILP (Vwindow_scroll_functions) here
3565 because that might itself be a local variable. */
3566 if (window_initialized
)
3568 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
3569 Fset_buffer (buffer
);
3572 XMARKER (w
->pointm
)->insertion_type
= !NILP (Vwindow_point_insertion_type
);
3574 if (!keep_margins_p
)
3576 /* Set left and right marginal area width etc. from buffer. */
3578 /* This may call adjust_window_margins three times, so
3579 temporarily disable window margins. */
3580 Lisp_Object save_left
= w
->left_margin_cols
;
3581 Lisp_Object save_right
= w
->right_margin_cols
;
3583 w
->left_margin_cols
= w
->right_margin_cols
= Qnil
;
3585 Fset_window_fringes (window
,
3586 b
->left_fringe_width
, b
->right_fringe_width
,
3587 b
->fringes_outside_margins
);
3589 Fset_window_scroll_bars (window
,
3590 b
->scroll_bar_width
,
3591 b
->vertical_scroll_bar_type
, Qnil
);
3593 w
->left_margin_cols
= save_left
;
3594 w
->right_margin_cols
= save_right
;
3596 Fset_window_margins (window
,
3597 b
->left_margin_cols
, b
->right_margin_cols
);
3602 if (! NILP (Vwindow_scroll_functions
))
3603 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
3604 Fmarker_position (w
->start
));
3605 run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w
)));
3608 unbind_to (count
, Qnil
);
3612 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 3, 0,
3613 doc
: /* Make WINDOW display BUFFER-OR-NAME as its contents.
3614 WINDOW defaults to the selected window. BUFFER-OR-NAME must be a buffer
3615 or the name of an existing buffer. Optional third argument KEEP-MARGINS
3616 non-nil means that WINDOW's current display margins, fringe widths, and
3617 scroll bar settings are preserved; the default is to reset these from
3618 the local settings for BUFFER-OR-NAME or the frame defaults. Return nil.
3620 This function throws an error when WINDOW is strongly dedicated to its
3621 buffer (that is `window-dedicated-p' returns t for WINDOW) and does not
3622 already display BUFFER-OR-NAME.
3624 This function runs `window-scroll-functions' before running
3625 `window-configuration-change-hook'. */)
3626 (window
, buffer_or_name
, keep_margins
)
3627 register Lisp_Object window
, buffer_or_name
, keep_margins
;
3629 register Lisp_Object tem
, buffer
;
3630 register struct window
*w
= decode_window (window
);
3632 XSETWINDOW (window
, w
);
3633 buffer
= Fget_buffer (buffer_or_name
);
3634 CHECK_BUFFER (buffer
);
3635 if (NILP (XBUFFER (buffer
)->name
))
3636 error ("Attempt to display deleted buffer");
3640 error ("Window is deleted");
3641 else if (!EQ (tem
, Qt
))
3642 /* w->buffer is t when the window is first being set up. */
3644 if (!EQ (tem
, buffer
))
3645 if (EQ (w
->dedicated
, Qt
))
3646 error ("Window is dedicated to `%s'", SDATA (XBUFFER (tem
)->name
));
3648 w
->dedicated
= Qnil
;
3653 set_window_buffer (window
, buffer
, 1, !NILP (keep_margins
));
3657 /* Note that selected_window can be nil when this is called from
3658 Fset_window_configuration. */
3660 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 2, 0,
3661 doc
: /* Select WINDOW. Most editing will apply to WINDOW's buffer.
3662 If WINDOW is not already selected, make WINDOW's buffer current
3663 and make WINDOW the frame's selected window. Return WINDOW.
3664 Optional second arg NORECORD non-nil means do not put this buffer
3665 at the front of the list of recently selected ones and do not
3666 make this window the most recently selected one.
3668 Note that the main editor command loop selects the buffer of the
3669 selected window before each command. */)
3671 register Lisp_Object window
, norecord
;
3673 register struct window
*w
;
3674 register struct window
*ow
;
3677 CHECK_LIVE_WINDOW (window
);
3679 w
= XWINDOW (window
);
3680 w
->frozen_window_start_p
= 0;
3682 if (NILP (norecord
))
3684 ++window_select_count
;
3685 XSETFASTINT (w
->use_time
, window_select_count
);
3686 record_buffer (w
->buffer
);
3689 if (EQ (window
, selected_window
))
3692 sf
= SELECTED_FRAME ();
3693 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
3695 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
3696 /* Use this rather than Fhandle_switch_frame
3697 so that FRAME_FOCUS_FRAME is moved appropriately as we
3698 move around in the state where a minibuffer in a separate
3700 Fselect_frame (WINDOW_FRAME (w
), norecord
);
3701 /* Fselect_frame called us back so we've done all the work already. */
3702 eassert (EQ (window
, selected_window
));
3706 sf
->selected_window
= window
;
3708 /* Store the current buffer's actual point into the
3709 old selected window. It belongs to that window,
3710 and when the window is not selected, must be in the window. */
3711 if (!NILP (selected_window
))
3713 ow
= XWINDOW (selected_window
);
3714 if (! NILP (ow
->buffer
))
3715 set_marker_both (ow
->pointm
, ow
->buffer
,
3716 BUF_PT (XBUFFER (ow
->buffer
)),
3717 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
3720 selected_window
= window
;
3722 Fset_buffer (w
->buffer
);
3724 XBUFFER (w
->buffer
)->last_selected_window
= window
;
3726 /* Go to the point recorded in the window.
3727 This is important when the buffer is in more
3728 than one window. It also matters when
3729 redisplay_window has altered point after scrolling,
3730 because it makes the change only in the window. */
3732 register int new_point
= marker_position (w
->pointm
);
3733 if (new_point
< BEGV
)
3735 else if (new_point
> ZV
)
3741 windows_or_buffers_changed
++;
3746 select_window_norecord (window
)
3749 return WINDOW_LIVE_P (window
)
3750 ? Fselect_window (window
, Qt
) : selected_window
;
3754 select_frame_norecord (frame
)
3757 return FRAME_LIVE_P (XFRAME (frame
))
3758 ? Fselect_frame (frame
, Qt
) : selected_frame
;
3762 display_buffer (buffer
, not_this_window_p
, override_frame
)
3763 Lisp_Object buffer
, not_this_window_p
, override_frame
;
3765 return call3 (Qdisplay_buffer
, buffer
, not_this_window_p
, override_frame
);
3768 DEFUN ("force-window-update", Fforce_window_update
, Sforce_window_update
,
3770 doc
: /* Force all windows to be updated on next redisplay.
3771 If optional arg OBJECT is a window, force redisplay of that window only.
3772 If OBJECT is a buffer or buffer name, force redisplay of all windows
3773 displaying that buffer. */)
3779 windows_or_buffers_changed
++;
3780 update_mode_lines
++;
3784 if (WINDOWP (object
))
3786 struct window
*w
= XWINDOW (object
);
3787 mark_window_display_accurate (object
, 0);
3788 w
->update_mode_line
= Qt
;
3789 if (BUFFERP (w
->buffer
))
3790 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
3791 ++update_mode_lines
;
3795 if (STRINGP (object
))
3796 object
= Fget_buffer (object
);
3797 if (BUFFERP (object
) && !NILP (XBUFFER (object
)->name
))
3799 /* Walk all windows looking for buffer, and force update
3800 of each of those windows. */
3802 object
= window_loop (REDISPLAY_BUFFER_WINDOWS
, object
, 0, Qvisible
);
3803 return NILP (object
) ? Qnil
: Qt
;
3806 /* If nothing suitable was found, just return.
3807 We could signal an error, but this feature will typically be used
3808 asynchronously in timers or process sentinels, so we don't. */
3814 temp_output_buffer_show (buf
)
3815 register Lisp_Object buf
;
3817 register struct buffer
*old
= current_buffer
;
3818 register Lisp_Object window
;
3819 register struct window
*w
;
3821 XBUFFER (buf
)->directory
= current_buffer
->directory
;
3824 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
3828 #if 0 /* rms: there should be no reason for this. */
3829 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
3831 set_buffer_internal (old
);
3833 if (!NILP (Vtemp_buffer_show_function
))
3834 call1 (Vtemp_buffer_show_function
, buf
);
3837 window
= display_buffer (buf
, Qnil
, Qnil
);
3839 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
3840 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
3841 Vminibuf_scroll_window
= window
;
3842 w
= XWINDOW (window
);
3843 XSETFASTINT (w
->hscroll
, 0);
3844 XSETFASTINT (w
->min_hscroll
, 0);
3845 set_marker_restricted_both (w
->start
, buf
, BEG
, BEG
);
3846 set_marker_restricted_both (w
->pointm
, buf
, BEG
, BEG
);
3848 /* Run temp-buffer-show-hook, with the chosen window selected
3849 and its buffer current. */
3851 if (!NILP (Vrun_hooks
)
3852 && !NILP (Fboundp (Qtemp_buffer_show_hook
))
3853 && !NILP (Fsymbol_value (Qtemp_buffer_show_hook
)))
3855 int count
= SPECPDL_INDEX ();
3856 Lisp_Object prev_window
, prev_buffer
;
3857 prev_window
= selected_window
;
3858 XSETBUFFER (prev_buffer
, old
);
3860 /* Select the window that was chosen, for running the hook.
3861 Note: Both Fselect_window and select_window_norecord may
3862 set-buffer to the buffer displayed in the window,
3863 so we need to save the current buffer. --stef */
3864 record_unwind_protect (Fset_buffer
, prev_buffer
);
3865 record_unwind_protect (select_window_norecord
, prev_window
);
3866 Fselect_window (window
, Qt
);
3867 Fset_buffer (w
->buffer
);
3868 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
3869 unbind_to (count
, Qnil
);
3875 make_dummy_parent (window
)
3879 register struct window
*o
, *p
;
3882 o
= XWINDOW (window
);
3883 p
= allocate_window ();
3884 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
3885 ((struct Lisp_Vector
*) p
)->contents
[i
]
3886 = ((struct Lisp_Vector
*)o
)->contents
[i
];
3887 XSETWINDOW (new, p
);
3890 XSETFASTINT (p
->sequence_number
, sequence_number
);
3892 /* Put new into window structure in place of window */
3893 replace_window (window
, new);
3906 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
3907 doc
: /* Split WINDOW, putting SIZE lines in the first of the pair.
3908 WINDOW defaults to selected one and SIZE to half its size.
3909 If optional third arg HORIZONTAL is non-nil, split side by side and put
3910 SIZE columns in the first of the pair. In that case, SIZE includes that
3911 window's scroll bar, or the divider column to its right.
3912 Interactively, all arguments are nil.
3913 Returns the newly created window (which is the lower or rightmost one).
3914 The upper or leftmost window is the original one, and remains selected
3915 if it was selected before.
3917 See Info node `(elisp)Splitting Windows' for more details and examples. */)
3918 (window
, size
, horizontal
)
3919 Lisp_Object window
, size
, horizontal
;
3921 register Lisp_Object
new;
3922 register struct window
*o
, *p
;
3924 register int size_int
;
3927 window
= selected_window
;
3929 CHECK_LIVE_WINDOW (window
);
3931 o
= XWINDOW (window
);
3932 fo
= XFRAME (WINDOW_FRAME (o
));
3936 if (!NILP (horizontal
))
3937 /* Calculate the size of the left-hand window, by dividing
3938 the usable space in columns by two.
3939 We round up, since the left-hand window may include
3940 a dividing line, while the right-hand may not. */
3941 size_int
= (XFASTINT (o
->total_cols
) + 1) >> 1;
3943 size_int
= XFASTINT (o
->total_lines
) >> 1;
3947 CHECK_NUMBER (size
);
3948 size_int
= XINT (size
);
3951 if (MINI_WINDOW_P (o
))
3952 error ("Attempt to split minibuffer window");
3953 else if (window_fixed_size_p (o
, !NILP (horizontal
), 0))
3954 error ("Attempt to split fixed-size window");
3956 if (NILP (horizontal
))
3958 int window_safe_height
= window_min_size_2 (o
, 0, 0);
3960 if (size_int
< window_safe_height
)
3961 error ("Window height %d too small (after splitting)", size_int
);
3962 if (size_int
+ window_safe_height
> XFASTINT (o
->total_lines
))
3963 error ("Window height %d too small (after splitting)",
3964 XFASTINT (o
->total_lines
) - size_int
);
3965 if (NILP (o
->parent
)
3966 || NILP (XWINDOW (o
->parent
)->vchild
))
3968 make_dummy_parent (window
);
3970 XWINDOW (new)->vchild
= window
;
3975 int window_safe_width
= window_min_size_2 (o
, 1, 0);
3977 if (size_int
< window_safe_width
)
3978 error ("Window width %d too small (after splitting)", size_int
);
3979 if (size_int
+ window_safe_width
> XFASTINT (o
->total_cols
))
3980 error ("Window width %d too small (after splitting)",
3981 XFASTINT (o
->total_cols
) - size_int
);
3982 if (NILP (o
->parent
)
3983 || NILP (XWINDOW (o
->parent
)->hchild
))
3985 make_dummy_parent (window
);
3987 XWINDOW (new)->hchild
= window
;
3991 /* Now we know that window's parent is a vertical combination
3992 if we are dividing vertically, or a horizontal combination
3993 if we are making side-by-side windows */
3995 windows_or_buffers_changed
++;
3996 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
3997 new = make_window ();
4000 p
->frame
= o
->frame
;
4002 if (!NILP (p
->next
))
4003 XWINDOW (p
->next
)->prev
= new;
4006 p
->parent
= o
->parent
;
4008 p
->window_end_valid
= Qnil
;
4009 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
4011 /* Duplicate special geometry settings. */
4013 p
->left_margin_cols
= o
->left_margin_cols
;
4014 p
->right_margin_cols
= o
->right_margin_cols
;
4015 p
->left_fringe_width
= o
->left_fringe_width
;
4016 p
->right_fringe_width
= o
->right_fringe_width
;
4017 p
->fringes_outside_margins
= o
->fringes_outside_margins
;
4018 p
->scroll_bar_width
= o
->scroll_bar_width
;
4019 p
->vertical_scroll_bar_type
= o
->vertical_scroll_bar_type
;
4021 /* Apportion the available frame space among the two new windows */
4023 if (!NILP (horizontal
))
4025 p
->total_lines
= o
->total_lines
;
4026 p
->top_line
= o
->top_line
;
4027 XSETFASTINT (p
->total_cols
, XFASTINT (o
->total_cols
) - size_int
);
4028 XSETFASTINT (o
->total_cols
, size_int
);
4029 XSETFASTINT (p
->left_col
, XFASTINT (o
->left_col
) + size_int
);
4030 adjust_window_margins (p
);
4031 adjust_window_margins (o
);
4035 p
->left_col
= o
->left_col
;
4036 p
->total_cols
= o
->total_cols
;
4037 XSETFASTINT (p
->total_lines
, XFASTINT (o
->total_lines
) - size_int
);
4038 XSETFASTINT (o
->total_lines
, size_int
);
4039 XSETFASTINT (p
->top_line
, XFASTINT (o
->top_line
) + size_int
);
4042 /* Adjust glyph matrices. */
4045 Fset_window_buffer (new, o
->buffer
, Qt
);
4049 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
4050 doc
: /* Make selected window SIZE lines taller.
4051 Interactively, if no argument is given, make the selected window one
4052 line taller. If optional argument HORIZONTAL is non-nil, make selected
4053 window wider by SIZE columns. If SIZE is negative, shrink the window by
4054 -SIZE lines or columns. Return nil.
4056 This function can delete windows if they get too small. The size of
4057 fixed size windows is not altered by this function. */)
4059 Lisp_Object size
, horizontal
;
4061 CHECK_NUMBER (size
);
4062 enlarge_window (selected_window
, XINT (size
), !NILP (horizontal
));
4064 run_window_configuration_change_hook (SELECTED_FRAME ());
4069 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
4070 doc
: /* Make selected window SIZE lines smaller.
4071 Interactively, if no argument is given, make the selected window one
4072 line smaller. If optional argument HORIZONTAL is non-nil, make the
4073 window narrower by SIZE columns. If SIZE is negative, enlarge selected
4074 window by -SIZE lines or columns. Return nil.
4076 This function can delete windows if they get too small. The size of
4077 fixed size windows is not altered by this function. */)
4079 Lisp_Object size
, horizontal
;
4081 CHECK_NUMBER (size
);
4082 enlarge_window (selected_window
, -XINT (size
), !NILP (horizontal
));
4084 run_window_configuration_change_hook (SELECTED_FRAME ());
4090 window_height (window
)
4093 register struct window
*p
= XWINDOW (window
);
4094 return WINDOW_TOTAL_LINES (p
);
4098 window_width (window
)
4101 register struct window
*p
= XWINDOW (window
);
4102 return WINDOW_TOTAL_COLS (p
);
4107 *(horiz_flag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
4109 #define CURSIZE(w) \
4110 *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
4113 /* Enlarge WINDOW by DELTA. HORIZ_FLAG nonzero means enlarge it
4114 horizontally; zero means do it vertically.
4116 Siblings of the selected window are resized to fulfill the size
4117 request. If they become too small in the process, they may be
4121 enlarge_window (window
, delta
, horiz_flag
)
4123 int delta
, horiz_flag
;
4125 Lisp_Object parent
, next
, prev
;
4129 int (*sizefun
) P_ ((Lisp_Object
))
4130 = horiz_flag
? window_width
: window_height
;
4131 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
4132 = (horiz_flag
? set_window_width
: set_window_height
);
4134 /* Give up if this window cannot be resized. */
4135 if (window_fixed_size_p (XWINDOW (window
), horiz_flag
, 1))
4136 error ("Window is not resizable");
4138 /* Find the parent of the selected window. */
4141 p
= XWINDOW (window
);
4147 error ("No other window to side of this one");
4152 ? !NILP (XWINDOW (parent
)->hchild
)
4153 : !NILP (XWINDOW (parent
)->vchild
))
4159 sizep
= &CURSIZE (window
);
4162 register int maxdelta
;
4164 /* Compute the maximum size increment this window can have. */
4166 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - XINT (*sizep
)
4167 /* This is a main window followed by a minibuffer. */
4168 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
4169 - window_min_size (XWINDOW (p
->next
),
4170 horiz_flag
, 0, 0, 0))
4171 /* This is a minibuffer following a main window. */
4172 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
4173 - window_min_size (XWINDOW (p
->prev
),
4174 horiz_flag
, 0, 0, 0))
4175 /* This is a frame with only one window, a minibuffer-only
4176 or a minibufferless frame. */
4179 if (delta
> maxdelta
)
4180 /* This case traps trying to make the minibuffer
4181 the full frame, or make the only window aside from the
4182 minibuffer the full frame. */
4186 if (XINT (*sizep
) + delta
< window_min_size (XWINDOW (window
),
4187 horiz_flag
, 0, 0, 0))
4189 delete_window (window
);
4196 /* Find the total we can get from other siblings without deleting them. */
4198 for (next
= p
->next
; WINDOWP (next
); next
= XWINDOW (next
)->next
)
4199 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
4200 horiz_flag
, 0, 0, 0);
4201 for (prev
= p
->prev
; WINDOWP (prev
); prev
= XWINDOW (prev
)->prev
)
4202 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
4203 horiz_flag
, 0, 0, 0);
4205 /* If we can get it all from them without deleting them, do so. */
4206 if (delta
<= maximum
)
4208 Lisp_Object first_unaffected
;
4209 Lisp_Object first_affected
;
4214 first_affected
= window
;
4215 /* Look at one sibling at a time,
4216 moving away from this window in both directions alternately,
4217 and take as much as we can get without deleting that sibling. */
4219 && (!NILP (next
) || !NILP (prev
)))
4223 int this_one
= ((*sizefun
) (next
)
4224 - window_min_size (XWINDOW (next
), horiz_flag
,
4228 if (this_one
> delta
)
4231 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
4232 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
4237 next
= XWINDOW (next
)->next
;
4245 int this_one
= ((*sizefun
) (prev
)
4246 - window_min_size (XWINDOW (prev
), horiz_flag
,
4250 if (this_one
> delta
)
4253 first_affected
= prev
;
4255 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
4256 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
4261 prev
= XWINDOW (prev
)->prev
;
4265 xassert (delta
== 0);
4267 /* Now recalculate the edge positions of all the windows affected,
4268 based on the new sizes. */
4269 first_unaffected
= next
;
4270 prev
= first_affected
;
4271 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
4272 prev
= next
, next
= XWINDOW (next
)->next
)
4274 XSETINT (CURBEG (next
), XINT (CURBEG (prev
)) + (*sizefun
) (prev
));
4275 /* This does not change size of NEXT,
4276 but it propagates the new top edge to its children */
4277 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
4282 register int delta1
;
4283 register int opht
= (*sizefun
) (parent
);
4285 if (opht
<= XINT (*sizep
) + delta
)
4287 /* If trying to grow this window to or beyond size of the parent,
4288 just delete all the sibling windows. */
4289 Lisp_Object start
, tem
, next
;
4291 start
= XWINDOW (parent
)->vchild
;
4293 start
= XWINDOW (parent
)->hchild
;
4295 /* Delete any siblings that come after WINDOW. */
4296 tem
= XWINDOW (window
)->next
;
4297 while (! NILP (tem
))
4299 next
= XWINDOW (tem
)->next
;
4300 delete_window (tem
);
4304 /* Delete any siblings that come after WINDOW.
4305 Note that if START is not WINDOW, then WINDOW still
4306 has siblings, so WINDOW has not yet replaced its parent. */
4308 while (! EQ (tem
, window
))
4310 next
= XWINDOW (tem
)->next
;
4311 delete_window (tem
);
4317 /* Otherwise, make delta1 just right so that if we add
4318 delta1 lines to this window and to the parent, and then
4319 shrink the parent back to its original size, the new
4320 proportional size of this window will increase by delta.
4322 The function size_window will compute the new height h'
4323 of the window from delta1 as:
4326 x = delta1 - delta1/n * n for the 1st resizable child
4329 where n is the number of children that can be resized.
4330 We can ignore x by choosing a delta1 that is a multiple of
4331 n. We want the height of this window to come out as
4341 The number of children n equals the number of resizable
4342 children of this window + 1 because we know window itself
4343 is resizable (otherwise we would have signaled an error).
4345 This reasoning is not correct when other windows become too
4346 small and shrink_windows refuses to delete them. Below we
4347 use resize_proportionally to work around this problem. */
4349 struct window
*w
= XWINDOW (window
);
4353 for (s
= w
->next
; WINDOWP (s
); s
= XWINDOW (s
)->next
)
4354 if (!window_fixed_size_p (XWINDOW (s
), horiz_flag
, 0))
4356 for (s
= w
->prev
; WINDOWP (s
); s
= XWINDOW (s
)->prev
)
4357 if (!window_fixed_size_p (XWINDOW (s
), horiz_flag
, 0))
4362 /* Add delta1 lines or columns to this window, and to the parent,
4363 keeping things consistent while not affecting siblings. */
4364 XSETINT (CURSIZE (parent
), opht
+ delta1
);
4365 (*setsizefun
) (window
, XINT (*sizep
) + delta1
, 0);
4367 /* Squeeze out delta1 lines or columns from our parent,
4368 shrinking this window and siblings proportionately. This
4369 brings parent back to correct size. Delta1 was calculated
4370 so this makes this window the desired size, taking it all
4371 out of the siblings.
4373 Temporarily set resize_proportionally to Qt to assure that,
4374 if necessary, shrink_windows deletes smaller windows rather
4375 than shrink this window. */
4376 w
->resize_proportionally
= Qt
;
4377 (*setsizefun
) (parent
, opht
, 0);
4378 w
->resize_proportionally
= Qnil
;
4382 XSETFASTINT (p
->last_modified
, 0);
4383 XSETFASTINT (p
->last_overlay_modified
, 0);
4385 /* Adjust glyph matrices. */
4386 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
4390 /* Adjust the size of WINDOW by DELTA, moving only its trailing edge.
4391 HORIZ_FLAG nonzero means adjust the width, moving the right edge.
4392 zero means adjust the height, moving the bottom edge.
4394 Following siblings of the selected window are resized to fulfill
4395 the size request. If they become too small in the process, they
4396 are not deleted; instead, we signal an error. */
4399 adjust_window_trailing_edge (window
, delta
, horiz_flag
)
4401 int delta
, horiz_flag
;
4403 Lisp_Object parent
, child
;
4405 Lisp_Object old_config
= Fcurrent_window_configuration (Qnil
);
4406 int delcount
= window_deletion_count
;
4408 CHECK_WINDOW (window
);
4410 /* Give up if this window cannot be resized. */
4411 if (window_fixed_size_p (XWINDOW (window
), horiz_flag
, 1))
4412 error ("Window is not resizable");
4416 Lisp_Object first_parallel
= Qnil
;
4420 /* This happens if WINDOW on the previous iteration was
4421 at top level of the window tree. */
4422 Fset_window_configuration (old_config
);
4423 error ("Specified window edge is fixed");
4426 p
= XWINDOW (window
);
4429 /* See if this level has windows in parallel in the specified
4430 direction. If so, set FIRST_PARALLEL to the first one. */
4433 if (! NILP (parent
) && !NILP (XWINDOW (parent
)->vchild
))
4434 first_parallel
= XWINDOW (parent
)->vchild
;
4435 else if (NILP (parent
) && !NILP (p
->next
))
4437 /* Handle the vertical chain of main window and minibuffer
4438 which has no parent. */
4439 first_parallel
= window
;
4440 while (! NILP (XWINDOW (first_parallel
)->prev
))
4441 first_parallel
= XWINDOW (first_parallel
)->prev
;
4446 if (! NILP (parent
) && !NILP (XWINDOW (parent
)->hchild
))
4447 first_parallel
= XWINDOW (parent
)->hchild
;
4450 /* If this level's succession is in the desired dimension,
4451 and this window is the last one, and there is no higher level,
4452 its trailing edge is fixed. */
4453 if (NILP (XWINDOW (window
)->next
) && NILP (first_parallel
)
4456 Fset_window_configuration (old_config
);
4457 error ("Specified window edge is fixed");
4460 /* Don't make this window too small. */
4461 if (XINT (CURSIZE (window
)) + delta
4462 < window_min_size_2 (XWINDOW (window
), horiz_flag
, 0))
4464 Fset_window_configuration (old_config
);
4465 error ("Cannot adjust window size as specified");
4468 /* Clear out some redisplay caches. */
4469 XSETFASTINT (p
->last_modified
, 0);
4470 XSETFASTINT (p
->last_overlay_modified
, 0);
4472 /* Adjust this window's edge. */
4473 XSETINT (CURSIZE (window
),
4474 XINT (CURSIZE (window
)) + delta
);
4476 /* If this window has following siblings in the desired dimension,
4477 make them smaller, and exit the loop.
4479 (If we reach the top of the tree and can never do this,
4480 we will fail and report an error, above.) */
4481 if (NILP (first_parallel
))
4483 if (!NILP (p
->next
))
4485 /* This may happen for the minibuffer. In that case
4486 the window_deletion_count check below does not work. */
4487 if (XINT (CURSIZE (p
->next
)) - delta
<= 0)
4489 Fset_window_configuration (old_config
);
4490 error ("Cannot adjust window size as specified");
4493 XSETINT (CURBEG (p
->next
),
4494 XINT (CURBEG (p
->next
)) + delta
);
4495 size_window (p
->next
, XINT (CURSIZE (p
->next
)) - delta
,
4496 horiz_flag
, 0, 1, 0);
4501 /* Here we have a chain of parallel siblings, in the other dimension.
4502 Change the size of the other siblings. */
4503 for (child
= first_parallel
;
4505 child
= XWINDOW (child
)->next
)
4506 if (! EQ (child
, window
))
4507 size_window (child
, XINT (CURSIZE (child
)) + delta
,
4508 horiz_flag
, 0, 0, 1);
4513 /* If we made a window so small it got deleted,
4514 we failed. Report failure. */
4515 if (delcount
!= window_deletion_count
)
4517 Fset_window_configuration (old_config
);
4518 error ("Cannot adjust window size as specified");
4521 /* Adjust glyph matrices. */
4522 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
4528 DEFUN ("adjust-window-trailing-edge", Fadjust_window_trailing_edge
,
4529 Sadjust_window_trailing_edge
, 3, 3, 0,
4530 doc
: /* Adjust the bottom or right edge of WINDOW by DELTA.
4531 If HORIZONTAL is non-nil, that means adjust the width, moving the right edge.
4532 Otherwise, adjust the height, moving the bottom edge.
4534 Following siblings of the selected window are resized to fulfill
4535 the size request. If they become too small in the process, they
4536 are not deleted; instead, we signal an error. */)
4537 (window
, delta
, horizontal
)
4538 Lisp_Object window
, delta
, horizontal
;
4540 CHECK_NUMBER (delta
);
4542 window
= selected_window
;
4543 adjust_window_trailing_edge (window
, XINT (delta
), !NILP (horizontal
));
4545 run_window_configuration_change_hook
4546 (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
4553 /***********************************************************************
4554 Resizing Mini-Windows
4555 ***********************************************************************/
4557 static void shrink_window_lowest_first
P_ ((struct window
*, int));
4559 enum save_restore_action
4566 static int save_restore_orig_size
P_ ((struct window
*,
4567 enum save_restore_action
));
4569 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
4570 from lowest windows first. */
4573 shrink_window_lowest_first (w
, height
)
4581 xassert (!MINI_WINDOW_P (w
));
4583 /* Set redisplay hints. */
4584 XSETFASTINT (w
->last_modified
, 0);
4585 XSETFASTINT (w
->last_overlay_modified
, 0);
4586 windows_or_buffers_changed
++;
4587 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
4589 old_height
= XFASTINT (w
->total_lines
);
4590 XSETFASTINT (w
->total_lines
, height
);
4592 if (!NILP (w
->hchild
))
4594 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
4596 c
= XWINDOW (child
);
4597 c
->top_line
= w
->top_line
;
4598 shrink_window_lowest_first (c
, height
);
4601 else if (!NILP (w
->vchild
))
4603 Lisp_Object last_child
;
4604 int delta
= old_height
- height
;
4609 /* Find the last child. We are taking space from lowest windows
4610 first, so we iterate over children from the last child
4612 for (child
= w
->vchild
; WINDOWP (child
); child
= XWINDOW (child
)->next
)
4615 /* Size children down to their safe heights. */
4616 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
4620 c
= XWINDOW (child
);
4621 this_one
= XFASTINT (c
->total_lines
) - window_min_size_1 (c
, 0, 1);
4623 if (this_one
> delta
)
4626 shrink_window_lowest_first (c
, XFASTINT (c
->total_lines
) - this_one
);
4630 /* Compute new positions. */
4631 last_top
= XINT (w
->top_line
);
4632 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
4634 c
= XWINDOW (child
);
4635 c
->top_line
= make_number (last_top
);
4636 shrink_window_lowest_first (c
, XFASTINT (c
->total_lines
));
4637 last_top
+= XFASTINT (c
->total_lines
);
4643 /* Save, restore, or check positions and sizes in the window tree
4644 rooted at W. ACTION says what to do.
4646 If ACTION is CHECK_ORIG_SIZES, check if orig_top_line and
4647 orig_total_lines members are valid for all windows in the window
4648 tree. Value is non-zero if they are valid.
4650 If ACTION is SAVE_ORIG_SIZES, save members top and height in
4651 orig_top_line and orig_total_lines for all windows in the tree.
4653 If ACTION is RESTORE_ORIG_SIZES, restore top and height from values
4654 stored in orig_top_line and orig_total_lines for all windows. */
4657 save_restore_orig_size (w
, action
)
4659 enum save_restore_action action
;
4665 if (!NILP (w
->hchild
))
4667 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
4670 else if (!NILP (w
->vchild
))
4672 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
4678 case CHECK_ORIG_SIZES
:
4679 if (!INTEGERP (w
->orig_top_line
) || !INTEGERP (w
->orig_total_lines
))
4683 case SAVE_ORIG_SIZES
:
4684 w
->orig_top_line
= w
->top_line
;
4685 w
->orig_total_lines
= w
->total_lines
;
4686 XSETFASTINT (w
->last_modified
, 0);
4687 XSETFASTINT (w
->last_overlay_modified
, 0);
4690 case RESTORE_ORIG_SIZES
:
4691 xassert (INTEGERP (w
->orig_top_line
) && INTEGERP (w
->orig_total_lines
));
4692 w
->top_line
= w
->orig_top_line
;
4693 w
->total_lines
= w
->orig_total_lines
;
4694 w
->orig_total_lines
= w
->orig_top_line
= Qnil
;
4695 XSETFASTINT (w
->last_modified
, 0);
4696 XSETFASTINT (w
->last_overlay_modified
, 0);
4703 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
4710 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
4711 without deleting other windows. */
4714 grow_mini_window (w
, delta
)
4718 struct frame
*f
= XFRAME (w
->frame
);
4719 struct window
*root
;
4721 xassert (MINI_WINDOW_P (w
));
4722 /* Commenting out the following assertion goes against the stated interface
4723 of the function, but it currently does not seem to do anything useful.
4724 See discussion of this issue in the thread for bug#4534.
4725 xassert (delta >= 0); */
4727 /* Compute how much we can enlarge the mini-window without deleting
4729 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4732 int min_height
= window_min_size (root
, 0, 0, 0, 0);
4733 if (XFASTINT (root
->total_lines
) - delta
< min_height
)
4734 /* Note that the root window may already be smaller than
4736 delta
= max (0, XFASTINT (root
->total_lines
) - min_height
);
4741 /* Save original window sizes and positions, if not already done. */
4742 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
4743 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
4745 /* Shrink other windows. */
4746 shrink_window_lowest_first (root
, XFASTINT (root
->total_lines
) - delta
);
4748 /* Grow the mini-window. */
4749 w
->top_line
= make_number (XFASTINT (root
->top_line
) + XFASTINT (root
->total_lines
));
4750 w
->total_lines
= make_number (XFASTINT (w
->total_lines
) + delta
);
4751 XSETFASTINT (w
->last_modified
, 0);
4752 XSETFASTINT (w
->last_overlay_modified
, 0);
4759 /* Shrink mini-window W. If there is recorded info about window sizes
4760 before a call to grow_mini_window, restore recorded window sizes.
4761 Otherwise, if the mini-window is higher than 1 line, resize it to 1
4765 shrink_mini_window (w
)
4768 struct frame
*f
= XFRAME (w
->frame
);
4769 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4771 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
4773 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
4775 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4776 windows_or_buffers_changed
= 1;
4778 else if (XFASTINT (w
->total_lines
) > 1)
4780 /* Distribute the additional lines of the mini-window
4781 among the other windows. */
4783 XSETWINDOW (window
, w
);
4784 enlarge_window (window
, 1 - XFASTINT (w
->total_lines
), 0);
4790 /* Mark window cursors off for all windows in the window tree rooted
4791 at W by setting their phys_cursor_on_p flag to zero. Called from
4792 xterm.c, e.g. when a frame is cleared and thereby all cursors on
4793 the frame are cleared. */
4796 mark_window_cursors_off (w
)
4801 if (!NILP (w
->hchild
))
4802 mark_window_cursors_off (XWINDOW (w
->hchild
));
4803 else if (!NILP (w
->vchild
))
4804 mark_window_cursors_off (XWINDOW (w
->vchild
));
4806 w
->phys_cursor_on_p
= 0;
4808 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4813 /* Return number of lines of text (not counting mode lines) in W. */
4816 window_internal_height (w
)
4819 int ht
= XFASTINT (w
->total_lines
);
4821 if (!MINI_WINDOW_P (w
))
4823 if (!NILP (w
->parent
)
4824 || !NILP (w
->vchild
)
4825 || !NILP (w
->hchild
)
4828 || WINDOW_WANTS_MODELINE_P (w
))
4831 if (WINDOW_WANTS_HEADER_LINE_P (w
))
4839 /* Return the number of columns in W.
4840 Don't count columns occupied by scroll bars or the vertical bar
4841 separating W from the sibling to its right. */
4844 window_box_text_cols (w
)
4847 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4848 int width
= XINT (w
->total_cols
);
4850 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
4851 /* Scroll bars occupy a few columns. */
4852 width
-= WINDOW_CONFIG_SCROLL_BAR_COLS (w
);
4853 else if (!FRAME_WINDOW_P (f
)
4854 && !WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
4855 /* The column of `|' characters separating side-by-side windows
4856 occupies one column only. */
4859 if (FRAME_WINDOW_P (f
))
4860 /* On window-systems, fringes and display margins cannot be
4861 used for normal text. */
4862 width
-= (WINDOW_FRINGE_COLS (w
)
4863 + WINDOW_LEFT_MARGIN_COLS (w
)
4864 + WINDOW_RIGHT_MARGIN_COLS (w
));
4870 /************************************************************************
4872 ***********************************************************************/
4874 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
4875 N screen-fulls, which is defined as the height of the window minus
4876 next_screen_context_lines. If WHOLE is zero, scroll up N lines
4877 instead. Negative values of N mean scroll down. NOERROR non-zero
4878 means don't signal an error if we try to move over BEGV or ZV,
4882 window_scroll (window
, n
, whole
, noerror
)
4890 /* If we must, use the pixel-based version which is much slower than
4891 the line-based one but can handle varying line heights. */
4892 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
4893 window_scroll_pixel_based (window
, n
, whole
, noerror
);
4895 window_scroll_line_based (window
, n
, whole
, noerror
);
4901 /* Implementation of window_scroll that works based on pixel line
4902 heights. See the comment of window_scroll for parameter
4906 window_scroll_pixel_based (window
, n
, whole
, noerror
)
4913 struct window
*w
= XWINDOW (window
);
4914 struct text_pos start
;
4915 int this_scroll_margin
;
4916 /* True if we fiddled the window vscroll field without really scrolling. */
4918 int x
, y
, rtop
, rbot
, rowh
, vpos
;
4920 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4922 /* If PT is not visible in WINDOW, move back one half of
4923 the screen. Allow PT to be partially visible, otherwise
4924 something like (scroll-down 1) with PT in the line before
4925 the partially visible one would recenter. */
4927 if (!pos_visible_p (w
, PT
, &x
, &y
, &rtop
, &rbot
, &rowh
, &vpos
))
4929 /* Move backward half the height of the window. Performance note:
4930 vmotion used here is about 10% faster, but would give wrong
4931 results for variable height lines. */
4932 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4933 it
.current_y
= it
.last_visible_y
;
4934 move_it_vertically_backward (&it
, window_box_height (w
) / 2);
4936 /* The function move_iterator_vertically may move over more than
4937 the specified y-distance. If it->w is small, e.g. a
4938 mini-buffer window, we may end up in front of the window's
4939 display area. This is the case when Start displaying at the
4940 start of the line containing PT in this case. */
4941 if (it
.current_y
<= 0)
4943 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4944 move_it_vertically_backward (&it
, 0);
4948 start
= it
.current
.pos
;
4950 else if (auto_window_vscroll_p
)
4952 if (rtop
|| rbot
) /* partially visible */
4955 int dy
= WINDOW_FRAME_LINE_HEIGHT (w
);
4957 dy
= max ((window_box_height (w
)
4958 - next_screen_context_lines
* dy
),
4964 /* Only vscroll backwards if already vscrolled forwards. */
4965 if (w
->vscroll
< 0 && rtop
> 0)
4967 px
= max (0, -w
->vscroll
- min (rtop
, -dy
));
4968 Fset_window_vscroll (window
, make_number (px
), Qt
);
4974 /* Do vscroll if already vscrolled or only display line. */
4975 if (rbot
> 0 && (w
->vscroll
< 0 || vpos
== 0))
4977 px
= max (0, -w
->vscroll
+ min (rbot
, dy
));
4978 Fset_window_vscroll (window
, make_number (px
), Qt
);
4982 /* Maybe modify window start instead of scrolling. */
4983 if (rbot
> 0 || w
->vscroll
< 0)
4987 Fset_window_vscroll (window
, make_number (0), Qt
);
4988 /* If there are other text lines above the current row,
4989 move window start to current row. Else to next row. */
4991 spos
= XINT (Fline_beginning_position (Qnil
));
4993 spos
= min (XINT (Fline_end_position (Qnil
)) + 1, ZV
);
4994 set_marker_restricted (w
->start
, make_number (spos
),
4996 w
->start_at_line_beg
= Qt
;
4997 w
->update_mode_line
= Qt
;
4998 XSETFASTINT (w
->last_modified
, 0);
4999 XSETFASTINT (w
->last_overlay_modified
, 0);
5000 /* Set force_start so that redisplay_window will run the
5001 window-scroll-functions. */
5002 w
->force_start
= Qt
;
5007 /* Cancel previous vscroll. */
5008 Fset_window_vscroll (window
, make_number (0), Qt
);
5011 /* If scroll_preserve_screen_position is non-nil, we try to set
5012 point in the same window line as it is now, so get that line. */
5013 if (!NILP (Vscroll_preserve_screen_position
))
5015 /* We preserve the goal pixel coordinate across consecutive
5016 calls to scroll-up, scroll-down and other commands that
5017 have the `scroll-command' property. This avoids the
5018 possibility of point becoming "stuck" on a tall line when
5019 scrolling by one line. */
5020 if (window_scroll_pixel_based_preserve_y
< 0
5021 || !SYMBOLP (current_kboard
->Vlast_command
)
5022 || NILP (Fget (current_kboard
->Vlast_command
, Qscroll_command
)))
5024 start_display (&it
, w
, start
);
5025 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
5026 window_scroll_pixel_based_preserve_y
= it
.current_y
;
5027 window_scroll_pixel_based_preserve_x
= it
.current_x
;
5031 window_scroll_pixel_based_preserve_y
5032 = window_scroll_pixel_based_preserve_x
= -1;
5034 /* Move iterator it from start the specified distance forward or
5035 backward. The result is the new window start. */
5036 start_display (&it
, w
, start
);
5039 int start_pos
= IT_CHARPOS (it
);
5040 int dy
= WINDOW_FRAME_LINE_HEIGHT (w
);
5041 dy
= max ((window_box_height (w
)
5042 - next_screen_context_lines
* dy
),
5045 /* Note that move_it_vertically always moves the iterator to the
5046 start of a line. So, if the last line doesn't have a newline,
5047 we would end up at the start of the line ending at ZV. */
5050 move_it_vertically_backward (&it
, -dy
);
5051 /* Ensure we actually do move, e.g. in case we are currently
5052 looking at an image that is taller that the window height. */
5053 while (start_pos
== IT_CHARPOS (it
)
5054 && start_pos
> BEGV
)
5055 move_it_by_lines (&it
, -1, 1);
5059 move_it_to (&it
, ZV
, -1, it
.current_y
+ dy
, -1,
5060 MOVE_TO_POS
| MOVE_TO_Y
);
5061 /* Ensure we actually do move, e.g. in case we are currently
5062 looking at an image that is taller that the window height. */
5063 while (start_pos
== IT_CHARPOS (it
)
5065 move_it_by_lines (&it
, 1, 1);
5069 move_it_by_lines (&it
, n
, 1);
5071 /* We failed if we find ZV is already on the screen (scrolling up,
5072 means there's nothing past the end), or if we can't start any
5073 earlier (scrolling down, means there's nothing past the top). */
5074 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
5075 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
5077 if (IT_CHARPOS (it
) == ZV
)
5079 if (it
.current_y
< it
.last_visible_y
5080 && (it
.current_y
+ it
.max_ascent
+ it
.max_descent
5081 > it
.last_visible_y
))
5083 /* The last line was only partially visible, make it fully
5085 w
->vscroll
= (it
.last_visible_y
5086 - it
.current_y
+ it
.max_ascent
+ it
.max_descent
);
5087 adjust_glyphs (it
.f
);
5091 else if (n
< 0) /* could happen with empty buffers */
5092 xsignal0 (Qbeginning_of_buffer
);
5094 xsignal0 (Qend_of_buffer
);
5098 if (w
->vscroll
!= 0)
5099 /* The first line was only partially visible, make it fully
5105 xsignal0 (Qbeginning_of_buffer
);
5108 /* If control gets here, then we vscrolled. */
5110 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
5112 /* Don't try to change the window start below. */
5118 int pos
= IT_CHARPOS (it
);
5121 /* If in the middle of a multi-glyph character move forward to
5122 the next character. */
5123 if (in_display_vector_p (&it
))
5126 move_it_to (&it
, pos
, -1, -1, -1, MOVE_TO_POS
);
5129 /* Set the window start, and set up the window for redisplay. */
5130 set_marker_restricted (w
->start
, make_number (pos
),
5132 bytepos
= XMARKER (w
->start
)->bytepos
;
5133 w
->start_at_line_beg
= ((pos
== BEGV
|| FETCH_BYTE (bytepos
- 1) == '\n')
5135 w
->update_mode_line
= Qt
;
5136 XSETFASTINT (w
->last_modified
, 0);
5137 XSETFASTINT (w
->last_overlay_modified
, 0);
5138 /* Set force_start so that redisplay_window will run the
5139 window-scroll-functions. */
5140 w
->force_start
= Qt
;
5143 /* The rest of this function uses current_y in a nonstandard way,
5144 not including the height of the header line if any. */
5145 it
.current_y
= it
.vpos
= 0;
5147 /* Move PT out of scroll margins.
5148 This code wants current_y to be zero at the window start position
5149 even if there is a header line. */
5150 this_scroll_margin
= max (0, scroll_margin
);
5151 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->total_lines
) / 4);
5152 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
5156 /* We moved the window start towards ZV, so PT may be now
5157 in the scroll margin at the top. */
5158 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
5159 if (IT_CHARPOS (it
) == PT
&& it
.current_y
>= this_scroll_margin
5160 && (NILP (Vscroll_preserve_screen_position
)
5161 || EQ (Vscroll_preserve_screen_position
, Qt
)))
5162 /* We found PT at a legitimate height. Leave it alone. */
5164 else if (window_scroll_pixel_based_preserve_y
>= 0)
5166 /* If we have a header line, take account of it.
5167 This is necessary because we set it.current_y to 0, above. */
5168 move_it_to (&it
, -1,
5169 window_scroll_pixel_based_preserve_x
,
5170 window_scroll_pixel_based_preserve_y
5171 - (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0 ),
5172 -1, MOVE_TO_Y
| MOVE_TO_X
);
5173 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5177 while (it
.current_y
< this_scroll_margin
)
5179 int prev
= it
.current_y
;
5180 move_it_by_lines (&it
, 1, 1);
5181 if (prev
== it
.current_y
)
5184 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5189 int charpos
, bytepos
;
5192 /* Save our position, for the
5193 window_scroll_pixel_based_preserve_y case. */
5194 charpos
= IT_CHARPOS (it
);
5195 bytepos
= IT_BYTEPOS (it
);
5197 /* We moved the window start towards BEGV, so PT may be now
5198 in the scroll margin at the bottom. */
5199 move_it_to (&it
, PT
, -1,
5200 (it
.last_visible_y
- CURRENT_HEADER_LINE_HEIGHT (w
)
5201 - this_scroll_margin
- 1),
5203 MOVE_TO_POS
| MOVE_TO_Y
);
5205 /* Save our position, in case it's correct. */
5206 charpos
= IT_CHARPOS (it
);
5207 bytepos
= IT_BYTEPOS (it
);
5209 /* See if point is on a partially visible line at the end. */
5210 if (it
.what
== IT_EOB
)
5211 partial_p
= it
.current_y
+ it
.ascent
+ it
.descent
> it
.last_visible_y
;
5214 move_it_by_lines (&it
, 1, 1);
5215 partial_p
= it
.current_y
> it
.last_visible_y
;
5218 if (charpos
== PT
&& !partial_p
5219 && (NILP (Vscroll_preserve_screen_position
)
5220 || EQ (Vscroll_preserve_screen_position
, Qt
)))
5221 /* We found PT before we found the display margin, so PT is ok. */
5223 else if (window_scroll_pixel_based_preserve_y
>= 0)
5225 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
5226 start_display (&it
, w
, start
);
5227 /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT
5228 here because we called start_display again and did not
5229 alter it.current_y this time. */
5230 move_it_to (&it
, -1, window_scroll_pixel_based_preserve_x
,
5231 window_scroll_pixel_based_preserve_y
, -1,
5232 MOVE_TO_Y
| MOVE_TO_X
);
5233 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5238 /* The last line was only partially visible, so back up two
5239 lines to make sure we're on a fully visible line. */
5241 move_it_by_lines (&it
, -2, 0);
5242 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5245 /* No, the position we saved is OK, so use it. */
5246 SET_PT_BOTH (charpos
, bytepos
);
5252 /* Implementation of window_scroll that works based on screen lines.
5253 See the comment of window_scroll for parameter descriptions. */
5256 window_scroll_line_based (window
, n
, whole
, noerror
)
5262 register struct window
*w
= XWINDOW (window
);
5263 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
5264 register int pos
, pos_byte
;
5265 register int ht
= window_internal_height (w
);
5266 register Lisp_Object tem
;
5270 Lisp_Object original_pos
= Qnil
;
5272 /* If scrolling screen-fulls, compute the number of lines to
5273 scroll from the window's height. */
5275 n
*= max (1, ht
- next_screen_context_lines
);
5277 startpos
= marker_position (w
->start
);
5279 if (!NILP (Vscroll_preserve_screen_position
))
5281 if (window_scroll_preserve_vpos
<= 0
5282 || !SYMBOLP (current_kboard
->Vlast_command
)
5283 || NILP (Fget (current_kboard
->Vlast_command
, Qscroll_command
)))
5285 struct position posit
5286 = *compute_motion (startpos
, 0, 0, 0,
5288 -1, XINT (w
->hscroll
),
5290 window_scroll_preserve_vpos
= posit
.vpos
;
5291 window_scroll_preserve_hpos
= posit
.hpos
+ XINT (w
->hscroll
);
5294 original_pos
= Fcons (make_number (window_scroll_preserve_hpos
),
5295 make_number (window_scroll_preserve_vpos
));
5298 XSETFASTINT (tem
, PT
);
5299 tem
= Fpos_visible_in_window_p (tem
, window
, Qnil
);
5303 Fvertical_motion (make_number (- (ht
/ 2)), window
);
5308 lose
= n
< 0 && PT
== BEGV
;
5309 Fvertical_motion (make_number (n
), window
);
5313 SET_PT_BOTH (opoint
, opoint_byte
);
5320 xsignal0 (Qbeginning_of_buffer
);
5325 int this_scroll_margin
= scroll_margin
;
5327 /* Don't use a scroll margin that is negative or too large. */
5328 if (this_scroll_margin
< 0)
5329 this_scroll_margin
= 0;
5331 if (XINT (w
->total_lines
) < 4 * scroll_margin
)
5332 this_scroll_margin
= XINT (w
->total_lines
) / 4;
5334 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
5335 w
->start_at_line_beg
= bolp
;
5336 w
->update_mode_line
= Qt
;
5337 XSETFASTINT (w
->last_modified
, 0);
5338 XSETFASTINT (w
->last_overlay_modified
, 0);
5339 /* Set force_start so that redisplay_window will run
5340 the window-scroll-functions. */
5341 w
->force_start
= Qt
;
5343 if (!NILP (Vscroll_preserve_screen_position
)
5344 && (whole
|| !EQ (Vscroll_preserve_screen_position
, Qt
)))
5346 SET_PT_BOTH (pos
, pos_byte
);
5347 Fvertical_motion (original_pos
, window
);
5349 /* If we scrolled forward, put point enough lines down
5350 that it is outside the scroll margin. */
5355 if (this_scroll_margin
> 0)
5357 SET_PT_BOTH (pos
, pos_byte
);
5358 Fvertical_motion (make_number (this_scroll_margin
), window
);
5364 if (top_margin
<= opoint
)
5365 SET_PT_BOTH (opoint
, opoint_byte
);
5366 else if (!NILP (Vscroll_preserve_screen_position
))
5368 SET_PT_BOTH (pos
, pos_byte
);
5369 Fvertical_motion (original_pos
, window
);
5372 SET_PT (top_margin
);
5378 /* If we scrolled backward, put point near the end of the window
5379 but not within the scroll margin. */
5380 SET_PT_BOTH (pos
, pos_byte
);
5381 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
5382 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
5385 bottom_margin
= PT
+ 1;
5387 if (bottom_margin
> opoint
)
5388 SET_PT_BOTH (opoint
, opoint_byte
);
5391 if (!NILP (Vscroll_preserve_screen_position
))
5393 SET_PT_BOTH (pos
, pos_byte
);
5394 Fvertical_motion (original_pos
, window
);
5397 Fvertical_motion (make_number (-1), window
);
5406 xsignal0 (Qend_of_buffer
);
5411 /* Scroll selected_window up or down. If N is nil, scroll a
5412 screen-full which is defined as the height of the window minus
5413 next_screen_context_lines. If N is the symbol `-', scroll.
5414 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
5415 up. This is the guts of Fscroll_up and Fscroll_down. */
5418 scroll_command (n
, direction
)
5422 int count
= SPECPDL_INDEX ();
5424 xassert (eabs (direction
) == 1);
5426 /* If selected window's buffer isn't current, make it current for
5427 the moment. But don't screw up if window_scroll gets an error. */
5428 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
5430 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
5431 Fset_buffer (XWINDOW (selected_window
)->buffer
);
5433 /* Make redisplay consider other windows than just selected_window. */
5434 ++windows_or_buffers_changed
;
5438 window_scroll (selected_window
, direction
, 1, 0);
5439 else if (EQ (n
, Qminus
))
5440 window_scroll (selected_window
, -direction
, 1, 0);
5443 n
= Fprefix_numeric_value (n
);
5444 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
5447 unbind_to (count
, Qnil
);
5450 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "^P",
5451 doc
: /* Scroll text of selected window upward ARG lines.
5452 If ARG is omitted or nil, scroll upward by a near full screen.
5453 A near full screen is `next-screen-context-lines' less than a full screen.
5454 Negative ARG means scroll downward.
5455 If ARG is the atom `-', scroll downward by nearly full screen.
5456 When calling from a program, supply as argument a number, nil, or `-'. */)
5460 scroll_command (arg
, 1);
5464 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "^P",
5465 doc
: /* Scroll text of selected window down ARG lines.
5466 If ARG is omitted or nil, scroll down by a near full screen.
5467 A near full screen is `next-screen-context-lines' less than a full screen.
5468 Negative ARG means scroll upward.
5469 If ARG is the atom `-', scroll upward by nearly full screen.
5470 When calling from a program, supply as argument a number, nil, or `-'. */)
5474 scroll_command (arg
, -1);
5478 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
5479 doc
: /* Return the other window for \"other window scroll\" commands.
5480 If `other-window-scroll-buffer' is non-nil, a window
5481 showing that buffer is used.
5482 If in the minibuffer, `minibuffer-scroll-window' if non-nil
5483 specifies the window. This takes precedence over
5484 `other-window-scroll-buffer'. */)
5489 if (MINI_WINDOW_P (XWINDOW (selected_window
))
5490 && !NILP (Vminibuf_scroll_window
))
5491 window
= Vminibuf_scroll_window
;
5492 /* If buffer is specified, scroll that buffer. */
5493 else if (!NILP (Vother_window_scroll_buffer
))
5495 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
5497 window
= display_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
5501 /* Nothing specified; look for a neighboring window on the same
5503 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
5505 if (EQ (window
, selected_window
))
5506 /* That didn't get us anywhere; look for a window on another
5509 window
= Fnext_window (window
, Qnil
, Qt
);
5510 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
5511 && ! EQ (window
, selected_window
));
5514 CHECK_LIVE_WINDOW (window
);
5516 if (EQ (window
, selected_window
))
5517 error ("There is no other window");
5522 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
5523 doc
: /* Scroll next window upward ARG lines; or near full screen if no ARG.
5524 A near full screen is `next-screen-context-lines' less than a full screen.
5525 The next window is the one below the current one; or the one at the top
5526 if the current one is at the bottom. Negative ARG means scroll downward.
5527 If ARG is the atom `-', scroll downward by nearly full screen.
5528 When calling from a program, supply as argument a number, nil, or `-'.
5530 If `other-window-scroll-buffer' is non-nil, scroll the window
5531 showing that buffer, popping the buffer up if necessary.
5532 If in the minibuffer, `minibuffer-scroll-window' if non-nil
5533 specifies the window to scroll. This takes precedence over
5534 `other-window-scroll-buffer'. */)
5540 int count
= SPECPDL_INDEX ();
5542 window
= Fother_window_for_scrolling ();
5543 w
= XWINDOW (window
);
5545 /* Don't screw up if window_scroll gets an error. */
5546 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
5547 ++windows_or_buffers_changed
;
5549 Fset_buffer (w
->buffer
);
5550 SET_PT (marker_position (w
->pointm
));
5553 window_scroll (window
, 1, 1, 1);
5554 else if (EQ (arg
, Qminus
))
5555 window_scroll (window
, -1, 1, 1);
5561 window_scroll (window
, XINT (arg
), 0, 1);
5564 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
5565 unbind_to (count
, Qnil
);
5570 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 2, "^P\np",
5571 doc
: /* Scroll selected window display ARG columns left.
5572 Default for ARG is window width minus 2.
5573 Value is the total amount of leftward horizontal scrolling in
5574 effect after the change.
5575 If SET-MINIMUM is non-nil, the new scroll amount becomes the
5576 lower bound for automatic scrolling, i.e. automatic scrolling
5577 will not scroll a window to a column less than the value returned
5578 by this function. This happens in an interactive call. */)
5580 register Lisp_Object arg
, set_minimum
;
5584 struct window
*w
= XWINDOW (selected_window
);
5587 XSETFASTINT (arg
, window_box_text_cols (w
) - 2);
5589 arg
= Fprefix_numeric_value (arg
);
5591 hscroll
= XINT (w
->hscroll
) + XINT (arg
);
5592 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
5594 if (!NILP (set_minimum
))
5595 w
->min_hscroll
= w
->hscroll
;
5600 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 2, "^P\np",
5601 doc
: /* Scroll selected window display ARG columns right.
5602 Default for ARG is window width minus 2.
5603 Value is the total amount of leftward horizontal scrolling in
5604 effect after the change.
5605 If SET-MINIMUM is non-nil, the new scroll amount becomes the
5606 lower bound for automatic scrolling, i.e. automatic scrolling
5607 will not scroll a window to a column less than the value returned
5608 by this function. This happens in an interactive call. */)
5610 register Lisp_Object arg
, set_minimum
;
5614 struct window
*w
= XWINDOW (selected_window
);
5617 XSETFASTINT (arg
, window_box_text_cols (w
) - 2);
5619 arg
= Fprefix_numeric_value (arg
);
5621 hscroll
= XINT (w
->hscroll
) - XINT (arg
);
5622 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
5624 if (!NILP (set_minimum
))
5625 w
->min_hscroll
= w
->hscroll
;
5630 DEFUN ("minibuffer-selected-window", Fminibuffer_selected_window
, Sminibuffer_selected_window
, 0, 0, 0,
5631 doc
: /* Return the window which was selected when entering the minibuffer.
5632 Returns nil, if selected window is not a minibuffer window. */)
5635 if (minibuf_level
> 0
5636 && MINI_WINDOW_P (XWINDOW (selected_window
))
5637 && WINDOW_LIVE_P (minibuf_selected_window
))
5638 return minibuf_selected_window
;
5643 /* Value is the number of lines actually displayed in window W,
5644 as opposed to its height. */
5647 displayed_window_lines (w
)
5651 struct text_pos start
;
5652 int height
= window_box_height (w
);
5653 struct buffer
*old_buffer
;
5656 if (XBUFFER (w
->buffer
) != current_buffer
)
5658 old_buffer
= current_buffer
;
5659 set_buffer_internal (XBUFFER (w
->buffer
));
5664 /* In case W->start is out of the accessible range, do something
5665 reasonable. This happens in Info mode when Info-scroll-down
5666 calls (recenter -1) while W->start is 1. */
5667 if (XMARKER (w
->start
)->charpos
< BEGV
)
5668 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
5669 else if (XMARKER (w
->start
)->charpos
> ZV
)
5670 SET_TEXT_POS (start
, ZV
, ZV_BYTE
);
5672 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
5674 start_display (&it
, w
, start
);
5675 move_it_vertically (&it
, height
);
5676 bottom_y
= line_bottom_y (&it
);
5678 /* rms: On a non-window display,
5679 the value of it.vpos at the bottom of the screen
5680 seems to be 1 larger than window_box_height (w).
5681 This kludge fixes a bug whereby (move-to-window-line -1)
5682 when ZV is on the last screen line
5683 moves to the previous screen line instead of the last one. */
5684 if (! FRAME_WINDOW_P (XFRAME (w
->frame
)))
5687 /* Add in empty lines at the bottom of the window. */
5688 if (bottom_y
< height
)
5690 int uy
= FRAME_LINE_HEIGHT (it
.f
);
5691 it
.vpos
+= (height
- bottom_y
+ uy
- 1) / uy
;
5695 set_buffer_internal (old_buffer
);
5701 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
5702 doc
: /* Center point in selected window and maybe redisplay frame.
5703 With prefix argument ARG, recenter putting point on screen line ARG
5704 relative to the selected window. If ARG is negative, it counts up from the
5705 bottom of the window. (ARG should be less than the height of the window.)
5707 If ARG is omitted or nil, then recenter with point on the middle line of
5708 the selected window; if the variable `recenter-redisplay' is non-nil,
5709 also erase the entire frame and redraw it (when `auto-resize-tool-bars'
5710 is set to `grow-only', this resets the tool-bar's height to the minimum
5711 height needed); if `recenter-redisplay' has the special value `tty',
5712 then only tty frame are redrawn.
5714 Just C-u as prefix means put point in the center of the window
5715 and redisplay normally--don't erase and redraw the frame. */)
5717 register Lisp_Object arg
;
5719 struct window
*w
= XWINDOW (selected_window
);
5720 struct buffer
*buf
= XBUFFER (w
->buffer
);
5721 struct buffer
*obuf
= current_buffer
;
5723 int charpos
, bytepos
;
5725 int this_scroll_margin
;
5727 /* If redisplay is suppressed due to an error, try again. */
5728 obuf
->display_error_modiff
= 0;
5732 if (!NILP (Vrecenter_redisplay
)
5733 && (!EQ (Vrecenter_redisplay
, Qtty
)
5734 || !NILP (Ftty_type (selected_frame
))))
5738 /* Invalidate pixel data calculated for all compositions. */
5739 for (i
= 0; i
< n_compositions
; i
++)
5740 composition_table
[i
]->font
= NULL
;
5742 WINDOW_XFRAME (w
)->minimize_tool_bar_window_p
= 1;
5744 Fredraw_frame (WINDOW_FRAME (w
));
5745 SET_FRAME_GARBAGED (WINDOW_XFRAME (w
));
5750 else if (CONSP (arg
)) /* Just C-u. */
5754 arg
= Fprefix_numeric_value (arg
);
5759 set_buffer_internal (buf
);
5761 /* Do this after making BUF current
5762 in case scroll_margin is buffer-local. */
5763 this_scroll_margin
= max (0, scroll_margin
);
5764 this_scroll_margin
= min (this_scroll_margin
,
5765 XFASTINT (w
->total_lines
) / 4);
5767 /* Handle centering on a graphical frame specially. Such frames can
5768 have variable-height lines and centering point on the basis of
5769 line counts would lead to strange effects. */
5770 if (FRAME_WINDOW_P (XFRAME (w
->frame
)))
5777 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
5778 start_display (&it
, w
, pt
);
5779 move_it_vertically_backward (&it
, window_box_height (w
) / 2);
5780 charpos
= IT_CHARPOS (it
);
5781 bytepos
= IT_BYTEPOS (it
);
5788 int extra_line_spacing
;
5789 int h
= window_box_height (w
);
5791 iarg
= - max (-iarg
, this_scroll_margin
);
5793 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
5794 start_display (&it
, w
, pt
);
5796 /* Be sure we have the exact height of the full line containing PT. */
5797 move_it_by_lines (&it
, 0, 1);
5799 /* The amount of pixels we have to move back is the window
5800 height minus what's displayed in the line containing PT,
5801 and the lines below. */
5804 move_it_by_lines (&it
, nlines
, 1);
5806 if (it
.vpos
== nlines
)
5810 /* Last line has no newline */
5811 h
-= line_bottom_y (&it
);
5815 /* Don't reserve space for extra line spacing of last line. */
5816 extra_line_spacing
= it
.max_extra_line_spacing
;
5818 /* If we can't move down NLINES lines because we hit
5819 the end of the buffer, count in some empty lines. */
5820 if (it
.vpos
< nlines
)
5823 extra_line_spacing
= it
.extra_line_spacing
;
5824 h
-= nlines
* (FRAME_LINE_HEIGHT (it
.f
) + extra_line_spacing
);
5829 /* Now find the new top line (starting position) of the window. */
5830 start_display (&it
, w
, pt
);
5832 move_it_vertically_backward (&it
, h
);
5834 /* If extra line spacing is present, we may move too far
5835 back. This causes the last line to be only partially
5836 visible (which triggers redisplay to recenter that line
5837 in the middle), so move forward.
5838 But ignore extra line spacing on last line, as it is not
5839 considered to be part of the visible height of the line.
5841 h
+= extra_line_spacing
;
5842 while (-it
.current_y
> h
)
5843 move_it_by_lines (&it
, 1, 1);
5845 charpos
= IT_CHARPOS (it
);
5846 bytepos
= IT_BYTEPOS (it
);
5850 struct position pos
;
5852 iarg
= max (iarg
, this_scroll_margin
);
5854 pos
= *vmotion (PT
, -iarg
, w
);
5855 charpos
= pos
.bufpos
;
5856 bytepos
= pos
.bytepos
;
5861 struct position pos
;
5862 int ht
= window_internal_height (w
);
5869 /* Don't let it get into the margin at either top or bottom. */
5870 iarg
= max (iarg
, this_scroll_margin
);
5871 iarg
= min (iarg
, ht
- this_scroll_margin
- 1);
5873 pos
= *vmotion (PT
, - iarg
, w
);
5874 charpos
= pos
.bufpos
;
5875 bytepos
= pos
.bytepos
;
5878 /* Set the new window start. */
5879 set_marker_both (w
->start
, w
->buffer
, charpos
, bytepos
);
5880 w
->window_end_valid
= Qnil
;
5882 w
->optional_new_start
= Qt
;
5884 if (bytepos
== BEGV_BYTE
|| FETCH_BYTE (bytepos
- 1) == '\n')
5885 w
->start_at_line_beg
= Qt
;
5887 w
->start_at_line_beg
= Qnil
;
5889 set_buffer_internal (obuf
);
5894 DEFUN ("window-text-height", Fwindow_text_height
, Swindow_text_height
,
5896 doc
: /* Return the height in lines of the text display area of WINDOW.
5897 WINDOW defaults to the selected window.
5899 The return value does not include the mode line, any header line, nor
5900 any partial-height lines in the text display area. */)
5904 struct window
*w
= decode_window (window
);
5905 int pixel_height
= window_box_height (w
);
5906 int line_height
= pixel_height
/ FRAME_LINE_HEIGHT (XFRAME (w
->frame
));
5907 return make_number (line_height
);
5912 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
5914 doc
: /* Position point relative to window.
5915 With no argument, position point at center of window.
5916 An argument specifies vertical position within the window;
5917 zero means top of window, negative means relative to bottom of window. */)
5921 struct window
*w
= XWINDOW (selected_window
);
5925 int this_scroll_margin
;
5928 window
= selected_window
;
5929 start
= marker_position (w
->start
);
5930 if (start
< BEGV
|| start
> ZV
)
5932 int height
= window_internal_height (w
);
5933 Fvertical_motion (make_number (- (height
/ 2)), window
);
5934 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
5935 w
->start_at_line_beg
= Fbolp ();
5936 w
->force_start
= Qt
;
5939 Fgoto_char (w
->start
);
5941 lines
= displayed_window_lines (w
);
5944 this_scroll_margin
= max (0, scroll_margin
);
5945 this_scroll_margin
= min (this_scroll_margin
, lines
/ 4);
5949 XSETFASTINT (arg
, lines
/ 2);
5952 int iarg
= XINT (Fprefix_numeric_value (arg
));
5955 iarg
= iarg
+ lines
;
5957 #if 0 /* This code would prevent move-to-window-line from moving point
5958 to a place inside the scroll margins (which would cause the
5959 next redisplay to scroll). I wrote this code, but then concluded
5960 it is probably better not to install it. However, it is here
5961 inside #if 0 so as not to lose it. -- rms. */
5963 /* Don't let it get into the margin at either top or bottom. */
5964 iarg
= max (iarg
, this_scroll_margin
);
5965 iarg
= min (iarg
, lines
- this_scroll_margin
- 1);
5968 arg
= make_number (iarg
);
5971 /* Skip past a partially visible first line. */
5973 XSETINT (arg
, XINT (arg
) + 1);
5975 return Fvertical_motion (arg
, window
);
5980 /***********************************************************************
5981 Window Configuration
5982 ***********************************************************************/
5984 struct save_window_data
5987 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
5988 Lisp_Object selected_frame
;
5989 Lisp_Object current_window
;
5990 Lisp_Object current_buffer
;
5991 Lisp_Object minibuf_scroll_window
;
5992 Lisp_Object minibuf_selected_window
;
5993 Lisp_Object root_window
;
5994 Lisp_Object focus_frame
;
5995 /* A vector, each of whose elements is a struct saved_window
5997 Lisp_Object saved_windows
;
5999 /* All fields above are traced by the GC.
6000 From `fame-cols' down, the fields are ignored by the GC. */
6002 int frame_cols
, frame_lines
, frame_menu_bar_lines
;
6003 int frame_tool_bar_lines
;
6006 /* This is saved as a Lisp_Vector */
6009 /* these first two must agree with struct Lisp_Vector in lisp.h */
6011 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
6014 Lisp_Object buffer
, start
, pointm
, mark
;
6015 Lisp_Object left_col
, top_line
, total_cols
, total_lines
;
6016 Lisp_Object hscroll
, min_hscroll
;
6017 Lisp_Object parent
, prev
;
6018 Lisp_Object start_at_line_beg
;
6019 Lisp_Object display_table
;
6020 Lisp_Object orig_top_line
, orig_total_lines
;
6021 Lisp_Object left_margin_cols
, right_margin_cols
;
6022 Lisp_Object left_fringe_width
, right_fringe_width
, fringes_outside_margins
;
6023 Lisp_Object scroll_bar_width
, vertical_scroll_bar_type
;
6024 Lisp_Object dedicated
, resize_proportionally
;
6027 #define SAVED_WINDOW_N(swv,n) \
6028 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
6030 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
6031 doc
: /* Return t if OBJECT is a window-configuration object. */)
6035 return WINDOW_CONFIGURATIONP (object
) ? Qt
: Qnil
;
6038 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
6039 doc
: /* Return the frame that CONFIG, a window-configuration object, is about. */)
6043 register struct save_window_data
*data
;
6044 struct Lisp_Vector
*saved_windows
;
6046 CHECK_WINDOW_CONFIGURATION (config
);
6048 data
= (struct save_window_data
*) XVECTOR (config
);
6049 saved_windows
= XVECTOR (data
->saved_windows
);
6050 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
6053 DEFUN ("set-window-configuration", Fset_window_configuration
,
6054 Sset_window_configuration
, 1, 1, 0,
6055 doc
: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
6056 CONFIGURATION must be a value previously returned
6057 by `current-window-configuration' (which see).
6058 If CONFIGURATION was made from a frame that is now deleted,
6059 only frame-independent values can be restored. In this case,
6060 the return value is nil. Otherwise the value is t. */)
6062 Lisp_Object configuration
;
6064 register struct save_window_data
*data
;
6065 struct Lisp_Vector
*saved_windows
;
6066 Lisp_Object new_current_buffer
;
6071 CHECK_WINDOW_CONFIGURATION (configuration
);
6073 data
= (struct save_window_data
*) XVECTOR (configuration
);
6074 saved_windows
= XVECTOR (data
->saved_windows
);
6076 new_current_buffer
= data
->current_buffer
;
6077 if (NILP (XBUFFER (new_current_buffer
)->name
))
6078 new_current_buffer
= Qnil
;
6081 if (XBUFFER (new_current_buffer
) == current_buffer
)
6082 /* The code further down "preserves point" by saving here PT in
6083 old_point and then setting it later back into PT. When the
6084 current-selected-window and the final-selected-window both show
6085 the current buffer, this suffers from the problem that the
6086 current PT is the window-point of the current-selected-window,
6087 while the final PT is the point of the final-selected-window, so
6088 this copy from one PT to the other would end up moving the
6089 window-point of the final-selected-window to the window-point of
6090 the current-selected-window. So we have to be careful which
6091 point of the current-buffer we copy into old_point. */
6092 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
)
6093 && WINDOWP (selected_window
)
6094 && EQ (XWINDOW (selected_window
)->buffer
, new_current_buffer
)
6095 && !EQ (selected_window
, data
->current_window
))
6096 old_point
= XMARKER (XWINDOW (data
->current_window
)->pointm
)->charpos
;
6100 /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of
6101 point in new_current_buffer as of the last time this buffer was
6102 used. This can be non-deterministic since it can be changed by
6103 things like jit-lock by mere temporary selection of some random
6104 window that happens to show this buffer.
6105 So if possible we want this arbitrary choice of "which point" to
6106 be the one from the to-be-selected-window so as to prevent this
6107 window's cursor from being copied from another window. */
6108 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
)
6109 /* If current_window = selected_window, its point is in BUF_PT. */
6110 && !EQ (selected_window
, data
->current_window
))
6111 old_point
= XMARKER (XWINDOW (data
->current_window
)->pointm
)->charpos
;
6113 old_point
= BUF_PT (XBUFFER (new_current_buffer
));
6116 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
6119 /* If f is a dead frame, don't bother rebuilding its window tree.
6120 However, there is other stuff we should still try to do below. */
6121 if (FRAME_LIVE_P (f
))
6123 register struct window
*w
;
6124 register struct saved_window
*p
;
6125 struct window
*root_window
;
6126 struct window
**leaf_windows
;
6130 /* If the frame has been resized since this window configuration was
6131 made, we change the frame to the size specified in the
6132 configuration, restore the configuration, and then resize it
6133 back. We keep track of the prevailing height in these variables. */
6134 int previous_frame_lines
= FRAME_LINES (f
);
6135 int previous_frame_cols
= FRAME_COLS (f
);
6136 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
6137 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
6139 /* The mouse highlighting code could get screwed up
6140 if it runs during this. */
6143 if (data
->frame_lines
!= previous_frame_lines
6144 || data
->frame_cols
!= previous_frame_cols
)
6145 change_frame_size (f
, data
->frame_lines
,
6146 data
->frame_cols
, 0, 0, 0);
6147 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
6148 if (data
->frame_menu_bar_lines
6149 != previous_frame_menu_bar_lines
)
6150 x_set_menu_bar_lines (f
, make_number (data
->frame_menu_bar_lines
),
6152 #ifdef HAVE_WINDOW_SYSTEM
6153 if (data
->frame_tool_bar_lines
6154 != previous_frame_tool_bar_lines
)
6155 x_set_tool_bar_lines (f
, make_number (data
->frame_tool_bar_lines
),
6160 /* "Swap out" point from the selected window's buffer
6161 into the window itself. (Normally the pointm of the selected
6162 window holds garbage.) We do this now, before
6163 restoring the window contents, and prevent it from
6164 being done later on when we select a new window. */
6165 if (! NILP (XWINDOW (selected_window
)->buffer
))
6167 w
= XWINDOW (selected_window
);
6168 set_marker_both (w
->pointm
,
6170 BUF_PT (XBUFFER (w
->buffer
)),
6171 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
6174 windows_or_buffers_changed
++;
6175 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
6177 /* Problem: Freeing all matrices and later allocating them again
6178 is a serious redisplay flickering problem. What we would
6179 really like to do is to free only those matrices not reused
6181 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
6183 = (struct window
**) alloca (count_windows (root_window
)
6184 * sizeof (struct window
*));
6185 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
6188 Mark all windows now on frame as "deleted".
6189 Restoring the new configuration "undeletes" any that are in it.
6191 Save their current buffers in their height fields, since we may
6192 need it later, if a buffer saved in the configuration is now
6194 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
6196 for (k
= 0; k
< saved_windows
->size
; k
++)
6198 p
= SAVED_WINDOW_N (saved_windows
, k
);
6199 w
= XWINDOW (p
->window
);
6202 if (!NILP (p
->parent
))
6203 w
->parent
= SAVED_WINDOW_N (saved_windows
,
6204 XFASTINT (p
->parent
))->window
;
6208 if (!NILP (p
->prev
))
6210 w
->prev
= SAVED_WINDOW_N (saved_windows
,
6211 XFASTINT (p
->prev
))->window
;
6212 XWINDOW (w
->prev
)->next
= p
->window
;
6217 if (!NILP (w
->parent
))
6219 if (EQ (p
->total_cols
, XWINDOW (w
->parent
)->total_cols
))
6221 XWINDOW (w
->parent
)->vchild
= p
->window
;
6222 XWINDOW (w
->parent
)->hchild
= Qnil
;
6226 XWINDOW (w
->parent
)->hchild
= p
->window
;
6227 XWINDOW (w
->parent
)->vchild
= Qnil
;
6232 /* If we squirreled away the buffer in the window's height,
6234 if (BUFFERP (w
->total_lines
))
6235 w
->buffer
= w
->total_lines
;
6236 w
->left_col
= p
->left_col
;
6237 w
->top_line
= p
->top_line
;
6238 w
->total_cols
= p
->total_cols
;
6239 w
->total_lines
= p
->total_lines
;
6240 w
->hscroll
= p
->hscroll
;
6241 w
->min_hscroll
= p
->min_hscroll
;
6242 w
->display_table
= p
->display_table
;
6243 w
->orig_top_line
= p
->orig_top_line
;
6244 w
->orig_total_lines
= p
->orig_total_lines
;
6245 w
->left_margin_cols
= p
->left_margin_cols
;
6246 w
->right_margin_cols
= p
->right_margin_cols
;
6247 w
->left_fringe_width
= p
->left_fringe_width
;
6248 w
->right_fringe_width
= p
->right_fringe_width
;
6249 w
->fringes_outside_margins
= p
->fringes_outside_margins
;
6250 w
->scroll_bar_width
= p
->scroll_bar_width
;
6251 w
->vertical_scroll_bar_type
= p
->vertical_scroll_bar_type
;
6252 w
->dedicated
= p
->dedicated
;
6253 w
->resize_proportionally
= p
->resize_proportionally
;
6254 XSETFASTINT (w
->last_modified
, 0);
6255 XSETFASTINT (w
->last_overlay_modified
, 0);
6257 /* Reinstall the saved buffer and pointers into it. */
6258 if (NILP (p
->buffer
))
6259 w
->buffer
= p
->buffer
;
6262 if (!NILP (XBUFFER (p
->buffer
)->name
))
6263 /* If saved buffer is alive, install it. */
6265 w
->buffer
= p
->buffer
;
6266 w
->start_at_line_beg
= p
->start_at_line_beg
;
6267 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
6268 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
6269 Fset_marker (XBUFFER (w
->buffer
)->mark
,
6270 p
->mark
, w
->buffer
);
6272 /* As documented in Fcurrent_window_configuration, don't
6273 restore the location of point in the buffer which was
6274 current when the window configuration was recorded. */
6275 if (!EQ (p
->buffer
, new_current_buffer
)
6276 && XBUFFER (p
->buffer
) == current_buffer
)
6277 Fgoto_char (w
->pointm
);
6279 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
6280 /* Else unless window has a live buffer, get one. */
6282 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
6283 /* This will set the markers to beginning of visible
6285 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
6286 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
6287 w
->start_at_line_beg
= Qt
;
6290 /* Keeping window's old buffer; make sure the markers
6293 /* Set window markers at start of visible range. */
6294 if (XMARKER (w
->start
)->buffer
== 0)
6295 set_marker_restricted (w
->start
, make_number (0),
6297 if (XMARKER (w
->pointm
)->buffer
== 0)
6298 set_marker_restricted_both (w
->pointm
, w
->buffer
,
6299 BUF_PT (XBUFFER (w
->buffer
)),
6300 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
6301 w
->start_at_line_beg
= Qt
;
6306 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
6307 /* Prevent "swapping out point" in the old selected window
6308 using the buffer that has been restored into it.
6309 We already swapped out point that from that window's old buffer. */
6310 selected_window
= Qnil
;
6312 /* Arrange *not* to restore point in the buffer that was
6313 current when the window configuration was saved. */
6314 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
))
6315 set_marker_restricted (XWINDOW (data
->current_window
)->pointm
,
6316 make_number (old_point
),
6317 XWINDOW (data
->current_window
)->buffer
);
6319 Fselect_window (data
->current_window
, Qnil
);
6320 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
6323 if (NILP (data
->focus_frame
)
6324 || (FRAMEP (data
->focus_frame
)
6325 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
6326 Fredirect_frame_focus (frame
, data
->focus_frame
);
6328 #if 0 /* I don't understand why this is needed, and it causes problems
6329 when the frame's old selected window has been deleted. */
6330 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
6331 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
6335 /* Set the screen height to the value it had before this function. */
6336 if (previous_frame_lines
!= FRAME_LINES (f
)
6337 || previous_frame_cols
!= FRAME_COLS (f
))
6338 change_frame_size (f
, previous_frame_lines
, previous_frame_cols
,
6340 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
6341 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
6342 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
6344 #ifdef HAVE_WINDOW_SYSTEM
6345 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
6346 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
6351 /* Now, free glyph matrices in windows that were not reused. */
6352 for (i
= n
= 0; i
< n_leaf_windows
; ++i
)
6354 if (NILP (leaf_windows
[i
]->buffer
))
6356 /* Assert it's not reused as a combination. */
6357 xassert (NILP (leaf_windows
[i
]->hchild
)
6358 && NILP (leaf_windows
[i
]->vchild
));
6359 free_window_matrices (leaf_windows
[i
]);
6361 else if (EQ (leaf_windows
[i
]->buffer
, new_current_buffer
))
6369 /* Fselect_window will have made f the selected frame, so we
6370 reselect the proper frame here. Fhandle_switch_frame will change the
6371 selected window too, but that doesn't make the call to
6372 Fselect_window above totally superfluous; it still sets f's
6374 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
6375 do_switch_frame (data
->selected_frame
, 0, 0, Qnil
);
6377 run_window_configuration_change_hook (f
);
6380 if (!NILP (new_current_buffer
))
6381 Fset_buffer (new_current_buffer
);
6383 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
6384 minibuf_selected_window
= data
->minibuf_selected_window
;
6386 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
6389 /* Mark all windows now on frame as deleted
6390 by setting their buffers to nil. */
6393 delete_all_subwindows (w
)
6394 register struct window
*w
;
6396 if (!NILP (w
->next
))
6397 delete_all_subwindows (XWINDOW (w
->next
));
6398 if (!NILP (w
->vchild
))
6399 delete_all_subwindows (XWINDOW (w
->vchild
));
6400 if (!NILP (w
->hchild
))
6401 delete_all_subwindows (XWINDOW (w
->hchild
));
6403 w
->total_lines
= w
->buffer
; /* See Fset_window_configuration for excuse. */
6405 if (!NILP (w
->buffer
))
6408 /* We set all three of these fields to nil, to make sure that we can
6409 distinguish this dead window from any live window. Live leaf
6410 windows will have buffer set, and combination windows will have
6411 vchild or hchild set. */
6416 Vwindow_list
= Qnil
;
6420 count_windows (window
)
6421 register struct window
*window
;
6423 register int count
= 1;
6424 if (!NILP (window
->next
))
6425 count
+= count_windows (XWINDOW (window
->next
));
6426 if (!NILP (window
->vchild
))
6427 count
+= count_windows (XWINDOW (window
->vchild
));
6428 if (!NILP (window
->hchild
))
6429 count
+= count_windows (XWINDOW (window
->hchild
));
6434 /* Fill vector FLAT with leaf windows under W, starting at index I.
6435 Value is last index + 1. */
6438 get_leaf_windows (w
, flat
, i
)
6440 struct window
**flat
;
6445 if (!NILP (w
->hchild
))
6446 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
6447 else if (!NILP (w
->vchild
))
6448 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
6452 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
6459 /* Return a pointer to the glyph W's physical cursor is on. Value is
6460 null if W's current matrix is invalid, so that no meaningfull glyph
6464 get_phys_cursor_glyph (w
)
6467 struct glyph_row
*row
;
6468 struct glyph
*glyph
;
6470 if (w
->phys_cursor
.vpos
>= 0
6471 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
6472 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
6474 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
6475 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
6484 save_window_save (window
, vector
, i
)
6486 struct Lisp_Vector
*vector
;
6489 register struct saved_window
*p
;
6490 register struct window
*w
;
6491 register Lisp_Object tem
;
6493 for (;!NILP (window
); window
= w
->next
)
6495 p
= SAVED_WINDOW_N (vector
, i
);
6496 w
= XWINDOW (window
);
6498 XSETFASTINT (w
->temslot
, i
); i
++;
6500 p
->buffer
= w
->buffer
;
6501 p
->left_col
= w
->left_col
;
6502 p
->top_line
= w
->top_line
;
6503 p
->total_cols
= w
->total_cols
;
6504 p
->total_lines
= w
->total_lines
;
6505 p
->hscroll
= w
->hscroll
;
6506 p
->min_hscroll
= w
->min_hscroll
;
6507 p
->display_table
= w
->display_table
;
6508 p
->orig_top_line
= w
->orig_top_line
;
6509 p
->orig_total_lines
= w
->orig_total_lines
;
6510 p
->left_margin_cols
= w
->left_margin_cols
;
6511 p
->right_margin_cols
= w
->right_margin_cols
;
6512 p
->left_fringe_width
= w
->left_fringe_width
;
6513 p
->right_fringe_width
= w
->right_fringe_width
;
6514 p
->fringes_outside_margins
= w
->fringes_outside_margins
;
6515 p
->scroll_bar_width
= w
->scroll_bar_width
;
6516 p
->vertical_scroll_bar_type
= w
->vertical_scroll_bar_type
;
6517 p
->dedicated
= w
->dedicated
;
6518 p
->resize_proportionally
= w
->resize_proportionally
;
6519 if (!NILP (w
->buffer
))
6521 /* Save w's value of point in the window configuration.
6522 If w is the selected window, then get the value of point
6523 from the buffer; pointm is garbage in the selected window. */
6524 if (EQ (window
, selected_window
))
6526 p
->pointm
= Fmake_marker ();
6527 set_marker_both (p
->pointm
, w
->buffer
,
6528 BUF_PT (XBUFFER (w
->buffer
)),
6529 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
6532 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
6534 p
->start
= Fcopy_marker (w
->start
, Qnil
);
6535 p
->start_at_line_beg
= w
->start_at_line_beg
;
6537 tem
= XBUFFER (w
->buffer
)->mark
;
6538 p
->mark
= Fcopy_marker (tem
, Qnil
);
6545 p
->start_at_line_beg
= Qnil
;
6548 if (NILP (w
->parent
))
6551 p
->parent
= XWINDOW (w
->parent
)->temslot
;
6556 p
->prev
= XWINDOW (w
->prev
)->temslot
;
6558 if (!NILP (w
->vchild
))
6559 i
= save_window_save (w
->vchild
, vector
, i
);
6560 if (!NILP (w
->hchild
))
6561 i
= save_window_save (w
->hchild
, vector
, i
);
6567 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
6568 Scurrent_window_configuration
, 0, 1, 0,
6569 doc
: /* Return an object representing the current window configuration of FRAME.
6570 If FRAME is nil or omitted, use the selected frame.
6571 This describes the number of windows, their sizes and current buffers,
6572 and for each displayed buffer, where display starts, and the positions of
6573 point and mark. An exception is made for point in the current buffer:
6574 its value is -not- saved.
6575 This also records the currently selected frame, and FRAME's focus
6576 redirection (see `redirect-frame-focus'). */)
6580 register Lisp_Object tem
;
6581 register int n_windows
;
6582 register struct save_window_data
*data
;
6587 frame
= selected_frame
;
6588 CHECK_LIVE_FRAME (frame
);
6591 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
6592 data
= ALLOCATE_PSEUDOVECTOR (struct save_window_data
, frame_cols
,
6593 PVEC_WINDOW_CONFIGURATION
);
6595 data
->frame_cols
= FRAME_COLS (f
);
6596 data
->frame_lines
= FRAME_LINES (f
);
6597 data
->frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
6598 data
->frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
6599 data
->selected_frame
= selected_frame
;
6600 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
6601 XSETBUFFER (data
->current_buffer
, current_buffer
);
6602 data
->minibuf_scroll_window
= minibuf_level
> 0 ? Vminibuf_scroll_window
: Qnil
;
6603 data
->minibuf_selected_window
= minibuf_level
> 0 ? minibuf_selected_window
: Qnil
;
6604 data
->root_window
= FRAME_ROOT_WINDOW (f
);
6605 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
6606 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
6607 data
->saved_windows
= tem
;
6608 for (i
= 0; i
< n_windows
; i
++)
6609 XVECTOR (tem
)->contents
[i
]
6610 = Fmake_vector (make_number (VECSIZE (struct saved_window
)), Qnil
);
6611 save_window_save (FRAME_ROOT_WINDOW (f
), XVECTOR (tem
), 0);
6612 XSETWINDOW_CONFIGURATION (tem
, data
);
6616 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
6618 doc
: /* Execute BODY, preserving window sizes and contents.
6619 Return the value of the last form in BODY.
6620 Restore which buffer appears in which window, where display starts,
6621 and the value of point and mark for each window.
6622 Also restore the choice of selected window.
6623 Also restore which buffer is current.
6624 Does not restore the value of point in current buffer.
6625 usage: (save-window-excursion BODY...) */)
6629 register Lisp_Object val
;
6630 register int count
= SPECPDL_INDEX ();
6632 record_unwind_protect (Fset_window_configuration
,
6633 Fcurrent_window_configuration (Qnil
));
6634 val
= Fprogn (args
);
6635 return unbind_to (count
, val
);
6640 /***********************************************************************
6642 ***********************************************************************/
6648 Lisp_Object tail
= Qnil
;
6649 Lisp_Object result
= Qnil
;
6656 if (!NILP (w
->hchild
))
6657 wn
= Fcons (Qnil
, Fcons (Fwindow_edges (wn
),
6658 window_tree (XWINDOW (w
->hchild
))));
6659 else if (!NILP (w
->vchild
))
6660 wn
= Fcons (Qt
, Fcons (Fwindow_edges (wn
),
6661 window_tree (XWINDOW (w
->vchild
))));
6665 result
= tail
= Fcons (wn
, Qnil
);
6669 XSETCDR (tail
, Fcons (wn
, Qnil
));
6673 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
6681 DEFUN ("window-tree", Fwindow_tree
, Swindow_tree
,
6683 doc
: /* Return the window tree for frame FRAME.
6685 The return value is a list of the form (ROOT MINI), where ROOT
6686 represents the window tree of the frame's root window, and MINI
6687 is the frame's minibuffer window.
6689 If the root window is not split, ROOT is the root window itself.
6690 Otherwise, ROOT is a list (DIR EDGES W1 W2 ...) where DIR is nil for a
6691 horizontal split, and t for a vertical split, EDGES gives the combined
6692 size and position of the subwindows in the split, and the rest of the
6693 elements are the subwindows in the split. Each of the subwindows may
6694 again be a window or a list representing a window split, and so on.
6695 EDGES is a list \(LEFT TOP RIGHT BOTTOM) as returned by `window-edges'.
6697 If FRAME is nil or omitted, return information on the currently
6705 frame
= selected_frame
;
6707 CHECK_FRAME (frame
);
6710 if (!FRAME_LIVE_P (f
))
6713 return window_tree (XWINDOW (FRAME_ROOT_WINDOW (f
)));
6717 /***********************************************************************
6719 ***********************************************************************/
6721 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
6723 doc
: /* Set width of marginal areas of window WINDOW.
6724 If WINDOW is nil, set margins of the currently selected window.
6725 Second arg LEFT-WIDTH specifies the number of character cells to
6726 reserve for the left marginal area. Optional third arg RIGHT-WIDTH
6727 does the same for the right marginal area. A nil width parameter
6728 means no margin. */)
6729 (window
, left_width
, right_width
)
6730 Lisp_Object window
, left_width
, right_width
;
6732 struct window
*w
= decode_window (window
);
6734 /* Translate negative or zero widths to nil.
6735 Margins that are too wide have to be checked elsewhere. */
6737 if (!NILP (left_width
))
6739 CHECK_NUMBER (left_width
);
6740 if (XINT (left_width
) <= 0)
6744 if (!NILP (right_width
))
6746 CHECK_NUMBER (right_width
);
6747 if (XINT (right_width
) <= 0)
6751 if (!EQ (w
->left_margin_cols
, left_width
)
6752 || !EQ (w
->right_margin_cols
, right_width
))
6754 w
->left_margin_cols
= left_width
;
6755 w
->right_margin_cols
= right_width
;
6757 adjust_window_margins (w
);
6759 ++windows_or_buffers_changed
;
6760 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
6767 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
6769 doc
: /* Get width of marginal areas of window WINDOW.
6770 If WINDOW is omitted or nil, use the currently selected window.
6771 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).
6772 If a marginal area does not exist, its width will be returned
6777 struct window
*w
= decode_window (window
);
6778 return Fcons (w
->left_margin_cols
, w
->right_margin_cols
);
6783 /***********************************************************************
6785 ***********************************************************************/
6787 DEFUN ("set-window-fringes", Fset_window_fringes
, Sset_window_fringes
,
6789 doc
: /* Set the fringe widths of window WINDOW.
6790 If WINDOW is nil, set the fringe widths of the currently selected
6792 Second arg LEFT-WIDTH specifies the number of pixels to reserve for
6793 the left fringe. Optional third arg RIGHT-WIDTH specifies the right
6794 fringe width. If a fringe width arg is nil, that means to use the
6795 frame's default fringe width. Default fringe widths can be set with
6796 the command `set-fringe-style'.
6797 If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes
6798 outside of the display margins. By default, fringes are drawn between
6799 display marginal areas and the text area. */)
6800 (window
, left_width
, right_width
, outside_margins
)
6801 Lisp_Object window
, left_width
, right_width
, outside_margins
;
6803 struct window
*w
= decode_window (window
);
6805 if (!NILP (left_width
))
6806 CHECK_NATNUM (left_width
);
6807 if (!NILP (right_width
))
6808 CHECK_NATNUM (right_width
);
6810 /* Do nothing on a tty. */
6811 if (FRAME_WINDOW_P (WINDOW_XFRAME (w
))
6812 && (!EQ (w
->left_fringe_width
, left_width
)
6813 || !EQ (w
->right_fringe_width
, right_width
)
6814 || !EQ (w
->fringes_outside_margins
, outside_margins
)))
6816 w
->left_fringe_width
= left_width
;
6817 w
->right_fringe_width
= right_width
;
6818 w
->fringes_outside_margins
= outside_margins
;
6820 adjust_window_margins (w
);
6822 clear_glyph_matrix (w
->current_matrix
);
6823 w
->window_end_valid
= Qnil
;
6825 ++windows_or_buffers_changed
;
6826 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
6833 DEFUN ("window-fringes", Fwindow_fringes
, Swindow_fringes
,
6835 doc
: /* Get width of fringes of window WINDOW.
6836 If WINDOW is omitted or nil, use the currently selected window.
6837 Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
6841 struct window
*w
= decode_window (window
);
6843 return Fcons (make_number (WINDOW_LEFT_FRINGE_WIDTH (w
)),
6844 Fcons (make_number (WINDOW_RIGHT_FRINGE_WIDTH (w
)),
6845 Fcons ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
6846 ? Qt
: Qnil
), Qnil
)));
6851 /***********************************************************************
6853 ***********************************************************************/
6855 DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars
, Sset_window_scroll_bars
,
6857 doc
: /* Set width and type of scroll bars of window WINDOW.
6858 If window is nil, set scroll bars of the currently selected window.
6859 Second parameter WIDTH specifies the pixel width for the scroll bar;
6860 this is automatically adjusted to a multiple of the frame column width.
6861 Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
6862 bar: left, right, or nil.
6863 If WIDTH is nil, use the frame's scroll-bar width.
6864 If VERTICAL-TYPE is t, use the frame's scroll-bar type.
6865 Fourth parameter HORIZONTAL-TYPE is currently unused. */)
6866 (window
, width
, vertical_type
, horizontal_type
)
6867 Lisp_Object window
, width
, vertical_type
, horizontal_type
;
6869 struct window
*w
= decode_window (window
);
6873 CHECK_NATNUM (width
);
6875 if (XINT (width
) == 0)
6876 vertical_type
= Qnil
;
6879 if (!(NILP (vertical_type
)
6880 || EQ (vertical_type
, Qleft
)
6881 || EQ (vertical_type
, Qright
)
6882 || EQ (vertical_type
, Qt
)))
6883 error ("Invalid type of vertical scroll bar");
6885 if (!EQ (w
->scroll_bar_width
, width
)
6886 || !EQ (w
->vertical_scroll_bar_type
, vertical_type
))
6888 w
->scroll_bar_width
= width
;
6889 w
->vertical_scroll_bar_type
= vertical_type
;
6891 adjust_window_margins (w
);
6893 clear_glyph_matrix (w
->current_matrix
);
6894 w
->window_end_valid
= Qnil
;
6896 ++windows_or_buffers_changed
;
6897 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
6904 DEFUN ("window-scroll-bars", Fwindow_scroll_bars
, Swindow_scroll_bars
,
6906 doc
: /* Get width and type of scroll bars of window WINDOW.
6907 If WINDOW is omitted or nil, use the currently selected window.
6908 Value is a list of the form (WIDTH COLS VERTICAL-TYPE HORIZONTAL-TYPE).
6909 If WIDTH is nil or TYPE is t, the window is using the frame's corresponding
6914 struct window
*w
= decode_window (window
);
6915 return Fcons (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
)
6916 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
)
6917 : WINDOW_SCROLL_BAR_AREA_WIDTH (w
))),
6918 Fcons (make_number (WINDOW_SCROLL_BAR_COLS (w
)),
6919 Fcons (w
->vertical_scroll_bar_type
,
6920 Fcons (Qnil
, Qnil
))));
6925 /***********************************************************************
6927 ***********************************************************************/
6929 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 2, 0,
6930 doc
: /* Return the amount by which WINDOW is scrolled vertically.
6931 Use the selected window if WINDOW is nil or omitted.
6932 Normally, value is a multiple of the canonical character height of WINDOW;
6933 optional second arg PIXELS-P means value is measured in pixels. */)
6935 Lisp_Object window
, pixels_p
;
6942 window
= selected_window
;
6944 CHECK_WINDOW (window
);
6945 w
= XWINDOW (window
);
6946 f
= XFRAME (w
->frame
);
6948 if (FRAME_WINDOW_P (f
))
6949 result
= (NILP (pixels_p
)
6950 ? FRAME_CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
)
6951 : make_number (-w
->vscroll
));
6953 result
= make_number (0);
6958 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
6960 doc
: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL.
6961 WINDOW nil means use the selected window. Normally, VSCROLL is a
6962 non-negative multiple of the canonical character height of WINDOW;
6963 optional third arg PIXELS-P non-nil means that VSCROLL is in pixels.
6964 If PIXELS-P is nil, VSCROLL may have to be rounded so that it
6965 corresponds to an integral number of pixels. The return value is the
6966 result of this rounding.
6967 If PIXELS-P is non-nil, the return value is VSCROLL. */)
6968 (window
, vscroll
, pixels_p
)
6969 Lisp_Object window
, vscroll
, pixels_p
;
6975 window
= selected_window
;
6977 CHECK_WINDOW (window
);
6978 CHECK_NUMBER_OR_FLOAT (vscroll
);
6980 w
= XWINDOW (window
);
6981 f
= XFRAME (w
->frame
);
6983 if (FRAME_WINDOW_P (f
))
6985 int old_dy
= w
->vscroll
;
6987 w
->vscroll
= - (NILP (pixels_p
)
6988 ? FRAME_LINE_HEIGHT (f
) * XFLOATINT (vscroll
)
6989 : XFLOATINT (vscroll
));
6990 w
->vscroll
= min (w
->vscroll
, 0);
6992 if (w
->vscroll
!= old_dy
)
6994 /* Adjust glyph matrix of the frame if the virtual display
6995 area becomes larger than before. */
6996 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
6999 /* Prevent redisplay shortcuts. */
7000 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
7004 return Fwindow_vscroll (window
, pixels_p
);
7008 /* Call FN for all leaf windows on frame F. FN is called with the
7009 first argument being a pointer to the leaf window, and with
7010 additional argument USER_DATA. Stops when FN returns 0. */
7013 foreach_window (f
, fn
, user_data
)
7015 int (* fn
) P_ ((struct window
*, void *));
7018 /* delete_frame may set FRAME_ROOT_WINDOW (f) to Qnil. */
7019 if (WINDOWP (FRAME_ROOT_WINDOW (f
)))
7020 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, user_data
);
7024 /* Helper function for foreach_window. Call FN for all leaf windows
7025 reachable from W. FN is called with the first argument being a
7026 pointer to the leaf window, and with additional argument USER_DATA.
7027 Stop when FN returns 0. Value is 0 if stopped by FN. */
7030 foreach_window_1 (w
, fn
, user_data
)
7032 int (* fn
) P_ ((struct window
*, void *));
7037 for (cont
= 1; w
&& cont
;)
7039 if (!NILP (w
->hchild
))
7040 cont
= foreach_window_1 (XWINDOW (w
->hchild
), fn
, user_data
);
7041 else if (!NILP (w
->vchild
))
7042 cont
= foreach_window_1 (XWINDOW (w
->vchild
), fn
, user_data
);
7044 cont
= fn (w
, user_data
);
7046 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
7053 /* Freeze or unfreeze the window start of W unless it is a
7054 mini-window or the selected window. FREEZE_P non-null means freeze
7055 the window start. */
7058 freeze_window_start (w
, freeze_p
)
7062 if (MINI_WINDOW_P (w
)
7063 || (WINDOWP (selected_window
) /* Can be nil in corner cases. */
7064 && (w
== XWINDOW (selected_window
)
7065 || (MINI_WINDOW_P (XWINDOW (selected_window
))
7066 && ! NILP (Vminibuf_scroll_window
)
7067 && w
== XWINDOW (Vminibuf_scroll_window
)))))
7070 w
->frozen_window_start_p
= freeze_p
!= NULL
;
7075 /* Freeze or unfreeze the window starts of all leaf windows on frame
7076 F, except the selected window and a mini-window. FREEZE_P non-zero
7077 means freeze the window start. */
7080 freeze_window_starts (f
, freeze_p
)
7084 foreach_window (f
, freeze_window_start
, (void *) (freeze_p
? f
: 0));
7088 /***********************************************************************
7090 ***********************************************************************/
7092 /* Return 1 if window configurations C1 and C2
7093 describe the same state of affairs. This is used by Fequal. */
7096 compare_window_configurations (c1
, c2
, ignore_positions
)
7098 int ignore_positions
;
7100 register struct save_window_data
*d1
, *d2
;
7101 struct Lisp_Vector
*sw1
, *sw2
;
7104 CHECK_WINDOW_CONFIGURATION (c1
);
7105 CHECK_WINDOW_CONFIGURATION (c2
);
7107 d1
= (struct save_window_data
*) XVECTOR (c1
);
7108 d2
= (struct save_window_data
*) XVECTOR (c2
);
7109 sw1
= XVECTOR (d1
->saved_windows
);
7110 sw2
= XVECTOR (d2
->saved_windows
);
7112 if (d1
->frame_cols
!= d2
->frame_cols
)
7114 if (d1
->frame_lines
!= d2
->frame_lines
)
7116 if (d1
->frame_menu_bar_lines
!= d2
->frame_menu_bar_lines
)
7118 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
7120 /* Don't compare the current_window field directly.
7121 Instead see w1_is_current and w2_is_current, below. */
7122 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
7124 if (! ignore_positions
)
7126 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
7128 if (! EQ (d1
->minibuf_selected_window
, d2
->minibuf_selected_window
))
7131 /* Don't compare the root_window field.
7132 We don't require the two configurations
7133 to use the same window object,
7134 and the two root windows must be equivalent
7135 if everything else compares equal. */
7136 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
7139 /* Verify that the two confis have the same number of windows. */
7140 if (sw1
->size
!= sw2
->size
)
7143 for (i
= 0; i
< sw1
->size
; i
++)
7145 struct saved_window
*p1
, *p2
;
7146 int w1_is_current
, w2_is_current
;
7148 p1
= SAVED_WINDOW_N (sw1
, i
);
7149 p2
= SAVED_WINDOW_N (sw2
, i
);
7151 /* Verify that the current windows in the two
7152 configurations correspond to each other. */
7153 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
7154 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
7156 if (w1_is_current
!= w2_is_current
)
7159 /* Verify that the corresponding windows do match. */
7160 if (! EQ (p1
->buffer
, p2
->buffer
))
7162 if (! EQ (p1
->left_col
, p2
->left_col
))
7164 if (! EQ (p1
->top_line
, p2
->top_line
))
7166 if (! EQ (p1
->total_cols
, p2
->total_cols
))
7168 if (! EQ (p1
->total_lines
, p2
->total_lines
))
7170 if (! EQ (p1
->display_table
, p2
->display_table
))
7172 if (! EQ (p1
->parent
, p2
->parent
))
7174 if (! EQ (p1
->prev
, p2
->prev
))
7176 if (! ignore_positions
)
7178 if (! EQ (p1
->hscroll
, p2
->hscroll
))
7180 if (!EQ (p1
->min_hscroll
, p2
->min_hscroll
))
7182 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
7184 if (NILP (Fequal (p1
->start
, p2
->start
)))
7186 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
7188 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
7191 if (! EQ (p1
->left_margin_cols
, p2
->left_margin_cols
))
7193 if (! EQ (p1
->right_margin_cols
, p2
->right_margin_cols
))
7195 if (! EQ (p1
->left_fringe_width
, p2
->left_fringe_width
))
7197 if (! EQ (p1
->right_fringe_width
, p2
->right_fringe_width
))
7199 if (! EQ (p1
->fringes_outside_margins
, p2
->fringes_outside_margins
))
7201 if (! EQ (p1
->scroll_bar_width
, p2
->scroll_bar_width
))
7203 if (! EQ (p1
->vertical_scroll_bar_type
, p2
->vertical_scroll_bar_type
))
7210 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
7211 Scompare_window_configurations
, 2, 2, 0,
7212 doc
: /* Compare two window configurations as regards the structure of windows.
7213 This function ignores details such as the values of point and mark
7214 and scrolling positions. */)
7218 if (compare_window_configurations (x
, y
, 1))
7226 struct frame
*f
= make_initial_frame ();
7227 XSETFRAME (selected_frame
, f
);
7228 Vterminal_frame
= selected_frame
;
7229 minibuf_window
= f
->minibuffer_window
;
7230 selected_window
= f
->selected_window
;
7231 last_nonminibuf_frame
= f
;
7233 window_initialized
= 1;
7239 Vwindow_list
= Qnil
;
7245 Qscroll_up
= intern_c_string ("scroll-up");
7246 staticpro (&Qscroll_up
);
7248 Qscroll_down
= intern_c_string ("scroll-down");
7249 staticpro (&Qscroll_down
);
7251 Qscroll_command
= intern_c_string ("scroll-command");
7252 staticpro (&Qscroll_command
);
7254 Fput (Qscroll_up
, Qscroll_command
, Qt
);
7255 Fput (Qscroll_down
, Qscroll_command
, Qt
);
7257 Qwindow_size_fixed
= intern_c_string ("window-size-fixed");
7258 staticpro (&Qwindow_size_fixed
);
7259 Fset (Qwindow_size_fixed
, Qnil
);
7261 staticpro (&Qwindow_configuration_change_hook
);
7262 Qwindow_configuration_change_hook
7263 = intern_c_string ("window-configuration-change-hook");
7265 Qwindowp
= intern_c_string ("windowp");
7266 staticpro (&Qwindowp
);
7268 Qwindow_configuration_p
= intern_c_string ("window-configuration-p");
7269 staticpro (&Qwindow_configuration_p
);
7271 Qwindow_live_p
= intern_c_string ("window-live-p");
7272 staticpro (&Qwindow_live_p
);
7274 Qdisplay_buffer
= intern_c_string ("display-buffer");
7275 staticpro (&Qdisplay_buffer
);
7277 Qtemp_buffer_show_hook
= intern_c_string ("temp-buffer-show-hook");
7278 staticpro (&Qtemp_buffer_show_hook
);
7280 staticpro (&Vwindow_list
);
7282 minibuf_selected_window
= Qnil
;
7283 staticpro (&minibuf_selected_window
);
7285 window_scroll_pixel_based_preserve_x
= -1;
7286 window_scroll_pixel_based_preserve_y
= -1;
7287 window_scroll_preserve_hpos
= -1;
7288 window_scroll_preserve_vpos
= -1;
7290 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
7291 doc
: /* Non-nil means call as function to display a help buffer.
7292 The function is called with one argument, the buffer to be displayed.
7293 Used by `with-output-to-temp-buffer'.
7294 If this function is used, then it must do the entire job of showing
7295 the buffer; `temp-buffer-show-hook' is not run unless this function runs it. */);
7296 Vtemp_buffer_show_function
= Qnil
;
7298 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
7299 doc
: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */);
7300 Vminibuf_scroll_window
= Qnil
;
7302 DEFVAR_BOOL ("mode-line-in-non-selected-windows", &mode_line_in_non_selected_windows
,
7303 doc
: /* Non-nil means to use `mode-line-inactive' face in non-selected windows.
7304 If the minibuffer is active, the `minibuffer-scroll-window' mode line
7305 is displayed in the `mode-line' face. */);
7306 mode_line_in_non_selected_windows
= 1;
7308 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
7309 doc
: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. */);
7310 Vother_window_scroll_buffer
= Qnil
;
7312 DEFVAR_BOOL ("auto-window-vscroll", &auto_window_vscroll_p
,
7313 doc
: /* *Non-nil means to automatically adjust `window-vscroll' to view tall lines. */);
7314 auto_window_vscroll_p
= 1;
7316 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
7317 doc
: /* *Number of lines of continuity when scrolling by screenfuls. */);
7318 next_screen_context_lines
= 2;
7320 DEFVAR_INT ("window-min-height", &window_min_height
,
7321 doc
: /* Allow deleting windows less than this tall.
7322 The value is measured in line units. If a window wants a modeline it
7323 is counted as one line.
7325 Emacs honors settings of this variable when enlarging or shrinking
7326 windows vertically. A value less than 1 is invalid. */);
7327 window_min_height
= 4;
7329 DEFVAR_INT ("window-min-width", &window_min_width
,
7330 doc
: /* Allow deleting windows less than this wide.
7331 The value is measured in characters and includes any fringes or
7334 Emacs honors settings of this variable when enlarging or shrinking
7335 windows horizontally. A value less than 2 is invalid. */);
7336 window_min_width
= 10;
7338 DEFVAR_LISP ("scroll-preserve-screen-position",
7339 &Vscroll_preserve_screen_position
,
7340 doc
: /* *Controls if scroll commands move point to keep its screen position unchanged.
7341 A value of nil means point does not keep its screen position except
7342 at the scroll margin or window boundary respectively.
7343 A value of t means point keeps its screen position if the scroll
7344 command moved it vertically out of the window, e.g. when scrolling
7346 Any other value means point always keeps its screen position.
7347 Scroll commands should have the `scroll-command' property
7348 on their symbols to be controlled by this variable. */);
7349 Vscroll_preserve_screen_position
= Qnil
;
7351 DEFVAR_LISP ("window-point-insertion-type", &Vwindow_point_insertion_type
,
7352 doc
: /* Type of marker to use for `window-point'. */);
7353 Vwindow_point_insertion_type
= Qnil
;
7355 DEFVAR_LISP ("window-configuration-change-hook",
7356 &Vwindow_configuration_change_hook
,
7357 doc
: /* Functions to call when window configuration changes.
7358 The buffer-local part is run once per window, with the relevant window
7359 selected; while the global part is run only once for the modified frame,
7360 with the relevant frame selected. */);
7361 Vwindow_configuration_change_hook
= Qnil
;
7363 DEFVAR_LISP ("recenter-redisplay", &Vrecenter_redisplay
,
7364 doc
: /* If non-nil, then the `recenter' command with a nil argument
7365 will redraw the entire frame; the special value `tty' causes the
7366 frame to be redrawn only if it is a tty frame. */);
7367 Vrecenter_redisplay
= Qtty
;
7370 defsubr (&Sselected_window
);
7371 defsubr (&Sminibuffer_window
);
7372 defsubr (&Swindow_minibuffer_p
);
7373 defsubr (&Swindowp
);
7374 defsubr (&Swindow_live_p
);
7375 defsubr (&Spos_visible_in_window_p
);
7376 defsubr (&Swindow_line_height
);
7377 defsubr (&Swindow_buffer
);
7378 defsubr (&Swindow_height
);
7379 defsubr (&Swindow_width
);
7380 defsubr (&Swindow_full_width_p
);
7381 defsubr (&Swindow_hscroll
);
7382 defsubr (&Sset_window_hscroll
);
7383 defsubr (&Swindow_redisplay_end_trigger
);
7384 defsubr (&Sset_window_redisplay_end_trigger
);
7385 defsubr (&Swindow_edges
);
7386 defsubr (&Swindow_pixel_edges
);
7387 defsubr (&Swindow_absolute_pixel_edges
);
7388 defsubr (&Swindow_inside_edges
);
7389 defsubr (&Swindow_inside_pixel_edges
);
7390 defsubr (&Swindow_inside_absolute_pixel_edges
);
7391 defsubr (&Scoordinates_in_window_p
);
7392 defsubr (&Swindow_at
);
7393 defsubr (&Swindow_point
);
7394 defsubr (&Swindow_start
);
7395 defsubr (&Swindow_end
);
7396 defsubr (&Sset_window_point
);
7397 defsubr (&Sset_window_start
);
7398 defsubr (&Swindow_dedicated_p
);
7399 defsubr (&Sset_window_dedicated_p
);
7400 defsubr (&Swindow_display_table
);
7401 defsubr (&Sset_window_display_table
);
7402 defsubr (&Snext_window
);
7403 defsubr (&Sprevious_window
);
7404 defsubr (&Sother_window
);
7405 defsubr (&Sget_lru_window
);
7406 defsubr (&Sget_largest_window
);
7407 defsubr (&Sget_buffer_window
);
7408 defsubr (&Sdelete_other_windows
);
7409 defsubr (&Sdelete_windows_on
);
7410 defsubr (&Sreplace_buffer_in_windows
);
7411 defsubr (&Sdelete_window
);
7412 defsubr (&Sset_window_buffer
);
7413 defsubr (&Sselect_window
);
7414 defsubr (&Sforce_window_update
);
7415 defsubr (&Ssplit_window
);
7416 defsubr (&Senlarge_window
);
7417 defsubr (&Sshrink_window
);
7418 defsubr (&Sadjust_window_trailing_edge
);
7419 defsubr (&Sscroll_up
);
7420 defsubr (&Sscroll_down
);
7421 defsubr (&Sscroll_left
);
7422 defsubr (&Sscroll_right
);
7423 defsubr (&Sother_window_for_scrolling
);
7424 defsubr (&Sscroll_other_window
);
7425 defsubr (&Sminibuffer_selected_window
);
7426 defsubr (&Srecenter
);
7427 defsubr (&Swindow_text_height
);
7428 defsubr (&Smove_to_window_line
);
7429 defsubr (&Swindow_configuration_p
);
7430 defsubr (&Swindow_configuration_frame
);
7431 defsubr (&Sset_window_configuration
);
7432 defsubr (&Scurrent_window_configuration
);
7433 defsubr (&Ssave_window_excursion
);
7434 defsubr (&Swindow_tree
);
7435 defsubr (&Sset_window_margins
);
7436 defsubr (&Swindow_margins
);
7437 defsubr (&Sset_window_fringes
);
7438 defsubr (&Swindow_fringes
);
7439 defsubr (&Sset_window_scroll_bars
);
7440 defsubr (&Swindow_scroll_bars
);
7441 defsubr (&Swindow_vscroll
);
7442 defsubr (&Sset_window_vscroll
);
7443 defsubr (&Scompare_window_configurations
);
7444 defsubr (&Swindow_list
);
7445 defsubr (&Swindow_parameters
);
7446 defsubr (&Swindow_parameter
);
7447 defsubr (&Sset_window_parameter
);
7454 initial_define_key (control_x_map
, '1', "delete-other-windows");
7455 initial_define_key (control_x_map
, '2', "split-window");
7456 initial_define_key (control_x_map
, '0', "delete-window");
7457 initial_define_key (control_x_map
, 'o', "other-window");
7458 initial_define_key (control_x_map
, '^', "enlarge-window");
7459 initial_define_key (control_x_map
, '<', "scroll-left");
7460 initial_define_key (control_x_map
, '>', "scroll-right");
7462 initial_define_key (global_map
, Ctl ('V'), "scroll-up-command");
7463 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
7464 initial_define_key (meta_map
, 'v', "scroll-down-command");
7467 /* arch-tag: 90a9c576-0590-48f1-a5f1-6c96a0452d9f
7468 (do not change this comment) */