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 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 /* Return true if POS is fully visible in the window W. If W's end
298 position is not known, then return false. */
301 pos_fully_visible_in_window_p (pos
, w
)
305 struct glyph_row
*first_row
= &w
->desired_matrix
->rows
[0];
306 struct glyph_row
*last_row
;
308 if (pos
< first_row
->start
.pos
.charpos
)
309 /* POS is before the beginning of W. */
311 else if (pos
< first_row
->end
.pos
.charpos
)
312 /* POS is on the first row of W, so see if that row is fully visible. */
313 return !MATRIX_ROW_PARTIALLY_VISIBLE_P (first_row
);
315 if (NILP (w
->window_end_valid
))
316 /* We can't determine where the end is, so we don't know. */
319 last_row
= &w
->desired_matrix
->rows
[XFASTINT (w
->window_end_vpos
)];
321 if (pos
< last_row
->start
.pos
.charpos
)
322 /* POS is somewhere in the middle of the window, not on the first or
323 last row, so it must be visible. */
325 else if (pos
>= last_row
->end
.pos
.charpos
)
326 /* POS is after the end of W. */
329 /* POS is on the last row of W, so see if that row is fully visible. */
330 return !MATRIX_ROW_PARTIALLY_VISIBLE_P (last_row
);
334 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
335 Spos_visible_in_window_p
, 0, 3, 0,
336 "Return t if position POS is currently on the frame in WINDOW.\n\
337 Returns nil if that position is scrolled vertically out of view.\n\
338 If FULLY is non-nil, then only return t when POS is completely visible.\n\
339 POS defaults to point; WINDOW, to the selected window.")
341 Lisp_Object pos
, window
, fully
;
343 register struct window
*w
;
345 register struct buffer
*buf
;
347 Lisp_Object in_window
;
353 CHECK_NUMBER_COERCE_MARKER (pos
, 0);
357 w
= decode_window (window
);
358 buf
= XBUFFER (w
->buffer
);
359 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
361 /* If position above window, it's not visible. */
362 if (posint
< CHARPOS (top
))
364 else if (XFASTINT (w
->last_modified
) >= BUF_MODIFF (buf
)
365 && XFASTINT (w
->last_overlay_modified
) >= BUF_OVERLAY_MODIFF (buf
)
366 && posint
< BUF_Z (buf
) - XFASTINT (w
->window_end_pos
))
367 /* If frame is up to date, and POSINT is < window end pos, use
368 that info. This doesn't work for POSINT == end pos, because
369 the window end pos is actually the position _after_ the last
370 char in the window. */
372 if (NILP (fully
) || pos_fully_visible_in_window_p (posint
, w
))
377 else if (posint
> BUF_ZV (buf
))
379 else if (CHARPOS (top
) < BUF_BEGV (buf
) || CHARPOS (top
) > BUF_ZV (buf
))
380 /* If window start is out of range, do something reasonable. */
385 start_display (&it
, w
, top
);
386 move_it_to (&it
, posint
, 0, it
.last_visible_y
, -1,
387 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
388 if (IT_CHARPOS (it
) == posint
)
394 struct glyph_row
*pos_row
= &w
->desired_matrix
->rows
[it
.vpos
];
395 return MATRIX_ROW_PARTIALLY_VISIBLE_P(pos_row
) ? Qnil
: Qt
;
405 static struct window
*
406 decode_window (window
)
407 register Lisp_Object window
;
410 return XWINDOW (selected_window
);
412 CHECK_LIVE_WINDOW (window
, 0);
413 return XWINDOW (window
);
416 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
417 "Return the buffer that WINDOW is displaying.")
421 return decode_window (window
)->buffer
;
424 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
425 "Return the number of lines in WINDOW (including its mode line).")
429 return decode_window (window
)->height
;
432 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
433 "Return the number of display columns in WINDOW.\n\
434 This is the width that is usable columns available for text in WINDOW.\n\
435 If you want to find out how many columns WINDOW takes up,\n\
436 use (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))).")
440 return make_number (window_internal_width (decode_window (window
)));
443 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
444 "Return the number of columns by which WINDOW is scrolled from left margin.")
448 return decode_window (window
)->hscroll
;
451 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
452 "Set number of columns WINDOW is scrolled from left margin to NCOL.\n\
453 NCOL should be zero or positive.")
455 register Lisp_Object window
, ncol
;
457 register struct window
*w
;
459 CHECK_NUMBER (ncol
, 1);
460 if (XINT (ncol
) < 0) XSETFASTINT (ncol
, 0);
461 w
= decode_window (window
);
462 if (XINT (w
->hscroll
) != XINT (ncol
))
463 /* Prevent redisplay shortcuts */
464 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
469 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
470 Swindow_redisplay_end_trigger
, 0, 1, 0,
471 "Return WINDOW's redisplay end trigger value.\n\
472 See `set-window-redisplay-end-trigger' for more information.")
476 return decode_window (window
)->redisplay_end_trigger
;
479 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
480 Sset_window_redisplay_end_trigger
, 2, 2, 0,
481 "Set WINDOW's redisplay end trigger value to VALUE.\n\
482 VALUE should be a buffer position (typically a marker) or nil.\n\
483 If it is a buffer position, then if redisplay in WINDOW reaches a position\n\
484 beyond VALUE, the functions in `redisplay-end-trigger-functions' are called\n\
485 with two arguments: WINDOW, and the end trigger value.\n\
486 Afterwards the end-trigger value is reset to nil.")
488 register Lisp_Object window
, value
;
490 register struct window
*w
;
492 w
= decode_window (window
);
493 w
->redisplay_end_trigger
= value
;
497 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
498 "Return a list of the edge coordinates of WINDOW.\n\
499 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.\n\
500 RIGHT is one more than the rightmost column used by WINDOW,\n\
501 and BOTTOM is one more than the bottommost row used by WINDOW\n\
506 register struct window
*w
= decode_window (window
);
508 return Fcons (w
->left
, Fcons (w
->top
,
509 Fcons (make_number (WINDOW_RIGHT_EDGE (w
)),
510 Fcons (make_number (XFASTINT (w
->top
)
511 + XFASTINT (w
->height
)),
515 /* Test if the character at column *X, row *Y is within window W.
516 If it is not, return 0;
517 if it is in the window's text area,
518 set *x and *y to its location relative to the upper left corner
521 if it is on the window's modeline, return 2;
522 if it is on the border between the window and its right sibling,
524 if it is on the window's top line, return 4;
525 if it is in the bitmap area to the left/right of the window,
526 return 5 or 6, and convert *X and *Y to window-relative corrdinates.
528 X and Y are frame relative pixel coordinates. */
531 coordinates_in_window (w
, x
, y
)
532 register struct window
*w
;
535 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
536 int left_x
, right_x
, top_y
, bottom_y
;
537 int flags_area_width
= FRAME_LEFT_FLAGS_AREA_WIDTH (f
);
539 /* In what's below, we subtract 1 when computing right_x because we
540 want the rightmost pixel, which is given by left_pixel+width-1. */
541 if (w
->pseudo_window_p
)
544 right_x
= XFASTINT (w
->width
) * CANON_Y_UNIT (f
) - 1;
545 top_y
= WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
);
546 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
550 left_x
= (WINDOW_DISPLAY_LEFT_EDGE_PIXEL_X (w
)
551 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
552 right_x
= WINDOW_DISPLAY_RIGHT_EDGE_PIXEL_X (w
) - 1;
553 top_y
= (WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
)
554 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
555 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
562 - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
)
564 || *x
> right_x
+ flags_area_width
)
565 /* Completely outside anything interesting. */
567 else if (WINDOW_WANTS_MODELINE_P (w
)
568 && *y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
))
569 /* On the mode line. */
571 else if (WINDOW_WANTS_HEADER_LINE_P (w
)
572 && *y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
))
573 /* On the top line. */
575 /* Need to say "*x > right_x" rather than >=, since on character
576 terminals, the vertical line's x coordinate is right_x. */
577 else if (*x
< left_x
|| *x
> right_x
)
579 /* Other lines than the mode line don't include flags areas and
580 scroll bars on the left. */
582 /* Convert X and Y to window-relative pixel coordinates. */
585 return *x
< left_x
? 5 : 6;
587 /* Here, too, "*x > right_x" is because of character terminals. */
588 else if (!w
->pseudo_window_p
589 && !WINDOW_RIGHTMOST_P (w
)
590 && *x
> right_x
- CANON_X_UNIT (f
))
591 /* On the border on the right side of the window? Assume that
592 this area begins at RIGHT_X minus a canonical char width. */
596 /* Convert X and Y to window-relative pixel coordinates. */
603 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
604 Scoordinates_in_window_p
, 2, 2, 0,
605 "Return non-nil if COORDINATES are in WINDOW.\n\
606 COORDINATES is a cons of the form (X . Y), X and Y being distances\n\
607 measured in characters from the upper-left corner of the frame.\n\
608 (0 . 0) denotes the character in the upper left corner of the\n\
610 If COORDINATES are in the text portion of WINDOW,\n\
611 the coordinates relative to the window are returned.\n\
612 If they are in the mode line of WINDOW, `mode-line' is returned.\n\
613 If they are in the top mode line of WINDOW, `header-line' is returned.\n\
614 If they are in the bitmap-area to the left of the window,\n\
615 `left-bitmap-area' is returned, if they are in the area on the right of\n\
616 the window, `right-bitmap-area' is returned.\n\
617 If they are on the border between WINDOW and its right sibling,\n\
618 `vertical-line' is returned.")
619 (coordinates
, window
)
620 register Lisp_Object coordinates
, window
;
627 CHECK_LIVE_WINDOW (window
, 0);
628 w
= XWINDOW (window
);
629 f
= XFRAME (w
->frame
);
630 CHECK_CONS (coordinates
, 1);
631 lx
= Fcar (coordinates
);
632 ly
= Fcdr (coordinates
);
633 CHECK_NUMBER_OR_FLOAT (lx
, 1);
634 CHECK_NUMBER_OR_FLOAT (ly
, 1);
635 x
= PIXEL_X_FROM_CANON_X (f
, lx
);
636 y
= PIXEL_Y_FROM_CANON_Y (f
, ly
);
638 switch (coordinates_in_window (w
, &x
, &y
))
640 case 0: /* NOT in window at all. */
643 case 1: /* In text part of window. */
644 /* X and Y are now window relative pixel coordinates.
645 Convert them to canonical char units before returning
647 return Fcons (CANON_X_FROM_PIXEL_X (f
, x
),
648 CANON_Y_FROM_PIXEL_Y (f
, y
));
650 case 2: /* In mode line of window. */
653 case 3: /* On right border of window. */
654 return Qvertical_line
;
660 return Qleft_bitmap_area
;
663 return Qright_bitmap_area
;
671 /* Callback for foreach_window, used in window_from_coordinates.
672 Check if window W contains coordinates specified by USER_DATA which
673 is actually a pointer to a struct check_window_data CW.
675 Check if window W contains coordinates *CW->x and *CW->y. If it
676 does, return W in *CW->window, as Lisp_Object, and return in
677 *CW->part the part of the window under coordinates *X,*Y. Return
678 zero from this function to stop iterating over windows. */
680 struct check_window_data
687 check_window_containing (w
, user_data
)
691 struct check_window_data
*cw
= (struct check_window_data
*) user_data
;
694 found
= coordinates_in_window (w
, cw
->x
, cw
->y
);
697 *cw
->part
= found
- 1;
698 XSETWINDOW (*cw
->window
, w
);
705 /* Find the window containing frame-relative pixel position X/Y and
706 return it as a Lisp_Object. If X, Y is on the window's modeline,
707 set *PART to 1; if it is on the separating line between the window
708 and its right sibling, set it to 2; otherwise set it to 0. If
709 there is no window under X, Y return nil and leave *PART
710 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows.
712 This function was previously implemented with a loop cycling over
713 windows with Fnext_window, and starting with the frame's selected
714 window. It turned out that this doesn't work with an
715 implementation of next_window using Vwindow_list, because
716 FRAME_SELECTED_WINDOW (F) is not always contained in the window
717 tree of F when this function is called asynchronously from
718 note_mouse_highlight. The original loop didn't terminate in this
722 window_from_coordinates (f
, x
, y
, part
, tool_bar_p
)
729 struct check_window_data cw
;
732 cw
.window
= &window
, cw
.x
= &x
, cw
.y
= &y
; cw
.part
= part
;
733 foreach_window (f
, check_window_containing
, &cw
);
735 /* If not found above, see if it's in the tool bar window, if a tool
739 && WINDOWP (f
->tool_bar_window
)
740 && XINT (XWINDOW (f
->tool_bar_window
)->height
) > 0
741 && coordinates_in_window (XWINDOW (f
->tool_bar_window
), &x
, &y
))
744 window
= f
->tool_bar_window
;
750 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
751 "Return window containing coordinates X and Y on FRAME.\n\
752 If omitted, FRAME defaults to the currently selected frame.\n\
753 The top left corner of the frame is considered to be row 0,\n\
756 Lisp_Object x
, y
, frame
;
762 frame
= selected_frame
;
763 CHECK_LIVE_FRAME (frame
, 2);
766 /* Check that arguments are integers or floats. */
767 CHECK_NUMBER_OR_FLOAT (x
, 0);
768 CHECK_NUMBER_OR_FLOAT (y
, 1);
770 return window_from_coordinates (f
,
771 PIXEL_X_FROM_CANON_X (f
, x
),
772 PIXEL_Y_FROM_CANON_Y (f
, y
),
776 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
777 "Return current value of point in WINDOW.\n\
778 For a nonselected window, this is the value point would have\n\
779 if that window were selected.\n\
781 Note that, when WINDOW is the selected window and its buffer\n\
782 is also currently selected, the value returned is the same as (point).\n\
783 It would be more strictly correct to return the `top-level' value\n\
784 of point, outside of any save-excursion forms.\n\
785 But that is hard to define.")
789 register struct window
*w
= decode_window (window
);
791 if (w
== XWINDOW (selected_window
)
792 && current_buffer
== XBUFFER (w
->buffer
))
794 return Fmarker_position (w
->pointm
);
797 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
798 "Return position at which display currently starts in WINDOW.\n\
799 This is updated by redisplay or by calling `set-window-start'.")
803 return Fmarker_position (decode_window (window
)->start
);
806 /* This is text temporarily removed from the doc string below.
808 This function returns nil if the position is not currently known.\n\
809 That happens when redisplay is preempted and doesn't finish.\n\
810 If in that case you want to compute where the end of the window would\n\
811 have been if redisplay had finished, do this:\n\
813 (goto-char (window-start window))\n\
814 (vertical-motion (1- (window-height window)) window)\n\
817 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
818 "Return position at which display currently ends in WINDOW.\n\
819 This is updated by redisplay, when it runs to completion.\n\
820 Simply changing the buffer text or setting `window-start'\n\
821 does not update this value.\n\
822 If UP-TO-DATE is non-nil, compute the up-to-date position\n\
823 if it isn't already recorded.")
825 Lisp_Object window
, update
;
828 struct window
*w
= decode_window (window
);
832 CHECK_BUFFER (buf
, 0);
834 #if 0 /* This change broke some things. We should make it later. */
835 /* If we don't know the end position, return nil.
836 The user can compute it with vertical-motion if he wants to.
837 It would be nicer to do it automatically,
838 but that's so slow that it would probably bother people. */
839 if (NILP (w
->window_end_valid
))
844 && ! (! NILP (w
->window_end_valid
)
845 && XFASTINT (w
->last_modified
) >= MODIFF
))
847 struct text_pos startp
;
850 /* In case W->start is out of the range, use something
851 reasonable. This situation occured when loading a file with
852 `-l' containing a call to `rmail' with subsequent other
853 commands. At the end, W->start happened to be BEG, while
854 rmail had already narrowed the buffer. */
855 if (XMARKER (w
->start
)->charpos
< BEGV
)
856 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
857 else if (XMARKER (w
->start
)->charpos
> ZV
)
858 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
860 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
862 /* Cannot use Fvertical_motion because that function doesn't
863 cope with variable-height lines. */
864 start_display (&it
, w
, startp
);
865 move_it_vertically (&it
, window_box_height (w
));
866 value
= make_number (IT_CHARPOS (it
));
869 XSETINT (value
, BUF_Z (XBUFFER (buf
)) - XFASTINT (w
->window_end_pos
));
874 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
875 "Make point value in WINDOW be at position POS in WINDOW's buffer.")
877 Lisp_Object window
, pos
;
879 register struct window
*w
= decode_window (window
);
881 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
882 if (w
== XWINDOW (selected_window
)
883 && XBUFFER (w
->buffer
) == current_buffer
)
886 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
891 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
892 "Make display in WINDOW start at position POS in WINDOW's buffer.\n\
893 Optional third arg NOFORCE non-nil inhibits next redisplay\n\
894 from overriding motion of point in order to display at this exact start.")
895 (window
, pos
, noforce
)
896 Lisp_Object window
, pos
, noforce
;
898 register struct window
*w
= decode_window (window
);
900 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
901 set_marker_restricted (w
->start
, pos
, w
->buffer
);
902 /* this is not right, but much easier than doing what is right. */
903 w
->start_at_line_beg
= Qnil
;
906 w
->update_mode_line
= Qt
;
907 XSETFASTINT (w
->last_modified
, 0);
908 XSETFASTINT (w
->last_overlay_modified
, 0);
909 if (!EQ (window
, selected_window
))
910 windows_or_buffers_changed
++;
915 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
917 "Return WINDOW's dedicated object, usually t or nil.\n\
918 See also `set-window-dedicated-p'.")
922 return decode_window (window
)->dedicated
;
925 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
926 Sset_window_dedicated_p
, 2, 2, 0,
927 "Control whether WINDOW is dedicated to the buffer it displays.\n\
928 If it is dedicated, Emacs will not automatically change\n\
929 which buffer appears in it.\n\
930 The second argument is the new value for the dedication flag;\n\
933 Lisp_Object window
, arg
;
935 register struct window
*w
= decode_window (window
);
945 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
947 "Return the display-table that WINDOW is using.")
951 return decode_window (window
)->display_table
;
954 /* Get the display table for use on window W. This is either W's
955 display table or W's buffer's display table. Ignore the specified
956 tables if they are not valid; if no valid table is specified,
959 struct Lisp_Char_Table
*
960 window_display_table (w
)
963 struct Lisp_Char_Table
*dp
= NULL
;
965 if (DISP_TABLE_P (w
->display_table
))
966 dp
= XCHAR_TABLE (w
->display_table
);
967 else if (BUFFERP (w
->buffer
))
969 struct buffer
*b
= XBUFFER (w
->buffer
);
971 if (DISP_TABLE_P (b
->display_table
))
972 dp
= XCHAR_TABLE (b
->display_table
);
973 else if (DISP_TABLE_P (Vstandard_display_table
))
974 dp
= XCHAR_TABLE (Vstandard_display_table
);
980 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
981 "Set WINDOW's display-table to TABLE.")
983 register Lisp_Object window
, table
;
985 register struct window
*w
;
987 w
= decode_window (window
);
988 w
->display_table
= table
;
992 /* Record info on buffer window w is displaying
993 when it is about to cease to display that buffer. */
996 register struct window
*w
;
1003 if (b
!= XMARKER (w
->pointm
)->buffer
)
1007 if (w
== XWINDOW (selected_window
)
1008 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
1009 /* Do this except when the selected window's buffer
1010 is being removed from some other window. */
1012 /* last_window_start records the start position that this buffer
1013 had in the last window to be disconnected from it.
1014 Now that this statement is unconditional,
1015 it is possible for the buffer to be displayed in the
1016 selected window, while last_window_start reflects another
1017 window which was recently showing the same buffer.
1018 Some people might say that might be a good thing. Let's see. */
1019 b
->last_window_start
= marker_position (w
->start
);
1021 /* Point in the selected window's buffer
1022 is actually stored in that buffer, and the window's pointm isn't used.
1023 So don't clobber point in that buffer. */
1024 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
)
1025 /* This line helps to fix Horsley's testbug.el bug. */
1026 && !(WINDOWP (b
->last_selected_window
)
1027 && w
!= XWINDOW (b
->last_selected_window
)
1028 && EQ (buf
, XWINDOW (b
->last_selected_window
)->buffer
)))
1029 temp_set_point_both (b
,
1030 clip_to_bounds (BUF_BEGV (b
),
1031 XMARKER (w
->pointm
)->charpos
,
1033 clip_to_bounds (BUF_BEGV_BYTE (b
),
1034 marker_byte_position (w
->pointm
),
1037 if (WINDOWP (b
->last_selected_window
)
1038 && w
== XWINDOW (b
->last_selected_window
))
1039 b
->last_selected_window
= Qnil
;
1042 /* Put replacement into the window structure in place of old. */
1044 replace_window (old
, replacement
)
1045 Lisp_Object old
, replacement
;
1047 register Lisp_Object tem
;
1048 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
1050 /* If OLD is its frame's root_window, then replacement is the new
1051 root_window for that frame. */
1053 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
1054 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
1058 p
->width
= o
->width
;
1059 p
->height
= o
->height
;
1060 p
->desired_matrix
= p
->current_matrix
= 0;
1062 bzero (&p
->cursor
, sizeof (p
->cursor
));
1063 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
1064 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
1065 p
->phys_cursor_type
= -1;
1066 p
->must_be_updated_p
= 0;
1067 p
->pseudo_window_p
= 0;
1068 XSETFASTINT (p
->window_end_vpos
, 0);
1069 XSETFASTINT (p
->window_end_pos
, 0);
1070 p
->window_end_valid
= Qnil
;
1071 p
->frozen_window_start_p
= 0;
1072 p
->orig_top
= p
->orig_height
= Qnil
;
1074 p
->next
= tem
= o
->next
;
1076 XWINDOW (tem
)->prev
= replacement
;
1078 p
->prev
= tem
= o
->prev
;
1080 XWINDOW (tem
)->next
= replacement
;
1082 p
->parent
= tem
= o
->parent
;
1085 if (EQ (XWINDOW (tem
)->vchild
, old
))
1086 XWINDOW (tem
)->vchild
= replacement
;
1087 if (EQ (XWINDOW (tem
)->hchild
, old
))
1088 XWINDOW (tem
)->hchild
= replacement
;
1091 /*** Here, if replacement is a vertical combination
1092 and so is its new parent, we should make replacement's
1093 children be children of that parent instead. ***/
1096 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
1097 "Remove WINDOW from the display. Default is selected window.")
1099 register Lisp_Object window
;
1101 delete_window (window
);
1103 if (! NILP (Vwindow_configuration_change_hook
)
1104 && ! NILP (Vrun_hooks
))
1105 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
1111 delete_window (window
)
1112 register Lisp_Object window
;
1114 register Lisp_Object tem
, parent
, sib
;
1115 register struct window
*p
;
1116 register struct window
*par
;
1119 /* Because this function is called by other C code on non-leaf
1120 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1121 so we can't decode_window here. */
1123 window
= selected_window
;
1125 CHECK_WINDOW (window
, 0);
1126 p
= XWINDOW (window
);
1128 /* It's okay to delete an already-deleted window. */
1129 if (NILP (p
->buffer
)
1131 && NILP (p
->vchild
))
1136 error ("Attempt to delete minibuffer or sole ordinary window");
1137 par
= XWINDOW (parent
);
1139 windows_or_buffers_changed
++;
1140 Vwindow_list
= Qnil
;
1141 frame
= XFRAME (WINDOW_FRAME (p
));
1142 FRAME_WINDOW_SIZES_CHANGED (frame
) = 1;
1144 /* Are we trying to delete any frame's selected window? */
1146 Lisp_Object frame
, pwindow
;
1148 /* See if the frame's selected window is either WINDOW
1149 or any subwindow of it, by finding all that window's parents
1150 and comparing each one with WINDOW. */
1151 frame
= WINDOW_FRAME (XWINDOW (window
));
1152 pwindow
= FRAME_SELECTED_WINDOW (XFRAME (frame
));
1154 while (!NILP (pwindow
))
1156 if (EQ (window
, pwindow
))
1158 pwindow
= XWINDOW (pwindow
)->parent
;
1161 if (EQ (window
, pwindow
))
1163 Lisp_Object alternative
;
1164 alternative
= Fnext_window (window
, Qlambda
, Qnil
);
1166 /* If we're about to delete the selected window on the
1167 selected frame, then we should use Fselect_window to select
1168 the new window. On the other hand, if we're about to
1169 delete the selected window on any other frame, we shouldn't do
1170 anything but set the frame's selected_window slot. */
1171 if (EQ (window
, selected_window
))
1172 Fselect_window (alternative
);
1174 FRAME_SELECTED_WINDOW (XFRAME (frame
)) = alternative
;
1179 /* tem is null for dummy parent windows
1180 (which have inferiors but not any contents themselves) */
1184 unchain_marker (p
->pointm
);
1185 unchain_marker (p
->start
);
1188 /* Free window glyph matrices. It is sure that they are allocated
1189 again when ADJUST_GLYPHS is called. Block input so that expose
1190 events and other events that access glyph matrices are not
1191 processed while we are changing them. */
1193 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (frame
)));
1197 XWINDOW (tem
)->prev
= p
->prev
;
1201 XWINDOW (tem
)->next
= p
->next
;
1203 if (EQ (window
, par
->hchild
))
1204 par
->hchild
= p
->next
;
1205 if (EQ (window
, par
->vchild
))
1206 par
->vchild
= p
->next
;
1208 /* Find one of our siblings to give our space to. */
1212 /* If p gives its space to its next sibling, that sibling needs
1213 to have its top/left side pulled back to where p's is.
1214 set_window_{height,width} will re-position the sibling's
1217 XWINDOW (sib
)->top
= p
->top
;
1218 XWINDOW (sib
)->left
= p
->left
;
1221 /* Stretch that sibling. */
1222 if (!NILP (par
->vchild
))
1223 set_window_height (sib
,
1224 XFASTINT (XWINDOW (sib
)->height
) + XFASTINT (p
->height
),
1226 if (!NILP (par
->hchild
))
1227 set_window_width (sib
,
1228 XFASTINT (XWINDOW (sib
)->width
) + XFASTINT (p
->width
),
1231 /* If parent now has only one child,
1232 put the child into the parent's place. */
1236 if (NILP (XWINDOW (tem
)->next
))
1237 replace_window (parent
, tem
);
1239 /* Since we may be deleting combination windows, we must make sure that
1240 not only p but all its children have been marked as deleted. */
1241 if (! NILP (p
->hchild
))
1242 delete_all_subwindows (XWINDOW (p
->hchild
));
1243 else if (! NILP (p
->vchild
))
1244 delete_all_subwindows (XWINDOW (p
->vchild
));
1246 /* Mark this window as deleted. */
1247 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
1249 /* Adjust glyph matrices. */
1250 adjust_glyphs (frame
);
1256 /***********************************************************************
1258 ***********************************************************************/
1260 /* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object
1261 pointer. This is a callback function for foreach_window, used in
1262 function window_list. */
1265 add_window_to_list (w
, user_data
)
1269 Lisp_Object
*list
= (Lisp_Object
*) user_data
;
1271 XSETWINDOW (window
, w
);
1272 *list
= Fcons (window
, *list
);
1277 /* Return a list of all windows, for use by next_window. If
1278 Vwindow_list is a list, return that list. Otherwise, build a new
1279 list, cache it in Vwindow_list, and return that. */
1284 if (!CONSP (Vwindow_list
))
1288 Vwindow_list
= Qnil
;
1289 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
1291 Lisp_Object args
[2];
1293 /* We are visiting windows in canonical order, and add
1294 new windows at the front of args[1], which means we
1295 have to reverse this list at the end. */
1297 foreach_window (XFRAME (XCAR (tail
)), add_window_to_list
, &args
[1]);
1298 args
[0] = Vwindow_list
;
1299 args
[1] = Fnreverse (args
[1]);
1300 Vwindow_list
= Fnconc (2, args
);
1304 return Vwindow_list
;
1308 /* Value is non-zero if WINDOW satisfies the constraints given by
1309 OWINDOW, MINIBUF and ALL_FRAMES.
1311 MINIBUF t means WINDOW may be minibuffer windows.
1312 `lambda' means WINDOW may not be a minibuffer window.
1313 a window means a specific minibuffer window
1315 ALL_FRAMES t means search all frames,
1316 nil means search just current frame,
1317 `visible' means search just visible frames,
1318 0 means search visible and iconified frames,
1319 a window means search the frame that window belongs to,
1320 a frame means consider windows on that frame, only. */
1323 candidate_window_p (window
, owindow
, minibuf
, all_frames
)
1324 Lisp_Object window
, owindow
, minibuf
, all_frames
;
1326 struct window
*w
= XWINDOW (window
);
1327 struct frame
*f
= XFRAME (w
->frame
);
1328 int candidate_p
= 1;
1330 if (!BUFFERP (w
->buffer
))
1332 else if (MINI_WINDOW_P (w
)
1333 && (EQ (minibuf
, Qlambda
)
1334 || (WINDOWP (minibuf
) && !EQ (minibuf
, window
))))
1336 /* If MINIBUF is `lambda' don't consider any mini-windows.
1337 If it is a window, consider only that one. */
1340 else if (EQ (all_frames
, Qt
))
1342 else if (NILP (all_frames
))
1344 xassert (WINDOWP (owindow
));
1345 candidate_p
= EQ (w
->frame
, XWINDOW (owindow
)->frame
);
1347 else if (EQ (all_frames
, Qvisible
))
1349 FRAME_SAMPLE_VISIBILITY (f
);
1350 candidate_p
= FRAME_VISIBLE_P (f
);
1352 else if (INTEGERP (all_frames
) && XINT (all_frames
) == 0)
1354 FRAME_SAMPLE_VISIBILITY (f
);
1355 candidate_p
= FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
);
1357 else if (WINDOWP (all_frames
))
1358 candidate_p
= (EQ (FRAME_MINIBUF_WINDOW (f
), all_frames
)
1359 || EQ (XWINDOW (all_frames
)->frame
, w
->frame
)
1360 || EQ (XWINDOW (all_frames
)->frame
, FRAME_FOCUS_FRAME (f
)));
1361 else if (FRAMEP (all_frames
))
1362 candidate_p
= EQ (all_frames
, w
->frame
);
1368 /* Decode arguments as allowed by Fnext_window, Fprevious_window, and
1369 Fwindow_list. See there for the meaning of WINDOW, MINIBUF, and
1373 decode_next_window_args (window
, minibuf
, all_frames
)
1374 Lisp_Object
*window
, *minibuf
, *all_frames
;
1377 *window
= selected_window
;
1379 CHECK_LIVE_WINDOW (*window
, 0);
1381 /* MINIBUF nil may or may not include minibuffers. Decide if it
1383 if (NILP (*minibuf
))
1384 *minibuf
= minibuf_level
? minibuf_window
: Qlambda
;
1385 else if (!EQ (*minibuf
, Qt
))
1388 /* Now *MINIBUF can be t => count all minibuffer windows, `lambda'
1389 => count none of them, or a specific minibuffer window (the
1390 active one) to count. */
1392 /* ALL_FRAMES nil doesn't specify which frames to include. */
1393 if (NILP (*all_frames
))
1394 *all_frames
= (!EQ (*minibuf
, Qlambda
)
1395 ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window
)->frame
))
1397 else if (EQ (*all_frames
, Qvisible
))
1399 else if (XFASTINT (*all_frames
) == 0)
1401 else if (FRAMEP (*all_frames
))
1403 else if (!EQ (*all_frames
, Qt
))
1406 /* Now *ALL_FRAMES is t meaning search all frames, nil meaning
1407 search just current frame, `visible' meaning search just visible
1408 frames, 0 meaning search visible and iconified frames, or a
1409 window, meaning search the frame that window belongs to, or a
1410 frame, meaning consider windows on that frame, only. */
1414 /* Return the next or previous window of WINDOW in canonical ordering
1415 of windows. NEXT_P non-zero means return the next window. See the
1416 documentation string of next-window for the meaning of MINIBUF and
1420 next_window (window
, minibuf
, all_frames
, next_p
)
1421 Lisp_Object window
, minibuf
, all_frames
;
1424 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1426 /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just
1427 return the first window on the frame. */
1428 if (FRAMEP (all_frames
)
1429 && !EQ (all_frames
, XWINDOW (window
)->frame
))
1430 return Fframe_first_window (all_frames
);
1436 /* Find WINDOW in the list of all windows. */
1437 list
= Fmemq (window
, window_list ());
1439 /* Scan forward from WINDOW to the end of the window list. */
1441 for (list
= XCDR (list
); CONSP (list
); list
= XCDR (list
))
1442 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1445 /* Scan from the start of the window list up to WINDOW. */
1447 for (list
= Vwindow_list
;
1448 CONSP (list
) && !EQ (XCAR (list
), window
);
1450 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1454 window
= XCAR (list
);
1458 Lisp_Object candidate
, list
;
1460 /* Scan through the list of windows for candidates. If there are
1461 candidate windows in front of WINDOW, the last one of these
1462 is the one we want. If there are candidates following WINDOW
1463 in the list, again the last one of these is the one we want. */
1465 for (list
= window_list (); CONSP (list
); list
= XCDR (list
))
1467 if (EQ (XCAR (list
), window
))
1469 if (WINDOWP (candidate
))
1472 else if (candidate_window_p (XCAR (list
), window
, minibuf
,
1474 candidate
= XCAR (list
);
1477 if (WINDOWP (candidate
))
1485 /* This comment supplies the doc string for `next-window',
1486 for make-docfile to see. We cannot put this in the real DEFUN
1487 due to limits in the Unix cpp.
1489 DEFUN ("next-window", Ffoo, Sfoo, 0, 3, 0,
1490 "Return next window after WINDOW in canonical ordering of windows.\n\
1491 If omitted, WINDOW defaults to the selected window.\n\
1493 Optional second arg MINIBUF t means count the minibuffer window even\n\
1494 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1495 it is active. MINIBUF neither t nor nil means not to count the\n\
1496 minibuffer even if it is active.\n\
1498 Several frames may share a single minibuffer; if the minibuffer\n\
1499 counts, all windows on all frames that share that minibuffer count\n\
1500 too. Therefore, `next-window' can be used to iterate through the\n\
1501 set of windows even when the minibuffer is on another frame. If the\n\
1502 minibuffer does not count, only windows from WINDOW's frame count.\n\
1504 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1505 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1506 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1507 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1508 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1509 Anything else means restrict to WINDOW's frame.\n\
1511 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1512 `next-window' to iterate through the entire cycle of acceptable\n\
1513 windows, eventually ending up back at the window you started with.\n\
1514 `previous-window' traverses the same cycle, in the reverse order.")
1515 (window, minibuf, all_frames) */
1517 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
1519 (window
, minibuf
, all_frames
)
1520 Lisp_Object window
, minibuf
, all_frames
;
1522 return next_window (window
, minibuf
, all_frames
, 1);
1526 /* This comment supplies the doc string for `previous-window',
1527 for make-docfile to see. We cannot put this in the real DEFUN
1528 due to limits in the Unix cpp.
1530 DEFUN ("previous-window", Ffoo, Sfoo, 0, 3, 0,
1531 "Return the window preceding WINDOW in canonical ordering of windows.\n\
1532 If omitted, WINDOW defaults to the selected window.\n\
1534 Optional second arg MINIBUF t means count the minibuffer window even\n\
1535 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1536 it is active. MINIBUF neither t nor nil means not to count the\n\
1537 minibuffer even if it is active.\n\
1539 Several frames may share a single minibuffer; if the minibuffer\n\
1540 counts, all windows on all frames that share that minibuffer count\n\
1541 too. Therefore, `previous-window' can be used to iterate through\n\
1542 the set of windows even when the minibuffer is on another frame. If\n\
1543 the minibuffer does not count, only windows from WINDOW's frame count\n\
1545 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1546 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1547 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1548 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1549 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1550 Anything else means restrict to WINDOW's frame.\n\
1552 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1553 `previous-window' to iterate through the entire cycle of acceptable\n\
1554 windows, eventually ending up back at the window you started with.\n\
1555 `next-window' traverses the same cycle, in the reverse order.")
1556 (window, minibuf, all_frames) */
1559 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
1561 (window
, minibuf
, all_frames
)
1562 Lisp_Object window
, minibuf
, all_frames
;
1564 return next_window (window
, minibuf
, all_frames
, 0);
1568 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1569 "Select the ARG'th different window on this frame.\n\
1570 All windows on current frame are arranged in a cyclic order.\n\
1571 This command selects the window ARG steps away in that order.\n\
1572 A negative ARG moves in the opposite order. If the optional second\n\
1573 argument ALL_FRAMES is non-nil, cycle through all frames.")
1575 Lisp_Object arg
, all_frames
;
1580 CHECK_NUMBER (arg
, 0);
1581 window
= selected_window
;
1583 for (i
= XINT (arg
); i
> 0; --i
)
1584 window
= Fnext_window (window
, Qnil
, all_frames
);
1586 window
= Fprevious_window (window
, Qnil
, all_frames
);
1588 Fselect_window (window
);
1593 DEFUN ("window-list", Fwindow_list
, Swindow_list
, 0, 3, 0,
1594 "Return a list of windows in canonical ordering.\n\
1595 Arguments are like for `next-window'.")
1596 (window
, minibuf
, all_frames
)
1597 Lisp_Object window
, minibuf
, all_frames
;
1599 Lisp_Object tail
, list
;
1601 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1604 for (tail
= window_list (); CONSP (tail
); tail
= XCDR (tail
))
1605 if (candidate_window_p (XCAR (tail
), window
, minibuf
, all_frames
))
1606 list
= Fcons (XCAR (tail
), list
);
1608 return Fnreverse (list
);
1613 /* Look at all windows, performing an operation specified by TYPE
1615 If FRAMES is Qt, look at all frames;
1616 Qnil, look at just the selected frame;
1617 Qvisible, look at visible frames;
1618 a frame, just look at windows on that frame.
1619 If MINI is non-zero, perform the operation on minibuffer windows too.
1625 GET_BUFFER_WINDOW
, /* Arg is buffer */
1626 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1627 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1628 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1630 UNSHOW_BUFFER
, /* Arg is buffer */
1635 window_loop (type
, obj
, mini
, frames
)
1636 enum window_loop type
;
1637 Lisp_Object obj
, frames
;
1640 Lisp_Object window
, windows
, best_window
, frame_arg
;
1642 struct gcpro gcpro1
;
1644 /* If we're only looping through windows on a particular frame,
1645 frame points to that frame. If we're looping through windows
1646 on all frames, frame is 0. */
1647 if (FRAMEP (frames
))
1648 f
= XFRAME (frames
);
1649 else if (NILP (frames
))
1650 f
= SELECTED_FRAME ();
1655 frame_arg
= Qlambda
;
1656 else if (XFASTINT (frames
) == 0)
1658 else if (EQ (frames
, Qvisible
))
1663 /* frame_arg is Qlambda to stick to one frame,
1664 Qvisible to consider all visible frames,
1667 /* Pick a window to start with. */
1671 window
= FRAME_SELECTED_WINDOW (f
);
1673 window
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
1675 /* Figure out the last window we're going to mess with. Since
1676 Fnext_window, given the same options, is guaranteed to go in a
1677 ring, we can just use Fprevious_window to find the last one.
1679 We can't just wait until we hit the first window again, because
1680 it might be deleted. */
1682 windows
= Fwindow_list (window
, mini
? Qt
: Qnil
, frame_arg
);
1686 for (; CONSP (windows
); windows
= CDR (windows
))
1690 window
= XCAR (windows
);
1691 w
= XWINDOW (window
);
1693 /* Note that we do not pay attention here to whether the frame
1694 is visible, since Fwindow_list skips non-visible frames if
1695 that is desired, under the control of frame_arg. */
1696 if (!MINI_WINDOW_P (w
)
1697 /* For UNSHOW_BUFFER, we must always consider all windows. */
1698 || type
== UNSHOW_BUFFER
1699 || (mini
&& minibuf_level
> 0))
1702 case GET_BUFFER_WINDOW
:
1703 if (EQ (w
->buffer
, obj
)
1704 /* Don't find any minibuffer window
1705 except the one that is currently in use. */
1706 && (MINI_WINDOW_P (w
)
1707 ? EQ (window
, minibuf_window
)
1715 case GET_LRU_WINDOW
:
1716 /* t as arg means consider only full-width windows */
1717 if (!NILP (obj
) && !WINDOW_FULL_WIDTH_P (w
))
1719 /* Ignore dedicated windows and minibuffers. */
1720 if (MINI_WINDOW_P (w
) || !NILP (w
->dedicated
))
1722 if (NILP (best_window
)
1723 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1724 > XFASTINT (w
->use_time
)))
1725 best_window
= window
;
1728 case DELETE_OTHER_WINDOWS
:
1729 if (!EQ (window
, obj
))
1730 Fdelete_window (window
);
1733 case DELETE_BUFFER_WINDOWS
:
1734 if (EQ (w
->buffer
, obj
))
1736 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1738 /* If this window is dedicated, and in a frame of its own,
1740 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
1741 && !NILP (w
->dedicated
)
1742 && other_visible_frames (f
))
1744 /* Skip the other windows on this frame.
1745 There might be one, the minibuffer! */
1746 while (CONSP (XCDR (windows
))
1747 && EQ (XWINDOW (XCAR (windows
))->frame
,
1748 XWINDOW (XCAR (XCDR (windows
)))->frame
))
1749 windows
= XCDR (windows
);
1751 /* Now we can safely delete the frame. */
1752 Fdelete_frame (w
->frame
, Qnil
);
1754 else if (NILP (w
->parent
))
1756 /* If we're deleting the buffer displayed in the
1757 only window on the frame, find a new buffer to
1760 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
1762 buffer
= Fget_buffer_create (build_string ("*scratch*"));
1763 Fset_window_buffer (window
, buffer
);
1764 if (EQ (window
, selected_window
))
1765 Fset_buffer (w
->buffer
);
1768 Fdelete_window (window
);
1772 case GET_LARGEST_WINDOW
:
1774 /* Ignore dedicated windows and minibuffers. */
1775 if (MINI_WINDOW_P (w
) || !NILP (w
->dedicated
))
1778 if (NILP (best_window
))
1779 best_window
= window
;
1782 struct window
*b
= XWINDOW (best_window
);
1783 if (XFASTINT (w
->height
) * XFASTINT (w
->width
)
1784 > XFASTINT (b
->height
) * XFASTINT (b
->width
))
1785 best_window
= window
;
1791 if (EQ (w
->buffer
, obj
))
1794 struct frame
*f
= XFRAME (w
->frame
);
1796 /* Find another buffer to show in this window. */
1797 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
1799 buffer
= Fget_buffer_create (build_string ("*scratch*"));
1801 /* If this window is dedicated, and in a frame of its own,
1803 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
1804 && !NILP (w
->dedicated
)
1805 && other_visible_frames (f
))
1807 /* Skip the other windows on this frame.
1808 There might be one, the minibuffer! */
1809 while (CONSP (XCDR (windows
))
1810 && EQ (XWINDOW (XCAR (windows
))->frame
,
1811 XWINDOW (XCAR (XCDR (windows
)))->frame
))
1812 windows
= XCDR (windows
);
1814 /* Now we can safely delete the frame. */
1815 Fdelete_frame (w
->frame
, Qnil
);
1819 /* Otherwise show a different buffer in the window. */
1820 w
->dedicated
= Qnil
;
1821 Fset_window_buffer (window
, buffer
);
1822 if (EQ (window
, selected_window
))
1823 Fset_buffer (w
->buffer
);
1828 /* Check for a window that has a killed buffer. */
1829 case CHECK_ALL_WINDOWS
:
1830 if (! NILP (w
->buffer
)
1831 && NILP (XBUFFER (w
->buffer
)->name
))
1835 case WINDOW_LOOP_UNUSED
:
1844 /* Used for debugging. Abort if any window has a dead buffer. */
1847 check_all_windows ()
1849 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
1852 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1853 "Return the window least recently selected or used for display.\n\
1854 If optional argument FRAME is `visible', search all visible frames.\n\
1855 If FRAME is 0, search all visible and iconified frames.\n\
1856 If FRAME is t, search all frames.\n\
1857 If FRAME is nil, search only the selected frame.\n\
1858 If FRAME is a frame, search only that frame.")
1862 register Lisp_Object w
;
1863 /* First try for a window that is full-width */
1864 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frame
);
1865 if (!NILP (w
) && !EQ (w
, selected_window
))
1867 /* If none of them, try the rest */
1868 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frame
);
1871 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1872 "Return the largest window in area.\n\
1873 If optional argument FRAME is `visible', search all visible frames.\n\
1874 If FRAME is 0, search all visible and iconified frames.\n\
1875 If FRAME is t, search all frames.\n\
1876 If FRAME is nil, search only the selected frame.\n\
1877 If FRAME is a frame, search only that frame.")
1881 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
1885 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
1886 "Return a window currently displaying BUFFER, or nil if none.\n\
1887 If optional argument FRAME is `visible', search all visible frames.\n\
1888 If optional argument FRAME is 0, search all visible and iconified frames.\n\
1889 If FRAME is t, search all frames.\n\
1890 If FRAME is nil, search only the selected frame.\n\
1891 If FRAME is a frame, search only that frame.")
1893 Lisp_Object buffer
, frame
;
1895 buffer
= Fget_buffer (buffer
);
1896 if (BUFFERP (buffer
))
1897 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
1902 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
1904 "Make WINDOW (or the selected window) fill its frame.\n\
1905 Only the frame WINDOW is on is affected.\n\
1906 This function tries to reduce display jumps\n\
1907 by keeping the text previously visible in WINDOW\n\
1908 in the same place on the frame. Doing this depends on\n\
1909 the value of (window-start WINDOW), so if calling this function\n\
1910 in a program gives strange scrolling, make sure the window-start\n\
1911 value is reasonable when this function is called.")
1920 window
= selected_window
;
1922 CHECK_LIVE_WINDOW (window
, 0);
1924 w
= XWINDOW (window
);
1926 startpos
= marker_position (w
->start
);
1927 top
= XFASTINT (w
->top
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
1929 if (MINI_WINDOW_P (w
) && top
> 0)
1930 error ("Can't expand minibuffer to full frame");
1932 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
1934 /* Try to minimize scrolling, by setting the window start to the point
1935 will cause the text at the old window start to be at the same place
1936 on the frame. But don't try to do this if the window start is
1937 outside the visible portion (as might happen when the display is
1938 not current, due to typeahead). */
1939 if (startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
1940 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
1942 struct position pos
;
1943 struct buffer
*obuf
= current_buffer
;
1945 Fset_buffer (w
->buffer
);
1946 /* This computation used to temporarily move point, but that can
1947 have unwanted side effects due to text properties. */
1948 pos
= *vmotion (startpos
, -top
, w
);
1950 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
1951 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
1952 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
1954 /* We need to do this, so that the window-scroll-functions
1956 w
->optional_new_start
= Qt
;
1958 set_buffer_internal (obuf
);
1964 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
1965 1, 2, "bDelete windows on (buffer): ",
1966 "Delete all windows showing BUFFER.\n\
1967 Optional second argument FRAME controls which frames are affected.\n\
1968 If optional argument FRAME is `visible', search all visible frames.\n\
1969 If FRAME is 0, search all visible and iconified frames.\n\
1970 If FRAME is nil, search all frames.\n\
1971 If FRAME is t, search only the selected frame.\n\
1972 If FRAME is a frame, search only that frame.")
1974 Lisp_Object buffer
, frame
;
1976 /* FRAME uses t and nil to mean the opposite of what window_loop
1980 else if (EQ (frame
, Qt
))
1985 buffer
= Fget_buffer (buffer
);
1986 CHECK_BUFFER (buffer
, 0);
1987 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
1993 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
1994 Sreplace_buffer_in_windows
,
1995 1, 1, "bReplace buffer in windows: ",
1996 "Replace BUFFER with some other buffer in all windows showing it.")
2002 buffer
= Fget_buffer (buffer
);
2003 CHECK_BUFFER (buffer
, 0);
2004 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
2009 /* Replace BUFFER with some other buffer in all windows
2010 of all frames, even those on other keyboards. */
2013 replace_buffer_in_all_windows (buffer
)
2017 Lisp_Object tail
, frame
;
2019 /* A single call to window_loop won't do the job
2020 because it only considers frames on the current keyboard.
2021 So loop manually over frames, and handle each one. */
2022 FOR_EACH_FRAME (tail
, frame
)
2023 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
2025 window_loop (UNSHOW_BUFFER
, buffer
, 1, Qt
);
2029 /* Set the height of WINDOW and all its inferiors. */
2031 /* The smallest acceptable dimensions for a window. Anything smaller
2032 might crash Emacs. */
2034 #define MIN_SAFE_WINDOW_WIDTH (2)
2035 #define MIN_SAFE_WINDOW_HEIGHT (2)
2037 /* Make sure that window_min_height and window_min_width are
2038 not too small; if they are, set them to safe minima. */
2041 check_min_window_sizes ()
2043 /* Smaller values might permit a crash. */
2044 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
2045 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
2046 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
2047 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
2050 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
2051 minimum allowable size. */
2054 check_frame_size (frame
, rows
, cols
)
2058 /* For height, we have to see:
2059 whether the frame has a minibuffer,
2060 whether it wants a mode line, and
2061 whether it has a menu bar. */
2063 (FRAME_MINIBUF_ONLY_P (frame
) ? MIN_SAFE_WINDOW_HEIGHT
- 1
2064 : (! FRAME_HAS_MINIBUF_P (frame
)) ? MIN_SAFE_WINDOW_HEIGHT
2065 : 2 * MIN_SAFE_WINDOW_HEIGHT
- 1);
2067 if (FRAME_TOP_MARGIN (frame
) > 0)
2068 min_height
+= FRAME_TOP_MARGIN (frame
);
2070 if (*rows
< min_height
)
2072 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
2073 *cols
= MIN_SAFE_WINDOW_WIDTH
;
2077 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
2078 check if W's width can be changed, otherwise check W's height.
2079 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
2080 siblings, too. If none of the siblings is resizable, WINDOW isn't
2084 window_fixed_size_p (w
, width_p
, check_siblings_p
)
2086 int width_p
, check_siblings_p
;
2091 if (!NILP (w
->hchild
))
2093 c
= XWINDOW (w
->hchild
);
2097 /* A horiz. combination is fixed-width if all of if its
2099 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2100 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2101 fixed_p
= c
== NULL
;
2105 /* A horiz. combination is fixed-height if one of if its
2107 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2108 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2109 fixed_p
= c
!= NULL
;
2112 else if (!NILP (w
->vchild
))
2114 c
= XWINDOW (w
->vchild
);
2118 /* A vert. combination is fixed-width if one of if its
2120 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2121 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2122 fixed_p
= c
!= NULL
;
2126 /* A vert. combination is fixed-height if all of if its
2128 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2129 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2130 fixed_p
= c
== NULL
;
2133 else if (BUFFERP (w
->buffer
))
2135 if (w
->height_fixed_p
&& !width_p
)
2139 struct buffer
*old
= current_buffer
;
2142 current_buffer
= XBUFFER (w
->buffer
);
2143 val
= find_symbol_value (Qwindow_size_fixed
);
2144 current_buffer
= old
;
2147 if (!EQ (val
, Qunbound
))
2149 fixed_p
= !NILP (val
);
2152 && ((EQ (val
, Qheight
) && width_p
)
2153 || (EQ (val
, Qwidth
) && !width_p
)))
2158 /* Can't tell if this one is resizable without looking at
2159 siblings. If all siblings are fixed-size this one is too. */
2160 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
2164 for (child
= w
->prev
; !NILP (child
); child
= XWINDOW (child
)->prev
)
2165 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2169 for (child
= w
->next
; !NILP (child
); child
= XWINDOW (child
)->next
)
2170 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2184 /* Return the minimum size of window W, not taking fixed-width windows
2185 into account. WIDTH_P non-zero means return the minimum width,
2186 otherwise return the minimum height. If W is a combination window,
2187 compute the minimum size from the minimum sizes of W's children. */
2190 window_min_size_1 (w
, width_p
)
2197 if (!NILP (w
->hchild
))
2199 c
= XWINDOW (w
->hchild
);
2204 /* The min width of a horizontal combination is
2205 the sum of the min widths of its children. */
2208 size
+= window_min_size_1 (c
, width_p
);
2209 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2214 /* The min height a horizontal combination equals
2215 the maximum of all min height of its children. */
2218 int min_size
= window_min_size_1 (c
, width_p
);
2219 size
= max (min_size
, size
);
2220 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2224 else if (!NILP (w
->vchild
))
2226 c
= XWINDOW (w
->vchild
);
2231 /* The min width of a vertical combination is
2232 the maximum of the min widths of its children. */
2235 int min_size
= window_min_size_1 (c
, width_p
);
2236 size
= max (min_size
, size
);
2237 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2242 /* The min height of a vertical combination equals
2243 the sum of the min height of its children. */
2246 size
+= window_min_size_1 (c
, width_p
);
2247 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2254 size
= window_min_width
;
2257 if (MINI_WINDOW_P (w
)
2258 || (!WINDOW_WANTS_MODELINE_P (w
)
2259 && !WINDOW_WANTS_HEADER_LINE_P (w
)))
2262 size
= window_min_height
;
2270 /* Return the minimum size of window W, taking fixed-size windows into
2271 account. WIDTH_P non-zero means return the minimum width,
2272 otherwise return the minimum height. IGNORE_FIXED_P non-zero means
2273 ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size
2274 unless FIXED is null. */
2277 window_min_size (w
, width_p
, ignore_fixed_p
, fixed
)
2279 int width_p
, ignore_fixed_p
, *fixed
;
2286 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
2292 size
= width_p
? XFASTINT (w
->width
) : XFASTINT (w
->height
);
2294 size
= window_min_size_1 (w
, width_p
);
2300 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
2301 WINDOW's width. Resize WINDOW's children, if any, so that they
2302 keep their proportionate size relative to WINDOW. Propagate
2303 WINDOW's top or left edge position to children. Delete windows
2304 that become too small unless NODELETE_P is non-zero. */
2307 size_window (window
, size
, width_p
, nodelete_p
)
2309 int size
, width_p
, nodelete_p
;
2311 struct window
*w
= XWINDOW (window
);
2313 Lisp_Object child
, *forward
, *sideward
;
2314 int old_size
, min_size
;
2316 check_min_window_sizes ();
2318 /* If the window has been "too small" at one point,
2319 don't delete it for being "too small" in the future.
2320 Preserve it as long as that is at all possible. */
2323 old_size
= XFASTINT (w
->width
);
2324 min_size
= window_min_width
;
2328 old_size
= XFASTINT (w
->height
);
2329 min_size
= window_min_height
;
2332 if (old_size
< window_min_width
)
2333 w
->too_small_ok
= Qt
;
2335 /* Maybe delete WINDOW if it's too small. */
2336 if (!nodelete_p
&& !NILP (w
->parent
))
2340 if (!MINI_WINDOW_P (w
) && !NILP (w
->too_small_ok
))
2341 min_size
= width_p
? MIN_SAFE_WINDOW_WIDTH
: MIN_SAFE_WINDOW_HEIGHT
;
2343 min_size
= width_p
? window_min_width
: window_min_height
;
2345 if (size
< min_size
)
2347 delete_window (window
);
2352 /* Set redisplay hints. */
2353 XSETFASTINT (w
->last_modified
, 0);
2354 XSETFASTINT (w
->last_overlay_modified
, 0);
2355 windows_or_buffers_changed
++;
2356 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
2360 sideward
= &w
->vchild
;
2361 forward
= &w
->hchild
;
2362 XSETFASTINT (w
->width
, size
);
2366 sideward
= &w
->hchild
;
2367 forward
= &w
->vchild
;
2368 XSETFASTINT (w
->height
, size
);
2371 if (!NILP (*sideward
))
2373 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
2375 c
= XWINDOW (child
);
2380 size_window (child
, size
, width_p
, nodelete_p
);
2383 else if (!NILP (*forward
))
2385 int fixed_size
, each
, extra
, n
;
2386 int resize_fixed_p
, nfixed
;
2387 int last_pos
, first_pos
, nchildren
;
2389 /* Determine the fixed-size portion of the this window, and the
2390 number of child windows. */
2391 fixed_size
= nchildren
= nfixed
= 0;
2392 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
2394 c
= XWINDOW (child
);
2395 if (window_fixed_size_p (c
, width_p
, 0))
2397 fixed_size
+= (width_p
2398 ? XFASTINT (c
->width
) : XFASTINT (c
->height
));
2403 /* If the new size is smaller than fixed_size, or if there
2404 aren't any resizable windows, allow resizing fixed-size
2406 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
2408 /* Compute how many lines/columns to add to each child. The
2409 value of extra takes care of rounding errors. */
2410 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
2411 each
= (size
- old_size
) / n
;
2412 extra
= (size
- old_size
) - n
* each
;
2414 /* Compute new children heights and edge positions. */
2415 first_pos
= width_p
? XFASTINT (w
->left
) : XFASTINT (w
->top
);
2416 last_pos
= first_pos
;
2417 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2419 int new_size
, old_size
;
2421 c
= XWINDOW (child
);
2422 old_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2423 new_size
= old_size
;
2425 /* The top or left edge position of this child equals the
2426 bottom or right edge of its predecessor. */
2428 c
->left
= make_number (last_pos
);
2430 c
->top
= make_number (last_pos
);
2432 /* If this child can be resized, do it. */
2433 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
2435 new_size
= old_size
+ each
+ extra
;
2439 /* Set new height. Note that size_window also propagates
2440 edge positions to children, so it's not a no-op if we
2441 didn't change the child's size. */
2442 size_window (child
, new_size
, width_p
, 1);
2444 /* Remember the bottom/right edge position of this child; it
2445 will be used to set the top/left edge of the next child. */
2446 last_pos
+= new_size
;
2449 /* We should have covered the parent exactly with child windows. */
2450 xassert (size
== last_pos
- first_pos
);
2452 /* Now delete any children that became too small. */
2454 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2457 c
= XWINDOW (child
);
2458 child_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2459 size_window (child
, child_size
, width_p
, 0);
2464 /* Set WINDOW's height to HEIGHT, and recursively change the height of
2465 WINDOW's children. NODELETE non-zero means don't delete windows
2466 that become too small in the process. (The caller should check
2467 later and do so if appropriate.) */
2470 set_window_height (window
, height
, nodelete
)
2475 size_window (window
, height
, 0, nodelete
);
2479 /* Set WINDOW's width to WIDTH, and recursively change the width of
2480 WINDOW's children. NODELETE non-zero means don't delete windows
2481 that become too small in the process. (The caller should check
2482 later and do so if appropriate.) */
2485 set_window_width (window
, width
, nodelete
)
2490 size_window (window
, width
, 1, nodelete
);
2494 int window_select_count
;
2497 Fset_window_buffer_unwind (obuf
)
2505 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
2506 means it's allowed to run hooks. See make_frame for a case where
2507 it's not allowed. */
2510 set_window_buffer (window
, buffer
, run_hooks_p
)
2511 Lisp_Object window
, buffer
;
2514 struct window
*w
= XWINDOW (window
);
2515 struct buffer
*b
= XBUFFER (buffer
);
2516 int count
= specpdl_ptr
- specpdl
;
2520 if (EQ (window
, selected_window
))
2521 b
->last_selected_window
= window
;
2523 /* Update time stamps of buffer display. */
2524 if (INTEGERP (b
->display_count
))
2525 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
2526 b
->display_time
= Fcurrent_time ();
2528 XSETFASTINT (w
->window_end_pos
, 0);
2529 XSETFASTINT (w
->window_end_vpos
, 0);
2530 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
2531 w
->window_end_valid
= Qnil
;
2532 XSETFASTINT (w
->hscroll
, 0);
2533 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
2534 set_marker_restricted (w
->start
,
2535 make_number (b
->last_window_start
),
2537 w
->start_at_line_beg
= Qnil
;
2538 w
->force_start
= Qnil
;
2539 XSETFASTINT (w
->last_modified
, 0);
2540 XSETFASTINT (w
->last_overlay_modified
, 0);
2541 windows_or_buffers_changed
++;
2543 /* We must select BUFFER for running the window-scroll-functions.
2544 If WINDOW is selected, switch permanently.
2545 Otherwise, switch but go back to the ambient buffer afterward. */
2546 if (EQ (window
, selected_window
))
2547 Fset_buffer (buffer
);
2548 /* We can't check ! NILP (Vwindow_scroll_functions) here
2549 because that might itself be a local variable. */
2550 else if (window_initialized
)
2552 record_unwind_protect (Fset_window_buffer_unwind
, Fcurrent_buffer ());
2553 Fset_buffer (buffer
);
2556 /* Set left and right marginal area width from buffer. */
2557 Fset_window_margins (window
, b
->left_margin_width
, b
->right_margin_width
);
2561 if (! NILP (Vwindow_scroll_functions
))
2562 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2563 Fmarker_position (w
->start
));
2565 if (! NILP (Vwindow_configuration_change_hook
)
2566 && ! NILP (Vrun_hooks
))
2567 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
2570 unbind_to (count
, Qnil
);
2574 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 2, 0,
2575 "Make WINDOW display BUFFER as its contents.\n\
2576 BUFFER can be a buffer or buffer name.")
2578 register Lisp_Object window
, buffer
;
2580 register Lisp_Object tem
;
2581 register struct window
*w
= decode_window (window
);
2583 XSETWINDOW (window
, w
);
2584 buffer
= Fget_buffer (buffer
);
2585 CHECK_BUFFER (buffer
, 1);
2587 if (NILP (XBUFFER (buffer
)->name
))
2588 error ("Attempt to display deleted buffer");
2592 error ("Window is deleted");
2593 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
2594 is first being set up. */
2596 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
2597 error ("Window is dedicated to `%s'",
2598 XSTRING (XBUFFER (tem
)->name
)->data
);
2603 set_window_buffer (window
, buffer
, 1);
2607 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 1, 0,
2608 "Select WINDOW. Most editing will apply to WINDOW's buffer.\n\
2609 If WINDOW is not already selected, also make WINDOW's buffer current.\n\
2610 Note that the main editor command loop\n\
2611 selects the buffer of the selected window before each command.")
2613 register Lisp_Object window
;
2615 return select_window_1 (window
, 1);
2618 /* Note that selected_window can be nil
2619 when this is called from Fset_window_configuration. */
2622 select_window_1 (window
, recordflag
)
2623 register Lisp_Object window
;
2626 register struct window
*w
;
2627 register struct window
*ow
;
2630 CHECK_LIVE_WINDOW (window
, 0);
2632 w
= XWINDOW (window
);
2634 if (NILP (w
->buffer
))
2635 error ("Trying to select deleted window or non-leaf window");
2637 XSETFASTINT (w
->use_time
, ++window_select_count
);
2638 if (EQ (window
, selected_window
))
2641 if (!NILP (selected_window
))
2643 ow
= XWINDOW (selected_window
);
2644 if (! NILP (ow
->buffer
))
2645 set_marker_both (ow
->pointm
, ow
->buffer
,
2646 BUF_PT (XBUFFER (ow
->buffer
)),
2647 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
2650 selected_window
= window
;
2651 sf
= SELECTED_FRAME ();
2652 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
2654 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
2655 /* Use this rather than Fhandle_switch_frame
2656 so that FRAME_FOCUS_FRAME is moved appropriately as we
2657 move around in the state where a minibuffer in a separate
2659 Fselect_frame (WINDOW_FRAME (w
), Qnil
);
2662 sf
->selected_window
= window
;
2665 record_buffer (w
->buffer
);
2666 Fset_buffer (w
->buffer
);
2668 XBUFFER (w
->buffer
)->last_selected_window
= window
;
2670 /* Go to the point recorded in the window.
2671 This is important when the buffer is in more
2672 than one window. It also matters when
2673 redisplay_window has altered point after scrolling,
2674 because it makes the change only in the window. */
2676 register int new_point
= marker_position (w
->pointm
);
2677 if (new_point
< BEGV
)
2679 else if (new_point
> ZV
)
2685 windows_or_buffers_changed
++;
2689 /* Deiconify the frame containing the window WINDOW,
2690 unless it is the selected frame;
2693 The reason for the exception for the selected frame
2694 is that it seems better not to change the selected frames visibility
2695 merely because of displaying a different buffer in it.
2696 The deiconification is useful when a buffer gets shown in
2697 another frame that you were not using lately. */
2700 display_buffer_1 (window
)
2703 Lisp_Object frame
= XWINDOW (window
)->frame
;
2704 FRAME_PTR f
= XFRAME (frame
);
2706 FRAME_SAMPLE_VISIBILITY (f
);
2708 if (!EQ (frame
, selected_frame
))
2710 if (FRAME_ICONIFIED_P (f
))
2711 Fmake_frame_visible (frame
);
2712 else if (FRAME_VISIBLE_P (f
))
2713 Fraise_frame (frame
);
2719 DEFUN ("special-display-p", Fspecial_display_p
, Sspecial_display_p
, 1, 1, 0,
2720 "Returns non-nil if a buffer named BUFFER-NAME would be created specially.\n\
2721 The value is actually t if the frame should be called with default frame\n\
2722 parameters, and a list of frame parameters if they were specified.\n\
2723 See `special-display-buffer-names', and `special-display-regexps'.")
2725 Lisp_Object buffer_name
;
2729 CHECK_STRING (buffer_name
, 1);
2731 tem
= Fmember (buffer_name
, Vspecial_display_buffer_names
);
2735 tem
= Fassoc (buffer_name
, Vspecial_display_buffer_names
);
2739 for (tem
= Vspecial_display_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2741 Lisp_Object car
= XCAR (tem
);
2743 && fast_string_match (car
, buffer_name
) >= 0)
2745 else if (CONSP (car
)
2746 && STRINGP (XCAR (car
))
2747 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2753 DEFUN ("same-window-p", Fsame_window_p
, Ssame_window_p
, 1, 1, 0,
2754 "Returns non-nil if a new buffer named BUFFER-NAME would use the same window.\n\
2755 See `same-window-buffer-names' and `same-window-regexps'.")
2757 Lisp_Object buffer_name
;
2761 CHECK_STRING (buffer_name
, 1);
2763 tem
= Fmember (buffer_name
, Vsame_window_buffer_names
);
2767 tem
= Fassoc (buffer_name
, Vsame_window_buffer_names
);
2771 for (tem
= Vsame_window_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2773 Lisp_Object car
= XCAR (tem
);
2775 && fast_string_match (car
, buffer_name
) >= 0)
2777 else if (CONSP (car
)
2778 && STRINGP (XCAR (car
))
2779 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2785 /* Use B so the default is (other-buffer). */
2786 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 3,
2787 "BDisplay buffer: \nP",
2788 "Make BUFFER appear in some window but don't select it.\n\
2789 BUFFER can be a buffer or a buffer name.\n\
2790 If BUFFER is shown already in some window, just use that one,\n\
2791 unless the window is the selected window and the optional second\n\
2792 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).\n\
2793 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.\n\
2794 Returns the window displaying BUFFER.\n\
2795 If `display-reuse-frames' is non-nil, and another frame is currently\n\
2796 displaying BUFFER, then simply raise that frame.\n\
2798 The variables `special-display-buffer-names', `special-display-regexps',\n\
2799 `same-window-buffer-names', and `same-window-regexps' customize how certain\n\
2800 buffer names are handled.\n\
2802 If optional argument FRAME is `visible', search all visible frames.\n\
2803 If FRAME is 0, search all visible and iconified frames.\n\
2804 If FRAME is t, search all frames.\n\
2805 If FRAME is a frame, search only that frame.\n\
2806 If FRAME is nil, search only the selected frame\n\
2807 (actually the last nonminibuffer frame),\n\
2808 unless `pop-up-frames' or `display-reuse-frames' is non-nil,\n\
2809 which means search visible and iconified frames.")
2810 (buffer
, not_this_window
, frame
)
2811 register Lisp_Object buffer
, not_this_window
, frame
;
2813 register Lisp_Object window
, tem
, swp
;
2817 buffer
= Fget_buffer (buffer
);
2818 CHECK_BUFFER (buffer
, 0);
2820 if (!NILP (Vdisplay_buffer_function
))
2821 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
2823 if (NILP (not_this_window
)
2824 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
2825 return display_buffer_1 (selected_window
);
2827 /* See if the user has specified this buffer should appear
2828 in the selected window. */
2829 if (NILP (not_this_window
))
2831 swp
= Fsame_window_p (XBUFFER (buffer
)->name
);
2832 if (!NILP (swp
) && !no_switch_window (selected_window
))
2834 Fswitch_to_buffer (buffer
, Qnil
);
2835 return display_buffer_1 (selected_window
);
2839 /* If the user wants pop-up-frames or display-reuse-frames, then
2840 look for a window showing BUFFER on any visible or iconified frame.
2841 Otherwise search only the current frame. */
2844 else if (pop_up_frames
2845 || display_buffer_reuse_frames
2846 || last_nonminibuf_frame
== 0)
2847 XSETFASTINT (tem
, 0);
2849 XSETFRAME (tem
, last_nonminibuf_frame
);
2851 window
= Fget_buffer_window (buffer
, tem
);
2853 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
2854 return display_buffer_1 (window
);
2856 /* Certain buffer names get special handling. */
2857 if (!NILP (Vspecial_display_function
) && NILP (swp
))
2859 tem
= Fspecial_display_p (XBUFFER (buffer
)->name
);
2861 return call1 (Vspecial_display_function
, buffer
);
2863 return call2 (Vspecial_display_function
, buffer
, tem
);
2866 /* If there are no frames open that have more than a minibuffer,
2867 we need to create a new frame. */
2868 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
2870 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2871 Fset_window_buffer (window
, buffer
);
2872 return display_buffer_1 (window
);
2875 f
= SELECTED_FRAME ();
2877 || FRAME_MINIBUF_ONLY_P (f
)
2878 /* If the current frame is a special display frame,
2879 don't try to reuse its windows. */
2880 || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f
))->dedicated
))
2885 if (FRAME_MINIBUF_ONLY_P (f
))
2886 XSETFRAME (frames
, last_nonminibuf_frame
);
2887 /* Don't try to create a window if would get an error */
2888 if (split_height_threshold
< window_min_height
<< 1)
2889 split_height_threshold
= window_min_height
<< 1;
2891 /* Note that both Fget_largest_window and Fget_lru_window
2892 ignore minibuffers and dedicated windows.
2893 This means they can return nil. */
2895 /* If the frame we would try to split cannot be split,
2896 try other frames. */
2897 if (FRAME_NO_SPLIT_P (NILP (frames
) ? f
: last_nonminibuf_frame
))
2899 /* Try visible frames first. */
2900 window
= Fget_largest_window (Qvisible
);
2901 /* If that didn't work, try iconified frames. */
2903 window
= Fget_largest_window (make_number (0));
2905 window
= Fget_largest_window (Qt
);
2908 window
= Fget_largest_window (frames
);
2910 /* If we got a tall enough full-width window that can be split,
2913 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2914 && window_height (window
) >= split_height_threshold
2915 && WINDOW_FULL_WIDTH_P (XWINDOW (window
)))
2916 window
= Fsplit_window (window
, Qnil
, Qnil
);
2919 Lisp_Object upper
, lower
, other
;
2921 window
= Fget_lru_window (frames
);
2922 /* If the LRU window is selected, and big enough,
2923 and can be split, split it. */
2925 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2926 && (EQ (window
, selected_window
)
2927 || EQ (XWINDOW (window
)->parent
, Qnil
))
2928 && window_height (window
) >= window_min_height
<< 1)
2929 window
= Fsplit_window (window
, Qnil
, Qnil
);
2930 /* If Fget_lru_window returned nil, try other approaches. */
2932 /* Try visible frames first. */
2934 window
= Fget_buffer_window (buffer
, Qvisible
);
2936 window
= Fget_largest_window (Qvisible
);
2937 /* If that didn't work, try iconified frames. */
2939 window
= Fget_buffer_window (buffer
, make_number (0));
2941 window
= Fget_largest_window (make_number (0));
2942 /* Try invisible frames. */
2944 window
= Fget_buffer_window (buffer
, Qt
);
2946 window
= Fget_largest_window (Qt
);
2947 /* As a last resort, make a new frame. */
2949 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2950 /* If window appears above or below another,
2951 even out their heights. */
2952 other
= upper
= lower
= Qnil
;
2953 if (!NILP (XWINDOW (window
)->prev
))
2954 other
= upper
= XWINDOW (window
)->prev
, lower
= window
;
2955 if (!NILP (XWINDOW (window
)->next
))
2956 other
= lower
= XWINDOW (window
)->next
, upper
= window
;
2958 /* Check that OTHER and WINDOW are vertically arrayed. */
2959 && !EQ (XWINDOW (other
)->top
, XWINDOW (window
)->top
)
2960 && (XFASTINT (XWINDOW (other
)->height
)
2961 > XFASTINT (XWINDOW (window
)->height
)))
2963 int total
= (XFASTINT (XWINDOW (other
)->height
)
2964 + XFASTINT (XWINDOW (window
)->height
));
2965 enlarge_window (upper
,
2966 total
/ 2 - XFASTINT (XWINDOW (upper
)->height
),
2972 window
= Fget_lru_window (Qnil
);
2974 Fset_window_buffer (window
, buffer
);
2975 return display_buffer_1 (window
);
2979 temp_output_buffer_show (buf
)
2980 register Lisp_Object buf
;
2982 register struct buffer
*old
= current_buffer
;
2983 register Lisp_Object window
;
2984 register struct window
*w
;
2986 XBUFFER (buf
)->directory
= current_buffer
->directory
;
2989 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
2993 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
2994 set_buffer_internal (old
);
2996 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
2997 call1 (Vtemp_buffer_show_function
, buf
);
3000 window
= Fdisplay_buffer (buf
, Qnil
, Qnil
);
3002 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
3003 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
3004 Vminibuf_scroll_window
= window
;
3005 w
= XWINDOW (window
);
3006 XSETFASTINT (w
->hscroll
, 0);
3007 set_marker_restricted_both (w
->start
, buf
, 1, 1);
3008 set_marker_restricted_both (w
->pointm
, buf
, 1, 1);
3010 /* Run temp-buffer-show-hook, with the chosen window selected
3011 and it sbuffer current. */
3012 if (!NILP (Vrun_hooks
))
3015 tem
= Fboundp (Qtemp_buffer_show_hook
);
3018 tem
= Fsymbol_value (Qtemp_buffer_show_hook
);
3021 int count
= specpdl_ptr
- specpdl
;
3022 Lisp_Object prev_window
;
3023 prev_window
= selected_window
;
3025 /* Select the window that was chosen, for running the hook. */
3026 record_unwind_protect (Fselect_window
, prev_window
);
3027 select_window_1 (window
, 0);
3028 Fset_buffer (w
->buffer
);
3029 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
3030 select_window_1 (prev_window
, 0);
3031 unbind_to (count
, Qnil
);
3039 make_dummy_parent (window
)
3043 register struct window
*o
, *p
;
3044 register struct Lisp_Vector
*vec
;
3047 o
= XWINDOW (window
);
3048 vec
= allocate_vectorlike ((EMACS_INT
)VECSIZE (struct window
));
3049 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
3050 vec
->contents
[i
] = ((struct Lisp_Vector
*)o
)->contents
[i
];
3051 vec
->size
= VECSIZE (struct window
);
3052 p
= (struct window
*)vec
;
3053 XSETWINDOW (new, p
);
3055 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
3057 /* Put new into window structure in place of window */
3058 replace_window (window
, new);
3071 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
3072 "Split WINDOW, putting SIZE lines in the first of the pair.\n\
3073 WINDOW defaults to selected one and SIZE to half its size.\n\
3074 If optional third arg HORFLAG is non-nil, split side by side\n\
3075 and put SIZE columns in the first of the pair. In that case,\n\
3076 SIZE includes that window's scroll bar, or the divider column to its right.")
3077 (window
, size
, horflag
)
3078 Lisp_Object window
, size
, horflag
;
3080 register Lisp_Object
new;
3081 register struct window
*o
, *p
;
3083 register int size_int
;
3086 window
= selected_window
;
3088 CHECK_LIVE_WINDOW (window
, 0);
3090 o
= XWINDOW (window
);
3091 fo
= XFRAME (WINDOW_FRAME (o
));
3095 if (!NILP (horflag
))
3096 /* Calculate the size of the left-hand window, by dividing
3097 the usable space in columns by two.
3098 We round up, since the left-hand window may include
3099 a dividing line, while the right-hand may not. */
3100 size_int
= (XFASTINT (o
->width
) + 1) >> 1;
3102 size_int
= XFASTINT (o
->height
) >> 1;
3106 CHECK_NUMBER (size
, 1);
3107 size_int
= XINT (size
);
3110 if (MINI_WINDOW_P (o
))
3111 error ("Attempt to split minibuffer window");
3112 else if (window_fixed_size_p (o
, !NILP (horflag
), 0))
3113 error ("Attempt to split fixed-size window");
3115 check_min_window_sizes ();
3119 if (size_int
< window_min_height
)
3120 error ("Window height %d too small (after splitting)", size_int
);
3121 if (size_int
+ window_min_height
> XFASTINT (o
->height
))
3122 error ("Window height %d too small (after splitting)",
3123 XFASTINT (o
->height
) - size_int
);
3124 if (NILP (o
->parent
)
3125 || NILP (XWINDOW (o
->parent
)->vchild
))
3127 make_dummy_parent (window
);
3129 XWINDOW (new)->vchild
= window
;
3134 if (size_int
< window_min_width
)
3135 error ("Window width %d too small (after splitting)", size_int
);
3137 if (size_int
+ window_min_width
> XFASTINT (o
->width
))
3138 error ("Window width %d too small (after splitting)",
3139 XFASTINT (o
->width
) - size_int
);
3140 if (NILP (o
->parent
)
3141 || NILP (XWINDOW (o
->parent
)->hchild
))
3143 make_dummy_parent (window
);
3145 XWINDOW (new)->hchild
= window
;
3149 /* Now we know that window's parent is a vertical combination
3150 if we are dividing vertically, or a horizontal combination
3151 if we are making side-by-side windows */
3153 windows_or_buffers_changed
++;
3154 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
3155 new = make_window ();
3158 p
->frame
= o
->frame
;
3160 if (!NILP (p
->next
))
3161 XWINDOW (p
->next
)->prev
= new;
3164 p
->parent
= o
->parent
;
3166 p
->window_end_valid
= Qnil
;
3167 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
3169 /* Apportion the available frame space among the two new windows */
3171 if (!NILP (horflag
))
3173 p
->height
= o
->height
;
3175 XSETFASTINT (p
->width
, XFASTINT (o
->width
) - size_int
);
3176 XSETFASTINT (o
->width
, size_int
);
3177 XSETFASTINT (p
->left
, XFASTINT (o
->left
) + size_int
);
3182 p
->width
= o
->width
;
3183 XSETFASTINT (p
->height
, XFASTINT (o
->height
) - size_int
);
3184 XSETFASTINT (o
->height
, size_int
);
3185 XSETFASTINT (p
->top
, XFASTINT (o
->top
) + size_int
);
3188 /* Adjust glyph matrices. */
3190 Fset_window_buffer (new, o
->buffer
);
3194 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
3195 "Make current window ARG lines bigger.\n\
3196 From program, optional second arg non-nil means grow sideways ARG columns.")
3198 register Lisp_Object arg
, side
;
3200 CHECK_NUMBER (arg
, 0);
3201 enlarge_window (selected_window
, XINT (arg
), !NILP (side
));
3203 if (! NILP (Vwindow_configuration_change_hook
))
3204 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3209 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
3210 "Make current window ARG lines smaller.\n\
3211 From program, optional second arg non-nil means shrink sideways arg columns.")
3213 register Lisp_Object arg
, side
;
3215 CHECK_NUMBER (arg
, 0);
3216 enlarge_window (selected_window
, -XINT (arg
), !NILP (side
));
3218 if (! NILP (Vwindow_configuration_change_hook
))
3219 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3225 window_height (window
)
3228 register struct window
*p
= XWINDOW (window
);
3229 return XFASTINT (p
->height
);
3233 window_width (window
)
3236 register struct window
*p
= XWINDOW (window
);
3237 return XFASTINT (p
->width
);
3242 *(widthflag ? &(XWINDOW (w)->left) : &(XWINDOW (w)->top))
3244 #define CURSIZE(w) \
3245 *(widthflag ? &(XWINDOW (w)->width) : &(XWINDOW (w)->height))
3248 /* Enlarge selected_window by DELTA. WIDTHFLAG non-zero means
3249 increase its width. Siblings of the selected window are resized to
3250 fullfil the size request. If they become too small in the process,
3251 they will be deleted. */
3254 enlarge_window (window
, delta
, widthflag
)
3256 int delta
, widthflag
;
3258 Lisp_Object parent
, next
, prev
;
3262 int (*sizefun
) P_ ((Lisp_Object
))
3263 = widthflag
? window_width
: window_height
;
3264 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
3265 = (widthflag
? set_window_width
: set_window_height
);
3267 /* Check values of window_min_width and window_min_height for
3269 check_min_window_sizes ();
3271 /* Give up if this window cannot be resized. */
3272 if (window_fixed_size_p (XWINDOW (window
), widthflag
, 1))
3273 error ("Window is not resizable");
3275 /* Find the parent of the selected window. */
3278 p
= XWINDOW (window
);
3284 error ("No other window to side of this one");
3289 ? !NILP (XWINDOW (parent
)->hchild
)
3290 : !NILP (XWINDOW (parent
)->vchild
))
3296 sizep
= &CURSIZE (window
);
3299 register int maxdelta
;
3301 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - XINT (*sizep
)
3302 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3303 - window_min_size (XWINDOW (p
->next
),
3305 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
3306 - window_min_size (XWINDOW (p
->prev
),
3308 /* This is a frame with only one window, a minibuffer-only
3309 or a minibufferless frame. */
3312 if (delta
> maxdelta
)
3313 /* This case traps trying to make the minibuffer
3314 the full frame, or make the only window aside from the
3315 minibuffer the full frame. */
3319 if (XINT (*sizep
) + delta
< window_min_size (XWINDOW (window
), widthflag
, 0, 0))
3321 delete_window (window
);
3328 /* Find the total we can get from other siblings. */
3330 for (next
= p
->next
; ! NILP (next
); next
= XWINDOW (next
)->next
)
3331 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
3333 for (prev
= p
->prev
; ! NILP (prev
); prev
= XWINDOW (prev
)->prev
)
3334 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
3337 /* If we can get it all from them, do so. */
3338 if (delta
<= maximum
)
3340 Lisp_Object first_unaffected
;
3341 Lisp_Object first_affected
;
3346 first_affected
= window
;
3347 /* Look at one sibling at a time,
3348 moving away from this window in both directions alternately,
3349 and take as much as we can get without deleting that sibling. */
3350 while (delta
!= 0 && (!NILP (next
) || !NILP (prev
)))
3354 int this_one
= ((*sizefun
) (next
)
3355 - window_min_size (XWINDOW (next
),
3356 widthflag
, 0, &fixed_p
));
3359 if (this_one
> delta
)
3362 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
3363 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3368 next
= XWINDOW (next
)->next
;
3376 int this_one
= ((*sizefun
) (prev
)
3377 - window_min_size (XWINDOW (prev
),
3378 widthflag
, 0, &fixed_p
));
3381 if (this_one
> delta
)
3384 first_affected
= prev
;
3386 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
3387 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3392 prev
= XWINDOW (prev
)->prev
;
3396 xassert (delta
== 0);
3398 /* Now recalculate the edge positions of all the windows affected,
3399 based on the new sizes. */
3400 first_unaffected
= next
;
3401 prev
= first_affected
;
3402 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
3403 prev
= next
, next
= XWINDOW (next
)->next
)
3405 XSETINT (CURBEG (next
), XINT (CURBEG (prev
)) + (*sizefun
) (prev
));
3406 /* This does not change size of NEXT,
3407 but it propagates the new top edge to its children */
3408 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
3413 register int delta1
;
3414 register int opht
= (*sizefun
) (parent
);
3416 /* If trying to grow this window to or beyond size of the parent,
3417 make delta1 so big that, on shrinking back down,
3418 all the siblings end up with less than one line and are deleted. */
3419 if (opht
<= XINT (*sizep
) + delta
)
3420 delta1
= opht
* opht
* 2;
3423 /* Otherwise, make delta1 just right so that if we add
3424 delta1 lines to this window and to the parent, and then
3425 shrink the parent back to its original size, the new
3426 proportional size of this window will increase by delta.
3428 The function size_window will compute the new height h'
3429 of the window from delta1 as:
3432 x = delta1 - delta1/n * n for the 1st resizable child
3435 where n is the number of children that can be resized.
3436 We can ignore x by choosing a delta1 that is a multiple of
3437 n. We want the height of this window to come out as
3447 The number of children n rquals the number of resizable
3448 children of this window + 1 because we know window itself
3449 is resizable (otherwise we would have signalled an error. */
3451 struct window
*w
= XWINDOW (window
);
3455 for (s
= w
->next
; !NILP (s
); s
= XWINDOW (s
)->next
)
3456 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3458 for (s
= w
->prev
; !NILP (s
); s
= XWINDOW (s
)->prev
)
3459 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3465 /* Add delta1 lines or columns to this window, and to the parent,
3466 keeping things consistent while not affecting siblings. */
3467 XSETINT (CURSIZE (parent
), opht
+ delta1
);
3468 (*setsizefun
) (window
, XINT (*sizep
) + delta1
, 0);
3470 /* Squeeze out delta1 lines or columns from our parent,
3471 shriking this window and siblings proportionately.
3472 This brings parent back to correct size.
3473 Delta1 was calculated so this makes this window the desired size,
3474 taking it all out of the siblings. */
3475 (*setsizefun
) (parent
, opht
, 0);
3478 XSETFASTINT (p
->last_modified
, 0);
3479 XSETFASTINT (p
->last_overlay_modified
, 0);
3481 /* Adjust glyph matrices. */
3482 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
3490 /***********************************************************************
3491 Resizing Mini-Windows
3492 ***********************************************************************/
3494 static void shrink_window_lowest_first
P_ ((struct window
*, int));
3496 enum save_restore_action
3503 static int save_restore_orig_size
P_ ((struct window
*,
3504 enum save_restore_action
));
3506 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
3507 from lowest windows first. */
3510 shrink_window_lowest_first (w
, height
)
3518 xassert (!MINI_WINDOW_P (w
));
3520 /* Set redisplay hints. */
3521 XSETFASTINT (w
->last_modified
, 0);
3522 XSETFASTINT (w
->last_overlay_modified
, 0);
3523 windows_or_buffers_changed
++;
3524 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
3526 old_height
= XFASTINT (w
->height
);
3527 XSETFASTINT (w
->height
, height
);
3529 if (!NILP (w
->hchild
))
3531 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
3533 c
= XWINDOW (child
);
3535 shrink_window_lowest_first (c
, height
);
3538 else if (!NILP (w
->vchild
))
3540 Lisp_Object last_child
;
3541 int delta
= old_height
- height
;
3546 /* Find the last child. We are taking space from lowest windows
3547 first, so we iterate over children from the last child
3549 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
3552 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
3553 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
3557 c
= XWINDOW (child
);
3558 this_one
= XFASTINT (c
->height
) - MIN_SAFE_WINDOW_HEIGHT
;
3560 if (this_one
> delta
)
3563 shrink_window_lowest_first (c
, XFASTINT (c
->height
) - this_one
);
3567 /* Compute new positions. */
3568 last_top
= XINT (w
->top
);
3569 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
3571 c
= XWINDOW (child
);
3572 c
->top
= make_number (last_top
);
3573 shrink_window_lowest_first (c
, XFASTINT (c
->height
));
3574 last_top
+= XFASTINT (c
->height
);
3580 /* Save, restore, or check positions and sizes in the window tree
3581 rooted at W. ACTION says what to do.
3583 If ACTION is CHECK_ORIG_SIZES, check if orig_top and orig_height
3584 members are valid for all windows in the window tree. Value is
3585 non-zero if they are valid.
3587 If ACTION is SAVE_ORIG_SIZES, save members top and height in
3588 orig_top and orig_height for all windows in the tree.
3590 If ACTION is RESTORE_ORIG_SIZES, restore top and height from
3591 values stored in orig_top and orig_height for all windows. */
3594 save_restore_orig_size (w
, action
)
3596 enum save_restore_action action
;
3602 if (!NILP (w
->hchild
))
3604 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
3607 else if (!NILP (w
->vchild
))
3609 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
3615 case CHECK_ORIG_SIZES
:
3616 if (!INTEGERP (w
->orig_top
) || !INTEGERP (w
->orig_height
))
3620 case SAVE_ORIG_SIZES
:
3621 w
->orig_top
= w
->top
;
3622 w
->orig_height
= w
->height
;
3623 XSETFASTINT (w
->last_modified
, 0);
3624 XSETFASTINT (w
->last_overlay_modified
, 0);
3627 case RESTORE_ORIG_SIZES
:
3628 xassert (INTEGERP (w
->orig_top
) && INTEGERP (w
->orig_height
));
3629 w
->top
= w
->orig_top
;
3630 w
->height
= w
->orig_height
;
3631 w
->orig_height
= w
->orig_top
= Qnil
;
3632 XSETFASTINT (w
->last_modified
, 0);
3633 XSETFASTINT (w
->last_overlay_modified
, 0);
3640 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
3647 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
3648 without deleting other windows. */
3651 grow_mini_window (w
, delta
)
3655 struct frame
*f
= XFRAME (w
->frame
);
3656 struct window
*root
;
3658 xassert (MINI_WINDOW_P (w
));
3659 xassert (delta
>= 0);
3661 /* Check values of window_min_width and window_min_height for
3663 check_min_window_sizes ();
3665 /* Compute how much we can enlarge the mini-window without deleting
3667 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3670 int min_height
= window_min_size (root
, 0, 0, 0);
3671 if (XFASTINT (root
->height
) - delta
< min_height
)
3672 delta
= XFASTINT (root
->height
) - min_height
;
3677 /* Save original window sizes and positions, if not already done. */
3678 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3679 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
3681 /* Shrink other windows. */
3682 shrink_window_lowest_first (root
, XFASTINT (root
->height
) - delta
);
3684 /* Grow the mini-window. */
3685 w
->top
= make_number (XFASTINT (root
->top
) + XFASTINT (root
->height
));
3686 w
->height
= make_number (XFASTINT (w
->height
) + delta
);
3687 XSETFASTINT (w
->last_modified
, 0);
3688 XSETFASTINT (w
->last_overlay_modified
, 0);
3695 /* Shrink mini-window W. If there is recorded info about window sizes
3696 before a call to grow_mini_window, restore recorded window sizes.
3697 Otherwise, if the mini-window is higher than 1 line, resize it to 1
3701 shrink_mini_window (w
)
3704 struct frame
*f
= XFRAME (w
->frame
);
3705 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3707 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3709 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
3711 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
3712 windows_or_buffers_changed
= 1;
3714 else if (XFASTINT (w
->height
) > 1)
3717 XSETWINDOW (window
, w
);
3718 enlarge_window (window
, 1 - XFASTINT (w
->height
), 0);
3724 /* Mark window cursors off for all windows in the window tree rooted
3725 at W by setting their phys_cursor_on_p flag to zero. Called from
3726 xterm.c, e.g. when a frame is cleared and thereby all cursors on
3727 the frame are cleared. */
3730 mark_window_cursors_off (w
)
3735 if (!NILP (w
->hchild
))
3736 mark_window_cursors_off (XWINDOW (w
->hchild
));
3737 else if (!NILP (w
->vchild
))
3738 mark_window_cursors_off (XWINDOW (w
->vchild
));
3740 w
->phys_cursor_on_p
= 0;
3742 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
3747 /* Return number of lines of text (not counting mode line) in W. */
3750 window_internal_height (w
)
3753 int ht
= XFASTINT (w
->height
);
3755 if (MINI_WINDOW_P (w
))
3758 if (!NILP (w
->parent
) || !NILP (w
->vchild
) || !NILP (w
->hchild
)
3759 || !NILP (w
->next
) || !NILP (w
->prev
)
3760 || FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (w
))))
3767 /* Return the number of columns in W.
3768 Don't count columns occupied by scroll bars or the vertical bar
3769 separating W from the sibling to its right. */
3772 window_internal_width (w
)
3775 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
3776 int width
= XINT (w
->width
);
3778 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
3779 /* Scroll bars occupy a few columns. */
3780 width
-= FRAME_SCROLL_BAR_COLS (f
);
3781 else if (!WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
3782 /* The column of `|' characters separating side-by-side windows
3783 occupies one column only. */
3786 /* On window-systems, areas to the left and right of the window
3787 are used to display bitmaps there. */
3788 if (FRAME_WINDOW_P (f
))
3789 width
-= FRAME_FLAGS_AREA_COLS (f
);
3795 /************************************************************************
3797 ***********************************************************************/
3799 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
3800 one screen-full, which is defined as the height of the window minus
3801 next_screen_context_lines. If WHOLE is zero, scroll up N lines
3802 instead. Negative values of N mean scroll down. NOERROR non-zero
3803 means don't signal an error if we try to move over BEGV or ZV,
3807 window_scroll (window
, n
, whole
, noerror
)
3813 /* If we must, use the pixel-based version which is much slower than
3814 the line-based one but can handle varying line heights. */
3815 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
3816 window_scroll_pixel_based (window
, n
, whole
, noerror
);
3818 window_scroll_line_based (window
, n
, whole
, noerror
);
3822 /* Implementation of window_scroll that works based on pixel line
3823 heights. See the comment of window_scroll for parameter
3827 window_scroll_pixel_based (window
, n
, whole
, noerror
)
3834 struct window
*w
= XWINDOW (window
);
3835 struct text_pos start
;
3837 int this_scroll_margin
;
3840 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
3842 /* If PT is not visible in WINDOW, move back one half of
3844 XSETFASTINT (tem
, PT
);
3845 tem
= Fpos_visible_in_window_p (tem
, window
, Qt
);
3848 /* Move backward half the height of the window. Performance note:
3849 vmotion used here is about 10% faster, but would give wrong
3850 results for variable height lines. */
3851 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3852 it
.current_y
= it
.last_visible_y
;
3853 move_it_vertically (&it
, -it
.last_visible_y
/ 2);
3855 /* The function move_iterator_vertically may move over more than
3856 the specified y-distance. If it->w is small, e.g. a
3857 mini-buffer window, we may end up in front of the window's
3858 display area. This is the case when Start displaying at the
3859 start of the line containing PT in this case. */
3860 if (it
.current_y
<= 0)
3862 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3863 move_it_vertically (&it
, 0);
3867 start
= it
.current
.pos
;
3870 /* If scroll_preserve_screen_position is non-zero, we try to set
3871 point in the same window line as it is now, so get that line. */
3872 if (!NILP (Vscroll_preserve_screen_position
))
3874 start_display (&it
, w
, start
);
3875 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3876 preserve_y
= it
.current_y
;
3881 /* Move iterator it from start the specified distance forward or
3882 backward. The result is the new window start. */
3883 start_display (&it
, w
, start
);
3886 int screen_full
= (it
.last_visible_y
3887 - next_screen_context_lines
* CANON_Y_UNIT (it
.f
));
3888 int direction
= n
< 0 ? -1 : 1;
3889 move_it_vertically (&it
, direction
* screen_full
);
3892 move_it_by_lines (&it
, n
, 1);
3894 /* End if we end up at ZV or BEGV. */
3895 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
3896 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
3900 else if (IT_CHARPOS (it
) == ZV
)
3901 Fsignal (Qend_of_buffer
, Qnil
);
3903 Fsignal (Qbeginning_of_buffer
, Qnil
);
3906 /* Set the window start, and set up the window for redisplay. */
3907 set_marker_restricted (w
->start
, make_number (IT_CHARPOS (it
)), w
->buffer
);
3908 w
->start_at_line_beg
= Fbolp ();
3909 w
->update_mode_line
= Qt
;
3910 XSETFASTINT (w
->last_modified
, 0);
3911 XSETFASTINT (w
->last_overlay_modified
, 0);
3912 /* Set force_start so that redisplay_window will run the
3913 window-scroll-functions. */
3914 w
->force_start
= Qt
;
3916 it
.current_y
= it
.vpos
= 0;
3918 /* Preserve the screen position if we must. */
3919 if (preserve_y
>= 0)
3921 move_it_to (&it
, -1, -1, preserve_y
, -1, MOVE_TO_Y
);
3922 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3926 /* Move PT out of scroll margins. */
3927 this_scroll_margin
= max (0, scroll_margin
);
3928 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->height
) / 4);
3929 this_scroll_margin
*= CANON_Y_UNIT (it
.f
);
3933 /* We moved the window start towards ZV, so PT may be now
3934 in the scroll margin at the top. */
3935 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3936 while (it
.current_y
< this_scroll_margin
)
3937 move_it_by_lines (&it
, 1, 1);
3938 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3942 /* We moved the window start towards BEGV, so PT may be now
3943 in the scroll margin at the bottom. */
3944 move_it_to (&it
, PT
, -1,
3945 it
.last_visible_y
- this_scroll_margin
- 1, -1,
3946 MOVE_TO_POS
| MOVE_TO_Y
);
3948 /* Don't put point on a partially visible line at the end. */
3949 if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
3950 > it
.last_visible_y
)
3951 move_it_by_lines (&it
, -1, 0);
3953 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3959 /* Implementation of window_scroll that works based on screen lines.
3960 See the comment of window_scroll for parameter descriptions. */
3963 window_scroll_line_based (window
, n
, whole
, noerror
)
3969 register struct window
*w
= XWINDOW (window
);
3970 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
3971 register int pos
, pos_byte
;
3972 register int ht
= window_internal_height (w
);
3973 register Lisp_Object tem
;
3977 struct position posit
;
3980 startpos
= marker_position (w
->start
);
3982 posit
= *compute_motion (startpos
, 0, 0, 0,
3984 window_internal_width (w
), XINT (w
->hscroll
),
3986 original_vpos
= posit
.vpos
;
3988 XSETFASTINT (tem
, PT
);
3989 tem
= Fpos_visible_in_window_p (tem
, window
, Qt
);
3993 Fvertical_motion (make_number (- (ht
/ 2)), window
);
3998 lose
= n
< 0 && PT
== BEGV
;
3999 Fvertical_motion (make_number (n
), window
);
4003 SET_PT_BOTH (opoint
, opoint_byte
);
4010 Fsignal (Qbeginning_of_buffer
, Qnil
);
4015 int this_scroll_margin
= scroll_margin
;
4017 /* Don't use a scroll margin that is negative or too large. */
4018 if (this_scroll_margin
< 0)
4019 this_scroll_margin
= 0;
4021 if (XINT (w
->height
) < 4 * scroll_margin
)
4022 this_scroll_margin
= XINT (w
->height
) / 4;
4024 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
4025 w
->start_at_line_beg
= bolp
;
4026 w
->update_mode_line
= Qt
;
4027 XSETFASTINT (w
->last_modified
, 0);
4028 XSETFASTINT (w
->last_overlay_modified
, 0);
4029 /* Set force_start so that redisplay_window will run
4030 the window-scroll-functions. */
4031 w
->force_start
= Qt
;
4033 if (whole
&& !NILP (Vscroll_preserve_screen_position
))
4035 SET_PT_BOTH (pos
, pos_byte
);
4036 Fvertical_motion (make_number (original_vpos
), window
);
4038 /* If we scrolled forward, put point enough lines down
4039 that it is outside the scroll margin. */
4044 if (this_scroll_margin
> 0)
4046 SET_PT_BOTH (pos
, pos_byte
);
4047 Fvertical_motion (make_number (this_scroll_margin
), window
);
4053 if (top_margin
<= opoint
)
4054 SET_PT_BOTH (opoint
, opoint_byte
);
4055 else if (!NILP (Vscroll_preserve_screen_position
))
4057 SET_PT_BOTH (pos
, pos_byte
);
4058 Fvertical_motion (make_number (original_vpos
), window
);
4061 SET_PT (top_margin
);
4067 /* If we scrolled backward, put point near the end of the window
4068 but not within the scroll margin. */
4069 SET_PT_BOTH (pos
, pos_byte
);
4070 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
4071 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
4074 bottom_margin
= PT
+ 1;
4076 if (bottom_margin
> opoint
)
4077 SET_PT_BOTH (opoint
, opoint_byte
);
4080 if (!NILP (Vscroll_preserve_screen_position
))
4082 SET_PT_BOTH (pos
, pos_byte
);
4083 Fvertical_motion (make_number (original_vpos
), window
);
4086 Fvertical_motion (make_number (-1), window
);
4095 Fsignal (Qend_of_buffer
, Qnil
);
4100 /* Scroll selected_window up or down. If N is nil, scroll a
4101 screen-full which is defined as the height of the window minus
4102 next_screen_context_lines. If N is the symbol `-', scroll.
4103 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
4104 up. This is the guts of Fscroll_up and Fscroll_down. */
4107 scroll_command (n
, direction
)
4111 register int defalt
;
4112 int count
= specpdl_ptr
- specpdl
;
4114 xassert (abs (direction
) == 1);
4116 /* If selected window's buffer isn't current, make it current for
4117 the moment. But don't screw up if window_scroll gets an error. */
4118 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
4120 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4121 Fset_buffer (XWINDOW (selected_window
)->buffer
);
4123 /* Make redisplay consider other windows than just selected_window. */
4124 ++windows_or_buffers_changed
;
4127 defalt
= (window_internal_height (XWINDOW (selected_window
))
4128 - next_screen_context_lines
);
4129 defalt
= direction
* (defalt
< 1 ? 1 : defalt
);
4132 window_scroll (selected_window
, defalt
, 1, 0);
4133 else if (EQ (n
, Qminus
))
4134 window_scroll (selected_window
, - defalt
, 1, 0);
4137 n
= Fprefix_numeric_value (n
);
4138 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
4141 unbind_to (count
, Qnil
);
4144 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
4145 "Scroll text of current window upward ARG lines; or near full screen if no ARG.\n\
4146 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4147 Negative ARG means scroll downward.\n\
4148 If ARG is the atom `-', scroll downward by nearly full screen.\n\
4149 When calling from a program, supply as argument a number, nil, or `-'.")
4153 scroll_command (arg
, 1);
4157 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
4158 "Scroll text of current window down ARG lines; or near full screen if no ARG.\n\
4159 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4160 Negative ARG means scroll upward.\n\
4161 If ARG is the atom `-', scroll upward by nearly full screen.\n\
4162 When calling from a program, supply as argument a number, nil, or `-'.")
4166 scroll_command (arg
, -1);
4170 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
4171 "Return the other window for \"other window scroll\" commands.\n\
4172 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4173 specifies the window.\n\
4174 If `other-window-scroll-buffer' is non-nil, a window\n\
4175 showing that buffer is used.")
4180 if (MINI_WINDOW_P (XWINDOW (selected_window
))
4181 && !NILP (Vminibuf_scroll_window
))
4182 window
= Vminibuf_scroll_window
;
4183 /* If buffer is specified, scroll that buffer. */
4184 else if (!NILP (Vother_window_scroll_buffer
))
4186 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
4188 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
4192 /* Nothing specified; look for a neighboring window on the same
4194 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
4196 if (EQ (window
, selected_window
))
4197 /* That didn't get us anywhere; look for a window on another
4200 window
= Fnext_window (window
, Qnil
, Qt
);
4201 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
4202 && ! EQ (window
, selected_window
));
4205 CHECK_LIVE_WINDOW (window
, 0);
4207 if (EQ (window
, selected_window
))
4208 error ("There is no other window");
4213 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
4214 "Scroll next window upward ARG lines; or near full screen if no ARG.\n\
4215 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4216 The next window is the one below the current one; or the one at the top\n\
4217 if the current one is at the bottom. Negative ARG means scroll downward.\n\
4218 If ARG is the atom `-', scroll downward by nearly full screen.\n\
4219 When calling from a program, supply as argument a number, nil, or `-'.\n\
4221 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4222 specifies the window to scroll.\n\
4223 If `other-window-scroll-buffer' is non-nil, scroll the window\n\
4224 showing that buffer, popping the buffer up if necessary.")
4226 register Lisp_Object arg
;
4228 register Lisp_Object window
;
4229 register int defalt
;
4230 register struct window
*w
;
4231 register int count
= specpdl_ptr
- specpdl
;
4233 window
= Fother_window_for_scrolling ();
4235 w
= XWINDOW (window
);
4236 defalt
= window_internal_height (w
) - next_screen_context_lines
;
4237 if (defalt
< 1) defalt
= 1;
4239 /* Don't screw up if window_scroll gets an error. */
4240 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4241 ++windows_or_buffers_changed
;
4243 Fset_buffer (w
->buffer
);
4244 SET_PT (marker_position (w
->pointm
));
4247 window_scroll (window
, defalt
, 1, 1);
4248 else if (EQ (arg
, Qminus
))
4249 window_scroll (window
, -defalt
, 1, 1);
4254 CHECK_NUMBER (arg
, 0);
4255 window_scroll (window
, XINT (arg
), 0, 1);
4258 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
4259 unbind_to (count
, Qnil
);
4264 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 1, "P",
4265 "Scroll selected window display ARG columns left.\n\
4266 Default for ARG is window width minus 2.")
4268 register Lisp_Object arg
;
4272 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4274 arg
= Fprefix_numeric_value (arg
);
4277 Fset_window_hscroll (selected_window
,
4278 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4282 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 1, "P",
4283 "Scroll selected window display ARG columns right.\n\
4284 Default for ARG is window width minus 2.")
4286 register Lisp_Object arg
;
4289 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4291 arg
= Fprefix_numeric_value (arg
);
4294 Fset_window_hscroll (selected_window
,
4295 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4299 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
4300 "Center point in window and redisplay frame. With ARG, put point on line ARG.\n\
4301 The desired position of point is always relative to the current window.\n\
4302 Just C-u as prefix means put point in the center of the window.\n\
4303 If ARG is omitted or nil, erases the entire frame and then\n\
4304 redraws with point in the center of the current window.")
4306 register Lisp_Object arg
;
4308 register struct window
*w
= XWINDOW (selected_window
);
4309 register int ht
= window_internal_height (w
);
4310 struct position pos
;
4311 struct buffer
*buf
= XBUFFER (w
->buffer
);
4312 struct buffer
*obuf
= current_buffer
;
4316 extern int frame_garbaged
;
4319 /* Invalidate pixel data calculated for all compositions. */
4320 for (i
= 0; i
< n_compositions
; i
++)
4321 composition_table
[i
]->font
= NULL
;
4323 Fredraw_frame (w
->frame
);
4324 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
4325 XSETFASTINT (arg
, ht
/ 2);
4327 else if (CONSP (arg
)) /* Just C-u. */
4329 XSETFASTINT (arg
, ht
/ 2);
4333 arg
= Fprefix_numeric_value (arg
);
4334 CHECK_NUMBER (arg
, 0);
4338 XSETINT (arg
, XINT (arg
) + ht
);
4340 set_buffer_internal (buf
);
4341 pos
= *vmotion (PT
, - XINT (arg
), w
);
4343 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
4344 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
4345 || FETCH_BYTE (pos
.bytepos
- 1) == '\n')
4347 w
->force_start
= Qt
;
4348 set_buffer_internal (obuf
);
4354 /* Value is the number of lines actually displayed in window W,
4355 as opposed to its height. */
4358 displayed_window_lines (w
)
4362 struct text_pos start
;
4363 int height
= window_box_height (w
);
4365 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4366 start_display (&it
, w
, start
);
4367 move_it_vertically (&it
, height
);
4369 /* Add in empty lines at the bottom of the window. */
4370 if (it
.current_y
< height
)
4372 struct frame
*f
= XFRAME (w
->frame
);
4373 int rest
= height
- it
.current_y
;
4374 int lines
= (rest
+ CANON_Y_UNIT (f
) - 1) / CANON_Y_UNIT (f
);
4383 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
4385 "Position point relative to window.\n\
4386 With no argument, position point at center of window.\n\
4387 An argument specifies vertical position within the window;\n\
4388 zero means top of window, negative means relative to bottom of window.")
4392 struct window
*w
= XWINDOW (selected_window
);
4396 window
= selected_window
;
4397 start
= marker_position (w
->start
);
4398 if (start
< BEGV
|| start
> ZV
)
4400 int height
= window_internal_height (w
);
4401 Fvertical_motion (make_number (- (height
/ 2)), window
);
4402 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
4403 w
->start_at_line_beg
= Fbolp ();
4404 w
->force_start
= Qt
;
4407 Fgoto_char (w
->start
);
4409 lines
= displayed_window_lines (w
);
4411 XSETFASTINT (arg
, lines
/ 2);
4414 arg
= Fprefix_numeric_value (arg
);
4416 XSETINT (arg
, XINT (arg
) + lines
);
4419 return Fvertical_motion (arg
, window
);
4424 /***********************************************************************
4425 Window Configuration
4426 ***********************************************************************/
4428 struct save_window_data
4430 EMACS_INT size_from_Lisp_Vector_struct
;
4431 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4432 Lisp_Object frame_width
, frame_height
, frame_menu_bar_lines
;
4433 Lisp_Object frame_tool_bar_lines
;
4434 Lisp_Object selected_frame
;
4435 Lisp_Object current_window
;
4436 Lisp_Object current_buffer
;
4437 Lisp_Object minibuf_scroll_window
;
4438 Lisp_Object root_window
;
4439 Lisp_Object focus_frame
;
4440 /* Record the values of window-min-width and window-min-height
4441 so that window sizes remain consistent with them. */
4442 Lisp_Object min_width
, min_height
;
4443 /* A vector, each of whose elements is a struct saved_window
4445 Lisp_Object saved_windows
;
4448 /* This is saved as a Lisp_Vector */
4451 /* these first two must agree with struct Lisp_Vector in lisp.h */
4452 EMACS_INT size_from_Lisp_Vector_struct
;
4453 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4456 Lisp_Object buffer
, start
, pointm
, mark
;
4457 Lisp_Object left
, top
, width
, height
, hscroll
;
4458 Lisp_Object parent
, prev
;
4459 Lisp_Object start_at_line_beg
;
4460 Lisp_Object display_table
;
4462 #define SAVED_WINDOW_VECTOR_SIZE 14 /* Arg to Fmake_vector */
4464 #define SAVED_WINDOW_N(swv,n) \
4465 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
4467 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
4468 "Return t if OBJECT is a window-configuration object.")
4472 if (WINDOW_CONFIGURATIONP (object
))
4477 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
4478 "Return the frame that CONFIG, a window-configuration object, is about.")
4482 register struct save_window_data
*data
;
4483 struct Lisp_Vector
*saved_windows
;
4485 if (! WINDOW_CONFIGURATIONP (config
))
4486 wrong_type_argument (Qwindow_configuration_p
, config
);
4488 data
= (struct save_window_data
*) XVECTOR (config
);
4489 saved_windows
= XVECTOR (data
->saved_windows
);
4490 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4493 DEFUN ("set-window-configuration", Fset_window_configuration
,
4494 Sset_window_configuration
, 1, 1, 0,
4495 "Set the configuration of windows and buffers as specified by CONFIGURATION.\n\
4496 CONFIGURATION must be a value previously returned\n\
4497 by `current-window-configuration' (which see).\n\
4498 If CONFIGURATION was made from a frame that is now deleted,\n\
4499 only frame-independent values can be restored. In this case,\n\
4500 the return value is nil. Otherwise the value is t.")
4502 Lisp_Object configuration
;
4504 register struct save_window_data
*data
;
4505 struct Lisp_Vector
*saved_windows
;
4506 Lisp_Object new_current_buffer
;
4511 while (!WINDOW_CONFIGURATIONP (configuration
))
4512 wrong_type_argument (Qwindow_configuration_p
, configuration
);
4514 data
= (struct save_window_data
*) XVECTOR (configuration
);
4515 saved_windows
= XVECTOR (data
->saved_windows
);
4517 new_current_buffer
= data
->current_buffer
;
4518 if (NILP (XBUFFER (new_current_buffer
)->name
))
4519 new_current_buffer
= Qnil
;
4522 if (XBUFFER (new_current_buffer
) == current_buffer
)
4527 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4530 /* If f is a dead frame, don't bother rebuilding its window tree.
4531 However, there is other stuff we should still try to do below. */
4532 if (FRAME_LIVE_P (f
))
4534 register struct window
*w
;
4535 register struct saved_window
*p
;
4536 struct window
*root_window
;
4537 struct window
**leaf_windows
;
4541 /* If the frame has been resized since this window configuration was
4542 made, we change the frame to the size specified in the
4543 configuration, restore the configuration, and then resize it
4544 back. We keep track of the prevailing height in these variables. */
4545 int previous_frame_height
= FRAME_HEIGHT (f
);
4546 int previous_frame_width
= FRAME_WIDTH (f
);
4547 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
4548 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
4550 /* The mouse highlighting code could get screwed up
4551 if it runs during this. */
4554 if (XFASTINT (data
->frame_height
) != previous_frame_height
4555 || XFASTINT (data
->frame_width
) != previous_frame_width
)
4556 change_frame_size (f
, XFASTINT (data
->frame_height
),
4557 XFASTINT (data
->frame_width
), 0, 0, 0);
4558 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4559 if (XFASTINT (data
->frame_menu_bar_lines
)
4560 != previous_frame_menu_bar_lines
)
4561 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, make_number (0));
4562 #ifdef HAVE_WINDOW_SYSTEM
4563 if (XFASTINT (data
->frame_tool_bar_lines
)
4564 != previous_frame_tool_bar_lines
)
4565 x_set_tool_bar_lines (f
, data
->frame_tool_bar_lines
, make_number (0));
4569 /* "Swap out" point from the selected window
4570 into its buffer. We do this now, before
4571 restoring the window contents, and prevent it from
4572 being done later on when we select a new window. */
4573 if (! NILP (XWINDOW (selected_window
)->buffer
))
4575 w
= XWINDOW (selected_window
);
4576 set_marker_both (w
->pointm
,
4578 BUF_PT (XBUFFER (w
->buffer
)),
4579 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4582 windows_or_buffers_changed
++;
4583 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4585 /* Problem: Freeing all matrices and later allocating them again
4586 is a serious redisplay flickering problem. What we would
4587 really like to do is to free only those matrices not reused
4589 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4591 = (struct window
**) alloca (count_windows (root_window
)
4592 * sizeof (struct window
*));
4593 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
4595 /* Temporarily avoid any problems with windows that are smaller
4596 than they are supposed to be. */
4597 window_min_height
= 1;
4598 window_min_width
= 1;
4601 Mark all windows now on frame as "deleted".
4602 Restoring the new configuration "undeletes" any that are in it.
4604 Save their current buffers in their height fields, since we may
4605 need it later, if a buffer saved in the configuration is now
4607 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4609 for (k
= 0; k
< saved_windows
->size
; k
++)
4611 p
= SAVED_WINDOW_N (saved_windows
, k
);
4612 w
= XWINDOW (p
->window
);
4615 if (!NILP (p
->parent
))
4616 w
->parent
= SAVED_WINDOW_N (saved_windows
,
4617 XFASTINT (p
->parent
))->window
;
4621 if (!NILP (p
->prev
))
4623 w
->prev
= SAVED_WINDOW_N (saved_windows
,
4624 XFASTINT (p
->prev
))->window
;
4625 XWINDOW (w
->prev
)->next
= p
->window
;
4630 if (!NILP (w
->parent
))
4632 if (EQ (p
->width
, XWINDOW (w
->parent
)->width
))
4634 XWINDOW (w
->parent
)->vchild
= p
->window
;
4635 XWINDOW (w
->parent
)->hchild
= Qnil
;
4639 XWINDOW (w
->parent
)->hchild
= p
->window
;
4640 XWINDOW (w
->parent
)->vchild
= Qnil
;
4645 /* If we squirreled away the buffer in the window's height,
4647 if (BUFFERP (w
->height
))
4648 w
->buffer
= w
->height
;
4651 w
->width
= p
->width
;
4652 w
->height
= p
->height
;
4653 w
->hscroll
= p
->hscroll
;
4654 w
->display_table
= p
->display_table
;
4655 XSETFASTINT (w
->last_modified
, 0);
4656 XSETFASTINT (w
->last_overlay_modified
, 0);
4658 /* Reinstall the saved buffer and pointers into it. */
4659 if (NILP (p
->buffer
))
4660 w
->buffer
= p
->buffer
;
4663 if (!NILP (XBUFFER (p
->buffer
)->name
))
4664 /* If saved buffer is alive, install it. */
4666 w
->buffer
= p
->buffer
;
4667 w
->start_at_line_beg
= p
->start_at_line_beg
;
4668 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
4669 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
4670 Fset_marker (XBUFFER (w
->buffer
)->mark
,
4671 p
->mark
, w
->buffer
);
4673 /* As documented in Fcurrent_window_configuration, don't
4674 save the location of point in the buffer which was current
4675 when the window configuration was recorded. */
4676 if (!EQ (p
->buffer
, new_current_buffer
)
4677 && XBUFFER (p
->buffer
) == current_buffer
)
4678 Fgoto_char (w
->pointm
);
4680 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
4681 /* Else unless window has a live buffer, get one. */
4683 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
4684 /* This will set the markers to beginning of visible
4686 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
4687 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
4688 w
->start_at_line_beg
= Qt
;
4691 /* Keeping window's old buffer; make sure the markers
4694 /* Set window markers at start of visible range. */
4695 if (XMARKER (w
->start
)->buffer
== 0)
4696 set_marker_restricted (w
->start
, make_number (0),
4698 if (XMARKER (w
->pointm
)->buffer
== 0)
4699 set_marker_restricted_both (w
->pointm
, w
->buffer
,
4700 BUF_PT (XBUFFER (w
->buffer
)),
4701 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4702 w
->start_at_line_beg
= Qt
;
4707 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
4708 /* Prevent "swapping out point" in the old selected window
4709 using the buffer that has been restored into it.
4710 That swapping out has already been done,
4711 near the beginning of this function. */
4712 selected_window
= Qnil
;
4713 Fselect_window (data
->current_window
);
4714 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
4717 if (NILP (data
->focus_frame
)
4718 || (FRAMEP (data
->focus_frame
)
4719 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
4720 Fredirect_frame_focus (frame
, data
->focus_frame
);
4722 #if 0 /* I don't understand why this is needed, and it causes problems
4723 when the frame's old selected window has been deleted. */
4724 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
4725 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
4729 /* Set the screen height to the value it had before this function. */
4730 if (previous_frame_height
!= FRAME_HEIGHT (f
)
4731 || previous_frame_width
!= FRAME_WIDTH (f
))
4732 change_frame_size (f
, previous_frame_height
, previous_frame_width
,
4734 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4735 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
4736 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
4738 #ifdef HAVE_WINDOW_SYSTEM
4739 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
4740 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
4745 /* Now, free glyph matrices in windows that were not reused. */
4746 for (i
= 0; i
< n_leaf_windows
; ++i
)
4747 if (NILP (leaf_windows
[i
]->buffer
))
4749 /* Assert it's not reused as a combination. */
4750 xassert (NILP (leaf_windows
[i
]->hchild
)
4751 && NILP (leaf_windows
[i
]->vchild
));
4752 free_window_matrices (leaf_windows
[i
]);
4753 SET_FRAME_GARBAGED (f
);
4760 /* Fselect_window will have made f the selected frame, so we
4761 reselect the proper frame here. Fhandle_switch_frame will change the
4762 selected window too, but that doesn't make the call to
4763 Fselect_window above totally superfluous; it still sets f's
4765 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
4766 do_switch_frame (data
->selected_frame
, Qnil
, 0);
4768 if (! NILP (Vwindow_configuration_change_hook
)
4769 && ! NILP (Vrun_hooks
))
4770 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
4773 if (!NILP (new_current_buffer
))
4775 Fset_buffer (new_current_buffer
);
4777 /* If the buffer that is current now is the same
4778 that was current before setting the window configuration,
4779 don't alter its PT. */
4784 /* Restore the minimum heights recorded in the configuration. */
4785 window_min_height
= XINT (data
->min_height
);
4786 window_min_width
= XINT (data
->min_width
);
4788 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
4790 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
4793 /* Mark all windows now on frame as deleted
4794 by setting their buffers to nil. */
4797 delete_all_subwindows (w
)
4798 register struct window
*w
;
4800 if (!NILP (w
->next
))
4801 delete_all_subwindows (XWINDOW (w
->next
));
4802 if (!NILP (w
->vchild
))
4803 delete_all_subwindows (XWINDOW (w
->vchild
));
4804 if (!NILP (w
->hchild
))
4805 delete_all_subwindows (XWINDOW (w
->hchild
));
4807 w
->height
= w
->buffer
; /* See Fset_window_configuration for excuse. */
4809 if (!NILP (w
->buffer
))
4812 /* We set all three of these fields to nil, to make sure that we can
4813 distinguish this dead window from any live window. Live leaf
4814 windows will have buffer set, and combination windows will have
4815 vchild or hchild set. */
4820 Vwindow_list
= Qnil
;
4824 count_windows (window
)
4825 register struct window
*window
;
4827 register int count
= 1;
4828 if (!NILP (window
->next
))
4829 count
+= count_windows (XWINDOW (window
->next
));
4830 if (!NILP (window
->vchild
))
4831 count
+= count_windows (XWINDOW (window
->vchild
));
4832 if (!NILP (window
->hchild
))
4833 count
+= count_windows (XWINDOW (window
->hchild
));
4838 /* Fill vector FLAT with leaf windows under W, starting at index I.
4839 Value is last index + 1. */
4842 get_leaf_windows (w
, flat
, i
)
4844 struct window
**flat
;
4849 if (!NILP (w
->hchild
))
4850 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
4851 else if (!NILP (w
->vchild
))
4852 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
4856 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4863 /* Return a pointer to the glyph W's physical cursor is on. Value is
4864 null if W's current matrix is invalid, so that no meaningfull glyph
4868 get_phys_cursor_glyph (w
)
4871 struct glyph_row
*row
;
4872 struct glyph
*glyph
;
4874 if (w
->phys_cursor
.vpos
>= 0
4875 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
4876 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
4878 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
4879 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
4888 save_window_save (window
, vector
, i
)
4890 struct Lisp_Vector
*vector
;
4893 register struct saved_window
*p
;
4894 register struct window
*w
;
4895 register Lisp_Object tem
;
4897 for (;!NILP (window
); window
= w
->next
)
4899 p
= SAVED_WINDOW_N (vector
, i
);
4900 w
= XWINDOW (window
);
4902 XSETFASTINT (w
->temslot
, i
++);
4904 p
->buffer
= w
->buffer
;
4907 p
->width
= w
->width
;
4908 p
->height
= w
->height
;
4909 p
->hscroll
= w
->hscroll
;
4910 p
->display_table
= w
->display_table
;
4911 if (!NILP (w
->buffer
))
4913 /* Save w's value of point in the window configuration.
4914 If w is the selected window, then get the value of point
4915 from the buffer; pointm is garbage in the selected window. */
4916 if (EQ (window
, selected_window
))
4918 p
->pointm
= Fmake_marker ();
4919 set_marker_both (p
->pointm
, w
->buffer
,
4920 BUF_PT (XBUFFER (w
->buffer
)),
4921 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4924 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
4926 p
->start
= Fcopy_marker (w
->start
, Qnil
);
4927 p
->start_at_line_beg
= w
->start_at_line_beg
;
4929 tem
= XBUFFER (w
->buffer
)->mark
;
4930 p
->mark
= Fcopy_marker (tem
, Qnil
);
4937 p
->start_at_line_beg
= Qnil
;
4940 if (NILP (w
->parent
))
4943 p
->parent
= XWINDOW (w
->parent
)->temslot
;
4948 p
->prev
= XWINDOW (w
->prev
)->temslot
;
4950 if (!NILP (w
->vchild
))
4951 i
= save_window_save (w
->vchild
, vector
, i
);
4952 if (!NILP (w
->hchild
))
4953 i
= save_window_save (w
->hchild
, vector
, i
);
4959 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
4960 Scurrent_window_configuration
, 0, 1, 0,
4961 "Return an object representing the current window configuration of FRAME.\n\
4962 If FRAME is nil or omitted, use the selected frame.\n\
4963 This describes the number of windows, their sizes and current buffers,\n\
4964 and for each displayed buffer, where display starts, and the positions of\n\
4965 point and mark. An exception is made for point in the current buffer:\n\
4966 its value is -not- saved.\n\
4967 This also records the currently selected frame, and FRAME's focus\n\
4968 redirection (see `redirect-frame-focus').")
4972 register Lisp_Object tem
;
4973 register int n_windows
;
4974 register struct save_window_data
*data
;
4975 register struct Lisp_Vector
*vec
;
4980 frame
= selected_frame
;
4981 CHECK_LIVE_FRAME (frame
, 0);
4984 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4985 vec
= allocate_vectorlike (VECSIZE (struct save_window_data
));
4986 for (i
= 0; i
< VECSIZE (struct save_window_data
); i
++)
4987 vec
->contents
[i
] = Qnil
;
4988 vec
->size
= VECSIZE (struct save_window_data
);
4989 data
= (struct save_window_data
*)vec
;
4991 XSETFASTINT (data
->frame_width
, FRAME_WIDTH (f
));
4992 XSETFASTINT (data
->frame_height
, FRAME_HEIGHT (f
));
4993 XSETFASTINT (data
->frame_menu_bar_lines
, FRAME_MENU_BAR_LINES (f
));
4994 XSETFASTINT (data
->frame_tool_bar_lines
, FRAME_TOOL_BAR_LINES (f
));
4995 data
->selected_frame
= selected_frame
;
4996 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
4997 XSETBUFFER (data
->current_buffer
, current_buffer
);
4998 data
->minibuf_scroll_window
= Vminibuf_scroll_window
;
4999 data
->root_window
= FRAME_ROOT_WINDOW (f
);
5000 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
5001 XSETINT (data
->min_height
, window_min_height
);
5002 XSETINT (data
->min_width
, window_min_width
);
5003 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
5004 data
->saved_windows
= tem
;
5005 for (i
= 0; i
< n_windows
; i
++)
5006 XVECTOR (tem
)->contents
[i
]
5007 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
5008 save_window_save (FRAME_ROOT_WINDOW (f
),
5010 XSETWINDOW_CONFIGURATION (tem
, data
);
5014 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
5016 "Execute body, preserving window sizes and contents.\n\
5017 Restore which buffer appears in which window, where display starts,\n\
5018 and the value of point and mark for each window.\n\
5019 Also restore the choice of selected window.\n\
5020 Also restore which buffer is current.\n\
5021 Does not restore the value of point in current buffer.")
5025 register Lisp_Object val
;
5026 register int count
= specpdl_ptr
- specpdl
;
5028 record_unwind_protect (Fset_window_configuration
,
5029 Fcurrent_window_configuration (Qnil
));
5030 val
= Fprogn (args
);
5031 return unbind_to (count
, val
);
5035 /***********************************************************************
5037 ***********************************************************************/
5039 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
5041 "Set width of marginal areas of window WINDOW.\n\
5042 If window is nil, set margins of the currently selected window.\n\
5043 First parameter LEFT-WIDTH specifies the number of character\n\
5044 cells to reserve for the left marginal area. Second parameter\n\
5045 RIGHT-WIDTH does the same for the right marginal area.\n\
5046 A nil width parameter means no margin.")
5047 (window
, left
, right
)
5048 Lisp_Object window
, left
, right
;
5050 struct window
*w
= decode_window (window
);
5053 CHECK_NUMBER_OR_FLOAT (left
, 1);
5055 CHECK_NUMBER_OR_FLOAT (right
, 2);
5057 /* Check widths < 0 and translate a zero width to nil.
5058 Margins that are too wide have to be checked elsewhere. */
5059 if ((INTEGERP (left
) && XINT (left
) < 0)
5060 || (FLOATP (left
) && XFLOAT_DATA (left
) <= 0))
5061 XSETFASTINT (left
, 0);
5062 if (INTEGERP (left
) && XFASTINT (left
) == 0)
5065 if ((INTEGERP (right
) && XINT (right
) < 0)
5066 || (FLOATP (right
) && XFLOAT_DATA (right
) <= 0))
5067 XSETFASTINT (right
, 0);
5068 if (INTEGERP (right
) && XFASTINT (right
) == 0)
5071 w
->left_margin_width
= left
;
5072 w
->right_margin_width
= right
;
5074 ++windows_or_buffers_changed
;
5075 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
5080 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
5082 "Get width of marginal areas of window WINDOW.\n\
5083 If WINDOW is omitted or nil, use the currently selected window.\n\
5084 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).\n\
5085 If a marginal area does not exist, its width will be returned\n\
5090 struct window
*w
= decode_window (window
);
5091 return Fcons (w
->left_margin_width
, w
->right_margin_width
);
5096 /***********************************************************************
5098 ***********************************************************************/
5100 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 1, 0,
5101 "Return the amount by which WINDOW is scrolled vertically.\n\
5102 Use the selected window if WINDOW is nil or omitted.\n\
5103 Value is a multiple of the canonical character height of WINDOW.")
5112 window
= selected_window
;
5114 CHECK_WINDOW (window
, 0);
5115 w
= XWINDOW (window
);
5116 f
= XFRAME (w
->frame
);
5118 if (FRAME_WINDOW_P (f
))
5119 result
= CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
);
5121 result
= make_number (0);
5126 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
5128 "Set amount by which WINDOW should be scrolled vertically to VSCROLL.\n\
5129 WINDOW nil or omitted means use the selected window. VSCROLL is a\n\
5130 non-negative multiple of the canonical character height of WINDOW.")
5132 Lisp_Object window
, vscroll
;
5138 window
= selected_window
;
5140 CHECK_WINDOW (window
, 0);
5141 CHECK_NUMBER_OR_FLOAT (vscroll
, 1);
5143 w
= XWINDOW (window
);
5144 f
= XFRAME (w
->frame
);
5146 if (FRAME_WINDOW_P (f
))
5148 int old_dy
= w
->vscroll
;
5150 w
->vscroll
= - CANON_Y_UNIT (f
) * XFLOATINT (vscroll
);
5151 w
->vscroll
= min (w
->vscroll
, 0);
5153 /* Adjust glyph matrix of the frame if the virtual display
5154 area becomes larger than before. */
5155 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
5158 /* Prevent redisplay shortcuts. */
5159 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
5162 return Fwindow_vscroll (window
);
5166 /* Call FN for all leaf windows on frame F. FN is called with the
5167 first argument being a pointer to the leaf window, and with
5168 additional argument USER_DATA. Stops when FN returns 0. */
5171 foreach_window (f
, fn
, user_data
)
5173 int (* fn
) P_ ((struct window
*, void *));
5176 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, user_data
);
5180 /* Helper function for foreach_window. Call FN for all leaf windows
5181 reachable from W. FN is called with the first argument being a
5182 pointer to the leaf window, and with additional argument USER_DATA.
5183 Stop when FN returns 0. Value is 0 if stopped by FN. */
5186 foreach_window_1 (w
, fn
, user_data
)
5188 int (* fn
) P_ ((struct window
*, void *));
5193 for (cont
= 1; w
&& cont
;)
5195 if (!NILP (w
->hchild
))
5196 cont
= foreach_window_1 (XWINDOW (w
->hchild
), fn
, user_data
);
5197 else if (!NILP (w
->vchild
))
5198 cont
= foreach_window_1 (XWINDOW (w
->vchild
), fn
, user_data
);
5200 cont
= fn (w
, user_data
);
5202 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5209 /* Freeze or unfreeze the window start of W if unless it is a
5210 mini-window or the selected window. FREEZE_P non-null means freeze
5211 the window start. */
5214 freeze_window_start (w
, freeze_p
)
5218 if (w
== XWINDOW (selected_window
)
5219 || MINI_WINDOW_P (w
)
5220 || (MINI_WINDOW_P (XWINDOW (selected_window
))
5221 && ! NILP (Vminibuf_scroll_window
)
5222 && w
== XWINDOW (Vminibuf_scroll_window
)))
5225 w
->frozen_window_start_p
= freeze_p
!= NULL
;
5230 /* Freeze or unfreeze the window starts of all leaf windows on frame
5231 F, except the selected window and a mini-window. FREEZE_P non-zero
5232 means freeze the window start. */
5235 freeze_window_starts (f
, freeze_p
)
5239 foreach_window (f
, freeze_window_start
, (void *) (freeze_p
? f
: 0));
5243 /***********************************************************************
5245 ***********************************************************************/
5247 /* Return 1 if window configurations C1 and C2
5248 describe the same state of affairs. This is used by Fequal. */
5251 compare_window_configurations (c1
, c2
, ignore_positions
)
5253 int ignore_positions
;
5255 register struct save_window_data
*d1
, *d2
;
5256 struct Lisp_Vector
*sw1
, *sw2
;
5259 if (!WINDOW_CONFIGURATIONP (c1
))
5260 wrong_type_argument (Qwindow_configuration_p
, c1
);
5261 if (!WINDOW_CONFIGURATIONP (c2
))
5262 wrong_type_argument (Qwindow_configuration_p
, c2
);
5264 d1
= (struct save_window_data
*) XVECTOR (c1
);
5265 d2
= (struct save_window_data
*) XVECTOR (c2
);
5266 sw1
= XVECTOR (d1
->saved_windows
);
5267 sw2
= XVECTOR (d2
->saved_windows
);
5269 if (! EQ (d1
->frame_width
, d2
->frame_width
))
5271 if (! EQ (d1
->frame_height
, d2
->frame_height
))
5273 if (! EQ (d1
->frame_menu_bar_lines
, d2
->frame_menu_bar_lines
))
5275 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
5277 /* Don't compare the current_window field directly.
5278 Instead see w1_is_current and w2_is_current, below. */
5279 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
5281 if (! ignore_positions
)
5282 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
5284 /* Don't compare the root_window field.
5285 We don't require the two configurations
5286 to use the same window object,
5287 and the two root windows must be equivalent
5288 if everything else compares equal. */
5289 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
5291 if (! EQ (d1
->min_width
, d2
->min_width
))
5293 if (! EQ (d1
->min_height
, d2
->min_height
))
5296 /* Verify that the two confis have the same number of windows. */
5297 if (sw1
->size
!= sw2
->size
)
5300 for (i
= 0; i
< sw1
->size
; i
++)
5302 struct saved_window
*p1
, *p2
;
5303 int w1_is_current
, w2_is_current
;
5305 p1
= SAVED_WINDOW_N (sw1
, i
);
5306 p2
= SAVED_WINDOW_N (sw2
, i
);
5308 /* Verify that the current windows in the two
5309 configurations correspond to each other. */
5310 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
5311 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
5313 if (w1_is_current
!= w2_is_current
)
5316 /* Verify that the corresponding windows do match. */
5317 if (! EQ (p1
->buffer
, p2
->buffer
))
5319 if (! EQ (p1
->left
, p2
->left
))
5321 if (! EQ (p1
->top
, p2
->top
))
5323 if (! EQ (p1
->width
, p2
->width
))
5325 if (! EQ (p1
->height
, p2
->height
))
5327 if (! EQ (p1
->display_table
, p2
->display_table
))
5329 if (! EQ (p1
->parent
, p2
->parent
))
5331 if (! EQ (p1
->prev
, p2
->prev
))
5333 if (! ignore_positions
)
5335 if (! EQ (p1
->hscroll
, p2
->hscroll
))
5337 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
5339 if (NILP (Fequal (p1
->start
, p2
->start
)))
5341 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
5343 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
5351 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
5352 Scompare_window_configurations
, 2, 2, 0,
5353 "Compare two window configurations as regards the structure of windows.\n\
5354 This function ignores details such as the values of point and mark\n\
5355 and scrolling positions.")
5359 if (compare_window_configurations (x
, y
, 1))
5367 struct frame
*f
= make_terminal_frame ();
5368 XSETFRAME (selected_frame
, f
);
5369 Vterminal_frame
= selected_frame
;
5370 minibuf_window
= f
->minibuffer_window
;
5371 selected_window
= f
->selected_window
;
5372 last_nonminibuf_frame
= f
;
5374 window_initialized
= 1;
5380 Vwindow_list
= Qnil
;
5386 Qleft_bitmap_area
= intern ("left-bitmap-area");
5387 staticpro (&Qleft_bitmap_area
);
5388 Qright_bitmap_area
= intern ("right-bitmap-area");
5389 staticpro (&Qright_bitmap_area
);
5391 Qwindow_size_fixed
= intern ("window-size-fixed");
5392 staticpro (&Qwindow_size_fixed
);
5394 staticpro (&Qwindow_configuration_change_hook
);
5395 Qwindow_configuration_change_hook
5396 = intern ("window-configuration-change-hook");
5398 Qwindowp
= intern ("windowp");
5399 staticpro (&Qwindowp
);
5401 Qwindow_configuration_p
= intern ("window-configuration-p");
5402 staticpro (&Qwindow_configuration_p
);
5404 Qwindow_live_p
= intern ("window-live-p");
5405 staticpro (&Qwindow_live_p
);
5407 Qtemp_buffer_show_hook
= intern ("temp-buffer-show-hook");
5408 staticpro (&Qtemp_buffer_show_hook
);
5410 staticpro (&Vwindow_list
);
5412 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
5413 "Non-nil means call as function to display a help buffer.\n\
5414 The function is called with one argument, the buffer to be displayed.\n\
5415 Used by `with-output-to-temp-buffer'.\n\
5416 If this function is used, then it must do the entire job of showing\n\
5417 the buffer; `temp-buffer-show-hook' is not run unless this function runs it.");
5418 Vtemp_buffer_show_function
= Qnil
;
5420 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
5421 "If non-nil, function to call to handle `display-buffer'.\n\
5422 It will receive two args, the buffer and a flag which if non-nil means\n\
5423 that the currently selected window is not acceptable.\n\
5424 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
5425 work using this function.");
5426 Vdisplay_buffer_function
= Qnil
;
5428 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
5429 "Non-nil means it is the window that C-M-v in minibuffer should scroll.");
5430 Vminibuf_scroll_window
= Qnil
;
5432 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
5433 "If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.");
5434 Vother_window_scroll_buffer
= Qnil
;
5436 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
5437 "*Non-nil means `display-buffer' should make a separate frame.");
5440 DEFVAR_BOOL ("display-buffer-reuse-frames", &display_buffer_reuse_frames
,
5441 "*Non-nil means `display-buffer' should reuse frames.\n\
5442 If the buffer in question is already displayed in a frame, raise that frame.");
5443 display_buffer_reuse_frames
= 0;
5445 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
5446 "Function to call to handle automatic new frame creation.\n\
5447 It is called with no arguments and should return a newly created frame.\n\
5449 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'\n\
5450 where `pop-up-frame-alist' would hold the default frame parameters.");
5451 Vpop_up_frame_function
= Qnil
;
5453 DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names
,
5454 "*List of buffer names that should have their own special frames.\n\
5455 Displaying a buffer whose name is in this list makes a special frame for it\n\
5456 using `special-display-function'. See also `special-display-regexps'.\n\
5458 An element of the list can be a list instead of just a string.\n\
5459 There are two ways to use a list as an element:\n\
5460 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)\n\
5461 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5462 In the latter case, FUNCTION is called with BUFFER as the first argument,\n\
5463 followed by OTHER-ARGS--it can display BUFFER in any way it likes.\n\
5464 All this is done by the function found in `special-display-function'.\n\
5466 If this variable appears \"not to work\", because you add a name to it\n\
5467 but that buffer still appears in the selected window, look at the\n\
5468 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5469 Those variables take precedence over this one.");
5470 Vspecial_display_buffer_names
= Qnil
;
5472 DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps
,
5473 "*List of regexps saying which buffers should have their own special frames.\n\
5474 If a buffer name matches one of these regexps, it gets its own frame.\n\
5475 Displaying a buffer whose name is in this list makes a special frame for it\n\
5476 using `special-display-function'.\n\
5478 An element of the list can be a list instead of just a string.\n\
5479 There are two ways to use a list as an element:\n\
5480 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)\n\
5481 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5482 In the latter case, FUNCTION is called with the buffer as first argument,\n\
5483 followed by OTHER-ARGS--it can display the buffer in any way it likes.\n\
5484 All this is done by the function found in `special-display-function'.\n\
5486 If this variable appears \"not to work\", because you add a regexp to it\n\
5487 but the matching buffers still appear in the selected window, look at the\n\
5488 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5489 Those variables take precedence over this one.");
5490 Vspecial_display_regexps
= Qnil
;
5492 DEFVAR_LISP ("special-display-function", &Vspecial_display_function
,
5493 "Function to call to make a new frame for a special buffer.\n\
5494 It is called with two arguments, the buffer and optional buffer specific\n\
5495 data, and should return a window displaying that buffer.\n\
5496 The default value makes a separate frame for the buffer,\n\
5497 using `special-display-frame-alist' to specify the frame parameters.\n\
5499 A buffer is special if its is listed in `special-display-buffer-names'\n\
5500 or matches a regexp in `special-display-regexps'.");
5501 Vspecial_display_function
= Qnil
;
5503 DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names
,
5504 "*List of buffer names that should appear in the selected window.\n\
5505 Displaying one of these buffers using `display-buffer' or `pop-to-buffer'\n\
5506 switches to it in the selected window, rather than making it appear\n\
5507 in some other window.\n\
5509 An element of the list can be a cons cell instead of just a string.\n\
5510 Then the car must be a string, which specifies the buffer name.\n\
5511 This is for compatibility with `special-display-buffer-names';\n\
5512 the cdr of the cons cell is ignored.\n\
5514 See also `same-window-regexps'.");
5515 Vsame_window_buffer_names
= Qnil
;
5517 DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps
,
5518 "*List of regexps saying which buffers should appear in the selected window.\n\
5519 If a buffer name matches one of these regexps, then displaying it\n\
5520 using `display-buffer' or `pop-to-buffer' switches to it\n\
5521 in the selected window, rather than making it appear in some other window.\n\
5523 An element of the list can be a cons cell instead of just a string.\n\
5524 Then the car must be a string, which specifies the buffer name.\n\
5525 This is for compatibility with `special-display-buffer-names';\n\
5526 the cdr of the cons cell is ignored.\n\
5528 See also `same-window-buffer-names'.");
5529 Vsame_window_regexps
= Qnil
;
5531 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
5532 "*Non-nil means display-buffer should make new windows.");
5535 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
5536 "*Number of lines of continuity when scrolling by screenfuls.");
5537 next_screen_context_lines
= 2;
5539 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
5540 "*display-buffer would prefer to split the largest window if this large.\n\
5541 If there is only one window, it is split regardless of this value.");
5542 split_height_threshold
= 500;
5544 DEFVAR_INT ("window-min-height", &window_min_height
,
5545 "*Delete any window less than this tall (including its mode line).");
5546 window_min_height
= 4;
5548 DEFVAR_INT ("window-min-width", &window_min_width
,
5549 "*Delete any window less than this wide.");
5550 window_min_width
= 10;
5552 DEFVAR_LISP ("scroll-preserve-screen-position",
5553 &Vscroll_preserve_screen_position
,
5554 "*Nonzero means scroll commands move point to keep its screen line unchanged.");
5555 Vscroll_preserve_screen_position
= Qnil
;
5557 DEFVAR_LISP ("window-configuration-change-hook",
5558 &Vwindow_configuration_change_hook
,
5559 "Functions to call when window configuration changes.\n\
5560 The selected frame is the one whose configuration has changed.");
5561 Vwindow_configuration_change_hook
= Qnil
;
5563 defsubr (&Sselected_window
);
5564 defsubr (&Sminibuffer_window
);
5565 defsubr (&Swindow_minibuffer_p
);
5566 defsubr (&Swindowp
);
5567 defsubr (&Swindow_live_p
);
5568 defsubr (&Spos_visible_in_window_p
);
5569 defsubr (&Swindow_buffer
);
5570 defsubr (&Swindow_height
);
5571 defsubr (&Swindow_width
);
5572 defsubr (&Swindow_hscroll
);
5573 defsubr (&Sset_window_hscroll
);
5574 defsubr (&Swindow_redisplay_end_trigger
);
5575 defsubr (&Sset_window_redisplay_end_trigger
);
5576 defsubr (&Swindow_edges
);
5577 defsubr (&Scoordinates_in_window_p
);
5578 defsubr (&Swindow_at
);
5579 defsubr (&Swindow_point
);
5580 defsubr (&Swindow_start
);
5581 defsubr (&Swindow_end
);
5582 defsubr (&Sset_window_point
);
5583 defsubr (&Sset_window_start
);
5584 defsubr (&Swindow_dedicated_p
);
5585 defsubr (&Sset_window_dedicated_p
);
5586 defsubr (&Swindow_display_table
);
5587 defsubr (&Sset_window_display_table
);
5588 defsubr (&Snext_window
);
5589 defsubr (&Sprevious_window
);
5590 defsubr (&Sother_window
);
5591 defsubr (&Sget_lru_window
);
5592 defsubr (&Sget_largest_window
);
5593 defsubr (&Sget_buffer_window
);
5594 defsubr (&Sdelete_other_windows
);
5595 defsubr (&Sdelete_windows_on
);
5596 defsubr (&Sreplace_buffer_in_windows
);
5597 defsubr (&Sdelete_window
);
5598 defsubr (&Sset_window_buffer
);
5599 defsubr (&Sselect_window
);
5600 defsubr (&Sspecial_display_p
);
5601 defsubr (&Ssame_window_p
);
5602 defsubr (&Sdisplay_buffer
);
5603 defsubr (&Ssplit_window
);
5604 defsubr (&Senlarge_window
);
5605 defsubr (&Sshrink_window
);
5606 defsubr (&Sscroll_up
);
5607 defsubr (&Sscroll_down
);
5608 defsubr (&Sscroll_left
);
5609 defsubr (&Sscroll_right
);
5610 defsubr (&Sother_window_for_scrolling
);
5611 defsubr (&Sscroll_other_window
);
5612 defsubr (&Srecenter
);
5613 defsubr (&Smove_to_window_line
);
5614 defsubr (&Swindow_configuration_p
);
5615 defsubr (&Swindow_configuration_frame
);
5616 defsubr (&Sset_window_configuration
);
5617 defsubr (&Scurrent_window_configuration
);
5618 defsubr (&Ssave_window_excursion
);
5619 defsubr (&Sset_window_margins
);
5620 defsubr (&Swindow_margins
);
5621 defsubr (&Swindow_vscroll
);
5622 defsubr (&Sset_window_vscroll
);
5623 defsubr (&Scompare_window_configurations
);
5624 defsubr (&Swindow_list
);
5630 initial_define_key (control_x_map
, '1', "delete-other-windows");
5631 initial_define_key (control_x_map
, '2', "split-window");
5632 initial_define_key (control_x_map
, '0', "delete-window");
5633 initial_define_key (control_x_map
, 'o', "other-window");
5634 initial_define_key (control_x_map
, '^', "enlarge-window");
5635 initial_define_key (control_x_map
, '<', "scroll-left");
5636 initial_define_key (control_x_map
, '>', "scroll-right");
5638 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
5639 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
5640 initial_define_key (meta_map
, 'v', "scroll-down");
5642 initial_define_key (global_map
, Ctl('L'), "recenter");
5643 initial_define_key (meta_map
, 'r', "move-to-window-line");