1 /* Window creation, deletion and examination for GNU Emacs.
2 Does not include redisplay.
3 Copyright (C) 1985,86,87,93,94,95,96,97,1998,2000, 2001, 2002, 2003
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 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., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, 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 /* The value of `window-size-fixed'. */
84 int window_size_fixed
;
86 /* This is the window in which the terminal's cursor should
87 be left when nothing is being done with it. This must
88 always be a leaf window, and its buffer is selected by
89 the top level editing loop at the end of each command.
91 This value is always the same as
92 FRAME_SELECTED_WINDOW (selected_frame). */
94 Lisp_Object selected_window
;
96 /* A list of all windows for use by next_window and Fwindow_list.
97 Functions creating or deleting windows should invalidate this cache
98 by setting it to nil. */
100 Lisp_Object Vwindow_list
;
102 /* The mini-buffer window of the selected frame.
103 Note that you cannot test for mini-bufferness of an arbitrary window
104 by comparing against this; but you can test for mini-bufferness of
105 the selected window. */
107 Lisp_Object minibuf_window
;
109 /* Non-nil means it is the window whose mode line should be
110 shown as the selected window when the minibuffer is selected. */
112 Lisp_Object minibuf_selected_window
;
114 /* Non-nil means it is the window for C-M-v to scroll
115 when the mini-buffer is selected. */
117 Lisp_Object Vminibuf_scroll_window
;
119 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
121 Lisp_Object Vother_window_scroll_buffer
;
123 /* Non-nil means it's function to call to display temp buffers. */
125 Lisp_Object Vtemp_buffer_show_function
;
127 /* Non-zero means to use mode-line-inactive face in all windows but the
128 selected-window and the minibuffer-scroll-window when the
129 minibuffer is active. */
130 int mode_line_in_non_selected_windows
;
132 /* If a window gets smaller than either of these, it is removed. */
134 EMACS_INT window_min_height
;
135 EMACS_INT window_min_width
;
137 /* Nonzero implies Fdisplay_buffer should create windows. */
141 /* Nonzero implies make new frames for Fdisplay_buffer. */
145 /* Nonzero means reuse existing frames for displaying buffers. */
147 int display_buffer_reuse_frames
;
149 /* Non-nil means use this function instead of default */
151 Lisp_Object Vpop_up_frame_function
;
153 /* Function to call to handle Fdisplay_buffer. */
155 Lisp_Object Vdisplay_buffer_function
;
157 /* Non-nil means that Fdisplay_buffer should even the heights of windows. */
159 Lisp_Object Veven_window_heights
;
161 /* List of buffer *names* for buffers that should have their own frames. */
163 Lisp_Object Vspecial_display_buffer_names
;
165 /* List of regexps for buffer names that should have their own frames. */
167 Lisp_Object Vspecial_display_regexps
;
169 /* Function to pop up a special frame. */
171 Lisp_Object Vspecial_display_function
;
173 /* List of buffer *names* for buffers to appear in selected window. */
175 Lisp_Object Vsame_window_buffer_names
;
177 /* List of regexps for buffer names to appear in selected window. */
179 Lisp_Object Vsame_window_regexps
;
181 /* Hook run at end of temp_output_buffer_show. */
183 Lisp_Object Qtemp_buffer_show_hook
;
185 /* Fdisplay_buffer always splits the largest window
186 if that window is more than this high. */
188 EMACS_INT split_height_threshold
;
190 /* Number of lines of continuity in scrolling by screenfuls. */
192 EMACS_INT next_screen_context_lines
;
194 /* Incremented for each window created. */
196 static int sequence_number
;
198 /* Nonzero after init_window_once has finished. */
200 static int window_initialized
;
202 /* Hook to run when window config changes. */
204 Lisp_Object Qwindow_configuration_change_hook
;
205 Lisp_Object Vwindow_configuration_change_hook
;
207 /* Nonzero means scroll commands try to put point
208 at the same screen height as previously. */
210 Lisp_Object Vscroll_preserve_screen_position
;
212 #if 0 /* This isn't used anywhere. */
213 /* Nonzero means we can split a frame even if it is "unsplittable". */
214 static int inhibit_frame_unsplittable
;
217 extern EMACS_INT scroll_margin
;
219 extern Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
221 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
222 doc
: /* Returns t if OBJECT is a window. */)
226 return WINDOWP (object
) ? Qt
: Qnil
;
229 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
230 doc
: /* Returns t if OBJECT is a window which is currently visible. */)
234 return WINDOW_LIVE_P (object
) ? Qt
: Qnil
;
241 register struct window
*p
;
243 p
= allocate_window ();
244 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
245 XSETFASTINT (p
->left_col
, 0);
246 XSETFASTINT (p
->top_line
, 0);
247 XSETFASTINT (p
->total_lines
, 0);
248 XSETFASTINT (p
->total_cols
, 0);
249 XSETFASTINT (p
->hscroll
, 0);
250 XSETFASTINT (p
->min_hscroll
, 0);
251 p
->orig_top_line
= p
->orig_total_lines
= Qnil
;
252 p
->start
= Fmake_marker ();
253 p
->pointm
= Fmake_marker ();
254 XSETFASTINT (p
->use_time
, 0);
256 p
->display_table
= Qnil
;
258 p
->pseudo_window_p
= 0;
259 bzero (&p
->cursor
, sizeof (p
->cursor
));
260 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
261 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
262 p
->desired_matrix
= p
->current_matrix
= 0;
263 p
->phys_cursor_type
= -1;
264 p
->phys_cursor_width
= -1;
265 p
->must_be_updated_p
= 0;
266 XSETFASTINT (p
->window_end_vpos
, 0);
267 XSETFASTINT (p
->window_end_pos
, 0);
268 p
->window_end_valid
= Qnil
;
271 XSETFASTINT (p
->last_point
, 0);
272 p
->frozen_window_start_p
= 0;
273 p
->height_fixed_p
= 0;
274 p
->last_cursor_off_p
= p
->cursor_off_p
= 0;
275 p
->left_margin_cols
= Qnil
;
276 p
->right_margin_cols
= Qnil
;
277 p
->left_fringe_width
= Qnil
;
278 p
->right_fringe_width
= Qnil
;
279 p
->fringes_outside_margins
= Qnil
;
280 p
->scroll_bar_width
= Qnil
;
281 p
->vertical_scroll_bar_type
= Qt
;
287 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
288 doc
: /* Return the window that the cursor now appears in and commands apply to. */)
291 return selected_window
;
294 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
295 doc
: /* Return the window used now for minibuffers.
296 If the optional argument FRAME is specified, return the minibuffer window
297 used by that frame. */)
302 frame
= selected_frame
;
303 CHECK_LIVE_FRAME (frame
);
304 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
307 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 0, 1, 0,
308 doc
: /* Returns non-nil if WINDOW is a minibuffer window. */)
312 struct window
*w
= decode_window (window
);
313 return MINI_WINDOW_P (w
) ? Qt
: Qnil
;
317 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
318 Spos_visible_in_window_p
, 0, 3, 0,
319 doc
: /* Return t if position POS is currently on the frame in WINDOW.
320 Return nil if that position is scrolled vertically out of view.
321 If a character is only partially visible, nil is returned, unless the
322 optional argument PARTIALLY is non-nil.
323 POS defaults to point in WINDOW; WINDOW defaults to the selected window. */)
324 (pos
, window
, partially
)
325 Lisp_Object pos
, window
, partially
;
327 register struct window
*w
;
329 register struct buffer
*buf
;
331 Lisp_Object in_window
;
334 w
= decode_window (window
);
335 buf
= XBUFFER (w
->buffer
);
336 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
340 CHECK_NUMBER_COERCE_MARKER (pos
);
343 else if (w
== XWINDOW (selected_window
))
346 posint
= XMARKER (w
->pointm
)->charpos
;
348 /* If position is above window start, it's not visible. */
349 if (posint
< CHARPOS (top
))
351 else if (XFASTINT (w
->last_modified
) >= BUF_MODIFF (buf
)
352 && XFASTINT (w
->last_overlay_modified
) >= BUF_OVERLAY_MODIFF (buf
)
353 && posint
< BUF_Z (buf
) - XFASTINT (w
->window_end_pos
))
355 /* If frame is up-to-date, and POSINT is < window end pos, use
356 that info. This doesn't work for POSINT == end pos, because
357 the window end pos is actually the position _after_ the last
358 char in the window. */
359 if (NILP (partially
))
361 pos_visible_p (w
, posint
, &fully_p
, NILP (partially
));
362 in_window
= fully_p
? Qt
: Qnil
;
367 else if (posint
> BUF_ZV (buf
))
369 else if (CHARPOS (top
) < BUF_BEGV (buf
) || CHARPOS (top
) > BUF_ZV (buf
))
370 /* If window start is out of range, do something reasonable. */
374 if (pos_visible_p (w
, posint
, &fully_p
, NILP (partially
)))
375 in_window
= !NILP (partially
) || fully_p
? Qt
: Qnil
;
384 static struct window
*
385 decode_window (window
)
386 register Lisp_Object window
;
389 return XWINDOW (selected_window
);
391 CHECK_LIVE_WINDOW (window
);
392 return XWINDOW (window
);
395 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
396 doc
: /* Return the buffer that WINDOW is displaying. */)
400 return decode_window (window
)->buffer
;
403 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
404 doc
: /* Return the number of lines in WINDOW (including its mode line). */)
408 return decode_window (window
)->total_lines
;
411 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
412 doc
: /* Return the number of display columns in WINDOW.
413 This is the width that is usable columns available for text in WINDOW.
414 If you want to find out how many columns WINDOW takes up,
415 use (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))). */)
419 return make_number (window_box_text_cols (decode_window (window
)));
422 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
423 doc
: /* Return the number of columns by which WINDOW is scrolled from left margin. */)
427 return decode_window (window
)->hscroll
;
430 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
431 doc
: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
432 NCOL should be zero or positive.
434 Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
435 window so that the location of point becomes invisible. */)
437 Lisp_Object window
, ncol
;
439 struct window
*w
= decode_window (window
);
443 hscroll
= max (0, XINT (ncol
));
445 /* Prevent redisplay shortcuts when changing the hscroll. */
446 if (XINT (w
->hscroll
) != hscroll
)
447 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
449 w
->hscroll
= make_number (hscroll
);
453 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
454 Swindow_redisplay_end_trigger
, 0, 1, 0,
455 doc
: /* Return WINDOW's redisplay end trigger value.
456 See `set-window-redisplay-end-trigger' for more information. */)
460 return decode_window (window
)->redisplay_end_trigger
;
463 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
464 Sset_window_redisplay_end_trigger
, 2, 2, 0,
465 doc
: /* Set WINDOW's redisplay end trigger value to VALUE.
466 VALUE should be a buffer position (typically a marker) or nil.
467 If it is a buffer position, then if redisplay in WINDOW reaches a position
468 beyond VALUE, the functions in `redisplay-end-trigger-functions' are called
469 with two arguments: WINDOW, and the end trigger value.
470 Afterwards the end-trigger value is reset to nil. */)
472 register Lisp_Object window
, value
;
474 register struct window
*w
;
476 w
= decode_window (window
);
477 w
->redisplay_end_trigger
= value
;
481 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
482 doc
: /* Return a list of the edge coordinates of WINDOW.
483 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.
484 RIGHT is one more than the rightmost column used by WINDOW,
485 and BOTTOM is one more than the bottommost row used by WINDOW
486 and its mode-line. */)
490 register struct window
*w
= decode_window (window
);
492 return Fcons (make_number (WINDOW_LEFT_EDGE_COL (w
)),
493 Fcons (make_number (WINDOW_TOP_EDGE_LINE (w
)),
494 Fcons (make_number (WINDOW_RIGHT_EDGE_COL (w
)),
495 Fcons (make_number (WINDOW_BOTTOM_EDGE_LINE (w
)),
499 /* Test if the character at column *X, row *Y is within window W.
500 If it is not, return ON_NOTHING;
501 if it is in the window's text area,
502 set *x and *y to its location relative to the upper left corner
505 if it is on the window's modeline, return ON_MODE_LINE;
506 if it is on the border between the window and its right sibling,
507 return ON_VERTICAL_BORDER.
508 if it is on the window's top line, return ON_HEADER_LINE;
509 if it is in left or right fringe of the window,
510 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE, and convert *X and *Y
511 to window-relative coordinates;
512 if it is in the marginal area to the left/right of the window,
513 return ON_LEFT_MARGIN or ON_RIGHT_MARGIN, and convert *X and *Y
514 to window-relative coordinates.
516 X and Y are frame relative pixel coordinates. */
518 static enum window_part
519 coordinates_in_window (w
, x
, y
)
520 register struct window
*w
;
523 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
524 int left_x
, right_x
, top_y
, bottom_y
;
525 enum window_part part
;
526 int ux
= FRAME_COLUMN_WIDTH (f
);
527 int x0
= WINDOW_LEFT_EDGE_X (w
);
528 int x1
= WINDOW_RIGHT_EDGE_X (w
);
529 /* The width of the area where the vertical line can be dragged.
530 (Between mode lines for instance. */
531 int grabbable_width
= ux
;
532 int lmargin_width
, rmargin_width
, text_left
, text_right
;
534 if (*x
< x0
|| *x
>= x1
)
537 /* In what's below, we subtract 1 when computing right_x because we
538 want the rightmost pixel, which is given by left_pixel+width-1. */
539 if (w
->pseudo_window_p
)
542 right_x
= WINDOW_TOTAL_WIDTH (w
) - 1;
543 top_y
= WINDOW_TOP_EDGE_Y (w
);
544 bottom_y
= WINDOW_BOTTOM_EDGE_Y (w
);
548 left_x
= WINDOW_BOX_LEFT_EDGE_X (w
);
549 right_x
= WINDOW_BOX_RIGHT_EDGE_X (w
) - 1;
550 top_y
= WINDOW_TOP_EDGE_Y (w
);
551 bottom_y
= WINDOW_BOTTOM_EDGE_Y (w
);
554 /* Outside any interesting row? */
555 if (*y
< top_y
|| *y
>= bottom_y
)
558 /* On the mode line or header line? If it's near the start of
559 the mode or header line of window that's has a horizontal
560 sibling, say it's on the vertical line. That's to be able
561 to resize windows horizontally in case we're using toolkit
564 if (WINDOW_WANTS_MODELINE_P (w
)
565 && *y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
)
570 header_vertical_border_check
:
571 /* We're somewhere on the mode line. We consider the place
572 between mode lines of horizontally adjacent mode lines
573 as the vertical border. If scroll bars on the left,
574 return the right window. */
575 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
576 || WINDOW_RIGHTMOST_P (w
))
578 if (!WINDOW_LEFTMOST_P (w
) && abs (*x
- x0
) < grabbable_width
)
579 return ON_VERTICAL_BORDER
;
583 if (abs (*x
- x1
) < grabbable_width
)
584 return ON_VERTICAL_BORDER
;
590 if (WINDOW_WANTS_HEADER_LINE_P (w
)
592 && *y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
))
594 part
= ON_HEADER_LINE
;
595 goto header_vertical_border_check
;
598 /* Outside any interesting column? */
599 if (*x
< left_x
|| *x
> right_x
)
602 lmargin_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
603 rmargin_width
= window_box_width (w
, RIGHT_MARGIN_AREA
);
605 text_left
= window_box_left (w
, TEXT_AREA
);
606 text_right
= text_left
+ window_box_width (w
, TEXT_AREA
);
608 if (FRAME_WINDOW_P (f
))
610 if (!w
->pseudo_window_p
611 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
)
612 && !WINDOW_RIGHTMOST_P (w
)
613 && (abs (*x
- right_x
) < grabbable_width
))
614 return ON_VERTICAL_BORDER
;
618 /* Need to say "*x > right_x" rather than >=, since on character
619 terminals, the vertical line's x coordinate is right_x. */
620 if (!w
->pseudo_window_p
621 && !WINDOW_RIGHTMOST_P (w
)
622 && *x
> right_x
- ux
)
624 /* On the border on the right side of the window? Assume that
625 this area begins at RIGHT_X minus a canonical char width. */
626 return ON_VERTICAL_BORDER
;
632 if (lmargin_width
> 0
633 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
634 ? (*x
>= left_x
+ WINDOW_LEFT_FRINGE_WIDTH (w
))
635 : (*x
< left_x
+ lmargin_width
)))
636 return ON_LEFT_MARGIN
;
638 /* Convert X and Y to window-relative pixel coordinates. */
641 return ON_LEFT_FRINGE
;
644 if (*x
>= text_right
)
646 if (rmargin_width
> 0
647 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
648 ? (*x
< right_x
- WINDOW_RIGHT_FRINGE_WIDTH (w
))
649 : (*x
>= right_x
- rmargin_width
)))
650 return ON_RIGHT_MARGIN
;
652 /* Convert X and Y to window-relative pixel coordinates. */
653 *x
-= left_x
+ WINDOW_LEFT_FRINGE_WIDTH (w
);
655 return ON_RIGHT_FRINGE
;
658 /* Everything special ruled out - must be on text area */
659 *x
-= left_x
+ WINDOW_LEFT_FRINGE_WIDTH (w
);
665 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
666 Scoordinates_in_window_p
, 2, 2, 0,
667 doc
: /* Return non-nil if COORDINATES are in WINDOW.
668 COORDINATES is a cons of the form (X . Y), X and Y being distances
669 measured in characters from the upper-left corner of the frame.
670 \(0 . 0) denotes the character in the upper left corner of the
672 If COORDINATES are in the text portion of WINDOW,
673 the coordinates relative to the window are returned.
674 If they are in the mode line of WINDOW, `mode-line' is returned.
675 If they are in the top mode line of WINDOW, `header-line' is returned.
676 If they are in the left fringe of WINDOW, `left-fringe' is returned.
677 If they are in the right fringe of WINDOW, `right-fringe' is returned.
678 If they are on the border between WINDOW and its right sibling,
679 `vertical-line' is returned.
680 If they are in the windows's left or right marginal areas, `left-margin'\n\
681 or `right-margin' is returned. */)
682 (coordinates
, window
)
683 register Lisp_Object coordinates
, window
;
690 CHECK_LIVE_WINDOW (window
);
691 w
= XWINDOW (window
);
692 f
= XFRAME (w
->frame
);
693 CHECK_CONS (coordinates
);
694 lx
= Fcar (coordinates
);
695 ly
= Fcdr (coordinates
);
696 CHECK_NUMBER_OR_FLOAT (lx
);
697 CHECK_NUMBER_OR_FLOAT (ly
);
698 x
= FRAME_PIXEL_X_FROM_CANON_X (f
, lx
);
699 y
= FRAME_PIXEL_Y_FROM_CANON_Y (f
, ly
);
701 switch (coordinates_in_window (w
, &x
, &y
))
707 /* X and Y are now window relative pixel coordinates. Convert
708 them to canonical char units before returning them. */
709 return Fcons (FRAME_CANON_X_FROM_PIXEL_X (f
, x
),
710 FRAME_CANON_Y_FROM_PIXEL_Y (f
, y
));
715 case ON_VERTICAL_BORDER
:
716 return Qvertical_line
;
724 case ON_RIGHT_FRINGE
:
725 return Qright_fringe
;
730 case ON_RIGHT_MARGIN
:
731 return Qright_margin
;
739 /* Callback for foreach_window, used in window_from_coordinates.
740 Check if window W contains coordinates specified by USER_DATA which
741 is actually a pointer to a struct check_window_data CW.
743 Check if window W contains coordinates *CW->x and *CW->y. If it
744 does, return W in *CW->window, as Lisp_Object, and return in
745 *CW->part the part of the window under coordinates *X,*Y. Return
746 zero from this function to stop iterating over windows. */
748 struct check_window_data
752 enum window_part
*part
;
756 check_window_containing (w
, user_data
)
760 struct check_window_data
*cw
= (struct check_window_data
*) user_data
;
761 enum window_part found
;
764 found
= coordinates_in_window (w
, cw
->x
, cw
->y
);
765 if (found
!= ON_NOTHING
)
768 XSETWINDOW (*cw
->window
, w
);
776 /* Find the window containing frame-relative pixel position X/Y and
777 return it as a Lisp_Object.
779 If X, Y is on one of the window's special `window_part' elements,
780 set *PART to the id of that element, and return X and Y converted
781 to window relative coordinates in WX and WY.
783 If there is no window under X, Y return nil and leave *PART
784 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows.
786 This function was previously implemented with a loop cycling over
787 windows with Fnext_window, and starting with the frame's selected
788 window. It turned out that this doesn't work with an
789 implementation of next_window using Vwindow_list, because
790 FRAME_SELECTED_WINDOW (F) is not always contained in the window
791 tree of F when this function is called asynchronously from
792 note_mouse_highlight. The original loop didn't terminate in this
796 window_from_coordinates (f
, x
, y
, part
, wx
, wy
, tool_bar_p
)
799 enum window_part
*part
;
804 struct check_window_data cw
;
805 enum window_part dummy
;
811 cw
.window
= &window
, cw
.x
= &x
, cw
.y
= &y
; cw
.part
= part
;
812 foreach_window (f
, check_window_containing
, &cw
);
814 /* If not found above, see if it's in the tool bar window, if a tool
818 && WINDOWP (f
->tool_bar_window
)
819 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0
820 && (coordinates_in_window (XWINDOW (f
->tool_bar_window
), &x
, &y
)
824 window
= f
->tool_bar_window
;
833 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
834 doc
: /* Return window containing coordinates X and Y on FRAME.
835 If omitted, FRAME defaults to the currently selected frame.
836 The top left corner of the frame is considered to be row 0,
839 Lisp_Object x
, y
, frame
;
844 frame
= selected_frame
;
845 CHECK_LIVE_FRAME (frame
);
848 /* Check that arguments are integers or floats. */
849 CHECK_NUMBER_OR_FLOAT (x
);
850 CHECK_NUMBER_OR_FLOAT (y
);
852 return window_from_coordinates (f
,
853 FRAME_PIXEL_X_FROM_CANON_X (f
, x
),
854 FRAME_PIXEL_Y_FROM_CANON_Y (f
, y
),
858 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
859 doc
: /* Return current value of point in WINDOW.
860 For a nonselected window, this is the value point would have
861 if that window were selected.
863 Note that, when WINDOW is the selected window and its buffer
864 is also currently selected, the value returned is the same as (point).
865 It would be more strictly correct to return the `top-level' value
866 of point, outside of any save-excursion forms.
867 But that is hard to define. */)
871 register struct window
*w
= decode_window (window
);
873 if (w
== XWINDOW (selected_window
)
874 && current_buffer
== XBUFFER (w
->buffer
))
876 return Fmarker_position (w
->pointm
);
879 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
880 doc
: /* Return position at which display currently starts in WINDOW.
881 This is updated by redisplay or by calling `set-window-start'. */)
885 return Fmarker_position (decode_window (window
)->start
);
888 /* This is text temporarily removed from the doc string below.
890 This function returns nil if the position is not currently known.
891 That happens when redisplay is preempted and doesn't finish.
892 If in that case you want to compute where the end of the window would
893 have been if redisplay had finished, do this:
895 (goto-char (window-start window))
896 (vertical-motion (1- (window-height window)) window)
899 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
900 doc
: /* Return position at which display currently ends in WINDOW.
901 This is updated by redisplay, when it runs to completion.
902 Simply changing the buffer text or setting `window-start'
903 does not update this value.
904 If UPDATE is non-nil, compute the up-to-date position
905 if it isn't already recorded. */)
907 Lisp_Object window
, update
;
910 struct window
*w
= decode_window (window
);
916 #if 0 /* This change broke some things. We should make it later. */
917 /* If we don't know the end position, return nil.
918 The user can compute it with vertical-motion if he wants to.
919 It would be nicer to do it automatically,
920 but that's so slow that it would probably bother people. */
921 if (NILP (w
->window_end_valid
))
926 && ! (! NILP (w
->window_end_valid
)
927 && XFASTINT (w
->last_modified
) >= MODIFF
))
929 struct text_pos startp
;
931 struct buffer
*old_buffer
= NULL
, *b
= XBUFFER (buf
);
933 /* In case W->start is out of the range, use something
934 reasonable. This situation occurred when loading a file with
935 `-l' containing a call to `rmail' with subsequent other
936 commands. At the end, W->start happened to be BEG, while
937 rmail had already narrowed the buffer. */
938 if (XMARKER (w
->start
)->charpos
< BEGV
)
939 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
940 else if (XMARKER (w
->start
)->charpos
> ZV
)
941 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
943 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
945 /* Cannot use Fvertical_motion because that function doesn't
946 cope with variable-height lines. */
947 if (b
!= current_buffer
)
949 old_buffer
= current_buffer
;
950 set_buffer_internal (b
);
953 start_display (&it
, w
, startp
);
954 move_it_vertically (&it
, window_box_height (w
));
955 if (it
.current_y
< it
.last_visible_y
)
956 move_it_past_eol (&it
);
957 value
= make_number (IT_CHARPOS (it
));
960 set_buffer_internal (old_buffer
);
963 XSETINT (value
, BUF_Z (XBUFFER (buf
)) - XFASTINT (w
->window_end_pos
));
968 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
969 doc
: /* Make point value in WINDOW be at position POS in WINDOW's buffer. */)
971 Lisp_Object window
, pos
;
973 register struct window
*w
= decode_window (window
);
975 CHECK_NUMBER_COERCE_MARKER (pos
);
976 if (w
== XWINDOW (selected_window
)
977 && XBUFFER (w
->buffer
) == current_buffer
)
980 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
982 /* We have to make sure that redisplay updates the window to show
983 the new value of point. */
984 if (!EQ (window
, selected_window
))
985 ++windows_or_buffers_changed
;
990 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
991 doc
: /* Make display in WINDOW start at position POS in WINDOW's buffer.
992 Optional third arg NOFORCE non-nil inhibits next redisplay
993 from overriding motion of point in order to display at this exact start. */)
994 (window
, pos
, noforce
)
995 Lisp_Object window
, pos
, noforce
;
997 register struct window
*w
= decode_window (window
);
999 CHECK_NUMBER_COERCE_MARKER (pos
);
1000 set_marker_restricted (w
->start
, pos
, w
->buffer
);
1001 /* this is not right, but much easier than doing what is right. */
1002 w
->start_at_line_beg
= Qnil
;
1004 w
->force_start
= Qt
;
1005 w
->update_mode_line
= Qt
;
1006 XSETFASTINT (w
->last_modified
, 0);
1007 XSETFASTINT (w
->last_overlay_modified
, 0);
1008 if (!EQ (window
, selected_window
))
1009 windows_or_buffers_changed
++;
1014 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
1016 doc
: /* Return WINDOW's dedicated object, usually t or nil.
1017 See also `set-window-dedicated-p'. */)
1021 return decode_window (window
)->dedicated
;
1024 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
1025 Sset_window_dedicated_p
, 2, 2, 0,
1026 doc
: /* Control whether WINDOW is dedicated to the buffer it displays.
1027 If it is dedicated, Emacs will not automatically change
1028 which buffer appears in it.
1029 The second argument is the new value for the dedication flag;
1030 non-nil means yes. */)
1032 Lisp_Object window
, arg
;
1034 register struct window
*w
= decode_window (window
);
1037 w
->dedicated
= Qnil
;
1041 return w
->dedicated
;
1044 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
1046 doc
: /* Return the display-table that WINDOW is using. */)
1050 return decode_window (window
)->display_table
;
1053 /* Get the display table for use on window W. This is either W's
1054 display table or W's buffer's display table. Ignore the specified
1055 tables if they are not valid; if no valid table is specified,
1058 struct Lisp_Char_Table
*
1059 window_display_table (w
)
1062 struct Lisp_Char_Table
*dp
= NULL
;
1064 if (DISP_TABLE_P (w
->display_table
))
1065 dp
= XCHAR_TABLE (w
->display_table
);
1066 else if (BUFFERP (w
->buffer
))
1068 struct buffer
*b
= XBUFFER (w
->buffer
);
1070 if (DISP_TABLE_P (b
->display_table
))
1071 dp
= XCHAR_TABLE (b
->display_table
);
1072 else if (DISP_TABLE_P (Vstandard_display_table
))
1073 dp
= XCHAR_TABLE (Vstandard_display_table
);
1079 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
1080 doc
: /* Set WINDOW's display-table to TABLE. */)
1082 register Lisp_Object window
, table
;
1084 register struct window
*w
;
1086 w
= decode_window (window
);
1087 w
->display_table
= table
;
1091 /* Record info on buffer window w is displaying
1092 when it is about to cease to display that buffer. */
1095 register struct window
*w
;
1102 if (b
!= XMARKER (w
->pointm
)->buffer
)
1106 if (w
== XWINDOW (selected_window
)
1107 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
1108 /* Do this except when the selected window's buffer
1109 is being removed from some other window. */
1111 /* last_window_start records the start position that this buffer
1112 had in the last window to be disconnected from it.
1113 Now that this statement is unconditional,
1114 it is possible for the buffer to be displayed in the
1115 selected window, while last_window_start reflects another
1116 window which was recently showing the same buffer.
1117 Some people might say that might be a good thing. Let's see. */
1118 b
->last_window_start
= marker_position (w
->start
);
1120 /* Point in the selected window's buffer
1121 is actually stored in that buffer, and the window's pointm isn't used.
1122 So don't clobber point in that buffer. */
1123 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
)
1124 /* This line helps to fix Horsley's testbug.el bug. */
1125 && !(WINDOWP (b
->last_selected_window
)
1126 && w
!= XWINDOW (b
->last_selected_window
)
1127 && EQ (buf
, XWINDOW (b
->last_selected_window
)->buffer
)))
1128 temp_set_point_both (b
,
1129 clip_to_bounds (BUF_BEGV (b
),
1130 XMARKER (w
->pointm
)->charpos
,
1132 clip_to_bounds (BUF_BEGV_BYTE (b
),
1133 marker_byte_position (w
->pointm
),
1136 if (WINDOWP (b
->last_selected_window
)
1137 && w
== XWINDOW (b
->last_selected_window
))
1138 b
->last_selected_window
= Qnil
;
1141 /* Put replacement into the window structure in place of old. */
1143 replace_window (old
, replacement
)
1144 Lisp_Object old
, replacement
;
1146 register Lisp_Object tem
;
1147 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
1149 /* If OLD is its frame's root_window, then replacement is the new
1150 root_window for that frame. */
1152 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
1153 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
1155 p
->left_col
= o
->left_col
;
1156 p
->top_line
= o
->top_line
;
1157 p
->total_cols
= o
->total_cols
;
1158 p
->total_lines
= o
->total_lines
;
1159 p
->desired_matrix
= p
->current_matrix
= 0;
1161 bzero (&p
->cursor
, sizeof (p
->cursor
));
1162 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
1163 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
1164 p
->phys_cursor_type
= -1;
1165 p
->phys_cursor_width
= -1;
1166 p
->must_be_updated_p
= 0;
1167 p
->pseudo_window_p
= 0;
1168 XSETFASTINT (p
->window_end_vpos
, 0);
1169 XSETFASTINT (p
->window_end_pos
, 0);
1170 p
->window_end_valid
= Qnil
;
1171 p
->frozen_window_start_p
= 0;
1172 p
->orig_top_line
= p
->orig_total_lines
= Qnil
;
1174 p
->next
= tem
= o
->next
;
1176 XWINDOW (tem
)->prev
= replacement
;
1178 p
->prev
= tem
= o
->prev
;
1180 XWINDOW (tem
)->next
= replacement
;
1182 p
->parent
= tem
= o
->parent
;
1185 if (EQ (XWINDOW (tem
)->vchild
, old
))
1186 XWINDOW (tem
)->vchild
= replacement
;
1187 if (EQ (XWINDOW (tem
)->hchild
, old
))
1188 XWINDOW (tem
)->hchild
= replacement
;
1191 /*** Here, if replacement is a vertical combination
1192 and so is its new parent, we should make replacement's
1193 children be children of that parent instead. ***/
1196 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
1197 doc
: /* Remove WINDOW from the display. Default is selected window. */)
1199 register Lisp_Object window
;
1201 delete_window (window
);
1203 if (! NILP (Vwindow_configuration_change_hook
)
1204 && ! NILP (Vrun_hooks
))
1205 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
1211 delete_window (window
)
1212 register Lisp_Object window
;
1214 register Lisp_Object tem
, parent
, sib
;
1215 register struct window
*p
;
1216 register struct window
*par
;
1219 /* Because this function is called by other C code on non-leaf
1220 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1221 so we can't decode_window here. */
1223 window
= selected_window
;
1225 CHECK_WINDOW (window
);
1226 p
= XWINDOW (window
);
1228 /* It's okay to delete an already-deleted window. */
1229 if (NILP (p
->buffer
)
1231 && NILP (p
->vchild
))
1236 error ("Attempt to delete minibuffer or sole ordinary window");
1237 par
= XWINDOW (parent
);
1239 windows_or_buffers_changed
++;
1240 Vwindow_list
= Qnil
;
1241 f
= XFRAME (WINDOW_FRAME (p
));
1242 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
1244 /* Are we trying to delete any frame's selected window? */
1246 Lisp_Object swindow
, pwindow
;
1248 /* See if the frame's selected window is either WINDOW
1249 or any subwindow of it, by finding all that window's parents
1250 and comparing each one with WINDOW. */
1251 swindow
= FRAME_SELECTED_WINDOW (f
);
1256 while (!NILP (pwindow
))
1258 if (EQ (window
, pwindow
))
1260 pwindow
= XWINDOW (pwindow
)->parent
;
1263 /* If the window being deleted is not a parent of SWINDOW,
1264 then SWINDOW is ok as the new selected window. */
1265 if (!EQ (window
, pwindow
))
1267 /* Otherwise, try another window for SWINDOW. */
1268 swindow
= Fnext_window (swindow
, Qlambda
, Qnil
);;
1270 /* If we get back to the frame's selected window,
1271 it means there was no acceptable alternative,
1272 so we cannot delete. */
1273 if (EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
1274 error ("Cannot delete window");
1277 /* If we need to change SWINDOW, do it. */
1278 if (! EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
1280 /* If we're about to delete the selected window on the
1281 selected frame, then we should use Fselect_window to select
1282 the new window. On the other hand, if we're about to
1283 delete the selected window on any other frame, we shouldn't do
1284 anything but set the frame's selected_window slot. */
1285 if (EQ (FRAME_SELECTED_WINDOW (f
), selected_window
))
1286 Fselect_window (swindow
, Qnil
);
1288 FRAME_SELECTED_WINDOW (f
) = swindow
;
1293 /* tem is null for dummy parent windows
1294 (which have inferiors but not any contents themselves) */
1298 unchain_marker (p
->pointm
);
1299 unchain_marker (p
->start
);
1302 /* Free window glyph matrices. It is sure that they are allocated
1303 again when ADJUST_GLYPHS is called. Block input so that expose
1304 events and other events that access glyph matrices are not
1305 processed while we are changing them. */
1307 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f
)));
1311 XWINDOW (tem
)->prev
= p
->prev
;
1315 XWINDOW (tem
)->next
= p
->next
;
1317 if (EQ (window
, par
->hchild
))
1318 par
->hchild
= p
->next
;
1319 if (EQ (window
, par
->vchild
))
1320 par
->vchild
= p
->next
;
1322 /* Find one of our siblings to give our space to. */
1326 /* If p gives its space to its next sibling, that sibling needs
1327 to have its top/left side pulled back to where p's is.
1328 set_window_{height,width} will re-position the sibling's
1331 XWINDOW (sib
)->top_line
= p
->top_line
;
1332 XWINDOW (sib
)->left_col
= p
->left_col
;
1335 /* Stretch that sibling. */
1336 if (!NILP (par
->vchild
))
1337 set_window_height (sib
,
1338 XFASTINT (XWINDOW (sib
)->total_lines
) + XFASTINT (p
->total_lines
),
1340 if (!NILP (par
->hchild
))
1341 set_window_width (sib
,
1342 XFASTINT (XWINDOW (sib
)->total_cols
) + XFASTINT (p
->total_cols
),
1345 /* If parent now has only one child,
1346 put the child into the parent's place. */
1350 if (NILP (XWINDOW (tem
)->next
))
1351 replace_window (parent
, tem
);
1353 /* Since we may be deleting combination windows, we must make sure that
1354 not only p but all its children have been marked as deleted. */
1355 if (! NILP (p
->hchild
))
1356 delete_all_subwindows (XWINDOW (p
->hchild
));
1357 else if (! NILP (p
->vchild
))
1358 delete_all_subwindows (XWINDOW (p
->vchild
));
1360 /* Mark this window as deleted. */
1361 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
1363 /* Adjust glyph matrices. */
1370 /***********************************************************************
1372 ***********************************************************************/
1374 /* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object
1375 pointer. This is a callback function for foreach_window, used in
1376 function window_list. */
1379 add_window_to_list (w
, user_data
)
1383 Lisp_Object
*list
= (Lisp_Object
*) user_data
;
1385 XSETWINDOW (window
, w
);
1386 *list
= Fcons (window
, *list
);
1391 /* Return a list of all windows, for use by next_window. If
1392 Vwindow_list is a list, return that list. Otherwise, build a new
1393 list, cache it in Vwindow_list, and return that. */
1398 if (!CONSP (Vwindow_list
))
1402 Vwindow_list
= Qnil
;
1403 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
1405 Lisp_Object args
[2];
1407 /* We are visiting windows in canonical order, and add
1408 new windows at the front of args[1], which means we
1409 have to reverse this list at the end. */
1411 foreach_window (XFRAME (XCAR (tail
)), add_window_to_list
, &args
[1]);
1412 args
[0] = Vwindow_list
;
1413 args
[1] = Fnreverse (args
[1]);
1414 Vwindow_list
= Fnconc (2, args
);
1418 return Vwindow_list
;
1422 /* Value is non-zero if WINDOW satisfies the constraints given by
1423 OWINDOW, MINIBUF and ALL_FRAMES.
1425 MINIBUF t means WINDOW may be minibuffer windows.
1426 `lambda' means WINDOW may not be a minibuffer window.
1427 a window means a specific minibuffer window
1429 ALL_FRAMES t means search all frames,
1430 nil means search just current frame,
1431 `visible' means search just visible frames,
1432 0 means search visible and iconified frames,
1433 a window means search the frame that window belongs to,
1434 a frame means consider windows on that frame, only. */
1437 candidate_window_p (window
, owindow
, minibuf
, all_frames
)
1438 Lisp_Object window
, owindow
, minibuf
, all_frames
;
1440 struct window
*w
= XWINDOW (window
);
1441 struct frame
*f
= XFRAME (w
->frame
);
1442 int candidate_p
= 1;
1444 if (!BUFFERP (w
->buffer
))
1446 else if (MINI_WINDOW_P (w
)
1447 && (EQ (minibuf
, Qlambda
)
1448 || (WINDOWP (minibuf
) && !EQ (minibuf
, window
))))
1450 /* If MINIBUF is `lambda' don't consider any mini-windows.
1451 If it is a window, consider only that one. */
1454 else if (EQ (all_frames
, Qt
))
1456 else if (NILP (all_frames
))
1458 xassert (WINDOWP (owindow
));
1459 candidate_p
= EQ (w
->frame
, XWINDOW (owindow
)->frame
);
1461 else if (EQ (all_frames
, Qvisible
))
1463 FRAME_SAMPLE_VISIBILITY (f
);
1464 candidate_p
= FRAME_VISIBLE_P (f
);
1466 else if (INTEGERP (all_frames
) && XINT (all_frames
) == 0)
1468 FRAME_SAMPLE_VISIBILITY (f
);
1469 candidate_p
= FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
);
1471 else if (WINDOWP (all_frames
))
1472 candidate_p
= (EQ (FRAME_MINIBUF_WINDOW (f
), all_frames
)
1473 || EQ (XWINDOW (all_frames
)->frame
, w
->frame
)
1474 || EQ (XWINDOW (all_frames
)->frame
, FRAME_FOCUS_FRAME (f
)));
1475 else if (FRAMEP (all_frames
))
1476 candidate_p
= EQ (all_frames
, w
->frame
);
1482 /* Decode arguments as allowed by Fnext_window, Fprevious_window, and
1483 Fwindow_list. See there for the meaning of WINDOW, MINIBUF, and
1487 decode_next_window_args (window
, minibuf
, all_frames
)
1488 Lisp_Object
*window
, *minibuf
, *all_frames
;
1491 *window
= selected_window
;
1493 CHECK_LIVE_WINDOW (*window
);
1495 /* MINIBUF nil may or may not include minibuffers. Decide if it
1497 if (NILP (*minibuf
))
1498 *minibuf
= minibuf_level
? minibuf_window
: Qlambda
;
1499 else if (!EQ (*minibuf
, Qt
))
1502 /* Now *MINIBUF can be t => count all minibuffer windows, `lambda'
1503 => count none of them, or a specific minibuffer window (the
1504 active one) to count. */
1506 /* ALL_FRAMES nil doesn't specify which frames to include. */
1507 if (NILP (*all_frames
))
1508 *all_frames
= (!EQ (*minibuf
, Qlambda
)
1509 ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window
)->frame
))
1511 else if (EQ (*all_frames
, Qvisible
))
1513 else if (XFASTINT (*all_frames
) == 0)
1515 else if (FRAMEP (*all_frames
))
1517 else if (!EQ (*all_frames
, Qt
))
1520 /* Now *ALL_FRAMES is t meaning search all frames, nil meaning
1521 search just current frame, `visible' meaning search just visible
1522 frames, 0 meaning search visible and iconified frames, or a
1523 window, meaning search the frame that window belongs to, or a
1524 frame, meaning consider windows on that frame, only. */
1528 /* Return the next or previous window of WINDOW in canonical ordering
1529 of windows. NEXT_P non-zero means return the next window. See the
1530 documentation string of next-window for the meaning of MINIBUF and
1534 next_window (window
, minibuf
, all_frames
, next_p
)
1535 Lisp_Object window
, minibuf
, all_frames
;
1538 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1540 /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just
1541 return the first window on the frame. */
1542 if (FRAMEP (all_frames
)
1543 && !EQ (all_frames
, XWINDOW (window
)->frame
))
1544 return Fframe_first_window (all_frames
);
1550 /* Find WINDOW in the list of all windows. */
1551 list
= Fmemq (window
, window_list ());
1553 /* Scan forward from WINDOW to the end of the window list. */
1555 for (list
= XCDR (list
); CONSP (list
); list
= XCDR (list
))
1556 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1559 /* Scan from the start of the window list up to WINDOW. */
1561 for (list
= Vwindow_list
;
1562 CONSP (list
) && !EQ (XCAR (list
), window
);
1564 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1568 window
= XCAR (list
);
1572 Lisp_Object candidate
, list
;
1574 /* Scan through the list of windows for candidates. If there are
1575 candidate windows in front of WINDOW, the last one of these
1576 is the one we want. If there are candidates following WINDOW
1577 in the list, again the last one of these is the one we want. */
1579 for (list
= window_list (); CONSP (list
); list
= XCDR (list
))
1581 if (EQ (XCAR (list
), window
))
1583 if (WINDOWP (candidate
))
1586 else if (candidate_window_p (XCAR (list
), window
, minibuf
,
1588 candidate
= XCAR (list
);
1591 if (WINDOWP (candidate
))
1599 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
1600 doc
: /* Return next window after WINDOW in canonical ordering of windows.
1601 If omitted, WINDOW defaults to the selected window.
1603 Optional second arg MINIBUF t means count the minibuffer window even
1604 if not active. MINIBUF nil or omitted means count the minibuffer iff
1605 it is active. MINIBUF neither t nor nil means not to count the
1606 minibuffer even if it is active.
1608 Several frames may share a single minibuffer; if the minibuffer
1609 counts, all windows on all frames that share that minibuffer count
1610 too. Therefore, `next-window' can be used to iterate through the
1611 set of windows even when the minibuffer is on another frame. If the
1612 minibuffer does not count, only windows from WINDOW's frame count.
1614 Optional third arg ALL-FRAMES t means include windows on all frames.
1615 ALL-FRAMES nil or omitted means cycle within the frames as specified
1616 above. ALL-FRAMES = `visible' means include windows on all visible frames.
1617 ALL-FRAMES = 0 means include windows on all visible and iconified frames.
1618 If ALL-FRAMES is a frame, restrict search to windows on that frame.
1619 Anything else means restrict to WINDOW's frame.
1621 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
1622 `next-window' to iterate through the entire cycle of acceptable
1623 windows, eventually ending up back at the window you started with.
1624 `previous-window' traverses the same cycle, in the reverse order. */)
1625 (window
, minibuf
, all_frames
)
1626 Lisp_Object window
, minibuf
, all_frames
;
1628 return next_window (window
, minibuf
, all_frames
, 1);
1632 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
1633 doc
: /* Return the window preceding WINDOW in canonical ordering of windows.
1634 If omitted, WINDOW defaults to the selected window.
1636 Optional second arg MINIBUF t means count the minibuffer window even
1637 if not active. MINIBUF nil or omitted means count the minibuffer iff
1638 it is active. MINIBUF neither t nor nil means not to count the
1639 minibuffer even if it is active.
1641 Several frames may share a single minibuffer; if the minibuffer
1642 counts, all windows on all frames that share that minibuffer count
1643 too. Therefore, `previous-window' can be used to iterate through
1644 the set of windows even when the minibuffer is on another frame. If
1645 the minibuffer does not count, only windows from WINDOW's frame count
1647 Optional third arg ALL-FRAMES t means include windows on all frames.
1648 ALL-FRAMES nil or omitted means cycle within the frames as specified
1649 above. ALL-FRAMES = `visible' means include windows on all visible frames.
1650 ALL-FRAMES = 0 means include windows on all visible and iconified frames.
1651 If ALL-FRAMES is a frame, restrict search to windows on that frame.
1652 Anything else means restrict to WINDOW's frame.
1654 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
1655 `previous-window' to iterate through the entire cycle of acceptable
1656 windows, eventually ending up back at the window you started with.
1657 `next-window' traverses the same cycle, in the reverse order. */)
1658 (window
, minibuf
, all_frames
)
1659 Lisp_Object window
, minibuf
, all_frames
;
1661 return next_window (window
, minibuf
, all_frames
, 0);
1665 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1666 doc
: /* Select the ARG'th different window on this frame.
1667 All windows on current frame are arranged in a cyclic order.
1668 This command selects the window ARG steps away in that order.
1669 A negative ARG moves in the opposite order. If the optional second
1670 argument ALL_FRAMES is non-nil, cycle through all frames. */)
1672 Lisp_Object arg
, all_frames
;
1678 window
= selected_window
;
1680 for (i
= XINT (arg
); i
> 0; --i
)
1681 window
= Fnext_window (window
, Qnil
, all_frames
);
1683 window
= Fprevious_window (window
, Qnil
, all_frames
);
1685 Fselect_window (window
, Qnil
);
1690 DEFUN ("window-list", Fwindow_list
, Swindow_list
, 0, 3, 0,
1691 doc
: /* Return a list of windows on FRAME, starting with WINDOW.
1692 FRAME nil or omitted means use the selected frame.
1693 WINDOW nil or omitted means use the selected window.
1694 MINIBUF t means include the minibuffer window, even if it isn't active.
1695 MINIBUF nil or omitted means include the minibuffer window only
1697 MINIBUF neither nil nor t means never include the minibuffer window. */)
1698 (frame
, minibuf
, window
)
1699 Lisp_Object frame
, minibuf
, window
;
1702 window
= selected_window
;
1704 frame
= selected_frame
;
1706 if (!EQ (frame
, XWINDOW (window
)->frame
))
1707 error ("Window is on a different frame");
1709 return window_list_1 (window
, minibuf
, frame
);
1713 /* Return a list of windows in canonical ordering. Arguments are like
1714 for `next-window'. */
1717 window_list_1 (window
, minibuf
, all_frames
)
1718 Lisp_Object window
, minibuf
, all_frames
;
1720 Lisp_Object tail
, list
;
1722 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1725 for (tail
= window_list (); CONSP (tail
); tail
= XCDR (tail
))
1726 if (candidate_window_p (XCAR (tail
), window
, minibuf
, all_frames
))
1727 list
= Fcons (XCAR (tail
), list
);
1729 return Fnreverse (list
);
1734 /* Look at all windows, performing an operation specified by TYPE
1736 If FRAMES is Qt, look at all frames;
1737 Qnil, look at just the selected frame;
1738 Qvisible, look at visible frames;
1739 a frame, just look at windows on that frame.
1740 If MINI is non-zero, perform the operation on minibuffer windows too. */
1745 GET_BUFFER_WINDOW
, /* Arg is buffer */
1746 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1747 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1748 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1750 UNSHOW_BUFFER
, /* Arg is buffer */
1755 window_loop (type
, obj
, mini
, frames
)
1756 enum window_loop type
;
1757 Lisp_Object obj
, frames
;
1760 Lisp_Object window
, windows
, best_window
, frame_arg
;
1762 struct gcpro gcpro1
;
1764 /* If we're only looping through windows on a particular frame,
1765 frame points to that frame. If we're looping through windows
1766 on all frames, frame is 0. */
1767 if (FRAMEP (frames
))
1768 f
= XFRAME (frames
);
1769 else if (NILP (frames
))
1770 f
= SELECTED_FRAME ();
1775 frame_arg
= Qlambda
;
1776 else if (XFASTINT (frames
) == 0)
1778 else if (EQ (frames
, Qvisible
))
1783 /* frame_arg is Qlambda to stick to one frame,
1784 Qvisible to consider all visible frames,
1787 /* Pick a window to start with. */
1791 window
= FRAME_SELECTED_WINDOW (f
);
1793 window
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
1795 windows
= window_list_1 (window
, mini
? Qt
: Qnil
, frame_arg
);
1799 for (; CONSP (windows
); windows
= CDR (windows
))
1803 window
= XCAR (windows
);
1804 w
= XWINDOW (window
);
1806 /* Note that we do not pay attention here to whether the frame
1807 is visible, since Fwindow_list skips non-visible frames if
1808 that is desired, under the control of frame_arg. */
1809 if (!MINI_WINDOW_P (w
)
1810 /* For UNSHOW_BUFFER, we must always consider all windows. */
1811 || type
== UNSHOW_BUFFER
1812 || (mini
&& minibuf_level
> 0))
1815 case GET_BUFFER_WINDOW
:
1816 if (EQ (w
->buffer
, obj
)
1817 /* Don't find any minibuffer window
1818 except the one that is currently in use. */
1819 && (MINI_WINDOW_P (w
)
1820 ? EQ (window
, minibuf_window
)
1823 if (NILP (best_window
))
1824 best_window
= window
;
1825 else if (EQ (window
, selected_window
))
1826 /* For compatibility with 20.x, prefer to return
1828 best_window
= window
;
1832 case GET_LRU_WINDOW
:
1833 /* t as arg means consider only full-width windows */
1834 if (!NILP (obj
) && !WINDOW_FULL_WIDTH_P (w
))
1836 /* Ignore dedicated windows and minibuffers. */
1837 if (MINI_WINDOW_P (w
) || EQ (w
->dedicated
, Qt
))
1839 if (NILP (best_window
)
1840 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1841 > XFASTINT (w
->use_time
)))
1842 best_window
= window
;
1845 case DELETE_OTHER_WINDOWS
:
1846 if (!EQ (window
, obj
))
1847 Fdelete_window (window
);
1850 case DELETE_BUFFER_WINDOWS
:
1851 if (EQ (w
->buffer
, obj
))
1853 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1855 /* If this window is dedicated, and in a frame of its own,
1857 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
1858 && !NILP (w
->dedicated
)
1859 && other_visible_frames (f
))
1861 /* Skip the other windows on this frame.
1862 There might be one, the minibuffer! */
1863 while (CONSP (XCDR (windows
))
1864 && EQ (XWINDOW (XCAR (windows
))->frame
,
1865 XWINDOW (XCAR (XCDR (windows
)))->frame
))
1866 windows
= XCDR (windows
);
1868 /* Now we can safely delete the frame. */
1869 Fdelete_frame (w
->frame
, Qnil
);
1871 else if (NILP (w
->parent
))
1873 /* If we're deleting the buffer displayed in the
1874 only window on the frame, find a new buffer to
1877 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
1878 Fset_window_buffer (window
, buffer
, Qnil
);
1879 if (EQ (window
, selected_window
))
1880 Fset_buffer (w
->buffer
);
1883 Fdelete_window (window
);
1887 case GET_LARGEST_WINDOW
:
1889 /* Ignore dedicated windows and minibuffers. */
1890 if (MINI_WINDOW_P (w
) || EQ (w
->dedicated
, Qt
))
1893 if (NILP (best_window
))
1894 best_window
= window
;
1897 struct window
*b
= XWINDOW (best_window
);
1898 if (XFASTINT (w
->total_lines
) * XFASTINT (w
->total_cols
)
1899 > XFASTINT (b
->total_lines
) * XFASTINT (b
->total_cols
))
1900 best_window
= window
;
1906 if (EQ (w
->buffer
, obj
))
1909 struct frame
*f
= XFRAME (w
->frame
);
1911 /* Find another buffer to show in this window. */
1912 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
1914 /* If this window is dedicated, and in a frame of its own,
1916 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
1917 && !NILP (w
->dedicated
)
1918 && other_visible_frames (f
))
1920 /* Skip the other windows on this frame.
1921 There might be one, the minibuffer! */
1922 while (CONSP (XCDR (windows
))
1923 && EQ (XWINDOW (XCAR (windows
))->frame
,
1924 XWINDOW (XCAR (XCDR (windows
)))->frame
))
1925 windows
= XCDR (windows
);
1927 /* Now we can safely delete the frame. */
1928 Fdelete_frame (w
->frame
, Qnil
);
1930 else if (!NILP (w
->dedicated
) && !NILP (w
->parent
))
1933 XSETWINDOW (window
, w
);
1934 /* If this window is dedicated and not the only window
1935 in its frame, then kill it. */
1936 Fdelete_window (window
);
1940 /* Otherwise show a different buffer in the window. */
1941 w
->dedicated
= Qnil
;
1942 Fset_window_buffer (window
, buffer
, Qnil
);
1943 if (EQ (window
, selected_window
))
1944 Fset_buffer (w
->buffer
);
1949 /* Check for a window that has a killed buffer. */
1950 case CHECK_ALL_WINDOWS
:
1951 if (! NILP (w
->buffer
)
1952 && NILP (XBUFFER (w
->buffer
)->name
))
1956 case WINDOW_LOOP_UNUSED
:
1965 /* Used for debugging. Abort if any window has a dead buffer. */
1968 check_all_windows ()
1970 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
1973 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1974 doc
: /* Return the window least recently selected or used for display.
1975 If optional argument FRAME is `visible', search all visible frames.
1976 If FRAME is 0, search all visible and iconified frames.
1977 If FRAME is t, search all frames.
1978 If FRAME is nil, search only the selected frame.
1979 If FRAME is a frame, search only that frame. */)
1983 register Lisp_Object w
;
1984 /* First try for a window that is full-width */
1985 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frame
);
1986 if (!NILP (w
) && !EQ (w
, selected_window
))
1988 /* If none of them, try the rest */
1989 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frame
);
1992 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1993 doc
: /* Return the largest window in area.
1994 If optional argument FRAME is `visible', search all visible frames.
1995 If FRAME is 0, search all visible and iconified frames.
1996 If FRAME is t, search all frames.
1997 If FRAME is nil, search only the selected frame.
1998 If FRAME is a frame, search only that frame. */)
2002 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
2006 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
2007 doc
: /* Return a window currently displaying BUFFER, or nil if none.
2008 If optional argument FRAME is `visible', search all visible frames.
2009 If optional argument FRAME is 0, search all visible and iconified frames.
2010 If FRAME is t, search all frames.
2011 If FRAME is nil, search only the selected frame.
2012 If FRAME is a frame, search only that frame. */)
2014 Lisp_Object buffer
, frame
;
2016 buffer
= Fget_buffer (buffer
);
2017 if (BUFFERP (buffer
))
2018 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
2023 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
2025 doc
: /* Make WINDOW (or the selected window) fill its frame.
2026 Only the frame WINDOW is on is affected.
2027 This function tries to reduce display jumps
2028 by keeping the text previously visible in WINDOW
2029 in the same place on the frame. Doing this depends on
2030 the value of (window-start WINDOW), so if calling this function
2031 in a program gives strange scrolling, make sure the window-start
2032 value is reasonable when this function is called. */)
2041 window
= selected_window
;
2043 CHECK_LIVE_WINDOW (window
);
2044 w
= XWINDOW (window
);
2046 startpos
= marker_position (w
->start
);
2047 top
= WINDOW_TOP_EDGE_LINE (w
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2049 if (MINI_WINDOW_P (w
) && top
> 0)
2050 error ("Can't expand minibuffer to full frame");
2052 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
2054 /* Try to minimize scrolling, by setting the window start to the point
2055 will cause the text at the old window start to be at the same place
2056 on the frame. But don't try to do this if the window start is
2057 outside the visible portion (as might happen when the display is
2058 not current, due to typeahead). */
2059 new_top
= WINDOW_TOP_EDGE_LINE (w
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2061 && startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
2062 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
2064 struct position pos
;
2065 struct buffer
*obuf
= current_buffer
;
2067 Fset_buffer (w
->buffer
);
2068 /* This computation used to temporarily move point, but that can
2069 have unwanted side effects due to text properties. */
2070 pos
= *vmotion (startpos
, -top
, w
);
2072 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
2073 w
->window_end_valid
= Qnil
;
2074 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
2075 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
2077 /* We need to do this, so that the window-scroll-functions
2079 w
->optional_new_start
= Qt
;
2081 set_buffer_internal (obuf
);
2087 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
2088 1, 2, "bDelete windows on (buffer): ",
2089 doc
: /* Delete all windows showing BUFFER.
2090 Optional second argument FRAME controls which frames are affected.
2091 If optional argument FRAME is `visible', search all visible frames.
2092 If FRAME is 0, search all visible and iconified frames.
2093 If FRAME is nil, search all frames.
2094 If FRAME is t, search only the selected frame.
2095 If FRAME is a frame, search only that frame. */)
2097 Lisp_Object buffer
, frame
;
2099 /* FRAME uses t and nil to mean the opposite of what window_loop
2103 else if (EQ (frame
, Qt
))
2108 buffer
= Fget_buffer (buffer
);
2109 CHECK_BUFFER (buffer
);
2110 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
2116 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
2117 Sreplace_buffer_in_windows
,
2118 1, 1, "bReplace buffer in windows: ",
2119 doc
: /* Replace BUFFER with some other buffer in all windows showing it. */)
2125 buffer
= Fget_buffer (buffer
);
2126 CHECK_BUFFER (buffer
);
2127 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
2132 /* Replace BUFFER with some other buffer in all windows
2133 of all frames, even those on other keyboards. */
2136 replace_buffer_in_all_windows (buffer
)
2140 Lisp_Object tail
, frame
;
2142 /* A single call to window_loop won't do the job
2143 because it only considers frames on the current keyboard.
2144 So loop manually over frames, and handle each one. */
2145 FOR_EACH_FRAME (tail
, frame
)
2146 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
2148 window_loop (UNSHOW_BUFFER
, buffer
, 1, Qt
);
2152 /* Set the height of WINDOW and all its inferiors. */
2154 /* The smallest acceptable dimensions for a window. Anything smaller
2155 might crash Emacs. */
2157 #define MIN_SAFE_WINDOW_WIDTH (2)
2158 #define MIN_SAFE_WINDOW_HEIGHT (1)
2160 /* Make sure that window_min_height and window_min_width are
2161 not too small; if they are, set them to safe minima. */
2164 check_min_window_sizes ()
2166 /* Smaller values might permit a crash. */
2167 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
2168 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
2169 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
2170 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
2173 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
2174 minimum allowable size. */
2177 check_frame_size (frame
, rows
, cols
)
2181 /* For height, we have to see:
2182 how many windows the frame has at minimum (one or two),
2183 and whether it has a menu bar or other special stuff at the top. */
2185 = ((FRAME_MINIBUF_ONLY_P (frame
) || ! FRAME_HAS_MINIBUF_P (frame
))
2186 ? MIN_SAFE_WINDOW_HEIGHT
2187 : 2 * MIN_SAFE_WINDOW_HEIGHT
);
2189 if (FRAME_TOP_MARGIN (frame
) > 0)
2190 min_height
+= FRAME_TOP_MARGIN (frame
);
2192 if (*rows
< min_height
)
2194 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
2195 *cols
= MIN_SAFE_WINDOW_WIDTH
;
2199 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
2200 check if W's width can be changed, otherwise check W's height.
2201 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
2202 siblings, too. If none of the siblings is resizable, WINDOW isn't
2206 window_fixed_size_p (w
, width_p
, check_siblings_p
)
2208 int width_p
, check_siblings_p
;
2213 if (!NILP (w
->hchild
))
2215 c
= XWINDOW (w
->hchild
);
2219 /* A horiz. combination is fixed-width if all of if its
2221 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2222 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2223 fixed_p
= c
== NULL
;
2227 /* A horiz. combination is fixed-height if one of if its
2229 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2230 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2231 fixed_p
= c
!= NULL
;
2234 else if (!NILP (w
->vchild
))
2236 c
= XWINDOW (w
->vchild
);
2240 /* A vert. combination is fixed-width if one of if its
2242 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2243 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2244 fixed_p
= c
!= NULL
;
2248 /* A vert. combination is fixed-height if all of if its
2250 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2251 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2252 fixed_p
= c
== NULL
;
2255 else if (BUFFERP (w
->buffer
))
2257 if (w
->height_fixed_p
&& !width_p
)
2261 struct buffer
*old
= current_buffer
;
2264 current_buffer
= XBUFFER (w
->buffer
);
2265 val
= find_symbol_value (Qwindow_size_fixed
);
2266 current_buffer
= old
;
2269 if (!EQ (val
, Qunbound
))
2271 fixed_p
= !NILP (val
);
2274 && ((EQ (val
, Qheight
) && width_p
)
2275 || (EQ (val
, Qwidth
) && !width_p
)))
2280 /* Can't tell if this one is resizable without looking at
2281 siblings. If all siblings are fixed-size this one is too. */
2282 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
2286 for (child
= w
->prev
; !NILP (child
); child
= XWINDOW (child
)->prev
)
2287 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2291 for (child
= w
->next
; !NILP (child
); child
= XWINDOW (child
)->next
)
2292 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2306 /* Return the minimum size of window W, not taking fixed-width windows
2307 into account. WIDTH_P non-zero means return the minimum width,
2308 otherwise return the minimum height. If W is a combination window,
2309 compute the minimum size from the minimum sizes of W's children. */
2312 window_min_size_1 (w
, width_p
)
2319 if (!NILP (w
->hchild
))
2321 c
= XWINDOW (w
->hchild
);
2326 /* The min width of a horizontal combination is
2327 the sum of the min widths of its children. */
2330 size
+= window_min_size_1 (c
, width_p
);
2331 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2336 /* The min height a horizontal combination equals
2337 the maximum of all min height of its children. */
2340 int min_size
= window_min_size_1 (c
, width_p
);
2341 size
= max (min_size
, size
);
2342 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2346 else if (!NILP (w
->vchild
))
2348 c
= XWINDOW (w
->vchild
);
2353 /* The min width of a vertical combination is
2354 the maximum of the min widths of its children. */
2357 int min_size
= window_min_size_1 (c
, width_p
);
2358 size
= max (min_size
, size
);
2359 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2364 /* The min height of a vertical combination equals
2365 the sum of the min height of its children. */
2368 size
+= window_min_size_1 (c
, width_p
);
2369 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2376 size
= window_min_width
;
2379 if (MINI_WINDOW_P (w
)
2380 || (!WINDOW_WANTS_MODELINE_P (w
)
2381 && !WINDOW_WANTS_HEADER_LINE_P (w
)))
2384 size
= window_min_height
;
2392 /* Return the minimum size of window W, taking fixed-size windows into
2393 account. WIDTH_P non-zero means return the minimum width,
2394 otherwise return the minimum height. IGNORE_FIXED_P non-zero means
2395 ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size
2396 unless FIXED is null. */
2399 window_min_size (w
, width_p
, ignore_fixed_p
, fixed
)
2401 int width_p
, ignore_fixed_p
, *fixed
;
2408 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
2414 size
= width_p
? XFASTINT (w
->total_cols
) : XFASTINT (w
->total_lines
);
2416 size
= window_min_size_1 (w
, width_p
);
2422 /* Adjust the margins of window W if text area is too small.
2423 Return 1 if window width is ok after adjustment; 0 if window
2424 is still too narrow. */
2427 adjust_window_margins (w
)
2430 int box_cols
= (WINDOW_TOTAL_COLS (w
)
2431 - WINDOW_FRINGE_COLS (w
)
2432 - WINDOW_SCROLL_BAR_COLS (w
));
2433 int margin_cols
= (WINDOW_LEFT_MARGIN_COLS (w
)
2434 + WINDOW_RIGHT_MARGIN_COLS (w
));
2436 if (box_cols
- margin_cols
>= MIN_SAFE_WINDOW_WIDTH
)
2439 if (margin_cols
< 0 || box_cols
< MIN_SAFE_WINDOW_WIDTH
)
2442 /* Window's text area is too narrow, but reducing the window
2443 margins will fix that. */
2444 margin_cols
= box_cols
- MIN_SAFE_WINDOW_WIDTH
;
2445 if (WINDOW_RIGHT_MARGIN_COLS (w
) > 0)
2447 if (WINDOW_LEFT_MARGIN_COLS (w
) > 0)
2448 w
->left_margin_cols
= w
->right_margin_cols
2449 = make_number (margin_cols
/2);
2451 w
->right_margin_cols
= make_number (margin_cols
);
2454 w
->left_margin_cols
= make_number (margin_cols
);
2459 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
2460 WINDOW's width. Resize WINDOW's children, if any, so that they
2461 keep their proportionate size relative to WINDOW. Propagate
2462 WINDOW's top or left edge position to children. Delete windows
2463 that become too small unless NODELETE_P is non-zero.
2465 If NODELETE_P is 2, that means we do delete windows that are
2466 too small, even if they were too small before! */
2469 size_window (window
, size
, width_p
, nodelete_p
)
2471 int size
, width_p
, nodelete_p
;
2473 struct window
*w
= XWINDOW (window
);
2475 Lisp_Object child
, *forward
, *sideward
;
2476 int old_size
, min_size
, safe_min_size
;
2478 /* We test nodelete_p != 2 and nodelete_p != 1 below, so it
2479 seems like it's too soon to do this here. ++KFS. */
2480 if (nodelete_p
== 2)
2483 check_min_window_sizes ();
2484 size
= max (0, size
);
2486 /* If the window has been "too small" at one point,
2487 don't delete it for being "too small" in the future.
2488 Preserve it as long as that is at all possible. */
2491 old_size
= WINDOW_TOTAL_COLS (w
);
2492 min_size
= window_min_width
;
2493 /* Ensure that there is room for the scroll bar and fringes!
2494 We may reduce display margins though. */
2495 safe_min_size
= (MIN_SAFE_WINDOW_WIDTH
2496 + WINDOW_FRINGE_COLS (w
)
2497 + WINDOW_SCROLL_BAR_COLS (w
));
2501 old_size
= XINT (w
->total_lines
);
2502 min_size
= window_min_height
;
2503 safe_min_size
= MIN_SAFE_WINDOW_HEIGHT
;
2506 if (old_size
< min_size
&& nodelete_p
!= 2)
2507 w
->too_small_ok
= Qt
;
2509 /* Maybe delete WINDOW if it's too small. */
2510 if (nodelete_p
!= 1 && !NILP (w
->parent
))
2512 if (!MINI_WINDOW_P (w
) && !NILP (w
->too_small_ok
))
2513 min_size
= width_p
? MIN_SAFE_WINDOW_WIDTH
: MIN_SAFE_WINDOW_HEIGHT
;
2514 if (min_size
< safe_min_size
)
2515 min_size
= safe_min_size
;
2516 if (size
< min_size
)
2518 delete_window (window
);
2523 /* Set redisplay hints. */
2524 w
->last_modified
= make_number (0);
2525 w
->last_overlay_modified
= make_number (0);
2526 windows_or_buffers_changed
++;
2527 FRAME_WINDOW_SIZES_CHANGED (XFRAME (w
->frame
)) = 1;
2531 sideward
= &w
->vchild
;
2532 forward
= &w
->hchild
;
2533 w
->total_cols
= make_number (size
);
2534 adjust_window_margins (w
);
2538 sideward
= &w
->hchild
;
2539 forward
= &w
->vchild
;
2540 w
->total_lines
= make_number (size
);
2541 w
->orig_total_lines
= Qnil
;
2544 if (!NILP (*sideward
))
2546 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
2548 c
= XWINDOW (child
);
2550 c
->left_col
= w
->left_col
;
2552 c
->top_line
= w
->top_line
;
2553 size_window (child
, size
, width_p
, nodelete_p
);
2556 else if (!NILP (*forward
))
2558 int fixed_size
, each
, extra
, n
;
2559 int resize_fixed_p
, nfixed
;
2560 int last_pos
, first_pos
, nchildren
, total
;
2562 /* Determine the fixed-size portion of the this window, and the
2563 number of child windows. */
2564 fixed_size
= nchildren
= nfixed
= total
= 0;
2565 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
2569 c
= XWINDOW (child
);
2570 child_size
= width_p
? XINT (c
->total_cols
) : XINT (c
->total_lines
);
2571 total
+= child_size
;
2573 if (window_fixed_size_p (c
, width_p
, 0))
2575 fixed_size
+= child_size
;
2580 /* If the new size is smaller than fixed_size, or if there
2581 aren't any resizable windows, allow resizing fixed-size
2583 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
2585 /* Compute how many lines/columns to add to each child. The
2586 value of extra takes care of rounding errors. */
2587 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
2588 each
= (size
- total
) / n
;
2589 extra
= (size
- total
) - n
* each
;
2591 /* Compute new children heights and edge positions. */
2592 first_pos
= width_p
? XINT (w
->left_col
) : XINT (w
->top_line
);
2593 last_pos
= first_pos
;
2594 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2596 int new_size
, old_size
;
2598 c
= XWINDOW (child
);
2599 old_size
= width_p
? XFASTINT (c
->total_cols
) : XFASTINT (c
->total_lines
);
2600 new_size
= old_size
;
2602 /* The top or left edge position of this child equals the
2603 bottom or right edge of its predecessor. */
2605 c
->left_col
= make_number (last_pos
);
2607 c
->top_line
= make_number (last_pos
);
2609 /* If this child can be resized, do it. */
2610 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
2612 new_size
= old_size
+ each
+ extra
;
2616 /* Set new height. Note that size_window also propagates
2617 edge positions to children, so it's not a no-op if we
2618 didn't change the child's size. */
2619 size_window (child
, new_size
, width_p
, 1);
2621 /* Remember the bottom/right edge position of this child; it
2622 will be used to set the top/left edge of the next child. */
2623 last_pos
+= new_size
;
2626 /* We should have covered the parent exactly with child windows. */
2627 xassert (size
== last_pos
- first_pos
);
2629 /* Now delete any children that became too small. */
2631 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2634 c
= XWINDOW (child
);
2635 child_size
= width_p
? XINT (c
->total_cols
) : XINT (c
->total_lines
);
2636 size_window (child
, child_size
, width_p
, 2);
2641 /* Set WINDOW's height to HEIGHT, and recursively change the height of
2642 WINDOW's children. NODELETE non-zero means don't delete windows
2643 that become too small in the process. (The caller should check
2644 later and do so if appropriate.) */
2647 set_window_height (window
, height
, nodelete
)
2652 size_window (window
, height
, 0, nodelete
);
2656 /* Set WINDOW's width to WIDTH, and recursively change the width of
2657 WINDOW's children. NODELETE non-zero means don't delete windows
2658 that become too small in the process. (The caller should check
2659 later and do so if appropriate.) */
2662 set_window_width (window
, width
, nodelete
)
2667 size_window (window
, width
, 1, nodelete
);
2670 /* Change window heights in windows rooted in WINDOW by N lines. */
2673 change_window_heights (window
, n
)
2677 struct window
*w
= XWINDOW (window
);
2679 XSETFASTINT (w
->top_line
, XFASTINT (w
->top_line
) + n
);
2680 XSETFASTINT (w
->total_lines
, XFASTINT (w
->total_lines
) - n
);
2682 if (INTEGERP (w
->orig_top_line
))
2683 XSETFASTINT (w
->orig_top_line
, XFASTINT (w
->orig_top_line
) + n
);
2684 if (INTEGERP (w
->orig_total_lines
))
2685 XSETFASTINT (w
->orig_total_lines
, XFASTINT (w
->orig_total_lines
) - n
);
2687 /* Handle just the top child in a vertical split. */
2688 if (!NILP (w
->vchild
))
2689 change_window_heights (w
->vchild
, n
);
2691 /* Adjust all children in a horizontal split. */
2692 for (window
= w
->hchild
; !NILP (window
); window
= w
->next
)
2694 w
= XWINDOW (window
);
2695 change_window_heights (window
, n
);
2700 int window_select_count
;
2703 Fset_window_buffer_unwind (obuf
)
2710 EXFUN (Fset_window_fringes
, 4);
2711 EXFUN (Fset_window_scroll_bars
, 4);
2713 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
2714 means it's allowed to run hooks. See make_frame for a case where
2715 it's not allowed. KEEP_MARGINS_P non-zero means that the current
2716 margins, fringes, and scroll-bar settings of the window are not
2717 reset from the buffer's local settings. */
2720 set_window_buffer (window
, buffer
, run_hooks_p
, keep_margins_p
)
2721 Lisp_Object window
, buffer
;
2722 int run_hooks_p
, keep_margins_p
;
2724 struct window
*w
= XWINDOW (window
);
2725 struct buffer
*b
= XBUFFER (buffer
);
2726 int count
= SPECPDL_INDEX ();
2730 if (EQ (window
, selected_window
))
2731 b
->last_selected_window
= window
;
2733 /* Update time stamps of buffer display. */
2734 if (INTEGERP (b
->display_count
))
2735 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
2736 b
->display_time
= Fcurrent_time ();
2738 XSETFASTINT (w
->window_end_pos
, 0);
2739 XSETFASTINT (w
->window_end_vpos
, 0);
2740 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
2741 w
->window_end_valid
= Qnil
;
2742 w
->hscroll
= w
->min_hscroll
= make_number (0);
2744 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
2745 set_marker_restricted (w
->start
,
2746 make_number (b
->last_window_start
),
2748 w
->start_at_line_beg
= Qnil
;
2749 w
->force_start
= Qnil
;
2750 XSETFASTINT (w
->last_modified
, 0);
2751 XSETFASTINT (w
->last_overlay_modified
, 0);
2752 windows_or_buffers_changed
++;
2754 /* We must select BUFFER for running the window-scroll-functions.
2755 If WINDOW is selected, switch permanently.
2756 Otherwise, switch but go back to the ambient buffer afterward. */
2757 if (EQ (window
, selected_window
))
2758 Fset_buffer (buffer
);
2759 /* We can't check ! NILP (Vwindow_scroll_functions) here
2760 because that might itself be a local variable. */
2761 else if (window_initialized
)
2763 record_unwind_protect (Fset_window_buffer_unwind
, Fcurrent_buffer ());
2764 Fset_buffer (buffer
);
2767 if (!keep_margins_p
)
2769 /* Set left and right marginal area width etc. from buffer. */
2771 /* This may call adjust_window_margins three times, so
2772 temporarily disable window margins. */
2773 w
->left_margin_cols
= w
->right_margin_cols
= Qnil
;
2775 Fset_window_fringes (window
,
2776 b
->left_fringe_width
, b
->right_fringe_width
,
2777 b
->fringes_outside_margins
);
2779 Fset_window_scroll_bars (window
,
2780 b
->scroll_bar_width
,
2781 b
->vertical_scroll_bar_type
, Qnil
);
2783 Fset_window_margins (window
,
2784 b
->left_margin_cols
, b
->right_margin_cols
);
2789 if (! NILP (Vwindow_scroll_functions
))
2790 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2791 Fmarker_position (w
->start
));
2793 if (! NILP (Vwindow_configuration_change_hook
)
2794 && ! NILP (Vrun_hooks
))
2795 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
2798 unbind_to (count
, Qnil
);
2802 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 3, 0,
2803 doc
: /* Make WINDOW display BUFFER as its contents.
2804 BUFFER can be a buffer or buffer name.
2805 Optional third arg KEEP_MARGINS non-nil means that WINDOW's current
2806 display margins, fringe widths, and scroll bar settings are maintained;
2807 the default is to reset these from BUFFER's local settings or the frame
2809 (window
, buffer
, keep_margins
)
2810 register Lisp_Object window
, buffer
, keep_margins
;
2812 register Lisp_Object tem
;
2813 register struct window
*w
= decode_window (window
);
2815 XSETWINDOW (window
, w
);
2816 buffer
= Fget_buffer (buffer
);
2817 CHECK_BUFFER (buffer
);
2819 if (NILP (XBUFFER (buffer
)->name
))
2820 error ("Attempt to display deleted buffer");
2824 error ("Window is deleted");
2825 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
2826 is first being set up. */
2828 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
2829 error ("Window is dedicated to `%s'",
2830 SDATA (XBUFFER (tem
)->name
));
2835 set_window_buffer (window
, buffer
, 1, !NILP (keep_margins
));
2839 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 2, 0,
2840 doc
: /* Select WINDOW. Most editing will apply to WINDOW's buffer.
2841 If WINDOW is not already selected, also make WINDOW's buffer current.
2842 Also make WINDOW the frame's selected window.
2843 Optional second arg NORECORD non-nil means
2844 do not put this buffer at the front of the list of recently selected ones.
2846 Note that the main editor command loop
2847 selects the buffer of the selected window before each command. */)
2849 register Lisp_Object window
, norecord
;
2851 register struct window
*w
;
2852 register struct window
*ow
;
2855 CHECK_LIVE_WINDOW (window
);
2857 w
= XWINDOW (window
);
2858 w
->frozen_window_start_p
= 0;
2860 XSETFASTINT (w
->use_time
, ++window_select_count
);
2861 if (EQ (window
, selected_window
))
2864 if (!NILP (selected_window
))
2866 ow
= XWINDOW (selected_window
);
2867 if (! NILP (ow
->buffer
))
2868 set_marker_both (ow
->pointm
, ow
->buffer
,
2869 BUF_PT (XBUFFER (ow
->buffer
)),
2870 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
2873 selected_window
= window
;
2874 sf
= SELECTED_FRAME ();
2875 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
2877 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
2878 /* Use this rather than Fhandle_switch_frame
2879 so that FRAME_FOCUS_FRAME is moved appropriately as we
2880 move around in the state where a minibuffer in a separate
2882 Fselect_frame (WINDOW_FRAME (w
), Qnil
);
2885 sf
->selected_window
= window
;
2887 if (NILP (norecord
))
2888 record_buffer (w
->buffer
);
2889 Fset_buffer (w
->buffer
);
2891 XBUFFER (w
->buffer
)->last_selected_window
= window
;
2893 /* Go to the point recorded in the window.
2894 This is important when the buffer is in more
2895 than one window. It also matters when
2896 redisplay_window has altered point after scrolling,
2897 because it makes the change only in the window. */
2899 register int new_point
= marker_position (w
->pointm
);
2900 if (new_point
< BEGV
)
2902 else if (new_point
> ZV
)
2908 windows_or_buffers_changed
++;
2913 select_window_norecord (window
)
2916 return Fselect_window (window
, Qt
);
2919 /* Deiconify the frame containing the window WINDOW,
2920 unless it is the selected frame;
2923 The reason for the exception for the selected frame
2924 is that it seems better not to change the selected frames visibility
2925 merely because of displaying a different buffer in it.
2926 The deiconification is useful when a buffer gets shown in
2927 another frame that you were not using lately. */
2930 display_buffer_1 (window
)
2933 Lisp_Object frame
= XWINDOW (window
)->frame
;
2934 FRAME_PTR f
= XFRAME (frame
);
2936 FRAME_SAMPLE_VISIBILITY (f
);
2938 if (!EQ (frame
, selected_frame
))
2940 if (FRAME_ICONIFIED_P (f
))
2941 Fmake_frame_visible (frame
);
2942 else if (FRAME_VISIBLE_P (f
))
2943 Fraise_frame (frame
);
2949 DEFUN ("special-display-p", Fspecial_display_p
, Sspecial_display_p
, 1, 1, 0,
2950 doc
: /* Returns non-nil if a buffer named BUFFER-NAME would be created specially.
2951 The value is actually t if the frame should be called with default frame
2952 parameters, and a list of frame parameters if they were specified.
2953 See `special-display-buffer-names', and `special-display-regexps'. */)
2955 Lisp_Object buffer_name
;
2959 CHECK_STRING (buffer_name
);
2961 tem
= Fmember (buffer_name
, Vspecial_display_buffer_names
);
2965 tem
= Fassoc (buffer_name
, Vspecial_display_buffer_names
);
2969 for (tem
= Vspecial_display_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2971 Lisp_Object car
= XCAR (tem
);
2973 && fast_string_match (car
, buffer_name
) >= 0)
2975 else if (CONSP (car
)
2976 && STRINGP (XCAR (car
))
2977 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2983 DEFUN ("same-window-p", Fsame_window_p
, Ssame_window_p
, 1, 1, 0,
2984 doc
: /* Returns non-nil if a new buffer named BUFFER-NAME would use the same window.
2985 See `same-window-buffer-names' and `same-window-regexps'. */)
2987 Lisp_Object buffer_name
;
2991 CHECK_STRING (buffer_name
);
2993 tem
= Fmember (buffer_name
, Vsame_window_buffer_names
);
2997 tem
= Fassoc (buffer_name
, Vsame_window_buffer_names
);
3001 for (tem
= Vsame_window_regexps
; CONSP (tem
); tem
= XCDR (tem
))
3003 Lisp_Object car
= XCAR (tem
);
3005 && fast_string_match (car
, buffer_name
) >= 0)
3007 else if (CONSP (car
)
3008 && STRINGP (XCAR (car
))
3009 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
3015 /* Use B so the default is (other-buffer). */
3016 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 3,
3017 "BDisplay buffer: \nP",
3018 doc
: /* Make BUFFER appear in some window but don't select it.
3019 BUFFER can be a buffer or a buffer name.
3020 If BUFFER is shown already in some window, just use that one,
3021 unless the window is the selected window and the optional second
3022 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).
3023 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.
3024 Returns the window displaying BUFFER.
3025 If `display-buffer-reuse-frames' is non-nil, and another frame is currently
3026 displaying BUFFER, then simply raise that frame.
3028 The variables `special-display-buffer-names', `special-display-regexps',
3029 `same-window-buffer-names', and `same-window-regexps' customize how certain
3030 buffer names are handled.
3032 If optional argument FRAME is `visible', search all visible frames.
3033 If FRAME is 0, search all visible and iconified frames.
3034 If FRAME is t, search all frames.
3035 If FRAME is a frame, search only that frame.
3036 If FRAME is nil, search only the selected frame
3037 (actually the last nonminibuffer frame),
3038 unless `pop-up-frames' or `display-buffer-reuse-frames' is non-nil,
3039 which means search visible and iconified frames.
3041 If `even-window-heights' is non-nil, window heights will be evened out
3042 if displaying the buffer causes two vertically adjacent windows to be
3044 (buffer
, not_this_window
, frame
)
3045 register Lisp_Object buffer
, not_this_window
, frame
;
3047 register Lisp_Object window
, tem
, swp
;
3051 buffer
= Fget_buffer (buffer
);
3052 CHECK_BUFFER (buffer
);
3054 if (!NILP (Vdisplay_buffer_function
))
3055 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
3057 if (NILP (not_this_window
)
3058 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
3059 return display_buffer_1 (selected_window
);
3061 /* See if the user has specified this buffer should appear
3062 in the selected window. */
3063 if (NILP (not_this_window
))
3065 swp
= Fsame_window_p (XBUFFER (buffer
)->name
);
3066 if (!NILP (swp
) && !no_switch_window (selected_window
))
3068 Fswitch_to_buffer (buffer
, Qnil
);
3069 return display_buffer_1 (selected_window
);
3073 /* If the user wants pop-up-frames or display-buffer-reuse-frames,
3074 look for a window showing BUFFER on any visible or iconified frame.
3075 Otherwise search only the current frame. */
3078 else if (pop_up_frames
3079 || display_buffer_reuse_frames
3080 || last_nonminibuf_frame
== 0)
3081 XSETFASTINT (tem
, 0);
3083 XSETFRAME (tem
, last_nonminibuf_frame
);
3085 window
= Fget_buffer_window (buffer
, tem
);
3087 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
3088 return display_buffer_1 (window
);
3090 /* Certain buffer names get special handling. */
3091 if (!NILP (Vspecial_display_function
) && NILP (swp
))
3093 tem
= Fspecial_display_p (XBUFFER (buffer
)->name
);
3095 return call1 (Vspecial_display_function
, buffer
);
3097 return call2 (Vspecial_display_function
, buffer
, tem
);
3100 /* If there are no frames open that have more than a minibuffer,
3101 we need to create a new frame. */
3102 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
3104 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
3105 Fset_window_buffer (window
, buffer
, Qnil
);
3106 return display_buffer_1 (window
);
3109 f
= SELECTED_FRAME ();
3111 || FRAME_MINIBUF_ONLY_P (f
)
3112 /* If the current frame is a special display frame,
3113 don't try to reuse its windows. */
3114 || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f
))->dedicated
))
3119 if (FRAME_MINIBUF_ONLY_P (f
))
3120 XSETFRAME (frames
, last_nonminibuf_frame
);
3121 /* Don't try to create a window if we would get an error. */
3122 if (split_height_threshold
< window_min_height
<< 1)
3123 split_height_threshold
= window_min_height
<< 1;
3125 /* Note that both Fget_largest_window and Fget_lru_window
3126 ignore minibuffers and dedicated windows.
3127 This means they can return nil. */
3129 /* If the frame we would try to split cannot be split,
3130 try other frames. */
3131 if (FRAME_NO_SPLIT_P (NILP (frames
) ? f
: last_nonminibuf_frame
))
3133 /* Try visible frames first. */
3134 window
= Fget_largest_window (Qvisible
);
3135 /* If that didn't work, try iconified frames. */
3137 window
= Fget_largest_window (make_number (0));
3139 window
= Fget_largest_window (Qt
);
3142 window
= Fget_largest_window (frames
);
3144 /* If we got a tall enough full-width window that can be split,
3147 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
3148 && window_height (window
) >= split_height_threshold
3149 && WINDOW_FULL_WIDTH_P (XWINDOW (window
)))
3150 window
= Fsplit_window (window
, Qnil
, Qnil
);
3153 Lisp_Object upper
, lower
, other
;
3155 window
= Fget_lru_window (frames
);
3156 /* If the LRU window is selected, and big enough,
3157 and can be split, split it. */
3159 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
3160 && (EQ (window
, selected_window
)
3161 || EQ (XWINDOW (window
)->parent
, Qnil
))
3162 && window_height (window
) >= window_min_height
<< 1)
3163 window
= Fsplit_window (window
, Qnil
, Qnil
);
3164 /* If Fget_lru_window returned nil, try other approaches. */
3166 /* Try visible frames first. */
3168 window
= Fget_buffer_window (buffer
, Qvisible
);
3170 window
= Fget_largest_window (Qvisible
);
3171 /* If that didn't work, try iconified frames. */
3173 window
= Fget_buffer_window (buffer
, make_number (0));
3175 window
= Fget_largest_window (make_number (0));
3176 /* Try invisible frames. */
3178 window
= Fget_buffer_window (buffer
, Qt
);
3180 window
= Fget_largest_window (Qt
);
3181 /* As a last resort, make a new frame. */
3183 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
3184 /* If window appears above or below another,
3185 even out their heights. */
3186 other
= upper
= lower
= Qnil
;
3187 if (!NILP (XWINDOW (window
)->prev
))
3188 other
= upper
= XWINDOW (window
)->prev
, lower
= window
;
3189 if (!NILP (XWINDOW (window
)->next
))
3190 other
= lower
= XWINDOW (window
)->next
, upper
= window
;
3192 && !NILP (Veven_window_heights
)
3193 /* Check that OTHER and WINDOW are vertically arrayed. */
3194 && !EQ (XWINDOW (other
)->top_line
, XWINDOW (window
)->top_line
)
3195 && (XFASTINT (XWINDOW (other
)->total_lines
)
3196 > XFASTINT (XWINDOW (window
)->total_lines
)))
3198 int total
= (XFASTINT (XWINDOW (other
)->total_lines
)
3199 + XFASTINT (XWINDOW (window
)->total_lines
));
3200 enlarge_window (upper
,
3201 total
/ 2 - XFASTINT (XWINDOW (upper
)->total_lines
),
3207 window
= Fget_lru_window (Qnil
);
3209 Fset_window_buffer (window
, buffer
, Qnil
);
3210 return display_buffer_1 (window
);
3214 temp_output_buffer_show (buf
)
3215 register Lisp_Object buf
;
3217 register struct buffer
*old
= current_buffer
;
3218 register Lisp_Object window
;
3219 register struct window
*w
;
3221 XBUFFER (buf
)->directory
= current_buffer
->directory
;
3224 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
3228 #if 0 /* rms: there should be no reason for this. */
3229 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
3231 set_buffer_internal (old
);
3233 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
3234 call1 (Vtemp_buffer_show_function
, buf
);
3237 window
= Fdisplay_buffer (buf
, Qnil
, Qnil
);
3239 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
3240 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
3241 Vminibuf_scroll_window
= window
;
3242 w
= XWINDOW (window
);
3243 XSETFASTINT (w
->hscroll
, 0);
3244 XSETFASTINT (w
->min_hscroll
, 0);
3245 set_marker_restricted_both (w
->start
, buf
, 1, 1);
3246 set_marker_restricted_both (w
->pointm
, buf
, 1, 1);
3248 /* Run temp-buffer-show-hook, with the chosen window selected
3249 and its buffer current. */
3250 if (!NILP (Vrun_hooks
))
3253 tem
= Fboundp (Qtemp_buffer_show_hook
);
3256 tem
= Fsymbol_value (Qtemp_buffer_show_hook
);
3259 int count
= SPECPDL_INDEX ();
3260 Lisp_Object prev_window
, prev_buffer
;
3261 prev_window
= selected_window
;
3262 XSETBUFFER (prev_buffer
, old
);
3264 /* Select the window that was chosen, for running the hook.
3265 Note: Both Fselect_window and select_window_norecord may
3266 set-buffer to the buffer displayed in the window,
3267 so we need to save the current buffer. --stef */
3268 record_unwind_protect (Fset_buffer
, prev_buffer
);
3269 record_unwind_protect (select_window_norecord
, prev_window
);
3270 Fselect_window (window
, Qt
);
3271 Fset_buffer (w
->buffer
);
3272 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
3273 unbind_to (count
, Qnil
);
3281 make_dummy_parent (window
)
3285 register struct window
*o
, *p
;
3288 o
= XWINDOW (window
);
3289 p
= allocate_window ();
3290 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
3291 ((struct Lisp_Vector
*) p
)->contents
[i
]
3292 = ((struct Lisp_Vector
*)o
)->contents
[i
];
3293 XSETWINDOW (new, p
);
3295 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
3297 /* Put new into window structure in place of window */
3298 replace_window (window
, new);
3311 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
3312 doc
: /* Split WINDOW, putting SIZE lines in the first of the pair.
3313 WINDOW defaults to selected one and SIZE to half its size.
3314 If optional third arg HORFLAG is non-nil, split side by side
3315 and put SIZE columns in the first of the pair. In that case,
3316 SIZE includes that window's scroll bar, or the divider column to its right. */)
3317 (window
, size
, horflag
)
3318 Lisp_Object window
, size
, horflag
;
3320 register Lisp_Object
new;
3321 register struct window
*o
, *p
;
3323 register int size_int
;
3326 window
= selected_window
;
3328 CHECK_LIVE_WINDOW (window
);
3330 o
= XWINDOW (window
);
3331 fo
= XFRAME (WINDOW_FRAME (o
));
3335 if (!NILP (horflag
))
3336 /* Calculate the size of the left-hand window, by dividing
3337 the usable space in columns by two.
3338 We round up, since the left-hand window may include
3339 a dividing line, while the right-hand may not. */
3340 size_int
= (XFASTINT (o
->total_cols
) + 1) >> 1;
3342 size_int
= XFASTINT (o
->total_lines
) >> 1;
3346 CHECK_NUMBER (size
);
3347 size_int
= XINT (size
);
3350 if (MINI_WINDOW_P (o
))
3351 error ("Attempt to split minibuffer window");
3352 else if (window_fixed_size_p (o
, !NILP (horflag
), 0))
3353 error ("Attempt to split fixed-size window");
3355 check_min_window_sizes ();
3359 if (size_int
< window_min_height
)
3360 error ("Window height %d too small (after splitting)", size_int
);
3361 if (size_int
+ window_min_height
> XFASTINT (o
->total_lines
))
3362 error ("Window height %d too small (after splitting)",
3363 XFASTINT (o
->total_lines
) - size_int
);
3364 if (NILP (o
->parent
)
3365 || NILP (XWINDOW (o
->parent
)->vchild
))
3367 make_dummy_parent (window
);
3369 XWINDOW (new)->vchild
= window
;
3374 if (size_int
< window_min_width
)
3375 error ("Window width %d too small (after splitting)", size_int
);
3377 if (size_int
+ window_min_width
> XFASTINT (o
->total_cols
))
3378 error ("Window width %d too small (after splitting)",
3379 XFASTINT (o
->total_cols
) - size_int
);
3380 if (NILP (o
->parent
)
3381 || NILP (XWINDOW (o
->parent
)->hchild
))
3383 make_dummy_parent (window
);
3385 XWINDOW (new)->hchild
= window
;
3389 /* Now we know that window's parent is a vertical combination
3390 if we are dividing vertically, or a horizontal combination
3391 if we are making side-by-side windows */
3393 windows_or_buffers_changed
++;
3394 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
3395 new = make_window ();
3398 p
->frame
= o
->frame
;
3400 if (!NILP (p
->next
))
3401 XWINDOW (p
->next
)->prev
= new;
3404 p
->parent
= o
->parent
;
3406 p
->window_end_valid
= Qnil
;
3407 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
3409 /* Duplicate special geometry settings. */
3411 p
->left_margin_cols
= o
->left_margin_cols
;
3412 p
->right_margin_cols
= o
->right_margin_cols
;
3413 p
->left_fringe_width
= o
->left_fringe_width
;
3414 p
->right_fringe_width
= o
->right_fringe_width
;
3415 p
->fringes_outside_margins
= o
->fringes_outside_margins
;
3416 p
->scroll_bar_width
= o
->scroll_bar_width
;
3417 p
->vertical_scroll_bar_type
= o
->vertical_scroll_bar_type
;
3419 /* Apportion the available frame space among the two new windows */
3421 if (!NILP (horflag
))
3423 p
->total_lines
= o
->total_lines
;
3424 p
->top_line
= o
->top_line
;
3425 XSETFASTINT (p
->total_cols
, XFASTINT (o
->total_cols
) - size_int
);
3426 XSETFASTINT (o
->total_cols
, size_int
);
3427 XSETFASTINT (p
->left_col
, XFASTINT (o
->left_col
) + size_int
);
3428 adjust_window_margins (p
);
3429 adjust_window_margins (o
);
3433 p
->left_col
= o
->left_col
;
3434 p
->total_cols
= o
->total_cols
;
3435 XSETFASTINT (p
->total_lines
, XFASTINT (o
->total_lines
) - size_int
);
3436 XSETFASTINT (o
->total_lines
, size_int
);
3437 XSETFASTINT (p
->top_line
, XFASTINT (o
->top_line
) + size_int
);
3440 /* Adjust glyph matrices. */
3443 Fset_window_buffer (new, o
->buffer
, Qt
);
3447 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 3, "p",
3448 doc
: /* Make current window ARG lines bigger.
3449 From program, optional second arg non-nil means grow sideways ARG columns.
3450 Interactively, if an argument is not given, make the window one line bigger.
3452 Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size
3453 of the siblings above or to the left of the selected window. Only
3454 siblings to the right or below are changed. */)
3455 (arg
, side
, preserve_before
)
3456 register Lisp_Object arg
, side
, preserve_before
;
3459 enlarge_window (selected_window
, XINT (arg
), !NILP (side
),
3460 !NILP (preserve_before
));
3462 if (! NILP (Vwindow_configuration_change_hook
))
3463 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3468 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 3, "p",
3469 doc
: /* Make current window ARG lines smaller.
3470 From program, optional second arg non-nil means shrink sideways arg columns.
3471 Interactively, if an argument is not given, make the window one line smaller.
3473 Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size
3474 of the siblings above or to the left of the selected window. Only
3475 siblings to the right or below are changed. */)
3476 (arg
, side
, preserve_before
)
3477 register Lisp_Object arg
, side
, preserve_before
;
3480 enlarge_window (selected_window
, -XINT (arg
), !NILP (side
),
3481 !NILP (preserve_before
));
3483 if (! NILP (Vwindow_configuration_change_hook
))
3484 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3490 window_height (window
)
3493 register struct window
*p
= XWINDOW (window
);
3494 return WINDOW_TOTAL_LINES (p
);
3498 window_width (window
)
3501 register struct window
*p
= XWINDOW (window
);
3502 return WINDOW_TOTAL_COLS (p
);
3507 *(widthflag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
3509 #define CURSIZE(w) \
3510 *(widthflag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
3513 /* Enlarge WINDOW by DELTA. WIDTHFLAG non-zero means
3514 increase its width. Siblings of the selected window are resized to
3515 fulfill the size request. If they become too small in the process,
3516 they will be deleted.
3518 If PRESERVE_BEFORE is nonzero, that means don't alter
3519 the siblings to the left or above WINDOW. */
3522 enlarge_window (window
, delta
, widthflag
, preserve_before
)
3524 int delta
, widthflag
, preserve_before
;
3526 Lisp_Object parent
, next
, prev
;
3530 int (*sizefun
) P_ ((Lisp_Object
))
3531 = widthflag
? window_width
: window_height
;
3532 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
3533 = (widthflag
? set_window_width
: set_window_height
);
3535 /* Check values of window_min_width and window_min_height for
3537 check_min_window_sizes ();
3539 /* Give up if this window cannot be resized. */
3540 if (window_fixed_size_p (XWINDOW (window
), widthflag
, 1))
3541 error ("Window is not resizable");
3543 /* Find the parent of the selected window. */
3546 p
= XWINDOW (window
);
3552 error ("No other window to side of this one");
3557 ? !NILP (XWINDOW (parent
)->hchild
)
3558 : !NILP (XWINDOW (parent
)->vchild
))
3564 sizep
= &CURSIZE (window
);
3567 register int maxdelta
;
3569 /* Compute the maximum size increment this window can have. */
3571 if (preserve_before
)
3575 maxdelta
= (*sizefun
) (parent
) - XINT (*sizep
);
3576 /* Subtract size of siblings before, since we can't take that. */
3577 maxdelta
-= XINT (CURBEG (window
)) - XINT (CURBEG (parent
));
3580 maxdelta
= (!NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3581 - window_min_size (XWINDOW (p
->next
),
3586 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - XINT (*sizep
)
3587 /* This is a main window followed by a minibuffer. */
3588 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3589 - window_min_size (XWINDOW (p
->next
),
3591 /* This is a minibuffer following a main window. */
3592 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
3593 - window_min_size (XWINDOW (p
->prev
),
3595 /* This is a frame with only one window, a minibuffer-only
3596 or a minibufferless frame. */
3599 if (delta
> maxdelta
)
3600 /* This case traps trying to make the minibuffer
3601 the full frame, or make the only window aside from the
3602 minibuffer the full frame. */
3606 if (XINT (*sizep
) + delta
< window_min_size (XWINDOW (window
), widthflag
, 0, 0))
3608 delete_window (window
);
3615 /* Find the total we can get from other siblings without deleting them. */
3617 for (next
= p
->next
; ! NILP (next
); next
= XWINDOW (next
)->next
)
3618 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
3620 if (! preserve_before
)
3621 for (prev
= p
->prev
; ! NILP (prev
); prev
= XWINDOW (prev
)->prev
)
3622 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
3625 /* If we can get it all from them without deleting them, do so. */
3626 if (delta
<= maximum
)
3628 Lisp_Object first_unaffected
;
3629 Lisp_Object first_affected
;
3634 first_affected
= window
;
3635 /* Look at one sibling at a time,
3636 moving away from this window in both directions alternately,
3637 and take as much as we can get without deleting that sibling. */
3639 && (!NILP (next
) || (!preserve_before
&& !NILP (prev
))))
3643 int this_one
= ((*sizefun
) (next
)
3644 - window_min_size (XWINDOW (next
),
3645 widthflag
, 0, &fixed_p
));
3648 if (this_one
> delta
)
3651 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
3652 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3657 next
= XWINDOW (next
)->next
;
3663 if (!preserve_before
&& ! NILP (prev
))
3665 int this_one
= ((*sizefun
) (prev
)
3666 - window_min_size (XWINDOW (prev
),
3667 widthflag
, 0, &fixed_p
));
3670 if (this_one
> delta
)
3673 first_affected
= prev
;
3675 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
3676 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3681 prev
= XWINDOW (prev
)->prev
;
3685 xassert (delta
== 0);
3687 /* Now recalculate the edge positions of all the windows affected,
3688 based on the new sizes. */
3689 first_unaffected
= next
;
3690 prev
= first_affected
;
3691 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
3692 prev
= next
, next
= XWINDOW (next
)->next
)
3694 XSETINT (CURBEG (next
), XINT (CURBEG (prev
)) + (*sizefun
) (prev
));
3695 /* This does not change size of NEXT,
3696 but it propagates the new top edge to its children */
3697 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
3702 register int delta1
;
3703 register int opht
= (*sizefun
) (parent
);
3705 if (opht
<= XINT (*sizep
) + delta
)
3707 /* If trying to grow this window to or beyond size of the parent,
3708 just delete all the sibling windows. */
3709 Lisp_Object start
, tem
, next
;
3711 start
= XWINDOW (parent
)->vchild
;
3713 start
= XWINDOW (parent
)->hchild
;
3715 /* Delete any siblings that come after WINDOW. */
3716 tem
= XWINDOW (window
)->next
;
3717 while (! NILP (tem
))
3719 next
= XWINDOW (tem
)->next
;
3720 delete_window (tem
);
3724 /* Delete any siblings that come after WINDOW.
3725 Note that if START is not WINDOW, then WINDOW still
3726 Fhas siblings, so WINDOW has not yet replaced its parent. */
3728 while (! EQ (tem
, window
))
3730 next
= XWINDOW (tem
)->next
;
3731 delete_window (tem
);
3737 /* Otherwise, make delta1 just right so that if we add
3738 delta1 lines to this window and to the parent, and then
3739 shrink the parent back to its original size, the new
3740 proportional size of this window will increase by delta.
3742 The function size_window will compute the new height h'
3743 of the window from delta1 as:
3746 x = delta1 - delta1/n * n for the 1st resizable child
3749 where n is the number of children that can be resized.
3750 We can ignore x by choosing a delta1 that is a multiple of
3751 n. We want the height of this window to come out as
3761 The number of children n equals the number of resizable
3762 children of this window + 1 because we know window itself
3763 is resizable (otherwise we would have signalled an error. */
3765 struct window
*w
= XWINDOW (window
);
3769 for (s
= w
->next
; !NILP (s
); s
= XWINDOW (s
)->next
)
3770 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3772 for (s
= w
->prev
; !NILP (s
); s
= XWINDOW (s
)->prev
)
3773 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3778 /* Add delta1 lines or columns to this window, and to the parent,
3779 keeping things consistent while not affecting siblings. */
3780 XSETINT (CURSIZE (parent
), opht
+ delta1
);
3781 (*setsizefun
) (window
, XINT (*sizep
) + delta1
, 0);
3783 /* Squeeze out delta1 lines or columns from our parent,
3784 shriking this window and siblings proportionately.
3785 This brings parent back to correct size.
3786 Delta1 was calculated so this makes this window the desired size,
3787 taking it all out of the siblings. */
3788 (*setsizefun
) (parent
, opht
, 0);
3793 XSETFASTINT (p
->last_modified
, 0);
3794 XSETFASTINT (p
->last_overlay_modified
, 0);
3796 /* Adjust glyph matrices. */
3797 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
3805 /***********************************************************************
3806 Resizing Mini-Windows
3807 ***********************************************************************/
3809 static void shrink_window_lowest_first
P_ ((struct window
*, int));
3811 enum save_restore_action
3818 static int save_restore_orig_size
P_ ((struct window
*,
3819 enum save_restore_action
));
3821 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
3822 from lowest windows first. */
3825 shrink_window_lowest_first (w
, height
)
3833 xassert (!MINI_WINDOW_P (w
));
3835 /* Set redisplay hints. */
3836 XSETFASTINT (w
->last_modified
, 0);
3837 XSETFASTINT (w
->last_overlay_modified
, 0);
3838 windows_or_buffers_changed
++;
3839 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
3841 old_height
= XFASTINT (w
->total_lines
);
3842 XSETFASTINT (w
->total_lines
, height
);
3844 if (!NILP (w
->hchild
))
3846 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
3848 c
= XWINDOW (child
);
3849 c
->top_line
= w
->top_line
;
3850 shrink_window_lowest_first (c
, height
);
3853 else if (!NILP (w
->vchild
))
3855 Lisp_Object last_child
;
3856 int delta
= old_height
- height
;
3861 /* Find the last child. We are taking space from lowest windows
3862 first, so we iterate over children from the last child
3864 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
3867 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
3868 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
3872 c
= XWINDOW (child
);
3873 this_one
= XFASTINT (c
->total_lines
) - MIN_SAFE_WINDOW_HEIGHT
;
3875 if (this_one
> delta
)
3878 shrink_window_lowest_first (c
, XFASTINT (c
->total_lines
) - this_one
);
3882 /* Compute new positions. */
3883 last_top
= XINT (w
->top_line
);
3884 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
3886 c
= XWINDOW (child
);
3887 c
->top_line
= make_number (last_top
);
3888 shrink_window_lowest_first (c
, XFASTINT (c
->total_lines
));
3889 last_top
+= XFASTINT (c
->total_lines
);
3895 /* Save, restore, or check positions and sizes in the window tree
3896 rooted at W. ACTION says what to do.
3898 If ACTION is CHECK_ORIG_SIZES, check if orig_top_line and
3899 orig_total_lines members are valid for all windows in the window
3900 tree. Value is non-zero if they are valid.
3902 If ACTION is SAVE_ORIG_SIZES, save members top and height in
3903 orig_top_line and orig_total_lines for all windows in the tree.
3905 If ACTION is RESTORE_ORIG_SIZES, restore top and height from values
3906 stored in orig_top_line and orig_total_lines for all windows. */
3909 save_restore_orig_size (w
, action
)
3911 enum save_restore_action action
;
3917 if (!NILP (w
->hchild
))
3919 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
3922 else if (!NILP (w
->vchild
))
3924 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
3930 case CHECK_ORIG_SIZES
:
3931 if (!INTEGERP (w
->orig_top_line
) || !INTEGERP (w
->orig_total_lines
))
3935 case SAVE_ORIG_SIZES
:
3936 w
->orig_top_line
= w
->top_line
;
3937 w
->orig_total_lines
= w
->total_lines
;
3938 XSETFASTINT (w
->last_modified
, 0);
3939 XSETFASTINT (w
->last_overlay_modified
, 0);
3942 case RESTORE_ORIG_SIZES
:
3943 xassert (INTEGERP (w
->orig_top_line
) && INTEGERP (w
->orig_total_lines
));
3944 w
->top_line
= w
->orig_top_line
;
3945 w
->total_lines
= w
->orig_total_lines
;
3946 w
->orig_total_lines
= w
->orig_top_line
= Qnil
;
3947 XSETFASTINT (w
->last_modified
, 0);
3948 XSETFASTINT (w
->last_overlay_modified
, 0);
3955 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
3962 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
3963 without deleting other windows. */
3966 grow_mini_window (w
, delta
)
3970 struct frame
*f
= XFRAME (w
->frame
);
3971 struct window
*root
;
3973 xassert (MINI_WINDOW_P (w
));
3974 xassert (delta
>= 0);
3976 /* Check values of window_min_width and window_min_height for
3978 check_min_window_sizes ();
3980 /* Compute how much we can enlarge the mini-window without deleting
3982 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3985 int min_height
= window_min_size (root
, 0, 0, 0);
3986 if (XFASTINT (root
->total_lines
) - delta
< min_height
)
3987 /* Note that the root window may already be smaller than
3989 delta
= max (0, XFASTINT (root
->total_lines
) - min_height
);
3994 /* Save original window sizes and positions, if not already done. */
3995 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3996 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
3998 /* Shrink other windows. */
3999 shrink_window_lowest_first (root
, XFASTINT (root
->total_lines
) - delta
);
4001 /* Grow the mini-window. */
4002 w
->top_line
= make_number (XFASTINT (root
->top_line
) + XFASTINT (root
->total_lines
));
4003 w
->total_lines
= make_number (XFASTINT (w
->total_lines
) + delta
);
4004 XSETFASTINT (w
->last_modified
, 0);
4005 XSETFASTINT (w
->last_overlay_modified
, 0);
4012 /* Shrink mini-window W. If there is recorded info about window sizes
4013 before a call to grow_mini_window, restore recorded window sizes.
4014 Otherwise, if the mini-window is higher than 1 line, resize it to 1
4018 shrink_mini_window (w
)
4021 struct frame
*f
= XFRAME (w
->frame
);
4022 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4024 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
4026 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
4028 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4029 windows_or_buffers_changed
= 1;
4031 else if (XFASTINT (w
->total_lines
) > 1)
4033 /* Distribute the additional lines of the mini-window
4034 among the other windows. */
4036 XSETWINDOW (window
, w
);
4037 enlarge_window (window
, 1 - XFASTINT (w
->total_lines
), 0, 0);
4043 /* Mark window cursors off for all windows in the window tree rooted
4044 at W by setting their phys_cursor_on_p flag to zero. Called from
4045 xterm.c, e.g. when a frame is cleared and thereby all cursors on
4046 the frame are cleared. */
4049 mark_window_cursors_off (w
)
4054 if (!NILP (w
->hchild
))
4055 mark_window_cursors_off (XWINDOW (w
->hchild
));
4056 else if (!NILP (w
->vchild
))
4057 mark_window_cursors_off (XWINDOW (w
->vchild
));
4059 w
->phys_cursor_on_p
= 0;
4061 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4066 /* Return number of lines of text (not counting mode lines) in W. */
4069 window_internal_height (w
)
4072 int ht
= XFASTINT (w
->total_lines
);
4074 if (!MINI_WINDOW_P (w
))
4076 if (!NILP (w
->parent
)
4077 || !NILP (w
->vchild
)
4078 || !NILP (w
->hchild
)
4081 || WINDOW_WANTS_MODELINE_P (w
))
4084 if (WINDOW_WANTS_HEADER_LINE_P (w
))
4092 /* Return the number of columns in W.
4093 Don't count columns occupied by scroll bars or the vertical bar
4094 separating W from the sibling to its right. */
4097 window_box_text_cols (w
)
4100 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4101 int width
= XINT (w
->total_cols
);
4103 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
4104 /* Scroll bars occupy a few columns. */
4105 width
-= WINDOW_CONFIG_SCROLL_BAR_COLS (w
);
4106 else if (!FRAME_WINDOW_P (f
)
4107 && !WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
4108 /* The column of `|' characters separating side-by-side windows
4109 occupies one column only. */
4112 if (FRAME_WINDOW_P (f
))
4113 /* On window-systems, fringes and display margins cannot be
4114 used for normal text. */
4115 width
-= (WINDOW_FRINGE_COLS (w
)
4116 + WINDOW_LEFT_MARGIN_COLS (w
)
4117 + WINDOW_RIGHT_MARGIN_COLS (w
));
4123 /************************************************************************
4125 ***********************************************************************/
4127 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
4128 N screen-fulls, which is defined as the height of the window minus
4129 next_screen_context_lines. If WHOLE is zero, scroll up N lines
4130 instead. Negative values of N mean scroll down. NOERROR non-zero
4131 means don't signal an error if we try to move over BEGV or ZV,
4135 window_scroll (window
, n
, whole
, noerror
)
4143 /* If we must, use the pixel-based version which is much slower than
4144 the line-based one but can handle varying line heights. */
4145 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
4146 window_scroll_pixel_based (window
, n
, whole
, noerror
);
4148 window_scroll_line_based (window
, n
, whole
, noerror
);
4154 /* Implementation of window_scroll that works based on pixel line
4155 heights. See the comment of window_scroll for parameter
4159 window_scroll_pixel_based (window
, n
, whole
, noerror
)
4166 struct window
*w
= XWINDOW (window
);
4167 struct text_pos start
;
4169 int this_scroll_margin
;
4171 /* True if we fiddled the window vscroll field without really scrolling. */
4174 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4176 /* If PT is not visible in WINDOW, move back one half of
4177 the screen. Allow PT to be partially visible, otherwise
4178 something like (scroll-down 1) with PT in the line before
4179 the partially visible one would recenter. */
4180 tem
= Fpos_visible_in_window_p (make_number (PT
), window
, Qt
);
4183 /* Move backward half the height of the window. Performance note:
4184 vmotion used here is about 10% faster, but would give wrong
4185 results for variable height lines. */
4186 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4187 it
.current_y
= it
.last_visible_y
;
4188 move_it_vertically (&it
, - window_box_height (w
) / 2);
4190 /* The function move_iterator_vertically may move over more than
4191 the specified y-distance. If it->w is small, e.g. a
4192 mini-buffer window, we may end up in front of the window's
4193 display area. This is the case when Start displaying at the
4194 start of the line containing PT in this case. */
4195 if (it
.current_y
<= 0)
4197 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4198 move_it_vertically (&it
, 0);
4202 start
= it
.current
.pos
;
4205 /* If scroll_preserve_screen_position is non-zero, we try to set
4206 point in the same window line as it is now, so get that line. */
4207 if (!NILP (Vscroll_preserve_screen_position
))
4209 start_display (&it
, w
, start
);
4210 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
4211 preserve_y
= it
.current_y
;
4216 /* Move iterator it from start the specified distance forward or
4217 backward. The result is the new window start. */
4218 start_display (&it
, w
, start
);
4221 int screen_full
= (window_box_height (w
)
4222 - next_screen_context_lines
* FRAME_LINE_HEIGHT (it
.f
));
4223 int dy
= n
* screen_full
;
4225 /* Note that move_it_vertically always moves the iterator to the
4226 start of a line. So, if the last line doesn't have a newline,
4227 we would end up at the start of the line ending at ZV. */
4229 move_it_vertically_backward (&it
, -dy
);
4231 move_it_to (&it
, ZV
, -1, it
.current_y
+ dy
, -1,
4232 MOVE_TO_POS
| MOVE_TO_Y
);
4235 move_it_by_lines (&it
, n
, 1);
4237 /* We failed if we find ZV is already on the screen (scrolling up,
4238 means there's nothing past the end), or if we can't start any
4239 earlier (scrolling down, means there's nothing past the top). */
4240 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
4241 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
4243 if (IT_CHARPOS (it
) == ZV
)
4245 if (it
.current_y
< it
.last_visible_y
4246 && (it
.current_y
+ it
.max_ascent
+ it
.max_descent
4247 >= it
.last_visible_y
))
4249 /* The last line was only partially visible, make it fully
4251 w
->vscroll
= (it
.last_visible_y
4252 - it
.current_y
+ it
.max_ascent
+ it
.max_descent
);
4253 adjust_glyphs (it
.f
);
4258 Fsignal (Qend_of_buffer
, Qnil
);
4262 if (w
->vscroll
!= 0)
4263 /* The first line was only partially visible, make it fully
4269 Fsignal (Qbeginning_of_buffer
, Qnil
);
4272 /* If control gets here, then we vscrolled. */
4274 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
4276 /* Don't try to change the window start below. */
4282 int pos
= IT_CHARPOS (it
);
4285 /* If in the middle of a multi-glyph character move forward to
4286 the next character. */
4287 if (in_display_vector_p (&it
))
4290 move_it_to (&it
, pos
, -1, -1, -1, MOVE_TO_POS
);
4293 /* Set the window start, and set up the window for redisplay. */
4294 set_marker_restricted (w
->start
, make_number (pos
),
4296 bytepos
= XMARKER (w
->start
)->bytepos
;
4297 w
->start_at_line_beg
= ((pos
== BEGV
|| FETCH_BYTE (bytepos
- 1) == '\n')
4299 w
->update_mode_line
= Qt
;
4300 XSETFASTINT (w
->last_modified
, 0);
4301 XSETFASTINT (w
->last_overlay_modified
, 0);
4302 /* Set force_start so that redisplay_window will run the
4303 window-scroll-functions. */
4304 w
->force_start
= Qt
;
4307 it
.current_y
= it
.vpos
= 0;
4309 /* Preserve the screen position if we must. */
4310 if (preserve_y
>= 0)
4312 move_it_to (&it
, -1, -1, preserve_y
, -1, MOVE_TO_Y
);
4313 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4317 /* Move PT out of scroll margins. */
4318 this_scroll_margin
= max (0, scroll_margin
);
4319 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->total_lines
) / 4);
4320 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
4324 /* We moved the window start towards ZV, so PT may be now
4325 in the scroll margin at the top. */
4326 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
4327 while (it
.current_y
< this_scroll_margin
)
4329 int prev
= it
.current_y
;
4330 move_it_by_lines (&it
, 1, 1);
4331 if (prev
== it
.current_y
)
4334 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4338 int charpos
, bytepos
;
4340 /* We moved the window start towards BEGV, so PT may be now
4341 in the scroll margin at the bottom. */
4342 move_it_to (&it
, PT
, -1,
4343 it
.last_visible_y
- this_scroll_margin
- 1, -1,
4344 MOVE_TO_POS
| MOVE_TO_Y
);
4346 /* Save our position, in case it's correct. */
4347 charpos
= IT_CHARPOS (it
);
4348 bytepos
= IT_BYTEPOS (it
);
4350 /* See if point is on a partially visible line at the end. */
4351 move_it_by_lines (&it
, 1, 1);
4352 if (it
.current_y
> it
.last_visible_y
)
4353 /* The last line was only partially visible, so back up two
4354 lines to make sure we're on a fully visible line. */
4356 move_it_by_lines (&it
, -2, 0);
4357 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4360 /* No, the position we saved is OK, so use it. */
4361 SET_PT_BOTH (charpos
, bytepos
);
4367 /* Implementation of window_scroll that works based on screen lines.
4368 See the comment of window_scroll for parameter descriptions. */
4371 window_scroll_line_based (window
, n
, whole
, noerror
)
4377 register struct window
*w
= XWINDOW (window
);
4378 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
4379 register int pos
, pos_byte
;
4380 register int ht
= window_internal_height (w
);
4381 register Lisp_Object tem
;
4385 struct position posit
;
4388 /* If scrolling screen-fulls, compute the number of lines to
4389 scroll from the window's height. */
4391 n
*= max (1, ht
- next_screen_context_lines
);
4393 startpos
= marker_position (w
->start
);
4395 posit
= *compute_motion (startpos
, 0, 0, 0,
4397 window_box_text_cols (w
), XINT (w
->hscroll
),
4399 original_vpos
= posit
.vpos
;
4401 XSETFASTINT (tem
, PT
);
4402 tem
= Fpos_visible_in_window_p (tem
, window
, Qnil
);
4406 Fvertical_motion (make_number (- (ht
/ 2)), window
);
4411 lose
= n
< 0 && PT
== BEGV
;
4412 Fvertical_motion (make_number (n
), window
);
4416 SET_PT_BOTH (opoint
, opoint_byte
);
4423 Fsignal (Qbeginning_of_buffer
, Qnil
);
4428 int this_scroll_margin
= scroll_margin
;
4430 /* Don't use a scroll margin that is negative or too large. */
4431 if (this_scroll_margin
< 0)
4432 this_scroll_margin
= 0;
4434 if (XINT (w
->total_lines
) < 4 * scroll_margin
)
4435 this_scroll_margin
= XINT (w
->total_lines
) / 4;
4437 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
4438 w
->start_at_line_beg
= bolp
;
4439 w
->update_mode_line
= Qt
;
4440 XSETFASTINT (w
->last_modified
, 0);
4441 XSETFASTINT (w
->last_overlay_modified
, 0);
4442 /* Set force_start so that redisplay_window will run
4443 the window-scroll-functions. */
4444 w
->force_start
= Qt
;
4446 if (whole
&& !NILP (Vscroll_preserve_screen_position
))
4448 SET_PT_BOTH (pos
, pos_byte
);
4449 Fvertical_motion (make_number (original_vpos
), window
);
4451 /* If we scrolled forward, put point enough lines down
4452 that it is outside the scroll margin. */
4457 if (this_scroll_margin
> 0)
4459 SET_PT_BOTH (pos
, pos_byte
);
4460 Fvertical_motion (make_number (this_scroll_margin
), window
);
4466 if (top_margin
<= opoint
)
4467 SET_PT_BOTH (opoint
, opoint_byte
);
4468 else if (!NILP (Vscroll_preserve_screen_position
))
4470 SET_PT_BOTH (pos
, pos_byte
);
4471 Fvertical_motion (make_number (original_vpos
), window
);
4474 SET_PT (top_margin
);
4480 /* If we scrolled backward, put point near the end of the window
4481 but not within the scroll margin. */
4482 SET_PT_BOTH (pos
, pos_byte
);
4483 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
4484 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
4487 bottom_margin
= PT
+ 1;
4489 if (bottom_margin
> opoint
)
4490 SET_PT_BOTH (opoint
, opoint_byte
);
4493 if (!NILP (Vscroll_preserve_screen_position
))
4495 SET_PT_BOTH (pos
, pos_byte
);
4496 Fvertical_motion (make_number (original_vpos
), window
);
4499 Fvertical_motion (make_number (-1), window
);
4508 Fsignal (Qend_of_buffer
, Qnil
);
4513 /* Scroll selected_window up or down. If N is nil, scroll a
4514 screen-full which is defined as the height of the window minus
4515 next_screen_context_lines. If N is the symbol `-', scroll.
4516 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
4517 up. This is the guts of Fscroll_up and Fscroll_down. */
4520 scroll_command (n
, direction
)
4524 int count
= SPECPDL_INDEX ();
4526 xassert (abs (direction
) == 1);
4528 /* If selected window's buffer isn't current, make it current for
4529 the moment. But don't screw up if window_scroll gets an error. */
4530 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
4532 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4533 Fset_buffer (XWINDOW (selected_window
)->buffer
);
4535 /* Make redisplay consider other windows than just selected_window. */
4536 ++windows_or_buffers_changed
;
4540 window_scroll (selected_window
, direction
, 1, 0);
4541 else if (EQ (n
, Qminus
))
4542 window_scroll (selected_window
, -direction
, 1, 0);
4545 n
= Fprefix_numeric_value (n
);
4546 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
4549 unbind_to (count
, Qnil
);
4552 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
4553 doc
: /* Scroll text of current window upward ARG lines; or near full screen if no ARG.
4554 A near full screen is `next-screen-context-lines' less than a full screen.
4555 Negative ARG means scroll downward.
4556 If ARG is the atom `-', scroll downward by nearly full screen.
4557 When calling from a program, supply as argument a number, nil, or `-'. */)
4561 scroll_command (arg
, 1);
4565 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
4566 doc
: /* Scroll text of current window down ARG lines; or near full screen if no ARG.
4567 A near full screen is `next-screen-context-lines' less than a full screen.
4568 Negative ARG means scroll upward.
4569 If ARG is the atom `-', scroll upward by nearly full screen.
4570 When calling from a program, supply as argument a number, nil, or `-'. */)
4574 scroll_command (arg
, -1);
4578 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
4579 doc
: /* Return the other window for \"other window scroll\" commands.
4580 If in the minibuffer, `minibuffer-scroll-window' if non-nil
4581 specifies the window.
4582 If `other-window-scroll-buffer' is non-nil, a window
4583 showing that buffer is used. */)
4588 if (MINI_WINDOW_P (XWINDOW (selected_window
))
4589 && !NILP (Vminibuf_scroll_window
))
4590 window
= Vminibuf_scroll_window
;
4591 /* If buffer is specified, scroll that buffer. */
4592 else if (!NILP (Vother_window_scroll_buffer
))
4594 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
4596 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
4600 /* Nothing specified; look for a neighboring window on the same
4602 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
4604 if (EQ (window
, selected_window
))
4605 /* That didn't get us anywhere; look for a window on another
4608 window
= Fnext_window (window
, Qnil
, Qt
);
4609 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
4610 && ! EQ (window
, selected_window
));
4613 CHECK_LIVE_WINDOW (window
);
4615 if (EQ (window
, selected_window
))
4616 error ("There is no other window");
4621 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
4622 doc
: /* Scroll next window upward ARG lines; or near full screen if no ARG.
4623 A near full screen is `next-screen-context-lines' less than a full screen.
4624 The next window is the one below the current one; or the one at the top
4625 if the current one is at the bottom. Negative ARG means scroll downward.
4626 If ARG is the atom `-', scroll downward by nearly full screen.
4627 When calling from a program, supply as argument a number, nil, or `-'.
4629 If in the minibuffer, `minibuffer-scroll-window' if non-nil
4630 specifies the window to scroll.
4631 If `other-window-scroll-buffer' is non-nil, scroll the window
4632 showing that buffer, popping the buffer up if necessary. */)
4638 int count
= SPECPDL_INDEX ();
4640 window
= Fother_window_for_scrolling ();
4641 w
= XWINDOW (window
);
4643 /* Don't screw up if window_scroll gets an error. */
4644 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4645 ++windows_or_buffers_changed
;
4647 Fset_buffer (w
->buffer
);
4648 SET_PT (marker_position (w
->pointm
));
4651 window_scroll (window
, 1, 1, 1);
4652 else if (EQ (arg
, Qminus
))
4653 window_scroll (window
, -1, 1, 1);
4659 window_scroll (window
, XINT (arg
), 0, 1);
4662 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
4663 unbind_to (count
, Qnil
);
4668 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 1, "P",
4669 doc
: /* Scroll selected window display ARG columns left.
4670 Default for ARG is window width minus 2.
4671 Value is the total amount of leftward horizontal scrolling in
4672 effect after the change.
4673 If `automatic-hscrolling' is non-nil, the argument ARG modifies
4674 a lower bound for automatic scrolling, i.e. automatic scrolling
4675 will not scroll a window to a column less than the value returned
4676 by this function. */)
4678 register Lisp_Object arg
;
4682 struct window
*w
= XWINDOW (selected_window
);
4685 XSETFASTINT (arg
, window_box_text_cols (w
) - 2);
4687 arg
= Fprefix_numeric_value (arg
);
4689 hscroll
= XINT (w
->hscroll
) + XINT (arg
);
4690 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
4692 if (interactive_p (0))
4693 w
->min_hscroll
= w
->hscroll
;
4698 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 1, "P",
4699 doc
: /* Scroll selected window display ARG columns right.
4700 Default for ARG is window width minus 2.
4701 Value is the total amount of leftward horizontal scrolling in
4702 effect after the change.
4703 If `automatic-hscrolling' is non-nil, the argument ARG modifies
4704 a lower bound for automatic scrolling, i.e. automatic scrolling
4705 will not scroll a window to a column less than the value returned
4706 by this function. */)
4708 register Lisp_Object arg
;
4712 struct window
*w
= XWINDOW (selected_window
);
4715 XSETFASTINT (arg
, window_box_text_cols (w
) - 2);
4717 arg
= Fprefix_numeric_value (arg
);
4719 hscroll
= XINT (w
->hscroll
) - XINT (arg
);
4720 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
4722 if (interactive_p (0))
4723 w
->min_hscroll
= w
->hscroll
;
4728 DEFUN ("minibuffer-selected-window", Fminibuffer_selected_window
, Sminibuffer_selected_window
, 0, 0, 0,
4729 doc
: /* Return the window which was selected when entering the minibuffer.
4730 Returns nil, if current window is not a minibuffer window. */)
4733 if (minibuf_level
> 0
4734 && MINI_WINDOW_P (XWINDOW (selected_window
))
4735 && !NILP (minibuf_selected_window
)
4736 && WINDOW_LIVE_P (minibuf_selected_window
))
4737 return minibuf_selected_window
;
4742 /* Value is the number of lines actually displayed in window W,
4743 as opposed to its height. */
4746 displayed_window_lines (w
)
4750 struct text_pos start
;
4751 int height
= window_box_height (w
);
4752 struct buffer
*old_buffer
;
4755 if (XBUFFER (w
->buffer
) != current_buffer
)
4757 old_buffer
= current_buffer
;
4758 set_buffer_internal (XBUFFER (w
->buffer
));
4763 /* In case W->start is out of the accessible range, do something
4764 reasonable. This happens in Info mode when Info-scroll-down
4765 calls (recenter -1) while W->start is 1. */
4766 if (XMARKER (w
->start
)->charpos
< BEGV
)
4767 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
4768 else if (XMARKER (w
->start
)->charpos
> ZV
)
4769 SET_TEXT_POS (start
, ZV
, ZV_BYTE
);
4771 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4773 start_display (&it
, w
, start
);
4774 move_it_vertically (&it
, height
);
4775 bottom_y
= line_bottom_y (&it
);
4777 /* rms: On a non-window display,
4778 the value of it.vpos at the bottom of the screen
4779 seems to be 1 larger than window_box_height (w).
4780 This kludge fixes a bug whereby (move-to-window-line -1)
4781 when ZV is on the last screen line
4782 moves to the previous screen line instead of the last one. */
4783 if (! FRAME_WINDOW_P (XFRAME (w
->frame
)))
4786 /* Add in empty lines at the bottom of the window. */
4787 if (bottom_y
< height
)
4789 int uy
= FRAME_LINE_HEIGHT (it
.f
);
4790 it
.vpos
+= (height
- bottom_y
+ uy
- 1) / uy
;
4794 set_buffer_internal (old_buffer
);
4800 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
4801 doc
: /* Center point in window and redisplay frame.
4802 With prefix argument ARG, recenter putting point on screen line ARG
4803 relative to the current window. If ARG is negative, it counts up from the
4804 bottom of the window. (ARG should be less than the height of the window.)
4806 If ARG is omitted or nil, erase the entire frame and then
4807 redraw with point in the center of the current window.
4808 Just C-u as prefix means put point in the center of the window
4809 and redisplay normally--don't erase and redraw the frame. */)
4811 register Lisp_Object arg
;
4813 struct window
*w
= XWINDOW (selected_window
);
4814 struct buffer
*buf
= XBUFFER (w
->buffer
);
4815 struct buffer
*obuf
= current_buffer
;
4817 int charpos
, bytepos
;
4819 /* If redisplay is suppressed due to an error, try again. */
4820 obuf
->display_error_modiff
= 0;
4826 /* Invalidate pixel data calculated for all compositions. */
4827 for (i
= 0; i
< n_compositions
; i
++)
4828 composition_table
[i
]->font
= NULL
;
4830 Fredraw_frame (w
->frame
);
4831 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
4834 else if (CONSP (arg
)) /* Just C-u. */
4838 arg
= Fprefix_numeric_value (arg
);
4842 set_buffer_internal (buf
);
4844 /* Handle centering on a graphical frame specially. Such frames can
4845 have variable-height lines and centering point on the basis of
4846 line counts would lead to strange effects. */
4847 if (FRAME_WINDOW_P (XFRAME (w
->frame
)))
4854 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
4855 start_display (&it
, w
, pt
);
4856 move_it_vertically (&it
, - window_box_height (w
) / 2);
4857 charpos
= IT_CHARPOS (it
);
4858 bytepos
= IT_BYTEPOS (it
);
4860 else if (XINT (arg
) < 0)
4864 int y0
, y1
, h
, nlines
;
4866 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
4867 start_display (&it
, w
, pt
);
4870 /* The amount of pixels we have to move back is the window
4871 height minus what's displayed in the line containing PT,
4872 and the lines below. */
4873 nlines
= - XINT (arg
) - 1;
4874 move_it_by_lines (&it
, nlines
, 1);
4876 y1
= line_bottom_y (&it
);
4878 /* If we can't move down NLINES lines because we hit
4879 the end of the buffer, count in some empty lines. */
4880 if (it
.vpos
< nlines
)
4881 y1
+= (nlines
- it
.vpos
) * FRAME_LINE_HEIGHT (it
.f
);
4883 h
= window_box_height (w
) - (y1
- y0
);
4885 start_display (&it
, w
, pt
);
4886 move_it_vertically (&it
, - h
);
4887 charpos
= IT_CHARPOS (it
);
4888 bytepos
= IT_BYTEPOS (it
);
4892 struct position pos
;
4893 pos
= *vmotion (PT
, - XINT (arg
), w
);
4894 charpos
= pos
.bufpos
;
4895 bytepos
= pos
.bytepos
;
4900 struct position pos
;
4901 int ht
= window_internal_height (w
);
4904 arg
= make_number (ht
/ 2);
4905 else if (XINT (arg
) < 0)
4906 arg
= make_number (XINT (arg
) + ht
);
4908 pos
= *vmotion (PT
, - XINT (arg
), w
);
4909 charpos
= pos
.bufpos
;
4910 bytepos
= pos
.bytepos
;
4913 /* Set the new window start. */
4914 set_marker_both (w
->start
, w
->buffer
, charpos
, bytepos
);
4915 w
->window_end_valid
= Qnil
;
4917 w
->optional_new_start
= Qt
;
4919 if (bytepos
== BEGV_BYTE
|| FETCH_BYTE (bytepos
- 1) == '\n')
4920 w
->start_at_line_beg
= Qt
;
4922 w
->start_at_line_beg
= Qnil
;
4924 set_buffer_internal (obuf
);
4929 DEFUN ("window-text-height", Fwindow_text_height
, Swindow_text_height
,
4931 doc
: /* Return the height in lines of the text display area of WINDOW.
4932 This doesn't include the mode-line (or header-line if any) or any
4933 partial-height lines in the text display area. */)
4937 struct window
*w
= decode_window (window
);
4938 int pixel_height
= window_box_height (w
);
4939 int line_height
= pixel_height
/ FRAME_LINE_HEIGHT (XFRAME (w
->frame
));
4940 return make_number (line_height
);
4945 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
4947 doc
: /* Position point relative to window.
4948 With no argument, position point at center of window.
4949 An argument specifies vertical position within the window;
4950 zero means top of window, negative means relative to bottom of window. */)
4954 struct window
*w
= XWINDOW (selected_window
);
4958 window
= selected_window
;
4959 start
= marker_position (w
->start
);
4960 if (start
< BEGV
|| start
> ZV
)
4962 int height
= window_internal_height (w
);
4963 Fvertical_motion (make_number (- (height
/ 2)), window
);
4964 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
4965 w
->start_at_line_beg
= Fbolp ();
4966 w
->force_start
= Qt
;
4969 Fgoto_char (w
->start
);
4971 lines
= displayed_window_lines (w
);
4973 XSETFASTINT (arg
, lines
/ 2);
4976 arg
= Fprefix_numeric_value (arg
);
4978 XSETINT (arg
, XINT (arg
) + lines
);
4981 /* Skip past a partially visible first line. */
4983 XSETINT (arg
, XINT (arg
) + 1);
4985 return Fvertical_motion (arg
, window
);
4990 /***********************************************************************
4991 Window Configuration
4992 ***********************************************************************/
4994 struct save_window_data
4996 EMACS_INT size_from_Lisp_Vector_struct
;
4997 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4998 Lisp_Object frame_cols
, frame_lines
, frame_menu_bar_lines
;
4999 Lisp_Object frame_tool_bar_lines
;
5000 Lisp_Object selected_frame
;
5001 Lisp_Object current_window
;
5002 Lisp_Object current_buffer
;
5003 Lisp_Object minibuf_scroll_window
;
5004 Lisp_Object minibuf_selected_window
;
5005 Lisp_Object root_window
;
5006 Lisp_Object focus_frame
;
5007 /* Record the values of window-min-width and window-min-height
5008 so that window sizes remain consistent with them. */
5009 Lisp_Object min_width
, min_height
;
5010 /* A vector, each of whose elements is a struct saved_window
5012 Lisp_Object saved_windows
;
5015 /* This is saved as a Lisp_Vector */
5018 /* these first two must agree with struct Lisp_Vector in lisp.h */
5019 EMACS_INT size_from_Lisp_Vector_struct
;
5020 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
5023 Lisp_Object buffer
, start
, pointm
, mark
;
5024 Lisp_Object left_col
, top_line
, total_cols
, total_lines
;
5025 Lisp_Object hscroll
, min_hscroll
;
5026 Lisp_Object parent
, prev
;
5027 Lisp_Object start_at_line_beg
;
5028 Lisp_Object display_table
;
5029 Lisp_Object orig_top_line
, orig_total_lines
;
5030 Lisp_Object left_margin_cols
, right_margin_cols
;
5031 Lisp_Object left_fringe_width
, right_fringe_width
, fringes_outside_margins
;
5032 Lisp_Object scroll_bar_width
, vertical_scroll_bar_type
;
5035 #define SAVED_WINDOW_VECTOR_SIZE 24 /* Arg to Fmake_vector */
5037 #define SAVED_WINDOW_N(swv,n) \
5038 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
5040 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
5041 doc
: /* Return t if OBJECT is a window-configuration object. */)
5045 if (WINDOW_CONFIGURATIONP (object
))
5050 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
5051 doc
: /* Return the frame that CONFIG, a window-configuration object, is about. */)
5055 register struct save_window_data
*data
;
5056 struct Lisp_Vector
*saved_windows
;
5058 if (! WINDOW_CONFIGURATIONP (config
))
5059 wrong_type_argument (Qwindow_configuration_p
, config
);
5061 data
= (struct save_window_data
*) XVECTOR (config
);
5062 saved_windows
= XVECTOR (data
->saved_windows
);
5063 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
5066 DEFUN ("set-window-configuration", Fset_window_configuration
,
5067 Sset_window_configuration
, 1, 1, 0,
5068 doc
: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
5069 CONFIGURATION must be a value previously returned
5070 by `current-window-configuration' (which see).
5071 If CONFIGURATION was made from a frame that is now deleted,
5072 only frame-independent values can be restored. In this case,
5073 the return value is nil. Otherwise the value is t. */)
5075 Lisp_Object configuration
;
5077 register struct save_window_data
*data
;
5078 struct Lisp_Vector
*saved_windows
;
5079 Lisp_Object new_current_buffer
;
5084 while (!WINDOW_CONFIGURATIONP (configuration
))
5085 wrong_type_argument (Qwindow_configuration_p
, configuration
);
5087 data
= (struct save_window_data
*) XVECTOR (configuration
);
5088 saved_windows
= XVECTOR (data
->saved_windows
);
5090 new_current_buffer
= data
->current_buffer
;
5091 if (NILP (XBUFFER (new_current_buffer
)->name
))
5092 new_current_buffer
= Qnil
;
5095 if (XBUFFER (new_current_buffer
) == current_buffer
)
5098 old_point
= BUF_PT (XBUFFER (new_current_buffer
));
5101 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
5104 /* If f is a dead frame, don't bother rebuilding its window tree.
5105 However, there is other stuff we should still try to do below. */
5106 if (FRAME_LIVE_P (f
))
5108 register struct window
*w
;
5109 register struct saved_window
*p
;
5110 struct window
*root_window
;
5111 struct window
**leaf_windows
;
5115 /* If the frame has been resized since this window configuration was
5116 made, we change the frame to the size specified in the
5117 configuration, restore the configuration, and then resize it
5118 back. We keep track of the prevailing height in these variables. */
5119 int previous_frame_lines
= FRAME_LINES (f
);
5120 int previous_frame_cols
= FRAME_COLS (f
);
5121 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
5122 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
5124 /* The mouse highlighting code could get screwed up
5125 if it runs during this. */
5128 if (XFASTINT (data
->frame_lines
) != previous_frame_lines
5129 || XFASTINT (data
->frame_cols
) != previous_frame_cols
)
5130 change_frame_size (f
, XFASTINT (data
->frame_lines
),
5131 XFASTINT (data
->frame_cols
), 0, 0, 0);
5132 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
5133 if (XFASTINT (data
->frame_menu_bar_lines
)
5134 != previous_frame_menu_bar_lines
)
5135 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, make_number (0));
5136 #ifdef HAVE_WINDOW_SYSTEM
5137 if (XFASTINT (data
->frame_tool_bar_lines
)
5138 != previous_frame_tool_bar_lines
)
5139 x_set_tool_bar_lines (f
, data
->frame_tool_bar_lines
, make_number (0));
5143 /* "Swap out" point from the selected window
5144 into its buffer. We do this now, before
5145 restoring the window contents, and prevent it from
5146 being done later on when we select a new window. */
5147 if (! NILP (XWINDOW (selected_window
)->buffer
))
5149 w
= XWINDOW (selected_window
);
5150 set_marker_both (w
->pointm
,
5152 BUF_PT (XBUFFER (w
->buffer
)),
5153 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5156 windows_or_buffers_changed
++;
5157 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
5159 /* Problem: Freeing all matrices and later allocating them again
5160 is a serious redisplay flickering problem. What we would
5161 really like to do is to free only those matrices not reused
5163 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
5165 = (struct window
**) alloca (count_windows (root_window
)
5166 * sizeof (struct window
*));
5167 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
5169 /* Temporarily avoid any problems with windows that are smaller
5170 than they are supposed to be. */
5171 window_min_height
= 1;
5172 window_min_width
= 1;
5175 Mark all windows now on frame as "deleted".
5176 Restoring the new configuration "undeletes" any that are in it.
5178 Save their current buffers in their height fields, since we may
5179 need it later, if a buffer saved in the configuration is now
5181 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5183 for (k
= 0; k
< saved_windows
->size
; k
++)
5185 p
= SAVED_WINDOW_N (saved_windows
, k
);
5186 w
= XWINDOW (p
->window
);
5189 if (!NILP (p
->parent
))
5190 w
->parent
= SAVED_WINDOW_N (saved_windows
,
5191 XFASTINT (p
->parent
))->window
;
5195 if (!NILP (p
->prev
))
5197 w
->prev
= SAVED_WINDOW_N (saved_windows
,
5198 XFASTINT (p
->prev
))->window
;
5199 XWINDOW (w
->prev
)->next
= p
->window
;
5204 if (!NILP (w
->parent
))
5206 if (EQ (p
->total_cols
, XWINDOW (w
->parent
)->total_cols
))
5208 XWINDOW (w
->parent
)->vchild
= p
->window
;
5209 XWINDOW (w
->parent
)->hchild
= Qnil
;
5213 XWINDOW (w
->parent
)->hchild
= p
->window
;
5214 XWINDOW (w
->parent
)->vchild
= Qnil
;
5219 /* If we squirreled away the buffer in the window's height,
5221 if (BUFFERP (w
->total_lines
))
5222 w
->buffer
= w
->total_lines
;
5223 w
->left_col
= p
->left_col
;
5224 w
->top_line
= p
->top_line
;
5225 w
->total_cols
= p
->total_cols
;
5226 w
->total_lines
= p
->total_lines
;
5227 w
->hscroll
= p
->hscroll
;
5228 w
->min_hscroll
= p
->min_hscroll
;
5229 w
->display_table
= p
->display_table
;
5230 w
->orig_top_line
= p
->orig_top_line
;
5231 w
->orig_total_lines
= p
->orig_total_lines
;
5232 w
->left_margin_cols
= p
->left_margin_cols
;
5233 w
->right_margin_cols
= p
->right_margin_cols
;
5234 w
->left_fringe_width
= p
->left_fringe_width
;
5235 w
->right_fringe_width
= p
->right_fringe_width
;
5236 w
->fringes_outside_margins
= p
->fringes_outside_margins
;
5237 w
->scroll_bar_width
= p
->scroll_bar_width
;
5238 w
->vertical_scroll_bar_type
= p
->vertical_scroll_bar_type
;
5239 XSETFASTINT (w
->last_modified
, 0);
5240 XSETFASTINT (w
->last_overlay_modified
, 0);
5242 /* Reinstall the saved buffer and pointers into it. */
5243 if (NILP (p
->buffer
))
5244 w
->buffer
= p
->buffer
;
5247 if (!NILP (XBUFFER (p
->buffer
)->name
))
5248 /* If saved buffer is alive, install it. */
5250 w
->buffer
= p
->buffer
;
5251 w
->start_at_line_beg
= p
->start_at_line_beg
;
5252 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
5253 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
5254 Fset_marker (XBUFFER (w
->buffer
)->mark
,
5255 p
->mark
, w
->buffer
);
5257 /* As documented in Fcurrent_window_configuration, don't
5258 restore the location of point in the buffer which was
5259 current when the window configuration was recorded. */
5260 if (!EQ (p
->buffer
, new_current_buffer
)
5261 && XBUFFER (p
->buffer
) == current_buffer
)
5262 Fgoto_char (w
->pointm
);
5264 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
5265 /* Else unless window has a live buffer, get one. */
5267 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
5268 /* This will set the markers to beginning of visible
5270 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
5271 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
5272 w
->start_at_line_beg
= Qt
;
5275 /* Keeping window's old buffer; make sure the markers
5278 /* Set window markers at start of visible range. */
5279 if (XMARKER (w
->start
)->buffer
== 0)
5280 set_marker_restricted (w
->start
, make_number (0),
5282 if (XMARKER (w
->pointm
)->buffer
== 0)
5283 set_marker_restricted_both (w
->pointm
, w
->buffer
,
5284 BUF_PT (XBUFFER (w
->buffer
)),
5285 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5286 w
->start_at_line_beg
= Qt
;
5291 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
5292 /* Prevent "swapping out point" in the old selected window
5293 using the buffer that has been restored into it.
5294 Use the point value from the beginning of this function
5295 since unshow_buffer (called from delete_all_subwindows)
5296 could have altered it. */
5297 selected_window
= Qnil
;
5298 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
))
5299 set_marker_restricted (XWINDOW (data
->current_window
)->pointm
,
5300 make_number (old_point
),
5301 XWINDOW (data
->current_window
)->buffer
);
5303 Fselect_window (data
->current_window
, Qnil
);
5304 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
5307 if (NILP (data
->focus_frame
)
5308 || (FRAMEP (data
->focus_frame
)
5309 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
5310 Fredirect_frame_focus (frame
, data
->focus_frame
);
5312 #if 0 /* I don't understand why this is needed, and it causes problems
5313 when the frame's old selected window has been deleted. */
5314 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
5315 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
5319 /* Set the screen height to the value it had before this function. */
5320 if (previous_frame_lines
!= FRAME_LINES (f
)
5321 || previous_frame_cols
!= FRAME_COLS (f
))
5322 change_frame_size (f
, previous_frame_lines
, previous_frame_cols
,
5324 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
5325 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
5326 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
5328 #ifdef HAVE_WINDOW_SYSTEM
5329 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
5330 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
5335 /* Now, free glyph matrices in windows that were not reused. */
5336 for (i
= n
= 0; i
< n_leaf_windows
; ++i
)
5338 if (NILP (leaf_windows
[i
]->buffer
))
5340 /* Assert it's not reused as a combination. */
5341 xassert (NILP (leaf_windows
[i
]->hchild
)
5342 && NILP (leaf_windows
[i
]->vchild
));
5343 free_window_matrices (leaf_windows
[i
]);
5345 else if (EQ (leaf_windows
[i
]->buffer
, new_current_buffer
))
5353 /* Fselect_window will have made f the selected frame, so we
5354 reselect the proper frame here. Fhandle_switch_frame will change the
5355 selected window too, but that doesn't make the call to
5356 Fselect_window above totally superfluous; it still sets f's
5358 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
5359 do_switch_frame (data
->selected_frame
, 0, 0);
5361 if (! NILP (Vwindow_configuration_change_hook
)
5362 && ! NILP (Vrun_hooks
))
5363 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
5366 if (!NILP (new_current_buffer
))
5367 Fset_buffer (new_current_buffer
);
5369 /* Restore the minimum heights recorded in the configuration. */
5370 window_min_height
= XINT (data
->min_height
);
5371 window_min_width
= XINT (data
->min_width
);
5373 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
5374 minibuf_selected_window
= data
->minibuf_selected_window
;
5376 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
5379 /* Mark all windows now on frame as deleted
5380 by setting their buffers to nil. */
5383 delete_all_subwindows (w
)
5384 register struct window
*w
;
5386 if (!NILP (w
->next
))
5387 delete_all_subwindows (XWINDOW (w
->next
));
5388 if (!NILP (w
->vchild
))
5389 delete_all_subwindows (XWINDOW (w
->vchild
));
5390 if (!NILP (w
->hchild
))
5391 delete_all_subwindows (XWINDOW (w
->hchild
));
5393 w
->total_lines
= w
->buffer
; /* See Fset_window_configuration for excuse. */
5395 if (!NILP (w
->buffer
))
5398 /* We set all three of these fields to nil, to make sure that we can
5399 distinguish this dead window from any live window. Live leaf
5400 windows will have buffer set, and combination windows will have
5401 vchild or hchild set. */
5406 Vwindow_list
= Qnil
;
5410 count_windows (window
)
5411 register struct window
*window
;
5413 register int count
= 1;
5414 if (!NILP (window
->next
))
5415 count
+= count_windows (XWINDOW (window
->next
));
5416 if (!NILP (window
->vchild
))
5417 count
+= count_windows (XWINDOW (window
->vchild
));
5418 if (!NILP (window
->hchild
))
5419 count
+= count_windows (XWINDOW (window
->hchild
));
5424 /* Fill vector FLAT with leaf windows under W, starting at index I.
5425 Value is last index + 1. */
5428 get_leaf_windows (w
, flat
, i
)
5430 struct window
**flat
;
5435 if (!NILP (w
->hchild
))
5436 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
5437 else if (!NILP (w
->vchild
))
5438 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
5442 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5449 /* Return a pointer to the glyph W's physical cursor is on. Value is
5450 null if W's current matrix is invalid, so that no meaningfull glyph
5454 get_phys_cursor_glyph (w
)
5457 struct glyph_row
*row
;
5458 struct glyph
*glyph
;
5460 if (w
->phys_cursor
.vpos
>= 0
5461 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
5462 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
5464 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
5465 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
5474 save_window_save (window
, vector
, i
)
5476 struct Lisp_Vector
*vector
;
5479 register struct saved_window
*p
;
5480 register struct window
*w
;
5481 register Lisp_Object tem
;
5483 for (;!NILP (window
); window
= w
->next
)
5485 p
= SAVED_WINDOW_N (vector
, i
);
5486 w
= XWINDOW (window
);
5488 XSETFASTINT (w
->temslot
, i
++);
5490 p
->buffer
= w
->buffer
;
5491 p
->left_col
= w
->left_col
;
5492 p
->top_line
= w
->top_line
;
5493 p
->total_cols
= w
->total_cols
;
5494 p
->total_lines
= w
->total_lines
;
5495 p
->hscroll
= w
->hscroll
;
5496 p
->min_hscroll
= w
->min_hscroll
;
5497 p
->display_table
= w
->display_table
;
5498 p
->orig_top_line
= w
->orig_top_line
;
5499 p
->orig_total_lines
= w
->orig_total_lines
;
5500 p
->left_margin_cols
= w
->left_margin_cols
;
5501 p
->right_margin_cols
= w
->right_margin_cols
;
5502 p
->left_fringe_width
= w
->left_fringe_width
;
5503 p
->right_fringe_width
= w
->right_fringe_width
;
5504 p
->fringes_outside_margins
= w
->fringes_outside_margins
;
5505 p
->scroll_bar_width
= w
->scroll_bar_width
;
5506 p
->vertical_scroll_bar_type
= w
->vertical_scroll_bar_type
;
5507 if (!NILP (w
->buffer
))
5509 /* Save w's value of point in the window configuration.
5510 If w is the selected window, then get the value of point
5511 from the buffer; pointm is garbage in the selected window. */
5512 if (EQ (window
, selected_window
))
5514 p
->pointm
= Fmake_marker ();
5515 set_marker_both (p
->pointm
, w
->buffer
,
5516 BUF_PT (XBUFFER (w
->buffer
)),
5517 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5520 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
5522 p
->start
= Fcopy_marker (w
->start
, Qnil
);
5523 p
->start_at_line_beg
= w
->start_at_line_beg
;
5525 tem
= XBUFFER (w
->buffer
)->mark
;
5526 p
->mark
= Fcopy_marker (tem
, Qnil
);
5533 p
->start_at_line_beg
= Qnil
;
5536 if (NILP (w
->parent
))
5539 p
->parent
= XWINDOW (w
->parent
)->temslot
;
5544 p
->prev
= XWINDOW (w
->prev
)->temslot
;
5546 if (!NILP (w
->vchild
))
5547 i
= save_window_save (w
->vchild
, vector
, i
);
5548 if (!NILP (w
->hchild
))
5549 i
= save_window_save (w
->hchild
, vector
, i
);
5555 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
5556 Scurrent_window_configuration
, 0, 1, 0,
5557 doc
: /* Return an object representing the current window configuration of FRAME.
5558 If FRAME is nil or omitted, use the selected frame.
5559 This describes the number of windows, their sizes and current buffers,
5560 and for each displayed buffer, where display starts, and the positions of
5561 point and mark. An exception is made for point in the current buffer:
5562 its value is -not- saved.
5563 This also records the currently selected frame, and FRAME's focus
5564 redirection (see `redirect-frame-focus'). */)
5568 register Lisp_Object tem
;
5569 register int n_windows
;
5570 register struct save_window_data
*data
;
5571 register struct Lisp_Vector
*vec
;
5576 frame
= selected_frame
;
5577 CHECK_LIVE_FRAME (frame
);
5580 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5581 vec
= allocate_other_vector (VECSIZE (struct save_window_data
));
5582 data
= (struct save_window_data
*)vec
;
5584 XSETFASTINT (data
->frame_cols
, FRAME_COLS (f
));
5585 XSETFASTINT (data
->frame_lines
, FRAME_LINES (f
));
5586 XSETFASTINT (data
->frame_menu_bar_lines
, FRAME_MENU_BAR_LINES (f
));
5587 XSETFASTINT (data
->frame_tool_bar_lines
, FRAME_TOOL_BAR_LINES (f
));
5588 data
->selected_frame
= selected_frame
;
5589 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
5590 XSETBUFFER (data
->current_buffer
, current_buffer
);
5591 data
->minibuf_scroll_window
= minibuf_level
> 0 ? Vminibuf_scroll_window
: Qnil
;
5592 data
->minibuf_selected_window
= minibuf_level
> 0 ? minibuf_selected_window
: Qnil
;
5593 data
->root_window
= FRAME_ROOT_WINDOW (f
);
5594 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
5595 XSETINT (data
->min_height
, window_min_height
);
5596 XSETINT (data
->min_width
, window_min_width
);
5597 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
5598 data
->saved_windows
= tem
;
5599 for (i
= 0; i
< n_windows
; i
++)
5600 XVECTOR (tem
)->contents
[i
]
5601 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
5602 save_window_save (FRAME_ROOT_WINDOW (f
), XVECTOR (tem
), 0);
5603 XSETWINDOW_CONFIGURATION (tem
, data
);
5607 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
5609 doc
: /* Execute body, preserving window sizes and contents.
5610 Restore which buffer appears in which window, where display starts,
5611 and the value of point and mark for each window.
5612 Also restore the choice of selected window.
5613 Also restore which buffer is current.
5614 Does not restore the value of point in current buffer.
5615 usage: (save-window-excursion BODY ...) */)
5619 register Lisp_Object val
;
5620 register int count
= SPECPDL_INDEX ();
5622 record_unwind_protect (Fset_window_configuration
,
5623 Fcurrent_window_configuration (Qnil
));
5624 val
= Fprogn (args
);
5625 return unbind_to (count
, val
);
5629 /***********************************************************************
5631 ***********************************************************************/
5633 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
5635 doc
: /* Set width of marginal areas of window WINDOW.
5636 If window is nil, set margins of the currently selected window.
5637 First parameter LEFT-WIDTH specifies the number of character
5638 cells to reserve for the left marginal area. Second parameter
5639 RIGHT-WIDTH does the same for the right marginal area.
5640 A nil width parameter means no margin. */)
5641 (window
, left
, right
)
5642 Lisp_Object window
, left
, right
;
5644 struct window
*w
= decode_window (window
);
5646 /* TODO: It doesn't make sense to use FLOATs here, since
5647 the rest of the code assumes they are integers.
5648 So don't allow floats! ++KFS */
5651 CHECK_NUMBER_OR_FLOAT (left
);
5653 CHECK_NUMBER_OR_FLOAT (right
);
5655 /* Check widths < 0 and translate a zero width to nil.
5656 Margins that are too wide have to be checked elsewhere. */
5657 if ((INTEGERP (left
) && XINT (left
) < 0)
5658 || (FLOATP (left
) && XFLOAT_DATA (left
) <= 0))
5659 XSETFASTINT (left
, 0);
5660 if (INTEGERP (left
) && XFASTINT (left
) == 0)
5663 if ((INTEGERP (right
) && XINT (right
) < 0)
5664 || (FLOATP (right
) && XFLOAT_DATA (right
) <= 0))
5665 XSETFASTINT (right
, 0);
5666 if (INTEGERP (right
) && XFASTINT (right
) == 0)
5669 if (!EQ (w
->left_margin_cols
, left
)
5670 || !EQ (w
->right_margin_cols
, right
))
5672 w
->left_margin_cols
= left
;
5673 w
->right_margin_cols
= right
;
5675 adjust_window_margins (w
);
5677 ++windows_or_buffers_changed
;
5678 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
5685 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
5687 doc
: /* Get width of marginal areas of window WINDOW.
5688 If WINDOW is omitted or nil, use the currently selected window.
5689 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).
5690 If a marginal area does not exist, its width will be returned
5695 struct window
*w
= decode_window (window
);
5696 return Fcons (w
->left_margin_cols
, w
->right_margin_cols
);
5701 /***********************************************************************
5703 ***********************************************************************/
5705 DEFUN ("set-window-fringes", Fset_window_fringes
, Sset_window_fringes
,
5707 doc
: /* Set width of fringes of window WINDOW.
5709 If window is nil, set fringes of the currently selected window.
5710 Second parameter LEFT-WIDTH specifies the number of pixels to reserve
5711 for the left fringe. Third parameter RIGHT-WIDTH does the same for
5712 the right fringe. Fourth parameter OUTSIDE-MARGINS non-nil specifies
5713 that fringes are drawn outside of the display margins; by default, fringes
5714 are drawn between display marginal areas and the text area.
5715 A nil width parameter means to use the frame's corresponding fringe width. */)
5716 (window
, left
, right
, outside_margins
)
5717 Lisp_Object window
, left
, right
, outside_margins
;
5719 struct window
*w
= decode_window (window
);
5722 CHECK_NUMBER (left
);
5724 CHECK_NUMBER (right
);
5726 if (!EQ (w
->left_fringe_width
, left
)
5727 || !EQ (w
->right_fringe_width
, right
)
5728 || !EQ (w
->fringes_outside_margins
, outside_margins
))
5730 w
->left_fringe_width
= left
;
5731 w
->right_fringe_width
= right
;
5732 w
->fringes_outside_margins
= outside_margins
;
5734 adjust_window_margins (w
);
5736 clear_glyph_matrix (w
->current_matrix
);
5737 w
->window_end_valid
= Qnil
;
5739 ++windows_or_buffers_changed
;
5740 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
5747 DEFUN ("window-fringes", Fwindow_fringes
, Swindow_fringes
,
5749 doc
: /* Get width of fringes of window WINDOW.
5750 If WINDOW is omitted or nil, use the currently selected window.
5751 Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS).
5752 If a window specific fringe width is not set, its width will be returned
5757 struct window
*w
= decode_window (window
);
5758 return Fcons (make_number (WINDOW_LEFT_FRINGE_WIDTH (w
)),
5759 Fcons (make_number (WINDOW_RIGHT_FRINGE_WIDTH (w
)),
5760 Fcons ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
) ?
5761 Qt
: Qnil
), Qnil
)));
5766 /***********************************************************************
5768 ***********************************************************************/
5770 DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars
, Sset_window_scroll_bars
,
5772 doc
: /* Set width and type of scroll bars of window WINDOW.
5773 If window is nil, set scroll bars of the currently selected window.
5774 Second parameter WIDTH specifies the pixel width for the scroll bar;
5775 this is automatically adjusted to a multiple of the frame column width.
5776 Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
5777 bar: left, right, or nil.
5778 A width of nil and type of t means to use the frame's corresponding value. */)
5779 (window
, width
, vertical_type
, horizontal_type
)
5780 Lisp_Object window
, width
, vertical_type
, horizontal_type
;
5782 struct window
*w
= decode_window (window
);
5785 CHECK_NUMBER (width
);
5787 if (XINT (width
) == 0)
5788 vertical_type
= Qnil
;
5790 if (!EQ (w
->scroll_bar_width
, width
)
5791 || !EQ (w
->vertical_scroll_bar_type
, vertical_type
))
5793 w
->scroll_bar_width
= width
;
5794 w
->vertical_scroll_bar_type
= vertical_type
;
5796 adjust_window_margins (w
);
5798 clear_glyph_matrix (w
->current_matrix
);
5799 w
->window_end_valid
= Qnil
;
5801 ++windows_or_buffers_changed
;
5802 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
5809 DEFUN ("window-scroll-bars", Fwindow_scroll_bars
, Swindow_scroll_bars
,
5811 doc
: /* Get width and type of scroll bars of window WINDOW.
5812 If WINDOW is omitted or nil, use the currently selected window.
5813 Value is a list of the form (WIDTH COLS VERTICAL-TYPE HORIZONTAL-TYPE). */)
5817 struct window
*w
= decode_window (window
);
5818 return Fcons (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
)
5819 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
)
5820 : WINDOW_SCROLL_BAR_AREA_WIDTH (w
))),
5821 Fcons (make_number (WINDOW_SCROLL_BAR_COLS (w
)),
5822 Fcons (w
->vertical_scroll_bar_type
,
5823 Fcons (Qnil
, Qnil
))));
5828 /***********************************************************************
5830 ***********************************************************************/
5832 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 1, 0,
5833 doc
: /* Return the amount by which WINDOW is scrolled vertically.
5834 Use the selected window if WINDOW is nil or omitted.
5835 Value is a multiple of the canonical character height of WINDOW. */)
5844 window
= selected_window
;
5846 CHECK_WINDOW (window
);
5847 w
= XWINDOW (window
);
5848 f
= XFRAME (w
->frame
);
5850 if (FRAME_WINDOW_P (f
))
5851 result
= FRAME_CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
);
5853 result
= make_number (0);
5858 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
5860 doc
: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL.
5861 WINDOW nil means use the selected window. VSCROLL is a non-negative
5862 multiple of the canonical character height of WINDOW. */)
5864 Lisp_Object window
, vscroll
;
5870 window
= selected_window
;
5872 CHECK_WINDOW (window
);
5873 CHECK_NUMBER_OR_FLOAT (vscroll
);
5875 w
= XWINDOW (window
);
5876 f
= XFRAME (w
->frame
);
5878 if (FRAME_WINDOW_P (f
))
5880 int old_dy
= w
->vscroll
;
5882 w
->vscroll
= - FRAME_LINE_HEIGHT (f
) * XFLOATINT (vscroll
);
5883 w
->vscroll
= min (w
->vscroll
, 0);
5885 /* Adjust glyph matrix of the frame if the virtual display
5886 area becomes larger than before. */
5887 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
5890 /* Prevent redisplay shortcuts. */
5891 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
5894 return Fwindow_vscroll (window
);
5898 /* Call FN for all leaf windows on frame F. FN is called with the
5899 first argument being a pointer to the leaf window, and with
5900 additional argument USER_DATA. Stops when FN returns 0. */
5903 foreach_window (f
, fn
, user_data
)
5905 int (* fn
) P_ ((struct window
*, void *));
5908 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, user_data
);
5912 /* Helper function for foreach_window. Call FN for all leaf windows
5913 reachable from W. FN is called with the first argument being a
5914 pointer to the leaf window, and with additional argument USER_DATA.
5915 Stop when FN returns 0. Value is 0 if stopped by FN. */
5918 foreach_window_1 (w
, fn
, user_data
)
5920 int (* fn
) P_ ((struct window
*, void *));
5925 for (cont
= 1; w
&& cont
;)
5927 if (!NILP (w
->hchild
))
5928 cont
= foreach_window_1 (XWINDOW (w
->hchild
), fn
, user_data
);
5929 else if (!NILP (w
->vchild
))
5930 cont
= foreach_window_1 (XWINDOW (w
->vchild
), fn
, user_data
);
5932 cont
= fn (w
, user_data
);
5934 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5941 /* Freeze or unfreeze the window start of W unless it is a
5942 mini-window or the selected window. FREEZE_P non-null means freeze
5943 the window start. */
5946 freeze_window_start (w
, freeze_p
)
5950 if (w
== XWINDOW (selected_window
)
5951 || MINI_WINDOW_P (w
)
5952 || (MINI_WINDOW_P (XWINDOW (selected_window
))
5953 && ! NILP (Vminibuf_scroll_window
)
5954 && w
== XWINDOW (Vminibuf_scroll_window
)))
5957 w
->frozen_window_start_p
= freeze_p
!= NULL
;
5962 /* Freeze or unfreeze the window starts of all leaf windows on frame
5963 F, except the selected window and a mini-window. FREEZE_P non-zero
5964 means freeze the window start. */
5967 freeze_window_starts (f
, freeze_p
)
5971 foreach_window (f
, freeze_window_start
, (void *) (freeze_p
? f
: 0));
5975 /***********************************************************************
5977 ***********************************************************************/
5979 /* Return 1 if window configurations C1 and C2
5980 describe the same state of affairs. This is used by Fequal. */
5983 compare_window_configurations (c1
, c2
, ignore_positions
)
5985 int ignore_positions
;
5987 register struct save_window_data
*d1
, *d2
;
5988 struct Lisp_Vector
*sw1
, *sw2
;
5991 if (!WINDOW_CONFIGURATIONP (c1
))
5992 wrong_type_argument (Qwindow_configuration_p
, c1
);
5993 if (!WINDOW_CONFIGURATIONP (c2
))
5994 wrong_type_argument (Qwindow_configuration_p
, c2
);
5996 d1
= (struct save_window_data
*) XVECTOR (c1
);
5997 d2
= (struct save_window_data
*) XVECTOR (c2
);
5998 sw1
= XVECTOR (d1
->saved_windows
);
5999 sw2
= XVECTOR (d2
->saved_windows
);
6001 if (! EQ (d1
->frame_cols
, d2
->frame_cols
))
6003 if (! EQ (d1
->frame_lines
, d2
->frame_lines
))
6005 if (! EQ (d1
->frame_menu_bar_lines
, d2
->frame_menu_bar_lines
))
6007 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
6009 /* Don't compare the current_window field directly.
6010 Instead see w1_is_current and w2_is_current, below. */
6011 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
6013 if (! ignore_positions
)
6015 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
6017 if (! EQ (d1
->minibuf_selected_window
, d2
->minibuf_selected_window
))
6020 /* Don't compare the root_window field.
6021 We don't require the two configurations
6022 to use the same window object,
6023 and the two root windows must be equivalent
6024 if everything else compares equal. */
6025 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
6027 if (! EQ (d1
->min_width
, d2
->min_width
))
6029 if (! EQ (d1
->min_height
, d2
->min_height
))
6032 /* Verify that the two confis have the same number of windows. */
6033 if (sw1
->size
!= sw2
->size
)
6036 for (i
= 0; i
< sw1
->size
; i
++)
6038 struct saved_window
*p1
, *p2
;
6039 int w1_is_current
, w2_is_current
;
6041 p1
= SAVED_WINDOW_N (sw1
, i
);
6042 p2
= SAVED_WINDOW_N (sw2
, i
);
6044 /* Verify that the current windows in the two
6045 configurations correspond to each other. */
6046 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
6047 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
6049 if (w1_is_current
!= w2_is_current
)
6052 /* Verify that the corresponding windows do match. */
6053 if (! EQ (p1
->buffer
, p2
->buffer
))
6055 if (! EQ (p1
->left_col
, p2
->left_col
))
6057 if (! EQ (p1
->top_line
, p2
->top_line
))
6059 if (! EQ (p1
->total_cols
, p2
->total_cols
))
6061 if (! EQ (p1
->total_lines
, p2
->total_lines
))
6063 if (! EQ (p1
->display_table
, p2
->display_table
))
6065 if (! EQ (p1
->parent
, p2
->parent
))
6067 if (! EQ (p1
->prev
, p2
->prev
))
6069 if (! ignore_positions
)
6071 if (! EQ (p1
->hscroll
, p2
->hscroll
))
6073 if (!EQ (p1
->min_hscroll
, p2
->min_hscroll
))
6075 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
6077 if (NILP (Fequal (p1
->start
, p2
->start
)))
6079 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
6081 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
6084 if (! EQ (p1
->left_margin_cols
, p2
->left_margin_cols
))
6086 if (! EQ (p1
->right_margin_cols
, p2
->right_margin_cols
))
6088 if (! EQ (p1
->left_fringe_width
, p2
->left_fringe_width
))
6090 if (! EQ (p1
->right_fringe_width
, p2
->right_fringe_width
))
6092 if (! EQ (p1
->fringes_outside_margins
, p2
->fringes_outside_margins
))
6094 if (! EQ (p1
->scroll_bar_width
, p2
->scroll_bar_width
))
6096 if (! EQ (p1
->vertical_scroll_bar_type
, p2
->vertical_scroll_bar_type
))
6103 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
6104 Scompare_window_configurations
, 2, 2, 0,
6105 doc
: /* Compare two window configurations as regards the structure of windows.
6106 This function ignores details such as the values of point and mark
6107 and scrolling positions. */)
6111 if (compare_window_configurations (x
, y
, 1))
6119 struct frame
*f
= make_terminal_frame ();
6120 XSETFRAME (selected_frame
, f
);
6121 Vterminal_frame
= selected_frame
;
6122 minibuf_window
= f
->minibuffer_window
;
6123 selected_window
= f
->selected_window
;
6124 last_nonminibuf_frame
= f
;
6126 window_initialized
= 1;
6132 Vwindow_list
= Qnil
;
6138 Qwindow_size_fixed
= intern ("window-size-fixed");
6139 staticpro (&Qwindow_size_fixed
);
6141 staticpro (&Qwindow_configuration_change_hook
);
6142 Qwindow_configuration_change_hook
6143 = intern ("window-configuration-change-hook");
6145 Qwindowp
= intern ("windowp");
6146 staticpro (&Qwindowp
);
6148 Qwindow_configuration_p
= intern ("window-configuration-p");
6149 staticpro (&Qwindow_configuration_p
);
6151 Qwindow_live_p
= intern ("window-live-p");
6152 staticpro (&Qwindow_live_p
);
6154 Qtemp_buffer_show_hook
= intern ("temp-buffer-show-hook");
6155 staticpro (&Qtemp_buffer_show_hook
);
6157 staticpro (&Vwindow_list
);
6159 minibuf_selected_window
= Qnil
;
6160 staticpro (&minibuf_selected_window
);
6162 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
6163 doc
: /* Non-nil means call as function to display a help buffer.
6164 The function is called with one argument, the buffer to be displayed.
6165 Used by `with-output-to-temp-buffer'.
6166 If this function is used, then it must do the entire job of showing
6167 the buffer; `temp-buffer-show-hook' is not run unless this function runs it. */);
6168 Vtemp_buffer_show_function
= Qnil
;
6170 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
6171 doc
: /* If non-nil, function to call to handle `display-buffer'.
6172 It will receive two args, the buffer and a flag which if non-nil means
6173 that the currently selected window is not acceptable.
6174 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'
6175 work using this function. */);
6176 Vdisplay_buffer_function
= Qnil
;
6178 DEFVAR_LISP ("even-window-heights", &Veven_window_heights
,
6179 doc
: /* *If non-nil, `display-buffer' should even the window heights.
6180 If nil, `display-buffer' will leave the window configuration alone. */);
6181 Veven_window_heights
= Qt
;
6183 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
6184 doc
: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */);
6185 Vminibuf_scroll_window
= Qnil
;
6187 DEFVAR_BOOL ("mode-line-in-non-selected-windows", &mode_line_in_non_selected_windows
,
6188 doc
: /* Non-nil means to use `mode-line-inactive' face in non-selected windows.
6189 If the minibuffer is active, the `minibuffer-scroll-window' mode line
6190 is displayed in the `mode-line' face. */);
6191 mode_line_in_non_selected_windows
= 1;
6193 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
6194 doc
: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. */);
6195 Vother_window_scroll_buffer
= Qnil
;
6197 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
6198 doc
: /* *Non-nil means `display-buffer' should make a separate frame. */);
6201 DEFVAR_BOOL ("display-buffer-reuse-frames", &display_buffer_reuse_frames
,
6202 doc
: /* *Non-nil means `display-buffer' should reuse frames.
6203 If the buffer in question is already displayed in a frame, raise that frame. */);
6204 display_buffer_reuse_frames
= 0;
6206 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
6207 doc
: /* Function to call to handle automatic new frame creation.
6208 It is called with no arguments and should return a newly created frame.
6210 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'
6211 where `pop-up-frame-alist' would hold the default frame parameters. */);
6212 Vpop_up_frame_function
= Qnil
;
6214 DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names
,
6215 doc
: /* *List of buffer names that should have their own special frames.
6216 Displaying a buffer whose name is in this list makes a special frame for it
6217 using `special-display-function'. See also `special-display-regexps'.
6219 An element of the list can be a list instead of just a string.
6220 There are two ways to use a list as an element:
6221 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)
6222 In the first case, FRAME-PARAMETERS are used to create the frame.
6223 In the latter case, FUNCTION is called with BUFFER as the first argument,
6224 followed by OTHER-ARGS--it can display BUFFER in any way it likes.
6225 All this is done by the function found in `special-display-function'.
6227 If this variable appears \"not to work\", because you add a name to it
6228 but that buffer still appears in the selected window, look at the
6229 values of `same-window-buffer-names' and `same-window-regexps'.
6230 Those variables take precedence over this one. */);
6231 Vspecial_display_buffer_names
= Qnil
;
6233 DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps
,
6234 doc
: /* *List of regexps saying which buffers should have their own special frames.
6235 If a buffer name matches one of these regexps, it gets its own frame.
6236 Displaying a buffer whose name is in this list makes a special frame for it
6237 using `special-display-function'.
6239 An element of the list can be a list instead of just a string.
6240 There are two ways to use a list as an element:
6241 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)
6242 In the first case, FRAME-PARAMETERS are used to create the frame.
6243 In the latter case, FUNCTION is called with the buffer as first argument,
6244 followed by OTHER-ARGS--it can display the buffer in any way it likes.
6245 All this is done by the function found in `special-display-function'.
6247 If this variable appears \"not to work\", because you add a regexp to it
6248 but the matching buffers still appear in the selected window, look at the
6249 values of `same-window-buffer-names' and `same-window-regexps'.
6250 Those variables take precedence over this one. */);
6251 Vspecial_display_regexps
= Qnil
;
6253 DEFVAR_LISP ("special-display-function", &Vspecial_display_function
,
6254 doc
: /* Function to call to make a new frame for a special buffer.
6255 It is called with two arguments, the buffer and optional buffer specific
6256 data, and should return a window displaying that buffer.
6257 The default value normally makes a separate frame for the buffer,
6258 using `special-display-frame-alist' to specify the frame parameters.
6259 But if the buffer specific data includes (same-buffer . t) then the
6260 buffer is displayed in the current selected window.
6261 Otherwise if it includes (same-frame . t) then the buffer is displayed in
6262 a new window in the currently selected frame.
6264 A buffer is special if it is listed in `special-display-buffer-names'
6265 or matches a regexp in `special-display-regexps'. */);
6266 Vspecial_display_function
= Qnil
;
6268 DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names
,
6269 doc
: /* *List of buffer names that should appear in the selected window.
6270 Displaying one of these buffers using `display-buffer' or `pop-to-buffer'
6271 switches to it in the selected window, rather than making it appear
6272 in some other window.
6274 An element of the list can be a cons cell instead of just a string.
6275 Then the car must be a string, which specifies the buffer name.
6276 This is for compatibility with `special-display-buffer-names';
6277 the cdr of the cons cell is ignored.
6279 See also `same-window-regexps'. */);
6280 Vsame_window_buffer_names
= Qnil
;
6282 DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps
,
6283 doc
: /* *List of regexps saying which buffers should appear in the selected window.
6284 If a buffer name matches one of these regexps, then displaying it
6285 using `display-buffer' or `pop-to-buffer' switches to it
6286 in the selected window, rather than making it appear in some other window.
6288 An element of the list can be a cons cell instead of just a string.
6289 Then the car must be a string, which specifies the buffer name.
6290 This is for compatibility with `special-display-buffer-names';
6291 the cdr of the cons cell is ignored.
6293 See also `same-window-buffer-names'. */);
6294 Vsame_window_regexps
= Qnil
;
6296 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
6297 doc
: /* *Non-nil means display-buffer should make new windows. */);
6300 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
6301 doc
: /* *Number of lines of continuity when scrolling by screenfuls. */);
6302 next_screen_context_lines
= 2;
6304 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
6305 doc
: /* *display-buffer would prefer to split the largest window if this large.
6306 If there is only one window, it is split regardless of this value. */);
6307 split_height_threshold
= 500;
6309 DEFVAR_INT ("window-min-height", &window_min_height
,
6310 doc
: /* *Delete any window less than this tall (including its mode line). */);
6311 window_min_height
= 4;
6313 DEFVAR_INT ("window-min-width", &window_min_width
,
6314 doc
: /* *Delete any window less than this wide. */);
6315 window_min_width
= 10;
6317 DEFVAR_LISP ("scroll-preserve-screen-position",
6318 &Vscroll_preserve_screen_position
,
6319 doc
: /* *Non-nil means scroll commands move point to keep its screen line unchanged. */);
6320 Vscroll_preserve_screen_position
= Qnil
;
6322 DEFVAR_LISP ("window-configuration-change-hook",
6323 &Vwindow_configuration_change_hook
,
6324 doc
: /* Functions to call when window configuration changes.
6325 The selected frame is the one whose configuration has changed. */);
6326 Vwindow_configuration_change_hook
= Qnil
;
6328 DEFVAR_BOOL ("window-size-fixed", &window_size_fixed
,
6329 doc
: /* Non-nil in a buffer means windows displaying the buffer are fixed-size.
6330 Emacs won't change the size of any window displaying that buffer,
6331 unless you explicitly change the size, or Emacs has no other choice.
6332 This variable automatically becomes buffer-local when set. */);
6333 Fmake_variable_buffer_local (Qwindow_size_fixed
);
6334 window_size_fixed
= 0;
6336 defsubr (&Sselected_window
);
6337 defsubr (&Sminibuffer_window
);
6338 defsubr (&Swindow_minibuffer_p
);
6339 defsubr (&Swindowp
);
6340 defsubr (&Swindow_live_p
);
6341 defsubr (&Spos_visible_in_window_p
);
6342 defsubr (&Swindow_buffer
);
6343 defsubr (&Swindow_height
);
6344 defsubr (&Swindow_width
);
6345 defsubr (&Swindow_hscroll
);
6346 defsubr (&Sset_window_hscroll
);
6347 defsubr (&Swindow_redisplay_end_trigger
);
6348 defsubr (&Sset_window_redisplay_end_trigger
);
6349 defsubr (&Swindow_edges
);
6350 defsubr (&Scoordinates_in_window_p
);
6351 defsubr (&Swindow_at
);
6352 defsubr (&Swindow_point
);
6353 defsubr (&Swindow_start
);
6354 defsubr (&Swindow_end
);
6355 defsubr (&Sset_window_point
);
6356 defsubr (&Sset_window_start
);
6357 defsubr (&Swindow_dedicated_p
);
6358 defsubr (&Sset_window_dedicated_p
);
6359 defsubr (&Swindow_display_table
);
6360 defsubr (&Sset_window_display_table
);
6361 defsubr (&Snext_window
);
6362 defsubr (&Sprevious_window
);
6363 defsubr (&Sother_window
);
6364 defsubr (&Sget_lru_window
);
6365 defsubr (&Sget_largest_window
);
6366 defsubr (&Sget_buffer_window
);
6367 defsubr (&Sdelete_other_windows
);
6368 defsubr (&Sdelete_windows_on
);
6369 defsubr (&Sreplace_buffer_in_windows
);
6370 defsubr (&Sdelete_window
);
6371 defsubr (&Sset_window_buffer
);
6372 defsubr (&Sselect_window
);
6373 defsubr (&Sspecial_display_p
);
6374 defsubr (&Ssame_window_p
);
6375 defsubr (&Sdisplay_buffer
);
6376 defsubr (&Ssplit_window
);
6377 defsubr (&Senlarge_window
);
6378 defsubr (&Sshrink_window
);
6379 defsubr (&Sscroll_up
);
6380 defsubr (&Sscroll_down
);
6381 defsubr (&Sscroll_left
);
6382 defsubr (&Sscroll_right
);
6383 defsubr (&Sother_window_for_scrolling
);
6384 defsubr (&Sscroll_other_window
);
6385 defsubr (&Sminibuffer_selected_window
);
6386 defsubr (&Srecenter
);
6387 defsubr (&Swindow_text_height
);
6388 defsubr (&Smove_to_window_line
);
6389 defsubr (&Swindow_configuration_p
);
6390 defsubr (&Swindow_configuration_frame
);
6391 defsubr (&Sset_window_configuration
);
6392 defsubr (&Scurrent_window_configuration
);
6393 defsubr (&Ssave_window_excursion
);
6394 defsubr (&Sset_window_margins
);
6395 defsubr (&Swindow_margins
);
6396 defsubr (&Sset_window_fringes
);
6397 defsubr (&Swindow_fringes
);
6398 defsubr (&Sset_window_scroll_bars
);
6399 defsubr (&Swindow_scroll_bars
);
6400 defsubr (&Swindow_vscroll
);
6401 defsubr (&Sset_window_vscroll
);
6402 defsubr (&Scompare_window_configurations
);
6403 defsubr (&Swindow_list
);
6409 initial_define_key (control_x_map
, '1', "delete-other-windows");
6410 initial_define_key (control_x_map
, '2', "split-window");
6411 initial_define_key (control_x_map
, '0', "delete-window");
6412 initial_define_key (control_x_map
, 'o', "other-window");
6413 initial_define_key (control_x_map
, '^', "enlarge-window");
6414 initial_define_key (control_x_map
, '<', "scroll-left");
6415 initial_define_key (control_x_map
, '>', "scroll-right");
6417 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
6418 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
6419 initial_define_key (meta_map
, 'v', "scroll-down");
6421 initial_define_key (global_map
, Ctl('L'), "recenter");
6422 initial_define_key (meta_map
, 'r', "move-to-window-line");