1 /* Window creation, deletion and examination for GNU Emacs.
2 Does not include redisplay.
3 Copyright (C) 1985,86,87,93,94,95,96,97,1998,2000, 2001, 2002
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. */
67 Lisp_Object Qwindowp
, Qwindow_live_p
, Qwindow_configuration_p
;
68 Lisp_Object Qwindow_size_fixed
;
69 extern Lisp_Object Qleft_margin
, Qright_margin
;
70 extern Lisp_Object Qheight
, Qwidth
;
72 static int displayed_window_lines
P_ ((struct window
*));
73 static struct window
*decode_window
P_ ((Lisp_Object
));
74 static Lisp_Object select_window_1
P_ ((Lisp_Object
, int));
75 static int count_windows
P_ ((struct window
*));
76 static int get_leaf_windows
P_ ((struct window
*, struct window
**, int));
77 static void window_scroll
P_ ((Lisp_Object
, int, int, int));
78 static void window_scroll_pixel_based
P_ ((Lisp_Object
, int, int, int));
79 static void window_scroll_line_based
P_ ((Lisp_Object
, int, int, int));
80 static int window_min_size_1
P_ ((struct window
*, int));
81 static int window_min_size
P_ ((struct window
*, int, int, int *));
82 static void size_window
P_ ((Lisp_Object
, int, int, int));
83 static int freeze_window_start
P_ ((struct window
*, void *));
84 static int window_fixed_size_p
P_ ((struct window
*, int, int));
85 static void enlarge_window
P_ ((Lisp_Object
, int, int, int));
86 static Lisp_Object window_list
P_ ((void));
87 static int add_window_to_list
P_ ((struct window
*, void *));
88 static int candidate_window_p
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
,
90 static Lisp_Object next_window
P_ ((Lisp_Object
, Lisp_Object
,
92 static void decode_next_window_args
P_ ((Lisp_Object
*, Lisp_Object
*,
94 static int foreach_window_1
P_ ((struct window
*,
95 int (* fn
) (struct window
*, void *),
97 static Lisp_Object window_list_1
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
));
99 /* The value of `window-size-fixed'. */
101 int window_size_fixed
;
103 /* This is the window in which the terminal's cursor should
104 be left when nothing is being done with it. This must
105 always be a leaf window, and its buffer is selected by
106 the top level editing loop at the end of each command.
108 This value is always the same as
109 FRAME_SELECTED_WINDOW (selected_frame). */
111 Lisp_Object selected_window
;
113 /* A list of all windows for use by next_window and Fwindow_list.
114 Functions creating or deleting windows should invalidate this cache
115 by setting it to nil. */
117 Lisp_Object Vwindow_list
;
119 /* The mini-buffer window of the selected frame.
120 Note that you cannot test for mini-bufferness of an arbitrary window
121 by comparing against this; but you can test for mini-bufferness of
122 the selected window. */
124 Lisp_Object minibuf_window
;
126 /* Non-nil means it is the window whose mode line should be
127 shown as the selected window when the minibuffer is selected. */
129 Lisp_Object minibuf_selected_window
;
131 /* Non-nil means it is the window for C-M-v to scroll
132 when the mini-buffer is selected. */
134 Lisp_Object Vminibuf_scroll_window
;
136 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
138 Lisp_Object Vother_window_scroll_buffer
;
140 /* Non-nil means it's function to call to display temp buffers. */
142 Lisp_Object Vtemp_buffer_show_function
;
144 /* Non-zero means to use mode-line-inactive face in all windows but the
145 selected-window and the minibuffer-scroll-window when the
146 minibuffer is active. */
147 int mode_line_in_non_selected_windows
;
149 /* If a window gets smaller than either of these, it is removed. */
151 EMACS_INT window_min_height
;
152 EMACS_INT window_min_width
;
154 /* Nonzero implies Fdisplay_buffer should create windows. */
158 /* Nonzero implies make new frames for Fdisplay_buffer. */
162 /* Nonzero means reuse existing frames for displaying buffers. */
164 int display_buffer_reuse_frames
;
166 /* Non-nil means use this function instead of default */
168 Lisp_Object Vpop_up_frame_function
;
170 /* Function to call to handle Fdisplay_buffer. */
172 Lisp_Object Vdisplay_buffer_function
;
174 /* Non-nil means that Fdisplay_buffer should even the heights of windows. */
176 Lisp_Object Veven_window_heights
;
178 /* List of buffer *names* for buffers that should have their own frames. */
180 Lisp_Object Vspecial_display_buffer_names
;
182 /* List of regexps for buffer names that should have their own frames. */
184 Lisp_Object Vspecial_display_regexps
;
186 /* Function to pop up a special frame. */
188 Lisp_Object Vspecial_display_function
;
190 /* List of buffer *names* for buffers to appear in selected window. */
192 Lisp_Object Vsame_window_buffer_names
;
194 /* List of regexps for buffer names to appear in selected window. */
196 Lisp_Object Vsame_window_regexps
;
198 /* Hook run at end of temp_output_buffer_show. */
200 Lisp_Object Qtemp_buffer_show_hook
;
202 /* Fdisplay_buffer always splits the largest window
203 if that window is more than this high. */
205 EMACS_INT split_height_threshold
;
207 /* Number of lines of continuity in scrolling by screenfuls. */
209 EMACS_INT next_screen_context_lines
;
211 /* Incremented for each window created. */
213 static int sequence_number
;
215 /* Nonzero after init_window_once has finished. */
217 static int window_initialized
;
219 /* Hook to run when window config changes. */
221 Lisp_Object Qwindow_configuration_change_hook
;
222 Lisp_Object Vwindow_configuration_change_hook
;
224 /* Nonzero means scroll commands try to put point
225 at the same screen height as previously. */
227 Lisp_Object Vscroll_preserve_screen_position
;
229 #if 0 /* This isn't used anywhere. */
230 /* Nonzero means we can split a frame even if it is "unsplittable". */
231 static int inhibit_frame_unsplittable
;
234 extern EMACS_INT scroll_margin
;
236 extern Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
238 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
239 doc
: /* Returns t if OBJECT is a window. */)
243 return WINDOWP (object
) ? Qt
: Qnil
;
246 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
247 doc
: /* Returns t if OBJECT is a window which is currently visible. */)
251 return WINDOW_LIVE_P (object
) ? Qt
: Qnil
;
258 register struct window
*p
;
260 p
= allocate_window ();
261 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
262 XSETFASTINT (p
->left
, 0);
263 XSETFASTINT (p
->top
, 0);
264 XSETFASTINT (p
->height
, 0);
265 XSETFASTINT (p
->width
, 0);
266 XSETFASTINT (p
->hscroll
, 0);
267 XSETFASTINT (p
->min_hscroll
, 0);
268 p
->orig_top
= p
->orig_height
= Qnil
;
269 p
->start
= Fmake_marker ();
270 p
->pointm
= Fmake_marker ();
271 XSETFASTINT (p
->use_time
, 0);
273 p
->display_table
= Qnil
;
275 p
->pseudo_window_p
= 0;
276 bzero (&p
->cursor
, sizeof (p
->cursor
));
277 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
278 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
279 p
->desired_matrix
= p
->current_matrix
= 0;
280 p
->phys_cursor_type
= -1;
281 p
->phys_cursor_width
= -1;
282 p
->must_be_updated_p
= 0;
283 XSETFASTINT (p
->window_end_vpos
, 0);
284 XSETFASTINT (p
->window_end_pos
, 0);
285 p
->window_end_valid
= Qnil
;
288 XSETFASTINT (p
->last_point
, 0);
289 p
->frozen_window_start_p
= 0;
295 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
296 doc
: /* Return the window that the cursor now appears in and commands apply to. */)
299 return selected_window
;
302 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
303 doc
: /* Return the window used now for minibuffers.
304 If the optional argument FRAME is specified, return the minibuffer window
305 used by that frame. */)
310 frame
= selected_frame
;
311 CHECK_LIVE_FRAME (frame
);
312 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
315 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 0, 1, 0,
316 doc
: /* Returns non-nil if WINDOW is a minibuffer window. */)
320 struct window
*w
= decode_window (window
);
321 return MINI_WINDOW_P (w
) ? Qt
: Qnil
;
325 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
326 Spos_visible_in_window_p
, 0, 3, 0,
327 doc
: /* Return t if position POS is currently on the frame in WINDOW.
328 Return nil if that position is scrolled vertically out of view.
329 If a character is only partially visible, nil is returned, unless the
330 optional argument PARTIALLY is non-nil.
331 POS defaults to point in WINDOW; WINDOW defaults to the selected window. */)
332 (pos
, window
, partially
)
333 Lisp_Object pos
, window
, partially
;
335 register struct window
*w
;
337 register struct buffer
*buf
;
339 Lisp_Object in_window
;
342 w
= decode_window (window
);
343 buf
= XBUFFER (w
->buffer
);
344 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
348 CHECK_NUMBER_COERCE_MARKER (pos
);
351 else if (w
== XWINDOW (selected_window
))
354 posint
= XMARKER (w
->pointm
)->charpos
;
356 /* If position is above window start, it's not visible. */
357 if (posint
< CHARPOS (top
))
359 else if (XFASTINT (w
->last_modified
) >= BUF_MODIFF (buf
)
360 && XFASTINT (w
->last_overlay_modified
) >= BUF_OVERLAY_MODIFF (buf
)
361 && posint
< BUF_Z (buf
) - XFASTINT (w
->window_end_pos
))
363 /* If frame is up-to-date, and POSINT is < window end pos, use
364 that info. This doesn't work for POSINT == end pos, because
365 the window end pos is actually the position _after_ the last
366 char in the window. */
367 if (NILP (partially
))
369 pos_visible_p (w
, posint
, &fully_p
, NILP (partially
));
370 in_window
= fully_p
? Qt
: Qnil
;
375 else if (posint
> BUF_ZV (buf
))
377 else if (CHARPOS (top
) < BUF_BEGV (buf
) || CHARPOS (top
) > BUF_ZV (buf
))
378 /* If window start is out of range, do something reasonable. */
382 if (pos_visible_p (w
, posint
, &fully_p
, NILP (partially
)))
383 in_window
= !NILP (partially
) || fully_p
? Qt
: Qnil
;
392 static struct window
*
393 decode_window (window
)
394 register Lisp_Object window
;
397 return XWINDOW (selected_window
);
399 CHECK_LIVE_WINDOW (window
);
400 return XWINDOW (window
);
403 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
404 doc
: /* Return the buffer that WINDOW is displaying. */)
408 return decode_window (window
)->buffer
;
411 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
412 doc
: /* Return the number of lines in WINDOW (including its mode line). */)
416 return decode_window (window
)->height
;
419 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
420 doc
: /* Return the number of display columns in WINDOW.
421 This is the width that is usable columns available for text in WINDOW.
422 If you want to find out how many columns WINDOW takes up,
423 use (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))). */)
427 return make_number (window_internal_width (decode_window (window
)));
430 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
431 doc
: /* Return the number of columns by which WINDOW is scrolled from left margin. */)
435 return decode_window (window
)->hscroll
;
438 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
439 doc
: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
440 NCOL should be zero or positive. */)
442 Lisp_Object window
, ncol
;
444 struct window
*w
= decode_window (window
);
448 hscroll
= max (0, XINT (ncol
));
450 /* Prevent redisplay shortcuts when changing the hscroll. */
451 if (XINT (w
->hscroll
) != hscroll
)
452 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
454 w
->hscroll
= make_number (hscroll
);
458 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
459 Swindow_redisplay_end_trigger
, 0, 1, 0,
460 doc
: /* Return WINDOW's redisplay end trigger value.
461 See `set-window-redisplay-end-trigger' for more information. */)
465 return decode_window (window
)->redisplay_end_trigger
;
468 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
469 Sset_window_redisplay_end_trigger
, 2, 2, 0,
470 doc
: /* Set WINDOW's redisplay end trigger value to VALUE.
471 VALUE should be a buffer position (typically a marker) or nil.
472 If it is a buffer position, then if redisplay in WINDOW reaches a position
473 beyond VALUE, the functions in `redisplay-end-trigger-functions' are called
474 with two arguments: WINDOW, and the end trigger value.
475 Afterwards the end-trigger value is reset to nil. */)
477 register Lisp_Object window
, value
;
479 register struct window
*w
;
481 w
= decode_window (window
);
482 w
->redisplay_end_trigger
= value
;
486 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
487 doc
: /* Return a list of the edge coordinates of WINDOW.
488 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.
489 RIGHT is one more than the rightmost column used by WINDOW,
490 and BOTTOM is one more than the bottommost row used by WINDOW
491 and its mode-line. */)
495 register struct window
*w
= decode_window (window
);
497 return Fcons (w
->left
, Fcons (w
->top
,
498 Fcons (make_number (WINDOW_RIGHT_EDGE (w
)),
499 Fcons (make_number (XFASTINT (w
->top
)
500 + XFASTINT (w
->height
)),
504 /* Test if the character at column *X, row *Y is within window W.
505 If it is not, return 0;
506 if it is in the window's text area,
507 set *x and *y to its location relative to the upper left corner
510 if it is on the window's modeline, return 2;
511 if it is on the border between the window and its right sibling,
513 if it is on the window's top line, return 4;
514 if it is in left or right fringe of the window,
515 return 5 or 6, and convert *X and *Y to window-relative coordinates;
516 if it is in the marginal area to the left/right of the window,
517 return 7 or 8, and convert *X and *Y to window-relative coordinates.
519 X and Y are frame relative pixel coordinates. */
521 static enum window_part
522 coordinates_in_window (w
, x
, y
)
523 register struct window
*w
;
526 /* Let's make this a global enum later, instead of using numbers
528 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
529 int left_x
, right_x
, top_y
, bottom_y
;
530 enum window_part part
;
531 int ux
= CANON_X_UNIT (f
);
532 int x0
= XFASTINT (w
->left
) * ux
;
533 int x1
= x0
+ XFASTINT (w
->width
) * ux
;
534 /* The width of the area where the vertical line can be dragged.
535 (Between mode lines for instance. */
536 int grabbable_width
= ux
;
538 if (*x
< x0
|| *x
>= x1
)
541 /* In what's below, we subtract 1 when computing right_x because we
542 want the rightmost pixel, which is given by left_pixel+width-1. */
543 if (w
->pseudo_window_p
)
546 right_x
= XFASTINT (w
->width
) * CANON_X_UNIT (f
) - 1;
547 top_y
= WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
);
548 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
552 left_x
= (WINDOW_DISPLAY_LEFT_EDGE_PIXEL_X (w
)
553 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
554 right_x
= WINDOW_DISPLAY_RIGHT_EDGE_PIXEL_X (w
) - 1;
555 top_y
= (WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
)
556 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
557 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
560 /* On the mode line or header line? If it's near the start of
561 the mode or header line of window that's has a horizontal
562 sibling, say it's on the vertical line. That's to be able
563 to resize windows horizontally in case we're using toolkit
566 if (WINDOW_WANTS_MODELINE_P (w
)
567 && *y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
)
570 /* We're somewhere on the mode line. We consider the place
571 between mode lines of horizontally adjacent mode lines
572 as the vertical border. If scroll bars on the left,
573 return the right window. */
576 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
578 if (abs (*x
- x0
) < grabbable_width
)
579 part
= ON_VERTICAL_BORDER
;
581 else if (!WINDOW_RIGHTMOST_P (w
) && abs (*x
- x1
) < grabbable_width
)
582 part
= ON_VERTICAL_BORDER
;
584 else if (WINDOW_WANTS_HEADER_LINE_P (w
)
585 && *y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
)
588 part
= ON_HEADER_LINE
;
590 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f
))
592 if (abs (*x
- x0
) < grabbable_width
)
593 part
= ON_VERTICAL_BORDER
;
595 else if (!WINDOW_RIGHTMOST_P (w
) && abs (*x
- x1
) < grabbable_width
)
596 part
= ON_VERTICAL_BORDER
;
598 /* Outside anything interesting? */
602 - FRAME_LEFT_FRINGE_WIDTH (f
)
603 - FRAME_LEFT_SCROLL_BAR_WIDTH (f
) * ux
)
605 + FRAME_RIGHT_FRINGE_WIDTH (f
)
606 + FRAME_RIGHT_SCROLL_BAR_WIDTH (f
) * ux
))
610 else if (FRAME_WINDOW_P (f
))
612 if (!w
->pseudo_window_p
613 && !FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
614 && !WINDOW_RIGHTMOST_P (w
)
615 && (abs (*x
- right_x
- FRAME_RIGHT_FRINGE_WIDTH (f
)) < grabbable_width
))
617 part
= ON_VERTICAL_BORDER
;
619 else if (*x
< left_x
|| *x
> right_x
)
621 /* Other lines than the mode line don't include fringes and
622 scroll bars on the left. */
624 /* Convert X and Y to window-relative pixel coordinates. */
627 part
= *x
< left_x
? ON_LEFT_FRINGE
: ON_RIGHT_FRINGE
;
631 if (*x
<= window_box_right (w
, LEFT_MARGIN_AREA
))
632 part
= ON_LEFT_MARGIN
;
633 else if (*x
>= window_box_left (w
, RIGHT_MARGIN_AREA
))
634 part
= ON_RIGHT_MARGIN
;
645 /* Need to say "*x > right_x" rather than >=, since on character
646 terminals, the vertical line's x coordinate is right_x. */
647 if (*x
< left_x
|| *x
> right_x
)
649 /* Other lines than the mode line don't include fringes and
650 scroll bars on the left. */
652 /* Convert X and Y to window-relative pixel coordinates. */
655 part
= *x
< left_x
? ON_LEFT_FRINGE
: ON_RIGHT_FRINGE
;
657 /* Here, too, "*x > right_x" is because of character terminals. */
658 else if (!w
->pseudo_window_p
659 && !WINDOW_RIGHTMOST_P (w
)
660 && *x
> right_x
- ux
)
662 /* On the border on the right side of the window? Assume that
663 this area begins at RIGHT_X minus a canonical char width. */
664 part
= ON_VERTICAL_BORDER
;
668 if (*x
<= window_box_right (w
, LEFT_MARGIN_AREA
))
669 part
= ON_LEFT_MARGIN
;
670 else if (*x
>= window_box_left (w
, RIGHT_MARGIN_AREA
))
671 part
= ON_RIGHT_MARGIN
;
675 /* Convert X and Y to window-relative pixel coordinates. */
686 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
687 Scoordinates_in_window_p
, 2, 2, 0,
688 doc
: /* Return non-nil if COORDINATES are in WINDOW.
689 COORDINATES is a cons of the form (X . Y), X and Y being distances
690 measured in characters from the upper-left corner of the frame.
691 \(0 . 0) denotes the character in the upper left corner of the
693 If COORDINATES are in the text portion of WINDOW,
694 the coordinates relative to the window are returned.
695 If they are in the mode line of WINDOW, `mode-line' is returned.
696 If they are in the top mode line of WINDOW, `header-line' is returned.
697 If they are in the left fringe of WINDOW, `left-fringe' is returned.
698 If they are in the right fringe of WINDOW, `right-fringe' is returned.
699 If they are on the border between WINDOW and its right sibling,
700 `vertical-line' is returned.
701 If they are in the windows's left or right marginal areas, `left-margin'\n\
702 or `right-margin' is returned. */)
703 (coordinates
, window
)
704 register Lisp_Object coordinates
, window
;
711 CHECK_LIVE_WINDOW (window
);
712 w
= XWINDOW (window
);
713 f
= XFRAME (w
->frame
);
714 CHECK_CONS (coordinates
);
715 lx
= Fcar (coordinates
);
716 ly
= Fcdr (coordinates
);
717 CHECK_NUMBER_OR_FLOAT (lx
);
718 CHECK_NUMBER_OR_FLOAT (ly
);
719 x
= PIXEL_X_FROM_CANON_X (f
, lx
);
720 y
= PIXEL_Y_FROM_CANON_Y (f
, ly
);
722 switch (coordinates_in_window (w
, &x
, &y
))
728 /* X and Y are now window relative pixel coordinates. Convert
729 them to canonical char units before returning them. */
730 return Fcons (CANON_X_FROM_PIXEL_X (f
, x
),
731 CANON_Y_FROM_PIXEL_Y (f
, y
));
736 case ON_VERTICAL_BORDER
:
737 return Qvertical_line
;
745 case ON_RIGHT_FRINGE
:
746 return Qright_fringe
;
751 case ON_RIGHT_MARGIN
:
752 return Qright_margin
;
760 /* Callback for foreach_window, used in window_from_coordinates.
761 Check if window W contains coordinates specified by USER_DATA which
762 is actually a pointer to a struct check_window_data CW.
764 Check if window W contains coordinates *CW->x and *CW->y. If it
765 does, return W in *CW->window, as Lisp_Object, and return in
766 *CW->part the part of the window under coordinates *X,*Y. Return
767 zero from this function to stop iterating over windows. */
769 struct check_window_data
776 check_window_containing (w
, user_data
)
780 struct check_window_data
*cw
= (struct check_window_data
*) user_data
;
781 enum window_part found
;
784 found
= coordinates_in_window (w
, cw
->x
, cw
->y
);
785 if (found
!= ON_NOTHING
)
787 *cw
->part
= found
- 1;
788 XSETWINDOW (*cw
->window
, w
);
796 /* Find the window containing frame-relative pixel position X/Y and
797 return it as a Lisp_Object. If X, Y is on the window's modeline,
798 set *PART to 1; if it is on the separating line between the window
799 and its right sibling, set it to 2; otherwise set it to 0. If
800 there is no window under X, Y return nil and leave *PART
801 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows.
803 This function was previously implemented with a loop cycling over
804 windows with Fnext_window, and starting with the frame's selected
805 window. It turned out that this doesn't work with an
806 implementation of next_window using Vwindow_list, because
807 FRAME_SELECTED_WINDOW (F) is not always contained in the window
808 tree of F when this function is called asynchronously from
809 note_mouse_highlight. The original loop didn't terminate in this
813 window_from_coordinates (f
, x
, y
, part
, tool_bar_p
)
820 struct check_window_data cw
;
823 cw
.window
= &window
, cw
.x
= &x
, cw
.y
= &y
; cw
.part
= part
;
824 foreach_window (f
, check_window_containing
, &cw
);
826 /* If not found above, see if it's in the tool bar window, if a tool
830 && WINDOWP (f
->tool_bar_window
)
831 && XINT (XWINDOW (f
->tool_bar_window
)->height
) > 0
832 && (coordinates_in_window (XWINDOW (f
->tool_bar_window
), &x
, &y
)
836 window
= f
->tool_bar_window
;
842 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
843 doc
: /* Return window containing coordinates X and Y on FRAME.
844 If omitted, FRAME defaults to the currently selected frame.
845 The top left corner of the frame is considered to be row 0,
848 Lisp_Object x
, y
, frame
;
854 frame
= selected_frame
;
855 CHECK_LIVE_FRAME (frame
);
858 /* Check that arguments are integers or floats. */
859 CHECK_NUMBER_OR_FLOAT (x
);
860 CHECK_NUMBER_OR_FLOAT (y
);
862 return window_from_coordinates (f
,
863 PIXEL_X_FROM_CANON_X (f
, x
),
864 PIXEL_Y_FROM_CANON_Y (f
, y
),
868 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
869 doc
: /* Return current value of point in WINDOW.
870 For a nonselected window, this is the value point would have
871 if that window were selected.
873 Note that, when WINDOW is the selected window and its buffer
874 is also currently selected, the value returned is the same as (point).
875 It would be more strictly correct to return the `top-level' value
876 of point, outside of any save-excursion forms.
877 But that is hard to define. */)
881 register struct window
*w
= decode_window (window
);
883 if (w
== XWINDOW (selected_window
)
884 && current_buffer
== XBUFFER (w
->buffer
))
886 return Fmarker_position (w
->pointm
);
889 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
890 doc
: /* Return position at which display currently starts in WINDOW.
891 This is updated by redisplay or by calling `set-window-start'. */)
895 return Fmarker_position (decode_window (window
)->start
);
898 /* This is text temporarily removed from the doc string below.
900 This function returns nil if the position is not currently known.
901 That happens when redisplay is preempted and doesn't finish.
902 If in that case you want to compute where the end of the window would
903 have been if redisplay had finished, do this:
905 (goto-char (window-start window))
906 (vertical-motion (1- (window-height window)) window)
909 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
910 doc
: /* Return position at which display currently ends in WINDOW.
911 This is updated by redisplay, when it runs to completion.
912 Simply changing the buffer text or setting `window-start'
913 does not update this value.
914 If UPDATE is non-nil, compute the up-to-date position
915 if it isn't already recorded. */)
917 Lisp_Object window
, update
;
920 struct window
*w
= decode_window (window
);
926 #if 0 /* This change broke some things. We should make it later. */
927 /* If we don't know the end position, return nil.
928 The user can compute it with vertical-motion if he wants to.
929 It would be nicer to do it automatically,
930 but that's so slow that it would probably bother people. */
931 if (NILP (w
->window_end_valid
))
936 && ! (! NILP (w
->window_end_valid
)
937 && XFASTINT (w
->last_modified
) >= MODIFF
))
939 struct text_pos startp
;
941 struct buffer
*old_buffer
= NULL
, *b
= XBUFFER (buf
);
943 /* In case W->start is out of the range, use something
944 reasonable. This situation occured when loading a file with
945 `-l' containing a call to `rmail' with subsequent other
946 commands. At the end, W->start happened to be BEG, while
947 rmail had already narrowed the buffer. */
948 if (XMARKER (w
->start
)->charpos
< BEGV
)
949 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
950 else if (XMARKER (w
->start
)->charpos
> ZV
)
951 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
953 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
955 /* Cannot use Fvertical_motion because that function doesn't
956 cope with variable-height lines. */
957 if (b
!= current_buffer
)
959 old_buffer
= current_buffer
;
960 set_buffer_internal (b
);
963 start_display (&it
, w
, startp
);
964 move_it_vertically (&it
, window_box_height (w
));
965 if (it
.current_y
< it
.last_visible_y
)
966 move_it_past_eol (&it
);
967 value
= make_number (IT_CHARPOS (it
));
970 set_buffer_internal (old_buffer
);
973 XSETINT (value
, BUF_Z (XBUFFER (buf
)) - XFASTINT (w
->window_end_pos
));
978 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
979 doc
: /* Make point value in WINDOW be at position POS in WINDOW's buffer. */)
981 Lisp_Object window
, pos
;
983 register struct window
*w
= decode_window (window
);
985 CHECK_NUMBER_COERCE_MARKER (pos
);
986 if (w
== XWINDOW (selected_window
)
987 && XBUFFER (w
->buffer
) == current_buffer
)
990 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
992 /* We have to make sure that redisplay updates the window to show
993 the new value of point. */
994 if (!EQ (window
, selected_window
))
995 ++windows_or_buffers_changed
;
1000 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
1001 doc
: /* Make display in WINDOW start at position POS in WINDOW's buffer.
1002 Optional third arg NOFORCE non-nil inhibits next redisplay
1003 from overriding motion of point in order to display at this exact start. */)
1004 (window
, pos
, noforce
)
1005 Lisp_Object window
, pos
, noforce
;
1007 register struct window
*w
= decode_window (window
);
1009 CHECK_NUMBER_COERCE_MARKER (pos
);
1010 set_marker_restricted (w
->start
, pos
, w
->buffer
);
1011 /* this is not right, but much easier than doing what is right. */
1012 w
->start_at_line_beg
= Qnil
;
1014 w
->force_start
= Qt
;
1015 w
->update_mode_line
= Qt
;
1016 XSETFASTINT (w
->last_modified
, 0);
1017 XSETFASTINT (w
->last_overlay_modified
, 0);
1018 if (!EQ (window
, selected_window
))
1019 windows_or_buffers_changed
++;
1024 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
1026 doc
: /* Return WINDOW's dedicated object, usually t or nil.
1027 See also `set-window-dedicated-p'. */)
1031 return decode_window (window
)->dedicated
;
1034 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
1035 Sset_window_dedicated_p
, 2, 2, 0,
1036 doc
: /* Control whether WINDOW is dedicated to the buffer it displays.
1037 If it is dedicated, Emacs will not automatically change
1038 which buffer appears in it.
1039 The second argument is the new value for the dedication flag;
1040 non-nil means yes. */)
1042 Lisp_Object window
, arg
;
1044 register struct window
*w
= decode_window (window
);
1047 w
->dedicated
= Qnil
;
1051 return w
->dedicated
;
1054 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
1056 doc
: /* Return the display-table that WINDOW is using. */)
1060 return decode_window (window
)->display_table
;
1063 /* Get the display table for use on window W. This is either W's
1064 display table or W's buffer's display table. Ignore the specified
1065 tables if they are not valid; if no valid table is specified,
1068 struct Lisp_Char_Table
*
1069 window_display_table (w
)
1072 struct Lisp_Char_Table
*dp
= NULL
;
1074 if (DISP_TABLE_P (w
->display_table
))
1075 dp
= XCHAR_TABLE (w
->display_table
);
1076 else if (BUFFERP (w
->buffer
))
1078 struct buffer
*b
= XBUFFER (w
->buffer
);
1080 if (DISP_TABLE_P (b
->display_table
))
1081 dp
= XCHAR_TABLE (b
->display_table
);
1082 else if (DISP_TABLE_P (Vstandard_display_table
))
1083 dp
= XCHAR_TABLE (Vstandard_display_table
);
1089 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
1090 doc
: /* Set WINDOW's display-table to TABLE. */)
1092 register Lisp_Object window
, table
;
1094 register struct window
*w
;
1096 w
= decode_window (window
);
1097 w
->display_table
= table
;
1101 /* Record info on buffer window w is displaying
1102 when it is about to cease to display that buffer. */
1105 register struct window
*w
;
1112 if (b
!= XMARKER (w
->pointm
)->buffer
)
1116 if (w
== XWINDOW (selected_window
)
1117 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
1118 /* Do this except when the selected window's buffer
1119 is being removed from some other window. */
1121 /* last_window_start records the start position that this buffer
1122 had in the last window to be disconnected from it.
1123 Now that this statement is unconditional,
1124 it is possible for the buffer to be displayed in the
1125 selected window, while last_window_start reflects another
1126 window which was recently showing the same buffer.
1127 Some people might say that might be a good thing. Let's see. */
1128 b
->last_window_start
= marker_position (w
->start
);
1130 /* Point in the selected window's buffer
1131 is actually stored in that buffer, and the window's pointm isn't used.
1132 So don't clobber point in that buffer. */
1133 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
)
1134 /* This line helps to fix Horsley's testbug.el bug. */
1135 && !(WINDOWP (b
->last_selected_window
)
1136 && w
!= XWINDOW (b
->last_selected_window
)
1137 && EQ (buf
, XWINDOW (b
->last_selected_window
)->buffer
)))
1138 temp_set_point_both (b
,
1139 clip_to_bounds (BUF_BEGV (b
),
1140 XMARKER (w
->pointm
)->charpos
,
1142 clip_to_bounds (BUF_BEGV_BYTE (b
),
1143 marker_byte_position (w
->pointm
),
1146 if (WINDOWP (b
->last_selected_window
)
1147 && w
== XWINDOW (b
->last_selected_window
))
1148 b
->last_selected_window
= Qnil
;
1151 /* Put replacement into the window structure in place of old. */
1153 replace_window (old
, replacement
)
1154 Lisp_Object old
, replacement
;
1156 register Lisp_Object tem
;
1157 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
1159 /* If OLD is its frame's root_window, then replacement is the new
1160 root_window for that frame. */
1162 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
1163 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
1167 p
->width
= o
->width
;
1168 p
->height
= o
->height
;
1169 p
->desired_matrix
= p
->current_matrix
= 0;
1171 bzero (&p
->cursor
, sizeof (p
->cursor
));
1172 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
1173 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
1174 p
->phys_cursor_type
= -1;
1175 p
->phys_cursor_width
= -1;
1176 p
->must_be_updated_p
= 0;
1177 p
->pseudo_window_p
= 0;
1178 XSETFASTINT (p
->window_end_vpos
, 0);
1179 XSETFASTINT (p
->window_end_pos
, 0);
1180 p
->window_end_valid
= Qnil
;
1181 p
->frozen_window_start_p
= 0;
1182 p
->orig_top
= p
->orig_height
= Qnil
;
1184 p
->next
= tem
= o
->next
;
1186 XWINDOW (tem
)->prev
= replacement
;
1188 p
->prev
= tem
= o
->prev
;
1190 XWINDOW (tem
)->next
= replacement
;
1192 p
->parent
= tem
= o
->parent
;
1195 if (EQ (XWINDOW (tem
)->vchild
, old
))
1196 XWINDOW (tem
)->vchild
= replacement
;
1197 if (EQ (XWINDOW (tem
)->hchild
, old
))
1198 XWINDOW (tem
)->hchild
= replacement
;
1201 /*** Here, if replacement is a vertical combination
1202 and so is its new parent, we should make replacement's
1203 children be children of that parent instead. ***/
1206 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
1207 doc
: /* Remove WINDOW from the display. Default is selected window. */)
1209 register Lisp_Object window
;
1211 delete_window (window
);
1213 if (! NILP (Vwindow_configuration_change_hook
)
1214 && ! NILP (Vrun_hooks
))
1215 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
1221 delete_window (window
)
1222 register Lisp_Object window
;
1224 register Lisp_Object tem
, parent
, sib
;
1225 register struct window
*p
;
1226 register struct window
*par
;
1229 /* Because this function is called by other C code on non-leaf
1230 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1231 so we can't decode_window here. */
1233 window
= selected_window
;
1235 CHECK_WINDOW (window
);
1236 p
= XWINDOW (window
);
1238 /* It's okay to delete an already-deleted window. */
1239 if (NILP (p
->buffer
)
1241 && NILP (p
->vchild
))
1246 error ("Attempt to delete minibuffer or sole ordinary window");
1247 par
= XWINDOW (parent
);
1249 windows_or_buffers_changed
++;
1250 Vwindow_list
= Qnil
;
1251 f
= XFRAME (WINDOW_FRAME (p
));
1252 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
1254 /* Are we trying to delete any frame's selected window? */
1256 Lisp_Object swindow
, pwindow
;
1258 /* See if the frame's selected window is either WINDOW
1259 or any subwindow of it, by finding all that window's parents
1260 and comparing each one with WINDOW. */
1261 swindow
= FRAME_SELECTED_WINDOW (f
);
1266 while (!NILP (pwindow
))
1268 if (EQ (window
, pwindow
))
1270 pwindow
= XWINDOW (pwindow
)->parent
;
1273 /* If the window being deleted is not a parent of SWINDOW,
1274 then SWINDOW is ok as the new selected window. */
1275 if (!EQ (window
, pwindow
))
1277 /* Otherwise, try another window for SWINDOW. */
1278 swindow
= Fnext_window (swindow
, Qlambda
, Qnil
);;
1280 /* If we get back to the frame's selected window,
1281 it means there was no acceptable alternative,
1282 so we cannot delete. */
1283 if (EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
1284 error ("Cannot delete window");
1287 /* If we need to change SWINDOW, do it. */
1288 if (! EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
1290 /* If we're about to delete the selected window on the
1291 selected frame, then we should use Fselect_window to select
1292 the new window. On the other hand, if we're about to
1293 delete the selected window on any other frame, we shouldn't do
1294 anything but set the frame's selected_window slot. */
1295 if (EQ (FRAME_SELECTED_WINDOW (f
), selected_window
))
1296 Fselect_window (swindow
);
1298 FRAME_SELECTED_WINDOW (f
) = swindow
;
1303 /* tem is null for dummy parent windows
1304 (which have inferiors but not any contents themselves) */
1308 unchain_marker (p
->pointm
);
1309 unchain_marker (p
->start
);
1312 /* Free window glyph matrices. It is sure that they are allocated
1313 again when ADJUST_GLYPHS is called. Block input so that expose
1314 events and other events that access glyph matrices are not
1315 processed while we are changing them. */
1317 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f
)));
1321 XWINDOW (tem
)->prev
= p
->prev
;
1325 XWINDOW (tem
)->next
= p
->next
;
1327 if (EQ (window
, par
->hchild
))
1328 par
->hchild
= p
->next
;
1329 if (EQ (window
, par
->vchild
))
1330 par
->vchild
= p
->next
;
1332 /* Find one of our siblings to give our space to. */
1336 /* If p gives its space to its next sibling, that sibling needs
1337 to have its top/left side pulled back to where p's is.
1338 set_window_{height,width} will re-position the sibling's
1341 XWINDOW (sib
)->top
= p
->top
;
1342 XWINDOW (sib
)->left
= p
->left
;
1345 /* Stretch that sibling. */
1346 if (!NILP (par
->vchild
))
1347 set_window_height (sib
,
1348 XFASTINT (XWINDOW (sib
)->height
) + XFASTINT (p
->height
),
1350 if (!NILP (par
->hchild
))
1351 set_window_width (sib
,
1352 XFASTINT (XWINDOW (sib
)->width
) + XFASTINT (p
->width
),
1355 /* If parent now has only one child,
1356 put the child into the parent's place. */
1360 if (NILP (XWINDOW (tem
)->next
))
1361 replace_window (parent
, tem
);
1363 /* Since we may be deleting combination windows, we must make sure that
1364 not only p but all its children have been marked as deleted. */
1365 if (! NILP (p
->hchild
))
1366 delete_all_subwindows (XWINDOW (p
->hchild
));
1367 else if (! NILP (p
->vchild
))
1368 delete_all_subwindows (XWINDOW (p
->vchild
));
1370 /* Mark this window as deleted. */
1371 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
1373 /* Adjust glyph matrices. */
1380 /***********************************************************************
1382 ***********************************************************************/
1384 /* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object
1385 pointer. This is a callback function for foreach_window, used in
1386 function window_list. */
1389 add_window_to_list (w
, user_data
)
1393 Lisp_Object
*list
= (Lisp_Object
*) user_data
;
1395 XSETWINDOW (window
, w
);
1396 *list
= Fcons (window
, *list
);
1401 /* Return a list of all windows, for use by next_window. If
1402 Vwindow_list is a list, return that list. Otherwise, build a new
1403 list, cache it in Vwindow_list, and return that. */
1408 if (!CONSP (Vwindow_list
))
1412 Vwindow_list
= Qnil
;
1413 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
1415 Lisp_Object args
[2];
1417 /* We are visiting windows in canonical order, and add
1418 new windows at the front of args[1], which means we
1419 have to reverse this list at the end. */
1421 foreach_window (XFRAME (XCAR (tail
)), add_window_to_list
, &args
[1]);
1422 args
[0] = Vwindow_list
;
1423 args
[1] = Fnreverse (args
[1]);
1424 Vwindow_list
= Fnconc (2, args
);
1428 return Vwindow_list
;
1432 /* Value is non-zero if WINDOW satisfies the constraints given by
1433 OWINDOW, MINIBUF and ALL_FRAMES.
1435 MINIBUF t means WINDOW may be minibuffer windows.
1436 `lambda' means WINDOW may not be a minibuffer window.
1437 a window means a specific minibuffer window
1439 ALL_FRAMES t means search all frames,
1440 nil means search just current frame,
1441 `visible' means search just visible frames,
1442 0 means search visible and iconified frames,
1443 a window means search the frame that window belongs to,
1444 a frame means consider windows on that frame, only. */
1447 candidate_window_p (window
, owindow
, minibuf
, all_frames
)
1448 Lisp_Object window
, owindow
, minibuf
, all_frames
;
1450 struct window
*w
= XWINDOW (window
);
1451 struct frame
*f
= XFRAME (w
->frame
);
1452 int candidate_p
= 1;
1454 if (!BUFFERP (w
->buffer
))
1456 else if (MINI_WINDOW_P (w
)
1457 && (EQ (minibuf
, Qlambda
)
1458 || (WINDOWP (minibuf
) && !EQ (minibuf
, window
))))
1460 /* If MINIBUF is `lambda' don't consider any mini-windows.
1461 If it is a window, consider only that one. */
1464 else if (EQ (all_frames
, Qt
))
1466 else if (NILP (all_frames
))
1468 xassert (WINDOWP (owindow
));
1469 candidate_p
= EQ (w
->frame
, XWINDOW (owindow
)->frame
);
1471 else if (EQ (all_frames
, Qvisible
))
1473 FRAME_SAMPLE_VISIBILITY (f
);
1474 candidate_p
= FRAME_VISIBLE_P (f
);
1476 else if (INTEGERP (all_frames
) && XINT (all_frames
) == 0)
1478 FRAME_SAMPLE_VISIBILITY (f
);
1479 candidate_p
= FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
);
1481 else if (WINDOWP (all_frames
))
1482 candidate_p
= (EQ (FRAME_MINIBUF_WINDOW (f
), all_frames
)
1483 || EQ (XWINDOW (all_frames
)->frame
, w
->frame
)
1484 || EQ (XWINDOW (all_frames
)->frame
, FRAME_FOCUS_FRAME (f
)));
1485 else if (FRAMEP (all_frames
))
1486 candidate_p
= EQ (all_frames
, w
->frame
);
1492 /* Decode arguments as allowed by Fnext_window, Fprevious_window, and
1493 Fwindow_list. See there for the meaning of WINDOW, MINIBUF, and
1497 decode_next_window_args (window
, minibuf
, all_frames
)
1498 Lisp_Object
*window
, *minibuf
, *all_frames
;
1501 *window
= selected_window
;
1503 CHECK_LIVE_WINDOW (*window
);
1505 /* MINIBUF nil may or may not include minibuffers. Decide if it
1507 if (NILP (*minibuf
))
1508 *minibuf
= minibuf_level
? minibuf_window
: Qlambda
;
1509 else if (!EQ (*minibuf
, Qt
))
1512 /* Now *MINIBUF can be t => count all minibuffer windows, `lambda'
1513 => count none of them, or a specific minibuffer window (the
1514 active one) to count. */
1516 /* ALL_FRAMES nil doesn't specify which frames to include. */
1517 if (NILP (*all_frames
))
1518 *all_frames
= (!EQ (*minibuf
, Qlambda
)
1519 ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window
)->frame
))
1521 else if (EQ (*all_frames
, Qvisible
))
1523 else if (XFASTINT (*all_frames
) == 0)
1525 else if (FRAMEP (*all_frames
))
1527 else if (!EQ (*all_frames
, Qt
))
1530 /* Now *ALL_FRAMES is t meaning search all frames, nil meaning
1531 search just current frame, `visible' meaning search just visible
1532 frames, 0 meaning search visible and iconified frames, or a
1533 window, meaning search the frame that window belongs to, or a
1534 frame, meaning consider windows on that frame, only. */
1538 /* Return the next or previous window of WINDOW in canonical ordering
1539 of windows. NEXT_P non-zero means return the next window. See the
1540 documentation string of next-window for the meaning of MINIBUF and
1544 next_window (window
, minibuf
, all_frames
, next_p
)
1545 Lisp_Object window
, minibuf
, all_frames
;
1548 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1550 /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just
1551 return the first window on the frame. */
1552 if (FRAMEP (all_frames
)
1553 && !EQ (all_frames
, XWINDOW (window
)->frame
))
1554 return Fframe_first_window (all_frames
);
1560 /* Find WINDOW in the list of all windows. */
1561 list
= Fmemq (window
, window_list ());
1563 /* Scan forward from WINDOW to the end of the window list. */
1565 for (list
= XCDR (list
); CONSP (list
); list
= XCDR (list
))
1566 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1569 /* Scan from the start of the window list up to WINDOW. */
1571 for (list
= Vwindow_list
;
1572 CONSP (list
) && !EQ (XCAR (list
), window
);
1574 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1578 window
= XCAR (list
);
1582 Lisp_Object candidate
, list
;
1584 /* Scan through the list of windows for candidates. If there are
1585 candidate windows in front of WINDOW, the last one of these
1586 is the one we want. If there are candidates following WINDOW
1587 in the list, again the last one of these is the one we want. */
1589 for (list
= window_list (); CONSP (list
); list
= XCDR (list
))
1591 if (EQ (XCAR (list
), window
))
1593 if (WINDOWP (candidate
))
1596 else if (candidate_window_p (XCAR (list
), window
, minibuf
,
1598 candidate
= XCAR (list
);
1601 if (WINDOWP (candidate
))
1609 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
1610 doc
: /* Return next window after WINDOW in canonical ordering of windows.
1611 If omitted, WINDOW defaults to the selected window.
1613 Optional second arg MINIBUF t means count the minibuffer window even
1614 if not active. MINIBUF nil or omitted means count the minibuffer iff
1615 it is active. MINIBUF neither t nor nil means not to count the
1616 minibuffer even if it is active.
1618 Several frames may share a single minibuffer; if the minibuffer
1619 counts, all windows on all frames that share that minibuffer count
1620 too. Therefore, `next-window' can be used to iterate through the
1621 set of windows even when the minibuffer is on another frame. If the
1622 minibuffer does not count, only windows from WINDOW's frame count.
1624 Optional third arg ALL-FRAMES t means include windows on all frames.
1625 ALL-FRAMES nil or omitted means cycle within the frames as specified
1626 above. ALL-FRAMES = `visible' means include windows on all visible frames.
1627 ALL-FRAMES = 0 means include windows on all visible and iconified frames.
1628 If ALL-FRAMES is a frame, restrict search to windows on that frame.
1629 Anything else means restrict to WINDOW's frame.
1631 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
1632 `next-window' to iterate through the entire cycle of acceptable
1633 windows, eventually ending up back at the window you started with.
1634 `previous-window' traverses the same cycle, in the reverse order. */)
1635 (window
, minibuf
, all_frames
)
1636 Lisp_Object window
, minibuf
, all_frames
;
1638 return next_window (window
, minibuf
, all_frames
, 1);
1642 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
1643 doc
: /* Return the window preceding WINDOW in canonical ordering of windows.
1644 If omitted, WINDOW defaults to the selected window.
1646 Optional second arg MINIBUF t means count the minibuffer window even
1647 if not active. MINIBUF nil or omitted means count the minibuffer iff
1648 it is active. MINIBUF neither t nor nil means not to count the
1649 minibuffer even if it is active.
1651 Several frames may share a single minibuffer; if the minibuffer
1652 counts, all windows on all frames that share that minibuffer count
1653 too. Therefore, `previous-window' can be used to iterate through
1654 the set of windows even when the minibuffer is on another frame. If
1655 the minibuffer does not count, only windows from WINDOW's frame count
1657 Optional third arg ALL-FRAMES t means include windows on all frames.
1658 ALL-FRAMES nil or omitted means cycle within the frames as specified
1659 above. ALL-FRAMES = `visible' means include windows on all visible frames.
1660 ALL-FRAMES = 0 means include windows on all visible and iconified frames.
1661 If ALL-FRAMES is a frame, restrict search to windows on that frame.
1662 Anything else means restrict to WINDOW's frame.
1664 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
1665 `previous-window' to iterate through the entire cycle of acceptable
1666 windows, eventually ending up back at the window you started with.
1667 `next-window' traverses the same cycle, in the reverse order. */)
1668 (window
, minibuf
, all_frames
)
1669 Lisp_Object window
, minibuf
, all_frames
;
1671 return next_window (window
, minibuf
, all_frames
, 0);
1675 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1676 doc
: /* Select the ARG'th different window on this frame.
1677 All windows on current frame are arranged in a cyclic order.
1678 This command selects the window ARG steps away in that order.
1679 A negative ARG moves in the opposite order. If the optional second
1680 argument ALL_FRAMES is non-nil, cycle through all frames. */)
1682 Lisp_Object arg
, all_frames
;
1688 window
= selected_window
;
1690 for (i
= XINT (arg
); i
> 0; --i
)
1691 window
= Fnext_window (window
, Qnil
, all_frames
);
1693 window
= Fprevious_window (window
, Qnil
, all_frames
);
1695 Fselect_window (window
);
1700 DEFUN ("window-list", Fwindow_list
, Swindow_list
, 0, 3, 0,
1701 doc
: /* Return a list of windows on FRAME, starting with WINDOW.
1702 FRAME nil or omitted means use the selected frame.
1703 WINDOW nil or omitted means use the selected window.
1704 MINIBUF t means include the minibuffer window, even if it isn't active.
1705 MINIBUF nil or omitted means include the minibuffer window only
1707 MINIBUF neither nil nor t means never include the minibuffer window. */)
1708 (frame
, minibuf
, window
)
1709 Lisp_Object frame
, minibuf
, window
;
1712 window
= selected_window
;
1714 frame
= selected_frame
;
1716 if (!EQ (frame
, XWINDOW (window
)->frame
))
1717 error ("Window is on a different frame");
1719 return window_list_1 (window
, minibuf
, frame
);
1723 /* Return a list of windows in canonical ordering. Arguments are like
1724 for `next-window'. */
1727 window_list_1 (window
, minibuf
, all_frames
)
1728 Lisp_Object window
, minibuf
, all_frames
;
1730 Lisp_Object tail
, list
;
1732 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1735 for (tail
= window_list (); CONSP (tail
); tail
= XCDR (tail
))
1736 if (candidate_window_p (XCAR (tail
), window
, minibuf
, all_frames
))
1737 list
= Fcons (XCAR (tail
), list
);
1739 return Fnreverse (list
);
1744 /* Look at all windows, performing an operation specified by TYPE
1746 If FRAMES is Qt, look at all frames;
1747 Qnil, look at just the selected frame;
1748 Qvisible, look at visible frames;
1749 a frame, just look at windows on that frame.
1750 If MINI is non-zero, perform the operation on minibuffer windows too. */
1755 GET_BUFFER_WINDOW
, /* Arg is buffer */
1756 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1757 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1758 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1760 UNSHOW_BUFFER
, /* Arg is buffer */
1765 window_loop (type
, obj
, mini
, frames
)
1766 enum window_loop type
;
1767 Lisp_Object obj
, frames
;
1770 Lisp_Object window
, windows
, best_window
, frame_arg
;
1772 struct gcpro gcpro1
;
1774 /* If we're only looping through windows on a particular frame,
1775 frame points to that frame. If we're looping through windows
1776 on all frames, frame is 0. */
1777 if (FRAMEP (frames
))
1778 f
= XFRAME (frames
);
1779 else if (NILP (frames
))
1780 f
= SELECTED_FRAME ();
1785 frame_arg
= Qlambda
;
1786 else if (XFASTINT (frames
) == 0)
1788 else if (EQ (frames
, Qvisible
))
1793 /* frame_arg is Qlambda to stick to one frame,
1794 Qvisible to consider all visible frames,
1797 /* Pick a window to start with. */
1801 window
= FRAME_SELECTED_WINDOW (f
);
1803 window
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
1805 windows
= window_list_1 (window
, mini
? Qt
: Qnil
, frame_arg
);
1809 for (; CONSP (windows
); windows
= CDR (windows
))
1813 window
= XCAR (windows
);
1814 w
= XWINDOW (window
);
1816 /* Note that we do not pay attention here to whether the frame
1817 is visible, since Fwindow_list skips non-visible frames if
1818 that is desired, under the control of frame_arg. */
1819 if (!MINI_WINDOW_P (w
)
1820 /* For UNSHOW_BUFFER, we must always consider all windows. */
1821 || type
== UNSHOW_BUFFER
1822 || (mini
&& minibuf_level
> 0))
1825 case GET_BUFFER_WINDOW
:
1826 if (EQ (w
->buffer
, obj
)
1827 /* Don't find any minibuffer window
1828 except the one that is currently in use. */
1829 && (MINI_WINDOW_P (w
)
1830 ? EQ (window
, minibuf_window
)
1833 if (NILP (best_window
))
1834 best_window
= window
;
1835 else if (EQ (window
, selected_window
))
1836 /* For compatibility with 20.x, prefer to return
1838 best_window
= window
;
1842 case GET_LRU_WINDOW
:
1843 /* t as arg means consider only full-width windows */
1844 if (!NILP (obj
) && !WINDOW_FULL_WIDTH_P (w
))
1846 /* Ignore dedicated windows and minibuffers. */
1847 if (MINI_WINDOW_P (w
) || !NILP (w
->dedicated
))
1849 if (NILP (best_window
)
1850 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1851 > XFASTINT (w
->use_time
)))
1852 best_window
= window
;
1855 case DELETE_OTHER_WINDOWS
:
1856 if (!EQ (window
, obj
))
1857 Fdelete_window (window
);
1860 case DELETE_BUFFER_WINDOWS
:
1861 if (EQ (w
->buffer
, obj
))
1863 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1865 /* If this window is dedicated, and in a frame of its own,
1867 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
1868 && !NILP (w
->dedicated
)
1869 && other_visible_frames (f
))
1871 /* Skip the other windows on this frame.
1872 There might be one, the minibuffer! */
1873 while (CONSP (XCDR (windows
))
1874 && EQ (XWINDOW (XCAR (windows
))->frame
,
1875 XWINDOW (XCAR (XCDR (windows
)))->frame
))
1876 windows
= XCDR (windows
);
1878 /* Now we can safely delete the frame. */
1879 Fdelete_frame (w
->frame
, Qnil
);
1881 else if (NILP (w
->parent
))
1883 /* If we're deleting the buffer displayed in the
1884 only window on the frame, find a new buffer to
1887 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
1888 Fset_window_buffer (window
, buffer
);
1889 if (EQ (window
, selected_window
))
1890 Fset_buffer (w
->buffer
);
1893 Fdelete_window (window
);
1897 case GET_LARGEST_WINDOW
:
1899 /* Ignore dedicated windows and minibuffers. */
1900 if (MINI_WINDOW_P (w
) || !NILP (w
->dedicated
))
1903 if (NILP (best_window
))
1904 best_window
= window
;
1907 struct window
*b
= XWINDOW (best_window
);
1908 if (XFASTINT (w
->height
) * XFASTINT (w
->width
)
1909 > XFASTINT (b
->height
) * XFASTINT (b
->width
))
1910 best_window
= window
;
1916 if (EQ (w
->buffer
, obj
))
1919 struct frame
*f
= XFRAME (w
->frame
);
1921 /* Find another buffer to show in this window. */
1922 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
1924 /* If this window is dedicated, and in a frame of its own,
1926 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
1927 && !NILP (w
->dedicated
)
1928 && other_visible_frames (f
))
1930 /* Skip the other windows on this frame.
1931 There might be one, the minibuffer! */
1932 while (CONSP (XCDR (windows
))
1933 && EQ (XWINDOW (XCAR (windows
))->frame
,
1934 XWINDOW (XCAR (XCDR (windows
)))->frame
))
1935 windows
= XCDR (windows
);
1937 /* Now we can safely delete the frame. */
1938 Fdelete_frame (w
->frame
, Qnil
);
1942 /* Otherwise show a different buffer in the window. */
1943 w
->dedicated
= Qnil
;
1944 Fset_window_buffer (window
, buffer
);
1945 if (EQ (window
, selected_window
))
1946 Fset_buffer (w
->buffer
);
1951 /* Check for a window that has a killed buffer. */
1952 case CHECK_ALL_WINDOWS
:
1953 if (! NILP (w
->buffer
)
1954 && NILP (XBUFFER (w
->buffer
)->name
))
1958 case WINDOW_LOOP_UNUSED
:
1967 /* Used for debugging. Abort if any window has a dead buffer. */
1970 check_all_windows ()
1972 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
1975 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1976 doc
: /* Return the window least recently selected or used for display.
1977 If optional argument FRAME is `visible', search all visible frames.
1978 If FRAME is 0, search all visible and iconified frames.
1979 If FRAME is t, search all frames.
1980 If FRAME is nil, search only the selected frame.
1981 If FRAME is a frame, search only that frame. */)
1985 register Lisp_Object w
;
1986 /* First try for a window that is full-width */
1987 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frame
);
1988 if (!NILP (w
) && !EQ (w
, selected_window
))
1990 /* If none of them, try the rest */
1991 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frame
);
1994 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1995 doc
: /* Return the largest window in area.
1996 If optional argument FRAME is `visible', search all visible frames.
1997 If FRAME is 0, search all visible and iconified frames.
1998 If FRAME is t, search all frames.
1999 If FRAME is nil, search only the selected frame.
2000 If FRAME is a frame, search only that frame. */)
2004 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
2008 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
2009 doc
: /* Return a window currently displaying BUFFER, or nil if none.
2010 If optional argument FRAME is `visible', search all visible frames.
2011 If optional argument FRAME is 0, search all visible and iconified frames.
2012 If FRAME is t, search all frames.
2013 If FRAME is nil, search only the selected frame.
2014 If FRAME is a frame, search only that frame. */)
2016 Lisp_Object buffer
, frame
;
2018 buffer
= Fget_buffer (buffer
);
2019 if (BUFFERP (buffer
))
2020 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
2025 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
2027 doc
: /* Make WINDOW (or the selected window) fill its frame.
2028 Only the frame WINDOW is on is affected.
2029 This function tries to reduce display jumps
2030 by keeping the text previously visible in WINDOW
2031 in the same place on the frame. Doing this depends on
2032 the value of (window-start WINDOW), so if calling this function
2033 in a program gives strange scrolling, make sure the window-start
2034 value is reasonable when this function is called. */)
2043 window
= selected_window
;
2045 CHECK_LIVE_WINDOW (window
);
2046 w
= XWINDOW (window
);
2048 startpos
= marker_position (w
->start
);
2049 top
= XFASTINT (w
->top
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2051 if (MINI_WINDOW_P (w
) && top
> 0)
2052 error ("Can't expand minibuffer to full frame");
2054 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
2056 /* Try to minimize scrolling, by setting the window start to the point
2057 will cause the text at the old window start to be at the same place
2058 on the frame. But don't try to do this if the window start is
2059 outside the visible portion (as might happen when the display is
2060 not current, due to typeahead). */
2061 new_top
= XFASTINT (w
->top
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2063 && startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
2064 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
2066 struct position pos
;
2067 struct buffer
*obuf
= current_buffer
;
2069 Fset_buffer (w
->buffer
);
2070 /* This computation used to temporarily move point, but that can
2071 have unwanted side effects due to text properties. */
2072 pos
= *vmotion (startpos
, -top
, w
);
2074 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
2075 w
->window_end_valid
= Qnil
;
2076 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
2077 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
2079 /* We need to do this, so that the window-scroll-functions
2081 w
->optional_new_start
= Qt
;
2083 set_buffer_internal (obuf
);
2089 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
2090 1, 2, "bDelete windows on (buffer): ",
2091 doc
: /* Delete all windows showing BUFFER.
2092 Optional second argument FRAME controls which frames are affected.
2093 If optional argument FRAME is `visible', search all visible frames.
2094 If FRAME is 0, search all visible and iconified frames.
2095 If FRAME is nil, search all frames.
2096 If FRAME is t, search only the selected frame.
2097 If FRAME is a frame, search only that frame. */)
2099 Lisp_Object buffer
, frame
;
2101 /* FRAME uses t and nil to mean the opposite of what window_loop
2105 else if (EQ (frame
, Qt
))
2110 buffer
= Fget_buffer (buffer
);
2111 CHECK_BUFFER (buffer
);
2112 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
2118 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
2119 Sreplace_buffer_in_windows
,
2120 1, 1, "bReplace buffer in windows: ",
2121 doc
: /* Replace BUFFER with some other buffer in all windows showing it. */)
2127 buffer
= Fget_buffer (buffer
);
2128 CHECK_BUFFER (buffer
);
2129 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
2134 /* Replace BUFFER with some other buffer in all windows
2135 of all frames, even those on other keyboards. */
2138 replace_buffer_in_all_windows (buffer
)
2142 Lisp_Object tail
, frame
;
2144 /* A single call to window_loop won't do the job
2145 because it only considers frames on the current keyboard.
2146 So loop manually over frames, and handle each one. */
2147 FOR_EACH_FRAME (tail
, frame
)
2148 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
2150 window_loop (UNSHOW_BUFFER
, buffer
, 1, Qt
);
2154 /* Set the height of WINDOW and all its inferiors. */
2156 /* The smallest acceptable dimensions for a window. Anything smaller
2157 might crash Emacs. */
2159 #define MIN_SAFE_WINDOW_WIDTH (2)
2160 #define MIN_SAFE_WINDOW_HEIGHT (1)
2162 /* Make sure that window_min_height and window_min_width are
2163 not too small; if they are, set them to safe minima. */
2166 check_min_window_sizes ()
2168 /* Smaller values might permit a crash. */
2169 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
2170 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
2171 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
2172 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
2175 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
2176 minimum allowable size. */
2179 check_frame_size (frame
, rows
, cols
)
2183 /* For height, we have to see:
2184 how many windows the frame has at minimum (one or two),
2185 and whether it has a menu bar or other special stuff at the top. */
2187 = ((FRAME_MINIBUF_ONLY_P (frame
) || ! FRAME_HAS_MINIBUF_P (frame
))
2188 ? MIN_SAFE_WINDOW_HEIGHT
2189 : 2 * MIN_SAFE_WINDOW_HEIGHT
);
2191 if (FRAME_TOP_MARGIN (frame
) > 0)
2192 min_height
+= FRAME_TOP_MARGIN (frame
);
2194 if (*rows
< min_height
)
2196 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
2197 *cols
= MIN_SAFE_WINDOW_WIDTH
;
2201 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
2202 check if W's width can be changed, otherwise check W's height.
2203 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
2204 siblings, too. If none of the siblings is resizable, WINDOW isn't
2208 window_fixed_size_p (w
, width_p
, check_siblings_p
)
2210 int width_p
, check_siblings_p
;
2215 if (!NILP (w
->hchild
))
2217 c
= XWINDOW (w
->hchild
);
2221 /* A horiz. combination is fixed-width if all of if its
2223 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2224 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2225 fixed_p
= c
== NULL
;
2229 /* A horiz. combination is fixed-height if one of if its
2231 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2232 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2233 fixed_p
= c
!= NULL
;
2236 else if (!NILP (w
->vchild
))
2238 c
= XWINDOW (w
->vchild
);
2242 /* A vert. combination is fixed-width if one of if its
2244 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2245 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2246 fixed_p
= c
!= NULL
;
2250 /* A vert. combination is fixed-height if all of if its
2252 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2253 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2254 fixed_p
= c
== NULL
;
2257 else if (BUFFERP (w
->buffer
))
2259 if (w
->height_fixed_p
&& !width_p
)
2263 struct buffer
*old
= current_buffer
;
2266 current_buffer
= XBUFFER (w
->buffer
);
2267 val
= find_symbol_value (Qwindow_size_fixed
);
2268 current_buffer
= old
;
2271 if (!EQ (val
, Qunbound
))
2273 fixed_p
= !NILP (val
);
2276 && ((EQ (val
, Qheight
) && width_p
)
2277 || (EQ (val
, Qwidth
) && !width_p
)))
2282 /* Can't tell if this one is resizable without looking at
2283 siblings. If all siblings are fixed-size this one is too. */
2284 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
2288 for (child
= w
->prev
; !NILP (child
); child
= XWINDOW (child
)->prev
)
2289 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2293 for (child
= w
->next
; !NILP (child
); child
= XWINDOW (child
)->next
)
2294 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2308 /* Return the minimum size of window W, not taking fixed-width windows
2309 into account. WIDTH_P non-zero means return the minimum width,
2310 otherwise return the minimum height. If W is a combination window,
2311 compute the minimum size from the minimum sizes of W's children. */
2314 window_min_size_1 (w
, width_p
)
2321 if (!NILP (w
->hchild
))
2323 c
= XWINDOW (w
->hchild
);
2328 /* The min width of a horizontal combination is
2329 the sum of the min widths of its children. */
2332 size
+= window_min_size_1 (c
, width_p
);
2333 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2338 /* The min height a horizontal combination equals
2339 the maximum of all min height of its children. */
2342 int min_size
= window_min_size_1 (c
, width_p
);
2343 size
= max (min_size
, size
);
2344 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2348 else if (!NILP (w
->vchild
))
2350 c
= XWINDOW (w
->vchild
);
2355 /* The min width of a vertical combination is
2356 the maximum of the min widths of its children. */
2359 int min_size
= window_min_size_1 (c
, width_p
);
2360 size
= max (min_size
, size
);
2361 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2366 /* The min height of a vertical combination equals
2367 the sum of the min height of its children. */
2370 size
+= window_min_size_1 (c
, width_p
);
2371 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2378 size
= window_min_width
;
2381 if (MINI_WINDOW_P (w
)
2382 || (!WINDOW_WANTS_MODELINE_P (w
)
2383 && !WINDOW_WANTS_HEADER_LINE_P (w
)))
2386 size
= window_min_height
;
2394 /* Return the minimum size of window W, taking fixed-size windows into
2395 account. WIDTH_P non-zero means return the minimum width,
2396 otherwise return the minimum height. IGNORE_FIXED_P non-zero means
2397 ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size
2398 unless FIXED is null. */
2401 window_min_size (w
, width_p
, ignore_fixed_p
, fixed
)
2403 int width_p
, ignore_fixed_p
, *fixed
;
2410 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
2416 size
= width_p
? XFASTINT (w
->width
) : XFASTINT (w
->height
);
2418 size
= window_min_size_1 (w
, width_p
);
2424 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
2425 WINDOW's width. Resize WINDOW's children, if any, so that they
2426 keep their proportionate size relative to WINDOW. Propagate
2427 WINDOW's top or left edge position to children. Delete windows
2428 that become too small unless NODELETE_P is non-zero.
2430 If NODELETE_P is 2, that means we do delete windows that are
2431 too small, even if they were too small before! */
2434 size_window (window
, size
, width_p
, nodelete_p
)
2436 int size
, width_p
, nodelete_p
;
2438 struct window
*w
= XWINDOW (window
);
2440 Lisp_Object child
, *forward
, *sideward
;
2441 int old_size
, min_size
;
2443 if (nodelete_p
== 2)
2446 check_min_window_sizes ();
2447 size
= max (0, size
);
2449 /* If the window has been "too small" at one point,
2450 don't delete it for being "too small" in the future.
2451 Preserve it as long as that is at all possible. */
2454 old_size
= XINT (w
->width
);
2455 min_size
= window_min_width
;
2459 old_size
= XINT (w
->height
);
2460 min_size
= window_min_height
;
2463 if (old_size
< min_size
&& nodelete_p
!= 2)
2464 w
->too_small_ok
= Qt
;
2466 /* Maybe delete WINDOW if it's too small. */
2467 if (nodelete_p
!= 1 && !NILP (w
->parent
))
2469 if (!MINI_WINDOW_P (w
) && !NILP (w
->too_small_ok
))
2470 min_size
= width_p
? MIN_SAFE_WINDOW_WIDTH
: MIN_SAFE_WINDOW_HEIGHT
;
2472 min_size
= width_p
? window_min_width
: window_min_height
;
2474 if (size
< min_size
)
2476 delete_window (window
);
2481 /* Set redisplay hints. */
2482 w
->last_modified
= make_number (0);
2483 w
->last_overlay_modified
= make_number (0);
2484 windows_or_buffers_changed
++;
2485 FRAME_WINDOW_SIZES_CHANGED (XFRAME (w
->frame
)) = 1;
2489 sideward
= &w
->vchild
;
2490 forward
= &w
->hchild
;
2491 w
->width
= make_number (size
);
2495 sideward
= &w
->hchild
;
2496 forward
= &w
->vchild
;
2497 w
->height
= make_number (size
);
2498 w
->orig_height
= Qnil
;
2501 if (!NILP (*sideward
))
2503 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
2505 c
= XWINDOW (child
);
2510 size_window (child
, size
, width_p
, nodelete_p
);
2513 else if (!NILP (*forward
))
2515 int fixed_size
, each
, extra
, n
;
2516 int resize_fixed_p
, nfixed
;
2517 int last_pos
, first_pos
, nchildren
, total
;
2519 /* Determine the fixed-size portion of the this window, and the
2520 number of child windows. */
2521 fixed_size
= nchildren
= nfixed
= total
= 0;
2522 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
2526 c
= XWINDOW (child
);
2527 child_size
= width_p
? XINT (c
->width
) : XINT (c
->height
);
2528 total
+= child_size
;
2530 if (window_fixed_size_p (c
, width_p
, 0))
2532 fixed_size
+= child_size
;
2537 /* If the new size is smaller than fixed_size, or if there
2538 aren't any resizable windows, allow resizing fixed-size
2540 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
2542 /* Compute how many lines/columns to add to each child. The
2543 value of extra takes care of rounding errors. */
2544 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
2545 each
= (size
- total
) / n
;
2546 extra
= (size
- total
) - n
* each
;
2548 /* Compute new children heights and edge positions. */
2549 first_pos
= width_p
? XINT (w
->left
) : XINT (w
->top
);
2550 last_pos
= first_pos
;
2551 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2553 int new_size
, old_size
;
2555 c
= XWINDOW (child
);
2556 old_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2557 new_size
= old_size
;
2559 /* The top or left edge position of this child equals the
2560 bottom or right edge of its predecessor. */
2562 c
->left
= make_number (last_pos
);
2564 c
->top
= make_number (last_pos
);
2566 /* If this child can be resized, do it. */
2567 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
2569 new_size
= old_size
+ each
+ extra
;
2573 /* Set new height. Note that size_window also propagates
2574 edge positions to children, so it's not a no-op if we
2575 didn't change the child's size. */
2576 size_window (child
, new_size
, width_p
, 1);
2578 /* Remember the bottom/right edge position of this child; it
2579 will be used to set the top/left edge of the next child. */
2580 last_pos
+= new_size
;
2583 /* We should have covered the parent exactly with child windows. */
2584 xassert (size
== last_pos
- first_pos
);
2586 /* Now delete any children that became too small. */
2588 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2591 c
= XWINDOW (child
);
2592 child_size
= width_p
? XINT (c
->width
) : XINT (c
->height
);
2593 size_window (child
, child_size
, width_p
, 2);
2598 /* Set WINDOW's height to HEIGHT, and recursively change the height of
2599 WINDOW's children. NODELETE non-zero means don't delete windows
2600 that become too small in the process. (The caller should check
2601 later and do so if appropriate.) */
2604 set_window_height (window
, height
, nodelete
)
2609 size_window (window
, height
, 0, nodelete
);
2613 /* Set WINDOW's width to WIDTH, and recursively change the width of
2614 WINDOW's children. NODELETE non-zero means don't delete windows
2615 that become too small in the process. (The caller should check
2616 later and do so if appropriate.) */
2619 set_window_width (window
, width
, nodelete
)
2624 size_window (window
, width
, 1, nodelete
);
2628 int window_select_count
;
2631 Fset_window_buffer_unwind (obuf
)
2639 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
2640 means it's allowed to run hooks. See make_frame for a case where
2641 it's not allowed. */
2644 set_window_buffer (window
, buffer
, run_hooks_p
)
2645 Lisp_Object window
, buffer
;
2648 struct window
*w
= XWINDOW (window
);
2649 struct buffer
*b
= XBUFFER (buffer
);
2650 int count
= specpdl_ptr
- specpdl
;
2654 if (EQ (window
, selected_window
))
2655 b
->last_selected_window
= window
;
2657 /* Update time stamps of buffer display. */
2658 if (INTEGERP (b
->display_count
))
2659 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
2660 b
->display_time
= Fcurrent_time ();
2662 XSETFASTINT (w
->window_end_pos
, 0);
2663 XSETFASTINT (w
->window_end_vpos
, 0);
2664 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
2665 w
->window_end_valid
= Qnil
;
2666 w
->hscroll
= w
->min_hscroll
= make_number (0);
2668 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
2669 set_marker_restricted (w
->start
,
2670 make_number (b
->last_window_start
),
2672 w
->start_at_line_beg
= Qnil
;
2673 w
->force_start
= Qnil
;
2674 XSETFASTINT (w
->last_modified
, 0);
2675 XSETFASTINT (w
->last_overlay_modified
, 0);
2676 windows_or_buffers_changed
++;
2678 /* We must select BUFFER for running the window-scroll-functions.
2679 If WINDOW is selected, switch permanently.
2680 Otherwise, switch but go back to the ambient buffer afterward. */
2681 if (EQ (window
, selected_window
))
2682 Fset_buffer (buffer
);
2683 /* We can't check ! NILP (Vwindow_scroll_functions) here
2684 because that might itself be a local variable. */
2685 else if (window_initialized
)
2687 record_unwind_protect (Fset_window_buffer_unwind
, Fcurrent_buffer ());
2688 Fset_buffer (buffer
);
2691 /* Set left and right marginal area width from buffer. */
2692 Fset_window_margins (window
, b
->left_margin_width
, b
->right_margin_width
);
2696 if (! NILP (Vwindow_scroll_functions
))
2697 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2698 Fmarker_position (w
->start
));
2700 if (! NILP (Vwindow_configuration_change_hook
)
2701 && ! NILP (Vrun_hooks
))
2702 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
2705 unbind_to (count
, Qnil
);
2709 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 2, 0,
2710 doc
: /* Make WINDOW display BUFFER as its contents.
2711 BUFFER can be a buffer or buffer name. */)
2713 register Lisp_Object window
, buffer
;
2715 register Lisp_Object tem
;
2716 register struct window
*w
= decode_window (window
);
2718 XSETWINDOW (window
, w
);
2719 buffer
= Fget_buffer (buffer
);
2720 CHECK_BUFFER (buffer
);
2722 if (NILP (XBUFFER (buffer
)->name
))
2723 error ("Attempt to display deleted buffer");
2727 error ("Window is deleted");
2728 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
2729 is first being set up. */
2731 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
2732 error ("Window is dedicated to `%s'",
2733 XSTRING (XBUFFER (tem
)->name
)->data
);
2738 set_window_buffer (window
, buffer
, 1);
2742 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 1, 0,
2743 doc
: /* Select WINDOW. Most editing will apply to WINDOW's buffer.
2744 If WINDOW is not already selected, also make WINDOW's buffer current.
2745 Note that the main editor command loop
2746 selects the buffer of the selected window before each command. */)
2748 register Lisp_Object window
;
2750 return select_window_1 (window
, 1);
2753 /* Note that selected_window can be nil
2754 when this is called from Fset_window_configuration. */
2757 select_window_1 (window
, recordflag
)
2758 register Lisp_Object window
;
2761 register struct window
*w
;
2762 register struct window
*ow
;
2765 CHECK_LIVE_WINDOW (window
);
2767 w
= XWINDOW (window
);
2768 w
->frozen_window_start_p
= 0;
2770 XSETFASTINT (w
->use_time
, ++window_select_count
);
2771 if (EQ (window
, selected_window
))
2774 if (!NILP (selected_window
))
2776 ow
= XWINDOW (selected_window
);
2777 if (! NILP (ow
->buffer
))
2778 set_marker_both (ow
->pointm
, ow
->buffer
,
2779 BUF_PT (XBUFFER (ow
->buffer
)),
2780 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
2783 selected_window
= window
;
2784 sf
= SELECTED_FRAME ();
2785 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
2787 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
2788 /* Use this rather than Fhandle_switch_frame
2789 so that FRAME_FOCUS_FRAME is moved appropriately as we
2790 move around in the state where a minibuffer in a separate
2792 Fselect_frame (WINDOW_FRAME (w
), Qnil
);
2795 sf
->selected_window
= window
;
2798 record_buffer (w
->buffer
);
2799 Fset_buffer (w
->buffer
);
2801 XBUFFER (w
->buffer
)->last_selected_window
= window
;
2803 /* Go to the point recorded in the window.
2804 This is important when the buffer is in more
2805 than one window. It also matters when
2806 redisplay_window has altered point after scrolling,
2807 because it makes the change only in the window. */
2809 register int new_point
= marker_position (w
->pointm
);
2810 if (new_point
< BEGV
)
2812 else if (new_point
> ZV
)
2818 windows_or_buffers_changed
++;
2822 /* Deiconify the frame containing the window WINDOW,
2823 unless it is the selected frame;
2826 The reason for the exception for the selected frame
2827 is that it seems better not to change the selected frames visibility
2828 merely because of displaying a different buffer in it.
2829 The deiconification is useful when a buffer gets shown in
2830 another frame that you were not using lately. */
2833 display_buffer_1 (window
)
2836 Lisp_Object frame
= XWINDOW (window
)->frame
;
2837 FRAME_PTR f
= XFRAME (frame
);
2839 FRAME_SAMPLE_VISIBILITY (f
);
2841 if (!EQ (frame
, selected_frame
))
2843 if (FRAME_ICONIFIED_P (f
))
2844 Fmake_frame_visible (frame
);
2845 else if (FRAME_VISIBLE_P (f
))
2846 Fraise_frame (frame
);
2852 DEFUN ("special-display-p", Fspecial_display_p
, Sspecial_display_p
, 1, 1, 0,
2853 doc
: /* Returns non-nil if a buffer named BUFFER-NAME would be created specially.
2854 The value is actually t if the frame should be called with default frame
2855 parameters, and a list of frame parameters if they were specified.
2856 See `special-display-buffer-names', and `special-display-regexps'. */)
2858 Lisp_Object buffer_name
;
2862 CHECK_STRING (buffer_name
);
2864 tem
= Fmember (buffer_name
, Vspecial_display_buffer_names
);
2868 tem
= Fassoc (buffer_name
, Vspecial_display_buffer_names
);
2872 for (tem
= Vspecial_display_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2874 Lisp_Object car
= XCAR (tem
);
2876 && fast_string_match (car
, buffer_name
) >= 0)
2878 else if (CONSP (car
)
2879 && STRINGP (XCAR (car
))
2880 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2886 DEFUN ("same-window-p", Fsame_window_p
, Ssame_window_p
, 1, 1, 0,
2887 doc
: /* Returns non-nil if a new buffer named BUFFER-NAME would use the same window.
2888 See `same-window-buffer-names' and `same-window-regexps'. */)
2890 Lisp_Object buffer_name
;
2894 CHECK_STRING (buffer_name
);
2896 tem
= Fmember (buffer_name
, Vsame_window_buffer_names
);
2900 tem
= Fassoc (buffer_name
, Vsame_window_buffer_names
);
2904 for (tem
= Vsame_window_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2906 Lisp_Object car
= XCAR (tem
);
2908 && fast_string_match (car
, buffer_name
) >= 0)
2910 else if (CONSP (car
)
2911 && STRINGP (XCAR (car
))
2912 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2918 /* Use B so the default is (other-buffer). */
2919 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 3,
2920 "BDisplay buffer: \nP",
2921 doc
: /* Make BUFFER appear in some window but don't select it.
2922 BUFFER can be a buffer or a buffer name.
2923 If BUFFER is shown already in some window, just use that one,
2924 unless the window is the selected window and the optional second
2925 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).
2926 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.
2927 Returns the window displaying BUFFER.
2928 If `display-buffer-reuse-frames' is non-nil, and another frame is currently
2929 displaying BUFFER, then simply raise that frame.
2931 The variables `special-display-buffer-names', `special-display-regexps',
2932 `same-window-buffer-names', and `same-window-regexps' customize how certain
2933 buffer names are handled.
2935 If optional argument FRAME is `visible', search all visible frames.
2936 If FRAME is 0, search all visible and iconified frames.
2937 If FRAME is t, search all frames.
2938 If FRAME is a frame, search only that frame.
2939 If FRAME is nil, search only the selected frame
2940 (actually the last nonminibuffer frame),
2941 unless `pop-up-frames' or `display-buffer-reuse-frames' is non-nil,
2942 which means search visible and iconified frames.
2944 If `even-window-heights' is non-nil, window heights will be evened out
2945 if displaying the buffer causes two vertically adjacent windows to be
2947 (buffer
, not_this_window
, frame
)
2948 register Lisp_Object buffer
, not_this_window
, frame
;
2950 register Lisp_Object window
, tem
, swp
;
2954 buffer
= Fget_buffer (buffer
);
2955 CHECK_BUFFER (buffer
);
2957 if (!NILP (Vdisplay_buffer_function
))
2958 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
2960 if (NILP (not_this_window
)
2961 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
2962 return display_buffer_1 (selected_window
);
2964 /* See if the user has specified this buffer should appear
2965 in the selected window. */
2966 if (NILP (not_this_window
))
2968 swp
= Fsame_window_p (XBUFFER (buffer
)->name
);
2969 if (!NILP (swp
) && !no_switch_window (selected_window
))
2971 Fswitch_to_buffer (buffer
, Qnil
);
2972 return display_buffer_1 (selected_window
);
2976 /* If the user wants pop-up-frames or display-buffer-reuse-frames,
2977 look for a window showing BUFFER on any visible or iconified frame.
2978 Otherwise search only the current frame. */
2981 else if (pop_up_frames
2982 || display_buffer_reuse_frames
2983 || last_nonminibuf_frame
== 0)
2984 XSETFASTINT (tem
, 0);
2986 XSETFRAME (tem
, last_nonminibuf_frame
);
2988 window
= Fget_buffer_window (buffer
, tem
);
2990 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
2991 return display_buffer_1 (window
);
2993 /* Certain buffer names get special handling. */
2994 if (!NILP (Vspecial_display_function
) && NILP (swp
))
2996 tem
= Fspecial_display_p (XBUFFER (buffer
)->name
);
2998 return call1 (Vspecial_display_function
, buffer
);
3000 return call2 (Vspecial_display_function
, buffer
, tem
);
3003 /* If there are no frames open that have more than a minibuffer,
3004 we need to create a new frame. */
3005 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
3007 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
3008 Fset_window_buffer (window
, buffer
);
3009 return display_buffer_1 (window
);
3012 f
= SELECTED_FRAME ();
3014 || FRAME_MINIBUF_ONLY_P (f
)
3015 /* If the current frame is a special display frame,
3016 don't try to reuse its windows. */
3017 || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f
))->dedicated
))
3022 if (FRAME_MINIBUF_ONLY_P (f
))
3023 XSETFRAME (frames
, last_nonminibuf_frame
);
3024 /* Don't try to create a window if would get an error */
3025 if (split_height_threshold
< window_min_height
<< 1)
3026 split_height_threshold
= window_min_height
<< 1;
3028 /* Note that both Fget_largest_window and Fget_lru_window
3029 ignore minibuffers and dedicated windows.
3030 This means they can return nil. */
3032 /* If the frame we would try to split cannot be split,
3033 try other frames. */
3034 if (FRAME_NO_SPLIT_P (NILP (frames
) ? f
: last_nonminibuf_frame
))
3036 /* Try visible frames first. */
3037 window
= Fget_largest_window (Qvisible
);
3038 /* If that didn't work, try iconified frames. */
3040 window
= Fget_largest_window (make_number (0));
3042 window
= Fget_largest_window (Qt
);
3045 window
= Fget_largest_window (frames
);
3047 /* If we got a tall enough full-width window that can be split,
3050 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
3051 && window_height (window
) >= split_height_threshold
3052 && WINDOW_FULL_WIDTH_P (XWINDOW (window
)))
3053 window
= Fsplit_window (window
, Qnil
, Qnil
);
3056 Lisp_Object upper
, lower
, other
;
3058 window
= Fget_lru_window (frames
);
3059 /* If the LRU window is selected, and big enough,
3060 and can be split, split it. */
3062 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
3063 && (EQ (window
, selected_window
)
3064 || EQ (XWINDOW (window
)->parent
, Qnil
))
3065 && window_height (window
) >= window_min_height
<< 1)
3066 window
= Fsplit_window (window
, Qnil
, Qnil
);
3067 /* If Fget_lru_window returned nil, try other approaches. */
3069 /* Try visible frames first. */
3071 window
= Fget_buffer_window (buffer
, Qvisible
);
3073 window
= Fget_largest_window (Qvisible
);
3074 /* If that didn't work, try iconified frames. */
3076 window
= Fget_buffer_window (buffer
, make_number (0));
3078 window
= Fget_largest_window (make_number (0));
3079 /* Try invisible frames. */
3081 window
= Fget_buffer_window (buffer
, Qt
);
3083 window
= Fget_largest_window (Qt
);
3084 /* As a last resort, make a new frame. */
3086 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
3087 /* If window appears above or below another,
3088 even out their heights. */
3089 other
= upper
= lower
= Qnil
;
3090 if (!NILP (XWINDOW (window
)->prev
))
3091 other
= upper
= XWINDOW (window
)->prev
, lower
= window
;
3092 if (!NILP (XWINDOW (window
)->next
))
3093 other
= lower
= XWINDOW (window
)->next
, upper
= window
;
3095 && !NILP (Veven_window_heights
)
3096 /* Check that OTHER and WINDOW are vertically arrayed. */
3097 && !EQ (XWINDOW (other
)->top
, XWINDOW (window
)->top
)
3098 && (XFASTINT (XWINDOW (other
)->height
)
3099 > XFASTINT (XWINDOW (window
)->height
)))
3101 int total
= (XFASTINT (XWINDOW (other
)->height
)
3102 + XFASTINT (XWINDOW (window
)->height
));
3103 enlarge_window (upper
,
3104 total
/ 2 - XFASTINT (XWINDOW (upper
)->height
),
3110 window
= Fget_lru_window (Qnil
);
3112 Fset_window_buffer (window
, buffer
);
3113 return display_buffer_1 (window
);
3117 temp_output_buffer_show (buf
)
3118 register Lisp_Object buf
;
3120 register struct buffer
*old
= current_buffer
;
3121 register Lisp_Object window
;
3122 register struct window
*w
;
3124 XBUFFER (buf
)->directory
= current_buffer
->directory
;
3127 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
3131 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
3132 set_buffer_internal (old
);
3134 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
3135 call1 (Vtemp_buffer_show_function
, buf
);
3138 window
= Fdisplay_buffer (buf
, Qnil
, Qnil
);
3140 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
3141 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
3142 Vminibuf_scroll_window
= window
;
3143 w
= XWINDOW (window
);
3144 XSETFASTINT (w
->hscroll
, 0);
3145 XSETFASTINT (w
->min_hscroll
, 0);
3146 set_marker_restricted_both (w
->start
, buf
, 1, 1);
3147 set_marker_restricted_both (w
->pointm
, buf
, 1, 1);
3149 /* Run temp-buffer-show-hook, with the chosen window selected
3150 and it sbuffer current. */
3151 if (!NILP (Vrun_hooks
))
3154 tem
= Fboundp (Qtemp_buffer_show_hook
);
3157 tem
= Fsymbol_value (Qtemp_buffer_show_hook
);
3160 int count
= specpdl_ptr
- specpdl
;
3161 Lisp_Object prev_window
;
3162 prev_window
= selected_window
;
3164 /* Select the window that was chosen, for running the hook. */
3165 record_unwind_protect (Fselect_window
, prev_window
);
3166 select_window_1 (window
, 0);
3167 Fset_buffer (w
->buffer
);
3168 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
3169 select_window_1 (prev_window
, 0);
3170 unbind_to (count
, Qnil
);
3178 make_dummy_parent (window
)
3182 register struct window
*o
, *p
;
3185 o
= XWINDOW (window
);
3186 p
= allocate_window ();
3187 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
3188 ((struct Lisp_Vector
*) p
)->contents
[i
]
3189 = ((struct Lisp_Vector
*)o
)->contents
[i
];
3190 XSETWINDOW (new, p
);
3192 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
3194 /* Put new into window structure in place of window */
3195 replace_window (window
, new);
3208 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
3209 doc
: /* Split WINDOW, putting SIZE lines in the first of the pair.
3210 WINDOW defaults to selected one and SIZE to half its size.
3211 If optional third arg HORFLAG is non-nil, split side by side
3212 and put SIZE columns in the first of the pair. In that case,
3213 SIZE includes that window's scroll bar, or the divider column to its right. */)
3214 (window
, size
, horflag
)
3215 Lisp_Object window
, size
, horflag
;
3217 register Lisp_Object
new;
3218 register struct window
*o
, *p
;
3220 register int size_int
;
3223 window
= selected_window
;
3225 CHECK_LIVE_WINDOW (window
);
3227 o
= XWINDOW (window
);
3228 fo
= XFRAME (WINDOW_FRAME (o
));
3232 if (!NILP (horflag
))
3233 /* Calculate the size of the left-hand window, by dividing
3234 the usable space in columns by two.
3235 We round up, since the left-hand window may include
3236 a dividing line, while the right-hand may not. */
3237 size_int
= (XFASTINT (o
->width
) + 1) >> 1;
3239 size_int
= XFASTINT (o
->height
) >> 1;
3243 CHECK_NUMBER (size
);
3244 size_int
= XINT (size
);
3247 if (MINI_WINDOW_P (o
))
3248 error ("Attempt to split minibuffer window");
3249 else if (window_fixed_size_p (o
, !NILP (horflag
), 0))
3250 error ("Attempt to split fixed-size window");
3252 check_min_window_sizes ();
3256 if (size_int
< window_min_height
)
3257 error ("Window height %d too small (after splitting)", size_int
);
3258 if (size_int
+ window_min_height
> XFASTINT (o
->height
))
3259 error ("Window height %d too small (after splitting)",
3260 XFASTINT (o
->height
) - size_int
);
3261 if (NILP (o
->parent
)
3262 || NILP (XWINDOW (o
->parent
)->vchild
))
3264 make_dummy_parent (window
);
3266 XWINDOW (new)->vchild
= window
;
3271 if (size_int
< window_min_width
)
3272 error ("Window width %d too small (after splitting)", size_int
);
3274 if (size_int
+ window_min_width
> XFASTINT (o
->width
))
3275 error ("Window width %d too small (after splitting)",
3276 XFASTINT (o
->width
) - size_int
);
3277 if (NILP (o
->parent
)
3278 || NILP (XWINDOW (o
->parent
)->hchild
))
3280 make_dummy_parent (window
);
3282 XWINDOW (new)->hchild
= window
;
3286 /* Now we know that window's parent is a vertical combination
3287 if we are dividing vertically, or a horizontal combination
3288 if we are making side-by-side windows */
3290 windows_or_buffers_changed
++;
3291 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
3292 new = make_window ();
3295 p
->frame
= o
->frame
;
3297 if (!NILP (p
->next
))
3298 XWINDOW (p
->next
)->prev
= new;
3301 p
->parent
= o
->parent
;
3303 p
->window_end_valid
= Qnil
;
3304 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
3306 /* Apportion the available frame space among the two new windows */
3308 if (!NILP (horflag
))
3310 p
->height
= o
->height
;
3312 XSETFASTINT (p
->width
, XFASTINT (o
->width
) - size_int
);
3313 XSETFASTINT (o
->width
, size_int
);
3314 XSETFASTINT (p
->left
, XFASTINT (o
->left
) + size_int
);
3319 p
->width
= o
->width
;
3320 XSETFASTINT (p
->height
, XFASTINT (o
->height
) - size_int
);
3321 XSETFASTINT (o
->height
, size_int
);
3322 XSETFASTINT (p
->top
, XFASTINT (o
->top
) + size_int
);
3325 /* Adjust glyph matrices. */
3327 Fset_window_buffer (new, o
->buffer
);
3331 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 3, "p",
3332 doc
: /* Make current window ARG lines bigger.
3333 From program, optional second arg non-nil means grow sideways ARG columns.
3334 Interactively, if an argument is not given, make the window one line bigger.
3336 Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size
3337 of the siblings above or to the left of the selected window. Only
3338 siblings to the right or below are changed. */)
3339 (arg
, side
, preserve_before
)
3340 register Lisp_Object arg
, side
, preserve_before
;
3343 enlarge_window (selected_window
, XINT (arg
), !NILP (side
),
3344 !NILP (preserve_before
));
3346 if (! NILP (Vwindow_configuration_change_hook
))
3347 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3352 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
3353 doc
: /* Make current window ARG lines smaller.
3354 From program, optional second arg non-nil means shrink sideways arg columns.
3355 Interactively, if an argument is not given, make the window one line smaller. */)
3357 register Lisp_Object arg
, side
;
3360 enlarge_window (selected_window
, -XINT (arg
), !NILP (side
), 0);
3362 if (! NILP (Vwindow_configuration_change_hook
))
3363 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3369 window_height (window
)
3372 register struct window
*p
= XWINDOW (window
);
3373 return XFASTINT (p
->height
);
3377 window_width (window
)
3380 register struct window
*p
= XWINDOW (window
);
3381 return XFASTINT (p
->width
);
3386 *(widthflag ? &(XWINDOW (w)->left) : &(XWINDOW (w)->top))
3388 #define CURSIZE(w) \
3389 *(widthflag ? &(XWINDOW (w)->width) : &(XWINDOW (w)->height))
3392 /* Enlarge WINDOW by DELTA. WIDTHFLAG non-zero means
3393 increase its width. Siblings of the selected window are resized to
3394 fulfill the size request. If they become too small in the process,
3395 they will be deleted.
3397 If PRESERVE_BEFORE is nonzero, that means don't alter
3398 the siblings to the left or above WINDOW. */
3401 enlarge_window (window
, delta
, widthflag
, preserve_before
)
3403 int delta
, widthflag
, preserve_before
;
3405 Lisp_Object parent
, next
, prev
;
3409 int (*sizefun
) P_ ((Lisp_Object
))
3410 = widthflag
? window_width
: window_height
;
3411 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
3412 = (widthflag
? set_window_width
: set_window_height
);
3414 /* Check values of window_min_width and window_min_height for
3416 check_min_window_sizes ();
3418 /* Give up if this window cannot be resized. */
3419 if (window_fixed_size_p (XWINDOW (window
), widthflag
, 1))
3420 error ("Window is not resizable");
3422 /* Find the parent of the selected window. */
3425 p
= XWINDOW (window
);
3431 error ("No other window to side of this one");
3436 ? !NILP (XWINDOW (parent
)->hchild
)
3437 : !NILP (XWINDOW (parent
)->vchild
))
3443 sizep
= &CURSIZE (window
);
3446 register int maxdelta
;
3448 /* Compute the maximum size increment this window can have. */
3450 if (preserve_before
)
3454 maxdelta
= (*sizefun
) (parent
) - XINT (*sizep
);
3455 /* Subtract size of siblings before, since we can't take that. */
3456 maxdelta
-= XINT (CURBEG (window
)) - XINT (CURBEG (parent
));
3459 maxdelta
= (!NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3460 - window_min_size (XWINDOW (p
->next
),
3465 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - XINT (*sizep
)
3466 /* This is a main window followed by a minibuffer. */
3467 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3468 - window_min_size (XWINDOW (p
->next
),
3470 /* This is a minibuffer following a main window. */
3471 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
3472 - window_min_size (XWINDOW (p
->prev
),
3474 /* This is a frame with only one window, a minibuffer-only
3475 or a minibufferless frame. */
3478 if (delta
> maxdelta
)
3479 /* This case traps trying to make the minibuffer
3480 the full frame, or make the only window aside from the
3481 minibuffer the full frame. */
3485 if (XINT (*sizep
) + delta
< window_min_size (XWINDOW (window
), widthflag
, 0, 0))
3487 delete_window (window
);
3494 /* Find the total we can get from other siblings without deleting them. */
3496 for (next
= p
->next
; ! NILP (next
); next
= XWINDOW (next
)->next
)
3497 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
3499 if (! preserve_before
)
3500 for (prev
= p
->prev
; ! NILP (prev
); prev
= XWINDOW (prev
)->prev
)
3501 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
3504 /* If we can get it all from them without deleting them, do so. */
3505 if (delta
<= maximum
)
3507 Lisp_Object first_unaffected
;
3508 Lisp_Object first_affected
;
3513 first_affected
= window
;
3514 /* Look at one sibling at a time,
3515 moving away from this window in both directions alternately,
3516 and take as much as we can get without deleting that sibling. */
3518 && (!NILP (next
) || (!preserve_before
&& !NILP (prev
))))
3522 int this_one
= ((*sizefun
) (next
)
3523 - window_min_size (XWINDOW (next
),
3524 widthflag
, 0, &fixed_p
));
3527 if (this_one
> delta
)
3530 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
3531 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3536 next
= XWINDOW (next
)->next
;
3542 if (!preserve_before
&& ! NILP (prev
))
3544 int this_one
= ((*sizefun
) (prev
)
3545 - window_min_size (XWINDOW (prev
),
3546 widthflag
, 0, &fixed_p
));
3549 if (this_one
> delta
)
3552 first_affected
= prev
;
3554 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
3555 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3560 prev
= XWINDOW (prev
)->prev
;
3564 xassert (delta
== 0);
3566 /* Now recalculate the edge positions of all the windows affected,
3567 based on the new sizes. */
3568 first_unaffected
= next
;
3569 prev
= first_affected
;
3570 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
3571 prev
= next
, next
= XWINDOW (next
)->next
)
3573 XSETINT (CURBEG (next
), XINT (CURBEG (prev
)) + (*sizefun
) (prev
));
3574 /* This does not change size of NEXT,
3575 but it propagates the new top edge to its children */
3576 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
3581 register int delta1
;
3582 register int opht
= (*sizefun
) (parent
);
3584 if (opht
<= XINT (*sizep
) + delta
)
3586 /* If trying to grow this window to or beyond size of the parent,
3587 just delete all the sibling windows. */
3588 Lisp_Object start
, tem
, next
;
3590 start
= XWINDOW (parent
)->vchild
;
3592 start
= XWINDOW (parent
)->hchild
;
3594 /* Delete any siblings that come after WINDOW. */
3595 tem
= XWINDOW (window
)->next
;
3596 while (! NILP (tem
))
3598 next
= XWINDOW (tem
)->next
;
3599 delete_window (tem
);
3603 /* Delete any siblings that come after WINDOW.
3604 Note that if START is not WINDOW, then WINDOW still
3605 Fhas siblings, so WINDOW has not yet replaced its parent. */
3607 while (! EQ (tem
, window
))
3609 next
= XWINDOW (tem
)->next
;
3610 delete_window (tem
);
3616 /* Otherwise, make delta1 just right so that if we add
3617 delta1 lines to this window and to the parent, and then
3618 shrink the parent back to its original size, the new
3619 proportional size of this window will increase by delta.
3621 The function size_window will compute the new height h'
3622 of the window from delta1 as:
3625 x = delta1 - delta1/n * n for the 1st resizable child
3628 where n is the number of children that can be resized.
3629 We can ignore x by choosing a delta1 that is a multiple of
3630 n. We want the height of this window to come out as
3640 The number of children n rquals the number of resizable
3641 children of this window + 1 because we know window itself
3642 is resizable (otherwise we would have signalled an error. */
3644 struct window
*w
= XWINDOW (window
);
3648 for (s
= w
->next
; !NILP (s
); s
= XWINDOW (s
)->next
)
3649 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3651 for (s
= w
->prev
; !NILP (s
); s
= XWINDOW (s
)->prev
)
3652 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3657 /* Add delta1 lines or columns to this window, and to the parent,
3658 keeping things consistent while not affecting siblings. */
3659 XSETINT (CURSIZE (parent
), opht
+ delta1
);
3660 (*setsizefun
) (window
, XINT (*sizep
) + delta1
, 0);
3662 /* Squeeze out delta1 lines or columns from our parent,
3663 shriking this window and siblings proportionately.
3664 This brings parent back to correct size.
3665 Delta1 was calculated so this makes this window the desired size,
3666 taking it all out of the siblings. */
3667 (*setsizefun
) (parent
, opht
, 0);
3672 XSETFASTINT (p
->last_modified
, 0);
3673 XSETFASTINT (p
->last_overlay_modified
, 0);
3675 /* Adjust glyph matrices. */
3676 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
3684 /***********************************************************************
3685 Resizing Mini-Windows
3686 ***********************************************************************/
3688 static void shrink_window_lowest_first
P_ ((struct window
*, int));
3690 enum save_restore_action
3697 static int save_restore_orig_size
P_ ((struct window
*,
3698 enum save_restore_action
));
3700 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
3701 from lowest windows first. */
3704 shrink_window_lowest_first (w
, height
)
3712 xassert (!MINI_WINDOW_P (w
));
3714 /* Set redisplay hints. */
3715 XSETFASTINT (w
->last_modified
, 0);
3716 XSETFASTINT (w
->last_overlay_modified
, 0);
3717 windows_or_buffers_changed
++;
3718 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
3720 old_height
= XFASTINT (w
->height
);
3721 XSETFASTINT (w
->height
, height
);
3723 if (!NILP (w
->hchild
))
3725 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
3727 c
= XWINDOW (child
);
3729 shrink_window_lowest_first (c
, height
);
3732 else if (!NILP (w
->vchild
))
3734 Lisp_Object last_child
;
3735 int delta
= old_height
- height
;
3740 /* Find the last child. We are taking space from lowest windows
3741 first, so we iterate over children from the last child
3743 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
3746 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
3747 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
3751 c
= XWINDOW (child
);
3752 this_one
= XFASTINT (c
->height
) - MIN_SAFE_WINDOW_HEIGHT
;
3754 if (this_one
> delta
)
3757 shrink_window_lowest_first (c
, XFASTINT (c
->height
) - this_one
);
3761 /* Compute new positions. */
3762 last_top
= XINT (w
->top
);
3763 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
3765 c
= XWINDOW (child
);
3766 c
->top
= make_number (last_top
);
3767 shrink_window_lowest_first (c
, XFASTINT (c
->height
));
3768 last_top
+= XFASTINT (c
->height
);
3774 /* Save, restore, or check positions and sizes in the window tree
3775 rooted at W. ACTION says what to do.
3777 If ACTION is CHECK_ORIG_SIZES, check if orig_top and orig_height
3778 members are valid for all windows in the window tree. Value is
3779 non-zero if they are valid.
3781 If ACTION is SAVE_ORIG_SIZES, save members top and height in
3782 orig_top and orig_height for all windows in the tree.
3784 If ACTION is RESTORE_ORIG_SIZES, restore top and height from
3785 values stored in orig_top and orig_height for all windows. */
3788 save_restore_orig_size (w
, action
)
3790 enum save_restore_action action
;
3796 if (!NILP (w
->hchild
))
3798 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
3801 else if (!NILP (w
->vchild
))
3803 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
3809 case CHECK_ORIG_SIZES
:
3810 if (!INTEGERP (w
->orig_top
) || !INTEGERP (w
->orig_height
))
3814 case SAVE_ORIG_SIZES
:
3815 w
->orig_top
= w
->top
;
3816 w
->orig_height
= w
->height
;
3817 XSETFASTINT (w
->last_modified
, 0);
3818 XSETFASTINT (w
->last_overlay_modified
, 0);
3821 case RESTORE_ORIG_SIZES
:
3822 xassert (INTEGERP (w
->orig_top
) && INTEGERP (w
->orig_height
));
3823 w
->top
= w
->orig_top
;
3824 w
->height
= w
->orig_height
;
3825 w
->orig_height
= w
->orig_top
= Qnil
;
3826 XSETFASTINT (w
->last_modified
, 0);
3827 XSETFASTINT (w
->last_overlay_modified
, 0);
3834 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
3841 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
3842 without deleting other windows. */
3845 grow_mini_window (w
, delta
)
3849 struct frame
*f
= XFRAME (w
->frame
);
3850 struct window
*root
;
3852 xassert (MINI_WINDOW_P (w
));
3853 xassert (delta
>= 0);
3855 /* Check values of window_min_width and window_min_height for
3857 check_min_window_sizes ();
3859 /* Compute how much we can enlarge the mini-window without deleting
3861 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3864 int min_height
= window_min_size (root
, 0, 0, 0);
3865 if (XFASTINT (root
->height
) - delta
< min_height
)
3866 /* Note that the root window may already be smaller than
3868 delta
= max (0, XFASTINT (root
->height
) - min_height
);
3873 /* Save original window sizes and positions, if not already done. */
3874 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3875 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
3877 /* Shrink other windows. */
3878 shrink_window_lowest_first (root
, XFASTINT (root
->height
) - delta
);
3880 /* Grow the mini-window. */
3881 w
->top
= make_number (XFASTINT (root
->top
) + XFASTINT (root
->height
));
3882 w
->height
= make_number (XFASTINT (w
->height
) + delta
);
3883 XSETFASTINT (w
->last_modified
, 0);
3884 XSETFASTINT (w
->last_overlay_modified
, 0);
3891 /* Shrink mini-window W. If there is recorded info about window sizes
3892 before a call to grow_mini_window, restore recorded window sizes.
3893 Otherwise, if the mini-window is higher than 1 line, resize it to 1
3897 shrink_mini_window (w
)
3900 struct frame
*f
= XFRAME (w
->frame
);
3901 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3903 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3905 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
3907 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
3908 windows_or_buffers_changed
= 1;
3910 else if (XFASTINT (w
->height
) > 1)
3912 /* Distribute the additional lines of the mini-window
3913 among the other windows. */
3915 XSETWINDOW (window
, w
);
3916 enlarge_window (window
, 1 - XFASTINT (w
->height
), 0, 0);
3922 /* Mark window cursors off for all windows in the window tree rooted
3923 at W by setting their phys_cursor_on_p flag to zero. Called from
3924 xterm.c, e.g. when a frame is cleared and thereby all cursors on
3925 the frame are cleared. */
3928 mark_window_cursors_off (w
)
3933 if (!NILP (w
->hchild
))
3934 mark_window_cursors_off (XWINDOW (w
->hchild
));
3935 else if (!NILP (w
->vchild
))
3936 mark_window_cursors_off (XWINDOW (w
->vchild
));
3938 w
->phys_cursor_on_p
= 0;
3940 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
3945 /* Return number of lines of text (not counting mode lines) in W. */
3948 window_internal_height (w
)
3951 int ht
= XFASTINT (w
->height
);
3953 if (!MINI_WINDOW_P (w
))
3955 if (!NILP (w
->parent
)
3956 || !NILP (w
->vchild
)
3957 || !NILP (w
->hchild
)
3960 || WINDOW_WANTS_MODELINE_P (w
))
3963 if (WINDOW_WANTS_HEADER_LINE_P (w
))
3971 /* Return the number of columns in W.
3972 Don't count columns occupied by scroll bars or the vertical bar
3973 separating W from the sibling to its right. */
3976 window_internal_width (w
)
3979 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
3980 int width
= XINT (w
->width
);
3982 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
3983 /* Scroll bars occupy a few columns. */
3984 width
-= FRAME_SCROLL_BAR_COLS (f
);
3985 else if (!WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
3986 /* The column of `|' characters separating side-by-side windows
3987 occupies one column only. */
3990 /* On window-systems, areas to the left and right of the window
3991 are used as fringes. */
3992 if (FRAME_WINDOW_P (f
))
3993 width
-= FRAME_FRINGE_COLS (f
);
3999 /************************************************************************
4001 ***********************************************************************/
4003 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
4004 N screen-fulls, which is defined as the height of the window minus
4005 next_screen_context_lines. If WHOLE is zero, scroll up N lines
4006 instead. Negative values of N mean scroll down. NOERROR non-zero
4007 means don't signal an error if we try to move over BEGV or ZV,
4011 window_scroll (window
, n
, whole
, noerror
)
4017 /* If we must, use the pixel-based version which is much slower than
4018 the line-based one but can handle varying line heights. */
4019 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
4020 window_scroll_pixel_based (window
, n
, whole
, noerror
);
4022 window_scroll_line_based (window
, n
, whole
, noerror
);
4026 /* Implementation of window_scroll that works based on pixel line
4027 heights. See the comment of window_scroll for parameter
4031 window_scroll_pixel_based (window
, n
, whole
, noerror
)
4038 struct window
*w
= XWINDOW (window
);
4039 struct text_pos start
;
4041 int this_scroll_margin
;
4043 /* True if we fiddled the window vscroll field without really scrolling. */
4046 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4048 /* If PT is not visible in WINDOW, move back one half of
4049 the screen. Allow PT to be partially visible, otherwise
4050 something like (scroll-down 1) with PT in the line before
4051 the partially visible one would recenter. */
4052 tem
= Fpos_visible_in_window_p (make_number (PT
), window
, Qt
);
4055 /* Move backward half the height of the window. Performance note:
4056 vmotion used here is about 10% faster, but would give wrong
4057 results for variable height lines. */
4058 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4059 it
.current_y
= it
.last_visible_y
;
4060 move_it_vertically (&it
, - window_box_height (w
) / 2);
4062 /* The function move_iterator_vertically may move over more than
4063 the specified y-distance. If it->w is small, e.g. a
4064 mini-buffer window, we may end up in front of the window's
4065 display area. This is the case when Start displaying at the
4066 start of the line containing PT in this case. */
4067 if (it
.current_y
<= 0)
4069 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4070 move_it_vertically (&it
, 0);
4074 start
= it
.current
.pos
;
4077 /* If scroll_preserve_screen_position is non-zero, we try to set
4078 point in the same window line as it is now, so get that line. */
4079 if (!NILP (Vscroll_preserve_screen_position
))
4081 start_display (&it
, w
, start
);
4082 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
4083 preserve_y
= it
.current_y
;
4088 /* Move iterator it from start the specified distance forward or
4089 backward. The result is the new window start. */
4090 start_display (&it
, w
, start
);
4093 int screen_full
= (window_box_height (w
)
4094 - next_screen_context_lines
* CANON_Y_UNIT (it
.f
));
4095 int dy
= n
* screen_full
;
4097 /* Note that move_it_vertically always moves the iterator to the
4098 start of a line. So, if the last line doesn't have a newline,
4099 we would end up at the start of the line ending at ZV. */
4101 move_it_vertically_backward (&it
, -dy
);
4103 move_it_to (&it
, ZV
, -1, it
.current_y
+ dy
, -1,
4104 MOVE_TO_POS
| MOVE_TO_Y
);
4107 move_it_by_lines (&it
, n
, 1);
4109 /* End if we end up at ZV or BEGV. */
4110 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
4111 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
4113 if (IT_CHARPOS (it
) == ZV
)
4115 if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
4116 > it
.last_visible_y
)
4118 /* The last line was only partially visible, make it fully
4120 w
->vscroll
= (it
.last_visible_y
4121 - it
.current_y
+ it
.max_ascent
+ it
.max_descent
);
4122 adjust_glyphs (it
.f
);
4127 Fsignal (Qend_of_buffer
, Qnil
);
4131 if (w
->vscroll
!= 0)
4132 /* The first line was only partially visible, make it fully
4138 Fsignal (Qbeginning_of_buffer
, Qnil
);
4141 /* If control gets here, then we vscrolled. */
4143 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
4145 /* Don't try to change the window start below. */
4151 /* Set the window start, and set up the window for redisplay. */
4152 set_marker_restricted (w
->start
, make_number (IT_CHARPOS (it
)),
4154 w
->start_at_line_beg
= Fbolp ();
4155 w
->update_mode_line
= Qt
;
4156 XSETFASTINT (w
->last_modified
, 0);
4157 XSETFASTINT (w
->last_overlay_modified
, 0);
4158 /* Set force_start so that redisplay_window will run the
4159 window-scroll-functions. */
4160 w
->force_start
= Qt
;
4163 it
.current_y
= it
.vpos
= 0;
4165 /* Preserve the screen position if we must. */
4166 if (preserve_y
>= 0)
4168 move_it_to (&it
, -1, -1, preserve_y
, -1, MOVE_TO_Y
);
4169 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4173 /* Move PT out of scroll margins. */
4174 this_scroll_margin
= max (0, scroll_margin
);
4175 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->height
) / 4);
4176 this_scroll_margin
*= CANON_Y_UNIT (it
.f
);
4180 /* We moved the window start towards ZV, so PT may be now
4181 in the scroll margin at the top. */
4182 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
4183 while (it
.current_y
< this_scroll_margin
)
4185 int prev
= it
.current_y
;
4186 move_it_by_lines (&it
, 1, 1);
4187 if (prev
== it
.current_y
)
4190 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4194 int charpos
, bytepos
;
4196 /* We moved the window start towards BEGV, so PT may be now
4197 in the scroll margin at the bottom. */
4198 move_it_to (&it
, PT
, -1,
4199 it
.last_visible_y
- this_scroll_margin
- 1, -1,
4200 MOVE_TO_POS
| MOVE_TO_Y
);
4202 /* Save our position, in case it's correct. */
4203 charpos
= IT_CHARPOS (it
);
4204 bytepos
= IT_BYTEPOS (it
);
4206 /* See if point is on a partially visible line at the end. */
4207 move_it_by_lines (&it
, 1, 1);
4208 if (it
.current_y
> it
.last_visible_y
)
4209 /* The last line was only partially visible, so back up two
4210 lines to make sure we're on a fully visible line. */
4212 move_it_by_lines (&it
, -2, 0);
4213 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4216 /* No, the position we saved is OK, so use it. */
4217 SET_PT_BOTH (charpos
, bytepos
);
4223 /* Implementation of window_scroll that works based on screen lines.
4224 See the comment of window_scroll for parameter descriptions. */
4227 window_scroll_line_based (window
, n
, whole
, noerror
)
4233 register struct window
*w
= XWINDOW (window
);
4234 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
4235 register int pos
, pos_byte
;
4236 register int ht
= window_internal_height (w
);
4237 register Lisp_Object tem
;
4241 struct position posit
;
4244 /* If scrolling screen-fulls, compute the number of lines to
4245 scroll from the window's height. */
4247 n
*= max (1, ht
- next_screen_context_lines
);
4249 startpos
= marker_position (w
->start
);
4251 posit
= *compute_motion (startpos
, 0, 0, 0,
4253 window_internal_width (w
), XINT (w
->hscroll
),
4255 original_vpos
= posit
.vpos
;
4257 XSETFASTINT (tem
, PT
);
4258 tem
= Fpos_visible_in_window_p (tem
, window
, Qnil
);
4262 Fvertical_motion (make_number (- (ht
/ 2)), window
);
4267 lose
= n
< 0 && PT
== BEGV
;
4268 Fvertical_motion (make_number (n
), window
);
4272 SET_PT_BOTH (opoint
, opoint_byte
);
4279 Fsignal (Qbeginning_of_buffer
, Qnil
);
4284 int this_scroll_margin
= scroll_margin
;
4286 /* Don't use a scroll margin that is negative or too large. */
4287 if (this_scroll_margin
< 0)
4288 this_scroll_margin
= 0;
4290 if (XINT (w
->height
) < 4 * scroll_margin
)
4291 this_scroll_margin
= XINT (w
->height
) / 4;
4293 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
4294 w
->start_at_line_beg
= bolp
;
4295 w
->update_mode_line
= Qt
;
4296 XSETFASTINT (w
->last_modified
, 0);
4297 XSETFASTINT (w
->last_overlay_modified
, 0);
4298 /* Set force_start so that redisplay_window will run
4299 the window-scroll-functions. */
4300 w
->force_start
= Qt
;
4302 if (whole
&& !NILP (Vscroll_preserve_screen_position
))
4304 SET_PT_BOTH (pos
, pos_byte
);
4305 Fvertical_motion (make_number (original_vpos
), window
);
4307 /* If we scrolled forward, put point enough lines down
4308 that it is outside the scroll margin. */
4313 if (this_scroll_margin
> 0)
4315 SET_PT_BOTH (pos
, pos_byte
);
4316 Fvertical_motion (make_number (this_scroll_margin
), window
);
4322 if (top_margin
<= opoint
)
4323 SET_PT_BOTH (opoint
, opoint_byte
);
4324 else if (!NILP (Vscroll_preserve_screen_position
))
4326 SET_PT_BOTH (pos
, pos_byte
);
4327 Fvertical_motion (make_number (original_vpos
), window
);
4330 SET_PT (top_margin
);
4336 /* If we scrolled backward, put point near the end of the window
4337 but not within the scroll margin. */
4338 SET_PT_BOTH (pos
, pos_byte
);
4339 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
4340 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
4343 bottom_margin
= PT
+ 1;
4345 if (bottom_margin
> opoint
)
4346 SET_PT_BOTH (opoint
, opoint_byte
);
4349 if (!NILP (Vscroll_preserve_screen_position
))
4351 SET_PT_BOTH (pos
, pos_byte
);
4352 Fvertical_motion (make_number (original_vpos
), window
);
4355 Fvertical_motion (make_number (-1), window
);
4364 Fsignal (Qend_of_buffer
, Qnil
);
4369 /* Scroll selected_window up or down. If N is nil, scroll a
4370 screen-full which is defined as the height of the window minus
4371 next_screen_context_lines. If N is the symbol `-', scroll.
4372 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
4373 up. This is the guts of Fscroll_up and Fscroll_down. */
4376 scroll_command (n
, direction
)
4380 int count
= BINDING_STACK_SIZE ();
4382 xassert (abs (direction
) == 1);
4384 /* If selected window's buffer isn't current, make it current for
4385 the moment. But don't screw up if window_scroll gets an error. */
4386 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
4388 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4389 Fset_buffer (XWINDOW (selected_window
)->buffer
);
4391 /* Make redisplay consider other windows than just selected_window. */
4392 ++windows_or_buffers_changed
;
4396 window_scroll (selected_window
, direction
, 1, 0);
4397 else if (EQ (n
, Qminus
))
4398 window_scroll (selected_window
, -direction
, 1, 0);
4401 n
= Fprefix_numeric_value (n
);
4402 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
4405 unbind_to (count
, Qnil
);
4408 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
4409 doc
: /* Scroll text of current window upward ARG lines; or near full screen if no ARG.
4410 A near full screen is `next-screen-context-lines' less than a full screen.
4411 Negative ARG means scroll downward.
4412 If ARG is the atom `-', scroll downward by nearly full screen.
4413 When calling from a program, supply as argument a number, nil, or `-'. */)
4417 scroll_command (arg
, 1);
4421 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
4422 doc
: /* Scroll text of current window down ARG lines; or near full screen if no ARG.
4423 A near full screen is `next-screen-context-lines' less than a full screen.
4424 Negative ARG means scroll upward.
4425 If ARG is the atom `-', scroll upward by nearly full screen.
4426 When calling from a program, supply as argument a number, nil, or `-'. */)
4430 scroll_command (arg
, -1);
4434 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
4435 doc
: /* Return the other window for \"other window scroll\" commands.
4436 If in the minibuffer, `minibuffer-scroll-window' if non-nil
4437 specifies the window.
4438 If `other-window-scroll-buffer' is non-nil, a window
4439 showing that buffer is used. */)
4444 if (MINI_WINDOW_P (XWINDOW (selected_window
))
4445 && !NILP (Vminibuf_scroll_window
))
4446 window
= Vminibuf_scroll_window
;
4447 /* If buffer is specified, scroll that buffer. */
4448 else if (!NILP (Vother_window_scroll_buffer
))
4450 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
4452 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
4456 /* Nothing specified; look for a neighboring window on the same
4458 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
4460 if (EQ (window
, selected_window
))
4461 /* That didn't get us anywhere; look for a window on another
4464 window
= Fnext_window (window
, Qnil
, Qt
);
4465 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
4466 && ! EQ (window
, selected_window
));
4469 CHECK_LIVE_WINDOW (window
);
4471 if (EQ (window
, selected_window
))
4472 error ("There is no other window");
4477 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
4478 doc
: /* Scroll next window upward ARG lines; or near full screen if no ARG.
4479 A near full screen is `next-screen-context-lines' less than a full screen.
4480 The next window is the one below the current one; or the one at the top
4481 if the current one is at the bottom. Negative ARG means scroll downward.
4482 If ARG is the atom `-', scroll downward by nearly full screen.
4483 When calling from a program, supply as argument a number, nil, or `-'.
4485 If in the minibuffer, `minibuffer-scroll-window' if non-nil
4486 specifies the window to scroll.
4487 If `other-window-scroll-buffer' is non-nil, scroll the window
4488 showing that buffer, popping the buffer up if necessary. */)
4494 int count
= BINDING_STACK_SIZE ();
4496 window
= Fother_window_for_scrolling ();
4497 w
= XWINDOW (window
);
4499 /* Don't screw up if window_scroll gets an error. */
4500 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4501 ++windows_or_buffers_changed
;
4503 Fset_buffer (w
->buffer
);
4504 SET_PT (marker_position (w
->pointm
));
4507 window_scroll (window
, 1, 1, 1);
4508 else if (EQ (arg
, Qminus
))
4509 window_scroll (window
, -1, 1, 1);
4515 window_scroll (window
, XINT (arg
), 0, 1);
4518 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
4519 unbind_to (count
, Qnil
);
4524 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 1, "P",
4525 doc
: /* Scroll selected window display ARG columns left.
4526 Default for ARG is window width minus 2.
4527 Value is the total amount of leftward horizontal scrolling in
4528 effect after the change.
4529 If `automatic-hscrolling' is non-nil, the argument ARG modifies
4530 a lower bound for automatic scrolling, i.e. automatic scrolling
4531 will not scroll a window to a column less than the value returned
4532 by this function. */)
4534 register Lisp_Object arg
;
4538 struct window
*w
= XWINDOW (selected_window
);
4541 XSETFASTINT (arg
, window_internal_width (w
) - 2);
4543 arg
= Fprefix_numeric_value (arg
);
4545 hscroll
= XINT (w
->hscroll
) + XINT (arg
);
4546 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
4548 if (interactive_p (0))
4549 w
->min_hscroll
= w
->hscroll
;
4554 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 1, "P",
4555 doc
: /* Scroll selected window display ARG columns right.
4556 Default for ARG is window width minus 2.
4557 Value is the total amount of leftward horizontal scrolling in
4558 effect after the change.
4559 If `automatic-hscrolling' is non-nil, the argument ARG modifies
4560 a lower bound for automatic scrolling, i.e. automatic scrolling
4561 will not scroll a window to a column less than the value returned
4562 by this function. */)
4564 register Lisp_Object arg
;
4568 struct window
*w
= XWINDOW (selected_window
);
4571 XSETFASTINT (arg
, window_internal_width (w
) - 2);
4573 arg
= Fprefix_numeric_value (arg
);
4575 hscroll
= XINT (w
->hscroll
) - XINT (arg
);
4576 result
= Fset_window_hscroll (selected_window
, make_number (hscroll
));
4578 if (interactive_p (0))
4579 w
->min_hscroll
= w
->hscroll
;
4584 DEFUN ("minibuffer-selected-window", Fminibuffer_selected_window
, Sminibuffer_selected_window
, 0, 0, 0,
4585 doc
: /* Return the window which was selected when entering the minibuffer.
4586 Returns nil, if current window is not a minibuffer window. */)
4589 if (minibuf_level
> 0
4590 && MINI_WINDOW_P (XWINDOW (selected_window
))
4591 && !NILP (minibuf_selected_window
)
4592 && WINDOW_LIVE_P (minibuf_selected_window
))
4593 return minibuf_selected_window
;
4598 /* Value is the number of lines actually displayed in window W,
4599 as opposed to its height. */
4602 displayed_window_lines (w
)
4606 struct text_pos start
;
4607 int height
= window_box_height (w
);
4608 struct buffer
*old_buffer
;
4611 if (XBUFFER (w
->buffer
) != current_buffer
)
4613 old_buffer
= current_buffer
;
4614 set_buffer_internal (XBUFFER (w
->buffer
));
4619 /* In case W->start is out of the accessible range, do something
4620 reasonable. This happens in Info mode when Info-scroll-down
4621 calls (recenter -1) while W->start is 1. */
4622 if (XMARKER (w
->start
)->charpos
< BEGV
)
4623 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
4624 else if (XMARKER (w
->start
)->charpos
> ZV
)
4625 SET_TEXT_POS (start
, ZV
, ZV_BYTE
);
4627 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4629 start_display (&it
, w
, start
);
4630 move_it_vertically (&it
, height
);
4631 bottom_y
= line_bottom_y (&it
);
4633 /* Add in empty lines at the bottom of the window. */
4634 if (bottom_y
< height
)
4636 int uy
= CANON_Y_UNIT (it
.f
);
4637 it
.vpos
+= (height
- bottom_y
+ uy
- 1) / uy
;
4641 set_buffer_internal (old_buffer
);
4647 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
4648 doc
: /* Center point in window and redisplay frame.
4649 With prefix argument ARG, recenter putting point on screen line ARG
4650 relative to the current window. If ARG is negative, it counts up from the
4651 bottom of the window. (ARG should be less than the height of the window.)
4653 If ARG is omitted or nil, erase the entire frame and then
4654 redraw with point in the center of the current window.
4655 Just C-u as prefix means put point in the center of the window
4656 and redisplay normally--don't erase and redraw the frame. */)
4658 register Lisp_Object arg
;
4660 struct window
*w
= XWINDOW (selected_window
);
4661 struct buffer
*buf
= XBUFFER (w
->buffer
);
4662 struct buffer
*obuf
= current_buffer
;
4664 int charpos
, bytepos
;
4666 /* If redisplay is suppressed due to an error, try again. */
4667 obuf
->display_error_modiff
= 0;
4673 /* Invalidate pixel data calculated for all compositions. */
4674 for (i
= 0; i
< n_compositions
; i
++)
4675 composition_table
[i
]->font
= NULL
;
4677 Fredraw_frame (w
->frame
);
4678 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
4681 else if (CONSP (arg
)) /* Just C-u. */
4685 arg
= Fprefix_numeric_value (arg
);
4689 set_buffer_internal (buf
);
4691 /* Handle centering on a graphical frame specially. Such frames can
4692 have variable-height lines and centering point on the basis of
4693 line counts would lead to strange effects. */
4694 if (FRAME_WINDOW_P (XFRAME (w
->frame
)))
4701 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
4702 start_display (&it
, w
, pt
);
4703 move_it_vertically (&it
, - window_box_height (w
) / 2);
4704 charpos
= IT_CHARPOS (it
);
4705 bytepos
= IT_BYTEPOS (it
);
4707 else if (XINT (arg
) < 0)
4711 int y0
, y1
, h
, nlines
;
4713 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
4714 start_display (&it
, w
, pt
);
4717 /* The amount of pixels we have to move back is the window
4718 height minus what's displayed in the line containing PT,
4719 and the lines below. */
4720 nlines
= - XINT (arg
) - 1;
4721 move_it_by_lines (&it
, nlines
, 1);
4723 y1
= line_bottom_y (&it
);
4725 /* If we can't move down NLINES lines because we hit
4726 the end of the buffer, count in some empty lines. */
4727 if (it
.vpos
< nlines
)
4728 y1
+= (nlines
- it
.vpos
) * CANON_Y_UNIT (it
.f
);
4730 h
= window_box_height (w
) - (y1
- y0
);
4732 start_display (&it
, w
, pt
);
4733 move_it_vertically (&it
, - h
);
4734 charpos
= IT_CHARPOS (it
);
4735 bytepos
= IT_BYTEPOS (it
);
4739 struct position pos
;
4740 pos
= *vmotion (PT
, - XINT (arg
), w
);
4741 charpos
= pos
.bufpos
;
4742 bytepos
= pos
.bytepos
;
4747 struct position pos
;
4748 int ht
= window_internal_height (w
);
4751 arg
= make_number (ht
/ 2);
4752 else if (XINT (arg
) < 0)
4753 arg
= make_number (XINT (arg
) + ht
);
4755 pos
= *vmotion (PT
, - XINT (arg
), w
);
4756 charpos
= pos
.bufpos
;
4757 bytepos
= pos
.bytepos
;
4760 /* Set the new window start. */
4761 set_marker_both (w
->start
, w
->buffer
, charpos
, bytepos
);
4762 w
->window_end_valid
= Qnil
;
4763 w
->force_start
= Qt
;
4764 if (bytepos
== BEGV_BYTE
|| FETCH_BYTE (bytepos
- 1) == '\n')
4765 w
->start_at_line_beg
= Qt
;
4767 w
->start_at_line_beg
= Qnil
;
4769 set_buffer_internal (obuf
);
4774 DEFUN ("window-text-height", Fwindow_text_height
, Swindow_text_height
,
4776 doc
: /* Return the height in lines of the text display area of WINDOW.
4777 This doesn't include the mode-line (or header-line if any) or any
4778 partial-height lines in the text display area. */)
4782 struct window
*w
= decode_window (window
);
4783 int pixel_height
= window_box_height (w
);
4784 int line_height
= pixel_height
/ CANON_Y_UNIT (XFRAME (w
->frame
));
4785 return make_number (line_height
);
4790 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
4792 doc
: /* Position point relative to window.
4793 With no argument, position point at center of window.
4794 An argument specifies vertical position within the window;
4795 zero means top of window, negative means relative to bottom of window. */)
4799 struct window
*w
= XWINDOW (selected_window
);
4803 window
= selected_window
;
4804 start
= marker_position (w
->start
);
4805 if (start
< BEGV
|| start
> ZV
)
4807 int height
= window_internal_height (w
);
4808 Fvertical_motion (make_number (- (height
/ 2)), window
);
4809 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
4810 w
->start_at_line_beg
= Fbolp ();
4811 w
->force_start
= Qt
;
4814 Fgoto_char (w
->start
);
4816 lines
= displayed_window_lines (w
);
4818 XSETFASTINT (arg
, lines
/ 2);
4821 arg
= Fprefix_numeric_value (arg
);
4823 XSETINT (arg
, XINT (arg
) + lines
);
4826 /* Skip past a partially visible first line. */
4828 XSETINT (arg
, XINT (arg
) + 1);
4830 return Fvertical_motion (arg
, window
);
4835 /***********************************************************************
4836 Window Configuration
4837 ***********************************************************************/
4839 struct save_window_data
4841 EMACS_INT size_from_Lisp_Vector_struct
;
4842 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4843 Lisp_Object frame_width
, frame_height
, frame_menu_bar_lines
;
4844 Lisp_Object frame_tool_bar_lines
;
4845 Lisp_Object selected_frame
;
4846 Lisp_Object current_window
;
4847 Lisp_Object current_buffer
;
4848 Lisp_Object minibuf_scroll_window
;
4849 Lisp_Object minibuf_selected_window
;
4850 Lisp_Object root_window
;
4851 Lisp_Object focus_frame
;
4852 /* Record the values of window-min-width and window-min-height
4853 so that window sizes remain consistent with them. */
4854 Lisp_Object min_width
, min_height
;
4855 /* A vector, each of whose elements is a struct saved_window
4857 Lisp_Object saved_windows
;
4860 /* This is saved as a Lisp_Vector */
4863 /* these first two must agree with struct Lisp_Vector in lisp.h */
4864 EMACS_INT size_from_Lisp_Vector_struct
;
4865 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4868 Lisp_Object buffer
, start
, pointm
, mark
;
4869 Lisp_Object left
, top
, width
, height
, hscroll
, min_hscroll
;
4870 Lisp_Object parent
, prev
;
4871 Lisp_Object start_at_line_beg
;
4872 Lisp_Object display_table
;
4873 Lisp_Object orig_top
, orig_height
;
4876 #define SAVED_WINDOW_VECTOR_SIZE 17 /* Arg to Fmake_vector */
4878 #define SAVED_WINDOW_N(swv,n) \
4879 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
4881 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
4882 doc
: /* Return t if OBJECT is a window-configuration object. */)
4886 if (WINDOW_CONFIGURATIONP (object
))
4891 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
4892 doc
: /* Return the frame that CONFIG, a window-configuration object, is about. */)
4896 register struct save_window_data
*data
;
4897 struct Lisp_Vector
*saved_windows
;
4899 if (! WINDOW_CONFIGURATIONP (config
))
4900 wrong_type_argument (Qwindow_configuration_p
, config
);
4902 data
= (struct save_window_data
*) XVECTOR (config
);
4903 saved_windows
= XVECTOR (data
->saved_windows
);
4904 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4907 DEFUN ("set-window-configuration", Fset_window_configuration
,
4908 Sset_window_configuration
, 1, 1, 0,
4909 doc
: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
4910 CONFIGURATION must be a value previously returned
4911 by `current-window-configuration' (which see).
4912 If CONFIGURATION was made from a frame that is now deleted,
4913 only frame-independent values can be restored. In this case,
4914 the return value is nil. Otherwise the value is t. */)
4916 Lisp_Object configuration
;
4918 register struct save_window_data
*data
;
4919 struct Lisp_Vector
*saved_windows
;
4920 Lisp_Object new_current_buffer
;
4925 while (!WINDOW_CONFIGURATIONP (configuration
))
4926 wrong_type_argument (Qwindow_configuration_p
, configuration
);
4928 data
= (struct save_window_data
*) XVECTOR (configuration
);
4929 saved_windows
= XVECTOR (data
->saved_windows
);
4931 new_current_buffer
= data
->current_buffer
;
4932 if (NILP (XBUFFER (new_current_buffer
)->name
))
4933 new_current_buffer
= Qnil
;
4936 if (XBUFFER (new_current_buffer
) == current_buffer
)
4940 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4943 /* If f is a dead frame, don't bother rebuilding its window tree.
4944 However, there is other stuff we should still try to do below. */
4945 if (FRAME_LIVE_P (f
))
4947 register struct window
*w
;
4948 register struct saved_window
*p
;
4949 struct window
*root_window
;
4950 struct window
**leaf_windows
;
4954 /* If the frame has been resized since this window configuration was
4955 made, we change the frame to the size specified in the
4956 configuration, restore the configuration, and then resize it
4957 back. We keep track of the prevailing height in these variables. */
4958 int previous_frame_height
= FRAME_HEIGHT (f
);
4959 int previous_frame_width
= FRAME_WIDTH (f
);
4960 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
4961 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
4963 /* The mouse highlighting code could get screwed up
4964 if it runs during this. */
4967 if (XFASTINT (data
->frame_height
) != previous_frame_height
4968 || XFASTINT (data
->frame_width
) != previous_frame_width
)
4969 change_frame_size (f
, XFASTINT (data
->frame_height
),
4970 XFASTINT (data
->frame_width
), 0, 0, 0);
4971 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4972 if (XFASTINT (data
->frame_menu_bar_lines
)
4973 != previous_frame_menu_bar_lines
)
4974 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, make_number (0));
4975 #ifdef HAVE_WINDOW_SYSTEM
4976 if (XFASTINT (data
->frame_tool_bar_lines
)
4977 != previous_frame_tool_bar_lines
)
4978 x_set_tool_bar_lines (f
, data
->frame_tool_bar_lines
, make_number (0));
4982 /* "Swap out" point from the selected window
4983 into its buffer. We do this now, before
4984 restoring the window contents, and prevent it from
4985 being done later on when we select a new window. */
4986 if (! NILP (XWINDOW (selected_window
)->buffer
))
4988 w
= XWINDOW (selected_window
);
4989 set_marker_both (w
->pointm
,
4991 BUF_PT (XBUFFER (w
->buffer
)),
4992 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4995 windows_or_buffers_changed
++;
4996 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4998 /* Problem: Freeing all matrices and later allocating them again
4999 is a serious redisplay flickering problem. What we would
5000 really like to do is to free only those matrices not reused
5002 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
5004 = (struct window
**) alloca (count_windows (root_window
)
5005 * sizeof (struct window
*));
5006 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
5008 /* Temporarily avoid any problems with windows that are smaller
5009 than they are supposed to be. */
5010 window_min_height
= 1;
5011 window_min_width
= 1;
5014 Mark all windows now on frame as "deleted".
5015 Restoring the new configuration "undeletes" any that are in it.
5017 Save their current buffers in their height fields, since we may
5018 need it later, if a buffer saved in the configuration is now
5020 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5022 for (k
= 0; k
< saved_windows
->size
; k
++)
5024 p
= SAVED_WINDOW_N (saved_windows
, k
);
5025 w
= XWINDOW (p
->window
);
5028 if (!NILP (p
->parent
))
5029 w
->parent
= SAVED_WINDOW_N (saved_windows
,
5030 XFASTINT (p
->parent
))->window
;
5034 if (!NILP (p
->prev
))
5036 w
->prev
= SAVED_WINDOW_N (saved_windows
,
5037 XFASTINT (p
->prev
))->window
;
5038 XWINDOW (w
->prev
)->next
= p
->window
;
5043 if (!NILP (w
->parent
))
5045 if (EQ (p
->width
, XWINDOW (w
->parent
)->width
))
5047 XWINDOW (w
->parent
)->vchild
= p
->window
;
5048 XWINDOW (w
->parent
)->hchild
= Qnil
;
5052 XWINDOW (w
->parent
)->hchild
= p
->window
;
5053 XWINDOW (w
->parent
)->vchild
= Qnil
;
5058 /* If we squirreled away the buffer in the window's height,
5060 if (BUFFERP (w
->height
))
5061 w
->buffer
= w
->height
;
5064 w
->width
= p
->width
;
5065 w
->height
= p
->height
;
5066 w
->hscroll
= p
->hscroll
;
5067 w
->min_hscroll
= p
->min_hscroll
;
5068 w
->display_table
= p
->display_table
;
5069 w
->orig_top
= p
->orig_top
;
5070 w
->orig_height
= p
->orig_height
;
5071 XSETFASTINT (w
->last_modified
, 0);
5072 XSETFASTINT (w
->last_overlay_modified
, 0);
5074 /* Reinstall the saved buffer and pointers into it. */
5075 if (NILP (p
->buffer
))
5076 w
->buffer
= p
->buffer
;
5079 if (!NILP (XBUFFER (p
->buffer
)->name
))
5080 /* If saved buffer is alive, install it. */
5082 w
->buffer
= p
->buffer
;
5083 w
->start_at_line_beg
= p
->start_at_line_beg
;
5084 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
5085 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
5086 Fset_marker (XBUFFER (w
->buffer
)->mark
,
5087 p
->mark
, w
->buffer
);
5089 /* As documented in Fcurrent_window_configuration, don't
5090 save the location of point in the buffer which was current
5091 when the window configuration was recorded. */
5092 if (!EQ (p
->buffer
, new_current_buffer
)
5093 && XBUFFER (p
->buffer
) == current_buffer
)
5094 Fgoto_char (w
->pointm
);
5096 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
5097 /* Else unless window has a live buffer, get one. */
5099 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
5100 /* This will set the markers to beginning of visible
5102 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
5103 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
5104 w
->start_at_line_beg
= Qt
;
5107 /* Keeping window's old buffer; make sure the markers
5110 /* Set window markers at start of visible range. */
5111 if (XMARKER (w
->start
)->buffer
== 0)
5112 set_marker_restricted (w
->start
, make_number (0),
5114 if (XMARKER (w
->pointm
)->buffer
== 0)
5115 set_marker_restricted_both (w
->pointm
, w
->buffer
,
5116 BUF_PT (XBUFFER (w
->buffer
)),
5117 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5118 w
->start_at_line_beg
= Qt
;
5123 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
5124 /* Prevent "swapping out point" in the old selected window
5125 using the buffer that has been restored into it.
5126 That swapping out has already been done,
5127 near the beginning of this function. */
5128 selected_window
= Qnil
;
5129 Fselect_window (data
->current_window
);
5130 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
5133 if (NILP (data
->focus_frame
)
5134 || (FRAMEP (data
->focus_frame
)
5135 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
5136 Fredirect_frame_focus (frame
, data
->focus_frame
);
5138 #if 0 /* I don't understand why this is needed, and it causes problems
5139 when the frame's old selected window has been deleted. */
5140 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
5141 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
5145 /* Set the screen height to the value it had before this function. */
5146 if (previous_frame_height
!= FRAME_HEIGHT (f
)
5147 || previous_frame_width
!= FRAME_WIDTH (f
))
5148 change_frame_size (f
, previous_frame_height
, previous_frame_width
,
5150 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
5151 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
5152 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
5154 #ifdef HAVE_WINDOW_SYSTEM
5155 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
5156 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
5161 /* Now, free glyph matrices in windows that were not reused. */
5162 for (i
= n
= 0; i
< n_leaf_windows
; ++i
)
5164 if (NILP (leaf_windows
[i
]->buffer
))
5166 /* Assert it's not reused as a combination. */
5167 xassert (NILP (leaf_windows
[i
]->hchild
)
5168 && NILP (leaf_windows
[i
]->vchild
));
5169 free_window_matrices (leaf_windows
[i
]);
5171 else if (EQ (leaf_windows
[i
]->buffer
, new_current_buffer
))
5175 /* If more than one window shows the new and old current buffer,
5176 don't try to preserve point in that buffer. */
5177 if (old_point
> 0 && n
> 1)
5184 /* Fselect_window will have made f the selected frame, so we
5185 reselect the proper frame here. Fhandle_switch_frame will change the
5186 selected window too, but that doesn't make the call to
5187 Fselect_window above totally superfluous; it still sets f's
5189 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
5190 do_switch_frame (data
->selected_frame
, 0, 0);
5192 if (! NILP (Vwindow_configuration_change_hook
)
5193 && ! NILP (Vrun_hooks
))
5194 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
5197 if (!NILP (new_current_buffer
))
5199 Fset_buffer (new_current_buffer
);
5201 /* If the buffer that is current now is the same
5202 that was current before setting the window configuration,
5203 don't alter its PT. */
5208 /* Restore the minimum heights recorded in the configuration. */
5209 window_min_height
= XINT (data
->min_height
);
5210 window_min_width
= XINT (data
->min_width
);
5212 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
5213 minibuf_selected_window
= data
->minibuf_selected_window
;
5215 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
5218 /* Mark all windows now on frame as deleted
5219 by setting their buffers to nil. */
5222 delete_all_subwindows (w
)
5223 register struct window
*w
;
5225 if (!NILP (w
->next
))
5226 delete_all_subwindows (XWINDOW (w
->next
));
5227 if (!NILP (w
->vchild
))
5228 delete_all_subwindows (XWINDOW (w
->vchild
));
5229 if (!NILP (w
->hchild
))
5230 delete_all_subwindows (XWINDOW (w
->hchild
));
5232 w
->height
= w
->buffer
; /* See Fset_window_configuration for excuse. */
5234 if (!NILP (w
->buffer
))
5237 /* We set all three of these fields to nil, to make sure that we can
5238 distinguish this dead window from any live window. Live leaf
5239 windows will have buffer set, and combination windows will have
5240 vchild or hchild set. */
5245 Vwindow_list
= Qnil
;
5249 count_windows (window
)
5250 register struct window
*window
;
5252 register int count
= 1;
5253 if (!NILP (window
->next
))
5254 count
+= count_windows (XWINDOW (window
->next
));
5255 if (!NILP (window
->vchild
))
5256 count
+= count_windows (XWINDOW (window
->vchild
));
5257 if (!NILP (window
->hchild
))
5258 count
+= count_windows (XWINDOW (window
->hchild
));
5263 /* Fill vector FLAT with leaf windows under W, starting at index I.
5264 Value is last index + 1. */
5267 get_leaf_windows (w
, flat
, i
)
5269 struct window
**flat
;
5274 if (!NILP (w
->hchild
))
5275 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
5276 else if (!NILP (w
->vchild
))
5277 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
5281 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5288 /* Return a pointer to the glyph W's physical cursor is on. Value is
5289 null if W's current matrix is invalid, so that no meaningfull glyph
5293 get_phys_cursor_glyph (w
)
5296 struct glyph_row
*row
;
5297 struct glyph
*glyph
;
5299 if (w
->phys_cursor
.vpos
>= 0
5300 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
5301 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
5303 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
5304 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
5313 save_window_save (window
, vector
, i
)
5315 struct Lisp_Vector
*vector
;
5318 register struct saved_window
*p
;
5319 register struct window
*w
;
5320 register Lisp_Object tem
;
5322 for (;!NILP (window
); window
= w
->next
)
5324 p
= SAVED_WINDOW_N (vector
, i
);
5325 w
= XWINDOW (window
);
5327 XSETFASTINT (w
->temslot
, i
++);
5329 p
->buffer
= w
->buffer
;
5332 p
->width
= w
->width
;
5333 p
->height
= w
->height
;
5334 p
->hscroll
= w
->hscroll
;
5335 p
->min_hscroll
= w
->min_hscroll
;
5336 p
->display_table
= w
->display_table
;
5337 p
->orig_top
= w
->orig_top
;
5338 p
->orig_height
= w
->orig_height
;
5339 if (!NILP (w
->buffer
))
5341 /* Save w's value of point in the window configuration.
5342 If w is the selected window, then get the value of point
5343 from the buffer; pointm is garbage in the selected window. */
5344 if (EQ (window
, selected_window
))
5346 p
->pointm
= Fmake_marker ();
5347 set_marker_both (p
->pointm
, w
->buffer
,
5348 BUF_PT (XBUFFER (w
->buffer
)),
5349 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5352 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
5354 p
->start
= Fcopy_marker (w
->start
, Qnil
);
5355 p
->start_at_line_beg
= w
->start_at_line_beg
;
5357 tem
= XBUFFER (w
->buffer
)->mark
;
5358 p
->mark
= Fcopy_marker (tem
, Qnil
);
5365 p
->start_at_line_beg
= Qnil
;
5368 if (NILP (w
->parent
))
5371 p
->parent
= XWINDOW (w
->parent
)->temslot
;
5376 p
->prev
= XWINDOW (w
->prev
)->temslot
;
5378 if (!NILP (w
->vchild
))
5379 i
= save_window_save (w
->vchild
, vector
, i
);
5380 if (!NILP (w
->hchild
))
5381 i
= save_window_save (w
->hchild
, vector
, i
);
5387 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
5388 Scurrent_window_configuration
, 0, 1, 0,
5389 doc
: /* Return an object representing the current window configuration of FRAME.
5390 If FRAME is nil or omitted, use the selected frame.
5391 This describes the number of windows, their sizes and current buffers,
5392 and for each displayed buffer, where display starts, and the positions of
5393 point and mark. An exception is made for point in the current buffer:
5394 its value is -not- saved.
5395 This also records the currently selected frame, and FRAME's focus
5396 redirection (see `redirect-frame-focus'). */)
5400 register Lisp_Object tem
;
5401 register int n_windows
;
5402 register struct save_window_data
*data
;
5403 register struct Lisp_Vector
*vec
;
5408 frame
= selected_frame
;
5409 CHECK_LIVE_FRAME (frame
);
5412 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
5413 vec
= allocate_other_vector (VECSIZE (struct save_window_data
));
5414 data
= (struct save_window_data
*)vec
;
5416 XSETFASTINT (data
->frame_width
, FRAME_WIDTH (f
));
5417 XSETFASTINT (data
->frame_height
, FRAME_HEIGHT (f
));
5418 XSETFASTINT (data
->frame_menu_bar_lines
, FRAME_MENU_BAR_LINES (f
));
5419 XSETFASTINT (data
->frame_tool_bar_lines
, FRAME_TOOL_BAR_LINES (f
));
5420 data
->selected_frame
= selected_frame
;
5421 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
5422 XSETBUFFER (data
->current_buffer
, current_buffer
);
5423 data
->minibuf_scroll_window
= minibuf_level
> 0 ? Vminibuf_scroll_window
: Qnil
;
5424 data
->minibuf_selected_window
= minibuf_level
> 0 ? minibuf_selected_window
: Qnil
;
5425 data
->root_window
= FRAME_ROOT_WINDOW (f
);
5426 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
5427 XSETINT (data
->min_height
, window_min_height
);
5428 XSETINT (data
->min_width
, window_min_width
);
5429 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
5430 data
->saved_windows
= tem
;
5431 for (i
= 0; i
< n_windows
; i
++)
5432 XVECTOR (tem
)->contents
[i
]
5433 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
5434 save_window_save (FRAME_ROOT_WINDOW (f
), XVECTOR (tem
), 0);
5435 XSETWINDOW_CONFIGURATION (tem
, data
);
5439 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
5441 doc
: /* Execute body, preserving window sizes and contents.
5442 Restore which buffer appears in which window, where display starts,
5443 and the value of point and mark for each window.
5444 Also restore the choice of selected window.
5445 Also restore which buffer is current.
5446 Does not restore the value of point in current buffer.
5447 usage: (save-window-excursion BODY ...) */)
5451 register Lisp_Object val
;
5452 register int count
= specpdl_ptr
- specpdl
;
5454 record_unwind_protect (Fset_window_configuration
,
5455 Fcurrent_window_configuration (Qnil
));
5456 val
= Fprogn (args
);
5457 return unbind_to (count
, val
);
5461 /***********************************************************************
5463 ***********************************************************************/
5465 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
5467 doc
: /* Set width of marginal areas of window WINDOW.
5468 If window is nil, set margins of the currently selected window.
5469 First parameter LEFT-WIDTH specifies the number of character
5470 cells to reserve for the left marginal area. Second parameter
5471 RIGHT-WIDTH does the same for the right marginal area.
5472 A nil width parameter means no margin. */)
5473 (window
, left
, right
)
5474 Lisp_Object window
, left
, right
;
5476 struct window
*w
= decode_window (window
);
5479 CHECK_NUMBER_OR_FLOAT (left
);
5481 CHECK_NUMBER_OR_FLOAT (right
);
5483 /* Check widths < 0 and translate a zero width to nil.
5484 Margins that are too wide have to be checked elsewhere. */
5485 if ((INTEGERP (left
) && XINT (left
) < 0)
5486 || (FLOATP (left
) && XFLOAT_DATA (left
) <= 0))
5487 XSETFASTINT (left
, 0);
5488 if (INTEGERP (left
) && XFASTINT (left
) == 0)
5491 if ((INTEGERP (right
) && XINT (right
) < 0)
5492 || (FLOATP (right
) && XFLOAT_DATA (right
) <= 0))
5493 XSETFASTINT (right
, 0);
5494 if (INTEGERP (right
) && XFASTINT (right
) == 0)
5497 w
->left_margin_width
= left
;
5498 w
->right_margin_width
= right
;
5500 ++windows_or_buffers_changed
;
5501 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
5506 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
5508 doc
: /* Get width of marginal areas of window WINDOW.
5509 If WINDOW is omitted or nil, use the currently selected window.
5510 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).
5511 If a marginal area does not exist, its width will be returned
5516 struct window
*w
= decode_window (window
);
5517 return Fcons (w
->left_margin_width
, w
->right_margin_width
);
5522 /***********************************************************************
5524 ***********************************************************************/
5526 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 1, 0,
5527 doc
: /* Return the amount by which WINDOW is scrolled vertically.
5528 Use the selected window if WINDOW is nil or omitted.
5529 Value is a multiple of the canonical character height of WINDOW. */)
5538 window
= selected_window
;
5540 CHECK_WINDOW (window
);
5541 w
= XWINDOW (window
);
5542 f
= XFRAME (w
->frame
);
5544 if (FRAME_WINDOW_P (f
))
5545 result
= CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
);
5547 result
= make_number (0);
5552 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
5554 doc
: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL.
5555 WINDOW nil means use the selected window. VSCROLL is a non-negative
5556 multiple of the canonical character height of WINDOW. */)
5558 Lisp_Object window
, vscroll
;
5564 window
= selected_window
;
5566 CHECK_WINDOW (window
);
5567 CHECK_NUMBER_OR_FLOAT (vscroll
);
5569 w
= XWINDOW (window
);
5570 f
= XFRAME (w
->frame
);
5572 if (FRAME_WINDOW_P (f
))
5574 int old_dy
= w
->vscroll
;
5576 w
->vscroll
= - CANON_Y_UNIT (f
) * XFLOATINT (vscroll
);
5577 w
->vscroll
= min (w
->vscroll
, 0);
5579 /* Adjust glyph matrix of the frame if the virtual display
5580 area becomes larger than before. */
5581 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
5584 /* Prevent redisplay shortcuts. */
5585 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
5588 return Fwindow_vscroll (window
);
5592 /* Call FN for all leaf windows on frame F. FN is called with the
5593 first argument being a pointer to the leaf window, and with
5594 additional argument USER_DATA. Stops when FN returns 0. */
5597 foreach_window (f
, fn
, user_data
)
5599 int (* fn
) P_ ((struct window
*, void *));
5602 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, user_data
);
5606 /* Helper function for foreach_window. Call FN for all leaf windows
5607 reachable from W. FN is called with the first argument being a
5608 pointer to the leaf window, and with additional argument USER_DATA.
5609 Stop when FN returns 0. Value is 0 if stopped by FN. */
5612 foreach_window_1 (w
, fn
, user_data
)
5614 int (* fn
) P_ ((struct window
*, void *));
5619 for (cont
= 1; w
&& cont
;)
5621 if (!NILP (w
->hchild
))
5622 cont
= foreach_window_1 (XWINDOW (w
->hchild
), fn
, user_data
);
5623 else if (!NILP (w
->vchild
))
5624 cont
= foreach_window_1 (XWINDOW (w
->vchild
), fn
, user_data
);
5626 cont
= fn (w
, user_data
);
5628 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5635 /* Freeze or unfreeze the window start of W unless it is a
5636 mini-window or the selected window. FREEZE_P non-null means freeze
5637 the window start. */
5640 freeze_window_start (w
, freeze_p
)
5644 if (w
== XWINDOW (selected_window
)
5645 || MINI_WINDOW_P (w
)
5646 || (MINI_WINDOW_P (XWINDOW (selected_window
))
5647 && ! NILP (Vminibuf_scroll_window
)
5648 && w
== XWINDOW (Vminibuf_scroll_window
)))
5651 w
->frozen_window_start_p
= freeze_p
!= NULL
;
5656 /* Freeze or unfreeze the window starts of all leaf windows on frame
5657 F, except the selected window and a mini-window. FREEZE_P non-zero
5658 means freeze the window start. */
5661 freeze_window_starts (f
, freeze_p
)
5665 foreach_window (f
, freeze_window_start
, (void *) (freeze_p
? f
: 0));
5669 /***********************************************************************
5671 ***********************************************************************/
5673 /* Return 1 if window configurations C1 and C2
5674 describe the same state of affairs. This is used by Fequal. */
5677 compare_window_configurations (c1
, c2
, ignore_positions
)
5679 int ignore_positions
;
5681 register struct save_window_data
*d1
, *d2
;
5682 struct Lisp_Vector
*sw1
, *sw2
;
5685 if (!WINDOW_CONFIGURATIONP (c1
))
5686 wrong_type_argument (Qwindow_configuration_p
, c1
);
5687 if (!WINDOW_CONFIGURATIONP (c2
))
5688 wrong_type_argument (Qwindow_configuration_p
, c2
);
5690 d1
= (struct save_window_data
*) XVECTOR (c1
);
5691 d2
= (struct save_window_data
*) XVECTOR (c2
);
5692 sw1
= XVECTOR (d1
->saved_windows
);
5693 sw2
= XVECTOR (d2
->saved_windows
);
5695 if (! EQ (d1
->frame_width
, d2
->frame_width
))
5697 if (! EQ (d1
->frame_height
, d2
->frame_height
))
5699 if (! EQ (d1
->frame_menu_bar_lines
, d2
->frame_menu_bar_lines
))
5701 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
5703 /* Don't compare the current_window field directly.
5704 Instead see w1_is_current and w2_is_current, below. */
5705 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
5707 if (! ignore_positions
)
5709 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
5711 if (! EQ (d1
->minibuf_selected_window
, d2
->minibuf_selected_window
))
5714 /* Don't compare the root_window field.
5715 We don't require the two configurations
5716 to use the same window object,
5717 and the two root windows must be equivalent
5718 if everything else compares equal. */
5719 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
5721 if (! EQ (d1
->min_width
, d2
->min_width
))
5723 if (! EQ (d1
->min_height
, d2
->min_height
))
5726 /* Verify that the two confis have the same number of windows. */
5727 if (sw1
->size
!= sw2
->size
)
5730 for (i
= 0; i
< sw1
->size
; i
++)
5732 struct saved_window
*p1
, *p2
;
5733 int w1_is_current
, w2_is_current
;
5735 p1
= SAVED_WINDOW_N (sw1
, i
);
5736 p2
= SAVED_WINDOW_N (sw2
, i
);
5738 /* Verify that the current windows in the two
5739 configurations correspond to each other. */
5740 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
5741 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
5743 if (w1_is_current
!= w2_is_current
)
5746 /* Verify that the corresponding windows do match. */
5747 if (! EQ (p1
->buffer
, p2
->buffer
))
5749 if (! EQ (p1
->left
, p2
->left
))
5751 if (! EQ (p1
->top
, p2
->top
))
5753 if (! EQ (p1
->width
, p2
->width
))
5755 if (! EQ (p1
->height
, p2
->height
))
5757 if (! EQ (p1
->display_table
, p2
->display_table
))
5759 if (! EQ (p1
->parent
, p2
->parent
))
5761 if (! EQ (p1
->prev
, p2
->prev
))
5763 if (! ignore_positions
)
5765 if (! EQ (p1
->hscroll
, p2
->hscroll
))
5767 if (!EQ (p1
->min_hscroll
, p2
->min_hscroll
))
5769 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
5771 if (NILP (Fequal (p1
->start
, p2
->start
)))
5773 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
5775 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
5783 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
5784 Scompare_window_configurations
, 2, 2, 0,
5785 doc
: /* Compare two window configurations as regards the structure of windows.
5786 This function ignores details such as the values of point and mark
5787 and scrolling positions. */)
5791 if (compare_window_configurations (x
, y
, 1))
5799 struct frame
*f
= make_terminal_frame ();
5800 XSETFRAME (selected_frame
, f
);
5801 Vterminal_frame
= selected_frame
;
5802 minibuf_window
= f
->minibuffer_window
;
5803 selected_window
= f
->selected_window
;
5804 last_nonminibuf_frame
= f
;
5806 window_initialized
= 1;
5812 Vwindow_list
= Qnil
;
5818 Qwindow_size_fixed
= intern ("window-size-fixed");
5819 staticpro (&Qwindow_size_fixed
);
5821 staticpro (&Qwindow_configuration_change_hook
);
5822 Qwindow_configuration_change_hook
5823 = intern ("window-configuration-change-hook");
5825 Qwindowp
= intern ("windowp");
5826 staticpro (&Qwindowp
);
5828 Qwindow_configuration_p
= intern ("window-configuration-p");
5829 staticpro (&Qwindow_configuration_p
);
5831 Qwindow_live_p
= intern ("window-live-p");
5832 staticpro (&Qwindow_live_p
);
5834 Qtemp_buffer_show_hook
= intern ("temp-buffer-show-hook");
5835 staticpro (&Qtemp_buffer_show_hook
);
5837 staticpro (&Vwindow_list
);
5839 minibuf_selected_window
= Qnil
;
5840 staticpro (&minibuf_selected_window
);
5842 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
5843 doc
: /* Non-nil means call as function to display a help buffer.
5844 The function is called with one argument, the buffer to be displayed.
5845 Used by `with-output-to-temp-buffer'.
5846 If this function is used, then it must do the entire job of showing
5847 the buffer; `temp-buffer-show-hook' is not run unless this function runs it. */);
5848 Vtemp_buffer_show_function
= Qnil
;
5850 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
5851 doc
: /* If non-nil, function to call to handle `display-buffer'.
5852 It will receive two args, the buffer and a flag which if non-nil means
5853 that the currently selected window is not acceptable.
5854 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'
5855 work using this function. */);
5856 Vdisplay_buffer_function
= Qnil
;
5858 DEFVAR_LISP ("even-window-heights", &Veven_window_heights
,
5859 doc
: /* *If non-nil, `display-buffer' should even the window heights.
5860 If nil, `display-buffer' will leave the window configuration alone. */);
5861 Veven_window_heights
= Qt
;
5863 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
5864 doc
: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */);
5865 Vminibuf_scroll_window
= Qnil
;
5867 DEFVAR_BOOL ("mode-line-in-non-selected-windows", &mode_line_in_non_selected_windows
,
5868 doc
: /* Non-nil means to use `mode-line-inactive' face in non-selected windows.
5869 If the minibuffer is active, the `minibuffer-scroll-window' mode line
5870 is displayed in the `mode-line' face. */);
5871 mode_line_in_non_selected_windows
= 1;
5873 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
5874 doc
: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. */);
5875 Vother_window_scroll_buffer
= Qnil
;
5877 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
5878 doc
: /* *Non-nil means `display-buffer' should make a separate frame. */);
5881 DEFVAR_BOOL ("display-buffer-reuse-frames", &display_buffer_reuse_frames
,
5882 doc
: /* *Non-nil means `display-buffer' should reuse frames.
5883 If the buffer in question is already displayed in a frame, raise that frame. */);
5884 display_buffer_reuse_frames
= 0;
5886 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
5887 doc
: /* Function to call to handle automatic new frame creation.
5888 It is called with no arguments and should return a newly created frame.
5890 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'
5891 where `pop-up-frame-alist' would hold the default frame parameters. */);
5892 Vpop_up_frame_function
= Qnil
;
5894 DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names
,
5895 doc
: /* *List of buffer names that should have their own special frames.
5896 Displaying a buffer whose name is in this list makes a special frame for it
5897 using `special-display-function'. See also `special-display-regexps'.
5899 An element of the list can be a list instead of just a string.
5900 There are two ways to use a list as an element:
5901 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)
5902 In the first case, FRAME-PARAMETERS are used to create the frame.
5903 In the latter case, FUNCTION is called with BUFFER as the first argument,
5904 followed by OTHER-ARGS--it can display BUFFER in any way it likes.
5905 All this is done by the function found in `special-display-function'.
5907 If this variable appears \"not to work\", because you add a name to it
5908 but that buffer still appears in the selected window, look at the
5909 values of `same-window-buffer-names' and `same-window-regexps'.
5910 Those variables take precedence over this one. */);
5911 Vspecial_display_buffer_names
= Qnil
;
5913 DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps
,
5914 doc
: /* *List of regexps saying which buffers should have their own special frames.
5915 If a buffer name matches one of these regexps, it gets its own frame.
5916 Displaying a buffer whose name is in this list makes a special frame for it
5917 using `special-display-function'.
5919 An element of the list can be a list instead of just a string.
5920 There are two ways to use a list as an element:
5921 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)
5922 In the first case, FRAME-PARAMETERS are used to create the frame.
5923 In the latter case, FUNCTION is called with the buffer as first argument,
5924 followed by OTHER-ARGS--it can display the buffer in any way it likes.
5925 All this is done by the function found in `special-display-function'.
5927 If this variable appears \"not to work\", because you add a regexp to it
5928 but the matching buffers still appear in the selected window, look at the
5929 values of `same-window-buffer-names' and `same-window-regexps'.
5930 Those variables take precedence over this one. */);
5931 Vspecial_display_regexps
= Qnil
;
5933 DEFVAR_LISP ("special-display-function", &Vspecial_display_function
,
5934 doc
: /* Function to call to make a new frame for a special buffer.
5935 It is called with two arguments, the buffer and optional buffer specific
5936 data, and should return a window displaying that buffer.
5937 The default value makes a separate frame for the buffer,
5938 using `special-display-frame-alist' to specify the frame parameters.
5940 A buffer is special if its is listed in `special-display-buffer-names'
5941 or matches a regexp in `special-display-regexps'. */);
5942 Vspecial_display_function
= Qnil
;
5944 DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names
,
5945 doc
: /* *List of buffer names that should appear in the selected window.
5946 Displaying one of these buffers using `display-buffer' or `pop-to-buffer'
5947 switches to it in the selected window, rather than making it appear
5948 in some other window.
5950 An element of the list can be a cons cell instead of just a string.
5951 Then the car must be a string, which specifies the buffer name.
5952 This is for compatibility with `special-display-buffer-names';
5953 the cdr of the cons cell is ignored.
5955 See also `same-window-regexps'. */);
5956 Vsame_window_buffer_names
= Qnil
;
5958 DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps
,
5959 doc
: /* *List of regexps saying which buffers should appear in the selected window.
5960 If a buffer name matches one of these regexps, then displaying it
5961 using `display-buffer' or `pop-to-buffer' switches to it
5962 in the selected window, rather than making it appear in some other window.
5964 An element of the list can be a cons cell instead of just a string.
5965 Then the car must be a string, which specifies the buffer name.
5966 This is for compatibility with `special-display-buffer-names';
5967 the cdr of the cons cell is ignored.
5969 See also `same-window-buffer-names'. */);
5970 Vsame_window_regexps
= Qnil
;
5972 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
5973 doc
: /* *Non-nil means display-buffer should make new windows. */);
5976 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
5977 doc
: /* *Number of lines of continuity when scrolling by screenfuls. */);
5978 next_screen_context_lines
= 2;
5980 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
5981 doc
: /* *display-buffer would prefer to split the largest window if this large.
5982 If there is only one window, it is split regardless of this value. */);
5983 split_height_threshold
= 500;
5985 DEFVAR_INT ("window-min-height", &window_min_height
,
5986 doc
: /* *Delete any window less than this tall (including its mode line). */);
5987 window_min_height
= 4;
5989 DEFVAR_INT ("window-min-width", &window_min_width
,
5990 doc
: /* *Delete any window less than this wide. */);
5991 window_min_width
= 10;
5993 DEFVAR_LISP ("scroll-preserve-screen-position",
5994 &Vscroll_preserve_screen_position
,
5995 doc
: /* *Non-nil means scroll commands move point to keep its screen line unchanged. */);
5996 Vscroll_preserve_screen_position
= Qnil
;
5998 DEFVAR_LISP ("window-configuration-change-hook",
5999 &Vwindow_configuration_change_hook
,
6000 doc
: /* Functions to call when window configuration changes.
6001 The selected frame is the one whose configuration has changed. */);
6002 Vwindow_configuration_change_hook
= Qnil
;
6004 DEFVAR_BOOL ("window-size-fixed", &window_size_fixed
,
6005 doc
: /* Non-nil in a buffer means windows displaying the buffer are fixed-size.
6006 Emacs won't change the size of any window displaying that buffer,
6007 unless you explicitly change the size, or Emacs has no other choice.
6008 This variable automatically becomes buffer-local when set. */);
6009 Fmake_variable_buffer_local (Qwindow_size_fixed
);
6010 window_size_fixed
= 0;
6012 defsubr (&Sselected_window
);
6013 defsubr (&Sminibuffer_window
);
6014 defsubr (&Swindow_minibuffer_p
);
6015 defsubr (&Swindowp
);
6016 defsubr (&Swindow_live_p
);
6017 defsubr (&Spos_visible_in_window_p
);
6018 defsubr (&Swindow_buffer
);
6019 defsubr (&Swindow_height
);
6020 defsubr (&Swindow_width
);
6021 defsubr (&Swindow_hscroll
);
6022 defsubr (&Sset_window_hscroll
);
6023 defsubr (&Swindow_redisplay_end_trigger
);
6024 defsubr (&Sset_window_redisplay_end_trigger
);
6025 defsubr (&Swindow_edges
);
6026 defsubr (&Scoordinates_in_window_p
);
6027 defsubr (&Swindow_at
);
6028 defsubr (&Swindow_point
);
6029 defsubr (&Swindow_start
);
6030 defsubr (&Swindow_end
);
6031 defsubr (&Sset_window_point
);
6032 defsubr (&Sset_window_start
);
6033 defsubr (&Swindow_dedicated_p
);
6034 defsubr (&Sset_window_dedicated_p
);
6035 defsubr (&Swindow_display_table
);
6036 defsubr (&Sset_window_display_table
);
6037 defsubr (&Snext_window
);
6038 defsubr (&Sprevious_window
);
6039 defsubr (&Sother_window
);
6040 defsubr (&Sget_lru_window
);
6041 defsubr (&Sget_largest_window
);
6042 defsubr (&Sget_buffer_window
);
6043 defsubr (&Sdelete_other_windows
);
6044 defsubr (&Sdelete_windows_on
);
6045 defsubr (&Sreplace_buffer_in_windows
);
6046 defsubr (&Sdelete_window
);
6047 defsubr (&Sset_window_buffer
);
6048 defsubr (&Sselect_window
);
6049 defsubr (&Sspecial_display_p
);
6050 defsubr (&Ssame_window_p
);
6051 defsubr (&Sdisplay_buffer
);
6052 defsubr (&Ssplit_window
);
6053 defsubr (&Senlarge_window
);
6054 defsubr (&Sshrink_window
);
6055 defsubr (&Sscroll_up
);
6056 defsubr (&Sscroll_down
);
6057 defsubr (&Sscroll_left
);
6058 defsubr (&Sscroll_right
);
6059 defsubr (&Sother_window_for_scrolling
);
6060 defsubr (&Sscroll_other_window
);
6061 defsubr (&Sminibuffer_selected_window
);
6062 defsubr (&Srecenter
);
6063 defsubr (&Swindow_text_height
);
6064 defsubr (&Smove_to_window_line
);
6065 defsubr (&Swindow_configuration_p
);
6066 defsubr (&Swindow_configuration_frame
);
6067 defsubr (&Sset_window_configuration
);
6068 defsubr (&Scurrent_window_configuration
);
6069 defsubr (&Ssave_window_excursion
);
6070 defsubr (&Sset_window_margins
);
6071 defsubr (&Swindow_margins
);
6072 defsubr (&Swindow_vscroll
);
6073 defsubr (&Sset_window_vscroll
);
6074 defsubr (&Scompare_window_configurations
);
6075 defsubr (&Swindow_list
);
6081 initial_define_key (control_x_map
, '1', "delete-other-windows");
6082 initial_define_key (control_x_map
, '2', "split-window");
6083 initial_define_key (control_x_map
, '0', "delete-window");
6084 initial_define_key (control_x_map
, 'o', "other-window");
6085 initial_define_key (control_x_map
, '^', "enlarge-window");
6086 initial_define_key (control_x_map
, '<', "scroll-left");
6087 initial_define_key (control_x_map
, '>', "scroll-right");
6089 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
6090 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
6091 initial_define_key (meta_map
, 'v', "scroll-down");
6093 initial_define_key (global_map
, Ctl('L'), "recenter");
6094 initial_define_key (meta_map
, 'r', "move-to-window-line");