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 */
47 #define max(a, b) ((a) < (b) ? (b) : (a))
51 Lisp_Object Qwindowp
, Qwindow_live_p
, Qwindow_configuration_p
;
52 Lisp_Object Qwindow_size_fixed
, Qleft_bitmap_area
, Qright_bitmap_area
;
53 extern Lisp_Object Qheight
, Qwidth
;
55 static struct window
*decode_window
P_ ((Lisp_Object
));
56 static Lisp_Object select_window_1
P_ ((Lisp_Object
, int));
57 static int count_windows
P_ ((struct window
*));
58 static int get_leaf_windows
P_ ((struct window
*, struct window
**, int));
59 static void window_scroll
P_ ((Lisp_Object
, int, int, int));
60 static void window_scroll_pixel_based
P_ ((Lisp_Object
, int, int, int));
61 static void window_scroll_line_based
P_ ((Lisp_Object
, int, int, int));
62 static int window_min_size_1
P_ ((struct window
*, int));
63 static int window_min_size
P_ ((struct window
*, int, int, int *));
64 static void size_window
P_ ((Lisp_Object
, int, int, int));
65 static int freeze_window_start
P_ ((struct window
*, void *));
66 static int window_fixed_size_p
P_ ((struct window
*, int, int));
67 static void enlarge_window
P_ ((Lisp_Object
, int, int));
68 static Lisp_Object window_list
P_ ((void));
69 static int add_window_to_list
P_ ((struct window
*, void *));
70 static int candidate_window_p
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
,
72 static Lisp_Object next_window
P_ ((Lisp_Object
, Lisp_Object
,
74 static void decode_next_window_args
P_ ((Lisp_Object
*, Lisp_Object
*,
76 static int foreach_window_1
P_ ((struct window
*,
77 int (* fn
) (struct window
*, void *),
80 /* This is the window in which the terminal's cursor should
81 be left when nothing is being done with it. This must
82 always be a leaf window, and its buffer is selected by
83 the top level editing loop at the end of each command.
85 This value is always the same as
86 FRAME_SELECTED_WINDOW (selected_frame). */
88 Lisp_Object selected_window
;
90 /* A list of all windows for use by next_window and Fwindow_list.
91 Functions creating or deleting windows should invalidate this cache
92 by setting it to nil. */
94 Lisp_Object Vwindow_list
;
96 /* The mini-buffer window of the selected frame.
97 Note that you cannot test for mini-bufferness of an arbitrary window
98 by comparing against this; but you can test for mini-bufferness of
99 the selected window. */
101 Lisp_Object minibuf_window
;
103 /* Non-nil means it is the window for C-M-v to scroll
104 when the mini-buffer is selected. */
106 Lisp_Object Vminibuf_scroll_window
;
108 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
110 Lisp_Object Vother_window_scroll_buffer
;
112 /* Non-nil means it's function to call to display temp buffers. */
114 Lisp_Object Vtemp_buffer_show_function
;
116 /* If a window gets smaller than either of these, it is removed. */
118 int window_min_height
;
119 int window_min_width
;
121 /* Nonzero implies Fdisplay_buffer should create windows. */
125 /* Nonzero implies make new frames for Fdisplay_buffer. */
129 /* Nonzero means reuse existing frames for displaying buffers. */
131 int display_buffer_reuse_frames
;
133 /* Non-nil means use this function instead of default */
135 Lisp_Object Vpop_up_frame_function
;
137 /* Function to call to handle Fdisplay_buffer. */
139 Lisp_Object Vdisplay_buffer_function
;
141 /* List of buffer *names* for buffers that should have their own frames. */
143 Lisp_Object Vspecial_display_buffer_names
;
145 /* List of regexps for buffer names that should have their own frames. */
147 Lisp_Object Vspecial_display_regexps
;
149 /* Function to pop up a special frame. */
151 Lisp_Object Vspecial_display_function
;
153 /* List of buffer *names* for buffers to appear in selected window. */
155 Lisp_Object Vsame_window_buffer_names
;
157 /* List of regexps for buffer names to appear in selected window. */
159 Lisp_Object Vsame_window_regexps
;
161 /* Hook run at end of temp_output_buffer_show. */
163 Lisp_Object Qtemp_buffer_show_hook
;
165 /* Fdisplay_buffer always splits the largest window
166 if that window is more than this high. */
168 int split_height_threshold
;
170 /* Number of lines of continuity in scrolling by screenfuls. */
172 int next_screen_context_lines
;
174 /* Incremented for each window created. */
176 static int sequence_number
;
178 /* Nonzero after init_window_once has finished. */
180 static int window_initialized
;
182 /* Hook to run when window config changes. */
184 Lisp_Object Qwindow_configuration_change_hook
;
185 Lisp_Object Vwindow_configuration_change_hook
;
187 /* Nonzero means scroll commands try to put point
188 at the same screen height as previously. */
190 Lisp_Object Vscroll_preserve_screen_position
;
192 #if 0 /* This isn't used anywhere. */
193 /* Nonzero means we can split a frame even if it is "unsplittable". */
194 static int inhibit_frame_unsplittable
;
197 #define min(a, b) ((a) < (b) ? (a) : (b))
199 extern int scroll_margin
;
201 extern Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
203 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
204 "Returns t if OBJECT is a window.")
208 return WINDOWP (object
) ? Qt
: Qnil
;
211 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
212 "Returns t if OBJECT is a window which is currently visible.")
216 return (WINDOWP (object
) && ! NILP (XWINDOW (object
)->buffer
) ? Qt
: Qnil
);
223 register struct window
*p
;
224 register struct Lisp_Vector
*vec
;
227 vec
= allocate_vectorlike ((EMACS_INT
) VECSIZE (struct window
));
228 for (i
= 0; i
< VECSIZE (struct window
); i
++)
229 vec
->contents
[i
] = Qnil
;
230 vec
->size
= VECSIZE (struct window
);
231 p
= (struct window
*) vec
;
232 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
233 XSETFASTINT (p
->left
, 0);
234 XSETFASTINT (p
->top
, 0);
235 XSETFASTINT (p
->height
, 0);
236 XSETFASTINT (p
->width
, 0);
237 XSETFASTINT (p
->hscroll
, 0);
238 p
->orig_top
= p
->orig_height
= Qnil
;
239 p
->start
= Fmake_marker ();
240 p
->pointm
= Fmake_marker ();
241 XSETFASTINT (p
->use_time
, 0);
243 p
->display_table
= Qnil
;
245 p
->pseudo_window_p
= 0;
246 bzero (&p
->cursor
, sizeof (p
->cursor
));
247 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
248 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
249 p
->desired_matrix
= p
->current_matrix
= 0;
250 p
->phys_cursor_type
= -1;
251 p
->must_be_updated_p
= 0;
252 XSETFASTINT (p
->window_end_vpos
, 0);
253 XSETFASTINT (p
->window_end_pos
, 0);
254 p
->window_end_valid
= Qnil
;
257 XSETFASTINT (p
->last_point
, 0);
258 p
->frozen_window_start_p
= 0;
264 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
265 "Return the window that the cursor now appears in and commands apply to.")
268 return selected_window
;
271 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
272 "Return the window used now for minibuffers.\n\
273 If the optional argument FRAME is specified, return the minibuffer window\n\
274 used by that frame.")
279 frame
= selected_frame
;
280 CHECK_LIVE_FRAME (frame
, 0);
281 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
284 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 0, 1, 0,
285 "Returns non-nil if WINDOW is a minibuffer window.")
289 struct window
*w
= decode_window (window
);
290 return (MINI_WINDOW_P (w
) ? Qt
: Qnil
);
294 /* Return true if POS is fully visible in the window W. If W's end
295 position is not known, then return false. */
298 pos_fully_visible_in_window_p (pos
, w
)
302 struct glyph_row
*first_row
= &w
->desired_matrix
->rows
[0];
303 struct glyph_row
*last_row
;
305 if (pos
< first_row
->start
.pos
.charpos
)
306 /* POS is before the beginning of W. */
308 else if (pos
< first_row
->end
.pos
.charpos
)
309 /* POS is on the first row of W, so see if that row is fully visible. */
310 return !MATRIX_ROW_PARTIALLY_VISIBLE_P (first_row
);
312 if (NILP (w
->window_end_valid
))
313 /* We can't determine where the end is, so we don't know. */
316 last_row
= &w
->desired_matrix
->rows
[XFASTINT (w
->window_end_vpos
)];
318 if (pos
< last_row
->start
.pos
.charpos
)
319 /* POS is somewhere in the middle of the window, not on the first or
320 last row, so it must be visible. */
322 else if (pos
>= last_row
->end
.pos
.charpos
)
323 /* POS is after the end of W. */
326 /* POS is on the last row of W, so see if that row is fully visible. */
327 return !MATRIX_ROW_PARTIALLY_VISIBLE_P (last_row
);
331 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
332 Spos_visible_in_window_p
, 0, 3, 0,
333 "Return t if position POS is currently on the frame in WINDOW.\n\
334 Returns nil if that position is scrolled vertically out of view.\n\
335 If FULLY is non-nil, then only return t when POS is completely visible.\n\
336 POS defaults to point; WINDOW, to the selected window.")
338 Lisp_Object pos
, window
, fully
;
340 register struct window
*w
;
342 register struct buffer
*buf
;
344 Lisp_Object in_window
;
350 CHECK_NUMBER_COERCE_MARKER (pos
, 0);
354 w
= decode_window (window
);
355 buf
= XBUFFER (w
->buffer
);
356 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
358 /* If position above window, it's not visible. */
359 if (posint
< CHARPOS (top
))
361 else if (XFASTINT (w
->last_modified
) >= BUF_MODIFF (buf
)
362 && XFASTINT (w
->last_overlay_modified
) >= BUF_OVERLAY_MODIFF (buf
)
363 && posint
< BUF_Z (buf
) - XFASTINT (w
->window_end_pos
))
364 /* If frame is up to date, and POSINT is < window end pos, use
365 that info. This doesn't work for POSINT == end pos, because
366 the window end pos is actually the position _after_ the last
367 char in the window. */
369 if (NILP (fully
) || pos_fully_visible_in_window_p (posint
, w
))
374 else if (posint
> BUF_ZV (buf
))
376 else if (CHARPOS (top
) < BUF_BEGV (buf
) || CHARPOS (top
) > BUF_ZV (buf
))
377 /* If window start is out of range, do something reasonable. */
382 start_display (&it
, w
, top
);
383 move_it_to (&it
, posint
, 0, it
.last_visible_y
, -1,
384 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
385 if (IT_CHARPOS (it
) == posint
)
391 struct glyph_row
*pos_row
= &w
->desired_matrix
->rows
[it
.vpos
];
392 return MATRIX_ROW_PARTIALLY_VISIBLE_P(pos_row
) ? Qnil
: Qt
;
402 static struct window
*
403 decode_window (window
)
404 register Lisp_Object window
;
407 return XWINDOW (selected_window
);
409 CHECK_LIVE_WINDOW (window
, 0);
410 return XWINDOW (window
);
413 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
414 "Return the buffer that WINDOW is displaying.")
418 return decode_window (window
)->buffer
;
421 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
422 "Return the number of lines in WINDOW (including its mode line).")
426 return decode_window (window
)->height
;
429 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
430 "Return the number of display columns in WINDOW.\n\
431 This is the width that is usable columns available for text in WINDOW.\n\
432 If you want to find out how many columns WINDOW takes up,\n\
433 use (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))).")
437 return make_number (window_internal_width (decode_window (window
)));
440 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
441 "Return the number of columns by which WINDOW is scrolled from left margin.")
445 return decode_window (window
)->hscroll
;
448 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
449 "Set number of columns WINDOW is scrolled from left margin to NCOL.\n\
450 NCOL should be zero or positive.")
452 register Lisp_Object window
, ncol
;
454 register struct window
*w
;
456 CHECK_NUMBER (ncol
, 1);
457 if (XINT (ncol
) < 0) XSETFASTINT (ncol
, 0);
458 w
= decode_window (window
);
459 if (XINT (w
->hscroll
) != XINT (ncol
))
460 /* Prevent redisplay shortcuts */
461 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
466 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
467 Swindow_redisplay_end_trigger
, 0, 1, 0,
468 "Return WINDOW's redisplay end trigger value.\n\
469 See `set-window-redisplay-end-trigger' for more information.")
473 return decode_window (window
)->redisplay_end_trigger
;
476 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
477 Sset_window_redisplay_end_trigger
, 2, 2, 0,
478 "Set WINDOW's redisplay end trigger value to VALUE.\n\
479 VALUE should be a buffer position (typically a marker) or nil.\n\
480 If it is a buffer position, then if redisplay in WINDOW reaches a position\n\
481 beyond VALUE, the functions in `redisplay-end-trigger-functions' are called\n\
482 with two arguments: WINDOW, and the end trigger value.\n\
483 Afterwards the end-trigger value is reset to nil.")
485 register Lisp_Object window
, value
;
487 register struct window
*w
;
489 w
= decode_window (window
);
490 w
->redisplay_end_trigger
= value
;
494 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
495 "Return a list of the edge coordinates of WINDOW.\n\
496 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.\n\
497 RIGHT is one more than the rightmost column used by WINDOW,\n\
498 and BOTTOM is one more than the bottommost row used by WINDOW\n\
503 register struct window
*w
= decode_window (window
);
505 return Fcons (w
->left
, Fcons (w
->top
,
506 Fcons (make_number (WINDOW_RIGHT_EDGE (w
)),
507 Fcons (make_number (XFASTINT (w
->top
)
508 + XFASTINT (w
->height
)),
512 /* Test if the character at column *X, row *Y is within window W.
513 If it is not, return 0;
514 if it is in the window's text area,
515 set *x and *y to its location relative to the upper left corner
518 if it is on the window's modeline, return 2;
519 if it is on the border between the window and its right sibling,
521 if it is on the window's top line, return 4;
522 if it is in the bitmap area to the left/right of the window,
523 return 5 or 6, and convert *X and *Y to window-relative corrdinates.
525 X and Y are frame relative pixel coordinates. */
528 coordinates_in_window (w
, x
, y
)
529 register struct window
*w
;
532 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
533 int left_x
, right_x
, top_y
, bottom_y
;
534 int flags_area_width
= FRAME_LEFT_FLAGS_AREA_WIDTH (f
);
536 /* In what's below, we subtract 1 when computing right_x because we
537 want the rightmost pixel, which is given by left_pixel+width-1. */
538 if (w
->pseudo_window_p
)
541 right_x
= XFASTINT (w
->width
) * CANON_Y_UNIT (f
) - 1;
542 top_y
= WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
);
543 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
547 left_x
= (WINDOW_DISPLAY_LEFT_EDGE_PIXEL_X (w
)
548 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
549 right_x
= WINDOW_DISPLAY_RIGHT_EDGE_PIXEL_X (w
) - 1;
550 top_y
= (WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
)
551 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
552 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
559 - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
)
561 || *x
> right_x
+ flags_area_width
)
562 /* Completely outside anything interesting. */
564 else if (WINDOW_WANTS_MODELINE_P (w
)
565 && *y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
))
566 /* On the mode line. */
568 else if (WINDOW_WANTS_HEADER_LINE_P (w
)
569 && *y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
))
570 /* On the top line. */
572 /* Need to say "*x > right_x" rather than >=, since on character
573 terminals, the vertical line's x coordinate is right_x. */
574 else if (*x
< left_x
|| *x
> right_x
)
576 /* Other lines than the mode line don't include flags areas and
577 scroll bars on the left. */
579 /* Convert X and Y to window-relative pixel coordinates. */
582 return *x
< left_x
? 5 : 6;
584 /* Here, too, "*x > right_x" is because of character terminals. */
585 else if (!w
->pseudo_window_p
586 && !WINDOW_RIGHTMOST_P (w
)
587 && *x
> right_x
- CANON_X_UNIT (f
))
588 /* On the border on the right side of the window? Assume that
589 this area begins at RIGHT_X minus a canonical char width. */
593 /* Convert X and Y to window-relative pixel coordinates. */
600 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
601 Scoordinates_in_window_p
, 2, 2, 0,
602 "Return non-nil if COORDINATES are in WINDOW.\n\
603 COORDINATES is a cons of the form (X . Y), X and Y being distances\n\
604 measured in characters from the upper-left corner of the frame.\n\
605 (0 . 0) denotes the character in the upper left corner of the\n\
607 If COORDINATES are in the text portion of WINDOW,\n\
608 the coordinates relative to the window are returned.\n\
609 If they are in the mode line of WINDOW, `mode-line' is returned.\n\
610 If they are in the top mode line of WINDOW, `header-line' is returned.\n\
611 If they are in the bitmap-area to the left of the window,\n\
612 `left-bitmap-area' is returned, if they are in the area on the right of\n\
613 the window, `right-bitmap-area' is returned.\n\
614 If they are on the border between WINDOW and its right sibling,\n\
615 `vertical-line' is returned.")
616 (coordinates
, window
)
617 register Lisp_Object coordinates
, window
;
624 CHECK_LIVE_WINDOW (window
, 0);
625 w
= XWINDOW (window
);
626 f
= XFRAME (w
->frame
);
627 CHECK_CONS (coordinates
, 1);
628 lx
= Fcar (coordinates
);
629 ly
= Fcdr (coordinates
);
630 CHECK_NUMBER_OR_FLOAT (lx
, 1);
631 CHECK_NUMBER_OR_FLOAT (ly
, 1);
632 x
= PIXEL_X_FROM_CANON_X (f
, lx
);
633 y
= PIXEL_Y_FROM_CANON_Y (f
, ly
);
635 switch (coordinates_in_window (w
, &x
, &y
))
637 case 0: /* NOT in window at all. */
640 case 1: /* In text part of window. */
641 /* X and Y are now window relative pixel coordinates.
642 Convert them to canonical char units before returning
644 return Fcons (CANON_X_FROM_PIXEL_X (f
, x
),
645 CANON_Y_FROM_PIXEL_Y (f
, y
));
647 case 2: /* In mode line of window. */
650 case 3: /* On right border of window. */
651 return Qvertical_line
;
657 return Qleft_bitmap_area
;
660 return Qright_bitmap_area
;
668 /* Callback for foreach_window, used in window_from_coordinates.
669 Check if window W contains coordinates specified by USER_DATA which
670 is actually a pointer to a struct check_window_data CW.
672 Check if window W contains coordinates *CW->x and *CW->y. If it
673 does, return W in *CW->window, as Lisp_Object, and return in
674 *CW->part the part of the window under coordinates *X,*Y. Return
675 zero from this function to stop iterating over windows. */
677 struct check_window_data
684 check_window_containing (w
, user_data
)
688 struct check_window_data
*cw
= (struct check_window_data
*) user_data
;
691 found
= coordinates_in_window (w
, cw
->x
, cw
->y
);
694 *cw
->part
= found
- 1;
695 XSETWINDOW (*cw
->window
, w
);
702 /* Find the window containing frame-relative pixel position X/Y and
703 return it as a Lisp_Object. If X, Y is on the window's modeline,
704 set *PART to 1; if it is on the separating line between the window
705 and its right sibling, set it to 2; otherwise set it to 0. If
706 there is no window under X, Y return nil and leave *PART
707 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows.
709 This function was previously implemented with a loop cycling over
710 windows with Fnext_window, and starting with the frame's selected
711 window. It turned out that this doesn't work with an
712 implementation of next_window using Vwindow_list, because
713 FRAME_SELECTED_WINDOW (F) is not always contained in the window
714 tree of F when this function is called asynchronously from
715 note_mouse_highlight. The original loop didn't terminate in this
719 window_from_coordinates (f
, x
, y
, part
, tool_bar_p
)
726 struct check_window_data cw
;
729 cw
.window
= &window
, cw
.x
= &x
, cw
.y
= &y
; cw
.part
= part
;
730 foreach_window (f
, check_window_containing
, &cw
);
732 /* If not found above, see if it's in the tool bar window, if a tool
736 && WINDOWP (f
->tool_bar_window
)
737 && XINT (XWINDOW (f
->tool_bar_window
)->height
) > 0
738 && coordinates_in_window (XWINDOW (f
->tool_bar_window
), &x
, &y
))
741 window
= f
->tool_bar_window
;
747 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
748 "Return window containing coordinates X and Y on FRAME.\n\
749 If omitted, FRAME defaults to the currently selected frame.\n\
750 The top left corner of the frame is considered to be row 0,\n\
753 Lisp_Object x
, y
, frame
;
759 frame
= selected_frame
;
760 CHECK_LIVE_FRAME (frame
, 2);
763 /* Check that arguments are integers or floats. */
764 CHECK_NUMBER_OR_FLOAT (x
, 0);
765 CHECK_NUMBER_OR_FLOAT (y
, 1);
767 return window_from_coordinates (f
,
768 PIXEL_X_FROM_CANON_X (f
, x
),
769 PIXEL_Y_FROM_CANON_Y (f
, y
),
773 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
774 "Return current value of point in WINDOW.\n\
775 For a nonselected window, this is the value point would have\n\
776 if that window were selected.\n\
778 Note that, when WINDOW is the selected window and its buffer\n\
779 is also currently selected, the value returned is the same as (point).\n\
780 It would be more strictly correct to return the `top-level' value\n\
781 of point, outside of any save-excursion forms.\n\
782 But that is hard to define.")
786 register struct window
*w
= decode_window (window
);
788 if (w
== XWINDOW (selected_window
)
789 && current_buffer
== XBUFFER (w
->buffer
))
791 return Fmarker_position (w
->pointm
);
794 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
795 "Return position at which display currently starts in WINDOW.\n\
796 This is updated by redisplay or by calling `set-window-start'.")
800 return Fmarker_position (decode_window (window
)->start
);
803 /* This is text temporarily removed from the doc string below.
805 This function returns nil if the position is not currently known.\n\
806 That happens when redisplay is preempted and doesn't finish.\n\
807 If in that case you want to compute where the end of the window would\n\
808 have been if redisplay had finished, do this:\n\
810 (goto-char (window-start window))\n\
811 (vertical-motion (1- (window-height window)) window)\n\
814 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
815 "Return position at which display currently ends in WINDOW.\n\
816 This is updated by redisplay, when it runs to completion.\n\
817 Simply changing the buffer text or setting `window-start'\n\
818 does not update this value.\n\
819 If UP-TO-DATE is non-nil, compute the up-to-date position\n\
820 if it isn't already recorded.")
822 Lisp_Object window
, update
;
825 struct window
*w
= decode_window (window
);
829 CHECK_BUFFER (buf
, 0);
831 #if 0 /* This change broke some things. We should make it later. */
832 /* If we don't know the end position, return nil.
833 The user can compute it with vertical-motion if he wants to.
834 It would be nicer to do it automatically,
835 but that's so slow that it would probably bother people. */
836 if (NILP (w
->window_end_valid
))
841 && ! (! NILP (w
->window_end_valid
)
842 && XFASTINT (w
->last_modified
) >= MODIFF
))
844 struct text_pos startp
;
847 /* In case W->start is out of the range, use something
848 reasonable. This situation occured when loading a file with
849 `-l' containing a call to `rmail' with subsequent other
850 commands. At the end, W->start happened to be BEG, while
851 rmail had already narrowed the buffer. */
852 if (XMARKER (w
->start
)->charpos
< BEGV
)
853 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
854 else if (XMARKER (w
->start
)->charpos
> ZV
)
855 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
857 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
859 /* Cannot use Fvertical_motion because that function doesn't
860 cope with variable-height lines. */
861 start_display (&it
, w
, startp
);
862 move_it_vertically (&it
, window_box_height (w
));
863 value
= make_number (IT_CHARPOS (it
));
866 XSETINT (value
, BUF_Z (XBUFFER (buf
)) - XFASTINT (w
->window_end_pos
));
871 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
872 "Make point value in WINDOW be at position POS in WINDOW's buffer.")
874 Lisp_Object window
, pos
;
876 register struct window
*w
= decode_window (window
);
878 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
879 if (w
== XWINDOW (selected_window
)
880 && XBUFFER (w
->buffer
) == current_buffer
)
883 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
888 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
889 "Make display in WINDOW start at position POS in WINDOW's buffer.\n\
890 Optional third arg NOFORCE non-nil inhibits next redisplay\n\
891 from overriding motion of point in order to display at this exact start.")
892 (window
, pos
, noforce
)
893 Lisp_Object window
, pos
, noforce
;
895 register struct window
*w
= decode_window (window
);
897 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
898 set_marker_restricted (w
->start
, pos
, w
->buffer
);
899 /* this is not right, but much easier than doing what is right. */
900 w
->start_at_line_beg
= Qnil
;
903 w
->update_mode_line
= Qt
;
904 XSETFASTINT (w
->last_modified
, 0);
905 XSETFASTINT (w
->last_overlay_modified
, 0);
906 if (!EQ (window
, selected_window
))
907 windows_or_buffers_changed
++;
912 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
914 "Return WINDOW's dedicated object, usually t or nil.\n\
915 See also `set-window-dedicated-p'.")
919 return decode_window (window
)->dedicated
;
922 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
923 Sset_window_dedicated_p
, 2, 2, 0,
924 "Control whether WINDOW is dedicated to the buffer it displays.\n\
925 If it is dedicated, Emacs will not automatically change\n\
926 which buffer appears in it.\n\
927 The second argument is the new value for the dedication flag;\n\
930 Lisp_Object window
, arg
;
932 register struct window
*w
= decode_window (window
);
942 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
944 "Return the display-table that WINDOW is using.")
948 return decode_window (window
)->display_table
;
951 /* Get the display table for use on window W. This is either W's
952 display table or W's buffer's display table. Ignore the specified
953 tables if they are not valid; if no valid table is specified,
956 struct Lisp_Char_Table
*
957 window_display_table (w
)
960 struct Lisp_Char_Table
*dp
= NULL
;
962 if (DISP_TABLE_P (w
->display_table
))
963 dp
= XCHAR_TABLE (w
->display_table
);
964 else if (BUFFERP (w
->buffer
))
966 struct buffer
*b
= XBUFFER (w
->buffer
);
968 if (DISP_TABLE_P (b
->display_table
))
969 dp
= XCHAR_TABLE (b
->display_table
);
970 else if (DISP_TABLE_P (Vstandard_display_table
))
971 dp
= XCHAR_TABLE (Vstandard_display_table
);
977 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
978 "Set WINDOW's display-table to TABLE.")
980 register Lisp_Object window
, table
;
982 register struct window
*w
;
984 w
= decode_window (window
);
985 w
->display_table
= table
;
989 /* Record info on buffer window w is displaying
990 when it is about to cease to display that buffer. */
993 register struct window
*w
;
1000 if (b
!= XMARKER (w
->pointm
)->buffer
)
1004 if (w
== XWINDOW (selected_window
)
1005 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
1006 /* Do this except when the selected window's buffer
1007 is being removed from some other window. */
1009 /* last_window_start records the start position that this buffer
1010 had in the last window to be disconnected from it.
1011 Now that this statement is unconditional,
1012 it is possible for the buffer to be displayed in the
1013 selected window, while last_window_start reflects another
1014 window which was recently showing the same buffer.
1015 Some people might say that might be a good thing. Let's see. */
1016 b
->last_window_start
= marker_position (w
->start
);
1018 /* Point in the selected window's buffer
1019 is actually stored in that buffer, and the window's pointm isn't used.
1020 So don't clobber point in that buffer. */
1021 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
)
1022 /* This line helps to fix Horsley's testbug.el bug. */
1023 && !(WINDOWP (b
->last_selected_window
)
1024 && w
!= XWINDOW (b
->last_selected_window
)
1025 && EQ (buf
, XWINDOW (b
->last_selected_window
)->buffer
)))
1026 temp_set_point_both (b
,
1027 clip_to_bounds (BUF_BEGV (b
),
1028 XMARKER (w
->pointm
)->charpos
,
1030 clip_to_bounds (BUF_BEGV_BYTE (b
),
1031 marker_byte_position (w
->pointm
),
1034 if (WINDOWP (b
->last_selected_window
)
1035 && w
== XWINDOW (b
->last_selected_window
))
1036 b
->last_selected_window
= Qnil
;
1039 /* Put replacement into the window structure in place of old. */
1041 replace_window (old
, replacement
)
1042 Lisp_Object old
, replacement
;
1044 register Lisp_Object tem
;
1045 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
1047 /* If OLD is its frame's root_window, then replacement is the new
1048 root_window for that frame. */
1050 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
1051 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
1055 p
->width
= o
->width
;
1056 p
->height
= o
->height
;
1057 p
->desired_matrix
= p
->current_matrix
= 0;
1059 bzero (&p
->cursor
, sizeof (p
->cursor
));
1060 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
1061 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
1062 p
->phys_cursor_type
= -1;
1063 p
->must_be_updated_p
= 0;
1064 p
->pseudo_window_p
= 0;
1065 XSETFASTINT (p
->window_end_vpos
, 0);
1066 XSETFASTINT (p
->window_end_pos
, 0);
1067 p
->window_end_valid
= Qnil
;
1068 p
->frozen_window_start_p
= 0;
1069 p
->orig_top
= p
->orig_height
= Qnil
;
1071 p
->next
= tem
= o
->next
;
1073 XWINDOW (tem
)->prev
= replacement
;
1075 p
->prev
= tem
= o
->prev
;
1077 XWINDOW (tem
)->next
= replacement
;
1079 p
->parent
= tem
= o
->parent
;
1082 if (EQ (XWINDOW (tem
)->vchild
, old
))
1083 XWINDOW (tem
)->vchild
= replacement
;
1084 if (EQ (XWINDOW (tem
)->hchild
, old
))
1085 XWINDOW (tem
)->hchild
= replacement
;
1088 /*** Here, if replacement is a vertical combination
1089 and so is its new parent, we should make replacement's
1090 children be children of that parent instead. ***/
1093 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
1094 "Remove WINDOW from the display. Default is selected window.")
1096 register Lisp_Object window
;
1098 delete_window (window
);
1100 if (! NILP (Vwindow_configuration_change_hook
)
1101 && ! NILP (Vrun_hooks
))
1102 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
1108 delete_window (window
)
1109 register Lisp_Object window
;
1111 register Lisp_Object tem
, parent
, sib
;
1112 register struct window
*p
;
1113 register struct window
*par
;
1116 /* Because this function is called by other C code on non-leaf
1117 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1118 so we can't decode_window here. */
1120 window
= selected_window
;
1122 CHECK_WINDOW (window
, 0);
1123 p
= XWINDOW (window
);
1125 /* It's okay to delete an already-deleted window. */
1126 if (NILP (p
->buffer
)
1128 && NILP (p
->vchild
))
1133 error ("Attempt to delete minibuffer or sole ordinary window");
1134 par
= XWINDOW (parent
);
1136 windows_or_buffers_changed
++;
1137 Vwindow_list
= Qnil
;
1138 frame
= XFRAME (WINDOW_FRAME (p
));
1139 FRAME_WINDOW_SIZES_CHANGED (frame
) = 1;
1141 /* Are we trying to delete any frame's selected window? */
1143 Lisp_Object frame
, pwindow
;
1145 /* See if the frame's selected window is either WINDOW
1146 or any subwindow of it, by finding all that window's parents
1147 and comparing each one with WINDOW. */
1148 frame
= WINDOW_FRAME (XWINDOW (window
));
1149 pwindow
= FRAME_SELECTED_WINDOW (XFRAME (frame
));
1151 while (!NILP (pwindow
))
1153 if (EQ (window
, pwindow
))
1155 pwindow
= XWINDOW (pwindow
)->parent
;
1158 if (EQ (window
, pwindow
))
1160 Lisp_Object alternative
;
1161 alternative
= Fnext_window (window
, Qlambda
, Qnil
);
1163 /* If we're about to delete the selected window on the
1164 selected frame, then we should use Fselect_window to select
1165 the new window. On the other hand, if we're about to
1166 delete the selected window on any other frame, we shouldn't do
1167 anything but set the frame's selected_window slot. */
1168 if (EQ (window
, selected_window
))
1169 Fselect_window (alternative
);
1171 FRAME_SELECTED_WINDOW (XFRAME (frame
)) = alternative
;
1176 /* tem is null for dummy parent windows
1177 (which have inferiors but not any contents themselves) */
1181 unchain_marker (p
->pointm
);
1182 unchain_marker (p
->start
);
1185 /* Free window glyph matrices. It is sure that they are allocated
1186 again when ADJUST_GLYPHS is called. Block input so that expose
1187 events and other events that access glyph matrices are not
1188 processed while we are changing them. */
1190 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (frame
)));
1194 XWINDOW (tem
)->prev
= p
->prev
;
1198 XWINDOW (tem
)->next
= p
->next
;
1200 if (EQ (window
, par
->hchild
))
1201 par
->hchild
= p
->next
;
1202 if (EQ (window
, par
->vchild
))
1203 par
->vchild
= p
->next
;
1205 /* Find one of our siblings to give our space to. */
1209 /* If p gives its space to its next sibling, that sibling needs
1210 to have its top/left side pulled back to where p's is.
1211 set_window_{height,width} will re-position the sibling's
1214 XWINDOW (sib
)->top
= p
->top
;
1215 XWINDOW (sib
)->left
= p
->left
;
1218 /* Stretch that sibling. */
1219 if (!NILP (par
->vchild
))
1220 set_window_height (sib
,
1221 XFASTINT (XWINDOW (sib
)->height
) + XFASTINT (p
->height
),
1223 if (!NILP (par
->hchild
))
1224 set_window_width (sib
,
1225 XFASTINT (XWINDOW (sib
)->width
) + XFASTINT (p
->width
),
1228 /* If parent now has only one child,
1229 put the child into the parent's place. */
1233 if (NILP (XWINDOW (tem
)->next
))
1234 replace_window (parent
, tem
);
1236 /* Since we may be deleting combination windows, we must make sure that
1237 not only p but all its children have been marked as deleted. */
1238 if (! NILP (p
->hchild
))
1239 delete_all_subwindows (XWINDOW (p
->hchild
));
1240 else if (! NILP (p
->vchild
))
1241 delete_all_subwindows (XWINDOW (p
->vchild
));
1243 /* Mark this window as deleted. */
1244 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
1246 /* Adjust glyph matrices. */
1247 adjust_glyphs (frame
);
1253 /***********************************************************************
1255 ***********************************************************************/
1257 /* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object
1258 pointer. This is a callback function for foreach_window, used in
1259 function window_list. */
1262 add_window_to_list (w
, user_data
)
1266 Lisp_Object
*list
= (Lisp_Object
*) user_data
;
1268 XSETWINDOW (window
, w
);
1269 *list
= Fcons (window
, *list
);
1274 /* Return a list of all windows, for use by next_window. If
1275 Vwindow_list is a list, return that list. Otherwise, build a new
1276 list, cache it in Vwindow_list, and return that. */
1281 if (!CONSP (Vwindow_list
))
1285 Vwindow_list
= Qnil
;
1286 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
1288 Lisp_Object args
[2];
1290 /* We are visiting windows in canonical order, and add
1291 new windows at the front of args[1], which means we
1292 have to reverse this list at the end. */
1294 foreach_window (XFRAME (XCAR (tail
)), add_window_to_list
, &args
[1]);
1295 args
[0] = Vwindow_list
;
1296 args
[1] = Fnreverse (args
[1]);
1297 Vwindow_list
= Fnconc (2, args
);
1301 return Vwindow_list
;
1305 /* Value is non-zero if WINDOW satisfies the constraints given by
1306 OWINDOW, MINIBUF and ALL_FRAMES.
1308 MINIBUF t means WINDOW may be minibuffer windows.
1309 `lambda' means WINDOW may not be a minibuffer window.
1310 a window means a specific minibuffer window
1312 ALL_FRAMES t means search all frames,
1313 nil means search just current frame,
1314 `visible' means search just visible frames,
1315 0 means search visible and iconified frames,
1316 a window means search the frame that window belongs to,
1317 a frame means consider windows on that frame, only. */
1320 candidate_window_p (window
, owindow
, minibuf
, all_frames
)
1321 Lisp_Object window
, owindow
, minibuf
, all_frames
;
1323 struct window
*w
= XWINDOW (window
);
1324 struct frame
*f
= XFRAME (w
->frame
);
1325 int candidate_p
= 1;
1327 if (!BUFFERP (w
->buffer
))
1329 else if (MINI_WINDOW_P (w
)
1330 && (EQ (minibuf
, Qlambda
)
1331 || (WINDOWP (minibuf
) && !EQ (minibuf
, window
))))
1333 /* If MINIBUF is `lambda' don't consider any mini-windows.
1334 If it is a window, consider only that one. */
1337 else if (EQ (all_frames
, Qt
))
1339 else if (NILP (all_frames
))
1341 xassert (WINDOWP (owindow
));
1342 candidate_p
= EQ (w
->frame
, XWINDOW (owindow
)->frame
);
1344 else if (EQ (all_frames
, Qvisible
))
1346 FRAME_SAMPLE_VISIBILITY (f
);
1347 candidate_p
= FRAME_VISIBLE_P (f
);
1349 else if (INTEGERP (all_frames
) && XINT (all_frames
) == 0)
1351 FRAME_SAMPLE_VISIBILITY (f
);
1352 candidate_p
= FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
);
1354 else if (WINDOWP (all_frames
))
1355 candidate_p
= (EQ (FRAME_MINIBUF_WINDOW (f
), all_frames
)
1356 || EQ (XWINDOW (all_frames
)->frame
, w
->frame
)
1357 || EQ (XWINDOW (all_frames
)->frame
, FRAME_FOCUS_FRAME (f
)));
1358 else if (FRAMEP (all_frames
))
1359 candidate_p
= EQ (all_frames
, w
->frame
);
1365 /* Decode arguments as allowed by Fnext_window, Fprevious_window, and
1366 Fwindow_list. See there for the meaning of WINDOW, MINIBUF, and
1370 decode_next_window_args (window
, minibuf
, all_frames
)
1371 Lisp_Object
*window
, *minibuf
, *all_frames
;
1374 *window
= selected_window
;
1376 CHECK_LIVE_WINDOW (*window
, 0);
1378 /* MINIBUF nil may or may not include minibuffers. Decide if it
1380 if (NILP (*minibuf
))
1381 *minibuf
= minibuf_level
? minibuf_window
: Qlambda
;
1382 else if (!EQ (*minibuf
, Qt
))
1385 /* Now *MINIBUF can be t => count all minibuffer windows, `lambda'
1386 => count none of them, or a specific minibuffer window (the
1387 active one) to count. */
1389 /* ALL_FRAMES nil doesn't specify which frames to include. */
1390 if (NILP (*all_frames
))
1391 *all_frames
= (!EQ (*minibuf
, Qlambda
)
1392 ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window
)->frame
))
1394 else if (EQ (*all_frames
, Qvisible
))
1396 else if (XFASTINT (*all_frames
) == 0)
1398 else if (FRAMEP (*all_frames
))
1400 else if (!EQ (*all_frames
, Qt
))
1403 /* Now *ALL_FRAMES is t meaning search all frames, nil meaning
1404 search just current frame, `visible' meaning search just visible
1405 frames, 0 meaning search visible and iconified frames, or a
1406 window, meaning search the frame that window belongs to, or a
1407 frame, meaning consider windows on that frame, only. */
1411 /* Return the next or previous window of WINDOW in canonical ordering
1412 of windows. NEXT_P non-zero means return the next window. See the
1413 documentation string of next-window for the meaning of MINIBUF and
1417 next_window (window
, minibuf
, all_frames
, next_p
)
1418 Lisp_Object window
, minibuf
, all_frames
;
1421 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1423 /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just
1424 return the first window on the frame. */
1425 if (FRAMEP (all_frames
)
1426 && !EQ (all_frames
, XWINDOW (window
)->frame
))
1427 return Fframe_first_window (all_frames
);
1433 /* Find WINDOW in the list of all windows. */
1434 list
= Fmemq (window
, window_list ());
1436 /* Scan forward from WINDOW to the end of the window list. */
1438 for (list
= XCDR (list
); CONSP (list
); list
= XCDR (list
))
1439 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1442 /* Scan from the start of the window list up to WINDOW. */
1444 for (list
= Vwindow_list
;
1445 CONSP (list
) && !EQ (XCAR (list
), window
);
1447 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1451 window
= XCAR (list
);
1455 Lisp_Object candidate
, list
;
1457 /* Scan through the list of windows for candidates. If there are
1458 candidate windows in front of WINDOW, the last one of these
1459 is the one we want. If there are candidates following WINDOW
1460 in the list, again the last one of these is the one we want. */
1462 for (list
= window_list (); CONSP (list
); list
= XCDR (list
))
1464 if (EQ (XCAR (list
), window
))
1466 if (WINDOWP (candidate
))
1469 else if (candidate_window_p (XCAR (list
), window
, minibuf
,
1471 candidate
= XCAR (list
);
1474 if (WINDOWP (candidate
))
1482 /* This comment supplies the doc string for `next-window',
1483 for make-docfile to see. We cannot put this in the real DEFUN
1484 due to limits in the Unix cpp.
1486 DEFUN ("next-window", Ffoo, Sfoo, 0, 3, 0,
1487 "Return next window after WINDOW in canonical ordering of windows.\n\
1488 If omitted, WINDOW defaults to the selected window.\n\
1490 Optional second arg MINIBUF t means count the minibuffer window even\n\
1491 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1492 it is active. MINIBUF neither t nor nil means not to count the\n\
1493 minibuffer even if it is active.\n\
1495 Several frames may share a single minibuffer; if the minibuffer\n\
1496 counts, all windows on all frames that share that minibuffer count\n\
1497 too. Therefore, `next-window' can be used to iterate through the\n\
1498 set of windows even when the minibuffer is on another frame. If the\n\
1499 minibuffer does not count, only windows from WINDOW's frame count.\n\
1501 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1502 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1503 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1504 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1505 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1506 Anything else means restrict to WINDOW's frame.\n\
1508 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1509 `next-window' to iterate through the entire cycle of acceptable\n\
1510 windows, eventually ending up back at the window you started with.\n\
1511 `previous-window' traverses the same cycle, in the reverse order.")
1512 (window, minibuf, all_frames) */
1514 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
1516 (window
, minibuf
, all_frames
)
1517 Lisp_Object window
, minibuf
, all_frames
;
1519 return next_window (window
, minibuf
, all_frames
, 1);
1523 /* This comment supplies the doc string for `previous-window',
1524 for make-docfile to see. We cannot put this in the real DEFUN
1525 due to limits in the Unix cpp.
1527 DEFUN ("previous-window", Ffoo, Sfoo, 0, 3, 0,
1528 "Return the window preceding WINDOW in canonical ordering of windows.\n\
1529 If omitted, WINDOW defaults to the selected window.\n\
1531 Optional second arg MINIBUF t means count the minibuffer window even\n\
1532 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1533 it is active. MINIBUF neither t nor nil means not to count the\n\
1534 minibuffer even if it is active.\n\
1536 Several frames may share a single minibuffer; if the minibuffer\n\
1537 counts, all windows on all frames that share that minibuffer count\n\
1538 too. Therefore, `previous-window' can be used to iterate through\n\
1539 the set of windows even when the minibuffer is on another frame. If\n\
1540 the minibuffer does not count, only windows from WINDOW's frame count\n\
1542 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1543 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1544 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1545 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1546 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1547 Anything else means restrict to WINDOW's frame.\n\
1549 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1550 `previous-window' to iterate through the entire cycle of acceptable\n\
1551 windows, eventually ending up back at the window you started with.\n\
1552 `next-window' traverses the same cycle, in the reverse order.")
1553 (window, minibuf, all_frames) */
1556 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
1558 (window
, minibuf
, all_frames
)
1559 Lisp_Object window
, minibuf
, all_frames
;
1561 return next_window (window
, minibuf
, all_frames
, 0);
1565 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1566 "Select the ARG'th different window on this frame.\n\
1567 All windows on current frame are arranged in a cyclic order.\n\
1568 This command selects the window ARG steps away in that order.\n\
1569 A negative ARG moves in the opposite order. If the optional second\n\
1570 argument ALL_FRAMES is non-nil, cycle through all frames.")
1572 Lisp_Object arg
, all_frames
;
1577 CHECK_NUMBER (arg
, 0);
1578 window
= selected_window
;
1580 for (i
= XINT (arg
); i
> 0; --i
)
1581 window
= Fnext_window (window
, Qnil
, all_frames
);
1583 window
= Fprevious_window (window
, Qnil
, all_frames
);
1585 Fselect_window (window
);
1590 DEFUN ("window-list", Fwindow_list
, Swindow_list
, 0, 3, 0,
1591 "Return a list of windows in canonical ordering.\n\
1592 Arguments are like for `next-window'.")
1593 (window
, minibuf
, all_frames
)
1594 Lisp_Object window
, minibuf
, all_frames
;
1596 Lisp_Object tail
, list
;
1598 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1601 for (tail
= window_list (); CONSP (tail
); tail
= XCDR (tail
))
1602 if (candidate_window_p (XCAR (tail
), window
, minibuf
, all_frames
))
1603 list
= Fcons (XCAR (tail
), list
);
1605 return Fnreverse (list
);
1610 /* Look at all windows, performing an operation specified by TYPE
1612 If FRAMES is Qt, look at all frames;
1613 Qnil, look at just the selected frame;
1614 Qvisible, look at visible frames;
1615 a frame, just look at windows on that frame.
1616 If MINI is non-zero, perform the operation on minibuffer windows too.
1622 GET_BUFFER_WINDOW
, /* Arg is buffer */
1623 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1624 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1625 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1627 UNSHOW_BUFFER
, /* Arg is buffer */
1632 window_loop (type
, obj
, mini
, frames
)
1633 enum window_loop type
;
1634 Lisp_Object obj
, frames
;
1637 Lisp_Object window
, windows
, best_window
, frame_arg
;
1639 struct gcpro gcpro1
;
1641 /* If we're only looping through windows on a particular frame,
1642 frame points to that frame. If we're looping through windows
1643 on all frames, frame is 0. */
1644 if (FRAMEP (frames
))
1645 f
= XFRAME (frames
);
1646 else if (NILP (frames
))
1647 f
= SELECTED_FRAME ();
1652 frame_arg
= Qlambda
;
1653 else if (XFASTINT (frames
) == 0)
1655 else if (EQ (frames
, Qvisible
))
1660 /* frame_arg is Qlambda to stick to one frame,
1661 Qvisible to consider all visible frames,
1664 /* Pick a window to start with. */
1668 window
= FRAME_SELECTED_WINDOW (f
);
1670 window
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
1672 /* Figure out the last window we're going to mess with. Since
1673 Fnext_window, given the same options, is guaranteed to go in a
1674 ring, we can just use Fprevious_window to find the last one.
1676 We can't just wait until we hit the first window again, because
1677 it might be deleted. */
1679 windows
= Fwindow_list (window
, mini
? Qt
: Qnil
, frame_arg
);
1683 for (; CONSP (windows
); windows
= CDR (windows
))
1687 window
= XCAR (windows
);
1688 w
= XWINDOW (window
);
1690 /* Note that we do not pay attention here to whether the frame
1691 is visible, since Fwindow_list skips non-visible frames if
1692 that is desired, under the control of frame_arg. */
1693 if (!MINI_WINDOW_P (w
)
1694 /* For UNSHOW_BUFFER, we must always consider all windows. */
1695 || type
== UNSHOW_BUFFER
1696 || (mini
&& minibuf_level
> 0))
1699 case GET_BUFFER_WINDOW
:
1700 if (EQ (w
->buffer
, obj
)
1701 /* Don't find any minibuffer window
1702 except the one that is currently in use. */
1703 && (MINI_WINDOW_P (w
)
1704 ? EQ (window
, minibuf_window
)
1712 case GET_LRU_WINDOW
:
1713 /* t as arg means consider only full-width windows */
1714 if (!NILP (obj
) && !WINDOW_FULL_WIDTH_P (w
))
1716 /* Ignore dedicated windows and minibuffers. */
1717 if (MINI_WINDOW_P (w
) || !NILP (w
->dedicated
))
1719 if (NILP (best_window
)
1720 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1721 > XFASTINT (w
->use_time
)))
1722 best_window
= window
;
1725 case DELETE_OTHER_WINDOWS
:
1726 if (!EQ (window
, obj
))
1727 Fdelete_window (window
);
1730 case DELETE_BUFFER_WINDOWS
:
1731 if (EQ (w
->buffer
, obj
))
1733 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1735 /* If this window is dedicated, and in a frame of its own,
1737 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
1738 && !NILP (w
->dedicated
)
1739 && other_visible_frames (f
))
1741 /* Skip the other windows on this frame.
1742 There might be one, the minibuffer! */
1743 while (CONSP (XCDR (windows
))
1744 && EQ (XWINDOW (XCAR (windows
))->frame
,
1745 XWINDOW (XCAR (XCDR (windows
)))->frame
))
1746 windows
= XCDR (windows
);
1748 /* Now we can safely delete the frame. */
1749 Fdelete_frame (w
->frame
, Qnil
);
1751 else if (NILP (w
->parent
))
1753 /* If we're deleting the buffer displayed in the
1754 only window on the frame, find a new buffer to
1757 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
1759 buffer
= Fget_buffer_create (build_string ("*scratch*"));
1760 Fset_window_buffer (window
, buffer
);
1761 if (EQ (window
, selected_window
))
1762 Fset_buffer (w
->buffer
);
1765 Fdelete_window (window
);
1769 case GET_LARGEST_WINDOW
:
1771 /* Ignore dedicated windows and minibuffers. */
1772 if (MINI_WINDOW_P (w
) || !NILP (w
->dedicated
))
1775 if (NILP (best_window
))
1776 best_window
= window
;
1779 struct window
*b
= XWINDOW (best_window
);
1780 if (XFASTINT (w
->height
) * XFASTINT (w
->width
)
1781 > XFASTINT (b
->height
) * XFASTINT (b
->width
))
1782 best_window
= window
;
1788 if (EQ (w
->buffer
, obj
))
1791 struct frame
*f
= XFRAME (w
->frame
);
1793 /* Find another buffer to show in this window. */
1794 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
1796 buffer
= Fget_buffer_create (build_string ("*scratch*"));
1798 /* If this window is dedicated, and in a frame of its own,
1800 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
1801 && !NILP (w
->dedicated
)
1802 && other_visible_frames (f
))
1804 /* Skip the other windows on this frame.
1805 There might be one, the minibuffer! */
1806 while (CONSP (XCDR (windows
))
1807 && EQ (XWINDOW (XCAR (windows
))->frame
,
1808 XWINDOW (XCAR (XCDR (windows
)))->frame
))
1809 windows
= XCDR (windows
);
1811 /* Now we can safely delete the frame. */
1812 Fdelete_frame (w
->frame
, Qnil
);
1816 /* Otherwise show a different buffer in the window. */
1817 w
->dedicated
= Qnil
;
1818 Fset_window_buffer (window
, buffer
);
1819 if (EQ (window
, selected_window
))
1820 Fset_buffer (w
->buffer
);
1825 /* Check for a window that has a killed buffer. */
1826 case CHECK_ALL_WINDOWS
:
1827 if (! NILP (w
->buffer
)
1828 && NILP (XBUFFER (w
->buffer
)->name
))
1832 case WINDOW_LOOP_UNUSED
:
1841 /* Used for debugging. Abort if any window has a dead buffer. */
1844 check_all_windows ()
1846 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
1849 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1850 "Return the window least recently selected or used for display.\n\
1851 If optional argument FRAME is `visible', search all visible frames.\n\
1852 If FRAME is 0, search all visible and iconified frames.\n\
1853 If FRAME is t, search all frames.\n\
1854 If FRAME is nil, search only the selected frame.\n\
1855 If FRAME is a frame, search only that frame.")
1859 register Lisp_Object w
;
1860 /* First try for a window that is full-width */
1861 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frame
);
1862 if (!NILP (w
) && !EQ (w
, selected_window
))
1864 /* If none of them, try the rest */
1865 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frame
);
1868 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1869 "Return the largest window in area.\n\
1870 If optional argument FRAME is `visible', search all visible frames.\n\
1871 If FRAME is 0, search all visible and iconified frames.\n\
1872 If FRAME is t, search all frames.\n\
1873 If FRAME is nil, search only the selected frame.\n\
1874 If FRAME is a frame, search only that frame.")
1878 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
1882 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
1883 "Return a window currently displaying BUFFER, or nil if none.\n\
1884 If optional argument FRAME is `visible', search all visible frames.\n\
1885 If optional argument FRAME is 0, search all visible and iconified frames.\n\
1886 If FRAME is t, search all frames.\n\
1887 If FRAME is nil, search only the selected frame.\n\
1888 If FRAME is a frame, search only that frame.")
1890 Lisp_Object buffer
, frame
;
1892 buffer
= Fget_buffer (buffer
);
1893 if (BUFFERP (buffer
))
1894 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
1899 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
1901 "Make WINDOW (or the selected window) fill its frame.\n\
1902 Only the frame WINDOW is on is affected.\n\
1903 This function tries to reduce display jumps\n\
1904 by keeping the text previously visible in WINDOW\n\
1905 in the same place on the frame. Doing this depends on\n\
1906 the value of (window-start WINDOW), so if calling this function\n\
1907 in a program gives strange scrolling, make sure the window-start\n\
1908 value is reasonable when this function is called.")
1917 window
= selected_window
;
1919 CHECK_LIVE_WINDOW (window
, 0);
1921 w
= XWINDOW (window
);
1923 startpos
= marker_position (w
->start
);
1924 top
= XFASTINT (w
->top
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
1926 if (MINI_WINDOW_P (w
) && top
> 0)
1927 error ("Can't expand minibuffer to full frame");
1929 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
1931 /* Try to minimize scrolling, by setting the window start to the point
1932 will cause the text at the old window start to be at the same place
1933 on the frame. But don't try to do this if the window start is
1934 outside the visible portion (as might happen when the display is
1935 not current, due to typeahead). */
1936 if (startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
1937 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
1939 struct position pos
;
1940 struct buffer
*obuf
= current_buffer
;
1942 Fset_buffer (w
->buffer
);
1943 /* This computation used to temporarily move point, but that can
1944 have unwanted side effects due to text properties. */
1945 pos
= *vmotion (startpos
, -top
, w
);
1947 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
1948 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
1949 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
1951 /* We need to do this, so that the window-scroll-functions
1953 w
->optional_new_start
= Qt
;
1955 set_buffer_internal (obuf
);
1961 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
1962 1, 2, "bDelete windows on (buffer): ",
1963 "Delete all windows showing BUFFER.\n\
1964 Optional second argument FRAME controls which frames are affected.\n\
1965 If optional argument FRAME is `visible', search all visible frames.\n\
1966 If FRAME is 0, search all visible and iconified frames.\n\
1967 If FRAME is nil, search all frames.\n\
1968 If FRAME is t, search only the selected frame.\n\
1969 If FRAME is a frame, search only that frame.")
1971 Lisp_Object buffer
, frame
;
1973 /* FRAME uses t and nil to mean the opposite of what window_loop
1977 else if (EQ (frame
, Qt
))
1982 buffer
= Fget_buffer (buffer
);
1983 CHECK_BUFFER (buffer
, 0);
1984 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
1990 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
1991 Sreplace_buffer_in_windows
,
1992 1, 1, "bReplace buffer in windows: ",
1993 "Replace BUFFER with some other buffer in all windows showing it.")
1999 buffer
= Fget_buffer (buffer
);
2000 CHECK_BUFFER (buffer
, 0);
2001 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
2006 /* Replace BUFFER with some other buffer in all windows
2007 of all frames, even those on other keyboards. */
2010 replace_buffer_in_all_windows (buffer
)
2014 Lisp_Object tail
, frame
;
2016 /* A single call to window_loop won't do the job
2017 because it only considers frames on the current keyboard.
2018 So loop manually over frames, and handle each one. */
2019 FOR_EACH_FRAME (tail
, frame
)
2020 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
2022 window_loop (UNSHOW_BUFFER
, buffer
, 1, Qt
);
2026 /* Set the height of WINDOW and all its inferiors. */
2028 /* The smallest acceptable dimensions for a window. Anything smaller
2029 might crash Emacs. */
2031 #define MIN_SAFE_WINDOW_WIDTH (2)
2032 #define MIN_SAFE_WINDOW_HEIGHT (2)
2034 /* Make sure that window_min_height and window_min_width are
2035 not too small; if they are, set them to safe minima. */
2038 check_min_window_sizes ()
2040 /* Smaller values might permit a crash. */
2041 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
2042 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
2043 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
2044 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
2047 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
2048 minimum allowable size. */
2051 check_frame_size (frame
, rows
, cols
)
2055 /* For height, we have to see:
2056 whether the frame has a minibuffer,
2057 whether it wants a mode line, and
2058 whether it has a menu bar. */
2060 (FRAME_MINIBUF_ONLY_P (frame
) ? MIN_SAFE_WINDOW_HEIGHT
- 1
2061 : (! FRAME_HAS_MINIBUF_P (frame
)) ? MIN_SAFE_WINDOW_HEIGHT
2062 : 2 * MIN_SAFE_WINDOW_HEIGHT
- 1);
2064 if (FRAME_TOP_MARGIN (frame
) > 0)
2065 min_height
+= FRAME_TOP_MARGIN (frame
);
2067 if (*rows
< min_height
)
2069 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
2070 *cols
= MIN_SAFE_WINDOW_WIDTH
;
2074 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
2075 check if W's width can be changed, otherwise check W's height.
2076 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
2077 siblings, too. If none of the siblings is resizable, WINDOW isn't
2081 window_fixed_size_p (w
, width_p
, check_siblings_p
)
2083 int width_p
, check_siblings_p
;
2088 if (!NILP (w
->hchild
))
2090 c
= XWINDOW (w
->hchild
);
2094 /* A horiz. combination is fixed-width if all of if its
2096 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2097 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2098 fixed_p
= c
== NULL
;
2102 /* A horiz. combination is fixed-height if one of if its
2104 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2105 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2106 fixed_p
= c
!= NULL
;
2109 else if (!NILP (w
->vchild
))
2111 c
= XWINDOW (w
->vchild
);
2115 /* A vert. combination is fixed-width if one of if its
2117 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2118 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2119 fixed_p
= c
!= NULL
;
2123 /* A vert. combination is fixed-height if all of if its
2125 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2126 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2127 fixed_p
= c
== NULL
;
2130 else if (BUFFERP (w
->buffer
))
2132 if (w
->height_fixed_p
&& !width_p
)
2136 struct buffer
*old
= current_buffer
;
2139 current_buffer
= XBUFFER (w
->buffer
);
2140 val
= find_symbol_value (Qwindow_size_fixed
);
2141 current_buffer
= old
;
2144 if (!EQ (val
, Qunbound
))
2146 fixed_p
= !NILP (val
);
2149 && ((EQ (val
, Qheight
) && width_p
)
2150 || (EQ (val
, Qwidth
) && !width_p
)))
2155 /* Can't tell if this one is resizable without looking at
2156 siblings. If all siblings are fixed-size this one is too. */
2157 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
2161 for (child
= w
->prev
; !NILP (child
); child
= XWINDOW (child
)->prev
)
2162 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2166 for (child
= w
->next
; !NILP (child
); child
= XWINDOW (child
)->next
)
2167 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2181 /* Return the minimum size of window W, not taking fixed-width windows
2182 into account. WIDTH_P non-zero means return the minimum width,
2183 otherwise return the minimum height. If W is a combination window,
2184 compute the minimum size from the minimum sizes of W's children. */
2187 window_min_size_1 (w
, width_p
)
2194 if (!NILP (w
->hchild
))
2196 c
= XWINDOW (w
->hchild
);
2201 /* The min width of a horizontal combination is
2202 the sum of the min widths of its children. */
2205 size
+= window_min_size_1 (c
, width_p
);
2206 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2211 /* The min height a horizontal combination equals
2212 the maximum of all min height of its children. */
2215 int min_size
= window_min_size_1 (c
, width_p
);
2216 size
= max (min_size
, size
);
2217 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2221 else if (!NILP (w
->vchild
))
2223 c
= XWINDOW (w
->vchild
);
2228 /* The min width of a vertical combination is
2229 the maximum of the min widths of its children. */
2232 int min_size
= window_min_size_1 (c
, width_p
);
2233 size
= max (min_size
, size
);
2234 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2239 /* The min height of a vertical combination equals
2240 the sum of the min height of its children. */
2243 size
+= window_min_size_1 (c
, width_p
);
2244 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2251 size
= window_min_width
;
2254 if (MINI_WINDOW_P (w
)
2255 || (!WINDOW_WANTS_MODELINE_P (w
)
2256 && !WINDOW_WANTS_HEADER_LINE_P (w
)))
2259 size
= window_min_height
;
2267 /* Return the minimum size of window W, taking fixed-size windows into
2268 account. WIDTH_P non-zero means return the minimum width,
2269 otherwise return the minimum height. IGNORE_FIXED_P non-zero means
2270 ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size
2271 unless FIXED is null. */
2274 window_min_size (w
, width_p
, ignore_fixed_p
, fixed
)
2276 int width_p
, ignore_fixed_p
, *fixed
;
2283 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
2289 size
= width_p
? XFASTINT (w
->width
) : XFASTINT (w
->height
);
2291 size
= window_min_size_1 (w
, width_p
);
2297 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
2298 WINDOW's width. Resize WINDOW's children, if any, so that they
2299 keep their proportionate size relative to WINDOW. Propagate
2300 WINDOW's top or left edge position to children. Delete windows
2301 that become too small unless NODELETE_P is non-zero. */
2304 size_window (window
, size
, width_p
, nodelete_p
)
2306 int size
, width_p
, nodelete_p
;
2308 struct window
*w
= XWINDOW (window
);
2310 Lisp_Object child
, *forward
, *sideward
;
2311 int old_size
, min_size
;
2313 check_min_window_sizes ();
2315 /* If the window has been "too small" at one point,
2316 don't delete it for being "too small" in the future.
2317 Preserve it as long as that is at all possible. */
2320 old_size
= XFASTINT (w
->width
);
2321 min_size
= window_min_width
;
2325 old_size
= XFASTINT (w
->height
);
2326 min_size
= window_min_height
;
2329 if (old_size
< window_min_width
)
2330 w
->too_small_ok
= Qt
;
2332 /* Maybe delete WINDOW if it's too small. */
2333 if (!nodelete_p
&& !NILP (w
->parent
))
2337 if (!MINI_WINDOW_P (w
) && !NILP (w
->too_small_ok
))
2338 min_size
= width_p
? MIN_SAFE_WINDOW_WIDTH
: MIN_SAFE_WINDOW_HEIGHT
;
2340 min_size
= width_p
? window_min_width
: window_min_height
;
2342 if (size
< min_size
)
2344 delete_window (window
);
2349 /* Set redisplay hints. */
2350 XSETFASTINT (w
->last_modified
, 0);
2351 XSETFASTINT (w
->last_overlay_modified
, 0);
2352 windows_or_buffers_changed
++;
2353 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
2357 sideward
= &w
->vchild
;
2358 forward
= &w
->hchild
;
2359 XSETFASTINT (w
->width
, size
);
2363 sideward
= &w
->hchild
;
2364 forward
= &w
->vchild
;
2365 XSETFASTINT (w
->height
, size
);
2368 if (!NILP (*sideward
))
2370 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
2372 c
= XWINDOW (child
);
2377 size_window (child
, size
, width_p
, nodelete_p
);
2380 else if (!NILP (*forward
))
2382 int fixed_size
, each
, extra
, n
;
2383 int resize_fixed_p
, nfixed
;
2384 int last_pos
, first_pos
, nchildren
;
2386 /* Determine the fixed-size portion of the this window, and the
2387 number of child windows. */
2388 fixed_size
= nchildren
= nfixed
= 0;
2389 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
2391 c
= XWINDOW (child
);
2392 if (window_fixed_size_p (c
, width_p
, 0))
2394 fixed_size
+= (width_p
2395 ? XFASTINT (c
->width
) : XFASTINT (c
->height
));
2400 /* If the new size is smaller than fixed_size, or if there
2401 aren't any resizable windows, allow resizing fixed-size
2403 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
2405 /* Compute how many lines/columns to add to each child. The
2406 value of extra takes care of rounding errors. */
2407 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
2408 each
= (size
- old_size
) / n
;
2409 extra
= (size
- old_size
) - n
* each
;
2411 /* Compute new children heights and edge positions. */
2412 first_pos
= width_p
? XFASTINT (w
->left
) : XFASTINT (w
->top
);
2413 last_pos
= first_pos
;
2414 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2416 int new_size
, old_size
;
2418 c
= XWINDOW (child
);
2419 old_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2420 new_size
= old_size
;
2422 /* The top or left edge position of this child equals the
2423 bottom or right edge of its predecessor. */
2425 c
->left
= make_number (last_pos
);
2427 c
->top
= make_number (last_pos
);
2429 /* If this child can be resized, do it. */
2430 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
2432 new_size
= old_size
+ each
+ extra
;
2436 /* Set new height. Note that size_window also propagates
2437 edge positions to children, so it's not a no-op if we
2438 didn't change the child's size. */
2439 size_window (child
, new_size
, width_p
, 1);
2441 /* Remember the bottom/right edge position of this child; it
2442 will be used to set the top/left edge of the next child. */
2443 last_pos
+= new_size
;
2446 /* We should have covered the parent exactly with child windows. */
2447 xassert (size
== last_pos
- first_pos
);
2449 /* Now delete any children that became too small. */
2451 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2454 c
= XWINDOW (child
);
2455 child_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2456 size_window (child
, child_size
, width_p
, 0);
2461 /* Set WINDOW's height to HEIGHT, and recursively change the height of
2462 WINDOW's children. NODELETE non-zero means don't delete windows
2463 that become too small in the process. (The caller should check
2464 later and do so if appropriate.) */
2467 set_window_height (window
, height
, nodelete
)
2472 size_window (window
, height
, 0, nodelete
);
2476 /* Set WINDOW's width to WIDTH, and recursively change the width of
2477 WINDOW's children. NODELETE non-zero means don't delete windows
2478 that become too small in the process. (The caller should check
2479 later and do so if appropriate.) */
2482 set_window_width (window
, width
, nodelete
)
2487 size_window (window
, width
, 1, nodelete
);
2491 int window_select_count
;
2494 Fset_window_buffer_unwind (obuf
)
2502 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
2503 means it's allowed to run hooks. See make_frame for a case where
2504 it's not allowed. */
2507 set_window_buffer (window
, buffer
, run_hooks_p
)
2508 Lisp_Object window
, buffer
;
2511 struct window
*w
= XWINDOW (window
);
2512 struct buffer
*b
= XBUFFER (buffer
);
2513 int count
= specpdl_ptr
- specpdl
;
2517 if (EQ (window
, selected_window
))
2518 b
->last_selected_window
= window
;
2520 /* Update time stamps of buffer display. */
2521 if (INTEGERP (b
->display_count
))
2522 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
2523 b
->display_time
= Fcurrent_time ();
2525 XSETFASTINT (w
->window_end_pos
, 0);
2526 XSETFASTINT (w
->window_end_vpos
, 0);
2527 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
2528 w
->window_end_valid
= Qnil
;
2529 XSETFASTINT (w
->hscroll
, 0);
2530 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
2531 set_marker_restricted (w
->start
,
2532 make_number (b
->last_window_start
),
2534 w
->start_at_line_beg
= Qnil
;
2535 w
->force_start
= Qnil
;
2536 XSETFASTINT (w
->last_modified
, 0);
2537 XSETFASTINT (w
->last_overlay_modified
, 0);
2538 windows_or_buffers_changed
++;
2540 /* We must select BUFFER for running the window-scroll-functions.
2541 If WINDOW is selected, switch permanently.
2542 Otherwise, switch but go back to the ambient buffer afterward. */
2543 if (EQ (window
, selected_window
))
2544 Fset_buffer (buffer
);
2545 /* We can't check ! NILP (Vwindow_scroll_functions) here
2546 because that might itself be a local variable. */
2547 else if (window_initialized
)
2549 record_unwind_protect (Fset_window_buffer_unwind
, Fcurrent_buffer ());
2550 Fset_buffer (buffer
);
2553 /* Set left and right marginal area width from buffer. */
2554 Fset_window_margins (window
, b
->left_margin_width
, b
->right_margin_width
);
2558 if (! NILP (Vwindow_scroll_functions
))
2559 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2560 Fmarker_position (w
->start
));
2562 if (! NILP (Vwindow_configuration_change_hook
)
2563 && ! NILP (Vrun_hooks
))
2564 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
2567 unbind_to (count
, Qnil
);
2571 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 2, 0,
2572 "Make WINDOW display BUFFER as its contents.\n\
2573 BUFFER can be a buffer or buffer name.")
2575 register Lisp_Object window
, buffer
;
2577 register Lisp_Object tem
;
2578 register struct window
*w
= decode_window (window
);
2580 XSETWINDOW (window
, w
);
2581 buffer
= Fget_buffer (buffer
);
2582 CHECK_BUFFER (buffer
, 1);
2584 if (NILP (XBUFFER (buffer
)->name
))
2585 error ("Attempt to display deleted buffer");
2589 error ("Window is deleted");
2590 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
2591 is first being set up. */
2593 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
2594 error ("Window is dedicated to `%s'",
2595 XSTRING (XBUFFER (tem
)->name
)->data
);
2600 set_window_buffer (window
, buffer
, 1);
2604 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 1, 0,
2605 "Select WINDOW. Most editing will apply to WINDOW's buffer.\n\
2606 If WINDOW is not already selected, also make WINDOW's buffer current.\n\
2607 Note that the main editor command loop\n\
2608 selects the buffer of the selected window before each command.")
2610 register Lisp_Object window
;
2612 return select_window_1 (window
, 1);
2615 /* Note that selected_window can be nil
2616 when this is called from Fset_window_configuration. */
2619 select_window_1 (window
, recordflag
)
2620 register Lisp_Object window
;
2623 register struct window
*w
;
2624 register struct window
*ow
;
2627 CHECK_LIVE_WINDOW (window
, 0);
2629 w
= XWINDOW (window
);
2631 if (NILP (w
->buffer
))
2632 error ("Trying to select deleted window or non-leaf window");
2634 XSETFASTINT (w
->use_time
, ++window_select_count
);
2635 if (EQ (window
, selected_window
))
2638 if (!NILP (selected_window
))
2640 ow
= XWINDOW (selected_window
);
2641 if (! NILP (ow
->buffer
))
2642 set_marker_both (ow
->pointm
, ow
->buffer
,
2643 BUF_PT (XBUFFER (ow
->buffer
)),
2644 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
2647 selected_window
= window
;
2648 sf
= SELECTED_FRAME ();
2649 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
2651 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
2652 /* Use this rather than Fhandle_switch_frame
2653 so that FRAME_FOCUS_FRAME is moved appropriately as we
2654 move around in the state where a minibuffer in a separate
2656 Fselect_frame (WINDOW_FRAME (w
), Qnil
);
2659 sf
->selected_window
= window
;
2662 record_buffer (w
->buffer
);
2663 Fset_buffer (w
->buffer
);
2665 XBUFFER (w
->buffer
)->last_selected_window
= window
;
2667 /* Go to the point recorded in the window.
2668 This is important when the buffer is in more
2669 than one window. It also matters when
2670 redisplay_window has altered point after scrolling,
2671 because it makes the change only in the window. */
2673 register int new_point
= marker_position (w
->pointm
);
2674 if (new_point
< BEGV
)
2676 else if (new_point
> ZV
)
2682 windows_or_buffers_changed
++;
2686 /* Deiconify the frame containing the window WINDOW,
2687 unless it is the selected frame;
2690 The reason for the exception for the selected frame
2691 is that it seems better not to change the selected frames visibility
2692 merely because of displaying a different buffer in it.
2693 The deiconification is useful when a buffer gets shown in
2694 another frame that you were not using lately. */
2697 display_buffer_1 (window
)
2700 Lisp_Object frame
= XWINDOW (window
)->frame
;
2701 FRAME_PTR f
= XFRAME (frame
);
2703 FRAME_SAMPLE_VISIBILITY (f
);
2705 if (!EQ (frame
, selected_frame
))
2707 if (FRAME_ICONIFIED_P (f
))
2708 Fmake_frame_visible (frame
);
2709 else if (FRAME_VISIBLE_P (f
))
2710 Fraise_frame (frame
);
2716 DEFUN ("special-display-p", Fspecial_display_p
, Sspecial_display_p
, 1, 1, 0,
2717 "Returns non-nil if a buffer named BUFFER-NAME would be created specially.\n\
2718 The value is actually t if the frame should be called with default frame\n\
2719 parameters, and a list of frame parameters if they were specified.\n\
2720 See `special-display-buffer-names', and `special-display-regexps'.")
2722 Lisp_Object buffer_name
;
2726 CHECK_STRING (buffer_name
, 1);
2728 tem
= Fmember (buffer_name
, Vspecial_display_buffer_names
);
2732 tem
= Fassoc (buffer_name
, Vspecial_display_buffer_names
);
2736 for (tem
= Vspecial_display_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2738 Lisp_Object car
= XCAR (tem
);
2740 && fast_string_match (car
, buffer_name
) >= 0)
2742 else if (CONSP (car
)
2743 && STRINGP (XCAR (car
))
2744 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2750 DEFUN ("same-window-p", Fsame_window_p
, Ssame_window_p
, 1, 1, 0,
2751 "Returns non-nil if a new buffer named BUFFER-NAME would use the same window.\n\
2752 See `same-window-buffer-names' and `same-window-regexps'.")
2754 Lisp_Object buffer_name
;
2758 CHECK_STRING (buffer_name
, 1);
2760 tem
= Fmember (buffer_name
, Vsame_window_buffer_names
);
2764 tem
= Fassoc (buffer_name
, Vsame_window_buffer_names
);
2768 for (tem
= Vsame_window_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2770 Lisp_Object car
= XCAR (tem
);
2772 && fast_string_match (car
, buffer_name
) >= 0)
2774 else if (CONSP (car
)
2775 && STRINGP (XCAR (car
))
2776 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2782 /* Use B so the default is (other-buffer). */
2783 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 3,
2784 "BDisplay buffer: \nP",
2785 "Make BUFFER appear in some window but don't select it.\n\
2786 BUFFER can be a buffer or a buffer name.\n\
2787 If BUFFER is shown already in some window, just use that one,\n\
2788 unless the window is the selected window and the optional second\n\
2789 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).\n\
2790 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.\n\
2791 Returns the window displaying BUFFER.\n\
2792 If `display-reuse-frames' is non-nil, and another frame is currently\n\
2793 displaying BUFFER, then simply raise that frame.\n\
2795 The variables `special-display-buffer-names', `special-display-regexps',\n\
2796 `same-window-buffer-names', and `same-window-regexps' customize how certain\n\
2797 buffer names are handled.\n\
2799 If optional argument FRAME is `visible', search all visible frames.\n\
2800 If FRAME is 0, search all visible and iconified frames.\n\
2801 If FRAME is t, search all frames.\n\
2802 If FRAME is a frame, search only that frame.\n\
2803 If FRAME is nil, search only the selected frame\n\
2804 (actually the last nonminibuffer frame),\n\
2805 unless `pop-up-frames' or `display-reuse-frames' is non-nil,\n\
2806 which means search visible and iconified frames.")
2807 (buffer
, not_this_window
, frame
)
2808 register Lisp_Object buffer
, not_this_window
, frame
;
2810 register Lisp_Object window
, tem
, swp
;
2814 buffer
= Fget_buffer (buffer
);
2815 CHECK_BUFFER (buffer
, 0);
2817 if (!NILP (Vdisplay_buffer_function
))
2818 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
2820 if (NILP (not_this_window
)
2821 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
2822 return display_buffer_1 (selected_window
);
2824 /* See if the user has specified this buffer should appear
2825 in the selected window. */
2826 if (NILP (not_this_window
))
2828 swp
= Fsame_window_p (XBUFFER (buffer
)->name
);
2829 if (!NILP (swp
) && !no_switch_window (selected_window
))
2831 Fswitch_to_buffer (buffer
, Qnil
);
2832 return display_buffer_1 (selected_window
);
2836 /* If the user wants pop-up-frames or display-reuse-frames, then
2837 look for a window showing BUFFER on any visible or iconified frame.
2838 Otherwise search only the current frame. */
2841 else if (pop_up_frames
2842 || display_buffer_reuse_frames
2843 || last_nonminibuf_frame
== 0)
2844 XSETFASTINT (tem
, 0);
2846 XSETFRAME (tem
, last_nonminibuf_frame
);
2848 window
= Fget_buffer_window (buffer
, tem
);
2850 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
2851 return display_buffer_1 (window
);
2853 /* Certain buffer names get special handling. */
2854 if (!NILP (Vspecial_display_function
) && NILP (swp
))
2856 tem
= Fspecial_display_p (XBUFFER (buffer
)->name
);
2858 return call1 (Vspecial_display_function
, buffer
);
2860 return call2 (Vspecial_display_function
, buffer
, tem
);
2863 /* If there are no frames open that have more than a minibuffer,
2864 we need to create a new frame. */
2865 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
2867 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2868 Fset_window_buffer (window
, buffer
);
2869 return display_buffer_1 (window
);
2872 f
= SELECTED_FRAME ();
2874 || FRAME_MINIBUF_ONLY_P (f
)
2875 /* If the current frame is a special display frame,
2876 don't try to reuse its windows. */
2877 || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f
))->dedicated
))
2882 if (FRAME_MINIBUF_ONLY_P (f
))
2883 XSETFRAME (frames
, last_nonminibuf_frame
);
2884 /* Don't try to create a window if would get an error */
2885 if (split_height_threshold
< window_min_height
<< 1)
2886 split_height_threshold
= window_min_height
<< 1;
2888 /* Note that both Fget_largest_window and Fget_lru_window
2889 ignore minibuffers and dedicated windows.
2890 This means they can return nil. */
2892 /* If the frame we would try to split cannot be split,
2893 try other frames. */
2894 if (FRAME_NO_SPLIT_P (NILP (frames
) ? f
: last_nonminibuf_frame
))
2896 /* Try visible frames first. */
2897 window
= Fget_largest_window (Qvisible
);
2898 /* If that didn't work, try iconified frames. */
2900 window
= Fget_largest_window (make_number (0));
2902 window
= Fget_largest_window (Qt
);
2905 window
= Fget_largest_window (frames
);
2907 /* If we got a tall enough full-width window that can be split,
2910 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2911 && window_height (window
) >= split_height_threshold
2912 && WINDOW_FULL_WIDTH_P (XWINDOW (window
)))
2913 window
= Fsplit_window (window
, Qnil
, Qnil
);
2916 Lisp_Object upper
, lower
, other
;
2918 window
= Fget_lru_window (frames
);
2919 /* If the LRU window is selected, and big enough,
2920 and can be split, split it. */
2922 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2923 && (EQ (window
, selected_window
)
2924 || EQ (XWINDOW (window
)->parent
, Qnil
))
2925 && window_height (window
) >= window_min_height
<< 1)
2926 window
= Fsplit_window (window
, Qnil
, Qnil
);
2927 /* If Fget_lru_window returned nil, try other approaches. */
2929 /* Try visible frames first. */
2931 window
= Fget_buffer_window (buffer
, Qvisible
);
2933 window
= Fget_largest_window (Qvisible
);
2934 /* If that didn't work, try iconified frames. */
2936 window
= Fget_buffer_window (buffer
, make_number (0));
2938 window
= Fget_largest_window (make_number (0));
2939 /* Try invisible frames. */
2941 window
= Fget_buffer_window (buffer
, Qt
);
2943 window
= Fget_largest_window (Qt
);
2944 /* As a last resort, make a new frame. */
2946 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2947 /* If window appears above or below another,
2948 even out their heights. */
2949 other
= upper
= lower
= Qnil
;
2950 if (!NILP (XWINDOW (window
)->prev
))
2951 other
= upper
= XWINDOW (window
)->prev
, lower
= window
;
2952 if (!NILP (XWINDOW (window
)->next
))
2953 other
= lower
= XWINDOW (window
)->next
, upper
= window
;
2955 /* Check that OTHER and WINDOW are vertically arrayed. */
2956 && !EQ (XWINDOW (other
)->top
, XWINDOW (window
)->top
)
2957 && (XFASTINT (XWINDOW (other
)->height
)
2958 > XFASTINT (XWINDOW (window
)->height
)))
2960 int total
= (XFASTINT (XWINDOW (other
)->height
)
2961 + XFASTINT (XWINDOW (window
)->height
));
2962 enlarge_window (upper
,
2963 total
/ 2 - XFASTINT (XWINDOW (upper
)->height
),
2969 window
= Fget_lru_window (Qnil
);
2971 Fset_window_buffer (window
, buffer
);
2972 return display_buffer_1 (window
);
2976 temp_output_buffer_show (buf
)
2977 register Lisp_Object buf
;
2979 register struct buffer
*old
= current_buffer
;
2980 register Lisp_Object window
;
2981 register struct window
*w
;
2983 XBUFFER (buf
)->directory
= current_buffer
->directory
;
2986 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
2990 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
2991 set_buffer_internal (old
);
2993 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
2994 call1 (Vtemp_buffer_show_function
, buf
);
2997 window
= Fdisplay_buffer (buf
, Qnil
, Qnil
);
2999 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
3000 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
3001 Vminibuf_scroll_window
= window
;
3002 w
= XWINDOW (window
);
3003 XSETFASTINT (w
->hscroll
, 0);
3004 set_marker_restricted_both (w
->start
, buf
, 1, 1);
3005 set_marker_restricted_both (w
->pointm
, buf
, 1, 1);
3007 /* Run temp-buffer-show-hook, with the chosen window selected
3008 and it sbuffer current. */
3009 if (!NILP (Vrun_hooks
))
3012 tem
= Fboundp (Qtemp_buffer_show_hook
);
3015 tem
= Fsymbol_value (Qtemp_buffer_show_hook
);
3018 int count
= specpdl_ptr
- specpdl
;
3019 Lisp_Object prev_window
;
3020 prev_window
= selected_window
;
3022 /* Select the window that was chosen, for running the hook. */
3023 record_unwind_protect (Fselect_window
, prev_window
);
3024 select_window_1 (window
, 0);
3025 Fset_buffer (w
->buffer
);
3026 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
3027 select_window_1 (prev_window
, 0);
3028 unbind_to (count
, Qnil
);
3036 make_dummy_parent (window
)
3040 register struct window
*o
, *p
;
3041 register struct Lisp_Vector
*vec
;
3044 o
= XWINDOW (window
);
3045 vec
= allocate_vectorlike ((EMACS_INT
)VECSIZE (struct window
));
3046 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
3047 vec
->contents
[i
] = ((struct Lisp_Vector
*)o
)->contents
[i
];
3048 vec
->size
= VECSIZE (struct window
);
3049 p
= (struct window
*)vec
;
3050 XSETWINDOW (new, p
);
3052 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
3054 /* Put new into window structure in place of window */
3055 replace_window (window
, new);
3068 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
3069 "Split WINDOW, putting SIZE lines in the first of the pair.\n\
3070 WINDOW defaults to selected one and SIZE to half its size.\n\
3071 If optional third arg HORFLAG is non-nil, split side by side\n\
3072 and put SIZE columns in the first of the pair. In that case,\n\
3073 SIZE includes that window's scroll bar, or the divider column to its right.")
3074 (window
, size
, horflag
)
3075 Lisp_Object window
, size
, horflag
;
3077 register Lisp_Object
new;
3078 register struct window
*o
, *p
;
3080 register int size_int
;
3083 window
= selected_window
;
3085 CHECK_LIVE_WINDOW (window
, 0);
3087 o
= XWINDOW (window
);
3088 fo
= XFRAME (WINDOW_FRAME (o
));
3092 if (!NILP (horflag
))
3093 /* Calculate the size of the left-hand window, by dividing
3094 the usable space in columns by two.
3095 We round up, since the left-hand window may include
3096 a dividing line, while the right-hand may not. */
3097 size_int
= (XFASTINT (o
->width
) + 1) >> 1;
3099 size_int
= XFASTINT (o
->height
) >> 1;
3103 CHECK_NUMBER (size
, 1);
3104 size_int
= XINT (size
);
3107 if (MINI_WINDOW_P (o
))
3108 error ("Attempt to split minibuffer window");
3109 else if (window_fixed_size_p (o
, !NILP (horflag
), 0))
3110 error ("Attempt to split fixed-size window");
3112 check_min_window_sizes ();
3116 if (size_int
< window_min_height
)
3117 error ("Window height %d too small (after splitting)", size_int
);
3118 if (size_int
+ window_min_height
> XFASTINT (o
->height
))
3119 error ("Window height %d too small (after splitting)",
3120 XFASTINT (o
->height
) - size_int
);
3121 if (NILP (o
->parent
)
3122 || NILP (XWINDOW (o
->parent
)->vchild
))
3124 make_dummy_parent (window
);
3126 XWINDOW (new)->vchild
= window
;
3131 if (size_int
< window_min_width
)
3132 error ("Window width %d too small (after splitting)", size_int
);
3134 if (size_int
+ window_min_width
> XFASTINT (o
->width
))
3135 error ("Window width %d too small (after splitting)",
3136 XFASTINT (o
->width
) - size_int
);
3137 if (NILP (o
->parent
)
3138 || NILP (XWINDOW (o
->parent
)->hchild
))
3140 make_dummy_parent (window
);
3142 XWINDOW (new)->hchild
= window
;
3146 /* Now we know that window's parent is a vertical combination
3147 if we are dividing vertically, or a horizontal combination
3148 if we are making side-by-side windows */
3150 windows_or_buffers_changed
++;
3151 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
3152 new = make_window ();
3155 p
->frame
= o
->frame
;
3157 if (!NILP (p
->next
))
3158 XWINDOW (p
->next
)->prev
= new;
3161 p
->parent
= o
->parent
;
3163 p
->window_end_valid
= Qnil
;
3164 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
3166 /* Apportion the available frame space among the two new windows */
3168 if (!NILP (horflag
))
3170 p
->height
= o
->height
;
3172 XSETFASTINT (p
->width
, XFASTINT (o
->width
) - size_int
);
3173 XSETFASTINT (o
->width
, size_int
);
3174 XSETFASTINT (p
->left
, XFASTINT (o
->left
) + size_int
);
3179 p
->width
= o
->width
;
3180 XSETFASTINT (p
->height
, XFASTINT (o
->height
) - size_int
);
3181 XSETFASTINT (o
->height
, size_int
);
3182 XSETFASTINT (p
->top
, XFASTINT (o
->top
) + size_int
);
3185 /* Adjust glyph matrices. */
3187 Fset_window_buffer (new, o
->buffer
);
3191 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
3192 "Make current window ARG lines bigger.\n\
3193 From program, optional second arg non-nil means grow sideways ARG columns.")
3195 register Lisp_Object arg
, side
;
3197 CHECK_NUMBER (arg
, 0);
3198 enlarge_window (selected_window
, XINT (arg
), !NILP (side
));
3200 if (! NILP (Vwindow_configuration_change_hook
))
3201 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3206 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
3207 "Make current window ARG lines smaller.\n\
3208 From program, optional second arg non-nil means shrink sideways arg columns.")
3210 register Lisp_Object arg
, side
;
3212 CHECK_NUMBER (arg
, 0);
3213 enlarge_window (selected_window
, -XINT (arg
), !NILP (side
));
3215 if (! NILP (Vwindow_configuration_change_hook
))
3216 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3222 window_height (window
)
3225 register struct window
*p
= XWINDOW (window
);
3226 return XFASTINT (p
->height
);
3230 window_width (window
)
3233 register struct window
*p
= XWINDOW (window
);
3234 return XFASTINT (p
->width
);
3239 *(widthflag ? &(XWINDOW (w)->left) : &(XWINDOW (w)->top))
3241 #define CURSIZE(w) \
3242 *(widthflag ? &(XWINDOW (w)->width) : &(XWINDOW (w)->height))
3245 /* Enlarge selected_window by DELTA. WIDTHFLAG non-zero means
3246 increase its width. Siblings of the selected window are resized to
3247 fullfil the size request. If they become too small in the process,
3248 they will be deleted. */
3251 enlarge_window (window
, delta
, widthflag
)
3253 int delta
, widthflag
;
3255 Lisp_Object parent
, next
, prev
;
3259 int (*sizefun
) P_ ((Lisp_Object
))
3260 = widthflag
? window_width
: window_height
;
3261 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
3262 = (widthflag
? set_window_width
: set_window_height
);
3264 /* Check values of window_min_width and window_min_height for
3266 check_min_window_sizes ();
3268 /* Give up if this window cannot be resized. */
3269 if (window_fixed_size_p (XWINDOW (window
), widthflag
, 1))
3270 error ("Window is not resizable");
3272 /* Find the parent of the selected window. */
3275 p
= XWINDOW (window
);
3281 error ("No other window to side of this one");
3286 ? !NILP (XWINDOW (parent
)->hchild
)
3287 : !NILP (XWINDOW (parent
)->vchild
))
3293 sizep
= &CURSIZE (window
);
3296 register int maxdelta
;
3298 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - XINT (*sizep
)
3299 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3300 - window_min_size (XWINDOW (p
->next
),
3302 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
3303 - window_min_size (XWINDOW (p
->prev
),
3305 /* This is a frame with only one window, a minibuffer-only
3306 or a minibufferless frame. */
3309 if (delta
> maxdelta
)
3310 /* This case traps trying to make the minibuffer
3311 the full frame, or make the only window aside from the
3312 minibuffer the full frame. */
3316 if (XINT (*sizep
) + delta
< window_min_size (XWINDOW (window
), widthflag
, 0, 0))
3318 delete_window (window
);
3325 /* Find the total we can get from other siblings. */
3327 for (next
= p
->next
; ! NILP (next
); next
= XWINDOW (next
)->next
)
3328 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
3330 for (prev
= p
->prev
; ! NILP (prev
); prev
= XWINDOW (prev
)->prev
)
3331 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
3334 /* If we can get it all from them, do so. */
3335 if (delta
<= maximum
)
3337 Lisp_Object first_unaffected
;
3338 Lisp_Object first_affected
;
3343 first_affected
= window
;
3344 /* Look at one sibling at a time,
3345 moving away from this window in both directions alternately,
3346 and take as much as we can get without deleting that sibling. */
3347 while (delta
!= 0 && (!NILP (next
) || !NILP (prev
)))
3351 int this_one
= ((*sizefun
) (next
)
3352 - window_min_size (XWINDOW (next
),
3353 widthflag
, 0, &fixed_p
));
3356 if (this_one
> delta
)
3359 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
3360 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3365 next
= XWINDOW (next
)->next
;
3373 int this_one
= ((*sizefun
) (prev
)
3374 - window_min_size (XWINDOW (prev
),
3375 widthflag
, 0, &fixed_p
));
3378 if (this_one
> delta
)
3381 first_affected
= prev
;
3383 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
3384 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3389 prev
= XWINDOW (prev
)->prev
;
3393 xassert (delta
== 0);
3395 /* Now recalculate the edge positions of all the windows affected,
3396 based on the new sizes. */
3397 first_unaffected
= next
;
3398 prev
= first_affected
;
3399 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
3400 prev
= next
, next
= XWINDOW (next
)->next
)
3402 XSETINT (CURBEG (next
), XINT (CURBEG (prev
)) + (*sizefun
) (prev
));
3403 /* This does not change size of NEXT,
3404 but it propagates the new top edge to its children */
3405 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
3410 register int delta1
;
3411 register int opht
= (*sizefun
) (parent
);
3413 /* If trying to grow this window to or beyond size of the parent,
3414 make delta1 so big that, on shrinking back down,
3415 all the siblings end up with less than one line and are deleted. */
3416 if (opht
<= XINT (*sizep
) + delta
)
3417 delta1
= opht
* opht
* 2;
3420 /* Otherwise, make delta1 just right so that if we add
3421 delta1 lines to this window and to the parent, and then
3422 shrink the parent back to its original size, the new
3423 proportional size of this window will increase by delta.
3425 The function size_window will compute the new height h'
3426 of the window from delta1 as:
3429 x = delta1 - delta1/n * n for the 1st resizable child
3432 where n is the number of children that can be resized.
3433 We can ignore x by choosing a delta1 that is a multiple of
3434 n. We want the height of this window to come out as
3444 The number of children n rquals the number of resizable
3445 children of this window + 1 because we know window itself
3446 is resizable (otherwise we would have signalled an error. */
3448 struct window
*w
= XWINDOW (window
);
3452 for (s
= w
->next
; !NILP (s
); s
= XWINDOW (s
)->next
)
3453 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3455 for (s
= w
->prev
; !NILP (s
); s
= XWINDOW (s
)->prev
)
3456 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3462 /* Add delta1 lines or columns to this window, and to the parent,
3463 keeping things consistent while not affecting siblings. */
3464 XSETINT (CURSIZE (parent
), opht
+ delta1
);
3465 (*setsizefun
) (window
, XINT (*sizep
) + delta1
, 0);
3467 /* Squeeze out delta1 lines or columns from our parent,
3468 shriking this window and siblings proportionately.
3469 This brings parent back to correct size.
3470 Delta1 was calculated so this makes this window the desired size,
3471 taking it all out of the siblings. */
3472 (*setsizefun
) (parent
, opht
, 0);
3475 XSETFASTINT (p
->last_modified
, 0);
3476 XSETFASTINT (p
->last_overlay_modified
, 0);
3478 /* Adjust glyph matrices. */
3479 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
3487 /***********************************************************************
3488 Resizing Mini-Windows
3489 ***********************************************************************/
3491 static void shrink_window_lowest_first
P_ ((struct window
*, int));
3493 enum save_restore_action
3500 static int save_restore_orig_size
P_ ((struct window
*,
3501 enum save_restore_action
));
3503 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
3504 from lowest windows first. */
3507 shrink_window_lowest_first (w
, height
)
3515 xassert (!MINI_WINDOW_P (w
));
3517 /* Set redisplay hints. */
3518 XSETFASTINT (w
->last_modified
, 0);
3519 XSETFASTINT (w
->last_overlay_modified
, 0);
3520 windows_or_buffers_changed
++;
3521 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
3523 old_height
= XFASTINT (w
->height
);
3524 XSETFASTINT (w
->height
, height
);
3526 if (!NILP (w
->hchild
))
3528 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
3530 c
= XWINDOW (child
);
3532 shrink_window_lowest_first (c
, height
);
3535 else if (!NILP (w
->vchild
))
3537 Lisp_Object last_child
;
3538 int delta
= old_height
- height
;
3543 /* Find the last child. We are taking space from lowest windows
3544 first, so we iterate over children from the last child
3546 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
3549 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
3550 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
3554 c
= XWINDOW (child
);
3555 this_one
= XFASTINT (c
->height
) - MIN_SAFE_WINDOW_HEIGHT
;
3557 if (this_one
> delta
)
3560 shrink_window_lowest_first (c
, XFASTINT (c
->height
) - this_one
);
3564 /* Compute new positions. */
3565 last_top
= XINT (w
->top
);
3566 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
3568 c
= XWINDOW (child
);
3569 c
->top
= make_number (last_top
);
3570 shrink_window_lowest_first (c
, XFASTINT (c
->height
));
3571 last_top
+= XFASTINT (c
->height
);
3577 /* Save, restore, or check positions and sizes in the window tree
3578 rooted at W. ACTION says what to do.
3580 If ACTION is CHECK_ORIG_SIZES, check if orig_top and orig_height
3581 members are valid for all windows in the window tree. Value is
3582 non-zero if they are valid.
3584 If ACTION is SAVE_ORIG_SIZES, save members top and height in
3585 orig_top and orig_height for all windows in the tree.
3587 If ACTION is RESTORE_ORIG_SIZES, restore top and height from
3588 values stored in orig_top and orig_height for all windows. */
3591 save_restore_orig_size (w
, action
)
3593 enum save_restore_action action
;
3599 if (!NILP (w
->hchild
))
3601 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
3604 else if (!NILP (w
->vchild
))
3606 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
3612 case CHECK_ORIG_SIZES
:
3613 if (!INTEGERP (w
->orig_top
) || !INTEGERP (w
->orig_height
))
3617 case SAVE_ORIG_SIZES
:
3618 w
->orig_top
= w
->top
;
3619 w
->orig_height
= w
->height
;
3620 XSETFASTINT (w
->last_modified
, 0);
3621 XSETFASTINT (w
->last_overlay_modified
, 0);
3624 case RESTORE_ORIG_SIZES
:
3625 xassert (INTEGERP (w
->orig_top
) && INTEGERP (w
->orig_height
));
3626 w
->top
= w
->orig_top
;
3627 w
->height
= w
->orig_height
;
3628 w
->orig_height
= w
->orig_top
= Qnil
;
3629 XSETFASTINT (w
->last_modified
, 0);
3630 XSETFASTINT (w
->last_overlay_modified
, 0);
3637 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
3644 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
3645 without deleting other windows. */
3648 grow_mini_window (w
, delta
)
3652 struct frame
*f
= XFRAME (w
->frame
);
3653 struct window
*root
;
3655 xassert (MINI_WINDOW_P (w
));
3656 xassert (delta
>= 0);
3658 /* Check values of window_min_width and window_min_height for
3660 check_min_window_sizes ();
3662 /* Compute how much we can enlarge the mini-window without deleting
3664 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3667 int min_height
= window_min_size (root
, 0, 0, 0);
3668 if (XFASTINT (root
->height
) - delta
< min_height
)
3669 delta
= XFASTINT (root
->height
) - min_height
;
3674 /* Save original window sizes and positions, if not already done. */
3675 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3676 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
3678 /* Shrink other windows. */
3679 shrink_window_lowest_first (root
, XFASTINT (root
->height
) - delta
);
3681 /* Grow the mini-window. */
3682 w
->top
= make_number (XFASTINT (root
->top
) + XFASTINT (root
->height
));
3683 w
->height
= make_number (XFASTINT (w
->height
) + delta
);
3684 XSETFASTINT (w
->last_modified
, 0);
3685 XSETFASTINT (w
->last_overlay_modified
, 0);
3692 /* Shrink mini-window W. If there is recorded info about window sizes
3693 before a call to grow_mini_window, restore recorded window sizes.
3694 Otherwise, if the mini-window is higher than 1 line, resize it to 1
3698 shrink_mini_window (w
)
3701 struct frame
*f
= XFRAME (w
->frame
);
3702 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3704 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3706 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
3708 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
3709 windows_or_buffers_changed
= 1;
3711 else if (XFASTINT (w
->height
) > 1)
3714 XSETWINDOW (window
, w
);
3715 enlarge_window (window
, 1 - XFASTINT (w
->height
), 0);
3721 /* Mark window cursors off for all windows in the window tree rooted
3722 at W by setting their phys_cursor_on_p flag to zero. Called from
3723 xterm.c, e.g. when a frame is cleared and thereby all cursors on
3724 the frame are cleared. */
3727 mark_window_cursors_off (w
)
3732 if (!NILP (w
->hchild
))
3733 mark_window_cursors_off (XWINDOW (w
->hchild
));
3734 else if (!NILP (w
->vchild
))
3735 mark_window_cursors_off (XWINDOW (w
->vchild
));
3737 w
->phys_cursor_on_p
= 0;
3739 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
3744 /* Return number of lines of text (not counting mode line) in W. */
3747 window_internal_height (w
)
3750 int ht
= XFASTINT (w
->height
);
3752 if (MINI_WINDOW_P (w
))
3755 if (!NILP (w
->parent
) || !NILP (w
->vchild
) || !NILP (w
->hchild
)
3756 || !NILP (w
->next
) || !NILP (w
->prev
)
3757 || FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (w
))))
3764 /* Return the number of columns in W.
3765 Don't count columns occupied by scroll bars or the vertical bar
3766 separating W from the sibling to its right. */
3769 window_internal_width (w
)
3772 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
3773 int width
= XINT (w
->width
);
3775 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
3776 /* Scroll bars occupy a few columns. */
3777 width
-= FRAME_SCROLL_BAR_COLS (f
);
3778 else if (!WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
3779 /* The column of `|' characters separating side-by-side windows
3780 occupies one column only. */
3783 /* On window-systems, areas to the left and right of the window
3784 are used to display bitmaps there. */
3785 if (FRAME_WINDOW_P (f
))
3786 width
-= FRAME_FLAGS_AREA_COLS (f
);
3792 /************************************************************************
3794 ***********************************************************************/
3796 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
3797 one screen-full, which is defined as the height of the window minus
3798 next_screen_context_lines. If WHOLE is zero, scroll up N lines
3799 instead. Negative values of N mean scroll down. NOERROR non-zero
3800 means don't signal an error if we try to move over BEGV or ZV,
3804 window_scroll (window
, n
, whole
, noerror
)
3810 /* If we must, use the pixel-based version which is much slower than
3811 the line-based one but can handle varying line heights. */
3812 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
3813 window_scroll_pixel_based (window
, n
, whole
, noerror
);
3815 window_scroll_line_based (window
, n
, whole
, noerror
);
3819 /* Implementation of window_scroll that works based on pixel line
3820 heights. See the comment of window_scroll for parameter
3824 window_scroll_pixel_based (window
, n
, whole
, noerror
)
3831 struct window
*w
= XWINDOW (window
);
3832 struct text_pos start
;
3834 int this_scroll_margin
;
3837 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
3839 /* If PT is not visible in WINDOW, move back one half of
3841 XSETFASTINT (tem
, PT
);
3842 tem
= Fpos_visible_in_window_p (tem
, window
, Qt
);
3845 /* Move backward half the height of the window. Performance note:
3846 vmotion used here is about 10% faster, but would give wrong
3847 results for variable height lines. */
3848 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3849 it
.current_y
= it
.last_visible_y
;
3850 move_it_vertically (&it
, -it
.last_visible_y
/ 2);
3852 /* The function move_iterator_vertically may move over more than
3853 the specified y-distance. If it->w is small, e.g. a
3854 mini-buffer window, we may end up in front of the window's
3855 display area. This is the case when Start displaying at the
3856 start of the line containing PT in this case. */
3857 if (it
.current_y
<= 0)
3859 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3860 move_it_vertically (&it
, 0);
3864 start
= it
.current
.pos
;
3867 /* If scroll_preserve_screen_position is non-zero, we try to set
3868 point in the same window line as it is now, so get that line. */
3869 if (!NILP (Vscroll_preserve_screen_position
))
3871 start_display (&it
, w
, start
);
3872 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3873 preserve_y
= it
.current_y
;
3878 /* Move iterator it from start the specified distance forward or
3879 backward. The result is the new window start. */
3880 start_display (&it
, w
, start
);
3883 int screen_full
= (it
.last_visible_y
3884 - next_screen_context_lines
* CANON_Y_UNIT (it
.f
));
3885 int direction
= n
< 0 ? -1 : 1;
3886 move_it_vertically (&it
, direction
* screen_full
);
3889 move_it_by_lines (&it
, n
, 1);
3891 /* End if we end up at ZV or BEGV. */
3892 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
3893 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
3897 else if (IT_CHARPOS (it
) == ZV
)
3898 Fsignal (Qend_of_buffer
, Qnil
);
3900 Fsignal (Qbeginning_of_buffer
, Qnil
);
3903 /* Set the window start, and set up the window for redisplay. */
3904 set_marker_restricted (w
->start
, make_number (IT_CHARPOS (it
)), w
->buffer
);
3905 w
->start_at_line_beg
= Fbolp ();
3906 w
->update_mode_line
= Qt
;
3907 XSETFASTINT (w
->last_modified
, 0);
3908 XSETFASTINT (w
->last_overlay_modified
, 0);
3909 /* Set force_start so that redisplay_window will run the
3910 window-scroll-functions. */
3911 w
->force_start
= Qt
;
3913 it
.current_y
= it
.vpos
= 0;
3915 /* Preserve the screen position if we must. */
3916 if (preserve_y
>= 0)
3918 move_it_to (&it
, -1, -1, preserve_y
, -1, MOVE_TO_Y
);
3919 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3923 /* Move PT out of scroll margins. */
3924 this_scroll_margin
= max (0, scroll_margin
);
3925 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->height
) / 4);
3926 this_scroll_margin
*= CANON_Y_UNIT (it
.f
);
3930 /* We moved the window start towards ZV, so PT may be now
3931 in the scroll margin at the top. */
3932 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3933 while (it
.current_y
< this_scroll_margin
)
3934 move_it_by_lines (&it
, 1, 1);
3935 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3939 /* We moved the window start towards BEGV, so PT may be now
3940 in the scroll margin at the bottom. */
3941 move_it_to (&it
, PT
, -1,
3942 it
.last_visible_y
- this_scroll_margin
- 1, -1,
3943 MOVE_TO_POS
| MOVE_TO_Y
);
3945 /* Don't put point on a partially visible line at the end. */
3946 if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
3947 > it
.last_visible_y
)
3948 move_it_by_lines (&it
, -1, 0);
3950 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3956 /* Implementation of window_scroll that works based on screen lines.
3957 See the comment of window_scroll for parameter descriptions. */
3960 window_scroll_line_based (window
, n
, whole
, noerror
)
3966 register struct window
*w
= XWINDOW (window
);
3967 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
3968 register int pos
, pos_byte
;
3969 register int ht
= window_internal_height (w
);
3970 register Lisp_Object tem
;
3974 struct position posit
;
3977 startpos
= marker_position (w
->start
);
3979 posit
= *compute_motion (startpos
, 0, 0, 0,
3981 window_internal_width (w
), XINT (w
->hscroll
),
3983 original_vpos
= posit
.vpos
;
3985 XSETFASTINT (tem
, PT
);
3986 tem
= Fpos_visible_in_window_p (tem
, window
, Qt
);
3990 Fvertical_motion (make_number (- (ht
/ 2)), window
);
3995 lose
= n
< 0 && PT
== BEGV
;
3996 Fvertical_motion (make_number (n
), window
);
4000 SET_PT_BOTH (opoint
, opoint_byte
);
4007 Fsignal (Qbeginning_of_buffer
, Qnil
);
4012 int this_scroll_margin
= scroll_margin
;
4014 /* Don't use a scroll margin that is negative or too large. */
4015 if (this_scroll_margin
< 0)
4016 this_scroll_margin
= 0;
4018 if (XINT (w
->height
) < 4 * scroll_margin
)
4019 this_scroll_margin
= XINT (w
->height
) / 4;
4021 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
4022 w
->start_at_line_beg
= bolp
;
4023 w
->update_mode_line
= Qt
;
4024 XSETFASTINT (w
->last_modified
, 0);
4025 XSETFASTINT (w
->last_overlay_modified
, 0);
4026 /* Set force_start so that redisplay_window will run
4027 the window-scroll-functions. */
4028 w
->force_start
= Qt
;
4030 if (whole
&& !NILP (Vscroll_preserve_screen_position
))
4032 SET_PT_BOTH (pos
, pos_byte
);
4033 Fvertical_motion (make_number (original_vpos
), window
);
4035 /* If we scrolled forward, put point enough lines down
4036 that it is outside the scroll margin. */
4041 if (this_scroll_margin
> 0)
4043 SET_PT_BOTH (pos
, pos_byte
);
4044 Fvertical_motion (make_number (this_scroll_margin
), window
);
4050 if (top_margin
<= opoint
)
4051 SET_PT_BOTH (opoint
, opoint_byte
);
4052 else if (!NILP (Vscroll_preserve_screen_position
))
4054 SET_PT_BOTH (pos
, pos_byte
);
4055 Fvertical_motion (make_number (original_vpos
), window
);
4058 SET_PT (top_margin
);
4064 /* If we scrolled backward, put point near the end of the window
4065 but not within the scroll margin. */
4066 SET_PT_BOTH (pos
, pos_byte
);
4067 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
4068 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
4071 bottom_margin
= PT
+ 1;
4073 if (bottom_margin
> opoint
)
4074 SET_PT_BOTH (opoint
, opoint_byte
);
4077 if (!NILP (Vscroll_preserve_screen_position
))
4079 SET_PT_BOTH (pos
, pos_byte
);
4080 Fvertical_motion (make_number (original_vpos
), window
);
4083 Fvertical_motion (make_number (-1), window
);
4092 Fsignal (Qend_of_buffer
, Qnil
);
4097 /* Scroll selected_window up or down. If N is nil, scroll a
4098 screen-full which is defined as the height of the window minus
4099 next_screen_context_lines. If N is the symbol `-', scroll.
4100 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
4101 up. This is the guts of Fscroll_up and Fscroll_down. */
4104 scroll_command (n
, direction
)
4108 register int defalt
;
4109 int count
= specpdl_ptr
- specpdl
;
4111 xassert (abs (direction
) == 1);
4113 /* If selected window's buffer isn't current, make it current for
4114 the moment. But don't screw up if window_scroll gets an error. */
4115 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
4117 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4118 Fset_buffer (XWINDOW (selected_window
)->buffer
);
4120 /* Make redisplay consider other windows than just selected_window. */
4121 ++windows_or_buffers_changed
;
4124 defalt
= (window_internal_height (XWINDOW (selected_window
))
4125 - next_screen_context_lines
);
4126 defalt
= direction
* (defalt
< 1 ? 1 : defalt
);
4129 window_scroll (selected_window
, defalt
, 1, 0);
4130 else if (EQ (n
, Qminus
))
4131 window_scroll (selected_window
, - defalt
, 1, 0);
4134 n
= Fprefix_numeric_value (n
);
4135 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
4138 unbind_to (count
, Qnil
);
4141 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
4142 "Scroll text of current window upward ARG lines; or near full screen if no ARG.\n\
4143 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4144 Negative ARG means scroll downward.\n\
4145 If ARG is the atom `-', scroll downward by nearly full screen.\n\
4146 When calling from a program, supply as argument a number, nil, or `-'.")
4150 scroll_command (arg
, 1);
4154 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
4155 "Scroll text of current window down ARG lines; or near full screen if no ARG.\n\
4156 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4157 Negative ARG means scroll upward.\n\
4158 If ARG is the atom `-', scroll upward by nearly full screen.\n\
4159 When calling from a program, supply as argument a number, nil, or `-'.")
4163 scroll_command (arg
, -1);
4167 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
4168 "Return the other window for \"other window scroll\" commands.\n\
4169 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4170 specifies the window.\n\
4171 If `other-window-scroll-buffer' is non-nil, a window\n\
4172 showing that buffer is used.")
4177 if (MINI_WINDOW_P (XWINDOW (selected_window
))
4178 && !NILP (Vminibuf_scroll_window
))
4179 window
= Vminibuf_scroll_window
;
4180 /* If buffer is specified, scroll that buffer. */
4181 else if (!NILP (Vother_window_scroll_buffer
))
4183 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
4185 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
4189 /* Nothing specified; look for a neighboring window on the same
4191 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
4193 if (EQ (window
, selected_window
))
4194 /* That didn't get us anywhere; look for a window on another
4197 window
= Fnext_window (window
, Qnil
, Qt
);
4198 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
4199 && ! EQ (window
, selected_window
));
4202 CHECK_LIVE_WINDOW (window
, 0);
4204 if (EQ (window
, selected_window
))
4205 error ("There is no other window");
4210 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
4211 "Scroll next window upward ARG lines; or near full screen if no ARG.\n\
4212 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4213 The next window is the one below the current one; or the one at the top\n\
4214 if the current one is at the bottom. Negative ARG means scroll downward.\n\
4215 If ARG is the atom `-', scroll downward by nearly full screen.\n\
4216 When calling from a program, supply as argument a number, nil, or `-'.\n\
4218 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4219 specifies the window to scroll.\n\
4220 If `other-window-scroll-buffer' is non-nil, scroll the window\n\
4221 showing that buffer, popping the buffer up if necessary.")
4223 register Lisp_Object arg
;
4225 register Lisp_Object window
;
4226 register int defalt
;
4227 register struct window
*w
;
4228 register int count
= specpdl_ptr
- specpdl
;
4230 window
= Fother_window_for_scrolling ();
4232 w
= XWINDOW (window
);
4233 defalt
= window_internal_height (w
) - next_screen_context_lines
;
4234 if (defalt
< 1) defalt
= 1;
4236 /* Don't screw up if window_scroll gets an error. */
4237 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4238 ++windows_or_buffers_changed
;
4240 Fset_buffer (w
->buffer
);
4241 SET_PT (marker_position (w
->pointm
));
4244 window_scroll (window
, defalt
, 1, 1);
4245 else if (EQ (arg
, Qminus
))
4246 window_scroll (window
, -defalt
, 1, 1);
4251 CHECK_NUMBER (arg
, 0);
4252 window_scroll (window
, XINT (arg
), 0, 1);
4255 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
4256 unbind_to (count
, Qnil
);
4261 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 1, "P",
4262 "Scroll selected window display ARG columns left.\n\
4263 Default for ARG is window width minus 2.")
4265 register Lisp_Object arg
;
4269 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4271 arg
= Fprefix_numeric_value (arg
);
4274 Fset_window_hscroll (selected_window
,
4275 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4279 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 1, "P",
4280 "Scroll selected window display ARG columns right.\n\
4281 Default for ARG is window width minus 2.")
4283 register Lisp_Object arg
;
4286 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4288 arg
= Fprefix_numeric_value (arg
);
4291 Fset_window_hscroll (selected_window
,
4292 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4296 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
4297 "Center point in window and redisplay frame. With ARG, put point on line ARG.\n\
4298 The desired position of point is always relative to the current window.\n\
4299 Just C-u as prefix means put point in the center of the window.\n\
4300 If ARG is omitted or nil, erases the entire frame and then\n\
4301 redraws with point in the center of the current window.")
4303 register Lisp_Object arg
;
4305 register struct window
*w
= XWINDOW (selected_window
);
4306 register int ht
= window_internal_height (w
);
4307 struct position pos
;
4308 struct buffer
*buf
= XBUFFER (w
->buffer
);
4309 struct buffer
*obuf
= current_buffer
;
4313 extern int frame_garbaged
;
4316 /* Invalidate pixel data calculated for all compositions. */
4317 for (i
= 0; i
< n_compositions
; i
++)
4318 composition_table
[i
]->font
= NULL
;
4320 Fredraw_frame (w
->frame
);
4321 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
4322 XSETFASTINT (arg
, ht
/ 2);
4324 else if (CONSP (arg
)) /* Just C-u. */
4326 XSETFASTINT (arg
, ht
/ 2);
4330 arg
= Fprefix_numeric_value (arg
);
4331 CHECK_NUMBER (arg
, 0);
4335 XSETINT (arg
, XINT (arg
) + ht
);
4337 set_buffer_internal (buf
);
4338 pos
= *vmotion (PT
, - XINT (arg
), w
);
4340 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
4341 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
4342 || FETCH_BYTE (pos
.bytepos
- 1) == '\n')
4344 w
->force_start
= Qt
;
4345 set_buffer_internal (obuf
);
4351 /* Value is the number of lines actually displayed in window W,
4352 as opposed to its height. */
4355 displayed_window_lines (w
)
4359 struct text_pos start
;
4360 int height
= window_box_height (w
);
4362 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4363 start_display (&it
, w
, start
);
4364 move_it_vertically (&it
, height
);
4366 /* Add in empty lines at the bottom of the window. */
4367 if (it
.current_y
< height
)
4369 struct frame
*f
= XFRAME (w
->frame
);
4370 int rest
= height
- it
.current_y
;
4371 int lines
= (rest
+ CANON_Y_UNIT (f
) - 1) / CANON_Y_UNIT (f
);
4380 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
4382 "Position point relative to window.\n\
4383 With no argument, position point at center of window.\n\
4384 An argument specifies vertical position within the window;\n\
4385 zero means top of window, negative means relative to bottom of window.")
4389 struct window
*w
= XWINDOW (selected_window
);
4393 window
= selected_window
;
4394 start
= marker_position (w
->start
);
4395 if (start
< BEGV
|| start
> ZV
)
4397 int height
= window_internal_height (w
);
4398 Fvertical_motion (make_number (- (height
/ 2)), window
);
4399 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
4400 w
->start_at_line_beg
= Fbolp ();
4401 w
->force_start
= Qt
;
4404 Fgoto_char (w
->start
);
4406 lines
= displayed_window_lines (w
);
4408 XSETFASTINT (arg
, lines
/ 2);
4411 arg
= Fprefix_numeric_value (arg
);
4413 XSETINT (arg
, XINT (arg
) + lines
);
4416 return Fvertical_motion (arg
, window
);
4421 /***********************************************************************
4422 Window Configuration
4423 ***********************************************************************/
4425 struct save_window_data
4427 EMACS_INT size_from_Lisp_Vector_struct
;
4428 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4429 Lisp_Object frame_width
, frame_height
, frame_menu_bar_lines
;
4430 Lisp_Object frame_tool_bar_lines
;
4431 Lisp_Object selected_frame
;
4432 Lisp_Object current_window
;
4433 Lisp_Object current_buffer
;
4434 Lisp_Object minibuf_scroll_window
;
4435 Lisp_Object root_window
;
4436 Lisp_Object focus_frame
;
4437 /* Record the values of window-min-width and window-min-height
4438 so that window sizes remain consistent with them. */
4439 Lisp_Object min_width
, min_height
;
4440 /* A vector, each of whose elements is a struct saved_window
4442 Lisp_Object saved_windows
;
4445 /* This is saved as a Lisp_Vector */
4448 /* these first two must agree with struct Lisp_Vector in lisp.h */
4449 EMACS_INT size_from_Lisp_Vector_struct
;
4450 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4453 Lisp_Object buffer
, start
, pointm
, mark
;
4454 Lisp_Object left
, top
, width
, height
, hscroll
;
4455 Lisp_Object parent
, prev
;
4456 Lisp_Object start_at_line_beg
;
4457 Lisp_Object display_table
;
4459 #define SAVED_WINDOW_VECTOR_SIZE 14 /* Arg to Fmake_vector */
4461 #define SAVED_WINDOW_N(swv,n) \
4462 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
4464 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
4465 "Return t if OBJECT is a window-configuration object.")
4469 if (WINDOW_CONFIGURATIONP (object
))
4474 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
4475 "Return the frame that CONFIG, a window-configuration object, is about.")
4479 register struct save_window_data
*data
;
4480 struct Lisp_Vector
*saved_windows
;
4482 if (! WINDOW_CONFIGURATIONP (config
))
4483 wrong_type_argument (Qwindow_configuration_p
, config
);
4485 data
= (struct save_window_data
*) XVECTOR (config
);
4486 saved_windows
= XVECTOR (data
->saved_windows
);
4487 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4490 DEFUN ("set-window-configuration", Fset_window_configuration
,
4491 Sset_window_configuration
, 1, 1, 0,
4492 "Set the configuration of windows and buffers as specified by CONFIGURATION.\n\
4493 CONFIGURATION must be a value previously returned\n\
4494 by `current-window-configuration' (which see).\n\
4495 If CONFIGURATION was made from a frame that is now deleted,\n\
4496 only frame-independent values can be restored. In this case,\n\
4497 the return value is nil. Otherwise the value is t.")
4499 Lisp_Object configuration
;
4501 register struct save_window_data
*data
;
4502 struct Lisp_Vector
*saved_windows
;
4503 Lisp_Object new_current_buffer
;
4508 while (!WINDOW_CONFIGURATIONP (configuration
))
4509 wrong_type_argument (Qwindow_configuration_p
, configuration
);
4511 data
= (struct save_window_data
*) XVECTOR (configuration
);
4512 saved_windows
= XVECTOR (data
->saved_windows
);
4514 new_current_buffer
= data
->current_buffer
;
4515 if (NILP (XBUFFER (new_current_buffer
)->name
))
4516 new_current_buffer
= Qnil
;
4519 if (XBUFFER (new_current_buffer
) == current_buffer
)
4524 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4527 /* If f is a dead frame, don't bother rebuilding its window tree.
4528 However, there is other stuff we should still try to do below. */
4529 if (FRAME_LIVE_P (f
))
4531 register struct window
*w
;
4532 register struct saved_window
*p
;
4533 struct window
*root_window
;
4534 struct window
**leaf_windows
;
4538 /* If the frame has been resized since this window configuration was
4539 made, we change the frame to the size specified in the
4540 configuration, restore the configuration, and then resize it
4541 back. We keep track of the prevailing height in these variables. */
4542 int previous_frame_height
= FRAME_HEIGHT (f
);
4543 int previous_frame_width
= FRAME_WIDTH (f
);
4544 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
4545 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
4547 /* The mouse highlighting code could get screwed up
4548 if it runs during this. */
4551 if (XFASTINT (data
->frame_height
) != previous_frame_height
4552 || XFASTINT (data
->frame_width
) != previous_frame_width
)
4553 change_frame_size (f
, XFASTINT (data
->frame_height
),
4554 XFASTINT (data
->frame_width
), 0, 0, 0);
4555 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4556 if (XFASTINT (data
->frame_menu_bar_lines
)
4557 != previous_frame_menu_bar_lines
)
4558 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, make_number (0));
4559 #ifdef HAVE_WINDOW_SYSTEM
4560 if (XFASTINT (data
->frame_tool_bar_lines
)
4561 != previous_frame_tool_bar_lines
)
4562 x_set_tool_bar_lines (f
, data
->frame_tool_bar_lines
, make_number (0));
4566 /* "Swap out" point from the selected window
4567 into its buffer. We do this now, before
4568 restoring the window contents, and prevent it from
4569 being done later on when we select a new window. */
4570 if (! NILP (XWINDOW (selected_window
)->buffer
))
4572 w
= XWINDOW (selected_window
);
4573 set_marker_both (w
->pointm
,
4575 BUF_PT (XBUFFER (w
->buffer
)),
4576 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4579 windows_or_buffers_changed
++;
4580 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4582 /* Problem: Freeing all matrices and later allocating them again
4583 is a serious redisplay flickering problem. What we would
4584 really like to do is to free only those matrices not reused
4586 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4588 = (struct window
**) alloca (count_windows (root_window
)
4589 * sizeof (struct window
*));
4590 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
4592 /* Temporarily avoid any problems with windows that are smaller
4593 than they are supposed to be. */
4594 window_min_height
= 1;
4595 window_min_width
= 1;
4598 Mark all windows now on frame as "deleted".
4599 Restoring the new configuration "undeletes" any that are in it.
4601 Save their current buffers in their height fields, since we may
4602 need it later, if a buffer saved in the configuration is now
4604 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4606 for (k
= 0; k
< saved_windows
->size
; k
++)
4608 p
= SAVED_WINDOW_N (saved_windows
, k
);
4609 w
= XWINDOW (p
->window
);
4612 if (!NILP (p
->parent
))
4613 w
->parent
= SAVED_WINDOW_N (saved_windows
,
4614 XFASTINT (p
->parent
))->window
;
4618 if (!NILP (p
->prev
))
4620 w
->prev
= SAVED_WINDOW_N (saved_windows
,
4621 XFASTINT (p
->prev
))->window
;
4622 XWINDOW (w
->prev
)->next
= p
->window
;
4627 if (!NILP (w
->parent
))
4629 if (EQ (p
->width
, XWINDOW (w
->parent
)->width
))
4631 XWINDOW (w
->parent
)->vchild
= p
->window
;
4632 XWINDOW (w
->parent
)->hchild
= Qnil
;
4636 XWINDOW (w
->parent
)->hchild
= p
->window
;
4637 XWINDOW (w
->parent
)->vchild
= Qnil
;
4642 /* If we squirreled away the buffer in the window's height,
4644 if (BUFFERP (w
->height
))
4645 w
->buffer
= w
->height
;
4648 w
->width
= p
->width
;
4649 w
->height
= p
->height
;
4650 w
->hscroll
= p
->hscroll
;
4651 w
->display_table
= p
->display_table
;
4652 XSETFASTINT (w
->last_modified
, 0);
4653 XSETFASTINT (w
->last_overlay_modified
, 0);
4655 /* Reinstall the saved buffer and pointers into it. */
4656 if (NILP (p
->buffer
))
4657 w
->buffer
= p
->buffer
;
4660 if (!NILP (XBUFFER (p
->buffer
)->name
))
4661 /* If saved buffer is alive, install it. */
4663 w
->buffer
= p
->buffer
;
4664 w
->start_at_line_beg
= p
->start_at_line_beg
;
4665 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
4666 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
4667 Fset_marker (XBUFFER (w
->buffer
)->mark
,
4668 p
->mark
, w
->buffer
);
4670 /* As documented in Fcurrent_window_configuration, don't
4671 save the location of point in the buffer which was current
4672 when the window configuration was recorded. */
4673 if (!EQ (p
->buffer
, new_current_buffer
)
4674 && XBUFFER (p
->buffer
) == current_buffer
)
4675 Fgoto_char (w
->pointm
);
4677 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
4678 /* Else unless window has a live buffer, get one. */
4680 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
4681 /* This will set the markers to beginning of visible
4683 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
4684 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
4685 w
->start_at_line_beg
= Qt
;
4688 /* Keeping window's old buffer; make sure the markers
4691 /* Set window markers at start of visible range. */
4692 if (XMARKER (w
->start
)->buffer
== 0)
4693 set_marker_restricted (w
->start
, make_number (0),
4695 if (XMARKER (w
->pointm
)->buffer
== 0)
4696 set_marker_restricted_both (w
->pointm
, w
->buffer
,
4697 BUF_PT (XBUFFER (w
->buffer
)),
4698 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4699 w
->start_at_line_beg
= Qt
;
4704 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
4705 /* Prevent "swapping out point" in the old selected window
4706 using the buffer that has been restored into it.
4707 That swapping out has already been done,
4708 near the beginning of this function. */
4709 selected_window
= Qnil
;
4710 Fselect_window (data
->current_window
);
4711 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
4714 if (NILP (data
->focus_frame
)
4715 || (FRAMEP (data
->focus_frame
)
4716 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
4717 Fredirect_frame_focus (frame
, data
->focus_frame
);
4719 #if 0 /* I don't understand why this is needed, and it causes problems
4720 when the frame's old selected window has been deleted. */
4721 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
4722 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
4726 /* Set the screen height to the value it had before this function. */
4727 if (previous_frame_height
!= FRAME_HEIGHT (f
)
4728 || previous_frame_width
!= FRAME_WIDTH (f
))
4729 change_frame_size (f
, previous_frame_height
, previous_frame_width
,
4731 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4732 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
4733 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
4735 #ifdef HAVE_WINDOW_SYSTEM
4736 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
4737 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
4742 /* Now, free glyph matrices in windows that were not reused. */
4743 for (i
= 0; i
< n_leaf_windows
; ++i
)
4744 if (NILP (leaf_windows
[i
]->buffer
))
4746 /* Assert it's not reused as a combination. */
4747 xassert (NILP (leaf_windows
[i
]->hchild
)
4748 && NILP (leaf_windows
[i
]->vchild
));
4749 free_window_matrices (leaf_windows
[i
]);
4750 SET_FRAME_GARBAGED (f
);
4757 /* Fselect_window will have made f the selected frame, so we
4758 reselect the proper frame here. Fhandle_switch_frame will change the
4759 selected window too, but that doesn't make the call to
4760 Fselect_window above totally superfluous; it still sets f's
4762 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
4763 do_switch_frame (data
->selected_frame
, Qnil
, 0);
4765 if (! NILP (Vwindow_configuration_change_hook
)
4766 && ! NILP (Vrun_hooks
))
4767 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
4770 if (!NILP (new_current_buffer
))
4772 Fset_buffer (new_current_buffer
);
4774 /* If the buffer that is current now is the same
4775 that was current before setting the window configuration,
4776 don't alter its PT. */
4781 /* Restore the minimum heights recorded in the configuration. */
4782 window_min_height
= XINT (data
->min_height
);
4783 window_min_width
= XINT (data
->min_width
);
4785 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
4787 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
4790 /* Mark all windows now on frame as deleted
4791 by setting their buffers to nil. */
4794 delete_all_subwindows (w
)
4795 register struct window
*w
;
4797 if (!NILP (w
->next
))
4798 delete_all_subwindows (XWINDOW (w
->next
));
4799 if (!NILP (w
->vchild
))
4800 delete_all_subwindows (XWINDOW (w
->vchild
));
4801 if (!NILP (w
->hchild
))
4802 delete_all_subwindows (XWINDOW (w
->hchild
));
4804 w
->height
= w
->buffer
; /* See Fset_window_configuration for excuse. */
4806 if (!NILP (w
->buffer
))
4809 /* We set all three of these fields to nil, to make sure that we can
4810 distinguish this dead window from any live window. Live leaf
4811 windows will have buffer set, and combination windows will have
4812 vchild or hchild set. */
4817 Vwindow_list
= Qnil
;
4821 count_windows (window
)
4822 register struct window
*window
;
4824 register int count
= 1;
4825 if (!NILP (window
->next
))
4826 count
+= count_windows (XWINDOW (window
->next
));
4827 if (!NILP (window
->vchild
))
4828 count
+= count_windows (XWINDOW (window
->vchild
));
4829 if (!NILP (window
->hchild
))
4830 count
+= count_windows (XWINDOW (window
->hchild
));
4835 /* Fill vector FLAT with leaf windows under W, starting at index I.
4836 Value is last index + 1. */
4839 get_leaf_windows (w
, flat
, i
)
4841 struct window
**flat
;
4846 if (!NILP (w
->hchild
))
4847 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
4848 else if (!NILP (w
->vchild
))
4849 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
4853 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4860 /* Return a pointer to the glyph W's physical cursor is on. Value is
4861 null if W's current matrix is invalid, so that no meaningfull glyph
4865 get_phys_cursor_glyph (w
)
4868 struct glyph_row
*row
;
4869 struct glyph
*glyph
;
4871 if (w
->phys_cursor
.vpos
>= 0
4872 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
4873 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
4875 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
4876 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
4885 save_window_save (window
, vector
, i
)
4887 struct Lisp_Vector
*vector
;
4890 register struct saved_window
*p
;
4891 register struct window
*w
;
4892 register Lisp_Object tem
;
4894 for (;!NILP (window
); window
= w
->next
)
4896 p
= SAVED_WINDOW_N (vector
, i
);
4897 w
= XWINDOW (window
);
4899 XSETFASTINT (w
->temslot
, i
++);
4901 p
->buffer
= w
->buffer
;
4904 p
->width
= w
->width
;
4905 p
->height
= w
->height
;
4906 p
->hscroll
= w
->hscroll
;
4907 p
->display_table
= w
->display_table
;
4908 if (!NILP (w
->buffer
))
4910 /* Save w's value of point in the window configuration.
4911 If w is the selected window, then get the value of point
4912 from the buffer; pointm is garbage in the selected window. */
4913 if (EQ (window
, selected_window
))
4915 p
->pointm
= Fmake_marker ();
4916 set_marker_both (p
->pointm
, w
->buffer
,
4917 BUF_PT (XBUFFER (w
->buffer
)),
4918 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4921 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
4923 p
->start
= Fcopy_marker (w
->start
, Qnil
);
4924 p
->start_at_line_beg
= w
->start_at_line_beg
;
4926 tem
= XBUFFER (w
->buffer
)->mark
;
4927 p
->mark
= Fcopy_marker (tem
, Qnil
);
4934 p
->start_at_line_beg
= Qnil
;
4937 if (NILP (w
->parent
))
4940 p
->parent
= XWINDOW (w
->parent
)->temslot
;
4945 p
->prev
= XWINDOW (w
->prev
)->temslot
;
4947 if (!NILP (w
->vchild
))
4948 i
= save_window_save (w
->vchild
, vector
, i
);
4949 if (!NILP (w
->hchild
))
4950 i
= save_window_save (w
->hchild
, vector
, i
);
4956 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
4957 Scurrent_window_configuration
, 0, 1, 0,
4958 "Return an object representing the current window configuration of FRAME.\n\
4959 If FRAME is nil or omitted, use the selected frame.\n\
4960 This describes the number of windows, their sizes and current buffers,\n\
4961 and for each displayed buffer, where display starts, and the positions of\n\
4962 point and mark. An exception is made for point in the current buffer:\n\
4963 its value is -not- saved.\n\
4964 This also records the currently selected frame, and FRAME's focus\n\
4965 redirection (see `redirect-frame-focus').")
4969 register Lisp_Object tem
;
4970 register int n_windows
;
4971 register struct save_window_data
*data
;
4972 register struct Lisp_Vector
*vec
;
4977 frame
= selected_frame
;
4978 CHECK_LIVE_FRAME (frame
, 0);
4981 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4982 vec
= allocate_vectorlike (VECSIZE (struct save_window_data
));
4983 for (i
= 0; i
< VECSIZE (struct save_window_data
); i
++)
4984 vec
->contents
[i
] = Qnil
;
4985 vec
->size
= VECSIZE (struct save_window_data
);
4986 data
= (struct save_window_data
*)vec
;
4988 XSETFASTINT (data
->frame_width
, FRAME_WIDTH (f
));
4989 XSETFASTINT (data
->frame_height
, FRAME_HEIGHT (f
));
4990 XSETFASTINT (data
->frame_menu_bar_lines
, FRAME_MENU_BAR_LINES (f
));
4991 XSETFASTINT (data
->frame_tool_bar_lines
, FRAME_TOOL_BAR_LINES (f
));
4992 data
->selected_frame
= selected_frame
;
4993 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
4994 XSETBUFFER (data
->current_buffer
, current_buffer
);
4995 data
->minibuf_scroll_window
= Vminibuf_scroll_window
;
4996 data
->root_window
= FRAME_ROOT_WINDOW (f
);
4997 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
4998 XSETINT (data
->min_height
, window_min_height
);
4999 XSETINT (data
->min_width
, window_min_width
);
5000 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
5001 data
->saved_windows
= tem
;
5002 for (i
= 0; i
< n_windows
; i
++)
5003 XVECTOR (tem
)->contents
[i
]
5004 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
5005 save_window_save (FRAME_ROOT_WINDOW (f
),
5007 XSETWINDOW_CONFIGURATION (tem
, data
);
5011 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
5013 "Execute body, preserving window sizes and contents.\n\
5014 Restore which buffer appears in which window, where display starts,\n\
5015 and the value of point and mark for each window.\n\
5016 Also restore the choice of selected window.\n\
5017 Also restore which buffer is current.\n\
5018 Does not restore the value of point in current buffer.")
5022 register Lisp_Object val
;
5023 register int count
= specpdl_ptr
- specpdl
;
5025 record_unwind_protect (Fset_window_configuration
,
5026 Fcurrent_window_configuration (Qnil
));
5027 val
= Fprogn (args
);
5028 return unbind_to (count
, val
);
5032 /***********************************************************************
5034 ***********************************************************************/
5036 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
5038 "Set width of marginal areas of window WINDOW.\n\
5039 If window is nil, set margins of the currently selected window.\n\
5040 First parameter LEFT-WIDTH specifies the number of character\n\
5041 cells to reserve for the left marginal area. Second parameter\n\
5042 RIGHT-WIDTH does the same for the right marginal area.\n\
5043 A nil width parameter means no margin.")
5044 (window
, left
, right
)
5045 Lisp_Object window
, left
, right
;
5047 struct window
*w
= decode_window (window
);
5050 CHECK_NUMBER_OR_FLOAT (left
, 1);
5052 CHECK_NUMBER_OR_FLOAT (right
, 2);
5054 /* Check widths < 0 and translate a zero width to nil.
5055 Margins that are too wide have to be checked elsewhere. */
5056 if ((INTEGERP (left
) && XINT (left
) < 0)
5057 || (FLOATP (left
) && XFLOAT_DATA (left
) <= 0))
5058 XSETFASTINT (left
, 0);
5059 if (INTEGERP (left
) && XFASTINT (left
) == 0)
5062 if ((INTEGERP (right
) && XINT (right
) < 0)
5063 || (FLOATP (right
) && XFLOAT_DATA (right
) <= 0))
5064 XSETFASTINT (right
, 0);
5065 if (INTEGERP (right
) && XFASTINT (right
) == 0)
5068 w
->left_margin_width
= left
;
5069 w
->right_margin_width
= right
;
5071 ++windows_or_buffers_changed
;
5072 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
5077 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
5079 "Get width of marginal areas of window WINDOW.\n\
5080 If WINDOW is omitted or nil, use the currently selected window.\n\
5081 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).\n\
5082 If a marginal area does not exist, its width will be returned\n\
5087 struct window
*w
= decode_window (window
);
5088 return Fcons (w
->left_margin_width
, w
->right_margin_width
);
5093 /***********************************************************************
5095 ***********************************************************************/
5097 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 1, 0,
5098 "Return the amount by which WINDOW is scrolled vertically.\n\
5099 Use the selected window if WINDOW is nil or omitted.\n\
5100 Value is a multiple of the canonical character height of WINDOW.")
5109 window
= selected_window
;
5111 CHECK_WINDOW (window
, 0);
5112 w
= XWINDOW (window
);
5113 f
= XFRAME (w
->frame
);
5115 if (FRAME_WINDOW_P (f
))
5116 result
= CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
);
5118 result
= make_number (0);
5123 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
5125 "Set amount by which WINDOW should be scrolled vertically to VSCROLL.\n\
5126 WINDOW nil or omitted means use the selected window. VSCROLL is a\n\
5127 non-negative multiple of the canonical character height of WINDOW.")
5129 Lisp_Object window
, vscroll
;
5135 window
= selected_window
;
5137 CHECK_WINDOW (window
, 0);
5138 CHECK_NUMBER_OR_FLOAT (vscroll
, 1);
5140 w
= XWINDOW (window
);
5141 f
= XFRAME (w
->frame
);
5143 if (FRAME_WINDOW_P (f
))
5145 int old_dy
= w
->vscroll
;
5147 w
->vscroll
= - CANON_Y_UNIT (f
) * XFLOATINT (vscroll
);
5148 w
->vscroll
= min (w
->vscroll
, 0);
5150 /* Adjust glyph matrix of the frame if the virtual display
5151 area becomes larger than before. */
5152 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
5155 /* Prevent redisplay shortcuts. */
5156 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
5159 return Fwindow_vscroll (window
);
5163 /* Call FN for all leaf windows on frame F. FN is called with the
5164 first argument being a pointer to the leaf window, and with
5165 additional argument USER_DATA. Stops when FN returns 0. */
5168 foreach_window (f
, fn
, user_data
)
5170 int (* fn
) P_ ((struct window
*, void *));
5173 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, user_data
);
5177 /* Helper function for foreach_window. Call FN for all leaf windows
5178 reachable from W. FN is called with the first argument being a
5179 pointer to the leaf window, and with additional argument USER_DATA.
5180 Stop when FN returns 0. Value is 0 if stopped by FN. */
5183 foreach_window_1 (w
, fn
, user_data
)
5185 int (* fn
) P_ ((struct window
*, void *));
5190 for (cont
= 1; w
&& cont
;)
5192 if (!NILP (w
->hchild
))
5193 cont
= foreach_window_1 (XWINDOW (w
->hchild
), fn
, user_data
);
5194 else if (!NILP (w
->vchild
))
5195 cont
= foreach_window_1 (XWINDOW (w
->vchild
), fn
, user_data
);
5197 cont
= fn (w
, user_data
);
5199 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5206 /* Freeze or unfreeze the window start of W if unless it is a
5207 mini-window or the selected window. FREEZE_P non-null means freeze
5208 the window start. */
5211 freeze_window_start (w
, freeze_p
)
5215 if (w
== XWINDOW (selected_window
)
5216 || MINI_WINDOW_P (w
)
5217 || (MINI_WINDOW_P (XWINDOW (selected_window
))
5218 && ! NILP (Vminibuf_scroll_window
)
5219 && w
== XWINDOW (Vminibuf_scroll_window
)))
5222 w
->frozen_window_start_p
= freeze_p
!= NULL
;
5227 /* Freeze or unfreeze the window starts of all leaf windows on frame
5228 F, except the selected window and a mini-window. FREEZE_P non-zero
5229 means freeze the window start. */
5232 freeze_window_starts (f
, freeze_p
)
5236 foreach_window (f
, freeze_window_start
, (void *) (freeze_p
? f
: 0));
5240 /***********************************************************************
5242 ***********************************************************************/
5244 /* Return 1 if window configurations C1 and C2
5245 describe the same state of affairs. This is used by Fequal. */
5248 compare_window_configurations (c1
, c2
, ignore_positions
)
5250 int ignore_positions
;
5252 register struct save_window_data
*d1
, *d2
;
5253 struct Lisp_Vector
*sw1
, *sw2
;
5256 if (!WINDOW_CONFIGURATIONP (c1
))
5257 wrong_type_argument (Qwindow_configuration_p
, c1
);
5258 if (!WINDOW_CONFIGURATIONP (c2
))
5259 wrong_type_argument (Qwindow_configuration_p
, c2
);
5261 d1
= (struct save_window_data
*) XVECTOR (c1
);
5262 d2
= (struct save_window_data
*) XVECTOR (c2
);
5263 sw1
= XVECTOR (d1
->saved_windows
);
5264 sw2
= XVECTOR (d2
->saved_windows
);
5266 if (! EQ (d1
->frame_width
, d2
->frame_width
))
5268 if (! EQ (d1
->frame_height
, d2
->frame_height
))
5270 if (! EQ (d1
->frame_menu_bar_lines
, d2
->frame_menu_bar_lines
))
5272 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
5274 /* Don't compare the current_window field directly.
5275 Instead see w1_is_current and w2_is_current, below. */
5276 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
5278 if (! ignore_positions
)
5279 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
5281 /* Don't compare the root_window field.
5282 We don't require the two configurations
5283 to use the same window object,
5284 and the two root windows must be equivalent
5285 if everything else compares equal. */
5286 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
5288 if (! EQ (d1
->min_width
, d2
->min_width
))
5290 if (! EQ (d1
->min_height
, d2
->min_height
))
5293 /* Verify that the two confis have the same number of windows. */
5294 if (sw1
->size
!= sw2
->size
)
5297 for (i
= 0; i
< sw1
->size
; i
++)
5299 struct saved_window
*p1
, *p2
;
5300 int w1_is_current
, w2_is_current
;
5302 p1
= SAVED_WINDOW_N (sw1
, i
);
5303 p2
= SAVED_WINDOW_N (sw2
, i
);
5305 /* Verify that the current windows in the two
5306 configurations correspond to each other. */
5307 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
5308 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
5310 if (w1_is_current
!= w2_is_current
)
5313 /* Verify that the corresponding windows do match. */
5314 if (! EQ (p1
->buffer
, p2
->buffer
))
5316 if (! EQ (p1
->left
, p2
->left
))
5318 if (! EQ (p1
->top
, p2
->top
))
5320 if (! EQ (p1
->width
, p2
->width
))
5322 if (! EQ (p1
->height
, p2
->height
))
5324 if (! EQ (p1
->display_table
, p2
->display_table
))
5326 if (! EQ (p1
->parent
, p2
->parent
))
5328 if (! EQ (p1
->prev
, p2
->prev
))
5330 if (! ignore_positions
)
5332 if (! EQ (p1
->hscroll
, p2
->hscroll
))
5334 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
5336 if (NILP (Fequal (p1
->start
, p2
->start
)))
5338 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
5340 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
5348 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
5349 Scompare_window_configurations
, 2, 2, 0,
5350 "Compare two window configurations as regards the structure of windows.\n\
5351 This function ignores details such as the values of point and mark\n\
5352 and scrolling positions.")
5356 if (compare_window_configurations (x
, y
, 1))
5364 struct frame
*f
= make_terminal_frame ();
5365 XSETFRAME (selected_frame
, f
);
5366 Vterminal_frame
= selected_frame
;
5367 minibuf_window
= f
->minibuffer_window
;
5368 selected_window
= f
->selected_window
;
5369 last_nonminibuf_frame
= f
;
5371 window_initialized
= 1;
5377 Vwindow_list
= Qnil
;
5383 Qleft_bitmap_area
= intern ("left-bitmap-area");
5384 staticpro (&Qleft_bitmap_area
);
5385 Qright_bitmap_area
= intern ("right-bitmap-area");
5386 staticpro (&Qright_bitmap_area
);
5388 Qwindow_size_fixed
= intern ("window-size-fixed");
5389 staticpro (&Qwindow_size_fixed
);
5391 staticpro (&Qwindow_configuration_change_hook
);
5392 Qwindow_configuration_change_hook
5393 = intern ("window-configuration-change-hook");
5395 Qwindowp
= intern ("windowp");
5396 staticpro (&Qwindowp
);
5398 Qwindow_configuration_p
= intern ("window-configuration-p");
5399 staticpro (&Qwindow_configuration_p
);
5401 Qwindow_live_p
= intern ("window-live-p");
5402 staticpro (&Qwindow_live_p
);
5404 Qtemp_buffer_show_hook
= intern ("temp-buffer-show-hook");
5405 staticpro (&Qtemp_buffer_show_hook
);
5407 staticpro (&Vwindow_list
);
5409 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
5410 "Non-nil means call as function to display a help buffer.\n\
5411 The function is called with one argument, the buffer to be displayed.\n\
5412 Used by `with-output-to-temp-buffer'.\n\
5413 If this function is used, then it must do the entire job of showing\n\
5414 the buffer; `temp-buffer-show-hook' is not run unless this function runs it.");
5415 Vtemp_buffer_show_function
= Qnil
;
5417 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
5418 "If non-nil, function to call to handle `display-buffer'.\n\
5419 It will receive two args, the buffer and a flag which if non-nil means\n\
5420 that the currently selected window is not acceptable.\n\
5421 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
5422 work using this function.");
5423 Vdisplay_buffer_function
= Qnil
;
5425 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
5426 "Non-nil means it is the window that C-M-v in minibuffer should scroll.");
5427 Vminibuf_scroll_window
= Qnil
;
5429 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
5430 "If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.");
5431 Vother_window_scroll_buffer
= Qnil
;
5433 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
5434 "*Non-nil means `display-buffer' should make a separate frame.");
5437 DEFVAR_BOOL ("display-buffer-reuse-frames", &display_buffer_reuse_frames
,
5438 "*Non-nil means `display-buffer' should reuse frames.\n\
5439 If the buffer in question is already displayed in a frame, raise that frame.");
5440 display_buffer_reuse_frames
= 0;
5442 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
5443 "Function to call to handle automatic new frame creation.\n\
5444 It is called with no arguments and should return a newly created frame.\n\
5446 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'\n\
5447 where `pop-up-frame-alist' would hold the default frame parameters.");
5448 Vpop_up_frame_function
= Qnil
;
5450 DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names
,
5451 "*List of buffer names that should have their own special frames.\n\
5452 Displaying a buffer whose name is in this list makes a special frame for it\n\
5453 using `special-display-function'. See also `special-display-regexps'.\n\
5455 An element of the list can be a list instead of just a string.\n\
5456 There are two ways to use a list as an element:\n\
5457 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)\n\
5458 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5459 In the latter case, FUNCTION is called with BUFFER as the first argument,\n\
5460 followed by OTHER-ARGS--it can display BUFFER in any way it likes.\n\
5461 All this is done by the function found in `special-display-function'.\n\
5463 If this variable appears \"not to work\", because you add a name to it\n\
5464 but that buffer still appears in the selected window, look at the\n\
5465 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5466 Those variables take precedence over this one.");
5467 Vspecial_display_buffer_names
= Qnil
;
5469 DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps
,
5470 "*List of regexps saying which buffers should have their own special frames.\n\
5471 If a buffer name matches one of these regexps, it gets its own frame.\n\
5472 Displaying a buffer whose name is in this list makes a special frame for it\n\
5473 using `special-display-function'.\n\
5475 An element of the list can be a list instead of just a string.\n\
5476 There are two ways to use a list as an element:\n\
5477 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)\n\
5478 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5479 In the latter case, FUNCTION is called with the buffer as first argument,\n\
5480 followed by OTHER-ARGS--it can display the buffer in any way it likes.\n\
5481 All this is done by the function found in `special-display-function'.\n\
5483 If this variable appears \"not to work\", because you add a regexp to it\n\
5484 but the matching buffers still appear in the selected window, look at the\n\
5485 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5486 Those variables take precedence over this one.");
5487 Vspecial_display_regexps
= Qnil
;
5489 DEFVAR_LISP ("special-display-function", &Vspecial_display_function
,
5490 "Function to call to make a new frame for a special buffer.\n\
5491 It is called with two arguments, the buffer and optional buffer specific\n\
5492 data, and should return a window displaying that buffer.\n\
5493 The default value makes a separate frame for the buffer,\n\
5494 using `special-display-frame-alist' to specify the frame parameters.\n\
5496 A buffer is special if its is listed in `special-display-buffer-names'\n\
5497 or matches a regexp in `special-display-regexps'.");
5498 Vspecial_display_function
= Qnil
;
5500 DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names
,
5501 "*List of buffer names that should appear in the selected window.\n\
5502 Displaying one of these buffers using `display-buffer' or `pop-to-buffer'\n\
5503 switches to it in the selected window, rather than making it appear\n\
5504 in some other window.\n\
5506 An element of the list can be a cons cell instead of just a string.\n\
5507 Then the car must be a string, which specifies the buffer name.\n\
5508 This is for compatibility with `special-display-buffer-names';\n\
5509 the cdr of the cons cell is ignored.\n\
5511 See also `same-window-regexps'.");
5512 Vsame_window_buffer_names
= Qnil
;
5514 DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps
,
5515 "*List of regexps saying which buffers should appear in the selected window.\n\
5516 If a buffer name matches one of these regexps, then displaying it\n\
5517 using `display-buffer' or `pop-to-buffer' switches to it\n\
5518 in the selected window, rather than making it appear in some other window.\n\
5520 An element of the list can be a cons cell instead of just a string.\n\
5521 Then the car must be a string, which specifies the buffer name.\n\
5522 This is for compatibility with `special-display-buffer-names';\n\
5523 the cdr of the cons cell is ignored.\n\
5525 See also `same-window-buffer-names'.");
5526 Vsame_window_regexps
= Qnil
;
5528 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
5529 "*Non-nil means display-buffer should make new windows.");
5532 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
5533 "*Number of lines of continuity when scrolling by screenfuls.");
5534 next_screen_context_lines
= 2;
5536 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
5537 "*display-buffer would prefer to split the largest window if this large.\n\
5538 If there is only one window, it is split regardless of this value.");
5539 split_height_threshold
= 500;
5541 DEFVAR_INT ("window-min-height", &window_min_height
,
5542 "*Delete any window less than this tall (including its mode line).");
5543 window_min_height
= 4;
5545 DEFVAR_INT ("window-min-width", &window_min_width
,
5546 "*Delete any window less than this wide.");
5547 window_min_width
= 10;
5549 DEFVAR_LISP ("scroll-preserve-screen-position",
5550 &Vscroll_preserve_screen_position
,
5551 "*Nonzero means scroll commands move point to keep its screen line unchanged.");
5552 Vscroll_preserve_screen_position
= Qnil
;
5554 DEFVAR_LISP ("window-configuration-change-hook",
5555 &Vwindow_configuration_change_hook
,
5556 "Functions to call when window configuration changes.\n\
5557 The selected frame is the one whose configuration has changed.");
5558 Vwindow_configuration_change_hook
= Qnil
;
5560 defsubr (&Sselected_window
);
5561 defsubr (&Sminibuffer_window
);
5562 defsubr (&Swindow_minibuffer_p
);
5563 defsubr (&Swindowp
);
5564 defsubr (&Swindow_live_p
);
5565 defsubr (&Spos_visible_in_window_p
);
5566 defsubr (&Swindow_buffer
);
5567 defsubr (&Swindow_height
);
5568 defsubr (&Swindow_width
);
5569 defsubr (&Swindow_hscroll
);
5570 defsubr (&Sset_window_hscroll
);
5571 defsubr (&Swindow_redisplay_end_trigger
);
5572 defsubr (&Sset_window_redisplay_end_trigger
);
5573 defsubr (&Swindow_edges
);
5574 defsubr (&Scoordinates_in_window_p
);
5575 defsubr (&Swindow_at
);
5576 defsubr (&Swindow_point
);
5577 defsubr (&Swindow_start
);
5578 defsubr (&Swindow_end
);
5579 defsubr (&Sset_window_point
);
5580 defsubr (&Sset_window_start
);
5581 defsubr (&Swindow_dedicated_p
);
5582 defsubr (&Sset_window_dedicated_p
);
5583 defsubr (&Swindow_display_table
);
5584 defsubr (&Sset_window_display_table
);
5585 defsubr (&Snext_window
);
5586 defsubr (&Sprevious_window
);
5587 defsubr (&Sother_window
);
5588 defsubr (&Sget_lru_window
);
5589 defsubr (&Sget_largest_window
);
5590 defsubr (&Sget_buffer_window
);
5591 defsubr (&Sdelete_other_windows
);
5592 defsubr (&Sdelete_windows_on
);
5593 defsubr (&Sreplace_buffer_in_windows
);
5594 defsubr (&Sdelete_window
);
5595 defsubr (&Sset_window_buffer
);
5596 defsubr (&Sselect_window
);
5597 defsubr (&Sspecial_display_p
);
5598 defsubr (&Ssame_window_p
);
5599 defsubr (&Sdisplay_buffer
);
5600 defsubr (&Ssplit_window
);
5601 defsubr (&Senlarge_window
);
5602 defsubr (&Sshrink_window
);
5603 defsubr (&Sscroll_up
);
5604 defsubr (&Sscroll_down
);
5605 defsubr (&Sscroll_left
);
5606 defsubr (&Sscroll_right
);
5607 defsubr (&Sother_window_for_scrolling
);
5608 defsubr (&Sscroll_other_window
);
5609 defsubr (&Srecenter
);
5610 defsubr (&Smove_to_window_line
);
5611 defsubr (&Swindow_configuration_p
);
5612 defsubr (&Swindow_configuration_frame
);
5613 defsubr (&Sset_window_configuration
);
5614 defsubr (&Scurrent_window_configuration
);
5615 defsubr (&Ssave_window_excursion
);
5616 defsubr (&Sset_window_margins
);
5617 defsubr (&Swindow_margins
);
5618 defsubr (&Swindow_vscroll
);
5619 defsubr (&Sset_window_vscroll
);
5620 defsubr (&Scompare_window_configurations
);
5621 defsubr (&Swindow_list
);
5627 initial_define_key (control_x_map
, '1', "delete-other-windows");
5628 initial_define_key (control_x_map
, '2', "split-window");
5629 initial_define_key (control_x_map
, '0', "delete-window");
5630 initial_define_key (control_x_map
, 'o', "other-window");
5631 initial_define_key (control_x_map
, '^', "enlarge-window");
5632 initial_define_key (control_x_map
, '<', "scroll-left");
5633 initial_define_key (control_x_map
, '>', "scroll-right");
5635 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
5636 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
5637 initial_define_key (meta_map
, 'v', "scroll-down");
5639 initial_define_key (global_map
, Ctl('L'), "recenter");
5640 initial_define_key (meta_map
, 'r', "move-to-window-line");