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 void foreach_window_1
P_ ((struct window
*, void (*fn
) (), int, int,
67 static void freeze_window_start
P_ ((struct window
*, int));
68 static int window_fixed_size_p
P_ ((struct window
*, int, int));
69 static void enlarge_window
P_ ((Lisp_Object
, int, int));
72 /* This is the window in which the terminal's cursor should
73 be left when nothing is being done with it. This must
74 always be a leaf window, and its buffer is selected by
75 the top level editing loop at the end of each command.
77 This value is always the same as
78 FRAME_SELECTED_WINDOW (selected_frame). */
80 Lisp_Object selected_window
;
82 /* The mini-buffer window of the selected frame.
83 Note that you cannot test for mini-bufferness of an arbitrary window
84 by comparing against this; but you can test for mini-bufferness of
85 the selected window. */
87 Lisp_Object minibuf_window
;
89 /* Non-nil means it is the window for C-M-v to scroll
90 when the mini-buffer is selected. */
92 Lisp_Object Vminibuf_scroll_window
;
94 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
96 Lisp_Object Vother_window_scroll_buffer
;
98 /* Non-nil means it's function to call to display temp buffers. */
100 Lisp_Object Vtemp_buffer_show_function
;
102 /* If a window gets smaller than either of these, it is removed. */
104 int window_min_height
;
105 int window_min_width
;
107 /* Nonzero implies Fdisplay_buffer should create windows. */
111 /* Nonzero implies make new frames for Fdisplay_buffer. */
115 /* Non-nil means use this function instead of default */
117 Lisp_Object Vpop_up_frame_function
;
119 /* Function to call to handle Fdisplay_buffer. */
121 Lisp_Object Vdisplay_buffer_function
;
123 /* List of buffer *names* for buffers that should have their own frames. */
125 Lisp_Object Vspecial_display_buffer_names
;
127 /* List of regexps for buffer names that should have their own frames. */
129 Lisp_Object Vspecial_display_regexps
;
131 /* Function to pop up a special frame. */
133 Lisp_Object Vspecial_display_function
;
135 /* List of buffer *names* for buffers to appear in selected window. */
137 Lisp_Object Vsame_window_buffer_names
;
139 /* List of regexps for buffer names to appear in selected window. */
141 Lisp_Object Vsame_window_regexps
;
143 /* Hook run at end of temp_output_buffer_show. */
145 Lisp_Object Qtemp_buffer_show_hook
;
147 /* Fdisplay_buffer always splits the largest window
148 if that window is more than this high. */
150 int split_height_threshold
;
152 /* Number of lines of continuity in scrolling by screenfuls. */
154 int next_screen_context_lines
;
156 /* Incremented for each window created. */
158 static int sequence_number
;
160 /* Nonzero after init_window_once has finished. */
162 static int window_initialized
;
164 /* Hook to run when window config changes. */
166 Lisp_Object Qwindow_configuration_change_hook
;
167 Lisp_Object Vwindow_configuration_change_hook
;
169 /* Nonzero means scroll commands try to put point
170 at the same screen height as previously. */
172 Lisp_Object Vscroll_preserve_screen_position
;
174 #if 0 /* This isn't used anywhere. */
175 /* Nonzero means we can split a frame even if it is "unsplittable". */
176 static int inhibit_frame_unsplittable
;
179 #define min(a, b) ((a) < (b) ? (a) : (b))
181 extern int scroll_margin
;
183 extern Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
185 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
186 "Returns t if OBJECT is a window.")
190 return WINDOWP (object
) ? Qt
: Qnil
;
193 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
194 "Returns t if OBJECT is a window which is currently visible.")
198 return (WINDOWP (object
) && ! NILP (XWINDOW (object
)->buffer
) ? Qt
: Qnil
);
205 register struct window
*p
;
206 register struct Lisp_Vector
*vec
;
209 vec
= allocate_vectorlike ((EMACS_INT
) VECSIZE (struct window
));
210 for (i
= 0; i
< VECSIZE (struct window
); i
++)
211 vec
->contents
[i
] = Qnil
;
212 vec
->size
= VECSIZE (struct window
);
213 p
= (struct window
*) vec
;
214 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
215 XSETFASTINT (p
->left
, 0);
216 XSETFASTINT (p
->top
, 0);
217 XSETFASTINT (p
->height
, 0);
218 XSETFASTINT (p
->width
, 0);
219 XSETFASTINT (p
->hscroll
, 0);
220 p
->orig_top
= p
->orig_height
= Qnil
;
221 p
->start
= Fmake_marker ();
222 p
->pointm
= Fmake_marker ();
223 XSETFASTINT (p
->use_time
, 0);
225 p
->display_table
= Qnil
;
227 p
->pseudo_window_p
= 0;
228 bzero (&p
->cursor
, sizeof (p
->cursor
));
229 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
230 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
231 p
->desired_matrix
= p
->current_matrix
= 0;
232 p
->phys_cursor_type
= -1;
233 p
->must_be_updated_p
= 0;
234 XSETFASTINT (p
->window_end_vpos
, 0);
235 XSETFASTINT (p
->window_end_pos
, 0);
236 p
->window_end_valid
= Qnil
;
239 XSETFASTINT (p
->last_point
, 0);
240 p
->frozen_window_start_p
= 0;
244 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
245 "Return the window that the cursor now appears in and commands apply to.")
248 return selected_window
;
251 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
252 "Return the window used now for minibuffers.\n\
253 If the optional argument FRAME is specified, return the minibuffer window\n\
254 used by that frame.")
259 frame
= selected_frame
;
260 CHECK_LIVE_FRAME (frame
, 0);
261 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
264 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 0, 1, 0,
265 "Returns non-nil if WINDOW is a minibuffer window.")
269 struct window
*w
= decode_window (window
);
270 return (MINI_WINDOW_P (w
) ? Qt
: Qnil
);
273 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
274 Spos_visible_in_window_p
, 0, 2, 0,
275 "Return t if position POS is currently on the frame in WINDOW.\n\
276 Returns nil if that position is scrolled vertically out of view.\n\
277 POS defaults to point; WINDOW, to the selected window.")
279 Lisp_Object pos
, window
;
281 register struct window
*w
;
283 register struct buffer
*buf
;
285 Lisp_Object in_window
;
291 CHECK_NUMBER_COERCE_MARKER (pos
, 0);
295 w
= decode_window (window
);
296 buf
= XBUFFER (w
->buffer
);
297 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
299 /* If position above window, it's not visible. */
300 if (posint
< CHARPOS (top
))
302 else if (XFASTINT (w
->last_modified
) >= BUF_MODIFF (buf
)
303 && XFASTINT (w
->last_overlay_modified
) >= BUF_OVERLAY_MODIFF (buf
)
304 && posint
< BUF_Z (buf
) - XFASTINT (w
->window_end_pos
))
305 /* If frame is up to date, and POSINT is < window end pos, use
306 that info. This doesn't work for POSINT == end pos, because
307 the window end pos is actually the position _after_ the last
308 char in the window. */
310 else if (posint
> BUF_ZV (buf
))
312 else if (CHARPOS (top
) < BUF_BEGV (buf
) || CHARPOS (top
) > BUF_ZV (buf
))
313 /* If window start is out of range, do something reasonable. */
318 start_display (&it
, w
, top
);
319 move_it_to (&it
, posint
, 0, it
.last_visible_y
, -1,
320 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
321 in_window
= IT_CHARPOS (it
) == posint
? Qt
: Qnil
;
327 static struct window
*
328 decode_window (window
)
329 register Lisp_Object window
;
332 return XWINDOW (selected_window
);
334 CHECK_LIVE_WINDOW (window
, 0);
335 return XWINDOW (window
);
338 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
339 "Return the buffer that WINDOW is displaying.")
343 return decode_window (window
)->buffer
;
346 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
347 "Return the number of lines in WINDOW (including its mode line).")
351 return decode_window (window
)->height
;
354 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
355 "Return the number of display columns in WINDOW.\n\
356 This is the width that is usable columns available for text in WINDOW.\n\
357 If you want to find out how many columns WINDOW takes up,\n\
358 use (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))).")
362 return make_number (window_internal_width (decode_window (window
)));
365 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
366 "Return the number of columns by which WINDOW is scrolled from left margin.")
370 return decode_window (window
)->hscroll
;
373 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
374 "Set number of columns WINDOW is scrolled from left margin to NCOL.\n\
375 NCOL should be zero or positive.")
377 register Lisp_Object window
, ncol
;
379 register struct window
*w
;
381 CHECK_NUMBER (ncol
, 1);
382 if (XINT (ncol
) < 0) XSETFASTINT (ncol
, 0);
383 w
= decode_window (window
);
384 if (XINT (w
->hscroll
) != XINT (ncol
))
385 /* Prevent redisplay shortcuts */
386 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
391 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
392 Swindow_redisplay_end_trigger
, 0, 1, 0,
393 "Return WINDOW's redisplay end trigger value.\n\
394 See `set-window-redisplay-end-trigger' for more information.")
398 return decode_window (window
)->redisplay_end_trigger
;
401 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
402 Sset_window_redisplay_end_trigger
, 2, 2, 0,
403 "Set WINDOW's redisplay end trigger value to VALUE.\n\
404 VALUE should be a buffer position (typically a marker) or nil.\n\
405 If it is a buffer position, then if redisplay in WINDOW reaches a position\n\
406 beyond VALUE, the functions in `redisplay-end-trigger-functions' are called\n\
407 with two arguments: WINDOW, and the end trigger value.\n\
408 Afterwards the end-trigger value is reset to nil.")
410 register Lisp_Object window
, value
;
412 register struct window
*w
;
414 w
= decode_window (window
);
415 w
->redisplay_end_trigger
= value
;
419 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
420 "Return a list of the edge coordinates of WINDOW.\n\
421 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.\n\
422 RIGHT is one more than the rightmost column used by WINDOW,\n\
423 and BOTTOM is one more than the bottommost row used by WINDOW\n\
428 register struct window
*w
= decode_window (window
);
430 return Fcons (w
->left
, Fcons (w
->top
,
431 Fcons (make_number (WINDOW_RIGHT_EDGE (w
)),
432 Fcons (make_number (XFASTINT (w
->top
)
433 + XFASTINT (w
->height
)),
437 /* Test if the character at column *X, row *Y is within window W.
438 If it is not, return 0;
439 if it is in the window's text area,
440 set *x and *y to its location relative to the upper left corner
443 if it is on the window's modeline, return 2;
444 if it is on the border between the window and its right sibling,
446 if it is on the window's top line, return 4;
447 if it is in the bitmap area to the left/right of the window,
448 return 5 or 6, and convert *X and *Y to window-relative corrdinates.
450 X and Y are frame relative pixel coordinates. */
453 coordinates_in_window (w
, x
, y
)
454 register struct window
*w
;
457 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
458 int left_x
, right_x
, top_y
, bottom_y
;
459 int flags_area_width
= FRAME_LEFT_FLAGS_AREA_WIDTH (f
);
461 if (w
->pseudo_window_p
)
464 right_x
= XFASTINT (w
->width
) * CANON_Y_UNIT (f
);
465 top_y
= WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
);
466 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
470 left_x
= (WINDOW_DISPLAY_LEFT_EDGE_PIXEL_X (w
)
471 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
472 right_x
= WINDOW_DISPLAY_RIGHT_EDGE_PIXEL_X (w
);
473 top_y
= (WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
)
474 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
475 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
482 - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
)
484 || *x
> right_x
+ flags_area_width
)
485 /* Completely outside anything interesting. */
487 else if (WINDOW_WANTS_MODELINE_P (w
)
488 && *y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
))
489 /* On the mode line. */
491 else if (WINDOW_WANTS_HEADER_LINE_P (w
)
492 && *y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
))
493 /* On the top line. */
495 else if (*x
< left_x
|| *x
>= right_x
)
497 /* Other lines than the mode line don't include flags areas and
498 scroll bars on the left. */
500 /* Convert X and Y to window-relative pixel coordinates. */
503 return *x
< left_x
? 5 : 6;
505 else if (!w
->pseudo_window_p
506 && !WINDOW_RIGHTMOST_P (w
)
507 && *x
>= right_x
- CANON_X_UNIT (f
))
508 /* On the border on the right side of the window? Assume that
509 this area begins at RIGHT_X minus a canonical char width. */
513 /* Convert X and Y to window-relative pixel coordinates. */
520 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
521 Scoordinates_in_window_p
, 2, 2, 0,
522 "Return non-nil if COORDINATES are in WINDOW.\n\
523 COORDINATES is a cons of the form (X . Y), X and Y being distances\n\
524 measured in characters from the upper-left corner of the frame.\n\
525 (0 . 0) denotes the character in the upper left corner of the\n\
527 If COORDINATES are in the text portion of WINDOW,\n\
528 the coordinates relative to the window are returned.\n\
529 If they are in the mode line of WINDOW, `mode-line' is returned.\n\
530 If they are in the top mode line of WINDOW, `header-line' is returned.\n\
531 If they are in the bitmap-area to the left of the window,\n\
532 `left-bitmap-area' is returned, if they are in the area on the right of\n\
533 the window, `right-bitmap-area' is returned.\n\
534 If they are on the border between WINDOW and its right sibling,\n\
535 `vertical-line' is returned.")
536 (coordinates
, window
)
537 register Lisp_Object coordinates
, window
;
544 CHECK_LIVE_WINDOW (window
, 0);
545 w
= XWINDOW (window
);
546 f
= XFRAME (w
->frame
);
547 CHECK_CONS (coordinates
, 1);
548 lx
= Fcar (coordinates
);
549 ly
= Fcdr (coordinates
);
550 CHECK_NUMBER_OR_FLOAT (lx
, 1);
551 CHECK_NUMBER_OR_FLOAT (ly
, 1);
552 x
= PIXEL_X_FROM_CANON_X (f
, lx
);
553 y
= PIXEL_Y_FROM_CANON_Y (f
, ly
);
555 switch (coordinates_in_window (w
, &x
, &y
))
557 case 0: /* NOT in window at all. */
560 case 1: /* In text part of window. */
561 /* X and Y are now window relative pixel coordinates.
562 Convert them to canonical char units before returning
564 return Fcons (CANON_X_FROM_PIXEL_X (f
, x
),
565 CANON_Y_FROM_PIXEL_Y (f
, y
));
567 case 2: /* In mode line of window. */
570 case 3: /* On right border of window. */
571 return Qvertical_line
;
577 return Qleft_bitmap_area
;
580 return Qright_bitmap_area
;
587 /* Find the window containing frame-relative pixel position X/Y and
588 return it as a Lisp_Object. If X, Y is on the window's modeline,
589 set *PART to 1; if it is on the separating line between the window
590 and its right sibling, set it to 2; otherwise set it to 0. If
591 there is no window under X, Y return nil and leave *PART
592 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows. */
595 window_from_coordinates (frame
, x
, y
, part
, tool_bar_p
)
601 register Lisp_Object tem
, first
;
604 tem
= first
= FRAME_SELECTED_WINDOW (frame
);
608 found
= coordinates_in_window (XWINDOW (tem
), &x
, &y
);
616 tem
= Fnext_window (tem
, Qt
, Qlambda
);
618 while (!EQ (tem
, first
));
620 /* See if it's in the tool bar window, if a tool bar exists. */
622 && WINDOWP (frame
->tool_bar_window
)
623 && XFASTINT (XWINDOW (frame
->tool_bar_window
)->height
)
624 && coordinates_in_window (XWINDOW (frame
->tool_bar_window
), &x
, &y
))
627 return frame
->tool_bar_window
;
633 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
634 "Return window containing coordinates X and Y on FRAME.\n\
635 If omitted, FRAME defaults to the currently selected frame.\n\
636 The top left corner of the frame is considered to be row 0,\n\
639 Lisp_Object x
, y
, frame
;
645 frame
= selected_frame
;
646 CHECK_LIVE_FRAME (frame
, 2);
649 /* Check that arguments are integers or floats. */
650 CHECK_NUMBER_OR_FLOAT (x
, 0);
651 CHECK_NUMBER_OR_FLOAT (y
, 1);
653 return window_from_coordinates (f
,
654 PIXEL_X_FROM_CANON_X (f
, x
),
655 PIXEL_Y_FROM_CANON_Y (f
, y
),
659 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
660 "Return current value of point in WINDOW.\n\
661 For a nonselected window, this is the value point would have\n\
662 if that window were selected.\n\
664 Note that, when WINDOW is the selected window and its buffer\n\
665 is also currently selected, the value returned is the same as (point).\n\
666 It would be more strictly correct to return the `top-level' value\n\
667 of point, outside of any save-excursion forms.\n\
668 But that is hard to define.")
672 register struct window
*w
= decode_window (window
);
674 if (w
== XWINDOW (selected_window
)
675 && current_buffer
== XBUFFER (w
->buffer
))
677 return Fmarker_position (w
->pointm
);
680 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
681 "Return position at which display currently starts in WINDOW.\n\
682 This is updated by redisplay or by calling `set-window-start'.")
686 return Fmarker_position (decode_window (window
)->start
);
689 /* This is text temporarily removed from the doc string below.
691 This function returns nil if the position is not currently known.\n\
692 That happens when redisplay is preempted and doesn't finish.\n\
693 If in that case you want to compute where the end of the window would\n\
694 have been if redisplay had finished, do this:\n\
696 (goto-char (window-start window))\n\
697 (vertical-motion (1- (window-height window)) window)\n\
700 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
701 "Return position at which display currently ends in WINDOW.\n\
702 This is updated by redisplay, when it runs to completion.\n\
703 Simply changing the buffer text or setting `window-start'\n\
704 does not update this value.\n\
705 If UP-TO-DATE is non-nil, compute the up-to-date position\n\
706 if it isn't already recorded.")
708 Lisp_Object window
, update
;
711 struct window
*w
= decode_window (window
);
715 CHECK_BUFFER (buf
, 0);
717 #if 0 /* This change broke some things. We should make it later. */
718 /* If we don't know the end position, return nil.
719 The user can compute it with vertical-motion if he wants to.
720 It would be nicer to do it automatically,
721 but that's so slow that it would probably bother people. */
722 if (NILP (w
->window_end_valid
))
727 && ! (! NILP (w
->window_end_valid
)
728 && XFASTINT (w
->last_modified
) >= MODIFF
))
730 int opoint
= PT
, opoint_byte
= PT_BYTE
;
732 /* In case W->start is out of the range, use something
733 reasonable. This situation occured when loading a file with
734 `-l' containing a call to `rmail' with subsequent other
735 commands. At the end, W->start happened to be BEG, while
736 rmail had already narrowed the buffer. This leads to an
737 abort in temp_set_pt_both. */
738 if (XMARKER (w
->start
)->charpos
< BEGV
)
739 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
740 else if (XMARKER (w
->start
)->charpos
> ZV
)
741 TEMP_SET_PT_BOTH (ZV
, ZV_BYTE
);
743 TEMP_SET_PT_BOTH (XMARKER (w
->start
)->charpos
,
744 XMARKER (w
->start
)->bytepos
);
746 Fvertical_motion (make_number (window_internal_height (w
)), Qnil
);
748 TEMP_SET_PT_BOTH (opoint
, opoint_byte
);
752 BUF_Z (XBUFFER (buf
)) - XFASTINT (w
->window_end_pos
));
757 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
758 "Make point value in WINDOW be at position POS in WINDOW's buffer.")
760 Lisp_Object window
, pos
;
762 register struct window
*w
= decode_window (window
);
764 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
765 if (w
== XWINDOW (selected_window
)
766 && XBUFFER (w
->buffer
) == current_buffer
)
769 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
774 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
775 "Make display in WINDOW start at position POS in WINDOW's buffer.\n\
776 Optional third arg NOFORCE non-nil inhibits next redisplay\n\
777 from overriding motion of point in order to display at this exact start.")
778 (window
, pos
, noforce
)
779 Lisp_Object window
, pos
, noforce
;
781 register struct window
*w
= decode_window (window
);
783 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
784 set_marker_restricted (w
->start
, pos
, w
->buffer
);
785 /* this is not right, but much easier than doing what is right. */
786 w
->start_at_line_beg
= Qnil
;
789 w
->update_mode_line
= Qt
;
790 XSETFASTINT (w
->last_modified
, 0);
791 XSETFASTINT (w
->last_overlay_modified
, 0);
792 if (!EQ (window
, selected_window
))
793 windows_or_buffers_changed
++;
798 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
800 "Return WINDOW's dedicated object, usually t or nil.\n\
801 See also `set-window-dedicated-p'.")
805 return decode_window (window
)->dedicated
;
808 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
809 Sset_window_dedicated_p
, 2, 2, 0,
810 "Control whether WINDOW is dedicated to the buffer it displays.\n\
811 If it is dedicated, Emacs will not automatically change\n\
812 which buffer appears in it.\n\
813 The second argument is the new value for the dedication flag;\n\
816 Lisp_Object window
, arg
;
818 register struct window
*w
= decode_window (window
);
828 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
830 "Return the display-table that WINDOW is using.")
834 return decode_window (window
)->display_table
;
837 /* Get the display table for use on window W. This is either W's
838 display table or W's buffer's display table. Ignore the specified
839 tables if they are not valid; if no valid table is specified,
842 struct Lisp_Char_Table
*
843 window_display_table (w
)
847 tem
= w
->display_table
;
848 if (DISP_TABLE_P (tem
))
849 return XCHAR_TABLE (tem
);
850 if (NILP (w
->buffer
))
853 tem
= XBUFFER (w
->buffer
)->display_table
;
854 if (DISP_TABLE_P (tem
))
855 return XCHAR_TABLE (tem
);
856 tem
= Vstandard_display_table
;
857 if (DISP_TABLE_P (tem
))
858 return XCHAR_TABLE (tem
);
862 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
863 "Set WINDOW's display-table to TABLE.")
865 register Lisp_Object window
, table
;
867 register struct window
*w
;
869 w
= decode_window (window
);
870 w
->display_table
= table
;
874 /* Record info on buffer window w is displaying
875 when it is about to cease to display that buffer. */
878 register struct window
*w
;
885 if (b
!= XMARKER (w
->pointm
)->buffer
)
889 if (w
== XWINDOW (selected_window
)
890 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
891 /* Do this except when the selected window's buffer
892 is being removed from some other window. */
894 /* last_window_start records the start position that this buffer
895 had in the last window to be disconnected from it.
896 Now that this statement is unconditional,
897 it is possible for the buffer to be displayed in the
898 selected window, while last_window_start reflects another
899 window which was recently showing the same buffer.
900 Some people might say that might be a good thing. Let's see. */
901 b
->last_window_start
= marker_position (w
->start
);
903 /* Point in the selected window's buffer
904 is actually stored in that buffer, and the window's pointm isn't used.
905 So don't clobber point in that buffer. */
906 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
)
907 /* This line helps to fix Horsley's testbug.el bug. */
908 && !(WINDOWP (b
->last_selected_window
)
909 && w
!= XWINDOW (b
->last_selected_window
)
910 && EQ (buf
, XWINDOW (b
->last_selected_window
)->buffer
)))
911 temp_set_point_both (b
,
912 clip_to_bounds (BUF_BEGV (b
),
913 XMARKER (w
->pointm
)->charpos
,
915 clip_to_bounds (BUF_BEGV_BYTE (b
),
916 marker_byte_position (w
->pointm
),
919 if (WINDOWP (b
->last_selected_window
)
920 && w
== XWINDOW (b
->last_selected_window
))
921 b
->last_selected_window
= Qnil
;
924 /* Put replacement into the window structure in place of old. */
926 replace_window (old
, replacement
)
927 Lisp_Object old
, replacement
;
929 register Lisp_Object tem
;
930 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
932 /* If OLD is its frame's root_window, then replacement is the new
933 root_window for that frame. */
935 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
936 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
941 p
->height
= o
->height
;
942 p
->desired_matrix
= p
->current_matrix
= 0;
944 bzero (&p
->cursor
, sizeof (p
->cursor
));
945 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
946 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
947 p
->phys_cursor_type
= -1;
948 p
->must_be_updated_p
= 0;
949 p
->pseudo_window_p
= 0;
950 XSETFASTINT (p
->window_end_vpos
, 0);
951 XSETFASTINT (p
->window_end_pos
, 0);
952 p
->window_end_valid
= Qnil
;
953 p
->frozen_window_start_p
= 0;
954 p
->orig_top
= p
->orig_height
= Qnil
;
956 p
->next
= tem
= o
->next
;
958 XWINDOW (tem
)->prev
= replacement
;
960 p
->prev
= tem
= o
->prev
;
962 XWINDOW (tem
)->next
= replacement
;
964 p
->parent
= tem
= o
->parent
;
967 if (EQ (XWINDOW (tem
)->vchild
, old
))
968 XWINDOW (tem
)->vchild
= replacement
;
969 if (EQ (XWINDOW (tem
)->hchild
, old
))
970 XWINDOW (tem
)->hchild
= replacement
;
973 /*** Here, if replacement is a vertical combination
974 and so is its new parent, we should make replacement's
975 children be children of that parent instead. ***/
978 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
979 "Remove WINDOW from the display. Default is selected window.")
981 register Lisp_Object window
;
983 delete_window (window
);
985 if (! NILP (Vwindow_configuration_change_hook
)
986 && ! NILP (Vrun_hooks
))
987 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
993 delete_window (window
)
994 register Lisp_Object window
;
996 register Lisp_Object tem
, parent
, sib
;
997 register struct window
*p
;
998 register struct window
*par
;
1001 /* Because this function is called by other C code on non-leaf
1002 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1003 so we can't decode_window here. */
1005 window
= selected_window
;
1007 CHECK_WINDOW (window
, 0);
1008 p
= XWINDOW (window
);
1010 /* It's okay to delete an already-deleted window. */
1011 if (NILP (p
->buffer
)
1013 && NILP (p
->vchild
))
1018 error ("Attempt to delete minibuffer or sole ordinary window");
1019 par
= XWINDOW (parent
);
1021 windows_or_buffers_changed
++;
1022 frame
= XFRAME (WINDOW_FRAME (p
));
1023 FRAME_WINDOW_SIZES_CHANGED (frame
) = 1;
1025 /* Are we trying to delete any frame's selected window? */
1027 Lisp_Object frame
, pwindow
;
1029 /* See if the frame's selected window is either WINDOW
1030 or any subwindow of it, by finding all that window's parents
1031 and comparing each one with WINDOW. */
1032 frame
= WINDOW_FRAME (XWINDOW (window
));
1033 pwindow
= FRAME_SELECTED_WINDOW (XFRAME (frame
));
1035 while (!NILP (pwindow
))
1037 if (EQ (window
, pwindow
))
1039 pwindow
= XWINDOW (pwindow
)->parent
;
1042 if (EQ (window
, pwindow
))
1044 Lisp_Object alternative
;
1045 alternative
= Fnext_window (window
, Qlambda
, Qnil
);
1047 /* If we're about to delete the selected window on the
1048 selected frame, then we should use Fselect_window to select
1049 the new window. On the other hand, if we're about to
1050 delete the selected window on any other frame, we shouldn't do
1051 anything but set the frame's selected_window slot. */
1052 if (EQ (window
, selected_window
))
1053 Fselect_window (alternative
);
1055 FRAME_SELECTED_WINDOW (XFRAME (frame
)) = alternative
;
1060 /* tem is null for dummy parent windows
1061 (which have inferiors but not any contents themselves) */
1065 unchain_marker (p
->pointm
);
1066 unchain_marker (p
->start
);
1069 /* Free window glyph matrices. It is sure that they are allocated
1070 again when ADJUST_GLYPHS is called. Block input so that expose
1071 events and other events that access glyph matrices are not
1072 processed while we are changing them. */
1074 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (frame
)));
1078 XWINDOW (tem
)->prev
= p
->prev
;
1082 XWINDOW (tem
)->next
= p
->next
;
1084 if (EQ (window
, par
->hchild
))
1085 par
->hchild
= p
->next
;
1086 if (EQ (window
, par
->vchild
))
1087 par
->vchild
= p
->next
;
1089 /* Find one of our siblings to give our space to. */
1093 /* If p gives its space to its next sibling, that sibling needs
1094 to have its top/left side pulled back to where p's is.
1095 set_window_{height,width} will re-position the sibling's
1098 XWINDOW (sib
)->top
= p
->top
;
1099 XWINDOW (sib
)->left
= p
->left
;
1102 /* Stretch that sibling. */
1103 if (!NILP (par
->vchild
))
1104 set_window_height (sib
,
1105 XFASTINT (XWINDOW (sib
)->height
) + XFASTINT (p
->height
),
1107 if (!NILP (par
->hchild
))
1108 set_window_width (sib
,
1109 XFASTINT (XWINDOW (sib
)->width
) + XFASTINT (p
->width
),
1112 /* If parent now has only one child,
1113 put the child into the parent's place. */
1117 if (NILP (XWINDOW (tem
)->next
))
1118 replace_window (parent
, tem
);
1120 /* Since we may be deleting combination windows, we must make sure that
1121 not only p but all its children have been marked as deleted. */
1122 if (! NILP (p
->hchild
))
1123 delete_all_subwindows (XWINDOW (p
->hchild
));
1124 else if (! NILP (p
->vchild
))
1125 delete_all_subwindows (XWINDOW (p
->vchild
));
1127 /* Mark this window as deleted. */
1128 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
1130 /* Adjust glyph matrices. */
1131 adjust_glyphs (frame
);
1136 extern Lisp_Object
next_frame (), prev_frame ();
1138 /* This comment supplies the doc string for `next-window',
1139 for make-docfile to see. We cannot put this in the real DEFUN
1140 due to limits in the Unix cpp.
1142 DEFUN ("next-window", Ffoo, Sfoo, 0, 3, 0,
1143 "Return next window after WINDOW in canonical ordering of windows.\n\
1144 If omitted, WINDOW defaults to the selected window.\n\
1146 Optional second arg MINIBUF t means count the minibuffer window even\n\
1147 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1148 it is active. MINIBUF neither t nor nil means not to count the\n\
1149 minibuffer even if it is active.\n\
1151 Several frames may share a single minibuffer; if the minibuffer\n\
1152 counts, all windows on all frames that share that minibuffer count\n\
1153 too. Therefore, `next-window' can be used to iterate through the\n\
1154 set of windows even when the minibuffer is on another frame. If the\n\
1155 minibuffer does not count, only windows from WINDOW's frame count.\n\
1157 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1158 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1159 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1160 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1161 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1162 Anything else means restrict to WINDOW's frame.\n\
1164 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1165 `next-window' to iterate through the entire cycle of acceptable\n\
1166 windows, eventually ending up back at the window you started with.\n\
1167 `previous-window' traverses the same cycle, in the reverse order.")
1168 (window, minibuf, all_frames) */
1170 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
1172 (window
, minibuf
, all_frames
)
1173 register Lisp_Object window
, minibuf
, all_frames
;
1175 register Lisp_Object tem
;
1176 Lisp_Object start_window
;
1179 window
= selected_window
;
1181 CHECK_LIVE_WINDOW (window
, 0);
1183 start_window
= window
;
1185 /* minibuf == nil may or may not include minibuffers.
1186 Decide if it does. */
1188 minibuf
= (minibuf_level
? minibuf_window
: Qlambda
);
1189 else if (! EQ (minibuf
, Qt
))
1191 /* Now minibuf can be t => count all minibuffer windows,
1192 lambda => count none of them,
1193 or a specific minibuffer window (the active one) to count. */
1195 /* all_frames == nil doesn't specify which frames to include. */
1196 if (NILP (all_frames
))
1197 all_frames
= (! EQ (minibuf
, Qlambda
)
1198 ? (FRAME_MINIBUF_WINDOW
1201 (XWINDOW (window
)))))
1203 else if (EQ (all_frames
, Qvisible
))
1205 else if (XFASTINT (all_frames
) == 0)
1207 else if (FRAMEP (all_frames
) && ! EQ (all_frames
, Fwindow_frame (window
)))
1208 /* If all_frames is a frame and window arg isn't on that frame, just
1209 return the first window on the frame. */
1210 return Fframe_first_window (all_frames
);
1211 else if (! EQ (all_frames
, Qt
))
1213 /* Now all_frames is t meaning search all frames,
1214 nil meaning search just current frame,
1215 visible meaning search just visible frames,
1216 0 meaning search visible and iconified frames,
1217 or a window, meaning search the frame that window belongs to. */
1219 /* Do this loop at least once, to get the next window, and perhaps
1220 again, if we hit the minibuffer and that is not acceptable. */
1223 /* Find a window that actually has a next one. This loop
1224 climbs up the tree. */
1225 while (tem
= XWINDOW (window
)->next
, NILP (tem
))
1226 if (tem
= XWINDOW (window
)->parent
, !NILP (tem
))
1230 /* We've reached the end of this frame.
1231 Which other frames are acceptable? */
1232 tem
= WINDOW_FRAME (XWINDOW (window
));
1233 if (! NILP (all_frames
))
1238 tem
= next_frame (tem
, all_frames
);
1239 /* In the case where the minibuffer is active,
1240 and we include its frame as well as the selected one,
1241 next_frame may get stuck in that frame.
1242 If that happens, go back to the selected frame
1243 so we can complete the cycle. */
1245 tem
= selected_frame
;
1247 tem
= FRAME_ROOT_WINDOW (XFRAME (tem
));
1254 /* If we're in a combination window, find its first child and
1255 recurse on that. Otherwise, we've found the window we want. */
1258 if (!NILP (XWINDOW (window
)->hchild
))
1259 window
= XWINDOW (window
)->hchild
;
1260 else if (!NILP (XWINDOW (window
)->vchild
))
1261 window
= XWINDOW (window
)->vchild
;
1267 /* Which windows are acceptable?
1268 Exit the loop and accept this window if
1269 this isn't a minibuffer window,
1270 or we're accepting all minibuffer windows,
1271 or this is the active minibuffer and we are accepting that one, or
1272 we've come all the way around and we're back at the original window. */
1273 while (MINI_WINDOW_P (XWINDOW (window
))
1274 && ! EQ (minibuf
, Qt
)
1275 && ! EQ (minibuf
, window
)
1276 && ! EQ (window
, start_window
));
1281 /* This comment supplies the doc string for `previous-window',
1282 for make-docfile to see. We cannot put this in the real DEFUN
1283 due to limits in the Unix cpp.
1285 DEFUN ("previous-window", Ffoo, Sfoo, 0, 3, 0,
1286 "Return the window preceding WINDOW in canonical ordering of windows.\n\
1287 If omitted, WINDOW defaults to the selected window.\n\
1289 Optional second arg MINIBUF t means count the minibuffer window even\n\
1290 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1291 it is active. MINIBUF neither t nor nil means not to count the\n\
1292 minibuffer even if it is active.\n\
1294 Several frames may share a single minibuffer; if the minibuffer\n\
1295 counts, all windows on all frames that share that minibuffer count\n\
1296 too. Therefore, `previous-window' can be used to iterate through\n\
1297 the set of windows even when the minibuffer is on another frame. If\n\
1298 the minibuffer does not count, only windows from WINDOW's frame count\n\
1300 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1301 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1302 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1303 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1304 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1305 Anything else means restrict to WINDOW's frame.\n\
1307 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1308 `previous-window' to iterate through the entire cycle of acceptable\n\
1309 windows, eventually ending up back at the window you started with.\n\
1310 `next-window' traverses the same cycle, in the reverse order.")
1311 (window, minibuf, all_frames) */
1314 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
1316 (window
, minibuf
, all_frames
)
1317 register Lisp_Object window
, minibuf
, all_frames
;
1319 register Lisp_Object tem
;
1320 Lisp_Object start_window
;
1323 window
= selected_window
;
1325 CHECK_LIVE_WINDOW (window
, 0);
1327 start_window
= window
;
1329 /* minibuf == nil may or may not include minibuffers.
1330 Decide if it does. */
1332 minibuf
= (minibuf_level
? minibuf_window
: Qlambda
);
1333 else if (! EQ (minibuf
, Qt
))
1335 /* Now minibuf can be t => count all minibuffer windows,
1336 lambda => count none of them,
1337 or a specific minibuffer window (the active one) to count. */
1339 /* all_frames == nil doesn't specify which frames to include.
1340 Decide which frames it includes. */
1341 if (NILP (all_frames
))
1342 all_frames
= (! EQ (minibuf
, Qlambda
)
1343 ? (FRAME_MINIBUF_WINDOW
1346 (XWINDOW (window
)))))
1348 else if (EQ (all_frames
, Qvisible
))
1350 else if (XFASTINT (all_frames
) == 0)
1352 else if (FRAMEP (all_frames
) && ! EQ (all_frames
, Fwindow_frame (window
)))
1353 /* If all_frames is a frame and window arg isn't on that frame, just
1354 return the first window on the frame. */
1355 return Fframe_first_window (all_frames
);
1356 else if (! EQ (all_frames
, Qt
))
1358 /* Now all_frames is t meaning search all frames,
1359 nil meaning search just current frame,
1360 visible meaning search just visible frames,
1361 0 meaning search visible and iconified frames,
1362 or a window, meaning search the frame that window belongs to. */
1364 /* Do this loop at least once, to get the previous window, and perhaps
1365 again, if we hit the minibuffer and that is not acceptable. */
1368 /* Find a window that actually has a previous one. This loop
1369 climbs up the tree. */
1370 while (tem
= XWINDOW (window
)->prev
, NILP (tem
))
1371 if (tem
= XWINDOW (window
)->parent
, !NILP (tem
))
1375 /* We have found the top window on the frame.
1376 Which frames are acceptable? */
1377 tem
= WINDOW_FRAME (XWINDOW (window
));
1378 if (! NILP (all_frames
))
1379 /* It's actually important that we use prev_frame here,
1380 rather than next_frame. All the windows acceptable
1381 according to the given parameters should form a ring;
1382 Fnext_window and Fprevious_window should go back and
1383 forth around the ring. If we use next_frame here,
1384 then Fnext_window and Fprevious_window take different
1385 paths through the set of acceptable windows.
1386 window_loop assumes that these `ring' requirement are
1392 tem
= prev_frame (tem
, all_frames
);
1393 /* In the case where the minibuffer is active,
1394 and we include its frame as well as the selected one,
1395 next_frame may get stuck in that frame.
1396 If that happens, go back to the selected frame
1397 so we can complete the cycle. */
1399 tem
= selected_frame
;
1401 /* If this frame has a minibuffer, find that window first,
1402 because it is conceptually the last window in that frame. */
1403 if (FRAME_HAS_MINIBUF_P (XFRAME (tem
)))
1404 tem
= FRAME_MINIBUF_WINDOW (XFRAME (tem
));
1406 tem
= FRAME_ROOT_WINDOW (XFRAME (tem
));
1412 /* If we're in a combination window, find its last child and
1413 recurse on that. Otherwise, we've found the window we want. */
1416 if (!NILP (XWINDOW (window
)->hchild
))
1417 window
= XWINDOW (window
)->hchild
;
1418 else if (!NILP (XWINDOW (window
)->vchild
))
1419 window
= XWINDOW (window
)->vchild
;
1421 while (tem
= XWINDOW (window
)->next
, !NILP (tem
))
1425 /* Which windows are acceptable?
1426 Exit the loop and accept this window if
1427 this isn't a minibuffer window,
1428 or we're accepting all minibuffer windows,
1429 or this is the active minibuffer and we are accepting that one, or
1430 we've come all the way around and we're back at the original window. */
1431 while (MINI_WINDOW_P (XWINDOW (window
))
1432 && ! EQ (minibuf
, Qt
)
1433 && ! EQ (minibuf
, window
)
1434 && ! EQ (window
, start_window
));
1439 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1440 "Select the ARG'th different window on this frame.\n\
1441 All windows on current frame are arranged in a cyclic order.\n\
1442 This command selects the window ARG steps away in that order.\n\
1443 A negative ARG moves in the opposite order. If the optional second\n\
1444 argument ALL_FRAMES is non-nil, cycle through all frames.")
1446 register Lisp_Object arg
, all_frames
;
1449 register Lisp_Object w
;
1451 CHECK_NUMBER (arg
, 0);
1452 w
= selected_window
;
1457 w
= Fnext_window (w
, Qnil
, all_frames
);
1462 w
= Fprevious_window (w
, Qnil
, all_frames
);
1469 /* Look at all windows, performing an operation specified by TYPE
1471 If FRAMES is Qt, look at all frames;
1472 Qnil, look at just the selected frame;
1473 Qvisible, look at visible frames;
1474 a frame, just look at windows on that frame.
1475 If MINI is non-zero, perform the operation on minibuffer windows too.
1481 GET_BUFFER_WINDOW
, /* Arg is buffer */
1482 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1483 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1484 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1486 UNSHOW_BUFFER
, /* Arg is buffer */
1491 window_loop (type
, obj
, mini
, frames
)
1492 enum window_loop type
;
1493 register Lisp_Object obj
, frames
;
1496 register Lisp_Object w
;
1497 register Lisp_Object best_window
;
1498 register Lisp_Object next_window
;
1499 register Lisp_Object last_window
;
1501 Lisp_Object frame_arg
;
1504 /* If we're only looping through windows on a particular frame,
1505 frame points to that frame. If we're looping through windows
1506 on all frames, frame is 0. */
1507 if (FRAMEP (frames
))
1508 frame
= XFRAME (frames
);
1509 else if (NILP (frames
))
1510 frame
= SELECTED_FRAME ();
1514 frame_arg
= Qlambda
;
1515 else if (XFASTINT (frames
) == 0)
1517 else if (EQ (frames
, Qvisible
))
1520 /* frame_arg is Qlambda to stick to one frame,
1521 Qvisible to consider all visible frames,
1524 /* Pick a window to start with. */
1528 w
= FRAME_SELECTED_WINDOW (frame
);
1530 w
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
1532 /* Figure out the last window we're going to mess with. Since
1533 Fnext_window, given the same options, is guaranteed to go in a
1534 ring, we can just use Fprevious_window to find the last one.
1536 We can't just wait until we hit the first window again, because
1537 it might be deleted. */
1539 last_window
= Fprevious_window (w
, mini
? Qt
: Qnil
, frame_arg
);
1544 /* Pick the next window now, since some operations will delete
1545 the current window. */
1546 next_window
= Fnext_window (w
, mini
? Qt
: Qnil
, frame_arg
);
1548 /* Note that we do not pay attention here to whether
1549 the frame is visible, since Fnext_window skips non-visible frames
1550 if that is desired, under the control of frame_arg. */
1551 if (! MINI_WINDOW_P (XWINDOW (w
))
1552 /* For UNSHOW_BUFFER, we must always consider all windows. */
1553 || type
== UNSHOW_BUFFER
1554 || (mini
&& minibuf_level
> 0))
1557 case GET_BUFFER_WINDOW
:
1558 if (XBUFFER (XWINDOW (w
)->buffer
) == XBUFFER (obj
)
1559 /* Don't find any minibuffer window
1560 except the one that is currently in use. */
1561 && (MINI_WINDOW_P (XWINDOW (w
))
1562 ? EQ (w
, minibuf_window
) : 1))
1566 case GET_LRU_WINDOW
:
1567 /* t as arg means consider only full-width windows */
1568 if (!NILP (obj
) && !WINDOW_FULL_WIDTH_P (XWINDOW (w
)))
1570 /* Ignore dedicated windows and minibuffers. */
1571 if (MINI_WINDOW_P (XWINDOW (w
))
1572 || !NILP (XWINDOW (w
)->dedicated
))
1574 if (NILP (best_window
)
1575 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1576 > XFASTINT (XWINDOW (w
)->use_time
)))
1580 case DELETE_OTHER_WINDOWS
:
1581 if (XWINDOW (w
) != XWINDOW (obj
))
1585 case DELETE_BUFFER_WINDOWS
:
1586 if (EQ (XWINDOW (w
)->buffer
, obj
))
1588 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (w
)));
1590 /* If this window is dedicated, and in a frame of its own,
1592 if (EQ (w
, FRAME_ROOT_WINDOW (f
))
1593 && !NILP (XWINDOW (w
)->dedicated
)
1594 && other_visible_frames (f
))
1596 /* Skip the other windows on this frame.
1597 There might be one, the minibuffer! */
1598 if (! EQ (w
, last_window
))
1599 while (f
== XFRAME (WINDOW_FRAME (XWINDOW (next_window
))))
1601 /* As we go, check for the end of the loop.
1602 We mustn't start going around a second time. */
1603 if (EQ (next_window
, last_window
))
1608 next_window
= Fnext_window (next_window
,
1612 /* Now we can safely delete the frame. */
1613 Fdelete_frame (WINDOW_FRAME (XWINDOW (w
)), Qnil
);
1616 /* If we're deleting the buffer displayed in the only window
1617 on the frame, find a new buffer to display there. */
1618 if (NILP (XWINDOW (w
)->parent
))
1620 Lisp_Object new_buffer
;
1621 new_buffer
= Fother_buffer (obj
, Qnil
,
1622 XWINDOW (w
)->frame
);
1623 if (NILP (new_buffer
))
1625 = Fget_buffer_create (build_string ("*scratch*"));
1626 Fset_window_buffer (w
, new_buffer
);
1627 if (EQ (w
, selected_window
))
1628 Fset_buffer (XWINDOW (w
)->buffer
);
1635 case GET_LARGEST_WINDOW
:
1636 /* Ignore dedicated windows and minibuffers. */
1637 if (MINI_WINDOW_P (XWINDOW (w
))
1638 || !NILP (XWINDOW (w
)->dedicated
)
1639 || NILP (best_window
))
1642 struct window
*best_window_ptr
= XWINDOW (best_window
);
1643 struct window
*w_ptr
= XWINDOW (w
);
1644 if (NILP (best_window
)
1645 || (XFASTINT (w_ptr
->height
) * XFASTINT (w_ptr
->width
)
1646 > (XFASTINT (best_window_ptr
->height
)
1647 * XFASTINT (best_window_ptr
->width
))))
1653 if (EQ (XWINDOW (w
)->buffer
, obj
))
1655 /* Find another buffer to show in this window. */
1656 Lisp_Object another_buffer
;
1657 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (w
)));
1658 another_buffer
= Fother_buffer (obj
, Qnil
, XWINDOW (w
)->frame
);
1659 if (NILP (another_buffer
))
1661 = Fget_buffer_create (build_string ("*scratch*"));
1662 /* If this window is dedicated, and in a frame of its own,
1664 if (EQ (w
, FRAME_ROOT_WINDOW (f
))
1665 && !NILP (XWINDOW (w
)->dedicated
)
1666 && other_visible_frames (f
))
1668 /* Skip the other windows on this frame.
1669 There might be one, the minibuffer! */
1670 if (! EQ (w
, last_window
))
1671 while (f
== XFRAME (WINDOW_FRAME (XWINDOW (next_window
))))
1673 /* As we go, check for the end of the loop.
1674 We mustn't start going around a second time. */
1675 if (EQ (next_window
, last_window
))
1680 next_window
= Fnext_window (next_window
,
1684 /* Now we can safely delete the frame. */
1685 Fdelete_frame (WINDOW_FRAME (XWINDOW (w
)), Qnil
);
1689 /* Otherwise show a different buffer in the window. */
1690 XWINDOW (w
)->dedicated
= Qnil
;
1691 Fset_window_buffer (w
, another_buffer
);
1692 if (EQ (w
, selected_window
))
1693 Fset_buffer (XWINDOW (w
)->buffer
);
1698 /* Check for a window that has a killed buffer. */
1699 case CHECK_ALL_WINDOWS
:
1700 if (! NILP (XWINDOW (w
)->buffer
)
1701 && NILP (XBUFFER (XWINDOW (w
)->buffer
)->name
))
1705 if (EQ (w
, last_window
))
1714 /* Used for debugging. Abort if any window has a dead buffer. */
1717 check_all_windows ()
1719 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
1722 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1723 "Return the window least recently selected or used for display.\n\
1724 If optional argument FRAME is `visible', search all visible frames.\n\
1725 If FRAME is 0, search all visible and iconified frames.\n\
1726 If FRAME is t, search all frames.\n\
1727 If FRAME is nil, search only the selected frame.\n\
1728 If FRAME is a frame, search only that frame.")
1732 register Lisp_Object w
;
1733 /* First try for a window that is full-width */
1734 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frame
);
1735 if (!NILP (w
) && !EQ (w
, selected_window
))
1737 /* If none of them, try the rest */
1738 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frame
);
1741 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1742 "Return the largest window in area.\n\
1743 If optional argument FRAME is `visible', search all visible frames.\n\
1744 If FRAME is 0, search all visible and iconified frames.\n\
1745 If FRAME is t, search all frames.\n\
1746 If FRAME is nil, search only the selected frame.\n\
1747 If FRAME is a frame, search only that frame.")
1751 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
1755 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
1756 "Return a window currently displaying BUFFER, or nil if none.\n\
1757 If optional argument FRAME is `visible', search all visible frames.\n\
1758 If optional argument FRAME is 0, search all visible and iconified frames.\n\
1759 If FRAME is t, search all frames.\n\
1760 If FRAME is nil, search only the selected frame.\n\
1761 If FRAME is a frame, search only that frame.")
1763 Lisp_Object buffer
, frame
;
1765 buffer
= Fget_buffer (buffer
);
1766 if (BUFFERP (buffer
))
1767 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
1772 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
1774 "Make WINDOW (or the selected window) fill its frame.\n\
1775 Only the frame WINDOW is on is affected.\n\
1776 This function tries to reduce display jumps\n\
1777 by keeping the text previously visible in WINDOW\n\
1778 in the same place on the frame. Doing this depends on\n\
1779 the value of (window-start WINDOW), so if calling this function\n\
1780 in a program gives strange scrolling, make sure the window-start\n\
1781 value is reasonable when this function is called.")
1790 window
= selected_window
;
1792 CHECK_LIVE_WINDOW (window
, 0);
1794 w
= XWINDOW (window
);
1796 startpos
= marker_position (w
->start
);
1797 top
= XFASTINT (w
->top
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
1799 if (MINI_WINDOW_P (w
) && top
> 0)
1800 error ("Can't expand minibuffer to full frame");
1802 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
1804 /* Try to minimize scrolling, by setting the window start to the point
1805 will cause the text at the old window start to be at the same place
1806 on the frame. But don't try to do this if the window start is
1807 outside the visible portion (as might happen when the display is
1808 not current, due to typeahead). */
1809 if (startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
1810 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
1812 struct position pos
;
1813 struct buffer
*obuf
= current_buffer
;
1815 Fset_buffer (w
->buffer
);
1816 /* This computation used to temporarily move point, but that can
1817 have unwanted side effects due to text properties. */
1818 pos
= *vmotion (startpos
, -top
, w
);
1820 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
1821 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
1822 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
1824 /* We need to do this, so that the window-scroll-functions
1826 w
->optional_new_start
= Qt
;
1828 set_buffer_internal (obuf
);
1834 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
1835 1, 2, "bDelete windows on (buffer): ",
1836 "Delete all windows showing BUFFER.\n\
1837 Optional second argument FRAME controls which frames are affected.\n\
1838 If optional argument FRAME is `visible', search all visible frames.\n\
1839 If FRAME is 0, search all visible and iconified frames.\n\
1840 If FRAME is nil, search all frames.\n\
1841 If FRAME is t, search only the selected frame.\n\
1842 If FRAME is a frame, search only that frame.")
1844 Lisp_Object buffer
, frame
;
1846 /* FRAME uses t and nil to mean the opposite of what window_loop
1850 else if (EQ (frame
, Qt
))
1855 buffer
= Fget_buffer (buffer
);
1856 CHECK_BUFFER (buffer
, 0);
1857 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
1863 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
1864 Sreplace_buffer_in_windows
,
1865 1, 1, "bReplace buffer in windows: ",
1866 "Replace BUFFER with some other buffer in all windows showing it.")
1872 buffer
= Fget_buffer (buffer
);
1873 CHECK_BUFFER (buffer
, 0);
1874 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
1879 /* Replace BUFFER with some other buffer in all windows
1880 of all frames, even those on other keyboards. */
1883 replace_buffer_in_all_windows (buffer
)
1887 Lisp_Object tail
, frame
;
1889 /* A single call to window_loop won't do the job
1890 because it only considers frames on the current keyboard.
1891 So loop manually over frames, and handle each one. */
1892 FOR_EACH_FRAME (tail
, frame
)
1893 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
1895 window_loop (UNSHOW_BUFFER
, buffer
, 1, Qt
);
1899 /* Set the height of WINDOW and all its inferiors. */
1901 /* The smallest acceptable dimensions for a window. Anything smaller
1902 might crash Emacs. */
1904 #define MIN_SAFE_WINDOW_WIDTH (2)
1905 #define MIN_SAFE_WINDOW_HEIGHT (2)
1907 /* Make sure that window_min_height and window_min_width are
1908 not too small; if they are, set them to safe minima. */
1911 check_min_window_sizes ()
1913 /* Smaller values might permit a crash. */
1914 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
1915 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
1916 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
1917 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
1920 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
1921 minimum allowable size. */
1924 check_frame_size (frame
, rows
, cols
)
1928 /* For height, we have to see:
1929 whether the frame has a minibuffer,
1930 whether it wants a mode line, and
1931 whether it has a menu bar. */
1933 (FRAME_MINIBUF_ONLY_P (frame
) ? MIN_SAFE_WINDOW_HEIGHT
- 1
1934 : (! FRAME_HAS_MINIBUF_P (frame
)) ? MIN_SAFE_WINDOW_HEIGHT
1935 : 2 * MIN_SAFE_WINDOW_HEIGHT
- 1);
1937 if (FRAME_TOP_MARGIN (frame
) > 0)
1938 min_height
+= FRAME_TOP_MARGIN (frame
);
1940 if (*rows
< min_height
)
1942 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
1943 *cols
= MIN_SAFE_WINDOW_WIDTH
;
1947 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
1948 check if W's width can be changed, otherwise check W's height.
1949 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
1950 siblings, too. If none of the siblings is resizable, WINDOW isn't
1954 window_fixed_size_p (w
, width_p
, check_siblings_p
)
1956 int width_p
, check_siblings_p
;
1961 if (!NILP (w
->hchild
))
1963 c
= XWINDOW (w
->hchild
);
1967 /* A horiz. combination is fixed-width if all of if its
1969 while (c
&& window_fixed_size_p (c
, width_p
, 0))
1970 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
1971 fixed_p
= c
== NULL
;
1975 /* A horiz. combination is fixed-height if one of if its
1977 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
1978 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
1979 fixed_p
= c
!= NULL
;
1982 else if (!NILP (w
->vchild
))
1984 c
= XWINDOW (w
->vchild
);
1988 /* A vert. combination is fixed-width if one of if its
1990 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
1991 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
1992 fixed_p
= c
!= NULL
;
1996 /* A vert. combination is fixed-height if all of if its
1998 while (c
&& window_fixed_size_p (c
, width_p
, 0))
1999 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2000 fixed_p
= c
== NULL
;
2003 else if (BUFFERP (w
->buffer
))
2005 if (w
->height_fixed_p
&& !width_p
)
2009 struct buffer
*old
= current_buffer
;
2012 current_buffer
= XBUFFER (w
->buffer
);
2013 val
= find_symbol_value (Qwindow_size_fixed
);
2014 current_buffer
= old
;
2017 if (!EQ (val
, Qunbound
))
2019 fixed_p
= !NILP (val
);
2022 && ((EQ (val
, Qheight
) && width_p
)
2023 || (EQ (val
, Qwidth
) && !width_p
)))
2028 /* Can't tell if this one is resizable without looking at
2029 siblings. If all siblings are fixed-size this one is too. */
2030 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
2034 for (child
= w
->prev
; !NILP (child
); child
= XWINDOW (child
)->prev
)
2035 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2039 for (child
= w
->next
; !NILP (child
); child
= XWINDOW (child
)->next
)
2040 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2054 /* Return the minimum size of window W, not taking fixed-width windows
2055 into account. WIDTH_P non-zero means return the minimum width,
2056 otherwise return the minimum height. If W is a combination window,
2057 compute the minimum size from the minimum sizes of W's children. */
2060 window_min_size_1 (w
, width_p
)
2067 if (!NILP (w
->hchild
))
2069 c
= XWINDOW (w
->hchild
);
2074 /* The min width of a horizontal combination is
2075 the sum of the min widths of its children. */
2078 size
+= window_min_size_1 (c
, width_p
);
2079 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2084 /* The min height a horizontal combination equals
2085 the maximum of all min height of its children. */
2088 int min_size
= window_min_size_1 (c
, width_p
);
2089 size
= max (min_size
, size
);
2090 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2094 else if (!NILP (w
->vchild
))
2096 c
= XWINDOW (w
->vchild
);
2101 /* The min width of a vertical combination is
2102 the maximum of the min widths of its children. */
2105 int min_size
= window_min_size_1 (c
, width_p
);
2106 size
= max (min_size
, size
);
2107 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2112 /* The min height of a vertical combination equals
2113 the sum of the min height of its children. */
2116 size
+= window_min_size_1 (c
, width_p
);
2117 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2124 size
= window_min_width
;
2127 if (MINI_WINDOW_P (w
)
2128 || (!WINDOW_WANTS_MODELINE_P (w
)
2129 && !WINDOW_WANTS_HEADER_LINE_P (w
)))
2132 size
= window_min_height
;
2140 /* Return the minimum size of window W, taking fixed-size windows into
2141 account. WIDTH_P non-zero means return the minimum width,
2142 otherwise return the minimum height. IGNORE_FIXED_P non-zero means
2143 ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size
2144 unless FIXED is null. */
2147 window_min_size (w
, width_p
, ignore_fixed_p
, fixed
)
2149 int width_p
, ignore_fixed_p
, *fixed
;
2156 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
2162 size
= width_p
? XFASTINT (w
->width
) : XFASTINT (w
->height
);
2164 size
= window_min_size_1 (w
, width_p
);
2170 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
2171 WINDOW's width. Resize WINDOW's children, if any, so that they
2172 keep their proportionate size relative to WINDOW. Propagate
2173 WINDOW's top or left edge position to children. Delete windows
2174 that become too small unless NODELETE_P is non-zero. */
2177 size_window (window
, size
, width_p
, nodelete_p
)
2179 int size
, width_p
, nodelete_p
;
2181 struct window
*w
= XWINDOW (window
);
2183 Lisp_Object child
, *forward
, *sideward
;
2184 int old_size
, min_size
;
2186 check_min_window_sizes ();
2188 /* If the window has been "too small" at one point,
2189 don't delete it for being "too small" in the future.
2190 Preserve it as long as that is at all possible. */
2193 old_size
= XFASTINT (w
->width
);
2194 min_size
= window_min_width
;
2198 old_size
= XFASTINT (w
->height
);
2199 min_size
= window_min_height
;
2202 if (old_size
< window_min_width
)
2203 w
->too_small_ok
= Qt
;
2205 /* Maybe delete WINDOW if it's too small. */
2206 if (!nodelete_p
&& !NILP (w
->parent
))
2210 if (!MINI_WINDOW_P (w
) && !NILP (w
->too_small_ok
))
2211 min_size
= width_p
? MIN_SAFE_WINDOW_WIDTH
: MIN_SAFE_WINDOW_HEIGHT
;
2213 min_size
= width_p
? window_min_width
: window_min_height
;
2215 if (size
< min_size
)
2217 delete_window (window
);
2222 /* Set redisplay hints. */
2223 XSETFASTINT (w
->last_modified
, 0);
2224 XSETFASTINT (w
->last_overlay_modified
, 0);
2225 windows_or_buffers_changed
++;
2226 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
2230 sideward
= &w
->vchild
;
2231 forward
= &w
->hchild
;
2232 XSETFASTINT (w
->width
, size
);
2236 sideward
= &w
->hchild
;
2237 forward
= &w
->vchild
;
2238 XSETFASTINT (w
->height
, size
);
2241 if (!NILP (*sideward
))
2243 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
2245 c
= XWINDOW (child
);
2250 size_window (child
, size
, width_p
, nodelete_p
);
2253 else if (!NILP (*forward
))
2255 int fixed_size
, each
, extra
, n
;
2256 int resize_fixed_p
, nfixed
;
2257 int last_pos
, first_pos
, nchildren
;
2259 /* Determine the fixed-size portion of the this window, and the
2260 number of child windows. */
2261 fixed_size
= nchildren
= nfixed
= 0;
2262 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
2264 c
= XWINDOW (child
);
2265 if (window_fixed_size_p (c
, width_p
, 0))
2267 fixed_size
+= (width_p
2268 ? XFASTINT (c
->width
) : XFASTINT (c
->height
));
2273 /* If the new size is smaller than fixed_size, or if there
2274 aren't any resizable windows, allow resizing fixed-size
2276 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
2278 /* Compute how many lines/columns to add to each child. The
2279 value of extra takes care of rounding errors. */
2280 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
2281 each
= (size
- old_size
) / n
;
2282 extra
= (size
- old_size
) - n
* each
;
2284 /* Compute new children heights and edge positions. */
2285 first_pos
= width_p
? XFASTINT (w
->left
) : XFASTINT (w
->top
);
2286 last_pos
= first_pos
;
2287 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2289 int new_size
, old_size
;
2291 c
= XWINDOW (child
);
2292 old_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2293 new_size
= old_size
;
2295 /* The top or left edge position of this child equals the
2296 bottom or right edge of its predecessor. */
2298 c
->left
= make_number (last_pos
);
2300 c
->top
= make_number (last_pos
);
2302 /* If this child can be resized, do it. */
2303 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
2305 new_size
= old_size
+ each
+ extra
;
2309 /* Set new height. Note that size_window also propagates
2310 edge positions to children, so it's not a no-op if we
2311 didn't change the child's size. */
2312 size_window (child
, new_size
, width_p
, 1);
2314 /* Remember the bottom/right edge position of this child; it
2315 will be used to set the top/left edge of the next child. */
2316 last_pos
+= new_size
;
2319 /* We should have covered the parent exactly with child windows. */
2320 xassert (size
== last_pos
- first_pos
);
2322 /* Now delete any children that became too small. */
2324 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2327 c
= XWINDOW (child
);
2328 child_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2329 size_window (child
, child_size
, width_p
, 0);
2334 /* Set WINDOW's height to HEIGHT, and recursively change the height of
2335 WINDOW's children. NODELETE non-zero means don't delete windows
2336 that become too small in the process. (The caller should check
2337 later and do so if appropriate.) */
2340 set_window_height (window
, height
, nodelete
)
2345 size_window (window
, height
, 0, nodelete
);
2349 /* Set WINDOW's width to WIDTH, and recursively change the width of
2350 WINDOW's children. NODELETE non-zero means don't delete windows
2351 that become too small in the process. (The caller should check
2352 later and do so if appropriate.) */
2355 set_window_width (window
, width
, nodelete
)
2360 size_window (window
, width
, 1, nodelete
);
2364 int window_select_count
;
2367 Fset_window_buffer_unwind (obuf
)
2375 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
2376 means it's allowed to run hooks. See make_frame for a case where
2377 it's not allowed. */
2380 set_window_buffer (window
, buffer
, run_hooks_p
)
2381 Lisp_Object window
, buffer
;
2384 struct window
*w
= XWINDOW (window
);
2385 struct buffer
*b
= XBUFFER (buffer
);
2386 int count
= specpdl_ptr
- specpdl
;
2390 if (EQ (window
, selected_window
))
2391 b
->last_selected_window
= window
;
2393 /* Update time stamps of buffer display. */
2394 if (INTEGERP (b
->display_count
))
2395 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
2396 b
->display_time
= Fcurrent_time ();
2398 XSETFASTINT (w
->window_end_pos
, 0);
2399 XSETFASTINT (w
->window_end_vpos
, 0);
2400 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
2401 w
->window_end_valid
= Qnil
;
2402 XSETFASTINT (w
->hscroll
, 0);
2403 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
2404 set_marker_restricted (w
->start
,
2405 make_number (b
->last_window_start
),
2407 w
->start_at_line_beg
= Qnil
;
2408 w
->force_start
= Qnil
;
2409 XSETFASTINT (w
->last_modified
, 0);
2410 XSETFASTINT (w
->last_overlay_modified
, 0);
2411 windows_or_buffers_changed
++;
2413 /* We must select BUFFER for running the window-scroll-functions.
2414 If WINDOW is selected, switch permanently.
2415 Otherwise, switch but go back to the ambient buffer afterward. */
2416 if (EQ (window
, selected_window
))
2417 Fset_buffer (buffer
);
2418 /* We can't check ! NILP (Vwindow_scroll_functions) here
2419 because that might itself be a local variable. */
2420 else if (window_initialized
)
2422 record_unwind_protect (Fset_window_buffer_unwind
, Fcurrent_buffer ());
2423 Fset_buffer (buffer
);
2426 /* Set left and right marginal area width from buffer. */
2427 Fset_window_margins (window
, b
->left_margin_width
, b
->right_margin_width
);
2431 if (! NILP (Vwindow_scroll_functions
))
2432 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2433 Fmarker_position (w
->start
));
2435 if (! NILP (Vwindow_configuration_change_hook
)
2436 && ! NILP (Vrun_hooks
))
2437 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
2440 unbind_to (count
, Qnil
);
2444 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 2, 0,
2445 "Make WINDOW display BUFFER as its contents.\n\
2446 BUFFER can be a buffer or buffer name.")
2448 register Lisp_Object window
, buffer
;
2450 register Lisp_Object tem
;
2451 register struct window
*w
= decode_window (window
);
2453 XSETWINDOW (window
, w
);
2454 buffer
= Fget_buffer (buffer
);
2455 CHECK_BUFFER (buffer
, 1);
2457 if (NILP (XBUFFER (buffer
)->name
))
2458 error ("Attempt to display deleted buffer");
2462 error ("Window is deleted");
2463 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
2464 is first being set up. */
2466 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
2467 error ("Window is dedicated to `%s'",
2468 XSTRING (XBUFFER (tem
)->name
)->data
);
2473 set_window_buffer (window
, buffer
, 1);
2477 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 1, 0,
2478 "Select WINDOW. Most editing will apply to WINDOW's buffer.\n\
2479 If WINDOW is not already selected, also make WINDOW's buffer current.\n\
2480 Note that the main editor command loop\n\
2481 selects the buffer of the selected window before each command.")
2483 register Lisp_Object window
;
2485 return select_window_1 (window
, 1);
2488 /* Note that selected_window can be nil
2489 when this is called from Fset_window_configuration. */
2492 select_window_1 (window
, recordflag
)
2493 register Lisp_Object window
;
2496 register struct window
*w
;
2497 register struct window
*ow
;
2500 CHECK_LIVE_WINDOW (window
, 0);
2502 w
= XWINDOW (window
);
2504 if (NILP (w
->buffer
))
2505 error ("Trying to select deleted window or non-leaf window");
2507 XSETFASTINT (w
->use_time
, ++window_select_count
);
2508 if (EQ (window
, selected_window
))
2511 if (!NILP (selected_window
))
2513 ow
= XWINDOW (selected_window
);
2514 if (! NILP (ow
->buffer
))
2515 set_marker_both (ow
->pointm
, ow
->buffer
,
2516 BUF_PT (XBUFFER (ow
->buffer
)),
2517 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
2520 selected_window
= window
;
2521 sf
= SELECTED_FRAME ();
2522 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
2524 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
2525 /* Use this rather than Fhandle_switch_frame
2526 so that FRAME_FOCUS_FRAME is moved appropriately as we
2527 move around in the state where a minibuffer in a separate
2529 Fselect_frame (WINDOW_FRAME (w
), Qnil
);
2532 sf
->selected_window
= window
;
2535 record_buffer (w
->buffer
);
2536 Fset_buffer (w
->buffer
);
2538 XBUFFER (w
->buffer
)->last_selected_window
= window
;
2540 /* Go to the point recorded in the window.
2541 This is important when the buffer is in more
2542 than one window. It also matters when
2543 redisplay_window has altered point after scrolling,
2544 because it makes the change only in the window. */
2546 register int new_point
= marker_position (w
->pointm
);
2547 if (new_point
< BEGV
)
2549 else if (new_point
> ZV
)
2555 windows_or_buffers_changed
++;
2559 /* Deiconify the frame containing the window WINDOW,
2560 unless it is the selected frame;
2563 The reason for the exception for the selected frame
2564 is that it seems better not to change the selected frames visibility
2565 merely because of displaying a different buffer in it.
2566 The deiconification is useful when a buffer gets shown in
2567 another frame that you were not using lately. */
2570 display_buffer_1 (window
)
2573 Lisp_Object frame
= XWINDOW (window
)->frame
;
2574 FRAME_PTR f
= XFRAME (frame
);
2576 FRAME_SAMPLE_VISIBILITY (f
);
2578 if (!EQ (frame
, selected_frame
))
2580 if (FRAME_ICONIFIED_P (f
))
2581 Fmake_frame_visible (frame
);
2582 else if (FRAME_VISIBLE_P (f
))
2583 Fraise_frame (frame
);
2589 DEFUN ("special-display-p", Fspecial_display_p
, Sspecial_display_p
, 1, 1, 0,
2590 "Returns non-nil if a buffer named BUFFER-NAME would be created specially.\n\
2591 The value is actually t if the frame should be called with default frame\n\
2592 parameters, and a list of frame parameters if they were specified.\n\
2593 See `special-display-buffer-names', and `special-display-regexps'.")
2595 Lisp_Object buffer_name
;
2599 CHECK_STRING (buffer_name
, 1);
2601 tem
= Fmember (buffer_name
, Vspecial_display_buffer_names
);
2605 tem
= Fassoc (buffer_name
, Vspecial_display_buffer_names
);
2609 for (tem
= Vspecial_display_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2611 Lisp_Object car
= XCAR (tem
);
2613 && fast_string_match (car
, buffer_name
) >= 0)
2615 else if (CONSP (car
)
2616 && STRINGP (XCAR (car
))
2617 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2623 DEFUN ("same-window-p", Fsame_window_p
, Ssame_window_p
, 1, 1, 0,
2624 "Returns non-nil if a new buffer named BUFFER-NAME would use the same window.\n\
2625 See `same-window-buffer-names' and `same-window-regexps'.")
2627 Lisp_Object buffer_name
;
2631 CHECK_STRING (buffer_name
, 1);
2633 tem
= Fmember (buffer_name
, Vsame_window_buffer_names
);
2637 tem
= Fassoc (buffer_name
, Vsame_window_buffer_names
);
2641 for (tem
= Vsame_window_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2643 Lisp_Object car
= XCAR (tem
);
2645 && fast_string_match (car
, buffer_name
) >= 0)
2647 else if (CONSP (car
)
2648 && STRINGP (XCAR (car
))
2649 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2655 /* Use B so the default is (other-buffer). */
2656 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 3,
2657 "BDisplay buffer: \nP",
2658 "Make BUFFER appear in some window but don't select it.\n\
2659 BUFFER can be a buffer or a buffer name.\n\
2660 If BUFFER is shown already in some window, just use that one,\n\
2661 unless the window is the selected window and the optional second\n\
2662 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).\n\
2663 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.\n\
2664 Returns the window displaying BUFFER.\n\
2666 The variables `special-display-buffer-names', `special-display-regexps',\n\
2667 `same-window-buffer-names', and `same-window-regexps' customize how certain\n\
2668 buffer names are handled.\n\
2670 If optional argument FRAME is `visible', search all visible frames.\n\
2671 If FRAME is 0, search all visible and iconified frames.\n\
2672 If FRAME is t, search all frames.\n\
2673 If FRAME is a frame, search only that frame.\n\
2674 If FRAME is nil, search only the selected frame\n\
2675 (actually the last nonminibuffer frame),\n\
2676 unless `pop-up-frames' is non-nil,\n\
2677 which means search visible and iconified frames.")
2678 (buffer
, not_this_window
, frame
)
2679 register Lisp_Object buffer
, not_this_window
, frame
;
2681 register Lisp_Object window
, tem
, swp
;
2685 buffer
= Fget_buffer (buffer
);
2686 CHECK_BUFFER (buffer
, 0);
2688 if (!NILP (Vdisplay_buffer_function
))
2689 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
2691 if (NILP (not_this_window
)
2692 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
2693 return display_buffer_1 (selected_window
);
2695 /* See if the user has specified this buffer should appear
2696 in the selected window. */
2697 if (NILP (not_this_window
))
2699 swp
= Fsame_window_p (XBUFFER (buffer
)->name
);
2700 if (!NILP (swp
) && !no_switch_window (selected_window
))
2702 Fswitch_to_buffer (buffer
, Qnil
);
2703 return display_buffer_1 (selected_window
);
2707 /* If pop_up_frames,
2708 look for a window showing BUFFER on any visible or iconified frame.
2709 Otherwise search only the current frame. */
2712 else if (pop_up_frames
|| last_nonminibuf_frame
== 0)
2713 XSETFASTINT (tem
, 0);
2715 XSETFRAME (tem
, last_nonminibuf_frame
);
2716 window
= Fget_buffer_window (buffer
, tem
);
2718 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
2720 return display_buffer_1 (window
);
2723 /* Certain buffer names get special handling. */
2724 if (!NILP (Vspecial_display_function
) && NILP (swp
))
2726 tem
= Fspecial_display_p (XBUFFER (buffer
)->name
);
2728 return call1 (Vspecial_display_function
, buffer
);
2730 return call2 (Vspecial_display_function
, buffer
, tem
);
2733 /* If there are no frames open that have more than a minibuffer,
2734 we need to create a new frame. */
2735 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
2737 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2738 Fset_window_buffer (window
, buffer
);
2739 return display_buffer_1 (window
);
2742 f
= SELECTED_FRAME ();
2744 || FRAME_MINIBUF_ONLY_P (f
)
2745 /* If the current frame is a special display frame,
2746 don't try to reuse its windows. */
2747 || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f
))->dedicated
))
2752 if (FRAME_MINIBUF_ONLY_P (f
))
2753 XSETFRAME (frames
, last_nonminibuf_frame
);
2754 /* Don't try to create a window if would get an error */
2755 if (split_height_threshold
< window_min_height
<< 1)
2756 split_height_threshold
= window_min_height
<< 1;
2758 /* Note that both Fget_largest_window and Fget_lru_window
2759 ignore minibuffers and dedicated windows.
2760 This means they can return nil. */
2762 /* If the frame we would try to split cannot be split,
2763 try other frames. */
2764 if (FRAME_NO_SPLIT_P (NILP (frames
) ? f
: last_nonminibuf_frame
))
2766 /* Try visible frames first. */
2767 window
= Fget_largest_window (Qvisible
);
2768 /* If that didn't work, try iconified frames. */
2770 window
= Fget_largest_window (make_number (0));
2772 window
= Fget_largest_window (Qt
);
2775 window
= Fget_largest_window (frames
);
2777 /* If we got a tall enough full-width window that can be split,
2780 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2781 && window_height (window
) >= split_height_threshold
2782 && WINDOW_FULL_WIDTH_P (XWINDOW (window
)))
2783 window
= Fsplit_window (window
, Qnil
, Qnil
);
2786 Lisp_Object upper
, lower
, other
;
2788 window
= Fget_lru_window (frames
);
2789 /* If the LRU window is selected, and big enough,
2790 and can be split, split it. */
2792 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2793 && (EQ (window
, selected_window
)
2794 || EQ (XWINDOW (window
)->parent
, Qnil
))
2795 && window_height (window
) >= window_min_height
<< 1)
2796 window
= Fsplit_window (window
, Qnil
, Qnil
);
2797 /* If Fget_lru_window returned nil, try other approaches. */
2799 /* Try visible frames first. */
2801 window
= Fget_buffer_window (buffer
, Qvisible
);
2803 window
= Fget_largest_window (Qvisible
);
2804 /* If that didn't work, try iconified frames. */
2806 window
= Fget_buffer_window (buffer
, make_number (0));
2808 window
= Fget_largest_window (make_number (0));
2809 /* Try invisible frames. */
2811 window
= Fget_buffer_window (buffer
, Qt
);
2813 window
= Fget_largest_window (Qt
);
2814 /* As a last resort, make a new frame. */
2816 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2817 /* If window appears above or below another,
2818 even out their heights. */
2819 other
= upper
= lower
= Qnil
;
2820 if (!NILP (XWINDOW (window
)->prev
))
2821 other
= upper
= XWINDOW (window
)->prev
, lower
= window
;
2822 if (!NILP (XWINDOW (window
)->next
))
2823 other
= lower
= XWINDOW (window
)->next
, upper
= window
;
2825 /* Check that OTHER and WINDOW are vertically arrayed. */
2826 && !EQ (XWINDOW (other
)->top
, XWINDOW (window
)->top
)
2827 && (XFASTINT (XWINDOW (other
)->height
)
2828 > XFASTINT (XWINDOW (window
)->height
)))
2830 int total
= (XFASTINT (XWINDOW (other
)->height
)
2831 + XFASTINT (XWINDOW (window
)->height
));
2832 enlarge_window (upper
,
2833 total
/ 2 - XFASTINT (XWINDOW (upper
)->height
),
2839 window
= Fget_lru_window (Qnil
);
2841 Fset_window_buffer (window
, buffer
);
2842 return display_buffer_1 (window
);
2846 temp_output_buffer_show (buf
)
2847 register Lisp_Object buf
;
2849 register struct buffer
*old
= current_buffer
;
2850 register Lisp_Object window
;
2851 register struct window
*w
;
2853 XBUFFER (buf
)->directory
= current_buffer
->directory
;
2856 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
2860 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
2861 set_buffer_internal (old
);
2863 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
2864 call1 (Vtemp_buffer_show_function
, buf
);
2867 window
= Fdisplay_buffer (buf
, Qnil
, Qnil
);
2869 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
2870 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
2871 Vminibuf_scroll_window
= window
;
2872 w
= XWINDOW (window
);
2873 XSETFASTINT (w
->hscroll
, 0);
2874 set_marker_restricted_both (w
->start
, buf
, 1, 1);
2875 set_marker_restricted_both (w
->pointm
, buf
, 1, 1);
2877 /* Run temp-buffer-show-hook, with the chosen window selected
2878 and it sbuffer current. */
2879 if (!NILP (Vrun_hooks
))
2882 tem
= Fboundp (Qtemp_buffer_show_hook
);
2885 tem
= Fsymbol_value (Qtemp_buffer_show_hook
);
2888 int count
= specpdl_ptr
- specpdl
;
2889 Lisp_Object prev_window
;
2890 prev_window
= selected_window
;
2892 /* Select the window that was chosen, for running the hook. */
2893 record_unwind_protect (Fselect_window
, prev_window
);
2894 select_window_1 (window
, 0);
2895 Fset_buffer (w
->buffer
);
2896 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
2897 select_window_1 (prev_window
, 0);
2898 unbind_to (count
, Qnil
);
2906 make_dummy_parent (window
)
2910 register struct window
*o
, *p
;
2911 register struct Lisp_Vector
*vec
;
2914 o
= XWINDOW (window
);
2915 vec
= allocate_vectorlike ((EMACS_INT
)VECSIZE (struct window
));
2916 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
2917 vec
->contents
[i
] = ((struct Lisp_Vector
*)o
)->contents
[i
];
2918 vec
->size
= VECSIZE (struct window
);
2919 p
= (struct window
*)vec
;
2920 XSETWINDOW (new, p
);
2922 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
2924 /* Put new into window structure in place of window */
2925 replace_window (window
, new);
2938 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
2939 "Split WINDOW, putting SIZE lines in the first of the pair.\n\
2940 WINDOW defaults to selected one and SIZE to half its size.\n\
2941 If optional third arg HORFLAG is non-nil, split side by side\n\
2942 and put SIZE columns in the first of the pair. In that case,\n\
2943 SIZE includes that window's scroll bar, or the divider column to its right.")
2944 (window
, size
, horflag
)
2945 Lisp_Object window
, size
, horflag
;
2947 register Lisp_Object
new;
2948 register struct window
*o
, *p
;
2950 register int size_int
;
2953 window
= selected_window
;
2955 CHECK_LIVE_WINDOW (window
, 0);
2957 o
= XWINDOW (window
);
2958 fo
= XFRAME (WINDOW_FRAME (o
));
2962 if (!NILP (horflag
))
2963 /* Calculate the size of the left-hand window, by dividing
2964 the usable space in columns by two.
2965 We round up, since the left-hand window may include
2966 a dividing line, while the right-hand may not. */
2967 size_int
= (XFASTINT (o
->width
) + 1) >> 1;
2969 size_int
= XFASTINT (o
->height
) >> 1;
2973 CHECK_NUMBER (size
, 1);
2974 size_int
= XINT (size
);
2977 if (MINI_WINDOW_P (o
))
2978 error ("Attempt to split minibuffer window");
2979 else if (window_fixed_size_p (o
, !NILP (horflag
), 0))
2980 error ("Attempt to split fixed-size window");
2982 check_min_window_sizes ();
2986 if (size_int
< window_min_height
)
2987 error ("Window height %d too small (after splitting)", size_int
);
2988 if (size_int
+ window_min_height
> XFASTINT (o
->height
))
2989 error ("Window height %d too small (after splitting)",
2990 XFASTINT (o
->height
) - size_int
);
2991 if (NILP (o
->parent
)
2992 || NILP (XWINDOW (o
->parent
)->vchild
))
2994 make_dummy_parent (window
);
2996 XWINDOW (new)->vchild
= window
;
3001 if (size_int
< window_min_width
)
3002 error ("Window width %d too small (after splitting)", size_int
);
3004 if (size_int
+ window_min_width
> XFASTINT (o
->width
))
3005 error ("Window width %d too small (after splitting)",
3006 XFASTINT (o
->width
) - size_int
);
3007 if (NILP (o
->parent
)
3008 || NILP (XWINDOW (o
->parent
)->hchild
))
3010 make_dummy_parent (window
);
3012 XWINDOW (new)->hchild
= window
;
3016 /* Now we know that window's parent is a vertical combination
3017 if we are dividing vertically, or a horizontal combination
3018 if we are making side-by-side windows */
3020 windows_or_buffers_changed
++;
3021 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
3022 new = make_window ();
3025 p
->frame
= o
->frame
;
3027 if (!NILP (p
->next
))
3028 XWINDOW (p
->next
)->prev
= new;
3031 p
->parent
= o
->parent
;
3033 p
->window_end_valid
= Qnil
;
3034 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
3036 /* Apportion the available frame space among the two new windows */
3038 if (!NILP (horflag
))
3040 p
->height
= o
->height
;
3042 XSETFASTINT (p
->width
, XFASTINT (o
->width
) - size_int
);
3043 XSETFASTINT (o
->width
, size_int
);
3044 XSETFASTINT (p
->left
, XFASTINT (o
->left
) + size_int
);
3049 p
->width
= o
->width
;
3050 XSETFASTINT (p
->height
, XFASTINT (o
->height
) - size_int
);
3051 XSETFASTINT (o
->height
, size_int
);
3052 XSETFASTINT (p
->top
, XFASTINT (o
->top
) + size_int
);
3055 /* Adjust glyph matrices. */
3057 Fset_window_buffer (new, o
->buffer
);
3061 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
3062 "Make current window ARG lines bigger.\n\
3063 From program, optional second arg non-nil means grow sideways ARG columns.")
3065 register Lisp_Object arg
, side
;
3067 CHECK_NUMBER (arg
, 0);
3068 enlarge_window (selected_window
, XINT (arg
), !NILP (side
));
3070 if (! NILP (Vwindow_configuration_change_hook
))
3071 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3076 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
3077 "Make current window ARG lines smaller.\n\
3078 From program, optional second arg non-nil means shrink sideways arg columns.")
3080 register Lisp_Object arg
, side
;
3082 CHECK_NUMBER (arg
, 0);
3083 enlarge_window (selected_window
, -XINT (arg
), !NILP (side
));
3085 if (! NILP (Vwindow_configuration_change_hook
))
3086 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3092 window_height (window
)
3095 register struct window
*p
= XWINDOW (window
);
3096 return XFASTINT (p
->height
);
3100 window_width (window
)
3103 register struct window
*p
= XWINDOW (window
);
3104 return XFASTINT (p
->width
);
3109 *(widthflag ? &(XWINDOW (w)->left) : &(XWINDOW (w)->top))
3111 #define CURSIZE(w) \
3112 *(widthflag ? &(XWINDOW (w)->width) : &(XWINDOW (w)->height))
3115 /* Enlarge selected_window by DELTA. WIDTHFLAG non-zero means
3116 increase its width. Siblings of the selected window are resized to
3117 fullfil the size request. If they become too small in the process,
3118 they will be deleted. */
3121 enlarge_window (window
, delta
, widthflag
)
3123 int delta
, widthflag
;
3125 Lisp_Object parent
, next
, prev
;
3129 int (*sizefun
) P_ ((Lisp_Object
))
3130 = widthflag
? window_width
: window_height
;
3131 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
3132 = (widthflag
? set_window_width
: set_window_height
);
3134 /* Check values of window_min_width and window_min_height for
3136 check_min_window_sizes ();
3138 /* Give up if this window cannot be resized. */
3139 if (window_fixed_size_p (XWINDOW (window
), widthflag
, 1))
3140 error ("Window is not resizable");
3142 /* Find the parent of the selected window. */
3145 p
= XWINDOW (window
);
3151 error ("No other window to side of this one");
3156 ? !NILP (XWINDOW (parent
)->hchild
)
3157 : !NILP (XWINDOW (parent
)->vchild
))
3163 sizep
= &CURSIZE (window
);
3166 register int maxdelta
;
3168 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - XINT (*sizep
)
3169 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3170 - window_min_size (XWINDOW (p
->next
),
3172 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
3173 - window_min_size (XWINDOW (p
->prev
),
3175 /* This is a frame with only one window, a minibuffer-only
3176 or a minibufferless frame. */
3179 if (delta
> maxdelta
)
3180 /* This case traps trying to make the minibuffer
3181 the full frame, or make the only window aside from the
3182 minibuffer the full frame. */
3186 if (XINT (*sizep
) + delta
< window_min_size (XWINDOW (window
), widthflag
, 0, 0))
3188 delete_window (window
);
3195 /* Find the total we can get from other siblings. */
3197 for (next
= p
->next
; ! NILP (next
); next
= XWINDOW (next
)->next
)
3198 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
3200 for (prev
= p
->prev
; ! NILP (prev
); prev
= XWINDOW (prev
)->prev
)
3201 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
3204 /* If we can get it all from them, do so. */
3205 if (delta
<= maximum
)
3207 Lisp_Object first_unaffected
;
3208 Lisp_Object first_affected
;
3213 first_affected
= window
;
3214 /* Look at one sibling at a time,
3215 moving away from this window in both directions alternately,
3216 and take as much as we can get without deleting that sibling. */
3217 while (delta
!= 0 && (!NILP (next
) || !NILP (prev
)))
3221 int this_one
= ((*sizefun
) (next
)
3222 - window_min_size (XWINDOW (next
),
3223 widthflag
, 0, &fixed_p
));
3226 if (this_one
> delta
)
3229 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
3230 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3235 next
= XWINDOW (next
)->next
;
3243 int this_one
= ((*sizefun
) (prev
)
3244 - window_min_size (XWINDOW (prev
),
3245 widthflag
, 0, &fixed_p
));
3248 if (this_one
> delta
)
3251 first_affected
= prev
;
3253 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
3254 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3259 prev
= XWINDOW (prev
)->prev
;
3263 xassert (delta
== 0);
3265 /* Now recalculate the edge positions of all the windows affected,
3266 based on the new sizes. */
3267 first_unaffected
= next
;
3268 prev
= first_affected
;
3269 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
3270 prev
= next
, next
= XWINDOW (next
)->next
)
3272 XSETINT (CURBEG (next
), XINT (CURBEG (prev
)) + (*sizefun
) (prev
));
3273 /* This does not change size of NEXT,
3274 but it propagates the new top edge to its children */
3275 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
3280 register int delta1
;
3281 register int opht
= (*sizefun
) (parent
);
3283 /* If trying to grow this window to or beyond size of the parent,
3284 make delta1 so big that, on shrinking back down,
3285 all the siblings end up with less than one line and are deleted. */
3286 if (opht
<= XINT (*sizep
) + delta
)
3287 delta1
= opht
* opht
* 2;
3290 /* Otherwise, make delta1 just right so that if we add
3291 delta1 lines to this window and to the parent, and then
3292 shrink the parent back to its original size, the new
3293 proportional size of this window will increase by delta.
3295 The function size_window will compute the new height h'
3296 of the window from delta1 as:
3299 x = delta1 - delta1/n * n for the 1st resizable child
3302 where n is the number of children that can be resized.
3303 We can ignore x by choosing a delta1 that is a multiple of
3304 n. We want the height of this window to come out as
3314 The number of children n rquals the number of resizable
3315 children of this window + 1 because we know window itself
3316 is resizable (otherwise we would have signalled an error. */
3318 struct window
*w
= XWINDOW (window
);
3322 for (s
= w
->next
; !NILP (s
); s
= XWINDOW (s
)->next
)
3323 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3325 for (s
= w
->prev
; !NILP (s
); s
= XWINDOW (s
)->prev
)
3326 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3332 /* Add delta1 lines or columns to this window, and to the parent,
3333 keeping things consistent while not affecting siblings. */
3334 XSETINT (CURSIZE (parent
), opht
+ delta1
);
3335 (*setsizefun
) (window
, XINT (*sizep
) + delta1
, 0);
3337 /* Squeeze out delta1 lines or columns from our parent,
3338 shriking this window and siblings proportionately.
3339 This brings parent back to correct size.
3340 Delta1 was calculated so this makes this window the desired size,
3341 taking it all out of the siblings. */
3342 (*setsizefun
) (parent
, opht
, 0);
3345 XSETFASTINT (p
->last_modified
, 0);
3346 XSETFASTINT (p
->last_overlay_modified
, 0);
3348 /* Adjust glyph matrices. */
3349 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
3357 /***********************************************************************
3358 Resizing Mini-Windows
3359 ***********************************************************************/
3361 static void shrink_window_lowest_first
P_ ((struct window
*, int));
3363 enum save_restore_action
3370 static int save_restore_orig_size
P_ ((struct window
*,
3371 enum save_restore_action
));
3373 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
3374 from lowest windows first. */
3377 shrink_window_lowest_first (w
, height
)
3385 xassert (!MINI_WINDOW_P (w
));
3387 /* Set redisplay hints. */
3388 XSETFASTINT (w
->last_modified
, 0);
3389 XSETFASTINT (w
->last_overlay_modified
, 0);
3390 windows_or_buffers_changed
++;
3391 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
3393 old_height
= XFASTINT (w
->height
);
3394 XSETFASTINT (w
->height
, height
);
3396 if (!NILP (w
->hchild
))
3398 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
3400 c
= XWINDOW (child
);
3402 shrink_window_lowest_first (c
, height
);
3405 else if (!NILP (w
->vchild
))
3407 Lisp_Object last_child
;
3408 int delta
= old_height
- height
;
3411 /* Find the last child. We are taking space from lowest windows
3412 first, so we iterate over children from the last child
3414 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
3417 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
3418 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
3422 c
= XWINDOW (child
);
3423 this_one
= XFASTINT (c
->height
) - MIN_SAFE_WINDOW_HEIGHT
;
3425 if (this_one
> delta
)
3428 shrink_window_lowest_first (c
, XFASTINT (c
->height
) - this_one
);
3432 /* Compute new positions. */
3433 last_top
= XINT (w
->top
);
3434 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
3436 c
= XWINDOW (child
);
3437 c
->top
= make_number (last_top
);
3438 shrink_window_lowest_first (c
, XFASTINT (c
->height
));
3439 last_top
+= XFASTINT (c
->height
);
3445 /* Save, restore, or check positions and sizes in the window tree
3446 rooted at W. ACTION says what to do.
3448 If ACTION is CHECK_ORIG_SIZES, check if orig_top and orig_height
3449 members are valid for all windows in the window tree. Value is
3450 non-zero if they are valid.
3452 If ACTION is SAVE_ORIG_SIZES, save members top and height in
3453 orig_top and orig_height for all windows in the tree.
3455 If ACTION is RESTORE_ORIG_SIZES, restore top and height from
3456 values stored in orig_top and orig_height for all windows. */
3459 save_restore_orig_size (w
, action
)
3461 enum save_restore_action action
;
3467 if (!NILP (w
->hchild
))
3469 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
3472 else if (!NILP (w
->vchild
))
3474 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
3480 case CHECK_ORIG_SIZES
:
3481 if (!INTEGERP (w
->orig_top
) || !INTEGERP (w
->orig_height
))
3485 case SAVE_ORIG_SIZES
:
3486 w
->orig_top
= w
->top
;
3487 w
->orig_height
= w
->height
;
3488 XSETFASTINT (w
->last_modified
, 0);
3489 XSETFASTINT (w
->last_overlay_modified
, 0);
3492 case RESTORE_ORIG_SIZES
:
3493 xassert (INTEGERP (w
->orig_top
) && INTEGERP (w
->orig_height
));
3494 w
->top
= w
->orig_top
;
3495 w
->height
= w
->orig_height
;
3496 w
->orig_height
= w
->orig_top
= Qnil
;
3497 XSETFASTINT (w
->last_modified
, 0);
3498 XSETFASTINT (w
->last_overlay_modified
, 0);
3505 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
3512 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
3513 without deleting other windows. */
3516 grow_mini_window (w
, delta
)
3520 struct frame
*f
= XFRAME (w
->frame
);
3521 struct window
*root
;
3523 xassert (MINI_WINDOW_P (w
));
3524 xassert (delta
>= 0);
3526 /* Check values of window_min_width and window_min_height for
3528 check_min_window_sizes ();
3530 /* Compute how much we can enlarge the mini-window without deleting
3532 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3535 int min_height
= window_min_size (root
, 0, 0, 0);
3536 if (XFASTINT (root
->height
) - delta
< min_height
)
3537 delta
= XFASTINT (root
->height
) - min_height
;
3542 /* Save original window sizes and positions, if not already done. */
3543 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3544 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
3546 /* Shrink other windows. */
3547 shrink_window_lowest_first (root
, XFASTINT (root
->height
) - delta
);
3549 /* Grow the mini-window. */
3550 w
->top
= make_number (XFASTINT (root
->top
) + XFASTINT (root
->height
));
3551 w
->height
= make_number (XFASTINT (w
->height
) + delta
);
3552 XSETFASTINT (w
->last_modified
, 0);
3553 XSETFASTINT (w
->last_overlay_modified
, 0);
3560 /* Shrink mini-window W. If there is recorded info about window sizes
3561 before a call to grow_mini_window, restore recorded window sizes.
3562 Otherwise, if the mini-window is higher than 1 line, resize it to 1
3566 shrink_mini_window (w
)
3569 struct frame
*f
= XFRAME (w
->frame
);
3570 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3572 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3574 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
3576 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
3577 windows_or_buffers_changed
= 1;
3579 else if (XFASTINT (w
->height
) > 1)
3582 XSETWINDOW (window
, w
);
3583 enlarge_window (window
, 1 - XFASTINT (w
->height
), 0);
3589 /* Mark window cursors off for all windows in the window tree rooted
3590 at W by setting their phys_cursor_on_p flag to zero. Called from
3591 xterm.c, e.g. when a frame is cleared and thereby all cursors on
3592 the frame are cleared. */
3595 mark_window_cursors_off (w
)
3600 if (!NILP (w
->hchild
))
3601 mark_window_cursors_off (XWINDOW (w
->hchild
));
3602 else if (!NILP (w
->vchild
))
3603 mark_window_cursors_off (XWINDOW (w
->vchild
));
3605 w
->phys_cursor_on_p
= 0;
3607 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
3612 /* Return number of lines of text (not counting mode line) in W. */
3615 window_internal_height (w
)
3618 int ht
= XFASTINT (w
->height
);
3620 if (MINI_WINDOW_P (w
))
3623 if (!NILP (w
->parent
) || !NILP (w
->vchild
) || !NILP (w
->hchild
)
3624 || !NILP (w
->next
) || !NILP (w
->prev
)
3625 || FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (w
))))
3632 /* Return the number of columns in W.
3633 Don't count columns occupied by scroll bars or the vertical bar
3634 separating W from the sibling to its right. */
3637 window_internal_width (w
)
3640 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
3641 int width
= XINT (w
->width
);
3643 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
3644 /* Scroll bars occupy a few columns. */
3645 width
-= FRAME_SCROLL_BAR_COLS (f
);
3646 else if (!WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
3647 /* The column of `|' characters separating side-by-side windows
3648 occupies one column only. */
3651 /* On window-systems, areas to the left and right of the window
3652 are used to display bitmaps there. */
3653 if (FRAME_WINDOW_P (f
))
3654 width
-= FRAME_FLAGS_AREA_COLS (f
);
3660 /************************************************************************
3662 ***********************************************************************/
3664 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
3665 one screen-full, which is defined as the height of the window minus
3666 next_screen_context_lines. If WHOLE is zero, scroll up N lines
3667 instead. Negative values of N mean scroll down. NOERROR non-zero
3668 means don't signal an error if we try to move over BEGV or ZV,
3672 window_scroll (window
, n
, whole
, noerror
)
3678 /* If we must, use the pixel-based version which is much slower than
3679 the line-based one but can handle varying line heights. */
3680 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
3681 window_scroll_pixel_based (window
, n
, whole
, noerror
);
3683 window_scroll_line_based (window
, n
, whole
, noerror
);
3687 /* Implementation of window_scroll that works based on pixel line
3688 heights. See the comment of window_scroll for parameter
3692 window_scroll_pixel_based (window
, n
, whole
, noerror
)
3699 struct window
*w
= XWINDOW (window
);
3700 struct text_pos start
;
3702 int this_scroll_margin
;
3705 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
3707 /* If PT is not visible in WINDOW, move back one half of
3709 XSETFASTINT (tem
, PT
);
3710 tem
= Fpos_visible_in_window_p (tem
, window
);
3713 /* Move backward half the height of the window. Performance note:
3714 vmotion used here is about 10% faster, but would give wrong
3715 results for variable height lines. */
3716 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3717 it
.current_y
= it
.last_visible_y
;
3718 move_it_vertically (&it
, -it
.last_visible_y
/ 2);
3720 /* The function move_iterator_vertically may move over more than
3721 the specified y-distance. If it->w is small, e.g. a
3722 mini-buffer window, we may end up in front of the window's
3723 display area. This is the case when Start displaying at the
3724 start of the line containing PT in this case. */
3725 if (it
.current_y
<= 0)
3727 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3728 move_it_vertically (&it
, 0);
3732 start
= it
.current
.pos
;
3735 /* If scroll_preserve_screen_position is non-zero, we try to set
3736 point in the same window line as it is now, so get that line. */
3737 if (!NILP (Vscroll_preserve_screen_position
))
3739 start_display (&it
, w
, start
);
3740 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3741 preserve_y
= it
.current_y
;
3746 /* Move iterator it from start the specified distance forward or
3747 backward. The result is the new window start. */
3748 start_display (&it
, w
, start
);
3751 int screen_full
= (it
.last_visible_y
3752 - next_screen_context_lines
* CANON_Y_UNIT (it
.f
));
3753 int direction
= n
< 0 ? -1 : 1;
3754 move_it_vertically (&it
, direction
* screen_full
);
3757 move_it_by_lines (&it
, n
, 1);
3759 /* End if we end up at ZV or BEGV. */
3760 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
3761 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
3765 else if (IT_CHARPOS (it
) == ZV
)
3766 Fsignal (Qend_of_buffer
, Qnil
);
3768 Fsignal (Qbeginning_of_buffer
, Qnil
);
3771 /* Set the window start, and set up the window for redisplay. */
3772 set_marker_restricted (w
->start
, make_number (IT_CHARPOS (it
)), w
->buffer
);
3773 w
->start_at_line_beg
= Fbolp ();
3774 w
->update_mode_line
= Qt
;
3775 XSETFASTINT (w
->last_modified
, 0);
3776 XSETFASTINT (w
->last_overlay_modified
, 0);
3777 /* Set force_start so that redisplay_window will run the
3778 window-scroll-functions. */
3779 w
->force_start
= Qt
;
3781 it
.current_y
= it
.vpos
= 0;
3783 /* Preserve the screen position if we must. */
3784 if (preserve_y
>= 0)
3786 move_it_to (&it
, -1, -1, preserve_y
, -1, MOVE_TO_Y
);
3787 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3791 /* Move PT out of scroll margins. */
3792 this_scroll_margin
= max (0, scroll_margin
);
3793 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->height
) / 4);
3794 this_scroll_margin
*= CANON_Y_UNIT (it
.f
);
3798 /* We moved the window start towards ZV, so PT may be now
3799 in the scroll margin at the top. */
3800 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3801 while (it
.current_y
< this_scroll_margin
)
3802 move_it_by_lines (&it
, 1, 1);
3803 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3807 /* We moved the window start towards BEGV, so PT may be now
3808 in the scroll margin at the bottom. */
3809 move_it_to (&it
, PT
, -1,
3810 it
.last_visible_y
- this_scroll_margin
- 1, -1,
3811 MOVE_TO_POS
| MOVE_TO_Y
);
3813 /* Don't put point on a partially visible line at the end. */
3814 if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
3815 > it
.last_visible_y
)
3816 move_it_by_lines (&it
, -1, 0);
3818 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3824 /* Implementation of window_scroll that works based on screen lines.
3825 See the comment of window_scroll for parameter descriptions. */
3828 window_scroll_line_based (window
, n
, whole
, noerror
)
3834 register struct window
*w
= XWINDOW (window
);
3835 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
3836 register int pos
, pos_byte
;
3837 register int ht
= window_internal_height (w
);
3838 register Lisp_Object tem
;
3842 struct position posit
;
3845 startpos
= marker_position (w
->start
);
3847 posit
= *compute_motion (startpos
, 0, 0, 0,
3849 window_internal_width (w
), XINT (w
->hscroll
),
3851 original_vpos
= posit
.vpos
;
3853 XSETFASTINT (tem
, PT
);
3854 tem
= Fpos_visible_in_window_p (tem
, window
);
3858 Fvertical_motion (make_number (- (ht
/ 2)), window
);
3863 lose
= n
< 0 && PT
== BEGV
;
3864 Fvertical_motion (make_number (n
), window
);
3868 SET_PT_BOTH (opoint
, opoint_byte
);
3875 Fsignal (Qbeginning_of_buffer
, Qnil
);
3880 int this_scroll_margin
= scroll_margin
;
3882 /* Don't use a scroll margin that is negative or too large. */
3883 if (this_scroll_margin
< 0)
3884 this_scroll_margin
= 0;
3886 if (XINT (w
->height
) < 4 * scroll_margin
)
3887 this_scroll_margin
= XINT (w
->height
) / 4;
3889 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
3890 w
->start_at_line_beg
= bolp
;
3891 w
->update_mode_line
= Qt
;
3892 XSETFASTINT (w
->last_modified
, 0);
3893 XSETFASTINT (w
->last_overlay_modified
, 0);
3894 /* Set force_start so that redisplay_window will run
3895 the window-scroll-functions. */
3896 w
->force_start
= Qt
;
3898 if (whole
&& !NILP (Vscroll_preserve_screen_position
))
3900 SET_PT_BOTH (pos
, pos_byte
);
3901 Fvertical_motion (make_number (original_vpos
), window
);
3903 /* If we scrolled forward, put point enough lines down
3904 that it is outside the scroll margin. */
3909 if (this_scroll_margin
> 0)
3911 SET_PT_BOTH (pos
, pos_byte
);
3912 Fvertical_motion (make_number (this_scroll_margin
), window
);
3918 if (top_margin
<= opoint
)
3919 SET_PT_BOTH (opoint
, opoint_byte
);
3920 else if (!NILP (Vscroll_preserve_screen_position
))
3922 SET_PT_BOTH (pos
, pos_byte
);
3923 Fvertical_motion (make_number (original_vpos
), window
);
3926 SET_PT (top_margin
);
3932 /* If we scrolled backward, put point near the end of the window
3933 but not within the scroll margin. */
3934 SET_PT_BOTH (pos
, pos_byte
);
3935 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
3936 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
3939 bottom_margin
= PT
+ 1;
3941 if (bottom_margin
> opoint
)
3942 SET_PT_BOTH (opoint
, opoint_byte
);
3945 if (!NILP (Vscroll_preserve_screen_position
))
3947 SET_PT_BOTH (pos
, pos_byte
);
3948 Fvertical_motion (make_number (original_vpos
), window
);
3951 Fvertical_motion (make_number (-1), window
);
3960 Fsignal (Qend_of_buffer
, Qnil
);
3965 /* Scroll selected_window up or down. If N is nil, scroll a
3966 screen-full which is defined as the height of the window minus
3967 next_screen_context_lines. If N is the symbol `-', scroll.
3968 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
3969 up. This is the guts of Fscroll_up and Fscroll_down. */
3972 scroll_command (n
, direction
)
3976 register int defalt
;
3977 int count
= specpdl_ptr
- specpdl
;
3979 xassert (abs (direction
) == 1);
3981 /* If selected window's buffer isn't current, make it current for
3982 the moment. But don't screw up if window_scroll gets an error. */
3983 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
3985 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
3986 Fset_buffer (XWINDOW (selected_window
)->buffer
);
3988 /* Make redisplay consider other windows than just selected_window. */
3989 ++windows_or_buffers_changed
;
3992 defalt
= (window_internal_height (XWINDOW (selected_window
))
3993 - next_screen_context_lines
);
3994 defalt
= direction
* (defalt
< 1 ? 1 : defalt
);
3997 window_scroll (selected_window
, defalt
, 1, 0);
3998 else if (EQ (n
, Qminus
))
3999 window_scroll (selected_window
, - defalt
, 1, 0);
4002 n
= Fprefix_numeric_value (n
);
4003 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
4006 unbind_to (count
, Qnil
);
4009 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
4010 "Scroll text of current window upward ARG lines; or near full screen if no ARG.\n\
4011 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4012 Negative ARG means scroll downward.\n\
4013 If ARG is the atom `-', scroll downward by nearly full screen.\n\
4014 When calling from a program, supply as argument a number, nil, or `-'.")
4018 scroll_command (arg
, 1);
4022 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
4023 "Scroll text of current window down ARG lines; or near full screen if no ARG.\n\
4024 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4025 Negative ARG means scroll upward.\n\
4026 If ARG is the atom `-', scroll upward by nearly full screen.\n\
4027 When calling from a program, supply as argument a number, nil, or `-'.")
4031 scroll_command (arg
, -1);
4035 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
4036 "Return the other window for \"other window scroll\" commands.\n\
4037 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4038 specifies the window.\n\
4039 If `other-window-scroll-buffer' is non-nil, a window\n\
4040 showing that buffer is used.")
4045 if (MINI_WINDOW_P (XWINDOW (selected_window
))
4046 && !NILP (Vminibuf_scroll_window
))
4047 window
= Vminibuf_scroll_window
;
4048 /* If buffer is specified, scroll that buffer. */
4049 else if (!NILP (Vother_window_scroll_buffer
))
4051 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
4053 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
4057 /* Nothing specified; look for a neighboring window on the same
4059 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
4061 if (EQ (window
, selected_window
))
4062 /* That didn't get us anywhere; look for a window on another
4065 window
= Fnext_window (window
, Qnil
, Qt
);
4066 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
4067 && ! EQ (window
, selected_window
));
4070 CHECK_LIVE_WINDOW (window
, 0);
4072 if (EQ (window
, selected_window
))
4073 error ("There is no other window");
4078 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
4079 "Scroll next window upward ARG lines; or near full screen if no ARG.\n\
4080 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4081 The next window is the one below the current one; or the one at the top\n\
4082 if the current one is at the bottom. Negative ARG means scroll downward.\n\
4083 If ARG is the atom `-', scroll downward by nearly full screen.\n\
4084 When calling from a program, supply as argument a number, nil, or `-'.\n\
4086 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4087 specifies the window to scroll.\n\
4088 If `other-window-scroll-buffer' is non-nil, scroll the window\n\
4089 showing that buffer, popping the buffer up if necessary.")
4091 register Lisp_Object arg
;
4093 register Lisp_Object window
;
4094 register int defalt
;
4095 register struct window
*w
;
4096 register int count
= specpdl_ptr
- specpdl
;
4098 window
= Fother_window_for_scrolling ();
4100 w
= XWINDOW (window
);
4101 defalt
= window_internal_height (w
) - next_screen_context_lines
;
4102 if (defalt
< 1) defalt
= 1;
4104 /* Don't screw up if window_scroll gets an error. */
4105 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4106 ++windows_or_buffers_changed
;
4108 Fset_buffer (w
->buffer
);
4109 SET_PT (marker_position (w
->pointm
));
4112 window_scroll (window
, defalt
, 1, 1);
4113 else if (EQ (arg
, Qminus
))
4114 window_scroll (window
, -defalt
, 1, 1);
4119 CHECK_NUMBER (arg
, 0);
4120 window_scroll (window
, XINT (arg
), 0, 1);
4123 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
4124 unbind_to (count
, Qnil
);
4129 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 1, "P",
4130 "Scroll selected window display ARG columns left.\n\
4131 Default for ARG is window width minus 2.")
4133 register Lisp_Object arg
;
4137 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4139 arg
= Fprefix_numeric_value (arg
);
4142 Fset_window_hscroll (selected_window
,
4143 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4147 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 1, "P",
4148 "Scroll selected window display ARG columns right.\n\
4149 Default for ARG is window width minus 2.")
4151 register Lisp_Object arg
;
4154 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4156 arg
= Fprefix_numeric_value (arg
);
4159 Fset_window_hscroll (selected_window
,
4160 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4164 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
4165 "Center point in window and redisplay frame. With ARG, put point on line ARG.\n\
4166 The desired position of point is always relative to the current window.\n\
4167 Just C-u as prefix means put point in the center of the window.\n\
4168 If ARG is omitted or nil, erases the entire frame and then\n\
4169 redraws with point in the center of the current window.")
4171 register Lisp_Object arg
;
4173 register struct window
*w
= XWINDOW (selected_window
);
4174 register int ht
= window_internal_height (w
);
4175 struct position pos
;
4176 struct buffer
*buf
= XBUFFER (w
->buffer
);
4177 struct buffer
*obuf
= current_buffer
;
4181 extern int frame_garbaged
;
4184 /* Invalidate pixel data calculated for all compositions. */
4185 for (i
= 0; i
< n_compositions
; i
++)
4186 composition_table
[i
]->font
= NULL
;
4188 Fredraw_frame (w
->frame
);
4189 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
4190 XSETFASTINT (arg
, ht
/ 2);
4192 else if (CONSP (arg
)) /* Just C-u. */
4194 XSETFASTINT (arg
, ht
/ 2);
4198 arg
= Fprefix_numeric_value (arg
);
4199 CHECK_NUMBER (arg
, 0);
4203 XSETINT (arg
, XINT (arg
) + ht
);
4205 set_buffer_internal (buf
);
4206 pos
= *vmotion (PT
, - XINT (arg
), w
);
4208 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
4209 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
4210 || FETCH_BYTE (pos
.bytepos
- 1) == '\n')
4212 w
->force_start
= Qt
;
4213 set_buffer_internal (obuf
);
4218 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
4220 "Position point relative to window.\n\
4221 With no argument, position point at center of window.\n\
4222 An argument specifies vertical position within the window;\n\
4223 zero means top of window, negative means relative to bottom of window.")
4225 register Lisp_Object arg
;
4227 register struct window
*w
= XWINDOW (selected_window
);
4228 register int height
= window_internal_height (w
);
4233 XSETFASTINT (arg
, height
/ 2);
4236 arg
= Fprefix_numeric_value (arg
);
4238 XSETINT (arg
, XINT (arg
) + height
);
4241 start
= marker_position (w
->start
);
4242 XSETWINDOW (window
, w
);
4243 if (start
< BEGV
|| start
> ZV
)
4245 Fvertical_motion (make_number (- (height
/ 2)), window
);
4246 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
4247 w
->start_at_line_beg
= Fbolp ();
4248 w
->force_start
= Qt
;
4251 Fgoto_char (w
->start
);
4253 return Fvertical_motion (arg
, window
);
4258 /***********************************************************************
4259 Window Configuration
4260 ***********************************************************************/
4262 struct save_window_data
4264 EMACS_INT size_from_Lisp_Vector_struct
;
4265 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4266 Lisp_Object frame_width
, frame_height
, frame_menu_bar_lines
;
4267 Lisp_Object frame_tool_bar_lines
;
4268 Lisp_Object selected_frame
;
4269 Lisp_Object current_window
;
4270 Lisp_Object current_buffer
;
4271 Lisp_Object minibuf_scroll_window
;
4272 Lisp_Object root_window
;
4273 Lisp_Object focus_frame
;
4274 /* Record the values of window-min-width and window-min-height
4275 so that window sizes remain consistent with them. */
4276 Lisp_Object min_width
, min_height
;
4277 /* A vector, each of whose elements is a struct saved_window
4279 Lisp_Object saved_windows
;
4282 /* This is saved as a Lisp_Vector */
4285 /* these first two must agree with struct Lisp_Vector in lisp.h */
4286 EMACS_INT size_from_Lisp_Vector_struct
;
4287 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4290 Lisp_Object buffer
, start
, pointm
, mark
;
4291 Lisp_Object left
, top
, width
, height
, hscroll
;
4292 Lisp_Object parent
, prev
;
4293 Lisp_Object start_at_line_beg
;
4294 Lisp_Object display_table
;
4296 #define SAVED_WINDOW_VECTOR_SIZE 14 /* Arg to Fmake_vector */
4298 #define SAVED_WINDOW_N(swv,n) \
4299 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
4301 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
4302 "Return t if OBJECT is a window-configuration object.")
4306 if (WINDOW_CONFIGURATIONP (object
))
4311 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
4312 "Return the frame that CONFIG, a window-configuration object, is about.")
4316 register struct save_window_data
*data
;
4317 struct Lisp_Vector
*saved_windows
;
4319 if (! WINDOW_CONFIGURATIONP (config
))
4320 wrong_type_argument (Qwindow_configuration_p
, config
);
4322 data
= (struct save_window_data
*) XVECTOR (config
);
4323 saved_windows
= XVECTOR (data
->saved_windows
);
4324 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4327 DEFUN ("set-window-configuration", Fset_window_configuration
,
4328 Sset_window_configuration
, 1, 1, 0,
4329 "Set the configuration of windows and buffers as specified by CONFIGURATION.\n\
4330 CONFIGURATION must be a value previously returned\n\
4331 by `current-window-configuration' (which see).\n\
4332 If CONFIGURATION was made from a frame that is now deleted,\n\
4333 only frame-independent values can be restored. In this case,\n\
4334 the return value is nil. Otherwise the value is t.")
4336 Lisp_Object configuration
;
4338 register struct save_window_data
*data
;
4339 struct Lisp_Vector
*saved_windows
;
4340 Lisp_Object new_current_buffer
;
4345 while (!WINDOW_CONFIGURATIONP (configuration
))
4346 wrong_type_argument (Qwindow_configuration_p
, configuration
);
4348 data
= (struct save_window_data
*) XVECTOR (configuration
);
4349 saved_windows
= XVECTOR (data
->saved_windows
);
4351 new_current_buffer
= data
->current_buffer
;
4352 if (NILP (XBUFFER (new_current_buffer
)->name
))
4353 new_current_buffer
= Qnil
;
4356 if (XBUFFER (new_current_buffer
) == current_buffer
)
4361 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4364 /* If f is a dead frame, don't bother rebuilding its window tree.
4365 However, there is other stuff we should still try to do below. */
4366 if (FRAME_LIVE_P (f
))
4368 register struct window
*w
;
4369 register struct saved_window
*p
;
4370 struct window
*root_window
;
4371 struct window
**leaf_windows
;
4375 /* If the frame has been resized since this window configuration was
4376 made, we change the frame to the size specified in the
4377 configuration, restore the configuration, and then resize it
4378 back. We keep track of the prevailing height in these variables. */
4379 int previous_frame_height
= FRAME_HEIGHT (f
);
4380 int previous_frame_width
= FRAME_WIDTH (f
);
4381 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
4382 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
4384 /* The mouse highlighting code could get screwed up
4385 if it runs during this. */
4388 if (XFASTINT (data
->frame_height
) != previous_frame_height
4389 || XFASTINT (data
->frame_width
) != previous_frame_width
)
4390 change_frame_size (f
, XFASTINT (data
->frame_height
),
4391 XFASTINT (data
->frame_width
), 0, 0, 0);
4392 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4393 if (XFASTINT (data
->frame_menu_bar_lines
)
4394 != previous_frame_menu_bar_lines
)
4395 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, make_number (0));
4396 #ifdef HAVE_WINDOW_SYSTEM
4397 if (XFASTINT (data
->frame_tool_bar_lines
)
4398 != previous_frame_tool_bar_lines
)
4399 x_set_tool_bar_lines (f
, data
->frame_tool_bar_lines
, make_number (0));
4403 /* "Swap out" point from the selected window
4404 into its buffer. We do this now, before
4405 restoring the window contents, and prevent it from
4406 being done later on when we select a new window. */
4407 if (! NILP (XWINDOW (selected_window
)->buffer
))
4409 w
= XWINDOW (selected_window
);
4410 set_marker_both (w
->pointm
,
4412 BUF_PT (XBUFFER (w
->buffer
)),
4413 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4416 windows_or_buffers_changed
++;
4417 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4419 /* Problem: Freeing all matrices and later allocating them again
4420 is a serious redisplay flickering problem. What we would
4421 really like to do is to free only those matrices not reused
4423 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4425 = (struct window
**) alloca (count_windows (root_window
)
4426 * sizeof (struct window
*));
4427 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
4429 /* Temporarily avoid any problems with windows that are smaller
4430 than they are supposed to be. */
4431 window_min_height
= 1;
4432 window_min_width
= 1;
4435 Mark all windows now on frame as "deleted".
4436 Restoring the new configuration "undeletes" any that are in it.
4438 Save their current buffers in their height fields, since we may
4439 need it later, if a buffer saved in the configuration is now
4441 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4443 for (k
= 0; k
< saved_windows
->size
; k
++)
4445 p
= SAVED_WINDOW_N (saved_windows
, k
);
4446 w
= XWINDOW (p
->window
);
4449 if (!NILP (p
->parent
))
4450 w
->parent
= SAVED_WINDOW_N (saved_windows
,
4451 XFASTINT (p
->parent
))->window
;
4455 if (!NILP (p
->prev
))
4457 w
->prev
= SAVED_WINDOW_N (saved_windows
,
4458 XFASTINT (p
->prev
))->window
;
4459 XWINDOW (w
->prev
)->next
= p
->window
;
4464 if (!NILP (w
->parent
))
4466 if (EQ (p
->width
, XWINDOW (w
->parent
)->width
))
4468 XWINDOW (w
->parent
)->vchild
= p
->window
;
4469 XWINDOW (w
->parent
)->hchild
= Qnil
;
4473 XWINDOW (w
->parent
)->hchild
= p
->window
;
4474 XWINDOW (w
->parent
)->vchild
= Qnil
;
4479 /* If we squirreled away the buffer in the window's height,
4481 if (BUFFERP (w
->height
))
4482 w
->buffer
= w
->height
;
4485 w
->width
= p
->width
;
4486 w
->height
= p
->height
;
4487 w
->hscroll
= p
->hscroll
;
4488 w
->display_table
= p
->display_table
;
4489 XSETFASTINT (w
->last_modified
, 0);
4490 XSETFASTINT (w
->last_overlay_modified
, 0);
4492 /* Reinstall the saved buffer and pointers into it. */
4493 if (NILP (p
->buffer
))
4494 w
->buffer
= p
->buffer
;
4497 if (!NILP (XBUFFER (p
->buffer
)->name
))
4498 /* If saved buffer is alive, install it. */
4500 w
->buffer
= p
->buffer
;
4501 w
->start_at_line_beg
= p
->start_at_line_beg
;
4502 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
4503 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
4504 Fset_marker (XBUFFER (w
->buffer
)->mark
,
4505 p
->mark
, w
->buffer
);
4507 /* As documented in Fcurrent_window_configuration, don't
4508 save the location of point in the buffer which was current
4509 when the window configuration was recorded. */
4510 if (!EQ (p
->buffer
, new_current_buffer
)
4511 && XBUFFER (p
->buffer
) == current_buffer
)
4512 Fgoto_char (w
->pointm
);
4514 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
4515 /* Else unless window has a live buffer, get one. */
4517 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
4518 /* This will set the markers to beginning of visible
4520 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
4521 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
4522 w
->start_at_line_beg
= Qt
;
4525 /* Keeping window's old buffer; make sure the markers
4528 /* Set window markers at start of visible range. */
4529 if (XMARKER (w
->start
)->buffer
== 0)
4530 set_marker_restricted (w
->start
, make_number (0),
4532 if (XMARKER (w
->pointm
)->buffer
== 0)
4533 set_marker_restricted_both (w
->pointm
, w
->buffer
,
4534 BUF_PT (XBUFFER (w
->buffer
)),
4535 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4536 w
->start_at_line_beg
= Qt
;
4541 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
4542 /* Prevent "swapping out point" in the old selected window
4543 using the buffer that has been restored into it.
4544 That swapping out has already been done,
4545 near the beginning of this function. */
4546 selected_window
= Qnil
;
4547 Fselect_window (data
->current_window
);
4548 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
4551 if (NILP (data
->focus_frame
)
4552 || (FRAMEP (data
->focus_frame
)
4553 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
4554 Fredirect_frame_focus (frame
, data
->focus_frame
);
4556 #if 0 /* I don't understand why this is needed, and it causes problems
4557 when the frame's old selected window has been deleted. */
4558 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
4559 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
4563 /* Set the screen height to the value it had before this function. */
4564 if (previous_frame_height
!= FRAME_HEIGHT (f
)
4565 || previous_frame_width
!= FRAME_WIDTH (f
))
4566 change_frame_size (f
, previous_frame_height
, previous_frame_width
,
4568 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4569 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
4570 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
4572 #ifdef HAVE_WINDOW_SYSTEM
4573 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
4574 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
4579 /* Now, free glyph matrices in windows that were not reused. */
4580 for (i
= 0; i
< n_leaf_windows
; ++i
)
4581 if (NILP (leaf_windows
[i
]->buffer
))
4583 /* Assert it's not reused as a combination. */
4584 xassert (NILP (leaf_windows
[i
]->hchild
)
4585 && NILP (leaf_windows
[i
]->vchild
));
4586 free_window_matrices (leaf_windows
[i
]);
4587 SET_FRAME_GARBAGED (f
);
4594 /* Fselect_window will have made f the selected frame, so we
4595 reselect the proper frame here. Fhandle_switch_frame will change the
4596 selected window too, but that doesn't make the call to
4597 Fselect_window above totally superfluous; it still sets f's
4599 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
4600 do_switch_frame (data
->selected_frame
, Qnil
, 0);
4602 if (! NILP (Vwindow_configuration_change_hook
)
4603 && ! NILP (Vrun_hooks
))
4604 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
4607 if (!NILP (new_current_buffer
))
4609 Fset_buffer (new_current_buffer
);
4611 /* If the buffer that is current now is the same
4612 that was current before setting the window configuration,
4613 don't alter its PT. */
4618 /* Restore the minimum heights recorded in the configuration. */
4619 window_min_height
= XINT (data
->min_height
);
4620 window_min_width
= XINT (data
->min_width
);
4622 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
4624 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
4627 /* Mark all windows now on frame as deleted
4628 by setting their buffers to nil. */
4631 delete_all_subwindows (w
)
4632 register struct window
*w
;
4634 if (!NILP (w
->next
))
4635 delete_all_subwindows (XWINDOW (w
->next
));
4636 if (!NILP (w
->vchild
))
4637 delete_all_subwindows (XWINDOW (w
->vchild
));
4638 if (!NILP (w
->hchild
))
4639 delete_all_subwindows (XWINDOW (w
->hchild
));
4641 w
->height
= w
->buffer
; /* See Fset_window_configuration for excuse. */
4643 if (!NILP (w
->buffer
))
4646 /* We set all three of these fields to nil, to make sure that we can
4647 distinguish this dead window from any live window. Live leaf
4648 windows will have buffer set, and combination windows will have
4649 vchild or hchild set. */
4656 count_windows (window
)
4657 register struct window
*window
;
4659 register int count
= 1;
4660 if (!NILP (window
->next
))
4661 count
+= count_windows (XWINDOW (window
->next
));
4662 if (!NILP (window
->vchild
))
4663 count
+= count_windows (XWINDOW (window
->vchild
));
4664 if (!NILP (window
->hchild
))
4665 count
+= count_windows (XWINDOW (window
->hchild
));
4670 /* Fill vector FLAT with leaf windows under W, starting at index I.
4671 Value is last index + 1. */
4674 get_leaf_windows (w
, flat
, i
)
4676 struct window
**flat
;
4681 if (!NILP (w
->hchild
))
4682 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
4683 else if (!NILP (w
->vchild
))
4684 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
4688 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4695 /* Return a pointer to the glyph W's physical cursor is on. Value is
4696 null if W's current matrix is invalid, so that no meaningfull glyph
4700 get_phys_cursor_glyph (w
)
4703 struct glyph_row
*row
;
4704 struct glyph
*glyph
;
4706 if (w
->phys_cursor
.vpos
>= 0
4707 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
4708 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
4710 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
4711 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
4720 save_window_save (window
, vector
, i
)
4722 struct Lisp_Vector
*vector
;
4725 register struct saved_window
*p
;
4726 register struct window
*w
;
4727 register Lisp_Object tem
;
4729 for (;!NILP (window
); window
= w
->next
)
4731 p
= SAVED_WINDOW_N (vector
, i
);
4732 w
= XWINDOW (window
);
4734 XSETFASTINT (w
->temslot
, i
++);
4736 p
->buffer
= w
->buffer
;
4739 p
->width
= w
->width
;
4740 p
->height
= w
->height
;
4741 p
->hscroll
= w
->hscroll
;
4742 p
->display_table
= w
->display_table
;
4743 if (!NILP (w
->buffer
))
4745 /* Save w's value of point in the window configuration.
4746 If w is the selected window, then get the value of point
4747 from the buffer; pointm is garbage in the selected window. */
4748 if (EQ (window
, selected_window
))
4750 p
->pointm
= Fmake_marker ();
4751 set_marker_both (p
->pointm
, w
->buffer
,
4752 BUF_PT (XBUFFER (w
->buffer
)),
4753 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4756 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
4758 p
->start
= Fcopy_marker (w
->start
, Qnil
);
4759 p
->start_at_line_beg
= w
->start_at_line_beg
;
4761 tem
= XBUFFER (w
->buffer
)->mark
;
4762 p
->mark
= Fcopy_marker (tem
, Qnil
);
4769 p
->start_at_line_beg
= Qnil
;
4772 if (NILP (w
->parent
))
4775 p
->parent
= XWINDOW (w
->parent
)->temslot
;
4780 p
->prev
= XWINDOW (w
->prev
)->temslot
;
4782 if (!NILP (w
->vchild
))
4783 i
= save_window_save (w
->vchild
, vector
, i
);
4784 if (!NILP (w
->hchild
))
4785 i
= save_window_save (w
->hchild
, vector
, i
);
4791 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
4792 Scurrent_window_configuration
, 0, 1, 0,
4793 "Return an object representing the current window configuration of FRAME.\n\
4794 If FRAME is nil or omitted, use the selected frame.\n\
4795 This describes the number of windows, their sizes and current buffers,\n\
4796 and for each displayed buffer, where display starts, and the positions of\n\
4797 point and mark. An exception is made for point in the current buffer:\n\
4798 its value is -not- saved.\n\
4799 This also records the currently selected frame, and FRAME's focus\n\
4800 redirection (see `redirect-frame-focus').")
4804 register Lisp_Object tem
;
4805 register int n_windows
;
4806 register struct save_window_data
*data
;
4807 register struct Lisp_Vector
*vec
;
4812 frame
= selected_frame
;
4813 CHECK_LIVE_FRAME (frame
, 0);
4816 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4817 vec
= allocate_vectorlike (VECSIZE (struct save_window_data
));
4818 for (i
= 0; i
< VECSIZE (struct save_window_data
); i
++)
4819 vec
->contents
[i
] = Qnil
;
4820 vec
->size
= VECSIZE (struct save_window_data
);
4821 data
= (struct save_window_data
*)vec
;
4823 XSETFASTINT (data
->frame_width
, FRAME_WIDTH (f
));
4824 XSETFASTINT (data
->frame_height
, FRAME_HEIGHT (f
));
4825 XSETFASTINT (data
->frame_menu_bar_lines
, FRAME_MENU_BAR_LINES (f
));
4826 XSETFASTINT (data
->frame_tool_bar_lines
, FRAME_TOOL_BAR_LINES (f
));
4827 data
->selected_frame
= selected_frame
;
4828 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
4829 XSETBUFFER (data
->current_buffer
, current_buffer
);
4830 data
->minibuf_scroll_window
= Vminibuf_scroll_window
;
4831 data
->root_window
= FRAME_ROOT_WINDOW (f
);
4832 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
4833 XSETINT (data
->min_height
, window_min_height
);
4834 XSETINT (data
->min_width
, window_min_width
);
4835 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
4836 data
->saved_windows
= tem
;
4837 for (i
= 0; i
< n_windows
; i
++)
4838 XVECTOR (tem
)->contents
[i
]
4839 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
4840 save_window_save (FRAME_ROOT_WINDOW (f
),
4842 XSETWINDOW_CONFIGURATION (tem
, data
);
4846 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
4848 "Execute body, preserving window sizes and contents.\n\
4849 Restore which buffer appears in which window, where display starts,\n\
4850 and the value of point and mark for each window.\n\
4851 Also restore the choice of selected window.\n\
4852 Also restore which buffer is current.\n\
4853 Does not restore the value of point in current buffer.")
4857 register Lisp_Object val
;
4858 register int count
= specpdl_ptr
- specpdl
;
4860 record_unwind_protect (Fset_window_configuration
,
4861 Fcurrent_window_configuration (Qnil
));
4862 val
= Fprogn (args
);
4863 return unbind_to (count
, val
);
4867 /***********************************************************************
4869 ***********************************************************************/
4871 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
4873 "Set width of marginal areas of window WINDOW.\n\
4874 If window is nil, set margins of the currently selected window.\n\
4875 First parameter LEFT-WIDTH specifies the number of character\n\
4876 cells to reserve for the left marginal area. Second parameter\n\
4877 RIGHT-WIDTH does the same for the right marginal area.\n\
4878 A nil width parameter means no margin.")
4879 (window
, left
, right
)
4880 Lisp_Object window
, left
, right
;
4882 struct window
*w
= decode_window (window
);
4885 CHECK_NUMBER_OR_FLOAT (left
, 1);
4887 CHECK_NUMBER_OR_FLOAT (right
, 2);
4889 /* Check widths < 0 and translate a zero width to nil.
4890 Margins that are too wide have to be checked elsewhere. */
4891 if ((INTEGERP (left
) && XINT (left
) < 0)
4892 || (FLOATP (left
) && XFLOAT_DATA (left
) <= 0))
4893 XSETFASTINT (left
, 0);
4894 if (INTEGERP (left
) && XFASTINT (left
) == 0)
4897 if ((INTEGERP (right
) && XINT (right
) < 0)
4898 || (FLOATP (right
) && XFLOAT_DATA (right
) <= 0))
4899 XSETFASTINT (right
, 0);
4900 if (INTEGERP (right
) && XFASTINT (right
) == 0)
4903 w
->left_margin_width
= left
;
4904 w
->right_margin_width
= right
;
4906 ++windows_or_buffers_changed
;
4907 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
4912 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
4914 "Get width of marginal areas of window WINDOW.\n\
4915 If WINDOW is omitted or nil, use the currently selected window.\n\
4916 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).\n\
4917 If a marginal area does not exist, its width will be returned\n\
4922 struct window
*w
= decode_window (window
);
4923 return Fcons (w
->left_margin_width
, w
->right_margin_width
);
4928 /***********************************************************************
4930 ***********************************************************************/
4932 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 1, 0,
4933 "Return the amount by which WINDOW is scrolled vertically.\n\
4934 Use the selected window if WINDOW is nil or omitted.\n\
4935 Value is a multiple of the canonical character height of WINDOW.")
4944 window
= selected_window
;
4946 CHECK_WINDOW (window
, 0);
4947 w
= XWINDOW (window
);
4948 f
= XFRAME (w
->frame
);
4950 if (FRAME_WINDOW_P (f
))
4951 result
= CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
);
4953 result
= make_number (0);
4958 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
4960 "Set amount by which WINDOW should be scrolled vertically to VSCROLL.\n\
4961 WINDOW nil or omitted means use the selected window. VSCROLL is a\n\
4962 non-negative multiple of the canonical character height of WINDOW.")
4964 Lisp_Object window
, vscroll
;
4970 window
= selected_window
;
4972 CHECK_WINDOW (window
, 0);
4973 CHECK_NUMBER_OR_FLOAT (vscroll
, 1);
4975 w
= XWINDOW (window
);
4976 f
= XFRAME (w
->frame
);
4978 if (FRAME_WINDOW_P (f
))
4980 int old_dy
= w
->vscroll
;
4982 w
->vscroll
= - CANON_Y_UNIT (f
) * XFLOATINT (vscroll
);
4983 w
->vscroll
= min (w
->vscroll
, 0);
4985 /* Adjust glyph matrix of the frame if the virtual display
4986 area becomes larger than before. */
4987 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
4990 /* Prevent redisplay shortcuts. */
4991 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
4994 return Fwindow_vscroll (window
);
4998 /* Call FN for all leaf windows on frame F. FN is called with the
4999 first argument being a pointer to the leaf window, and with
5000 additional arguments A1..A4. */
5003 foreach_window (f
, fn
, a1
, a2
, a3
, a4
)
5008 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, a1
, a2
, a3
, a4
);
5012 /* Helper function for foreach_window. Call FN for all leaf windows
5013 reachable from W. FN is called with the first argument being a
5014 pointer to the leaf window, and with additional arguments A1..A4. */
5017 foreach_window_1 (w
, fn
, a1
, a2
, a3
, a4
)
5024 if (!NILP (w
->hchild
))
5025 foreach_window_1 (XWINDOW (w
->hchild
), fn
, a1
, a2
, a3
, a4
);
5026 else if (!NILP (w
->vchild
))
5027 foreach_window_1 (XWINDOW (w
->vchild
), fn
, a1
, a2
, a3
, a4
);
5029 fn (w
, a1
, a2
, a3
, a4
);
5031 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5036 /* Freeze or unfreeze the window start of W if unless it is a
5037 mini-window or the selected window. FREEZE_P non-zero means freeze
5038 the window start. */
5041 freeze_window_start (w
, freeze_p
)
5045 if (w
== XWINDOW (selected_window
)
5046 || MINI_WINDOW_P (w
)
5047 || (MINI_WINDOW_P (XWINDOW (selected_window
))
5048 && ! NILP (Vminibuf_scroll_window
)
5049 && w
== XWINDOW (Vminibuf_scroll_window
)))
5052 w
->frozen_window_start_p
= freeze_p
;
5056 /* Freeze or unfreeze the window starts of all leaf windows on frame
5057 F, except the selected window and a mini-window. FREEZE_P non-zero
5058 means freeze the window start. */
5061 freeze_window_starts (f
, freeze_p
)
5065 foreach_window (f
, freeze_window_start
, freeze_p
);
5069 /***********************************************************************
5071 ***********************************************************************/
5073 /* Return 1 if window configurations C1 and C2
5074 describe the same state of affairs. This is used by Fequal. */
5077 compare_window_configurations (c1
, c2
, ignore_positions
)
5079 int ignore_positions
;
5081 register struct save_window_data
*d1
, *d2
;
5082 struct Lisp_Vector
*sw1
, *sw2
;
5085 if (!WINDOW_CONFIGURATIONP (c1
))
5086 wrong_type_argument (Qwindow_configuration_p
, c1
);
5087 if (!WINDOW_CONFIGURATIONP (c2
))
5088 wrong_type_argument (Qwindow_configuration_p
, c2
);
5090 d1
= (struct save_window_data
*) XVECTOR (c1
);
5091 d2
= (struct save_window_data
*) XVECTOR (c2
);
5092 sw1
= XVECTOR (d1
->saved_windows
);
5093 sw2
= XVECTOR (d2
->saved_windows
);
5095 if (! EQ (d1
->frame_width
, d2
->frame_width
))
5097 if (! EQ (d1
->frame_height
, d2
->frame_height
))
5099 if (! EQ (d1
->frame_menu_bar_lines
, d2
->frame_menu_bar_lines
))
5101 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
5103 /* Don't compare the current_window field directly.
5104 Instead see w1_is_current and w2_is_current, below. */
5105 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
5107 if (! ignore_positions
)
5108 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
5110 /* Don't compare the root_window field.
5111 We don't require the two configurations
5112 to use the same window object,
5113 and the two root windows must be equivalent
5114 if everything else compares equal. */
5115 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
5117 if (! EQ (d1
->min_width
, d2
->min_width
))
5119 if (! EQ (d1
->min_height
, d2
->min_height
))
5122 /* Verify that the two confis have the same number of windows. */
5123 if (sw1
->size
!= sw2
->size
)
5126 for (i
= 0; i
< sw1
->size
; i
++)
5128 struct saved_window
*p1
, *p2
;
5129 int w1_is_current
, w2_is_current
;
5131 p1
= SAVED_WINDOW_N (sw1
, i
);
5132 p2
= SAVED_WINDOW_N (sw2
, i
);
5134 /* Verify that the current windows in the two
5135 configurations correspond to each other. */
5136 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
5137 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
5139 if (w1_is_current
!= w2_is_current
)
5142 /* Verify that the corresponding windows do match. */
5143 if (! EQ (p1
->buffer
, p2
->buffer
))
5145 if (! EQ (p1
->left
, p2
->left
))
5147 if (! EQ (p1
->top
, p2
->top
))
5149 if (! EQ (p1
->width
, p2
->width
))
5151 if (! EQ (p1
->height
, p2
->height
))
5153 if (! EQ (p1
->display_table
, p2
->display_table
))
5155 if (! EQ (p1
->parent
, p2
->parent
))
5157 if (! EQ (p1
->prev
, p2
->prev
))
5159 if (! ignore_positions
)
5161 if (! EQ (p1
->hscroll
, p2
->hscroll
))
5163 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
5165 if (NILP (Fequal (p1
->start
, p2
->start
)))
5167 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
5169 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
5177 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
5178 Scompare_window_configurations
, 2, 2, 0,
5179 "Compare two window configurations as regards the structure of windows.\n\
5180 This function ignores details such as the values of point and mark\n\
5181 and scrolling positions.")
5185 if (compare_window_configurations (x
, y
, 1))
5193 struct frame
*f
= make_terminal_frame ();
5194 XSETFRAME (selected_frame
, f
);
5195 Vterminal_frame
= selected_frame
;
5196 minibuf_window
= f
->minibuffer_window
;
5197 selected_window
= f
->selected_window
;
5198 last_nonminibuf_frame
= f
;
5200 window_initialized
= 1;
5206 Qleft_bitmap_area
= intern ("left-bitmap-area");
5207 staticpro (&Qleft_bitmap_area
);
5208 Qright_bitmap_area
= intern ("right-bitmap-area");
5209 staticpro (&Qright_bitmap_area
);
5211 Qwindow_size_fixed
= intern ("window-size-fixed");
5212 staticpro (&Qwindow_size_fixed
);
5214 staticpro (&Qwindow_configuration_change_hook
);
5215 Qwindow_configuration_change_hook
5216 = intern ("window-configuration-change-hook");
5218 Qwindowp
= intern ("windowp");
5219 staticpro (&Qwindowp
);
5221 Qwindow_configuration_p
= intern ("window-configuration-p");
5222 staticpro (&Qwindow_configuration_p
);
5224 Qwindow_live_p
= intern ("window-live-p");
5225 staticpro (&Qwindow_live_p
);
5227 Qtemp_buffer_show_hook
= intern ("temp-buffer-show-hook");
5228 staticpro (&Qtemp_buffer_show_hook
);
5230 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
5231 "Non-nil means call as function to display a help buffer.\n\
5232 The function is called with one argument, the buffer to be displayed.\n\
5233 Used by `with-output-to-temp-buffer'.\n\
5234 If this function is used, then it must do the entire job of showing\n\
5235 the buffer; `temp-buffer-show-hook' is not run unless this function runs it.");
5236 Vtemp_buffer_show_function
= Qnil
;
5238 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
5239 "If non-nil, function to call to handle `display-buffer'.\n\
5240 It will receive two args, the buffer and a flag which if non-nil means\n\
5241 that the currently selected window is not acceptable.\n\
5242 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
5243 work using this function.");
5244 Vdisplay_buffer_function
= Qnil
;
5246 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
5247 "Non-nil means it is the window that C-M-v in minibuffer should scroll.");
5248 Vminibuf_scroll_window
= Qnil
;
5250 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
5251 "If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.");
5252 Vother_window_scroll_buffer
= Qnil
;
5254 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
5255 "*Non-nil means `display-buffer' should make a separate frame.");
5258 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
5259 "Function to call to handle automatic new frame creation.\n\
5260 It is called with no arguments and should return a newly created frame.\n\
5262 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'\n\
5263 where `pop-up-frame-alist' would hold the default frame parameters.");
5264 Vpop_up_frame_function
= Qnil
;
5266 DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names
,
5267 "*List of buffer names that should have their own special frames.\n\
5268 Displaying a buffer whose name is in this list makes a special frame for it\n\
5269 using `special-display-function'. See also `special-display-regexps'.\n\
5271 An element of the list can be a list instead of just a string.\n\
5272 There are two ways to use a list as an element:\n\
5273 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)\n\
5274 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5275 In the latter case, FUNCTION is called with BUFFER as the first argument,\n\
5276 followed by OTHER-ARGS--it can display BUFFER in any way it likes.\n\
5277 All this is done by the function found in `special-display-function'.\n\
5279 If this variable appears \"not to work\", because you add a name to it\n\
5280 but that buffer still appears in the selected window, look at the\n\
5281 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5282 Those variables take precedence over this one.");
5283 Vspecial_display_buffer_names
= Qnil
;
5285 DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps
,
5286 "*List of regexps saying which buffers should have their own special frames.\n\
5287 If a buffer name matches one of these regexps, it gets its own frame.\n\
5288 Displaying a buffer whose name is in this list makes a special frame for it\n\
5289 using `special-display-function'.\n\
5291 An element of the list can be a list instead of just a string.\n\
5292 There are two ways to use a list as an element:\n\
5293 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)\n\
5294 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5295 In the latter case, FUNCTION is called with the buffer as first argument,\n\
5296 followed by OTHER-ARGS--it can display the buffer in any way it likes.\n\
5297 All this is done by the function found in `special-display-function'.\n\
5299 If this variable appears \"not to work\", because you add a regexp to it\n\
5300 but the matching buffers still appear in the selected window, look at the\n\
5301 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5302 Those variables take precedence over this one.");
5303 Vspecial_display_regexps
= Qnil
;
5305 DEFVAR_LISP ("special-display-function", &Vspecial_display_function
,
5306 "Function to call to make a new frame for a special buffer.\n\
5307 It is called with two arguments, the buffer and optional buffer specific\n\
5308 data, and should return a window displaying that buffer.\n\
5309 The default value makes a separate frame for the buffer,\n\
5310 using `special-display-frame-alist' to specify the frame parameters.\n\
5312 A buffer is special if its is listed in `special-display-buffer-names'\n\
5313 or matches a regexp in `special-display-regexps'.");
5314 Vspecial_display_function
= Qnil
;
5316 DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names
,
5317 "*List of buffer names that should appear in the selected window.\n\
5318 Displaying one of these buffers using `display-buffer' or `pop-to-buffer'\n\
5319 switches to it in the selected window, rather than making it appear\n\
5320 in some other window.\n\
5322 An element of the list can be a cons cell instead of just a string.\n\
5323 Then the car must be a string, which specifies the buffer name.\n\
5324 This is for compatibility with `special-display-buffer-names';\n\
5325 the cdr of the cons cell is ignored.\n\
5327 See also `same-window-regexps'.");
5328 Vsame_window_buffer_names
= Qnil
;
5330 DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps
,
5331 "*List of regexps saying which buffers should appear in the selected window.\n\
5332 If a buffer name matches one of these regexps, then displaying it\n\
5333 using `display-buffer' or `pop-to-buffer' switches to it\n\
5334 in the selected window, rather than making it appear in some other window.\n\
5336 An element of the list can be a cons cell instead of just a string.\n\
5337 Then the car must be a string, which specifies the buffer name.\n\
5338 This is for compatibility with `special-display-buffer-names';\n\
5339 the cdr of the cons cell is ignored.\n\
5341 See also `same-window-buffer-names'.");
5342 Vsame_window_regexps
= Qnil
;
5344 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
5345 "*Non-nil means display-buffer should make new windows.");
5348 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
5349 "*Number of lines of continuity when scrolling by screenfuls.");
5350 next_screen_context_lines
= 2;
5352 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
5353 "*display-buffer would prefer to split the largest window if this large.\n\
5354 If there is only one window, it is split regardless of this value.");
5355 split_height_threshold
= 500;
5357 DEFVAR_INT ("window-min-height", &window_min_height
,
5358 "*Delete any window less than this tall (including its mode line).");
5359 window_min_height
= 4;
5361 DEFVAR_INT ("window-min-width", &window_min_width
,
5362 "*Delete any window less than this wide.");
5363 window_min_width
= 10;
5365 DEFVAR_LISP ("scroll-preserve-screen-position",
5366 &Vscroll_preserve_screen_position
,
5367 "*Nonzero means scroll commands move point to keep its screen line unchanged.");
5368 Vscroll_preserve_screen_position
= Qnil
;
5370 DEFVAR_LISP ("window-configuration-change-hook",
5371 &Vwindow_configuration_change_hook
,
5372 "Functions to call when window configuration changes.\n\
5373 The selected frame is the one whose configuration has changed.");
5374 Vwindow_configuration_change_hook
= Qnil
;
5376 defsubr (&Sselected_window
);
5377 defsubr (&Sminibuffer_window
);
5378 defsubr (&Swindow_minibuffer_p
);
5379 defsubr (&Swindowp
);
5380 defsubr (&Swindow_live_p
);
5381 defsubr (&Spos_visible_in_window_p
);
5382 defsubr (&Swindow_buffer
);
5383 defsubr (&Swindow_height
);
5384 defsubr (&Swindow_width
);
5385 defsubr (&Swindow_hscroll
);
5386 defsubr (&Sset_window_hscroll
);
5387 defsubr (&Swindow_redisplay_end_trigger
);
5388 defsubr (&Sset_window_redisplay_end_trigger
);
5389 defsubr (&Swindow_edges
);
5390 defsubr (&Scoordinates_in_window_p
);
5391 defsubr (&Swindow_at
);
5392 defsubr (&Swindow_point
);
5393 defsubr (&Swindow_start
);
5394 defsubr (&Swindow_end
);
5395 defsubr (&Sset_window_point
);
5396 defsubr (&Sset_window_start
);
5397 defsubr (&Swindow_dedicated_p
);
5398 defsubr (&Sset_window_dedicated_p
);
5399 defsubr (&Swindow_display_table
);
5400 defsubr (&Sset_window_display_table
);
5401 defsubr (&Snext_window
);
5402 defsubr (&Sprevious_window
);
5403 defsubr (&Sother_window
);
5404 defsubr (&Sget_lru_window
);
5405 defsubr (&Sget_largest_window
);
5406 defsubr (&Sget_buffer_window
);
5407 defsubr (&Sdelete_other_windows
);
5408 defsubr (&Sdelete_windows_on
);
5409 defsubr (&Sreplace_buffer_in_windows
);
5410 defsubr (&Sdelete_window
);
5411 defsubr (&Sset_window_buffer
);
5412 defsubr (&Sselect_window
);
5413 defsubr (&Sspecial_display_p
);
5414 defsubr (&Ssame_window_p
);
5415 defsubr (&Sdisplay_buffer
);
5416 defsubr (&Ssplit_window
);
5417 defsubr (&Senlarge_window
);
5418 defsubr (&Sshrink_window
);
5419 defsubr (&Sscroll_up
);
5420 defsubr (&Sscroll_down
);
5421 defsubr (&Sscroll_left
);
5422 defsubr (&Sscroll_right
);
5423 defsubr (&Sother_window_for_scrolling
);
5424 defsubr (&Sscroll_other_window
);
5425 defsubr (&Srecenter
);
5426 defsubr (&Smove_to_window_line
);
5427 defsubr (&Swindow_configuration_p
);
5428 defsubr (&Swindow_configuration_frame
);
5429 defsubr (&Sset_window_configuration
);
5430 defsubr (&Scurrent_window_configuration
);
5431 defsubr (&Ssave_window_excursion
);
5432 defsubr (&Sset_window_margins
);
5433 defsubr (&Swindow_margins
);
5434 defsubr (&Swindow_vscroll
);
5435 defsubr (&Sset_window_vscroll
);
5436 defsubr (&Scompare_window_configurations
);
5442 initial_define_key (control_x_map
, '1', "delete-other-windows");
5443 initial_define_key (control_x_map
, '2', "split-window");
5444 initial_define_key (control_x_map
, '0', "delete-window");
5445 initial_define_key (control_x_map
, 'o', "other-window");
5446 initial_define_key (control_x_map
, '^', "enlarge-window");
5447 initial_define_key (control_x_map
, '<', "scroll-left");
5448 initial_define_key (control_x_map
, '>', "scroll-right");
5450 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
5451 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
5452 initial_define_key (meta_map
, 'v', "scroll-down");
5454 initial_define_key (global_map
, Ctl('L'), "recenter");
5455 initial_define_key (meta_map
, 'r', "move-to-window-line");