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 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
34 #include "dispextern.h"
35 #include "blockinput.h"
36 #include "intervals.h"
40 #endif /* HAVE_X_WINDOWS */
52 Lisp_Object Qwindowp
, Qwindow_live_p
, Qwindow_configuration_p
;
53 Lisp_Object Qwindow_size_fixed
;
54 extern Lisp_Object Qleft_margin
, Qright_margin
;
56 static int displayed_window_lines
P_ ((struct window
*));
57 static struct window
*decode_window
P_ ((Lisp_Object
));
58 static int count_windows
P_ ((struct window
*));
59 static int get_leaf_windows
P_ ((struct window
*, struct window
**, int));
60 static void window_scroll
P_ ((Lisp_Object
, int, int, int));
61 static void window_scroll_pixel_based
P_ ((Lisp_Object
, int, int, int));
62 static void window_scroll_line_based
P_ ((Lisp_Object
, int, int, int));
63 static int window_min_size_1
P_ ((struct window
*, int));
64 static int window_min_size
P_ ((struct window
*, int, int, int *));
65 static void size_window
P_ ((Lisp_Object
, int, int, int));
66 static int freeze_window_start
P_ ((struct window
*, void *));
67 static int window_fixed_size_p
P_ ((struct window
*, int, int));
68 static void enlarge_window
P_ ((Lisp_Object
, int, int, int));
69 static Lisp_Object window_list
P_ ((void));
70 static int add_window_to_list
P_ ((struct window
*, void *));
71 static int candidate_window_p
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
,
73 static Lisp_Object next_window
P_ ((Lisp_Object
, Lisp_Object
,
75 static void decode_next_window_args
P_ ((Lisp_Object
*, Lisp_Object
*,
77 static int foreach_window_1
P_ ((struct window
*,
78 int (* fn
) (struct window
*, void *),
80 static Lisp_Object window_list_1
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
));
82 /* This is the window in which the terminal's cursor should
83 be left when nothing is being done with it. This must
84 always be a leaf window, and its buffer is selected by
85 the top level editing loop at the end of each command.
87 This value is always the same as
88 FRAME_SELECTED_WINDOW (selected_frame). */
90 Lisp_Object selected_window
;
92 /* A list of all windows for use by next_window and Fwindow_list.
93 Functions creating or deleting windows should invalidate this cache
94 by setting it to nil. */
96 Lisp_Object Vwindow_list
;
98 /* The mini-buffer window of the selected frame.
99 Note that you cannot test for mini-bufferness of an arbitrary window
100 by comparing against this; but you can test for mini-bufferness of
101 the selected window. */
103 Lisp_Object minibuf_window
;
105 /* Non-nil means it is the window whose mode line should be
106 shown as the selected window when the minibuffer is selected. */
108 Lisp_Object minibuf_selected_window
;
110 /* Non-nil means it is the window for C-M-v to scroll
111 when the mini-buffer is selected. */
113 Lisp_Object Vminibuf_scroll_window
;
115 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
117 Lisp_Object Vother_window_scroll_buffer
;
119 /* Non-nil means it's function to call to display temp buffers. */
121 Lisp_Object Vtemp_buffer_show_function
;
123 /* Non-zero means line and page scrolling on tall lines (with images)
124 does partial scrolling by modifying window-vscroll. */
126 int auto_window_vscroll_p
;
128 /* Non-zero means to use mode-line-inactive face in all windows but the
129 selected-window and the minibuffer-scroll-window when the
130 minibuffer is active. */
131 int mode_line_in_non_selected_windows
;
133 /* If a window gets smaller than either of these, it is removed. */
135 EMACS_INT window_min_height
;
136 EMACS_INT window_min_width
;
138 /* Nonzero implies Fdisplay_buffer should create windows. */
142 /* Nonzero implies make new frames for Fdisplay_buffer. */
146 /* Nonzero means reuse existing frames for displaying buffers. */
148 int display_buffer_reuse_frames
;
150 /* Non-nil means use this function instead of default */
152 Lisp_Object Vpop_up_frame_function
;
154 /* Function to call to handle Fdisplay_buffer. */
156 Lisp_Object Vdisplay_buffer_function
;
158 /* Non-nil means that Fdisplay_buffer should even the heights of windows. */
160 Lisp_Object Veven_window_heights
;
162 /* List of buffer *names* for buffers that should have their own frames. */
164 Lisp_Object Vspecial_display_buffer_names
;
166 /* List of regexps for buffer names that should have their own frames. */
168 Lisp_Object Vspecial_display_regexps
;
170 /* Function to pop up a special frame. */
172 Lisp_Object Vspecial_display_function
;
174 /* List of buffer *names* for buffers to appear in selected window. */
176 Lisp_Object Vsame_window_buffer_names
;
178 /* List of regexps for buffer names to appear in selected window. */
180 Lisp_Object Vsame_window_regexps
;
182 /* Hook run at end of temp_output_buffer_show. */
184 Lisp_Object Qtemp_buffer_show_hook
;
186 /* Fdisplay_buffer always splits the largest window
187 if that window is more than this high. */
189 EMACS_INT split_height_threshold
;
191 /* Number of lines of continuity in scrolling by screenfuls. */
193 EMACS_INT next_screen_context_lines
;
195 /* Incremented for each window created. */
197 static int sequence_number
;
199 /* Nonzero after init_window_once has finished. */
201 static int window_initialized
;
203 /* Hook to run when window config changes. */
205 Lisp_Object Qwindow_configuration_change_hook
;
206 Lisp_Object Vwindow_configuration_change_hook
;
208 /* Non-nil means scroll commands try to put point
209 at the same screen height as previously. */
211 Lisp_Object Vscroll_preserve_screen_position
;
213 #if 0 /* This isn't used anywhere. */
214 /* Nonzero means we can split a frame even if it is "unsplittable". */
215 static int inhibit_frame_unsplittable
;
218 extern EMACS_INT scroll_margin
;
220 extern Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
222 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
223 doc
: /* Returns t if OBJECT is a window. */)
227 return WINDOWP (object
) ? Qt
: Qnil
;
230 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
231 doc
: /* Returns t if OBJECT is a window which is currently visible. */)
235 return WINDOW_LIVE_P (object
) ? Qt
: Qnil
;
242 register struct window
*p
;
244 p
= allocate_window ();
246 XSETFASTINT (p
->sequence_number
, sequence_number
);
247 XSETFASTINT (p
->left_col
, 0);
248 XSETFASTINT (p
->top_line
, 0);
249 XSETFASTINT (p
->total_lines
, 0);
250 XSETFASTINT (p
->total_cols
, 0);
251 XSETFASTINT (p
->hscroll
, 0);
252 XSETFASTINT (p
->min_hscroll
, 0);
253 p
->orig_top_line
= p
->orig_total_lines
= Qnil
;
254 p
->start
= Fmake_marker ();
255 p
->pointm
= Fmake_marker ();
256 XSETFASTINT (p
->use_time
, 0);
258 p
->display_table
= Qnil
;
260 p
->pseudo_window_p
= 0;
261 bzero (&p
->cursor
, sizeof (p
->cursor
));
262 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
263 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
264 p
->desired_matrix
= p
->current_matrix
= 0;
265 p
->nrows_scale_factor
= p
->ncols_scale_factor
= 1;
266 p
->phys_cursor_type
= -1;
267 p
->phys_cursor_width
= -1;
268 p
->must_be_updated_p
= 0;
269 XSETFASTINT (p
->window_end_vpos
, 0);
270 XSETFASTINT (p
->window_end_pos
, 0);
271 p
->window_end_valid
= Qnil
;
274 XSETFASTINT (p
->last_point
, 0);
275 p
->frozen_window_start_p
= 0;
276 p
->last_cursor_off_p
= p
->cursor_off_p
= 0;
277 p
->left_margin_cols
= Qnil
;
278 p
->right_margin_cols
= Qnil
;
279 p
->left_fringe_width
= Qnil
;
280 p
->right_fringe_width
= Qnil
;
281 p
->fringes_outside_margins
= Qnil
;
282 p
->scroll_bar_width
= Qnil
;
283 p
->vertical_scroll_bar_type
= Qt
;
289 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
290 doc
: /* Return the window that the cursor now appears in and commands apply to. */)
293 return selected_window
;
296 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
297 doc
: /* Return the window used now for minibuffers.
298 If the optional argument FRAME is specified, return the minibuffer window
299 used by that frame. */)
304 frame
= selected_frame
;
305 CHECK_LIVE_FRAME (frame
);
306 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
309 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 0, 1, 0,
310 doc
: /* Returns non-nil if WINDOW is a minibuffer window.
311 WINDOW defaults to the selected window. */)
315 struct window
*w
= decode_window (window
);
316 return MINI_WINDOW_P (w
) ? Qt
: Qnil
;
320 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
321 Spos_visible_in_window_p
, 0, 3, 0,
322 doc
: /* Return non-nil if position POS is currently on the frame in WINDOW.
323 Return nil if that position is scrolled vertically out of view.
324 If a character is only partially visible, nil is returned, unless the
325 optional argument PARTIALLY is non-nil.
326 If POS is only out of view because of horizontal scrolling, return non-nil.
327 POS defaults to point in WINDOW; WINDOW defaults to the selected window.
329 If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
330 return value is a list (X Y PARTIAL) where X and Y are the pixel coordinates
331 relative to the top left corner of the window. PARTIAL is nil if the character
332 after POS is fully visible; otherwise it is a cons (RTOP . RBOT) where RTOP
333 and RBOT are the number of pixels invisible at the top and bottom of the row. */)
334 (pos
, window
, partially
)
335 Lisp_Object pos
, window
, partially
;
337 register struct window
*w
;
339 register struct buffer
*buf
;
341 Lisp_Object in_window
= Qnil
;
342 int rtop
, rbot
, fully_p
= 1;
345 w
= decode_window (window
);
346 buf
= XBUFFER (w
->buffer
);
347 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
351 CHECK_NUMBER_COERCE_MARKER (pos
);
354 else if (w
== XWINDOW (selected_window
))
357 posint
= XMARKER (w
->pointm
)->charpos
;
359 /* If position is above window start or outside buffer boundaries,
360 or if window start is out of range, position is not visible. */
361 if (posint
>= CHARPOS (top
)
362 && posint
<= BUF_ZV (buf
)
363 && CHARPOS (top
) >= BUF_BEGV (buf
)
364 && CHARPOS (top
) <= BUF_ZV (buf
)
365 && pos_visible_p (w
, posint
, &x
, &y
, &rtop
, &rbot
, NILP (partially
))
366 && (fully_p
= !rtop
&& !rbot
, (!NILP (partially
) || fully_p
)))
369 if (!NILP (in_window
) && !NILP (partially
))
370 in_window
= Fcons (make_number (x
),
371 Fcons (make_number (y
),
372 Fcons ((fully_p
? Qnil
373 : Fcons (make_number (rtop
),
374 make_number (rbot
))),
380 static struct window
*
381 decode_window (window
)
382 register Lisp_Object window
;
385 return XWINDOW (selected_window
);
387 CHECK_LIVE_WINDOW (window
);
388 return XWINDOW (window
);
391 static struct window
*
392 decode_any_window (window
)
393 register Lisp_Object window
;
396 return XWINDOW (selected_window
);
398 CHECK_WINDOW (window
);
399 return XWINDOW (window
);
402 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
403 doc
: /* Return the buffer that WINDOW is displaying.
404 WINDOW defaults to the selected window. */)
408 return decode_window (window
)->buffer
;
411 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
412 doc
: /* Return the number of lines in WINDOW (including its mode line). */)
416 return decode_any_window (window
)->total_lines
;
419 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
420 doc
: /* Return the number of display columns in WINDOW.
421 This is the width that is usable columns available for text in WINDOW.
422 If you want to find out how many columns WINDOW takes up,
423 use (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))). */)
427 return make_number (window_box_text_cols (decode_any_window (window
)));
430 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
431 doc
: /* Return the number of columns by which WINDOW is scrolled from left margin. */)
435 return decode_window (window
)->hscroll
;
438 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
439 doc
: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
440 Return NCOL. NCOL should be zero or positive.
442 Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
443 window so that the location of point becomes invisible. */)
445 Lisp_Object window
, ncol
;
447 struct window
*w
= decode_window (window
);
451 hscroll
= max (0, XINT (ncol
));
453 /* Prevent redisplay shortcuts when changing the hscroll. */
454 if (XINT (w
->hscroll
) != hscroll
)
455 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
457 w
->hscroll
= make_number (hscroll
);
461 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
462 Swindow_redisplay_end_trigger
, 0, 1, 0,
463 doc
: /* Return WINDOW's redisplay end trigger value.
464 See `set-window-redisplay-end-trigger' for more information. */)
468 return decode_window (window
)->redisplay_end_trigger
;
471 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
472 Sset_window_redisplay_end_trigger
, 2, 2, 0,
473 doc
: /* Set WINDOW's redisplay end trigger value to VALUE.
474 VALUE should be a buffer position (typically a marker) or nil.
475 If it is a buffer position, then if redisplay in WINDOW reaches a position
476 beyond VALUE, the functions in `redisplay-end-trigger-functions' are called
477 with two arguments: WINDOW, and the end trigger value.
478 Afterwards the end-trigger value is reset to nil. */)
480 register Lisp_Object window
, value
;
482 register struct window
*w
;
484 w
= decode_window (window
);
485 w
->redisplay_end_trigger
= value
;
489 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
490 doc
: /* Return a list of the edge coordinates of WINDOW.
491 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.
492 RIGHT is one more than the rightmost column occupied by WINDOW,
493 and BOTTOM is one more than the bottommost row occupied by WINDOW.
494 The edges include the space used by the window's scroll bar,
495 display margins, fringes, header line, and mode line, if it has them.
496 To get the edges of the actual text area, use `window-inside-edges'. */)
500 register struct window
*w
= decode_any_window (window
);
502 return Fcons (make_number (WINDOW_LEFT_EDGE_COL (w
)),
503 Fcons (make_number (WINDOW_TOP_EDGE_LINE (w
)),
504 Fcons (make_number (WINDOW_RIGHT_EDGE_COL (w
)),
505 Fcons (make_number (WINDOW_BOTTOM_EDGE_LINE (w
)),
509 DEFUN ("window-pixel-edges", Fwindow_pixel_edges
, Swindow_pixel_edges
, 0, 1, 0,
510 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
511 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.
512 RIGHT is one more than the rightmost x position occupied by WINDOW,
513 and BOTTOM is one more than the bottommost y position occupied by WINDOW.
514 The pixel edges include the space used by the window's scroll bar,
515 display margins, fringes, header line, and mode line, if it has them.
516 To get the edges of the actual text area, use `window-inside-pixel-edges'. */)
520 register struct window
*w
= decode_any_window (window
);
522 return Fcons (make_number (WINDOW_LEFT_EDGE_X (w
)),
523 Fcons (make_number (WINDOW_TOP_EDGE_Y (w
)),
524 Fcons (make_number (WINDOW_RIGHT_EDGE_X (w
)),
525 Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w
)),
529 DEFUN ("window-inside-edges", Fwindow_inside_edges
, Swindow_inside_edges
, 0, 1, 0,
530 doc
: /* Return a list of the edge coordinates of WINDOW.
531 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.
532 RIGHT is one more than the rightmost column used by text in WINDOW,
533 and BOTTOM is one more than the bottommost row used by text in WINDOW.
534 The inside edges do not include the space used by the window's scroll bar,
535 display margins, fringes, header line, and/or mode line. */)
539 register struct window
*w
= decode_any_window (window
);
541 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_COL (w
)
542 + WINDOW_LEFT_MARGIN_COLS (w
)
543 + WINDOW_LEFT_FRINGE_COLS (w
)),
544 make_number (WINDOW_TOP_EDGE_LINE (w
)
545 + WINDOW_HEADER_LINE_LINES (w
)),
546 make_number (WINDOW_BOX_RIGHT_EDGE_COL (w
)
547 - WINDOW_RIGHT_MARGIN_COLS (w
)
548 - WINDOW_RIGHT_FRINGE_COLS (w
)),
549 make_number (WINDOW_BOTTOM_EDGE_LINE (w
)
550 - WINDOW_MODE_LINE_LINES (w
)));
553 DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges
, Swindow_inside_pixel_edges
, 0, 1, 0,
554 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
555 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.
556 RIGHT is one more than the rightmost x position used by text in WINDOW,
557 and BOTTOM is one more than the bottommost y position used by text in WINDOW.
558 The inside edges do not include the space used by the window's scroll bar,
559 display margins, fringes, header line, and/or mode line. */)
563 register struct window
*w
= decode_any_window (window
);
565 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w
)
566 + WINDOW_LEFT_MARGIN_WIDTH (w
)
567 + WINDOW_LEFT_FRINGE_WIDTH (w
)),
568 make_number (WINDOW_TOP_EDGE_Y (w
)
569 + WINDOW_HEADER_LINE_HEIGHT (w
)),
570 make_number (WINDOW_BOX_RIGHT_EDGE_X (w
)
571 - WINDOW_RIGHT_MARGIN_WIDTH (w
)
572 - WINDOW_RIGHT_FRINGE_WIDTH (w
)),
573 make_number (WINDOW_BOTTOM_EDGE_Y (w
)
574 - WINDOW_MODE_LINE_HEIGHT (w
)));
577 /* Test if the character at column *X, row *Y is within window W.
578 If it is not, return ON_NOTHING;
579 if it is in the window's text area,
580 set *x and *y to its location relative to the upper left corner
583 if it is on the window's modeline, return ON_MODE_LINE;
584 if it is on the border between the window and its right sibling,
585 return ON_VERTICAL_BORDER.
586 if it is on a scroll bar,
587 return ON_SCROLL_BAR.
588 if it is on the window's top line, return ON_HEADER_LINE;
589 if it is in left or right fringe of the window,
590 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE, and convert *X and *Y
591 to window-relative coordinates;
592 if it is in the marginal area to the left/right of the window,
593 return ON_LEFT_MARGIN or ON_RIGHT_MARGIN, and convert *X and *Y
594 to window-relative coordinates.
596 X and Y are frame relative pixel coordinates. */
598 static enum window_part
599 coordinates_in_window (w
, x
, y
)
600 register struct window
*w
;
603 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
604 int left_x
, right_x
, top_y
, bottom_y
;
605 enum window_part part
;
606 int ux
= FRAME_COLUMN_WIDTH (f
);
607 int x0
= WINDOW_LEFT_EDGE_X (w
);
608 int x1
= WINDOW_RIGHT_EDGE_X (w
);
609 /* The width of the area where the vertical line can be dragged.
610 (Between mode lines for instance. */
611 int grabbable_width
= ux
;
612 int lmargin_width
, rmargin_width
, text_left
, text_right
;
614 /* In what's below, we subtract 1 when computing right_x because we
615 want the rightmost pixel, which is given by left_pixel+width-1. */
616 if (w
->pseudo_window_p
)
619 right_x
= WINDOW_TOTAL_WIDTH (w
) - 1;
620 top_y
= WINDOW_TOP_EDGE_Y (w
);
621 bottom_y
= WINDOW_BOTTOM_EDGE_Y (w
);
625 left_x
= WINDOW_BOX_LEFT_EDGE_X (w
);
626 right_x
= WINDOW_BOX_RIGHT_EDGE_X (w
) - 1;
627 top_y
= WINDOW_TOP_EDGE_Y (w
);
628 bottom_y
= WINDOW_BOTTOM_EDGE_Y (w
);
631 /* Outside any interesting row? */
632 if (*y
< top_y
|| *y
>= bottom_y
)
635 /* On the mode line or header line? If it's near the start of
636 the mode or header line of window that's has a horizontal
637 sibling, say it's on the vertical line. That's to be able
638 to resize windows horizontally in case we're using toolkit
641 if (WINDOW_WANTS_MODELINE_P (w
)
642 && *y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
))
646 header_vertical_border_check
:
647 /* We're somewhere on the mode line. We consider the place
648 between mode lines of horizontally adjacent mode lines
649 as the vertical border. If scroll bars on the left,
650 return the right window. */
651 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
652 || WINDOW_RIGHTMOST_P (w
))
654 if (!WINDOW_LEFTMOST_P (w
) && abs (*x
- x0
) < grabbable_width
)
655 return ON_VERTICAL_BORDER
;
659 if (abs (*x
- x1
) < grabbable_width
)
660 return ON_VERTICAL_BORDER
;
663 if (*x
< x0
|| *x
>= x1
)
666 /* Convert X and Y to window relative coordinates.
667 Mode line starts at left edge of window. */
673 if (WINDOW_WANTS_HEADER_LINE_P (w
)
674 && *y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
))
676 part
= ON_HEADER_LINE
;
677 goto header_vertical_border_check
;
680 if (*x
< x0
|| *x
>= x1
)
683 /* Outside any interesting column? */
684 if (*x
< left_x
|| *x
> right_x
)
685 return ON_SCROLL_BAR
;
687 lmargin_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
688 rmargin_width
= window_box_width (w
, RIGHT_MARGIN_AREA
);
690 text_left
= window_box_left (w
, TEXT_AREA
);
691 text_right
= text_left
+ window_box_width (w
, TEXT_AREA
);
693 if (FRAME_WINDOW_P (f
))
695 if (!w
->pseudo_window_p
696 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
)
697 && !WINDOW_RIGHTMOST_P (w
)
698 && (abs (*x
- right_x
) < grabbable_width
))
699 return ON_VERTICAL_BORDER
;
703 /* Need to say "*x > right_x" rather than >=, since on character
704 terminals, the vertical line's x coordinate is right_x. */
705 if (!w
->pseudo_window_p
706 && !WINDOW_RIGHTMOST_P (w
)
707 && *x
> right_x
- ux
)
709 /* On the border on the right side of the window? Assume that
710 this area begins at RIGHT_X minus a canonical char width. */
711 return ON_VERTICAL_BORDER
;
717 if (lmargin_width
> 0
718 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
719 ? (*x
>= left_x
+ WINDOW_LEFT_FRINGE_WIDTH (w
))
720 : (*x
< left_x
+ lmargin_width
)))
723 if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
724 *x
-= WINDOW_LEFT_FRINGE_WIDTH (w
);
726 return ON_LEFT_MARGIN
;
729 /* Convert X and Y to window-relative pixel coordinates. */
732 return ON_LEFT_FRINGE
;
735 if (*x
>= text_right
)
737 if (rmargin_width
> 0
738 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
739 ? (*x
< right_x
- WINDOW_RIGHT_FRINGE_WIDTH (w
))
740 : (*x
>= right_x
- rmargin_width
)))
743 if (!WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
744 *x
-= WINDOW_RIGHT_FRINGE_WIDTH (w
);
746 return ON_RIGHT_MARGIN
;
749 /* Convert X and Y to window-relative pixel coordinates. */
750 *x
-= left_x
+ WINDOW_LEFT_FRINGE_WIDTH (w
);
752 return ON_RIGHT_FRINGE
;
755 /* Everything special ruled out - must be on text area */
756 *x
-= left_x
+ WINDOW_LEFT_FRINGE_WIDTH (w
);
762 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
763 Scoordinates_in_window_p
, 2, 2, 0,
764 doc
: /* Return non-nil if COORDINATES are in WINDOW.
765 COORDINATES is a cons of the form (X . Y), X and Y being distances
766 measured in characters from the upper-left corner of the frame.
767 \(0 . 0) denotes the character in the upper left corner of the
769 If COORDINATES are in the text portion of WINDOW,
770 the coordinates relative to the window are returned.
771 If they are in the mode line of WINDOW, `mode-line' is returned.
772 If they are in the top mode line of WINDOW, `header-line' is returned.
773 If they are in the left fringe of WINDOW, `left-fringe' is returned.
774 If they are in the right fringe of WINDOW, `right-fringe' is returned.
775 If they are on the border between WINDOW and its right sibling,
776 `vertical-line' is returned.
777 If they are in the windows's left or right marginal areas, `left-margin'\n\
778 or `right-margin' is returned. */)
779 (coordinates
, window
)
780 register Lisp_Object coordinates
, window
;
787 CHECK_WINDOW (window
);
788 w
= XWINDOW (window
);
789 f
= XFRAME (w
->frame
);
790 CHECK_CONS (coordinates
);
791 lx
= Fcar (coordinates
);
792 ly
= Fcdr (coordinates
);
793 CHECK_NUMBER_OR_FLOAT (lx
);
794 CHECK_NUMBER_OR_FLOAT (ly
);
795 x
= FRAME_PIXEL_X_FROM_CANON_X (f
, lx
) + FRAME_INTERNAL_BORDER_WIDTH (f
);
796 y
= FRAME_PIXEL_Y_FROM_CANON_Y (f
, ly
) + FRAME_INTERNAL_BORDER_WIDTH (f
);
798 switch (coordinates_in_window (w
, &x
, &y
))
804 /* X and Y are now window relative pixel coordinates. Convert
805 them to canonical char units before returning them. */
806 return Fcons (FRAME_CANON_X_FROM_PIXEL_X (f
, x
),
807 FRAME_CANON_Y_FROM_PIXEL_Y (f
, y
));
812 case ON_VERTICAL_BORDER
:
813 return Qvertical_line
;
821 case ON_RIGHT_FRINGE
:
822 return Qright_fringe
;
827 case ON_RIGHT_MARGIN
:
828 return Qright_margin
;
831 /* Historically we are supposed to return nil in this case. */
840 /* Callback for foreach_window, used in window_from_coordinates.
841 Check if window W contains coordinates specified by USER_DATA which
842 is actually a pointer to a struct check_window_data CW.
844 Check if window W contains coordinates *CW->x and *CW->y. If it
845 does, return W in *CW->window, as Lisp_Object, and return in
846 *CW->part the part of the window under coordinates *X,*Y. Return
847 zero from this function to stop iterating over windows. */
849 struct check_window_data
853 enum window_part
*part
;
857 check_window_containing (w
, user_data
)
861 struct check_window_data
*cw
= (struct check_window_data
*) user_data
;
862 enum window_part found
;
865 found
= coordinates_in_window (w
, cw
->x
, cw
->y
);
866 if (found
!= ON_NOTHING
)
869 XSETWINDOW (*cw
->window
, w
);
877 /* Find the window containing frame-relative pixel position X/Y and
878 return it as a Lisp_Object.
880 If X, Y is on one of the window's special `window_part' elements,
881 set *PART to the id of that element, and return X and Y converted
882 to window relative coordinates in WX and WY.
884 If there is no window under X, Y return nil and leave *PART
885 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows.
887 This function was previously implemented with a loop cycling over
888 windows with Fnext_window, and starting with the frame's selected
889 window. It turned out that this doesn't work with an
890 implementation of next_window using Vwindow_list, because
891 FRAME_SELECTED_WINDOW (F) is not always contained in the window
892 tree of F when this function is called asynchronously from
893 note_mouse_highlight. The original loop didn't terminate in this
897 window_from_coordinates (f
, x
, y
, part
, wx
, wy
, tool_bar_p
)
900 enum window_part
*part
;
905 struct check_window_data cw
;
906 enum window_part dummy
;
912 cw
.window
= &window
, cw
.x
= &x
, cw
.y
= &y
; cw
.part
= part
;
913 foreach_window (f
, check_window_containing
, &cw
);
915 /* If not found above, see if it's in the tool bar window, if a tool
919 && WINDOWP (f
->tool_bar_window
)
920 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0
921 && (coordinates_in_window (XWINDOW (f
->tool_bar_window
), &x
, &y
)
925 window
= f
->tool_bar_window
;
934 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
935 doc
: /* Return window containing coordinates X and Y on FRAME.
936 If omitted, FRAME defaults to the currently selected frame.
937 The top left corner of the frame is considered to be row 0,
940 Lisp_Object x
, y
, frame
;
945 frame
= selected_frame
;
946 CHECK_LIVE_FRAME (frame
);
949 /* Check that arguments are integers or floats. */
950 CHECK_NUMBER_OR_FLOAT (x
);
951 CHECK_NUMBER_OR_FLOAT (y
);
953 return window_from_coordinates (f
,
954 (FRAME_PIXEL_X_FROM_CANON_X (f
, x
)
955 + FRAME_INTERNAL_BORDER_WIDTH (f
)),
956 (FRAME_PIXEL_Y_FROM_CANON_Y (f
, y
)
957 + FRAME_INTERNAL_BORDER_WIDTH (f
)),
961 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
962 doc
: /* Return current value of point in WINDOW.
963 For a nonselected window, this is the value point would have
964 if that window were selected.
966 Note that, when WINDOW is the selected window and its buffer
967 is also currently selected, the value returned is the same as (point).
968 It would be more strictly correct to return the `top-level' value
969 of point, outside of any save-excursion forms.
970 But that is hard to define. */)
974 register struct window
*w
= decode_window (window
);
976 if (w
== XWINDOW (selected_window
)
977 && current_buffer
== XBUFFER (w
->buffer
))
979 return Fmarker_position (w
->pointm
);
982 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
983 doc
: /* Return position at which display currently starts in WINDOW.
984 This is updated by redisplay or by calling `set-window-start'. */)
988 return Fmarker_position (decode_window (window
)->start
);
991 /* This is text temporarily removed from the doc string below.
993 This function returns nil if the position is not currently known.
994 That happens when redisplay is preempted and doesn't finish.
995 If in that case you want to compute where the end of the window would
996 have been if redisplay had finished, do this:
998 (goto-char (window-start window))
999 (vertical-motion (1- (window-height window)) window)
1002 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
1003 doc
: /* Return position at which display currently ends in WINDOW.
1004 This is updated by redisplay, when it runs to completion.
1005 Simply changing the buffer text or setting `window-start'
1006 does not update this value.
1007 Return nil if there is no recorded value. \(This can happen if the
1008 last redisplay of WINDOW was preempted, and did not finish.)
1009 If UPDATE is non-nil, compute the up-to-date position
1010 if it isn't already recorded. */)
1012 Lisp_Object window
, update
;
1015 struct window
*w
= decode_window (window
);
1021 #if 0 /* This change broke some things. We should make it later. */
1022 /* If we don't know the end position, return nil.
1023 The user can compute it with vertical-motion if he wants to.
1024 It would be nicer to do it automatically,
1025 but that's so slow that it would probably bother people. */
1026 if (NILP (w
->window_end_valid
))
1031 && ! (! NILP (w
->window_end_valid
)
1032 && XFASTINT (w
->last_modified
) >= MODIFF
))
1034 struct text_pos startp
;
1036 struct buffer
*old_buffer
= NULL
, *b
= XBUFFER (buf
);
1038 /* In case W->start is out of the range, use something
1039 reasonable. This situation occurred when loading a file with
1040 `-l' containing a call to `rmail' with subsequent other
1041 commands. At the end, W->start happened to be BEG, while
1042 rmail had already narrowed the buffer. */
1043 if (XMARKER (w
->start
)->charpos
< BEGV
)
1044 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
1045 else if (XMARKER (w
->start
)->charpos
> ZV
)
1046 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
1048 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
1050 /* Cannot use Fvertical_motion because that function doesn't
1051 cope with variable-height lines. */
1052 if (b
!= current_buffer
)
1054 old_buffer
= current_buffer
;
1055 set_buffer_internal (b
);
1058 start_display (&it
, w
, startp
);
1059 move_it_vertically (&it
, window_box_height (w
));
1060 if (it
.current_y
< it
.last_visible_y
)
1061 move_it_past_eol (&it
);
1062 value
= make_number (IT_CHARPOS (it
));
1065 set_buffer_internal (old_buffer
);
1068 XSETINT (value
, BUF_Z (XBUFFER (buf
)) - XFASTINT (w
->window_end_pos
));
1073 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
1074 doc
: /* Make point value in WINDOW be at position POS in WINDOW's buffer.
1077 Lisp_Object window
, pos
;
1079 register struct window
*w
= decode_window (window
);
1081 CHECK_NUMBER_COERCE_MARKER (pos
);
1082 if (w
== XWINDOW (selected_window
)
1083 && XBUFFER (w
->buffer
) == current_buffer
)
1086 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
1088 /* We have to make sure that redisplay updates the window to show
1089 the new value of point. */
1090 if (!EQ (window
, selected_window
))
1091 ++windows_or_buffers_changed
;
1096 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
1097 doc
: /* Make display in WINDOW start at position POS in WINDOW's buffer.
1099 Optional third arg NOFORCE non-nil inhibits next redisplay
1100 from overriding motion of point in order to display at this exact start. */)
1101 (window
, pos
, noforce
)
1102 Lisp_Object window
, pos
, noforce
;
1104 register struct window
*w
= decode_window (window
);
1106 CHECK_NUMBER_COERCE_MARKER (pos
);
1107 set_marker_restricted (w
->start
, pos
, w
->buffer
);
1108 /* this is not right, but much easier than doing what is right. */
1109 w
->start_at_line_beg
= Qnil
;
1111 w
->force_start
= Qt
;
1112 w
->update_mode_line
= Qt
;
1113 XSETFASTINT (w
->last_modified
, 0);
1114 XSETFASTINT (w
->last_overlay_modified
, 0);
1115 if (!EQ (window
, selected_window
))
1116 windows_or_buffers_changed
++;
1121 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
1123 doc
: /* Return WINDOW's dedicated object, usually t or nil.
1124 See also `set-window-dedicated-p'. */)
1128 return decode_window (window
)->dedicated
;
1131 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
1132 Sset_window_dedicated_p
, 2, 2, 0,
1133 doc
: /* Control whether WINDOW is dedicated to the buffer it displays.
1134 If it is dedicated, Emacs will not automatically change
1135 which buffer appears in it.
1136 The second argument is the new value for the dedication flag;
1137 non-nil means yes. */)
1139 Lisp_Object window
, arg
;
1141 register struct window
*w
= decode_window (window
);
1145 return w
->dedicated
;
1148 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
1150 doc
: /* Return the display-table that WINDOW is using. */)
1154 return decode_window (window
)->display_table
;
1157 /* Get the display table for use on window W. This is either W's
1158 display table or W's buffer's display table. Ignore the specified
1159 tables if they are not valid; if no valid table is specified,
1162 struct Lisp_Char_Table
*
1163 window_display_table (w
)
1166 struct Lisp_Char_Table
*dp
= NULL
;
1168 if (DISP_TABLE_P (w
->display_table
))
1169 dp
= XCHAR_TABLE (w
->display_table
);
1170 else if (BUFFERP (w
->buffer
))
1172 struct buffer
*b
= XBUFFER (w
->buffer
);
1174 if (DISP_TABLE_P (b
->display_table
))
1175 dp
= XCHAR_TABLE (b
->display_table
);
1176 else if (DISP_TABLE_P (Vstandard_display_table
))
1177 dp
= XCHAR_TABLE (Vstandard_display_table
);
1183 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
1184 doc
: /* Set WINDOW's display-table to TABLE. */)
1186 register Lisp_Object window
, table
;
1188 register struct window
*w
;
1190 w
= decode_window (window
);
1191 w
->display_table
= table
;
1195 /* Record info on buffer window w is displaying
1196 when it is about to cease to display that buffer. */
1199 register struct window
*w
;
1206 if (b
!= XMARKER (w
->pointm
)->buffer
)
1210 if (w
== XWINDOW (selected_window
)
1211 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
1212 /* Do this except when the selected window's buffer
1213 is being removed from some other window. */
1215 /* last_window_start records the start position that this buffer
1216 had in the last window to be disconnected from it.
1217 Now that this statement is unconditional,
1218 it is possible for the buffer to be displayed in the
1219 selected window, while last_window_start reflects another
1220 window which was recently showing the same buffer.
1221 Some people might say that might be a good thing. Let's see. */
1222 b
->last_window_start
= marker_position (w
->start
);
1224 /* Point in the selected window's buffer
1225 is actually stored in that buffer, and the window's pointm isn't used.
1226 So don't clobber point in that buffer. */
1227 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
)
1228 /* This line helps to fix Horsley's testbug.el bug. */
1229 && !(WINDOWP (b
->last_selected_window
)
1230 && w
!= XWINDOW (b
->last_selected_window
)
1231 && EQ (buf
, XWINDOW (b
->last_selected_window
)->buffer
)))
1232 temp_set_point_both (b
,
1233 clip_to_bounds (BUF_BEGV (b
),
1234 XMARKER (w
->pointm
)->charpos
,
1236 clip_to_bounds (BUF_BEGV_BYTE (b
),
1237 marker_byte_position (w
->pointm
),
1240 if (WINDOWP (b
->last_selected_window
)
1241 && w
== XWINDOW (b
->last_selected_window
))
1242 b
->last_selected_window
= Qnil
;
1245 /* Put replacement into the window structure in place of old. */
1247 replace_window (old
, replacement
)
1248 Lisp_Object old
, replacement
;
1250 register Lisp_Object tem
;
1251 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
1253 /* If OLD is its frame's root_window, then replacement is the new
1254 root_window for that frame. */
1256 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
1257 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
1259 p
->left_col
= o
->left_col
;
1260 p
->top_line
= o
->top_line
;
1261 p
->total_cols
= o
->total_cols
;
1262 p
->total_lines
= o
->total_lines
;
1263 p
->desired_matrix
= p
->current_matrix
= 0;
1265 bzero (&p
->cursor
, sizeof (p
->cursor
));
1266 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
1267 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
1268 p
->phys_cursor_type
= -1;
1269 p
->phys_cursor_width
= -1;
1270 p
->must_be_updated_p
= 0;
1271 p
->pseudo_window_p
= 0;
1272 XSETFASTINT (p
->window_end_vpos
, 0);
1273 XSETFASTINT (p
->window_end_pos
, 0);
1274 p
->window_end_valid
= Qnil
;
1275 p
->frozen_window_start_p
= 0;
1276 p
->orig_top_line
= p
->orig_total_lines
= Qnil
;
1278 p
->next
= tem
= o
->next
;
1280 XWINDOW (tem
)->prev
= replacement
;
1282 p
->prev
= tem
= o
->prev
;
1284 XWINDOW (tem
)->next
= replacement
;
1286 p
->parent
= tem
= o
->parent
;
1289 if (EQ (XWINDOW (tem
)->vchild
, old
))
1290 XWINDOW (tem
)->vchild
= replacement
;
1291 if (EQ (XWINDOW (tem
)->hchild
, old
))
1292 XWINDOW (tem
)->hchild
= replacement
;
1295 /*** Here, if replacement is a vertical combination
1296 and so is its new parent, we should make replacement's
1297 children be children of that parent instead. ***/
1300 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
1301 doc
: /* Remove WINDOW from the display. Default is selected window. */)
1303 register Lisp_Object window
;
1305 delete_window (window
);
1307 if (! NILP (Vwindow_configuration_change_hook
)
1308 && ! NILP (Vrun_hooks
))
1309 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
1315 delete_window (window
)
1316 register Lisp_Object window
;
1318 register Lisp_Object tem
, parent
, sib
;
1319 register struct window
*p
;
1320 register struct window
*par
;
1323 /* Because this function is called by other C code on non-leaf
1324 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1325 so we can't decode_window here. */
1327 window
= selected_window
;
1329 CHECK_WINDOW (window
);
1330 p
= XWINDOW (window
);
1332 /* It's okay to delete an already-deleted window. */
1333 if (NILP (p
->buffer
)
1335 && NILP (p
->vchild
))
1340 error ("Attempt to delete minibuffer or sole ordinary window");
1341 par
= XWINDOW (parent
);
1343 windows_or_buffers_changed
++;
1344 Vwindow_list
= Qnil
;
1345 f
= XFRAME (WINDOW_FRAME (p
));
1346 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
1348 /* Are we trying to delete any frame's selected window? */
1350 Lisp_Object swindow
, pwindow
;
1352 /* See if the frame's selected window is either WINDOW
1353 or any subwindow of it, by finding all that window's parents
1354 and comparing each one with WINDOW. */
1355 swindow
= FRAME_SELECTED_WINDOW (f
);
1360 while (!NILP (pwindow
))
1362 if (EQ (window
, pwindow
))
1364 pwindow
= XWINDOW (pwindow
)->parent
;
1367 /* If the window being deleted is not a parent of SWINDOW,
1368 then SWINDOW is ok as the new selected window. */
1369 if (!EQ (window
, pwindow
))
1371 /* Otherwise, try another window for SWINDOW. */
1372 swindow
= Fnext_window (swindow
, Qlambda
, Qnil
);;
1374 /* If we get back to the frame's selected window,
1375 it means there was no acceptable alternative,
1376 so we cannot delete. */
1377 if (EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
1378 error ("Cannot delete window");
1381 /* If we need to change SWINDOW, do it. */
1382 if (! EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
1384 /* If we're about to delete the selected window on the
1385 selected frame, then we should use Fselect_window to select
1386 the new window. On the other hand, if we're about to
1387 delete the selected window on any other frame, we shouldn't do
1388 anything but set the frame's selected_window slot. */
1389 if (EQ (FRAME_SELECTED_WINDOW (f
), selected_window
))
1390 Fselect_window (swindow
, Qnil
);
1392 FRAME_SELECTED_WINDOW (f
) = swindow
;
1397 /* tem is null for dummy parent windows
1398 (which have inferiors but not any contents themselves) */
1402 unchain_marker (XMARKER (p
->pointm
));
1403 unchain_marker (XMARKER (p
->start
));
1406 /* Free window glyph matrices. It is sure that they are allocated
1407 again when ADJUST_GLYPHS is called. Block input so that expose
1408 events and other events that access glyph matrices are not
1409 processed while we are changing them. */
1411 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f
)));
1415 XWINDOW (tem
)->prev
= p
->prev
;
1419 XWINDOW (tem
)->next
= p
->next
;
1421 if (EQ (window
, par
->hchild
))
1422 par
->hchild
= p
->next
;
1423 if (EQ (window
, par
->vchild
))
1424 par
->vchild
= p
->next
;
1426 /* Find one of our siblings to give our space to. */
1430 /* If p gives its space to its next sibling, that sibling needs
1431 to have its top/left side pulled back to where p's is.
1432 set_window_{height,width} will re-position the sibling's
1435 XWINDOW (sib
)->top_line
= p
->top_line
;
1436 XWINDOW (sib
)->left_col
= p
->left_col
;
1439 /* Stretch that sibling. */
1440 if (!NILP (par
->vchild
))
1441 set_window_height (sib
,
1442 XFASTINT (XWINDOW (sib
)->total_lines
) + XFASTINT (p
->total_lines
),
1444 if (!NILP (par
->hchild
))
1445 set_window_width (sib
,
1446 XFASTINT (XWINDOW (sib
)->total_cols
) + XFASTINT (p
->total_cols
),
1449 /* If parent now has only one child,
1450 put the child into the parent's place. */
1454 if (NILP (XWINDOW (tem
)->next
)) {
1455 replace_window (parent
, tem
);
1456 par
= XWINDOW (tem
);
1459 /* Since we may be deleting combination windows, we must make sure that
1460 not only p but all its children have been marked as deleted. */
1461 if (! NILP (p
->hchild
))
1462 delete_all_subwindows (XWINDOW (p
->hchild
));
1463 else if (! NILP (p
->vchild
))
1464 delete_all_subwindows (XWINDOW (p
->vchild
));
1466 /* Mark this window as deleted. */
1467 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
1469 if (! NILP (par
->parent
))
1470 par
= XWINDOW (par
->parent
);
1472 /* Check if we have a v/hchild with a v/hchild. In that case remove
1475 if (! NILP (par
->vchild
) && ! NILP (XWINDOW (par
->vchild
)->vchild
))
1477 p
= XWINDOW (par
->vchild
);
1478 par
->vchild
= p
->vchild
;
1481 else if (! NILP (par
->hchild
) && ! NILP (XWINDOW (par
->hchild
)->hchild
))
1483 p
= XWINDOW (par
->hchild
);
1484 par
->hchild
= p
->hchild
;
1492 while (! NILP (tem
)) {
1493 XWINDOW (tem
)->parent
= p
->parent
;
1494 if (NILP (XWINDOW (tem
)->next
))
1496 tem
= XWINDOW (tem
)->next
;
1499 /* The next of the v/hchild we are removing is now the next of the
1500 last child for the v/hchild:
1501 Before v/hchild -> v/hchild -> next1 -> next2
1504 After: v/hchild -> next1 -> next2 -> next3
1506 XWINDOW (tem
)->next
= p
->next
;
1507 if (! NILP (p
->next
))
1508 XWINDOW (p
->next
)->prev
= tem
;
1510 p
->next
= p
->prev
= p
->vchild
= p
->hchild
= p
->buffer
= Qnil
;
1514 /* Adjust glyph matrices. */
1521 /***********************************************************************
1523 ***********************************************************************/
1525 /* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object
1526 pointer. This is a callback function for foreach_window, used in
1527 function window_list. */
1530 add_window_to_list (w
, user_data
)
1534 Lisp_Object
*list
= (Lisp_Object
*) user_data
;
1536 XSETWINDOW (window
, w
);
1537 *list
= Fcons (window
, *list
);
1542 /* Return a list of all windows, for use by next_window. If
1543 Vwindow_list is a list, return that list. Otherwise, build a new
1544 list, cache it in Vwindow_list, and return that. */
1549 if (!CONSP (Vwindow_list
))
1553 Vwindow_list
= Qnil
;
1554 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
1556 Lisp_Object args
[2];
1558 /* We are visiting windows in canonical order, and add
1559 new windows at the front of args[1], which means we
1560 have to reverse this list at the end. */
1562 foreach_window (XFRAME (XCAR (tail
)), add_window_to_list
, &args
[1]);
1563 args
[0] = Vwindow_list
;
1564 args
[1] = Fnreverse (args
[1]);
1565 Vwindow_list
= Fnconc (2, args
);
1569 return Vwindow_list
;
1573 /* Value is non-zero if WINDOW satisfies the constraints given by
1574 OWINDOW, MINIBUF and ALL_FRAMES.
1576 MINIBUF t means WINDOW may be minibuffer windows.
1577 `lambda' means WINDOW may not be a minibuffer window.
1578 a window means a specific minibuffer window
1580 ALL_FRAMES t means search all frames,
1581 nil means search just current frame,
1582 `visible' means search just visible frames,
1583 0 means search visible and iconified frames,
1584 a window means search the frame that window belongs to,
1585 a frame means consider windows on that frame, only. */
1588 candidate_window_p (window
, owindow
, minibuf
, all_frames
)
1589 Lisp_Object window
, owindow
, minibuf
, all_frames
;
1591 struct window
*w
= XWINDOW (window
);
1592 struct frame
*f
= XFRAME (w
->frame
);
1593 int candidate_p
= 1;
1595 if (!BUFFERP (w
->buffer
))
1597 else if (MINI_WINDOW_P (w
)
1598 && (EQ (minibuf
, Qlambda
)
1599 || (WINDOWP (minibuf
) && !EQ (minibuf
, window
))))
1601 /* If MINIBUF is `lambda' don't consider any mini-windows.
1602 If it is a window, consider only that one. */
1605 else if (EQ (all_frames
, Qt
))
1607 else if (NILP (all_frames
))
1609 xassert (WINDOWP (owindow
));
1610 candidate_p
= EQ (w
->frame
, XWINDOW (owindow
)->frame
);
1612 else if (EQ (all_frames
, Qvisible
))
1614 FRAME_SAMPLE_VISIBILITY (f
);
1615 candidate_p
= FRAME_VISIBLE_P (f
);
1617 else if (INTEGERP (all_frames
) && XINT (all_frames
) == 0)
1619 FRAME_SAMPLE_VISIBILITY (f
);
1620 candidate_p
= FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
);
1622 else if (WINDOWP (all_frames
))
1623 candidate_p
= (EQ (FRAME_MINIBUF_WINDOW (f
), all_frames
)
1624 || EQ (XWINDOW (all_frames
)->frame
, w
->frame
)
1625 || EQ (XWINDOW (all_frames
)->frame
, FRAME_FOCUS_FRAME (f
)));
1626 else if (FRAMEP (all_frames
))
1627 candidate_p
= EQ (all_frames
, w
->frame
);
1633 /* Decode arguments as allowed by Fnext_window, Fprevious_window, and
1634 Fwindow_list. See there for the meaning of WINDOW, MINIBUF, and
1638 decode_next_window_args (window
, minibuf
, all_frames
)
1639 Lisp_Object
*window
, *minibuf
, *all_frames
;
1642 *window
= selected_window
;
1644 CHECK_LIVE_WINDOW (*window
);
1646 /* MINIBUF nil may or may not include minibuffers. Decide if it
1648 if (NILP (*minibuf
))
1649 *minibuf
= minibuf_level
? minibuf_window
: Qlambda
;
1650 else if (!EQ (*minibuf
, Qt
))
1653 /* Now *MINIBUF can be t => count all minibuffer windows, `lambda'
1654 => count none of them, or a specific minibuffer window (the
1655 active one) to count. */
1657 /* ALL_FRAMES nil doesn't specify which frames to include. */
1658 if (NILP (*all_frames
))
1659 *all_frames
= (!EQ (*minibuf
, Qlambda
)
1660 ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window
)->frame
))
1662 else if (EQ (*all_frames
, Qvisible
))
1664 else if (EQ (*all_frames
, make_number (0)))
1666 else if (FRAMEP (*all_frames
))
1668 else if (!EQ (*all_frames
, Qt
))
1671 /* Now *ALL_FRAMES is t meaning search all frames, nil meaning
1672 search just current frame, `visible' meaning search just visible
1673 frames, 0 meaning search visible and iconified frames, or a
1674 window, meaning search the frame that window belongs to, or a
1675 frame, meaning consider windows on that frame, only. */
1679 /* Return the next or previous window of WINDOW in canonical ordering
1680 of windows. NEXT_P non-zero means return the next window. See the
1681 documentation string of next-window for the meaning of MINIBUF and
1685 next_window (window
, minibuf
, all_frames
, next_p
)
1686 Lisp_Object window
, minibuf
, all_frames
;
1689 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1691 /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just
1692 return the first window on the frame. */
1693 if (FRAMEP (all_frames
)
1694 && !EQ (all_frames
, XWINDOW (window
)->frame
))
1695 return Fframe_first_window (all_frames
);
1701 /* Find WINDOW in the list of all windows. */
1702 list
= Fmemq (window
, window_list ());
1704 /* Scan forward from WINDOW to the end of the window list. */
1706 for (list
= XCDR (list
); CONSP (list
); list
= XCDR (list
))
1707 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1710 /* Scan from the start of the window list up to WINDOW. */
1712 for (list
= Vwindow_list
;
1713 CONSP (list
) && !EQ (XCAR (list
), window
);
1715 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1719 window
= XCAR (list
);
1723 Lisp_Object candidate
, list
;
1725 /* Scan through the list of windows for candidates. If there are
1726 candidate windows in front of WINDOW, the last one of these
1727 is the one we want. If there are candidates following WINDOW
1728 in the list, again the last one of these is the one we want. */
1730 for (list
= window_list (); CONSP (list
); list
= XCDR (list
))
1732 if (EQ (XCAR (list
), window
))
1734 if (WINDOWP (candidate
))
1737 else if (candidate_window_p (XCAR (list
), window
, minibuf
,
1739 candidate
= XCAR (list
);
1742 if (WINDOWP (candidate
))
1750 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
1751 doc
: /* Return next window after WINDOW in canonical ordering of windows.
1752 If omitted, WINDOW defaults to the selected window.
1754 Optional second arg MINIBUF t means count the minibuffer window even
1755 if not active. MINIBUF nil or omitted means count the minibuffer iff
1756 it is active. MINIBUF neither t nor nil means not to count the
1757 minibuffer even if it is active.
1759 Several frames may share a single minibuffer; if the minibuffer
1760 counts, all windows on all frames that share that minibuffer count
1761 too. Therefore, `next-window' can be used to iterate through the
1762 set of windows even when the minibuffer is on another frame. If the
1763 minibuffer does not count, only windows from WINDOW's frame count.
1765 Optional third arg ALL-FRAMES t means include windows on all frames.
1766 ALL-FRAMES nil or omitted means cycle within the frames as specified
1767 above. ALL-FRAMES = `visible' means include windows on all visible frames.
1768 ALL-FRAMES = 0 means include windows on all visible and iconified frames.
1769 If ALL-FRAMES is a frame, restrict search to windows on that frame.
1770 Anything else means restrict to WINDOW's frame.
1772 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
1773 `next-window' to iterate through the entire cycle of acceptable
1774 windows, eventually ending up back at the window you started with.
1775 `previous-window' traverses the same cycle, in the reverse order. */)
1776 (window
, minibuf
, all_frames
)
1777 Lisp_Object window
, minibuf
, all_frames
;
1779 return next_window (window
, minibuf
, all_frames
, 1);
1783 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
1784 doc
: /* Return the window preceding WINDOW in canonical ordering of windows.
1785 If omitted, WINDOW defaults to the selected window.
1787 Optional second arg MINIBUF t means count the minibuffer window even
1788 if not active. MINIBUF nil or omitted means count the minibuffer iff
1789 it is active. MINIBUF neither t nor nil means not to count the
1790 minibuffer even if it is active.
1792 Several frames may share a single minibuffer; if the minibuffer
1793 counts, all windows on all frames that share that minibuffer count
1794 too. Therefore, `previous-window' can be used to iterate through
1795 the set of windows even when the minibuffer is on another frame. If
1796 the minibuffer does not count, only windows from WINDOW's frame count
1798 Optional third arg ALL-FRAMES t means include windows on all frames.
1799 ALL-FRAMES nil or omitted means cycle within the frames as specified
1800 above. ALL-FRAMES = `visible' means include windows on all visible frames.
1801 ALL-FRAMES = 0 means include windows on all visible and iconified frames.
1802 If ALL-FRAMES is a frame, restrict search to windows on that frame.
1803 Anything else means restrict to WINDOW's frame.
1805 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
1806 `previous-window' to iterate through the entire cycle of acceptable
1807 windows, eventually ending up back at the window you started with.
1808 `next-window' traverses the same cycle, in the reverse order. */)
1809 (window
, minibuf
, all_frames
)
1810 Lisp_Object window
, minibuf
, all_frames
;
1812 return next_window (window
, minibuf
, all_frames
, 0);
1816 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1817 doc
: /* Select the ARG'th different window on this frame.
1818 All windows on current frame are arranged in a cyclic order.
1819 This command selects the window ARG steps away in that order.
1820 A negative ARG moves in the opposite order. The optional second
1821 argument ALL_FRAMES has the same meaning as in `next-window', which see. */)
1823 Lisp_Object arg
, all_frames
;
1829 window
= selected_window
;
1831 for (i
= XINT (arg
); i
> 0; --i
)
1832 window
= Fnext_window (window
, Qnil
, all_frames
);
1834 window
= Fprevious_window (window
, Qnil
, all_frames
);
1836 Fselect_window (window
, Qnil
);
1841 DEFUN ("window-list", Fwindow_list
, Swindow_list
, 0, 3, 0,
1842 doc
: /* Return a list of windows on FRAME, starting with WINDOW.
1843 FRAME nil or omitted means use the selected frame.
1844 WINDOW nil or omitted means use the selected window.
1845 MINIBUF t means include the minibuffer window, even if it isn't active.
1846 MINIBUF nil or omitted means include the minibuffer window only
1848 MINIBUF neither nil nor t means never include the minibuffer window. */)
1849 (frame
, minibuf
, window
)
1850 Lisp_Object frame
, minibuf
, window
;
1853 window
= selected_window
;
1855 frame
= selected_frame
;
1857 if (!EQ (frame
, XWINDOW (window
)->frame
))
1858 error ("Window is on a different frame");
1860 return window_list_1 (window
, minibuf
, frame
);
1864 /* Return a list of windows in canonical ordering. Arguments are like
1865 for `next-window'. */
1868 window_list_1 (window
, minibuf
, all_frames
)
1869 Lisp_Object window
, minibuf
, all_frames
;
1871 Lisp_Object tail
, list
, rest
;
1873 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1876 for (tail
= window_list (); CONSP (tail
); tail
= XCDR (tail
))
1877 if (candidate_window_p (XCAR (tail
), window
, minibuf
, all_frames
))
1878 list
= Fcons (XCAR (tail
), list
);
1880 /* Rotate the list to start with WINDOW. */
1881 list
= Fnreverse (list
);
1882 rest
= Fmemq (window
, list
);
1883 if (!NILP (rest
) && !EQ (rest
, list
))
1885 for (tail
= list
; !EQ (XCDR (tail
), rest
); tail
= XCDR (tail
))
1887 XSETCDR (tail
, Qnil
);
1888 list
= nconc2 (rest
, list
);
1895 /* Look at all windows, performing an operation specified by TYPE
1897 If FRAMES is Qt, look at all frames;
1898 Qnil, look at just the selected frame;
1899 Qvisible, look at visible frames;
1900 a frame, just look at windows on that frame.
1901 If MINI is non-zero, perform the operation on minibuffer windows too. */
1906 GET_BUFFER_WINDOW
, /* Arg is buffer */
1907 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1908 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1909 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1911 UNSHOW_BUFFER
, /* Arg is buffer */
1912 REDISPLAY_BUFFER_WINDOWS
, /* Arg is buffer */
1917 window_loop (type
, obj
, mini
, frames
)
1918 enum window_loop type
;
1919 Lisp_Object obj
, frames
;
1922 Lisp_Object window
, windows
, best_window
, frame_arg
;
1924 struct gcpro gcpro1
;
1926 /* If we're only looping through windows on a particular frame,
1927 frame points to that frame. If we're looping through windows
1928 on all frames, frame is 0. */
1929 if (FRAMEP (frames
))
1930 f
= XFRAME (frames
);
1931 else if (NILP (frames
))
1932 f
= SELECTED_FRAME ();
1937 frame_arg
= Qlambda
;
1938 else if (EQ (frames
, make_number (0)))
1940 else if (EQ (frames
, Qvisible
))
1945 /* frame_arg is Qlambda to stick to one frame,
1946 Qvisible to consider all visible frames,
1949 /* Pick a window to start with. */
1953 window
= FRAME_SELECTED_WINDOW (f
);
1955 window
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
1957 windows
= window_list_1 (window
, mini
? Qt
: Qnil
, frame_arg
);
1961 for (; CONSP (windows
); windows
= CDR (windows
))
1965 window
= XCAR (windows
);
1966 w
= XWINDOW (window
);
1968 /* Note that we do not pay attention here to whether the frame
1969 is visible, since Fwindow_list skips non-visible frames if
1970 that is desired, under the control of frame_arg. */
1971 if (!MINI_WINDOW_P (w
)
1972 /* For UNSHOW_BUFFER, we must always consider all windows. */
1973 || type
== UNSHOW_BUFFER
1974 || (mini
&& minibuf_level
> 0))
1977 case GET_BUFFER_WINDOW
:
1978 if (EQ (w
->buffer
, obj
)
1979 /* Don't find any minibuffer window
1980 except the one that is currently in use. */
1981 && (MINI_WINDOW_P (w
)
1982 ? EQ (window
, minibuf_window
)
1985 if (NILP (best_window
))
1986 best_window
= window
;
1987 else if (EQ (window
, selected_window
))
1988 /* For compatibility with 20.x, prefer to return
1990 best_window
= window
;
1994 case GET_LRU_WINDOW
:
1995 /* t as arg means consider only full-width windows */
1996 if (!NILP (obj
) && !WINDOW_FULL_WIDTH_P (w
))
1998 /* Ignore dedicated windows and minibuffers. */
1999 if (MINI_WINDOW_P (w
) || EQ (w
->dedicated
, Qt
))
2001 if (NILP (best_window
)
2002 || (XFASTINT (XWINDOW (best_window
)->use_time
)
2003 > XFASTINT (w
->use_time
)))
2004 best_window
= window
;
2007 case DELETE_OTHER_WINDOWS
:
2008 if (!EQ (window
, obj
))
2009 Fdelete_window (window
);
2012 case DELETE_BUFFER_WINDOWS
:
2013 if (EQ (w
->buffer
, obj
))
2015 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2017 /* If this window is dedicated, and in a frame of its own,
2019 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
2020 && !NILP (w
->dedicated
)
2021 && other_visible_frames (f
))
2023 /* Skip the other windows on this frame.
2024 There might be one, the minibuffer! */
2025 while (CONSP (XCDR (windows
))
2026 && EQ (XWINDOW (XCAR (windows
))->frame
,
2027 XWINDOW (XCAR (XCDR (windows
)))->frame
))
2028 windows
= XCDR (windows
);
2030 /* Now we can safely delete the frame. */
2031 Fdelete_frame (w
->frame
, Qnil
);
2033 else if (NILP (w
->parent
))
2035 /* If we're deleting the buffer displayed in the
2036 only window on the frame, find a new buffer to
2039 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
2040 Fset_window_buffer (window
, buffer
, Qnil
);
2041 if (EQ (window
, selected_window
))
2042 Fset_buffer (w
->buffer
);
2045 Fdelete_window (window
);
2049 case GET_LARGEST_WINDOW
:
2051 /* Ignore dedicated windows and minibuffers. */
2052 if (MINI_WINDOW_P (w
) || EQ (w
->dedicated
, Qt
))
2055 if (NILP (best_window
))
2056 best_window
= window
;
2059 struct window
*b
= XWINDOW (best_window
);
2060 if (XFASTINT (w
->total_lines
) * XFASTINT (w
->total_cols
)
2061 > XFASTINT (b
->total_lines
) * XFASTINT (b
->total_cols
))
2062 best_window
= window
;
2068 if (EQ (w
->buffer
, obj
))
2071 struct frame
*f
= XFRAME (w
->frame
);
2073 /* Find another buffer to show in this window. */
2074 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
2076 /* If this window is dedicated, and in a frame of its own,
2078 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
2079 && !NILP (w
->dedicated
)
2080 && other_visible_frames (f
))
2082 /* Skip the other windows on this frame.
2083 There might be one, the minibuffer! */
2084 while (CONSP (XCDR (windows
))
2085 && EQ (XWINDOW (XCAR (windows
))->frame
,
2086 XWINDOW (XCAR (XCDR (windows
)))->frame
))
2087 windows
= XCDR (windows
);
2089 /* Now we can safely delete the frame. */
2090 Fdelete_frame (w
->frame
, Qnil
);
2092 else if (!NILP (w
->dedicated
) && !NILP (w
->parent
))
2095 XSETWINDOW (window
, w
);
2096 /* If this window is dedicated and not the only window
2097 in its frame, then kill it. */
2098 Fdelete_window (window
);
2102 /* Otherwise show a different buffer in the window. */
2103 w
->dedicated
= Qnil
;
2104 Fset_window_buffer (window
, buffer
, Qnil
);
2105 if (EQ (window
, selected_window
))
2106 Fset_buffer (w
->buffer
);
2111 case REDISPLAY_BUFFER_WINDOWS
:
2112 if (EQ (w
->buffer
, obj
))
2114 mark_window_display_accurate (window
, 0);
2115 w
->update_mode_line
= Qt
;
2116 XBUFFER (obj
)->prevent_redisplay_optimizations_p
= 1;
2117 ++update_mode_lines
;
2118 best_window
= window
;
2122 /* Check for a window that has a killed buffer. */
2123 case CHECK_ALL_WINDOWS
:
2124 if (! NILP (w
->buffer
)
2125 && NILP (XBUFFER (w
->buffer
)->name
))
2129 case WINDOW_LOOP_UNUSED
:
2138 /* Used for debugging. Abort if any window has a dead buffer. */
2141 check_all_windows ()
2143 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
2146 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
2147 doc
: /* Return the window least recently selected or used for display.
2148 Return a full-width window if possible.
2149 A minibuffer window is never a candidate.
2150 A dedicated window is never a candidate, so if all windows are dedicated,
2152 If optional argument FRAME is `visible', search all visible frames.
2153 If FRAME is 0, search all visible and iconified frames.
2154 If FRAME is t, search all frames.
2155 If FRAME is nil, search only the selected frame.
2156 If FRAME is a frame, search only that frame. */)
2160 register Lisp_Object w
;
2161 /* First try for a window that is full-width */
2162 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frame
);
2163 if (!NILP (w
) && !EQ (w
, selected_window
))
2165 /* If none of them, try the rest */
2166 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frame
);
2169 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
2170 doc
: /* Return the largest window in area.
2171 A minibuffer window is never a candidate.
2172 A dedicated window is never a candidate, so if all windows are dedicated,
2174 If optional argument FRAME is `visible', search all visible frames.
2175 If FRAME is 0, search all visible and iconified frames.
2176 If FRAME is t, search all frames.
2177 If FRAME is nil, search only the selected frame.
2178 If FRAME is a frame, search only that frame. */)
2182 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
2186 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
2187 doc
: /* Return a window currently displaying BUFFER, or nil if none.
2188 BUFFER can be a buffer or a buffer name.
2189 If optional argument FRAME is `visible', search all visible frames.
2190 If optional argument FRAME is 0, search all visible and iconified frames.
2191 If FRAME is t, search all frames.
2192 If FRAME is nil, search only the selected frame.
2193 If FRAME is a frame, search only that frame. */)
2195 Lisp_Object buffer
, frame
;
2197 buffer
= Fget_buffer (buffer
);
2198 if (BUFFERP (buffer
))
2199 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
2204 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
2206 doc
: /* Make WINDOW (or the selected window) fill its frame.
2207 Only the frame WINDOW is on is affected.
2208 This function tries to reduce display jumps
2209 by keeping the text previously visible in WINDOW
2210 in the same place on the frame. Doing this depends on
2211 the value of (window-start WINDOW), so if calling this function
2212 in a program gives strange scrolling, make sure the window-start
2213 value is reasonable when this function is called. */)
2222 window
= selected_window
;
2224 CHECK_LIVE_WINDOW (window
);
2225 w
= XWINDOW (window
);
2227 startpos
= marker_position (w
->start
);
2228 top
= WINDOW_TOP_EDGE_LINE (w
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2230 if (MINI_WINDOW_P (w
) && top
> 0)
2231 error ("Can't expand minibuffer to full frame");
2233 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
2235 /* Try to minimize scrolling, by setting the window start to the point
2236 will cause the text at the old window start to be at the same place
2237 on the frame. But don't try to do this if the window start is
2238 outside the visible portion (as might happen when the display is
2239 not current, due to typeahead). */
2240 new_top
= WINDOW_TOP_EDGE_LINE (w
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2242 && startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
2243 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
2245 struct position pos
;
2246 struct buffer
*obuf
= current_buffer
;
2248 Fset_buffer (w
->buffer
);
2249 /* This computation used to temporarily move point, but that can
2250 have unwanted side effects due to text properties. */
2251 pos
= *vmotion (startpos
, -top
, w
);
2253 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
2254 w
->window_end_valid
= Qnil
;
2255 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
2256 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
2258 /* We need to do this, so that the window-scroll-functions
2260 w
->optional_new_start
= Qt
;
2262 set_buffer_internal (obuf
);
2268 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
2269 1, 2, "bDelete windows on (buffer): ",
2270 doc
: /* Delete all windows showing BUFFER.
2271 BUFFER must be a buffer or the name of an existing buffer.
2272 Optional second argument FRAME controls which frames are affected.
2273 If optional argument FRAME is `visible', search all visible frames.
2274 If FRAME is 0, search all visible and iconified frames.
2275 If FRAME is nil, search all frames.
2276 If FRAME is t, search only the selected frame.
2277 If FRAME is a frame, search only that frame. */)
2279 Lisp_Object buffer
, frame
;
2281 /* FRAME uses t and nil to mean the opposite of what window_loop
2285 else if (EQ (frame
, Qt
))
2290 buffer
= Fget_buffer (buffer
);
2291 CHECK_BUFFER (buffer
);
2292 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
2298 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
2299 Sreplace_buffer_in_windows
,
2300 1, 1, "bReplace buffer in windows: ",
2301 doc
: /* Replace BUFFER with some other buffer in all windows showing it.
2302 BUFFER may be a buffer or the name of an existing buffer. */)
2308 buffer
= Fget_buffer (buffer
);
2309 CHECK_BUFFER (buffer
);
2310 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
2315 /* Replace BUFFER with some other buffer in all windows
2316 of all frames, even those on other keyboards. */
2319 replace_buffer_in_all_windows (buffer
)
2323 Lisp_Object tail
, frame
;
2325 /* A single call to window_loop won't do the job
2326 because it only considers frames on the current keyboard.
2327 So loop manually over frames, and handle each one. */
2328 FOR_EACH_FRAME (tail
, frame
)
2329 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
2331 window_loop (UNSHOW_BUFFER
, buffer
, 1, Qt
);
2335 /* Set the height of WINDOW and all its inferiors. */
2337 /* The smallest acceptable dimensions for a window. Anything smaller
2338 might crash Emacs. */
2340 #define MIN_SAFE_WINDOW_WIDTH (2)
2341 #define MIN_SAFE_WINDOW_HEIGHT (1)
2343 /* Make sure that window_min_height and window_min_width are
2344 not too small; if they are, set them to safe minima. */
2347 check_min_window_sizes ()
2349 /* Smaller values might permit a crash. */
2350 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
2351 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
2352 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
2353 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
2356 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
2357 minimum allowable size. */
2360 check_frame_size (frame
, rows
, cols
)
2364 /* For height, we have to see:
2365 how many windows the frame has at minimum (one or two),
2366 and whether it has a menu bar or other special stuff at the top. */
2368 = ((FRAME_MINIBUF_ONLY_P (frame
) || ! FRAME_HAS_MINIBUF_P (frame
))
2369 ? MIN_SAFE_WINDOW_HEIGHT
2370 : 2 * MIN_SAFE_WINDOW_HEIGHT
);
2372 if (FRAME_TOP_MARGIN (frame
) > 0)
2373 min_height
+= FRAME_TOP_MARGIN (frame
);
2375 if (*rows
< min_height
)
2377 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
2378 *cols
= MIN_SAFE_WINDOW_WIDTH
;
2382 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
2383 check if W's width can be changed, otherwise check W's height.
2384 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
2385 siblings, too. If none of the siblings is resizable, WINDOW isn't
2389 window_fixed_size_p (w
, width_p
, check_siblings_p
)
2391 int width_p
, check_siblings_p
;
2396 if (!NILP (w
->hchild
))
2398 c
= XWINDOW (w
->hchild
);
2402 /* A horiz. combination is fixed-width if all of if its
2404 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2405 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2406 fixed_p
= c
== NULL
;
2410 /* A horiz. combination is fixed-height if one of if its
2412 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2413 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2414 fixed_p
= c
!= NULL
;
2417 else if (!NILP (w
->vchild
))
2419 c
= XWINDOW (w
->vchild
);
2423 /* A vert. combination is fixed-width if one of if its
2425 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2426 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2427 fixed_p
= c
!= NULL
;
2431 /* A vert. combination is fixed-height if all of if its
2433 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2434 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2435 fixed_p
= c
== NULL
;
2438 else if (BUFFERP (w
->buffer
))
2440 struct buffer
*old
= current_buffer
;
2443 current_buffer
= XBUFFER (w
->buffer
);
2444 val
= find_symbol_value (Qwindow_size_fixed
);
2445 current_buffer
= old
;
2448 if (!EQ (val
, Qunbound
))
2450 fixed_p
= !NILP (val
);
2453 && ((EQ (val
, Qheight
) && width_p
)
2454 || (EQ (val
, Qwidth
) && !width_p
)))
2458 /* Can't tell if this one is resizable without looking at
2459 siblings. If all siblings are fixed-size this one is too. */
2460 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
2464 for (child
= w
->prev
; !NILP (child
); child
= XWINDOW (child
)->prev
)
2465 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2469 for (child
= w
->next
; !NILP (child
); child
= XWINDOW (child
)->next
)
2470 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2484 /* Return the minimum size of window W, not taking fixed-width windows
2485 into account. WIDTH_P non-zero means return the minimum width,
2486 otherwise return the minimum height. If W is a combination window,
2487 compute the minimum size from the minimum sizes of W's children. */
2490 window_min_size_1 (w
, width_p
)
2497 if (!NILP (w
->hchild
))
2499 c
= XWINDOW (w
->hchild
);
2504 /* The min width of a horizontal combination is
2505 the sum of the min widths of its children. */
2508 size
+= window_min_size_1 (c
, width_p
);
2509 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2514 /* The min height a horizontal combination equals
2515 the maximum of all min height of its children. */
2518 int min_size
= window_min_size_1 (c
, width_p
);
2519 size
= max (min_size
, size
);
2520 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2524 else if (!NILP (w
->vchild
))
2526 c
= XWINDOW (w
->vchild
);
2531 /* The min width of a vertical combination is
2532 the maximum of the min widths of its children. */
2535 int min_size
= window_min_size_1 (c
, width_p
);
2536 size
= max (min_size
, size
);
2537 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2542 /* The min height of a vertical combination equals
2543 the sum of the min height of its children. */
2546 size
+= window_min_size_1 (c
, width_p
);
2547 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2554 size
= window_min_width
;
2557 if (MINI_WINDOW_P (w
)
2558 || (!WINDOW_WANTS_MODELINE_P (w
)
2559 && !WINDOW_WANTS_HEADER_LINE_P (w
)))
2562 size
= window_min_height
;
2570 /* Return the minimum size of window W, taking fixed-size windows into
2571 account. WIDTH_P non-zero means return the minimum width,
2572 otherwise return the minimum height. IGNORE_FIXED_P non-zero means
2573 ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size
2574 unless FIXED is null. */
2577 window_min_size (w
, width_p
, ignore_fixed_p
, fixed
)
2579 int width_p
, ignore_fixed_p
, *fixed
;
2586 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
2592 size
= width_p
? XFASTINT (w
->total_cols
) : XFASTINT (w
->total_lines
);
2594 size
= window_min_size_1 (w
, width_p
);
2600 /* Adjust the margins of window W if text area is too small.
2601 Return 1 if window width is ok after adjustment; 0 if window
2602 is still too narrow. */
2605 adjust_window_margins (w
)
2608 int box_cols
= (WINDOW_TOTAL_COLS (w
)
2609 - WINDOW_FRINGE_COLS (w
)
2610 - WINDOW_SCROLL_BAR_COLS (w
));
2611 int margin_cols
= (WINDOW_LEFT_MARGIN_COLS (w
)
2612 + WINDOW_RIGHT_MARGIN_COLS (w
));
2614 if (box_cols
- margin_cols
>= MIN_SAFE_WINDOW_WIDTH
)
2617 if (margin_cols
< 0 || box_cols
< MIN_SAFE_WINDOW_WIDTH
)
2620 /* Window's text area is too narrow, but reducing the window
2621 margins will fix that. */
2622 margin_cols
= box_cols
- MIN_SAFE_WINDOW_WIDTH
;
2623 if (WINDOW_RIGHT_MARGIN_COLS (w
) > 0)
2625 if (WINDOW_LEFT_MARGIN_COLS (w
) > 0)
2626 w
->left_margin_cols
= w
->right_margin_cols
2627 = make_number (margin_cols
/2);
2629 w
->right_margin_cols
= make_number (margin_cols
);
2632 w
->left_margin_cols
= make_number (margin_cols
);
2636 /* Calculate new sizes for windows in the list FORWARD when the window size
2637 goes from TOTAL to SIZE. TOTAL must be greater than SIZE.
2638 The number of windows in FORWARD is NCHILDREN, and the number that
2639 can shrink is SHRINKABLE.
2640 The minimum size a window can have is MIN_SIZE.
2641 If we are shrinking fixed windows, RESIZE_FIXED_P is non-zero.
2642 If we are shrinking columns, WIDTH_P is non-zero, otherwise we are
2645 This function returns an allocated array of new sizes that the caller
2646 must free. The size -1 means the window is fixed and RESIZE_FIXED_P
2647 is zero. Array index 0 refers to the first window in FORWARD, 1 to
2648 the second, and so on.
2650 This function tries to keep windows at least at the minimum size
2651 and resize other windows before it resizes any window to zero (i.e.
2652 delete that window).
2654 Windows are resized proportional to their size, so bigger windows
2655 shrink more than smaller windows. */
2657 shrink_windows (total
, size
, nchildren
, shrinkable
,
2658 min_size
, resize_fixed_p
, forward
, width_p
)
2659 int total
, size
, nchildren
, shrinkable
, min_size
;
2660 int resize_fixed_p
, width_p
;
2661 Lisp_Object forward
;
2663 int available_resize
= 0;
2667 int smallest
= total
;
2668 int total_removed
= 0;
2669 int total_shrink
= total
- size
;
2672 new_sizes
= xmalloc (sizeof (*new_sizes
) * nchildren
);
2674 for (i
= 0, child
= forward
; !NILP (child
); child
= c
->next
, ++i
)
2678 c
= XWINDOW (child
);
2679 child_size
= width_p
? XINT (c
->total_cols
) : XINT (c
->total_lines
);
2681 if (! resize_fixed_p
&& window_fixed_size_p (c
, width_p
, 0))
2685 new_sizes
[i
] = child_size
;
2686 if (child_size
> min_size
)
2687 available_resize
+= child_size
- min_size
;
2690 /* We might need to shrink some windows to zero. Find the smallest
2691 windows and set them to 0 until we can fulfil the new size. */
2693 while (shrinkable
> 1 && size
+ available_resize
< total
)
2695 for (i
= 0; i
< nchildren
; ++i
)
2696 if (new_sizes
[i
] > 0 && smallest
> new_sizes
[i
])
2697 smallest
= new_sizes
[i
];
2699 for (i
= 0; i
< nchildren
; ++i
)
2700 if (new_sizes
[i
] == smallest
)
2702 /* Resize this window down to zero. */
2704 if (smallest
> min_size
)
2705 available_resize
-= smallest
- min_size
;
2706 available_resize
+= smallest
;
2708 total_removed
+= smallest
;
2710 /* We don't know what the smallest is now. */
2713 /* Out of for, just remove one window at the time and
2714 check again if we have enough space. */
2719 /* Now, calculate the new sizes. Try to shrink each window
2720 proportional to its size. */
2721 for (i
= 0; i
< nchildren
; ++i
)
2723 if (new_sizes
[i
] > min_size
)
2725 int to_shrink
= total_shrink
*new_sizes
[i
]/total
;
2726 if (new_sizes
[i
] - to_shrink
< min_size
)
2727 to_shrink
= new_sizes
[i
] - min_size
;
2728 new_sizes
[i
] -= to_shrink
;
2729 total_removed
+= to_shrink
;
2733 /* Any reminder due to rounding, we just subtract from windows
2734 that are left and still can be shrunk. */
2735 while (total_shrink
> total_removed
)
2737 int nonzero_sizes
= 0;
2738 int nonzero_idx
= -1;
2740 for (i
= 0; i
< nchildren
; ++i
)
2741 if (new_sizes
[i
] > 0)
2747 for (i
= 0; i
< nchildren
; ++i
)
2748 if (new_sizes
[i
] > min_size
)
2753 /* Out of for, just shrink one window at the time and
2754 check again if we have enough space. */
2759 /* Special case, only one window left. */
2760 if (nonzero_sizes
== 1)
2764 /* Any surplus due to rounding, we add to windows that are left. */
2765 while (total_shrink
< total_removed
)
2767 for (i
= 0; i
< nchildren
; ++i
)
2769 if (new_sizes
[i
] != 0 && total_shrink
< total_removed
)
2781 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
2782 WINDOW's width. Resize WINDOW's children, if any, so that they
2783 keep their proportionate size relative to WINDOW. Propagate
2784 WINDOW's top or left edge position to children. Delete windows
2785 that become too small unless NODELETE_P is non-zero.
2787 If NODELETE_P is 2, that means we do delete windows that are
2788 too small, even if they were too small before! */
2791 size_window (window
, size
, width_p
, nodelete_p
)
2793 int size
, width_p
, nodelete_p
;
2795 struct window
*w
= XWINDOW (window
);
2797 Lisp_Object child
, *forward
, *sideward
;
2798 int old_size
, min_size
, safe_min_size
;
2800 /* We test nodelete_p != 2 and nodelete_p != 1 below, so it
2801 seems like it's too soon to do this here. ++KFS. */
2802 if (nodelete_p
== 2)
2805 check_min_window_sizes ();
2806 size
= max (0, size
);
2808 /* If the window has been "too small" at one point,
2809 don't delete it for being "too small" in the future.
2810 Preserve it as long as that is at all possible. */
2813 old_size
= WINDOW_TOTAL_COLS (w
);
2814 min_size
= window_min_width
;
2815 /* Ensure that there is room for the scroll bar and fringes!
2816 We may reduce display margins though. */
2817 safe_min_size
= (MIN_SAFE_WINDOW_WIDTH
2818 + WINDOW_FRINGE_COLS (w
)
2819 + WINDOW_SCROLL_BAR_COLS (w
));
2823 old_size
= XINT (w
->total_lines
);
2824 min_size
= window_min_height
;
2825 safe_min_size
= MIN_SAFE_WINDOW_HEIGHT
;
2828 if (old_size
< min_size
&& nodelete_p
!= 2)
2829 w
->too_small_ok
= Qt
;
2831 /* Maybe delete WINDOW if it's too small. */
2832 if (nodelete_p
!= 1 && !NILP (w
->parent
))
2834 if (!MINI_WINDOW_P (w
) && !NILP (w
->too_small_ok
))
2835 min_size
= width_p
? MIN_SAFE_WINDOW_WIDTH
: MIN_SAFE_WINDOW_HEIGHT
;
2836 if (min_size
< safe_min_size
)
2837 min_size
= safe_min_size
;
2838 if (size
< min_size
)
2840 delete_window (window
);
2845 /* Set redisplay hints. */
2846 w
->last_modified
= make_number (0);
2847 w
->last_overlay_modified
= make_number (0);
2848 windows_or_buffers_changed
++;
2849 FRAME_WINDOW_SIZES_CHANGED (XFRAME (w
->frame
)) = 1;
2853 sideward
= &w
->vchild
;
2854 forward
= &w
->hchild
;
2855 w
->total_cols
= make_number (size
);
2856 adjust_window_margins (w
);
2860 sideward
= &w
->hchild
;
2861 forward
= &w
->vchild
;
2862 w
->total_lines
= make_number (size
);
2863 w
->orig_total_lines
= Qnil
;
2866 if (!NILP (*sideward
))
2868 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
2870 c
= XWINDOW (child
);
2872 c
->left_col
= w
->left_col
;
2874 c
->top_line
= w
->top_line
;
2875 size_window (child
, size
, width_p
, nodelete_p
);
2878 else if (!NILP (*forward
))
2880 int fixed_size
, each
, extra
, n
;
2881 int resize_fixed_p
, nfixed
;
2882 int last_pos
, first_pos
, nchildren
, total
;
2883 int *new_sizes
= NULL
;
2885 /* Determine the fixed-size portion of the this window, and the
2886 number of child windows. */
2887 fixed_size
= nchildren
= nfixed
= total
= 0;
2888 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
2892 c
= XWINDOW (child
);
2893 child_size
= width_p
? XINT (c
->total_cols
) : XINT (c
->total_lines
);
2894 total
+= child_size
;
2896 if (window_fixed_size_p (c
, width_p
, 0))
2898 fixed_size
+= child_size
;
2903 /* If the new size is smaller than fixed_size, or if there
2904 aren't any resizable windows, allow resizing fixed-size
2906 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
2908 /* Compute how many lines/columns to add/remove to each child. The
2909 value of extra takes care of rounding errors. */
2910 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
2911 if (size
< total
&& n
> 1)
2912 new_sizes
= shrink_windows (total
, size
, nchildren
, n
, min_size
,
2913 resize_fixed_p
, *forward
, width_p
);
2916 each
= (size
- total
) / n
;
2917 extra
= (size
- total
) - n
* each
;
2920 /* Compute new children heights and edge positions. */
2921 first_pos
= width_p
? XINT (w
->left_col
) : XINT (w
->top_line
);
2922 last_pos
= first_pos
;
2923 for (n
= 0, child
= *forward
; !NILP (child
); child
= c
->next
, ++n
)
2925 int new_size
, old_size
;
2927 c
= XWINDOW (child
);
2928 old_size
= width_p
? XFASTINT (c
->total_cols
) : XFASTINT (c
->total_lines
);
2929 new_size
= old_size
;
2931 /* The top or left edge position of this child equals the
2932 bottom or right edge of its predecessor. */
2934 c
->left_col
= make_number (last_pos
);
2936 c
->top_line
= make_number (last_pos
);
2938 /* If this child can be resized, do it. */
2939 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
2941 new_size
= new_sizes
? new_sizes
[n
] : old_size
+ each
+ extra
;
2945 /* Set new height. Note that size_window also propagates
2946 edge positions to children, so it's not a no-op if we
2947 didn't change the child's size. */
2948 size_window (child
, new_size
, width_p
, 1);
2950 /* Remember the bottom/right edge position of this child; it
2951 will be used to set the top/left edge of the next child. */
2952 last_pos
+= new_size
;
2955 if (new_sizes
) xfree (new_sizes
);
2957 /* We should have covered the parent exactly with child windows. */
2958 xassert (size
== last_pos
- first_pos
);
2960 /* Now delete any children that became too small. */
2962 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2965 c
= XWINDOW (child
);
2966 child_size
= width_p
? XINT (c
->total_cols
) : XINT (c
->total_lines
);
2967 size_window (child
, child_size
, width_p
, 2);
2972 /* Set WINDOW's height to HEIGHT, and recursively change the height of
2973 WINDOW's children. NODELETE non-zero means don't delete windows
2974 that become too small in the process. (The caller should check
2975 later and do so if appropriate.) */
2978 set_window_height (window
, height
, nodelete
)
2983 size_window (window
, height
, 0, nodelete
);
2987 /* Set WINDOW's width to WIDTH, and recursively change the width of
2988 WINDOW's children. NODELETE non-zero means don't delete windows
2989 that become too small in the process. (The caller should check
2990 later and do so if appropriate.) */
2993 set_window_width (window
, width
, nodelete
)
2998 size_window (window
, width
, 1, nodelete
);
3001 /* Change window heights in windows rooted in WINDOW by N lines. */
3004 change_window_heights (window
, n
)
3008 struct window
*w
= XWINDOW (window
);
3010 XSETFASTINT (w
->top_line
, XFASTINT (w
->top_line
) + n
);
3011 XSETFASTINT (w
->total_lines
, XFASTINT (w
->total_lines
) - n
);
3013 if (INTEGERP (w
->orig_top_line
))
3014 XSETFASTINT (w
->orig_top_line
, XFASTINT (w
->orig_top_line
) + n
);
3015 if (INTEGERP (w
->orig_total_lines
))
3016 XSETFASTINT (w
->orig_total_lines
, XFASTINT (w
->orig_total_lines
) - n
);
3018 /* Handle just the top child in a vertical split. */
3019 if (!NILP (w
->vchild
))
3020 change_window_heights (w
->vchild
, n
);
3022 /* Adjust all children in a horizontal split. */
3023 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
3025 w
= XWINDOW (window
);
3026 change_window_heights (window
, n
);
3031 int window_select_count
;
3034 Fset_window_buffer_unwind (obuf
)
3041 EXFUN (Fset_window_fringes
, 4);
3042 EXFUN (Fset_window_scroll_bars
, 4);
3044 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
3045 means it's allowed to run hooks. See make_frame for a case where
3046 it's not allowed. KEEP_MARGINS_P non-zero means that the current
3047 margins, fringes, and scroll-bar settings of the window are not
3048 reset from the buffer's local settings. */
3051 set_window_buffer (window
, buffer
, run_hooks_p
, keep_margins_p
)
3052 Lisp_Object window
, buffer
;
3053 int run_hooks_p
, keep_margins_p
;
3055 struct window
*w
= XWINDOW (window
);
3056 struct buffer
*b
= XBUFFER (buffer
);
3057 int count
= SPECPDL_INDEX ();
3061 if (EQ (window
, selected_window
))
3062 b
->last_selected_window
= window
;
3064 /* Let redisplay errors through. */
3065 b
->display_error_modiff
= 0;
3067 /* Update time stamps of buffer display. */
3068 if (INTEGERP (b
->display_count
))
3069 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
3070 b
->display_time
= Fcurrent_time ();
3072 XSETFASTINT (w
->window_end_pos
, 0);
3073 XSETFASTINT (w
->window_end_vpos
, 0);
3074 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
3075 w
->window_end_valid
= Qnil
;
3076 w
->hscroll
= w
->min_hscroll
= make_number (0);
3078 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
3079 set_marker_restricted (w
->start
,
3080 make_number (b
->last_window_start
),
3082 w
->start_at_line_beg
= Qnil
;
3083 w
->force_start
= Qnil
;
3084 XSETFASTINT (w
->last_modified
, 0);
3085 XSETFASTINT (w
->last_overlay_modified
, 0);
3086 windows_or_buffers_changed
++;
3088 /* We must select BUFFER for running the window-scroll-functions.
3089 If WINDOW is selected, switch permanently.
3090 Otherwise, switch but go back to the ambient buffer afterward. */
3091 if (EQ (window
, selected_window
))
3092 Fset_buffer (buffer
);
3093 /* We can't check ! NILP (Vwindow_scroll_functions) here
3094 because that might itself be a local variable. */
3095 else if (window_initialized
)
3097 record_unwind_protect (Fset_window_buffer_unwind
, Fcurrent_buffer ());
3098 Fset_buffer (buffer
);
3101 if (!keep_margins_p
)
3103 /* Set left and right marginal area width etc. from buffer. */
3105 /* This may call adjust_window_margins three times, so
3106 temporarily disable window margins. */
3107 Lisp_Object save_left
= w
->left_margin_cols
;
3108 Lisp_Object save_right
= w
->right_margin_cols
;
3110 w
->left_margin_cols
= w
->right_margin_cols
= Qnil
;
3112 Fset_window_fringes (window
,
3113 b
->left_fringe_width
, b
->right_fringe_width
,
3114 b
->fringes_outside_margins
);
3116 Fset_window_scroll_bars (window
,
3117 b
->scroll_bar_width
,
3118 b
->vertical_scroll_bar_type
, Qnil
);
3120 w
->left_margin_cols
= save_left
;
3121 w
->right_margin_cols
= save_right
;
3123 Fset_window_margins (window
,
3124 b
->left_margin_cols
, b
->right_margin_cols
);
3129 if (! NILP (Vwindow_scroll_functions
))
3130 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
3131 Fmarker_position (w
->start
));
3133 if (! NILP (Vwindow_configuration_change_hook
)
3134 && ! NILP (Vrun_hooks
))
3135 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3138 unbind_to (count
, Qnil
);
3142 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 3, 0,
3143 doc
: /* Make WINDOW display BUFFER as its contents.
3144 BUFFER can be a buffer or the name of an existing buffer.
3145 Optional third arg KEEP-MARGINS non-nil means that WINDOW's current
3146 display margins, fringe widths, and scroll bar settings are maintained;
3147 the default is to reset these from BUFFER's local settings or the frame
3150 This function runs the hook `window-scroll-functions'. */)
3151 (window
, buffer
, keep_margins
)
3152 register Lisp_Object window
, buffer
, keep_margins
;
3154 register Lisp_Object tem
;
3155 register struct window
*w
= decode_window (window
);
3157 XSETWINDOW (window
, w
);
3158 buffer
= Fget_buffer (buffer
);
3159 CHECK_BUFFER (buffer
);
3161 if (NILP (XBUFFER (buffer
)->name
))
3162 error ("Attempt to display deleted buffer");
3166 error ("Window is deleted");
3167 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
3168 is first being set up. */
3170 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
3171 error ("Window is dedicated to `%s'",
3172 SDATA (XBUFFER (tem
)->name
));
3177 set_window_buffer (window
, buffer
, 1, !NILP (keep_margins
));
3181 /* Note that selected_window can be nil
3182 when this is called from Fset_window_configuration. */
3184 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 2, 0,
3185 doc
: /* Select WINDOW. Most editing will apply to WINDOW's buffer.
3186 If WINDOW is not already selected, make WINDOW's buffer current
3187 and make WINDOW the frame's selected window. Return WINDOW.
3188 Optional second arg NORECORD non-nil means
3189 do not put this buffer at the front of the list of recently selected ones.
3191 Note that the main editor command loop
3192 selects the buffer of the selected window before each command. */)
3194 register Lisp_Object window
, norecord
;
3196 register struct window
*w
;
3197 register struct window
*ow
;
3200 CHECK_LIVE_WINDOW (window
);
3202 w
= XWINDOW (window
);
3203 w
->frozen_window_start_p
= 0;
3205 ++window_select_count
;
3206 XSETFASTINT (w
->use_time
, window_select_count
);
3207 if (EQ (window
, selected_window
))
3210 /* Store the current buffer's actual point into the
3211 old selected window. It belongs to that window,
3212 and when the window is not selected, must be in the window. */
3213 if (!NILP (selected_window
))
3215 ow
= XWINDOW (selected_window
);
3216 if (! NILP (ow
->buffer
))
3217 set_marker_both (ow
->pointm
, ow
->buffer
,
3218 BUF_PT (XBUFFER (ow
->buffer
)),
3219 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
3222 selected_window
= window
;
3223 sf
= SELECTED_FRAME ();
3224 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
3226 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
3227 /* Use this rather than Fhandle_switch_frame
3228 so that FRAME_FOCUS_FRAME is moved appropriately as we
3229 move around in the state where a minibuffer in a separate
3231 Fselect_frame (WINDOW_FRAME (w
));
3234 sf
->selected_window
= window
;
3236 if (NILP (norecord
))
3237 record_buffer (w
->buffer
);
3238 Fset_buffer (w
->buffer
);
3240 XBUFFER (w
->buffer
)->last_selected_window
= window
;
3242 /* Go to the point recorded in the window.
3243 This is important when the buffer is in more
3244 than one window. It also matters when
3245 redisplay_window has altered point after scrolling,
3246 because it makes the change only in the window. */
3248 register int new_point
= marker_position (w
->pointm
);
3249 if (new_point
< BEGV
)
3251 else if (new_point
> ZV
)
3257 windows_or_buffers_changed
++;
3262 select_window_norecord (window
)
3265 return Fselect_window (window
, Qt
);
3268 /* Deiconify the frame containing the window WINDOW,
3269 unless it is the selected frame;
3272 The reason for the exception for the selected frame
3273 is that it seems better not to change the selected frames visibility
3274 merely because of displaying a different buffer in it.
3275 The deiconification is useful when a buffer gets shown in
3276 another frame that you were not using lately. */
3279 display_buffer_1 (window
)
3282 Lisp_Object frame
= XWINDOW (window
)->frame
;
3283 FRAME_PTR f
= XFRAME (frame
);
3285 FRAME_SAMPLE_VISIBILITY (f
);
3287 if (EQ (frame
, selected_frame
))
3288 ; /* Assume the selected frame is already visible enough. */
3289 else if (minibuf_level
> 0
3290 && MINI_WINDOW_P (XWINDOW (selected_window
))
3291 && WINDOW_LIVE_P (minibuf_selected_window
)
3292 && EQ (frame
, WINDOW_FRAME (XWINDOW (minibuf_selected_window
))))
3293 ; /* Assume the frame from which we invoked the minibuffer is visible. */
3296 if (FRAME_ICONIFIED_P (f
))
3297 Fmake_frame_visible (frame
);
3298 else if (FRAME_VISIBLE_P (f
))
3299 Fraise_frame (frame
);
3305 DEFUN ("special-display-p", Fspecial_display_p
, Sspecial_display_p
, 1, 1, 0,
3306 doc
: /* Returns non-nil if a buffer named BUFFER-NAME gets a special frame.
3307 If the value is t, `display-buffer' or `pop-to-buffer' would create a
3308 special frame for that buffer using the default frame parameters.
3310 If the value is a list, it is a list of frame parameters that would be used
3311 to make a frame for that buffer.
3312 The variables `special-display-buffer-names'
3313 and `special-display-regexps' control this. */)
3315 Lisp_Object buffer_name
;
3319 CHECK_STRING (buffer_name
);
3321 tem
= Fmember (buffer_name
, Vspecial_display_buffer_names
);
3325 tem
= Fassoc (buffer_name
, Vspecial_display_buffer_names
);
3329 for (tem
= Vspecial_display_regexps
; CONSP (tem
); tem
= XCDR (tem
))
3331 Lisp_Object car
= XCAR (tem
);
3333 && fast_string_match (car
, buffer_name
) >= 0)
3335 else if (CONSP (car
)
3336 && STRINGP (XCAR (car
))
3337 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
3343 DEFUN ("same-window-p", Fsame_window_p
, Ssame_window_p
, 1, 1, 0,
3344 doc
: /* Returns non-nil if a buffer named BUFFER-NAME would use the same window.
3345 More precisely, if `display-buffer' or `pop-to-buffer' would display
3346 that buffer in the selected window rather than (as usual) in some other window.
3347 See `same-window-buffer-names' and `same-window-regexps'. */)
3349 Lisp_Object buffer_name
;
3353 CHECK_STRING (buffer_name
);
3355 tem
= Fmember (buffer_name
, Vsame_window_buffer_names
);
3359 tem
= Fassoc (buffer_name
, Vsame_window_buffer_names
);
3363 for (tem
= Vsame_window_regexps
; CONSP (tem
); tem
= XCDR (tem
))
3365 Lisp_Object car
= XCAR (tem
);
3367 && fast_string_match (car
, buffer_name
) >= 0)
3369 else if (CONSP (car
)
3370 && STRINGP (XCAR (car
))
3371 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
3377 /* Use B so the default is (other-buffer). */
3378 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 3,
3379 "BDisplay buffer: \nP",
3380 doc
: /* Make BUFFER appear in some window but don't select it.
3381 BUFFER must be the name of an existing buffer, or, when called from Lisp,
3383 If BUFFER is shown already in some window, just use that one,
3384 unless the window is the selected window and the optional second
3385 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).
3386 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.
3387 Returns the window displaying BUFFER.
3388 If `display-buffer-reuse-frames' is non-nil, and another frame is currently
3389 displaying BUFFER, then simply raise that frame.
3391 The variables `special-display-buffer-names',
3392 `special-display-regexps', `same-window-buffer-names', and
3393 `same-window-regexps' customize how certain buffer names are handled.
3394 The latter two take effect only if NOT-THIS-WINDOW is t.
3396 If optional argument FRAME is `visible', search all visible frames.
3397 If FRAME is 0, search all visible and iconified frames.
3398 If FRAME is t, search all frames.
3399 If FRAME is a frame, search only that frame.
3400 If FRAME is nil, search only the selected frame
3401 (actually the last nonminibuffer frame),
3402 unless `pop-up-frames' or `display-buffer-reuse-frames' is non-nil,
3403 which means search visible and iconified frames.
3405 If a full-width window on a splittable frame is available to display
3406 the buffer, it may be split, subject to the value of the variable
3407 `split-height-threshold'.
3409 If `even-window-heights' is non-nil, window heights will be evened out
3410 if displaying the buffer causes two vertically adjacent windows to be
3412 (buffer
, not_this_window
, frame
)
3413 register Lisp_Object buffer
, not_this_window
, frame
;
3415 register Lisp_Object window
, tem
, swp
;
3419 buffer
= Fget_buffer (buffer
);
3420 CHECK_BUFFER (buffer
);
3422 if (!NILP (Vdisplay_buffer_function
))
3423 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
3425 if (NILP (not_this_window
)
3426 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
3427 return display_buffer_1 (selected_window
);
3429 /* See if the user has specified this buffer should appear
3430 in the selected window. */
3431 if (NILP (not_this_window
))
3433 swp
= Fsame_window_p (XBUFFER (buffer
)->name
);
3434 if (!NILP (swp
) && !no_switch_window (selected_window
))
3436 Fswitch_to_buffer (buffer
, Qnil
);
3437 return display_buffer_1 (selected_window
);
3441 /* If the user wants pop-up-frames or display-buffer-reuse-frames,
3442 look for a window showing BUFFER on any visible or iconified frame.
3443 Otherwise search only the current frame. */
3446 else if (pop_up_frames
3447 || display_buffer_reuse_frames
3448 || last_nonminibuf_frame
== 0)
3449 XSETFASTINT (tem
, 0);
3451 XSETFRAME (tem
, last_nonminibuf_frame
);
3453 window
= Fget_buffer_window (buffer
, tem
);
3455 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
3456 return display_buffer_1 (window
);
3458 /* Certain buffer names get special handling. */
3459 if (!NILP (Vspecial_display_function
) && NILP (swp
))
3461 tem
= Fspecial_display_p (XBUFFER (buffer
)->name
);
3463 return call1 (Vspecial_display_function
, buffer
);
3465 return call2 (Vspecial_display_function
, buffer
, tem
);
3468 /* If there are no frames open that have more than a minibuffer,
3469 we need to create a new frame. */
3470 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
3472 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
3473 Fset_window_buffer (window
, buffer
, Qnil
);
3474 return display_buffer_1 (window
);
3477 f
= SELECTED_FRAME ();
3479 || FRAME_MINIBUF_ONLY_P (f
)
3480 /* If the current frame is a special display frame,
3481 don't try to reuse its windows. */
3482 || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f
))->dedicated
))
3487 if (FRAME_MINIBUF_ONLY_P (f
))
3488 XSETFRAME (frames
, last_nonminibuf_frame
);
3489 /* Don't try to create a window if we would get an error. */
3490 if (split_height_threshold
< window_min_height
<< 1)
3491 split_height_threshold
= window_min_height
<< 1;
3493 /* Note that both Fget_largest_window and Fget_lru_window
3494 ignore minibuffers and dedicated windows.
3495 This means they can return nil. */
3497 /* If the frame we would try to split cannot be split,
3498 try other frames. */
3499 if (FRAME_NO_SPLIT_P (NILP (frames
) ? f
: last_nonminibuf_frame
))
3501 /* Try visible frames first. */
3502 window
= Fget_largest_window (Qvisible
);
3503 /* If that didn't work, try iconified frames. */
3505 window
= Fget_largest_window (make_number (0));
3507 window
= Fget_largest_window (Qt
);
3510 window
= Fget_largest_window (frames
);
3512 /* If we got a tall enough full-width window that can be split,
3515 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
3516 && window_height (window
) >= split_height_threshold
3517 && WINDOW_FULL_WIDTH_P (XWINDOW (window
)))
3518 window
= Fsplit_window (window
, Qnil
, Qnil
);
3521 Lisp_Object upper
, lower
, other
;
3523 window
= Fget_lru_window (frames
);
3524 /* If the LRU window is selected, and big enough,
3525 and can be split, split it. */
3527 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
3528 && (EQ (window
, selected_window
)
3529 || EQ (XWINDOW (window
)->parent
, Qnil
))
3530 && window_height (window
) >= window_min_height
<< 1)
3531 window
= Fsplit_window (window
, Qnil
, Qnil
);
3532 /* If Fget_lru_window returned nil, try other approaches. */
3534 /* Try visible frames first. */
3536 window
= Fget_buffer_window (buffer
, Qvisible
);
3538 window
= Fget_largest_window (Qvisible
);
3539 /* If that didn't work, try iconified frames. */
3541 window
= Fget_buffer_window (buffer
, make_number (0));
3543 window
= Fget_largest_window (make_number (0));
3544 /* Try invisible frames. */
3546 window
= Fget_buffer_window (buffer
, Qt
);
3548 window
= Fget_largest_window (Qt
);
3549 /* As a last resort, make a new frame. */
3551 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
3552 /* If window appears above or below another,
3553 even out their heights. */
3554 other
= upper
= lower
= Qnil
;
3555 if (!NILP (XWINDOW (window
)->prev
))
3556 other
= upper
= XWINDOW (window
)->prev
, lower
= window
;
3557 if (!NILP (XWINDOW (window
)->next
))
3558 other
= lower
= XWINDOW (window
)->next
, upper
= window
;
3560 && !NILP (Veven_window_heights
)
3561 /* Check that OTHER and WINDOW are vertically arrayed. */
3562 && !EQ (XWINDOW (other
)->top_line
, XWINDOW (window
)->top_line
)
3563 && (XFASTINT (XWINDOW (other
)->total_lines
)
3564 > XFASTINT (XWINDOW (window
)->total_lines
)))
3566 int total
= (XFASTINT (XWINDOW (other
)->total_lines
)
3567 + XFASTINT (XWINDOW (window
)->total_lines
));
3568 enlarge_window (upper
,
3569 total
/ 2 - XFASTINT (XWINDOW (upper
)->total_lines
),
3575 window
= Fget_lru_window (Qnil
);
3577 Fset_window_buffer (window
, buffer
, Qnil
);
3578 return display_buffer_1 (window
);
3582 DEFUN ("force-window-update", Fforce_window_update
, Sforce_window_update
,
3584 doc
: /* Force redisplay of all windows.
3585 If optional arg OBJECT is a window, force redisplay of that window only.
3586 If OBJECT is a buffer or buffer name, force redisplay of all windows
3587 displaying that buffer. */)
3593 windows_or_buffers_changed
++;
3594 update_mode_lines
++;
3598 if (WINDOWP (object
))
3600 struct window
*w
= XWINDOW (object
);
3601 mark_window_display_accurate (object
, 0);
3602 w
->update_mode_line
= Qt
;
3603 if (BUFFERP (w
->buffer
))
3604 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
3605 ++update_mode_lines
;
3609 if (STRINGP (object
))
3610 object
= Fget_buffer (object
);
3611 if (BUFFERP (object
) && !NILP (XBUFFER (object
)->name
))
3613 /* Walk all windows looking for buffer, and force update
3614 of each of those windows. */
3616 object
= window_loop (REDISPLAY_BUFFER_WINDOWS
, object
, 0, Qvisible
);
3617 return NILP (object
) ? Qnil
: Qt
;
3620 /* If nothing suitable was found, just return.
3621 We could signal an error, but this feature will typically be used
3622 asynchronously in timers or process sentinels, so we don't. */
3628 temp_output_buffer_show (buf
)
3629 register Lisp_Object buf
;
3631 register struct buffer
*old
= current_buffer
;
3632 register Lisp_Object window
;
3633 register struct window
*w
;
3635 XBUFFER (buf
)->directory
= current_buffer
->directory
;
3638 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
3642 #if 0 /* rms: there should be no reason for this. */
3643 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
3645 set_buffer_internal (old
);
3647 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
3648 call1 (Vtemp_buffer_show_function
, buf
);
3651 window
= Fdisplay_buffer (buf
, Qnil
, Qnil
);
3653 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
3654 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
3655 Vminibuf_scroll_window
= window
;
3656 w
= XWINDOW (window
);
3657 XSETFASTINT (w
->hscroll
, 0);
3658 XSETFASTINT (w
->min_hscroll
, 0);
3659 set_marker_restricted_both (w
->start
, buf
, BEG
, BEG
);
3660 set_marker_restricted_both (w
->pointm
, buf
, BEG
, BEG
);
3662 /* Run temp-buffer-show-hook, with the chosen window selected
3663 and its buffer current. */
3665 if (!NILP (Vrun_hooks
)
3666 && !NILP (Fboundp (Qtemp_buffer_show_hook
))
3667 && !NILP (Fsymbol_value (Qtemp_buffer_show_hook
)))
3669 int count
= SPECPDL_INDEX ();
3670 Lisp_Object prev_window
, prev_buffer
;
3671 prev_window
= selected_window
;
3672 XSETBUFFER (prev_buffer
, old
);
3674 /* Select the window that was chosen, for running the hook.
3675 Note: Both Fselect_window and select_window_norecord may
3676 set-buffer to the buffer displayed in the window,
3677 so we need to save the current buffer. --stef */
3678 record_unwind_protect (Fset_buffer
, prev_buffer
);
3679 record_unwind_protect (select_window_norecord
, prev_window
);
3680 Fselect_window (window
, Qt
);
3681 Fset_buffer (w
->buffer
);
3682 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
3683 unbind_to (count
, Qnil
);
3689 make_dummy_parent (window
)
3693 register struct window
*o
, *p
;
3696 o
= XWINDOW (window
);
3697 p
= allocate_window ();
3698 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
3699 ((struct Lisp_Vector
*) p
)->contents
[i
]
3700 = ((struct Lisp_Vector
*)o
)->contents
[i
];
3701 XSETWINDOW (new, p
);
3704 XSETFASTINT (p
->sequence_number
, sequence_number
);
3706 /* Put new into window structure in place of window */
3707 replace_window (window
, new);
3720 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
3721 doc
: /* Split WINDOW, putting SIZE lines in the first of the pair.
3722 WINDOW defaults to selected one and SIZE to half its size.
3723 If optional third arg HORFLAG is non-nil, split side by side
3724 and put SIZE columns in the first of the pair. In that case,
3725 SIZE includes that window's scroll bar, or the divider column to its right.
3726 Interactively, all arguments are nil.
3728 Returns the newly created window (which is the lower or rightmost one).
3729 The upper or leftmost window is the original one and remains selected.
3730 See Info node `(elisp)Splitting Windows' for more details and examples.*/)
3731 (window
, size
, horflag
)
3732 Lisp_Object window
, size
, horflag
;
3734 register Lisp_Object
new;
3735 register struct window
*o
, *p
;
3737 register int size_int
;
3740 window
= selected_window
;
3742 CHECK_LIVE_WINDOW (window
);
3744 o
= XWINDOW (window
);
3745 fo
= XFRAME (WINDOW_FRAME (o
));
3749 if (!NILP (horflag
))
3750 /* Calculate the size of the left-hand window, by dividing
3751 the usable space in columns by two.
3752 We round up, since the left-hand window may include
3753 a dividing line, while the right-hand may not. */
3754 size_int
= (XFASTINT (o
->total_cols
) + 1) >> 1;
3756 size_int
= XFASTINT (o
->total_lines
) >> 1;
3760 CHECK_NUMBER (size
);
3761 size_int
= XINT (size
);
3764 if (MINI_WINDOW_P (o
))
3765 error ("Attempt to split minibuffer window");
3766 else if (window_fixed_size_p (o
, !NILP (horflag
), 0))
3767 error ("Attempt to split fixed-size window");
3769 check_min_window_sizes ();
3773 if (size_int
< window_min_height
)
3774 error ("Window height %d too small (after splitting)", size_int
);
3775 if (size_int
+ window_min_height
> XFASTINT (o
->total_lines
))
3776 error ("Window height %d too small (after splitting)",
3777 XFASTINT (o
->total_lines
) - size_int
);
3778 if (NILP (o
->parent
)
3779 || NILP (XWINDOW (o
->parent
)->vchild
))
3781 make_dummy_parent (window
);
3783 XWINDOW (new)->vchild
= window
;
3788 if (size_int
< window_min_width
)
3789 error ("Window width %d too small (after splitting)", size_int
);
3791 if (size_int
+ window_min_width
> XFASTINT (o
->total_cols
))
3792 error ("Window width %d too small (after splitting)",
3793 XFASTINT (o
->total_cols
) - size_int
);
3794 if (NILP (o
->parent
)
3795 || NILP (XWINDOW (o
->parent
)->hchild
))
3797 make_dummy_parent (window
);
3799 XWINDOW (new)->hchild
= window
;
3803 /* Now we know that window's parent is a vertical combination
3804 if we are dividing vertically, or a horizontal combination
3805 if we are making side-by-side windows */
3807 windows_or_buffers_changed
++;
3808 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
3809 new = make_window ();
3812 p
->frame
= o
->frame
;
3814 if (!NILP (p
->next
))
3815 XWINDOW (p
->next
)->prev
= new;
3818 p
->parent
= o
->parent
;
3820 p
->window_end_valid
= Qnil
;
3821 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
3823 /* Duplicate special geometry settings. */
3825 p
->left_margin_cols
= o
->left_margin_cols
;
3826 p
->right_margin_cols
= o
->right_margin_cols
;
3827 p
->left_fringe_width
= o
->left_fringe_width
;
3828 p
->right_fringe_width
= o
->right_fringe_width
;
3829 p
->fringes_outside_margins
= o
->fringes_outside_margins
;
3830 p
->scroll_bar_width
= o
->scroll_bar_width
;
3831 p
->vertical_scroll_bar_type
= o
->vertical_scroll_bar_type
;
3833 /* Apportion the available frame space among the two new windows */
3835 if (!NILP (horflag
))
3837 p
->total_lines
= o
->total_lines
;
3838 p
->top_line
= o
->top_line
;
3839 XSETFASTINT (p
->total_cols
, XFASTINT (o
->total_cols
) - size_int
);
3840 XSETFASTINT (o
->total_cols
, size_int
);
3841 XSETFASTINT (p
->left_col
, XFASTINT (o
->left_col
) + size_int
);
3842 adjust_window_margins (p
);
3843 adjust_window_margins (o
);
3847 p
->left_col
= o
->left_col
;
3848 p
->total_cols
= o
->total_cols
;
3849 XSETFASTINT (p
->total_lines
, XFASTINT (o
->total_lines
) - size_int
);
3850 XSETFASTINT (o
->total_lines
, size_int
);
3851 XSETFASTINT (p
->top_line
, XFASTINT (o
->top_line
) + size_int
);
3854 /* Adjust glyph matrices. */
3857 Fset_window_buffer (new, o
->buffer
, Qt
);
3861 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 3, "p",
3862 doc
: /* Make current window ARG lines bigger.
3863 From program, optional second arg non-nil means grow sideways ARG columns.
3864 Interactively, if an argument is not given, make the window one line bigger.
3866 Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size
3867 of the siblings above or to the left of the selected window. Only
3868 siblings to the right or below are changed. */)
3869 (arg
, side
, preserve_before
)
3870 register Lisp_Object arg
, side
, preserve_before
;
3873 enlarge_window (selected_window
, XINT (arg
), !NILP (side
),
3874 !NILP (preserve_before
));
3876 if (! NILP (Vwindow_configuration_change_hook
))
3877 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3882 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 3, "p",
3883 doc
: /* Make current window ARG lines smaller.
3884 From program, optional second arg non-nil means shrink sideways arg columns.
3885 Interactively, if an argument is not given, make the window one line smaller.
3887 Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size
3888 of the siblings above or to the left of the selected window. Only
3889 siblings to the right or below are changed. */)
3890 (arg
, side
, preserve_before
)
3891 register Lisp_Object arg
, side
, preserve_before
;
3894 enlarge_window (selected_window
, -XINT (arg
), !NILP (side
),
3895 !NILP (preserve_before
));
3897 if (! NILP (Vwindow_configuration_change_hook
))
3898 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3904 window_height (window
)
3907 register struct window
*p
= XWINDOW (window
);
3908 return WINDOW_TOTAL_LINES (p
);
3912 window_width (window
)
3915 register struct window
*p
= XWINDOW (window
);
3916 return WINDOW_TOTAL_COLS (p
);
3921 *(widthflag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
3923 #define CURSIZE(w) \
3924 *(widthflag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
3927 /* Enlarge WINDOW by DELTA. WIDTHFLAG non-zero means
3928 increase its width. Siblings of the selected window are resized to
3929 fulfill the size request. If they become too small in the process,
3930 they will be deleted.
3932 If PRESERVE_BEFORE is nonzero, that means don't alter
3933 the siblings to the left or above WINDOW. */
3936 enlarge_window (window
, delta
, widthflag
, preserve_before
)
3938 int delta
, widthflag
, preserve_before
;
3940 Lisp_Object parent
, next
, prev
;
3944 int (*sizefun
) P_ ((Lisp_Object
))
3945 = widthflag
? window_width
: window_height
;
3946 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
3947 = (widthflag
? set_window_width
: set_window_height
);
3949 /* Check values of window_min_width and window_min_height for
3951 check_min_window_sizes ();
3953 /* Give up if this window cannot be resized. */
3954 if (window_fixed_size_p (XWINDOW (window
), widthflag
, 1))
3955 error ("Window is not resizable");
3957 /* Find the parent of the selected window. */
3960 p
= XWINDOW (window
);
3966 error ("No other window to side of this one");
3971 ? !NILP (XWINDOW (parent
)->hchild
)
3972 : !NILP (XWINDOW (parent
)->vchild
))
3978 sizep
= &CURSIZE (window
);
3981 register int maxdelta
;
3983 /* Compute the maximum size increment this window can have. */
3985 if (preserve_before
)
3989 maxdelta
= (*sizefun
) (parent
) - XINT (*sizep
);
3990 /* Subtract size of siblings before, since we can't take that. */
3991 maxdelta
-= XINT (CURBEG (window
)) - XINT (CURBEG (parent
));
3994 maxdelta
= (!NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3995 - window_min_size (XWINDOW (p
->next
),
4000 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - XINT (*sizep
)
4001 /* This is a main window followed by a minibuffer. */
4002 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
4003 - window_min_size (XWINDOW (p
->next
),
4005 /* This is a minibuffer following a main window. */
4006 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
4007 - window_min_size (XWINDOW (p
->prev
),
4009 /* This is a frame with only one window, a minibuffer-only
4010 or a minibufferless frame. */
4013 if (delta
> maxdelta
)
4014 /* This case traps trying to make the minibuffer
4015 the full frame, or make the only window aside from the
4016 minibuffer the full frame. */
4020 if (XINT (*sizep
) + delta
< window_min_size (XWINDOW (window
), widthflag
, 0, 0))
4022 delete_window (window
);
4029 /* Find the total we can get from other siblings without deleting them. */
4031 for (next
= p
->next
; ! NILP (next
); next
= XWINDOW (next
)->next
)
4032 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
4034 if (! preserve_before
)
4035 for (prev
= p
->prev
; ! NILP (prev
); prev
= XWINDOW (prev
)->prev
)
4036 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
4039 /* If we can get it all from them without deleting them, do so. */
4040 if (delta
<= maximum
)
4042 Lisp_Object first_unaffected
;
4043 Lisp_Object first_affected
;
4048 first_affected
= window
;
4049 /* Look at one sibling at a time,
4050 moving away from this window in both directions alternately,
4051 and take as much as we can get without deleting that sibling. */
4053 && (!NILP (next
) || (!preserve_before
&& !NILP (prev
))))
4057 int this_one
= ((*sizefun
) (next
)
4058 - window_min_size (XWINDOW (next
),
4059 widthflag
, 0, &fixed_p
));
4062 if (this_one
> delta
)
4065 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
4066 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
4071 next
= XWINDOW (next
)->next
;
4077 if (!preserve_before
&& ! NILP (prev
))
4079 int this_one
= ((*sizefun
) (prev
)
4080 - window_min_size (XWINDOW (prev
),
4081 widthflag
, 0, &fixed_p
));
4084 if (this_one
> delta
)
4087 first_affected
= prev
;
4089 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
4090 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
4095 prev
= XWINDOW (prev
)->prev
;
4099 xassert (delta
== 0);
4101 /* Now recalculate the edge positions of all the windows affected,
4102 based on the new sizes. */
4103 first_unaffected
= next
;
4104 prev
= first_affected
;
4105 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
4106 prev
= next
, next
= XWINDOW (next
)->next
)
4108 XSETINT (CURBEG (next
), XINT (CURBEG (prev
)) + (*sizefun
) (prev
));
4109 /* This does not change size of NEXT,
4110 but it propagates the new top edge to its children */
4111 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
4116 register int delta1
;
4117 register int opht
= (*sizefun
) (parent
);
4119 if (opht
<= XINT (*sizep
) + delta
)
4121 /* If trying to grow this window to or beyond size of the parent,
4122 just delete all the sibling windows. */
4123 Lisp_Object start
, tem
, next
;
4125 start
= XWINDOW (parent
)->vchild
;
4127 start
= XWINDOW (parent
)->hchild
;
4129 /* Delete any siblings that come after WINDOW. */
4130 tem
= XWINDOW (window
)->next
;
4131 while (! NILP (tem
))
4133 next
= XWINDOW (tem
)->next
;
4134 delete_window (tem
);
4138 /* Delete any siblings that come after WINDOW.
4139 Note that if START is not WINDOW, then WINDOW still
4140 Fhas siblings, so WINDOW has not yet replaced its parent. */
4142 while (! EQ (tem
, window
))
4144 next
= XWINDOW (tem
)->next
;
4145 delete_window (tem
);
4151 /* Otherwise, make delta1 just right so that if we add
4152 delta1 lines to this window and to the parent, and then
4153 shrink the parent back to its original size, the new
4154 proportional size of this window will increase by delta.
4156 The function size_window will compute the new height h'
4157 of the window from delta1 as:
4160 x = delta1 - delta1/n * n for the 1st resizable child
4163 where n is the number of children that can be resized.
4164 We can ignore x by choosing a delta1 that is a multiple of
4165 n. We want the height of this window to come out as
4175 The number of children n equals the number of resizable
4176 children of this window + 1 because we know window itself
4177 is resizable (otherwise we would have signalled an error). */
4179 struct window
*w
= XWINDOW (window
);
4183 for (s
= w
->next
; !NILP (s
); s
= XWINDOW (s
)->next
)
4184 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
4186 for (s
= w
->prev
; !NILP (s
); s
= XWINDOW (s
)->prev
)
4187 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
4192 /* Add delta1 lines or columns to this window, and to the parent,
4193 keeping things consistent while not affecting siblings. */
4194 XSETINT (CURSIZE (parent
), opht
+ delta1
);
4195 (*setsizefun
) (window
, XINT (*sizep
) + delta1
, 0);
4197 /* Squeeze out delta1 lines or columns from our parent,
4198 shriking this window and siblings proportionately.
4199 This brings parent back to correct size.
4200 Delta1 was calculated so this makes this window the desired size,
4201 taking it all out of the siblings. */
4202 (*setsizefun
) (parent
, opht
, 0);
4207 XSETFASTINT (p
->last_modified
, 0);
4208 XSETFASTINT (p
->last_overlay_modified
, 0);
4210 /* Adjust glyph matrices. */
4211 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
4219 /***********************************************************************
4220 Resizing Mini-Windows
4221 ***********************************************************************/
4223 static void shrink_window_lowest_first
P_ ((struct window
*, int));
4225 enum save_restore_action
4232 static int save_restore_orig_size
P_ ((struct window
*,
4233 enum save_restore_action
));
4235 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
4236 from lowest windows first. */
4239 shrink_window_lowest_first (w
, height
)
4247 xassert (!MINI_WINDOW_P (w
));
4249 /* Set redisplay hints. */
4250 XSETFASTINT (w
->last_modified
, 0);
4251 XSETFASTINT (w
->last_overlay_modified
, 0);
4252 windows_or_buffers_changed
++;
4253 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
4255 old_height
= XFASTINT (w
->total_lines
);
4256 XSETFASTINT (w
->total_lines
, height
);
4258 if (!NILP (w
->hchild
))
4260 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
4262 c
= XWINDOW (child
);
4263 c
->top_line
= w
->top_line
;
4264 shrink_window_lowest_first (c
, height
);
4267 else if (!NILP (w
->vchild
))
4269 Lisp_Object last_child
;
4270 int delta
= old_height
- height
;
4275 /* Find the last child. We are taking space from lowest windows
4276 first, so we iterate over children from the last child
4278 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
4281 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
4282 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
4286 c
= XWINDOW (child
);
4287 this_one
= XFASTINT (c
->total_lines
) - MIN_SAFE_WINDOW_HEIGHT
;
4289 if (this_one
> delta
)
4292 shrink_window_lowest_first (c
, XFASTINT (c
->total_lines
) - this_one
);
4296 /* Compute new positions. */
4297 last_top
= XINT (w
->top_line
);
4298 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
4300 c
= XWINDOW (child
);
4301 c
->top_line
= make_number (last_top
);
4302 shrink_window_lowest_first (c
, XFASTINT (c
->total_lines
));
4303 last_top
+= XFASTINT (c
->total_lines
);
4309 /* Save, restore, or check positions and sizes in the window tree
4310 rooted at W. ACTION says what to do.
4312 If ACTION is CHECK_ORIG_SIZES, check if orig_top_line and
4313 orig_total_lines members are valid for all windows in the window
4314 tree. Value is non-zero if they are valid.
4316 If ACTION is SAVE_ORIG_SIZES, save members top and height in
4317 orig_top_line and orig_total_lines for all windows in the tree.
4319 If ACTION is RESTORE_ORIG_SIZES, restore top and height from values
4320 stored in orig_top_line and orig_total_lines for all windows. */
4323 save_restore_orig_size (w
, action
)
4325 enum save_restore_action action
;
4331 if (!NILP (w
->hchild
))
4333 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
4336 else if (!NILP (w
->vchild
))
4338 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
4344 case CHECK_ORIG_SIZES
:
4345 if (!INTEGERP (w
->orig_top_line
) || !INTEGERP (w
->orig_total_lines
))
4349 case SAVE_ORIG_SIZES
:
4350 w
->orig_top_line
= w
->top_line
;
4351 w
->orig_total_lines
= w
->total_lines
;
4352 XSETFASTINT (w
->last_modified
, 0);
4353 XSETFASTINT (w
->last_overlay_modified
, 0);
4356 case RESTORE_ORIG_SIZES
:
4357 xassert (INTEGERP (w
->orig_top_line
) && INTEGERP (w
->orig_total_lines
));
4358 w
->top_line
= w
->orig_top_line
;
4359 w
->total_lines
= w
->orig_total_lines
;
4360 w
->orig_total_lines
= w
->orig_top_line
= Qnil
;
4361 XSETFASTINT (w
->last_modified
, 0);
4362 XSETFASTINT (w
->last_overlay_modified
, 0);
4369 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
4376 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
4377 without deleting other windows. */
4380 grow_mini_window (w
, delta
)
4384 struct frame
*f
= XFRAME (w
->frame
);
4385 struct window
*root
;
4387 xassert (MINI_WINDOW_P (w
));
4388 xassert (delta
>= 0);
4390 /* Check values of window_min_width and window_min_height for
4392 check_min_window_sizes ();
4394 /* Compute how much we can enlarge the mini-window without deleting
4396 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4399 int min_height
= window_min_size (root
, 0, 0, 0);
4400 if (XFASTINT (root
->total_lines
) - delta
< min_height
)
4401 /* Note that the root window may already be smaller than
4403 delta
= max (0, XFASTINT (root
->total_lines
) - min_height
);
4408 /* Save original window sizes and positions, if not already done. */
4409 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
4410 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
4412 /* Shrink other windows. */
4413 shrink_window_lowest_first (root
, XFASTINT (root
->total_lines
) - delta
);
4415 /* Grow the mini-window. */
4416 w
->top_line
= make_number (XFASTINT (root
->top_line
) + XFASTINT (root
->total_lines
));
4417 w
->total_lines
= make_number (XFASTINT (w
->total_lines
) + delta
);
4418 XSETFASTINT (w
->last_modified
, 0);
4419 XSETFASTINT (w
->last_overlay_modified
, 0);
4426 /* Shrink mini-window W. If there is recorded info about window sizes
4427 before a call to grow_mini_window, restore recorded window sizes.
4428 Otherwise, if the mini-window is higher than 1 line, resize it to 1
4432 shrink_mini_window (w
)
4435 struct frame
*f
= XFRAME (w
->frame
);
4436 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4438 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
4440 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
4442 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4443 windows_or_buffers_changed
= 1;
4445 else if (XFASTINT (w
->total_lines
) > 1)
4447 /* Distribute the additional lines of the mini-window
4448 among the other windows. */
4450 XSETWINDOW (window
, w
);
4451 enlarge_window (window
, 1 - XFASTINT (w
->total_lines
), 0, 0);
4457 /* Mark window cursors off for all windows in the window tree rooted
4458 at W by setting their phys_cursor_on_p flag to zero. Called from
4459 xterm.c, e.g. when a frame is cleared and thereby all cursors on
4460 the frame are cleared. */
4463 mark_window_cursors_off (w
)
4468 if (!NILP (w
->hchild
))
4469 mark_window_cursors_off (XWINDOW (w
->hchild
));
4470 else if (!NILP (w
->vchild
))
4471 mark_window_cursors_off (XWINDOW (w
->vchild
));
4473 w
->phys_cursor_on_p
= 0;
4475 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4480 /* Return number of lines of text (not counting mode lines) in W. */
4483 window_internal_height (w
)
4486 int ht
= XFASTINT (w
->total_lines
);
4488 if (!MINI_WINDOW_P (w
))
4490 if (!NILP (w
->parent
)
4491 || !NILP (w
->vchild
)
4492 || !NILP (w
->hchild
)
4495 || WINDOW_WANTS_MODELINE_P (w
))
4498 if (WINDOW_WANTS_HEADER_LINE_P (w
))
4506 /* Return the number of columns in W.
4507 Don't count columns occupied by scroll bars or the vertical bar
4508 separating W from the sibling to its right. */
4511 window_box_text_cols (w
)
4514 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4515 int width
= XINT (w
->total_cols
);
4517 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
4518 /* Scroll bars occupy a few columns. */
4519 width
-= WINDOW_CONFIG_SCROLL_BAR_COLS (w
);
4520 else if (!FRAME_WINDOW_P (f
)
4521 && !WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
4522 /* The column of `|' characters separating side-by-side windows
4523 occupies one column only. */
4526 if (FRAME_WINDOW_P (f
))
4527 /* On window-systems, fringes and display margins cannot be
4528 used for normal text. */
4529 width
-= (WINDOW_FRINGE_COLS (w
)
4530 + WINDOW_LEFT_MARGIN_COLS (w
)
4531 + WINDOW_RIGHT_MARGIN_COLS (w
));
4537 /************************************************************************
4539 ***********************************************************************/
4541 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
4542 N screen-fulls, which is defined as the height of the window minus
4543 next_screen_context_lines. If WHOLE is zero, scroll up N lines
4544 instead. Negative values of N mean scroll down. NOERROR non-zero
4545 means don't signal an error if we try to move over BEGV or ZV,
4549 window_scroll (window
, n
, whole
, noerror
)
4557 /* If we must, use the pixel-based version which is much slower than
4558 the line-based one but can handle varying line heights. */
4559 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
4560 window_scroll_pixel_based (window
, n
, whole
, noerror
);
4562 window_scroll_line_based (window
, n
, whole
, noerror
);
4568 /* Implementation of window_scroll that works based on pixel line
4569 heights. See the comment of window_scroll for parameter
4573 window_scroll_pixel_based (window
, n
, whole
, noerror
)
4580 struct window
*w
= XWINDOW (window
);
4581 struct text_pos start
;
4583 int this_scroll_margin
;
4585 /* True if we fiddled the window vscroll field without really scrolling. */
4588 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4590 /* If PT is not visible in WINDOW, move back one half of
4591 the screen. Allow PT to be partially visible, otherwise
4592 something like (scroll-down 1) with PT in the line before
4593 the partially visible one would recenter. */
4594 tem
= Fpos_visible_in_window_p (make_number (PT
), window
, Qt
);
4597 /* Move backward half the height of the window. Performance note:
4598 vmotion used here is about 10% faster, but would give wrong
4599 results for variable height lines. */
4600 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4601 it
.current_y
= it
.last_visible_y
;
4602 move_it_vertically_backward (&it
, window_box_height (w
) / 2);
4604 /* The function move_iterator_vertically may move over more than
4605 the specified y-distance. If it->w is small, e.g. a
4606 mini-buffer window, we may end up in front of the window's
4607 display area. This is the case when Start displaying at the
4608 start of the line containing PT in this case. */
4609 if (it
.current_y
<= 0)
4611 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4612 move_it_vertically_backward (&it
, 0);
4616 start
= it
.current
.pos
;
4618 else if (auto_window_vscroll_p
)
4620 if (tem
= XCAR (XCDR (XCDR (tem
))), CONSP (tem
))
4623 int dy
= WINDOW_FRAME_LINE_HEIGHT (w
);
4625 dy
= max ((window_box_height (w
)
4626 - next_screen_context_lines
* dy
),
4630 if (n
< 0 && (px
= XINT (XCAR (tem
))) > 0)
4632 px
= max (0, -w
->vscroll
- min (px
, -dy
));
4633 Fset_window_vscroll (window
, make_number (px
), Qt
);
4636 if (n
> 0 && (px
= XINT (XCDR (tem
))) > 0)
4638 px
= max (0, -w
->vscroll
+ min (px
, dy
));
4639 Fset_window_vscroll (window
, make_number (px
), Qt
);
4643 Fset_window_vscroll (window
, make_number (0), Qt
);
4646 /* If scroll_preserve_screen_position is non-nil, we try to set
4647 point in the same window line as it is now, so get that line. */
4648 if (!NILP (Vscroll_preserve_screen_position
))
4650 start_display (&it
, w
, start
);
4651 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
4652 preserve_y
= it
.current_y
;
4657 /* Move iterator it from start the specified distance forward or
4658 backward. The result is the new window start. */
4659 start_display (&it
, w
, start
);
4662 int start_pos
= IT_CHARPOS (it
);
4663 int dy
= WINDOW_FRAME_LINE_HEIGHT (w
);
4664 dy
= max ((window_box_height (w
)
4665 - next_screen_context_lines
* dy
),
4668 /* Note that move_it_vertically always moves the iterator to the
4669 start of a line. So, if the last line doesn't have a newline,
4670 we would end up at the start of the line ending at ZV. */
4673 move_it_vertically_backward (&it
, -dy
);
4674 /* Ensure we actually does move, e.g. in case we are currently
4675 looking at an image that is taller that the window height. */
4676 while (start_pos
== IT_CHARPOS (it
)
4677 && start_pos
> BEGV
)
4678 move_it_by_lines (&it
, -1, 1);
4682 move_it_to (&it
, ZV
, -1, it
.current_y
+ dy
, -1,
4683 MOVE_TO_POS
| MOVE_TO_Y
);
4684 /* Ensure we actually does move, e.g. in case we are currently
4685 looking at an image that is taller that the window height. */
4686 while (start_pos
== IT_CHARPOS (it
)
4688 move_it_by_lines (&it
, 1, 1);
4692 move_it_by_lines (&it
, n
, 1);
4694 /* We failed if we find ZV is already on the screen (scrolling up,
4695 means there's nothing past the end), or if we can't start any
4696 earlier (scrolling down, means there's nothing past the top). */
4697 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
4698 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
4700 if (IT_CHARPOS (it
) == ZV
)
4702 if (it
.current_y
< it
.last_visible_y
4703 && (it
.current_y
+ it
.max_ascent
+ it
.max_descent
4704 >= it
.last_visible_y
))
4706 /* The last line was only partially visible, make it fully
4708 w
->vscroll
= (it
.last_visible_y
4709 - it
.current_y
+ it
.max_ascent
+ it
.max_descent
);
4710 adjust_glyphs (it
.f
);
4715 Fsignal (Qend_of_buffer
, Qnil
);
4719 if (w
->vscroll
!= 0)
4720 /* The first line was only partially visible, make it fully
4726 Fsignal (Qbeginning_of_buffer
, Qnil
);
4729 /* If control gets here, then we vscrolled. */
4731 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
4733 /* Don't try to change the window start below. */
4739 int pos
= IT_CHARPOS (it
);
4742 /* If in the middle of a multi-glyph character move forward to
4743 the next character. */
4744 if (in_display_vector_p (&it
))
4747 move_it_to (&it
, pos
, -1, -1, -1, MOVE_TO_POS
);
4750 /* Set the window start, and set up the window for redisplay. */
4751 set_marker_restricted (w
->start
, make_number (pos
),
4753 bytepos
= XMARKER (w
->start
)->bytepos
;
4754 w
->start_at_line_beg
= ((pos
== BEGV
|| FETCH_BYTE (bytepos
- 1) == '\n')
4756 w
->update_mode_line
= Qt
;
4757 XSETFASTINT (w
->last_modified
, 0);
4758 XSETFASTINT (w
->last_overlay_modified
, 0);
4759 /* Set force_start so that redisplay_window will run the
4760 window-scroll-functions. */
4761 w
->force_start
= Qt
;
4764 /* The rest of this function uses current_y in a nonstandard way,
4765 not including the height of the header line if any. */
4766 it
.current_y
= it
.vpos
= 0;
4768 /* Move PT out of scroll margins.
4769 This code wants current_y to be zero at the window start position
4770 even if there is a header line. */
4771 this_scroll_margin
= max (0, scroll_margin
);
4772 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->total_lines
) / 4);
4773 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
4777 /* We moved the window start towards ZV, so PT may be now
4778 in the scroll margin at the top. */
4779 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
4780 if (IT_CHARPOS (it
) == PT
&& it
.current_y
>= this_scroll_margin
4781 && (NILP (Vscroll_preserve_screen_position
)
4782 || EQ (Vscroll_preserve_screen_position
, Qt
)))
4783 /* We found PT at a legitimate height. Leave it alone. */
4785 else if (preserve_y
>= 0)
4787 /* If we have a header line, take account of it.
4788 This is necessary because we set it.current_y to 0, above. */
4789 if (WINDOW_WANTS_HEADER_LINE_P (w
))
4790 preserve_y
-= CURRENT_HEADER_LINE_HEIGHT (w
);
4792 move_it_to (&it
, -1, -1, preserve_y
, -1, MOVE_TO_Y
);
4793 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4797 while (it
.current_y
< this_scroll_margin
)
4799 int prev
= it
.current_y
;
4800 move_it_by_lines (&it
, 1, 1);
4801 if (prev
== it
.current_y
)
4804 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4809 int charpos
, bytepos
;
4812 /* Save our position, for the preserve_y case. */
4813 charpos
= IT_CHARPOS (it
);
4814 bytepos
= IT_BYTEPOS (it
);
4816 /* We moved the window start towards BEGV, so PT may be now
4817 in the scroll margin at the bottom. */
4818 move_it_to (&it
, PT
, -1,
4819 (it
.last_visible_y
- CURRENT_HEADER_LINE_HEIGHT (w
)
4820 - this_scroll_margin
- 1),
4822 MOVE_TO_POS
| MOVE_TO_Y
);
4824 /* Save our position, in case it's correct. */
4825 charpos
= IT_CHARPOS (it
);
4826 bytepos
= IT_BYTEPOS (it
);
4828 /* See if point is on a partially visible line at the end. */
4829 if (it
.what
== IT_EOB
)
4830 partial_p
= it
.current_y
+ it
.ascent
+ it
.descent
> it
.last_visible_y
;
4833 move_it_by_lines (&it
, 1, 1);
4834 partial_p
= it
.current_y
> it
.last_visible_y
;
4837 if (charpos
== PT
&& !partial_p
4838 && (NILP (Vscroll_preserve_screen_position
)
4839 || EQ (Vscroll_preserve_screen_position
, Qt
)))
4840 /* We found PT before we found the display margin, so PT is ok. */
4842 else if (preserve_y
>= 0)
4844 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4845 start_display (&it
, w
, start
);
4846 #if 0 /* It's wrong to subtract this here
4847 because we called start_display again
4848 and did not alter it.current_y this time. */
4850 /* If we have a header line, take account of it. */
4851 if (WINDOW_WANTS_HEADER_LINE_P (w
))
4852 preserve_y
-= CURRENT_HEADER_LINE_HEIGHT (w
);
4855 move_it_to (&it
, -1, -1, preserve_y
, -1, MOVE_TO_Y
);
4856 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4861 /* The last line was only partially visible, so back up two
4862 lines to make sure we're on a fully visible line. */
4864 move_it_by_lines (&it
, -2, 0);
4865 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4868 /* No, the position we saved is OK, so use it. */
4869 SET_PT_BOTH (charpos
, bytepos
);
4875 /* Implementation of window_scroll that works based on screen lines.
4876 See the comment of window_scroll for parameter descriptions. */
4879 window_scroll_line_based (window
, n
, whole
, noerror
)
4885 register struct window
*w
= XWINDOW (window
);
4886 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
4887 register int pos
, pos_byte
;
4888 register int ht
= window_internal_height (w
);
4889 register Lisp_Object tem
;
4893 struct position posit
;
4896 /* If scrolling screen-fulls, compute the number of lines to
4897 scroll from the window's height. */
4899 n
*= max (1, ht
- next_screen_context_lines
);
4901 startpos
= marker_position (w
->start
);
4903 posit
= *compute_motion (startpos
, 0, 0, 0,
4905 -1, XINT (w
->hscroll
),
4907 original_vpos
= posit
.vpos
;
4909 XSETFASTINT (tem
, PT
);
4910 tem
= Fpos_visible_in_window_p (tem
, window
, Qnil
);
4914 Fvertical_motion (make_number (- (ht
/ 2)), window
);
4919 lose
= n
< 0 && PT
== BEGV
;
4920 Fvertical_motion (make_number (n
), window
);
4924 SET_PT_BOTH (opoint
, opoint_byte
);
4931 Fsignal (Qbeginning_of_buffer
, Qnil
);
4936 int this_scroll_margin
= scroll_margin
;
4938 /* Don't use a scroll margin that is negative or too large. */
4939 if (this_scroll_margin
< 0)
4940 this_scroll_margin
= 0;
4942 if (XINT (w
->total_lines
) < 4 * scroll_margin
)
4943 this_scroll_margin
= XINT (w
->total_lines
) / 4;
4945 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
4946 w
->start_at_line_beg
= bolp
;
4947 w
->update_mode_line
= Qt
;
4948 XSETFASTINT (w
->last_modified
, 0);
4949 XSETFASTINT (w
->last_overlay_modified
, 0);
4950 /* Set force_start so that redisplay_window will run
4951 the window-scroll-functions. */
4952 w
->force_start
= Qt
;
4954 if (!NILP (Vscroll_preserve_screen_position
)
4955 && (whole
|| !EQ (Vscroll_preserve_screen_position
, Qt
)))
4957 SET_PT_BOTH (pos
, pos_byte
);
4958 Fvertical_motion (make_number (original_vpos
), window
);
4960 /* If we scrolled forward, put point enough lines down
4961 that it is outside the scroll margin. */
4966 if (this_scroll_margin
> 0)
4968 SET_PT_BOTH (pos
, pos_byte
);
4969 Fvertical_motion (make_number (this_scroll_margin
), window
);
4975 if (top_margin
<= opoint
)
4976 SET_PT_BOTH (opoint
, opoint_byte
);
4977 else if (!NILP (Vscroll_preserve_screen_position
))
4979 SET_PT_BOTH (pos
, pos_byte
);
4980 Fvertical_motion (make_number (original_vpos
), window
);
4983 SET_PT (top_margin
);
4989 /* If we scrolled backward, put point near the end of the window
4990 but not within the scroll margin. */
4991 SET_PT_BOTH (pos
, pos_byte
);
4992 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
4993 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
4996 bottom_margin
= PT
+ 1;
4998 if (bottom_margin
> opoint
)
4999 SET_PT_BOTH (opoint
, opoint_byte
);
5002 if (!NILP (Vscroll_preserve_screen_position
))
5004 SET_PT_BOTH (pos
, pos_byte
);
5005 Fvertical_motion (make_number (original_vpos
), window
);
5008 Fvertical_motion (make_number (-1), window
);
5017 Fsignal (Qend_of_buffer
, Qnil
);
5022 /* Scroll selected_window up or down. If N is nil, scroll a
5023 screen-full which is defined as the height of the window minus
5024 next_screen_context_lines. If N is the symbol `-', scroll.
5025 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
5026 up. This is the guts of Fscroll_up and Fscroll_down. */
5029 scroll_command (n
, direction
)
5033 int count
= SPECPDL_INDEX ();
5035 xassert (abs (direction
) == 1);
5037 /* If selected window's buffer isn't current, make it current for
5038 the moment. But don't screw up if window_scroll gets an error. */
5039 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
5041 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
5042 Fset_buffer (XWINDOW (selected_window
)->buffer
);
5044 /* Make redisplay consider other windows than just selected_window. */
5045 ++windows_or_buffers_changed
;
5049 window_scroll (selected_window
, direction
, 1, 0);
5050 else if (EQ (n
, Qminus
))
5051 window_scroll (selected_window
, -direction
, 1, 0);
5054 n
= Fprefix_numeric_value (n
);
5055 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
5058 unbind_to (count
, Qnil
);
5061 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
5062 doc
: /* Scroll text of current window upward ARG lines.
5063 If ARG is omitted or nil, scroll upward by a near full screen.
5064 A near full screen is `next-screen-context-lines' less than a full screen.
5065 Negative ARG means scroll downward.
5066 If ARG is the atom `-', scroll downward by nearly full screen.
5067 When calling from a program, supply as argument a number, nil, or `-'. */)
5071 scroll_command (arg
, 1);
5075 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
5076 doc
: /* Scroll text of current window down ARG lines.
5077 If ARG is omitted or nil, scroll down by a near full screen.
5078 A near full screen is `next-screen-context-lines' less than a full screen.
5079 Negative ARG means scroll upward.
5080 If ARG is the atom `-', scroll upward by nearly full screen.
5081 When calling from a program, supply as argument a number, nil, or `-'. */)
5085 scroll_command (arg
, -1);
5089 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
5090 doc
: /* Return the other window for \"other window scroll\" commands.
5091 If `other-window-scroll-buffer' is non-nil, a window
5092 showing that buffer is used.
5093 If in the minibuffer, `minibuffer-scroll-window' if non-nil
5094 specifies the window. This takes precedence over
5095 `other-window-scroll-buffer'. */)
5100 if (MINI_WINDOW_P (XWINDOW (selected_window
))
5101 && !NILP (Vminibuf_scroll_window
))
5102 window
= Vminibuf_scroll_window
;
5103 /* If buffer is specified, scroll that buffer. */
5104 else if (!NILP (Vother_window_scroll_buffer
))
5106 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
5108 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
5112 /* Nothing specified; look for a neighboring window on the same
5114 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
5116 if (EQ (window
, selected_window
))
5117 /* That didn't get us anywhere; look for a window on another
5120 window
= Fnext_window (window
, Qnil
, Qt
);
5121 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
5122 && ! EQ (window
, selected_window
));
5125 CHECK_LIVE_WINDOW (window
);
5127 if (EQ (window
, selected_window
))
5128 error ("There is no other window");
5133 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
5134 doc
: /* Scroll next window upward ARG lines; or near full screen if no ARG.
5135 A near full screen is `next-screen-context-lines' less than a full screen.
5136 The next window is the one below the current one; or the one at the top
5137 if the current one is at the bottom. Negative ARG means scroll downward.
5138 If ARG is the atom `-', scroll downward by nearly full screen.
5139 When calling from a program, supply as argument a number, nil, or `-'.
5141 If `other-window-scroll-buffer' is non-nil, scroll the window
5142 showing that buffer, popping the buffer up if necessary.
5143 If in the minibuffer, `minibuffer-scroll-window' if non-nil
5144 specifies the window to scroll. This takes precedence over
5145 `other-window-scroll-buffer'. */)
5151 int count
= SPECPDL_INDEX ();
5153 window
= Fother_window_for_scrolling ();
5154 w
= XWINDOW (window
);
5156 /* Don't screw up if window_scroll gets an error. */
5157 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
5158 ++windows_or_buffers_changed
;
5160 Fset_buffer (w
->buffer
);
5161 SET_PT (marker_position (w
->pointm
));
5164 window_scroll (window
, 1, 1, 1);
5165 else if (EQ (arg
, Qminus
))
5166 window_scroll (window
, -1, 1, 1);
5172 window_scroll (window
, XINT (arg
), 0, 1);
5175 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
5176 unbind_to (count
, Qnil
);
5181 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 2, "P\np",
5182 doc
: /* Scroll selected window display ARG columns left.
5183 Default for ARG is window width minus 2.
5184 Value is the total amount of leftward horizontal scrolling in
5185 effect after the change.
5186 If SET_MINIMUM is non-nil, the new scroll amount becomes the
5187 lower bound for automatic scrolling, i.e. automatic scrolling
5188 will not scroll a window to a column less than the value returned
5189 by this function. This happens in an interactive call. */)
5191 register Lisp_Object arg
, set_minimum
;
5195 struct window
*w
= XWINDOW (selected_window
);
5198 XSETFASTINT (arg
, window_box_text_cols (w
) - 2);
5200 arg
= Fprefix_numeric_value (arg
);
5202 hscroll
= XINT (w
->hscroll
) + XINT (arg
);
5203 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
5205 if (!NILP (set_minimum
))
5206 w
->min_hscroll
= w
->hscroll
;
5211 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 2, "P\np",
5212 doc
: /* Scroll selected window display ARG columns right.
5213 Default for ARG is window width minus 2.
5214 Value is the total amount of leftward horizontal scrolling in
5215 effect after the change.
5216 If SET_MINIMUM is non-nil, the new scroll amount becomes the
5217 lower bound for automatic scrolling, i.e. automatic scrolling
5218 will not scroll a window to a column less than the value returned
5219 by this function. This happens in an interactive call. */)
5221 register Lisp_Object arg
, set_minimum
;
5225 struct window
*w
= XWINDOW (selected_window
);
5228 XSETFASTINT (arg
, window_box_text_cols (w
) - 2);
5230 arg
= Fprefix_numeric_value (arg
);
5232 hscroll
= XINT (w
->hscroll
) - XINT (arg
);
5233 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
5235 if (!NILP (set_minimum
))
5236 w
->min_hscroll
= w
->hscroll
;
5241 DEFUN ("minibuffer-selected-window", Fminibuffer_selected_window
, Sminibuffer_selected_window
, 0, 0, 0,
5242 doc
: /* Return the window which was selected when entering the minibuffer.
5243 Returns nil, if current window is not a minibuffer window. */)
5246 if (minibuf_level
> 0
5247 && MINI_WINDOW_P (XWINDOW (selected_window
))
5248 && WINDOW_LIVE_P (minibuf_selected_window
))
5249 return minibuf_selected_window
;
5254 /* Value is the number of lines actually displayed in window W,
5255 as opposed to its height. */
5258 displayed_window_lines (w
)
5262 struct text_pos start
;
5263 int height
= window_box_height (w
);
5264 struct buffer
*old_buffer
;
5267 if (XBUFFER (w
->buffer
) != current_buffer
)
5269 old_buffer
= current_buffer
;
5270 set_buffer_internal (XBUFFER (w
->buffer
));
5275 /* In case W->start is out of the accessible range, do something
5276 reasonable. This happens in Info mode when Info-scroll-down
5277 calls (recenter -1) while W->start is 1. */
5278 if (XMARKER (w
->start
)->charpos
< BEGV
)
5279 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
5280 else if (XMARKER (w
->start
)->charpos
> ZV
)
5281 SET_TEXT_POS (start
, ZV
, ZV_BYTE
);
5283 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
5285 start_display (&it
, w
, start
);
5286 move_it_vertically (&it
, height
);
5287 bottom_y
= line_bottom_y (&it
);
5289 /* rms: On a non-window display,
5290 the value of it.vpos at the bottom of the screen
5291 seems to be 1 larger than window_box_height (w).
5292 This kludge fixes a bug whereby (move-to-window-line -1)
5293 when ZV is on the last screen line
5294 moves to the previous screen line instead of the last one. */
5295 if (! FRAME_WINDOW_P (XFRAME (w
->frame
)))
5298 /* Add in empty lines at the bottom of the window. */
5299 if (bottom_y
< height
)
5301 int uy
= FRAME_LINE_HEIGHT (it
.f
);
5302 it
.vpos
+= (height
- bottom_y
+ uy
- 1) / uy
;
5306 set_buffer_internal (old_buffer
);
5312 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
5313 doc
: /* Center point in window and redisplay frame.
5314 With prefix argument ARG, recenter putting point on screen line ARG
5315 relative to the current window. If ARG is negative, it counts up from the
5316 bottom of the window. (ARG should be less than the height of the window.)
5318 If ARG is omitted or nil, erase the entire frame and then
5319 redraw with point in the center of the current window.
5320 Just C-u as prefix means put point in the center of the window
5321 and redisplay normally--don't erase and redraw the frame. */)
5323 register Lisp_Object arg
;
5325 struct window
*w
= XWINDOW (selected_window
);
5326 struct buffer
*buf
= XBUFFER (w
->buffer
);
5327 struct buffer
*obuf
= current_buffer
;
5329 int charpos
, bytepos
;
5331 int this_scroll_margin
;
5333 /* If redisplay is suppressed due to an error, try again. */
5334 obuf
->display_error_modiff
= 0;
5340 /* Invalidate pixel data calculated for all compositions. */
5341 for (i
= 0; i
< n_compositions
; i
++)
5342 composition_table
[i
]->font
= NULL
;
5344 Fredraw_frame (w
->frame
);
5345 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
5348 else if (CONSP (arg
)) /* Just C-u. */
5352 arg
= Fprefix_numeric_value (arg
);
5357 set_buffer_internal (buf
);
5359 /* Do this after making BUF current
5360 in case scroll_margin is buffer-local. */
5361 this_scroll_margin
= max (0, scroll_margin
);
5362 this_scroll_margin
= min (this_scroll_margin
,
5363 XFASTINT (w
->total_lines
) / 4);
5365 /* Handle centering on a graphical frame specially. Such frames can
5366 have variable-height lines and centering point on the basis of
5367 line counts would lead to strange effects. */
5368 if (FRAME_WINDOW_P (XFRAME (w
->frame
)))
5375 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
5376 start_display (&it
, w
, pt
);
5377 move_it_vertically_backward (&it
, window_box_height (w
) / 2);
5378 charpos
= IT_CHARPOS (it
);
5379 bytepos
= IT_BYTEPOS (it
);
5386 int extra_line_spacing
;
5387 int h
= window_box_height (w
);
5389 iarg
= - max (-iarg
, this_scroll_margin
);
5391 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
5392 start_display (&it
, w
, pt
);
5394 /* Be sure we have the exact height of the full line containing PT. */
5395 move_it_by_lines (&it
, 0, 1);
5397 /* The amount of pixels we have to move back is the window
5398 height minus what's displayed in the line containing PT,
5399 and the lines below. */
5402 move_it_by_lines (&it
, nlines
, 1);
5404 if (it
.vpos
== nlines
)
5408 /* Last line has no newline */
5409 h
-= line_bottom_y (&it
);
5413 /* Don't reserve space for extra line spacing of last line. */
5414 extra_line_spacing
= it
.max_extra_line_spacing
;
5416 /* If we can't move down NLINES lines because we hit
5417 the end of the buffer, count in some empty lines. */
5418 if (it
.vpos
< nlines
)
5421 extra_line_spacing
= it
.extra_line_spacing
;
5422 h
-= nlines
* (FRAME_LINE_HEIGHT (it
.f
) + extra_line_spacing
);
5427 /* Now find the new top line (starting position) of the window. */
5428 start_display (&it
, w
, pt
);
5430 move_it_vertically_backward (&it
, h
);
5432 /* If extra line spacing is present, we may move too far
5433 back. This causes the last line to be only partially
5434 visible (which triggers redisplay to recenter that line
5435 in the middle), so move forward.
5436 But ignore extra line spacing on last line, as it is not
5437 considered to be part of the visible height of the line.
5439 h
+= extra_line_spacing
;
5440 while (-it
.current_y
> h
)
5441 move_it_by_lines (&it
, 1, 1);
5443 charpos
= IT_CHARPOS (it
);
5444 bytepos
= IT_BYTEPOS (it
);
5448 struct position pos
;
5450 iarg
= max (iarg
, this_scroll_margin
);
5452 pos
= *vmotion (PT
, -iarg
, w
);
5453 charpos
= pos
.bufpos
;
5454 bytepos
= pos
.bytepos
;
5459 struct position pos
;
5460 int ht
= window_internal_height (w
);
5467 /* Don't let it get into the margin at either top or bottom. */
5468 iarg
= max (iarg
, this_scroll_margin
);
5469 iarg
= min (iarg
, ht
- this_scroll_margin
- 1);
5471 pos
= *vmotion (PT
, - iarg
, w
);
5472 charpos
= pos
.bufpos
;
5473 bytepos
= pos
.bytepos
;
5476 /* Set the new window start. */
5477 set_marker_both (w
->start
, w
->buffer
, charpos
, bytepos
);
5478 w
->window_end_valid
= Qnil
;
5480 w
->optional_new_start
= Qt
;
5482 if (bytepos
== BEGV_BYTE
|| FETCH_BYTE (bytepos
- 1) == '\n')
5483 w
->start_at_line_beg
= Qt
;
5485 w
->start_at_line_beg
= Qnil
;
5487 set_buffer_internal (obuf
);
5492 DEFUN ("window-text-height", Fwindow_text_height
, Swindow_text_height
,
5494 doc
: /* Return the height in lines of the text display area of WINDOW.
5495 This doesn't include the mode-line (or header-line if any) or any
5496 partial-height lines in the text display area. */)
5500 struct window
*w
= decode_window (window
);
5501 int pixel_height
= window_box_height (w
);
5502 int line_height
= pixel_height
/ FRAME_LINE_HEIGHT (XFRAME (w
->frame
));
5503 return make_number (line_height
);
5508 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
5510 doc
: /* Position point relative to window.
5511 With no argument, position point at center of window.
5512 An argument specifies vertical position within the window;
5513 zero means top of window, negative means relative to bottom of window. */)
5517 struct window
*w
= XWINDOW (selected_window
);
5521 int this_scroll_margin
;
5524 window
= selected_window
;
5525 start
= marker_position (w
->start
);
5526 if (start
< BEGV
|| start
> ZV
)
5528 int height
= window_internal_height (w
);
5529 Fvertical_motion (make_number (- (height
/ 2)), window
);
5530 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
5531 w
->start_at_line_beg
= Fbolp ();
5532 w
->force_start
= Qt
;
5535 Fgoto_char (w
->start
);
5537 lines
= displayed_window_lines (w
);
5540 this_scroll_margin
= max (0, scroll_margin
);
5541 this_scroll_margin
= min (this_scroll_margin
, lines
/ 4);
5545 XSETFASTINT (arg
, lines
/ 2);
5548 int iarg
= XINT (Fprefix_numeric_value (arg
));
5551 iarg
= iarg
+ lines
;
5553 #if 0 /* This code would prevent move-to-window-line from moving point
5554 to a place inside the scroll margins (which would cause the
5555 next redisplay to scroll). I wrote this code, but then concluded
5556 it is probably better not to install it. However, it is here
5557 inside #if 0 so as not to lose it. -- rms. */
5559 /* Don't let it get into the margin at either top or bottom. */
5560 iarg
= max (iarg
, this_scroll_margin
);
5561 iarg
= min (iarg
, lines
- this_scroll_margin
- 1);
5564 arg
= make_number (iarg
);
5567 /* Skip past a partially visible first line. */
5569 XSETINT (arg
, XINT (arg
) + 1);
5571 return Fvertical_motion (arg
, window
);
5576 /***********************************************************************
5577 Window Configuration
5578 ***********************************************************************/
5580 struct save_window_data
5582 EMACS_INT size_from_Lisp_Vector_struct
;
5583 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
5584 Lisp_Object frame_cols
, frame_lines
, frame_menu_bar_lines
;
5585 Lisp_Object frame_tool_bar_lines
;
5586 Lisp_Object selected_frame
;
5587 Lisp_Object current_window
;
5588 Lisp_Object current_buffer
;
5589 Lisp_Object minibuf_scroll_window
;
5590 Lisp_Object minibuf_selected_window
;
5591 Lisp_Object root_window
;
5592 Lisp_Object focus_frame
;
5593 /* Record the values of window-min-width and window-min-height
5594 so that window sizes remain consistent with them. */
5595 Lisp_Object min_width
, min_height
;
5596 /* A vector, each of whose elements is a struct saved_window
5598 Lisp_Object saved_windows
;
5601 /* This is saved as a Lisp_Vector */
5604 /* these first two must agree with struct Lisp_Vector in lisp.h */
5605 EMACS_INT size_from_Lisp_Vector_struct
;
5606 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
5609 Lisp_Object buffer
, start
, pointm
, mark
;
5610 Lisp_Object left_col
, top_line
, total_cols
, total_lines
;
5611 Lisp_Object hscroll
, min_hscroll
;
5612 Lisp_Object parent
, prev
;
5613 Lisp_Object start_at_line_beg
;
5614 Lisp_Object display_table
;
5615 Lisp_Object orig_top_line
, orig_total_lines
;
5616 Lisp_Object left_margin_cols
, right_margin_cols
;
5617 Lisp_Object left_fringe_width
, right_fringe_width
, fringes_outside_margins
;
5618 Lisp_Object scroll_bar_width
, vertical_scroll_bar_type
;
5621 #define SAVED_WINDOW_N(swv,n) \
5622 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
5624 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
5625 doc
: /* Return t if OBJECT is a window-configuration object. */)
5629 if (WINDOW_CONFIGURATIONP (object
))
5634 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
5635 doc
: /* Return the frame that CONFIG, a window-configuration object, is about. */)
5639 register struct save_window_data
*data
;
5640 struct Lisp_Vector
*saved_windows
;
5642 if (! WINDOW_CONFIGURATIONP (config
))
5643 wrong_type_argument (Qwindow_configuration_p
, config
);
5645 data
= (struct save_window_data
*) XVECTOR (config
);
5646 saved_windows
= XVECTOR (data
->saved_windows
);
5647 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
5650 DEFUN ("set-window-configuration", Fset_window_configuration
,
5651 Sset_window_configuration
, 1, 1, 0,
5652 doc
: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
5653 CONFIGURATION must be a value previously returned
5654 by `current-window-configuration' (which see).
5655 If CONFIGURATION was made from a frame that is now deleted,
5656 only frame-independent values can be restored. In this case,
5657 the return value is nil. Otherwise the value is t. */)
5659 Lisp_Object configuration
;
5661 register struct save_window_data
*data
;
5662 struct Lisp_Vector
*saved_windows
;
5663 Lisp_Object new_current_buffer
;
5668 while (!WINDOW_CONFIGURATIONP (configuration
))
5669 wrong_type_argument (Qwindow_configuration_p
, configuration
);
5671 data
= (struct save_window_data
*) XVECTOR (configuration
);
5672 saved_windows
= XVECTOR (data
->saved_windows
);
5674 new_current_buffer
= data
->current_buffer
;
5675 if (NILP (XBUFFER (new_current_buffer
)->name
))
5676 new_current_buffer
= Qnil
;
5679 if (XBUFFER (new_current_buffer
) == current_buffer
)
5682 /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of
5683 point in new_current_buffer as of the last time this buffer was
5684 used. This can be non-deterministic since it can be changed by
5685 things like jit-lock by mere temporary selection of some random
5686 window that happens to show this buffer.
5687 So if possible we want this arbitrary choice of "which point" to
5688 be the one from the to-be-selected-window so as to prevent this
5689 window's cursor from being copied from another window. */
5690 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
)
5691 /* If current_window = selected_window, its point is in BUF_PT. */
5692 && !EQ (selected_window
, data
->current_window
))
5693 old_point
= XMARKER (XWINDOW (data
->current_window
)->pointm
)->charpos
;
5695 old_point
= BUF_PT (XBUFFER (new_current_buffer
));
5698 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
5701 /* If f is a dead frame, don't bother rebuilding its window tree.
5702 However, there is other stuff we should still try to do below. */
5703 if (FRAME_LIVE_P (f
))
5705 register struct window
*w
;
5706 register struct saved_window
*p
;
5707 struct window
*root_window
;
5708 struct window
**leaf_windows
;
5712 /* If the frame has been resized since this window configuration was
5713 made, we change the frame to the size specified in the
5714 configuration, restore the configuration, and then resize it
5715 back. We keep track of the prevailing height in these variables. */
5716 int previous_frame_lines
= FRAME_LINES (f
);
5717 int previous_frame_cols
= FRAME_COLS (f
);
5718 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
5719 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
5721 /* The mouse highlighting code could get screwed up
5722 if it runs during this. */
5725 if (XFASTINT (data
->frame_lines
) != previous_frame_lines
5726 || XFASTINT (data
->frame_cols
) != previous_frame_cols
)
5727 change_frame_size (f
, XFASTINT (data
->frame_lines
),
5728 XFASTINT (data
->frame_cols
), 0, 0, 0);
5729 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
5730 if (XFASTINT (data
->frame_menu_bar_lines
)
5731 != previous_frame_menu_bar_lines
)
5732 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, make_number (0));
5733 #ifdef HAVE_WINDOW_SYSTEM
5734 if (XFASTINT (data
->frame_tool_bar_lines
)
5735 != previous_frame_tool_bar_lines
)
5736 x_set_tool_bar_lines (f
, data
->frame_tool_bar_lines
, make_number (0));
5740 /* "Swap out" point from the selected window's buffer
5741 into the window itself. (Normally the pointm of the selected
5742 window holds garbage.) We do this now, before
5743 restoring the window contents, and prevent it from
5744 being done later on when we select a new window. */
5745 if (! NILP (XWINDOW (selected_window
)->buffer
))
5747 w
= XWINDOW (selected_window
);
5748 set_marker_both (w
->pointm
,
5750 BUF_PT (XBUFFER (w
->buffer
)),
5751 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5754 windows_or_buffers_changed
++;
5755 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
5757 /* Problem: Freeing all matrices and later allocating them again
5758 is a serious redisplay flickering problem. What we would
5759 really like to do is to free only those matrices not reused
5761 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
5763 = (struct window
**) alloca (count_windows (root_window
)
5764 * sizeof (struct window
*));
5765 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
5767 /* Temporarily avoid any problems with windows that are smaller
5768 than they are supposed to be. */
5769 window_min_height
= 1;
5770 window_min_width
= 1;
5773 Mark all windows now on frame as "deleted".
5774 Restoring the new configuration "undeletes" any that are in it.
5776 Save their current buffers in their height fields, since we may
5777 need it later, if a buffer saved in the configuration is now
5779 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5781 for (k
= 0; k
< saved_windows
->size
; k
++)
5783 p
= SAVED_WINDOW_N (saved_windows
, k
);
5784 w
= XWINDOW (p
->window
);
5787 if (!NILP (p
->parent
))
5788 w
->parent
= SAVED_WINDOW_N (saved_windows
,
5789 XFASTINT (p
->parent
))->window
;
5793 if (!NILP (p
->prev
))
5795 w
->prev
= SAVED_WINDOW_N (saved_windows
,
5796 XFASTINT (p
->prev
))->window
;
5797 XWINDOW (w
->prev
)->next
= p
->window
;
5802 if (!NILP (w
->parent
))
5804 if (EQ (p
->total_cols
, XWINDOW (w
->parent
)->total_cols
))
5806 XWINDOW (w
->parent
)->vchild
= p
->window
;
5807 XWINDOW (w
->parent
)->hchild
= Qnil
;
5811 XWINDOW (w
->parent
)->hchild
= p
->window
;
5812 XWINDOW (w
->parent
)->vchild
= Qnil
;
5817 /* If we squirreled away the buffer in the window's height,
5819 if (BUFFERP (w
->total_lines
))
5820 w
->buffer
= w
->total_lines
;
5821 w
->left_col
= p
->left_col
;
5822 w
->top_line
= p
->top_line
;
5823 w
->total_cols
= p
->total_cols
;
5824 w
->total_lines
= p
->total_lines
;
5825 w
->hscroll
= p
->hscroll
;
5826 w
->min_hscroll
= p
->min_hscroll
;
5827 w
->display_table
= p
->display_table
;
5828 w
->orig_top_line
= p
->orig_top_line
;
5829 w
->orig_total_lines
= p
->orig_total_lines
;
5830 w
->left_margin_cols
= p
->left_margin_cols
;
5831 w
->right_margin_cols
= p
->right_margin_cols
;
5832 w
->left_fringe_width
= p
->left_fringe_width
;
5833 w
->right_fringe_width
= p
->right_fringe_width
;
5834 w
->fringes_outside_margins
= p
->fringes_outside_margins
;
5835 w
->scroll_bar_width
= p
->scroll_bar_width
;
5836 w
->vertical_scroll_bar_type
= p
->vertical_scroll_bar_type
;
5837 XSETFASTINT (w
->last_modified
, 0);
5838 XSETFASTINT (w
->last_overlay_modified
, 0);
5840 /* Reinstall the saved buffer and pointers into it. */
5841 if (NILP (p
->buffer
))
5842 w
->buffer
= p
->buffer
;
5845 if (!NILP (XBUFFER (p
->buffer
)->name
))
5846 /* If saved buffer is alive, install it. */
5848 w
->buffer
= p
->buffer
;
5849 w
->start_at_line_beg
= p
->start_at_line_beg
;
5850 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
5851 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
5852 Fset_marker (XBUFFER (w
->buffer
)->mark
,
5853 p
->mark
, w
->buffer
);
5855 /* As documented in Fcurrent_window_configuration, don't
5856 restore the location of point in the buffer which was
5857 current when the window configuration was recorded. */
5858 if (!EQ (p
->buffer
, new_current_buffer
)
5859 && XBUFFER (p
->buffer
) == current_buffer
)
5860 Fgoto_char (w
->pointm
);
5862 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
5863 /* Else unless window has a live buffer, get one. */
5865 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
5866 /* This will set the markers to beginning of visible
5868 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
5869 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
5870 w
->start_at_line_beg
= Qt
;
5873 /* Keeping window's old buffer; make sure the markers
5876 /* Set window markers at start of visible range. */
5877 if (XMARKER (w
->start
)->buffer
== 0)
5878 set_marker_restricted (w
->start
, make_number (0),
5880 if (XMARKER (w
->pointm
)->buffer
== 0)
5881 set_marker_restricted_both (w
->pointm
, w
->buffer
,
5882 BUF_PT (XBUFFER (w
->buffer
)),
5883 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5884 w
->start_at_line_beg
= Qt
;
5889 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
5890 /* Prevent "swapping out point" in the old selected window
5891 using the buffer that has been restored into it.
5892 We already swapped out point that from that window's old buffer. */
5893 selected_window
= Qnil
;
5895 /* Arrange *not* to restore point in the buffer that was
5896 current when the window configuration was saved. */
5897 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
))
5898 set_marker_restricted (XWINDOW (data
->current_window
)->pointm
,
5899 make_number (old_point
),
5900 XWINDOW (data
->current_window
)->buffer
);
5902 Fselect_window (data
->current_window
, Qnil
);
5903 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
5906 if (NILP (data
->focus_frame
)
5907 || (FRAMEP (data
->focus_frame
)
5908 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
5909 Fredirect_frame_focus (frame
, data
->focus_frame
);
5911 #if 0 /* I don't understand why this is needed, and it causes problems
5912 when the frame's old selected window has been deleted. */
5913 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
5914 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
5918 /* Set the screen height to the value it had before this function. */
5919 if (previous_frame_lines
!= FRAME_LINES (f
)
5920 || previous_frame_cols
!= FRAME_COLS (f
))
5921 change_frame_size (f
, previous_frame_lines
, previous_frame_cols
,
5923 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
5924 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
5925 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
5927 #ifdef HAVE_WINDOW_SYSTEM
5928 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
5929 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
5934 /* Now, free glyph matrices in windows that were not reused. */
5935 for (i
= n
= 0; i
< n_leaf_windows
; ++i
)
5937 if (NILP (leaf_windows
[i
]->buffer
))
5939 /* Assert it's not reused as a combination. */
5940 xassert (NILP (leaf_windows
[i
]->hchild
)
5941 && NILP (leaf_windows
[i
]->vchild
));
5942 free_window_matrices (leaf_windows
[i
]);
5944 else if (EQ (leaf_windows
[i
]->buffer
, new_current_buffer
))
5952 /* Fselect_window will have made f the selected frame, so we
5953 reselect the proper frame here. Fhandle_switch_frame will change the
5954 selected window too, but that doesn't make the call to
5955 Fselect_window above totally superfluous; it still sets f's
5957 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
5958 do_switch_frame (data
->selected_frame
, 0, 0);
5960 if (! NILP (Vwindow_configuration_change_hook
)
5961 && ! NILP (Vrun_hooks
))
5962 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
5965 if (!NILP (new_current_buffer
))
5966 Fset_buffer (new_current_buffer
);
5968 /* Restore the minimum heights recorded in the configuration. */
5969 window_min_height
= XINT (data
->min_height
);
5970 window_min_width
= XINT (data
->min_width
);
5972 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
5973 minibuf_selected_window
= data
->minibuf_selected_window
;
5975 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
5978 /* Mark all windows now on frame as deleted
5979 by setting their buffers to nil. */
5982 delete_all_subwindows (w
)
5983 register struct window
*w
;
5985 if (!NILP (w
->next
))
5986 delete_all_subwindows (XWINDOW (w
->next
));
5987 if (!NILP (w
->vchild
))
5988 delete_all_subwindows (XWINDOW (w
->vchild
));
5989 if (!NILP (w
->hchild
))
5990 delete_all_subwindows (XWINDOW (w
->hchild
));
5992 w
->total_lines
= w
->buffer
; /* See Fset_window_configuration for excuse. */
5994 if (!NILP (w
->buffer
))
5997 /* We set all three of these fields to nil, to make sure that we can
5998 distinguish this dead window from any live window. Live leaf
5999 windows will have buffer set, and combination windows will have
6000 vchild or hchild set. */
6005 Vwindow_list
= Qnil
;
6009 count_windows (window
)
6010 register struct window
*window
;
6012 register int count
= 1;
6013 if (!NILP (window
->next
))
6014 count
+= count_windows (XWINDOW (window
->next
));
6015 if (!NILP (window
->vchild
))
6016 count
+= count_windows (XWINDOW (window
->vchild
));
6017 if (!NILP (window
->hchild
))
6018 count
+= count_windows (XWINDOW (window
->hchild
));
6023 /* Fill vector FLAT with leaf windows under W, starting at index I.
6024 Value is last index + 1. */
6027 get_leaf_windows (w
, flat
, i
)
6029 struct window
**flat
;
6034 if (!NILP (w
->hchild
))
6035 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
6036 else if (!NILP (w
->vchild
))
6037 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
6041 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
6048 /* Return a pointer to the glyph W's physical cursor is on. Value is
6049 null if W's current matrix is invalid, so that no meaningfull glyph
6053 get_phys_cursor_glyph (w
)
6056 struct glyph_row
*row
;
6057 struct glyph
*glyph
;
6059 if (w
->phys_cursor
.vpos
>= 0
6060 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
6061 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
6063 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
6064 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
6073 save_window_save (window
, vector
, i
)
6075 struct Lisp_Vector
*vector
;
6078 register struct saved_window
*p
;
6079 register struct window
*w
;
6080 register Lisp_Object tem
;
6082 for (;!NILP (window
); window
= w
->next
)
6084 p
= SAVED_WINDOW_N (vector
, i
);
6085 w
= XWINDOW (window
);
6087 XSETFASTINT (w
->temslot
, i
); i
++;
6089 p
->buffer
= w
->buffer
;
6090 p
->left_col
= w
->left_col
;
6091 p
->top_line
= w
->top_line
;
6092 p
->total_cols
= w
->total_cols
;
6093 p
->total_lines
= w
->total_lines
;
6094 p
->hscroll
= w
->hscroll
;
6095 p
->min_hscroll
= w
->min_hscroll
;
6096 p
->display_table
= w
->display_table
;
6097 p
->orig_top_line
= w
->orig_top_line
;
6098 p
->orig_total_lines
= w
->orig_total_lines
;
6099 p
->left_margin_cols
= w
->left_margin_cols
;
6100 p
->right_margin_cols
= w
->right_margin_cols
;
6101 p
->left_fringe_width
= w
->left_fringe_width
;
6102 p
->right_fringe_width
= w
->right_fringe_width
;
6103 p
->fringes_outside_margins
= w
->fringes_outside_margins
;
6104 p
->scroll_bar_width
= w
->scroll_bar_width
;
6105 p
->vertical_scroll_bar_type
= w
->vertical_scroll_bar_type
;
6106 if (!NILP (w
->buffer
))
6108 /* Save w's value of point in the window configuration.
6109 If w is the selected window, then get the value of point
6110 from the buffer; pointm is garbage in the selected window. */
6111 if (EQ (window
, selected_window
))
6113 p
->pointm
= Fmake_marker ();
6114 set_marker_both (p
->pointm
, w
->buffer
,
6115 BUF_PT (XBUFFER (w
->buffer
)),
6116 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
6119 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
6121 p
->start
= Fcopy_marker (w
->start
, Qnil
);
6122 p
->start_at_line_beg
= w
->start_at_line_beg
;
6124 tem
= XBUFFER (w
->buffer
)->mark
;
6125 p
->mark
= Fcopy_marker (tem
, Qnil
);
6132 p
->start_at_line_beg
= Qnil
;
6135 if (NILP (w
->parent
))
6138 p
->parent
= XWINDOW (w
->parent
)->temslot
;
6143 p
->prev
= XWINDOW (w
->prev
)->temslot
;
6145 if (!NILP (w
->vchild
))
6146 i
= save_window_save (w
->vchild
, vector
, i
);
6147 if (!NILP (w
->hchild
))
6148 i
= save_window_save (w
->hchild
, vector
, i
);
6154 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
6155 Scurrent_window_configuration
, 0, 1, 0,
6156 doc
: /* Return an object representing the current window configuration of FRAME.
6157 If FRAME is nil or omitted, use the selected frame.
6158 This describes the number of windows, their sizes and current buffers,
6159 and for each displayed buffer, where display starts, and the positions of
6160 point and mark. An exception is made for point in the current buffer:
6161 its value is -not- saved.
6162 This also records the currently selected frame, and FRAME's focus
6163 redirection (see `redirect-frame-focus'). */)
6167 register Lisp_Object tem
;
6168 register int n_windows
;
6169 register struct save_window_data
*data
;
6170 register struct Lisp_Vector
*vec
;
6175 frame
= selected_frame
;
6176 CHECK_LIVE_FRAME (frame
);
6179 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
6180 vec
= allocate_other_vector (VECSIZE (struct save_window_data
));
6181 data
= (struct save_window_data
*)vec
;
6183 XSETFASTINT (data
->frame_cols
, FRAME_COLS (f
));
6184 XSETFASTINT (data
->frame_lines
, FRAME_LINES (f
));
6185 XSETFASTINT (data
->frame_menu_bar_lines
, FRAME_MENU_BAR_LINES (f
));
6186 XSETFASTINT (data
->frame_tool_bar_lines
, FRAME_TOOL_BAR_LINES (f
));
6187 data
->selected_frame
= selected_frame
;
6188 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
6189 XSETBUFFER (data
->current_buffer
, current_buffer
);
6190 data
->minibuf_scroll_window
= minibuf_level
> 0 ? Vminibuf_scroll_window
: Qnil
;
6191 data
->minibuf_selected_window
= minibuf_level
> 0 ? minibuf_selected_window
: Qnil
;
6192 data
->root_window
= FRAME_ROOT_WINDOW (f
);
6193 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
6194 XSETINT (data
->min_height
, window_min_height
);
6195 XSETINT (data
->min_width
, window_min_width
);
6196 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
6197 data
->saved_windows
= tem
;
6198 for (i
= 0; i
< n_windows
; i
++)
6199 XVECTOR (tem
)->contents
[i
]
6200 = Fmake_vector (make_number (VECSIZE (struct saved_window
)), Qnil
);
6201 save_window_save (FRAME_ROOT_WINDOW (f
), XVECTOR (tem
), 0);
6202 XSETWINDOW_CONFIGURATION (tem
, data
);
6206 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
6208 doc
: /* Execute BODY, preserving window sizes and contents.
6209 Return the value of the last form in BODY.
6210 Restore which buffer appears in which window, where display starts,
6211 and the value of point and mark for each window.
6212 Also restore the choice of selected window.
6213 Also restore which buffer is current.
6214 Does not restore the value of point in current buffer.
6215 usage: (save-window-excursion BODY ...) */)
6219 register Lisp_Object val
;
6220 register int count
= SPECPDL_INDEX ();
6222 record_unwind_protect (Fset_window_configuration
,
6223 Fcurrent_window_configuration (Qnil
));
6224 val
= Fprogn (args
);
6225 return unbind_to (count
, val
);
6230 /***********************************************************************
6232 ***********************************************************************/
6238 Lisp_Object tail
= Qnil
;
6239 Lisp_Object result
= Qnil
;
6246 if (!NILP (w
->hchild
))
6247 wn
= Fcons (Qnil
, Fcons (Fwindow_edges (wn
),
6248 window_tree (XWINDOW (w
->hchild
))));
6249 else if (!NILP (w
->vchild
))
6250 wn
= Fcons (Qt
, Fcons (Fwindow_edges (wn
),
6251 window_tree (XWINDOW (w
->vchild
))));
6255 result
= tail
= Fcons (wn
, Qnil
);
6259 XSETCDR (tail
, Fcons (wn
, Qnil
));
6263 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
6271 DEFUN ("window-tree", Fwindow_tree
, Swindow_tree
,
6273 doc
: /* Return the window tree for frame FRAME.
6275 The return value is a list of the form (ROOT MINI), where ROOT
6276 represents the window tree of the frame's root window, and MINI
6277 is the frame's minibuffer window.
6279 If the root window is not split, ROOT is the root window itself.
6280 Otherwise, ROOT is a list (DIR EDGES W1 W2 ...) where DIR is nil for a
6281 horisontal split, and t for a vertical split, EDGES gives the combined
6282 size and position of the subwindows in the split, and the rest of the
6283 elements are the subwindows in the split. Each of the subwindows may
6284 again be a window or a list representing a window split, and so on.
6285 EDGES is a list \(LEFT TOP RIGHT BOTTOM) as returned by `window-edges'.
6287 If FRAME is nil or omitted, return information on the currently
6296 frame
= selected_frame
;
6298 CHECK_FRAME (frame
);
6301 if (!FRAME_LIVE_P (f
))
6304 return window_tree (XWINDOW (FRAME_ROOT_WINDOW (f
)));
6308 /***********************************************************************
6310 ***********************************************************************/
6312 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
6314 doc
: /* Set width of marginal areas of window WINDOW.
6315 If WINDOW is nil, set margins of the currently selected window.
6316 Second arg LEFT-WIDTH specifies the number of character cells to
6317 reserve for the left marginal area. Optional third arg RIGHT-WIDTH
6318 does the same for the right marginal area. A nil width parameter
6319 means no margin. */)
6320 (window
, left_width
, right_width
)
6321 Lisp_Object window
, left_width
, right_width
;
6323 struct window
*w
= decode_window (window
);
6325 /* Translate negative or zero widths to nil.
6326 Margins that are too wide have to be checked elsewhere. */
6328 if (!NILP (left_width
))
6330 CHECK_NUMBER (left_width
);
6331 if (XINT (left_width
) <= 0)
6335 if (!NILP (right_width
))
6337 CHECK_NUMBER (right_width
);
6338 if (XINT (right_width
) <= 0)
6342 if (!EQ (w
->left_margin_cols
, left_width
)
6343 || !EQ (w
->right_margin_cols
, right_width
))
6345 w
->left_margin_cols
= left_width
;
6346 w
->right_margin_cols
= right_width
;
6348 adjust_window_margins (w
);
6350 ++windows_or_buffers_changed
;
6351 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
6358 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
6360 doc
: /* Get width of marginal areas of window WINDOW.
6361 If WINDOW is omitted or nil, use the currently selected window.
6362 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).
6363 If a marginal area does not exist, its width will be returned
6368 struct window
*w
= decode_window (window
);
6369 return Fcons (w
->left_margin_cols
, w
->right_margin_cols
);
6374 /***********************************************************************
6376 ***********************************************************************/
6378 DEFUN ("set-window-fringes", Fset_window_fringes
, Sset_window_fringes
,
6380 doc
: /* Set the fringe widths of window WINDOW.
6381 If WINDOW is nil, set the fringe widths of the currently selected
6383 Second arg LEFT-WIDTH specifies the number of pixels to reserve for
6384 the left fringe. Optional third arg RIGHT-WIDTH specifies the right
6385 fringe width. If a fringe width arg is nil, that means to use the
6386 frame's default fringe width. Default fringe widths can be set with
6387 the command `set-fringe-style'.
6388 If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes
6389 outside of the display margins. By default, fringes are drawn between
6390 display marginal areas and the text area. */)
6391 (window
, left_width
, right_width
, outside_margins
)
6392 Lisp_Object window
, left_width
, right_width
, outside_margins
;
6394 struct window
*w
= decode_window (window
);
6396 if (!NILP (left_width
))
6397 CHECK_NATNUM (left_width
);
6398 if (!NILP (right_width
))
6399 CHECK_NATNUM (right_width
);
6401 if (!EQ (w
->left_fringe_width
, left_width
)
6402 || !EQ (w
->right_fringe_width
, right_width
)
6403 || !EQ (w
->fringes_outside_margins
, outside_margins
))
6405 w
->left_fringe_width
= left_width
;
6406 w
->right_fringe_width
= right_width
;
6407 w
->fringes_outside_margins
= outside_margins
;
6409 adjust_window_margins (w
);
6411 clear_glyph_matrix (w
->current_matrix
);
6412 w
->window_end_valid
= Qnil
;
6414 ++windows_or_buffers_changed
;
6415 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
6422 DEFUN ("window-fringes", Fwindow_fringes
, Swindow_fringes
,
6424 doc
: /* Get width of fringes of window WINDOW.
6425 If WINDOW is omitted or nil, use the currently selected window.
6426 Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
6430 struct window
*w
= decode_window (window
);
6431 return Fcons (make_number (WINDOW_LEFT_FRINGE_WIDTH (w
)),
6432 Fcons (make_number (WINDOW_RIGHT_FRINGE_WIDTH (w
)),
6433 Fcons ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
) ?
6434 Qt
: Qnil
), Qnil
)));
6439 /***********************************************************************
6441 ***********************************************************************/
6443 DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars
, Sset_window_scroll_bars
,
6445 doc
: /* Set width and type of scroll bars of window WINDOW.
6446 If window is nil, set scroll bars of the currently selected window.
6447 Second parameter WIDTH specifies the pixel width for the scroll bar;
6448 this is automatically adjusted to a multiple of the frame column width.
6449 Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
6450 bar: left, right, or nil.
6451 If WIDTH is nil, use the frame's scroll-bar width.
6452 If TYPE is t, use the frame's scroll-bar type. */)
6453 (window
, width
, vertical_type
, horizontal_type
)
6454 Lisp_Object window
, width
, vertical_type
, horizontal_type
;
6456 struct window
*w
= decode_window (window
);
6460 CHECK_NATNUM (width
);
6462 if (XINT (width
) == 0)
6463 vertical_type
= Qnil
;
6466 if (!(EQ (vertical_type
, Qnil
)
6467 || EQ (vertical_type
, Qleft
)
6468 || EQ (vertical_type
, Qright
)
6469 || EQ (vertical_type
, Qt
)))
6470 error ("Invalid type of vertical scroll bar");
6472 if (!EQ (w
->scroll_bar_width
, width
)
6473 || !EQ (w
->vertical_scroll_bar_type
, vertical_type
))
6475 w
->scroll_bar_width
= width
;
6476 w
->vertical_scroll_bar_type
= vertical_type
;
6478 adjust_window_margins (w
);
6480 clear_glyph_matrix (w
->current_matrix
);
6481 w
->window_end_valid
= Qnil
;
6483 ++windows_or_buffers_changed
;
6484 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
6491 DEFUN ("window-scroll-bars", Fwindow_scroll_bars
, Swindow_scroll_bars
,
6493 doc
: /* Get width and type of scroll bars of window WINDOW.
6494 If WINDOW is omitted or nil, use the currently selected window.
6495 Value is a list of the form (WIDTH COLS VERTICAL-TYPE HORIZONTAL-TYPE).
6496 If WIDTH is nil or TYPE is t, the window is using the frame's corresponding
6501 struct window
*w
= decode_window (window
);
6502 return Fcons (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
)
6503 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
)
6504 : WINDOW_SCROLL_BAR_AREA_WIDTH (w
))),
6505 Fcons (make_number (WINDOW_SCROLL_BAR_COLS (w
)),
6506 Fcons (w
->vertical_scroll_bar_type
,
6507 Fcons (Qnil
, Qnil
))));
6512 /***********************************************************************
6514 ***********************************************************************/
6516 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 2, 0,
6517 doc
: /* Return the amount by which WINDOW is scrolled vertically.
6518 Use the selected window if WINDOW is nil or omitted.
6519 Normally, value is a multiple of the canonical character height of WINDOW;
6520 optional second arg PIXELS_P means value is measured in pixels. */)
6522 Lisp_Object window
, pixels_p
;
6529 window
= selected_window
;
6531 CHECK_WINDOW (window
);
6532 w
= XWINDOW (window
);
6533 f
= XFRAME (w
->frame
);
6535 if (FRAME_WINDOW_P (f
))
6536 result
= (NILP (pixels_p
)
6537 ? FRAME_CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
)
6538 : make_number (-w
->vscroll
));
6540 result
= make_number (0);
6545 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
6547 doc
: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL.
6548 WINDOW nil means use the selected window. Normally, VSCROLL is a
6549 non-negative multiple of the canonical character height of WINDOW;
6550 optional third arg PIXELS_P non-nil means that VSCROLL is in pixels.
6551 If PIXELS-P is nil, VSCROLL may have to be rounded so that it
6552 corresponds to an integral number of pixels. The return value is the
6553 result of this rounding.
6554 If PIXELS-P is non-nil, the return value is VSCROLL. */)
6555 (window
, vscroll
, pixels_p
)
6556 Lisp_Object window
, vscroll
, pixels_p
;
6562 window
= selected_window
;
6564 CHECK_WINDOW (window
);
6565 CHECK_NUMBER_OR_FLOAT (vscroll
);
6567 w
= XWINDOW (window
);
6568 f
= XFRAME (w
->frame
);
6570 if (FRAME_WINDOW_P (f
))
6572 int old_dy
= w
->vscroll
;
6574 w
->vscroll
= - (NILP (pixels_p
)
6575 ? FRAME_LINE_HEIGHT (f
) * XFLOATINT (vscroll
)
6576 : XFLOATINT (vscroll
));
6577 w
->vscroll
= min (w
->vscroll
, 0);
6579 if (w
->vscroll
!= old_dy
)
6581 /* Adjust glyph matrix of the frame if the virtual display
6582 area becomes larger than before. */
6583 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
6586 /* Prevent redisplay shortcuts. */
6587 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
6591 return Fwindow_vscroll (window
, pixels_p
);
6595 /* Call FN for all leaf windows on frame F. FN is called with the
6596 first argument being a pointer to the leaf window, and with
6597 additional argument USER_DATA. Stops when FN returns 0. */
6600 foreach_window (f
, fn
, user_data
)
6602 int (* fn
) P_ ((struct window
*, void *));
6605 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, user_data
);
6609 /* Helper function for foreach_window. Call FN for all leaf windows
6610 reachable from W. FN is called with the first argument being a
6611 pointer to the leaf window, and with additional argument USER_DATA.
6612 Stop when FN returns 0. Value is 0 if stopped by FN. */
6615 foreach_window_1 (w
, fn
, user_data
)
6617 int (* fn
) P_ ((struct window
*, void *));
6622 for (cont
= 1; w
&& cont
;)
6624 if (!NILP (w
->hchild
))
6625 cont
= foreach_window_1 (XWINDOW (w
->hchild
), fn
, user_data
);
6626 else if (!NILP (w
->vchild
))
6627 cont
= foreach_window_1 (XWINDOW (w
->vchild
), fn
, user_data
);
6629 cont
= fn (w
, user_data
);
6631 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
6638 /* Freeze or unfreeze the window start of W unless it is a
6639 mini-window or the selected window. FREEZE_P non-null means freeze
6640 the window start. */
6643 freeze_window_start (w
, freeze_p
)
6647 if (w
== XWINDOW (selected_window
)
6648 || MINI_WINDOW_P (w
)
6649 || (MINI_WINDOW_P (XWINDOW (selected_window
))
6650 && ! NILP (Vminibuf_scroll_window
)
6651 && w
== XWINDOW (Vminibuf_scroll_window
)))
6654 w
->frozen_window_start_p
= freeze_p
!= NULL
;
6659 /* Freeze or unfreeze the window starts of all leaf windows on frame
6660 F, except the selected window and a mini-window. FREEZE_P non-zero
6661 means freeze the window start. */
6664 freeze_window_starts (f
, freeze_p
)
6668 foreach_window (f
, freeze_window_start
, (void *) (freeze_p
? f
: 0));
6672 /***********************************************************************
6674 ***********************************************************************/
6676 /* Return 1 if window configurations C1 and C2
6677 describe the same state of affairs. This is used by Fequal. */
6680 compare_window_configurations (c1
, c2
, ignore_positions
)
6682 int ignore_positions
;
6684 register struct save_window_data
*d1
, *d2
;
6685 struct Lisp_Vector
*sw1
, *sw2
;
6688 if (!WINDOW_CONFIGURATIONP (c1
))
6689 wrong_type_argument (Qwindow_configuration_p
, c1
);
6690 if (!WINDOW_CONFIGURATIONP (c2
))
6691 wrong_type_argument (Qwindow_configuration_p
, c2
);
6693 d1
= (struct save_window_data
*) XVECTOR (c1
);
6694 d2
= (struct save_window_data
*) XVECTOR (c2
);
6695 sw1
= XVECTOR (d1
->saved_windows
);
6696 sw2
= XVECTOR (d2
->saved_windows
);
6698 if (! EQ (d1
->frame_cols
, d2
->frame_cols
))
6700 if (! EQ (d1
->frame_lines
, d2
->frame_lines
))
6702 if (! EQ (d1
->frame_menu_bar_lines
, d2
->frame_menu_bar_lines
))
6704 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
6706 /* Don't compare the current_window field directly.
6707 Instead see w1_is_current and w2_is_current, below. */
6708 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
6710 if (! ignore_positions
)
6712 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
6714 if (! EQ (d1
->minibuf_selected_window
, d2
->minibuf_selected_window
))
6717 /* Don't compare the root_window field.
6718 We don't require the two configurations
6719 to use the same window object,
6720 and the two root windows must be equivalent
6721 if everything else compares equal. */
6722 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
6724 if (! EQ (d1
->min_width
, d2
->min_width
))
6726 if (! EQ (d1
->min_height
, d2
->min_height
))
6729 /* Verify that the two confis have the same number of windows. */
6730 if (sw1
->size
!= sw2
->size
)
6733 for (i
= 0; i
< sw1
->size
; i
++)
6735 struct saved_window
*p1
, *p2
;
6736 int w1_is_current
, w2_is_current
;
6738 p1
= SAVED_WINDOW_N (sw1
, i
);
6739 p2
= SAVED_WINDOW_N (sw2
, i
);
6741 /* Verify that the current windows in the two
6742 configurations correspond to each other. */
6743 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
6744 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
6746 if (w1_is_current
!= w2_is_current
)
6749 /* Verify that the corresponding windows do match. */
6750 if (! EQ (p1
->buffer
, p2
->buffer
))
6752 if (! EQ (p1
->left_col
, p2
->left_col
))
6754 if (! EQ (p1
->top_line
, p2
->top_line
))
6756 if (! EQ (p1
->total_cols
, p2
->total_cols
))
6758 if (! EQ (p1
->total_lines
, p2
->total_lines
))
6760 if (! EQ (p1
->display_table
, p2
->display_table
))
6762 if (! EQ (p1
->parent
, p2
->parent
))
6764 if (! EQ (p1
->prev
, p2
->prev
))
6766 if (! ignore_positions
)
6768 if (! EQ (p1
->hscroll
, p2
->hscroll
))
6770 if (!EQ (p1
->min_hscroll
, p2
->min_hscroll
))
6772 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
6774 if (NILP (Fequal (p1
->start
, p2
->start
)))
6776 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
6778 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
6781 if (! EQ (p1
->left_margin_cols
, p2
->left_margin_cols
))
6783 if (! EQ (p1
->right_margin_cols
, p2
->right_margin_cols
))
6785 if (! EQ (p1
->left_fringe_width
, p2
->left_fringe_width
))
6787 if (! EQ (p1
->right_fringe_width
, p2
->right_fringe_width
))
6789 if (! EQ (p1
->fringes_outside_margins
, p2
->fringes_outside_margins
))
6791 if (! EQ (p1
->scroll_bar_width
, p2
->scroll_bar_width
))
6793 if (! EQ (p1
->vertical_scroll_bar_type
, p2
->vertical_scroll_bar_type
))
6800 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
6801 Scompare_window_configurations
, 2, 2, 0,
6802 doc
: /* Compare two window configurations as regards the structure of windows.
6803 This function ignores details such as the values of point and mark
6804 and scrolling positions. */)
6808 if (compare_window_configurations (x
, y
, 1))
6816 struct frame
*f
= make_terminal_frame ();
6817 XSETFRAME (selected_frame
, f
);
6818 Vterminal_frame
= selected_frame
;
6819 minibuf_window
= f
->minibuffer_window
;
6820 selected_window
= f
->selected_window
;
6821 last_nonminibuf_frame
= f
;
6823 window_initialized
= 1;
6829 Vwindow_list
= Qnil
;
6835 Qwindow_size_fixed
= intern ("window-size-fixed");
6836 staticpro (&Qwindow_size_fixed
);
6837 Fset (Qwindow_size_fixed
, Qnil
);
6839 staticpro (&Qwindow_configuration_change_hook
);
6840 Qwindow_configuration_change_hook
6841 = intern ("window-configuration-change-hook");
6843 Qwindowp
= intern ("windowp");
6844 staticpro (&Qwindowp
);
6846 Qwindow_configuration_p
= intern ("window-configuration-p");
6847 staticpro (&Qwindow_configuration_p
);
6849 Qwindow_live_p
= intern ("window-live-p");
6850 staticpro (&Qwindow_live_p
);
6852 Qtemp_buffer_show_hook
= intern ("temp-buffer-show-hook");
6853 staticpro (&Qtemp_buffer_show_hook
);
6855 staticpro (&Vwindow_list
);
6857 minibuf_selected_window
= Qnil
;
6858 staticpro (&minibuf_selected_window
);
6860 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
6861 doc
: /* Non-nil means call as function to display a help buffer.
6862 The function is called with one argument, the buffer to be displayed.
6863 Used by `with-output-to-temp-buffer'.
6864 If this function is used, then it must do the entire job of showing
6865 the buffer; `temp-buffer-show-hook' is not run unless this function runs it. */);
6866 Vtemp_buffer_show_function
= Qnil
;
6868 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
6869 doc
: /* If non-nil, function to call to handle `display-buffer'.
6870 It will receive two args, the buffer and a flag which if non-nil means
6871 that the currently selected window is not acceptable.
6872 It should choose or create a window, display the specified buffer in it,
6873 and return the window.
6874 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'
6875 work using this function. */);
6876 Vdisplay_buffer_function
= Qnil
;
6878 DEFVAR_LISP ("even-window-heights", &Veven_window_heights
,
6879 doc
: /* *If non-nil, `display-buffer' should even the window heights.
6880 If nil, `display-buffer' will leave the window configuration alone. */);
6881 Veven_window_heights
= Qt
;
6883 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
6884 doc
: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */);
6885 Vminibuf_scroll_window
= Qnil
;
6887 DEFVAR_BOOL ("mode-line-in-non-selected-windows", &mode_line_in_non_selected_windows
,
6888 doc
: /* Non-nil means to use `mode-line-inactive' face in non-selected windows.
6889 If the minibuffer is active, the `minibuffer-scroll-window' mode line
6890 is displayed in the `mode-line' face. */);
6891 mode_line_in_non_selected_windows
= 1;
6893 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
6894 doc
: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. */);
6895 Vother_window_scroll_buffer
= Qnil
;
6897 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
6898 doc
: /* *Non-nil means `display-buffer' should make a separate frame. */);
6901 DEFVAR_BOOL ("auto-window-vscroll", &auto_window_vscroll_p
,
6902 doc
: /* *Non-nil means to automatically adjust `window-vscroll' to view tall lines. */);
6903 auto_window_vscroll_p
= 1;
6905 DEFVAR_BOOL ("display-buffer-reuse-frames", &display_buffer_reuse_frames
,
6906 doc
: /* *Non-nil means `display-buffer' should reuse frames.
6907 If the buffer in question is already displayed in a frame, raise that frame. */);
6908 display_buffer_reuse_frames
= 0;
6910 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
6911 doc
: /* Function to call to handle automatic new frame creation.
6912 It is called with no arguments and should return a newly created frame.
6914 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'
6915 where `pop-up-frame-alist' would hold the default frame parameters. */);
6916 Vpop_up_frame_function
= Qnil
;
6918 DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names
,
6919 doc
: /* *List of buffer names that should have their own special frames.
6920 Displaying a buffer with `display-buffer' or `pop-to-buffer',
6921 if its name is in this list, makes a special frame for it
6922 using `special-display-function'. See also `special-display-regexps'.
6924 An element of the list can be a list instead of just a string.
6925 There are two ways to use a list as an element:
6926 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)
6927 In the first case, the FRAME-PARAMETERS are pairs of the form
6928 \(PARAMETER . VALUE); these parameter values are used to create the frame.
6929 In the second case, FUNCTION is called with BUFFER as the first argument,
6930 followed by the OTHER-ARGS--it can display BUFFER in any way it likes.
6931 All this is done by the function found in `special-display-function'.
6933 If the specified frame parameters include (same-buffer . t), the
6934 buffer is displayed in the currently selected window. Otherwise, if
6935 they include (same-frame . t), the buffer is displayed in a new window
6936 in the currently selected frame.
6938 If this variable appears \"not to work\", because you add a name to it
6939 but that buffer still appears in the selected window, look at the
6940 values of `same-window-buffer-names' and `same-window-regexps'.
6941 Those variables take precedence over this one. */);
6942 Vspecial_display_buffer_names
= Qnil
;
6944 DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps
,
6945 doc
: /* *List of regexps saying which buffers should have their own special frames.
6946 When displaying a buffer with `display-buffer' or `pop-to-buffer',
6947 if any regexp in this list matches the buffer name, it makes a
6948 special frame for the buffer by calling `special-display-function'.
6950 An element of the list can be a list instead of just a string.
6951 There are two ways to use a list as an element:
6952 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)
6953 In the first case, the FRAME-PARAMETERS are pairs of the form
6954 \(PARAMETER . VALUE); these parameter values are used to create the frame.
6955 In the second case, FUNCTION is called with BUFFER as the first argument,
6956 followed by the OTHER-ARGS--it can display the buffer in any way it likes.
6957 All this is done by the function found in `special-display-function'.
6959 If the specified frame parameters include (same-buffer . t), the
6960 buffer is displayed in the currently selected window. Otherwise, if
6961 they include (same-frame . t), the buffer is displayed in a new window
6962 in the currently selected frame.
6964 If this variable appears \"not to work\", because you add a regexp to it
6965 but the matching buffers still appear in the selected window, look at the
6966 values of `same-window-buffer-names' and `same-window-regexps'.
6967 Those variables take precedence over this one. */);
6968 Vspecial_display_regexps
= Qnil
;
6970 DEFVAR_LISP ("special-display-function", &Vspecial_display_function
,
6971 doc
: /* Function to call to make a new frame for a special buffer.
6972 It is called with two arguments, the buffer and optional buffer specific
6973 data, and should return a window displaying that buffer.
6974 The default value normally makes a separate frame for the buffer,
6975 using `special-display-frame-alist' to specify the frame parameters.
6976 But if the buffer specific data includes (same-buffer . t) then the
6977 buffer is displayed in the current selected window.
6978 Otherwise if it includes (same-frame . t) then the buffer is displayed in
6979 a new window in the currently selected frame.
6981 A buffer is special if it is listed in `special-display-buffer-names'
6982 or matches a regexp in `special-display-regexps'. */);
6983 Vspecial_display_function
= Qnil
;
6985 DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names
,
6986 doc
: /* *List of buffer names that should appear in the selected window.
6987 Displaying one of these buffers using `display-buffer' or `pop-to-buffer'
6988 switches to it in the selected window, rather than making it appear
6989 in some other window.
6991 An element of the list can be a cons cell instead of just a string.
6992 Then the car must be a string, which specifies the buffer name.
6993 This is for compatibility with `special-display-buffer-names';
6994 the cdr of the cons cell is ignored.
6996 See also `same-window-regexps'. */);
6997 Vsame_window_buffer_names
= Qnil
;
6999 DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps
,
7000 doc
: /* *List of regexps saying which buffers should appear in the selected window.
7001 If a buffer name matches one of these regexps, then displaying it
7002 using `display-buffer' or `pop-to-buffer' switches to it
7003 in the selected window, rather than making it appear in some other window.
7005 An element of the list can be a cons cell instead of just a string.
7006 Then the car must be a string, which specifies the buffer name.
7007 This is for compatibility with `special-display-buffer-names';
7008 the cdr of the cons cell is ignored.
7010 See also `same-window-buffer-names'. */);
7011 Vsame_window_regexps
= Qnil
;
7013 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
7014 doc
: /* *Non-nil means display-buffer should make new windows. */);
7017 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
7018 doc
: /* *Number of lines of continuity when scrolling by screenfuls. */);
7019 next_screen_context_lines
= 2;
7021 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
7022 doc
: /* *A window must be at least this tall to be eligible for splitting by `display-buffer'.
7023 If there is only one window, it is split regardless of this value. */);
7024 split_height_threshold
= 500;
7026 DEFVAR_INT ("window-min-height", &window_min_height
,
7027 doc
: /* *Delete any window less than this tall (including its mode line). */);
7028 window_min_height
= 4;
7030 DEFVAR_INT ("window-min-width", &window_min_width
,
7031 doc
: /* *Delete any window less than this wide. */);
7032 window_min_width
= 10;
7034 DEFVAR_LISP ("scroll-preserve-screen-position",
7035 &Vscroll_preserve_screen_position
,
7036 doc
: /* *Controls if scroll commands move point to keep its screen line unchanged.
7037 A value of nil means point does not keep its screen position except
7038 at the scroll margin or window boundary respectively.
7039 A value of t means point keeps its screen position if the scroll
7040 command moved it vertically out of the window, e.g. when scrolling
7042 Any other value means point always keeps its screen position. */);
7043 Vscroll_preserve_screen_position
= Qnil
;
7045 DEFVAR_LISP ("window-configuration-change-hook",
7046 &Vwindow_configuration_change_hook
,
7047 doc
: /* Functions to call when window configuration changes.
7048 The selected frame is the one whose configuration has changed. */);
7049 Vwindow_configuration_change_hook
= Qnil
;
7051 defsubr (&Sselected_window
);
7052 defsubr (&Sminibuffer_window
);
7053 defsubr (&Swindow_minibuffer_p
);
7054 defsubr (&Swindowp
);
7055 defsubr (&Swindow_live_p
);
7056 defsubr (&Spos_visible_in_window_p
);
7057 defsubr (&Swindow_buffer
);
7058 defsubr (&Swindow_height
);
7059 defsubr (&Swindow_width
);
7060 defsubr (&Swindow_hscroll
);
7061 defsubr (&Sset_window_hscroll
);
7062 defsubr (&Swindow_redisplay_end_trigger
);
7063 defsubr (&Sset_window_redisplay_end_trigger
);
7064 defsubr (&Swindow_edges
);
7065 defsubr (&Swindow_pixel_edges
);
7066 defsubr (&Swindow_inside_edges
);
7067 defsubr (&Swindow_inside_pixel_edges
);
7068 defsubr (&Scoordinates_in_window_p
);
7069 defsubr (&Swindow_at
);
7070 defsubr (&Swindow_point
);
7071 defsubr (&Swindow_start
);
7072 defsubr (&Swindow_end
);
7073 defsubr (&Sset_window_point
);
7074 defsubr (&Sset_window_start
);
7075 defsubr (&Swindow_dedicated_p
);
7076 defsubr (&Sset_window_dedicated_p
);
7077 defsubr (&Swindow_display_table
);
7078 defsubr (&Sset_window_display_table
);
7079 defsubr (&Snext_window
);
7080 defsubr (&Sprevious_window
);
7081 defsubr (&Sother_window
);
7082 defsubr (&Sget_lru_window
);
7083 defsubr (&Sget_largest_window
);
7084 defsubr (&Sget_buffer_window
);
7085 defsubr (&Sdelete_other_windows
);
7086 defsubr (&Sdelete_windows_on
);
7087 defsubr (&Sreplace_buffer_in_windows
);
7088 defsubr (&Sdelete_window
);
7089 defsubr (&Sset_window_buffer
);
7090 defsubr (&Sselect_window
);
7091 defsubr (&Sspecial_display_p
);
7092 defsubr (&Ssame_window_p
);
7093 defsubr (&Sdisplay_buffer
);
7094 defsubr (&Sforce_window_update
);
7095 defsubr (&Ssplit_window
);
7096 defsubr (&Senlarge_window
);
7097 defsubr (&Sshrink_window
);
7098 defsubr (&Sscroll_up
);
7099 defsubr (&Sscroll_down
);
7100 defsubr (&Sscroll_left
);
7101 defsubr (&Sscroll_right
);
7102 defsubr (&Sother_window_for_scrolling
);
7103 defsubr (&Sscroll_other_window
);
7104 defsubr (&Sminibuffer_selected_window
);
7105 defsubr (&Srecenter
);
7106 defsubr (&Swindow_text_height
);
7107 defsubr (&Smove_to_window_line
);
7108 defsubr (&Swindow_configuration_p
);
7109 defsubr (&Swindow_configuration_frame
);
7110 defsubr (&Sset_window_configuration
);
7111 defsubr (&Scurrent_window_configuration
);
7112 defsubr (&Ssave_window_excursion
);
7113 defsubr (&Swindow_tree
);
7114 defsubr (&Sset_window_margins
);
7115 defsubr (&Swindow_margins
);
7116 defsubr (&Sset_window_fringes
);
7117 defsubr (&Swindow_fringes
);
7118 defsubr (&Sset_window_scroll_bars
);
7119 defsubr (&Swindow_scroll_bars
);
7120 defsubr (&Swindow_vscroll
);
7121 defsubr (&Sset_window_vscroll
);
7122 defsubr (&Scompare_window_configurations
);
7123 defsubr (&Swindow_list
);
7129 initial_define_key (control_x_map
, '1', "delete-other-windows");
7130 initial_define_key (control_x_map
, '2', "split-window");
7131 initial_define_key (control_x_map
, '0', "delete-window");
7132 initial_define_key (control_x_map
, 'o', "other-window");
7133 initial_define_key (control_x_map
, '^', "enlarge-window");
7134 initial_define_key (control_x_map
, '<', "scroll-left");
7135 initial_define_key (control_x_map
, '>', "scroll-right");
7137 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
7138 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
7139 initial_define_key (meta_map
, 'v', "scroll-down");
7141 initial_define_key (global_map
, Ctl('L'), "recenter");
7142 initial_define_key (meta_map
, 'r', "move-to-window-line");
7145 /* arch-tag: 90a9c576-0590-48f1-a5f1-6c96a0452d9f
7146 (do not change this comment) */