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 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
32 #include "dispextern.h"
33 #include "blockinput.h"
34 #include "intervals.h"
38 #endif /* HAVE_X_WINDOWS */
50 #define max(a, b) ((a) < (b) ? (b) : (a))
54 Lisp_Object Qwindowp
, Qwindow_live_p
, Qwindow_configuration_p
;
55 Lisp_Object Qwindow_size_fixed
, Qleft_bitmap_area
, Qright_bitmap_area
;
56 extern Lisp_Object Qheight
, Qwidth
;
58 static struct window
*decode_window
P_ ((Lisp_Object
));
59 static Lisp_Object select_window_1
P_ ((Lisp_Object
, int));
60 static int count_windows
P_ ((struct window
*));
61 static int get_leaf_windows
P_ ((struct window
*, struct window
**, int));
62 static void window_scroll
P_ ((Lisp_Object
, int, int, int));
63 static void window_scroll_pixel_based
P_ ((Lisp_Object
, int, int, int));
64 static void window_scroll_line_based
P_ ((Lisp_Object
, int, int, int));
65 static int window_min_size_1
P_ ((struct window
*, int));
66 static int window_min_size
P_ ((struct window
*, int, int, int *));
67 static void size_window
P_ ((Lisp_Object
, int, int, int));
68 static int freeze_window_start
P_ ((struct window
*, void *));
69 static int window_fixed_size_p
P_ ((struct window
*, int, int));
70 static void enlarge_window
P_ ((Lisp_Object
, int, int));
71 static Lisp_Object window_list
P_ ((void));
72 static int add_window_to_list
P_ ((struct window
*, void *));
73 static int candidate_window_p
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
,
75 static Lisp_Object next_window
P_ ((Lisp_Object
, Lisp_Object
,
77 static void decode_next_window_args
P_ ((Lisp_Object
*, Lisp_Object
*,
79 static int foreach_window_1
P_ ((struct window
*,
80 int (* fn
) (struct window
*, void *),
83 /* This is the window in which the terminal's cursor should
84 be left when nothing is being done with it. This must
85 always be a leaf window, and its buffer is selected by
86 the top level editing loop at the end of each command.
88 This value is always the same as
89 FRAME_SELECTED_WINDOW (selected_frame). */
91 Lisp_Object selected_window
;
93 /* A list of all windows for use by next_window and Fwindow_list.
94 Functions creating or deleting windows should invalidate this cache
95 by setting it to nil. */
97 Lisp_Object Vwindow_list
;
99 /* The mini-buffer window of the selected frame.
100 Note that you cannot test for mini-bufferness of an arbitrary window
101 by comparing against this; but you can test for mini-bufferness of
102 the selected window. */
104 Lisp_Object minibuf_window
;
106 /* Non-nil means it is the window for C-M-v to scroll
107 when the mini-buffer is selected. */
109 Lisp_Object Vminibuf_scroll_window
;
111 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
113 Lisp_Object Vother_window_scroll_buffer
;
115 /* Non-nil means it's function to call to display temp buffers. */
117 Lisp_Object Vtemp_buffer_show_function
;
119 /* If a window gets smaller than either of these, it is removed. */
121 int window_min_height
;
122 int window_min_width
;
124 /* Nonzero implies Fdisplay_buffer should create windows. */
128 /* Nonzero implies make new frames for Fdisplay_buffer. */
132 /* Nonzero means reuse existing frames for displaying buffers. */
134 int display_buffer_reuse_frames
;
136 /* Non-nil means use this function instead of default */
138 Lisp_Object Vpop_up_frame_function
;
140 /* Function to call to handle Fdisplay_buffer. */
142 Lisp_Object Vdisplay_buffer_function
;
144 /* List of buffer *names* for buffers that should have their own frames. */
146 Lisp_Object Vspecial_display_buffer_names
;
148 /* List of regexps for buffer names that should have their own frames. */
150 Lisp_Object Vspecial_display_regexps
;
152 /* Function to pop up a special frame. */
154 Lisp_Object Vspecial_display_function
;
156 /* List of buffer *names* for buffers to appear in selected window. */
158 Lisp_Object Vsame_window_buffer_names
;
160 /* List of regexps for buffer names to appear in selected window. */
162 Lisp_Object Vsame_window_regexps
;
164 /* Hook run at end of temp_output_buffer_show. */
166 Lisp_Object Qtemp_buffer_show_hook
;
168 /* Fdisplay_buffer always splits the largest window
169 if that window is more than this high. */
171 int split_height_threshold
;
173 /* Number of lines of continuity in scrolling by screenfuls. */
175 int next_screen_context_lines
;
177 /* Incremented for each window created. */
179 static int sequence_number
;
181 /* Nonzero after init_window_once has finished. */
183 static int window_initialized
;
185 /* Hook to run when window config changes. */
187 Lisp_Object Qwindow_configuration_change_hook
;
188 Lisp_Object Vwindow_configuration_change_hook
;
190 /* Nonzero means scroll commands try to put point
191 at the same screen height as previously. */
193 Lisp_Object Vscroll_preserve_screen_position
;
195 #if 0 /* This isn't used anywhere. */
196 /* Nonzero means we can split a frame even if it is "unsplittable". */
197 static int inhibit_frame_unsplittable
;
200 #define min(a, b) ((a) < (b) ? (a) : (b))
202 extern int scroll_margin
;
204 extern Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
206 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
207 "Returns t if OBJECT is a window.")
211 return WINDOWP (object
) ? Qt
: Qnil
;
214 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
215 "Returns t if OBJECT is a window which is currently visible.")
219 return (WINDOWP (object
) && ! NILP (XWINDOW (object
)->buffer
) ? Qt
: Qnil
);
226 register struct window
*p
;
227 register struct Lisp_Vector
*vec
;
230 vec
= allocate_vectorlike ((EMACS_INT
) VECSIZE (struct window
));
231 for (i
= 0; i
< VECSIZE (struct window
); i
++)
232 vec
->contents
[i
] = Qnil
;
233 vec
->size
= VECSIZE (struct window
);
234 p
= (struct window
*) vec
;
235 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
236 XSETFASTINT (p
->left
, 0);
237 XSETFASTINT (p
->top
, 0);
238 XSETFASTINT (p
->height
, 0);
239 XSETFASTINT (p
->width
, 0);
240 XSETFASTINT (p
->hscroll
, 0);
241 p
->orig_top
= p
->orig_height
= Qnil
;
242 p
->start
= Fmake_marker ();
243 p
->pointm
= Fmake_marker ();
244 XSETFASTINT (p
->use_time
, 0);
246 p
->display_table
= Qnil
;
248 p
->pseudo_window_p
= 0;
249 bzero (&p
->cursor
, sizeof (p
->cursor
));
250 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
251 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
252 p
->desired_matrix
= p
->current_matrix
= 0;
253 p
->phys_cursor_type
= -1;
254 p
->must_be_updated_p
= 0;
255 XSETFASTINT (p
->window_end_vpos
, 0);
256 XSETFASTINT (p
->window_end_pos
, 0);
257 p
->window_end_valid
= Qnil
;
260 XSETFASTINT (p
->last_point
, 0);
261 p
->frozen_window_start_p
= 0;
267 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
268 "Return the window that the cursor now appears in and commands apply to.")
271 return selected_window
;
274 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
275 "Return the window used now for minibuffers.\n\
276 If the optional argument FRAME is specified, return the minibuffer window\n\
277 used by that frame.")
282 frame
= selected_frame
;
283 CHECK_LIVE_FRAME (frame
, 0);
284 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
287 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 0, 1, 0,
288 "Returns non-nil if WINDOW is a minibuffer window.")
292 struct window
*w
= decode_window (window
);
293 return MINI_WINDOW_P (w
) ? Qt
: Qnil
;
297 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
298 Spos_visible_in_window_p
, 0, 3, 0,
299 "Return t if position POS is currently on the frame in WINDOW.\n\
300 Return nil if that position is scrolled vertically out of view.\n\
301 If FULLY is non-nil, then only return t when POS is completely visible.\n\
302 POS defaults to point in WINDOW; WINDOW defaults to the selected window.")
304 Lisp_Object pos
, window
, fully
;
306 register struct window
*w
;
308 register struct buffer
*buf
;
310 Lisp_Object in_window
;
313 w
= decode_window (window
);
314 buf
= XBUFFER (w
->buffer
);
315 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
319 CHECK_NUMBER_COERCE_MARKER (pos
, 0);
322 else if (w
== XWINDOW (selected_window
))
325 posint
= XMARKER (w
->pointm
)->charpos
;
327 /* If position is above window start, it's not visible. */
328 if (posint
< CHARPOS (top
))
330 else if (XFASTINT (w
->last_modified
) >= BUF_MODIFF (buf
)
331 && XFASTINT (w
->last_overlay_modified
) >= BUF_OVERLAY_MODIFF (buf
)
332 && posint
< BUF_Z (buf
) - XFASTINT (w
->window_end_pos
))
334 /* If frame is up-to-date, and POSINT is < window end pos, use
335 that info. This doesn't work for POSINT == end pos, because
336 the window end pos is actually the position _after_ the last
337 char in the window. */
340 pos_visible_p (w
, posint
, &fully_p
);
341 in_window
= fully_p
? Qt
: Qnil
;
346 else if (posint
> BUF_ZV (buf
))
348 else if (CHARPOS (top
) < BUF_BEGV (buf
) || CHARPOS (top
) > BUF_ZV (buf
))
349 /* If window start is out of range, do something reasonable. */
353 if (pos_visible_p (w
, posint
, &fully_p
))
354 in_window
= NILP (fully
) || fully_p
? Qt
: Qnil
;
363 static struct window
*
364 decode_window (window
)
365 register Lisp_Object window
;
368 return XWINDOW (selected_window
);
370 CHECK_LIVE_WINDOW (window
, 0);
371 return XWINDOW (window
);
374 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
375 "Return the buffer that WINDOW is displaying.")
379 return decode_window (window
)->buffer
;
382 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
383 "Return the number of lines in WINDOW (including its mode line).")
387 return decode_window (window
)->height
;
390 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
391 "Return the number of display columns in WINDOW.\n\
392 This is the width that is usable columns available for text in WINDOW.\n\
393 If you want to find out how many columns WINDOW takes up,\n\
394 use (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))).")
398 return make_number (window_internal_width (decode_window (window
)));
401 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
402 "Return the number of columns by which WINDOW is scrolled from left margin.")
406 return decode_window (window
)->hscroll
;
409 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
410 "Set number of columns WINDOW is scrolled from left margin to NCOL.\n\
411 NCOL should be zero or positive.")
413 register Lisp_Object window
, ncol
;
415 register struct window
*w
;
417 CHECK_NUMBER (ncol
, 1);
418 if (XINT (ncol
) < 0) XSETFASTINT (ncol
, 0);
419 w
= decode_window (window
);
420 if (XINT (w
->hscroll
) != XINT (ncol
))
421 /* Prevent redisplay shortcuts */
422 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
427 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
428 Swindow_redisplay_end_trigger
, 0, 1, 0,
429 "Return WINDOW's redisplay end trigger value.\n\
430 See `set-window-redisplay-end-trigger' for more information.")
434 return decode_window (window
)->redisplay_end_trigger
;
437 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
438 Sset_window_redisplay_end_trigger
, 2, 2, 0,
439 "Set WINDOW's redisplay end trigger value to VALUE.\n\
440 VALUE should be a buffer position (typically a marker) or nil.\n\
441 If it is a buffer position, then if redisplay in WINDOW reaches a position\n\
442 beyond VALUE, the functions in `redisplay-end-trigger-functions' are called\n\
443 with two arguments: WINDOW, and the end trigger value.\n\
444 Afterwards the end-trigger value is reset to nil.")
446 register Lisp_Object window
, value
;
448 register struct window
*w
;
450 w
= decode_window (window
);
451 w
->redisplay_end_trigger
= value
;
455 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
456 "Return a list of the edge coordinates of WINDOW.\n\
457 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.\n\
458 RIGHT is one more than the rightmost column used by WINDOW,\n\
459 and BOTTOM is one more than the bottommost row used by WINDOW\n\
464 register struct window
*w
= decode_window (window
);
466 return Fcons (w
->left
, Fcons (w
->top
,
467 Fcons (make_number (WINDOW_RIGHT_EDGE (w
)),
468 Fcons (make_number (XFASTINT (w
->top
)
469 + XFASTINT (w
->height
)),
473 /* Test if the character at column *X, row *Y is within window W.
474 If it is not, return 0;
475 if it is in the window's text area,
476 set *x and *y to its location relative to the upper left corner
479 if it is on the window's modeline, return 2;
480 if it is on the border between the window and its right sibling,
482 if it is on the window's top line, return 4;
483 if it is in the bitmap area to the left/right of the window,
484 return 5 or 6, and convert *X and *Y to window-relative corrdinates.
486 X and Y are frame relative pixel coordinates. */
489 coordinates_in_window (w
, x
, y
)
490 register struct window
*w
;
493 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
494 int left_x
, right_x
, top_y
, bottom_y
;
495 int flags_area_width
= FRAME_LEFT_FLAGS_AREA_WIDTH (f
);
497 /* In what's below, we subtract 1 when computing right_x because we
498 want the rightmost pixel, which is given by left_pixel+width-1. */
499 if (w
->pseudo_window_p
)
502 right_x
= XFASTINT (w
->width
) * CANON_Y_UNIT (f
) - 1;
503 top_y
= WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
);
504 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
508 left_x
= (WINDOW_DISPLAY_LEFT_EDGE_PIXEL_X (w
)
509 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
510 right_x
= WINDOW_DISPLAY_RIGHT_EDGE_PIXEL_X (w
) - 1;
511 top_y
= (WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
)
512 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
513 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
520 - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
)
522 || *x
> right_x
+ flags_area_width
)
523 /* Completely outside anything interesting. */
525 else if (WINDOW_WANTS_MODELINE_P (w
)
526 && *y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
))
527 /* On the mode line. */
529 else if (WINDOW_WANTS_HEADER_LINE_P (w
)
530 && *y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
))
531 /* On the top line. */
533 /* Need to say "*x > right_x" rather than >=, since on character
534 terminals, the vertical line's x coordinate is right_x. */
535 else if (*x
< left_x
|| *x
> right_x
)
537 /* Other lines than the mode line don't include flags areas and
538 scroll bars on the left. */
540 /* Convert X and Y to window-relative pixel coordinates. */
543 return *x
< left_x
? 5 : 6;
545 /* Here, too, "*x > right_x" is because of character terminals. */
546 else if (!w
->pseudo_window_p
547 && !WINDOW_RIGHTMOST_P (w
)
548 && *x
> right_x
- CANON_X_UNIT (f
))
549 /* On the border on the right side of the window? Assume that
550 this area begins at RIGHT_X minus a canonical char width. */
554 /* Convert X and Y to window-relative pixel coordinates. */
561 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
562 Scoordinates_in_window_p
, 2, 2, 0,
563 "Return non-nil if COORDINATES are in WINDOW.\n\
564 COORDINATES is a cons of the form (X . Y), X and Y being distances\n\
565 measured in characters from the upper-left corner of the frame.\n\
566 (0 . 0) denotes the character in the upper left corner of the\n\
568 If COORDINATES are in the text portion of WINDOW,\n\
569 the coordinates relative to the window are returned.\n\
570 If they are in the mode line of WINDOW, `mode-line' is returned.\n\
571 If they are in the top mode line of WINDOW, `header-line' is returned.\n\
572 If they are in the bitmap-area to the left of the window,\n\
573 `left-bitmap-area' is returned, if they are in the area on the right of\n\
574 the window, `right-bitmap-area' is returned.\n\
575 If they are on the border between WINDOW and its right sibling,\n\
576 `vertical-line' is returned.")
577 (coordinates
, window
)
578 register Lisp_Object coordinates
, window
;
585 CHECK_LIVE_WINDOW (window
, 0);
586 w
= XWINDOW (window
);
587 f
= XFRAME (w
->frame
);
588 CHECK_CONS (coordinates
, 1);
589 lx
= Fcar (coordinates
);
590 ly
= Fcdr (coordinates
);
591 CHECK_NUMBER_OR_FLOAT (lx
, 1);
592 CHECK_NUMBER_OR_FLOAT (ly
, 1);
593 x
= PIXEL_X_FROM_CANON_X (f
, lx
);
594 y
= PIXEL_Y_FROM_CANON_Y (f
, ly
);
596 switch (coordinates_in_window (w
, &x
, &y
))
598 case 0: /* NOT in window at all. */
601 case 1: /* In text part of window. */
602 /* X and Y are now window relative pixel coordinates.
603 Convert them to canonical char units before returning
605 return Fcons (CANON_X_FROM_PIXEL_X (f
, x
),
606 CANON_Y_FROM_PIXEL_Y (f
, y
));
608 case 2: /* In mode line of window. */
611 case 3: /* On right border of window. */
612 return Qvertical_line
;
618 return Qleft_bitmap_area
;
621 return Qright_bitmap_area
;
629 /* Callback for foreach_window, used in window_from_coordinates.
630 Check if window W contains coordinates specified by USER_DATA which
631 is actually a pointer to a struct check_window_data CW.
633 Check if window W contains coordinates *CW->x and *CW->y. If it
634 does, return W in *CW->window, as Lisp_Object, and return in
635 *CW->part the part of the window under coordinates *X,*Y. Return
636 zero from this function to stop iterating over windows. */
638 struct check_window_data
645 check_window_containing (w
, user_data
)
649 struct check_window_data
*cw
= (struct check_window_data
*) user_data
;
652 found
= coordinates_in_window (w
, cw
->x
, cw
->y
);
655 *cw
->part
= found
- 1;
656 XSETWINDOW (*cw
->window
, w
);
663 /* Find the window containing frame-relative pixel position X/Y and
664 return it as a Lisp_Object. If X, Y is on the window's modeline,
665 set *PART to 1; if it is on the separating line between the window
666 and its right sibling, set it to 2; otherwise set it to 0. If
667 there is no window under X, Y return nil and leave *PART
668 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows.
670 This function was previously implemented with a loop cycling over
671 windows with Fnext_window, and starting with the frame's selected
672 window. It turned out that this doesn't work with an
673 implementation of next_window using Vwindow_list, because
674 FRAME_SELECTED_WINDOW (F) is not always contained in the window
675 tree of F when this function is called asynchronously from
676 note_mouse_highlight. The original loop didn't terminate in this
680 window_from_coordinates (f
, x
, y
, part
, tool_bar_p
)
687 struct check_window_data cw
;
690 cw
.window
= &window
, cw
.x
= &x
, cw
.y
= &y
; cw
.part
= part
;
691 foreach_window (f
, check_window_containing
, &cw
);
693 /* If not found above, see if it's in the tool bar window, if a tool
697 && WINDOWP (f
->tool_bar_window
)
698 && XINT (XWINDOW (f
->tool_bar_window
)->height
) > 0
699 && coordinates_in_window (XWINDOW (f
->tool_bar_window
), &x
, &y
))
702 window
= f
->tool_bar_window
;
708 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
709 "Return window containing coordinates X and Y on FRAME.\n\
710 If omitted, FRAME defaults to the currently selected frame.\n\
711 The top left corner of the frame is considered to be row 0,\n\
714 Lisp_Object x
, y
, frame
;
720 frame
= selected_frame
;
721 CHECK_LIVE_FRAME (frame
, 2);
724 /* Check that arguments are integers or floats. */
725 CHECK_NUMBER_OR_FLOAT (x
, 0);
726 CHECK_NUMBER_OR_FLOAT (y
, 1);
728 return window_from_coordinates (f
,
729 PIXEL_X_FROM_CANON_X (f
, x
),
730 PIXEL_Y_FROM_CANON_Y (f
, y
),
734 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
735 "Return current value of point in WINDOW.\n\
736 For a nonselected window, this is the value point would have\n\
737 if that window were selected.\n\
739 Note that, when WINDOW is the selected window and its buffer\n\
740 is also currently selected, the value returned is the same as (point).\n\
741 It would be more strictly correct to return the `top-level' value\n\
742 of point, outside of any save-excursion forms.\n\
743 But that is hard to define.")
747 register struct window
*w
= decode_window (window
);
749 if (w
== XWINDOW (selected_window
)
750 && current_buffer
== XBUFFER (w
->buffer
))
752 return Fmarker_position (w
->pointm
);
755 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
756 "Return position at which display currently starts in WINDOW.\n\
757 This is updated by redisplay or by calling `set-window-start'.")
761 return Fmarker_position (decode_window (window
)->start
);
764 /* This is text temporarily removed from the doc string below.
766 This function returns nil if the position is not currently known.\n\
767 That happens when redisplay is preempted and doesn't finish.\n\
768 If in that case you want to compute where the end of the window would\n\
769 have been if redisplay had finished, do this:\n\
771 (goto-char (window-start window))\n\
772 (vertical-motion (1- (window-height window)) window)\n\
775 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
776 "Return position at which display currently ends in WINDOW.\n\
777 This is updated by redisplay, when it runs to completion.\n\
778 Simply changing the buffer text or setting `window-start'\n\
779 does not update this value.\n\
780 If UP-TO-DATE is non-nil, compute the up-to-date position\n\
781 if it isn't already recorded.")
783 Lisp_Object window
, update
;
786 struct window
*w
= decode_window (window
);
790 CHECK_BUFFER (buf
, 0);
792 #if 0 /* This change broke some things. We should make it later. */
793 /* If we don't know the end position, return nil.
794 The user can compute it with vertical-motion if he wants to.
795 It would be nicer to do it automatically,
796 but that's so slow that it would probably bother people. */
797 if (NILP (w
->window_end_valid
))
802 && ! (! NILP (w
->window_end_valid
)
803 && XFASTINT (w
->last_modified
) >= MODIFF
))
805 struct text_pos startp
;
808 /* In case W->start is out of the range, use something
809 reasonable. This situation occured when loading a file with
810 `-l' containing a call to `rmail' with subsequent other
811 commands. At the end, W->start happened to be BEG, while
812 rmail had already narrowed the buffer. */
813 if (XMARKER (w
->start
)->charpos
< BEGV
)
814 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
815 else if (XMARKER (w
->start
)->charpos
> ZV
)
816 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
818 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
820 /* Cannot use Fvertical_motion because that function doesn't
821 cope with variable-height lines. */
822 start_display (&it
, w
, startp
);
823 move_it_vertically (&it
, window_box_height (w
));
824 value
= make_number (IT_CHARPOS (it
));
827 XSETINT (value
, BUF_Z (XBUFFER (buf
)) - XFASTINT (w
->window_end_pos
));
832 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
833 "Make point value in WINDOW be at position POS in WINDOW's buffer.")
835 Lisp_Object window
, pos
;
837 register struct window
*w
= decode_window (window
);
839 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
840 if (w
== XWINDOW (selected_window
)
841 && XBUFFER (w
->buffer
) == current_buffer
)
844 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
849 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
850 "Make display in WINDOW start at position POS in WINDOW's buffer.\n\
851 Optional third arg NOFORCE non-nil inhibits next redisplay\n\
852 from overriding motion of point in order to display at this exact start.")
853 (window
, pos
, noforce
)
854 Lisp_Object window
, pos
, noforce
;
856 register struct window
*w
= decode_window (window
);
858 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
859 set_marker_restricted (w
->start
, pos
, w
->buffer
);
860 /* this is not right, but much easier than doing what is right. */
861 w
->start_at_line_beg
= Qnil
;
864 w
->update_mode_line
= Qt
;
865 XSETFASTINT (w
->last_modified
, 0);
866 XSETFASTINT (w
->last_overlay_modified
, 0);
867 if (!EQ (window
, selected_window
))
868 windows_or_buffers_changed
++;
873 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
875 "Return WINDOW's dedicated object, usually t or nil.\n\
876 See also `set-window-dedicated-p'.")
880 return decode_window (window
)->dedicated
;
883 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
884 Sset_window_dedicated_p
, 2, 2, 0,
885 "Control whether WINDOW is dedicated to the buffer it displays.\n\
886 If it is dedicated, Emacs will not automatically change\n\
887 which buffer appears in it.\n\
888 The second argument is the new value for the dedication flag;\n\
891 Lisp_Object window
, arg
;
893 register struct window
*w
= decode_window (window
);
903 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
905 "Return the display-table that WINDOW is using.")
909 return decode_window (window
)->display_table
;
912 /* Get the display table for use on window W. This is either W's
913 display table or W's buffer's display table. Ignore the specified
914 tables if they are not valid; if no valid table is specified,
917 struct Lisp_Char_Table
*
918 window_display_table (w
)
921 struct Lisp_Char_Table
*dp
= NULL
;
923 if (DISP_TABLE_P (w
->display_table
))
924 dp
= XCHAR_TABLE (w
->display_table
);
925 else if (BUFFERP (w
->buffer
))
927 struct buffer
*b
= XBUFFER (w
->buffer
);
929 if (DISP_TABLE_P (b
->display_table
))
930 dp
= XCHAR_TABLE (b
->display_table
);
931 else if (DISP_TABLE_P (Vstandard_display_table
))
932 dp
= XCHAR_TABLE (Vstandard_display_table
);
938 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
939 "Set WINDOW's display-table to TABLE.")
941 register Lisp_Object window
, table
;
943 register struct window
*w
;
945 w
= decode_window (window
);
946 w
->display_table
= table
;
950 /* Record info on buffer window w is displaying
951 when it is about to cease to display that buffer. */
954 register struct window
*w
;
961 if (b
!= XMARKER (w
->pointm
)->buffer
)
965 if (w
== XWINDOW (selected_window
)
966 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
967 /* Do this except when the selected window's buffer
968 is being removed from some other window. */
970 /* last_window_start records the start position that this buffer
971 had in the last window to be disconnected from it.
972 Now that this statement is unconditional,
973 it is possible for the buffer to be displayed in the
974 selected window, while last_window_start reflects another
975 window which was recently showing the same buffer.
976 Some people might say that might be a good thing. Let's see. */
977 b
->last_window_start
= marker_position (w
->start
);
979 /* Point in the selected window's buffer
980 is actually stored in that buffer, and the window's pointm isn't used.
981 So don't clobber point in that buffer. */
982 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
)
983 /* This line helps to fix Horsley's testbug.el bug. */
984 && !(WINDOWP (b
->last_selected_window
)
985 && w
!= XWINDOW (b
->last_selected_window
)
986 && EQ (buf
, XWINDOW (b
->last_selected_window
)->buffer
)))
987 temp_set_point_both (b
,
988 clip_to_bounds (BUF_BEGV (b
),
989 XMARKER (w
->pointm
)->charpos
,
991 clip_to_bounds (BUF_BEGV_BYTE (b
),
992 marker_byte_position (w
->pointm
),
995 if (WINDOWP (b
->last_selected_window
)
996 && w
== XWINDOW (b
->last_selected_window
))
997 b
->last_selected_window
= Qnil
;
1000 /* Put replacement into the window structure in place of old. */
1002 replace_window (old
, replacement
)
1003 Lisp_Object old
, replacement
;
1005 register Lisp_Object tem
;
1006 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
1008 /* If OLD is its frame's root_window, then replacement is the new
1009 root_window for that frame. */
1011 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
1012 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
1016 p
->width
= o
->width
;
1017 p
->height
= o
->height
;
1018 p
->desired_matrix
= p
->current_matrix
= 0;
1020 bzero (&p
->cursor
, sizeof (p
->cursor
));
1021 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
1022 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
1023 p
->phys_cursor_type
= -1;
1024 p
->must_be_updated_p
= 0;
1025 p
->pseudo_window_p
= 0;
1026 XSETFASTINT (p
->window_end_vpos
, 0);
1027 XSETFASTINT (p
->window_end_pos
, 0);
1028 p
->window_end_valid
= Qnil
;
1029 p
->frozen_window_start_p
= 0;
1030 p
->orig_top
= p
->orig_height
= Qnil
;
1032 p
->next
= tem
= o
->next
;
1034 XWINDOW (tem
)->prev
= replacement
;
1036 p
->prev
= tem
= o
->prev
;
1038 XWINDOW (tem
)->next
= replacement
;
1040 p
->parent
= tem
= o
->parent
;
1043 if (EQ (XWINDOW (tem
)->vchild
, old
))
1044 XWINDOW (tem
)->vchild
= replacement
;
1045 if (EQ (XWINDOW (tem
)->hchild
, old
))
1046 XWINDOW (tem
)->hchild
= replacement
;
1049 /*** Here, if replacement is a vertical combination
1050 and so is its new parent, we should make replacement's
1051 children be children of that parent instead. ***/
1054 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
1055 "Remove WINDOW from the display. Default is selected window.")
1057 register Lisp_Object window
;
1059 delete_window (window
);
1061 if (! NILP (Vwindow_configuration_change_hook
)
1062 && ! NILP (Vrun_hooks
))
1063 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
1069 delete_window (window
)
1070 register Lisp_Object window
;
1072 register Lisp_Object tem
, parent
, sib
;
1073 register struct window
*p
;
1074 register struct window
*par
;
1077 /* Because this function is called by other C code on non-leaf
1078 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1079 so we can't decode_window here. */
1081 window
= selected_window
;
1083 CHECK_WINDOW (window
, 0);
1084 p
= XWINDOW (window
);
1086 /* It's okay to delete an already-deleted window. */
1087 if (NILP (p
->buffer
)
1089 && NILP (p
->vchild
))
1094 error ("Attempt to delete minibuffer or sole ordinary window");
1095 par
= XWINDOW (parent
);
1097 windows_or_buffers_changed
++;
1098 Vwindow_list
= Qnil
;
1099 frame
= XFRAME (WINDOW_FRAME (p
));
1100 FRAME_WINDOW_SIZES_CHANGED (frame
) = 1;
1102 /* Are we trying to delete any frame's selected window? */
1104 Lisp_Object frame
, pwindow
;
1106 /* See if the frame's selected window is either WINDOW
1107 or any subwindow of it, by finding all that window's parents
1108 and comparing each one with WINDOW. */
1109 frame
= WINDOW_FRAME (XWINDOW (window
));
1110 pwindow
= FRAME_SELECTED_WINDOW (XFRAME (frame
));
1112 while (!NILP (pwindow
))
1114 if (EQ (window
, pwindow
))
1116 pwindow
= XWINDOW (pwindow
)->parent
;
1119 if (EQ (window
, pwindow
))
1121 Lisp_Object alternative
;
1122 alternative
= Fnext_window (window
, Qlambda
, Qnil
);
1124 /* If we're about to delete the selected window on the
1125 selected frame, then we should use Fselect_window to select
1126 the new window. On the other hand, if we're about to
1127 delete the selected window on any other frame, we shouldn't do
1128 anything but set the frame's selected_window slot. */
1129 if (EQ (window
, selected_window
))
1130 Fselect_window (alternative
);
1132 FRAME_SELECTED_WINDOW (XFRAME (frame
)) = alternative
;
1137 /* tem is null for dummy parent windows
1138 (which have inferiors but not any contents themselves) */
1142 unchain_marker (p
->pointm
);
1143 unchain_marker (p
->start
);
1146 /* Free window glyph matrices. It is sure that they are allocated
1147 again when ADJUST_GLYPHS is called. Block input so that expose
1148 events and other events that access glyph matrices are not
1149 processed while we are changing them. */
1151 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (frame
)));
1155 XWINDOW (tem
)->prev
= p
->prev
;
1159 XWINDOW (tem
)->next
= p
->next
;
1161 if (EQ (window
, par
->hchild
))
1162 par
->hchild
= p
->next
;
1163 if (EQ (window
, par
->vchild
))
1164 par
->vchild
= p
->next
;
1166 /* Find one of our siblings to give our space to. */
1170 /* If p gives its space to its next sibling, that sibling needs
1171 to have its top/left side pulled back to where p's is.
1172 set_window_{height,width} will re-position the sibling's
1175 XWINDOW (sib
)->top
= p
->top
;
1176 XWINDOW (sib
)->left
= p
->left
;
1179 /* Stretch that sibling. */
1180 if (!NILP (par
->vchild
))
1181 set_window_height (sib
,
1182 XFASTINT (XWINDOW (sib
)->height
) + XFASTINT (p
->height
),
1184 if (!NILP (par
->hchild
))
1185 set_window_width (sib
,
1186 XFASTINT (XWINDOW (sib
)->width
) + XFASTINT (p
->width
),
1189 /* If parent now has only one child,
1190 put the child into the parent's place. */
1194 if (NILP (XWINDOW (tem
)->next
))
1195 replace_window (parent
, tem
);
1197 /* Since we may be deleting combination windows, we must make sure that
1198 not only p but all its children have been marked as deleted. */
1199 if (! NILP (p
->hchild
))
1200 delete_all_subwindows (XWINDOW (p
->hchild
));
1201 else if (! NILP (p
->vchild
))
1202 delete_all_subwindows (XWINDOW (p
->vchild
));
1204 /* Mark this window as deleted. */
1205 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
1207 /* Adjust glyph matrices. */
1208 adjust_glyphs (frame
);
1214 /***********************************************************************
1216 ***********************************************************************/
1218 /* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object
1219 pointer. This is a callback function for foreach_window, used in
1220 function window_list. */
1223 add_window_to_list (w
, user_data
)
1227 Lisp_Object
*list
= (Lisp_Object
*) user_data
;
1229 XSETWINDOW (window
, w
);
1230 *list
= Fcons (window
, *list
);
1235 /* Return a list of all windows, for use by next_window. If
1236 Vwindow_list is a list, return that list. Otherwise, build a new
1237 list, cache it in Vwindow_list, and return that. */
1242 if (!CONSP (Vwindow_list
))
1246 Vwindow_list
= Qnil
;
1247 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
1249 Lisp_Object args
[2];
1251 /* We are visiting windows in canonical order, and add
1252 new windows at the front of args[1], which means we
1253 have to reverse this list at the end. */
1255 foreach_window (XFRAME (XCAR (tail
)), add_window_to_list
, &args
[1]);
1256 args
[0] = Vwindow_list
;
1257 args
[1] = Fnreverse (args
[1]);
1258 Vwindow_list
= Fnconc (2, args
);
1262 return Vwindow_list
;
1266 /* Value is non-zero if WINDOW satisfies the constraints given by
1267 OWINDOW, MINIBUF and ALL_FRAMES.
1269 MINIBUF t means WINDOW may be minibuffer windows.
1270 `lambda' means WINDOW may not be a minibuffer window.
1271 a window means a specific minibuffer window
1273 ALL_FRAMES t means search all frames,
1274 nil means search just current frame,
1275 `visible' means search just visible frames,
1276 0 means search visible and iconified frames,
1277 a window means search the frame that window belongs to,
1278 a frame means consider windows on that frame, only. */
1281 candidate_window_p (window
, owindow
, minibuf
, all_frames
)
1282 Lisp_Object window
, owindow
, minibuf
, all_frames
;
1284 struct window
*w
= XWINDOW (window
);
1285 struct frame
*f
= XFRAME (w
->frame
);
1286 int candidate_p
= 1;
1288 if (!BUFFERP (w
->buffer
))
1290 else if (MINI_WINDOW_P (w
)
1291 && (EQ (minibuf
, Qlambda
)
1292 || (WINDOWP (minibuf
) && !EQ (minibuf
, window
))))
1294 /* If MINIBUF is `lambda' don't consider any mini-windows.
1295 If it is a window, consider only that one. */
1298 else if (EQ (all_frames
, Qt
))
1300 else if (NILP (all_frames
))
1302 xassert (WINDOWP (owindow
));
1303 candidate_p
= EQ (w
->frame
, XWINDOW (owindow
)->frame
);
1305 else if (EQ (all_frames
, Qvisible
))
1307 FRAME_SAMPLE_VISIBILITY (f
);
1308 candidate_p
= FRAME_VISIBLE_P (f
);
1310 else if (INTEGERP (all_frames
) && XINT (all_frames
) == 0)
1312 FRAME_SAMPLE_VISIBILITY (f
);
1313 candidate_p
= FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
);
1315 else if (WINDOWP (all_frames
))
1316 candidate_p
= (EQ (FRAME_MINIBUF_WINDOW (f
), all_frames
)
1317 || EQ (XWINDOW (all_frames
)->frame
, w
->frame
)
1318 || EQ (XWINDOW (all_frames
)->frame
, FRAME_FOCUS_FRAME (f
)));
1319 else if (FRAMEP (all_frames
))
1320 candidate_p
= EQ (all_frames
, w
->frame
);
1326 /* Decode arguments as allowed by Fnext_window, Fprevious_window, and
1327 Fwindow_list. See there for the meaning of WINDOW, MINIBUF, and
1331 decode_next_window_args (window
, minibuf
, all_frames
)
1332 Lisp_Object
*window
, *minibuf
, *all_frames
;
1335 *window
= selected_window
;
1337 CHECK_LIVE_WINDOW (*window
, 0);
1339 /* MINIBUF nil may or may not include minibuffers. Decide if it
1341 if (NILP (*minibuf
))
1342 *minibuf
= minibuf_level
? minibuf_window
: Qlambda
;
1343 else if (!EQ (*minibuf
, Qt
))
1346 /* Now *MINIBUF can be t => count all minibuffer windows, `lambda'
1347 => count none of them, or a specific minibuffer window (the
1348 active one) to count. */
1350 /* ALL_FRAMES nil doesn't specify which frames to include. */
1351 if (NILP (*all_frames
))
1352 *all_frames
= (!EQ (*minibuf
, Qlambda
)
1353 ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window
)->frame
))
1355 else if (EQ (*all_frames
, Qvisible
))
1357 else if (XFASTINT (*all_frames
) == 0)
1359 else if (FRAMEP (*all_frames
))
1361 else if (!EQ (*all_frames
, Qt
))
1364 /* Now *ALL_FRAMES is t meaning search all frames, nil meaning
1365 search just current frame, `visible' meaning search just visible
1366 frames, 0 meaning search visible and iconified frames, or a
1367 window, meaning search the frame that window belongs to, or a
1368 frame, meaning consider windows on that frame, only. */
1372 /* Return the next or previous window of WINDOW in canonical ordering
1373 of windows. NEXT_P non-zero means return the next window. See the
1374 documentation string of next-window for the meaning of MINIBUF and
1378 next_window (window
, minibuf
, all_frames
, next_p
)
1379 Lisp_Object window
, minibuf
, all_frames
;
1382 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1384 /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just
1385 return the first window on the frame. */
1386 if (FRAMEP (all_frames
)
1387 && !EQ (all_frames
, XWINDOW (window
)->frame
))
1388 return Fframe_first_window (all_frames
);
1394 /* Find WINDOW in the list of all windows. */
1395 list
= Fmemq (window
, window_list ());
1397 /* Scan forward from WINDOW to the end of the window list. */
1399 for (list
= XCDR (list
); CONSP (list
); list
= XCDR (list
))
1400 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1403 /* Scan from the start of the window list up to WINDOW. */
1405 for (list
= Vwindow_list
;
1406 CONSP (list
) && !EQ (XCAR (list
), window
);
1408 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1412 window
= XCAR (list
);
1416 Lisp_Object candidate
, list
;
1418 /* Scan through the list of windows for candidates. If there are
1419 candidate windows in front of WINDOW, the last one of these
1420 is the one we want. If there are candidates following WINDOW
1421 in the list, again the last one of these is the one we want. */
1423 for (list
= window_list (); CONSP (list
); list
= XCDR (list
))
1425 if (EQ (XCAR (list
), window
))
1427 if (WINDOWP (candidate
))
1430 else if (candidate_window_p (XCAR (list
), window
, minibuf
,
1432 candidate
= XCAR (list
);
1435 if (WINDOWP (candidate
))
1443 /* This comment supplies the doc string for `next-window',
1444 for make-docfile to see. We cannot put this in the real DEFUN
1445 due to limits in the Unix cpp.
1447 DEFUN ("next-window", Ffoo, Sfoo, 0, 3, 0,
1448 "Return next window after WINDOW in canonical ordering of windows.\n\
1449 If omitted, WINDOW defaults to the selected window.\n\
1451 Optional second arg MINIBUF t means count the minibuffer window even\n\
1452 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1453 it is active. MINIBUF neither t nor nil means not to count the\n\
1454 minibuffer even if it is active.\n\
1456 Several frames may share a single minibuffer; if the minibuffer\n\
1457 counts, all windows on all frames that share that minibuffer count\n\
1458 too. Therefore, `next-window' can be used to iterate through the\n\
1459 set of windows even when the minibuffer is on another frame. If the\n\
1460 minibuffer does not count, only windows from WINDOW's frame count.\n\
1462 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1463 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1464 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1465 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1466 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1467 Anything else means restrict to WINDOW's frame.\n\
1469 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1470 `next-window' to iterate through the entire cycle of acceptable\n\
1471 windows, eventually ending up back at the window you started with.\n\
1472 `previous-window' traverses the same cycle, in the reverse order.")
1473 (window, minibuf, all_frames) */
1475 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
1477 (window
, minibuf
, all_frames
)
1478 Lisp_Object window
, minibuf
, all_frames
;
1480 return next_window (window
, minibuf
, all_frames
, 1);
1484 /* This comment supplies the doc string for `previous-window',
1485 for make-docfile to see. We cannot put this in the real DEFUN
1486 due to limits in the Unix cpp.
1488 DEFUN ("previous-window", Ffoo, Sfoo, 0, 3, 0,
1489 "Return the window preceding WINDOW in canonical ordering of windows.\n\
1490 If omitted, WINDOW defaults to the selected window.\n\
1492 Optional second arg MINIBUF t means count the minibuffer window even\n\
1493 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1494 it is active. MINIBUF neither t nor nil means not to count the\n\
1495 minibuffer even if it is active.\n\
1497 Several frames may share a single minibuffer; if the minibuffer\n\
1498 counts, all windows on all frames that share that minibuffer count\n\
1499 too. Therefore, `previous-window' can be used to iterate through\n\
1500 the set of windows even when the minibuffer is on another frame. If\n\
1501 the minibuffer does not count, only windows from WINDOW's frame count\n\
1503 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1504 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1505 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1506 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1507 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1508 Anything else means restrict to WINDOW's frame.\n\
1510 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1511 `previous-window' to iterate through the entire cycle of acceptable\n\
1512 windows, eventually ending up back at the window you started with.\n\
1513 `next-window' traverses the same cycle, in the reverse order.")
1514 (window, minibuf, all_frames) */
1517 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
1519 (window
, minibuf
, all_frames
)
1520 Lisp_Object window
, minibuf
, all_frames
;
1522 return next_window (window
, minibuf
, all_frames
, 0);
1526 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1527 "Select the ARG'th different window on this frame.\n\
1528 All windows on current frame are arranged in a cyclic order.\n\
1529 This command selects the window ARG steps away in that order.\n\
1530 A negative ARG moves in the opposite order. If the optional second\n\
1531 argument ALL_FRAMES is non-nil, cycle through all frames.")
1533 Lisp_Object arg
, all_frames
;
1538 CHECK_NUMBER (arg
, 0);
1539 window
= selected_window
;
1541 for (i
= XINT (arg
); i
> 0; --i
)
1542 window
= Fnext_window (window
, Qnil
, all_frames
);
1544 window
= Fprevious_window (window
, Qnil
, all_frames
);
1546 Fselect_window (window
);
1551 DEFUN ("window-list", Fwindow_list
, Swindow_list
, 0, 3, 0,
1552 "Return a list of windows in canonical ordering.\n\
1553 Arguments are like for `next-window'.")
1554 (window
, minibuf
, all_frames
)
1555 Lisp_Object window
, minibuf
, all_frames
;
1557 Lisp_Object tail
, list
;
1559 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1562 for (tail
= window_list (); CONSP (tail
); tail
= XCDR (tail
))
1563 if (candidate_window_p (XCAR (tail
), window
, minibuf
, all_frames
))
1564 list
= Fcons (XCAR (tail
), list
);
1566 return Fnreverse (list
);
1571 /* Look at all windows, performing an operation specified by TYPE
1573 If FRAMES is Qt, look at all frames;
1574 Qnil, look at just the selected frame;
1575 Qvisible, look at visible frames;
1576 a frame, just look at windows on that frame.
1577 If MINI is non-zero, perform the operation on minibuffer windows too.
1583 GET_BUFFER_WINDOW
, /* Arg is buffer */
1584 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1585 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1586 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1588 UNSHOW_BUFFER
, /* Arg is buffer */
1593 window_loop (type
, obj
, mini
, frames
)
1594 enum window_loop type
;
1595 Lisp_Object obj
, frames
;
1598 Lisp_Object window
, windows
, best_window
, frame_arg
;
1600 struct gcpro gcpro1
;
1602 /* If we're only looping through windows on a particular frame,
1603 frame points to that frame. If we're looping through windows
1604 on all frames, frame is 0. */
1605 if (FRAMEP (frames
))
1606 f
= XFRAME (frames
);
1607 else if (NILP (frames
))
1608 f
= SELECTED_FRAME ();
1613 frame_arg
= Qlambda
;
1614 else if (XFASTINT (frames
) == 0)
1616 else if (EQ (frames
, Qvisible
))
1621 /* frame_arg is Qlambda to stick to one frame,
1622 Qvisible to consider all visible frames,
1625 /* Pick a window to start with. */
1629 window
= FRAME_SELECTED_WINDOW (f
);
1631 window
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
1633 /* Figure out the last window we're going to mess with. Since
1634 Fnext_window, given the same options, is guaranteed to go in a
1635 ring, we can just use Fprevious_window to find the last one.
1637 We can't just wait until we hit the first window again, because
1638 it might be deleted. */
1640 windows
= Fwindow_list (window
, mini
? Qt
: Qnil
, frame_arg
);
1644 for (; CONSP (windows
); windows
= CDR (windows
))
1648 window
= XCAR (windows
);
1649 w
= XWINDOW (window
);
1651 /* Note that we do not pay attention here to whether the frame
1652 is visible, since Fwindow_list skips non-visible frames if
1653 that is desired, under the control of frame_arg. */
1654 if (!MINI_WINDOW_P (w
)
1655 /* For UNSHOW_BUFFER, we must always consider all windows. */
1656 || type
== UNSHOW_BUFFER
1657 || (mini
&& minibuf_level
> 0))
1660 case GET_BUFFER_WINDOW
:
1661 if (EQ (w
->buffer
, obj
)
1662 /* Don't find any minibuffer window
1663 except the one that is currently in use. */
1664 && (MINI_WINDOW_P (w
)
1665 ? EQ (window
, minibuf_window
)
1673 case GET_LRU_WINDOW
:
1674 /* t as arg means consider only full-width windows */
1675 if (!NILP (obj
) && !WINDOW_FULL_WIDTH_P (w
))
1677 /* Ignore dedicated windows and minibuffers. */
1678 if (MINI_WINDOW_P (w
) || !NILP (w
->dedicated
))
1680 if (NILP (best_window
)
1681 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1682 > XFASTINT (w
->use_time
)))
1683 best_window
= window
;
1686 case DELETE_OTHER_WINDOWS
:
1687 if (!EQ (window
, obj
))
1688 Fdelete_window (window
);
1691 case DELETE_BUFFER_WINDOWS
:
1692 if (EQ (w
->buffer
, obj
))
1694 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1696 /* If this window is dedicated, and in a frame of its own,
1698 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
1699 && !NILP (w
->dedicated
)
1700 && other_visible_frames (f
))
1702 /* Skip the other windows on this frame.
1703 There might be one, the minibuffer! */
1704 while (CONSP (XCDR (windows
))
1705 && EQ (XWINDOW (XCAR (windows
))->frame
,
1706 XWINDOW (XCAR (XCDR (windows
)))->frame
))
1707 windows
= XCDR (windows
);
1709 /* Now we can safely delete the frame. */
1710 Fdelete_frame (w
->frame
, Qnil
);
1712 else if (NILP (w
->parent
))
1714 /* If we're deleting the buffer displayed in the
1715 only window on the frame, find a new buffer to
1718 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
1720 buffer
= Fget_buffer_create (build_string ("*scratch*"));
1721 Fset_window_buffer (window
, buffer
);
1722 if (EQ (window
, selected_window
))
1723 Fset_buffer (w
->buffer
);
1726 Fdelete_window (window
);
1730 case GET_LARGEST_WINDOW
:
1732 /* Ignore dedicated windows and minibuffers. */
1733 if (MINI_WINDOW_P (w
) || !NILP (w
->dedicated
))
1736 if (NILP (best_window
))
1737 best_window
= window
;
1740 struct window
*b
= XWINDOW (best_window
);
1741 if (XFASTINT (w
->height
) * XFASTINT (w
->width
)
1742 > XFASTINT (b
->height
) * XFASTINT (b
->width
))
1743 best_window
= window
;
1749 if (EQ (w
->buffer
, obj
))
1752 struct frame
*f
= XFRAME (w
->frame
);
1754 /* Find another buffer to show in this window. */
1755 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
1757 buffer
= Fget_buffer_create (build_string ("*scratch*"));
1759 /* If this window is dedicated, and in a frame of its own,
1761 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
1762 && !NILP (w
->dedicated
)
1763 && other_visible_frames (f
))
1765 /* Skip the other windows on this frame.
1766 There might be one, the minibuffer! */
1767 while (CONSP (XCDR (windows
))
1768 && EQ (XWINDOW (XCAR (windows
))->frame
,
1769 XWINDOW (XCAR (XCDR (windows
)))->frame
))
1770 windows
= XCDR (windows
);
1772 /* Now we can safely delete the frame. */
1773 Fdelete_frame (w
->frame
, Qnil
);
1777 /* Otherwise show a different buffer in the window. */
1778 w
->dedicated
= Qnil
;
1779 Fset_window_buffer (window
, buffer
);
1780 if (EQ (window
, selected_window
))
1781 Fset_buffer (w
->buffer
);
1786 /* Check for a window that has a killed buffer. */
1787 case CHECK_ALL_WINDOWS
:
1788 if (! NILP (w
->buffer
)
1789 && NILP (XBUFFER (w
->buffer
)->name
))
1793 case WINDOW_LOOP_UNUSED
:
1802 /* Used for debugging. Abort if any window has a dead buffer. */
1805 check_all_windows ()
1807 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
1810 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1811 "Return the window least recently selected or used for display.\n\
1812 If optional argument FRAME is `visible', search all visible frames.\n\
1813 If FRAME is 0, search all visible and iconified frames.\n\
1814 If FRAME is t, search all frames.\n\
1815 If FRAME is nil, search only the selected frame.\n\
1816 If FRAME is a frame, search only that frame.")
1820 register Lisp_Object w
;
1821 /* First try for a window that is full-width */
1822 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frame
);
1823 if (!NILP (w
) && !EQ (w
, selected_window
))
1825 /* If none of them, try the rest */
1826 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frame
);
1829 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1830 "Return the largest window in area.\n\
1831 If optional argument FRAME is `visible', search all visible frames.\n\
1832 If FRAME is 0, search all visible and iconified frames.\n\
1833 If FRAME is t, search all frames.\n\
1834 If FRAME is nil, search only the selected frame.\n\
1835 If FRAME is a frame, search only that frame.")
1839 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
1843 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
1844 "Return a window currently displaying BUFFER, or nil if none.\n\
1845 If optional argument FRAME is `visible', search all visible frames.\n\
1846 If optional argument FRAME is 0, search all visible and iconified frames.\n\
1847 If FRAME is t, search all frames.\n\
1848 If FRAME is nil, search only the selected frame.\n\
1849 If FRAME is a frame, search only that frame.")
1851 Lisp_Object buffer
, frame
;
1853 buffer
= Fget_buffer (buffer
);
1854 if (BUFFERP (buffer
))
1855 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
1860 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
1862 "Make WINDOW (or the selected window) fill its frame.\n\
1863 Only the frame WINDOW is on is affected.\n\
1864 This function tries to reduce display jumps\n\
1865 by keeping the text previously visible in WINDOW\n\
1866 in the same place on the frame. Doing this depends on\n\
1867 the value of (window-start WINDOW), so if calling this function\n\
1868 in a program gives strange scrolling, make sure the window-start\n\
1869 value is reasonable when this function is called.")
1878 window
= selected_window
;
1880 CHECK_LIVE_WINDOW (window
, 0);
1882 w
= XWINDOW (window
);
1884 startpos
= marker_position (w
->start
);
1885 top
= XFASTINT (w
->top
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
1887 if (MINI_WINDOW_P (w
) && top
> 0)
1888 error ("Can't expand minibuffer to full frame");
1890 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
1892 /* Try to minimize scrolling, by setting the window start to the point
1893 will cause the text at the old window start to be at the same place
1894 on the frame. But don't try to do this if the window start is
1895 outside the visible portion (as might happen when the display is
1896 not current, due to typeahead). */
1897 if (startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
1898 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
1900 struct position pos
;
1901 struct buffer
*obuf
= current_buffer
;
1903 Fset_buffer (w
->buffer
);
1904 /* This computation used to temporarily move point, but that can
1905 have unwanted side effects due to text properties. */
1906 pos
= *vmotion (startpos
, -top
, w
);
1908 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
1909 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
1910 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
1912 /* We need to do this, so that the window-scroll-functions
1914 w
->optional_new_start
= Qt
;
1916 set_buffer_internal (obuf
);
1922 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
1923 1, 2, "bDelete windows on (buffer): ",
1924 "Delete all windows showing BUFFER.\n\
1925 Optional second argument FRAME controls which frames are affected.\n\
1926 If optional argument FRAME is `visible', search all visible frames.\n\
1927 If FRAME is 0, search all visible and iconified frames.\n\
1928 If FRAME is nil, search all frames.\n\
1929 If FRAME is t, search only the selected frame.\n\
1930 If FRAME is a frame, search only that frame.")
1932 Lisp_Object buffer
, frame
;
1934 /* FRAME uses t and nil to mean the opposite of what window_loop
1938 else if (EQ (frame
, Qt
))
1943 buffer
= Fget_buffer (buffer
);
1944 CHECK_BUFFER (buffer
, 0);
1945 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
1951 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
1952 Sreplace_buffer_in_windows
,
1953 1, 1, "bReplace buffer in windows: ",
1954 "Replace BUFFER with some other buffer in all windows showing it.")
1960 buffer
= Fget_buffer (buffer
);
1961 CHECK_BUFFER (buffer
, 0);
1962 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
1967 /* Replace BUFFER with some other buffer in all windows
1968 of all frames, even those on other keyboards. */
1971 replace_buffer_in_all_windows (buffer
)
1975 Lisp_Object tail
, frame
;
1977 /* A single call to window_loop won't do the job
1978 because it only considers frames on the current keyboard.
1979 So loop manually over frames, and handle each one. */
1980 FOR_EACH_FRAME (tail
, frame
)
1981 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
1983 window_loop (UNSHOW_BUFFER
, buffer
, 1, Qt
);
1987 /* Set the height of WINDOW and all its inferiors. */
1989 /* The smallest acceptable dimensions for a window. Anything smaller
1990 might crash Emacs. */
1992 #define MIN_SAFE_WINDOW_WIDTH (2)
1993 #define MIN_SAFE_WINDOW_HEIGHT (2)
1995 /* Make sure that window_min_height and window_min_width are
1996 not too small; if they are, set them to safe minima. */
1999 check_min_window_sizes ()
2001 /* Smaller values might permit a crash. */
2002 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
2003 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
2004 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
2005 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
2008 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
2009 minimum allowable size. */
2012 check_frame_size (frame
, rows
, cols
)
2016 /* For height, we have to see:
2017 whether the frame has a minibuffer,
2018 whether it wants a mode line, and
2019 whether it has a menu bar. */
2021 (FRAME_MINIBUF_ONLY_P (frame
) ? MIN_SAFE_WINDOW_HEIGHT
- 1
2022 : (! FRAME_HAS_MINIBUF_P (frame
)) ? MIN_SAFE_WINDOW_HEIGHT
2023 : 2 * MIN_SAFE_WINDOW_HEIGHT
- 1);
2025 if (FRAME_TOP_MARGIN (frame
) > 0)
2026 min_height
+= FRAME_TOP_MARGIN (frame
);
2028 if (*rows
< min_height
)
2030 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
2031 *cols
= MIN_SAFE_WINDOW_WIDTH
;
2035 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
2036 check if W's width can be changed, otherwise check W's height.
2037 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
2038 siblings, too. If none of the siblings is resizable, WINDOW isn't
2042 window_fixed_size_p (w
, width_p
, check_siblings_p
)
2044 int width_p
, check_siblings_p
;
2049 if (!NILP (w
->hchild
))
2051 c
= XWINDOW (w
->hchild
);
2055 /* A horiz. combination is fixed-width if all of if its
2057 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2058 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2059 fixed_p
= c
== NULL
;
2063 /* A horiz. combination is fixed-height if one of if its
2065 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2066 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2067 fixed_p
= c
!= NULL
;
2070 else if (!NILP (w
->vchild
))
2072 c
= XWINDOW (w
->vchild
);
2076 /* A vert. combination is fixed-width if one of if its
2078 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2079 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2080 fixed_p
= c
!= NULL
;
2084 /* A vert. combination is fixed-height if all of if its
2086 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2087 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2088 fixed_p
= c
== NULL
;
2091 else if (BUFFERP (w
->buffer
))
2093 if (w
->height_fixed_p
&& !width_p
)
2097 struct buffer
*old
= current_buffer
;
2100 current_buffer
= XBUFFER (w
->buffer
);
2101 val
= find_symbol_value (Qwindow_size_fixed
);
2102 current_buffer
= old
;
2105 if (!EQ (val
, Qunbound
))
2107 fixed_p
= !NILP (val
);
2110 && ((EQ (val
, Qheight
) && width_p
)
2111 || (EQ (val
, Qwidth
) && !width_p
)))
2116 /* Can't tell if this one is resizable without looking at
2117 siblings. If all siblings are fixed-size this one is too. */
2118 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
2122 for (child
= w
->prev
; !NILP (child
); child
= XWINDOW (child
)->prev
)
2123 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2127 for (child
= w
->next
; !NILP (child
); child
= XWINDOW (child
)->next
)
2128 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2142 /* Return the minimum size of window W, not taking fixed-width windows
2143 into account. WIDTH_P non-zero means return the minimum width,
2144 otherwise return the minimum height. If W is a combination window,
2145 compute the minimum size from the minimum sizes of W's children. */
2148 window_min_size_1 (w
, width_p
)
2155 if (!NILP (w
->hchild
))
2157 c
= XWINDOW (w
->hchild
);
2162 /* The min width of a horizontal combination is
2163 the sum of the min widths of its children. */
2166 size
+= window_min_size_1 (c
, width_p
);
2167 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2172 /* The min height a horizontal combination equals
2173 the maximum of all min height of its children. */
2176 int min_size
= window_min_size_1 (c
, width_p
);
2177 size
= max (min_size
, size
);
2178 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2182 else if (!NILP (w
->vchild
))
2184 c
= XWINDOW (w
->vchild
);
2189 /* The min width of a vertical combination is
2190 the maximum of the min widths of its children. */
2193 int min_size
= window_min_size_1 (c
, width_p
);
2194 size
= max (min_size
, size
);
2195 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2200 /* The min height of a vertical combination equals
2201 the sum of the min height of its children. */
2204 size
+= window_min_size_1 (c
, width_p
);
2205 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2212 size
= window_min_width
;
2215 if (MINI_WINDOW_P (w
)
2216 || (!WINDOW_WANTS_MODELINE_P (w
)
2217 && !WINDOW_WANTS_HEADER_LINE_P (w
)))
2220 size
= window_min_height
;
2228 /* Return the minimum size of window W, taking fixed-size windows into
2229 account. WIDTH_P non-zero means return the minimum width,
2230 otherwise return the minimum height. IGNORE_FIXED_P non-zero means
2231 ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size
2232 unless FIXED is null. */
2235 window_min_size (w
, width_p
, ignore_fixed_p
, fixed
)
2237 int width_p
, ignore_fixed_p
, *fixed
;
2244 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
2250 size
= width_p
? XFASTINT (w
->width
) : XFASTINT (w
->height
);
2252 size
= window_min_size_1 (w
, width_p
);
2258 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
2259 WINDOW's width. Resize WINDOW's children, if any, so that they
2260 keep their proportionate size relative to WINDOW. Propagate
2261 WINDOW's top or left edge position to children. Delete windows
2262 that become too small unless NODELETE_P is non-zero. */
2265 size_window (window
, size
, width_p
, nodelete_p
)
2267 int size
, width_p
, nodelete_p
;
2269 struct window
*w
= XWINDOW (window
);
2271 Lisp_Object child
, *forward
, *sideward
;
2272 int old_size
, min_size
;
2274 check_min_window_sizes ();
2275 size
= max (0, size
);
2277 /* If the window has been "too small" at one point,
2278 don't delete it for being "too small" in the future.
2279 Preserve it as long as that is at all possible. */
2282 old_size
= XINT (w
->width
);
2283 min_size
= window_min_width
;
2287 old_size
= XINT (w
->height
);
2288 min_size
= window_min_height
;
2291 if (old_size
< window_min_width
)
2292 w
->too_small_ok
= Qt
;
2294 /* Maybe delete WINDOW if it's too small. */
2295 if (!nodelete_p
&& !NILP (w
->parent
))
2299 if (!MINI_WINDOW_P (w
) && !NILP (w
->too_small_ok
))
2300 min_size
= width_p
? MIN_SAFE_WINDOW_WIDTH
: MIN_SAFE_WINDOW_HEIGHT
;
2302 min_size
= width_p
? window_min_width
: window_min_height
;
2304 if (size
< min_size
)
2306 delete_window (window
);
2311 /* Set redisplay hints. */
2312 w
->last_modified
= make_number (0);
2313 w
->last_overlay_modified
= make_number (0);
2314 windows_or_buffers_changed
++;
2315 FRAME_WINDOW_SIZES_CHANGED (XFRAME (w
->frame
)) = 1;
2319 sideward
= &w
->vchild
;
2320 forward
= &w
->hchild
;
2321 w
->width
= make_number (size
);
2325 sideward
= &w
->hchild
;
2326 forward
= &w
->vchild
;
2327 w
->height
= make_number (size
);
2330 if (!NILP (*sideward
))
2332 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
2334 c
= XWINDOW (child
);
2339 size_window (child
, size
, width_p
, nodelete_p
);
2342 else if (!NILP (*forward
))
2344 int fixed_size
, each
, extra
, n
;
2345 int resize_fixed_p
, nfixed
;
2346 int last_pos
, first_pos
, nchildren
, total
;
2348 /* Determine the fixed-size portion of the this window, and the
2349 number of child windows. */
2350 fixed_size
= nchildren
= nfixed
= total
= 0;
2351 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
2355 c
= XWINDOW (child
);
2356 child_size
= width_p
? XINT (c
->width
) : XINT (c
->height
);
2357 total
+= child_size
;
2359 if (window_fixed_size_p (c
, width_p
, 0))
2361 fixed_size
+= child_size
;
2366 /* If the new size is smaller than fixed_size, or if there
2367 aren't any resizable windows, allow resizing fixed-size
2369 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
2371 /* Compute how many lines/columns to add to each child. The
2372 value of extra takes care of rounding errors. */
2373 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
2374 each
= (size
- total
) / n
;
2375 extra
= (size
- total
) - n
* each
;
2377 /* Compute new children heights and edge positions. */
2378 first_pos
= width_p
? XINT (w
->left
) : XINT (w
->top
);
2379 last_pos
= first_pos
;
2380 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2382 int new_size
, old_size
;
2384 c
= XWINDOW (child
);
2385 old_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2386 new_size
= old_size
;
2388 /* The top or left edge position of this child equals the
2389 bottom or right edge of its predecessor. */
2391 c
->left
= make_number (last_pos
);
2393 c
->top
= make_number (last_pos
);
2395 /* If this child can be resized, do it. */
2396 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
2398 new_size
= old_size
+ each
+ extra
;
2402 /* Set new height. Note that size_window also propagates
2403 edge positions to children, so it's not a no-op if we
2404 didn't change the child's size. */
2405 size_window (child
, new_size
, width_p
, 1);
2407 /* Remember the bottom/right edge position of this child; it
2408 will be used to set the top/left edge of the next child. */
2409 last_pos
+= new_size
;
2412 /* We should have covered the parent exactly with child windows. */
2413 xassert (size
== last_pos
- first_pos
);
2415 /* Now delete any children that became too small. */
2417 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2420 c
= XWINDOW (child
);
2421 child_size
= width_p
? XINT (c
->width
) : XINT (c
->height
);
2422 size_window (child
, child_size
, width_p
, 0);
2427 /* Set WINDOW's height to HEIGHT, and recursively change the height of
2428 WINDOW's children. NODELETE non-zero means don't delete windows
2429 that become too small in the process. (The caller should check
2430 later and do so if appropriate.) */
2433 set_window_height (window
, height
, nodelete
)
2438 size_window (window
, height
, 0, nodelete
);
2442 /* Set WINDOW's width to WIDTH, and recursively change the width of
2443 WINDOW's children. NODELETE non-zero means don't delete windows
2444 that become too small in the process. (The caller should check
2445 later and do so if appropriate.) */
2448 set_window_width (window
, width
, nodelete
)
2453 size_window (window
, width
, 1, nodelete
);
2457 int window_select_count
;
2460 Fset_window_buffer_unwind (obuf
)
2468 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
2469 means it's allowed to run hooks. See make_frame for a case where
2470 it's not allowed. */
2473 set_window_buffer (window
, buffer
, run_hooks_p
)
2474 Lisp_Object window
, buffer
;
2477 struct window
*w
= XWINDOW (window
);
2478 struct buffer
*b
= XBUFFER (buffer
);
2479 int count
= specpdl_ptr
- specpdl
;
2483 if (EQ (window
, selected_window
))
2484 b
->last_selected_window
= window
;
2486 /* Update time stamps of buffer display. */
2487 if (INTEGERP (b
->display_count
))
2488 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
2489 b
->display_time
= Fcurrent_time ();
2491 XSETFASTINT (w
->window_end_pos
, 0);
2492 XSETFASTINT (w
->window_end_vpos
, 0);
2493 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
2494 w
->window_end_valid
= Qnil
;
2495 XSETFASTINT (w
->hscroll
, 0);
2496 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
2497 set_marker_restricted (w
->start
,
2498 make_number (b
->last_window_start
),
2500 w
->start_at_line_beg
= Qnil
;
2501 w
->force_start
= Qnil
;
2502 XSETFASTINT (w
->last_modified
, 0);
2503 XSETFASTINT (w
->last_overlay_modified
, 0);
2504 windows_or_buffers_changed
++;
2506 /* We must select BUFFER for running the window-scroll-functions.
2507 If WINDOW is selected, switch permanently.
2508 Otherwise, switch but go back to the ambient buffer afterward. */
2509 if (EQ (window
, selected_window
))
2510 Fset_buffer (buffer
);
2511 /* We can't check ! NILP (Vwindow_scroll_functions) here
2512 because that might itself be a local variable. */
2513 else if (window_initialized
)
2515 record_unwind_protect (Fset_window_buffer_unwind
, Fcurrent_buffer ());
2516 Fset_buffer (buffer
);
2519 /* Set left and right marginal area width from buffer. */
2520 Fset_window_margins (window
, b
->left_margin_width
, b
->right_margin_width
);
2524 if (! NILP (Vwindow_scroll_functions
))
2525 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2526 Fmarker_position (w
->start
));
2528 if (! NILP (Vwindow_configuration_change_hook
)
2529 && ! NILP (Vrun_hooks
))
2530 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
2533 unbind_to (count
, Qnil
);
2537 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 2, 0,
2538 "Make WINDOW display BUFFER as its contents.\n\
2539 BUFFER can be a buffer or buffer name.")
2541 register Lisp_Object window
, buffer
;
2543 register Lisp_Object tem
;
2544 register struct window
*w
= decode_window (window
);
2546 XSETWINDOW (window
, w
);
2547 buffer
= Fget_buffer (buffer
);
2548 CHECK_BUFFER (buffer
, 1);
2550 if (NILP (XBUFFER (buffer
)->name
))
2551 error ("Attempt to display deleted buffer");
2555 error ("Window is deleted");
2556 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
2557 is first being set up. */
2559 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
2560 error ("Window is dedicated to `%s'",
2561 XSTRING (XBUFFER (tem
)->name
)->data
);
2566 set_window_buffer (window
, buffer
, 1);
2570 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 1, 0,
2571 "Select WINDOW. Most editing will apply to WINDOW's buffer.\n\
2572 If WINDOW is not already selected, also make WINDOW's buffer current.\n\
2573 Note that the main editor command loop\n\
2574 selects the buffer of the selected window before each command.")
2576 register Lisp_Object window
;
2578 return select_window_1 (window
, 1);
2581 /* Note that selected_window can be nil
2582 when this is called from Fset_window_configuration. */
2585 select_window_1 (window
, recordflag
)
2586 register Lisp_Object window
;
2589 register struct window
*w
;
2590 register struct window
*ow
;
2593 CHECK_LIVE_WINDOW (window
, 0);
2595 w
= XWINDOW (window
);
2597 if (NILP (w
->buffer
))
2598 error ("Trying to select deleted window or non-leaf window");
2600 XSETFASTINT (w
->use_time
, ++window_select_count
);
2601 if (EQ (window
, selected_window
))
2604 if (!NILP (selected_window
))
2606 ow
= XWINDOW (selected_window
);
2607 if (! NILP (ow
->buffer
))
2608 set_marker_both (ow
->pointm
, ow
->buffer
,
2609 BUF_PT (XBUFFER (ow
->buffer
)),
2610 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
2613 selected_window
= window
;
2614 sf
= SELECTED_FRAME ();
2615 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
2617 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
2618 /* Use this rather than Fhandle_switch_frame
2619 so that FRAME_FOCUS_FRAME is moved appropriately as we
2620 move around in the state where a minibuffer in a separate
2622 Fselect_frame (WINDOW_FRAME (w
), Qnil
);
2625 sf
->selected_window
= window
;
2628 record_buffer (w
->buffer
);
2629 Fset_buffer (w
->buffer
);
2631 XBUFFER (w
->buffer
)->last_selected_window
= window
;
2633 /* Go to the point recorded in the window.
2634 This is important when the buffer is in more
2635 than one window. It also matters when
2636 redisplay_window has altered point after scrolling,
2637 because it makes the change only in the window. */
2639 register int new_point
= marker_position (w
->pointm
);
2640 if (new_point
< BEGV
)
2642 else if (new_point
> ZV
)
2648 windows_or_buffers_changed
++;
2652 /* Deiconify the frame containing the window WINDOW,
2653 unless it is the selected frame;
2656 The reason for the exception for the selected frame
2657 is that it seems better not to change the selected frames visibility
2658 merely because of displaying a different buffer in it.
2659 The deiconification is useful when a buffer gets shown in
2660 another frame that you were not using lately. */
2663 display_buffer_1 (window
)
2666 Lisp_Object frame
= XWINDOW (window
)->frame
;
2667 FRAME_PTR f
= XFRAME (frame
);
2669 FRAME_SAMPLE_VISIBILITY (f
);
2671 if (!EQ (frame
, selected_frame
))
2673 if (FRAME_ICONIFIED_P (f
))
2674 Fmake_frame_visible (frame
);
2675 else if (FRAME_VISIBLE_P (f
))
2676 Fraise_frame (frame
);
2682 DEFUN ("special-display-p", Fspecial_display_p
, Sspecial_display_p
, 1, 1, 0,
2683 "Returns non-nil if a buffer named BUFFER-NAME would be created specially.\n\
2684 The value is actually t if the frame should be called with default frame\n\
2685 parameters, and a list of frame parameters if they were specified.\n\
2686 See `special-display-buffer-names', and `special-display-regexps'.")
2688 Lisp_Object buffer_name
;
2692 CHECK_STRING (buffer_name
, 1);
2694 tem
= Fmember (buffer_name
, Vspecial_display_buffer_names
);
2698 tem
= Fassoc (buffer_name
, Vspecial_display_buffer_names
);
2702 for (tem
= Vspecial_display_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2704 Lisp_Object car
= XCAR (tem
);
2706 && fast_string_match (car
, buffer_name
) >= 0)
2708 else if (CONSP (car
)
2709 && STRINGP (XCAR (car
))
2710 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2716 DEFUN ("same-window-p", Fsame_window_p
, Ssame_window_p
, 1, 1, 0,
2717 "Returns non-nil if a new buffer named BUFFER-NAME would use the same window.\n\
2718 See `same-window-buffer-names' and `same-window-regexps'.")
2720 Lisp_Object buffer_name
;
2724 CHECK_STRING (buffer_name
, 1);
2726 tem
= Fmember (buffer_name
, Vsame_window_buffer_names
);
2730 tem
= Fassoc (buffer_name
, Vsame_window_buffer_names
);
2734 for (tem
= Vsame_window_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2736 Lisp_Object car
= XCAR (tem
);
2738 && fast_string_match (car
, buffer_name
) >= 0)
2740 else if (CONSP (car
)
2741 && STRINGP (XCAR (car
))
2742 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2748 /* Use B so the default is (other-buffer). */
2749 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 3,
2750 "BDisplay buffer: \nP",
2751 "Make BUFFER appear in some window but don't select it.\n\
2752 BUFFER can be a buffer or a buffer name.\n\
2753 If BUFFER is shown already in some window, just use that one,\n\
2754 unless the window is the selected window and the optional second\n\
2755 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).\n\
2756 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.\n\
2757 Returns the window displaying BUFFER.\n\
2758 If `display-reuse-frames' is non-nil, and another frame is currently\n\
2759 displaying BUFFER, then simply raise that frame.\n\
2761 The variables `special-display-buffer-names', `special-display-regexps',\n\
2762 `same-window-buffer-names', and `same-window-regexps' customize how certain\n\
2763 buffer names are handled.\n\
2765 If optional argument FRAME is `visible', search all visible frames.\n\
2766 If FRAME is 0, search all visible and iconified frames.\n\
2767 If FRAME is t, search all frames.\n\
2768 If FRAME is a frame, search only that frame.\n\
2769 If FRAME is nil, search only the selected frame\n\
2770 (actually the last nonminibuffer frame),\n\
2771 unless `pop-up-frames' or `display-buffer-reuse-frames' is non-nil,\n\
2772 which means search visible and iconified frames.")
2773 (buffer
, not_this_window
, frame
)
2774 register Lisp_Object buffer
, not_this_window
, frame
;
2776 register Lisp_Object window
, tem
, swp
;
2780 buffer
= Fget_buffer (buffer
);
2781 CHECK_BUFFER (buffer
, 0);
2783 if (!NILP (Vdisplay_buffer_function
))
2784 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
2786 if (NILP (not_this_window
)
2787 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
2788 return display_buffer_1 (selected_window
);
2790 /* See if the user has specified this buffer should appear
2791 in the selected window. */
2792 if (NILP (not_this_window
))
2794 swp
= Fsame_window_p (XBUFFER (buffer
)->name
);
2795 if (!NILP (swp
) && !no_switch_window (selected_window
))
2797 Fswitch_to_buffer (buffer
, Qnil
);
2798 return display_buffer_1 (selected_window
);
2802 /* If the user wants pop-up-frames or display-reuse-frames, then
2803 look for a window showing BUFFER on any visible or iconified frame.
2804 Otherwise search only the current frame. */
2807 else if (pop_up_frames
2808 || display_buffer_reuse_frames
2809 || last_nonminibuf_frame
== 0)
2810 XSETFASTINT (tem
, 0);
2812 XSETFRAME (tem
, last_nonminibuf_frame
);
2814 window
= Fget_buffer_window (buffer
, tem
);
2816 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
2817 return display_buffer_1 (window
);
2819 /* Certain buffer names get special handling. */
2820 if (!NILP (Vspecial_display_function
) && NILP (swp
))
2822 tem
= Fspecial_display_p (XBUFFER (buffer
)->name
);
2824 return call1 (Vspecial_display_function
, buffer
);
2826 return call2 (Vspecial_display_function
, buffer
, tem
);
2829 /* If there are no frames open that have more than a minibuffer,
2830 we need to create a new frame. */
2831 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
2833 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2834 Fset_window_buffer (window
, buffer
);
2835 return display_buffer_1 (window
);
2838 f
= SELECTED_FRAME ();
2840 || FRAME_MINIBUF_ONLY_P (f
)
2841 /* If the current frame is a special display frame,
2842 don't try to reuse its windows. */
2843 || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f
))->dedicated
))
2848 if (FRAME_MINIBUF_ONLY_P (f
))
2849 XSETFRAME (frames
, last_nonminibuf_frame
);
2850 /* Don't try to create a window if would get an error */
2851 if (split_height_threshold
< window_min_height
<< 1)
2852 split_height_threshold
= window_min_height
<< 1;
2854 /* Note that both Fget_largest_window and Fget_lru_window
2855 ignore minibuffers and dedicated windows.
2856 This means they can return nil. */
2858 /* If the frame we would try to split cannot be split,
2859 try other frames. */
2860 if (FRAME_NO_SPLIT_P (NILP (frames
) ? f
: last_nonminibuf_frame
))
2862 /* Try visible frames first. */
2863 window
= Fget_largest_window (Qvisible
);
2864 /* If that didn't work, try iconified frames. */
2866 window
= Fget_largest_window (make_number (0));
2868 window
= Fget_largest_window (Qt
);
2871 window
= Fget_largest_window (frames
);
2873 /* If we got a tall enough full-width window that can be split,
2876 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2877 && window_height (window
) >= split_height_threshold
2878 && WINDOW_FULL_WIDTH_P (XWINDOW (window
)))
2879 window
= Fsplit_window (window
, Qnil
, Qnil
);
2882 Lisp_Object upper
, lower
, other
;
2884 window
= Fget_lru_window (frames
);
2885 /* If the LRU window is selected, and big enough,
2886 and can be split, split it. */
2888 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2889 && (EQ (window
, selected_window
)
2890 || EQ (XWINDOW (window
)->parent
, Qnil
))
2891 && window_height (window
) >= window_min_height
<< 1)
2892 window
= Fsplit_window (window
, Qnil
, Qnil
);
2893 /* If Fget_lru_window returned nil, try other approaches. */
2895 /* Try visible frames first. */
2897 window
= Fget_buffer_window (buffer
, Qvisible
);
2899 window
= Fget_largest_window (Qvisible
);
2900 /* If that didn't work, try iconified frames. */
2902 window
= Fget_buffer_window (buffer
, make_number (0));
2904 window
= Fget_largest_window (make_number (0));
2905 /* Try invisible frames. */
2907 window
= Fget_buffer_window (buffer
, Qt
);
2909 window
= Fget_largest_window (Qt
);
2910 /* As a last resort, make a new frame. */
2912 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2913 /* If window appears above or below another,
2914 even out their heights. */
2915 other
= upper
= lower
= Qnil
;
2916 if (!NILP (XWINDOW (window
)->prev
))
2917 other
= upper
= XWINDOW (window
)->prev
, lower
= window
;
2918 if (!NILP (XWINDOW (window
)->next
))
2919 other
= lower
= XWINDOW (window
)->next
, upper
= window
;
2921 /* Check that OTHER and WINDOW are vertically arrayed. */
2922 && !EQ (XWINDOW (other
)->top
, XWINDOW (window
)->top
)
2923 && (XFASTINT (XWINDOW (other
)->height
)
2924 > XFASTINT (XWINDOW (window
)->height
)))
2926 int total
= (XFASTINT (XWINDOW (other
)->height
)
2927 + XFASTINT (XWINDOW (window
)->height
));
2928 enlarge_window (upper
,
2929 total
/ 2 - XFASTINT (XWINDOW (upper
)->height
),
2935 window
= Fget_lru_window (Qnil
);
2937 Fset_window_buffer (window
, buffer
);
2938 return display_buffer_1 (window
);
2942 temp_output_buffer_show (buf
)
2943 register Lisp_Object buf
;
2945 register struct buffer
*old
= current_buffer
;
2946 register Lisp_Object window
;
2947 register struct window
*w
;
2949 XBUFFER (buf
)->directory
= current_buffer
->directory
;
2952 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
2956 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
2957 set_buffer_internal (old
);
2959 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
2960 call1 (Vtemp_buffer_show_function
, buf
);
2963 window
= Fdisplay_buffer (buf
, Qnil
, Qnil
);
2965 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
2966 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
2967 Vminibuf_scroll_window
= window
;
2968 w
= XWINDOW (window
);
2969 XSETFASTINT (w
->hscroll
, 0);
2970 set_marker_restricted_both (w
->start
, buf
, 1, 1);
2971 set_marker_restricted_both (w
->pointm
, buf
, 1, 1);
2973 /* Run temp-buffer-show-hook, with the chosen window selected
2974 and it sbuffer current. */
2975 if (!NILP (Vrun_hooks
))
2978 tem
= Fboundp (Qtemp_buffer_show_hook
);
2981 tem
= Fsymbol_value (Qtemp_buffer_show_hook
);
2984 int count
= specpdl_ptr
- specpdl
;
2985 Lisp_Object prev_window
;
2986 prev_window
= selected_window
;
2988 /* Select the window that was chosen, for running the hook. */
2989 record_unwind_protect (Fselect_window
, prev_window
);
2990 select_window_1 (window
, 0);
2991 Fset_buffer (w
->buffer
);
2992 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
2993 select_window_1 (prev_window
, 0);
2994 unbind_to (count
, Qnil
);
3002 make_dummy_parent (window
)
3006 register struct window
*o
, *p
;
3007 register struct Lisp_Vector
*vec
;
3010 o
= XWINDOW (window
);
3011 vec
= allocate_vectorlike ((EMACS_INT
)VECSIZE (struct window
));
3012 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
3013 vec
->contents
[i
] = ((struct Lisp_Vector
*)o
)->contents
[i
];
3014 vec
->size
= VECSIZE (struct window
);
3015 p
= (struct window
*)vec
;
3016 XSETWINDOW (new, p
);
3018 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
3020 /* Put new into window structure in place of window */
3021 replace_window (window
, new);
3034 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
3035 "Split WINDOW, putting SIZE lines in the first of the pair.\n\
3036 WINDOW defaults to selected one and SIZE to half its size.\n\
3037 If optional third arg HORFLAG is non-nil, split side by side\n\
3038 and put SIZE columns in the first of the pair. In that case,\n\
3039 SIZE includes that window's scroll bar, or the divider column to its right.")
3040 (window
, size
, horflag
)
3041 Lisp_Object window
, size
, horflag
;
3043 register Lisp_Object
new;
3044 register struct window
*o
, *p
;
3046 register int size_int
;
3049 window
= selected_window
;
3051 CHECK_LIVE_WINDOW (window
, 0);
3053 o
= XWINDOW (window
);
3054 fo
= XFRAME (WINDOW_FRAME (o
));
3058 if (!NILP (horflag
))
3059 /* Calculate the size of the left-hand window, by dividing
3060 the usable space in columns by two.
3061 We round up, since the left-hand window may include
3062 a dividing line, while the right-hand may not. */
3063 size_int
= (XFASTINT (o
->width
) + 1) >> 1;
3065 size_int
= XFASTINT (o
->height
) >> 1;
3069 CHECK_NUMBER (size
, 1);
3070 size_int
= XINT (size
);
3073 if (MINI_WINDOW_P (o
))
3074 error ("Attempt to split minibuffer window");
3075 else if (window_fixed_size_p (o
, !NILP (horflag
), 0))
3076 error ("Attempt to split fixed-size window");
3078 check_min_window_sizes ();
3082 if (size_int
< window_min_height
)
3083 error ("Window height %d too small (after splitting)", size_int
);
3084 if (size_int
+ window_min_height
> XFASTINT (o
->height
))
3085 error ("Window height %d too small (after splitting)",
3086 XFASTINT (o
->height
) - size_int
);
3087 if (NILP (o
->parent
)
3088 || NILP (XWINDOW (o
->parent
)->vchild
))
3090 make_dummy_parent (window
);
3092 XWINDOW (new)->vchild
= window
;
3097 if (size_int
< window_min_width
)
3098 error ("Window width %d too small (after splitting)", size_int
);
3100 if (size_int
+ window_min_width
> XFASTINT (o
->width
))
3101 error ("Window width %d too small (after splitting)",
3102 XFASTINT (o
->width
) - size_int
);
3103 if (NILP (o
->parent
)
3104 || NILP (XWINDOW (o
->parent
)->hchild
))
3106 make_dummy_parent (window
);
3108 XWINDOW (new)->hchild
= window
;
3112 /* Now we know that window's parent is a vertical combination
3113 if we are dividing vertically, or a horizontal combination
3114 if we are making side-by-side windows */
3116 windows_or_buffers_changed
++;
3117 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
3118 new = make_window ();
3121 p
->frame
= o
->frame
;
3123 if (!NILP (p
->next
))
3124 XWINDOW (p
->next
)->prev
= new;
3127 p
->parent
= o
->parent
;
3129 p
->window_end_valid
= Qnil
;
3130 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
3132 /* Apportion the available frame space among the two new windows */
3134 if (!NILP (horflag
))
3136 p
->height
= o
->height
;
3138 XSETFASTINT (p
->width
, XFASTINT (o
->width
) - size_int
);
3139 XSETFASTINT (o
->width
, size_int
);
3140 XSETFASTINT (p
->left
, XFASTINT (o
->left
) + size_int
);
3145 p
->width
= o
->width
;
3146 XSETFASTINT (p
->height
, XFASTINT (o
->height
) - size_int
);
3147 XSETFASTINT (o
->height
, size_int
);
3148 XSETFASTINT (p
->top
, XFASTINT (o
->top
) + size_int
);
3151 /* Adjust glyph matrices. */
3153 Fset_window_buffer (new, o
->buffer
);
3157 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
3158 "Make current window ARG lines bigger.\n\
3159 From program, optional second arg non-nil means grow sideways ARG columns.")
3161 register Lisp_Object arg
, side
;
3163 CHECK_NUMBER (arg
, 0);
3164 enlarge_window (selected_window
, XINT (arg
), !NILP (side
));
3166 if (! NILP (Vwindow_configuration_change_hook
))
3167 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3172 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
3173 "Make current window ARG lines smaller.\n\
3174 From program, optional second arg non-nil means shrink sideways arg columns.")
3176 register Lisp_Object arg
, side
;
3178 CHECK_NUMBER (arg
, 0);
3179 enlarge_window (selected_window
, -XINT (arg
), !NILP (side
));
3181 if (! NILP (Vwindow_configuration_change_hook
))
3182 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3188 window_height (window
)
3191 register struct window
*p
= XWINDOW (window
);
3192 return XFASTINT (p
->height
);
3196 window_width (window
)
3199 register struct window
*p
= XWINDOW (window
);
3200 return XFASTINT (p
->width
);
3205 *(widthflag ? &(XWINDOW (w)->left) : &(XWINDOW (w)->top))
3207 #define CURSIZE(w) \
3208 *(widthflag ? &(XWINDOW (w)->width) : &(XWINDOW (w)->height))
3211 /* Enlarge selected_window by DELTA. WIDTHFLAG non-zero means
3212 increase its width. Siblings of the selected window are resized to
3213 fullfil the size request. If they become too small in the process,
3214 they will be deleted. */
3217 enlarge_window (window
, delta
, widthflag
)
3219 int delta
, widthflag
;
3221 Lisp_Object parent
, next
, prev
;
3225 int (*sizefun
) P_ ((Lisp_Object
))
3226 = widthflag
? window_width
: window_height
;
3227 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
3228 = (widthflag
? set_window_width
: set_window_height
);
3230 /* Check values of window_min_width and window_min_height for
3232 check_min_window_sizes ();
3234 /* Give up if this window cannot be resized. */
3235 if (window_fixed_size_p (XWINDOW (window
), widthflag
, 1))
3236 error ("Window is not resizable");
3238 /* Find the parent of the selected window. */
3241 p
= XWINDOW (window
);
3247 error ("No other window to side of this one");
3252 ? !NILP (XWINDOW (parent
)->hchild
)
3253 : !NILP (XWINDOW (parent
)->vchild
))
3259 sizep
= &CURSIZE (window
);
3262 register int maxdelta
;
3264 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - XINT (*sizep
)
3265 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3266 - window_min_size (XWINDOW (p
->next
),
3268 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
3269 - window_min_size (XWINDOW (p
->prev
),
3271 /* This is a frame with only one window, a minibuffer-only
3272 or a minibufferless frame. */
3275 if (delta
> maxdelta
)
3276 /* This case traps trying to make the minibuffer
3277 the full frame, or make the only window aside from the
3278 minibuffer the full frame. */
3282 if (XINT (*sizep
) + delta
< window_min_size (XWINDOW (window
), widthflag
, 0, 0))
3284 delete_window (window
);
3291 /* Find the total we can get from other siblings. */
3293 for (next
= p
->next
; ! NILP (next
); next
= XWINDOW (next
)->next
)
3294 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
3296 for (prev
= p
->prev
; ! NILP (prev
); prev
= XWINDOW (prev
)->prev
)
3297 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
3300 /* If we can get it all from them, do so. */
3301 if (delta
<= maximum
)
3303 Lisp_Object first_unaffected
;
3304 Lisp_Object first_affected
;
3309 first_affected
= window
;
3310 /* Look at one sibling at a time,
3311 moving away from this window in both directions alternately,
3312 and take as much as we can get without deleting that sibling. */
3313 while (delta
!= 0 && (!NILP (next
) || !NILP (prev
)))
3317 int this_one
= ((*sizefun
) (next
)
3318 - window_min_size (XWINDOW (next
),
3319 widthflag
, 0, &fixed_p
));
3322 if (this_one
> delta
)
3325 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
3326 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3331 next
= XWINDOW (next
)->next
;
3339 int this_one
= ((*sizefun
) (prev
)
3340 - window_min_size (XWINDOW (prev
),
3341 widthflag
, 0, &fixed_p
));
3344 if (this_one
> delta
)
3347 first_affected
= prev
;
3349 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
3350 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3355 prev
= XWINDOW (prev
)->prev
;
3359 xassert (delta
== 0);
3361 /* Now recalculate the edge positions of all the windows affected,
3362 based on the new sizes. */
3363 first_unaffected
= next
;
3364 prev
= first_affected
;
3365 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
3366 prev
= next
, next
= XWINDOW (next
)->next
)
3368 XSETINT (CURBEG (next
), XINT (CURBEG (prev
)) + (*sizefun
) (prev
));
3369 /* This does not change size of NEXT,
3370 but it propagates the new top edge to its children */
3371 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
3376 register int delta1
;
3377 register int opht
= (*sizefun
) (parent
);
3379 /* If trying to grow this window to or beyond size of the parent,
3380 make delta1 so big that, on shrinking back down,
3381 all the siblings end up with less than one line and are deleted. */
3382 if (opht
<= XINT (*sizep
) + delta
)
3383 delta1
= opht
* opht
* 2;
3386 /* Otherwise, make delta1 just right so that if we add
3387 delta1 lines to this window and to the parent, and then
3388 shrink the parent back to its original size, the new
3389 proportional size of this window will increase by delta.
3391 The function size_window will compute the new height h'
3392 of the window from delta1 as:
3395 x = delta1 - delta1/n * n for the 1st resizable child
3398 where n is the number of children that can be resized.
3399 We can ignore x by choosing a delta1 that is a multiple of
3400 n. We want the height of this window to come out as
3410 The number of children n rquals the number of resizable
3411 children of this window + 1 because we know window itself
3412 is resizable (otherwise we would have signalled an error. */
3414 struct window
*w
= XWINDOW (window
);
3418 for (s
= w
->next
; !NILP (s
); s
= XWINDOW (s
)->next
)
3419 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3421 for (s
= w
->prev
; !NILP (s
); s
= XWINDOW (s
)->prev
)
3422 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3428 /* Add delta1 lines or columns to this window, and to the parent,
3429 keeping things consistent while not affecting siblings. */
3430 XSETINT (CURSIZE (parent
), opht
+ delta1
);
3431 (*setsizefun
) (window
, XINT (*sizep
) + delta1
, 0);
3433 /* Squeeze out delta1 lines or columns from our parent,
3434 shriking this window and siblings proportionately.
3435 This brings parent back to correct size.
3436 Delta1 was calculated so this makes this window the desired size,
3437 taking it all out of the siblings. */
3438 (*setsizefun
) (parent
, opht
, 0);
3441 XSETFASTINT (p
->last_modified
, 0);
3442 XSETFASTINT (p
->last_overlay_modified
, 0);
3444 /* Adjust glyph matrices. */
3445 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
3453 /***********************************************************************
3454 Resizing Mini-Windows
3455 ***********************************************************************/
3457 static void shrink_window_lowest_first
P_ ((struct window
*, int));
3459 enum save_restore_action
3466 static int save_restore_orig_size
P_ ((struct window
*,
3467 enum save_restore_action
));
3469 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
3470 from lowest windows first. */
3473 shrink_window_lowest_first (w
, height
)
3481 xassert (!MINI_WINDOW_P (w
));
3483 /* Set redisplay hints. */
3484 XSETFASTINT (w
->last_modified
, 0);
3485 XSETFASTINT (w
->last_overlay_modified
, 0);
3486 windows_or_buffers_changed
++;
3487 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
3489 old_height
= XFASTINT (w
->height
);
3490 XSETFASTINT (w
->height
, height
);
3492 if (!NILP (w
->hchild
))
3494 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
3496 c
= XWINDOW (child
);
3498 shrink_window_lowest_first (c
, height
);
3501 else if (!NILP (w
->vchild
))
3503 Lisp_Object last_child
;
3504 int delta
= old_height
- height
;
3509 /* Find the last child. We are taking space from lowest windows
3510 first, so we iterate over children from the last child
3512 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
3515 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
3516 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
3520 c
= XWINDOW (child
);
3521 this_one
= XFASTINT (c
->height
) - MIN_SAFE_WINDOW_HEIGHT
;
3523 if (this_one
> delta
)
3526 shrink_window_lowest_first (c
, XFASTINT (c
->height
) - this_one
);
3530 /* Compute new positions. */
3531 last_top
= XINT (w
->top
);
3532 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
3534 c
= XWINDOW (child
);
3535 c
->top
= make_number (last_top
);
3536 shrink_window_lowest_first (c
, XFASTINT (c
->height
));
3537 last_top
+= XFASTINT (c
->height
);
3543 /* Save, restore, or check positions and sizes in the window tree
3544 rooted at W. ACTION says what to do.
3546 If ACTION is CHECK_ORIG_SIZES, check if orig_top and orig_height
3547 members are valid for all windows in the window tree. Value is
3548 non-zero if they are valid.
3550 If ACTION is SAVE_ORIG_SIZES, save members top and height in
3551 orig_top and orig_height for all windows in the tree.
3553 If ACTION is RESTORE_ORIG_SIZES, restore top and height from
3554 values stored in orig_top and orig_height for all windows. */
3557 save_restore_orig_size (w
, action
)
3559 enum save_restore_action action
;
3565 if (!NILP (w
->hchild
))
3567 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
3570 else if (!NILP (w
->vchild
))
3572 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
3578 case CHECK_ORIG_SIZES
:
3579 if (!INTEGERP (w
->orig_top
) || !INTEGERP (w
->orig_height
))
3583 case SAVE_ORIG_SIZES
:
3584 w
->orig_top
= w
->top
;
3585 w
->orig_height
= w
->height
;
3586 XSETFASTINT (w
->last_modified
, 0);
3587 XSETFASTINT (w
->last_overlay_modified
, 0);
3590 case RESTORE_ORIG_SIZES
:
3591 xassert (INTEGERP (w
->orig_top
) && INTEGERP (w
->orig_height
));
3592 w
->top
= w
->orig_top
;
3593 w
->height
= w
->orig_height
;
3594 w
->orig_height
= w
->orig_top
= Qnil
;
3595 XSETFASTINT (w
->last_modified
, 0);
3596 XSETFASTINT (w
->last_overlay_modified
, 0);
3603 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
3610 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
3611 without deleting other windows. */
3614 grow_mini_window (w
, delta
)
3618 struct frame
*f
= XFRAME (w
->frame
);
3619 struct window
*root
;
3621 xassert (MINI_WINDOW_P (w
));
3622 xassert (delta
>= 0);
3624 /* Check values of window_min_width and window_min_height for
3626 check_min_window_sizes ();
3628 /* Compute how much we can enlarge the mini-window without deleting
3630 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3633 int min_height
= window_min_size (root
, 0, 0, 0);
3634 if (XFASTINT (root
->height
) - delta
< min_height
)
3635 delta
= XFASTINT (root
->height
) - min_height
;
3640 /* Save original window sizes and positions, if not already done. */
3641 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3642 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
3644 /* Shrink other windows. */
3645 shrink_window_lowest_first (root
, XFASTINT (root
->height
) - delta
);
3647 /* Grow the mini-window. */
3648 w
->top
= make_number (XFASTINT (root
->top
) + XFASTINT (root
->height
));
3649 w
->height
= make_number (XFASTINT (w
->height
) + delta
);
3650 XSETFASTINT (w
->last_modified
, 0);
3651 XSETFASTINT (w
->last_overlay_modified
, 0);
3658 /* Shrink mini-window W. If there is recorded info about window sizes
3659 before a call to grow_mini_window, restore recorded window sizes.
3660 Otherwise, if the mini-window is higher than 1 line, resize it to 1
3664 shrink_mini_window (w
)
3667 struct frame
*f
= XFRAME (w
->frame
);
3668 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3670 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3672 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
3674 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
3675 windows_or_buffers_changed
= 1;
3677 else if (XFASTINT (w
->height
) > 1)
3680 XSETWINDOW (window
, w
);
3681 enlarge_window (window
, 1 - XFASTINT (w
->height
), 0);
3687 /* Mark window cursors off for all windows in the window tree rooted
3688 at W by setting their phys_cursor_on_p flag to zero. Called from
3689 xterm.c, e.g. when a frame is cleared and thereby all cursors on
3690 the frame are cleared. */
3693 mark_window_cursors_off (w
)
3698 if (!NILP (w
->hchild
))
3699 mark_window_cursors_off (XWINDOW (w
->hchild
));
3700 else if (!NILP (w
->vchild
))
3701 mark_window_cursors_off (XWINDOW (w
->vchild
));
3703 w
->phys_cursor_on_p
= 0;
3705 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
3710 /* Return number of lines of text (not counting mode line) in W. */
3713 window_internal_height (w
)
3716 int ht
= XFASTINT (w
->height
);
3718 if (MINI_WINDOW_P (w
))
3721 if (!NILP (w
->parent
) || !NILP (w
->vchild
) || !NILP (w
->hchild
)
3722 || !NILP (w
->next
) || !NILP (w
->prev
)
3723 || FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (w
))))
3730 /* Return the number of columns in W.
3731 Don't count columns occupied by scroll bars or the vertical bar
3732 separating W from the sibling to its right. */
3735 window_internal_width (w
)
3738 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
3739 int width
= XINT (w
->width
);
3741 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
3742 /* Scroll bars occupy a few columns. */
3743 width
-= FRAME_SCROLL_BAR_COLS (f
);
3744 else if (!WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
3745 /* The column of `|' characters separating side-by-side windows
3746 occupies one column only. */
3749 /* On window-systems, areas to the left and right of the window
3750 are used to display bitmaps there. */
3751 if (FRAME_WINDOW_P (f
))
3752 width
-= FRAME_FLAGS_AREA_COLS (f
);
3758 /************************************************************************
3760 ***********************************************************************/
3762 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
3763 one screen-full, which is defined as the height of the window minus
3764 next_screen_context_lines. If WHOLE is zero, scroll up N lines
3765 instead. Negative values of N mean scroll down. NOERROR non-zero
3766 means don't signal an error if we try to move over BEGV or ZV,
3770 window_scroll (window
, n
, whole
, noerror
)
3776 /* If we must, use the pixel-based version which is much slower than
3777 the line-based one but can handle varying line heights. */
3778 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
3779 window_scroll_pixel_based (window
, n
, whole
, noerror
);
3781 window_scroll_line_based (window
, n
, whole
, noerror
);
3785 /* Implementation of window_scroll that works based on pixel line
3786 heights. See the comment of window_scroll for parameter
3790 window_scroll_pixel_based (window
, n
, whole
, noerror
)
3797 struct window
*w
= XWINDOW (window
);
3798 struct text_pos start
;
3800 int this_scroll_margin
;
3803 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
3805 /* If PT is not visible in WINDOW, move back one half of
3807 XSETFASTINT (tem
, PT
);
3808 tem
= Fpos_visible_in_window_p (tem
, window
, Qnil
);
3811 /* Move backward half the height of the window. Performance note:
3812 vmotion used here is about 10% faster, but would give wrong
3813 results for variable height lines. */
3814 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3815 it
.current_y
= it
.last_visible_y
;
3816 move_it_vertically (&it
, -it
.last_visible_y
/ 2);
3818 /* The function move_iterator_vertically may move over more than
3819 the specified y-distance. If it->w is small, e.g. a
3820 mini-buffer window, we may end up in front of the window's
3821 display area. This is the case when Start displaying at the
3822 start of the line containing PT in this case. */
3823 if (it
.current_y
<= 0)
3825 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3826 move_it_vertically (&it
, 0);
3830 start
= it
.current
.pos
;
3833 /* If scroll_preserve_screen_position is non-zero, we try to set
3834 point in the same window line as it is now, so get that line. */
3835 if (!NILP (Vscroll_preserve_screen_position
))
3837 start_display (&it
, w
, start
);
3838 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3839 preserve_y
= it
.current_y
;
3844 /* Move iterator it from start the specified distance forward or
3845 backward. The result is the new window start. */
3846 start_display (&it
, w
, start
);
3849 int screen_full
= (it
.last_visible_y
3850 - next_screen_context_lines
* CANON_Y_UNIT (it
.f
));
3851 int direction
= n
< 0 ? -1 : 1;
3852 move_it_vertically (&it
, direction
* screen_full
);
3855 move_it_by_lines (&it
, n
, 1);
3857 /* End if we end up at ZV or BEGV. */
3858 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
3859 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
3863 else if (IT_CHARPOS (it
) == ZV
)
3864 Fsignal (Qend_of_buffer
, Qnil
);
3866 Fsignal (Qbeginning_of_buffer
, Qnil
);
3869 /* Set the window start, and set up the window for redisplay. */
3870 set_marker_restricted (w
->start
, make_number (IT_CHARPOS (it
)), w
->buffer
);
3871 w
->start_at_line_beg
= Fbolp ();
3872 w
->update_mode_line
= Qt
;
3873 XSETFASTINT (w
->last_modified
, 0);
3874 XSETFASTINT (w
->last_overlay_modified
, 0);
3875 /* Set force_start so that redisplay_window will run the
3876 window-scroll-functions. */
3877 w
->force_start
= Qt
;
3879 it
.current_y
= it
.vpos
= 0;
3881 /* Preserve the screen position if we must. */
3882 if (preserve_y
>= 0)
3884 move_it_to (&it
, -1, -1, preserve_y
, -1, MOVE_TO_Y
);
3885 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3889 /* Move PT out of scroll margins. */
3890 this_scroll_margin
= max (0, scroll_margin
);
3891 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->height
) / 4);
3892 this_scroll_margin
*= CANON_Y_UNIT (it
.f
);
3896 /* We moved the window start towards ZV, so PT may be now
3897 in the scroll margin at the top. */
3898 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3899 while (it
.current_y
< this_scroll_margin
)
3900 move_it_by_lines (&it
, 1, 1);
3901 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3905 /* We moved the window start towards BEGV, so PT may be now
3906 in the scroll margin at the bottom. */
3907 move_it_to (&it
, PT
, -1,
3908 it
.last_visible_y
- this_scroll_margin
- 1, -1,
3909 MOVE_TO_POS
| MOVE_TO_Y
);
3911 /* Don't put point on a partially visible line at the end. */
3912 if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
3913 > it
.last_visible_y
)
3914 move_it_by_lines (&it
, -1, 0);
3916 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3922 /* Implementation of window_scroll that works based on screen lines.
3923 See the comment of window_scroll for parameter descriptions. */
3926 window_scroll_line_based (window
, n
, whole
, noerror
)
3932 register struct window
*w
= XWINDOW (window
);
3933 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
3934 register int pos
, pos_byte
;
3935 register int ht
= window_internal_height (w
);
3936 register Lisp_Object tem
;
3940 struct position posit
;
3943 startpos
= marker_position (w
->start
);
3945 posit
= *compute_motion (startpos
, 0, 0, 0,
3947 window_internal_width (w
), XINT (w
->hscroll
),
3949 original_vpos
= posit
.vpos
;
3951 XSETFASTINT (tem
, PT
);
3952 tem
= Fpos_visible_in_window_p (tem
, window
, Qnil
);
3956 Fvertical_motion (make_number (- (ht
/ 2)), window
);
3961 lose
= n
< 0 && PT
== BEGV
;
3962 Fvertical_motion (make_number (n
), window
);
3966 SET_PT_BOTH (opoint
, opoint_byte
);
3973 Fsignal (Qbeginning_of_buffer
, Qnil
);
3978 int this_scroll_margin
= scroll_margin
;
3980 /* Don't use a scroll margin that is negative or too large. */
3981 if (this_scroll_margin
< 0)
3982 this_scroll_margin
= 0;
3984 if (XINT (w
->height
) < 4 * scroll_margin
)
3985 this_scroll_margin
= XINT (w
->height
) / 4;
3987 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
3988 w
->start_at_line_beg
= bolp
;
3989 w
->update_mode_line
= Qt
;
3990 XSETFASTINT (w
->last_modified
, 0);
3991 XSETFASTINT (w
->last_overlay_modified
, 0);
3992 /* Set force_start so that redisplay_window will run
3993 the window-scroll-functions. */
3994 w
->force_start
= Qt
;
3996 if (whole
&& !NILP (Vscroll_preserve_screen_position
))
3998 SET_PT_BOTH (pos
, pos_byte
);
3999 Fvertical_motion (make_number (original_vpos
), window
);
4001 /* If we scrolled forward, put point enough lines down
4002 that it is outside the scroll margin. */
4007 if (this_scroll_margin
> 0)
4009 SET_PT_BOTH (pos
, pos_byte
);
4010 Fvertical_motion (make_number (this_scroll_margin
), window
);
4016 if (top_margin
<= opoint
)
4017 SET_PT_BOTH (opoint
, opoint_byte
);
4018 else if (!NILP (Vscroll_preserve_screen_position
))
4020 SET_PT_BOTH (pos
, pos_byte
);
4021 Fvertical_motion (make_number (original_vpos
), window
);
4024 SET_PT (top_margin
);
4030 /* If we scrolled backward, put point near the end of the window
4031 but not within the scroll margin. */
4032 SET_PT_BOTH (pos
, pos_byte
);
4033 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
4034 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
4037 bottom_margin
= PT
+ 1;
4039 if (bottom_margin
> opoint
)
4040 SET_PT_BOTH (opoint
, opoint_byte
);
4043 if (!NILP (Vscroll_preserve_screen_position
))
4045 SET_PT_BOTH (pos
, pos_byte
);
4046 Fvertical_motion (make_number (original_vpos
), window
);
4049 Fvertical_motion (make_number (-1), window
);
4058 Fsignal (Qend_of_buffer
, Qnil
);
4063 /* Scroll selected_window up or down. If N is nil, scroll a
4064 screen-full which is defined as the height of the window minus
4065 next_screen_context_lines. If N is the symbol `-', scroll.
4066 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
4067 up. This is the guts of Fscroll_up and Fscroll_down. */
4070 scroll_command (n
, direction
)
4074 register int defalt
;
4075 int count
= specpdl_ptr
- specpdl
;
4077 xassert (abs (direction
) == 1);
4079 /* If selected window's buffer isn't current, make it current for
4080 the moment. But don't screw up if window_scroll gets an error. */
4081 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
4083 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4084 Fset_buffer (XWINDOW (selected_window
)->buffer
);
4086 /* Make redisplay consider other windows than just selected_window. */
4087 ++windows_or_buffers_changed
;
4090 defalt
= (window_internal_height (XWINDOW (selected_window
))
4091 - next_screen_context_lines
);
4092 defalt
= direction
* (defalt
< 1 ? 1 : defalt
);
4095 window_scroll (selected_window
, defalt
, 1, 0);
4096 else if (EQ (n
, Qminus
))
4097 window_scroll (selected_window
, - defalt
, 1, 0);
4100 n
= Fprefix_numeric_value (n
);
4101 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
4104 unbind_to (count
, Qnil
);
4107 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
4108 "Scroll text of current window upward ARG lines; or near full screen if no ARG.\n\
4109 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4110 Negative ARG means scroll downward.\n\
4111 If ARG is the atom `-', scroll downward by nearly full screen.\n\
4112 When calling from a program, supply as argument a number, nil, or `-'.")
4116 scroll_command (arg
, 1);
4120 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
4121 "Scroll text of current window down ARG lines; or near full screen if no ARG.\n\
4122 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4123 Negative ARG means scroll upward.\n\
4124 If ARG is the atom `-', scroll upward by nearly full screen.\n\
4125 When calling from a program, supply as argument a number, nil, or `-'.")
4129 scroll_command (arg
, -1);
4133 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
4134 "Return the other window for \"other window scroll\" commands.\n\
4135 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4136 specifies the window.\n\
4137 If `other-window-scroll-buffer' is non-nil, a window\n\
4138 showing that buffer is used.")
4143 if (MINI_WINDOW_P (XWINDOW (selected_window
))
4144 && !NILP (Vminibuf_scroll_window
))
4145 window
= Vminibuf_scroll_window
;
4146 /* If buffer is specified, scroll that buffer. */
4147 else if (!NILP (Vother_window_scroll_buffer
))
4149 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
4151 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
4155 /* Nothing specified; look for a neighboring window on the same
4157 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
4159 if (EQ (window
, selected_window
))
4160 /* That didn't get us anywhere; look for a window on another
4163 window
= Fnext_window (window
, Qnil
, Qt
);
4164 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
4165 && ! EQ (window
, selected_window
));
4168 CHECK_LIVE_WINDOW (window
, 0);
4170 if (EQ (window
, selected_window
))
4171 error ("There is no other window");
4176 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
4177 "Scroll next window upward ARG lines; or near full screen if no ARG.\n\
4178 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4179 The next window is the one below the current one; or the one at the top\n\
4180 if the current one is at the bottom. Negative ARG means scroll downward.\n\
4181 If ARG is the atom `-', scroll downward by nearly full screen.\n\
4182 When calling from a program, supply as argument a number, nil, or `-'.\n\
4184 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4185 specifies the window to scroll.\n\
4186 If `other-window-scroll-buffer' is non-nil, scroll the window\n\
4187 showing that buffer, popping the buffer up if necessary.")
4189 register Lisp_Object arg
;
4191 register Lisp_Object window
;
4192 register int defalt
;
4193 register struct window
*w
;
4194 register int count
= specpdl_ptr
- specpdl
;
4196 window
= Fother_window_for_scrolling ();
4198 w
= XWINDOW (window
);
4199 defalt
= window_internal_height (w
) - next_screen_context_lines
;
4200 if (defalt
< 1) defalt
= 1;
4202 /* Don't screw up if window_scroll gets an error. */
4203 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4204 ++windows_or_buffers_changed
;
4206 Fset_buffer (w
->buffer
);
4207 SET_PT (marker_position (w
->pointm
));
4210 window_scroll (window
, defalt
, 1, 1);
4211 else if (EQ (arg
, Qminus
))
4212 window_scroll (window
, -defalt
, 1, 1);
4217 CHECK_NUMBER (arg
, 0);
4218 window_scroll (window
, XINT (arg
), 0, 1);
4221 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
4222 unbind_to (count
, Qnil
);
4227 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 1, "P",
4228 "Scroll selected window display ARG columns left.\n\
4229 Default for ARG is window width minus 2.")
4231 register Lisp_Object arg
;
4235 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4237 arg
= Fprefix_numeric_value (arg
);
4240 Fset_window_hscroll (selected_window
,
4241 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4245 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 1, "P",
4246 "Scroll selected window display ARG columns right.\n\
4247 Default for ARG is window width minus 2.")
4249 register Lisp_Object arg
;
4252 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4254 arg
= Fprefix_numeric_value (arg
);
4257 Fset_window_hscroll (selected_window
,
4258 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4262 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
4263 "Center point in window and redisplay frame. With ARG, put point on line ARG.\n\
4264 The desired position of point is always relative to the current window.\n\
4265 Just C-u as prefix means put point in the center of the window.\n\
4266 If ARG is omitted or nil, erases the entire frame and then\n\
4267 redraws with point in the center of the current window.")
4269 register Lisp_Object arg
;
4271 register struct window
*w
= XWINDOW (selected_window
);
4272 register int ht
= window_internal_height (w
);
4273 struct position pos
;
4274 struct buffer
*buf
= XBUFFER (w
->buffer
);
4275 struct buffer
*obuf
= current_buffer
;
4279 extern int frame_garbaged
;
4282 /* Invalidate pixel data calculated for all compositions. */
4283 for (i
= 0; i
< n_compositions
; i
++)
4284 composition_table
[i
]->font
= NULL
;
4286 Fredraw_frame (w
->frame
);
4287 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
4288 XSETFASTINT (arg
, ht
/ 2);
4290 else if (CONSP (arg
)) /* Just C-u. */
4292 XSETFASTINT (arg
, ht
/ 2);
4296 arg
= Fprefix_numeric_value (arg
);
4297 CHECK_NUMBER (arg
, 0);
4301 XSETINT (arg
, XINT (arg
) + ht
);
4303 set_buffer_internal (buf
);
4304 pos
= *vmotion (PT
, - XINT (arg
), w
);
4306 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
4307 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
4308 || FETCH_BYTE (pos
.bytepos
- 1) == '\n')
4310 w
->force_start
= Qt
;
4311 set_buffer_internal (obuf
);
4317 /* Value is the number of lines actually displayed in window W,
4318 as opposed to its height. */
4321 displayed_window_lines (w
)
4325 struct text_pos start
;
4326 int height
= window_box_height (w
);
4327 struct buffer
*old_buffer
;
4330 if (XBUFFER (w
->buffer
) != current_buffer
)
4332 old_buffer
= current_buffer
;
4333 set_buffer_internal (XBUFFER (w
->buffer
));
4338 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4339 start_display (&it
, w
, start
);
4340 move_it_vertically (&it
, height
);
4343 set_buffer_internal (old_buffer
);
4345 /* Add in empty lines at the bottom of the window. */
4346 bottom_y
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
4347 if (bottom_y
< height
)
4349 struct frame
*f
= XFRAME (w
->frame
);
4350 int rest
= height
- bottom_y
;
4351 int lines
= (rest
+ CANON_Y_UNIT (f
) - 1) / CANON_Y_UNIT (f
);
4354 else if (it
.current_y
< height
&& bottom_y
> height
)
4355 /* Partially visible line at the bottom. */
4363 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
4365 "Position point relative to window.\n\
4366 With no argument, position point at center of window.\n\
4367 An argument specifies vertical position within the window;\n\
4368 zero means top of window, negative means relative to bottom of window.")
4372 struct window
*w
= XWINDOW (selected_window
);
4376 window
= selected_window
;
4377 start
= marker_position (w
->start
);
4378 if (start
< BEGV
|| start
> ZV
)
4380 int height
= window_internal_height (w
);
4381 Fvertical_motion (make_number (- (height
/ 2)), window
);
4382 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
4383 w
->start_at_line_beg
= Fbolp ();
4384 w
->force_start
= Qt
;
4387 Fgoto_char (w
->start
);
4389 lines
= displayed_window_lines (w
);
4391 XSETFASTINT (arg
, lines
/ 2);
4394 arg
= Fprefix_numeric_value (arg
);
4396 XSETINT (arg
, XINT (arg
) + lines
);
4399 return Fvertical_motion (arg
, window
);
4404 /***********************************************************************
4405 Window Configuration
4406 ***********************************************************************/
4408 struct save_window_data
4410 EMACS_INT size_from_Lisp_Vector_struct
;
4411 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4412 Lisp_Object frame_width
, frame_height
, frame_menu_bar_lines
;
4413 Lisp_Object frame_tool_bar_lines
;
4414 Lisp_Object selected_frame
;
4415 Lisp_Object current_window
;
4416 Lisp_Object current_buffer
;
4417 Lisp_Object minibuf_scroll_window
;
4418 Lisp_Object root_window
;
4419 Lisp_Object focus_frame
;
4420 /* Record the values of window-min-width and window-min-height
4421 so that window sizes remain consistent with them. */
4422 Lisp_Object min_width
, min_height
;
4423 /* A vector, each of whose elements is a struct saved_window
4425 Lisp_Object saved_windows
;
4428 /* This is saved as a Lisp_Vector */
4431 /* these first two must agree with struct Lisp_Vector in lisp.h */
4432 EMACS_INT size_from_Lisp_Vector_struct
;
4433 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4436 Lisp_Object buffer
, start
, pointm
, mark
;
4437 Lisp_Object left
, top
, width
, height
, hscroll
;
4438 Lisp_Object parent
, prev
;
4439 Lisp_Object start_at_line_beg
;
4440 Lisp_Object display_table
;
4442 #define SAVED_WINDOW_VECTOR_SIZE 14 /* Arg to Fmake_vector */
4444 #define SAVED_WINDOW_N(swv,n) \
4445 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
4447 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
4448 "Return t if OBJECT is a window-configuration object.")
4452 if (WINDOW_CONFIGURATIONP (object
))
4457 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
4458 "Return the frame that CONFIG, a window-configuration object, is about.")
4462 register struct save_window_data
*data
;
4463 struct Lisp_Vector
*saved_windows
;
4465 if (! WINDOW_CONFIGURATIONP (config
))
4466 wrong_type_argument (Qwindow_configuration_p
, config
);
4468 data
= (struct save_window_data
*) XVECTOR (config
);
4469 saved_windows
= XVECTOR (data
->saved_windows
);
4470 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4473 DEFUN ("set-window-configuration", Fset_window_configuration
,
4474 Sset_window_configuration
, 1, 1, 0,
4475 "Set the configuration of windows and buffers as specified by CONFIGURATION.\n\
4476 CONFIGURATION must be a value previously returned\n\
4477 by `current-window-configuration' (which see).\n\
4478 If CONFIGURATION was made from a frame that is now deleted,\n\
4479 only frame-independent values can be restored. In this case,\n\
4480 the return value is nil. Otherwise the value is t.")
4482 Lisp_Object configuration
;
4484 register struct save_window_data
*data
;
4485 struct Lisp_Vector
*saved_windows
;
4486 Lisp_Object new_current_buffer
;
4491 while (!WINDOW_CONFIGURATIONP (configuration
))
4492 wrong_type_argument (Qwindow_configuration_p
, configuration
);
4494 data
= (struct save_window_data
*) XVECTOR (configuration
);
4495 saved_windows
= XVECTOR (data
->saved_windows
);
4497 new_current_buffer
= data
->current_buffer
;
4498 if (NILP (XBUFFER (new_current_buffer
)->name
))
4499 new_current_buffer
= Qnil
;
4502 if (XBUFFER (new_current_buffer
) == current_buffer
)
4506 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4509 /* If f is a dead frame, don't bother rebuilding its window tree.
4510 However, there is other stuff we should still try to do below. */
4511 if (FRAME_LIVE_P (f
))
4513 register struct window
*w
;
4514 register struct saved_window
*p
;
4515 struct window
*root_window
;
4516 struct window
**leaf_windows
;
4520 /* If the frame has been resized since this window configuration was
4521 made, we change the frame to the size specified in the
4522 configuration, restore the configuration, and then resize it
4523 back. We keep track of the prevailing height in these variables. */
4524 int previous_frame_height
= FRAME_HEIGHT (f
);
4525 int previous_frame_width
= FRAME_WIDTH (f
);
4526 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
4527 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
4529 /* The mouse highlighting code could get screwed up
4530 if it runs during this. */
4533 if (XFASTINT (data
->frame_height
) != previous_frame_height
4534 || XFASTINT (data
->frame_width
) != previous_frame_width
)
4535 change_frame_size (f
, XFASTINT (data
->frame_height
),
4536 XFASTINT (data
->frame_width
), 0, 0, 0);
4537 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4538 if (XFASTINT (data
->frame_menu_bar_lines
)
4539 != previous_frame_menu_bar_lines
)
4540 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, make_number (0));
4541 #ifdef HAVE_WINDOW_SYSTEM
4542 if (XFASTINT (data
->frame_tool_bar_lines
)
4543 != previous_frame_tool_bar_lines
)
4544 x_set_tool_bar_lines (f
, data
->frame_tool_bar_lines
, make_number (0));
4548 /* "Swap out" point from the selected window
4549 into its buffer. We do this now, before
4550 restoring the window contents, and prevent it from
4551 being done later on when we select a new window. */
4552 if (! NILP (XWINDOW (selected_window
)->buffer
))
4554 w
= XWINDOW (selected_window
);
4555 set_marker_both (w
->pointm
,
4557 BUF_PT (XBUFFER (w
->buffer
)),
4558 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4561 windows_or_buffers_changed
++;
4562 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4564 /* Problem: Freeing all matrices and later allocating them again
4565 is a serious redisplay flickering problem. What we would
4566 really like to do is to free only those matrices not reused
4568 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4570 = (struct window
**) alloca (count_windows (root_window
)
4571 * sizeof (struct window
*));
4572 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
4574 /* Temporarily avoid any problems with windows that are smaller
4575 than they are supposed to be. */
4576 window_min_height
= 1;
4577 window_min_width
= 1;
4580 Mark all windows now on frame as "deleted".
4581 Restoring the new configuration "undeletes" any that are in it.
4583 Save their current buffers in their height fields, since we may
4584 need it later, if a buffer saved in the configuration is now
4586 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4588 for (k
= 0; k
< saved_windows
->size
; k
++)
4590 p
= SAVED_WINDOW_N (saved_windows
, k
);
4591 w
= XWINDOW (p
->window
);
4594 if (!NILP (p
->parent
))
4595 w
->parent
= SAVED_WINDOW_N (saved_windows
,
4596 XFASTINT (p
->parent
))->window
;
4600 if (!NILP (p
->prev
))
4602 w
->prev
= SAVED_WINDOW_N (saved_windows
,
4603 XFASTINT (p
->prev
))->window
;
4604 XWINDOW (w
->prev
)->next
= p
->window
;
4609 if (!NILP (w
->parent
))
4611 if (EQ (p
->width
, XWINDOW (w
->parent
)->width
))
4613 XWINDOW (w
->parent
)->vchild
= p
->window
;
4614 XWINDOW (w
->parent
)->hchild
= Qnil
;
4618 XWINDOW (w
->parent
)->hchild
= p
->window
;
4619 XWINDOW (w
->parent
)->vchild
= Qnil
;
4624 /* If we squirreled away the buffer in the window's height,
4626 if (BUFFERP (w
->height
))
4627 w
->buffer
= w
->height
;
4630 w
->width
= p
->width
;
4631 w
->height
= p
->height
;
4632 w
->hscroll
= p
->hscroll
;
4633 w
->display_table
= p
->display_table
;
4634 XSETFASTINT (w
->last_modified
, 0);
4635 XSETFASTINT (w
->last_overlay_modified
, 0);
4637 /* Reinstall the saved buffer and pointers into it. */
4638 if (NILP (p
->buffer
))
4639 w
->buffer
= p
->buffer
;
4642 if (!NILP (XBUFFER (p
->buffer
)->name
))
4643 /* If saved buffer is alive, install it. */
4645 w
->buffer
= p
->buffer
;
4646 w
->start_at_line_beg
= p
->start_at_line_beg
;
4647 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
4648 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
4649 Fset_marker (XBUFFER (w
->buffer
)->mark
,
4650 p
->mark
, w
->buffer
);
4652 /* As documented in Fcurrent_window_configuration, don't
4653 save the location of point in the buffer which was current
4654 when the window configuration was recorded. */
4655 if (!EQ (p
->buffer
, new_current_buffer
)
4656 && XBUFFER (p
->buffer
) == current_buffer
)
4657 Fgoto_char (w
->pointm
);
4659 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
4660 /* Else unless window has a live buffer, get one. */
4662 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
4663 /* This will set the markers to beginning of visible
4665 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
4666 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
4667 w
->start_at_line_beg
= Qt
;
4670 /* Keeping window's old buffer; make sure the markers
4673 /* Set window markers at start of visible range. */
4674 if (XMARKER (w
->start
)->buffer
== 0)
4675 set_marker_restricted (w
->start
, make_number (0),
4677 if (XMARKER (w
->pointm
)->buffer
== 0)
4678 set_marker_restricted_both (w
->pointm
, w
->buffer
,
4679 BUF_PT (XBUFFER (w
->buffer
)),
4680 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4681 w
->start_at_line_beg
= Qt
;
4686 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
4687 /* Prevent "swapping out point" in the old selected window
4688 using the buffer that has been restored into it.
4689 That swapping out has already been done,
4690 near the beginning of this function. */
4691 selected_window
= Qnil
;
4692 Fselect_window (data
->current_window
);
4693 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
4696 if (NILP (data
->focus_frame
)
4697 || (FRAMEP (data
->focus_frame
)
4698 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
4699 Fredirect_frame_focus (frame
, data
->focus_frame
);
4701 #if 0 /* I don't understand why this is needed, and it causes problems
4702 when the frame's old selected window has been deleted. */
4703 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
4704 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
4708 /* Set the screen height to the value it had before this function. */
4709 if (previous_frame_height
!= FRAME_HEIGHT (f
)
4710 || previous_frame_width
!= FRAME_WIDTH (f
))
4711 change_frame_size (f
, previous_frame_height
, previous_frame_width
,
4713 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4714 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
4715 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
4717 #ifdef HAVE_WINDOW_SYSTEM
4718 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
4719 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
4724 /* Now, free glyph matrices in windows that were not reused. */
4725 for (i
= n
= 0; i
< n_leaf_windows
; ++i
)
4727 if (NILP (leaf_windows
[i
]->buffer
))
4729 /* Assert it's not reused as a combination. */
4730 xassert (NILP (leaf_windows
[i
]->hchild
)
4731 && NILP (leaf_windows
[i
]->vchild
));
4732 free_window_matrices (leaf_windows
[i
]);
4733 SET_FRAME_GARBAGED (f
);
4735 else if (EQ (leaf_windows
[i
]->buffer
, new_current_buffer
))
4739 /* If more than one window shows the new and old current buffer,
4740 don't try to preserve point in that buffer. */
4741 if (old_point
> 0 && n
> 1)
4748 /* Fselect_window will have made f the selected frame, so we
4749 reselect the proper frame here. Fhandle_switch_frame will change the
4750 selected window too, but that doesn't make the call to
4751 Fselect_window above totally superfluous; it still sets f's
4753 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
4754 do_switch_frame (data
->selected_frame
, Qnil
, 0);
4756 if (! NILP (Vwindow_configuration_change_hook
)
4757 && ! NILP (Vrun_hooks
))
4758 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
4761 if (!NILP (new_current_buffer
))
4763 Fset_buffer (new_current_buffer
);
4765 /* If the buffer that is current now is the same
4766 that was current before setting the window configuration,
4767 don't alter its PT. */
4772 /* Restore the minimum heights recorded in the configuration. */
4773 window_min_height
= XINT (data
->min_height
);
4774 window_min_width
= XINT (data
->min_width
);
4776 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
4778 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
4781 /* Mark all windows now on frame as deleted
4782 by setting their buffers to nil. */
4785 delete_all_subwindows (w
)
4786 register struct window
*w
;
4788 if (!NILP (w
->next
))
4789 delete_all_subwindows (XWINDOW (w
->next
));
4790 if (!NILP (w
->vchild
))
4791 delete_all_subwindows (XWINDOW (w
->vchild
));
4792 if (!NILP (w
->hchild
))
4793 delete_all_subwindows (XWINDOW (w
->hchild
));
4795 w
->height
= w
->buffer
; /* See Fset_window_configuration for excuse. */
4797 if (!NILP (w
->buffer
))
4800 /* We set all three of these fields to nil, to make sure that we can
4801 distinguish this dead window from any live window. Live leaf
4802 windows will have buffer set, and combination windows will have
4803 vchild or hchild set. */
4808 Vwindow_list
= Qnil
;
4812 count_windows (window
)
4813 register struct window
*window
;
4815 register int count
= 1;
4816 if (!NILP (window
->next
))
4817 count
+= count_windows (XWINDOW (window
->next
));
4818 if (!NILP (window
->vchild
))
4819 count
+= count_windows (XWINDOW (window
->vchild
));
4820 if (!NILP (window
->hchild
))
4821 count
+= count_windows (XWINDOW (window
->hchild
));
4826 /* Fill vector FLAT with leaf windows under W, starting at index I.
4827 Value is last index + 1. */
4830 get_leaf_windows (w
, flat
, i
)
4832 struct window
**flat
;
4837 if (!NILP (w
->hchild
))
4838 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
4839 else if (!NILP (w
->vchild
))
4840 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
4844 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4851 /* Return a pointer to the glyph W's physical cursor is on. Value is
4852 null if W's current matrix is invalid, so that no meaningfull glyph
4856 get_phys_cursor_glyph (w
)
4859 struct glyph_row
*row
;
4860 struct glyph
*glyph
;
4862 if (w
->phys_cursor
.vpos
>= 0
4863 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
4864 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
4866 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
4867 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
4876 save_window_save (window
, vector
, i
)
4878 struct Lisp_Vector
*vector
;
4881 register struct saved_window
*p
;
4882 register struct window
*w
;
4883 register Lisp_Object tem
;
4885 for (;!NILP (window
); window
= w
->next
)
4887 p
= SAVED_WINDOW_N (vector
, i
);
4888 w
= XWINDOW (window
);
4890 XSETFASTINT (w
->temslot
, i
++);
4892 p
->buffer
= w
->buffer
;
4895 p
->width
= w
->width
;
4896 p
->height
= w
->height
;
4897 p
->hscroll
= w
->hscroll
;
4898 p
->display_table
= w
->display_table
;
4899 if (!NILP (w
->buffer
))
4901 /* Save w's value of point in the window configuration.
4902 If w is the selected window, then get the value of point
4903 from the buffer; pointm is garbage in the selected window. */
4904 if (EQ (window
, selected_window
))
4906 p
->pointm
= Fmake_marker ();
4907 set_marker_both (p
->pointm
, w
->buffer
,
4908 BUF_PT (XBUFFER (w
->buffer
)),
4909 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4912 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
4914 p
->start
= Fcopy_marker (w
->start
, Qnil
);
4915 p
->start_at_line_beg
= w
->start_at_line_beg
;
4917 tem
= XBUFFER (w
->buffer
)->mark
;
4918 p
->mark
= Fcopy_marker (tem
, Qnil
);
4925 p
->start_at_line_beg
= Qnil
;
4928 if (NILP (w
->parent
))
4931 p
->parent
= XWINDOW (w
->parent
)->temslot
;
4936 p
->prev
= XWINDOW (w
->prev
)->temslot
;
4938 if (!NILP (w
->vchild
))
4939 i
= save_window_save (w
->vchild
, vector
, i
);
4940 if (!NILP (w
->hchild
))
4941 i
= save_window_save (w
->hchild
, vector
, i
);
4947 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
4948 Scurrent_window_configuration
, 0, 1, 0,
4949 "Return an object representing the current window configuration of FRAME.\n\
4950 If FRAME is nil or omitted, use the selected frame.\n\
4951 This describes the number of windows, their sizes and current buffers,\n\
4952 and for each displayed buffer, where display starts, and the positions of\n\
4953 point and mark. An exception is made for point in the current buffer:\n\
4954 its value is -not- saved.\n\
4955 This also records the currently selected frame, and FRAME's focus\n\
4956 redirection (see `redirect-frame-focus').")
4960 register Lisp_Object tem
;
4961 register int n_windows
;
4962 register struct save_window_data
*data
;
4963 register struct Lisp_Vector
*vec
;
4968 frame
= selected_frame
;
4969 CHECK_LIVE_FRAME (frame
, 0);
4972 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4973 vec
= allocate_vectorlike (VECSIZE (struct save_window_data
));
4974 for (i
= 0; i
< VECSIZE (struct save_window_data
); i
++)
4975 vec
->contents
[i
] = Qnil
;
4976 vec
->size
= VECSIZE (struct save_window_data
);
4977 data
= (struct save_window_data
*)vec
;
4979 XSETFASTINT (data
->frame_width
, FRAME_WIDTH (f
));
4980 XSETFASTINT (data
->frame_height
, FRAME_HEIGHT (f
));
4981 XSETFASTINT (data
->frame_menu_bar_lines
, FRAME_MENU_BAR_LINES (f
));
4982 XSETFASTINT (data
->frame_tool_bar_lines
, FRAME_TOOL_BAR_LINES (f
));
4983 data
->selected_frame
= selected_frame
;
4984 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
4985 XSETBUFFER (data
->current_buffer
, current_buffer
);
4986 data
->minibuf_scroll_window
= Vminibuf_scroll_window
;
4987 data
->root_window
= FRAME_ROOT_WINDOW (f
);
4988 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
4989 XSETINT (data
->min_height
, window_min_height
);
4990 XSETINT (data
->min_width
, window_min_width
);
4991 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
4992 data
->saved_windows
= tem
;
4993 for (i
= 0; i
< n_windows
; i
++)
4994 XVECTOR (tem
)->contents
[i
]
4995 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
4996 save_window_save (FRAME_ROOT_WINDOW (f
),
4998 XSETWINDOW_CONFIGURATION (tem
, data
);
5002 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
5004 "Execute body, preserving window sizes and contents.\n\
5005 Restore which buffer appears in which window, where display starts,\n\
5006 and the value of point and mark for each window.\n\
5007 Also restore the choice of selected window.\n\
5008 Also restore which buffer is current.\n\
5009 Does not restore the value of point in current buffer.")
5013 register Lisp_Object val
;
5014 register int count
= specpdl_ptr
- specpdl
;
5016 record_unwind_protect (Fset_window_configuration
,
5017 Fcurrent_window_configuration (Qnil
));
5018 val
= Fprogn (args
);
5019 return unbind_to (count
, val
);
5023 /***********************************************************************
5025 ***********************************************************************/
5027 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
5029 "Set width of marginal areas of window WINDOW.\n\
5030 If window is nil, set margins of the currently selected window.\n\
5031 First parameter LEFT-WIDTH specifies the number of character\n\
5032 cells to reserve for the left marginal area. Second parameter\n\
5033 RIGHT-WIDTH does the same for the right marginal area.\n\
5034 A nil width parameter means no margin.")
5035 (window
, left
, right
)
5036 Lisp_Object window
, left
, right
;
5038 struct window
*w
= decode_window (window
);
5041 CHECK_NUMBER_OR_FLOAT (left
, 1);
5043 CHECK_NUMBER_OR_FLOAT (right
, 2);
5045 /* Check widths < 0 and translate a zero width to nil.
5046 Margins that are too wide have to be checked elsewhere. */
5047 if ((INTEGERP (left
) && XINT (left
) < 0)
5048 || (FLOATP (left
) && XFLOAT_DATA (left
) <= 0))
5049 XSETFASTINT (left
, 0);
5050 if (INTEGERP (left
) && XFASTINT (left
) == 0)
5053 if ((INTEGERP (right
) && XINT (right
) < 0)
5054 || (FLOATP (right
) && XFLOAT_DATA (right
) <= 0))
5055 XSETFASTINT (right
, 0);
5056 if (INTEGERP (right
) && XFASTINT (right
) == 0)
5059 w
->left_margin_width
= left
;
5060 w
->right_margin_width
= right
;
5062 ++windows_or_buffers_changed
;
5063 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
5068 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
5070 "Get width of marginal areas of window WINDOW.\n\
5071 If WINDOW is omitted or nil, use the currently selected window.\n\
5072 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).\n\
5073 If a marginal area does not exist, its width will be returned\n\
5078 struct window
*w
= decode_window (window
);
5079 return Fcons (w
->left_margin_width
, w
->right_margin_width
);
5084 /***********************************************************************
5086 ***********************************************************************/
5088 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 1, 0,
5089 "Return the amount by which WINDOW is scrolled vertically.\n\
5090 Use the selected window if WINDOW is nil or omitted.\n\
5091 Value is a multiple of the canonical character height of WINDOW.")
5100 window
= selected_window
;
5102 CHECK_WINDOW (window
, 0);
5103 w
= XWINDOW (window
);
5104 f
= XFRAME (w
->frame
);
5106 if (FRAME_WINDOW_P (f
))
5107 result
= CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
);
5109 result
= make_number (0);
5114 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
5116 "Set amount by which WINDOW should be scrolled vertically to VSCROLL.\n\
5117 WINDOW nil or omitted means use the selected window. VSCROLL is a\n\
5118 non-negative multiple of the canonical character height of WINDOW.")
5120 Lisp_Object window
, vscroll
;
5126 window
= selected_window
;
5128 CHECK_WINDOW (window
, 0);
5129 CHECK_NUMBER_OR_FLOAT (vscroll
, 1);
5131 w
= XWINDOW (window
);
5132 f
= XFRAME (w
->frame
);
5134 if (FRAME_WINDOW_P (f
))
5136 int old_dy
= w
->vscroll
;
5138 w
->vscroll
= - CANON_Y_UNIT (f
) * XFLOATINT (vscroll
);
5139 w
->vscroll
= min (w
->vscroll
, 0);
5141 /* Adjust glyph matrix of the frame if the virtual display
5142 area becomes larger than before. */
5143 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
5146 /* Prevent redisplay shortcuts. */
5147 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
5150 return Fwindow_vscroll (window
);
5154 /* Call FN for all leaf windows on frame F. FN is called with the
5155 first argument being a pointer to the leaf window, and with
5156 additional argument USER_DATA. Stops when FN returns 0. */
5159 foreach_window (f
, fn
, user_data
)
5161 int (* fn
) P_ ((struct window
*, void *));
5164 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, user_data
);
5168 /* Helper function for foreach_window. Call FN for all leaf windows
5169 reachable from W. FN is called with the first argument being a
5170 pointer to the leaf window, and with additional argument USER_DATA.
5171 Stop when FN returns 0. Value is 0 if stopped by FN. */
5174 foreach_window_1 (w
, fn
, user_data
)
5176 int (* fn
) P_ ((struct window
*, void *));
5181 for (cont
= 1; w
&& cont
;)
5183 if (!NILP (w
->hchild
))
5184 cont
= foreach_window_1 (XWINDOW (w
->hchild
), fn
, user_data
);
5185 else if (!NILP (w
->vchild
))
5186 cont
= foreach_window_1 (XWINDOW (w
->vchild
), fn
, user_data
);
5188 cont
= fn (w
, user_data
);
5190 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5197 /* Freeze or unfreeze the window start of W if unless it is a
5198 mini-window or the selected window. FREEZE_P non-null means freeze
5199 the window start. */
5202 freeze_window_start (w
, freeze_p
)
5206 if (w
== XWINDOW (selected_window
)
5207 || MINI_WINDOW_P (w
)
5208 || (MINI_WINDOW_P (XWINDOW (selected_window
))
5209 && ! NILP (Vminibuf_scroll_window
)
5210 && w
== XWINDOW (Vminibuf_scroll_window
)))
5213 w
->frozen_window_start_p
= freeze_p
!= NULL
;
5218 /* Freeze or unfreeze the window starts of all leaf windows on frame
5219 F, except the selected window and a mini-window. FREEZE_P non-zero
5220 means freeze the window start. */
5223 freeze_window_starts (f
, freeze_p
)
5227 foreach_window (f
, freeze_window_start
, (void *) (freeze_p
? f
: 0));
5231 /***********************************************************************
5233 ***********************************************************************/
5235 /* Return 1 if window configurations C1 and C2
5236 describe the same state of affairs. This is used by Fequal. */
5239 compare_window_configurations (c1
, c2
, ignore_positions
)
5241 int ignore_positions
;
5243 register struct save_window_data
*d1
, *d2
;
5244 struct Lisp_Vector
*sw1
, *sw2
;
5247 if (!WINDOW_CONFIGURATIONP (c1
))
5248 wrong_type_argument (Qwindow_configuration_p
, c1
);
5249 if (!WINDOW_CONFIGURATIONP (c2
))
5250 wrong_type_argument (Qwindow_configuration_p
, c2
);
5252 d1
= (struct save_window_data
*) XVECTOR (c1
);
5253 d2
= (struct save_window_data
*) XVECTOR (c2
);
5254 sw1
= XVECTOR (d1
->saved_windows
);
5255 sw2
= XVECTOR (d2
->saved_windows
);
5257 if (! EQ (d1
->frame_width
, d2
->frame_width
))
5259 if (! EQ (d1
->frame_height
, d2
->frame_height
))
5261 if (! EQ (d1
->frame_menu_bar_lines
, d2
->frame_menu_bar_lines
))
5263 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
5265 /* Don't compare the current_window field directly.
5266 Instead see w1_is_current and w2_is_current, below. */
5267 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
5269 if (! ignore_positions
)
5270 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
5272 /* Don't compare the root_window field.
5273 We don't require the two configurations
5274 to use the same window object,
5275 and the two root windows must be equivalent
5276 if everything else compares equal. */
5277 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
5279 if (! EQ (d1
->min_width
, d2
->min_width
))
5281 if (! EQ (d1
->min_height
, d2
->min_height
))
5284 /* Verify that the two confis have the same number of windows. */
5285 if (sw1
->size
!= sw2
->size
)
5288 for (i
= 0; i
< sw1
->size
; i
++)
5290 struct saved_window
*p1
, *p2
;
5291 int w1_is_current
, w2_is_current
;
5293 p1
= SAVED_WINDOW_N (sw1
, i
);
5294 p2
= SAVED_WINDOW_N (sw2
, i
);
5296 /* Verify that the current windows in the two
5297 configurations correspond to each other. */
5298 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
5299 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
5301 if (w1_is_current
!= w2_is_current
)
5304 /* Verify that the corresponding windows do match. */
5305 if (! EQ (p1
->buffer
, p2
->buffer
))
5307 if (! EQ (p1
->left
, p2
->left
))
5309 if (! EQ (p1
->top
, p2
->top
))
5311 if (! EQ (p1
->width
, p2
->width
))
5313 if (! EQ (p1
->height
, p2
->height
))
5315 if (! EQ (p1
->display_table
, p2
->display_table
))
5317 if (! EQ (p1
->parent
, p2
->parent
))
5319 if (! EQ (p1
->prev
, p2
->prev
))
5321 if (! ignore_positions
)
5323 if (! EQ (p1
->hscroll
, p2
->hscroll
))
5325 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
5327 if (NILP (Fequal (p1
->start
, p2
->start
)))
5329 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
5331 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
5339 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
5340 Scompare_window_configurations
, 2, 2, 0,
5341 "Compare two window configurations as regards the structure of windows.\n\
5342 This function ignores details such as the values of point and mark\n\
5343 and scrolling positions.")
5347 if (compare_window_configurations (x
, y
, 1))
5355 struct frame
*f
= make_terminal_frame ();
5356 XSETFRAME (selected_frame
, f
);
5357 Vterminal_frame
= selected_frame
;
5358 minibuf_window
= f
->minibuffer_window
;
5359 selected_window
= f
->selected_window
;
5360 last_nonminibuf_frame
= f
;
5362 window_initialized
= 1;
5368 Vwindow_list
= Qnil
;
5374 Qleft_bitmap_area
= intern ("left-bitmap-area");
5375 staticpro (&Qleft_bitmap_area
);
5376 Qright_bitmap_area
= intern ("right-bitmap-area");
5377 staticpro (&Qright_bitmap_area
);
5379 Qwindow_size_fixed
= intern ("window-size-fixed");
5380 staticpro (&Qwindow_size_fixed
);
5382 staticpro (&Qwindow_configuration_change_hook
);
5383 Qwindow_configuration_change_hook
5384 = intern ("window-configuration-change-hook");
5386 Qwindowp
= intern ("windowp");
5387 staticpro (&Qwindowp
);
5389 Qwindow_configuration_p
= intern ("window-configuration-p");
5390 staticpro (&Qwindow_configuration_p
);
5392 Qwindow_live_p
= intern ("window-live-p");
5393 staticpro (&Qwindow_live_p
);
5395 Qtemp_buffer_show_hook
= intern ("temp-buffer-show-hook");
5396 staticpro (&Qtemp_buffer_show_hook
);
5398 staticpro (&Vwindow_list
);
5400 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
5401 "Non-nil means call as function to display a help buffer.\n\
5402 The function is called with one argument, the buffer to be displayed.\n\
5403 Used by `with-output-to-temp-buffer'.\n\
5404 If this function is used, then it must do the entire job of showing\n\
5405 the buffer; `temp-buffer-show-hook' is not run unless this function runs it.");
5406 Vtemp_buffer_show_function
= Qnil
;
5408 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
5409 "If non-nil, function to call to handle `display-buffer'.\n\
5410 It will receive two args, the buffer and a flag which if non-nil means\n\
5411 that the currently selected window is not acceptable.\n\
5412 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
5413 work using this function.");
5414 Vdisplay_buffer_function
= Qnil
;
5416 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
5417 "Non-nil means it is the window that C-M-v in minibuffer should scroll.");
5418 Vminibuf_scroll_window
= Qnil
;
5420 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
5421 "If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.");
5422 Vother_window_scroll_buffer
= Qnil
;
5424 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
5425 "*Non-nil means `display-buffer' should make a separate frame.");
5428 DEFVAR_BOOL ("display-buffer-reuse-frames", &display_buffer_reuse_frames
,
5429 "*Non-nil means `display-buffer' should reuse frames.\n\
5430 If the buffer in question is already displayed in a frame, raise that frame.");
5431 display_buffer_reuse_frames
= 0;
5433 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
5434 "Function to call to handle automatic new frame creation.\n\
5435 It is called with no arguments and should return a newly created frame.\n\
5437 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'\n\
5438 where `pop-up-frame-alist' would hold the default frame parameters.");
5439 Vpop_up_frame_function
= Qnil
;
5441 DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names
,
5442 "*List of buffer names that should have their own special frames.\n\
5443 Displaying a buffer whose name is in this list makes a special frame for it\n\
5444 using `special-display-function'. See also `special-display-regexps'.\n\
5446 An element of the list can be a list instead of just a string.\n\
5447 There are two ways to use a list as an element:\n\
5448 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)\n\
5449 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5450 In the latter case, FUNCTION is called with BUFFER as the first argument,\n\
5451 followed by OTHER-ARGS--it can display BUFFER in any way it likes.\n\
5452 All this is done by the function found in `special-display-function'.\n\
5454 If this variable appears \"not to work\", because you add a name to it\n\
5455 but that buffer still appears in the selected window, look at the\n\
5456 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5457 Those variables take precedence over this one.");
5458 Vspecial_display_buffer_names
= Qnil
;
5460 DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps
,
5461 "*List of regexps saying which buffers should have their own special frames.\n\
5462 If a buffer name matches one of these regexps, it gets its own frame.\n\
5463 Displaying a buffer whose name is in this list makes a special frame for it\n\
5464 using `special-display-function'.\n\
5466 An element of the list can be a list instead of just a string.\n\
5467 There are two ways to use a list as an element:\n\
5468 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)\n\
5469 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5470 In the latter case, FUNCTION is called with the buffer as first argument,\n\
5471 followed by OTHER-ARGS--it can display the buffer in any way it likes.\n\
5472 All this is done by the function found in `special-display-function'.\n\
5474 If this variable appears \"not to work\", because you add a regexp to it\n\
5475 but the matching buffers still appear in the selected window, look at the\n\
5476 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5477 Those variables take precedence over this one.");
5478 Vspecial_display_regexps
= Qnil
;
5480 DEFVAR_LISP ("special-display-function", &Vspecial_display_function
,
5481 "Function to call to make a new frame for a special buffer.\n\
5482 It is called with two arguments, the buffer and optional buffer specific\n\
5483 data, and should return a window displaying that buffer.\n\
5484 The default value makes a separate frame for the buffer,\n\
5485 using `special-display-frame-alist' to specify the frame parameters.\n\
5487 A buffer is special if its is listed in `special-display-buffer-names'\n\
5488 or matches a regexp in `special-display-regexps'.");
5489 Vspecial_display_function
= Qnil
;
5491 DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names
,
5492 "*List of buffer names that should appear in the selected window.\n\
5493 Displaying one of these buffers using `display-buffer' or `pop-to-buffer'\n\
5494 switches to it in the selected window, rather than making it appear\n\
5495 in some other window.\n\
5497 An element of the list can be a cons cell instead of just a string.\n\
5498 Then the car must be a string, which specifies the buffer name.\n\
5499 This is for compatibility with `special-display-buffer-names';\n\
5500 the cdr of the cons cell is ignored.\n\
5502 See also `same-window-regexps'.");
5503 Vsame_window_buffer_names
= Qnil
;
5505 DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps
,
5506 "*List of regexps saying which buffers should appear in the selected window.\n\
5507 If a buffer name matches one of these regexps, then displaying it\n\
5508 using `display-buffer' or `pop-to-buffer' switches to it\n\
5509 in the selected window, rather than making it appear in some other window.\n\
5511 An element of the list can be a cons cell instead of just a string.\n\
5512 Then the car must be a string, which specifies the buffer name.\n\
5513 This is for compatibility with `special-display-buffer-names';\n\
5514 the cdr of the cons cell is ignored.\n\
5516 See also `same-window-buffer-names'.");
5517 Vsame_window_regexps
= Qnil
;
5519 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
5520 "*Non-nil means display-buffer should make new windows.");
5523 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
5524 "*Number of lines of continuity when scrolling by screenfuls.");
5525 next_screen_context_lines
= 2;
5527 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
5528 "*display-buffer would prefer to split the largest window if this large.\n\
5529 If there is only one window, it is split regardless of this value.");
5530 split_height_threshold
= 500;
5532 DEFVAR_INT ("window-min-height", &window_min_height
,
5533 "*Delete any window less than this tall (including its mode line).");
5534 window_min_height
= 4;
5536 DEFVAR_INT ("window-min-width", &window_min_width
,
5537 "*Delete any window less than this wide.");
5538 window_min_width
= 10;
5540 DEFVAR_LISP ("scroll-preserve-screen-position",
5541 &Vscroll_preserve_screen_position
,
5542 "*Nonzero means scroll commands move point to keep its screen line unchanged.");
5543 Vscroll_preserve_screen_position
= Qnil
;
5545 DEFVAR_LISP ("window-configuration-change-hook",
5546 &Vwindow_configuration_change_hook
,
5547 "Functions to call when window configuration changes.\n\
5548 The selected frame is the one whose configuration has changed.");
5549 Vwindow_configuration_change_hook
= Qnil
;
5551 defsubr (&Sselected_window
);
5552 defsubr (&Sminibuffer_window
);
5553 defsubr (&Swindow_minibuffer_p
);
5554 defsubr (&Swindowp
);
5555 defsubr (&Swindow_live_p
);
5556 defsubr (&Spos_visible_in_window_p
);
5557 defsubr (&Swindow_buffer
);
5558 defsubr (&Swindow_height
);
5559 defsubr (&Swindow_width
);
5560 defsubr (&Swindow_hscroll
);
5561 defsubr (&Sset_window_hscroll
);
5562 defsubr (&Swindow_redisplay_end_trigger
);
5563 defsubr (&Sset_window_redisplay_end_trigger
);
5564 defsubr (&Swindow_edges
);
5565 defsubr (&Scoordinates_in_window_p
);
5566 defsubr (&Swindow_at
);
5567 defsubr (&Swindow_point
);
5568 defsubr (&Swindow_start
);
5569 defsubr (&Swindow_end
);
5570 defsubr (&Sset_window_point
);
5571 defsubr (&Sset_window_start
);
5572 defsubr (&Swindow_dedicated_p
);
5573 defsubr (&Sset_window_dedicated_p
);
5574 defsubr (&Swindow_display_table
);
5575 defsubr (&Sset_window_display_table
);
5576 defsubr (&Snext_window
);
5577 defsubr (&Sprevious_window
);
5578 defsubr (&Sother_window
);
5579 defsubr (&Sget_lru_window
);
5580 defsubr (&Sget_largest_window
);
5581 defsubr (&Sget_buffer_window
);
5582 defsubr (&Sdelete_other_windows
);
5583 defsubr (&Sdelete_windows_on
);
5584 defsubr (&Sreplace_buffer_in_windows
);
5585 defsubr (&Sdelete_window
);
5586 defsubr (&Sset_window_buffer
);
5587 defsubr (&Sselect_window
);
5588 defsubr (&Sspecial_display_p
);
5589 defsubr (&Ssame_window_p
);
5590 defsubr (&Sdisplay_buffer
);
5591 defsubr (&Ssplit_window
);
5592 defsubr (&Senlarge_window
);
5593 defsubr (&Sshrink_window
);
5594 defsubr (&Sscroll_up
);
5595 defsubr (&Sscroll_down
);
5596 defsubr (&Sscroll_left
);
5597 defsubr (&Sscroll_right
);
5598 defsubr (&Sother_window_for_scrolling
);
5599 defsubr (&Sscroll_other_window
);
5600 defsubr (&Srecenter
);
5601 defsubr (&Smove_to_window_line
);
5602 defsubr (&Swindow_configuration_p
);
5603 defsubr (&Swindow_configuration_frame
);
5604 defsubr (&Sset_window_configuration
);
5605 defsubr (&Scurrent_window_configuration
);
5606 defsubr (&Ssave_window_excursion
);
5607 defsubr (&Sset_window_margins
);
5608 defsubr (&Swindow_margins
);
5609 defsubr (&Swindow_vscroll
);
5610 defsubr (&Sset_window_vscroll
);
5611 defsubr (&Scompare_window_configurations
);
5612 defsubr (&Swindow_list
);
5618 initial_define_key (control_x_map
, '1', "delete-other-windows");
5619 initial_define_key (control_x_map
, '2', "split-window");
5620 initial_define_key (control_x_map
, '0', "delete-window");
5621 initial_define_key (control_x_map
, 'o', "other-window");
5622 initial_define_key (control_x_map
, '^', "enlarge-window");
5623 initial_define_key (control_x_map
, '<', "scroll-left");
5624 initial_define_key (control_x_map
, '>', "scroll-right");
5626 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
5627 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
5628 initial_define_key (meta_map
, 'v', "scroll-down");
5630 initial_define_key (global_map
, Ctl('L'), "recenter");
5631 initial_define_key (meta_map
, 'r', "move-to-window-line");