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
)
2711 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
2712 means it's allowed to run hooks. See make_frame for a case where
2713 it's not allowed. KEEP_MARGINS_P non-zero means that the current
2714 margins, fringes, and scroll-bar settings of the window are not
2715 reset from the buffer's local settings. */
2718 set_window_buffer (window
, buffer
, run_hooks_p
, keep_margins_p
)
2719 Lisp_Object window
, buffer
;
2720 int run_hooks_p
, keep_margins_p
;
2722 struct window
*w
= XWINDOW (window
);
2723 struct buffer
*b
= XBUFFER (buffer
);
2724 int count
= SPECPDL_INDEX ();
2728 if (EQ (window
, selected_window
))
2729 b
->last_selected_window
= window
;
2731 /* Update time stamps of buffer display. */
2732 if (INTEGERP (b
->display_count
))
2733 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
2734 b
->display_time
= Fcurrent_time ();
2736 XSETFASTINT (w
->window_end_pos
, 0);
2737 XSETFASTINT (w
->window_end_vpos
, 0);
2738 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
2739 w
->window_end_valid
= Qnil
;
2740 w
->hscroll
= w
->min_hscroll
= make_number (0);
2742 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
2743 set_marker_restricted (w
->start
,
2744 make_number (b
->last_window_start
),
2746 w
->start_at_line_beg
= Qnil
;
2747 w
->force_start
= Qnil
;
2748 XSETFASTINT (w
->last_modified
, 0);
2749 XSETFASTINT (w
->last_overlay_modified
, 0);
2750 windows_or_buffers_changed
++;
2752 /* We must select BUFFER for running the window-scroll-functions.
2753 If WINDOW is selected, switch permanently.
2754 Otherwise, switch but go back to the ambient buffer afterward. */
2755 if (EQ (window
, selected_window
))
2756 Fset_buffer (buffer
);
2757 /* We can't check ! NILP (Vwindow_scroll_functions) here
2758 because that might itself be a local variable. */
2759 else if (window_initialized
)
2761 record_unwind_protect (Fset_window_buffer_unwind
, Fcurrent_buffer ());
2762 Fset_buffer (buffer
);
2765 if (!keep_margins_p
)
2767 /* Set left and right marginal area width etc. from buffer. */
2769 /* This may call adjust_window_margins three times, so
2770 temporarily disable window margins. */
2771 w
->left_margin_cols
= w
->right_margin_cols
= Qnil
;
2773 Fset_window_fringes (window
,
2774 b
->left_fringe_width
, b
->right_fringe_width
,
2775 b
->fringes_outside_margins
);
2777 Fset_window_scroll_bars (window
,
2778 b
->scroll_bar_width
,
2779 b
->vertical_scroll_bar_type
, Qnil
);
2781 Fset_window_margins (window
,
2782 b
->left_margin_cols
, b
->right_margin_cols
);
2787 if (! NILP (Vwindow_scroll_functions
))
2788 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2789 Fmarker_position (w
->start
));
2791 if (! NILP (Vwindow_configuration_change_hook
)
2792 && ! NILP (Vrun_hooks
))
2793 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
2796 unbind_to (count
, Qnil
);
2800 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 3, 0,
2801 doc
: /* Make WINDOW display BUFFER as its contents.
2802 BUFFER can be a buffer or buffer name.
2803 Optional third arg KEEP_MARGINS non-nil means that WINDOW's current
2804 display margins, fringe widths, and scroll bar settings are maintained;
2805 the default is to reset these from BUFFER's local settings or the frame
2807 (window
, buffer
, keep_margins
)
2808 register Lisp_Object window
, buffer
;
2810 register Lisp_Object tem
;
2811 register struct window
*w
= decode_window (window
);
2813 XSETWINDOW (window
, w
);
2814 buffer
= Fget_buffer (buffer
);
2815 CHECK_BUFFER (buffer
);
2817 if (NILP (XBUFFER (buffer
)->name
))
2818 error ("Attempt to display deleted buffer");
2822 error ("Window is deleted");
2823 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
2824 is first being set up. */
2826 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
2827 error ("Window is dedicated to `%s'",
2828 SDATA (XBUFFER (tem
)->name
));
2833 set_window_buffer (window
, buffer
, 1, !NILP (keep_margins
));
2837 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 2, 0,
2838 doc
: /* Select WINDOW. Most editing will apply to WINDOW's buffer.
2839 If WINDOW is not already selected, also make WINDOW's buffer current.
2840 Also make WINDOW the frame's selected window.
2841 Optional second arg NORECORD non-nil means
2842 do not put this buffer at the front of the list of recently selected ones.
2844 Note that the main editor command loop
2845 selects the buffer of the selected window before each command. */)
2847 register Lisp_Object window
, norecord
;
2849 register struct window
*w
;
2850 register struct window
*ow
;
2853 CHECK_LIVE_WINDOW (window
);
2855 w
= XWINDOW (window
);
2856 w
->frozen_window_start_p
= 0;
2858 XSETFASTINT (w
->use_time
, ++window_select_count
);
2859 if (EQ (window
, selected_window
))
2862 if (!NILP (selected_window
))
2864 ow
= XWINDOW (selected_window
);
2865 if (! NILP (ow
->buffer
))
2866 set_marker_both (ow
->pointm
, ow
->buffer
,
2867 BUF_PT (XBUFFER (ow
->buffer
)),
2868 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
2871 selected_window
= window
;
2872 sf
= SELECTED_FRAME ();
2873 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
2875 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
2876 /* Use this rather than Fhandle_switch_frame
2877 so that FRAME_FOCUS_FRAME is moved appropriately as we
2878 move around in the state where a minibuffer in a separate
2880 Fselect_frame (WINDOW_FRAME (w
), Qnil
);
2883 sf
->selected_window
= window
;
2885 if (NILP (norecord
))
2886 record_buffer (w
->buffer
);
2887 Fset_buffer (w
->buffer
);
2889 XBUFFER (w
->buffer
)->last_selected_window
= window
;
2891 /* Go to the point recorded in the window.
2892 This is important when the buffer is in more
2893 than one window. It also matters when
2894 redisplay_window has altered point after scrolling,
2895 because it makes the change only in the window. */
2897 register int new_point
= marker_position (w
->pointm
);
2898 if (new_point
< BEGV
)
2900 else if (new_point
> ZV
)
2906 windows_or_buffers_changed
++;
2911 select_window_norecord (window
)
2914 return Fselect_window (window
, Qt
);
2917 /* Deiconify the frame containing the window WINDOW,
2918 unless it is the selected frame;
2921 The reason for the exception for the selected frame
2922 is that it seems better not to change the selected frames visibility
2923 merely because of displaying a different buffer in it.
2924 The deiconification is useful when a buffer gets shown in
2925 another frame that you were not using lately. */
2928 display_buffer_1 (window
)
2931 Lisp_Object frame
= XWINDOW (window
)->frame
;
2932 FRAME_PTR f
= XFRAME (frame
);
2934 FRAME_SAMPLE_VISIBILITY (f
);
2936 if (!EQ (frame
, selected_frame
))
2938 if (FRAME_ICONIFIED_P (f
))
2939 Fmake_frame_visible (frame
);
2940 else if (FRAME_VISIBLE_P (f
))
2941 Fraise_frame (frame
);
2947 DEFUN ("special-display-p", Fspecial_display_p
, Sspecial_display_p
, 1, 1, 0,
2948 doc
: /* Returns non-nil if a buffer named BUFFER-NAME would be created specially.
2949 The value is actually t if the frame should be called with default frame
2950 parameters, and a list of frame parameters if they were specified.
2951 See `special-display-buffer-names', and `special-display-regexps'. */)
2953 Lisp_Object buffer_name
;
2957 CHECK_STRING (buffer_name
);
2959 tem
= Fmember (buffer_name
, Vspecial_display_buffer_names
);
2963 tem
= Fassoc (buffer_name
, Vspecial_display_buffer_names
);
2967 for (tem
= Vspecial_display_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2969 Lisp_Object car
= XCAR (tem
);
2971 && fast_string_match (car
, buffer_name
) >= 0)
2973 else if (CONSP (car
)
2974 && STRINGP (XCAR (car
))
2975 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2981 DEFUN ("same-window-p", Fsame_window_p
, Ssame_window_p
, 1, 1, 0,
2982 doc
: /* Returns non-nil if a new buffer named BUFFER-NAME would use the same window.
2983 See `same-window-buffer-names' and `same-window-regexps'. */)
2985 Lisp_Object buffer_name
;
2989 CHECK_STRING (buffer_name
);
2991 tem
= Fmember (buffer_name
, Vsame_window_buffer_names
);
2995 tem
= Fassoc (buffer_name
, Vsame_window_buffer_names
);
2999 for (tem
= Vsame_window_regexps
; CONSP (tem
); tem
= XCDR (tem
))
3001 Lisp_Object car
= XCAR (tem
);
3003 && fast_string_match (car
, buffer_name
) >= 0)
3005 else if (CONSP (car
)
3006 && STRINGP (XCAR (car
))
3007 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
3013 /* Use B so the default is (other-buffer). */
3014 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 3,
3015 "BDisplay buffer: \nP",
3016 doc
: /* Make BUFFER appear in some window but don't select it.
3017 BUFFER can be a buffer or a buffer name.
3018 If BUFFER is shown already in some window, just use that one,
3019 unless the window is the selected window and the optional second
3020 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).
3021 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.
3022 Returns the window displaying BUFFER.
3023 If `display-buffer-reuse-frames' is non-nil, and another frame is currently
3024 displaying BUFFER, then simply raise that frame.
3026 The variables `special-display-buffer-names', `special-display-regexps',
3027 `same-window-buffer-names', and `same-window-regexps' customize how certain
3028 buffer names are handled.
3030 If optional argument FRAME is `visible', search all visible frames.
3031 If FRAME is 0, search all visible and iconified frames.
3032 If FRAME is t, search all frames.
3033 If FRAME is a frame, search only that frame.
3034 If FRAME is nil, search only the selected frame
3035 (actually the last nonminibuffer frame),
3036 unless `pop-up-frames' or `display-buffer-reuse-frames' is non-nil,
3037 which means search visible and iconified frames.
3039 If `even-window-heights' is non-nil, window heights will be evened out
3040 if displaying the buffer causes two vertically adjacent windows to be
3042 (buffer
, not_this_window
, frame
)
3043 register Lisp_Object buffer
, not_this_window
, frame
;
3045 register Lisp_Object window
, tem
, swp
;
3049 buffer
= Fget_buffer (buffer
);
3050 CHECK_BUFFER (buffer
);
3052 if (!NILP (Vdisplay_buffer_function
))
3053 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
3055 if (NILP (not_this_window
)
3056 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
3057 return display_buffer_1 (selected_window
);
3059 /* See if the user has specified this buffer should appear
3060 in the selected window. */
3061 if (NILP (not_this_window
))
3063 swp
= Fsame_window_p (XBUFFER (buffer
)->name
);
3064 if (!NILP (swp
) && !no_switch_window (selected_window
))
3066 Fswitch_to_buffer (buffer
, Qnil
);
3067 return display_buffer_1 (selected_window
);
3071 /* If the user wants pop-up-frames or display-buffer-reuse-frames,
3072 look for a window showing BUFFER on any visible or iconified frame.
3073 Otherwise search only the current frame. */
3076 else if (pop_up_frames
3077 || display_buffer_reuse_frames
3078 || last_nonminibuf_frame
== 0)
3079 XSETFASTINT (tem
, 0);
3081 XSETFRAME (tem
, last_nonminibuf_frame
);
3083 window
= Fget_buffer_window (buffer
, tem
);
3085 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
3086 return display_buffer_1 (window
);
3088 /* Certain buffer names get special handling. */
3089 if (!NILP (Vspecial_display_function
) && NILP (swp
))
3091 tem
= Fspecial_display_p (XBUFFER (buffer
)->name
);
3093 return call1 (Vspecial_display_function
, buffer
);
3095 return call2 (Vspecial_display_function
, buffer
, tem
);
3098 /* If there are no frames open that have more than a minibuffer,
3099 we need to create a new frame. */
3100 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
3102 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
3103 Fset_window_buffer (window
, buffer
, Qnil
);
3104 return display_buffer_1 (window
);
3107 f
= SELECTED_FRAME ();
3109 || FRAME_MINIBUF_ONLY_P (f
)
3110 /* If the current frame is a special display frame,
3111 don't try to reuse its windows. */
3112 || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f
))->dedicated
))
3117 if (FRAME_MINIBUF_ONLY_P (f
))
3118 XSETFRAME (frames
, last_nonminibuf_frame
);
3119 /* Don't try to create a window if we would get an error. */
3120 if (split_height_threshold
< window_min_height
<< 1)
3121 split_height_threshold
= window_min_height
<< 1;
3123 /* Note that both Fget_largest_window and Fget_lru_window
3124 ignore minibuffers and dedicated windows.
3125 This means they can return nil. */
3127 /* If the frame we would try to split cannot be split,
3128 try other frames. */
3129 if (FRAME_NO_SPLIT_P (NILP (frames
) ? f
: last_nonminibuf_frame
))
3131 /* Try visible frames first. */
3132 window
= Fget_largest_window (Qvisible
);
3133 /* If that didn't work, try iconified frames. */
3135 window
= Fget_largest_window (make_number (0));
3137 window
= Fget_largest_window (Qt
);
3140 window
= Fget_largest_window (frames
);
3142 /* If we got a tall enough full-width window that can be split,
3145 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
3146 && window_height (window
) >= split_height_threshold
3147 && WINDOW_FULL_WIDTH_P (XWINDOW (window
)))
3148 window
= Fsplit_window (window
, Qnil
, Qnil
);
3151 Lisp_Object upper
, lower
, other
;
3153 window
= Fget_lru_window (frames
);
3154 /* If the LRU window is selected, and big enough,
3155 and can be split, split it. */
3157 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
3158 && (EQ (window
, selected_window
)
3159 || EQ (XWINDOW (window
)->parent
, Qnil
))
3160 && window_height (window
) >= window_min_height
<< 1)
3161 window
= Fsplit_window (window
, Qnil
, Qnil
);
3162 /* If Fget_lru_window returned nil, try other approaches. */
3164 /* Try visible frames first. */
3166 window
= Fget_buffer_window (buffer
, Qvisible
);
3168 window
= Fget_largest_window (Qvisible
);
3169 /* If that didn't work, try iconified frames. */
3171 window
= Fget_buffer_window (buffer
, make_number (0));
3173 window
= Fget_largest_window (make_number (0));
3174 /* Try invisible frames. */
3176 window
= Fget_buffer_window (buffer
, Qt
);
3178 window
= Fget_largest_window (Qt
);
3179 /* As a last resort, make a new frame. */
3181 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
3182 /* If window appears above or below another,
3183 even out their heights. */
3184 other
= upper
= lower
= Qnil
;
3185 if (!NILP (XWINDOW (window
)->prev
))
3186 other
= upper
= XWINDOW (window
)->prev
, lower
= window
;
3187 if (!NILP (XWINDOW (window
)->next
))
3188 other
= lower
= XWINDOW (window
)->next
, upper
= window
;
3190 && !NILP (Veven_window_heights
)
3191 /* Check that OTHER and WINDOW are vertically arrayed. */
3192 && !EQ (XWINDOW (other
)->top_line
, XWINDOW (window
)->top_line
)
3193 && (XFASTINT (XWINDOW (other
)->total_lines
)
3194 > XFASTINT (XWINDOW (window
)->total_lines
)))
3196 int total
= (XFASTINT (XWINDOW (other
)->total_lines
)
3197 + XFASTINT (XWINDOW (window
)->total_lines
));
3198 enlarge_window (upper
,
3199 total
/ 2 - XFASTINT (XWINDOW (upper
)->total_lines
),
3205 window
= Fget_lru_window (Qnil
);
3207 Fset_window_buffer (window
, buffer
, Qnil
);
3208 return display_buffer_1 (window
);
3212 temp_output_buffer_show (buf
)
3213 register Lisp_Object buf
;
3215 register struct buffer
*old
= current_buffer
;
3216 register Lisp_Object window
;
3217 register struct window
*w
;
3219 XBUFFER (buf
)->directory
= current_buffer
->directory
;
3222 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
3226 #if 0 /* rms: there should be no reason for this. */
3227 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
3229 set_buffer_internal (old
);
3231 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
3232 call1 (Vtemp_buffer_show_function
, buf
);
3235 window
= Fdisplay_buffer (buf
, Qnil
, Qnil
);
3237 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
3238 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
3239 Vminibuf_scroll_window
= window
;
3240 w
= XWINDOW (window
);
3241 XSETFASTINT (w
->hscroll
, 0);
3242 XSETFASTINT (w
->min_hscroll
, 0);
3243 set_marker_restricted_both (w
->start
, buf
, 1, 1);
3244 set_marker_restricted_both (w
->pointm
, buf
, 1, 1);
3246 /* Run temp-buffer-show-hook, with the chosen window selected
3247 and its buffer current. */
3248 if (!NILP (Vrun_hooks
))
3251 tem
= Fboundp (Qtemp_buffer_show_hook
);
3254 tem
= Fsymbol_value (Qtemp_buffer_show_hook
);
3257 int count
= SPECPDL_INDEX ();
3258 Lisp_Object prev_window
, prev_buffer
;
3259 prev_window
= selected_window
;
3260 XSETBUFFER (prev_buffer
, old
);
3262 /* Select the window that was chosen, for running the hook.
3263 Note: Both Fselect_window and select_window_norecord may
3264 set-buffer to the buffer displayed in the window,
3265 so we need to save the current buffer. --stef */
3266 record_unwind_protect (Fset_buffer
, prev_buffer
);
3267 record_unwind_protect (select_window_norecord
, prev_window
);
3268 Fselect_window (window
, Qt
);
3269 Fset_buffer (w
->buffer
);
3270 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
3271 unbind_to (count
, Qnil
);
3279 make_dummy_parent (window
)
3283 register struct window
*o
, *p
;
3286 o
= XWINDOW (window
);
3287 p
= allocate_window ();
3288 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
3289 ((struct Lisp_Vector
*) p
)->contents
[i
]
3290 = ((struct Lisp_Vector
*)o
)->contents
[i
];
3291 XSETWINDOW (new, p
);
3293 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
3295 /* Put new into window structure in place of window */
3296 replace_window (window
, new);
3309 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
3310 doc
: /* Split WINDOW, putting SIZE lines in the first of the pair.
3311 WINDOW defaults to selected one and SIZE to half its size.
3312 If optional third arg HORFLAG is non-nil, split side by side
3313 and put SIZE columns in the first of the pair. In that case,
3314 SIZE includes that window's scroll bar, or the divider column to its right. */)
3315 (window
, size
, horflag
)
3316 Lisp_Object window
, size
, horflag
;
3318 register Lisp_Object
new;
3319 register struct window
*o
, *p
;
3321 register int size_int
;
3324 window
= selected_window
;
3326 CHECK_LIVE_WINDOW (window
);
3328 o
= XWINDOW (window
);
3329 fo
= XFRAME (WINDOW_FRAME (o
));
3333 if (!NILP (horflag
))
3334 /* Calculate the size of the left-hand window, by dividing
3335 the usable space in columns by two.
3336 We round up, since the left-hand window may include
3337 a dividing line, while the right-hand may not. */
3338 size_int
= (XFASTINT (o
->total_cols
) + 1) >> 1;
3340 size_int
= XFASTINT (o
->total_lines
) >> 1;
3344 CHECK_NUMBER (size
);
3345 size_int
= XINT (size
);
3348 if (MINI_WINDOW_P (o
))
3349 error ("Attempt to split minibuffer window");
3350 else if (window_fixed_size_p (o
, !NILP (horflag
), 0))
3351 error ("Attempt to split fixed-size window");
3353 check_min_window_sizes ();
3357 if (size_int
< window_min_height
)
3358 error ("Window height %d too small (after splitting)", size_int
);
3359 if (size_int
+ window_min_height
> XFASTINT (o
->total_lines
))
3360 error ("Window height %d too small (after splitting)",
3361 XFASTINT (o
->total_lines
) - size_int
);
3362 if (NILP (o
->parent
)
3363 || NILP (XWINDOW (o
->parent
)->vchild
))
3365 make_dummy_parent (window
);
3367 XWINDOW (new)->vchild
= window
;
3372 if (size_int
< window_min_width
)
3373 error ("Window width %d too small (after splitting)", size_int
);
3375 if (size_int
+ window_min_width
> XFASTINT (o
->total_cols
))
3376 error ("Window width %d too small (after splitting)",
3377 XFASTINT (o
->total_cols
) - size_int
);
3378 if (NILP (o
->parent
)
3379 || NILP (XWINDOW (o
->parent
)->hchild
))
3381 make_dummy_parent (window
);
3383 XWINDOW (new)->hchild
= window
;
3387 /* Now we know that window's parent is a vertical combination
3388 if we are dividing vertically, or a horizontal combination
3389 if we are making side-by-side windows */
3391 windows_or_buffers_changed
++;
3392 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
3393 new = make_window ();
3396 p
->frame
= o
->frame
;
3398 if (!NILP (p
->next
))
3399 XWINDOW (p
->next
)->prev
= new;
3402 p
->parent
= o
->parent
;
3404 p
->window_end_valid
= Qnil
;
3405 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
3407 /* Duplicate special geometry settings. */
3409 p
->left_margin_cols
= o
->left_margin_cols
;
3410 p
->right_margin_cols
= o
->right_margin_cols
;
3411 p
->left_fringe_width
= o
->left_fringe_width
;
3412 p
->right_fringe_width
= o
->right_fringe_width
;
3413 p
->fringes_outside_margins
= o
->fringes_outside_margins
;
3414 p
->scroll_bar_width
= o
->scroll_bar_width
;
3415 p
->vertical_scroll_bar_type
= o
->vertical_scroll_bar_type
;
3417 /* Apportion the available frame space among the two new windows */
3419 if (!NILP (horflag
))
3421 p
->total_lines
= o
->total_lines
;
3422 p
->top_line
= o
->top_line
;
3423 XSETFASTINT (p
->total_cols
, XFASTINT (o
->total_cols
) - size_int
);
3424 XSETFASTINT (o
->total_cols
, size_int
);
3425 XSETFASTINT (p
->left_col
, XFASTINT (o
->left_col
) + size_int
);
3426 adjust_window_margins (p
);
3427 adjust_window_margins (o
);
3431 p
->left_col
= o
->left_col
;
3432 p
->total_cols
= o
->total_cols
;
3433 XSETFASTINT (p
->total_lines
, XFASTINT (o
->total_lines
) - size_int
);
3434 XSETFASTINT (o
->total_lines
, size_int
);
3435 XSETFASTINT (p
->top_line
, XFASTINT (o
->top_line
) + size_int
);
3438 /* Adjust glyph matrices. */
3441 Fset_window_buffer (new, o
->buffer
, Qt
);
3445 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 3, "p",
3446 doc
: /* Make current window ARG lines bigger.
3447 From program, optional second arg non-nil means grow sideways ARG columns.
3448 Interactively, if an argument is not given, make the window one line bigger.
3450 Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size
3451 of the siblings above or to the left of the selected window. Only
3452 siblings to the right or below are changed. */)
3453 (arg
, side
, preserve_before
)
3454 register Lisp_Object arg
, side
, preserve_before
;
3457 enlarge_window (selected_window
, XINT (arg
), !NILP (side
),
3458 !NILP (preserve_before
));
3460 if (! NILP (Vwindow_configuration_change_hook
))
3461 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3466 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 3, "p",
3467 doc
: /* Make current window ARG lines smaller.
3468 From program, optional second arg non-nil means shrink sideways arg columns.
3469 Interactively, if an argument is not given, make the window one line smaller.
3471 Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size
3472 of the siblings above or to the left of the selected window. Only
3473 siblings to the right or below are changed. */)
3474 (arg
, side
, preserve_before
)
3475 register Lisp_Object arg
, side
, preserve_before
;
3478 enlarge_window (selected_window
, -XINT (arg
), !NILP (side
),
3479 !NILP (preserve_before
));
3481 if (! NILP (Vwindow_configuration_change_hook
))
3482 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3488 window_height (window
)
3491 register struct window
*p
= XWINDOW (window
);
3492 return WINDOW_TOTAL_LINES (p
);
3496 window_width (window
)
3499 register struct window
*p
= XWINDOW (window
);
3500 return WINDOW_TOTAL_COLS (p
);
3505 *(widthflag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
3507 #define CURSIZE(w) \
3508 *(widthflag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
3511 /* Enlarge WINDOW by DELTA. WIDTHFLAG non-zero means
3512 increase its width. Siblings of the selected window are resized to
3513 fulfill the size request. If they become too small in the process,
3514 they will be deleted.
3516 If PRESERVE_BEFORE is nonzero, that means don't alter
3517 the siblings to the left or above WINDOW. */
3520 enlarge_window (window
, delta
, widthflag
, preserve_before
)
3522 int delta
, widthflag
, preserve_before
;
3524 Lisp_Object parent
, next
, prev
;
3528 int (*sizefun
) P_ ((Lisp_Object
))
3529 = widthflag
? window_width
: window_height
;
3530 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
3531 = (widthflag
? set_window_width
: set_window_height
);
3533 /* Check values of window_min_width and window_min_height for
3535 check_min_window_sizes ();
3537 /* Give up if this window cannot be resized. */
3538 if (window_fixed_size_p (XWINDOW (window
), widthflag
, 1))
3539 error ("Window is not resizable");
3541 /* Find the parent of the selected window. */
3544 p
= XWINDOW (window
);
3550 error ("No other window to side of this one");
3555 ? !NILP (XWINDOW (parent
)->hchild
)
3556 : !NILP (XWINDOW (parent
)->vchild
))
3562 sizep
= &CURSIZE (window
);
3565 register int maxdelta
;
3567 /* Compute the maximum size increment this window can have. */
3569 if (preserve_before
)
3573 maxdelta
= (*sizefun
) (parent
) - XINT (*sizep
);
3574 /* Subtract size of siblings before, since we can't take that. */
3575 maxdelta
-= XINT (CURBEG (window
)) - XINT (CURBEG (parent
));
3578 maxdelta
= (!NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3579 - window_min_size (XWINDOW (p
->next
),
3584 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - XINT (*sizep
)
3585 /* This is a main window followed by a minibuffer. */
3586 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3587 - window_min_size (XWINDOW (p
->next
),
3589 /* This is a minibuffer following a main window. */
3590 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
3591 - window_min_size (XWINDOW (p
->prev
),
3593 /* This is a frame with only one window, a minibuffer-only
3594 or a minibufferless frame. */
3597 if (delta
> maxdelta
)
3598 /* This case traps trying to make the minibuffer
3599 the full frame, or make the only window aside from the
3600 minibuffer the full frame. */
3604 if (XINT (*sizep
) + delta
< window_min_size (XWINDOW (window
), widthflag
, 0, 0))
3606 delete_window (window
);
3613 /* Find the total we can get from other siblings without deleting them. */
3615 for (next
= p
->next
; ! NILP (next
); next
= XWINDOW (next
)->next
)
3616 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
3618 if (! preserve_before
)
3619 for (prev
= p
->prev
; ! NILP (prev
); prev
= XWINDOW (prev
)->prev
)
3620 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
3623 /* If we can get it all from them without deleting them, do so. */
3624 if (delta
<= maximum
)
3626 Lisp_Object first_unaffected
;
3627 Lisp_Object first_affected
;
3632 first_affected
= window
;
3633 /* Look at one sibling at a time,
3634 moving away from this window in both directions alternately,
3635 and take as much as we can get without deleting that sibling. */
3637 && (!NILP (next
) || (!preserve_before
&& !NILP (prev
))))
3641 int this_one
= ((*sizefun
) (next
)
3642 - window_min_size (XWINDOW (next
),
3643 widthflag
, 0, &fixed_p
));
3646 if (this_one
> delta
)
3649 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
3650 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3655 next
= XWINDOW (next
)->next
;
3661 if (!preserve_before
&& ! NILP (prev
))
3663 int this_one
= ((*sizefun
) (prev
)
3664 - window_min_size (XWINDOW (prev
),
3665 widthflag
, 0, &fixed_p
));
3668 if (this_one
> delta
)
3671 first_affected
= prev
;
3673 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
3674 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3679 prev
= XWINDOW (prev
)->prev
;
3683 xassert (delta
== 0);
3685 /* Now recalculate the edge positions of all the windows affected,
3686 based on the new sizes. */
3687 first_unaffected
= next
;
3688 prev
= first_affected
;
3689 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
3690 prev
= next
, next
= XWINDOW (next
)->next
)
3692 XSETINT (CURBEG (next
), XINT (CURBEG (prev
)) + (*sizefun
) (prev
));
3693 /* This does not change size of NEXT,
3694 but it propagates the new top edge to its children */
3695 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
3700 register int delta1
;
3701 register int opht
= (*sizefun
) (parent
);
3703 if (opht
<= XINT (*sizep
) + delta
)
3705 /* If trying to grow this window to or beyond size of the parent,
3706 just delete all the sibling windows. */
3707 Lisp_Object start
, tem
, next
;
3709 start
= XWINDOW (parent
)->vchild
;
3711 start
= XWINDOW (parent
)->hchild
;
3713 /* Delete any siblings that come after WINDOW. */
3714 tem
= XWINDOW (window
)->next
;
3715 while (! NILP (tem
))
3717 next
= XWINDOW (tem
)->next
;
3718 delete_window (tem
);
3722 /* Delete any siblings that come after WINDOW.
3723 Note that if START is not WINDOW, then WINDOW still
3724 Fhas siblings, so WINDOW has not yet replaced its parent. */
3726 while (! EQ (tem
, window
))
3728 next
= XWINDOW (tem
)->next
;
3729 delete_window (tem
);
3735 /* Otherwise, make delta1 just right so that if we add
3736 delta1 lines to this window and to the parent, and then
3737 shrink the parent back to its original size, the new
3738 proportional size of this window will increase by delta.
3740 The function size_window will compute the new height h'
3741 of the window from delta1 as:
3744 x = delta1 - delta1/n * n for the 1st resizable child
3747 where n is the number of children that can be resized.
3748 We can ignore x by choosing a delta1 that is a multiple of
3749 n. We want the height of this window to come out as
3759 The number of children n equals the number of resizable
3760 children of this window + 1 because we know window itself
3761 is resizable (otherwise we would have signalled an error. */
3763 struct window
*w
= XWINDOW (window
);
3767 for (s
= w
->next
; !NILP (s
); s
= XWINDOW (s
)->next
)
3768 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3770 for (s
= w
->prev
; !NILP (s
); s
= XWINDOW (s
)->prev
)
3771 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3776 /* Add delta1 lines or columns to this window, and to the parent,
3777 keeping things consistent while not affecting siblings. */
3778 XSETINT (CURSIZE (parent
), opht
+ delta1
);
3779 (*setsizefun
) (window
, XINT (*sizep
) + delta1
, 0);
3781 /* Squeeze out delta1 lines or columns from our parent,
3782 shriking this window and siblings proportionately.
3783 This brings parent back to correct size.
3784 Delta1 was calculated so this makes this window the desired size,
3785 taking it all out of the siblings. */
3786 (*setsizefun
) (parent
, opht
, 0);
3791 XSETFASTINT (p
->last_modified
, 0);
3792 XSETFASTINT (p
->last_overlay_modified
, 0);
3794 /* Adjust glyph matrices. */
3795 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
3803 /***********************************************************************
3804 Resizing Mini-Windows
3805 ***********************************************************************/
3807 static void shrink_window_lowest_first
P_ ((struct window
*, int));
3809 enum save_restore_action
3816 static int save_restore_orig_size
P_ ((struct window
*,
3817 enum save_restore_action
));
3819 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
3820 from lowest windows first. */
3823 shrink_window_lowest_first (w
, height
)
3831 xassert (!MINI_WINDOW_P (w
));
3833 /* Set redisplay hints. */
3834 XSETFASTINT (w
->last_modified
, 0);
3835 XSETFASTINT (w
->last_overlay_modified
, 0);
3836 windows_or_buffers_changed
++;
3837 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
3839 old_height
= XFASTINT (w
->total_lines
);
3840 XSETFASTINT (w
->total_lines
, height
);
3842 if (!NILP (w
->hchild
))
3844 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
3846 c
= XWINDOW (child
);
3847 c
->top_line
= w
->top_line
;
3848 shrink_window_lowest_first (c
, height
);
3851 else if (!NILP (w
->vchild
))
3853 Lisp_Object last_child
;
3854 int delta
= old_height
- height
;
3859 /* Find the last child. We are taking space from lowest windows
3860 first, so we iterate over children from the last child
3862 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
3865 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
3866 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
3870 c
= XWINDOW (child
);
3871 this_one
= XFASTINT (c
->total_lines
) - MIN_SAFE_WINDOW_HEIGHT
;
3873 if (this_one
> delta
)
3876 shrink_window_lowest_first (c
, XFASTINT (c
->total_lines
) - this_one
);
3880 /* Compute new positions. */
3881 last_top
= XINT (w
->top_line
);
3882 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
3884 c
= XWINDOW (child
);
3885 c
->top_line
= make_number (last_top
);
3886 shrink_window_lowest_first (c
, XFASTINT (c
->total_lines
));
3887 last_top
+= XFASTINT (c
->total_lines
);
3893 /* Save, restore, or check positions and sizes in the window tree
3894 rooted at W. ACTION says what to do.
3896 If ACTION is CHECK_ORIG_SIZES, check if orig_top_line and
3897 orig_total_lines members are valid for all windows in the window
3898 tree. Value is non-zero if they are valid.
3900 If ACTION is SAVE_ORIG_SIZES, save members top and height in
3901 orig_top_line and orig_total_lines for all windows in the tree.
3903 If ACTION is RESTORE_ORIG_SIZES, restore top and height from values
3904 stored in orig_top_line and orig_total_lines for all windows. */
3907 save_restore_orig_size (w
, action
)
3909 enum save_restore_action action
;
3915 if (!NILP (w
->hchild
))
3917 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
3920 else if (!NILP (w
->vchild
))
3922 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
3928 case CHECK_ORIG_SIZES
:
3929 if (!INTEGERP (w
->orig_top_line
) || !INTEGERP (w
->orig_total_lines
))
3933 case SAVE_ORIG_SIZES
:
3934 w
->orig_top_line
= w
->top_line
;
3935 w
->orig_total_lines
= w
->total_lines
;
3936 XSETFASTINT (w
->last_modified
, 0);
3937 XSETFASTINT (w
->last_overlay_modified
, 0);
3940 case RESTORE_ORIG_SIZES
:
3941 xassert (INTEGERP (w
->orig_top_line
) && INTEGERP (w
->orig_total_lines
));
3942 w
->top_line
= w
->orig_top_line
;
3943 w
->total_lines
= w
->orig_total_lines
;
3944 w
->orig_total_lines
= w
->orig_top_line
= Qnil
;
3945 XSETFASTINT (w
->last_modified
, 0);
3946 XSETFASTINT (w
->last_overlay_modified
, 0);
3953 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
3960 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
3961 without deleting other windows. */
3964 grow_mini_window (w
, delta
)
3968 struct frame
*f
= XFRAME (w
->frame
);
3969 struct window
*root
;
3971 xassert (MINI_WINDOW_P (w
));
3972 xassert (delta
>= 0);
3974 /* Check values of window_min_width and window_min_height for
3976 check_min_window_sizes ();
3978 /* Compute how much we can enlarge the mini-window without deleting
3980 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3983 int min_height
= window_min_size (root
, 0, 0, 0);
3984 if (XFASTINT (root
->total_lines
) - delta
< min_height
)
3985 /* Note that the root window may already be smaller than
3987 delta
= max (0, XFASTINT (root
->total_lines
) - min_height
);
3992 /* Save original window sizes and positions, if not already done. */
3993 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3994 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
3996 /* Shrink other windows. */
3997 shrink_window_lowest_first (root
, XFASTINT (root
->total_lines
) - delta
);
3999 /* Grow the mini-window. */
4000 w
->top_line
= make_number (XFASTINT (root
->top_line
) + XFASTINT (root
->total_lines
));
4001 w
->total_lines
= make_number (XFASTINT (w
->total_lines
) + delta
);
4002 XSETFASTINT (w
->last_modified
, 0);
4003 XSETFASTINT (w
->last_overlay_modified
, 0);
4010 /* Shrink mini-window W. If there is recorded info about window sizes
4011 before a call to grow_mini_window, restore recorded window sizes.
4012 Otherwise, if the mini-window is higher than 1 line, resize it to 1
4016 shrink_mini_window (w
)
4019 struct frame
*f
= XFRAME (w
->frame
);
4020 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4022 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
4024 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
4026 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4027 windows_or_buffers_changed
= 1;
4029 else if (XFASTINT (w
->total_lines
) > 1)
4031 /* Distribute the additional lines of the mini-window
4032 among the other windows. */
4034 XSETWINDOW (window
, w
);
4035 enlarge_window (window
, 1 - XFASTINT (w
->total_lines
), 0, 0);
4041 /* Mark window cursors off for all windows in the window tree rooted
4042 at W by setting their phys_cursor_on_p flag to zero. Called from
4043 xterm.c, e.g. when a frame is cleared and thereby all cursors on
4044 the frame are cleared. */
4047 mark_window_cursors_off (w
)
4052 if (!NILP (w
->hchild
))
4053 mark_window_cursors_off (XWINDOW (w
->hchild
));
4054 else if (!NILP (w
->vchild
))
4055 mark_window_cursors_off (XWINDOW (w
->vchild
));
4057 w
->phys_cursor_on_p
= 0;
4059 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4064 /* Return number of lines of text (not counting mode lines) in W. */
4067 window_internal_height (w
)
4070 int ht
= XFASTINT (w
->total_lines
);
4072 if (!MINI_WINDOW_P (w
))
4074 if (!NILP (w
->parent
)
4075 || !NILP (w
->vchild
)
4076 || !NILP (w
->hchild
)
4079 || WINDOW_WANTS_MODELINE_P (w
))
4082 if (WINDOW_WANTS_HEADER_LINE_P (w
))
4090 /* Return the number of columns in W.
4091 Don't count columns occupied by scroll bars or the vertical bar
4092 separating W from the sibling to its right. */
4095 window_box_text_cols (w
)
4098 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
4099 int width
= XINT (w
->total_cols
);
4101 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
4102 /* Scroll bars occupy a few columns. */
4103 width
-= WINDOW_CONFIG_SCROLL_BAR_COLS (w
);
4104 else if (!FRAME_WINDOW_P (f
)
4105 && !WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
4106 /* The column of `|' characters separating side-by-side windows
4107 occupies one column only. */
4110 if (FRAME_WINDOW_P (f
))
4111 /* On window-systems, fringes and display margins cannot be
4112 used for normal text. */
4113 width
-= (WINDOW_FRINGE_COLS (w
)
4114 + WINDOW_LEFT_MARGIN_COLS (w
)
4115 + WINDOW_RIGHT_MARGIN_COLS (w
));
4121 /************************************************************************
4123 ***********************************************************************/
4125 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
4126 N screen-fulls, which is defined as the height of the window minus
4127 next_screen_context_lines. If WHOLE is zero, scroll up N lines
4128 instead. Negative values of N mean scroll down. NOERROR non-zero
4129 means don't signal an error if we try to move over BEGV or ZV,
4133 window_scroll (window
, n
, whole
, noerror
)
4141 /* If we must, use the pixel-based version which is much slower than
4142 the line-based one but can handle varying line heights. */
4143 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
4144 window_scroll_pixel_based (window
, n
, whole
, noerror
);
4146 window_scroll_line_based (window
, n
, whole
, noerror
);
4152 /* Implementation of window_scroll that works based on pixel line
4153 heights. See the comment of window_scroll for parameter
4157 window_scroll_pixel_based (window
, n
, whole
, noerror
)
4164 struct window
*w
= XWINDOW (window
);
4165 struct text_pos start
;
4167 int this_scroll_margin
;
4169 /* True if we fiddled the window vscroll field without really scrolling. */
4172 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4174 /* If PT is not visible in WINDOW, move back one half of
4175 the screen. Allow PT to be partially visible, otherwise
4176 something like (scroll-down 1) with PT in the line before
4177 the partially visible one would recenter. */
4178 tem
= Fpos_visible_in_window_p (make_number (PT
), window
, Qt
);
4181 /* Move backward half the height of the window. Performance note:
4182 vmotion used here is about 10% faster, but would give wrong
4183 results for variable height lines. */
4184 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4185 it
.current_y
= it
.last_visible_y
;
4186 move_it_vertically (&it
, - window_box_height (w
) / 2);
4188 /* The function move_iterator_vertically may move over more than
4189 the specified y-distance. If it->w is small, e.g. a
4190 mini-buffer window, we may end up in front of the window's
4191 display area. This is the case when Start displaying at the
4192 start of the line containing PT in this case. */
4193 if (it
.current_y
<= 0)
4195 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4196 move_it_vertically (&it
, 0);
4200 start
= it
.current
.pos
;
4203 /* If scroll_preserve_screen_position is non-zero, we try to set
4204 point in the same window line as it is now, so get that line. */
4205 if (!NILP (Vscroll_preserve_screen_position
))
4207 start_display (&it
, w
, start
);
4208 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
4209 preserve_y
= it
.current_y
;
4214 /* Move iterator it from start the specified distance forward or
4215 backward. The result is the new window start. */
4216 start_display (&it
, w
, start
);
4219 int screen_full
= (window_box_height (w
)
4220 - next_screen_context_lines
* FRAME_LINE_HEIGHT (it
.f
));
4221 int dy
= n
* screen_full
;
4223 /* Note that move_it_vertically always moves the iterator to the
4224 start of a line. So, if the last line doesn't have a newline,
4225 we would end up at the start of the line ending at ZV. */
4227 move_it_vertically_backward (&it
, -dy
);
4229 move_it_to (&it
, ZV
, -1, it
.current_y
+ dy
, -1,
4230 MOVE_TO_POS
| MOVE_TO_Y
);
4233 move_it_by_lines (&it
, n
, 1);
4235 /* We failed if we find ZV is already on the screen (scrolling up,
4236 means there's nothing past the end), or if we can't start any
4237 earlier (scrolling down, means there's nothing past the top). */
4238 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
4239 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
4241 if (IT_CHARPOS (it
) == ZV
)
4243 if (it
.current_y
< it
.last_visible_y
4244 && (it
.current_y
+ it
.max_ascent
+ it
.max_descent
4245 >= it
.last_visible_y
))
4247 /* The last line was only partially visible, make it fully
4249 w
->vscroll
= (it
.last_visible_y
4250 - it
.current_y
+ it
.max_ascent
+ it
.max_descent
);
4251 adjust_glyphs (it
.f
);
4256 Fsignal (Qend_of_buffer
, Qnil
);
4260 if (w
->vscroll
!= 0)
4261 /* The first line was only partially visible, make it fully
4267 Fsignal (Qbeginning_of_buffer
, Qnil
);
4270 /* If control gets here, then we vscrolled. */
4272 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
4274 /* Don't try to change the window start below. */
4280 int pos
= IT_CHARPOS (it
);
4283 /* If in the middle of a multi-glyph character move forward to
4284 the next character. */
4285 if (in_display_vector_p (&it
))
4288 move_it_to (&it
, pos
, -1, -1, -1, MOVE_TO_POS
);
4291 /* Set the window start, and set up the window for redisplay. */
4292 set_marker_restricted (w
->start
, make_number (pos
),
4294 bytepos
= XMARKER (w
->start
)->bytepos
;
4295 w
->start_at_line_beg
= ((pos
== BEGV
|| FETCH_BYTE (bytepos
- 1) == '\n')
4297 w
->update_mode_line
= Qt
;
4298 XSETFASTINT (w
->last_modified
, 0);
4299 XSETFASTINT (w
->last_overlay_modified
, 0);
4300 /* Set force_start so that redisplay_window will run the
4301 window-scroll-functions. */
4302 w
->force_start
= Qt
;
4305 it
.current_y
= it
.vpos
= 0;
4307 /* Preserve the screen position if we must. */
4308 if (preserve_y
>= 0)
4310 move_it_to (&it
, -1, -1, preserve_y
, -1, MOVE_TO_Y
);
4311 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4315 /* Move PT out of scroll margins. */
4316 this_scroll_margin
= max (0, scroll_margin
);
4317 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->total_lines
) / 4);
4318 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
4322 /* We moved the window start towards ZV, so PT may be now
4323 in the scroll margin at the top. */
4324 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
4325 while (it
.current_y
< this_scroll_margin
)
4327 int prev
= it
.current_y
;
4328 move_it_by_lines (&it
, 1, 1);
4329 if (prev
== it
.current_y
)
4332 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4336 int charpos
, bytepos
;
4338 /* We moved the window start towards BEGV, so PT may be now
4339 in the scroll margin at the bottom. */
4340 move_it_to (&it
, PT
, -1,
4341 it
.last_visible_y
- this_scroll_margin
- 1, -1,
4342 MOVE_TO_POS
| MOVE_TO_Y
);
4344 /* Save our position, in case it's correct. */
4345 charpos
= IT_CHARPOS (it
);
4346 bytepos
= IT_BYTEPOS (it
);
4348 /* See if point is on a partially visible line at the end. */
4349 move_it_by_lines (&it
, 1, 1);
4350 if (it
.current_y
> it
.last_visible_y
)
4351 /* The last line was only partially visible, so back up two
4352 lines to make sure we're on a fully visible line. */
4354 move_it_by_lines (&it
, -2, 0);
4355 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4358 /* No, the position we saved is OK, so use it. */
4359 SET_PT_BOTH (charpos
, bytepos
);
4365 /* Implementation of window_scroll that works based on screen lines.
4366 See the comment of window_scroll for parameter descriptions. */
4369 window_scroll_line_based (window
, n
, whole
, noerror
)
4375 register struct window
*w
= XWINDOW (window
);
4376 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
4377 register int pos
, pos_byte
;
4378 register int ht
= window_internal_height (w
);
4379 register Lisp_Object tem
;
4383 struct position posit
;
4386 /* If scrolling screen-fulls, compute the number of lines to
4387 scroll from the window's height. */
4389 n
*= max (1, ht
- next_screen_context_lines
);
4391 startpos
= marker_position (w
->start
);
4393 posit
= *compute_motion (startpos
, 0, 0, 0,
4395 window_box_text_cols (w
), XINT (w
->hscroll
),
4397 original_vpos
= posit
.vpos
;
4399 XSETFASTINT (tem
, PT
);
4400 tem
= Fpos_visible_in_window_p (tem
, window
, Qnil
);
4404 Fvertical_motion (make_number (- (ht
/ 2)), window
);
4409 lose
= n
< 0 && PT
== BEGV
;
4410 Fvertical_motion (make_number (n
), window
);
4414 SET_PT_BOTH (opoint
, opoint_byte
);
4421 Fsignal (Qbeginning_of_buffer
, Qnil
);
4426 int this_scroll_margin
= scroll_margin
;
4428 /* Don't use a scroll margin that is negative or too large. */
4429 if (this_scroll_margin
< 0)
4430 this_scroll_margin
= 0;
4432 if (XINT (w
->total_lines
) < 4 * scroll_margin
)
4433 this_scroll_margin
= XINT (w
->total_lines
) / 4;
4435 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
4436 w
->start_at_line_beg
= bolp
;
4437 w
->update_mode_line
= Qt
;
4438 XSETFASTINT (w
->last_modified
, 0);
4439 XSETFASTINT (w
->last_overlay_modified
, 0);
4440 /* Set force_start so that redisplay_window will run
4441 the window-scroll-functions. */
4442 w
->force_start
= Qt
;
4444 if (whole
&& !NILP (Vscroll_preserve_screen_position
))
4446 SET_PT_BOTH (pos
, pos_byte
);
4447 Fvertical_motion (make_number (original_vpos
), window
);
4449 /* If we scrolled forward, put point enough lines down
4450 that it is outside the scroll margin. */
4455 if (this_scroll_margin
> 0)
4457 SET_PT_BOTH (pos
, pos_byte
);
4458 Fvertical_motion (make_number (this_scroll_margin
), window
);
4464 if (top_margin
<= opoint
)
4465 SET_PT_BOTH (opoint
, opoint_byte
);
4466 else if (!NILP (Vscroll_preserve_screen_position
))
4468 SET_PT_BOTH (pos
, pos_byte
);
4469 Fvertical_motion (make_number (original_vpos
), window
);
4472 SET_PT (top_margin
);
4478 /* If we scrolled backward, put point near the end of the window
4479 but not within the scroll margin. */
4480 SET_PT_BOTH (pos
, pos_byte
);
4481 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
4482 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
4485 bottom_margin
= PT
+ 1;
4487 if (bottom_margin
> opoint
)
4488 SET_PT_BOTH (opoint
, opoint_byte
);
4491 if (!NILP (Vscroll_preserve_screen_position
))
4493 SET_PT_BOTH (pos
, pos_byte
);
4494 Fvertical_motion (make_number (original_vpos
), window
);
4497 Fvertical_motion (make_number (-1), window
);
4506 Fsignal (Qend_of_buffer
, Qnil
);
4511 /* Scroll selected_window up or down. If N is nil, scroll a
4512 screen-full which is defined as the height of the window minus
4513 next_screen_context_lines. If N is the symbol `-', scroll.
4514 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
4515 up. This is the guts of Fscroll_up and Fscroll_down. */
4518 scroll_command (n
, direction
)
4522 int count
= SPECPDL_INDEX ();
4524 xassert (abs (direction
) == 1);
4526 /* If selected window's buffer isn't current, make it current for
4527 the moment. But don't screw up if window_scroll gets an error. */
4528 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
4530 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4531 Fset_buffer (XWINDOW (selected_window
)->buffer
);
4533 /* Make redisplay consider other windows than just selected_window. */
4534 ++windows_or_buffers_changed
;
4538 window_scroll (selected_window
, direction
, 1, 0);
4539 else if (EQ (n
, Qminus
))
4540 window_scroll (selected_window
, -direction
, 1, 0);
4543 n
= Fprefix_numeric_value (n
);
4544 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
4547 unbind_to (count
, Qnil
);
4550 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
4551 doc
: /* Scroll text of current window upward ARG lines; or near full screen if no ARG.
4552 A near full screen is `next-screen-context-lines' less than a full screen.
4553 Negative ARG means scroll downward.
4554 If ARG is the atom `-', scroll downward by nearly full screen.
4555 When calling from a program, supply as argument a number, nil, or `-'. */)
4559 scroll_command (arg
, 1);
4563 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
4564 doc
: /* Scroll text of current window down ARG lines; or near full screen if no ARG.
4565 A near full screen is `next-screen-context-lines' less than a full screen.
4566 Negative ARG means scroll upward.
4567 If ARG is the atom `-', scroll upward by nearly full screen.
4568 When calling from a program, supply as argument a number, nil, or `-'. */)
4572 scroll_command (arg
, -1);
4576 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
4577 doc
: /* Return the other window for \"other window scroll\" commands.
4578 If in the minibuffer, `minibuffer-scroll-window' if non-nil
4579 specifies the window.
4580 If `other-window-scroll-buffer' is non-nil, a window
4581 showing that buffer is used. */)
4586 if (MINI_WINDOW_P (XWINDOW (selected_window
))
4587 && !NILP (Vminibuf_scroll_window
))
4588 window
= Vminibuf_scroll_window
;
4589 /* If buffer is specified, scroll that buffer. */
4590 else if (!NILP (Vother_window_scroll_buffer
))
4592 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
4594 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
4598 /* Nothing specified; look for a neighboring window on the same
4600 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
4602 if (EQ (window
, selected_window
))
4603 /* That didn't get us anywhere; look for a window on another
4606 window
= Fnext_window (window
, Qnil
, Qt
);
4607 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
4608 && ! EQ (window
, selected_window
));
4611 CHECK_LIVE_WINDOW (window
);
4613 if (EQ (window
, selected_window
))
4614 error ("There is no other window");
4619 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
4620 doc
: /* Scroll next window upward ARG lines; or near full screen if no ARG.
4621 A near full screen is `next-screen-context-lines' less than a full screen.
4622 The next window is the one below the current one; or the one at the top
4623 if the current one is at the bottom. Negative ARG means scroll downward.
4624 If ARG is the atom `-', scroll downward by nearly full screen.
4625 When calling from a program, supply as argument a number, nil, or `-'.
4627 If in the minibuffer, `minibuffer-scroll-window' if non-nil
4628 specifies the window to scroll.
4629 If `other-window-scroll-buffer' is non-nil, scroll the window
4630 showing that buffer, popping the buffer up if necessary. */)
4636 int count
= SPECPDL_INDEX ();
4638 window
= Fother_window_for_scrolling ();
4639 w
= XWINDOW (window
);
4641 /* Don't screw up if window_scroll gets an error. */
4642 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4643 ++windows_or_buffers_changed
;
4645 Fset_buffer (w
->buffer
);
4646 SET_PT (marker_position (w
->pointm
));
4649 window_scroll (window
, 1, 1, 1);
4650 else if (EQ (arg
, Qminus
))
4651 window_scroll (window
, -1, 1, 1);
4657 window_scroll (window
, XINT (arg
), 0, 1);
4660 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
4661 unbind_to (count
, Qnil
);
4666 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 1, "P",
4667 doc
: /* Scroll selected window display ARG columns left.
4668 Default for ARG is window width minus 2.
4669 Value is the total amount of leftward horizontal scrolling in
4670 effect after the change.
4671 If `automatic-hscrolling' is non-nil, the argument ARG modifies
4672 a lower bound for automatic scrolling, i.e. automatic scrolling
4673 will not scroll a window to a column less than the value returned
4674 by this function. */)
4676 register Lisp_Object arg
;
4680 struct window
*w
= XWINDOW (selected_window
);
4683 XSETFASTINT (arg
, window_box_text_cols (w
) - 2);
4685 arg
= Fprefix_numeric_value (arg
);
4687 hscroll
= XINT (w
->hscroll
) + XINT (arg
);
4688 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
4690 if (interactive_p (0))
4691 w
->min_hscroll
= w
->hscroll
;
4696 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 1, "P",
4697 doc
: /* Scroll selected window display ARG columns right.
4698 Default for ARG is window width minus 2.
4699 Value is the total amount of leftward horizontal scrolling in
4700 effect after the change.
4701 If `automatic-hscrolling' is non-nil, the argument ARG modifies
4702 a lower bound for automatic scrolling, i.e. automatic scrolling
4703 will not scroll a window to a column less than the value returned
4704 by this function. */)
4706 register Lisp_Object arg
;
4710 struct window
*w
= XWINDOW (selected_window
);
4713 XSETFASTINT (arg
, window_box_text_cols (w
) - 2);
4715 arg
= Fprefix_numeric_value (arg
);
4717 hscroll
= XINT (w
->hscroll
) - XINT (arg
);
4718 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
4720 if (interactive_p (0))
4721 w
->min_hscroll
= w
->hscroll
;
4726 DEFUN ("minibuffer-selected-window", Fminibuffer_selected_window
, Sminibuffer_selected_window
, 0, 0, 0,
4727 doc
: /* Return the window which was selected when entering the minibuffer.
4728 Returns nil, if current window is not a minibuffer window. */)
4731 if (minibuf_level
> 0
4732 && MINI_WINDOW_P (XWINDOW (selected_window
))
4733 && !NILP (minibuf_selected_window
)
4734 && WINDOW_LIVE_P (minibuf_selected_window
))
4735 return minibuf_selected_window
;
4740 /* Value is the number of lines actually displayed in window W,
4741 as opposed to its height. */
4744 displayed_window_lines (w
)
4748 struct text_pos start
;
4749 int height
= window_box_height (w
);
4750 struct buffer
*old_buffer
;
4753 if (XBUFFER (w
->buffer
) != current_buffer
)
4755 old_buffer
= current_buffer
;
4756 set_buffer_internal (XBUFFER (w
->buffer
));
4761 /* In case W->start is out of the accessible range, do something
4762 reasonable. This happens in Info mode when Info-scroll-down
4763 calls (recenter -1) while W->start is 1. */
4764 if (XMARKER (w
->start
)->charpos
< BEGV
)
4765 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
4766 else if (XMARKER (w
->start
)->charpos
> ZV
)
4767 SET_TEXT_POS (start
, ZV
, ZV_BYTE
);
4769 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4771 start_display (&it
, w
, start
);
4772 move_it_vertically (&it
, height
);
4773 bottom_y
= line_bottom_y (&it
);
4775 /* rms: On a non-window display,
4776 the value of it.vpos at the bottom of the screen
4777 seems to be 1 larger than window_box_height (w).
4778 This kludge fixes a bug whereby (move-to-window-line -1)
4779 when ZV is on the last screen line
4780 moves to the previous screen line instead of the last one. */
4781 if (! FRAME_WINDOW_P (XFRAME (w
->frame
)))
4784 /* Add in empty lines at the bottom of the window. */
4785 if (bottom_y
< height
)
4787 int uy
= FRAME_LINE_HEIGHT (it
.f
);
4788 it
.vpos
+= (height
- bottom_y
+ uy
- 1) / uy
;
4792 set_buffer_internal (old_buffer
);
4798 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
4799 doc
: /* Center point in window and redisplay frame.
4800 With prefix argument ARG, recenter putting point on screen line ARG
4801 relative to the current window. If ARG is negative, it counts up from the
4802 bottom of the window. (ARG should be less than the height of the window.)
4804 If ARG is omitted or nil, erase the entire frame and then
4805 redraw with point in the center of the current window.
4806 Just C-u as prefix means put point in the center of the window
4807 and redisplay normally--don't erase and redraw the frame. */)
4809 register Lisp_Object arg
;
4811 struct window
*w
= XWINDOW (selected_window
);
4812 struct buffer
*buf
= XBUFFER (w
->buffer
);
4813 struct buffer
*obuf
= current_buffer
;
4815 int charpos
, bytepos
;
4817 /* If redisplay is suppressed due to an error, try again. */
4818 obuf
->display_error_modiff
= 0;
4824 /* Invalidate pixel data calculated for all compositions. */
4825 for (i
= 0; i
< n_compositions
; i
++)
4826 composition_table
[i
]->font
= NULL
;
4828 Fredraw_frame (w
->frame
);
4829 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
4832 else if (CONSP (arg
)) /* Just C-u. */
4836 arg
= Fprefix_numeric_value (arg
);
4840 set_buffer_internal (buf
);
4842 /* Handle centering on a graphical frame specially. Such frames can
4843 have variable-height lines and centering point on the basis of
4844 line counts would lead to strange effects. */
4845 if (FRAME_WINDOW_P (XFRAME (w
->frame
)))
4852 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
4853 start_display (&it
, w
, pt
);
4854 move_it_vertically (&it
, - window_box_height (w
) / 2);
4855 charpos
= IT_CHARPOS (it
);
4856 bytepos
= IT_BYTEPOS (it
);
4858 else if (XINT (arg
) < 0)
4862 int y0
, y1
, h
, nlines
;
4864 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
4865 start_display (&it
, w
, pt
);
4868 /* The amount of pixels we have to move back is the window
4869 height minus what's displayed in the line containing PT,
4870 and the lines below. */
4871 nlines
= - XINT (arg
) - 1;
4872 move_it_by_lines (&it
, nlines
, 1);
4874 y1
= line_bottom_y (&it
);
4876 /* If we can't move down NLINES lines because we hit
4877 the end of the buffer, count in some empty lines. */
4878 if (it
.vpos
< nlines
)
4879 y1
+= (nlines
- it
.vpos
) * FRAME_LINE_HEIGHT (it
.f
);
4881 h
= window_box_height (w
) - (y1
- y0
);
4883 start_display (&it
, w
, pt
);
4884 move_it_vertically (&it
, - h
);
4885 charpos
= IT_CHARPOS (it
);
4886 bytepos
= IT_BYTEPOS (it
);
4890 struct position pos
;
4891 pos
= *vmotion (PT
, - XINT (arg
), w
);
4892 charpos
= pos
.bufpos
;
4893 bytepos
= pos
.bytepos
;
4898 struct position pos
;
4899 int ht
= window_internal_height (w
);
4902 arg
= make_number (ht
/ 2);
4903 else if (XINT (arg
) < 0)
4904 arg
= make_number (XINT (arg
) + ht
);
4906 pos
= *vmotion (PT
, - XINT (arg
), w
);
4907 charpos
= pos
.bufpos
;
4908 bytepos
= pos
.bytepos
;
4911 /* Set the new window start. */
4912 set_marker_both (w
->start
, w
->buffer
, charpos
, bytepos
);
4913 w
->window_end_valid
= Qnil
;
4915 w
->optional_new_start
= Qt
;
4917 if (bytepos
== BEGV_BYTE
|| FETCH_BYTE (bytepos
- 1) == '\n')
4918 w
->start_at_line_beg
= Qt
;
4920 w
->start_at_line_beg
= Qnil
;
4922 set_buffer_internal (obuf
);
4927 DEFUN ("window-text-height", Fwindow_text_height
, Swindow_text_height
,
4929 doc
: /* Return the height in lines of the text display area of WINDOW.
4930 This doesn't include the mode-line (or header-line if any) or any
4931 partial-height lines in the text display area. */)
4935 struct window
*w
= decode_window (window
);
4936 int pixel_height
= window_box_height (w
);
4937 int line_height
= pixel_height
/ FRAME_LINE_HEIGHT (XFRAME (w
->frame
));
4938 return make_number (line_height
);
4943 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
4945 doc
: /* Position point relative to window.
4946 With no argument, position point at center of window.
4947 An argument specifies vertical position within the window;
4948 zero means top of window, negative means relative to bottom of window. */)
4952 struct window
*w
= XWINDOW (selected_window
);
4956 window
= selected_window
;
4957 start
= marker_position (w
->start
);
4958 if (start
< BEGV
|| start
> ZV
)
4960 int height
= window_internal_height (w
);
4961 Fvertical_motion (make_number (- (height
/ 2)), window
);
4962 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
4963 w
->start_at_line_beg
= Fbolp ();
4964 w
->force_start
= Qt
;
4967 Fgoto_char (w
->start
);
4969 lines
= displayed_window_lines (w
);
4971 XSETFASTINT (arg
, lines
/ 2);
4974 arg
= Fprefix_numeric_value (arg
);
4976 XSETINT (arg
, XINT (arg
) + lines
);
4979 /* Skip past a partially visible first line. */
4981 XSETINT (arg
, XINT (arg
) + 1);
4983 return Fvertical_motion (arg
, window
);
4988 /***********************************************************************
4989 Window Configuration
4990 ***********************************************************************/
4992 struct save_window_data
4994 EMACS_INT size_from_Lisp_Vector_struct
;
4995 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4996 Lisp_Object frame_cols
, frame_lines
, frame_menu_bar_lines
;
4997 Lisp_Object frame_tool_bar_lines
;
4998 Lisp_Object selected_frame
;
4999 Lisp_Object current_window
;
5000 Lisp_Object current_buffer
;
5001 Lisp_Object minibuf_scroll_window
;
5002 Lisp_Object minibuf_selected_window
;
5003 Lisp_Object root_window
;
5004 Lisp_Object focus_frame
;
5005 /* Record the values of window-min-width and window-min-height
5006 so that window sizes remain consistent with them. */
5007 Lisp_Object min_width
, min_height
;
5008 /* A vector, each of whose elements is a struct saved_window
5010 Lisp_Object saved_windows
;
5013 /* This is saved as a Lisp_Vector */
5016 /* these first two must agree with struct Lisp_Vector in lisp.h */
5017 EMACS_INT size_from_Lisp_Vector_struct
;
5018 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
5021 Lisp_Object buffer
, start
, pointm
, mark
;
5022 Lisp_Object left_col
, top_line
, total_cols
, total_lines
;
5023 Lisp_Object hscroll
, min_hscroll
;
5024 Lisp_Object parent
, prev
;
5025 Lisp_Object start_at_line_beg
;
5026 Lisp_Object display_table
;
5027 Lisp_Object orig_top_line
, orig_total_lines
;
5028 Lisp_Object left_margin_cols
, right_margin_cols
;
5029 Lisp_Object left_fringe_width
, right_fringe_width
, fringes_outside_margins
;
5030 Lisp_Object scroll_bar_width
, vertical_scroll_bar_type
;
5033 #define SAVED_WINDOW_VECTOR_SIZE 24 /* Arg to Fmake_vector */
5035 #define SAVED_WINDOW_N(swv,n) \
5036 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
5038 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
5039 doc
: /* Return t if OBJECT is a window-configuration object. */)
5043 if (WINDOW_CONFIGURATIONP (object
))
5048 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
5049 doc
: /* Return the frame that CONFIG, a window-configuration object, is about. */)
5053 register struct save_window_data
*data
;
5054 struct Lisp_Vector
*saved_windows
;
5056 if (! WINDOW_CONFIGURATIONP (config
))
5057 wrong_type_argument (Qwindow_configuration_p
, config
);
5059 data
= (struct save_window_data
*) XVECTOR (config
);
5060 saved_windows
= XVECTOR (data
->saved_windows
);
5061 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
5064 DEFUN ("set-window-configuration", Fset_window_configuration
,
5065 Sset_window_configuration
, 1, 1, 0,
5066 doc
: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
5067 CONFIGURATION must be a value previously returned
5068 by `current-window-configuration' (which see).
5069 If CONFIGURATION was made from a frame that is now deleted,
5070 only frame-independent values can be restored. In this case,
5071 the return value is nil. Otherwise the value is t. */)
5073 Lisp_Object configuration
;
5075 register struct save_window_data
*data
;
5076 struct Lisp_Vector
*saved_windows
;
5077 Lisp_Object new_current_buffer
;
5082 while (!WINDOW_CONFIGURATIONP (configuration
))
5083 wrong_type_argument (Qwindow_configuration_p
, configuration
);
5085 data
= (struct save_window_data
*) XVECTOR (configuration
);
5086 saved_windows
= XVECTOR (data
->saved_windows
);
5088 new_current_buffer
= data
->current_buffer
;
5089 if (NILP (XBUFFER (new_current_buffer
)->name
))
5090 new_current_buffer
= Qnil
;
5093 if (XBUFFER (new_current_buffer
) == current_buffer
)
5096 old_point
= BUF_PT (XBUFFER (new_current_buffer
));
5099 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
5102 /* If f is a dead frame, don't bother rebuilding its window tree.
5103 However, there is other stuff we should still try to do below. */
5104 if (FRAME_LIVE_P (f
))
5106 register struct window
*w
;
5107 register struct saved_window
*p
;
5108 struct window
*root_window
;
5109 struct window
**leaf_windows
;
5113 /* If the frame has been resized since this window configuration was
5114 made, we change the frame to the size specified in the
5115 configuration, restore the configuration, and then resize it
5116 back. We keep track of the prevailing height in these variables. */
5117 int previous_frame_lines
= FRAME_LINES (f
);
5118 int previous_frame_cols
= FRAME_COLS (f
);
5119 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
5120 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
5122 /* The mouse highlighting code could get screwed up
5123 if it runs during this. */
5126 if (XFASTINT (data
->frame_lines
) != previous_frame_lines
5127 || XFASTINT (data
->frame_cols
) != previous_frame_cols
)
5128 change_frame_size (f
, XFASTINT (data
->frame_lines
),
5129 XFASTINT (data
->frame_cols
), 0, 0, 0);
5130 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
5131 if (XFASTINT (data
->frame_menu_bar_lines
)
5132 != previous_frame_menu_bar_lines
)
5133 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, make_number (0));
5134 #ifdef HAVE_WINDOW_SYSTEM
5135 if (XFASTINT (data
->frame_tool_bar_lines
)
5136 != previous_frame_tool_bar_lines
)
5137 x_set_tool_bar_lines (f
, data
->frame_tool_bar_lines
, make_number (0));
5141 /* "Swap out" point from the selected window
5142 into its buffer. We do this now, before
5143 restoring the window contents, and prevent it from
5144 being done later on when we select a new window. */
5145 if (! NILP (XWINDOW (selected_window
)->buffer
))
5147 w
= XWINDOW (selected_window
);
5148 set_marker_both (w
->pointm
,
5150 BUF_PT (XBUFFER (w
->buffer
)),
5151 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5154 windows_or_buffers_changed
++;
5155 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
5157 /* Problem: Freeing all matrices and later allocating them again
5158 is a serious redisplay flickering problem. What we would
5159 really like to do is to free only those matrices not reused
5161 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
5163 = (struct window
**) alloca (count_windows (root_window
)
5164 * sizeof (struct window
*));
5165 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
5167 /* Temporarily avoid any problems with windows that are smaller
5168 than they are supposed to be. */
5169 window_min_height
= 1;
5170 window_min_width
= 1;
5173 Mark all windows now on frame as "deleted".
5174 Restoring the new configuration "undeletes" any that are in it.
5176 Save their current buffers in their height fields, since we may
5177 need it later, if a buffer saved in the configuration is now
5179 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5181 for (k
= 0; k
< saved_windows
->size
; k
++)
5183 p
= SAVED_WINDOW_N (saved_windows
, k
);
5184 w
= XWINDOW (p
->window
);
5187 if (!NILP (p
->parent
))
5188 w
->parent
= SAVED_WINDOW_N (saved_windows
,
5189 XFASTINT (p
->parent
))->window
;
5193 if (!NILP (p
->prev
))
5195 w
->prev
= SAVED_WINDOW_N (saved_windows
,
5196 XFASTINT (p
->prev
))->window
;
5197 XWINDOW (w
->prev
)->next
= p
->window
;
5202 if (!NILP (w
->parent
))
5204 if (EQ (p
->total_cols
, XWINDOW (w
->parent
)->total_cols
))
5206 XWINDOW (w
->parent
)->vchild
= p
->window
;
5207 XWINDOW (w
->parent
)->hchild
= Qnil
;
5211 XWINDOW (w
->parent
)->hchild
= p
->window
;
5212 XWINDOW (w
->parent
)->vchild
= Qnil
;
5217 /* If we squirreled away the buffer in the window's height,
5219 if (BUFFERP (w
->total_lines
))
5220 w
->buffer
= w
->total_lines
;
5221 w
->left_col
= p
->left_col
;
5222 w
->top_line
= p
->top_line
;
5223 w
->total_cols
= p
->total_cols
;
5224 w
->total_lines
= p
->total_lines
;
5225 w
->hscroll
= p
->hscroll
;
5226 w
->min_hscroll
= p
->min_hscroll
;
5227 w
->display_table
= p
->display_table
;
5228 w
->orig_top_line
= p
->orig_top_line
;
5229 w
->orig_total_lines
= p
->orig_total_lines
;
5230 w
->left_margin_cols
= p
->left_margin_cols
;
5231 w
->right_margin_cols
= p
->right_margin_cols
;
5232 w
->left_fringe_width
= p
->left_fringe_width
;
5233 w
->right_fringe_width
= p
->right_fringe_width
;
5234 w
->fringes_outside_margins
= p
->fringes_outside_margins
;
5235 w
->scroll_bar_width
= p
->scroll_bar_width
;
5236 w
->vertical_scroll_bar_type
= p
->vertical_scroll_bar_type
;
5237 XSETFASTINT (w
->last_modified
, 0);
5238 XSETFASTINT (w
->last_overlay_modified
, 0);
5240 /* Reinstall the saved buffer and pointers into it. */
5241 if (NILP (p
->buffer
))
5242 w
->buffer
= p
->buffer
;
5245 if (!NILP (XBUFFER (p
->buffer
)->name
))
5246 /* If saved buffer is alive, install it. */
5248 w
->buffer
= p
->buffer
;
5249 w
->start_at_line_beg
= p
->start_at_line_beg
;
5250 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
5251 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
5252 Fset_marker (XBUFFER (w
->buffer
)->mark
,
5253 p
->mark
, w
->buffer
);
5255 /* As documented in Fcurrent_window_configuration, don't
5256 restore the location of point in the buffer which was
5257 current when the window configuration was recorded. */
5258 if (!EQ (p
->buffer
, new_current_buffer
)
5259 && XBUFFER (p
->buffer
) == current_buffer
)
5260 Fgoto_char (w
->pointm
);
5262 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
5263 /* Else unless window has a live buffer, get one. */
5265 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
5266 /* This will set the markers to beginning of visible
5268 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
5269 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
5270 w
->start_at_line_beg
= Qt
;
5273 /* Keeping window's old buffer; make sure the markers
5276 /* Set window markers at start of visible range. */
5277 if (XMARKER (w
->start
)->buffer
== 0)
5278 set_marker_restricted (w
->start
, make_number (0),
5280 if (XMARKER (w
->pointm
)->buffer
== 0)
5281 set_marker_restricted_both (w
->pointm
, w
->buffer
,
5282 BUF_PT (XBUFFER (w
->buffer
)),
5283 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5284 w
->start_at_line_beg
= Qt
;
5289 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
5290 /* Prevent "swapping out point" in the old selected window
5291 using the buffer that has been restored into it.
5292 Use the point value from the beginning of this function
5293 since unshow_buffer (called from delete_all_subwindows)
5294 could have altered it. */
5295 selected_window
= Qnil
;
5296 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
))
5297 set_marker_restricted (XWINDOW (data
->current_window
)->pointm
,
5298 make_number (old_point
),
5299 XWINDOW (data
->current_window
)->buffer
);
5301 Fselect_window (data
->current_window
, Qnil
);
5302 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
5305 if (NILP (data
->focus_frame
)
5306 || (FRAMEP (data
->focus_frame
)
5307 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
5308 Fredirect_frame_focus (frame
, data
->focus_frame
);
5310 #if 0 /* I don't understand why this is needed, and it causes problems
5311 when the frame's old selected window has been deleted. */
5312 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
5313 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
5317 /* Set the screen height to the value it had before this function. */
5318 if (previous_frame_lines
!= FRAME_LINES (f
)
5319 || previous_frame_cols
!= FRAME_COLS (f
))
5320 change_frame_size (f
, previous_frame_lines
, previous_frame_cols
,
5322 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
5323 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
5324 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
5326 #ifdef HAVE_WINDOW_SYSTEM
5327 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
5328 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
5333 /* Now, free glyph matrices in windows that were not reused. */
5334 for (i
= n
= 0; i
< n_leaf_windows
; ++i
)
5336 if (NILP (leaf_windows
[i
]->buffer
))
5338 /* Assert it's not reused as a combination. */
5339 xassert (NILP (leaf_windows
[i
]->hchild
)
5340 && NILP (leaf_windows
[i
]->vchild
));
5341 free_window_matrices (leaf_windows
[i
]);
5343 else if (EQ (leaf_windows
[i
]->buffer
, new_current_buffer
))
5351 /* Fselect_window will have made f the selected frame, so we
5352 reselect the proper frame here. Fhandle_switch_frame will change the
5353 selected window too, but that doesn't make the call to
5354 Fselect_window above totally superfluous; it still sets f's
5356 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
5357 do_switch_frame (data
->selected_frame
, 0, 0);
5359 if (! NILP (Vwindow_configuration_change_hook
)
5360 && ! NILP (Vrun_hooks
))
5361 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
5364 if (!NILP (new_current_buffer
))
5365 Fset_buffer (new_current_buffer
);
5367 /* Restore the minimum heights recorded in the configuration. */
5368 window_min_height
= XINT (data
->min_height
);
5369 window_min_width
= XINT (data
->min_width
);
5371 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
5372 minibuf_selected_window
= data
->minibuf_selected_window
;
5374 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
5377 /* Mark all windows now on frame as deleted
5378 by setting their buffers to nil. */
5381 delete_all_subwindows (w
)
5382 register struct window
*w
;
5384 if (!NILP (w
->next
))
5385 delete_all_subwindows (XWINDOW (w
->next
));
5386 if (!NILP (w
->vchild
))
5387 delete_all_subwindows (XWINDOW (w
->vchild
));
5388 if (!NILP (w
->hchild
))
5389 delete_all_subwindows (XWINDOW (w
->hchild
));
5391 w
->total_lines
= w
->buffer
; /* See Fset_window_configuration for excuse. */
5393 if (!NILP (w
->buffer
))
5396 /* We set all three of these fields to nil, to make sure that we can
5397 distinguish this dead window from any live window. Live leaf
5398 windows will have buffer set, and combination windows will have
5399 vchild or hchild set. */
5404 Vwindow_list
= Qnil
;
5408 count_windows (window
)
5409 register struct window
*window
;
5411 register int count
= 1;
5412 if (!NILP (window
->next
))
5413 count
+= count_windows (XWINDOW (window
->next
));
5414 if (!NILP (window
->vchild
))
5415 count
+= count_windows (XWINDOW (window
->vchild
));
5416 if (!NILP (window
->hchild
))
5417 count
+= count_windows (XWINDOW (window
->hchild
));
5422 /* Fill vector FLAT with leaf windows under W, starting at index I.
5423 Value is last index + 1. */
5426 get_leaf_windows (w
, flat
, i
)
5428 struct window
**flat
;
5433 if (!NILP (w
->hchild
))
5434 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
5435 else if (!NILP (w
->vchild
))
5436 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
5440 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5447 /* Return a pointer to the glyph W's physical cursor is on. Value is
5448 null if W's current matrix is invalid, so that no meaningfull glyph
5452 get_phys_cursor_glyph (w
)
5455 struct glyph_row
*row
;
5456 struct glyph
*glyph
;
5458 if (w
->phys_cursor
.vpos
>= 0
5459 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
5460 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
5462 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
5463 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
5472 save_window_save (window
, vector
, i
)
5474 struct Lisp_Vector
*vector
;
5477 register struct saved_window
*p
;
5478 register struct window
*w
;
5479 register Lisp_Object tem
;
5481 for (;!NILP (window
); window
= w
->next
)
5483 p
= SAVED_WINDOW_N (vector
, i
);
5484 w
= XWINDOW (window
);
5486 XSETFASTINT (w
->temslot
, i
++);
5488 p
->buffer
= w
->buffer
;
5489 p
->left_col
= w
->left_col
;
5490 p
->top_line
= w
->top_line
;
5491 p
->total_cols
= w
->total_cols
;
5492 p
->total_lines
= w
->total_lines
;
5493 p
->hscroll
= w
->hscroll
;
5494 p
->min_hscroll
= w
->min_hscroll
;
5495 p
->display_table
= w
->display_table
;
5496 p
->orig_top_line
= w
->orig_top_line
;
5497 p
->orig_total_lines
= w
->orig_total_lines
;
5498 p
->left_margin_cols
= w
->left_margin_cols
;
5499 p
->right_margin_cols
= w
->right_margin_cols
;
5500 p
->left_fringe_width
= w
->left_fringe_width
;
5501 p
->right_fringe_width
= w
->right_fringe_width
;
5502 p
->fringes_outside_margins
= w
->fringes_outside_margins
;
5503 p
->scroll_bar_width
= w
->scroll_bar_width
;
5504 p
->vertical_scroll_bar_type
= w
->vertical_scroll_bar_type
;
5505 if (!NILP (w
->buffer
))
5507 /* Save w's value of point in the window configuration.
5508 If w is the selected window, then get the value of point
5509 from the buffer; pointm is garbage in the selected window. */
5510 if (EQ (window
, selected_window
))
5512 p
->pointm
= Fmake_marker ();
5513 set_marker_both (p
->pointm
, w
->buffer
,
5514 BUF_PT (XBUFFER (w
->buffer
)),
5515 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5518 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
5520 p
->start
= Fcopy_marker (w
->start
, Qnil
);
5521 p
->start_at_line_beg
= w
->start_at_line_beg
;
5523 tem
= XBUFFER (w
->buffer
)->mark
;
5524 p
->mark
= Fcopy_marker (tem
, Qnil
);
5531 p
->start_at_line_beg
= Qnil
;
5534 if (NILP (w
->parent
))
5537 p
->parent
= XWINDOW (w
->parent
)->temslot
;
5542 p
->prev
= XWINDOW (w
->prev
)->temslot
;
5544 if (!NILP (w
->vchild
))
5545 i
= save_window_save (w
->vchild
, vector
, i
);
5546 if (!NILP (w
->hchild
))
5547 i
= save_window_save (w
->hchild
, vector
, i
);
5553 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
5554 Scurrent_window_configuration
, 0, 1, 0,
5555 doc
: /* Return an object representing the current window configuration of FRAME.
5556 If FRAME is nil or omitted, use the selected frame.
5557 This describes the number of windows, their sizes and current buffers,
5558 and for each displayed buffer, where display starts, and the positions of
5559 point and mark. An exception is made for point in the current buffer:
5560 its value is -not- saved.
5561 This also records the currently selected frame, and FRAME's focus
5562 redirection (see `redirect-frame-focus'). */)
5566 register Lisp_Object tem
;
5567 register int n_windows
;
5568 register struct save_window_data
*data
;
5569 register struct Lisp_Vector
*vec
;
5574 frame
= selected_frame
;
5575 CHECK_LIVE_FRAME (frame
);
5578 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5579 vec
= allocate_other_vector (VECSIZE (struct save_window_data
));
5580 data
= (struct save_window_data
*)vec
;
5582 XSETFASTINT (data
->frame_cols
, FRAME_COLS (f
));
5583 XSETFASTINT (data
->frame_lines
, FRAME_LINES (f
));
5584 XSETFASTINT (data
->frame_menu_bar_lines
, FRAME_MENU_BAR_LINES (f
));
5585 XSETFASTINT (data
->frame_tool_bar_lines
, FRAME_TOOL_BAR_LINES (f
));
5586 data
->selected_frame
= selected_frame
;
5587 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
5588 XSETBUFFER (data
->current_buffer
, current_buffer
);
5589 data
->minibuf_scroll_window
= minibuf_level
> 0 ? Vminibuf_scroll_window
: Qnil
;
5590 data
->minibuf_selected_window
= minibuf_level
> 0 ? minibuf_selected_window
: Qnil
;
5591 data
->root_window
= FRAME_ROOT_WINDOW (f
);
5592 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
5593 XSETINT (data
->min_height
, window_min_height
);
5594 XSETINT (data
->min_width
, window_min_width
);
5595 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
5596 data
->saved_windows
= tem
;
5597 for (i
= 0; i
< n_windows
; i
++)
5598 XVECTOR (tem
)->contents
[i
]
5599 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
5600 save_window_save (FRAME_ROOT_WINDOW (f
), XVECTOR (tem
), 0);
5601 XSETWINDOW_CONFIGURATION (tem
, data
);
5605 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
5607 doc
: /* Execute body, preserving window sizes and contents.
5608 Restore which buffer appears in which window, where display starts,
5609 and the value of point and mark for each window.
5610 Also restore the choice of selected window.
5611 Also restore which buffer is current.
5612 Does not restore the value of point in current buffer.
5613 usage: (save-window-excursion BODY ...) */)
5617 register Lisp_Object val
;
5618 register int count
= SPECPDL_INDEX ();
5620 record_unwind_protect (Fset_window_configuration
,
5621 Fcurrent_window_configuration (Qnil
));
5622 val
= Fprogn (args
);
5623 return unbind_to (count
, val
);
5627 /***********************************************************************
5629 ***********************************************************************/
5631 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
5633 doc
: /* Set width of marginal areas of window WINDOW.
5634 If window is nil, set margins of the currently selected window.
5635 First parameter LEFT-WIDTH specifies the number of character
5636 cells to reserve for the left marginal area. Second parameter
5637 RIGHT-WIDTH does the same for the right marginal area.
5638 A nil width parameter means no margin. */)
5639 (window
, left
, right
)
5640 Lisp_Object window
, left
, right
;
5642 struct window
*w
= decode_window (window
);
5644 /* TODO: It doesn't make sense to use FLOATs here, since
5645 the rest of the code assumes they are integers.
5646 So don't allow floats! ++KFS */
5649 CHECK_NUMBER_OR_FLOAT (left
);
5651 CHECK_NUMBER_OR_FLOAT (right
);
5653 /* Check widths < 0 and translate a zero width to nil.
5654 Margins that are too wide have to be checked elsewhere. */
5655 if ((INTEGERP (left
) && XINT (left
) < 0)
5656 || (FLOATP (left
) && XFLOAT_DATA (left
) <= 0))
5657 XSETFASTINT (left
, 0);
5658 if (INTEGERP (left
) && XFASTINT (left
) == 0)
5661 if ((INTEGERP (right
) && XINT (right
) < 0)
5662 || (FLOATP (right
) && XFLOAT_DATA (right
) <= 0))
5663 XSETFASTINT (right
, 0);
5664 if (INTEGERP (right
) && XFASTINT (right
) == 0)
5667 if (!EQ (w
->left_margin_cols
, left
)
5668 || !EQ (w
->right_margin_cols
, right
))
5670 w
->left_margin_cols
= left
;
5671 w
->right_margin_cols
= right
;
5673 adjust_window_margins (w
);
5675 ++windows_or_buffers_changed
;
5676 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
5683 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
5685 doc
: /* Get width of marginal areas of window WINDOW.
5686 If WINDOW is omitted or nil, use the currently selected window.
5687 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).
5688 If a marginal area does not exist, its width will be returned
5693 struct window
*w
= decode_window (window
);
5694 return Fcons (w
->left_margin_cols
, w
->right_margin_cols
);
5699 /***********************************************************************
5701 ***********************************************************************/
5703 DEFUN ("set-window-fringes", Fset_window_fringes
, Sset_window_fringes
,
5705 doc
: /* Set width of fringes of window WINDOW.
5707 If window is nil, set fringes of the currently selected window.
5708 Second parameter LEFT-WIDTH specifies the number of pixels to reserve
5709 for the left fringe. Third parameter RIGHT-WIDTH does the same for
5710 the right fringe. Fourth parameter OUTSIDE-MARGINS non-nil specifies
5711 that fringes are drawn outside of the display margins; by default, fringes
5712 are drawn between display marginal areas and the text area.
5713 A nil width parameter means to use the frame's corresponding fringe width. */)
5714 (window
, left
, right
, outside_margins
)
5715 Lisp_Object window
, left
, right
, outside_margins
;
5717 struct window
*w
= decode_window (window
);
5720 CHECK_NUMBER (left
);
5722 CHECK_NUMBER (right
);
5724 if (!EQ (w
->left_fringe_width
, left
)
5725 || !EQ (w
->right_fringe_width
, right
)
5726 || !EQ (w
->fringes_outside_margins
, outside_margins
))
5728 w
->left_fringe_width
= left
;
5729 w
->right_fringe_width
= right
;
5730 w
->fringes_outside_margins
= outside_margins
;
5732 adjust_window_margins (w
);
5734 clear_glyph_matrix (w
->current_matrix
);
5735 w
->window_end_valid
= Qnil
;
5737 ++windows_or_buffers_changed
;
5738 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
5745 DEFUN ("window-fringes", Fwindow_fringes
, Swindow_fringes
,
5747 doc
: /* Get width of fringes of window WINDOW.
5748 If WINDOW is omitted or nil, use the currently selected window.
5749 Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS).
5750 If a window specific fringe width is not set, its width will be returned
5755 struct window
*w
= decode_window (window
);
5756 return Fcons (make_number (WINDOW_LEFT_FRINGE_WIDTH (w
)),
5757 Fcons (make_number (WINDOW_RIGHT_FRINGE_WIDTH (w
)),
5758 Fcons ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
) ?
5759 Qt
: Qnil
), Qnil
)));
5764 /***********************************************************************
5766 ***********************************************************************/
5768 DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars
, Sset_window_scroll_bars
,
5770 doc
: /* Set width and type of scroll bars of window WINDOW.
5771 If window is nil, set scroll bars of the currently selected window.
5772 Second parameter WIDTH specifies the pixel width for the scroll bar;
5773 this is automatically adjusted to a multiple of the frame column width.
5774 Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
5775 bar: left, right, or nil.
5776 A width of nil and type of t means to use the frame's corresponding value. */)
5777 (window
, width
, vertical_type
, horisontal_type
)
5778 Lisp_Object window
, width
, vertical_type
, horisontal_type
;
5780 struct window
*w
= decode_window (window
);
5783 CHECK_NUMBER (width
);
5785 if (XINT (width
) == 0)
5786 vertical_type
= Qnil
;
5788 if (!EQ (w
->scroll_bar_width
, width
)
5789 || !EQ (w
->vertical_scroll_bar_type
, vertical_type
))
5791 w
->scroll_bar_width
= width
;
5792 w
->vertical_scroll_bar_type
= vertical_type
;
5794 adjust_window_margins (w
);
5796 clear_glyph_matrix (w
->current_matrix
);
5797 w
->window_end_valid
= Qnil
;
5799 ++windows_or_buffers_changed
;
5800 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
5807 DEFUN ("window-scroll-bars", Fwindow_scroll_bars
, Swindow_scroll_bars
,
5809 doc
: /* Get width and type of scroll bars of window WINDOW.
5810 If WINDOW is omitted or nil, use the currently selected window.
5811 Value is a list of the form (WIDTH COLS VERTICAL-TYPE HORISONTAL-TYPE). */)
5815 struct window
*w
= decode_window (window
);
5816 return Fcons (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
)
5817 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
)
5818 : WINDOW_SCROLL_BAR_AREA_WIDTH (w
))),
5819 Fcons (make_number (WINDOW_SCROLL_BAR_COLS (w
)),
5820 Fcons (w
->vertical_scroll_bar_type
,
5821 Fcons (Qnil
, Qnil
))));
5826 /***********************************************************************
5828 ***********************************************************************/
5830 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 1, 0,
5831 doc
: /* Return the amount by which WINDOW is scrolled vertically.
5832 Use the selected window if WINDOW is nil or omitted.
5833 Value is a multiple of the canonical character height of WINDOW. */)
5842 window
= selected_window
;
5844 CHECK_WINDOW (window
);
5845 w
= XWINDOW (window
);
5846 f
= XFRAME (w
->frame
);
5848 if (FRAME_WINDOW_P (f
))
5849 result
= FRAME_CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
);
5851 result
= make_number (0);
5856 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
5858 doc
: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL.
5859 WINDOW nil means use the selected window. VSCROLL is a non-negative
5860 multiple of the canonical character height of WINDOW. */)
5862 Lisp_Object window
, vscroll
;
5868 window
= selected_window
;
5870 CHECK_WINDOW (window
);
5871 CHECK_NUMBER_OR_FLOAT (vscroll
);
5873 w
= XWINDOW (window
);
5874 f
= XFRAME (w
->frame
);
5876 if (FRAME_WINDOW_P (f
))
5878 int old_dy
= w
->vscroll
;
5880 w
->vscroll
= - FRAME_LINE_HEIGHT (f
) * XFLOATINT (vscroll
);
5881 w
->vscroll
= min (w
->vscroll
, 0);
5883 /* Adjust glyph matrix of the frame if the virtual display
5884 area becomes larger than before. */
5885 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
5888 /* Prevent redisplay shortcuts. */
5889 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
5892 return Fwindow_vscroll (window
);
5896 /* Call FN for all leaf windows on frame F. FN is called with the
5897 first argument being a pointer to the leaf window, and with
5898 additional argument USER_DATA. Stops when FN returns 0. */
5901 foreach_window (f
, fn
, user_data
)
5903 int (* fn
) P_ ((struct window
*, void *));
5906 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, user_data
);
5910 /* Helper function for foreach_window. Call FN for all leaf windows
5911 reachable from W. FN is called with the first argument being a
5912 pointer to the leaf window, and with additional argument USER_DATA.
5913 Stop when FN returns 0. Value is 0 if stopped by FN. */
5916 foreach_window_1 (w
, fn
, user_data
)
5918 int (* fn
) P_ ((struct window
*, void *));
5923 for (cont
= 1; w
&& cont
;)
5925 if (!NILP (w
->hchild
))
5926 cont
= foreach_window_1 (XWINDOW (w
->hchild
), fn
, user_data
);
5927 else if (!NILP (w
->vchild
))
5928 cont
= foreach_window_1 (XWINDOW (w
->vchild
), fn
, user_data
);
5930 cont
= fn (w
, user_data
);
5932 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5939 /* Freeze or unfreeze the window start of W unless it is a
5940 mini-window or the selected window. FREEZE_P non-null means freeze
5941 the window start. */
5944 freeze_window_start (w
, freeze_p
)
5948 if (w
== XWINDOW (selected_window
)
5949 || MINI_WINDOW_P (w
)
5950 || (MINI_WINDOW_P (XWINDOW (selected_window
))
5951 && ! NILP (Vminibuf_scroll_window
)
5952 && w
== XWINDOW (Vminibuf_scroll_window
)))
5955 w
->frozen_window_start_p
= freeze_p
!= NULL
;
5960 /* Freeze or unfreeze the window starts of all leaf windows on frame
5961 F, except the selected window and a mini-window. FREEZE_P non-zero
5962 means freeze the window start. */
5965 freeze_window_starts (f
, freeze_p
)
5969 foreach_window (f
, freeze_window_start
, (void *) (freeze_p
? f
: 0));
5973 /***********************************************************************
5975 ***********************************************************************/
5977 /* Return 1 if window configurations C1 and C2
5978 describe the same state of affairs. This is used by Fequal. */
5981 compare_window_configurations (c1
, c2
, ignore_positions
)
5983 int ignore_positions
;
5985 register struct save_window_data
*d1
, *d2
;
5986 struct Lisp_Vector
*sw1
, *sw2
;
5989 if (!WINDOW_CONFIGURATIONP (c1
))
5990 wrong_type_argument (Qwindow_configuration_p
, c1
);
5991 if (!WINDOW_CONFIGURATIONP (c2
))
5992 wrong_type_argument (Qwindow_configuration_p
, c2
);
5994 d1
= (struct save_window_data
*) XVECTOR (c1
);
5995 d2
= (struct save_window_data
*) XVECTOR (c2
);
5996 sw1
= XVECTOR (d1
->saved_windows
);
5997 sw2
= XVECTOR (d2
->saved_windows
);
5999 if (! EQ (d1
->frame_cols
, d2
->frame_cols
))
6001 if (! EQ (d1
->frame_lines
, d2
->frame_lines
))
6003 if (! EQ (d1
->frame_menu_bar_lines
, d2
->frame_menu_bar_lines
))
6005 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
6007 /* Don't compare the current_window field directly.
6008 Instead see w1_is_current and w2_is_current, below. */
6009 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
6011 if (! ignore_positions
)
6013 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
6015 if (! EQ (d1
->minibuf_selected_window
, d2
->minibuf_selected_window
))
6018 /* Don't compare the root_window field.
6019 We don't require the two configurations
6020 to use the same window object,
6021 and the two root windows must be equivalent
6022 if everything else compares equal. */
6023 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
6025 if (! EQ (d1
->min_width
, d2
->min_width
))
6027 if (! EQ (d1
->min_height
, d2
->min_height
))
6030 /* Verify that the two confis have the same number of windows. */
6031 if (sw1
->size
!= sw2
->size
)
6034 for (i
= 0; i
< sw1
->size
; i
++)
6036 struct saved_window
*p1
, *p2
;
6037 int w1_is_current
, w2_is_current
;
6039 p1
= SAVED_WINDOW_N (sw1
, i
);
6040 p2
= SAVED_WINDOW_N (sw2
, i
);
6042 /* Verify that the current windows in the two
6043 configurations correspond to each other. */
6044 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
6045 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
6047 if (w1_is_current
!= w2_is_current
)
6050 /* Verify that the corresponding windows do match. */
6051 if (! EQ (p1
->buffer
, p2
->buffer
))
6053 if (! EQ (p1
->left_col
, p2
->left_col
))
6055 if (! EQ (p1
->top_line
, p2
->top_line
))
6057 if (! EQ (p1
->total_cols
, p2
->total_cols
))
6059 if (! EQ (p1
->total_lines
, p2
->total_lines
))
6061 if (! EQ (p1
->display_table
, p2
->display_table
))
6063 if (! EQ (p1
->parent
, p2
->parent
))
6065 if (! EQ (p1
->prev
, p2
->prev
))
6067 if (! ignore_positions
)
6069 if (! EQ (p1
->hscroll
, p2
->hscroll
))
6071 if (!EQ (p1
->min_hscroll
, p2
->min_hscroll
))
6073 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
6075 if (NILP (Fequal (p1
->start
, p2
->start
)))
6077 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
6079 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
6082 if (! EQ (p1
->left_margin_cols
, p2
->left_margin_cols
))
6084 if (! EQ (p1
->right_margin_cols
, p2
->right_margin_cols
))
6086 if (! EQ (p1
->left_fringe_width
, p2
->left_fringe_width
))
6088 if (! EQ (p1
->right_fringe_width
, p2
->right_fringe_width
))
6090 if (! EQ (p1
->fringes_outside_margins
, p2
->fringes_outside_margins
))
6092 if (! EQ (p1
->scroll_bar_width
, p2
->scroll_bar_width
))
6094 if (! EQ (p1
->vertical_scroll_bar_type
, p2
->vertical_scroll_bar_type
))
6101 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
6102 Scompare_window_configurations
, 2, 2, 0,
6103 doc
: /* Compare two window configurations as regards the structure of windows.
6104 This function ignores details such as the values of point and mark
6105 and scrolling positions. */)
6109 if (compare_window_configurations (x
, y
, 1))
6117 struct frame
*f
= make_terminal_frame ();
6118 XSETFRAME (selected_frame
, f
);
6119 Vterminal_frame
= selected_frame
;
6120 minibuf_window
= f
->minibuffer_window
;
6121 selected_window
= f
->selected_window
;
6122 last_nonminibuf_frame
= f
;
6124 window_initialized
= 1;
6130 Vwindow_list
= Qnil
;
6136 Qwindow_size_fixed
= intern ("window-size-fixed");
6137 staticpro (&Qwindow_size_fixed
);
6139 staticpro (&Qwindow_configuration_change_hook
);
6140 Qwindow_configuration_change_hook
6141 = intern ("window-configuration-change-hook");
6143 Qwindowp
= intern ("windowp");
6144 staticpro (&Qwindowp
);
6146 Qwindow_configuration_p
= intern ("window-configuration-p");
6147 staticpro (&Qwindow_configuration_p
);
6149 Qwindow_live_p
= intern ("window-live-p");
6150 staticpro (&Qwindow_live_p
);
6152 Qtemp_buffer_show_hook
= intern ("temp-buffer-show-hook");
6153 staticpro (&Qtemp_buffer_show_hook
);
6155 staticpro (&Vwindow_list
);
6157 minibuf_selected_window
= Qnil
;
6158 staticpro (&minibuf_selected_window
);
6160 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
6161 doc
: /* Non-nil means call as function to display a help buffer.
6162 The function is called with one argument, the buffer to be displayed.
6163 Used by `with-output-to-temp-buffer'.
6164 If this function is used, then it must do the entire job of showing
6165 the buffer; `temp-buffer-show-hook' is not run unless this function runs it. */);
6166 Vtemp_buffer_show_function
= Qnil
;
6168 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
6169 doc
: /* If non-nil, function to call to handle `display-buffer'.
6170 It will receive two args, the buffer and a flag which if non-nil means
6171 that the currently selected window is not acceptable.
6172 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'
6173 work using this function. */);
6174 Vdisplay_buffer_function
= Qnil
;
6176 DEFVAR_LISP ("even-window-heights", &Veven_window_heights
,
6177 doc
: /* *If non-nil, `display-buffer' should even the window heights.
6178 If nil, `display-buffer' will leave the window configuration alone. */);
6179 Veven_window_heights
= Qt
;
6181 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
6182 doc
: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */);
6183 Vminibuf_scroll_window
= Qnil
;
6185 DEFVAR_BOOL ("mode-line-in-non-selected-windows", &mode_line_in_non_selected_windows
,
6186 doc
: /* Non-nil means to use `mode-line-inactive' face in non-selected windows.
6187 If the minibuffer is active, the `minibuffer-scroll-window' mode line
6188 is displayed in the `mode-line' face. */);
6189 mode_line_in_non_selected_windows
= 1;
6191 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
6192 doc
: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. */);
6193 Vother_window_scroll_buffer
= Qnil
;
6195 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
6196 doc
: /* *Non-nil means `display-buffer' should make a separate frame. */);
6199 DEFVAR_BOOL ("display-buffer-reuse-frames", &display_buffer_reuse_frames
,
6200 doc
: /* *Non-nil means `display-buffer' should reuse frames.
6201 If the buffer in question is already displayed in a frame, raise that frame. */);
6202 display_buffer_reuse_frames
= 0;
6204 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
6205 doc
: /* Function to call to handle automatic new frame creation.
6206 It is called with no arguments and should return a newly created frame.
6208 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'
6209 where `pop-up-frame-alist' would hold the default frame parameters. */);
6210 Vpop_up_frame_function
= Qnil
;
6212 DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names
,
6213 doc
: /* *List of buffer names that should have their own special frames.
6214 Displaying a buffer whose name is in this list makes a special frame for it
6215 using `special-display-function'. See also `special-display-regexps'.
6217 An element of the list can be a list instead of just a string.
6218 There are two ways to use a list as an element:
6219 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)
6220 In the first case, FRAME-PARAMETERS are used to create the frame.
6221 In the latter case, FUNCTION is called with BUFFER as the first argument,
6222 followed by OTHER-ARGS--it can display BUFFER in any way it likes.
6223 All this is done by the function found in `special-display-function'.
6225 If this variable appears \"not to work\", because you add a name to it
6226 but that buffer still appears in the selected window, look at the
6227 values of `same-window-buffer-names' and `same-window-regexps'.
6228 Those variables take precedence over this one. */);
6229 Vspecial_display_buffer_names
= Qnil
;
6231 DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps
,
6232 doc
: /* *List of regexps saying which buffers should have their own special frames.
6233 If a buffer name matches one of these regexps, it gets its own frame.
6234 Displaying a buffer whose name is in this list makes a special frame for it
6235 using `special-display-function'.
6237 An element of the list can be a list instead of just a string.
6238 There are two ways to use a list as an element:
6239 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)
6240 In the first case, FRAME-PARAMETERS are used to create the frame.
6241 In the latter case, FUNCTION is called with the buffer as first argument,
6242 followed by OTHER-ARGS--it can display the buffer in any way it likes.
6243 All this is done by the function found in `special-display-function'.
6245 If this variable appears \"not to work\", because you add a regexp to it
6246 but the matching buffers still appear in the selected window, look at the
6247 values of `same-window-buffer-names' and `same-window-regexps'.
6248 Those variables take precedence over this one. */);
6249 Vspecial_display_regexps
= Qnil
;
6251 DEFVAR_LISP ("special-display-function", &Vspecial_display_function
,
6252 doc
: /* Function to call to make a new frame for a special buffer.
6253 It is called with two arguments, the buffer and optional buffer specific
6254 data, and should return a window displaying that buffer.
6255 The default value normally makes a separate frame for the buffer,
6256 using `special-display-frame-alist' to specify the frame parameters.
6257 But if the buffer specific data includes (same-buffer . t) then the
6258 buffer is displayed in the current selected window.
6259 Otherwise if it includes (same-frame . t) then the buffer is displayed in
6260 a new window in the currently selected frame.
6262 A buffer is special if it is listed in `special-display-buffer-names'
6263 or matches a regexp in `special-display-regexps'. */);
6264 Vspecial_display_function
= Qnil
;
6266 DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names
,
6267 doc
: /* *List of buffer names that should appear in the selected window.
6268 Displaying one of these buffers using `display-buffer' or `pop-to-buffer'
6269 switches to it in the selected window, rather than making it appear
6270 in some other window.
6272 An element of the list can be a cons cell instead of just a string.
6273 Then the car must be a string, which specifies the buffer name.
6274 This is for compatibility with `special-display-buffer-names';
6275 the cdr of the cons cell is ignored.
6277 See also `same-window-regexps'. */);
6278 Vsame_window_buffer_names
= Qnil
;
6280 DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps
,
6281 doc
: /* *List of regexps saying which buffers should appear in the selected window.
6282 If a buffer name matches one of these regexps, then displaying it
6283 using `display-buffer' or `pop-to-buffer' switches to it
6284 in the selected window, rather than making it appear in some other window.
6286 An element of the list can be a cons cell instead of just a string.
6287 Then the car must be a string, which specifies the buffer name.
6288 This is for compatibility with `special-display-buffer-names';
6289 the cdr of the cons cell is ignored.
6291 See also `same-window-buffer-names'. */);
6292 Vsame_window_regexps
= Qnil
;
6294 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
6295 doc
: /* *Non-nil means display-buffer should make new windows. */);
6298 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
6299 doc
: /* *Number of lines of continuity when scrolling by screenfuls. */);
6300 next_screen_context_lines
= 2;
6302 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
6303 doc
: /* *display-buffer would prefer to split the largest window if this large.
6304 If there is only one window, it is split regardless of this value. */);
6305 split_height_threshold
= 500;
6307 DEFVAR_INT ("window-min-height", &window_min_height
,
6308 doc
: /* *Delete any window less than this tall (including its mode line). */);
6309 window_min_height
= 4;
6311 DEFVAR_INT ("window-min-width", &window_min_width
,
6312 doc
: /* *Delete any window less than this wide. */);
6313 window_min_width
= 10;
6315 DEFVAR_LISP ("scroll-preserve-screen-position",
6316 &Vscroll_preserve_screen_position
,
6317 doc
: /* *Non-nil means scroll commands move point to keep its screen line unchanged. */);
6318 Vscroll_preserve_screen_position
= Qnil
;
6320 DEFVAR_LISP ("window-configuration-change-hook",
6321 &Vwindow_configuration_change_hook
,
6322 doc
: /* Functions to call when window configuration changes.
6323 The selected frame is the one whose configuration has changed. */);
6324 Vwindow_configuration_change_hook
= Qnil
;
6326 DEFVAR_BOOL ("window-size-fixed", &window_size_fixed
,
6327 doc
: /* Non-nil in a buffer means windows displaying the buffer are fixed-size.
6328 Emacs won't change the size of any window displaying that buffer,
6329 unless you explicitly change the size, or Emacs has no other choice.
6330 This variable automatically becomes buffer-local when set. */);
6331 Fmake_variable_buffer_local (Qwindow_size_fixed
);
6332 window_size_fixed
= 0;
6334 defsubr (&Sselected_window
);
6335 defsubr (&Sminibuffer_window
);
6336 defsubr (&Swindow_minibuffer_p
);
6337 defsubr (&Swindowp
);
6338 defsubr (&Swindow_live_p
);
6339 defsubr (&Spos_visible_in_window_p
);
6340 defsubr (&Swindow_buffer
);
6341 defsubr (&Swindow_height
);
6342 defsubr (&Swindow_width
);
6343 defsubr (&Swindow_hscroll
);
6344 defsubr (&Sset_window_hscroll
);
6345 defsubr (&Swindow_redisplay_end_trigger
);
6346 defsubr (&Sset_window_redisplay_end_trigger
);
6347 defsubr (&Swindow_edges
);
6348 defsubr (&Scoordinates_in_window_p
);
6349 defsubr (&Swindow_at
);
6350 defsubr (&Swindow_point
);
6351 defsubr (&Swindow_start
);
6352 defsubr (&Swindow_end
);
6353 defsubr (&Sset_window_point
);
6354 defsubr (&Sset_window_start
);
6355 defsubr (&Swindow_dedicated_p
);
6356 defsubr (&Sset_window_dedicated_p
);
6357 defsubr (&Swindow_display_table
);
6358 defsubr (&Sset_window_display_table
);
6359 defsubr (&Snext_window
);
6360 defsubr (&Sprevious_window
);
6361 defsubr (&Sother_window
);
6362 defsubr (&Sget_lru_window
);
6363 defsubr (&Sget_largest_window
);
6364 defsubr (&Sget_buffer_window
);
6365 defsubr (&Sdelete_other_windows
);
6366 defsubr (&Sdelete_windows_on
);
6367 defsubr (&Sreplace_buffer_in_windows
);
6368 defsubr (&Sdelete_window
);
6369 defsubr (&Sset_window_buffer
);
6370 defsubr (&Sselect_window
);
6371 defsubr (&Sspecial_display_p
);
6372 defsubr (&Ssame_window_p
);
6373 defsubr (&Sdisplay_buffer
);
6374 defsubr (&Ssplit_window
);
6375 defsubr (&Senlarge_window
);
6376 defsubr (&Sshrink_window
);
6377 defsubr (&Sscroll_up
);
6378 defsubr (&Sscroll_down
);
6379 defsubr (&Sscroll_left
);
6380 defsubr (&Sscroll_right
);
6381 defsubr (&Sother_window_for_scrolling
);
6382 defsubr (&Sscroll_other_window
);
6383 defsubr (&Sminibuffer_selected_window
);
6384 defsubr (&Srecenter
);
6385 defsubr (&Swindow_text_height
);
6386 defsubr (&Smove_to_window_line
);
6387 defsubr (&Swindow_configuration_p
);
6388 defsubr (&Swindow_configuration_frame
);
6389 defsubr (&Sset_window_configuration
);
6390 defsubr (&Scurrent_window_configuration
);
6391 defsubr (&Ssave_window_excursion
);
6392 defsubr (&Sset_window_margins
);
6393 defsubr (&Swindow_margins
);
6394 defsubr (&Sset_window_fringes
);
6395 defsubr (&Swindow_fringes
);
6396 defsubr (&Sset_window_scroll_bars
);
6397 defsubr (&Swindow_scroll_bars
);
6398 defsubr (&Swindow_vscroll
);
6399 defsubr (&Sset_window_vscroll
);
6400 defsubr (&Scompare_window_configurations
);
6401 defsubr (&Swindow_list
);
6407 initial_define_key (control_x_map
, '1', "delete-other-windows");
6408 initial_define_key (control_x_map
, '2', "split-window");
6409 initial_define_key (control_x_map
, '0', "delete-window");
6410 initial_define_key (control_x_map
, 'o', "other-window");
6411 initial_define_key (control_x_map
, '^', "enlarge-window");
6412 initial_define_key (control_x_map
, '<', "scroll-left");
6413 initial_define_key (control_x_map
, '>', "scroll-right");
6415 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
6416 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
6417 initial_define_key (meta_map
, 'v', "scroll-down");
6419 initial_define_key (global_map
, Ctl('L'), "recenter");
6420 initial_define_key (meta_map
, 'r', "move-to-window-line");