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 */
41 #define max(a, b) ((a) < (b) ? (b) : (a))
45 Lisp_Object Qwindowp
, Qwindow_live_p
, Qwindow_configuration_p
;
46 Lisp_Object Qwindow_size_fixed
, Qleft_bitmap_area
, Qright_bitmap_area
;
47 extern Lisp_Object Qheight
, Qwidth
;
49 static struct window
*decode_window
P_ ((Lisp_Object
));
50 static Lisp_Object select_window_1
P_ ((Lisp_Object
, int));
51 static int count_windows
P_ ((struct window
*));
52 static int get_leaf_windows
P_ ((struct window
*, struct window
**, int));
53 static void window_scroll
P_ ((Lisp_Object
, int, int, int));
54 static void window_scroll_pixel_based
P_ ((Lisp_Object
, int, int, int));
55 static void window_scroll_line_based
P_ ((Lisp_Object
, int, int, int));
56 static int window_min_size_1
P_ ((struct window
*, int));
57 static int window_min_size
P_ ((struct window
*, int, int, int *));
58 static void size_window
P_ ((Lisp_Object
, int, int, int));
59 static void foreach_window_1
P_ ((struct window
*, void (*fn
) (), int, int,
61 static void freeze_window_start
P_ ((struct window
*, int));
62 static int window_fixed_size_p
P_ ((struct window
*, int, int));
63 static void enlarge_window
P_ ((Lisp_Object
, int, int));
66 /* This is the window in which the terminal's cursor should
67 be left when nothing is being done with it. This must
68 always be a leaf window, and its buffer is selected by
69 the top level editing loop at the end of each command.
71 This value is always the same as
72 FRAME_SELECTED_WINDOW (selected_frame). */
74 Lisp_Object selected_window
;
76 /* The mini-buffer window of the selected frame.
77 Note that you cannot test for mini-bufferness of an arbitrary window
78 by comparing against this; but you can test for mini-bufferness of
79 the selected window. */
81 Lisp_Object minibuf_window
;
83 /* Non-nil means it is the window for C-M-v to scroll
84 when the mini-buffer is selected. */
86 Lisp_Object Vminibuf_scroll_window
;
88 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
90 Lisp_Object Vother_window_scroll_buffer
;
92 /* Non-nil means it's function to call to display temp buffers. */
94 Lisp_Object Vtemp_buffer_show_function
;
96 /* If a window gets smaller than either of these, it is removed. */
98 int window_min_height
;
101 /* Nonzero implies Fdisplay_buffer should create windows. */
105 /* Nonzero implies make new frames for Fdisplay_buffer. */
109 /* Non-nil means use this function instead of default */
111 Lisp_Object Vpop_up_frame_function
;
113 /* Function to call to handle Fdisplay_buffer. */
115 Lisp_Object Vdisplay_buffer_function
;
117 /* List of buffer *names* for buffers that should have their own frames. */
119 Lisp_Object Vspecial_display_buffer_names
;
121 /* List of regexps for buffer names that should have their own frames. */
123 Lisp_Object Vspecial_display_regexps
;
125 /* Function to pop up a special frame. */
127 Lisp_Object Vspecial_display_function
;
129 /* List of buffer *names* for buffers to appear in selected window. */
131 Lisp_Object Vsame_window_buffer_names
;
133 /* List of regexps for buffer names to appear in selected window. */
135 Lisp_Object Vsame_window_regexps
;
137 /* Hook run at end of temp_output_buffer_show. */
139 Lisp_Object Qtemp_buffer_show_hook
;
141 /* Fdisplay_buffer always splits the largest window
142 if that window is more than this high. */
144 int split_height_threshold
;
146 /* Number of lines of continuity in scrolling by screenfuls. */
148 int next_screen_context_lines
;
150 /* Incremented for each window created. */
152 static int sequence_number
;
154 /* Nonzero after init_window_once has finished. */
156 static int window_initialized
;
158 /* Hook to run when window config changes. */
160 Lisp_Object Qwindow_configuration_change_hook
;
161 Lisp_Object Vwindow_configuration_change_hook
;
163 /* Nonzero means scroll commands try to put point
164 at the same screen height as previously. */
166 Lisp_Object Vscroll_preserve_screen_position
;
168 #if 0 /* This isn't used anywhere. */
169 /* Nonzero means we can split a frame even if it is "unsplittable". */
170 static int inhibit_frame_unsplittable
;
173 #define min(a, b) ((a) < (b) ? (a) : (b))
175 extern int scroll_margin
;
177 extern Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
179 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
180 "Returns t if OBJECT is a window.")
184 return WINDOWP (object
) ? Qt
: Qnil
;
187 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
188 "Returns t if OBJECT is a window which is currently visible.")
192 return (WINDOWP (object
) && ! NILP (XWINDOW (object
)->buffer
) ? Qt
: Qnil
);
199 register struct window
*p
;
200 register struct Lisp_Vector
*vec
;
203 vec
= allocate_vectorlike ((EMACS_INT
) VECSIZE (struct window
));
204 for (i
= 0; i
< VECSIZE (struct window
); i
++)
205 vec
->contents
[i
] = Qnil
;
206 vec
->size
= VECSIZE (struct window
);
207 p
= (struct window
*) vec
;
208 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
209 XSETFASTINT (p
->left
, 0);
210 XSETFASTINT (p
->top
, 0);
211 XSETFASTINT (p
->height
, 0);
212 XSETFASTINT (p
->width
, 0);
213 XSETFASTINT (p
->hscroll
, 0);
214 p
->orig_top
= p
->orig_height
= Qnil
;
215 p
->start
= Fmake_marker ();
216 p
->pointm
= Fmake_marker ();
217 XSETFASTINT (p
->use_time
, 0);
219 p
->display_table
= Qnil
;
221 p
->pseudo_window_p
= 0;
222 bzero (&p
->cursor
, sizeof (p
->cursor
));
223 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
224 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
225 p
->desired_matrix
= p
->current_matrix
= 0;
226 p
->phys_cursor_type
= -1;
227 p
->must_be_updated_p
= 0;
228 XSETFASTINT (p
->window_end_vpos
, 0);
229 XSETFASTINT (p
->window_end_pos
, 0);
230 p
->window_end_valid
= Qnil
;
233 XSETFASTINT (p
->last_point
, 0);
234 p
->frozen_window_start_p
= 0;
238 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
239 "Return the window that the cursor now appears in and commands apply to.")
242 return selected_window
;
245 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
246 "Return the window used now for minibuffers.\n\
247 If the optional argument FRAME is specified, return the minibuffer window\n\
248 used by that frame.")
253 frame
= selected_frame
;
254 CHECK_LIVE_FRAME (frame
, 0);
255 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
258 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 0, 1, 0,
259 "Returns non-nil if WINDOW is a minibuffer window.")
263 struct window
*w
= decode_window (window
);
264 return (MINI_WINDOW_P (w
) ? Qt
: Qnil
);
267 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
268 Spos_visible_in_window_p
, 0, 2, 0,
269 "Return t if position POS is currently on the frame in WINDOW.\n\
270 Returns nil if that position is scrolled vertically out of view.\n\
271 POS defaults to point; WINDOW, to the selected window.")
273 Lisp_Object pos
, window
;
275 register struct window
*w
;
277 register struct buffer
*buf
;
279 Lisp_Object in_window
;
285 CHECK_NUMBER_COERCE_MARKER (pos
, 0);
289 w
= decode_window (window
);
290 buf
= XBUFFER (w
->buffer
);
291 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
293 /* If position above window, it's not visible. */
294 if (posint
< CHARPOS (top
))
296 else if (XFASTINT (w
->last_modified
) >= BUF_MODIFF (buf
)
297 && XFASTINT (w
->last_overlay_modified
) >= BUF_OVERLAY_MODIFF (buf
)
298 && posint
< BUF_Z (buf
) - XFASTINT (w
->window_end_pos
))
299 /* If frame is up to date, and POSINT is < window end pos, use
300 that info. This doesn't work for POSINT == end pos, because
301 the window end pos is actually the position _after_ the last
302 char in the window. */
304 else if (posint
> BUF_ZV (buf
))
306 else if (CHARPOS (top
) < BUF_BEGV (buf
) || CHARPOS (top
) > BUF_ZV (buf
))
307 /* If window start is out of range, do something reasonable. */
312 start_display (&it
, w
, top
);
313 move_it_to (&it
, posint
, 0, it
.last_visible_y
, -1,
314 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
315 in_window
= IT_CHARPOS (it
) == posint
? Qt
: Qnil
;
321 static struct window
*
322 decode_window (window
)
323 register Lisp_Object window
;
326 return XWINDOW (selected_window
);
328 CHECK_LIVE_WINDOW (window
, 0);
329 return XWINDOW (window
);
332 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
333 "Return the buffer that WINDOW is displaying.")
337 return decode_window (window
)->buffer
;
340 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
341 "Return the number of lines in WINDOW (including its mode line).")
345 return decode_window (window
)->height
;
348 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
349 "Return the number of display columns in WINDOW.\n\
350 This is the width that is usable columns available for text in WINDOW.\n\
351 If you want to find out how many columns WINDOW takes up,\n\
352 use (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))).")
356 return make_number (window_internal_width (decode_window (window
)));
359 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
360 "Return the number of columns by which WINDOW is scrolled from left margin.")
364 return decode_window (window
)->hscroll
;
367 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
368 "Set number of columns WINDOW is scrolled from left margin to NCOL.\n\
369 NCOL should be zero or positive.")
371 register Lisp_Object window
, ncol
;
373 register struct window
*w
;
375 CHECK_NUMBER (ncol
, 1);
376 if (XINT (ncol
) < 0) XSETFASTINT (ncol
, 0);
377 w
= decode_window (window
);
378 if (XINT (w
->hscroll
) != XINT (ncol
))
379 /* Prevent redisplay shortcuts */
380 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
385 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
386 Swindow_redisplay_end_trigger
, 0, 1, 0,
387 "Return WINDOW's redisplay end trigger value.\n\
388 See `set-window-redisplay-end-trigger' for more information.")
392 return decode_window (window
)->redisplay_end_trigger
;
395 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
396 Sset_window_redisplay_end_trigger
, 2, 2, 0,
397 "Set WINDOW's redisplay end trigger value to VALUE.\n\
398 VALUE should be a buffer position (typically a marker) or nil.\n\
399 If it is a buffer position, then if redisplay in WINDOW reaches a position\n\
400 beyond VALUE, the functions in `redisplay-end-trigger-functions' are called\n\
401 with two arguments: WINDOW, and the end trigger value.\n\
402 Afterwards the end-trigger value is reset to nil.")
404 register Lisp_Object window
, value
;
406 register struct window
*w
;
408 w
= decode_window (window
);
409 w
->redisplay_end_trigger
= value
;
413 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
414 "Return a list of the edge coordinates of WINDOW.\n\
415 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.\n\
416 RIGHT is one more than the rightmost column used by WINDOW,\n\
417 and BOTTOM is one more than the bottommost row used by WINDOW\n\
422 register struct window
*w
= decode_window (window
);
424 return Fcons (w
->left
, Fcons (w
->top
,
425 Fcons (make_number (WINDOW_RIGHT_EDGE (w
)),
426 Fcons (make_number (XFASTINT (w
->top
)
427 + XFASTINT (w
->height
)),
431 /* Test if the character at column *X, row *Y is within window W.
432 If it is not, return 0;
433 if it is in the window's text area,
434 set *x and *y to its location relative to the upper left corner
437 if it is on the window's modeline, return 2;
438 if it is on the border between the window and its right sibling,
440 if it is on the window's top line, return 4;
441 if it is in the bitmap area to the left/right of the window,
442 return 5 or 6, and convert *X and *Y to window-relative corrdinates.
444 X and Y are frame relative pixel coordinates. */
447 coordinates_in_window (w
, x
, y
)
448 register struct window
*w
;
451 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
452 int left_x
, right_x
, top_y
, bottom_y
;
453 int flags_area_width
= FRAME_LEFT_FLAGS_AREA_WIDTH (f
);
455 if (w
->pseudo_window_p
)
458 right_x
= XFASTINT (w
->width
) * CANON_Y_UNIT (f
);
459 top_y
= WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
);
460 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
464 left_x
= WINDOW_DISPLAY_LEFT_EDGE_PIXEL_X (w
);
465 right_x
= WINDOW_DISPLAY_RIGHT_EDGE_PIXEL_X (w
);
466 top_y
= WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
);
467 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
474 - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
)
476 || *x
> right_x
+ flags_area_width
)
477 /* Completely outside anything interesting. */
479 else if (WINDOW_WANTS_MODELINE_P (w
)
480 && *y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
))
481 /* On the mode line. */
483 else if (WINDOW_WANTS_HEADER_LINE_P (w
)
484 && *y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
))
485 /* On the top line. */
487 else if (*x
< left_x
|| *x
>= right_x
)
489 /* Other lines than the mode line don't include flags areas and
490 scroll bars on the left. */
492 /* Convert X and Y to window-relative pixel coordinates. */
495 return *x
< left_x
? 5 : 6;
497 else if (!w
->pseudo_window_p
498 && !WINDOW_RIGHTMOST_P (w
)
499 && *x
>= right_x
- CANON_X_UNIT (f
))
500 /* On the border on the right side of the window? Assume that
501 this area begins at RIGHT_X minus a canonical char width. */
505 /* Convert X and Y to window-relative pixel coordinates. */
512 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
513 Scoordinates_in_window_p
, 2, 2, 0,
514 "Return non-nil if COORDINATES are in WINDOW.\n\
515 COORDINATES is a cons of the form (X . Y), X and Y being distances\n\
516 measured in characters from the upper-left corner of the frame.\n\
517 (0 . 0) denotes the character in the upper left corner of the\n\
519 If COORDINATES are in the text portion of WINDOW,\n\
520 the coordinates relative to the window are returned.\n\
521 If they are in the mode line of WINDOW, `mode-line' is returned.\n\
522 If they are in the top mode line of WINDOW, `header-line' is returned.\n\
523 If they are in the bitmap-area to the left of the window,\n\
524 `left-bitmap-area' is returned, if they are in the area on the right of\n\
525 the window, `right-bitmap-area' is returned.\n\
526 If they are on the border between WINDOW and its right sibling,\n\
527 `vertical-line' is returned.")
528 (coordinates
, window
)
529 register Lisp_Object coordinates
, window
;
536 CHECK_LIVE_WINDOW (window
, 0);
537 w
= XWINDOW (window
);
538 f
= XFRAME (w
->frame
);
539 CHECK_CONS (coordinates
, 1);
540 lx
= Fcar (coordinates
);
541 ly
= Fcdr (coordinates
);
542 CHECK_NUMBER_OR_FLOAT (lx
, 1);
543 CHECK_NUMBER_OR_FLOAT (ly
, 1);
544 x
= PIXEL_X_FROM_CANON_X (f
, lx
);
545 y
= PIXEL_Y_FROM_CANON_Y (f
, ly
);
547 switch (coordinates_in_window (w
, &x
, &y
))
549 case 0: /* NOT in window at all. */
552 case 1: /* In text part of window. */
553 /* X and Y are now window relative pixel coordinates.
554 Convert them to canonical char units before returning
556 return Fcons (CANON_X_FROM_PIXEL_X (f
, x
),
557 CANON_Y_FROM_PIXEL_Y (f
, y
));
559 case 2: /* In mode line of window. */
562 case 3: /* On right border of window. */
563 return Qvertical_line
;
569 return Qleft_bitmap_area
;
572 return Qright_bitmap_area
;
579 /* Find the window containing frame-relative pixel position X/Y and
580 return it as a Lisp_Object. If X, Y is on the window's modeline,
581 set *PART to 1; if it is on the separating line between the window
582 and its right sibling, set it to 2; otherwise set it to 0. If
583 there is no window under X, Y return nil and leave *PART
584 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows. */
587 window_from_coordinates (frame
, x
, y
, part
, tool_bar_p
)
593 register Lisp_Object tem
, first
;
596 tem
= first
= FRAME_SELECTED_WINDOW (frame
);
600 found
= coordinates_in_window (XWINDOW (tem
), &x
, &y
);
608 tem
= Fnext_window (tem
, Qt
, Qlambda
);
610 while (!EQ (tem
, first
));
612 /* See if it's in the tool bar window, if a tool bar exists. */
614 && WINDOWP (frame
->tool_bar_window
)
615 && XFASTINT (XWINDOW (frame
->tool_bar_window
)->height
)
616 && coordinates_in_window (XWINDOW (frame
->tool_bar_window
), &x
, &y
))
619 return frame
->tool_bar_window
;
625 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
626 "Return window containing coordinates X and Y on FRAME.\n\
627 If omitted, FRAME defaults to the currently selected frame.\n\
628 The top left corner of the frame is considered to be row 0,\n\
631 Lisp_Object x
, y
, frame
;
637 frame
= selected_frame
;
638 CHECK_LIVE_FRAME (frame
, 2);
641 /* Check that arguments are integers or floats. */
642 CHECK_NUMBER_OR_FLOAT (x
, 0);
643 CHECK_NUMBER_OR_FLOAT (y
, 1);
645 return window_from_coordinates (f
,
646 PIXEL_X_FROM_CANON_X (f
, x
),
647 PIXEL_Y_FROM_CANON_Y (f
, y
),
651 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
652 "Return current value of point in WINDOW.\n\
653 For a nonselected window, this is the value point would have\n\
654 if that window were selected.\n\
656 Note that, when WINDOW is the selected window and its buffer\n\
657 is also currently selected, the value returned is the same as (point).\n\
658 It would be more strictly correct to return the `top-level' value\n\
659 of point, outside of any save-excursion forms.\n\
660 But that is hard to define.")
664 register struct window
*w
= decode_window (window
);
666 if (w
== XWINDOW (selected_window
)
667 && current_buffer
== XBUFFER (w
->buffer
))
669 return Fmarker_position (w
->pointm
);
672 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
673 "Return position at which display currently starts in WINDOW.\n\
674 This is updated by redisplay or by calling `set-window-start'.")
678 return Fmarker_position (decode_window (window
)->start
);
681 /* This is text temporarily removed from the doc string below.
683 This function returns nil if the position is not currently known.\n\
684 That happens when redisplay is preempted and doesn't finish.\n\
685 If in that case you want to compute where the end of the window would\n\
686 have been if redisplay had finished, do this:\n\
688 (goto-char (window-start window))\n\
689 (vertical-motion (1- (window-height window)) window)\n\
692 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
693 "Return position at which display currently ends in WINDOW.\n\
694 This is updated by redisplay, when it runs to completion.\n\
695 Simply changing the buffer text or setting `window-start'\n\
696 does not update this value.\n\
697 If UP-TO-DATE is non-nil, compute the up-to-date position\n\
698 if it isn't already recorded.")
700 Lisp_Object window
, update
;
703 struct window
*w
= decode_window (window
);
707 CHECK_BUFFER (buf
, 0);
709 #if 0 /* This change broke some things. We should make it later. */
710 /* If we don't know the end position, return nil.
711 The user can compute it with vertical-motion if he wants to.
712 It would be nicer to do it automatically,
713 but that's so slow that it would probably bother people. */
714 if (NILP (w
->window_end_valid
))
719 && ! (! NILP (w
->window_end_valid
)
720 && XFASTINT (w
->last_modified
) >= MODIFF
))
722 int opoint
= PT
, opoint_byte
= PT_BYTE
;
723 TEMP_SET_PT_BOTH (XMARKER (w
->start
)->charpos
,
724 XMARKER (w
->start
)->bytepos
);
725 Fvertical_motion (make_number (window_internal_height (w
)), Qnil
);
727 TEMP_SET_PT_BOTH (opoint
, opoint_byte
);
731 BUF_Z (XBUFFER (buf
)) - XFASTINT (w
->window_end_pos
));
736 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
737 "Make point value in WINDOW be at position POS in WINDOW's buffer.")
739 Lisp_Object window
, pos
;
741 register struct window
*w
= decode_window (window
);
743 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
744 if (w
== XWINDOW (selected_window
)
745 && XBUFFER (w
->buffer
) == current_buffer
)
748 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
753 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
754 "Make display in WINDOW start at position POS in WINDOW's buffer.\n\
755 Optional third arg NOFORCE non-nil inhibits next redisplay\n\
756 from overriding motion of point in order to display at this exact start.")
757 (window
, pos
, noforce
)
758 Lisp_Object window
, pos
, noforce
;
760 register struct window
*w
= decode_window (window
);
762 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
763 set_marker_restricted (w
->start
, pos
, w
->buffer
);
764 /* this is not right, but much easier than doing what is right. */
765 w
->start_at_line_beg
= Qnil
;
768 w
->update_mode_line
= Qt
;
769 XSETFASTINT (w
->last_modified
, 0);
770 XSETFASTINT (w
->last_overlay_modified
, 0);
771 if (!EQ (window
, selected_window
))
772 windows_or_buffers_changed
++;
777 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
779 "Return WINDOW's dedicated object, usually t or nil.\n\
780 See also `set-window-dedicated-p'.")
784 return decode_window (window
)->dedicated
;
787 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
788 Sset_window_dedicated_p
, 2, 2, 0,
789 "Control whether WINDOW is dedicated to the buffer it displays.\n\
790 If it is dedicated, Emacs will not automatically change\n\
791 which buffer appears in it.\n\
792 The second argument is the new value for the dedication flag;\n\
795 Lisp_Object window
, arg
;
797 register struct window
*w
= decode_window (window
);
807 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
809 "Return the display-table that WINDOW is using.")
813 return decode_window (window
)->display_table
;
816 /* Get the display table for use on window W. This is either W's
817 display table or W's buffer's display table. Ignore the specified
818 tables if they are not valid; if no valid table is specified,
821 struct Lisp_Char_Table
*
822 window_display_table (w
)
826 tem
= w
->display_table
;
827 if (DISP_TABLE_P (tem
))
828 return XCHAR_TABLE (tem
);
829 if (NILP (w
->buffer
))
832 tem
= XBUFFER (w
->buffer
)->display_table
;
833 if (DISP_TABLE_P (tem
))
834 return XCHAR_TABLE (tem
);
835 tem
= Vstandard_display_table
;
836 if (DISP_TABLE_P (tem
))
837 return XCHAR_TABLE (tem
);
841 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
842 "Set WINDOW's display-table to TABLE.")
844 register Lisp_Object window
, table
;
846 register struct window
*w
;
848 w
= decode_window (window
);
849 w
->display_table
= table
;
853 /* Record info on buffer window w is displaying
854 when it is about to cease to display that buffer. */
857 register struct window
*w
;
864 if (b
!= XMARKER (w
->pointm
)->buffer
)
867 if (w
== XWINDOW (b
->last_selected_window
))
868 b
->last_selected_window
= Qnil
;
871 if (w
== XWINDOW (selected_window
)
872 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
873 /* Do this except when the selected window's buffer
874 is being removed from some other window. */
876 /* last_window_start records the start position that this buffer
877 had in the last window to be disconnected from it.
878 Now that this statement is unconditional,
879 it is possible for the buffer to be displayed in the
880 selected window, while last_window_start reflects another
881 window which was recently showing the same buffer.
882 Some people might say that might be a good thing. Let's see. */
883 b
->last_window_start
= marker_position (w
->start
);
885 /* Point in the selected window's buffer
886 is actually stored in that buffer, and the window's pointm isn't used.
887 So don't clobber point in that buffer. */
888 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
))
889 temp_set_point_both (b
,
890 clip_to_bounds (BUF_BEGV (b
),
891 XMARKER (w
->pointm
)->charpos
,
893 clip_to_bounds (BUF_BEGV_BYTE (b
),
894 marker_byte_position (w
->pointm
),
898 /* Put replacement into the window structure in place of old. */
900 replace_window (old
, replacement
)
901 Lisp_Object old
, replacement
;
903 register Lisp_Object tem
;
904 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
906 /* If OLD is its frame's root_window, then replacement is the new
907 root_window for that frame. */
909 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
910 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
915 p
->height
= o
->height
;
916 p
->desired_matrix
= p
->current_matrix
= 0;
918 bzero (&p
->cursor
, sizeof (p
->cursor
));
919 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
920 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
921 p
->phys_cursor_type
= -1;
922 p
->must_be_updated_p
= 0;
923 p
->pseudo_window_p
= 0;
924 XSETFASTINT (p
->window_end_vpos
, 0);
925 XSETFASTINT (p
->window_end_pos
, 0);
926 p
->window_end_valid
= Qnil
;
927 p
->frozen_window_start_p
= 0;
928 p
->orig_top
= p
->orig_height
= Qnil
;
930 p
->next
= tem
= o
->next
;
932 XWINDOW (tem
)->prev
= replacement
;
934 p
->prev
= tem
= o
->prev
;
936 XWINDOW (tem
)->next
= replacement
;
938 p
->parent
= tem
= o
->parent
;
941 if (EQ (XWINDOW (tem
)->vchild
, old
))
942 XWINDOW (tem
)->vchild
= replacement
;
943 if (EQ (XWINDOW (tem
)->hchild
, old
))
944 XWINDOW (tem
)->hchild
= replacement
;
947 /*** Here, if replacement is a vertical combination
948 and so is its new parent, we should make replacement's
949 children be children of that parent instead. ***/
952 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
953 "Remove WINDOW from the display. Default is selected window.")
955 register Lisp_Object window
;
957 delete_window (window
);
959 if (! NILP (Vwindow_configuration_change_hook
)
960 && ! NILP (Vrun_hooks
))
961 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
967 delete_window (window
)
968 register Lisp_Object window
;
970 register Lisp_Object tem
, parent
, sib
;
971 register struct window
*p
;
972 register struct window
*par
;
975 /* Because this function is called by other C code on non-leaf
976 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
977 so we can't decode_window here. */
979 window
= selected_window
;
981 CHECK_WINDOW (window
, 0);
982 p
= XWINDOW (window
);
984 /* It's okay to delete an already-deleted window. */
992 error ("Attempt to delete minibuffer or sole ordinary window");
993 par
= XWINDOW (parent
);
995 windows_or_buffers_changed
++;
996 frame
= XFRAME (WINDOW_FRAME (p
));
997 FRAME_WINDOW_SIZES_CHANGED (frame
) = 1;
999 /* Are we trying to delete any frame's selected window? */
1001 Lisp_Object frame
, pwindow
;
1003 /* See if the frame's selected window is either WINDOW
1004 or any subwindow of it, by finding all that window's parents
1005 and comparing each one with WINDOW. */
1006 frame
= WINDOW_FRAME (XWINDOW (window
));
1007 pwindow
= FRAME_SELECTED_WINDOW (XFRAME (frame
));
1009 while (!NILP (pwindow
))
1011 if (EQ (window
, pwindow
))
1013 pwindow
= XWINDOW (pwindow
)->parent
;
1016 if (EQ (window
, pwindow
))
1018 Lisp_Object alternative
;
1019 alternative
= Fnext_window (window
, Qlambda
, Qnil
);
1021 /* If we're about to delete the selected window on the
1022 selected frame, then we should use Fselect_window to select
1023 the new window. On the other hand, if we're about to
1024 delete the selected window on any other frame, we shouldn't do
1025 anything but set the frame's selected_window slot. */
1026 if (EQ (window
, selected_window
))
1027 Fselect_window (alternative
);
1029 FRAME_SELECTED_WINDOW (XFRAME (frame
)) = alternative
;
1034 /* tem is null for dummy parent windows
1035 (which have inferiors but not any contents themselves) */
1039 unchain_marker (p
->pointm
);
1040 unchain_marker (p
->start
);
1043 /* Free window glyph matrices.
1044 It is sure that they are allocated again when ADJUST_GLYPHS
1046 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (frame
)));
1050 XWINDOW (tem
)->prev
= p
->prev
;
1054 XWINDOW (tem
)->next
= p
->next
;
1056 if (EQ (window
, par
->hchild
))
1057 par
->hchild
= p
->next
;
1058 if (EQ (window
, par
->vchild
))
1059 par
->vchild
= p
->next
;
1061 /* Find one of our siblings to give our space to. */
1065 /* If p gives its space to its next sibling, that sibling needs
1066 to have its top/left side pulled back to where p's is.
1067 set_window_{height,width} will re-position the sibling's
1070 XWINDOW (sib
)->top
= p
->top
;
1071 XWINDOW (sib
)->left
= p
->left
;
1074 /* Stretch that sibling. */
1075 if (!NILP (par
->vchild
))
1076 set_window_height (sib
,
1077 XFASTINT (XWINDOW (sib
)->height
) + XFASTINT (p
->height
),
1079 if (!NILP (par
->hchild
))
1080 set_window_width (sib
,
1081 XFASTINT (XWINDOW (sib
)->width
) + XFASTINT (p
->width
),
1084 /* If parent now has only one child,
1085 put the child into the parent's place. */
1089 if (NILP (XWINDOW (tem
)->next
))
1090 replace_window (parent
, tem
);
1092 /* Since we may be deleting combination windows, we must make sure that
1093 not only p but all its children have been marked as deleted. */
1094 if (! NILP (p
->hchild
))
1095 delete_all_subwindows (XWINDOW (p
->hchild
));
1096 else if (! NILP (p
->vchild
))
1097 delete_all_subwindows (XWINDOW (p
->vchild
));
1099 /* Mark this window as deleted. */
1100 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
1102 /* Adjust glyph matrices. */
1103 adjust_glyphs (frame
);
1107 extern Lisp_Object
next_frame (), prev_frame ();
1109 /* This comment supplies the doc string for `next-window',
1110 for make-docfile to see. We cannot put this in the real DEFUN
1111 due to limits in the Unix cpp.
1113 DEFUN ("next-window", Ffoo, Sfoo, 0, 3, 0,
1114 "Return next window after WINDOW in canonical ordering of windows.\n\
1115 If omitted, WINDOW defaults to the selected window.\n\
1117 Optional second arg MINIBUF t means count the minibuffer window even\n\
1118 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1119 it is active. MINIBUF neither t nor nil means not to count the\n\
1120 minibuffer even if it is active.\n\
1122 Several frames may share a single minibuffer; if the minibuffer\n\
1123 counts, all windows on all frames that share that minibuffer count\n\
1124 too. Therefore, `next-window' can be used to iterate through the\n\
1125 set of windows even when the minibuffer is on another frame. If the\n\
1126 minibuffer does not count, only windows from WINDOW's frame count.\n\
1128 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1129 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1130 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1131 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1132 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1133 Anything else means restrict to WINDOW's frame.\n\
1135 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1136 `next-window' to iterate through the entire cycle of acceptable\n\
1137 windows, eventually ending up back at the window you started with.\n\
1138 `previous-window' traverses the same cycle, in the reverse order.")
1139 (window, minibuf, all_frames) */
1141 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
1143 (window
, minibuf
, all_frames
)
1144 register Lisp_Object window
, minibuf
, all_frames
;
1146 register Lisp_Object tem
;
1147 Lisp_Object start_window
;
1150 window
= selected_window
;
1152 CHECK_LIVE_WINDOW (window
, 0);
1154 start_window
= window
;
1156 /* minibuf == nil may or may not include minibuffers.
1157 Decide if it does. */
1159 minibuf
= (minibuf_level
? minibuf_window
: Qlambda
);
1160 else if (! EQ (minibuf
, Qt
))
1162 /* Now minibuf can be t => count all minibuffer windows,
1163 lambda => count none of them,
1164 or a specific minibuffer window (the active one) to count. */
1166 /* all_frames == nil doesn't specify which frames to include. */
1167 if (NILP (all_frames
))
1168 all_frames
= (! EQ (minibuf
, Qlambda
)
1169 ? (FRAME_MINIBUF_WINDOW
1172 (XWINDOW (window
)))))
1174 else if (EQ (all_frames
, Qvisible
))
1176 else if (XFASTINT (all_frames
) == 0)
1178 else if (FRAMEP (all_frames
) && ! EQ (all_frames
, Fwindow_frame (window
)))
1179 /* If all_frames is a frame and window arg isn't on that frame, just
1180 return the first window on the frame. */
1181 return Fframe_first_window (all_frames
);
1182 else if (! EQ (all_frames
, Qt
))
1184 /* Now all_frames is t meaning search all frames,
1185 nil meaning search just current frame,
1186 visible meaning search just visible frames,
1187 0 meaning search visible and iconified frames,
1188 or a window, meaning search the frame that window belongs to. */
1190 /* Do this loop at least once, to get the next window, and perhaps
1191 again, if we hit the minibuffer and that is not acceptable. */
1194 /* Find a window that actually has a next one. This loop
1195 climbs up the tree. */
1196 while (tem
= XWINDOW (window
)->next
, NILP (tem
))
1197 if (tem
= XWINDOW (window
)->parent
, !NILP (tem
))
1201 /* We've reached the end of this frame.
1202 Which other frames are acceptable? */
1203 tem
= WINDOW_FRAME (XWINDOW (window
));
1204 if (! NILP (all_frames
))
1209 tem
= next_frame (tem
, all_frames
);
1210 /* In the case where the minibuffer is active,
1211 and we include its frame as well as the selected one,
1212 next_frame may get stuck in that frame.
1213 If that happens, go back to the selected frame
1214 so we can complete the cycle. */
1216 tem
= selected_frame
;
1218 tem
= FRAME_ROOT_WINDOW (XFRAME (tem
));
1225 /* If we're in a combination window, find its first child and
1226 recurse on that. Otherwise, we've found the window we want. */
1229 if (!NILP (XWINDOW (window
)->hchild
))
1230 window
= XWINDOW (window
)->hchild
;
1231 else if (!NILP (XWINDOW (window
)->vchild
))
1232 window
= XWINDOW (window
)->vchild
;
1238 /* Which windows are acceptable?
1239 Exit the loop and accept this window if
1240 this isn't a minibuffer window,
1241 or we're accepting all minibuffer windows,
1242 or this is the active minibuffer and we are accepting that one, or
1243 we've come all the way around and we're back at the original window. */
1244 while (MINI_WINDOW_P (XWINDOW (window
))
1245 && ! EQ (minibuf
, Qt
)
1246 && ! EQ (minibuf
, window
)
1247 && ! EQ (window
, start_window
));
1252 /* This comment supplies the doc string for `previous-window',
1253 for make-docfile to see. We cannot put this in the real DEFUN
1254 due to limits in the Unix cpp.
1256 DEFUN ("previous-window", Ffoo, Sfoo, 0, 3, 0,
1257 "Return the window preceding WINDOW in canonical ordering of windows.\n\
1258 If omitted, WINDOW defaults to the selected window.\n\
1260 Optional second arg MINIBUF t means count the minibuffer window even\n\
1261 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1262 it is active. MINIBUF neither t nor nil means not to count the\n\
1263 minibuffer even if it is active.\n\
1265 Several frames may share a single minibuffer; if the minibuffer\n\
1266 counts, all windows on all frames that share that minibuffer count\n\
1267 too. Therefore, `previous-window' can be used to iterate through\n\
1268 the set of windows even when the minibuffer is on another frame. If\n\
1269 the minibuffer does not count, only windows from WINDOW's frame count\n\
1271 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1272 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1273 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1274 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1275 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1276 Anything else means restrict to WINDOW's frame.\n\
1278 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1279 `previous-window' to iterate through the entire cycle of acceptable\n\
1280 windows, eventually ending up back at the window you started with.\n\
1281 `next-window' traverses the same cycle, in the reverse order.")
1282 (window, minibuf, all_frames) */
1285 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
1287 (window
, minibuf
, all_frames
)
1288 register Lisp_Object window
, minibuf
, all_frames
;
1290 register Lisp_Object tem
;
1291 Lisp_Object start_window
;
1294 window
= selected_window
;
1296 CHECK_LIVE_WINDOW (window
, 0);
1298 start_window
= window
;
1300 /* minibuf == nil may or may not include minibuffers.
1301 Decide if it does. */
1303 minibuf
= (minibuf_level
? minibuf_window
: Qlambda
);
1304 else if (! EQ (minibuf
, Qt
))
1306 /* Now minibuf can be t => count all minibuffer windows,
1307 lambda => count none of them,
1308 or a specific minibuffer window (the active one) to count. */
1310 /* all_frames == nil doesn't specify which frames to include.
1311 Decide which frames it includes. */
1312 if (NILP (all_frames
))
1313 all_frames
= (! EQ (minibuf
, Qlambda
)
1314 ? (FRAME_MINIBUF_WINDOW
1317 (XWINDOW (window
)))))
1319 else if (EQ (all_frames
, Qvisible
))
1321 else if (XFASTINT (all_frames
) == 0)
1323 else if (FRAMEP (all_frames
) && ! EQ (all_frames
, Fwindow_frame (window
)))
1324 /* If all_frames is a frame and window arg isn't on that frame, just
1325 return the first window on the frame. */
1326 return Fframe_first_window (all_frames
);
1327 else if (! EQ (all_frames
, Qt
))
1329 /* Now all_frames is t meaning search all frames,
1330 nil meaning search just current frame,
1331 visible meaning search just visible frames,
1332 0 meaning search visible and iconified frames,
1333 or a window, meaning search the frame that window belongs to. */
1335 /* Do this loop at least once, to get the previous window, and perhaps
1336 again, if we hit the minibuffer and that is not acceptable. */
1339 /* Find a window that actually has a previous one. This loop
1340 climbs up the tree. */
1341 while (tem
= XWINDOW (window
)->prev
, NILP (tem
))
1342 if (tem
= XWINDOW (window
)->parent
, !NILP (tem
))
1346 /* We have found the top window on the frame.
1347 Which frames are acceptable? */
1348 tem
= WINDOW_FRAME (XWINDOW (window
));
1349 if (! NILP (all_frames
))
1350 /* It's actually important that we use prev_frame here,
1351 rather than next_frame. All the windows acceptable
1352 according to the given parameters should form a ring;
1353 Fnext_window and Fprevious_window should go back and
1354 forth around the ring. If we use next_frame here,
1355 then Fnext_window and Fprevious_window take different
1356 paths through the set of acceptable windows.
1357 window_loop assumes that these `ring' requirement are
1363 tem
= prev_frame (tem
, all_frames
);
1364 /* In the case where the minibuffer is active,
1365 and we include its frame as well as the selected one,
1366 next_frame may get stuck in that frame.
1367 If that happens, go back to the selected frame
1368 so we can complete the cycle. */
1370 tem
= selected_frame
;
1372 /* If this frame has a minibuffer, find that window first,
1373 because it is conceptually the last window in that frame. */
1374 if (FRAME_HAS_MINIBUF_P (XFRAME (tem
)))
1375 tem
= FRAME_MINIBUF_WINDOW (XFRAME (tem
));
1377 tem
= FRAME_ROOT_WINDOW (XFRAME (tem
));
1383 /* If we're in a combination window, find its last child and
1384 recurse on that. Otherwise, we've found the window we want. */
1387 if (!NILP (XWINDOW (window
)->hchild
))
1388 window
= XWINDOW (window
)->hchild
;
1389 else if (!NILP (XWINDOW (window
)->vchild
))
1390 window
= XWINDOW (window
)->vchild
;
1392 while (tem
= XWINDOW (window
)->next
, !NILP (tem
))
1396 /* Which windows are acceptable?
1397 Exit the loop and accept this window if
1398 this isn't a minibuffer window,
1399 or we're accepting all minibuffer windows,
1400 or this is the active minibuffer and we are accepting that one, or
1401 we've come all the way around and we're back at the original window. */
1402 while (MINI_WINDOW_P (XWINDOW (window
))
1403 && ! EQ (minibuf
, Qt
)
1404 && ! EQ (minibuf
, window
)
1405 && ! EQ (window
, start_window
));
1410 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1411 "Select the ARG'th different window on this frame.\n\
1412 All windows on current frame are arranged in a cyclic order.\n\
1413 This command selects the window ARG steps away in that order.\n\
1414 A negative ARG moves in the opposite order. If the optional second\n\
1415 argument ALL_FRAMES is non-nil, cycle through all frames.")
1417 register Lisp_Object arg
, all_frames
;
1420 register Lisp_Object w
;
1422 CHECK_NUMBER (arg
, 0);
1423 w
= selected_window
;
1428 w
= Fnext_window (w
, Qnil
, all_frames
);
1433 w
= Fprevious_window (w
, Qnil
, all_frames
);
1440 /* Look at all windows, performing an operation specified by TYPE
1442 If FRAMES is Qt, look at all frames;
1443 Qnil, look at just the selected frame;
1444 Qvisible, look at visible frames;
1445 a frame, just look at windows on that frame.
1446 If MINI is non-zero, perform the operation on minibuffer windows too.
1452 GET_BUFFER_WINDOW
, /* Arg is buffer */
1453 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1454 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1455 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1457 UNSHOW_BUFFER
, /* Arg is buffer */
1462 window_loop (type
, obj
, mini
, frames
)
1463 enum window_loop type
;
1464 register Lisp_Object obj
, frames
;
1467 register Lisp_Object w
;
1468 register Lisp_Object best_window
;
1469 register Lisp_Object next_window
;
1470 register Lisp_Object last_window
;
1472 Lisp_Object frame_arg
;
1475 /* If we're only looping through windows on a particular frame,
1476 frame points to that frame. If we're looping through windows
1477 on all frames, frame is 0. */
1478 if (FRAMEP (frames
))
1479 frame
= XFRAME (frames
);
1480 else if (NILP (frames
))
1481 frame
= SELECTED_FRAME ();
1485 frame_arg
= Qlambda
;
1486 else if (XFASTINT (frames
) == 0)
1488 else if (EQ (frames
, Qvisible
))
1491 /* frame_arg is Qlambda to stick to one frame,
1492 Qvisible to consider all visible frames,
1495 /* Pick a window to start with. */
1499 w
= FRAME_SELECTED_WINDOW (frame
);
1501 w
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
1503 /* Figure out the last window we're going to mess with. Since
1504 Fnext_window, given the same options, is guaranteed to go in a
1505 ring, we can just use Fprevious_window to find the last one.
1507 We can't just wait until we hit the first window again, because
1508 it might be deleted. */
1510 last_window
= Fprevious_window (w
, mini
? Qt
: Qnil
, frame_arg
);
1515 /* Pick the next window now, since some operations will delete
1516 the current window. */
1517 next_window
= Fnext_window (w
, mini
? Qt
: Qnil
, frame_arg
);
1519 /* Note that we do not pay attention here to whether
1520 the frame is visible, since Fnext_window skips non-visible frames
1521 if that is desired, under the control of frame_arg. */
1522 if (! MINI_WINDOW_P (XWINDOW (w
))
1523 /* For UNSHOW_BUFFER, we must always consider all windows. */
1524 || type
== UNSHOW_BUFFER
1525 || (mini
&& minibuf_level
> 0))
1528 case GET_BUFFER_WINDOW
:
1529 if (XBUFFER (XWINDOW (w
)->buffer
) == XBUFFER (obj
)
1530 /* Don't find any minibuffer window
1531 except the one that is currently in use. */
1532 && (MINI_WINDOW_P (XWINDOW (w
))
1533 ? EQ (w
, minibuf_window
) : 1))
1537 case GET_LRU_WINDOW
:
1538 /* t as arg means consider only full-width windows */
1539 if (!NILP (obj
) && !WINDOW_FULL_WIDTH_P (XWINDOW (w
)))
1541 /* Ignore dedicated windows and minibuffers. */
1542 if (MINI_WINDOW_P (XWINDOW (w
))
1543 || !NILP (XWINDOW (w
)->dedicated
))
1545 if (NILP (best_window
)
1546 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1547 > XFASTINT (XWINDOW (w
)->use_time
)))
1551 case DELETE_OTHER_WINDOWS
:
1552 if (XWINDOW (w
) != XWINDOW (obj
))
1556 case DELETE_BUFFER_WINDOWS
:
1557 if (EQ (XWINDOW (w
)->buffer
, obj
))
1559 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (w
)));
1561 /* If this window is dedicated, and in a frame of its own,
1563 if (EQ (w
, FRAME_ROOT_WINDOW (f
))
1564 && !NILP (XWINDOW (w
)->dedicated
)
1565 && other_visible_frames (f
))
1567 /* Skip the other windows on this frame.
1568 There might be one, the minibuffer! */
1569 if (! EQ (w
, last_window
))
1570 while (f
== XFRAME (WINDOW_FRAME (XWINDOW (next_window
))))
1572 /* As we go, check for the end of the loop.
1573 We mustn't start going around a second time. */
1574 if (EQ (next_window
, last_window
))
1579 next_window
= Fnext_window (next_window
,
1583 /* Now we can safely delete the frame. */
1584 Fdelete_frame (WINDOW_FRAME (XWINDOW (w
)), Qnil
);
1587 /* If we're deleting the buffer displayed in the only window
1588 on the frame, find a new buffer to display there. */
1589 if (NILP (XWINDOW (w
)->parent
))
1591 Lisp_Object new_buffer
;
1592 new_buffer
= Fother_buffer (obj
, Qnil
,
1593 XWINDOW (w
)->frame
);
1594 if (NILP (new_buffer
))
1596 = Fget_buffer_create (build_string ("*scratch*"));
1597 Fset_window_buffer (w
, new_buffer
);
1598 if (EQ (w
, selected_window
))
1599 Fset_buffer (XWINDOW (w
)->buffer
);
1606 case GET_LARGEST_WINDOW
:
1607 /* Ignore dedicated windows and minibuffers. */
1608 if (MINI_WINDOW_P (XWINDOW (w
))
1609 || !NILP (XWINDOW (w
)->dedicated
))
1612 struct window
*best_window_ptr
= XWINDOW (best_window
);
1613 struct window
*w_ptr
= XWINDOW (w
);
1614 if (NILP (best_window
)
1615 || (XFASTINT (w_ptr
->height
) * XFASTINT (w_ptr
->width
)
1616 > (XFASTINT (best_window_ptr
->height
)
1617 * XFASTINT (best_window_ptr
->width
))))
1623 if (EQ (XWINDOW (w
)->buffer
, obj
))
1625 /* Find another buffer to show in this window. */
1626 Lisp_Object another_buffer
;
1627 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (w
)));
1628 another_buffer
= Fother_buffer (obj
, Qnil
, XWINDOW (w
)->frame
);
1629 if (NILP (another_buffer
))
1631 = Fget_buffer_create (build_string ("*scratch*"));
1632 /* If this window is dedicated, and in a frame of its own,
1634 if (EQ (w
, FRAME_ROOT_WINDOW (f
))
1635 && !NILP (XWINDOW (w
)->dedicated
)
1636 && other_visible_frames (f
))
1638 /* Skip the other windows on this frame.
1639 There might be one, the minibuffer! */
1640 if (! EQ (w
, last_window
))
1641 while (f
== XFRAME (WINDOW_FRAME (XWINDOW (next_window
))))
1643 /* As we go, check for the end of the loop.
1644 We mustn't start going around a second time. */
1645 if (EQ (next_window
, last_window
))
1650 next_window
= Fnext_window (next_window
,
1654 /* Now we can safely delete the frame. */
1655 Fdelete_frame (WINDOW_FRAME (XWINDOW (w
)), Qnil
);
1659 /* Otherwise show a different buffer in the window. */
1660 XWINDOW (w
)->dedicated
= Qnil
;
1661 Fset_window_buffer (w
, another_buffer
);
1662 if (EQ (w
, selected_window
))
1663 Fset_buffer (XWINDOW (w
)->buffer
);
1668 /* Check for a window that has a killed buffer. */
1669 case CHECK_ALL_WINDOWS
:
1670 if (! NILP (XWINDOW (w
)->buffer
)
1671 && NILP (XBUFFER (XWINDOW (w
)->buffer
)->name
))
1675 if (EQ (w
, last_window
))
1684 /* Used for debugging. Abort if any window has a dead buffer. */
1687 check_all_windows ()
1689 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
1692 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1693 "Return the window least recently selected or used for display.\n\
1694 If optional argument FRAME is `visible', search all visible frames.\n\
1695 If FRAME is 0, search all visible and iconified frames.\n\
1696 If FRAME is t, search all frames.\n\
1697 If FRAME is nil, search only the selected frame.\n\
1698 If FRAME is a frame, search only that frame.")
1702 register Lisp_Object w
;
1703 /* First try for a window that is full-width */
1704 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frame
);
1705 if (!NILP (w
) && !EQ (w
, selected_window
))
1707 /* If none of them, try the rest */
1708 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frame
);
1711 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1712 "Return the largest window in area.\n\
1713 If optional argument FRAME is `visible', search all visible frames.\n\
1714 If FRAME is 0, search all visible and iconified frames.\n\
1715 If FRAME is t, search all frames.\n\
1716 If FRAME is nil, search only the selected frame.\n\
1717 If FRAME is a frame, search only that frame.")
1721 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
1725 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
1726 "Return a window currently displaying BUFFER, or nil if none.\n\
1727 If optional argument FRAME is `visible', search all visible frames.\n\
1728 If optional argument FRAME is 0, search all visible and iconified frames.\n\
1729 If FRAME is t, search all frames.\n\
1730 If FRAME is nil, search only the selected frame.\n\
1731 If FRAME is a frame, search only that frame.")
1733 Lisp_Object buffer
, frame
;
1735 buffer
= Fget_buffer (buffer
);
1736 if (BUFFERP (buffer
))
1737 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
1742 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
1744 "Make WINDOW (or the selected window) fill its frame.\n\
1745 Only the frame WINDOW is on is affected.\n\
1746 This function tries to reduce display jumps\n\
1747 by keeping the text previously visible in WINDOW\n\
1748 in the same place on the frame. Doing this depends on\n\
1749 the value of (window-start WINDOW), so if calling this function\n\
1750 in a program gives strange scrolling, make sure the window-start\n\
1751 value is reasonable when this function is called.")
1760 window
= selected_window
;
1762 CHECK_LIVE_WINDOW (window
, 0);
1764 w
= XWINDOW (window
);
1766 startpos
= marker_position (w
->start
);
1767 top
= XFASTINT (w
->top
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
1769 if (MINI_WINDOW_P (w
) && top
> 0)
1770 error ("Can't expand minibuffer to full frame");
1772 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
1774 /* Try to minimize scrolling, by setting the window start to the point
1775 will cause the text at the old window start to be at the same place
1776 on the frame. But don't try to do this if the window start is
1777 outside the visible portion (as might happen when the display is
1778 not current, due to typeahead). */
1779 if (startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
1780 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
1782 struct position pos
;
1783 struct buffer
*obuf
= current_buffer
;
1785 Fset_buffer (w
->buffer
);
1786 /* This computation used to temporarily move point, but that can
1787 have unwanted side effects due to text properties. */
1788 pos
= *vmotion (startpos
, -top
, w
);
1790 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
1791 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
1792 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
1794 /* We need to do this, so that the window-scroll-functions
1796 w
->optional_new_start
= Qt
;
1798 set_buffer_internal (obuf
);
1804 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
1805 1, 2, "bDelete windows on (buffer): ",
1806 "Delete all windows showing BUFFER.\n\
1807 Optional second argument FRAME controls which frames are affected.\n\
1808 If optional argument FRAME is `visible', search all visible frames.\n\
1809 If FRAME is 0, search all visible and iconified frames.\n\
1810 If FRAME is nil, search all frames.\n\
1811 If FRAME is t, search only the selected frame.\n\
1812 If FRAME is a frame, search only that frame.")
1814 Lisp_Object buffer
, frame
;
1816 /* FRAME uses t and nil to mean the opposite of what window_loop
1820 else if (EQ (frame
, Qt
))
1825 buffer
= Fget_buffer (buffer
);
1826 CHECK_BUFFER (buffer
, 0);
1827 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
1833 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
1834 Sreplace_buffer_in_windows
,
1835 1, 1, "bReplace buffer in windows: ",
1836 "Replace BUFFER with some other buffer in all windows showing it.")
1842 buffer
= Fget_buffer (buffer
);
1843 CHECK_BUFFER (buffer
, 0);
1844 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
1849 /* Replace BUFFER with some other buffer in all windows
1850 of all frames, even those on other keyboards. */
1853 replace_buffer_in_all_windows (buffer
)
1857 Lisp_Object tail
, frame
;
1859 /* A single call to window_loop won't do the job
1860 because it only considers frames on the current keyboard.
1861 So loop manually over frames, and handle each one. */
1862 FOR_EACH_FRAME (tail
, frame
)
1863 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
1865 window_loop (UNSHOW_BUFFER
, buffer
, 1, Qt
);
1869 /* Set the height of WINDOW and all its inferiors. */
1871 /* The smallest acceptable dimensions for a window. Anything smaller
1872 might crash Emacs. */
1874 #define MIN_SAFE_WINDOW_WIDTH (2)
1875 #define MIN_SAFE_WINDOW_HEIGHT (2)
1877 /* Make sure that window_min_height and window_min_width are
1878 not too small; if they are, set them to safe minima. */
1881 check_min_window_sizes ()
1883 /* Smaller values might permit a crash. */
1884 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
1885 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
1886 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
1887 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
1890 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
1891 minimum allowable size. */
1894 check_frame_size (frame
, rows
, cols
)
1898 /* For height, we have to see:
1899 whether the frame has a minibuffer,
1900 whether it wants a mode line, and
1901 whether it has a menu bar. */
1903 (FRAME_MINIBUF_ONLY_P (frame
) ? MIN_SAFE_WINDOW_HEIGHT
- 1
1904 : (! FRAME_HAS_MINIBUF_P (frame
)) ? MIN_SAFE_WINDOW_HEIGHT
1905 : 2 * MIN_SAFE_WINDOW_HEIGHT
- 1);
1907 if (FRAME_TOP_MARGIN (frame
) > 0)
1908 min_height
+= FRAME_TOP_MARGIN (frame
);
1910 if (*rows
< min_height
)
1912 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
1913 *cols
= MIN_SAFE_WINDOW_WIDTH
;
1917 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
1918 check if W's width can be changed, otherwise check W's height.
1919 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
1920 siblings, too. If none of the siblings is resizable, WINDOW isn't
1924 window_fixed_size_p (w
, width_p
, check_siblings_p
)
1926 int width_p
, check_siblings_p
;
1931 if (!NILP (w
->hchild
))
1933 c
= XWINDOW (w
->hchild
);
1937 /* A horiz. combination is fixed-width if all of if its
1939 while (c
&& window_fixed_size_p (c
, width_p
, 0))
1940 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
1941 fixed_p
= c
== NULL
;
1945 /* A horiz. combination is fixed-height if one of if its
1947 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
1948 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
1949 fixed_p
= c
!= NULL
;
1952 else if (!NILP (w
->vchild
))
1954 c
= XWINDOW (w
->vchild
);
1958 /* A vert. combination is fixed-width if one of if its
1960 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
1961 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
1962 fixed_p
= c
!= NULL
;
1966 /* A vert. combination is fixed-height if all of if its
1968 while (c
&& window_fixed_size_p (c
, width_p
, 0))
1969 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
1970 fixed_p
= c
== NULL
;
1973 else if (BUFFERP (w
->buffer
))
1975 if (w
->height_fixed_p
&& !width_p
)
1979 struct buffer
*old
= current_buffer
;
1982 current_buffer
= XBUFFER (w
->buffer
);
1983 val
= find_symbol_value (Qwindow_size_fixed
);
1984 current_buffer
= old
;
1987 if (!EQ (val
, Qunbound
))
1989 fixed_p
= !NILP (val
);
1992 && ((EQ (val
, Qheight
) && width_p
)
1993 || (EQ (val
, Qwidth
) && !width_p
)))
1998 /* Can't tell if this one is resizable without looking at
1999 siblings. If all siblings are fixed-size this one is too. */
2000 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
2004 for (child
= w
->prev
; !NILP (child
); child
= XWINDOW (child
)->prev
)
2005 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2009 for (child
= w
->next
; !NILP (child
); child
= XWINDOW (child
)->next
)
2010 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2024 /* Return the minimum size of window W, not taking fixed-width windows
2025 into account. WIDTH_P non-zero means return the minimum width,
2026 otherwise return the minimum height. If W is a combination window,
2027 compute the minimum size from the minimum sizes of W's children. */
2030 window_min_size_1 (w
, width_p
)
2037 if (!NILP (w
->hchild
))
2039 c
= XWINDOW (w
->hchild
);
2044 /* The min width of a horizontal combination is
2045 the sum of the min widths of its children. */
2048 size
+= window_min_size_1 (c
, width_p
);
2049 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2054 /* The min height a horizontal combination equals
2055 the maximum of all min height of its children. */
2058 int min_size
= window_min_size_1 (c
, width_p
);
2059 size
= max (min_size
, size
);
2060 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2064 else if (!NILP (w
->vchild
))
2066 c
= XWINDOW (w
->vchild
);
2071 /* The min width of a vertical combination is
2072 the maximum of the min widths of its children. */
2075 int min_size
= window_min_size_1 (c
, width_p
);
2076 size
= max (min_size
, size
);
2077 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2082 /* The min height of a vertical combination equals
2083 the sum of the min height of its children. */
2086 size
+= window_min_size_1 (c
, width_p
);
2087 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2094 size
= window_min_width
;
2097 if (MINI_WINDOW_P (w
)
2098 || (!WINDOW_WANTS_MODELINE_P (w
)
2099 && !WINDOW_WANTS_HEADER_LINE_P (w
)))
2102 size
= window_min_height
;
2110 /* Return the minimum size of window W, taking fixed-size windows into
2111 account. WIDTH_P non-zero means return the minimum width,
2112 otherwise return the minimum height. IGNORE_FIXED_P non-zero means
2113 ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size
2114 unless FIXED is null. */
2117 window_min_size (w
, width_p
, ignore_fixed_p
, fixed
)
2119 int width_p
, ignore_fixed_p
, *fixed
;
2126 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
2132 size
= width_p
? XFASTINT (w
->width
) : XFASTINT (w
->height
);
2134 size
= window_min_size_1 (w
, width_p
);
2140 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
2141 WINDOW's width. Resize WINDOW's children, if any, so that they
2142 keep their proportionate size relative to WINDOW. Propagate
2143 WINDOW's top or left edge position to children. Delete windows
2144 that become too small unless NODELETE_P is non-zero. */
2147 size_window (window
, size
, width_p
, nodelete_p
)
2149 int size
, width_p
, nodelete_p
;
2151 struct window
*w
= XWINDOW (window
);
2153 Lisp_Object child
, *forward
, *sideward
;
2154 int old_size
, min_size
;
2156 check_min_window_sizes ();
2158 /* If the window has been "too small" at one point,
2159 don't delete it for being "too small" in the future.
2160 Preserve it as long as that is at all possible. */
2163 old_size
= XFASTINT (w
->width
);
2164 min_size
= window_min_width
;
2168 old_size
= XFASTINT (w
->height
);
2169 min_size
= window_min_height
;
2172 if (old_size
< window_min_width
)
2173 w
->too_small_ok
= Qt
;
2175 /* Maybe delete WINDOW if it's too small. */
2176 if (!nodelete_p
&& !NILP (w
->parent
))
2180 if (!MINI_WINDOW_P (w
) && !NILP (w
->too_small_ok
))
2181 min_size
= width_p
? MIN_SAFE_WINDOW_WIDTH
: MIN_SAFE_WINDOW_HEIGHT
;
2183 min_size
= width_p
? window_min_width
: window_min_height
;
2185 if (size
< min_size
)
2187 delete_window (window
);
2192 /* Set redisplay hints. */
2193 XSETFASTINT (w
->last_modified
, 0);
2194 XSETFASTINT (w
->last_overlay_modified
, 0);
2195 windows_or_buffers_changed
++;
2196 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
2200 sideward
= &w
->vchild
;
2201 forward
= &w
->hchild
;
2202 XSETFASTINT (w
->width
, size
);
2206 sideward
= &w
->hchild
;
2207 forward
= &w
->vchild
;
2208 XSETFASTINT (w
->height
, size
);
2211 if (!NILP (*sideward
))
2213 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
2215 c
= XWINDOW (child
);
2220 size_window (child
, size
, width_p
, nodelete_p
);
2223 else if (!NILP (*forward
))
2225 int fixed_size
, each
, extra
, n
;
2226 int resize_fixed_p
, nfixed
;
2227 int last_pos
, first_pos
, nchildren
;
2229 /* Determine the fixed-size portion of the this window, and the
2230 number of child windows. */
2231 fixed_size
= nchildren
= nfixed
= 0;
2232 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
2234 c
= XWINDOW (child
);
2235 if (window_fixed_size_p (c
, width_p
, 0))
2237 fixed_size
+= (width_p
2238 ? XFASTINT (c
->width
) : XFASTINT (c
->height
));
2243 /* If the new size is smaller than fixed_size, or if there
2244 aren't any resizable windows, allow resizing fixed-size
2246 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
2248 /* Compute how many lines/columns to add to each child. The
2249 value of extra takes care of rounding errors. */
2250 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
2251 each
= (size
- old_size
) / n
;
2252 extra
= (size
- old_size
) - n
* each
;
2254 /* Compute new children heights and edge positions. */
2255 first_pos
= width_p
? XFASTINT (w
->left
) : XFASTINT (w
->top
);
2256 last_pos
= first_pos
;
2257 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2259 int new_size
, old_size
;
2261 c
= XWINDOW (child
);
2262 old_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2263 new_size
= old_size
;
2265 /* The top or left edge position of this child equals the
2266 bottom or right edge of its predecessor. */
2268 c
->left
= make_number (last_pos
);
2270 c
->top
= make_number (last_pos
);
2272 /* If this child can be resized, do it. */
2273 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
2275 new_size
= old_size
+ each
+ extra
;
2279 /* Set new height. Note that size_window also propagates
2280 edge positions to children, so it's not a no-op if we
2281 didn't change the child's size. */
2282 size_window (child
, new_size
, width_p
, 1);
2284 /* Remember the bottom/right edge position of this child; it
2285 will be used to set the top/left edge of the next child. */
2286 last_pos
+= new_size
;
2289 /* We should have covered the parent exactly with child windows. */
2290 xassert (size
== last_pos
- first_pos
);
2292 /* Now delete any children that became too small. */
2294 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2297 c
= XWINDOW (child
);
2298 child_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2299 size_window (child
, child_size
, width_p
, 0);
2304 /* Set WINDOW's height to HEIGHT, and recursively change the height of
2305 WINDOW's children. NODELETE non-zero means don't delete windows
2306 that become too small in the process. (The caller should check
2307 later and do so if appropriate.) */
2310 set_window_height (window
, height
, nodelete
)
2315 size_window (window
, height
, 0, nodelete
);
2319 /* Set WINDOW's width to WIDTH, and recursively change the width of
2320 WINDOW's children. NODELETE non-zero means don't delete windows
2321 that become too small in the process. (The caller should check
2322 later and do so if appropriate.) */
2325 set_window_width (window
, width
, nodelete
)
2330 size_window (window
, width
, 1, nodelete
);
2334 int window_select_count
;
2337 Fset_window_buffer_unwind (obuf
)
2345 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
2346 means it's allowed to run hooks. See make_frame for a case where
2347 it's not allowed. */
2350 set_window_buffer (window
, buffer
, run_hooks_p
)
2351 Lisp_Object window
, buffer
;
2354 struct window
*w
= XWINDOW (window
);
2355 struct buffer
*b
= XBUFFER (buffer
);
2356 int count
= specpdl_ptr
- specpdl
;
2360 if (EQ (window
, selected_window
))
2361 b
->last_selected_window
= window
;
2363 /* Update time stamps of buffer display. */
2364 if (INTEGERP (b
->display_count
))
2365 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
2366 b
->display_time
= Fcurrent_time ();
2368 XSETFASTINT (w
->window_end_pos
, 0);
2369 XSETFASTINT (w
->window_end_vpos
, 0);
2370 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
2371 w
->window_end_valid
= Qnil
;
2372 XSETFASTINT (w
->hscroll
, 0);
2373 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
2374 set_marker_restricted (w
->start
,
2375 make_number (b
->last_window_start
),
2377 w
->start_at_line_beg
= Qnil
;
2378 w
->force_start
= Qnil
;
2379 XSETFASTINT (w
->last_modified
, 0);
2380 XSETFASTINT (w
->last_overlay_modified
, 0);
2381 windows_or_buffers_changed
++;
2383 /* We must select BUFFER for running the window-scroll-functions.
2384 If WINDOW is selected, switch permanently.
2385 Otherwise, switch but go back to the ambient buffer afterward. */
2386 if (EQ (window
, selected_window
))
2387 Fset_buffer (buffer
);
2388 /* We can't check ! NILP (Vwindow_scroll_functions) here
2389 because that might itself be a local variable. */
2390 else if (window_initialized
)
2392 record_unwind_protect (Fset_window_buffer_unwind
, Fcurrent_buffer ());
2393 Fset_buffer (buffer
);
2396 /* Set left and right marginal area width from buffer. */
2397 Fset_window_margins (window
, b
->left_margin_width
, b
->right_margin_width
);
2401 if (! NILP (Vwindow_scroll_functions
))
2402 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2403 Fmarker_position (w
->start
));
2405 if (! NILP (Vwindow_configuration_change_hook
)
2406 && ! NILP (Vrun_hooks
))
2407 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
2410 unbind_to (count
, Qnil
);
2414 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 2, 0,
2415 "Make WINDOW display BUFFER as its contents.\n\
2416 BUFFER can be a buffer or buffer name.")
2418 register Lisp_Object window
, buffer
;
2420 register Lisp_Object tem
;
2421 register struct window
*w
= decode_window (window
);
2423 buffer
= Fget_buffer (buffer
);
2424 CHECK_BUFFER (buffer
, 1);
2426 if (NILP (XBUFFER (buffer
)->name
))
2427 error ("Attempt to display deleted buffer");
2431 error ("Window is deleted");
2432 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
2433 is first being set up. */
2435 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
2436 error ("Window is dedicated to `%s'",
2437 XSTRING (XBUFFER (tem
)->name
)->data
);
2442 set_window_buffer (window
, buffer
, 1);
2446 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 1, 0,
2447 "Select WINDOW. Most editing will apply to WINDOW's buffer.\n\
2448 If WINDOW is not already selected, also make WINDOW's buffer current.\n\
2449 Note that the main editor command loop\n\
2450 selects the buffer of the selected window before each command.")
2452 register Lisp_Object window
;
2454 return select_window_1 (window
, 1);
2458 select_window_1 (window
, recordflag
)
2459 register Lisp_Object window
;
2462 register struct window
*w
;
2463 register struct window
*ow
= XWINDOW (selected_window
);
2466 CHECK_LIVE_WINDOW (window
, 0);
2468 w
= XWINDOW (window
);
2470 if (NILP (w
->buffer
))
2471 error ("Trying to select deleted window or non-leaf window");
2473 XSETFASTINT (w
->use_time
, ++window_select_count
);
2474 if (EQ (window
, selected_window
))
2477 if (! NILP (ow
->buffer
))
2478 set_marker_both (ow
->pointm
, ow
->buffer
,
2479 BUF_PT (XBUFFER (ow
->buffer
)),
2480 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
2482 selected_window
= window
;
2483 sf
= SELECTED_FRAME ();
2484 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
2486 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
2487 /* Use this rather than Fhandle_switch_frame
2488 so that FRAME_FOCUS_FRAME is moved appropriately as we
2489 move around in the state where a minibuffer in a separate
2491 Fselect_frame (WINDOW_FRAME (w
), Qnil
);
2494 sf
->selected_window
= window
;
2497 record_buffer (w
->buffer
);
2498 Fset_buffer (w
->buffer
);
2500 XBUFFER (w
->buffer
)->last_selected_window
= window
;
2502 /* Go to the point recorded in the window.
2503 This is important when the buffer is in more
2504 than one window. It also matters when
2505 redisplay_window has altered point after scrolling,
2506 because it makes the change only in the window. */
2508 register int new_point
= marker_position (w
->pointm
);
2509 if (new_point
< BEGV
)
2511 else if (new_point
> ZV
)
2517 windows_or_buffers_changed
++;
2521 /* Deiconify the frame containing the window WINDOW,
2522 unless it is the selected frame;
2525 The reason for the exception for the selected frame
2526 is that it seems better not to change the selected frames visibility
2527 merely because of displaying a different buffer in it.
2528 The deiconification is useful when a buffer gets shown in
2529 another frame that you were not using lately. */
2532 display_buffer_1 (window
)
2535 Lisp_Object frame
= XWINDOW (window
)->frame
;
2536 FRAME_PTR f
= XFRAME (frame
);
2538 FRAME_SAMPLE_VISIBILITY (f
);
2540 if (!EQ (frame
, selected_frame
))
2542 if (FRAME_ICONIFIED_P (f
))
2543 Fmake_frame_visible (frame
);
2544 else if (FRAME_VISIBLE_P (f
))
2545 Fraise_frame (frame
);
2551 DEFUN ("special-display-p", Fspecial_display_p
, Sspecial_display_p
, 1, 1, 0,
2552 "Returns non-nil if a buffer named BUFFER-NAME would be created specially.\n\
2553 The value is actually t if the frame should be called with default frame\n\
2554 parameters, and a list of frame parameters if they were specified.\n\
2555 See `special-display-buffer-names', and `special-display-regexps'.")
2557 Lisp_Object buffer_name
;
2561 CHECK_STRING (buffer_name
, 1);
2563 tem
= Fmember (buffer_name
, Vspecial_display_buffer_names
);
2567 tem
= Fassoc (buffer_name
, Vspecial_display_buffer_names
);
2571 for (tem
= Vspecial_display_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2573 Lisp_Object car
= XCAR (tem
);
2575 && fast_string_match (car
, buffer_name
) >= 0)
2577 else if (CONSP (car
)
2578 && STRINGP (XCAR (car
))
2579 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2585 DEFUN ("same-window-p", Fsame_window_p
, Ssame_window_p
, 1, 1, 0,
2586 "Returns non-nil if a new buffer named BUFFER-NAME would use the same window.\n\
2587 See `same-window-buffer-names' and `same-window-regexps'.")
2589 Lisp_Object buffer_name
;
2593 CHECK_STRING (buffer_name
, 1);
2595 tem
= Fmember (buffer_name
, Vsame_window_buffer_names
);
2599 tem
= Fassoc (buffer_name
, Vsame_window_buffer_names
);
2603 for (tem
= Vsame_window_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2605 Lisp_Object car
= XCAR (tem
);
2607 && fast_string_match (car
, buffer_name
) >= 0)
2609 else if (CONSP (car
)
2610 && STRINGP (XCAR (car
))
2611 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2617 /* Use B so the default is (other-buffer). */
2618 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 3,
2619 "BDisplay buffer: \nP",
2620 "Make BUFFER appear in some window but don't select it.\n\
2621 BUFFER can be a buffer or a buffer name.\n\
2622 If BUFFER is shown already in some window, just use that one,\n\
2623 unless the window is the selected window and the optional second\n\
2624 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).\n\
2625 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.\n\
2626 Returns the window displaying BUFFER.\n\
2628 The variables `special-display-buffer-names', `special-display-regexps',\n\
2629 `same-window-buffer-names', and `same-window-regexps' customize how certain\n\
2630 buffer names are handled.\n\
2632 If optional argument FRAME is `visible', search all visible frames.\n\
2633 If FRAME is 0, search all visible and iconified frames.\n\
2634 If FRAME is t, search all frames.\n\
2635 If FRAME is a frame, search only that frame.\n\
2636 If FRAME is nil, search only the selected frame\n\
2637 (actually the last nonminibuffer frame),\n\
2638 unless `pop-up-frames' is non-nil,\n\
2639 which means search visible and iconified frames.")
2640 (buffer
, not_this_window
, frame
)
2641 register Lisp_Object buffer
, not_this_window
, frame
;
2643 register Lisp_Object window
, tem
, swp
;
2647 buffer
= Fget_buffer (buffer
);
2648 CHECK_BUFFER (buffer
, 0);
2650 if (!NILP (Vdisplay_buffer_function
))
2651 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
2653 if (NILP (not_this_window
)
2654 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
2655 return display_buffer_1 (selected_window
);
2657 /* See if the user has specified this buffer should appear
2658 in the selected window. */
2659 if (NILP (not_this_window
))
2661 swp
= Fsame_window_p (XBUFFER (buffer
)->name
);
2662 if (!NILP (swp
) && !no_switch_window (selected_window
))
2664 Fswitch_to_buffer (buffer
, Qnil
);
2665 return display_buffer_1 (selected_window
);
2669 /* If pop_up_frames,
2670 look for a window showing BUFFER on any visible or iconified frame.
2671 Otherwise search only the current frame. */
2674 else if (pop_up_frames
|| last_nonminibuf_frame
== 0)
2675 XSETFASTINT (tem
, 0);
2677 XSETFRAME (tem
, last_nonminibuf_frame
);
2678 window
= Fget_buffer_window (buffer
, tem
);
2680 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
2682 return display_buffer_1 (window
);
2685 /* Certain buffer names get special handling. */
2686 if (!NILP (Vspecial_display_function
) && NILP (swp
))
2688 tem
= Fspecial_display_p (XBUFFER (buffer
)->name
);
2690 return call1 (Vspecial_display_function
, buffer
);
2692 return call2 (Vspecial_display_function
, buffer
, tem
);
2695 /* If there are no frames open that have more than a minibuffer,
2696 we need to create a new frame. */
2697 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
2699 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2700 Fset_window_buffer (window
, buffer
);
2701 return display_buffer_1 (window
);
2704 f
= SELECTED_FRAME ();
2706 || FRAME_MINIBUF_ONLY_P (f
)
2707 /* If the current frame is a special display frame,
2708 don't try to reuse its windows. */
2709 || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f
))->dedicated
))
2714 if (FRAME_MINIBUF_ONLY_P (f
))
2715 XSETFRAME (frames
, last_nonminibuf_frame
);
2716 /* Don't try to create a window if would get an error */
2717 if (split_height_threshold
< window_min_height
<< 1)
2718 split_height_threshold
= window_min_height
<< 1;
2720 /* Note that both Fget_largest_window and Fget_lru_window
2721 ignore minibuffers and dedicated windows.
2722 This means they can return nil. */
2724 /* If the frame we would try to split cannot be split,
2725 try other frames. */
2726 if (FRAME_NO_SPLIT_P (NILP (frames
) ? f
: last_nonminibuf_frame
))
2728 /* Try visible frames first. */
2729 window
= Fget_largest_window (Qvisible
);
2730 /* If that didn't work, try iconified frames. */
2732 window
= Fget_largest_window (make_number (0));
2734 window
= Fget_largest_window (Qt
);
2737 window
= Fget_largest_window (frames
);
2739 /* If we got a tall enough full-width window that can be split,
2742 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2743 && window_height (window
) >= split_height_threshold
2744 && WINDOW_FULL_WIDTH_P (XWINDOW (window
)))
2745 window
= Fsplit_window (window
, Qnil
, Qnil
);
2748 Lisp_Object upper
, lower
, other
;
2750 window
= Fget_lru_window (frames
);
2751 /* If the LRU window is selected, and big enough,
2752 and can be split, split it. */
2754 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2755 && (EQ (window
, selected_window
)
2756 || EQ (XWINDOW (window
)->parent
, Qnil
))
2757 && window_height (window
) >= window_min_height
<< 1)
2758 window
= Fsplit_window (window
, Qnil
, Qnil
);
2759 /* If Fget_lru_window returned nil, try other approaches. */
2761 /* Try visible frames first. */
2763 window
= Fget_buffer_window (buffer
, Qvisible
);
2765 window
= Fget_largest_window (Qvisible
);
2766 /* If that didn't work, try iconified frames. */
2768 window
= Fget_buffer_window (buffer
, make_number (0));
2770 window
= Fget_largest_window (make_number (0));
2771 /* Try invisible frames. */
2773 window
= Fget_buffer_window (buffer
, Qt
);
2775 window
= Fget_largest_window (Qt
);
2776 /* As a last resort, make a new frame. */
2778 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2779 /* If window appears above or below another,
2780 even out their heights. */
2781 other
= upper
= lower
= Qnil
;
2782 if (!NILP (XWINDOW (window
)->prev
))
2783 other
= upper
= XWINDOW (window
)->prev
, lower
= window
;
2784 if (!NILP (XWINDOW (window
)->next
))
2785 other
= lower
= XWINDOW (window
)->next
, upper
= window
;
2787 /* Check that OTHER and WINDOW are vertically arrayed. */
2788 && !EQ (XWINDOW (other
)->top
, XWINDOW (window
)->top
)
2789 && (XFASTINT (XWINDOW (other
)->height
)
2790 > XFASTINT (XWINDOW (window
)->height
)))
2792 int total
= (XFASTINT (XWINDOW (other
)->height
)
2793 + XFASTINT (XWINDOW (window
)->height
));
2794 enlarge_window (upper
,
2795 total
/ 2 - XFASTINT (XWINDOW (upper
)->height
),
2801 window
= Fget_lru_window (Qnil
);
2803 Fset_window_buffer (window
, buffer
);
2804 return display_buffer_1 (window
);
2808 temp_output_buffer_show (buf
)
2809 register Lisp_Object buf
;
2811 register struct buffer
*old
= current_buffer
;
2812 register Lisp_Object window
;
2813 register struct window
*w
;
2815 XBUFFER (buf
)->directory
= current_buffer
->directory
;
2818 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
2822 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
2823 set_buffer_internal (old
);
2825 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
2826 call1 (Vtemp_buffer_show_function
, buf
);
2829 window
= Fdisplay_buffer (buf
, Qnil
, Qnil
);
2831 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
2832 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
2833 Vminibuf_scroll_window
= window
;
2834 w
= XWINDOW (window
);
2835 XSETFASTINT (w
->hscroll
, 0);
2836 set_marker_restricted_both (w
->start
, buf
, 1, 1);
2837 set_marker_restricted_both (w
->pointm
, buf
, 1, 1);
2839 /* Run temp-buffer-show-hook, with the chosen window selected
2840 and it sbuffer current. */
2841 if (!NILP (Vrun_hooks
))
2844 tem
= Fboundp (Qtemp_buffer_show_hook
);
2847 tem
= Fsymbol_value (Qtemp_buffer_show_hook
);
2850 int count
= specpdl_ptr
- specpdl
;
2851 Lisp_Object prev_window
;
2852 prev_window
= selected_window
;
2854 /* Select the window that was chosen, for running the hook. */
2855 record_unwind_protect (Fselect_window
, prev_window
);
2856 select_window_1 (window
, 0);
2857 Fset_buffer (w
->buffer
);
2858 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
2859 select_window_1 (prev_window
, 0);
2860 unbind_to (count
, Qnil
);
2868 make_dummy_parent (window
)
2872 register struct window
*o
, *p
;
2873 register struct Lisp_Vector
*vec
;
2876 o
= XWINDOW (window
);
2877 vec
= allocate_vectorlike ((EMACS_INT
)VECSIZE (struct window
));
2878 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
2879 vec
->contents
[i
] = ((struct Lisp_Vector
*)o
)->contents
[i
];
2880 vec
->size
= VECSIZE (struct window
);
2881 p
= (struct window
*)vec
;
2882 XSETWINDOW (new, p
);
2884 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
2886 /* Put new into window structure in place of window */
2887 replace_window (window
, new);
2900 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
2901 "Split WINDOW, putting SIZE lines in the first of the pair.\n\
2902 WINDOW defaults to selected one and SIZE to half its size.\n\
2903 If optional third arg HORFLAG is non-nil, split side by side\n\
2904 and put SIZE columns in the first of the pair. In that case,\n\
2905 SIZE includes that window's scroll bar, or the divider column to its right.")
2906 (window
, size
, horflag
)
2907 Lisp_Object window
, size
, horflag
;
2909 register Lisp_Object
new;
2910 register struct window
*o
, *p
;
2912 register int size_int
;
2915 window
= selected_window
;
2917 CHECK_LIVE_WINDOW (window
, 0);
2919 o
= XWINDOW (window
);
2920 fo
= XFRAME (WINDOW_FRAME (o
));
2924 if (!NILP (horflag
))
2925 /* Calculate the size of the left-hand window, by dividing
2926 the usable space in columns by two.
2927 We round up, since the left-hand window may include
2928 a dividing line, while the right-hand may not. */
2929 size_int
= (XFASTINT (o
->width
) + 1) >> 1;
2931 size_int
= XFASTINT (o
->height
) >> 1;
2935 CHECK_NUMBER (size
, 1);
2936 size_int
= XINT (size
);
2939 if (MINI_WINDOW_P (o
))
2940 error ("Attempt to split minibuffer window");
2941 else if (window_fixed_size_p (o
, !NILP (horflag
), 0))
2942 error ("Attempt to split fixed-size window");
2944 check_min_window_sizes ();
2948 if (size_int
< window_min_height
)
2949 error ("Window height %d too small (after splitting)", size_int
);
2950 if (size_int
+ window_min_height
> XFASTINT (o
->height
))
2951 error ("Window height %d too small (after splitting)",
2952 XFASTINT (o
->height
) - size_int
);
2953 if (NILP (o
->parent
)
2954 || NILP (XWINDOW (o
->parent
)->vchild
))
2956 make_dummy_parent (window
);
2958 XWINDOW (new)->vchild
= window
;
2963 if (size_int
< window_min_width
)
2964 error ("Window width %d too small (after splitting)", size_int
);
2966 if (size_int
+ window_min_width
> XFASTINT (o
->width
))
2967 error ("Window width %d too small (after splitting)",
2968 XFASTINT (o
->width
) - size_int
);
2969 if (NILP (o
->parent
)
2970 || NILP (XWINDOW (o
->parent
)->hchild
))
2972 make_dummy_parent (window
);
2974 XWINDOW (new)->hchild
= window
;
2978 /* Now we know that window's parent is a vertical combination
2979 if we are dividing vertically, or a horizontal combination
2980 if we are making side-by-side windows */
2982 windows_or_buffers_changed
++;
2983 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
2984 new = make_window ();
2987 p
->frame
= o
->frame
;
2989 if (!NILP (p
->next
))
2990 XWINDOW (p
->next
)->prev
= new;
2993 p
->parent
= o
->parent
;
2995 p
->window_end_valid
= Qnil
;
2996 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
2998 /* Apportion the available frame space among the two new windows */
3000 if (!NILP (horflag
))
3002 p
->height
= o
->height
;
3004 XSETFASTINT (p
->width
, XFASTINT (o
->width
) - size_int
);
3005 XSETFASTINT (o
->width
, size_int
);
3006 XSETFASTINT (p
->left
, XFASTINT (o
->left
) + size_int
);
3011 p
->width
= o
->width
;
3012 XSETFASTINT (p
->height
, XFASTINT (o
->height
) - size_int
);
3013 XSETFASTINT (o
->height
, size_int
);
3014 XSETFASTINT (p
->top
, XFASTINT (o
->top
) + size_int
);
3017 /* Adjust glyph matrices. */
3019 Fset_window_buffer (new, o
->buffer
);
3023 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
3024 "Make current window ARG lines bigger.\n\
3025 From program, optional second arg non-nil means grow sideways ARG columns.")
3027 register Lisp_Object arg
, side
;
3029 CHECK_NUMBER (arg
, 0);
3030 enlarge_window (selected_window
, XINT (arg
), !NILP (side
));
3032 if (! NILP (Vwindow_configuration_change_hook
))
3033 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3038 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
3039 "Make current window ARG lines smaller.\n\
3040 From program, optional second arg non-nil means shrink sideways arg columns.")
3042 register Lisp_Object arg
, side
;
3044 CHECK_NUMBER (arg
, 0);
3045 enlarge_window (selected_window
, -XINT (arg
), !NILP (side
));
3047 if (! NILP (Vwindow_configuration_change_hook
))
3048 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3054 window_height (window
)
3057 register struct window
*p
= XWINDOW (window
);
3058 return XFASTINT (p
->height
);
3062 window_width (window
)
3065 register struct window
*p
= XWINDOW (window
);
3066 return XFASTINT (p
->width
);
3071 *(widthflag ? (int *) &(XWINDOW (w)->left) : (int *) &(XWINDOW (w)->top))
3073 #define CURSIZE(w) \
3074 *(widthflag ? (int *) &(XWINDOW (w)->width) : (int *) &(XWINDOW (w)->height))
3077 /* Enlarge selected_window by DELTA. WIDTHFLAG non-zero means
3078 increase its width. Siblings of the selected window are resized to
3079 fullfil the size request. If they become too small in the process,
3080 they will be deleted. */
3083 enlarge_window (window
, delta
, widthflag
)
3085 int delta
, widthflag
;
3087 Lisp_Object parent
, next
, prev
;
3089 int *sizep
, maximum
;
3090 int (*sizefun
) P_ ((Lisp_Object
))
3091 = widthflag
? window_width
: window_height
;
3092 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
3093 = (widthflag
? set_window_width
: set_window_height
);
3095 /* Check values of window_min_width and window_min_height for
3097 check_min_window_sizes ();
3099 /* Give up if this window cannot be resized. */
3100 if (window_fixed_size_p (XWINDOW (window
), widthflag
, 1))
3101 error ("Window is not resizable");
3103 /* Find the parent of the selected window. */
3106 p
= XWINDOW (window
);
3112 error ("No other window to side of this one");
3117 ? !NILP (XWINDOW (parent
)->hchild
)
3118 : !NILP (XWINDOW (parent
)->vchild
))
3124 sizep
= &CURSIZE (window
);
3127 register int maxdelta
;
3129 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - *sizep
3130 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3131 - window_min_size (XWINDOW (p
->next
),
3133 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
3134 - window_min_size (XWINDOW (p
->prev
),
3136 /* This is a frame with only one window, a minibuffer-only
3137 or a minibufferless frame. */
3140 if (delta
> maxdelta
)
3141 /* This case traps trying to make the minibuffer
3142 the full frame, or make the only window aside from the
3143 minibuffer the full frame. */
3147 if (*sizep
+ delta
< window_min_size (XWINDOW (window
), widthflag
, 0, 0))
3149 delete_window (window
);
3156 /* Find the total we can get from other siblings. */
3158 for (next
= p
->next
; ! NILP (next
); next
= XWINDOW (next
)->next
)
3159 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
3161 for (prev
= p
->prev
; ! NILP (prev
); prev
= XWINDOW (prev
)->prev
)
3162 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
3165 /* If we can get it all from them, do so. */
3166 if (delta
<= maximum
)
3168 Lisp_Object first_unaffected
;
3169 Lisp_Object first_affected
;
3174 first_affected
= window
;
3175 /* Look at one sibling at a time,
3176 moving away from this window in both directions alternately,
3177 and take as much as we can get without deleting that sibling. */
3178 while (delta
!= 0 && (!NILP (next
) || !NILP (prev
)))
3182 int this_one
= ((*sizefun
) (next
)
3183 - window_min_size (XWINDOW (next
),
3184 widthflag
, 0, &fixed_p
));
3187 if (this_one
> delta
)
3190 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
3191 (*setsizefun
) (window
, *sizep
+ this_one
, 0);
3196 next
= XWINDOW (next
)->next
;
3204 int this_one
= ((*sizefun
) (prev
)
3205 - window_min_size (XWINDOW (prev
),
3206 widthflag
, 0, &fixed_p
));
3209 if (this_one
> delta
)
3212 first_affected
= prev
;
3214 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
3215 (*setsizefun
) (window
, *sizep
+ this_one
, 0);
3220 prev
= XWINDOW (prev
)->prev
;
3224 xassert (delta
== 0);
3226 /* Now recalculate the edge positions of all the windows affected,
3227 based on the new sizes. */
3228 first_unaffected
= next
;
3229 prev
= first_affected
;
3230 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
3231 prev
= next
, next
= XWINDOW (next
)->next
)
3233 CURBEG (next
) = CURBEG (prev
) + (*sizefun
) (prev
);
3234 /* This does not change size of NEXT,
3235 but it propagates the new top edge to its children */
3236 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
3241 register int delta1
;
3242 register int opht
= (*sizefun
) (parent
);
3244 /* If trying to grow this window to or beyond size of the parent,
3245 make delta1 so big that, on shrinking back down,
3246 all the siblings end up with less than one line and are deleted. */
3247 if (opht
<= *sizep
+ delta
)
3248 delta1
= opht
* opht
* 2;
3251 /* Otherwise, make delta1 just right so that if we add
3252 delta1 lines to this window and to the parent, and then
3253 shrink the parent back to its original size, the new
3254 proportional size of this window will increase by delta.
3256 The function size_window will compute the new height h'
3257 of the window from delta1 as:
3260 x = delta1 - delta1/n * n for the 1st resizable child
3263 where n is the number of children that can be resized.
3264 We can ignore x by choosing a delta1 that is a multiple of
3265 n. We want the height of this window to come out as
3275 The number of children n rquals the number of resizable
3276 children of this window + 1 because we know window itself
3277 is resizable (otherwise we would have signalled an error. */
3279 struct window
*w
= XWINDOW (window
);
3283 for (s
= w
->next
; !NILP (s
); s
= XWINDOW (s
)->next
)
3284 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3286 for (s
= w
->prev
; !NILP (s
); s
= XWINDOW (s
)->prev
)
3287 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3293 /* Add delta1 lines or columns to this window, and to the parent,
3294 keeping things consistent while not affecting siblings. */
3295 CURSIZE (parent
) = opht
+ delta1
;
3296 (*setsizefun
) (window
, *sizep
+ delta1
, 0);
3298 /* Squeeze out delta1 lines or columns from our parent,
3299 shriking this window and siblings proportionately.
3300 This brings parent back to correct size.
3301 Delta1 was calculated so this makes this window the desired size,
3302 taking it all out of the siblings. */
3303 (*setsizefun
) (parent
, opht
, 0);
3306 XSETFASTINT (p
->last_modified
, 0);
3307 XSETFASTINT (p
->last_overlay_modified
, 0);
3309 /* Adjust glyph matrices. */
3310 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
3318 /***********************************************************************
3319 Resizing Mini-Windows
3320 ***********************************************************************/
3322 static void shrink_window_lowest_first
P_ ((struct window
*, int));
3324 enum save_restore_action
3331 static int save_restore_orig_size
P_ ((struct window
*,
3332 enum save_restore_action
));
3334 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
3335 from lowest windows first. */
3338 shrink_window_lowest_first (w
, height
)
3346 xassert (!MINI_WINDOW_P (w
));
3348 /* Set redisplay hints. */
3349 XSETFASTINT (w
->last_modified
, 0);
3350 XSETFASTINT (w
->last_overlay_modified
, 0);
3351 windows_or_buffers_changed
++;
3352 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
3354 old_height
= XFASTINT (w
->height
);
3355 XSETFASTINT (w
->height
, height
);
3357 if (!NILP (w
->hchild
))
3359 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
3361 c
= XWINDOW (child
);
3363 shrink_window_lowest_first (c
, height
);
3366 else if (!NILP (w
->vchild
))
3368 Lisp_Object last_child
;
3369 int delta
= old_height
- height
;
3372 /* Find the last child. We are taking space from lowest windows
3373 first, so we iterate over children from the last child
3375 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
3378 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
3379 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
3383 c
= XWINDOW (child
);
3384 this_one
= XFASTINT (c
->height
) - MIN_SAFE_WINDOW_HEIGHT
;
3386 if (this_one
> delta
)
3389 shrink_window_lowest_first (c
, XFASTINT (c
->height
) - this_one
);
3393 /* Compute new positions. */
3395 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
3397 c
= XWINDOW (child
);
3398 c
->top
= make_number (last_top
);
3399 shrink_window_lowest_first (c
, XFASTINT (c
->height
));
3400 last_top
+= XFASTINT (c
->height
);
3406 /* Save, restore, or check positions and sizes in the window tree
3407 rooted at W. ACTION says what to do.
3409 If ACTION is CHECK_ORIG_SIZES, check if orig_top and orig_height
3410 members are valid for all windows in the window tree. Value is
3411 non-zero if they are valid.
3413 If ACTION is SAVE_ORIG_SIZES, save members top and height in
3414 orig_top and orig_height for all windows in the tree.
3416 If ACTION is RESTORE_ORIG_SIZES, restore top and height from
3417 values stored in orig_top and orig_height for all windows. */
3420 save_restore_orig_size (w
, action
)
3422 enum save_restore_action action
;
3428 if (!NILP (w
->hchild
))
3430 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
3433 else if (!NILP (w
->vchild
))
3435 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
3441 case CHECK_ORIG_SIZES
:
3442 if (!INTEGERP (w
->orig_top
) || !INTEGERP (w
->orig_height
))
3446 case SAVE_ORIG_SIZES
:
3447 w
->orig_top
= w
->top
;
3448 w
->orig_height
= w
->height
;
3449 XSETFASTINT (w
->last_modified
, 0);
3450 XSETFASTINT (w
->last_overlay_modified
, 0);
3453 case RESTORE_ORIG_SIZES
:
3454 xassert (INTEGERP (w
->orig_top
) && INTEGERP (w
->orig_height
));
3455 w
->top
= w
->orig_top
;
3456 w
->height
= w
->orig_height
;
3457 w
->orig_height
= w
->orig_top
= Qnil
;
3458 XSETFASTINT (w
->last_modified
, 0);
3459 XSETFASTINT (w
->last_overlay_modified
, 0);
3466 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
3473 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
3474 without deleting other windows. */
3477 grow_mini_window (w
, delta
)
3481 struct frame
*f
= XFRAME (w
->frame
);
3482 struct window
*root
;
3484 xassert (MINI_WINDOW_P (w
));
3485 xassert (delta
>= 0);
3487 /* Check values of window_min_width and window_min_height for
3489 check_min_window_sizes ();
3491 /* Compute how much we can enlarge the mini-window without deleting
3493 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3496 int min_height
= window_min_size (root
, 0, 0, 0);
3497 if (XFASTINT (root
->height
) - delta
< min_height
)
3498 delta
= XFASTINT (root
->height
) - min_height
;
3503 /* Save original window sizes and positions, if not already done. */
3504 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3505 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
3507 /* Shrink other windows. */
3508 shrink_window_lowest_first (root
, XFASTINT (root
->height
) - delta
);
3510 /* Grow the mini-window. */
3511 w
->top
= make_number (XFASTINT (root
->top
) + XFASTINT (root
)->height
);
3512 w
->height
= make_number (XFASTINT (w
->height
) + delta
);
3513 XSETFASTINT (w
->last_modified
, 0);
3514 XSETFASTINT (w
->last_overlay_modified
, 0);
3521 /* Shrink mini-window W. If there is recorded info about window sizes
3522 before a call to grow_mini_window, restore recorded window sizes.
3523 Otherwise, if the mini-window is higher than 1 line, resize it to 1
3527 shrink_mini_window (w
)
3530 struct frame
*f
= XFRAME (w
->frame
);
3531 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3533 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3535 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
3537 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
3538 windows_or_buffers_changed
= 1;
3540 else if (XFASTINT (w
->height
) > 1)
3543 XSETWINDOW (window
, w
);
3544 enlarge_window (window
, 1 - XFASTINT (w
->height
), 0);
3550 /* Mark window cursors off for all windows in the window tree rooted
3551 at W by setting their phys_cursor_on_p flag to zero. Called from
3552 xterm.c, e.g. when a frame is cleared and thereby all cursors on
3553 the frame are cleared. */
3556 mark_window_cursors_off (w
)
3561 if (!NILP (w
->hchild
))
3562 mark_window_cursors_off (XWINDOW (w
->hchild
));
3563 else if (!NILP (w
->vchild
))
3564 mark_window_cursors_off (XWINDOW (w
->vchild
));
3566 w
->phys_cursor_on_p
= 0;
3568 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
3573 /* Return number of lines of text (not counting mode line) in W. */
3576 window_internal_height (w
)
3579 int ht
= XFASTINT (w
->height
);
3581 if (MINI_WINDOW_P (w
))
3584 if (!NILP (w
->parent
) || !NILP (w
->vchild
) || !NILP (w
->hchild
)
3585 || !NILP (w
->next
) || !NILP (w
->prev
)
3586 || FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (w
))))
3593 /* Return the number of columns in W.
3594 Don't count columns occupied by scroll bars or the vertical bar
3595 separating W from the sibling to its right. */
3598 window_internal_width (w
)
3601 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
3602 int width
= XINT (w
->width
);
3604 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
3605 /* Scroll bars occupy a few columns. */
3606 width
-= FRAME_SCROLL_BAR_COLS (f
);
3607 else if (!WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
3608 /* The column of `|' characters separating side-by-side windows
3609 occupies one column only. */
3612 /* On window-systems, areas to the left and right of the window
3613 are used to display bitmaps there. */
3614 if (FRAME_WINDOW_P (f
))
3615 width
-= FRAME_FLAGS_AREA_COLS (f
);
3621 /************************************************************************
3623 ***********************************************************************/
3625 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
3626 one screen-full, which is defined as the height of the window minus
3627 next_screen_context_lines. If WHOLE is zero, scroll up N lines
3628 instead. Negative values of N mean scroll down. NOERROR non-zero
3629 means don't signal an error if we try to move over BEGV or ZV,
3633 window_scroll (window
, n
, whole
, noerror
)
3639 /* If we must, use the pixel-based version which is much slower than
3640 the line-based one but can handle varying line heights. */
3641 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
3642 window_scroll_pixel_based (window
, n
, whole
, noerror
);
3644 window_scroll_line_based (window
, n
, whole
, noerror
);
3648 /* Implementation of window_scroll that works based on pixel line
3649 heights. See the comment of window_scroll for parameter
3653 window_scroll_pixel_based (window
, n
, whole
, noerror
)
3660 struct window
*w
= XWINDOW (window
);
3661 struct text_pos start
;
3663 int this_scroll_margin
;
3666 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
3668 /* If PT is not visible in WINDOW, move back one half of
3670 XSETFASTINT (tem
, PT
);
3671 tem
= Fpos_visible_in_window_p (tem
, window
);
3674 /* Move backward half the height of the window. Performance note:
3675 vmotion used here is about 10% faster, but would give wrong
3676 results for variable height lines. */
3677 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3678 it
.current_y
= it
.last_visible_y
;
3679 move_it_vertically (&it
, -it
.last_visible_y
/ 2);
3681 /* The function move_iterator_vertically may move over more than
3682 the specified y-distance. If it->w is small, e.g. a
3683 mini-buffer window, we may end up in front of the window's
3684 display area. This is the case when Start displaying at the
3685 start of the line containing PT in this case. */
3686 if (it
.current_y
<= 0)
3688 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3689 move_it_vertically (&it
, 0);
3693 start
= it
.current
.pos
;
3696 /* If scroll_preserve_screen_position is non-zero, we try to set
3697 point in the same window line as it is now, so get that line. */
3698 if (!NILP (Vscroll_preserve_screen_position
))
3700 start_display (&it
, w
, start
);
3701 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3702 preserve_y
= it
.current_y
;
3707 /* Move iterator it from start the specified distance forward or
3708 backward. The result is the new window start. */
3709 start_display (&it
, w
, start
);
3712 int screen_full
= (it
.last_visible_y
3713 - next_screen_context_lines
* CANON_Y_UNIT (it
.f
));
3714 int direction
= n
< 0 ? -1 : 1;
3715 move_it_vertically (&it
, direction
* screen_full
);
3718 move_it_by_lines (&it
, n
, 1);
3720 /* End if we end up at ZV or BEGV. */
3721 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
3722 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
3726 else if (IT_CHARPOS (it
) == ZV
)
3727 Fsignal (Qend_of_buffer
, Qnil
);
3729 Fsignal (Qbeginning_of_buffer
, Qnil
);
3732 /* Set the window start, and set up the window for redisplay. */
3733 set_marker_restricted (w
->start
, make_number (IT_CHARPOS (it
)), w
->buffer
);
3734 w
->start_at_line_beg
= Fbolp ();
3735 w
->update_mode_line
= Qt
;
3736 XSETFASTINT (w
->last_modified
, 0);
3737 XSETFASTINT (w
->last_overlay_modified
, 0);
3738 /* Set force_start so that redisplay_window will run the
3739 window-scroll-functions. */
3740 w
->force_start
= Qt
;
3742 it
.current_y
= it
.vpos
= 0;
3744 /* Preserve the screen position if we must. */
3745 if (preserve_y
>= 0)
3747 move_it_to (&it
, -1, -1, preserve_y
, -1, MOVE_TO_Y
);
3748 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3752 /* Move PT out of scroll margins. */
3753 this_scroll_margin
= max (0, scroll_margin
);
3754 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->height
) / 4);
3755 this_scroll_margin
*= CANON_Y_UNIT (it
.f
);
3759 /* We moved the window start towards ZV, so PT may be now
3760 in the scroll margin at the top. */
3761 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3762 while (it
.current_y
< this_scroll_margin
)
3763 move_it_by_lines (&it
, 1, 1);
3764 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3768 /* We moved the window start towards BEGV, so PT may be now
3769 in the scroll margin at the bottom. */
3770 move_it_to (&it
, PT
, -1,
3771 it
.last_visible_y
- this_scroll_margin
- 1, -1,
3772 MOVE_TO_POS
| MOVE_TO_Y
);
3774 /* Don't put point on a partially visible line at the end. */
3775 if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
3776 > it
.last_visible_y
)
3777 move_it_by_lines (&it
, -1, 0);
3779 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3785 /* Implementation of window_scroll that works based on screen lines.
3786 See the comment of window_scroll for parameter descriptions. */
3789 window_scroll_line_based (window
, n
, whole
, noerror
)
3795 register struct window
*w
= XWINDOW (window
);
3796 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
3797 register int pos
, pos_byte
;
3798 register int ht
= window_internal_height (w
);
3799 register Lisp_Object tem
;
3803 struct position posit
;
3806 startpos
= marker_position (w
->start
);
3808 posit
= *compute_motion (startpos
, 0, 0, 0,
3810 window_internal_width (w
), XINT (w
->hscroll
),
3812 original_vpos
= posit
.vpos
;
3814 XSETFASTINT (tem
, PT
);
3815 tem
= Fpos_visible_in_window_p (tem
, window
);
3819 Fvertical_motion (make_number (- (ht
/ 2)), window
);
3824 lose
= n
< 0 && PT
== BEGV
;
3825 Fvertical_motion (make_number (n
), window
);
3829 SET_PT_BOTH (opoint
, opoint_byte
);
3836 Fsignal (Qbeginning_of_buffer
, Qnil
);
3841 int this_scroll_margin
= scroll_margin
;
3843 /* Don't use a scroll margin that is negative or too large. */
3844 if (this_scroll_margin
< 0)
3845 this_scroll_margin
= 0;
3847 if (XINT (w
->height
) < 4 * scroll_margin
)
3848 this_scroll_margin
= XINT (w
->height
) / 4;
3850 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
3851 w
->start_at_line_beg
= bolp
;
3852 w
->update_mode_line
= Qt
;
3853 XSETFASTINT (w
->last_modified
, 0);
3854 XSETFASTINT (w
->last_overlay_modified
, 0);
3855 /* Set force_start so that redisplay_window will run
3856 the window-scroll-functions. */
3857 w
->force_start
= Qt
;
3859 if (whole
&& !NILP (Vscroll_preserve_screen_position
))
3861 SET_PT_BOTH (pos
, pos_byte
);
3862 Fvertical_motion (make_number (original_vpos
), window
);
3864 /* If we scrolled forward, put point enough lines down
3865 that it is outside the scroll margin. */
3870 if (this_scroll_margin
> 0)
3872 SET_PT_BOTH (pos
, pos_byte
);
3873 Fvertical_motion (make_number (this_scroll_margin
), window
);
3879 if (top_margin
<= opoint
)
3880 SET_PT_BOTH (opoint
, opoint_byte
);
3881 else if (!NILP (Vscroll_preserve_screen_position
))
3883 SET_PT_BOTH (pos
, pos_byte
);
3884 Fvertical_motion (make_number (original_vpos
), window
);
3887 SET_PT (top_margin
);
3893 /* If we scrolled backward, put point near the end of the window
3894 but not within the scroll margin. */
3895 SET_PT_BOTH (pos
, pos_byte
);
3896 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
3897 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
3900 bottom_margin
= PT
+ 1;
3902 if (bottom_margin
> opoint
)
3903 SET_PT_BOTH (opoint
, opoint_byte
);
3906 if (!NILP (Vscroll_preserve_screen_position
))
3908 SET_PT_BOTH (pos
, pos_byte
);
3909 Fvertical_motion (make_number (original_vpos
), window
);
3912 Fvertical_motion (make_number (-1), window
);
3921 Fsignal (Qend_of_buffer
, Qnil
);
3926 /* Scroll selected_window up or down. If N is nil, scroll a
3927 screen-full which is defined as the height of the window minus
3928 next_screen_context_lines. If N is the symbol `-', scroll.
3929 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
3930 up. This is the guts of Fscroll_up and Fscroll_down. */
3933 scroll_command (n
, direction
)
3937 register int defalt
;
3938 int count
= specpdl_ptr
- specpdl
;
3940 xassert (abs (direction
) == 1);
3942 /* If selected window's buffer isn't current, make it current for
3943 the moment. But don't screw up if window_scroll gets an error. */
3944 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
3946 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
3947 Fset_buffer (XWINDOW (selected_window
)->buffer
);
3949 /* Make redisplay consider other windows than just selected_window. */
3950 ++windows_or_buffers_changed
;
3953 defalt
= (window_internal_height (XWINDOW (selected_window
))
3954 - next_screen_context_lines
);
3955 defalt
= direction
* (defalt
< 1 ? 1 : defalt
);
3958 window_scroll (selected_window
, defalt
, 1, 0);
3959 else if (EQ (n
, Qminus
))
3960 window_scroll (selected_window
, - defalt
, 1, 0);
3963 n
= Fprefix_numeric_value (n
);
3964 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
3967 unbind_to (count
, Qnil
);
3970 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
3971 "Scroll text of current window upward ARG lines; or near full screen if no ARG.\n\
3972 A near full screen is `next-screen-context-lines' less than a full screen.\n\
3973 Negative ARG means scroll downward.\n\
3974 If ARG is the atom `-', scroll downward by nearly full screen.\n\
3975 When calling from a program, supply as argument a number, nil, or `-'.")
3979 scroll_command (arg
, 1);
3983 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
3984 "Scroll text of current window down ARG lines; or near full screen if no ARG.\n\
3985 A near full screen is `next-screen-context-lines' less than a full screen.\n\
3986 Negative ARG means scroll upward.\n\
3987 If ARG is the atom `-', scroll upward by nearly full screen.\n\
3988 When calling from a program, supply as argument a number, nil, or `-'.")
3992 scroll_command (arg
, -1);
3996 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
3997 "Return the other window for \"other window scroll\" commands.\n\
3998 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
3999 specifies the window.\n\
4000 If `other-window-scroll-buffer' is non-nil, a window\n\
4001 showing that buffer is used.")
4006 if (MINI_WINDOW_P (XWINDOW (selected_window
))
4007 && !NILP (Vminibuf_scroll_window
))
4008 window
= Vminibuf_scroll_window
;
4009 /* If buffer is specified, scroll that buffer. */
4010 else if (!NILP (Vother_window_scroll_buffer
))
4012 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
4014 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
4018 /* Nothing specified; look for a neighboring window on the same
4020 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
4022 if (EQ (window
, selected_window
))
4023 /* That didn't get us anywhere; look for a window on another
4026 window
= Fnext_window (window
, Qnil
, Qt
);
4027 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
4028 && ! EQ (window
, selected_window
));
4031 CHECK_LIVE_WINDOW (window
, 0);
4033 if (EQ (window
, selected_window
))
4034 error ("There is no other window");
4039 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
4040 "Scroll next window upward ARG lines; or near full screen if no ARG.\n\
4041 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4042 The next window is the one below the current one; or the one at the top\n\
4043 if the current one is at the bottom. Negative ARG means scroll downward.\n\
4044 If ARG is the atom `-', scroll downward by nearly full screen.\n\
4045 When calling from a program, supply as argument a number, nil, or `-'.\n\
4047 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4048 specifies the window to scroll.\n\
4049 If `other-window-scroll-buffer' is non-nil, scroll the window\n\
4050 showing that buffer, popping the buffer up if necessary.")
4052 register Lisp_Object arg
;
4054 register Lisp_Object window
;
4055 register int defalt
;
4056 register struct window
*w
;
4057 register int count
= specpdl_ptr
- specpdl
;
4059 window
= Fother_window_for_scrolling ();
4061 w
= XWINDOW (window
);
4062 defalt
= window_internal_height (w
) - next_screen_context_lines
;
4063 if (defalt
< 1) defalt
= 1;
4065 /* Don't screw up if window_scroll gets an error. */
4066 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4067 ++windows_or_buffers_changed
;
4069 Fset_buffer (w
->buffer
);
4070 SET_PT (marker_position (w
->pointm
));
4073 window_scroll (window
, defalt
, 1, 1);
4074 else if (EQ (arg
, Qminus
))
4075 window_scroll (window
, -defalt
, 1, 1);
4080 CHECK_NUMBER (arg
, 0);
4081 window_scroll (window
, XINT (arg
), 0, 1);
4084 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
4085 unbind_to (count
, Qnil
);
4090 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 1, "P",
4091 "Scroll selected window display ARG columns left.\n\
4092 Default for ARG is window width minus 2.")
4094 register Lisp_Object arg
;
4098 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4100 arg
= Fprefix_numeric_value (arg
);
4103 Fset_window_hscroll (selected_window
,
4104 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4108 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 1, "P",
4109 "Scroll selected window display ARG columns right.\n\
4110 Default for ARG is window width minus 2.")
4112 register Lisp_Object arg
;
4115 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4117 arg
= Fprefix_numeric_value (arg
);
4120 Fset_window_hscroll (selected_window
,
4121 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4125 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
4126 "Center point in window and redisplay frame. With ARG, put point on line ARG.\n\
4127 The desired position of point is always relative to the current window.\n\
4128 Just C-u as prefix means put point in the center of the window.\n\
4129 If ARG is omitted or nil, erases the entire frame and then\n\
4130 redraws with point in the center of the current window.")
4132 register Lisp_Object arg
;
4134 register struct window
*w
= XWINDOW (selected_window
);
4135 register int ht
= window_internal_height (w
);
4136 struct position pos
;
4137 struct buffer
*buf
= XBUFFER (w
->buffer
);
4138 struct buffer
*obuf
= current_buffer
;
4142 extern int frame_garbaged
;
4144 Fredraw_frame (w
->frame
);
4145 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
4146 XSETFASTINT (arg
, ht
/ 2);
4148 else if (CONSP (arg
)) /* Just C-u. */
4150 XSETFASTINT (arg
, ht
/ 2);
4154 arg
= Fprefix_numeric_value (arg
);
4155 CHECK_NUMBER (arg
, 0);
4159 XSETINT (arg
, XINT (arg
) + ht
);
4161 set_buffer_internal (buf
);
4162 pos
= *vmotion (PT
, - XINT (arg
), w
);
4164 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
4165 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
4166 || FETCH_BYTE (pos
.bytepos
- 1) == '\n')
4168 w
->force_start
= Qt
;
4169 set_buffer_internal (obuf
);
4174 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
4176 "Position point relative to window.\n\
4177 With no argument, position point at center of window.\n\
4178 An argument specifies vertical position within the window;\n\
4179 zero means top of window, negative means relative to bottom of window.")
4181 register Lisp_Object arg
;
4183 register struct window
*w
= XWINDOW (selected_window
);
4184 register int height
= window_internal_height (w
);
4189 XSETFASTINT (arg
, height
/ 2);
4192 arg
= Fprefix_numeric_value (arg
);
4194 XSETINT (arg
, XINT (arg
) + height
);
4197 start
= marker_position (w
->start
);
4198 XSETWINDOW (window
, w
);
4199 if (start
< BEGV
|| start
> ZV
)
4201 Fvertical_motion (make_number (- (height
/ 2)), window
);
4202 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
4203 w
->start_at_line_beg
= Fbolp ();
4204 w
->force_start
= Qt
;
4207 Fgoto_char (w
->start
);
4209 return Fvertical_motion (arg
, window
);
4214 /***********************************************************************
4215 Window Configuration
4216 ***********************************************************************/
4218 struct save_window_data
4220 EMACS_INT size_from_Lisp_Vector_struct
;
4221 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4222 Lisp_Object frame_width
, frame_height
, frame_menu_bar_lines
;
4223 Lisp_Object frame_tool_bar_lines
;
4224 Lisp_Object selected_frame
;
4225 Lisp_Object current_window
;
4226 Lisp_Object current_buffer
;
4227 Lisp_Object minibuf_scroll_window
;
4228 Lisp_Object root_window
;
4229 Lisp_Object focus_frame
;
4230 /* Record the values of window-min-width and window-min-height
4231 so that window sizes remain consistent with them. */
4232 Lisp_Object min_width
, min_height
;
4233 /* A vector, each of whose elements is a struct saved_window
4235 Lisp_Object saved_windows
;
4238 /* This is saved as a Lisp_Vector */
4241 /* these first two must agree with struct Lisp_Vector in lisp.h */
4242 EMACS_INT size_from_Lisp_Vector_struct
;
4243 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4246 Lisp_Object buffer
, start
, pointm
, mark
;
4247 Lisp_Object left
, top
, width
, height
, hscroll
;
4248 Lisp_Object parent
, prev
;
4249 Lisp_Object start_at_line_beg
;
4250 Lisp_Object display_table
;
4252 #define SAVED_WINDOW_VECTOR_SIZE 14 /* Arg to Fmake_vector */
4254 #define SAVED_WINDOW_N(swv,n) \
4255 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
4257 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
4258 "Return t if OBJECT is a window-configuration object.")
4262 if (WINDOW_CONFIGURATIONP (object
))
4267 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
4268 "Return the frame that CONFIG, a window-configuration object, is about.")
4272 register struct save_window_data
*data
;
4273 struct Lisp_Vector
*saved_windows
;
4275 if (! WINDOW_CONFIGURATIONP (config
))
4276 wrong_type_argument (Qwindow_configuration_p
, config
);
4278 data
= (struct save_window_data
*) XVECTOR (config
);
4279 saved_windows
= XVECTOR (data
->saved_windows
);
4280 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4283 DEFUN ("set-window-configuration", Fset_window_configuration
,
4284 Sset_window_configuration
, 1, 1, 0,
4285 "Set the configuration of windows and buffers as specified by CONFIGURATION.\n\
4286 CONFIGURATION must be a value previously returned\n\
4287 by `current-window-configuration' (which see).\n\
4288 If CONFIGURATION was made from a frame that is now deleted,\n\
4289 only frame-independent values can be restored. In this case,\n\
4290 the return value is nil. Otherwise the value is t.")
4292 Lisp_Object configuration
;
4294 register struct save_window_data
*data
;
4295 struct Lisp_Vector
*saved_windows
;
4296 Lisp_Object new_current_buffer
;
4301 while (!WINDOW_CONFIGURATIONP (configuration
))
4302 wrong_type_argument (Qwindow_configuration_p
, configuration
);
4304 data
= (struct save_window_data
*) XVECTOR (configuration
);
4305 saved_windows
= XVECTOR (data
->saved_windows
);
4307 new_current_buffer
= data
->current_buffer
;
4308 if (NILP (XBUFFER (new_current_buffer
)->name
))
4309 new_current_buffer
= Qnil
;
4312 if (XBUFFER (new_current_buffer
) == current_buffer
)
4317 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4320 /* If f is a dead frame, don't bother rebuilding its window tree.
4321 However, there is other stuff we should still try to do below. */
4322 if (FRAME_LIVE_P (f
))
4324 register struct window
*w
;
4325 register struct saved_window
*p
;
4326 struct window
*root_window
;
4327 struct window
**leaf_windows
;
4331 /* If the frame has been resized since this window configuration was
4332 made, we change the frame to the size specified in the
4333 configuration, restore the configuration, and then resize it
4334 back. We keep track of the prevailing height in these variables. */
4335 int previous_frame_height
= FRAME_HEIGHT (f
);
4336 int previous_frame_width
= FRAME_WIDTH (f
);
4337 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
4338 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
4340 /* The mouse highlighting code could get screwed up
4341 if it runs during this. */
4344 if (XFASTINT (data
->frame_height
) != previous_frame_height
4345 || XFASTINT (data
->frame_width
) != previous_frame_width
)
4346 change_frame_size (f
, XFASTINT (data
->frame_height
),
4347 XFASTINT (data
->frame_width
), 0, 0, 0);
4348 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4349 if (XFASTINT (data
->frame_menu_bar_lines
)
4350 != previous_frame_menu_bar_lines
)
4351 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, make_number (0));
4352 #ifdef HAVE_WINDOW_SYSTEM
4353 if (XFASTINT (data
->frame_tool_bar_lines
)
4354 != previous_frame_tool_bar_lines
)
4355 x_set_tool_bar_lines (f
, data
->frame_tool_bar_lines
, make_number (0));
4359 if (! NILP (XWINDOW (selected_window
)->buffer
))
4361 w
= XWINDOW (selected_window
);
4362 set_marker_both (w
->pointm
,
4364 BUF_PT (XBUFFER (w
->buffer
)),
4365 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4368 windows_or_buffers_changed
++;
4369 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4371 /* Problem: Freeing all matrices and later allocating them again
4372 is a serious redisplay flickering problem. What we would
4373 really like to do is to free only those matrices not reused
4375 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4377 = (struct window
**) alloca (count_windows (root_window
)
4378 * sizeof (struct window
*));
4379 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
4381 /* Temporarily avoid any problems with windows that are smaller
4382 than they are supposed to be. */
4383 window_min_height
= 1;
4384 window_min_width
= 1;
4387 Mark all windows now on frame as "deleted".
4388 Restoring the new configuration "undeletes" any that are in it.
4390 Save their current buffers in their height fields, since we may
4391 need it later, if a buffer saved in the configuration is now
4393 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4395 for (k
= 0; k
< saved_windows
->size
; k
++)
4397 p
= SAVED_WINDOW_N (saved_windows
, k
);
4398 w
= XWINDOW (p
->window
);
4401 if (!NILP (p
->parent
))
4402 w
->parent
= SAVED_WINDOW_N (saved_windows
,
4403 XFASTINT (p
->parent
))->window
;
4407 if (!NILP (p
->prev
))
4409 w
->prev
= SAVED_WINDOW_N (saved_windows
,
4410 XFASTINT (p
->prev
))->window
;
4411 XWINDOW (w
->prev
)->next
= p
->window
;
4416 if (!NILP (w
->parent
))
4418 if (EQ (p
->width
, XWINDOW (w
->parent
)->width
))
4420 XWINDOW (w
->parent
)->vchild
= p
->window
;
4421 XWINDOW (w
->parent
)->hchild
= Qnil
;
4425 XWINDOW (w
->parent
)->hchild
= p
->window
;
4426 XWINDOW (w
->parent
)->vchild
= Qnil
;
4431 /* If we squirreled away the buffer in the window's height,
4433 if (BUFFERP (w
->height
))
4434 w
->buffer
= w
->height
;
4437 w
->width
= p
->width
;
4438 w
->height
= p
->height
;
4439 w
->hscroll
= p
->hscroll
;
4440 w
->display_table
= p
->display_table
;
4441 XSETFASTINT (w
->last_modified
, 0);
4442 XSETFASTINT (w
->last_overlay_modified
, 0);
4444 /* Reinstall the saved buffer and pointers into it. */
4445 if (NILP (p
->buffer
))
4446 w
->buffer
= p
->buffer
;
4449 if (!NILP (XBUFFER (p
->buffer
)->name
))
4450 /* If saved buffer is alive, install it. */
4452 w
->buffer
= p
->buffer
;
4453 w
->start_at_line_beg
= p
->start_at_line_beg
;
4454 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
4455 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
4456 Fset_marker (XBUFFER (w
->buffer
)->mark
,
4457 p
->mark
, w
->buffer
);
4459 /* As documented in Fcurrent_window_configuration, don't
4460 save the location of point in the buffer which was current
4461 when the window configuration was recorded. */
4462 if (!EQ (p
->buffer
, new_current_buffer
)
4463 && XBUFFER (p
->buffer
) == current_buffer
)
4464 Fgoto_char (w
->pointm
);
4466 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
4467 /* Else unless window has a live buffer, get one. */
4469 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
4470 /* This will set the markers to beginning of visible
4472 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
4473 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
4474 w
->start_at_line_beg
= Qt
;
4477 /* Keeping window's old buffer; make sure the markers
4480 /* Set window markers at start of visible range. */
4481 if (XMARKER (w
->start
)->buffer
== 0)
4482 set_marker_restricted (w
->start
, make_number (0),
4484 if (XMARKER (w
->pointm
)->buffer
== 0)
4485 set_marker_restricted_both (w
->pointm
, w
->buffer
,
4486 BUF_PT (XBUFFER (w
->buffer
)),
4487 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4488 w
->start_at_line_beg
= Qt
;
4493 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
4494 Fselect_window (data
->current_window
);
4495 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
4498 if (NILP (data
->focus_frame
)
4499 || (FRAMEP (data
->focus_frame
)
4500 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
4501 Fredirect_frame_focus (frame
, data
->focus_frame
);
4503 #if 0 /* I don't understand why this is needed, and it causes problems
4504 when the frame's old selected window has been deleted. */
4505 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
4506 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
4510 /* Set the screen height to the value it had before this function. */
4511 if (previous_frame_height
!= FRAME_HEIGHT (f
)
4512 || previous_frame_width
!= FRAME_WIDTH (f
))
4513 change_frame_size (f
, previous_frame_height
, previous_frame_width
,
4515 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4516 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
4517 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
4519 #ifdef HAVE_WINDOW_SYSTEM
4520 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
4521 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
4526 /* Now, free glyph matrices in windows that were not reused. */
4527 for (i
= 0; i
< n_leaf_windows
; ++i
)
4528 if (NILP (leaf_windows
[i
]->buffer
))
4530 /* Assert it's not reused as a combination. */
4531 xassert (NILP (leaf_windows
[i
]->hchild
)
4532 && NILP (leaf_windows
[i
]->vchild
));
4533 free_window_matrices (leaf_windows
[i
]);
4534 SET_FRAME_GARBAGED (f
);
4541 /* Fselect_window will have made f the selected frame, so we
4542 reselect the proper frame here. Fhandle_switch_frame will change the
4543 selected window too, but that doesn't make the call to
4544 Fselect_window above totally superfluous; it still sets f's
4546 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
4547 do_switch_frame (data
->selected_frame
, Qnil
, 0);
4549 if (! NILP (Vwindow_configuration_change_hook
)
4550 && ! NILP (Vrun_hooks
))
4551 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
4554 if (!NILP (new_current_buffer
))
4556 Fset_buffer (new_current_buffer
);
4558 /* If the buffer that is current now is the same
4559 that was current before setting the window configuration,
4560 don't alter its PT. */
4565 /* Restore the minimum heights recorded in the configuration. */
4566 window_min_height
= XINT (data
->min_height
);
4567 window_min_width
= XINT (data
->min_width
);
4569 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
4571 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
4574 /* Mark all windows now on frame as deleted
4575 by setting their buffers to nil. */
4578 delete_all_subwindows (w
)
4579 register struct window
*w
;
4581 if (!NILP (w
->next
))
4582 delete_all_subwindows (XWINDOW (w
->next
));
4583 if (!NILP (w
->vchild
))
4584 delete_all_subwindows (XWINDOW (w
->vchild
));
4585 if (!NILP (w
->hchild
))
4586 delete_all_subwindows (XWINDOW (w
->hchild
));
4588 w
->height
= w
->buffer
; /* See Fset_window_configuration for excuse. */
4590 if (!NILP (w
->buffer
))
4593 /* We set all three of these fields to nil, to make sure that we can
4594 distinguish this dead window from any live window. Live leaf
4595 windows will have buffer set, and combination windows will have
4596 vchild or hchild set. */
4603 count_windows (window
)
4604 register struct window
*window
;
4606 register int count
= 1;
4607 if (!NILP (window
->next
))
4608 count
+= count_windows (XWINDOW (window
->next
));
4609 if (!NILP (window
->vchild
))
4610 count
+= count_windows (XWINDOW (window
->vchild
));
4611 if (!NILP (window
->hchild
))
4612 count
+= count_windows (XWINDOW (window
->hchild
));
4617 /* Fill vector FLAT with leaf windows under W, starting at index I.
4618 Value is last index + 1. */
4621 get_leaf_windows (w
, flat
, i
)
4623 struct window
**flat
;
4628 if (!NILP (w
->hchild
))
4629 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
4630 else if (!NILP (w
->vchild
))
4631 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
4635 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4642 /* Return a pointer to the glyph W's physical cursor is on. Value is
4643 null if W's current matrix is invalid, so that no meaningfull glyph
4647 get_phys_cursor_glyph (w
)
4650 struct glyph_row
*row
;
4651 struct glyph
*glyph
;
4653 if (w
->phys_cursor
.vpos
>= 0
4654 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
4655 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
4657 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
4658 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
4667 save_window_save (window
, vector
, i
)
4669 struct Lisp_Vector
*vector
;
4672 register struct saved_window
*p
;
4673 register struct window
*w
;
4674 register Lisp_Object tem
;
4676 for (;!NILP (window
); window
= w
->next
)
4678 p
= SAVED_WINDOW_N (vector
, i
);
4679 w
= XWINDOW (window
);
4681 XSETFASTINT (w
->temslot
, i
++);
4683 p
->buffer
= w
->buffer
;
4686 p
->width
= w
->width
;
4687 p
->height
= w
->height
;
4688 p
->hscroll
= w
->hscroll
;
4689 p
->display_table
= w
->display_table
;
4690 if (!NILP (w
->buffer
))
4692 /* Save w's value of point in the window configuration.
4693 If w is the selected window, then get the value of point
4694 from the buffer; pointm is garbage in the selected window. */
4695 if (EQ (window
, selected_window
))
4697 p
->pointm
= Fmake_marker ();
4698 set_marker_both (p
->pointm
, w
->buffer
,
4699 BUF_PT (XBUFFER (w
->buffer
)),
4700 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4703 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
4705 p
->start
= Fcopy_marker (w
->start
, Qnil
);
4706 p
->start_at_line_beg
= w
->start_at_line_beg
;
4708 tem
= XBUFFER (w
->buffer
)->mark
;
4709 p
->mark
= Fcopy_marker (tem
, Qnil
);
4716 p
->start_at_line_beg
= Qnil
;
4719 if (NILP (w
->parent
))
4722 p
->parent
= XWINDOW (w
->parent
)->temslot
;
4727 p
->prev
= XWINDOW (w
->prev
)->temslot
;
4729 if (!NILP (w
->vchild
))
4730 i
= save_window_save (w
->vchild
, vector
, i
);
4731 if (!NILP (w
->hchild
))
4732 i
= save_window_save (w
->hchild
, vector
, i
);
4738 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
4739 Scurrent_window_configuration
, 0, 1, 0,
4740 "Return an object representing the current window configuration of FRAME.\n\
4741 If FRAME is nil or omitted, use the selected frame.\n\
4742 This describes the number of windows, their sizes and current buffers,\n\
4743 and for each displayed buffer, where display starts, and the positions of\n\
4744 point and mark. An exception is made for point in the current buffer:\n\
4745 its value is -not- saved.\n\
4746 This also records the currently selected frame, and FRAME's focus\n\
4747 redirection (see `redirect-frame-focus').")
4751 register Lisp_Object tem
;
4752 register int n_windows
;
4753 register struct save_window_data
*data
;
4754 register struct Lisp_Vector
*vec
;
4759 frame
= selected_frame
;
4760 CHECK_LIVE_FRAME (frame
, 0);
4763 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4764 vec
= allocate_vectorlike (VECSIZE (struct save_window_data
));
4765 for (i
= 0; i
< VECSIZE (struct save_window_data
); i
++)
4766 vec
->contents
[i
] = Qnil
;
4767 vec
->size
= VECSIZE (struct save_window_data
);
4768 data
= (struct save_window_data
*)vec
;
4770 XSETFASTINT (data
->frame_width
, FRAME_WIDTH (f
));
4771 XSETFASTINT (data
->frame_height
, FRAME_HEIGHT (f
));
4772 XSETFASTINT (data
->frame_menu_bar_lines
, FRAME_MENU_BAR_LINES (f
));
4773 XSETFASTINT (data
->frame_tool_bar_lines
, FRAME_TOOL_BAR_LINES (f
));
4774 data
->selected_frame
= selected_frame
;
4775 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
4776 XSETBUFFER (data
->current_buffer
, current_buffer
);
4777 data
->minibuf_scroll_window
= Vminibuf_scroll_window
;
4778 data
->root_window
= FRAME_ROOT_WINDOW (f
);
4779 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
4780 XSETINT (data
->min_height
, window_min_height
);
4781 XSETINT (data
->min_width
, window_min_width
);
4782 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
4783 data
->saved_windows
= tem
;
4784 for (i
= 0; i
< n_windows
; i
++)
4785 XVECTOR (tem
)->contents
[i
]
4786 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
4787 save_window_save (FRAME_ROOT_WINDOW (f
),
4789 XSETWINDOW_CONFIGURATION (tem
, data
);
4793 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
4795 "Execute body, preserving window sizes and contents.\n\
4796 Restore which buffer appears in which window, where display starts,\n\
4797 and the value of point and mark for each window.\n\
4798 Also restore which buffer is current.\n\
4799 But do not preserve point in the current buffer.\n\
4800 Does not restore the value of point in current buffer.")
4804 register Lisp_Object val
;
4805 register int count
= specpdl_ptr
- specpdl
;
4807 record_unwind_protect (Fset_window_configuration
,
4808 Fcurrent_window_configuration (Qnil
));
4809 val
= Fprogn (args
);
4810 return unbind_to (count
, val
);
4814 /***********************************************************************
4816 ***********************************************************************/
4818 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
4820 "Set width of marginal areas of window WINDOW.\n\
4821 If window is nil or omitted, set margins of the currently selected window.\n\
4822 First parameter LEFT-WIDTH specifies the number of character\n\
4823 cells to reserve for the left marginal area. Second parameter\n\
4824 RIGHT-WIDTH does the same for the right marginal area.\n\
4825 A nil width parameter means no margin.")
4826 (window
, left
, right
)
4827 Lisp_Object window
, left
, right
;
4829 struct window
*w
= decode_window (window
);
4832 CHECK_NUMBER_OR_FLOAT (left
, 1);
4834 CHECK_NUMBER_OR_FLOAT (right
, 2);
4836 /* Check widths < 0 and translate a zero width to nil.
4837 Margins that are too wide have to be checked elsewhere. */
4838 if ((INTEGERP (left
) && XINT (left
) < 0)
4839 || (FLOATP (left
) && XFLOAT_DATA (left
) <= 0))
4840 XSETFASTINT (left
, 0);
4841 if (INTEGERP (left
) && XFASTINT (left
) == 0)
4844 if ((INTEGERP (right
) && XINT (right
) < 0)
4845 || (FLOATP (right
) && XFLOAT_DATA (right
) <= 0))
4846 XSETFASTINT (right
, 0);
4847 if (INTEGERP (right
) && XFASTINT (right
) == 0)
4850 w
->left_margin_width
= left
;
4851 w
->right_margin_width
= right
;
4853 ++windows_or_buffers_changed
;
4854 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
4859 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
4861 "Get width of marginal areas of window WINDOW.\n\
4862 If WINDOW is omitted or nil, use the currently selected window.\n\
4863 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).\n\
4864 If a marginal area does not exist, its width will be returned\n\
4869 struct window
*w
= decode_window (window
);
4870 return Fcons (w
->left_margin_width
, w
->right_margin_width
);
4875 /***********************************************************************
4877 ***********************************************************************/
4879 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 1, 0,
4880 "Return the amount by which WINDOW is scrolled vertically.\n\
4881 Use the selected window if WINDOW is nil or omitted.\n\
4882 Value is a multiple of the canonical character height of WINDOW.")
4891 window
= selected_window
;
4893 CHECK_WINDOW (window
, 0);
4894 w
= XWINDOW (window
);
4895 f
= XFRAME (w
->frame
);
4897 if (FRAME_WINDOW_P (f
))
4898 result
= CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
);
4900 result
= make_number (0);
4905 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
4907 "Set amount by which WINDOW should be scrolled vertically to VSCROLL.\n\
4908 WINDOW nil or omitted means use the selected window. VSCROLL is a\n\
4909 non-negative multiple of the canonical character height of WINDOW.")
4911 Lisp_Object window
, vscroll
;
4917 window
= selected_window
;
4919 CHECK_WINDOW (window
, 0);
4920 CHECK_NUMBER_OR_FLOAT (vscroll
, 1);
4922 w
= XWINDOW (window
);
4923 f
= XFRAME (w
->frame
);
4925 if (FRAME_WINDOW_P (f
))
4927 int old_dy
= w
->vscroll
;
4929 w
->vscroll
= - CANON_Y_UNIT (f
) * XFLOATINT (vscroll
);
4930 w
->vscroll
= min (w
->vscroll
, 0);
4932 /* Adjust glyph matrix of the frame if the virtual display
4933 area becomes larger than before. */
4934 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
4937 /* Prevent redisplay shortcuts. */
4938 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
4941 return Fwindow_vscroll (window
);
4945 /* Call FN for all leaf windows on frame F. FN is called with the
4946 first argument being a pointer to the leaf window, and with
4947 additional arguments A1..A4. */
4950 foreach_window (f
, fn
, a1
, a2
, a3
, a4
)
4955 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, a1
, a2
, a3
, a4
);
4959 /* Helper function for foreach_window. Call FN for all leaf windows
4960 reachable from W. FN is called with the first argument being a
4961 pointer to the leaf window, and with additional arguments A1..A4. */
4964 foreach_window_1 (w
, fn
, a1
, a2
, a3
, a4
)
4971 if (!NILP (w
->hchild
))
4972 foreach_window_1 (XWINDOW (w
->hchild
), fn
, a1
, a2
, a3
, a4
);
4973 else if (!NILP (w
->vchild
))
4974 foreach_window_1 (XWINDOW (w
->vchild
), fn
, a1
, a2
, a3
, a4
);
4976 fn (w
, a1
, a2
, a3
, a4
);
4978 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4983 /* Freeze or unfreeze the window start of W if unless it is a
4984 mini-window or the selected window. FREEZE_P non-zero means freeze
4985 the window start. */
4988 freeze_window_start (w
, freeze_p
)
4992 if (w
== XWINDOW (selected_window
)
4993 || MINI_WINDOW_P (w
)
4994 || (MINI_WINDOW_P (XWINDOW (selected_window
))
4995 && w
== XWINDOW (Vminibuf_scroll_window
)))
4998 w
->frozen_window_start_p
= freeze_p
;
5002 /* Freeze or unfreeze the window starts of all leaf windows on frame
5003 F, except the selected window and a mini-window. FREEZE_P non-zero
5004 means freeze the window start. */
5007 freeze_window_starts (f
, freeze_p
)
5011 foreach_window (f
, freeze_window_start
, freeze_p
);
5015 /***********************************************************************
5017 ***********************************************************************/
5019 /* Return 1 if window configurations C1 and C2
5020 describe the same state of affairs. This is used by Fequal. */
5023 compare_window_configurations (c1
, c2
, ignore_positions
)
5025 int ignore_positions
;
5027 register struct save_window_data
*d1
, *d2
;
5028 struct Lisp_Vector
*sw1
, *sw2
;
5031 d1
= (struct save_window_data
*) XVECTOR (c1
);
5032 d2
= (struct save_window_data
*) XVECTOR (c2
);
5033 sw1
= XVECTOR (d1
->saved_windows
);
5034 sw2
= XVECTOR (d2
->saved_windows
);
5036 if (! EQ (d1
->frame_width
, d2
->frame_width
))
5038 if (! EQ (d1
->frame_height
, d2
->frame_height
))
5040 if (! EQ (d1
->frame_menu_bar_lines
, d2
->frame_menu_bar_lines
))
5042 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
5044 /* Don't compare the current_window field directly.
5045 Instead see w1_is_current and w2_is_current, below. */
5046 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
5048 if (! ignore_positions
)
5049 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
5051 /* Don't compare the root_window field.
5052 We don't require the two configurations
5053 to use the same window object,
5054 and the two root windows must be equivalent
5055 if everything else compares equal. */
5056 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
5058 if (! EQ (d1
->min_width
, d2
->min_width
))
5060 if (! EQ (d1
->min_height
, d2
->min_height
))
5063 /* Verify that the two confis have the same number of windows. */
5064 if (sw1
->size
!= sw2
->size
)
5067 for (i
= 0; i
< sw1
->size
; i
++)
5069 struct saved_window
*p1
, *p2
;
5070 int w1_is_current
, w2_is_current
;
5072 p1
= SAVED_WINDOW_N (sw1
, i
);
5073 p2
= SAVED_WINDOW_N (sw2
, i
);
5075 /* Verify that the current windows in the two
5076 configurations correspond to each other. */
5077 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
5078 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
5080 if (w1_is_current
!= w2_is_current
)
5083 /* Verify that the corresponding windows do match. */
5084 if (! EQ (p1
->buffer
, p2
->buffer
))
5086 if (! EQ (p1
->left
, p2
->left
))
5088 if (! EQ (p1
->top
, p2
->top
))
5090 if (! EQ (p1
->width
, p2
->width
))
5092 if (! EQ (p1
->height
, p2
->height
))
5094 if (! EQ (p1
->display_table
, p2
->display_table
))
5096 if (! EQ (p1
->parent
, p2
->parent
))
5098 if (! EQ (p1
->prev
, p2
->prev
))
5100 if (! ignore_positions
)
5102 if (! EQ (p1
->hscroll
, p2
->hscroll
))
5104 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
5106 if (NILP (Fequal (p1
->start
, p2
->start
)))
5108 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
5110 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
5118 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
5119 Scompare_window_configurations
, 2, 2, 0,
5120 "Compare two window configurations as regards the structure of windows.\n\
5121 This function ignores details such as the values of point and mark\n\
5122 and scrolling positions.")
5126 if (compare_window_configurations (x
, y
, 1))
5134 struct frame
*f
= make_terminal_frame ();
5135 XSETFRAME (selected_frame
, f
);
5136 Vterminal_frame
= selected_frame
;
5137 minibuf_window
= f
->minibuffer_window
;
5138 selected_window
= f
->selected_window
;
5139 last_nonminibuf_frame
= f
;
5141 window_initialized
= 1;
5147 Qleft_bitmap_area
= intern ("left-bitmap-area");
5148 staticpro (&Qleft_bitmap_area
);
5149 Qright_bitmap_area
= intern ("right-bitmap-area");
5150 staticpro (&Qright_bitmap_area
);
5152 Qwindow_size_fixed
= intern ("window-size-fixed");
5153 staticpro (&Qwindow_size_fixed
);
5155 staticpro (&Qwindow_configuration_change_hook
);
5156 Qwindow_configuration_change_hook
5157 = intern ("window-configuration-change-hook");
5159 Qwindowp
= intern ("windowp");
5160 staticpro (&Qwindowp
);
5162 Qwindow_configuration_p
= intern ("window-configuration-p");
5163 staticpro (&Qwindow_configuration_p
);
5165 Qwindow_live_p
= intern ("window-live-p");
5166 staticpro (&Qwindow_live_p
);
5168 Qtemp_buffer_show_hook
= intern ("temp-buffer-show-hook");
5169 staticpro (&Qtemp_buffer_show_hook
);
5171 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
5172 "Non-nil means call as function to display a help buffer.\n\
5173 The function is called with one argument, the buffer to be displayed.\n\
5174 Used by `with-output-to-temp-buffer'.\n\
5175 If this function is used, then it must do the entire job of showing\n\
5176 the buffer; `temp-buffer-show-hook' is not run unless this function runs it.");
5177 Vtemp_buffer_show_function
= Qnil
;
5179 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
5180 "If non-nil, function to call to handle `display-buffer'.\n\
5181 It will receive two args, the buffer and a flag which if non-nil means\n\
5182 that the currently selected window is not acceptable.\n\
5183 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
5184 work using this function.");
5185 Vdisplay_buffer_function
= Qnil
;
5187 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
5188 "Non-nil means it is the window that C-M-v in minibuffer should scroll.");
5189 Vminibuf_scroll_window
= Qnil
;
5191 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
5192 "If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.");
5193 Vother_window_scroll_buffer
= Qnil
;
5195 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
5196 "*Non-nil means `display-buffer' should make a separate frame.");
5199 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
5200 "Function to call to handle automatic new frame creation.\n\
5201 It is called with no arguments and should return a newly created frame.\n\
5203 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'\n\
5204 where `pop-up-frame-alist' would hold the default frame parameters.");
5205 Vpop_up_frame_function
= Qnil
;
5207 DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names
,
5208 "*List of buffer names that should have their own special frames.\n\
5209 Displaying a buffer whose name is in this list makes a special frame for it\n\
5210 using `special-display-function'. See also `special-display-regexps'.\n\
5212 An element of the list can be a list instead of just a string.\n\
5213 There are two ways to use a list as an element:\n\
5214 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)\n\
5215 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5216 In the latter case, FUNCTION is called with BUFFER as the first argument,\n\
5217 followed by OTHER-ARGS--it can display BUFFER in any way it likes.\n\
5218 All this is done by the function found in `special-display-function'.\n\
5220 If this variable appears \"not to work\", because you add a name to it\n\
5221 but that buffer still appears in the selected window, look at the\n\
5222 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5223 Those variables take precedence over this one.");
5224 Vspecial_display_buffer_names
= Qnil
;
5226 DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps
,
5227 "*List of regexps saying which buffers should have their own special frames.\n\
5228 If a buffer name matches one of these regexps, it gets its own frame.\n\
5229 Displaying a buffer whose name is in this list makes a special frame for it\n\
5230 using `special-display-function'.\n\
5232 An element of the list can be a list instead of just a string.\n\
5233 There are two ways to use a list as an element:\n\
5234 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)\n\
5235 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5236 In the latter case, FUNCTION is called with the buffer as first argument,\n\
5237 followed by OTHER-ARGS--it can display the buffer in any way it likes.\n\
5238 All this is done by the function found in `special-display-function'.\n\
5240 If this variable appears \"not to work\", because you add a regexp to it\n\
5241 but the matching buffers still appear in the selected window, look at the\n\
5242 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5243 Those variables take precedence over this one.");
5244 Vspecial_display_regexps
= Qnil
;
5246 DEFVAR_LISP ("special-display-function", &Vspecial_display_function
,
5247 "Function to call to make a new frame for a special buffer.\n\
5248 It is called with two arguments, the buffer and optional buffer specific\n\
5249 data, and should return a window displaying that buffer.\n\
5250 The default value makes a separate frame for the buffer,\n\
5251 using `special-display-frame-alist' to specify the frame parameters.\n\
5253 A buffer is special if its is listed in `special-display-buffer-names'\n\
5254 or matches a regexp in `special-display-regexps'.");
5255 Vspecial_display_function
= Qnil
;
5257 DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names
,
5258 "*List of buffer names that should appear in the selected window.\n\
5259 Displaying one of these buffers using `display-buffer' or `pop-to-buffer'\n\
5260 switches to it in the selected window, rather than making it appear\n\
5261 in some other window.\n\
5263 An element of the list can be a cons cell instead of just a string.\n\
5264 Then the car must be a string, which specifies the buffer name.\n\
5265 This is for compatibility with `special-display-buffer-names';\n\
5266 the cdr of the cons cell is ignored.\n\
5268 See also `same-window-regexps'.");
5269 Vsame_window_buffer_names
= Qnil
;
5271 DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps
,
5272 "*List of regexps saying which buffers should appear in the selected window.\n\
5273 If a buffer name matches one of these regexps, then displaying it\n\
5274 using `display-buffer' or `pop-to-buffer' switches to it\n\
5275 in the selected window, rather than making it appear in some other window.\n\
5277 An element of the list can be a cons cell instead of just a string.\n\
5278 Then the car must be a string, which specifies the buffer name.\n\
5279 This is for compatibility with `special-display-buffer-names';\n\
5280 the cdr of the cons cell is ignored.\n\
5282 See also `same-window-buffer-names'.");
5283 Vsame_window_regexps
= Qnil
;
5285 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
5286 "*Non-nil means display-buffer should make new windows.");
5289 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
5290 "*Number of lines of continuity when scrolling by screenfuls.");
5291 next_screen_context_lines
= 2;
5293 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
5294 "*display-buffer would prefer to split the largest window if this large.\n\
5295 If there is only one window, it is split regardless of this value.");
5296 split_height_threshold
= 500;
5298 DEFVAR_INT ("window-min-height", &window_min_height
,
5299 "*Delete any window less than this tall (including its mode line).");
5300 window_min_height
= 4;
5302 DEFVAR_INT ("window-min-width", &window_min_width
,
5303 "*Delete any window less than this wide.");
5304 window_min_width
= 10;
5306 DEFVAR_LISP ("scroll-preserve-screen-position",
5307 &Vscroll_preserve_screen_position
,
5308 "*Nonzero means scroll commands move point to keep its screen line unchanged.");
5309 Vscroll_preserve_screen_position
= Qnil
;
5311 DEFVAR_LISP ("window-configuration-change-hook",
5312 &Vwindow_configuration_change_hook
,
5313 "Functions to call when window configuration changes.\n\
5314 The selected frame is the one whose configuration has changed.");
5315 Vwindow_configuration_change_hook
= Qnil
;
5317 defsubr (&Sselected_window
);
5318 defsubr (&Sminibuffer_window
);
5319 defsubr (&Swindow_minibuffer_p
);
5320 defsubr (&Swindowp
);
5321 defsubr (&Swindow_live_p
);
5322 defsubr (&Spos_visible_in_window_p
);
5323 defsubr (&Swindow_buffer
);
5324 defsubr (&Swindow_height
);
5325 defsubr (&Swindow_width
);
5326 defsubr (&Swindow_hscroll
);
5327 defsubr (&Sset_window_hscroll
);
5328 defsubr (&Swindow_redisplay_end_trigger
);
5329 defsubr (&Sset_window_redisplay_end_trigger
);
5330 defsubr (&Swindow_edges
);
5331 defsubr (&Scoordinates_in_window_p
);
5332 defsubr (&Swindow_at
);
5333 defsubr (&Swindow_point
);
5334 defsubr (&Swindow_start
);
5335 defsubr (&Swindow_end
);
5336 defsubr (&Sset_window_point
);
5337 defsubr (&Sset_window_start
);
5338 defsubr (&Swindow_dedicated_p
);
5339 defsubr (&Sset_window_dedicated_p
);
5340 defsubr (&Swindow_display_table
);
5341 defsubr (&Sset_window_display_table
);
5342 defsubr (&Snext_window
);
5343 defsubr (&Sprevious_window
);
5344 defsubr (&Sother_window
);
5345 defsubr (&Sget_lru_window
);
5346 defsubr (&Sget_largest_window
);
5347 defsubr (&Sget_buffer_window
);
5348 defsubr (&Sdelete_other_windows
);
5349 defsubr (&Sdelete_windows_on
);
5350 defsubr (&Sreplace_buffer_in_windows
);
5351 defsubr (&Sdelete_window
);
5352 defsubr (&Sset_window_buffer
);
5353 defsubr (&Sselect_window
);
5354 defsubr (&Sspecial_display_p
);
5355 defsubr (&Ssame_window_p
);
5356 defsubr (&Sdisplay_buffer
);
5357 defsubr (&Ssplit_window
);
5358 defsubr (&Senlarge_window
);
5359 defsubr (&Sshrink_window
);
5360 defsubr (&Sscroll_up
);
5361 defsubr (&Sscroll_down
);
5362 defsubr (&Sscroll_left
);
5363 defsubr (&Sscroll_right
);
5364 defsubr (&Sother_window_for_scrolling
);
5365 defsubr (&Sscroll_other_window
);
5366 defsubr (&Srecenter
);
5367 defsubr (&Smove_to_window_line
);
5368 defsubr (&Swindow_configuration_p
);
5369 defsubr (&Swindow_configuration_frame
);
5370 defsubr (&Sset_window_configuration
);
5371 defsubr (&Scurrent_window_configuration
);
5372 defsubr (&Ssave_window_excursion
);
5373 defsubr (&Sset_window_margins
);
5374 defsubr (&Swindow_margins
);
5375 defsubr (&Swindow_vscroll
);
5376 defsubr (&Sset_window_vscroll
);
5377 defsubr (&Scompare_window_configurations
);
5383 initial_define_key (control_x_map
, '1', "delete-other-windows");
5384 initial_define_key (control_x_map
, '2', "split-window");
5385 initial_define_key (control_x_map
, '0', "delete-window");
5386 initial_define_key (control_x_map
, 'o', "other-window");
5387 initial_define_key (control_x_map
, '^', "enlarge-window");
5388 initial_define_key (control_x_map
, '<', "scroll-left");
5389 initial_define_key (control_x_map
, '>', "scroll-right");
5391 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
5392 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
5393 initial_define_key (meta_map
, 'v', "scroll-down");
5395 initial_define_key (global_map
, Ctl('L'), "recenter");
5396 initial_define_key (meta_map
, 'r', "move-to-window-line");