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
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 */
51 /* Values returned from coordinates_in_window. */
65 Lisp_Object Qwindowp
, Qwindow_live_p
, Qwindow_configuration_p
;
66 Lisp_Object Qwindow_size_fixed
;
67 extern Lisp_Object Qheight
, Qwidth
;
69 static int displayed_window_lines
P_ ((struct window
*));
70 static struct window
*decode_window
P_ ((Lisp_Object
));
71 static Lisp_Object select_window_1
P_ ((Lisp_Object
, int));
72 static int count_windows
P_ ((struct window
*));
73 static int get_leaf_windows
P_ ((struct window
*, struct window
**, int));
74 static void window_scroll
P_ ((Lisp_Object
, int, int, int));
75 static void window_scroll_pixel_based
P_ ((Lisp_Object
, int, int, int));
76 static void window_scroll_line_based
P_ ((Lisp_Object
, int, int, int));
77 static int window_min_size_1
P_ ((struct window
*, int));
78 static int window_min_size
P_ ((struct window
*, int, int, int *));
79 static void size_window
P_ ((Lisp_Object
, int, int, int));
80 static int freeze_window_start
P_ ((struct window
*, void *));
81 static int window_fixed_size_p
P_ ((struct window
*, int, int));
82 static void enlarge_window
P_ ((Lisp_Object
, int, int, int));
83 static Lisp_Object window_list
P_ ((void));
84 static int add_window_to_list
P_ ((struct window
*, void *));
85 static int candidate_window_p
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
,
87 static Lisp_Object next_window
P_ ((Lisp_Object
, Lisp_Object
,
89 static void decode_next_window_args
P_ ((Lisp_Object
*, Lisp_Object
*,
91 static int foreach_window_1
P_ ((struct window
*,
92 int (* fn
) (struct window
*, void *),
94 static Lisp_Object window_list_1
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
));
96 /* The value of `window-size-fixed'. */
98 int window_size_fixed
;
100 /* This is the window in which the terminal's cursor should
101 be left when nothing is being done with it. This must
102 always be a leaf window, and its buffer is selected by
103 the top level editing loop at the end of each command.
105 This value is always the same as
106 FRAME_SELECTED_WINDOW (selected_frame). */
108 Lisp_Object selected_window
;
110 /* A list of all windows for use by next_window and Fwindow_list.
111 Functions creating or deleting windows should invalidate this cache
112 by setting it to nil. */
114 Lisp_Object Vwindow_list
;
116 /* The mini-buffer window of the selected frame.
117 Note that you cannot test for mini-bufferness of an arbitrary window
118 by comparing against this; but you can test for mini-bufferness of
119 the selected window. */
121 Lisp_Object minibuf_window
;
123 /* Non-nil means it is the window for C-M-v to scroll
124 when the mini-buffer is selected. */
126 Lisp_Object Vminibuf_scroll_window
;
128 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
130 Lisp_Object Vother_window_scroll_buffer
;
132 /* Non-nil means it's function to call to display temp buffers. */
134 Lisp_Object Vtemp_buffer_show_function
;
136 /* If a window gets smaller than either of these, it is removed. */
138 int window_min_height
;
139 int window_min_width
;
141 /* Nonzero implies Fdisplay_buffer should create windows. */
145 /* Nonzero implies make new frames for Fdisplay_buffer. */
149 /* Nonzero means reuse existing frames for displaying buffers. */
151 int display_buffer_reuse_frames
;
153 /* Non-nil means use this function instead of default */
155 Lisp_Object Vpop_up_frame_function
;
157 /* Function to call to handle Fdisplay_buffer. */
159 Lisp_Object Vdisplay_buffer_function
;
161 /* Non-nil means that Fdisplay_buffer should even the heights of windows. */
163 Lisp_Object Veven_window_heights
;
165 /* List of buffer *names* for buffers that should have their own frames. */
167 Lisp_Object Vspecial_display_buffer_names
;
169 /* List of regexps for buffer names that should have their own frames. */
171 Lisp_Object Vspecial_display_regexps
;
173 /* Function to pop up a special frame. */
175 Lisp_Object Vspecial_display_function
;
177 /* List of buffer *names* for buffers to appear in selected window. */
179 Lisp_Object Vsame_window_buffer_names
;
181 /* List of regexps for buffer names to appear in selected window. */
183 Lisp_Object Vsame_window_regexps
;
185 /* Hook run at end of temp_output_buffer_show. */
187 Lisp_Object Qtemp_buffer_show_hook
;
189 /* Fdisplay_buffer always splits the largest window
190 if that window is more than this high. */
192 int split_height_threshold
;
194 /* Number of lines of continuity in scrolling by screenfuls. */
196 int next_screen_context_lines
;
198 /* Incremented for each window created. */
200 static int sequence_number
;
202 /* Nonzero after init_window_once has finished. */
204 static int window_initialized
;
206 /* Hook to run when window config changes. */
208 Lisp_Object Qwindow_configuration_change_hook
;
209 Lisp_Object Vwindow_configuration_change_hook
;
211 /* Nonzero means scroll commands try to put point
212 at the same screen height as previously. */
214 Lisp_Object Vscroll_preserve_screen_position
;
216 #if 0 /* This isn't used anywhere. */
217 /* Nonzero means we can split a frame even if it is "unsplittable". */
218 static int inhibit_frame_unsplittable
;
221 extern int scroll_margin
;
223 extern Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
225 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
226 doc
: /* Returns t if OBJECT is a window. */)
230 return WINDOWP (object
) ? Qt
: Qnil
;
233 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
234 doc
: /* Returns t if OBJECT is a window which is currently visible. */)
238 return WINDOW_LIVE_P (object
) ? Qt
: Qnil
;
245 register struct window
*p
;
247 p
= allocate_window ();
248 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
249 XSETFASTINT (p
->left
, 0);
250 XSETFASTINT (p
->top
, 0);
251 XSETFASTINT (p
->height
, 0);
252 XSETFASTINT (p
->width
, 0);
253 XSETFASTINT (p
->hscroll
, 0);
254 XSETFASTINT (p
->min_hscroll
, 0);
255 p
->orig_top
= p
->orig_height
= Qnil
;
256 p
->start
= Fmake_marker ();
257 p
->pointm
= Fmake_marker ();
258 XSETFASTINT (p
->use_time
, 0);
260 p
->display_table
= Qnil
;
262 p
->pseudo_window_p
= 0;
263 bzero (&p
->cursor
, sizeof (p
->cursor
));
264 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
265 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
266 p
->desired_matrix
= p
->current_matrix
= 0;
267 p
->phys_cursor_type
= -1;
268 p
->must_be_updated_p
= 0;
269 XSETFASTINT (p
->window_end_vpos
, 0);
270 XSETFASTINT (p
->window_end_pos
, 0);
271 p
->window_end_valid
= Qnil
;
274 XSETFASTINT (p
->last_point
, 0);
275 p
->frozen_window_start_p
= 0;
281 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
282 doc
: /* Return the window that the cursor now appears in and commands apply to. */)
285 return selected_window
;
288 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
289 doc
: /* Return the window used now for minibuffers.
290 If the optional argument FRAME is specified, return the minibuffer window
291 used by that frame. */)
296 frame
= selected_frame
;
297 CHECK_LIVE_FRAME (frame
);
298 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
301 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 0, 1, 0,
302 doc
: /* Returns non-nil if WINDOW is a minibuffer window. */)
306 struct window
*w
= decode_window (window
);
307 return MINI_WINDOW_P (w
) ? Qt
: Qnil
;
311 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
312 Spos_visible_in_window_p
, 0, 3, 0,
313 doc
: /* Return t if position POS is currently on the frame in WINDOW.
314 Return nil if that position is scrolled vertically out of view.
315 If a character is only partially visible, nil is returned, unless the
316 optional argument PARTIALLY is non-nil.
317 POS defaults to point in WINDOW; WINDOW defaults to the selected window. */)
318 (pos
, window
, partially
)
319 Lisp_Object pos
, window
, partially
;
321 register struct window
*w
;
323 register struct buffer
*buf
;
325 Lisp_Object in_window
;
328 w
= decode_window (window
);
329 buf
= XBUFFER (w
->buffer
);
330 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
334 CHECK_NUMBER_COERCE_MARKER (pos
);
337 else if (w
== XWINDOW (selected_window
))
340 posint
= XMARKER (w
->pointm
)->charpos
;
342 /* If position is above window start, it's not visible. */
343 if (posint
< CHARPOS (top
))
345 else if (XFASTINT (w
->last_modified
) >= BUF_MODIFF (buf
)
346 && XFASTINT (w
->last_overlay_modified
) >= BUF_OVERLAY_MODIFF (buf
)
347 && posint
< BUF_Z (buf
) - XFASTINT (w
->window_end_pos
))
349 /* If frame is up-to-date, and POSINT is < window end pos, use
350 that info. This doesn't work for POSINT == end pos, because
351 the window end pos is actually the position _after_ the last
352 char in the window. */
353 if (NILP (partially
))
355 pos_visible_p (w
, posint
, &fully_p
, NILP (partially
));
356 in_window
= fully_p
? Qt
: Qnil
;
361 else if (posint
> BUF_ZV (buf
))
363 else if (CHARPOS (top
) < BUF_BEGV (buf
) || CHARPOS (top
) > BUF_ZV (buf
))
364 /* If window start is out of range, do something reasonable. */
368 if (pos_visible_p (w
, posint
, &fully_p
, NILP (partially
)))
369 in_window
= !NILP (partially
) || fully_p
? Qt
: Qnil
;
378 static struct window
*
379 decode_window (window
)
380 register Lisp_Object window
;
383 return XWINDOW (selected_window
);
385 CHECK_LIVE_WINDOW (window
);
386 return XWINDOW (window
);
389 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
390 doc
: /* Return the buffer that WINDOW is displaying. */)
394 return decode_window (window
)->buffer
;
397 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
398 doc
: /* Return the number of lines in WINDOW (including its mode line). */)
402 return decode_window (window
)->height
;
405 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
406 doc
: /* Return the number of display columns in WINDOW.
407 This is the width that is usable columns available for text in WINDOW.
408 If you want to find out how many columns WINDOW takes up,
409 use (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))). */)
413 return make_number (window_internal_width (decode_window (window
)));
416 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
417 doc
: /* Return the number of columns by which WINDOW is scrolled from left margin. */)
421 return decode_window (window
)->hscroll
;
424 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
425 doc
: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
426 NCOL should be zero or positive. */)
428 Lisp_Object window
, ncol
;
430 struct window
*w
= decode_window (window
);
434 hscroll
= max (0, XINT (ncol
));
436 /* Prevent redisplay shortcuts when changing the hscroll. */
437 if (XINT (w
->hscroll
) != hscroll
)
438 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
440 w
->hscroll
= make_number (hscroll
);
444 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
445 Swindow_redisplay_end_trigger
, 0, 1, 0,
446 doc
: /* Return WINDOW's redisplay end trigger value.
447 See `set-window-redisplay-end-trigger' for more information. */)
451 return decode_window (window
)->redisplay_end_trigger
;
454 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
455 Sset_window_redisplay_end_trigger
, 2, 2, 0,
456 doc
: /* Set WINDOW's redisplay end trigger value to VALUE.
457 VALUE should be a buffer position (typically a marker) or nil.
458 If it is a buffer position, then if redisplay in WINDOW reaches a position
459 beyond VALUE, the functions in `redisplay-end-trigger-functions' are called
460 with two arguments: WINDOW, and the end trigger value.
461 Afterwards the end-trigger value is reset to nil. */)
463 register Lisp_Object window
, value
;
465 register struct window
*w
;
467 w
= decode_window (window
);
468 w
->redisplay_end_trigger
= value
;
472 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
473 doc
: /* Return a list of the edge coordinates of WINDOW.
474 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.
475 RIGHT is one more than the rightmost column used by WINDOW,
476 and BOTTOM is one more than the bottommost row used by WINDOW
477 and its mode-line. */)
481 register struct window
*w
= decode_window (window
);
483 return Fcons (w
->left
, Fcons (w
->top
,
484 Fcons (make_number (WINDOW_RIGHT_EDGE (w
)),
485 Fcons (make_number (XFASTINT (w
->top
)
486 + XFASTINT (w
->height
)),
490 /* Test if the character at column *X, row *Y is within window W.
491 If it is not, return 0;
492 if it is in the window's text area,
493 set *x and *y to its location relative to the upper left corner
496 if it is on the window's modeline, return 2;
497 if it is on the border between the window and its right sibling,
499 if it is on the window's top line, return 4;
500 if it is in left or right fringe of the window,
501 return 5 or 6, and convert *X and *Y to window-relative corrdinates.
503 X and Y are frame relative pixel coordinates. */
505 static enum window_part
506 coordinates_in_window (w
, x
, y
)
507 register struct window
*w
;
510 /* Let's make this a global enum later, instead of using numbers
512 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
513 int left_x
, right_x
, top_y
, bottom_y
;
514 enum window_part part
;
515 int ux
= CANON_X_UNIT (f
);
516 int x0
= XFASTINT (w
->left
) * ux
;
517 int x1
= x0
+ XFASTINT (w
->width
) * ux
;
518 /* The width of the area where the vertical line can be dragged.
519 (Between mode lines for instance. */
520 int grabbable_width
= ux
;
522 if (*x
< x0
|| *x
>= x1
)
525 /* In what's below, we subtract 1 when computing right_x because we
526 want the rightmost pixel, which is given by left_pixel+width-1. */
527 if (w
->pseudo_window_p
)
530 right_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
) - 1;
531 top_y
= WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
);
532 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
536 left_x
= (WINDOW_DISPLAY_LEFT_EDGE_PIXEL_X (w
)
537 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
538 right_x
= WINDOW_DISPLAY_RIGHT_EDGE_PIXEL_X (w
) - 1;
539 top_y
= (WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
)
540 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
541 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
544 /* On the mode line or header line? If it's near the start of
545 the mode or header line of window that's has a horizontal
546 sibling, say it's on the vertical line. That's to be able
547 to resize windows horizontally in case we're using toolkit
550 if (WINDOW_WANTS_MODELINE_P (w
)
551 && *y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
)
554 /* We're somewhere on the mode line. We consider the place
555 between mode lines of horizontally adjacent mode lines
556 as the vertical border. If scroll bars on the left,
557 return the right window. */
560 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
562 if (abs (*x
- x0
) < grabbable_width
)
563 part
= ON_VERTICAL_BORDER
;
565 else if (!WINDOW_RIGHTMOST_P (w
) && abs (*x
- x1
) < grabbable_width
)
566 part
= ON_VERTICAL_BORDER
;
568 else if (WINDOW_WANTS_HEADER_LINE_P (w
)
569 && *y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
)
572 part
= ON_HEADER_LINE
;
574 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
576 if (abs (*x
- x0
) < grabbable_width
)
577 part
= ON_VERTICAL_BORDER
;
579 else if (!WINDOW_RIGHTMOST_P (w
) && abs (*x
- x1
) < grabbable_width
)
580 part
= ON_VERTICAL_BORDER
;
582 /* Outside anything interesting? */
586 - FRAME_LEFT_FRINGE_WIDTH (f
)
587 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * ux
)
589 + FRAME_RIGHT_FRINGE_WIDTH (f
)
590 + FRAME_RIGHT_SCROLL_BAR_WIDTH (f
) * ux
))
594 else if (FRAME_WINDOW_P (f
))
596 if (!w
->pseudo_window_p
597 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
598 && !WINDOW_RIGHTMOST_P (w
)
599 && (abs (*x
- right_x
- FRAME_RIGHT_FRINGE_WIDTH (f
)) < grabbable_width
))
601 part
= ON_VERTICAL_BORDER
;
603 else if (*x
< left_x
|| *x
> right_x
)
605 /* Other lines than the mode line don't include fringes and
606 scroll bars on the left. */
608 /* Convert X and Y to window-relative pixel coordinates. */
611 part
= *x
< left_x
? ON_LEFT_FRINGE
: ON_RIGHT_FRINGE
;
622 /* Need to say "*x > right_x" rather than >=, since on character
623 terminals, the vertical line's x coordinate is right_x. */
624 if (*x
< left_x
|| *x
> right_x
)
626 /* Other lines than the mode line don't include fringes and
627 scroll bars on the left. */
629 /* Convert X and Y to window-relative pixel coordinates. */
632 part
= *x
< left_x
? ON_LEFT_FRINGE
: ON_RIGHT_FRINGE
;
634 /* Here, too, "*x > right_x" is because of character terminals. */
635 else if (!w
->pseudo_window_p
636 && !WINDOW_RIGHTMOST_P (w
)
637 && *x
> right_x
- ux
)
639 /* On the border on the right side of the window? Assume that
640 this area begins at RIGHT_X minus a canonical char width. */
641 part
= ON_VERTICAL_BORDER
;
645 /* Convert X and Y to window-relative pixel coordinates. */
656 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
657 Scoordinates_in_window_p
, 2, 2, 0,
658 doc
: /* Return non-nil if COORDINATES are in WINDOW.
659 COORDINATES is a cons of the form (X . Y), X and Y being distances
660 measured in characters from the upper-left corner of the frame.
661 \(0 . 0) denotes the character in the upper left corner of the
663 If COORDINATES are in the text portion of WINDOW,
664 the coordinates relative to the window are returned.
665 If they are in the mode line of WINDOW, `mode-line' is returned.
666 If they are in the top mode line of WINDOW, `header-line' is returned.
667 If they are in the left fringe of WINDOW, `left-fringe' is returned.
668 If they are in the right fringe of WINDOW, `right-fringe' is returned.
669 If they are on the border between WINDOW and its right sibling,
670 `vertical-line' is returned. */)
671 (coordinates
, window
)
672 register Lisp_Object coordinates
, window
;
679 CHECK_LIVE_WINDOW (window
);
680 w
= XWINDOW (window
);
681 f
= XFRAME (w
->frame
);
682 CHECK_CONS (coordinates
);
683 lx
= Fcar (coordinates
);
684 ly
= Fcdr (coordinates
);
685 CHECK_NUMBER_OR_FLOAT (lx
);
686 CHECK_NUMBER_OR_FLOAT (ly
);
687 x
= PIXEL_X_FROM_CANON_X (f
, lx
);
688 y
= PIXEL_Y_FROM_CANON_Y (f
, ly
);
690 switch (coordinates_in_window (w
, &x
, &y
))
696 /* X and Y are now window relative pixel coordinates. Convert
697 them to canonical char units before returning them. */
698 return Fcons (CANON_X_FROM_PIXEL_X (f
, x
),
699 CANON_Y_FROM_PIXEL_Y (f
, y
));
704 case ON_VERTICAL_BORDER
:
705 return Qvertical_line
;
713 case ON_RIGHT_FRINGE
:
714 return Qright_fringe
;
722 /* Callback for foreach_window, used in window_from_coordinates.
723 Check if window W contains coordinates specified by USER_DATA which
724 is actually a pointer to a struct check_window_data CW.
726 Check if window W contains coordinates *CW->x and *CW->y. If it
727 does, return W in *CW->window, as Lisp_Object, and return in
728 *CW->part the part of the window under coordinates *X,*Y. Return
729 zero from this function to stop iterating over windows. */
731 struct check_window_data
738 check_window_containing (w
, user_data
)
742 struct check_window_data
*cw
= (struct check_window_data
*) user_data
;
743 enum window_part found
;
746 found
= coordinates_in_window (w
, cw
->x
, cw
->y
);
747 if (found
!= ON_NOTHING
)
749 *cw
->part
= found
- 1;
750 XSETWINDOW (*cw
->window
, w
);
758 /* Find the window containing frame-relative pixel position X/Y and
759 return it as a Lisp_Object. If X, Y is on the window's modeline,
760 set *PART to 1; if it is on the separating line between the window
761 and its right sibling, set it to 2; otherwise set it to 0. If
762 there is no window under X, Y return nil and leave *PART
763 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows.
765 This function was previously implemented with a loop cycling over
766 windows with Fnext_window, and starting with the frame's selected
767 window. It turned out that this doesn't work with an
768 implementation of next_window using Vwindow_list, because
769 FRAME_SELECTED_WINDOW (F) is not always contained in the window
770 tree of F when this function is called asynchronously from
771 note_mouse_highlight. The original loop didn't terminate in this
775 window_from_coordinates (f
, x
, y
, part
, tool_bar_p
)
782 struct check_window_data cw
;
785 cw
.window
= &window
, cw
.x
= &x
, cw
.y
= &y
; cw
.part
= part
;
786 foreach_window (f
, check_window_containing
, &cw
);
788 /* If not found above, see if it's in the tool bar window, if a tool
792 && WINDOWP (f
->tool_bar_window
)
793 && XINT (XWINDOW (f
->tool_bar_window
)->height
) > 0
794 && (coordinates_in_window (XWINDOW (f
->tool_bar_window
), &x
, &y
)
798 window
= f
->tool_bar_window
;
804 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
805 doc
: /* Return window containing coordinates X and Y on FRAME.
806 If omitted, FRAME defaults to the currently selected frame.
807 The top left corner of the frame is considered to be row 0,
810 Lisp_Object x
, y
, frame
;
816 frame
= selected_frame
;
817 CHECK_LIVE_FRAME (frame
);
820 /* Check that arguments are integers or floats. */
821 CHECK_NUMBER_OR_FLOAT (x
);
822 CHECK_NUMBER_OR_FLOAT (y
);
824 return window_from_coordinates (f
,
825 PIXEL_X_FROM_CANON_X (f
, x
),
826 PIXEL_Y_FROM_CANON_Y (f
, y
),
830 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
831 doc
: /* Return current value of point in WINDOW.
832 For a nonselected window, this is the value point would have
833 if that window were selected.
835 Note that, when WINDOW is the selected window and its buffer
836 is also currently selected, the value returned is the same as (point).
837 It would be more strictly correct to return the `top-level' value
838 of point, outside of any save-excursion forms.
839 But that is hard to define. */)
843 register struct window
*w
= decode_window (window
);
845 if (w
== XWINDOW (selected_window
)
846 && current_buffer
== XBUFFER (w
->buffer
))
848 return Fmarker_position (w
->pointm
);
851 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
852 doc
: /* Return position at which display currently starts in WINDOW.
853 This is updated by redisplay or by calling `set-window-start'. */)
857 return Fmarker_position (decode_window (window
)->start
);
860 /* This is text temporarily removed from the doc string below.
862 This function returns nil if the position is not currently known.
863 That happens when redisplay is preempted and doesn't finish.
864 If in that case you want to compute where the end of the window would
865 have been if redisplay had finished, do this:
867 (goto-char (window-start window))
868 (vertical-motion (1- (window-height window)) window)
871 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
872 doc
: /* Return position at which display currently ends in WINDOW.
873 This is updated by redisplay, when it runs to completion.
874 Simply changing the buffer text or setting `window-start'
875 does not update this value.
876 If UPDATE is non-nil, compute the up-to-date position
877 if it isn't already recorded. */)
879 Lisp_Object window
, update
;
882 struct window
*w
= decode_window (window
);
888 #if 0 /* This change broke some things. We should make it later. */
889 /* If we don't know the end position, return nil.
890 The user can compute it with vertical-motion if he wants to.
891 It would be nicer to do it automatically,
892 but that's so slow that it would probably bother people. */
893 if (NILP (w
->window_end_valid
))
898 && ! (! NILP (w
->window_end_valid
)
899 && XFASTINT (w
->last_modified
) >= MODIFF
))
901 struct text_pos startp
;
903 struct buffer
*old_buffer
= NULL
, *b
= XBUFFER (buf
);
905 /* In case W->start is out of the range, use something
906 reasonable. This situation occured when loading a file with
907 `-l' containing a call to `rmail' with subsequent other
908 commands. At the end, W->start happened to be BEG, while
909 rmail had already narrowed the buffer. */
910 if (XMARKER (w
->start
)->charpos
< BEGV
)
911 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
912 else if (XMARKER (w
->start
)->charpos
> ZV
)
913 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
915 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
917 /* Cannot use Fvertical_motion because that function doesn't
918 cope with variable-height lines. */
919 if (b
!= current_buffer
)
921 old_buffer
= current_buffer
;
922 set_buffer_internal (b
);
925 start_display (&it
, w
, startp
);
926 move_it_vertically (&it
, window_box_height (w
));
927 if (it
.current_y
< it
.last_visible_y
)
928 move_it_past_eol (&it
);
929 value
= make_number (IT_CHARPOS (it
));
932 set_buffer_internal (old_buffer
);
935 XSETINT (value
, BUF_Z (XBUFFER (buf
)) - XFASTINT (w
->window_end_pos
));
940 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
941 doc
: /* Make point value in WINDOW be at position POS in WINDOW's buffer. */)
943 Lisp_Object window
, pos
;
945 register struct window
*w
= decode_window (window
);
947 CHECK_NUMBER_COERCE_MARKER (pos
);
948 if (w
== XWINDOW (selected_window
)
949 && XBUFFER (w
->buffer
) == current_buffer
)
952 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
954 /* We have to make sure that redisplay updates the window to show
955 the new value of point. */
956 if (!EQ (window
, selected_window
))
957 ++windows_or_buffers_changed
;
962 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
963 doc
: /* Make display in WINDOW start at position POS in WINDOW's buffer.
964 Optional third arg NOFORCE non-nil inhibits next redisplay
965 from overriding motion of point in order to display at this exact start. */)
966 (window
, pos
, noforce
)
967 Lisp_Object window
, pos
, noforce
;
969 register struct window
*w
= decode_window (window
);
971 CHECK_NUMBER_COERCE_MARKER (pos
);
972 set_marker_restricted (w
->start
, pos
, w
->buffer
);
973 /* this is not right, but much easier than doing what is right. */
974 w
->start_at_line_beg
= Qnil
;
977 w
->update_mode_line
= Qt
;
978 XSETFASTINT (w
->last_modified
, 0);
979 XSETFASTINT (w
->last_overlay_modified
, 0);
980 if (!EQ (window
, selected_window
))
981 windows_or_buffers_changed
++;
986 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
988 doc
: /* Return WINDOW's dedicated object, usually t or nil.
989 See also `set-window-dedicated-p'. */)
993 return decode_window (window
)->dedicated
;
996 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
997 Sset_window_dedicated_p
, 2, 2, 0,
998 doc
: /* Control whether WINDOW is dedicated to the buffer it displays.
999 If it is dedicated, Emacs will not automatically change
1000 which buffer appears in it.
1001 The second argument is the new value for the dedication flag;
1002 non-nil means yes. */)
1004 Lisp_Object window
, arg
;
1006 register struct window
*w
= decode_window (window
);
1009 w
->dedicated
= Qnil
;
1013 return w
->dedicated
;
1016 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
1018 doc
: /* Return the display-table that WINDOW is using. */)
1022 return decode_window (window
)->display_table
;
1025 /* Get the display table for use on window W. This is either W's
1026 display table or W's buffer's display table. Ignore the specified
1027 tables if they are not valid; if no valid table is specified,
1030 struct Lisp_Char_Table
*
1031 window_display_table (w
)
1034 struct Lisp_Char_Table
*dp
= NULL
;
1036 if (DISP_TABLE_P (w
->display_table
))
1037 dp
= XCHAR_TABLE (w
->display_table
);
1038 else if (BUFFERP (w
->buffer
))
1040 struct buffer
*b
= XBUFFER (w
->buffer
);
1042 if (DISP_TABLE_P (b
->display_table
))
1043 dp
= XCHAR_TABLE (b
->display_table
);
1044 else if (DISP_TABLE_P (Vstandard_display_table
))
1045 dp
= XCHAR_TABLE (Vstandard_display_table
);
1051 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
1052 doc
: /* Set WINDOW's display-table to TABLE. */)
1054 register Lisp_Object window
, table
;
1056 register struct window
*w
;
1058 w
= decode_window (window
);
1059 w
->display_table
= table
;
1063 /* Record info on buffer window w is displaying
1064 when it is about to cease to display that buffer. */
1067 register struct window
*w
;
1074 if (b
!= XMARKER (w
->pointm
)->buffer
)
1078 if (w
== XWINDOW (selected_window
)
1079 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
1080 /* Do this except when the selected window's buffer
1081 is being removed from some other window. */
1083 /* last_window_start records the start position that this buffer
1084 had in the last window to be disconnected from it.
1085 Now that this statement is unconditional,
1086 it is possible for the buffer to be displayed in the
1087 selected window, while last_window_start reflects another
1088 window which was recently showing the same buffer.
1089 Some people might say that might be a good thing. Let's see. */
1090 b
->last_window_start
= marker_position (w
->start
);
1092 /* Point in the selected window's buffer
1093 is actually stored in that buffer, and the window's pointm isn't used.
1094 So don't clobber point in that buffer. */
1095 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
)
1096 /* This line helps to fix Horsley's testbug.el bug. */
1097 && !(WINDOWP (b
->last_selected_window
)
1098 && w
!= XWINDOW (b
->last_selected_window
)
1099 && EQ (buf
, XWINDOW (b
->last_selected_window
)->buffer
)))
1100 temp_set_point_both (b
,
1101 clip_to_bounds (BUF_BEGV (b
),
1102 XMARKER (w
->pointm
)->charpos
,
1104 clip_to_bounds (BUF_BEGV_BYTE (b
),
1105 marker_byte_position (w
->pointm
),
1108 if (WINDOWP (b
->last_selected_window
)
1109 && w
== XWINDOW (b
->last_selected_window
))
1110 b
->last_selected_window
= Qnil
;
1113 /* Put replacement into the window structure in place of old. */
1115 replace_window (old
, replacement
)
1116 Lisp_Object old
, replacement
;
1118 register Lisp_Object tem
;
1119 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
1121 /* If OLD is its frame's root_window, then replacement is the new
1122 root_window for that frame. */
1124 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
1125 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
1129 p
->width
= o
->width
;
1130 p
->height
= o
->height
;
1131 p
->desired_matrix
= p
->current_matrix
= 0;
1133 bzero (&p
->cursor
, sizeof (p
->cursor
));
1134 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
1135 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
1136 p
->phys_cursor_type
= -1;
1137 p
->must_be_updated_p
= 0;
1138 p
->pseudo_window_p
= 0;
1139 XSETFASTINT (p
->window_end_vpos
, 0);
1140 XSETFASTINT (p
->window_end_pos
, 0);
1141 p
->window_end_valid
= Qnil
;
1142 p
->frozen_window_start_p
= 0;
1143 p
->orig_top
= p
->orig_height
= Qnil
;
1145 p
->next
= tem
= o
->next
;
1147 XWINDOW (tem
)->prev
= replacement
;
1149 p
->prev
= tem
= o
->prev
;
1151 XWINDOW (tem
)->next
= replacement
;
1153 p
->parent
= tem
= o
->parent
;
1156 if (EQ (XWINDOW (tem
)->vchild
, old
))
1157 XWINDOW (tem
)->vchild
= replacement
;
1158 if (EQ (XWINDOW (tem
)->hchild
, old
))
1159 XWINDOW (tem
)->hchild
= replacement
;
1162 /*** Here, if replacement is a vertical combination
1163 and so is its new parent, we should make replacement's
1164 children be children of that parent instead. ***/
1167 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
1168 doc
: /* Remove WINDOW from the display. Default is selected window. */)
1170 register Lisp_Object window
;
1172 delete_window (window
);
1174 if (! NILP (Vwindow_configuration_change_hook
)
1175 && ! NILP (Vrun_hooks
))
1176 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
1182 delete_window (window
)
1183 register Lisp_Object window
;
1185 register Lisp_Object tem
, parent
, sib
;
1186 register struct window
*p
;
1187 register struct window
*par
;
1190 /* Because this function is called by other C code on non-leaf
1191 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1192 so we can't decode_window here. */
1194 window
= selected_window
;
1196 CHECK_WINDOW (window
);
1197 p
= XWINDOW (window
);
1199 /* It's okay to delete an already-deleted window. */
1200 if (NILP (p
->buffer
)
1202 && NILP (p
->vchild
))
1207 error ("Attempt to delete minibuffer or sole ordinary window");
1208 par
= XWINDOW (parent
);
1210 windows_or_buffers_changed
++;
1211 Vwindow_list
= Qnil
;
1212 f
= XFRAME (WINDOW_FRAME (p
));
1213 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
1215 /* Are we trying to delete any frame's selected window? */
1217 Lisp_Object swindow
, pwindow
;
1219 /* See if the frame's selected window is either WINDOW
1220 or any subwindow of it, by finding all that window's parents
1221 and comparing each one with WINDOW. */
1222 swindow
= FRAME_SELECTED_WINDOW (f
);
1227 while (!NILP (pwindow
))
1229 if (EQ (window
, pwindow
))
1231 pwindow
= XWINDOW (pwindow
)->parent
;
1234 /* If the window being deleted is not a parent of SWINDOW,
1235 then SWINDOW is ok as the new selected window. */
1236 if (!EQ (window
, pwindow
))
1238 /* Otherwise, try another window for SWINDOW. */
1239 swindow
= Fnext_window (swindow
, Qlambda
, Qnil
);;
1241 /* If we get back to the frame's selected window,
1242 it means there was no acceptable alternative,
1243 so we cannot delete. */
1244 if (EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
1245 error ("Cannot delete window");
1248 /* If we need to change SWINDOW, do it. */
1249 if (! EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
1251 /* If we're about to delete the selected window on the
1252 selected frame, then we should use Fselect_window to select
1253 the new window. On the other hand, if we're about to
1254 delete the selected window on any other frame, we shouldn't do
1255 anything but set the frame's selected_window slot. */
1256 if (EQ (FRAME_SELECTED_WINDOW (f
), selected_window
))
1257 Fselect_window (swindow
);
1259 FRAME_SELECTED_WINDOW (f
) = swindow
;
1264 /* tem is null for dummy parent windows
1265 (which have inferiors but not any contents themselves) */
1269 unchain_marker (p
->pointm
);
1270 unchain_marker (p
->start
);
1273 /* Free window glyph matrices. It is sure that they are allocated
1274 again when ADJUST_GLYPHS is called. Block input so that expose
1275 events and other events that access glyph matrices are not
1276 processed while we are changing them. */
1278 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f
)));
1282 XWINDOW (tem
)->prev
= p
->prev
;
1286 XWINDOW (tem
)->next
= p
->next
;
1288 if (EQ (window
, par
->hchild
))
1289 par
->hchild
= p
->next
;
1290 if (EQ (window
, par
->vchild
))
1291 par
->vchild
= p
->next
;
1293 /* Find one of our siblings to give our space to. */
1297 /* If p gives its space to its next sibling, that sibling needs
1298 to have its top/left side pulled back to where p's is.
1299 set_window_{height,width} will re-position the sibling's
1302 XWINDOW (sib
)->top
= p
->top
;
1303 XWINDOW (sib
)->left
= p
->left
;
1306 /* Stretch that sibling. */
1307 if (!NILP (par
->vchild
))
1308 set_window_height (sib
,
1309 XFASTINT (XWINDOW (sib
)->height
) + XFASTINT (p
->height
),
1311 if (!NILP (par
->hchild
))
1312 set_window_width (sib
,
1313 XFASTINT (XWINDOW (sib
)->width
) + XFASTINT (p
->width
),
1316 /* If parent now has only one child,
1317 put the child into the parent's place. */
1321 if (NILP (XWINDOW (tem
)->next
))
1322 replace_window (parent
, tem
);
1324 /* Since we may be deleting combination windows, we must make sure that
1325 not only p but all its children have been marked as deleted. */
1326 if (! NILP (p
->hchild
))
1327 delete_all_subwindows (XWINDOW (p
->hchild
));
1328 else if (! NILP (p
->vchild
))
1329 delete_all_subwindows (XWINDOW (p
->vchild
));
1331 /* Mark this window as deleted. */
1332 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
1334 /* Adjust glyph matrices. */
1341 /***********************************************************************
1343 ***********************************************************************/
1345 /* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object
1346 pointer. This is a callback function for foreach_window, used in
1347 function window_list. */
1350 add_window_to_list (w
, user_data
)
1354 Lisp_Object
*list
= (Lisp_Object
*) user_data
;
1356 XSETWINDOW (window
, w
);
1357 *list
= Fcons (window
, *list
);
1362 /* Return a list of all windows, for use by next_window. If
1363 Vwindow_list is a list, return that list. Otherwise, build a new
1364 list, cache it in Vwindow_list, and return that. */
1369 if (!CONSP (Vwindow_list
))
1373 Vwindow_list
= Qnil
;
1374 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
1376 Lisp_Object args
[2];
1378 /* We are visiting windows in canonical order, and add
1379 new windows at the front of args[1], which means we
1380 have to reverse this list at the end. */
1382 foreach_window (XFRAME (XCAR (tail
)), add_window_to_list
, &args
[1]);
1383 args
[0] = Vwindow_list
;
1384 args
[1] = Fnreverse (args
[1]);
1385 Vwindow_list
= Fnconc (2, args
);
1389 return Vwindow_list
;
1393 /* Value is non-zero if WINDOW satisfies the constraints given by
1394 OWINDOW, MINIBUF and ALL_FRAMES.
1396 MINIBUF t means WINDOW may be minibuffer windows.
1397 `lambda' means WINDOW may not be a minibuffer window.
1398 a window means a specific minibuffer window
1400 ALL_FRAMES t means search all frames,
1401 nil means search just current frame,
1402 `visible' means search just visible frames,
1403 0 means search visible and iconified frames,
1404 a window means search the frame that window belongs to,
1405 a frame means consider windows on that frame, only. */
1408 candidate_window_p (window
, owindow
, minibuf
, all_frames
)
1409 Lisp_Object window
, owindow
, minibuf
, all_frames
;
1411 struct window
*w
= XWINDOW (window
);
1412 struct frame
*f
= XFRAME (w
->frame
);
1413 int candidate_p
= 1;
1415 if (!BUFFERP (w
->buffer
))
1417 else if (MINI_WINDOW_P (w
)
1418 && (EQ (minibuf
, Qlambda
)
1419 || (WINDOWP (minibuf
) && !EQ (minibuf
, window
))))
1421 /* If MINIBUF is `lambda' don't consider any mini-windows.
1422 If it is a window, consider only that one. */
1425 else if (EQ (all_frames
, Qt
))
1427 else if (NILP (all_frames
))
1429 xassert (WINDOWP (owindow
));
1430 candidate_p
= EQ (w
->frame
, XWINDOW (owindow
)->frame
);
1432 else if (EQ (all_frames
, Qvisible
))
1434 FRAME_SAMPLE_VISIBILITY (f
);
1435 candidate_p
= FRAME_VISIBLE_P (f
);
1437 else if (INTEGERP (all_frames
) && XINT (all_frames
) == 0)
1439 FRAME_SAMPLE_VISIBILITY (f
);
1440 candidate_p
= FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
);
1442 else if (WINDOWP (all_frames
))
1443 candidate_p
= (EQ (FRAME_MINIBUF_WINDOW (f
), all_frames
)
1444 || EQ (XWINDOW (all_frames
)->frame
, w
->frame
)
1445 || EQ (XWINDOW (all_frames
)->frame
, FRAME_FOCUS_FRAME (f
)));
1446 else if (FRAMEP (all_frames
))
1447 candidate_p
= EQ (all_frames
, w
->frame
);
1453 /* Decode arguments as allowed by Fnext_window, Fprevious_window, and
1454 Fwindow_list. See there for the meaning of WINDOW, MINIBUF, and
1458 decode_next_window_args (window
, minibuf
, all_frames
)
1459 Lisp_Object
*window
, *minibuf
, *all_frames
;
1462 *window
= selected_window
;
1464 CHECK_LIVE_WINDOW (*window
);
1466 /* MINIBUF nil may or may not include minibuffers. Decide if it
1468 if (NILP (*minibuf
))
1469 *minibuf
= minibuf_level
? minibuf_window
: Qlambda
;
1470 else if (!EQ (*minibuf
, Qt
))
1473 /* Now *MINIBUF can be t => count all minibuffer windows, `lambda'
1474 => count none of them, or a specific minibuffer window (the
1475 active one) to count. */
1477 /* ALL_FRAMES nil doesn't specify which frames to include. */
1478 if (NILP (*all_frames
))
1479 *all_frames
= (!EQ (*minibuf
, Qlambda
)
1480 ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window
)->frame
))
1482 else if (EQ (*all_frames
, Qvisible
))
1484 else if (XFASTINT (*all_frames
) == 0)
1486 else if (FRAMEP (*all_frames
))
1488 else if (!EQ (*all_frames
, Qt
))
1491 /* Now *ALL_FRAMES is t meaning search all frames, nil meaning
1492 search just current frame, `visible' meaning search just visible
1493 frames, 0 meaning search visible and iconified frames, or a
1494 window, meaning search the frame that window belongs to, or a
1495 frame, meaning consider windows on that frame, only. */
1499 /* Return the next or previous window of WINDOW in canonical ordering
1500 of windows. NEXT_P non-zero means return the next window. See the
1501 documentation string of next-window for the meaning of MINIBUF and
1505 next_window (window
, minibuf
, all_frames
, next_p
)
1506 Lisp_Object window
, minibuf
, all_frames
;
1509 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1511 /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just
1512 return the first window on the frame. */
1513 if (FRAMEP (all_frames
)
1514 && !EQ (all_frames
, XWINDOW (window
)->frame
))
1515 return Fframe_first_window (all_frames
);
1521 /* Find WINDOW in the list of all windows. */
1522 list
= Fmemq (window
, window_list ());
1524 /* Scan forward from WINDOW to the end of the window list. */
1526 for (list
= XCDR (list
); CONSP (list
); list
= XCDR (list
))
1527 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1530 /* Scan from the start of the window list up to WINDOW. */
1532 for (list
= Vwindow_list
;
1533 CONSP (list
) && !EQ (XCAR (list
), window
);
1535 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1539 window
= XCAR (list
);
1543 Lisp_Object candidate
, list
;
1545 /* Scan through the list of windows for candidates. If there are
1546 candidate windows in front of WINDOW, the last one of these
1547 is the one we want. If there are candidates following WINDOW
1548 in the list, again the last one of these is the one we want. */
1550 for (list
= window_list (); CONSP (list
); list
= XCDR (list
))
1552 if (EQ (XCAR (list
), window
))
1554 if (WINDOWP (candidate
))
1557 else if (candidate_window_p (XCAR (list
), window
, minibuf
,
1559 candidate
= XCAR (list
);
1562 if (WINDOWP (candidate
))
1570 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
1571 doc
: /* Return next window after WINDOW in canonical ordering of windows.
1572 If omitted, WINDOW defaults to the selected window.
1574 Optional second arg MINIBUF t means count the minibuffer window even
1575 if not active. MINIBUF nil or omitted means count the minibuffer iff
1576 it is active. MINIBUF neither t nor nil means not to count the
1577 minibuffer even if it is active.
1579 Several frames may share a single minibuffer; if the minibuffer
1580 counts, all windows on all frames that share that minibuffer count
1581 too. Therefore, `next-window' can be used to iterate through the
1582 set of windows even when the minibuffer is on another frame. If the
1583 minibuffer does not count, only windows from WINDOW's frame count.
1585 Optional third arg ALL-FRAMES t means include windows on all frames.
1586 ALL-FRAMES nil or omitted means cycle within the frames as specified
1587 above. ALL-FRAMES = `visible' means include windows on all visible frames.
1588 ALL-FRAMES = 0 means include windows on all visible and iconified frames.
1589 If ALL-FRAMES is a frame, restrict search to windows on that frame.
1590 Anything else means restrict to WINDOW's frame.
1592 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
1593 `next-window' to iterate through the entire cycle of acceptable
1594 windows, eventually ending up back at the window you started with.
1595 `previous-window' traverses the same cycle, in the reverse order. */)
1596 (window
, minibuf
, all_frames
)
1597 Lisp_Object window
, minibuf
, all_frames
;
1599 return next_window (window
, minibuf
, all_frames
, 1);
1603 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
1604 doc
: /* Return the window preceding WINDOW in canonical ordering of windows.
1605 If omitted, WINDOW defaults to the selected window.
1607 Optional second arg MINIBUF t means count the minibuffer window even
1608 if not active. MINIBUF nil or omitted means count the minibuffer iff
1609 it is active. MINIBUF neither t nor nil means not to count the
1610 minibuffer even if it is active.
1612 Several frames may share a single minibuffer; if the minibuffer
1613 counts, all windows on all frames that share that minibuffer count
1614 too. Therefore, `previous-window' can be used to iterate through
1615 the set of windows even when the minibuffer is on another frame. If
1616 the minibuffer does not count, only windows from WINDOW's frame count
1618 Optional third arg ALL-FRAMES t means include windows on all frames.
1619 ALL-FRAMES nil or omitted means cycle within the frames as specified
1620 above. ALL-FRAMES = `visible' means include windows on all visible frames.
1621 ALL-FRAMES = 0 means include windows on all visible and iconified frames.
1622 If ALL-FRAMES is a frame, restrict search to windows on that frame.
1623 Anything else means restrict to WINDOW's frame.
1625 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
1626 `previous-window' to iterate through the entire cycle of acceptable
1627 windows, eventually ending up back at the window you started with.
1628 `next-window' traverses the same cycle, in the reverse order. */)
1629 (window
, minibuf
, all_frames
)
1630 Lisp_Object window
, minibuf
, all_frames
;
1632 return next_window (window
, minibuf
, all_frames
, 0);
1636 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1637 doc
: /* Select the ARG'th different window on this frame.
1638 All windows on current frame are arranged in a cyclic order.
1639 This command selects the window ARG steps away in that order.
1640 A negative ARG moves in the opposite order. If the optional second
1641 argument ALL_FRAMES is non-nil, cycle through all frames. */)
1643 Lisp_Object arg
, all_frames
;
1649 window
= selected_window
;
1651 for (i
= XINT (arg
); i
> 0; --i
)
1652 window
= Fnext_window (window
, Qnil
, all_frames
);
1654 window
= Fprevious_window (window
, Qnil
, all_frames
);
1656 Fselect_window (window
);
1661 DEFUN ("window-list", Fwindow_list
, Swindow_list
, 0, 3, 0,
1662 doc
: /* Return a list of windows on FRAME, starting with WINDOW.
1663 FRAME nil or omitted means use the selected frame.
1664 WINDOW nil or omitted means use the selected window.
1665 MINIBUF t means include the minibuffer window, even if it isn't active.
1666 MINIBUF nil or omitted means include the minibuffer window only
1668 MINIBUF neither nil nor t means never include the minibuffer window. */)
1669 (frame
, minibuf
, window
)
1670 Lisp_Object frame
, minibuf
, window
;
1673 window
= selected_window
;
1675 frame
= selected_frame
;
1677 if (!EQ (frame
, XWINDOW (window
)->frame
))
1678 error ("Window is on a different frame");
1680 return window_list_1 (window
, minibuf
, frame
);
1684 /* Return a list of windows in canonical ordering. Arguments are like
1685 for `next-window'. */
1688 window_list_1 (window
, minibuf
, all_frames
)
1689 Lisp_Object window
, minibuf
, all_frames
;
1691 Lisp_Object tail
, list
;
1693 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1696 for (tail
= window_list (); CONSP (tail
); tail
= XCDR (tail
))
1697 if (candidate_window_p (XCAR (tail
), window
, minibuf
, all_frames
))
1698 list
= Fcons (XCAR (tail
), list
);
1700 return Fnreverse (list
);
1705 /* Look at all windows, performing an operation specified by TYPE
1707 If FRAMES is Qt, look at all frames;
1708 Qnil, look at just the selected frame;
1709 Qvisible, look at visible frames;
1710 a frame, just look at windows on that frame.
1711 If MINI is non-zero, perform the operation on minibuffer windows too. */
1716 GET_BUFFER_WINDOW
, /* Arg is buffer */
1717 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1718 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1719 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1721 UNSHOW_BUFFER
, /* Arg is buffer */
1726 window_loop (type
, obj
, mini
, frames
)
1727 enum window_loop type
;
1728 Lisp_Object obj
, frames
;
1731 Lisp_Object window
, windows
, best_window
, frame_arg
;
1733 struct gcpro gcpro1
;
1735 /* If we're only looping through windows on a particular frame,
1736 frame points to that frame. If we're looping through windows
1737 on all frames, frame is 0. */
1738 if (FRAMEP (frames
))
1739 f
= XFRAME (frames
);
1740 else if (NILP (frames
))
1741 f
= SELECTED_FRAME ();
1746 frame_arg
= Qlambda
;
1747 else if (XFASTINT (frames
) == 0)
1749 else if (EQ (frames
, Qvisible
))
1754 /* frame_arg is Qlambda to stick to one frame,
1755 Qvisible to consider all visible frames,
1758 /* Pick a window to start with. */
1762 window
= FRAME_SELECTED_WINDOW (f
);
1764 window
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
1766 windows
= window_list_1 (window
, mini
? Qt
: Qnil
, frame_arg
);
1770 for (; CONSP (windows
); windows
= CDR (windows
))
1774 window
= XCAR (windows
);
1775 w
= XWINDOW (window
);
1777 /* Note that we do not pay attention here to whether the frame
1778 is visible, since Fwindow_list skips non-visible frames if
1779 that is desired, under the control of frame_arg. */
1780 if (!MINI_WINDOW_P (w
)
1781 /* For UNSHOW_BUFFER, we must always consider all windows. */
1782 || type
== UNSHOW_BUFFER
1783 || (mini
&& minibuf_level
> 0))
1786 case GET_BUFFER_WINDOW
:
1787 if (EQ (w
->buffer
, obj
)
1788 /* Don't find any minibuffer window
1789 except the one that is currently in use. */
1790 && (MINI_WINDOW_P (w
)
1791 ? EQ (window
, minibuf_window
)
1794 if (NILP (best_window
))
1795 best_window
= window
;
1796 else if (EQ (window
, selected_window
))
1797 /* For compatibility with 20.x, prefer to return
1799 best_window
= window
;
1803 case GET_LRU_WINDOW
:
1804 /* t as arg means consider only full-width windows */
1805 if (!NILP (obj
) && !WINDOW_FULL_WIDTH_P (w
))
1807 /* Ignore dedicated windows and minibuffers. */
1808 if (MINI_WINDOW_P (w
) || !NILP (w
->dedicated
))
1810 if (NILP (best_window
)
1811 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1812 > XFASTINT (w
->use_time
)))
1813 best_window
= window
;
1816 case DELETE_OTHER_WINDOWS
:
1817 if (!EQ (window
, obj
))
1818 Fdelete_window (window
);
1821 case DELETE_BUFFER_WINDOWS
:
1822 if (EQ (w
->buffer
, obj
))
1824 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1826 /* If this window is dedicated, and in a frame of its own,
1828 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
1829 && !NILP (w
->dedicated
)
1830 && other_visible_frames (f
))
1832 /* Skip the other windows on this frame.
1833 There might be one, the minibuffer! */
1834 while (CONSP (XCDR (windows
))
1835 && EQ (XWINDOW (XCAR (windows
))->frame
,
1836 XWINDOW (XCAR (XCDR (windows
)))->frame
))
1837 windows
= XCDR (windows
);
1839 /* Now we can safely delete the frame. */
1840 Fdelete_frame (w
->frame
, Qnil
);
1842 else if (NILP (w
->parent
))
1844 /* If we're deleting the buffer displayed in the
1845 only window on the frame, find a new buffer to
1848 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
1849 Fset_window_buffer (window
, buffer
);
1850 if (EQ (window
, selected_window
))
1851 Fset_buffer (w
->buffer
);
1854 Fdelete_window (window
);
1858 case GET_LARGEST_WINDOW
:
1860 /* Ignore dedicated windows and minibuffers. */
1861 if (MINI_WINDOW_P (w
) || !NILP (w
->dedicated
))
1864 if (NILP (best_window
))
1865 best_window
= window
;
1868 struct window
*b
= XWINDOW (best_window
);
1869 if (XFASTINT (w
->height
) * XFASTINT (w
->width
)
1870 > XFASTINT (b
->height
) * XFASTINT (b
->width
))
1871 best_window
= window
;
1877 if (EQ (w
->buffer
, obj
))
1880 struct frame
*f
= XFRAME (w
->frame
);
1882 /* Find another buffer to show in this window. */
1883 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
1885 /* If this window is dedicated, and in a frame of its own,
1887 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
1888 && !NILP (w
->dedicated
)
1889 && other_visible_frames (f
))
1891 /* Skip the other windows on this frame.
1892 There might be one, the minibuffer! */
1893 while (CONSP (XCDR (windows
))
1894 && EQ (XWINDOW (XCAR (windows
))->frame
,
1895 XWINDOW (XCAR (XCDR (windows
)))->frame
))
1896 windows
= XCDR (windows
);
1898 /* Now we can safely delete the frame. */
1899 Fdelete_frame (w
->frame
, Qnil
);
1903 /* Otherwise show a different buffer in the window. */
1904 w
->dedicated
= Qnil
;
1905 Fset_window_buffer (window
, buffer
);
1906 if (EQ (window
, selected_window
))
1907 Fset_buffer (w
->buffer
);
1912 /* Check for a window that has a killed buffer. */
1913 case CHECK_ALL_WINDOWS
:
1914 if (! NILP (w
->buffer
)
1915 && NILP (XBUFFER (w
->buffer
)->name
))
1919 case WINDOW_LOOP_UNUSED
:
1928 /* Used for debugging. Abort if any window has a dead buffer. */
1931 check_all_windows ()
1933 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
1936 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1937 doc
: /* Return the window least recently selected or used for display.
1938 If optional argument FRAME is `visible', search all visible frames.
1939 If FRAME is 0, search all visible and iconified frames.
1940 If FRAME is t, search all frames.
1941 If FRAME is nil, search only the selected frame.
1942 If FRAME is a frame, search only that frame. */)
1946 register Lisp_Object w
;
1947 /* First try for a window that is full-width */
1948 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frame
);
1949 if (!NILP (w
) && !EQ (w
, selected_window
))
1951 /* If none of them, try the rest */
1952 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frame
);
1955 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1956 doc
: /* Return the largest window in area.
1957 If optional argument FRAME is `visible', search all visible frames.
1958 If FRAME is 0, search all visible and iconified frames.
1959 If FRAME is t, search all frames.
1960 If FRAME is nil, search only the selected frame.
1961 If FRAME is a frame, search only that frame. */)
1965 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
1969 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
1970 doc
: /* Return a window currently displaying BUFFER, or nil if none.
1971 If optional argument FRAME is `visible', search all visible frames.
1972 If optional argument FRAME is 0, search all visible and iconified frames.
1973 If FRAME is t, search all frames.
1974 If FRAME is nil, search only the selected frame.
1975 If FRAME is a frame, search only that frame. */)
1977 Lisp_Object buffer
, frame
;
1979 buffer
= Fget_buffer (buffer
);
1980 if (BUFFERP (buffer
))
1981 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
1986 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
1988 doc
: /* Make WINDOW (or the selected window) fill its frame.
1989 Only the frame WINDOW is on is affected.
1990 This function tries to reduce display jumps
1991 by keeping the text previously visible in WINDOW
1992 in the same place on the frame. Doing this depends on
1993 the value of (window-start WINDOW), so if calling this function
1994 in a program gives strange scrolling, make sure the window-start
1995 value is reasonable when this function is called. */)
2004 window
= selected_window
;
2006 CHECK_LIVE_WINDOW (window
);
2007 w
= XWINDOW (window
);
2009 startpos
= marker_position (w
->start
);
2010 top
= XFASTINT (w
->top
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2012 if (MINI_WINDOW_P (w
) && top
> 0)
2013 error ("Can't expand minibuffer to full frame");
2015 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
2017 /* Try to minimize scrolling, by setting the window start to the point
2018 will cause the text at the old window start to be at the same place
2019 on the frame. But don't try to do this if the window start is
2020 outside the visible portion (as might happen when the display is
2021 not current, due to typeahead). */
2022 new_top
= XFASTINT (w
->top
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2024 && startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
2025 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
2027 struct position pos
;
2028 struct buffer
*obuf
= current_buffer
;
2030 Fset_buffer (w
->buffer
);
2031 /* This computation used to temporarily move point, but that can
2032 have unwanted side effects due to text properties. */
2033 pos
= *vmotion (startpos
, -top
, w
);
2035 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
2036 w
->window_end_valid
= Qnil
;
2037 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
2038 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
2040 /* We need to do this, so that the window-scroll-functions
2042 w
->optional_new_start
= Qt
;
2044 set_buffer_internal (obuf
);
2050 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
2051 1, 2, "bDelete windows on (buffer): ",
2052 doc
: /* Delete all windows showing BUFFER.
2053 Optional second argument FRAME controls which frames are affected.
2054 If optional argument FRAME is `visible', search all visible frames.
2055 If FRAME is 0, search all visible and iconified frames.
2056 If FRAME is nil, search all frames.
2057 If FRAME is t, search only the selected frame.
2058 If FRAME is a frame, search only that frame. */)
2060 Lisp_Object buffer
, frame
;
2062 /* FRAME uses t and nil to mean the opposite of what window_loop
2066 else if (EQ (frame
, Qt
))
2071 buffer
= Fget_buffer (buffer
);
2072 CHECK_BUFFER (buffer
);
2073 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
2079 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
2080 Sreplace_buffer_in_windows
,
2081 1, 1, "bReplace buffer in windows: ",
2082 doc
: /* Replace BUFFER with some other buffer in all windows showing it. */)
2088 buffer
= Fget_buffer (buffer
);
2089 CHECK_BUFFER (buffer
);
2090 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
2095 /* Replace BUFFER with some other buffer in all windows
2096 of all frames, even those on other keyboards. */
2099 replace_buffer_in_all_windows (buffer
)
2103 Lisp_Object tail
, frame
;
2105 /* A single call to window_loop won't do the job
2106 because it only considers frames on the current keyboard.
2107 So loop manually over frames, and handle each one. */
2108 FOR_EACH_FRAME (tail
, frame
)
2109 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
2111 window_loop (UNSHOW_BUFFER
, buffer
, 1, Qt
);
2115 /* Set the height of WINDOW and all its inferiors. */
2117 /* The smallest acceptable dimensions for a window. Anything smaller
2118 might crash Emacs. */
2120 #define MIN_SAFE_WINDOW_WIDTH (2)
2121 #define MIN_SAFE_WINDOW_HEIGHT (1)
2123 /* Make sure that window_min_height and window_min_width are
2124 not too small; if they are, set them to safe minima. */
2127 check_min_window_sizes ()
2129 /* Smaller values might permit a crash. */
2130 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
2131 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
2132 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
2133 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
2136 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
2137 minimum allowable size. */
2140 check_frame_size (frame
, rows
, cols
)
2144 /* For height, we have to see:
2145 how many windows the frame has at minimum (one or two),
2146 and whether it has a menu bar or other special stuff at the top. */
2148 = ((FRAME_MINIBUF_ONLY_P (frame
) || ! FRAME_HAS_MINIBUF_P (frame
))
2149 ? MIN_SAFE_WINDOW_HEIGHT
2150 : 2 * MIN_SAFE_WINDOW_HEIGHT
);
2152 if (FRAME_TOP_MARGIN (frame
) > 0)
2153 min_height
+= FRAME_TOP_MARGIN (frame
);
2155 if (*rows
< min_height
)
2157 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
2158 *cols
= MIN_SAFE_WINDOW_WIDTH
;
2162 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
2163 check if W's width can be changed, otherwise check W's height.
2164 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
2165 siblings, too. If none of the siblings is resizable, WINDOW isn't
2169 window_fixed_size_p (w
, width_p
, check_siblings_p
)
2171 int width_p
, check_siblings_p
;
2176 if (!NILP (w
->hchild
))
2178 c
= XWINDOW (w
->hchild
);
2182 /* A horiz. combination is fixed-width if all of if its
2184 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2185 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2186 fixed_p
= c
== NULL
;
2190 /* A horiz. combination is fixed-height if one of if its
2192 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2193 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2194 fixed_p
= c
!= NULL
;
2197 else if (!NILP (w
->vchild
))
2199 c
= XWINDOW (w
->vchild
);
2203 /* A vert. combination is fixed-width if one of if its
2205 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2206 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2207 fixed_p
= c
!= NULL
;
2211 /* A vert. combination is fixed-height if all of if its
2213 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2214 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2215 fixed_p
= c
== NULL
;
2218 else if (BUFFERP (w
->buffer
))
2220 if (w
->height_fixed_p
&& !width_p
)
2224 struct buffer
*old
= current_buffer
;
2227 current_buffer
= XBUFFER (w
->buffer
);
2228 val
= find_symbol_value (Qwindow_size_fixed
);
2229 current_buffer
= old
;
2232 if (!EQ (val
, Qunbound
))
2234 fixed_p
= !NILP (val
);
2237 && ((EQ (val
, Qheight
) && width_p
)
2238 || (EQ (val
, Qwidth
) && !width_p
)))
2243 /* Can't tell if this one is resizable without looking at
2244 siblings. If all siblings are fixed-size this one is too. */
2245 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
2249 for (child
= w
->prev
; !NILP (child
); child
= XWINDOW (child
)->prev
)
2250 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2254 for (child
= w
->next
; !NILP (child
); child
= XWINDOW (child
)->next
)
2255 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2269 /* Return the minimum size of window W, not taking fixed-width windows
2270 into account. WIDTH_P non-zero means return the minimum width,
2271 otherwise return the minimum height. If W is a combination window,
2272 compute the minimum size from the minimum sizes of W's children. */
2275 window_min_size_1 (w
, width_p
)
2282 if (!NILP (w
->hchild
))
2284 c
= XWINDOW (w
->hchild
);
2289 /* The min width of a horizontal combination is
2290 the sum of the min widths of its children. */
2293 size
+= window_min_size_1 (c
, width_p
);
2294 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2299 /* The min height a horizontal combination equals
2300 the maximum of all min height of its children. */
2303 int min_size
= window_min_size_1 (c
, width_p
);
2304 size
= max (min_size
, size
);
2305 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2309 else if (!NILP (w
->vchild
))
2311 c
= XWINDOW (w
->vchild
);
2316 /* The min width of a vertical combination is
2317 the maximum of the min widths of its children. */
2320 int min_size
= window_min_size_1 (c
, width_p
);
2321 size
= max (min_size
, size
);
2322 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2327 /* The min height of a vertical combination equals
2328 the sum of the min height of its children. */
2331 size
+= window_min_size_1 (c
, width_p
);
2332 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2339 size
= window_min_width
;
2342 if (MINI_WINDOW_P (w
)
2343 || (!WINDOW_WANTS_MODELINE_P (w
)
2344 && !WINDOW_WANTS_HEADER_LINE_P (w
)))
2347 size
= window_min_height
;
2355 /* Return the minimum size of window W, taking fixed-size windows into
2356 account. WIDTH_P non-zero means return the minimum width,
2357 otherwise return the minimum height. IGNORE_FIXED_P non-zero means
2358 ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size
2359 unless FIXED is null. */
2362 window_min_size (w
, width_p
, ignore_fixed_p
, fixed
)
2364 int width_p
, ignore_fixed_p
, *fixed
;
2371 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
2377 size
= width_p
? XFASTINT (w
->width
) : XFASTINT (w
->height
);
2379 size
= window_min_size_1 (w
, width_p
);
2385 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
2386 WINDOW's width. Resize WINDOW's children, if any, so that they
2387 keep their proportionate size relative to WINDOW. Propagate
2388 WINDOW's top or left edge position to children. Delete windows
2389 that become too small unless NODELETE_P is non-zero.
2391 If NODELETE_P is 2, that means we do delete windows that are
2392 too small, even if they were too small before! */
2395 size_window (window
, size
, width_p
, nodelete_p
)
2397 int size
, width_p
, nodelete_p
;
2399 struct window
*w
= XWINDOW (window
);
2401 Lisp_Object child
, *forward
, *sideward
;
2402 int old_size
, min_size
;
2404 if (nodelete_p
== 2)
2407 check_min_window_sizes ();
2408 size
= max (0, size
);
2410 /* If the window has been "too small" at one point,
2411 don't delete it for being "too small" in the future.
2412 Preserve it as long as that is at all possible. */
2415 old_size
= XINT (w
->width
);
2416 min_size
= window_min_width
;
2420 old_size
= XINT (w
->height
);
2421 min_size
= window_min_height
;
2424 if (old_size
< min_size
&& nodelete_p
!= 2)
2425 w
->too_small_ok
= Qt
;
2427 /* Maybe delete WINDOW if it's too small. */
2428 if (nodelete_p
!= 1 && !NILP (w
->parent
))
2430 if (!MINI_WINDOW_P (w
) && !NILP (w
->too_small_ok
))
2431 min_size
= width_p
? MIN_SAFE_WINDOW_WIDTH
: MIN_SAFE_WINDOW_HEIGHT
;
2433 min_size
= width_p
? window_min_width
: window_min_height
;
2435 if (size
< min_size
)
2437 delete_window (window
);
2442 /* Set redisplay hints. */
2443 w
->last_modified
= make_number (0);
2444 w
->last_overlay_modified
= make_number (0);
2445 windows_or_buffers_changed
++;
2446 FRAME_WINDOW_SIZES_CHANGED (XFRAME (w
->frame
)) = 1;
2450 sideward
= &w
->vchild
;
2451 forward
= &w
->hchild
;
2452 w
->width
= make_number (size
);
2456 sideward
= &w
->hchild
;
2457 forward
= &w
->vchild
;
2458 w
->height
= make_number (size
);
2459 w
->orig_height
= Qnil
;
2462 if (!NILP (*sideward
))
2464 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
2466 c
= XWINDOW (child
);
2471 size_window (child
, size
, width_p
, nodelete_p
);
2474 else if (!NILP (*forward
))
2476 int fixed_size
, each
, extra
, n
;
2477 int resize_fixed_p
, nfixed
;
2478 int last_pos
, first_pos
, nchildren
, total
;
2480 /* Determine the fixed-size portion of the this window, and the
2481 number of child windows. */
2482 fixed_size
= nchildren
= nfixed
= total
= 0;
2483 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
2487 c
= XWINDOW (child
);
2488 child_size
= width_p
? XINT (c
->width
) : XINT (c
->height
);
2489 total
+= child_size
;
2491 if (window_fixed_size_p (c
, width_p
, 0))
2493 fixed_size
+= child_size
;
2498 /* If the new size is smaller than fixed_size, or if there
2499 aren't any resizable windows, allow resizing fixed-size
2501 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
2503 /* Compute how many lines/columns to add to each child. The
2504 value of extra takes care of rounding errors. */
2505 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
2506 each
= (size
- total
) / n
;
2507 extra
= (size
- total
) - n
* each
;
2509 /* Compute new children heights and edge positions. */
2510 first_pos
= width_p
? XINT (w
->left
) : XINT (w
->top
);
2511 last_pos
= first_pos
;
2512 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2514 int new_size
, old_size
;
2516 c
= XWINDOW (child
);
2517 old_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2518 new_size
= old_size
;
2520 /* The top or left edge position of this child equals the
2521 bottom or right edge of its predecessor. */
2523 c
->left
= make_number (last_pos
);
2525 c
->top
= make_number (last_pos
);
2527 /* If this child can be resized, do it. */
2528 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
2530 new_size
= old_size
+ each
+ extra
;
2534 /* Set new height. Note that size_window also propagates
2535 edge positions to children, so it's not a no-op if we
2536 didn't change the child's size. */
2537 size_window (child
, new_size
, width_p
, 1);
2539 /* Remember the bottom/right edge position of this child; it
2540 will be used to set the top/left edge of the next child. */
2541 last_pos
+= new_size
;
2544 /* We should have covered the parent exactly with child windows. */
2545 xassert (size
== last_pos
- first_pos
);
2547 /* Now delete any children that became too small. */
2549 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2552 c
= XWINDOW (child
);
2553 child_size
= width_p
? XINT (c
->width
) : XINT (c
->height
);
2554 size_window (child
, child_size
, width_p
, 2);
2559 /* Set WINDOW's height to HEIGHT, and recursively change the height of
2560 WINDOW's children. NODELETE non-zero means don't delete windows
2561 that become too small in the process. (The caller should check
2562 later and do so if appropriate.) */
2565 set_window_height (window
, height
, nodelete
)
2570 size_window (window
, height
, 0, nodelete
);
2574 /* Set WINDOW's width to WIDTH, and recursively change the width of
2575 WINDOW's children. NODELETE non-zero means don't delete windows
2576 that become too small in the process. (The caller should check
2577 later and do so if appropriate.) */
2580 set_window_width (window
, width
, nodelete
)
2585 size_window (window
, width
, 1, nodelete
);
2589 int window_select_count
;
2592 Fset_window_buffer_unwind (obuf
)
2600 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
2601 means it's allowed to run hooks. See make_frame for a case where
2602 it's not allowed. */
2605 set_window_buffer (window
, buffer
, run_hooks_p
)
2606 Lisp_Object window
, buffer
;
2609 struct window
*w
= XWINDOW (window
);
2610 struct buffer
*b
= XBUFFER (buffer
);
2611 int count
= specpdl_ptr
- specpdl
;
2615 if (EQ (window
, selected_window
))
2616 b
->last_selected_window
= window
;
2618 /* Update time stamps of buffer display. */
2619 if (INTEGERP (b
->display_count
))
2620 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
2621 b
->display_time
= Fcurrent_time ();
2623 XSETFASTINT (w
->window_end_pos
, 0);
2624 XSETFASTINT (w
->window_end_vpos
, 0);
2625 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
2626 w
->window_end_valid
= Qnil
;
2627 w
->hscroll
= w
->min_hscroll
= make_number (0);
2629 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
2630 set_marker_restricted (w
->start
,
2631 make_number (b
->last_window_start
),
2633 w
->start_at_line_beg
= Qnil
;
2634 w
->force_start
= Qnil
;
2635 XSETFASTINT (w
->last_modified
, 0);
2636 XSETFASTINT (w
->last_overlay_modified
, 0);
2637 windows_or_buffers_changed
++;
2639 /* We must select BUFFER for running the window-scroll-functions.
2640 If WINDOW is selected, switch permanently.
2641 Otherwise, switch but go back to the ambient buffer afterward. */
2642 if (EQ (window
, selected_window
))
2643 Fset_buffer (buffer
);
2644 /* We can't check ! NILP (Vwindow_scroll_functions) here
2645 because that might itself be a local variable. */
2646 else if (window_initialized
)
2648 record_unwind_protect (Fset_window_buffer_unwind
, Fcurrent_buffer ());
2649 Fset_buffer (buffer
);
2652 /* Set left and right marginal area width from buffer. */
2653 Fset_window_margins (window
, b
->left_margin_width
, b
->right_margin_width
);
2657 if (! NILP (Vwindow_scroll_functions
))
2658 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2659 Fmarker_position (w
->start
));
2661 if (! NILP (Vwindow_configuration_change_hook
)
2662 && ! NILP (Vrun_hooks
))
2663 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
2666 unbind_to (count
, Qnil
);
2670 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 2, 0,
2671 doc
: /* Make WINDOW display BUFFER as its contents.
2672 BUFFER can be a buffer or buffer name. */)
2674 register Lisp_Object window
, buffer
;
2676 register Lisp_Object tem
;
2677 register struct window
*w
= decode_window (window
);
2679 XSETWINDOW (window
, w
);
2680 buffer
= Fget_buffer (buffer
);
2681 CHECK_BUFFER (buffer
);
2683 if (NILP (XBUFFER (buffer
)->name
))
2684 error ("Attempt to display deleted buffer");
2688 error ("Window is deleted");
2689 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
2690 is first being set up. */
2692 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
2693 error ("Window is dedicated to `%s'",
2694 XSTRING (XBUFFER (tem
)->name
)->data
);
2699 set_window_buffer (window
, buffer
, 1);
2703 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 1, 0,
2704 doc
: /* Select WINDOW. Most editing will apply to WINDOW's buffer.
2705 If WINDOW is not already selected, also make WINDOW's buffer current.
2706 Note that the main editor command loop
2707 selects the buffer of the selected window before each command. */)
2709 register Lisp_Object window
;
2711 return select_window_1 (window
, 1);
2714 /* Note that selected_window can be nil
2715 when this is called from Fset_window_configuration. */
2718 select_window_1 (window
, recordflag
)
2719 register Lisp_Object window
;
2722 register struct window
*w
;
2723 register struct window
*ow
;
2726 CHECK_LIVE_WINDOW (window
);
2728 w
= XWINDOW (window
);
2729 w
->frozen_window_start_p
= 0;
2731 XSETFASTINT (w
->use_time
, ++window_select_count
);
2732 if (EQ (window
, selected_window
))
2735 if (!NILP (selected_window
))
2737 ow
= XWINDOW (selected_window
);
2738 if (! NILP (ow
->buffer
))
2739 set_marker_both (ow
->pointm
, ow
->buffer
,
2740 BUF_PT (XBUFFER (ow
->buffer
)),
2741 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
2744 selected_window
= window
;
2745 sf
= SELECTED_FRAME ();
2746 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
2748 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
2749 /* Use this rather than Fhandle_switch_frame
2750 so that FRAME_FOCUS_FRAME is moved appropriately as we
2751 move around in the state where a minibuffer in a separate
2753 Fselect_frame (WINDOW_FRAME (w
), Qnil
);
2756 sf
->selected_window
= window
;
2759 record_buffer (w
->buffer
);
2760 Fset_buffer (w
->buffer
);
2762 XBUFFER (w
->buffer
)->last_selected_window
= window
;
2764 /* Go to the point recorded in the window.
2765 This is important when the buffer is in more
2766 than one window. It also matters when
2767 redisplay_window has altered point after scrolling,
2768 because it makes the change only in the window. */
2770 register int new_point
= marker_position (w
->pointm
);
2771 if (new_point
< BEGV
)
2773 else if (new_point
> ZV
)
2779 windows_or_buffers_changed
++;
2783 /* Deiconify the frame containing the window WINDOW,
2784 unless it is the selected frame;
2787 The reason for the exception for the selected frame
2788 is that it seems better not to change the selected frames visibility
2789 merely because of displaying a different buffer in it.
2790 The deiconification is useful when a buffer gets shown in
2791 another frame that you were not using lately. */
2794 display_buffer_1 (window
)
2797 Lisp_Object frame
= XWINDOW (window
)->frame
;
2798 FRAME_PTR f
= XFRAME (frame
);
2800 FRAME_SAMPLE_VISIBILITY (f
);
2802 if (!EQ (frame
, selected_frame
))
2804 if (FRAME_ICONIFIED_P (f
))
2805 Fmake_frame_visible (frame
);
2806 else if (FRAME_VISIBLE_P (f
))
2807 Fraise_frame (frame
);
2813 DEFUN ("special-display-p", Fspecial_display_p
, Sspecial_display_p
, 1, 1, 0,
2814 doc
: /* Returns non-nil if a buffer named BUFFER-NAME would be created specially.
2815 The value is actually t if the frame should be called with default frame
2816 parameters, and a list of frame parameters if they were specified.
2817 See `special-display-buffer-names', and `special-display-regexps'. */)
2819 Lisp_Object buffer_name
;
2823 CHECK_STRING (buffer_name
);
2825 tem
= Fmember (buffer_name
, Vspecial_display_buffer_names
);
2829 tem
= Fassoc (buffer_name
, Vspecial_display_buffer_names
);
2833 for (tem
= Vspecial_display_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2835 Lisp_Object car
= XCAR (tem
);
2837 && fast_string_match (car
, buffer_name
) >= 0)
2839 else if (CONSP (car
)
2840 && STRINGP (XCAR (car
))
2841 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2847 DEFUN ("same-window-p", Fsame_window_p
, Ssame_window_p
, 1, 1, 0,
2848 doc
: /* Returns non-nil if a new buffer named BUFFER-NAME would use the same window.
2849 See `same-window-buffer-names' and `same-window-regexps'. */)
2851 Lisp_Object buffer_name
;
2855 CHECK_STRING (buffer_name
);
2857 tem
= Fmember (buffer_name
, Vsame_window_buffer_names
);
2861 tem
= Fassoc (buffer_name
, Vsame_window_buffer_names
);
2865 for (tem
= Vsame_window_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2867 Lisp_Object car
= XCAR (tem
);
2869 && fast_string_match (car
, buffer_name
) >= 0)
2871 else if (CONSP (car
)
2872 && STRINGP (XCAR (car
))
2873 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2879 /* Use B so the default is (other-buffer). */
2880 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 3,
2881 "BDisplay buffer: \nP",
2882 doc
: /* Make BUFFER appear in some window but don't select it.
2883 BUFFER can be a buffer or a buffer name.
2884 If BUFFER is shown already in some window, just use that one,
2885 unless the window is the selected window and the optional second
2886 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).
2887 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.
2888 Returns the window displaying BUFFER.
2889 If `display-reuse-frames' is non-nil, and another frame is currently
2890 displaying BUFFER, then simply raise that frame.
2892 The variables `special-display-buffer-names', `special-display-regexps',
2893 `same-window-buffer-names', and `same-window-regexps' customize how certain
2894 buffer names are handled.
2896 If optional argument FRAME is `visible', search all visible frames.
2897 If FRAME is 0, search all visible and iconified frames.
2898 If FRAME is t, search all frames.
2899 If FRAME is a frame, search only that frame.
2900 If FRAME is nil, search only the selected frame
2901 (actually the last nonminibuffer frame),
2902 unless `pop-up-frames' or `display-buffer-reuse-frames' is non-nil,
2903 which means search visible and iconified frames.
2905 If `even-window-heights' is non-nil, window heights will be evened out
2906 if displaying the buffer causes two vertically adjacent windows to be
2908 (buffer
, not_this_window
, frame
)
2909 register Lisp_Object buffer
, not_this_window
, frame
;
2911 register Lisp_Object window
, tem
, swp
;
2915 buffer
= Fget_buffer (buffer
);
2916 CHECK_BUFFER (buffer
);
2918 if (!NILP (Vdisplay_buffer_function
))
2919 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
2921 if (NILP (not_this_window
)
2922 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
2923 return display_buffer_1 (selected_window
);
2925 /* See if the user has specified this buffer should appear
2926 in the selected window. */
2927 if (NILP (not_this_window
))
2929 swp
= Fsame_window_p (XBUFFER (buffer
)->name
);
2930 if (!NILP (swp
) && !no_switch_window (selected_window
))
2932 Fswitch_to_buffer (buffer
, Qnil
);
2933 return display_buffer_1 (selected_window
);
2937 /* If the user wants pop-up-frames or display-reuse-frames, then
2938 look for a window showing BUFFER on any visible or iconified frame.
2939 Otherwise search only the current frame. */
2942 else if (pop_up_frames
2943 || display_buffer_reuse_frames
2944 || last_nonminibuf_frame
== 0)
2945 XSETFASTINT (tem
, 0);
2947 XSETFRAME (tem
, last_nonminibuf_frame
);
2949 window
= Fget_buffer_window (buffer
, tem
);
2951 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
2952 return display_buffer_1 (window
);
2954 /* Certain buffer names get special handling. */
2955 if (!NILP (Vspecial_display_function
) && NILP (swp
))
2957 tem
= Fspecial_display_p (XBUFFER (buffer
)->name
);
2959 return call1 (Vspecial_display_function
, buffer
);
2961 return call2 (Vspecial_display_function
, buffer
, tem
);
2964 /* If there are no frames open that have more than a minibuffer,
2965 we need to create a new frame. */
2966 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
2968 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2969 Fset_window_buffer (window
, buffer
);
2970 return display_buffer_1 (window
);
2973 f
= SELECTED_FRAME ();
2975 || FRAME_MINIBUF_ONLY_P (f
)
2976 /* If the current frame is a special display frame,
2977 don't try to reuse its windows. */
2978 || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f
))->dedicated
))
2983 if (FRAME_MINIBUF_ONLY_P (f
))
2984 XSETFRAME (frames
, last_nonminibuf_frame
);
2985 /* Don't try to create a window if would get an error */
2986 if (split_height_threshold
< window_min_height
<< 1)
2987 split_height_threshold
= window_min_height
<< 1;
2989 /* Note that both Fget_largest_window and Fget_lru_window
2990 ignore minibuffers and dedicated windows.
2991 This means they can return nil. */
2993 /* If the frame we would try to split cannot be split,
2994 try other frames. */
2995 if (FRAME_NO_SPLIT_P (NILP (frames
) ? f
: last_nonminibuf_frame
))
2997 /* Try visible frames first. */
2998 window
= Fget_largest_window (Qvisible
);
2999 /* If that didn't work, try iconified frames. */
3001 window
= Fget_largest_window (make_number (0));
3003 window
= Fget_largest_window (Qt
);
3006 window
= Fget_largest_window (frames
);
3008 /* If we got a tall enough full-width window that can be split,
3011 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
3012 && window_height (window
) >= split_height_threshold
3013 && WINDOW_FULL_WIDTH_P (XWINDOW (window
)))
3014 window
= Fsplit_window (window
, Qnil
, Qnil
);
3017 Lisp_Object upper
, lower
, other
;
3019 window
= Fget_lru_window (frames
);
3020 /* If the LRU window is selected, and big enough,
3021 and can be split, split it. */
3023 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
3024 && (EQ (window
, selected_window
)
3025 || EQ (XWINDOW (window
)->parent
, Qnil
))
3026 && window_height (window
) >= window_min_height
<< 1)
3027 window
= Fsplit_window (window
, Qnil
, Qnil
);
3028 /* If Fget_lru_window returned nil, try other approaches. */
3030 /* Try visible frames first. */
3032 window
= Fget_buffer_window (buffer
, Qvisible
);
3034 window
= Fget_largest_window (Qvisible
);
3035 /* If that didn't work, try iconified frames. */
3037 window
= Fget_buffer_window (buffer
, make_number (0));
3039 window
= Fget_largest_window (make_number (0));
3040 /* Try invisible frames. */
3042 window
= Fget_buffer_window (buffer
, Qt
);
3044 window
= Fget_largest_window (Qt
);
3045 /* As a last resort, make a new frame. */
3047 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
3048 /* If window appears above or below another,
3049 even out their heights. */
3050 other
= upper
= lower
= Qnil
;
3051 if (!NILP (XWINDOW (window
)->prev
))
3052 other
= upper
= XWINDOW (window
)->prev
, lower
= window
;
3053 if (!NILP (XWINDOW (window
)->next
))
3054 other
= lower
= XWINDOW (window
)->next
, upper
= window
;
3056 && !NILP (Veven_window_heights
)
3057 /* Check that OTHER and WINDOW are vertically arrayed. */
3058 && !EQ (XWINDOW (other
)->top
, XWINDOW (window
)->top
)
3059 && (XFASTINT (XWINDOW (other
)->height
)
3060 > XFASTINT (XWINDOW (window
)->height
)))
3062 int total
= (XFASTINT (XWINDOW (other
)->height
)
3063 + XFASTINT (XWINDOW (window
)->height
));
3064 enlarge_window (upper
,
3065 total
/ 2 - XFASTINT (XWINDOW (upper
)->height
),
3071 window
= Fget_lru_window (Qnil
);
3073 Fset_window_buffer (window
, buffer
);
3074 return display_buffer_1 (window
);
3078 temp_output_buffer_show (buf
)
3079 register Lisp_Object buf
;
3081 register struct buffer
*old
= current_buffer
;
3082 register Lisp_Object window
;
3083 register struct window
*w
;
3085 XBUFFER (buf
)->directory
= current_buffer
->directory
;
3088 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
3092 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
3093 set_buffer_internal (old
);
3095 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
3096 call1 (Vtemp_buffer_show_function
, buf
);
3099 window
= Fdisplay_buffer (buf
, Qnil
, Qnil
);
3101 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
3102 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
3103 Vminibuf_scroll_window
= window
;
3104 w
= XWINDOW (window
);
3105 XSETFASTINT (w
->hscroll
, 0);
3106 XSETFASTINT (w
->min_hscroll
, 0);
3107 set_marker_restricted_both (w
->start
, buf
, 1, 1);
3108 set_marker_restricted_both (w
->pointm
, buf
, 1, 1);
3110 /* Run temp-buffer-show-hook, with the chosen window selected
3111 and it sbuffer current. */
3112 if (!NILP (Vrun_hooks
))
3115 tem
= Fboundp (Qtemp_buffer_show_hook
);
3118 tem
= Fsymbol_value (Qtemp_buffer_show_hook
);
3121 int count
= specpdl_ptr
- specpdl
;
3122 Lisp_Object prev_window
;
3123 prev_window
= selected_window
;
3125 /* Select the window that was chosen, for running the hook. */
3126 record_unwind_protect (Fselect_window
, prev_window
);
3127 select_window_1 (window
, 0);
3128 Fset_buffer (w
->buffer
);
3129 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
3130 select_window_1 (prev_window
, 0);
3131 unbind_to (count
, Qnil
);
3139 make_dummy_parent (window
)
3143 register struct window
*o
, *p
;
3146 o
= XWINDOW (window
);
3147 p
= allocate_window ();
3148 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
3149 ((struct Lisp_Vector
*) p
)->contents
[i
]
3150 = ((struct Lisp_Vector
*)o
)->contents
[i
];
3151 XSETWINDOW (new, p
);
3153 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
3155 /* Put new into window structure in place of window */
3156 replace_window (window
, new);
3169 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
3170 doc
: /* Split WINDOW, putting SIZE lines in the first of the pair.
3171 WINDOW defaults to selected one and SIZE to half its size.
3172 If optional third arg HORFLAG is non-nil, split side by side
3173 and put SIZE columns in the first of the pair. In that case,
3174 SIZE includes that window's scroll bar, or the divider column to its right. */)
3175 (window
, size
, horflag
)
3176 Lisp_Object window
, size
, horflag
;
3178 register Lisp_Object
new;
3179 register struct window
*o
, *p
;
3181 register int size_int
;
3184 window
= selected_window
;
3186 CHECK_LIVE_WINDOW (window
);
3188 o
= XWINDOW (window
);
3189 fo
= XFRAME (WINDOW_FRAME (o
));
3193 if (!NILP (horflag
))
3194 /* Calculate the size of the left-hand window, by dividing
3195 the usable space in columns by two.
3196 We round up, since the left-hand window may include
3197 a dividing line, while the right-hand may not. */
3198 size_int
= (XFASTINT (o
->width
) + 1) >> 1;
3200 size_int
= XFASTINT (o
->height
) >> 1;
3204 CHECK_NUMBER (size
);
3205 size_int
= XINT (size
);
3208 if (MINI_WINDOW_P (o
))
3209 error ("Attempt to split minibuffer window");
3210 else if (window_fixed_size_p (o
, !NILP (horflag
), 0))
3211 error ("Attempt to split fixed-size window");
3213 check_min_window_sizes ();
3217 if (size_int
< window_min_height
)
3218 error ("Window height %d too small (after splitting)", size_int
);
3219 if (size_int
+ window_min_height
> XFASTINT (o
->height
))
3220 error ("Window height %d too small (after splitting)",
3221 XFASTINT (o
->height
) - size_int
);
3222 if (NILP (o
->parent
)
3223 || NILP (XWINDOW (o
->parent
)->vchild
))
3225 make_dummy_parent (window
);
3227 XWINDOW (new)->vchild
= window
;
3232 if (size_int
< window_min_width
)
3233 error ("Window width %d too small (after splitting)", size_int
);
3235 if (size_int
+ window_min_width
> XFASTINT (o
->width
))
3236 error ("Window width %d too small (after splitting)",
3237 XFASTINT (o
->width
) - size_int
);
3238 if (NILP (o
->parent
)
3239 || NILP (XWINDOW (o
->parent
)->hchild
))
3241 make_dummy_parent (window
);
3243 XWINDOW (new)->hchild
= window
;
3247 /* Now we know that window's parent is a vertical combination
3248 if we are dividing vertically, or a horizontal combination
3249 if we are making side-by-side windows */
3251 windows_or_buffers_changed
++;
3252 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
3253 new = make_window ();
3256 p
->frame
= o
->frame
;
3258 if (!NILP (p
->next
))
3259 XWINDOW (p
->next
)->prev
= new;
3262 p
->parent
= o
->parent
;
3264 p
->window_end_valid
= Qnil
;
3265 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
3267 /* Apportion the available frame space among the two new windows */
3269 if (!NILP (horflag
))
3271 p
->height
= o
->height
;
3273 XSETFASTINT (p
->width
, XFASTINT (o
->width
) - size_int
);
3274 XSETFASTINT (o
->width
, size_int
);
3275 XSETFASTINT (p
->left
, XFASTINT (o
->left
) + size_int
);
3280 p
->width
= o
->width
;
3281 XSETFASTINT (p
->height
, XFASTINT (o
->height
) - size_int
);
3282 XSETFASTINT (o
->height
, size_int
);
3283 XSETFASTINT (p
->top
, XFASTINT (o
->top
) + size_int
);
3286 /* Adjust glyph matrices. */
3288 Fset_window_buffer (new, o
->buffer
);
3292 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 3, "p",
3293 doc
: /* Make current window ARG lines bigger.
3294 From program, optional second arg non-nil means grow sideways ARG columns.
3295 Interactively, if an argument is not given, make the window one line bigger.
3297 Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size
3298 of the siblings above or to the left of the selected window. Only
3299 siblings to the right or below are changed. */)
3300 (arg
, side
, preserve_before
)
3301 register Lisp_Object arg
, side
, preserve_before
;
3304 enlarge_window (selected_window
, XINT (arg
), !NILP (side
),
3305 !NILP (preserve_before
));
3307 if (! NILP (Vwindow_configuration_change_hook
))
3308 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3313 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
3314 doc
: /* Make current window ARG lines smaller.
3315 From program, optional second arg non-nil means shrink sideways arg columns.
3316 Interactively, if an argument is not given, make the window one line smaller. */)
3318 register Lisp_Object arg
, side
;
3321 enlarge_window (selected_window
, -XINT (arg
), !NILP (side
), 0);
3323 if (! NILP (Vwindow_configuration_change_hook
))
3324 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3330 window_height (window
)
3333 register struct window
*p
= XWINDOW (window
);
3334 return XFASTINT (p
->height
);
3338 window_width (window
)
3341 register struct window
*p
= XWINDOW (window
);
3342 return XFASTINT (p
->width
);
3347 *(widthflag ? &(XWINDOW (w)->left) : &(XWINDOW (w)->top))
3349 #define CURSIZE(w) \
3350 *(widthflag ? &(XWINDOW (w)->width) : &(XWINDOW (w)->height))
3353 /* Enlarge WINDOW by DELTA. WIDTHFLAG non-zero means
3354 increase its width. Siblings of the selected window are resized to
3355 fulfill the size request. If they become too small in the process,
3356 they will be deleted.
3358 If PRESERVE_BEFORE is nonzero, that means don't alter
3359 the siblings to the left or above WINDOW. */
3362 enlarge_window (window
, delta
, widthflag
, preserve_before
)
3364 int delta
, widthflag
, preserve_before
;
3366 Lisp_Object parent
, next
, prev
;
3370 int (*sizefun
) P_ ((Lisp_Object
))
3371 = widthflag
? window_width
: window_height
;
3372 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
3373 = (widthflag
? set_window_width
: set_window_height
);
3375 /* Check values of window_min_width and window_min_height for
3377 check_min_window_sizes ();
3379 /* Give up if this window cannot be resized. */
3380 if (window_fixed_size_p (XWINDOW (window
), widthflag
, 1))
3381 error ("Window is not resizable");
3383 /* Find the parent of the selected window. */
3386 p
= XWINDOW (window
);
3392 error ("No other window to side of this one");
3397 ? !NILP (XWINDOW (parent
)->hchild
)
3398 : !NILP (XWINDOW (parent
)->vchild
))
3404 sizep
= &CURSIZE (window
);
3407 register int maxdelta
;
3409 /* Compute the maximum size increment this window can have. */
3411 if (preserve_before
)
3415 maxdelta
= (*sizefun
) (parent
) - XINT (*sizep
);
3416 /* Subtract size of siblings before, since we can't take that. */
3417 maxdelta
-= XINT (CURBEG (window
)) - XINT (CURBEG (parent
));
3420 maxdelta
= (!NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3421 - window_min_size (XWINDOW (p
->next
),
3426 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - XINT (*sizep
)
3427 /* This is a main window followed by a minibuffer. */
3428 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3429 - window_min_size (XWINDOW (p
->next
),
3431 /* This is a minibuffer following a main window. */
3432 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
3433 - window_min_size (XWINDOW (p
->prev
),
3435 /* This is a frame with only one window, a minibuffer-only
3436 or a minibufferless frame. */
3439 if (delta
> maxdelta
)
3440 /* This case traps trying to make the minibuffer
3441 the full frame, or make the only window aside from the
3442 minibuffer the full frame. */
3446 if (XINT (*sizep
) + delta
< window_min_size (XWINDOW (window
), widthflag
, 0, 0))
3448 delete_window (window
);
3455 /* Find the total we can get from other siblings without deleting them. */
3457 for (next
= p
->next
; ! NILP (next
); next
= XWINDOW (next
)->next
)
3458 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
3460 if (! preserve_before
)
3461 for (prev
= p
->prev
; ! NILP (prev
); prev
= XWINDOW (prev
)->prev
)
3462 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
3465 /* If we can get it all from them without deleting them, do so. */
3466 if (delta
<= maximum
)
3468 Lisp_Object first_unaffected
;
3469 Lisp_Object first_affected
;
3474 first_affected
= window
;
3475 /* Look at one sibling at a time,
3476 moving away from this window in both directions alternately,
3477 and take as much as we can get without deleting that sibling. */
3479 && (!NILP (next
) || (!preserve_before
&& !NILP (prev
))))
3483 int this_one
= ((*sizefun
) (next
)
3484 - window_min_size (XWINDOW (next
),
3485 widthflag
, 0, &fixed_p
));
3488 if (this_one
> delta
)
3491 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
3492 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3497 next
= XWINDOW (next
)->next
;
3503 if (!preserve_before
&& ! NILP (prev
))
3505 int this_one
= ((*sizefun
) (prev
)
3506 - window_min_size (XWINDOW (prev
),
3507 widthflag
, 0, &fixed_p
));
3510 if (this_one
> delta
)
3513 first_affected
= prev
;
3515 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
3516 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3521 prev
= XWINDOW (prev
)->prev
;
3525 xassert (delta
== 0);
3527 /* Now recalculate the edge positions of all the windows affected,
3528 based on the new sizes. */
3529 first_unaffected
= next
;
3530 prev
= first_affected
;
3531 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
3532 prev
= next
, next
= XWINDOW (next
)->next
)
3534 XSETINT (CURBEG (next
), XINT (CURBEG (prev
)) + (*sizefun
) (prev
));
3535 /* This does not change size of NEXT,
3536 but it propagates the new top edge to its children */
3537 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
3542 register int delta1
;
3543 register int opht
= (*sizefun
) (parent
);
3545 if (opht
<= XINT (*sizep
) + delta
)
3547 /* If trying to grow this window to or beyond size of the parent,
3548 just delete all the sibling windows. */
3549 Lisp_Object start
, tem
, next
;
3551 start
= XWINDOW (parent
)->vchild
;
3553 start
= XWINDOW (parent
)->hchild
;
3555 /* Delete any siblings that come after WINDOW. */
3556 tem
= XWINDOW (window
)->next
;
3557 while (! NILP (tem
))
3559 next
= XWINDOW (tem
)->next
;
3560 delete_window (tem
);
3564 /* Delete any siblings that come after WINDOW.
3565 Note that if START is not WINDOW, then WINDOW still
3566 Fhas siblings, so WINDOW has not yet replaced its parent. */
3568 while (! EQ (tem
, window
))
3570 next
= XWINDOW (tem
)->next
;
3571 delete_window (tem
);
3577 /* Otherwise, make delta1 just right so that if we add
3578 delta1 lines to this window and to the parent, and then
3579 shrink the parent back to its original size, the new
3580 proportional size of this window will increase by delta.
3582 The function size_window will compute the new height h'
3583 of the window from delta1 as:
3586 x = delta1 - delta1/n * n for the 1st resizable child
3589 where n is the number of children that can be resized.
3590 We can ignore x by choosing a delta1 that is a multiple of
3591 n. We want the height of this window to come out as
3601 The number of children n rquals the number of resizable
3602 children of this window + 1 because we know window itself
3603 is resizable (otherwise we would have signalled an error. */
3605 struct window
*w
= XWINDOW (window
);
3609 for (s
= w
->next
; !NILP (s
); s
= XWINDOW (s
)->next
)
3610 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3612 for (s
= w
->prev
; !NILP (s
); s
= XWINDOW (s
)->prev
)
3613 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3618 /* Add delta1 lines or columns to this window, and to the parent,
3619 keeping things consistent while not affecting siblings. */
3620 XSETINT (CURSIZE (parent
), opht
+ delta1
);
3621 (*setsizefun
) (window
, XINT (*sizep
) + delta1
, 0);
3623 /* Squeeze out delta1 lines or columns from our parent,
3624 shriking this window and siblings proportionately.
3625 This brings parent back to correct size.
3626 Delta1 was calculated so this makes this window the desired size,
3627 taking it all out of the siblings. */
3628 (*setsizefun
) (parent
, opht
, 0);
3633 XSETFASTINT (p
->last_modified
, 0);
3634 XSETFASTINT (p
->last_overlay_modified
, 0);
3636 /* Adjust glyph matrices. */
3637 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
3645 /***********************************************************************
3646 Resizing Mini-Windows
3647 ***********************************************************************/
3649 static void shrink_window_lowest_first
P_ ((struct window
*, int));
3651 enum save_restore_action
3658 static int save_restore_orig_size
P_ ((struct window
*,
3659 enum save_restore_action
));
3661 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
3662 from lowest windows first. */
3665 shrink_window_lowest_first (w
, height
)
3673 xassert (!MINI_WINDOW_P (w
));
3675 /* Set redisplay hints. */
3676 XSETFASTINT (w
->last_modified
, 0);
3677 XSETFASTINT (w
->last_overlay_modified
, 0);
3678 windows_or_buffers_changed
++;
3679 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
3681 old_height
= XFASTINT (w
->height
);
3682 XSETFASTINT (w
->height
, height
);
3684 if (!NILP (w
->hchild
))
3686 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
3688 c
= XWINDOW (child
);
3690 shrink_window_lowest_first (c
, height
);
3693 else if (!NILP (w
->vchild
))
3695 Lisp_Object last_child
;
3696 int delta
= old_height
- height
;
3701 /* Find the last child. We are taking space from lowest windows
3702 first, so we iterate over children from the last child
3704 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
3707 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
3708 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
3712 c
= XWINDOW (child
);
3713 this_one
= XFASTINT (c
->height
) - MIN_SAFE_WINDOW_HEIGHT
;
3715 if (this_one
> delta
)
3718 shrink_window_lowest_first (c
, XFASTINT (c
->height
) - this_one
);
3722 /* Compute new positions. */
3723 last_top
= XINT (w
->top
);
3724 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
3726 c
= XWINDOW (child
);
3727 c
->top
= make_number (last_top
);
3728 shrink_window_lowest_first (c
, XFASTINT (c
->height
));
3729 last_top
+= XFASTINT (c
->height
);
3735 /* Save, restore, or check positions and sizes in the window tree
3736 rooted at W. ACTION says what to do.
3738 If ACTION is CHECK_ORIG_SIZES, check if orig_top and orig_height
3739 members are valid for all windows in the window tree. Value is
3740 non-zero if they are valid.
3742 If ACTION is SAVE_ORIG_SIZES, save members top and height in
3743 orig_top and orig_height for all windows in the tree.
3745 If ACTION is RESTORE_ORIG_SIZES, restore top and height from
3746 values stored in orig_top and orig_height for all windows. */
3749 save_restore_orig_size (w
, action
)
3751 enum save_restore_action action
;
3757 if (!NILP (w
->hchild
))
3759 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
3762 else if (!NILP (w
->vchild
))
3764 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
3770 case CHECK_ORIG_SIZES
:
3771 if (!INTEGERP (w
->orig_top
) || !INTEGERP (w
->orig_height
))
3775 case SAVE_ORIG_SIZES
:
3776 w
->orig_top
= w
->top
;
3777 w
->orig_height
= w
->height
;
3778 XSETFASTINT (w
->last_modified
, 0);
3779 XSETFASTINT (w
->last_overlay_modified
, 0);
3782 case RESTORE_ORIG_SIZES
:
3783 xassert (INTEGERP (w
->orig_top
) && INTEGERP (w
->orig_height
));
3784 w
->top
= w
->orig_top
;
3785 w
->height
= w
->orig_height
;
3786 w
->orig_height
= w
->orig_top
= Qnil
;
3787 XSETFASTINT (w
->last_modified
, 0);
3788 XSETFASTINT (w
->last_overlay_modified
, 0);
3795 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
3802 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
3803 without deleting other windows. */
3806 grow_mini_window (w
, delta
)
3810 struct frame
*f
= XFRAME (w
->frame
);
3811 struct window
*root
;
3813 xassert (MINI_WINDOW_P (w
));
3814 xassert (delta
>= 0);
3816 /* Check values of window_min_width and window_min_height for
3818 check_min_window_sizes ();
3820 /* Compute how much we can enlarge the mini-window without deleting
3822 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3825 int min_height
= window_min_size (root
, 0, 0, 0);
3826 if (XFASTINT (root
->height
) - delta
< min_height
)
3827 /* Note that the root window may already be smaller than
3829 delta
= max (0, XFASTINT (root
->height
) - min_height
);
3834 /* Save original window sizes and positions, if not already done. */
3835 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3836 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
3838 /* Shrink other windows. */
3839 shrink_window_lowest_first (root
, XFASTINT (root
->height
) - delta
);
3841 /* Grow the mini-window. */
3842 w
->top
= make_number (XFASTINT (root
->top
) + XFASTINT (root
->height
));
3843 w
->height
= make_number (XFASTINT (w
->height
) + delta
);
3844 XSETFASTINT (w
->last_modified
, 0);
3845 XSETFASTINT (w
->last_overlay_modified
, 0);
3852 /* Shrink mini-window W. If there is recorded info about window sizes
3853 before a call to grow_mini_window, restore recorded window sizes.
3854 Otherwise, if the mini-window is higher than 1 line, resize it to 1
3858 shrink_mini_window (w
)
3861 struct frame
*f
= XFRAME (w
->frame
);
3862 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3864 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3866 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
3868 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
3869 windows_or_buffers_changed
= 1;
3871 else if (XFASTINT (w
->height
) > 1)
3873 /* Distribute the additional lines of the mini-window
3874 among the other windows. */
3876 XSETWINDOW (window
, w
);
3877 enlarge_window (window
, 1 - XFASTINT (w
->height
), 0, 0);
3883 /* Mark window cursors off for all windows in the window tree rooted
3884 at W by setting their phys_cursor_on_p flag to zero. Called from
3885 xterm.c, e.g. when a frame is cleared and thereby all cursors on
3886 the frame are cleared. */
3889 mark_window_cursors_off (w
)
3894 if (!NILP (w
->hchild
))
3895 mark_window_cursors_off (XWINDOW (w
->hchild
));
3896 else if (!NILP (w
->vchild
))
3897 mark_window_cursors_off (XWINDOW (w
->vchild
));
3899 w
->phys_cursor_on_p
= 0;
3901 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
3906 /* Return number of lines of text (not counting mode lines) in W. */
3909 window_internal_height (w
)
3912 int ht
= XFASTINT (w
->height
);
3914 if (!MINI_WINDOW_P (w
))
3916 if (!NILP (w
->parent
)
3917 || !NILP (w
->vchild
)
3918 || !NILP (w
->hchild
)
3921 || WINDOW_WANTS_MODELINE_P (w
))
3924 if (WINDOW_WANTS_HEADER_LINE_P (w
))
3932 /* Return the number of columns in W.
3933 Don't count columns occupied by scroll bars or the vertical bar
3934 separating W from the sibling to its right. */
3937 window_internal_width (w
)
3940 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
3941 int width
= XINT (w
->width
);
3943 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
3944 /* Scroll bars occupy a few columns. */
3945 width
-= FRAME_SCROLL_BAR_COLS (f
);
3946 else if (!WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
3947 /* The column of `|' characters separating side-by-side windows
3948 occupies one column only. */
3951 /* On window-systems, areas to the left and right of the window
3952 are used as fringes. */
3953 if (FRAME_WINDOW_P (f
))
3954 width
-= FRAME_FRINGE_COLS (f
);
3960 /************************************************************************
3962 ***********************************************************************/
3964 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
3965 N screen-fulls, which is defined as the height of the window minus
3966 next_screen_context_lines. If WHOLE is zero, scroll up N lines
3967 instead. Negative values of N mean scroll down. NOERROR non-zero
3968 means don't signal an error if we try to move over BEGV or ZV,
3972 window_scroll (window
, n
, whole
, noerror
)
3978 /* If we must, use the pixel-based version which is much slower than
3979 the line-based one but can handle varying line heights. */
3980 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
3981 window_scroll_pixel_based (window
, n
, whole
, noerror
);
3983 window_scroll_line_based (window
, n
, whole
, noerror
);
3987 /* Implementation of window_scroll that works based on pixel line
3988 heights. See the comment of window_scroll for parameter
3992 window_scroll_pixel_based (window
, n
, whole
, noerror
)
3999 struct window
*w
= XWINDOW (window
);
4000 struct text_pos start
;
4002 int this_scroll_margin
;
4004 /* True if we fiddled the window vscroll field without really scrolling. */
4007 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4009 /* If PT is not visible in WINDOW, move back one half of
4010 the screen. Allow PT to be partially visible, otherwise
4011 something like (scroll-down 1) with PT in the line before
4012 the partially visible one would recenter. */
4013 tem
= Fpos_visible_in_window_p (make_number (PT
), window
, Qt
);
4016 /* Move backward half the height of the window. Performance note:
4017 vmotion used here is about 10% faster, but would give wrong
4018 results for variable height lines. */
4019 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4020 it
.current_y
= it
.last_visible_y
;
4021 move_it_vertically (&it
, - window_box_height (w
) / 2);
4023 /* The function move_iterator_vertically may move over more than
4024 the specified y-distance. If it->w is small, e.g. a
4025 mini-buffer window, we may end up in front of the window's
4026 display area. This is the case when Start displaying at the
4027 start of the line containing PT in this case. */
4028 if (it
.current_y
<= 0)
4030 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4031 move_it_vertically (&it
, 0);
4035 start
= it
.current
.pos
;
4038 /* If scroll_preserve_screen_position is non-zero, we try to set
4039 point in the same window line as it is now, so get that line. */
4040 if (!NILP (Vscroll_preserve_screen_position
))
4042 start_display (&it
, w
, start
);
4043 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
4044 preserve_y
= it
.current_y
;
4049 /* Move iterator it from start the specified distance forward or
4050 backward. The result is the new window start. */
4051 start_display (&it
, w
, start
);
4054 int screen_full
= (window_box_height (w
)
4055 - next_screen_context_lines
* CANON_Y_UNIT (it
.f
));
4056 int dy
= n
* screen_full
;
4058 /* Note that move_it_vertically always moves the iterator to the
4059 start of a line. So, if the last line doesn't have a newline,
4060 we would end up at the start of the line ending at ZV. */
4062 move_it_vertically_backward (&it
, -dy
);
4064 move_it_to (&it
, ZV
, -1, it
.current_y
+ dy
, -1,
4065 MOVE_TO_POS
| MOVE_TO_Y
);
4068 move_it_by_lines (&it
, n
, 1);
4070 /* End if we end up at ZV or BEGV. */
4071 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
4072 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
4074 if (IT_CHARPOS (it
) == ZV
)
4076 if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
4077 > it
.last_visible_y
)
4079 /* The last line was only partially visible, make it fully
4081 w
->vscroll
= (it
.last_visible_y
4082 - it
.current_y
+ it
.max_ascent
+ it
.max_descent
);
4083 adjust_glyphs (it
.f
);
4088 Fsignal (Qend_of_buffer
, Qnil
);
4092 if (w
->vscroll
!= 0)
4093 /* The first line was only partially visible, make it fully
4099 Fsignal (Qbeginning_of_buffer
, Qnil
);
4102 /* If control gets here, then we vscrolled. */
4104 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
4106 /* Don't try to change the window start below. */
4112 /* Set the window start, and set up the window for redisplay. */
4113 set_marker_restricted (w
->start
, make_number (IT_CHARPOS (it
)),
4115 w
->start_at_line_beg
= Fbolp ();
4116 w
->update_mode_line
= Qt
;
4117 XSETFASTINT (w
->last_modified
, 0);
4118 XSETFASTINT (w
->last_overlay_modified
, 0);
4119 /* Set force_start so that redisplay_window will run the
4120 window-scroll-functions. */
4121 w
->force_start
= Qt
;
4124 it
.current_y
= it
.vpos
= 0;
4126 /* Preserve the screen position if we must. */
4127 if (preserve_y
>= 0)
4129 move_it_to (&it
, -1, -1, preserve_y
, -1, MOVE_TO_Y
);
4130 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4134 /* Move PT out of scroll margins. */
4135 this_scroll_margin
= max (0, scroll_margin
);
4136 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->height
) / 4);
4137 this_scroll_margin
*= CANON_Y_UNIT (it
.f
);
4141 /* We moved the window start towards ZV, so PT may be now
4142 in the scroll margin at the top. */
4143 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
4144 while (it
.current_y
< this_scroll_margin
)
4145 move_it_by_lines (&it
, 1, 1);
4146 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4150 int charpos
, bytepos
;
4152 /* We moved the window start towards BEGV, so PT may be now
4153 in the scroll margin at the bottom. */
4154 move_it_to (&it
, PT
, -1,
4155 it
.last_visible_y
- this_scroll_margin
- 1, -1,
4156 MOVE_TO_POS
| MOVE_TO_Y
);
4158 /* Save our position, in case it's correct. */
4159 charpos
= IT_CHARPOS (it
);
4160 bytepos
= IT_BYTEPOS (it
);
4162 /* See if point is on a partially visible line at the end. */
4163 move_it_by_lines (&it
, 1, 1);
4164 if (it
.current_y
> it
.last_visible_y
)
4165 /* The last line was only partially visible, so back up two
4166 lines to make sure we're on a fully visible line. */
4168 move_it_by_lines (&it
, -2, 0);
4169 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4172 /* No, the position we saved is OK, so use it. */
4173 SET_PT_BOTH (charpos
, bytepos
);
4179 /* Implementation of window_scroll that works based on screen lines.
4180 See the comment of window_scroll for parameter descriptions. */
4183 window_scroll_line_based (window
, n
, whole
, noerror
)
4189 register struct window
*w
= XWINDOW (window
);
4190 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
4191 register int pos
, pos_byte
;
4192 register int ht
= window_internal_height (w
);
4193 register Lisp_Object tem
;
4197 struct position posit
;
4200 /* If scrolling screen-fulls, compute the number of lines to
4201 scroll from the window's height. */
4203 n
*= max (1, ht
- next_screen_context_lines
);
4205 startpos
= marker_position (w
->start
);
4207 posit
= *compute_motion (startpos
, 0, 0, 0,
4209 window_internal_width (w
), XINT (w
->hscroll
),
4211 original_vpos
= posit
.vpos
;
4213 XSETFASTINT (tem
, PT
);
4214 tem
= Fpos_visible_in_window_p (tem
, window
, Qnil
);
4218 Fvertical_motion (make_number (- (ht
/ 2)), window
);
4223 lose
= n
< 0 && PT
== BEGV
;
4224 Fvertical_motion (make_number (n
), window
);
4228 SET_PT_BOTH (opoint
, opoint_byte
);
4235 Fsignal (Qbeginning_of_buffer
, Qnil
);
4240 int this_scroll_margin
= scroll_margin
;
4242 /* Don't use a scroll margin that is negative or too large. */
4243 if (this_scroll_margin
< 0)
4244 this_scroll_margin
= 0;
4246 if (XINT (w
->height
) < 4 * scroll_margin
)
4247 this_scroll_margin
= XINT (w
->height
) / 4;
4249 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
4250 w
->start_at_line_beg
= bolp
;
4251 w
->update_mode_line
= Qt
;
4252 XSETFASTINT (w
->last_modified
, 0);
4253 XSETFASTINT (w
->last_overlay_modified
, 0);
4254 /* Set force_start so that redisplay_window will run
4255 the window-scroll-functions. */
4256 w
->force_start
= Qt
;
4258 if (whole
&& !NILP (Vscroll_preserve_screen_position
))
4260 SET_PT_BOTH (pos
, pos_byte
);
4261 Fvertical_motion (make_number (original_vpos
), window
);
4263 /* If we scrolled forward, put point enough lines down
4264 that it is outside the scroll margin. */
4269 if (this_scroll_margin
> 0)
4271 SET_PT_BOTH (pos
, pos_byte
);
4272 Fvertical_motion (make_number (this_scroll_margin
), window
);
4278 if (top_margin
<= opoint
)
4279 SET_PT_BOTH (opoint
, opoint_byte
);
4280 else if (!NILP (Vscroll_preserve_screen_position
))
4282 SET_PT_BOTH (pos
, pos_byte
);
4283 Fvertical_motion (make_number (original_vpos
), window
);
4286 SET_PT (top_margin
);
4292 /* If we scrolled backward, put point near the end of the window
4293 but not within the scroll margin. */
4294 SET_PT_BOTH (pos
, pos_byte
);
4295 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
4296 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
4299 bottom_margin
= PT
+ 1;
4301 if (bottom_margin
> opoint
)
4302 SET_PT_BOTH (opoint
, opoint_byte
);
4305 if (!NILP (Vscroll_preserve_screen_position
))
4307 SET_PT_BOTH (pos
, pos_byte
);
4308 Fvertical_motion (make_number (original_vpos
), window
);
4311 Fvertical_motion (make_number (-1), window
);
4320 Fsignal (Qend_of_buffer
, Qnil
);
4325 /* Scroll selected_window up or down. If N is nil, scroll a
4326 screen-full which is defined as the height of the window minus
4327 next_screen_context_lines. If N is the symbol `-', scroll.
4328 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
4329 up. This is the guts of Fscroll_up and Fscroll_down. */
4332 scroll_command (n
, direction
)
4336 int count
= BINDING_STACK_SIZE ();
4338 xassert (abs (direction
) == 1);
4340 /* If selected window's buffer isn't current, make it current for
4341 the moment. But don't screw up if window_scroll gets an error. */
4342 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
4344 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4345 Fset_buffer (XWINDOW (selected_window
)->buffer
);
4347 /* Make redisplay consider other windows than just selected_window. */
4348 ++windows_or_buffers_changed
;
4352 window_scroll (selected_window
, direction
, 1, 0);
4353 else if (EQ (n
, Qminus
))
4354 window_scroll (selected_window
, -direction
, 1, 0);
4357 n
= Fprefix_numeric_value (n
);
4358 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
4361 unbind_to (count
, Qnil
);
4364 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
4365 doc
: /* Scroll text of current window upward ARG lines; or near full screen if no ARG.
4366 A near full screen is `next-screen-context-lines' less than a full screen.
4367 Negative ARG means scroll downward.
4368 If ARG is the atom `-', scroll downward by nearly full screen.
4369 When calling from a program, supply as argument a number, nil, or `-'. */)
4373 scroll_command (arg
, 1);
4377 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
4378 doc
: /* Scroll text of current window down ARG lines; or near full screen if no ARG.
4379 A near full screen is `next-screen-context-lines' less than a full screen.
4380 Negative ARG means scroll upward.
4381 If ARG is the atom `-', scroll upward by nearly full screen.
4382 When calling from a program, supply as argument a number, nil, or `-'. */)
4386 scroll_command (arg
, -1);
4390 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
4391 doc
: /* Return the other window for \"other window scroll\" commands.
4392 If in the minibuffer, `minibuffer-scroll-window' if non-nil
4393 specifies the window.
4394 If `other-window-scroll-buffer' is non-nil, a window
4395 showing that buffer is used. */)
4400 if (MINI_WINDOW_P (XWINDOW (selected_window
))
4401 && !NILP (Vminibuf_scroll_window
))
4402 window
= Vminibuf_scroll_window
;
4403 /* If buffer is specified, scroll that buffer. */
4404 else if (!NILP (Vother_window_scroll_buffer
))
4406 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
4408 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
4412 /* Nothing specified; look for a neighboring window on the same
4414 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
4416 if (EQ (window
, selected_window
))
4417 /* That didn't get us anywhere; look for a window on another
4420 window
= Fnext_window (window
, Qnil
, Qt
);
4421 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
4422 && ! EQ (window
, selected_window
));
4425 CHECK_LIVE_WINDOW (window
);
4427 if (EQ (window
, selected_window
))
4428 error ("There is no other window");
4433 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
4434 doc
: /* Scroll next window upward ARG lines; or near full screen if no ARG.
4435 A near full screen is `next-screen-context-lines' less than a full screen.
4436 The next window is the one below the current one; or the one at the top
4437 if the current one is at the bottom. Negative ARG means scroll downward.
4438 If ARG is the atom `-', scroll downward by nearly full screen.
4439 When calling from a program, supply as argument a number, nil, or `-'.
4441 If in the minibuffer, `minibuffer-scroll-window' if non-nil
4442 specifies the window to scroll.
4443 If `other-window-scroll-buffer' is non-nil, scroll the window
4444 showing that buffer, popping the buffer up if necessary. */)
4450 int count
= BINDING_STACK_SIZE ();
4452 window
= Fother_window_for_scrolling ();
4453 w
= XWINDOW (window
);
4455 /* Don't screw up if window_scroll gets an error. */
4456 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4457 ++windows_or_buffers_changed
;
4459 Fset_buffer (w
->buffer
);
4460 SET_PT (marker_position (w
->pointm
));
4463 window_scroll (window
, 1, 1, 1);
4464 else if (EQ (arg
, Qminus
))
4465 window_scroll (window
, -1, 1, 1);
4471 window_scroll (window
, XINT (arg
), 0, 1);
4474 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
4475 unbind_to (count
, Qnil
);
4480 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 1, "P",
4481 doc
: /* Scroll selected window display ARG columns left.
4482 Default for ARG is window width minus 2.
4483 Value is the total amount of leftward horizontal scrolling in
4484 effect after the change.
4485 If `automatic-hscrolling' is non-nil, the argument ARG modifies
4486 a lower bound for automatic scrolling, i.e. automatic scrolling
4487 will not scroll a window to a column less than the value returned
4488 by this function. */)
4490 register Lisp_Object arg
;
4494 struct window
*w
= XWINDOW (selected_window
);
4497 XSETFASTINT (arg
, window_internal_width (w
) - 2);
4499 arg
= Fprefix_numeric_value (arg
);
4501 hscroll
= XINT (w
->hscroll
) + XINT (arg
);
4502 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
4504 if (interactive_p (0))
4505 w
->min_hscroll
= w
->hscroll
;
4510 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 1, "P",
4511 doc
: /* Scroll selected window display ARG columns right.
4512 Default for ARG is window width minus 2.
4513 Value is the total amount of leftward horizontal scrolling in
4514 effect after the change.
4515 If `automatic-hscrolling' is non-nil, the argument ARG modifies
4516 a lower bound for automatic scrolling, i.e. automatic scrolling
4517 will not scroll a window to a column less than the value returned
4518 by this function. */)
4520 register Lisp_Object arg
;
4524 struct window
*w
= XWINDOW (selected_window
);
4527 XSETFASTINT (arg
, window_internal_width (w
) - 2);
4529 arg
= Fprefix_numeric_value (arg
);
4531 hscroll
= XINT (w
->hscroll
) - XINT (arg
);
4532 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
4534 if (interactive_p (0))
4535 w
->min_hscroll
= w
->hscroll
;
4540 /* Value is the number of lines actually displayed in window W,
4541 as opposed to its height. */
4544 displayed_window_lines (w
)
4548 struct text_pos start
;
4549 int height
= window_box_height (w
);
4550 struct buffer
*old_buffer
;
4553 if (XBUFFER (w
->buffer
) != current_buffer
)
4555 old_buffer
= current_buffer
;
4556 set_buffer_internal (XBUFFER (w
->buffer
));
4561 /* In case W->start is out of the accessible range, do something
4562 reasonable. This happens in Info mode when Info-scroll-down
4563 calls (recenter -1) while W->start is 1. */
4564 if (XMARKER (w
->start
)->charpos
< BEGV
)
4565 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
4566 else if (XMARKER (w
->start
)->charpos
> ZV
)
4567 SET_TEXT_POS (start
, ZV
, ZV_BYTE
);
4569 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4571 start_display (&it
, w
, start
);
4572 move_it_vertically (&it
, height
);
4573 bottom_y
= line_bottom_y (&it
);
4575 /* Add in empty lines at the bottom of the window. */
4576 if (bottom_y
< height
)
4578 int uy
= CANON_Y_UNIT (it
.f
);
4579 it
.vpos
+= (height
- bottom_y
+ uy
- 1) / uy
;
4583 set_buffer_internal (old_buffer
);
4589 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
4590 doc
: /* Center point in window and redisplay frame.
4591 With prefix argument ARG, recenter putting point on screen line ARG
4592 relative to the current window. If ARG is negative, it counts up from the
4593 bottom of the window. (ARG should be less than the height of the window.)
4595 If ARG is omitted or nil, erase the entire frame and then
4596 redraw with point in the center of the current window.
4597 Just C-u as prefix means put point in the center of the window
4598 and redisplay normally--don't erase and redraw the frame. */)
4600 register Lisp_Object arg
;
4602 struct window
*w
= XWINDOW (selected_window
);
4603 struct buffer
*buf
= XBUFFER (w
->buffer
);
4604 struct buffer
*obuf
= current_buffer
;
4606 int charpos
, bytepos
;
4608 /* If redisplay is suppressed due to an error, try again. */
4609 obuf
->display_error_modiff
= 0;
4615 /* Invalidate pixel data calculated for all compositions. */
4616 for (i
= 0; i
< n_compositions
; i
++)
4617 composition_table
[i
]->font
= NULL
;
4619 Fredraw_frame (w
->frame
);
4620 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
4623 else if (CONSP (arg
)) /* Just C-u. */
4627 arg
= Fprefix_numeric_value (arg
);
4631 set_buffer_internal (buf
);
4633 /* Handle centering on a graphical frame specially. Such frames can
4634 have variable-height lines and centering point on the basis of
4635 line counts would lead to strange effects. */
4636 if (FRAME_WINDOW_P (XFRAME (w
->frame
)))
4643 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
4644 start_display (&it
, w
, pt
);
4645 move_it_vertically (&it
, - window_box_height (w
) / 2);
4646 charpos
= IT_CHARPOS (it
);
4647 bytepos
= IT_BYTEPOS (it
);
4649 else if (XINT (arg
) < 0)
4653 int y0
, y1
, h
, nlines
;
4655 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
4656 start_display (&it
, w
, pt
);
4659 /* The amount of pixels we have to move back is the window
4660 height minus what's displayed in the line containing PT,
4661 and the lines below. */
4662 nlines
= - XINT (arg
) - 1;
4663 move_it_by_lines (&it
, nlines
, 1);
4665 y1
= line_bottom_y (&it
);
4667 /* If we can't move down NLINES lines because we hit
4668 the end of the buffer, count in some empty lines. */
4669 if (it
.vpos
< nlines
)
4670 y1
+= (nlines
- it
.vpos
) * CANON_Y_UNIT (it
.f
);
4672 h
= window_box_height (w
) - (y1
- y0
);
4674 start_display (&it
, w
, pt
);
4675 move_it_vertically (&it
, - h
);
4676 charpos
= IT_CHARPOS (it
);
4677 bytepos
= IT_BYTEPOS (it
);
4681 struct position pos
;
4682 pos
= *vmotion (PT
, - XINT (arg
), w
);
4683 charpos
= pos
.bufpos
;
4684 bytepos
= pos
.bytepos
;
4689 struct position pos
;
4690 int ht
= window_internal_height (w
);
4693 arg
= make_number (ht
/ 2);
4694 else if (XINT (arg
) < 0)
4695 arg
= make_number (XINT (arg
) + ht
);
4697 pos
= *vmotion (PT
, - XINT (arg
), w
);
4698 charpos
= pos
.bufpos
;
4699 bytepos
= pos
.bytepos
;
4702 /* Set the new window start. */
4703 set_marker_both (w
->start
, w
->buffer
, charpos
, bytepos
);
4704 w
->window_end_valid
= Qnil
;
4705 w
->force_start
= Qt
;
4706 if (bytepos
== BEGV_BYTE
|| FETCH_BYTE (bytepos
- 1) == '\n')
4707 w
->start_at_line_beg
= Qt
;
4709 w
->start_at_line_beg
= Qnil
;
4711 set_buffer_internal (obuf
);
4716 DEFUN ("window-text-height", Fwindow_text_height
, Swindow_text_height
,
4718 doc
: /* Return the height in lines of the text display area of WINDOW.
4719 This doesn't include the mode-line (or header-line if any) or any
4720 partial-height lines in the text display area. */)
4724 struct window
*w
= decode_window (window
);
4725 int pixel_height
= window_box_height (w
);
4726 int line_height
= pixel_height
/ CANON_Y_UNIT (XFRAME (w
->frame
));
4727 return make_number (line_height
);
4732 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
4734 doc
: /* Position point relative to window.
4735 With no argument, position point at center of window.
4736 An argument specifies vertical position within the window;
4737 zero means top of window, negative means relative to bottom of window. */)
4741 struct window
*w
= XWINDOW (selected_window
);
4745 window
= selected_window
;
4746 start
= marker_position (w
->start
);
4747 if (start
< BEGV
|| start
> ZV
)
4749 int height
= window_internal_height (w
);
4750 Fvertical_motion (make_number (- (height
/ 2)), window
);
4751 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
4752 w
->start_at_line_beg
= Fbolp ();
4753 w
->force_start
= Qt
;
4756 Fgoto_char (w
->start
);
4758 lines
= displayed_window_lines (w
);
4760 XSETFASTINT (arg
, lines
/ 2);
4763 arg
= Fprefix_numeric_value (arg
);
4765 XSETINT (arg
, XINT (arg
) + lines
);
4768 /* Skip past a partially visible first line. */
4770 XSETINT (arg
, XINT (arg
) + 1);
4772 return Fvertical_motion (arg
, window
);
4777 /***********************************************************************
4778 Window Configuration
4779 ***********************************************************************/
4781 struct save_window_data
4783 EMACS_INT size_from_Lisp_Vector_struct
;
4784 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4785 Lisp_Object frame_width
, frame_height
, frame_menu_bar_lines
;
4786 Lisp_Object frame_tool_bar_lines
;
4787 Lisp_Object selected_frame
;
4788 Lisp_Object current_window
;
4789 Lisp_Object current_buffer
;
4790 Lisp_Object minibuf_scroll_window
;
4791 Lisp_Object root_window
;
4792 Lisp_Object focus_frame
;
4793 /* Record the values of window-min-width and window-min-height
4794 so that window sizes remain consistent with them. */
4795 Lisp_Object min_width
, min_height
;
4796 /* A vector, each of whose elements is a struct saved_window
4798 Lisp_Object saved_windows
;
4801 /* This is saved as a Lisp_Vector */
4804 /* these first two must agree with struct Lisp_Vector in lisp.h */
4805 EMACS_INT size_from_Lisp_Vector_struct
;
4806 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4809 Lisp_Object buffer
, start
, pointm
, mark
;
4810 Lisp_Object left
, top
, width
, height
, hscroll
, min_hscroll
;
4811 Lisp_Object parent
, prev
;
4812 Lisp_Object start_at_line_beg
;
4813 Lisp_Object display_table
;
4814 Lisp_Object orig_top
, orig_height
;
4817 #define SAVED_WINDOW_VECTOR_SIZE 17 /* Arg to Fmake_vector */
4819 #define SAVED_WINDOW_N(swv,n) \
4820 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
4822 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
4823 doc
: /* Return t if OBJECT is a window-configuration object. */)
4827 if (WINDOW_CONFIGURATIONP (object
))
4832 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
4833 doc
: /* Return the frame that CONFIG, a window-configuration object, is about. */)
4837 register struct save_window_data
*data
;
4838 struct Lisp_Vector
*saved_windows
;
4840 if (! WINDOW_CONFIGURATIONP (config
))
4841 wrong_type_argument (Qwindow_configuration_p
, config
);
4843 data
= (struct save_window_data
*) XVECTOR (config
);
4844 saved_windows
= XVECTOR (data
->saved_windows
);
4845 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4848 DEFUN ("set-window-configuration", Fset_window_configuration
,
4849 Sset_window_configuration
, 1, 1, 0,
4850 doc
: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
4851 CONFIGURATION must be a value previously returned
4852 by `current-window-configuration' (which see).
4853 If CONFIGURATION was made from a frame that is now deleted,
4854 only frame-independent values can be restored. In this case,
4855 the return value is nil. Otherwise the value is t. */)
4857 Lisp_Object configuration
;
4859 register struct save_window_data
*data
;
4860 struct Lisp_Vector
*saved_windows
;
4861 Lisp_Object new_current_buffer
;
4866 while (!WINDOW_CONFIGURATIONP (configuration
))
4867 wrong_type_argument (Qwindow_configuration_p
, configuration
);
4869 data
= (struct save_window_data
*) XVECTOR (configuration
);
4870 saved_windows
= XVECTOR (data
->saved_windows
);
4872 new_current_buffer
= data
->current_buffer
;
4873 if (NILP (XBUFFER (new_current_buffer
)->name
))
4874 new_current_buffer
= Qnil
;
4877 if (XBUFFER (new_current_buffer
) == current_buffer
)
4881 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4884 /* If f is a dead frame, don't bother rebuilding its window tree.
4885 However, there is other stuff we should still try to do below. */
4886 if (FRAME_LIVE_P (f
))
4888 register struct window
*w
;
4889 register struct saved_window
*p
;
4890 struct window
*root_window
;
4891 struct window
**leaf_windows
;
4895 /* If the frame has been resized since this window configuration was
4896 made, we change the frame to the size specified in the
4897 configuration, restore the configuration, and then resize it
4898 back. We keep track of the prevailing height in these variables. */
4899 int previous_frame_height
= FRAME_HEIGHT (f
);
4900 int previous_frame_width
= FRAME_WIDTH (f
);
4901 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
4902 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
4904 /* The mouse highlighting code could get screwed up
4905 if it runs during this. */
4908 if (XFASTINT (data
->frame_height
) != previous_frame_height
4909 || XFASTINT (data
->frame_width
) != previous_frame_width
)
4910 change_frame_size (f
, XFASTINT (data
->frame_height
),
4911 XFASTINT (data
->frame_width
), 0, 0, 0);
4912 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4913 if (XFASTINT (data
->frame_menu_bar_lines
)
4914 != previous_frame_menu_bar_lines
)
4915 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, make_number (0));
4916 #ifdef HAVE_WINDOW_SYSTEM
4917 if (XFASTINT (data
->frame_tool_bar_lines
)
4918 != previous_frame_tool_bar_lines
)
4919 x_set_tool_bar_lines (f
, data
->frame_tool_bar_lines
, make_number (0));
4923 /* "Swap out" point from the selected window
4924 into its buffer. We do this now, before
4925 restoring the window contents, and prevent it from
4926 being done later on when we select a new window. */
4927 if (! NILP (XWINDOW (selected_window
)->buffer
))
4929 w
= XWINDOW (selected_window
);
4930 set_marker_both (w
->pointm
,
4932 BUF_PT (XBUFFER (w
->buffer
)),
4933 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4936 windows_or_buffers_changed
++;
4937 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4939 /* Problem: Freeing all matrices and later allocating them again
4940 is a serious redisplay flickering problem. What we would
4941 really like to do is to free only those matrices not reused
4943 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4945 = (struct window
**) alloca (count_windows (root_window
)
4946 * sizeof (struct window
*));
4947 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
4949 /* Temporarily avoid any problems with windows that are smaller
4950 than they are supposed to be. */
4951 window_min_height
= 1;
4952 window_min_width
= 1;
4955 Mark all windows now on frame as "deleted".
4956 Restoring the new configuration "undeletes" any that are in it.
4958 Save their current buffers in their height fields, since we may
4959 need it later, if a buffer saved in the configuration is now
4961 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4963 for (k
= 0; k
< saved_windows
->size
; k
++)
4965 p
= SAVED_WINDOW_N (saved_windows
, k
);
4966 w
= XWINDOW (p
->window
);
4969 if (!NILP (p
->parent
))
4970 w
->parent
= SAVED_WINDOW_N (saved_windows
,
4971 XFASTINT (p
->parent
))->window
;
4975 if (!NILP (p
->prev
))
4977 w
->prev
= SAVED_WINDOW_N (saved_windows
,
4978 XFASTINT (p
->prev
))->window
;
4979 XWINDOW (w
->prev
)->next
= p
->window
;
4984 if (!NILP (w
->parent
))
4986 if (EQ (p
->width
, XWINDOW (w
->parent
)->width
))
4988 XWINDOW (w
->parent
)->vchild
= p
->window
;
4989 XWINDOW (w
->parent
)->hchild
= Qnil
;
4993 XWINDOW (w
->parent
)->hchild
= p
->window
;
4994 XWINDOW (w
->parent
)->vchild
= Qnil
;
4999 /* If we squirreled away the buffer in the window's height,
5001 if (BUFFERP (w
->height
))
5002 w
->buffer
= w
->height
;
5005 w
->width
= p
->width
;
5006 w
->height
= p
->height
;
5007 w
->hscroll
= p
->hscroll
;
5008 w
->min_hscroll
= p
->min_hscroll
;
5009 w
->display_table
= p
->display_table
;
5010 w
->orig_top
= p
->orig_top
;
5011 w
->orig_height
= p
->orig_height
;
5012 XSETFASTINT (w
->last_modified
, 0);
5013 XSETFASTINT (w
->last_overlay_modified
, 0);
5015 /* Reinstall the saved buffer and pointers into it. */
5016 if (NILP (p
->buffer
))
5017 w
->buffer
= p
->buffer
;
5020 if (!NILP (XBUFFER (p
->buffer
)->name
))
5021 /* If saved buffer is alive, install it. */
5023 w
->buffer
= p
->buffer
;
5024 w
->start_at_line_beg
= p
->start_at_line_beg
;
5025 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
5026 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
5027 Fset_marker (XBUFFER (w
->buffer
)->mark
,
5028 p
->mark
, w
->buffer
);
5030 /* As documented in Fcurrent_window_configuration, don't
5031 save the location of point in the buffer which was current
5032 when the window configuration was recorded. */
5033 if (!EQ (p
->buffer
, new_current_buffer
)
5034 && XBUFFER (p
->buffer
) == current_buffer
)
5035 Fgoto_char (w
->pointm
);
5037 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
5038 /* Else unless window has a live buffer, get one. */
5040 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
5041 /* This will set the markers to beginning of visible
5043 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
5044 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
5045 w
->start_at_line_beg
= Qt
;
5048 /* Keeping window's old buffer; make sure the markers
5051 /* Set window markers at start of visible range. */
5052 if (XMARKER (w
->start
)->buffer
== 0)
5053 set_marker_restricted (w
->start
, make_number (0),
5055 if (XMARKER (w
->pointm
)->buffer
== 0)
5056 set_marker_restricted_both (w
->pointm
, w
->buffer
,
5057 BUF_PT (XBUFFER (w
->buffer
)),
5058 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5059 w
->start_at_line_beg
= Qt
;
5064 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
5065 /* Prevent "swapping out point" in the old selected window
5066 using the buffer that has been restored into it.
5067 That swapping out has already been done,
5068 near the beginning of this function. */
5069 selected_window
= Qnil
;
5070 Fselect_window (data
->current_window
);
5071 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
5074 if (NILP (data
->focus_frame
)
5075 || (FRAMEP (data
->focus_frame
)
5076 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
5077 Fredirect_frame_focus (frame
, data
->focus_frame
);
5079 #if 0 /* I don't understand why this is needed, and it causes problems
5080 when the frame's old selected window has been deleted. */
5081 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
5082 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
5086 /* Set the screen height to the value it had before this function. */
5087 if (previous_frame_height
!= FRAME_HEIGHT (f
)
5088 || previous_frame_width
!= FRAME_WIDTH (f
))
5089 change_frame_size (f
, previous_frame_height
, previous_frame_width
,
5091 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
5092 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
5093 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
5095 #ifdef HAVE_WINDOW_SYSTEM
5096 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
5097 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
5102 /* Now, free glyph matrices in windows that were not reused. */
5103 for (i
= n
= 0; i
< n_leaf_windows
; ++i
)
5105 if (NILP (leaf_windows
[i
]->buffer
))
5107 /* Assert it's not reused as a combination. */
5108 xassert (NILP (leaf_windows
[i
]->hchild
)
5109 && NILP (leaf_windows
[i
]->vchild
));
5110 free_window_matrices (leaf_windows
[i
]);
5112 else if (EQ (leaf_windows
[i
]->buffer
, new_current_buffer
))
5116 /* If more than one window shows the new and old current buffer,
5117 don't try to preserve point in that buffer. */
5118 if (old_point
> 0 && n
> 1)
5125 /* Fselect_window will have made f the selected frame, so we
5126 reselect the proper frame here. Fhandle_switch_frame will change the
5127 selected window too, but that doesn't make the call to
5128 Fselect_window above totally superfluous; it still sets f's
5130 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
5131 do_switch_frame (data
->selected_frame
, 0, 0);
5133 if (! NILP (Vwindow_configuration_change_hook
)
5134 && ! NILP (Vrun_hooks
))
5135 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
5138 if (!NILP (new_current_buffer
))
5140 Fset_buffer (new_current_buffer
);
5142 /* If the buffer that is current now is the same
5143 that was current before setting the window configuration,
5144 don't alter its PT. */
5149 /* Restore the minimum heights recorded in the configuration. */
5150 window_min_height
= XINT (data
->min_height
);
5151 window_min_width
= XINT (data
->min_width
);
5153 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
5155 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
5158 /* Mark all windows now on frame as deleted
5159 by setting their buffers to nil. */
5162 delete_all_subwindows (w
)
5163 register struct window
*w
;
5165 if (!NILP (w
->next
))
5166 delete_all_subwindows (XWINDOW (w
->next
));
5167 if (!NILP (w
->vchild
))
5168 delete_all_subwindows (XWINDOW (w
->vchild
));
5169 if (!NILP (w
->hchild
))
5170 delete_all_subwindows (XWINDOW (w
->hchild
));
5172 w
->height
= w
->buffer
; /* See Fset_window_configuration for excuse. */
5174 if (!NILP (w
->buffer
))
5177 /* We set all three of these fields to nil, to make sure that we can
5178 distinguish this dead window from any live window. Live leaf
5179 windows will have buffer set, and combination windows will have
5180 vchild or hchild set. */
5185 Vwindow_list
= Qnil
;
5189 count_windows (window
)
5190 register struct window
*window
;
5192 register int count
= 1;
5193 if (!NILP (window
->next
))
5194 count
+= count_windows (XWINDOW (window
->next
));
5195 if (!NILP (window
->vchild
))
5196 count
+= count_windows (XWINDOW (window
->vchild
));
5197 if (!NILP (window
->hchild
))
5198 count
+= count_windows (XWINDOW (window
->hchild
));
5203 /* Fill vector FLAT with leaf windows under W, starting at index I.
5204 Value is last index + 1. */
5207 get_leaf_windows (w
, flat
, i
)
5209 struct window
**flat
;
5214 if (!NILP (w
->hchild
))
5215 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
5216 else if (!NILP (w
->vchild
))
5217 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
5221 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5228 /* Return a pointer to the glyph W's physical cursor is on. Value is
5229 null if W's current matrix is invalid, so that no meaningfull glyph
5233 get_phys_cursor_glyph (w
)
5236 struct glyph_row
*row
;
5237 struct glyph
*glyph
;
5239 if (w
->phys_cursor
.vpos
>= 0
5240 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
5241 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
5243 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
5244 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
5253 save_window_save (window
, vector
, i
)
5255 struct Lisp_Vector
*vector
;
5258 register struct saved_window
*p
;
5259 register struct window
*w
;
5260 register Lisp_Object tem
;
5262 for (;!NILP (window
); window
= w
->next
)
5264 p
= SAVED_WINDOW_N (vector
, i
);
5265 w
= XWINDOW (window
);
5267 XSETFASTINT (w
->temslot
, i
++);
5269 p
->buffer
= w
->buffer
;
5272 p
->width
= w
->width
;
5273 p
->height
= w
->height
;
5274 p
->hscroll
= w
->hscroll
;
5275 p
->min_hscroll
= w
->min_hscroll
;
5276 p
->display_table
= w
->display_table
;
5277 p
->orig_top
= w
->orig_top
;
5278 p
->orig_height
= w
->orig_height
;
5279 if (!NILP (w
->buffer
))
5281 /* Save w's value of point in the window configuration.
5282 If w is the selected window, then get the value of point
5283 from the buffer; pointm is garbage in the selected window. */
5284 if (EQ (window
, selected_window
))
5286 p
->pointm
= Fmake_marker ();
5287 set_marker_both (p
->pointm
, w
->buffer
,
5288 BUF_PT (XBUFFER (w
->buffer
)),
5289 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5292 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
5294 p
->start
= Fcopy_marker (w
->start
, Qnil
);
5295 p
->start_at_line_beg
= w
->start_at_line_beg
;
5297 tem
= XBUFFER (w
->buffer
)->mark
;
5298 p
->mark
= Fcopy_marker (tem
, Qnil
);
5305 p
->start_at_line_beg
= Qnil
;
5308 if (NILP (w
->parent
))
5311 p
->parent
= XWINDOW (w
->parent
)->temslot
;
5316 p
->prev
= XWINDOW (w
->prev
)->temslot
;
5318 if (!NILP (w
->vchild
))
5319 i
= save_window_save (w
->vchild
, vector
, i
);
5320 if (!NILP (w
->hchild
))
5321 i
= save_window_save (w
->hchild
, vector
, i
);
5327 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
5328 Scurrent_window_configuration
, 0, 1, 0,
5329 doc
: /* Return an object representing the current window configuration of FRAME.
5330 If FRAME is nil or omitted, use the selected frame.
5331 This describes the number of windows, their sizes and current buffers,
5332 and for each displayed buffer, where display starts, and the positions of
5333 point and mark. An exception is made for point in the current buffer:
5334 its value is -not- saved.
5335 This also records the currently selected frame, and FRAME's focus
5336 redirection (see `redirect-frame-focus'). */)
5340 register Lisp_Object tem
;
5341 register int n_windows
;
5342 register struct save_window_data
*data
;
5343 register struct Lisp_Vector
*vec
;
5348 frame
= selected_frame
;
5349 CHECK_LIVE_FRAME (frame
);
5352 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5353 vec
= allocate_other_vector (VECSIZE (struct save_window_data
));
5354 data
= (struct save_window_data
*)vec
;
5356 XSETFASTINT (data
->frame_width
, FRAME_WIDTH (f
));
5357 XSETFASTINT (data
->frame_height
, FRAME_HEIGHT (f
));
5358 XSETFASTINT (data
->frame_menu_bar_lines
, FRAME_MENU_BAR_LINES (f
));
5359 XSETFASTINT (data
->frame_tool_bar_lines
, FRAME_TOOL_BAR_LINES (f
));
5360 data
->selected_frame
= selected_frame
;
5361 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
5362 XSETBUFFER (data
->current_buffer
, current_buffer
);
5363 data
->minibuf_scroll_window
= Vminibuf_scroll_window
;
5364 data
->root_window
= FRAME_ROOT_WINDOW (f
);
5365 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
5366 XSETINT (data
->min_height
, window_min_height
);
5367 XSETINT (data
->min_width
, window_min_width
);
5368 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
5369 data
->saved_windows
= tem
;
5370 for (i
= 0; i
< n_windows
; i
++)
5371 XVECTOR (tem
)->contents
[i
]
5372 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
5373 save_window_save (FRAME_ROOT_WINDOW (f
), XVECTOR (tem
), 0);
5374 XSETWINDOW_CONFIGURATION (tem
, data
);
5378 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
5380 doc
: /* Execute body, preserving window sizes and contents.
5381 Restore which buffer appears in which window, where display starts,
5382 and the value of point and mark for each window.
5383 Also restore the choice of selected window.
5384 Also restore which buffer is current.
5385 Does not restore the value of point in current buffer.
5386 usage: (save-window-excursion BODY ...) */)
5390 register Lisp_Object val
;
5391 register int count
= specpdl_ptr
- specpdl
;
5393 record_unwind_protect (Fset_window_configuration
,
5394 Fcurrent_window_configuration (Qnil
));
5395 val
= Fprogn (args
);
5396 return unbind_to (count
, val
);
5400 /***********************************************************************
5402 ***********************************************************************/
5404 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
5406 doc
: /* Set width of marginal areas of window WINDOW.
5407 If window is nil, set margins of the currently selected window.
5408 First parameter LEFT-WIDTH specifies the number of character
5409 cells to reserve for the left marginal area. Second parameter
5410 RIGHT-WIDTH does the same for the right marginal area.
5411 A nil width parameter means no margin. */)
5412 (window
, left
, right
)
5413 Lisp_Object window
, left
, right
;
5415 struct window
*w
= decode_window (window
);
5418 CHECK_NUMBER_OR_FLOAT (left
);
5420 CHECK_NUMBER_OR_FLOAT (right
);
5422 /* Check widths < 0 and translate a zero width to nil.
5423 Margins that are too wide have to be checked elsewhere. */
5424 if ((INTEGERP (left
) && XINT (left
) < 0)
5425 || (FLOATP (left
) && XFLOAT_DATA (left
) <= 0))
5426 XSETFASTINT (left
, 0);
5427 if (INTEGERP (left
) && XFASTINT (left
) == 0)
5430 if ((INTEGERP (right
) && XINT (right
) < 0)
5431 || (FLOATP (right
) && XFLOAT_DATA (right
) <= 0))
5432 XSETFASTINT (right
, 0);
5433 if (INTEGERP (right
) && XFASTINT (right
) == 0)
5436 w
->left_margin_width
= left
;
5437 w
->right_margin_width
= right
;
5439 ++windows_or_buffers_changed
;
5440 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
5445 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
5447 doc
: /* Get width of marginal areas of window WINDOW.
5448 If WINDOW is omitted or nil, use the currently selected window.
5449 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).
5450 If a marginal area does not exist, its width will be returned
5455 struct window
*w
= decode_window (window
);
5456 return Fcons (w
->left_margin_width
, w
->right_margin_width
);
5461 /***********************************************************************
5463 ***********************************************************************/
5465 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 1, 0,
5466 doc
: /* Return the amount by which WINDOW is scrolled vertically.
5467 Use the selected window if WINDOW is nil or omitted.
5468 Value is a multiple of the canonical character height of WINDOW. */)
5477 window
= selected_window
;
5479 CHECK_WINDOW (window
);
5480 w
= XWINDOW (window
);
5481 f
= XFRAME (w
->frame
);
5483 if (FRAME_WINDOW_P (f
))
5484 result
= CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
);
5486 result
= make_number (0);
5491 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
5493 doc
: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL.
5494 WINDOW nil means use the selected window. VSCROLL is a non-negative
5495 multiple of the canonical character height of WINDOW. */)
5497 Lisp_Object window
, vscroll
;
5503 window
= selected_window
;
5505 CHECK_WINDOW (window
);
5506 CHECK_NUMBER_OR_FLOAT (vscroll
);
5508 w
= XWINDOW (window
);
5509 f
= XFRAME (w
->frame
);
5511 if (FRAME_WINDOW_P (f
))
5513 int old_dy
= w
->vscroll
;
5515 w
->vscroll
= - CANON_Y_UNIT (f
) * XFLOATINT (vscroll
);
5516 w
->vscroll
= min (w
->vscroll
, 0);
5518 /* Adjust glyph matrix of the frame if the virtual display
5519 area becomes larger than before. */
5520 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
5523 /* Prevent redisplay shortcuts. */
5524 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
5527 return Fwindow_vscroll (window
);
5531 /* Call FN for all leaf windows on frame F. FN is called with the
5532 first argument being a pointer to the leaf window, and with
5533 additional argument USER_DATA. Stops when FN returns 0. */
5536 foreach_window (f
, fn
, user_data
)
5538 int (* fn
) P_ ((struct window
*, void *));
5541 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, user_data
);
5545 /* Helper function for foreach_window. Call FN for all leaf windows
5546 reachable from W. FN is called with the first argument being a
5547 pointer to the leaf window, and with additional argument USER_DATA.
5548 Stop when FN returns 0. Value is 0 if stopped by FN. */
5551 foreach_window_1 (w
, fn
, user_data
)
5553 int (* fn
) P_ ((struct window
*, void *));
5558 for (cont
= 1; w
&& cont
;)
5560 if (!NILP (w
->hchild
))
5561 cont
= foreach_window_1 (XWINDOW (w
->hchild
), fn
, user_data
);
5562 else if (!NILP (w
->vchild
))
5563 cont
= foreach_window_1 (XWINDOW (w
->vchild
), fn
, user_data
);
5565 cont
= fn (w
, user_data
);
5567 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5574 /* Freeze or unfreeze the window start of W unless it is a
5575 mini-window or the selected window. FREEZE_P non-null means freeze
5576 the window start. */
5579 freeze_window_start (w
, freeze_p
)
5583 if (w
== XWINDOW (selected_window
)
5584 || MINI_WINDOW_P (w
)
5585 || (MINI_WINDOW_P (XWINDOW (selected_window
))
5586 && ! NILP (Vminibuf_scroll_window
)
5587 && w
== XWINDOW (Vminibuf_scroll_window
)))
5590 w
->frozen_window_start_p
= freeze_p
!= NULL
;
5595 /* Freeze or unfreeze the window starts of all leaf windows on frame
5596 F, except the selected window and a mini-window. FREEZE_P non-zero
5597 means freeze the window start. */
5600 freeze_window_starts (f
, freeze_p
)
5604 foreach_window (f
, freeze_window_start
, (void *) (freeze_p
? f
: 0));
5608 /***********************************************************************
5610 ***********************************************************************/
5612 /* Return 1 if window configurations C1 and C2
5613 describe the same state of affairs. This is used by Fequal. */
5616 compare_window_configurations (c1
, c2
, ignore_positions
)
5618 int ignore_positions
;
5620 register struct save_window_data
*d1
, *d2
;
5621 struct Lisp_Vector
*sw1
, *sw2
;
5624 if (!WINDOW_CONFIGURATIONP (c1
))
5625 wrong_type_argument (Qwindow_configuration_p
, c1
);
5626 if (!WINDOW_CONFIGURATIONP (c2
))
5627 wrong_type_argument (Qwindow_configuration_p
, c2
);
5629 d1
= (struct save_window_data
*) XVECTOR (c1
);
5630 d2
= (struct save_window_data
*) XVECTOR (c2
);
5631 sw1
= XVECTOR (d1
->saved_windows
);
5632 sw2
= XVECTOR (d2
->saved_windows
);
5634 if (! EQ (d1
->frame_width
, d2
->frame_width
))
5636 if (! EQ (d1
->frame_height
, d2
->frame_height
))
5638 if (! EQ (d1
->frame_menu_bar_lines
, d2
->frame_menu_bar_lines
))
5640 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
5642 /* Don't compare the current_window field directly.
5643 Instead see w1_is_current and w2_is_current, below. */
5644 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
5646 if (! ignore_positions
)
5647 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
5649 /* Don't compare the root_window field.
5650 We don't require the two configurations
5651 to use the same window object,
5652 and the two root windows must be equivalent
5653 if everything else compares equal. */
5654 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
5656 if (! EQ (d1
->min_width
, d2
->min_width
))
5658 if (! EQ (d1
->min_height
, d2
->min_height
))
5661 /* Verify that the two confis have the same number of windows. */
5662 if (sw1
->size
!= sw2
->size
)
5665 for (i
= 0; i
< sw1
->size
; i
++)
5667 struct saved_window
*p1
, *p2
;
5668 int w1_is_current
, w2_is_current
;
5670 p1
= SAVED_WINDOW_N (sw1
, i
);
5671 p2
= SAVED_WINDOW_N (sw2
, i
);
5673 /* Verify that the current windows in the two
5674 configurations correspond to each other. */
5675 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
5676 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
5678 if (w1_is_current
!= w2_is_current
)
5681 /* Verify that the corresponding windows do match. */
5682 if (! EQ (p1
->buffer
, p2
->buffer
))
5684 if (! EQ (p1
->left
, p2
->left
))
5686 if (! EQ (p1
->top
, p2
->top
))
5688 if (! EQ (p1
->width
, p2
->width
))
5690 if (! EQ (p1
->height
, p2
->height
))
5692 if (! EQ (p1
->display_table
, p2
->display_table
))
5694 if (! EQ (p1
->parent
, p2
->parent
))
5696 if (! EQ (p1
->prev
, p2
->prev
))
5698 if (! ignore_positions
)
5700 if (! EQ (p1
->hscroll
, p2
->hscroll
))
5702 if (!EQ (p1
->min_hscroll
, p2
->min_hscroll
))
5704 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
5706 if (NILP (Fequal (p1
->start
, p2
->start
)))
5708 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
5710 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
5718 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
5719 Scompare_window_configurations
, 2, 2, 0,
5720 doc
: /* Compare two window configurations as regards the structure of windows.
5721 This function ignores details such as the values of point and mark
5722 and scrolling positions. */)
5726 if (compare_window_configurations (x
, y
, 1))
5734 struct frame
*f
= make_terminal_frame ();
5735 XSETFRAME (selected_frame
, f
);
5736 Vterminal_frame
= selected_frame
;
5737 minibuf_window
= f
->minibuffer_window
;
5738 selected_window
= f
->selected_window
;
5739 last_nonminibuf_frame
= f
;
5741 window_initialized
= 1;
5747 Vwindow_list
= Qnil
;
5753 Qwindow_size_fixed
= intern ("window-size-fixed");
5754 staticpro (&Qwindow_size_fixed
);
5756 staticpro (&Qwindow_configuration_change_hook
);
5757 Qwindow_configuration_change_hook
5758 = intern ("window-configuration-change-hook");
5760 Qwindowp
= intern ("windowp");
5761 staticpro (&Qwindowp
);
5763 Qwindow_configuration_p
= intern ("window-configuration-p");
5764 staticpro (&Qwindow_configuration_p
);
5766 Qwindow_live_p
= intern ("window-live-p");
5767 staticpro (&Qwindow_live_p
);
5769 Qtemp_buffer_show_hook
= intern ("temp-buffer-show-hook");
5770 staticpro (&Qtemp_buffer_show_hook
);
5772 staticpro (&Vwindow_list
);
5774 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
5775 doc
: /* Non-nil means call as function to display a help buffer.
5776 The function is called with one argument, the buffer to be displayed.
5777 Used by `with-output-to-temp-buffer'.
5778 If this function is used, then it must do the entire job of showing
5779 the buffer; `temp-buffer-show-hook' is not run unless this function runs it. */);
5780 Vtemp_buffer_show_function
= Qnil
;
5782 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
5783 doc
: /* If non-nil, function to call to handle `display-buffer'.
5784 It will receive two args, the buffer and a flag which if non-nil means
5785 that the currently selected window is not acceptable.
5786 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'
5787 work using this function. */);
5788 Vdisplay_buffer_function
= Qnil
;
5790 DEFVAR_LISP ("even-window-heights", &Veven_window_heights
,
5791 doc
: /* *If non-nil, `display-buffer' should even the window heights.
5792 If nil, `display-buffer' will leave the window configuration alone. */);
5793 Veven_window_heights
= Qt
;
5795 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
5796 doc
: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */);
5797 Vminibuf_scroll_window
= Qnil
;
5799 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
5800 doc
: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. */);
5801 Vother_window_scroll_buffer
= Qnil
;
5803 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
5804 doc
: /* *Non-nil means `display-buffer' should make a separate frame. */);
5807 DEFVAR_BOOL ("display-buffer-reuse-frames", &display_buffer_reuse_frames
,
5808 doc
: /* *Non-nil means `display-buffer' should reuse frames.
5809 If the buffer in question is already displayed in a frame, raise that frame. */);
5810 display_buffer_reuse_frames
= 0;
5812 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
5813 doc
: /* Function to call to handle automatic new frame creation.
5814 It is called with no arguments and should return a newly created frame.
5816 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'
5817 where `pop-up-frame-alist' would hold the default frame parameters. */);
5818 Vpop_up_frame_function
= Qnil
;
5820 DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names
,
5821 doc
: /* *List of buffer names that should have their own special frames.
5822 Displaying a buffer whose name is in this list makes a special frame for it
5823 using `special-display-function'. See also `special-display-regexps'.
5825 An element of the list can be a list instead of just a string.
5826 There are two ways to use a list as an element:
5827 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)
5828 In the first case, FRAME-PARAMETERS are used to create the frame.
5829 In the latter case, FUNCTION is called with BUFFER as the first argument,
5830 followed by OTHER-ARGS--it can display BUFFER in any way it likes.
5831 All this is done by the function found in `special-display-function'.
5833 If this variable appears \"not to work\", because you add a name to it
5834 but that buffer still appears in the selected window, look at the
5835 values of `same-window-buffer-names' and `same-window-regexps'.
5836 Those variables take precedence over this one. */);
5837 Vspecial_display_buffer_names
= Qnil
;
5839 DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps
,
5840 doc
: /* *List of regexps saying which buffers should have their own special frames.
5841 If a buffer name matches one of these regexps, it gets its own frame.
5842 Displaying a buffer whose name is in this list makes a special frame for it
5843 using `special-display-function'.
5845 An element of the list can be a list instead of just a string.
5846 There are two ways to use a list as an element:
5847 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)
5848 In the first case, FRAME-PARAMETERS are used to create the frame.
5849 In the latter case, FUNCTION is called with the buffer as first argument,
5850 followed by OTHER-ARGS--it can display the buffer in any way it likes.
5851 All this is done by the function found in `special-display-function'.
5853 If this variable appears \"not to work\", because you add a regexp to it
5854 but the matching buffers still appear in the selected window, look at the
5855 values of `same-window-buffer-names' and `same-window-regexps'.
5856 Those variables take precedence over this one. */);
5857 Vspecial_display_regexps
= Qnil
;
5859 DEFVAR_LISP ("special-display-function", &Vspecial_display_function
,
5860 doc
: /* Function to call to make a new frame for a special buffer.
5861 It is called with two arguments, the buffer and optional buffer specific
5862 data, and should return a window displaying that buffer.
5863 The default value makes a separate frame for the buffer,
5864 using `special-display-frame-alist' to specify the frame parameters.
5866 A buffer is special if its is listed in `special-display-buffer-names'
5867 or matches a regexp in `special-display-regexps'. */);
5868 Vspecial_display_function
= Qnil
;
5870 DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names
,
5871 doc
: /* *List of buffer names that should appear in the selected window.
5872 Displaying one of these buffers using `display-buffer' or `pop-to-buffer'
5873 switches to it in the selected window, rather than making it appear
5874 in some other window.
5876 An element of the list can be a cons cell instead of just a string.
5877 Then the car must be a string, which specifies the buffer name.
5878 This is for compatibility with `special-display-buffer-names';
5879 the cdr of the cons cell is ignored.
5881 See also `same-window-regexps'. */);
5882 Vsame_window_buffer_names
= Qnil
;
5884 DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps
,
5885 doc
: /* *List of regexps saying which buffers should appear in the selected window.
5886 If a buffer name matches one of these regexps, then displaying it
5887 using `display-buffer' or `pop-to-buffer' switches to it
5888 in the selected window, rather than making it appear in some other window.
5890 An element of the list can be a cons cell instead of just a string.
5891 Then the car must be a string, which specifies the buffer name.
5892 This is for compatibility with `special-display-buffer-names';
5893 the cdr of the cons cell is ignored.
5895 See also `same-window-buffer-names'. */);
5896 Vsame_window_regexps
= Qnil
;
5898 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
5899 doc
: /* *Non-nil means display-buffer should make new windows. */);
5902 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
5903 doc
: /* *Number of lines of continuity when scrolling by screenfuls. */);
5904 next_screen_context_lines
= 2;
5906 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
5907 doc
: /* *display-buffer would prefer to split the largest window if this large.
5908 If there is only one window, it is split regardless of this value. */);
5909 split_height_threshold
= 500;
5911 DEFVAR_INT ("window-min-height", &window_min_height
,
5912 doc
: /* *Delete any window less than this tall (including its mode line). */);
5913 window_min_height
= 4;
5915 DEFVAR_INT ("window-min-width", &window_min_width
,
5916 doc
: /* *Delete any window less than this wide. */);
5917 window_min_width
= 10;
5919 DEFVAR_LISP ("scroll-preserve-screen-position",
5920 &Vscroll_preserve_screen_position
,
5921 doc
: /* *Non-nil means scroll commands move point to keep its screen line unchanged. */);
5922 Vscroll_preserve_screen_position
= Qnil
;
5924 DEFVAR_LISP ("window-configuration-change-hook",
5925 &Vwindow_configuration_change_hook
,
5926 doc
: /* Functions to call when window configuration changes.
5927 The selected frame is the one whose configuration has changed. */);
5928 Vwindow_configuration_change_hook
= Qnil
;
5930 DEFVAR_BOOL ("window-size-fixed", &window_size_fixed
,
5931 doc
: /* Non-nil in a buffer means windows displaying the buffer are fixed-size.
5932 Emacs won't change the size of any window displaying that buffer,
5933 unless you explicitly change the size, or Emacs has no other choice.
5934 This variable automatically becomes buffer-local when set. */);
5935 Fmake_variable_buffer_local (Qwindow_size_fixed
);
5936 window_size_fixed
= 0;
5938 defsubr (&Sselected_window
);
5939 defsubr (&Sminibuffer_window
);
5940 defsubr (&Swindow_minibuffer_p
);
5941 defsubr (&Swindowp
);
5942 defsubr (&Swindow_live_p
);
5943 defsubr (&Spos_visible_in_window_p
);
5944 defsubr (&Swindow_buffer
);
5945 defsubr (&Swindow_height
);
5946 defsubr (&Swindow_width
);
5947 defsubr (&Swindow_hscroll
);
5948 defsubr (&Sset_window_hscroll
);
5949 defsubr (&Swindow_redisplay_end_trigger
);
5950 defsubr (&Sset_window_redisplay_end_trigger
);
5951 defsubr (&Swindow_edges
);
5952 defsubr (&Scoordinates_in_window_p
);
5953 defsubr (&Swindow_at
);
5954 defsubr (&Swindow_point
);
5955 defsubr (&Swindow_start
);
5956 defsubr (&Swindow_end
);
5957 defsubr (&Sset_window_point
);
5958 defsubr (&Sset_window_start
);
5959 defsubr (&Swindow_dedicated_p
);
5960 defsubr (&Sset_window_dedicated_p
);
5961 defsubr (&Swindow_display_table
);
5962 defsubr (&Sset_window_display_table
);
5963 defsubr (&Snext_window
);
5964 defsubr (&Sprevious_window
);
5965 defsubr (&Sother_window
);
5966 defsubr (&Sget_lru_window
);
5967 defsubr (&Sget_largest_window
);
5968 defsubr (&Sget_buffer_window
);
5969 defsubr (&Sdelete_other_windows
);
5970 defsubr (&Sdelete_windows_on
);
5971 defsubr (&Sreplace_buffer_in_windows
);
5972 defsubr (&Sdelete_window
);
5973 defsubr (&Sset_window_buffer
);
5974 defsubr (&Sselect_window
);
5975 defsubr (&Sspecial_display_p
);
5976 defsubr (&Ssame_window_p
);
5977 defsubr (&Sdisplay_buffer
);
5978 defsubr (&Ssplit_window
);
5979 defsubr (&Senlarge_window
);
5980 defsubr (&Sshrink_window
);
5981 defsubr (&Sscroll_up
);
5982 defsubr (&Sscroll_down
);
5983 defsubr (&Sscroll_left
);
5984 defsubr (&Sscroll_right
);
5985 defsubr (&Sother_window_for_scrolling
);
5986 defsubr (&Sscroll_other_window
);
5987 defsubr (&Srecenter
);
5988 defsubr (&Swindow_text_height
);
5989 defsubr (&Smove_to_window_line
);
5990 defsubr (&Swindow_configuration_p
);
5991 defsubr (&Swindow_configuration_frame
);
5992 defsubr (&Sset_window_configuration
);
5993 defsubr (&Scurrent_window_configuration
);
5994 defsubr (&Ssave_window_excursion
);
5995 defsubr (&Sset_window_margins
);
5996 defsubr (&Swindow_margins
);
5997 defsubr (&Swindow_vscroll
);
5998 defsubr (&Sset_window_vscroll
);
5999 defsubr (&Scompare_window_configurations
);
6000 defsubr (&Swindow_list
);
6006 initial_define_key (control_x_map
, '1', "delete-other-windows");
6007 initial_define_key (control_x_map
, '2', "split-window");
6008 initial_define_key (control_x_map
, '0', "delete-window");
6009 initial_define_key (control_x_map
, 'o', "other-window");
6010 initial_define_key (control_x_map
, '^', "enlarge-window");
6011 initial_define_key (control_x_map
, '<', "scroll-left");
6012 initial_define_key (control_x_map
, '>', "scroll-right");
6014 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
6015 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
6016 initial_define_key (meta_map
, 'v', "scroll-down");
6018 initial_define_key (global_map
, Ctl('L'), "recenter");
6019 initial_define_key (meta_map
, 'r', "move-to-window-line");