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
;
724 /* In case W->start is out of the range, use something
725 reasonable. This situation occured when loading a file with
726 `-l' containing a call to `rmail' with subsequent other
727 commands. At the end, W->start happened to be BEG, while
728 rmail had already narrowed the buffer. This leads to an
729 abort in temp_set_pt_both. */
730 if (XMARKER (w
->start
)->charpos
< BEGV
)
731 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
732 else if (XMARKER (w
->start
)->charpos
> ZV
)
733 TEMP_SET_PT_BOTH (ZV
, ZV_BYTE
);
735 TEMP_SET_PT_BOTH (XMARKER (w
->start
)->charpos
,
736 XMARKER (w
->start
)->bytepos
);
738 Fvertical_motion (make_number (window_internal_height (w
)), Qnil
);
740 TEMP_SET_PT_BOTH (opoint
, opoint_byte
);
744 BUF_Z (XBUFFER (buf
)) - XFASTINT (w
->window_end_pos
));
749 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
750 "Make point value in WINDOW be at position POS in WINDOW's buffer.")
752 Lisp_Object window
, pos
;
754 register struct window
*w
= decode_window (window
);
756 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
757 if (w
== XWINDOW (selected_window
)
758 && XBUFFER (w
->buffer
) == current_buffer
)
761 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
766 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
767 "Make display in WINDOW start at position POS in WINDOW's buffer.\n\
768 Optional third arg NOFORCE non-nil inhibits next redisplay\n\
769 from overriding motion of point in order to display at this exact start.")
770 (window
, pos
, noforce
)
771 Lisp_Object window
, pos
, noforce
;
773 register struct window
*w
= decode_window (window
);
775 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
776 set_marker_restricted (w
->start
, pos
, w
->buffer
);
777 /* this is not right, but much easier than doing what is right. */
778 w
->start_at_line_beg
= Qnil
;
781 w
->update_mode_line
= Qt
;
782 XSETFASTINT (w
->last_modified
, 0);
783 XSETFASTINT (w
->last_overlay_modified
, 0);
784 if (!EQ (window
, selected_window
))
785 windows_or_buffers_changed
++;
790 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
792 "Return WINDOW's dedicated object, usually t or nil.\n\
793 See also `set-window-dedicated-p'.")
797 return decode_window (window
)->dedicated
;
800 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
801 Sset_window_dedicated_p
, 2, 2, 0,
802 "Control whether WINDOW is dedicated to the buffer it displays.\n\
803 If it is dedicated, Emacs will not automatically change\n\
804 which buffer appears in it.\n\
805 The second argument is the new value for the dedication flag;\n\
808 Lisp_Object window
, arg
;
810 register struct window
*w
= decode_window (window
);
820 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
822 "Return the display-table that WINDOW is using.")
826 return decode_window (window
)->display_table
;
829 /* Get the display table for use on window W. This is either W's
830 display table or W's buffer's display table. Ignore the specified
831 tables if they are not valid; if no valid table is specified,
834 struct Lisp_Char_Table
*
835 window_display_table (w
)
839 tem
= w
->display_table
;
840 if (DISP_TABLE_P (tem
))
841 return XCHAR_TABLE (tem
);
842 if (NILP (w
->buffer
))
845 tem
= XBUFFER (w
->buffer
)->display_table
;
846 if (DISP_TABLE_P (tem
))
847 return XCHAR_TABLE (tem
);
848 tem
= Vstandard_display_table
;
849 if (DISP_TABLE_P (tem
))
850 return XCHAR_TABLE (tem
);
854 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
855 "Set WINDOW's display-table to TABLE.")
857 register Lisp_Object window
, table
;
859 register struct window
*w
;
861 w
= decode_window (window
);
862 w
->display_table
= table
;
866 /* Record info on buffer window w is displaying
867 when it is about to cease to display that buffer. */
870 register struct window
*w
;
877 if (b
!= XMARKER (w
->pointm
)->buffer
)
880 if (w
== XWINDOW (b
->last_selected_window
))
881 b
->last_selected_window
= Qnil
;
884 if (w
== XWINDOW (selected_window
)
885 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
886 /* Do this except when the selected window's buffer
887 is being removed from some other window. */
889 /* last_window_start records the start position that this buffer
890 had in the last window to be disconnected from it.
891 Now that this statement is unconditional,
892 it is possible for the buffer to be displayed in the
893 selected window, while last_window_start reflects another
894 window which was recently showing the same buffer.
895 Some people might say that might be a good thing. Let's see. */
896 b
->last_window_start
= marker_position (w
->start
);
898 /* Point in the selected window's buffer
899 is actually stored in that buffer, and the window's pointm isn't used.
900 So don't clobber point in that buffer. */
901 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
))
902 temp_set_point_both (b
,
903 clip_to_bounds (BUF_BEGV (b
),
904 XMARKER (w
->pointm
)->charpos
,
906 clip_to_bounds (BUF_BEGV_BYTE (b
),
907 marker_byte_position (w
->pointm
),
911 /* Put replacement into the window structure in place of old. */
913 replace_window (old
, replacement
)
914 Lisp_Object old
, replacement
;
916 register Lisp_Object tem
;
917 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
919 /* If OLD is its frame's root_window, then replacement is the new
920 root_window for that frame. */
922 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
923 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
928 p
->height
= o
->height
;
929 p
->desired_matrix
= p
->current_matrix
= 0;
931 bzero (&p
->cursor
, sizeof (p
->cursor
));
932 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
933 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
934 p
->phys_cursor_type
= -1;
935 p
->must_be_updated_p
= 0;
936 p
->pseudo_window_p
= 0;
937 XSETFASTINT (p
->window_end_vpos
, 0);
938 XSETFASTINT (p
->window_end_pos
, 0);
939 p
->window_end_valid
= Qnil
;
940 p
->frozen_window_start_p
= 0;
941 p
->orig_top
= p
->orig_height
= Qnil
;
943 p
->next
= tem
= o
->next
;
945 XWINDOW (tem
)->prev
= replacement
;
947 p
->prev
= tem
= o
->prev
;
949 XWINDOW (tem
)->next
= replacement
;
951 p
->parent
= tem
= o
->parent
;
954 if (EQ (XWINDOW (tem
)->vchild
, old
))
955 XWINDOW (tem
)->vchild
= replacement
;
956 if (EQ (XWINDOW (tem
)->hchild
, old
))
957 XWINDOW (tem
)->hchild
= replacement
;
960 /*** Here, if replacement is a vertical combination
961 and so is its new parent, we should make replacement's
962 children be children of that parent instead. ***/
965 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
966 "Remove WINDOW from the display. Default is selected window.")
968 register Lisp_Object window
;
970 delete_window (window
);
972 if (! NILP (Vwindow_configuration_change_hook
)
973 && ! NILP (Vrun_hooks
))
974 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
980 delete_window (window
)
981 register Lisp_Object window
;
983 register Lisp_Object tem
, parent
, sib
;
984 register struct window
*p
;
985 register struct window
*par
;
988 /* Because this function is called by other C code on non-leaf
989 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
990 so we can't decode_window here. */
992 window
= selected_window
;
994 CHECK_WINDOW (window
, 0);
995 p
= XWINDOW (window
);
997 /* It's okay to delete an already-deleted window. */
1000 && NILP (p
->vchild
))
1005 error ("Attempt to delete minibuffer or sole ordinary window");
1006 par
= XWINDOW (parent
);
1008 windows_or_buffers_changed
++;
1009 frame
= XFRAME (WINDOW_FRAME (p
));
1010 FRAME_WINDOW_SIZES_CHANGED (frame
) = 1;
1012 /* Are we trying to delete any frame's selected window? */
1014 Lisp_Object frame
, pwindow
;
1016 /* See if the frame's selected window is either WINDOW
1017 or any subwindow of it, by finding all that window's parents
1018 and comparing each one with WINDOW. */
1019 frame
= WINDOW_FRAME (XWINDOW (window
));
1020 pwindow
= FRAME_SELECTED_WINDOW (XFRAME (frame
));
1022 while (!NILP (pwindow
))
1024 if (EQ (window
, pwindow
))
1026 pwindow
= XWINDOW (pwindow
)->parent
;
1029 if (EQ (window
, pwindow
))
1031 Lisp_Object alternative
;
1032 alternative
= Fnext_window (window
, Qlambda
, Qnil
);
1034 /* If we're about to delete the selected window on the
1035 selected frame, then we should use Fselect_window to select
1036 the new window. On the other hand, if we're about to
1037 delete the selected window on any other frame, we shouldn't do
1038 anything but set the frame's selected_window slot. */
1039 if (EQ (window
, selected_window
))
1040 Fselect_window (alternative
);
1042 FRAME_SELECTED_WINDOW (XFRAME (frame
)) = alternative
;
1047 /* tem is null for dummy parent windows
1048 (which have inferiors but not any contents themselves) */
1052 unchain_marker (p
->pointm
);
1053 unchain_marker (p
->start
);
1056 /* Free window glyph matrices.
1057 It is sure that they are allocated again when ADJUST_GLYPHS
1059 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (frame
)));
1063 XWINDOW (tem
)->prev
= p
->prev
;
1067 XWINDOW (tem
)->next
= p
->next
;
1069 if (EQ (window
, par
->hchild
))
1070 par
->hchild
= p
->next
;
1071 if (EQ (window
, par
->vchild
))
1072 par
->vchild
= p
->next
;
1074 /* Find one of our siblings to give our space to. */
1078 /* If p gives its space to its next sibling, that sibling needs
1079 to have its top/left side pulled back to where p's is.
1080 set_window_{height,width} will re-position the sibling's
1083 XWINDOW (sib
)->top
= p
->top
;
1084 XWINDOW (sib
)->left
= p
->left
;
1087 /* Stretch that sibling. */
1088 if (!NILP (par
->vchild
))
1089 set_window_height (sib
,
1090 XFASTINT (XWINDOW (sib
)->height
) + XFASTINT (p
->height
),
1092 if (!NILP (par
->hchild
))
1093 set_window_width (sib
,
1094 XFASTINT (XWINDOW (sib
)->width
) + XFASTINT (p
->width
),
1097 /* If parent now has only one child,
1098 put the child into the parent's place. */
1102 if (NILP (XWINDOW (tem
)->next
))
1103 replace_window (parent
, tem
);
1105 /* Since we may be deleting combination windows, we must make sure that
1106 not only p but all its children have been marked as deleted. */
1107 if (! NILP (p
->hchild
))
1108 delete_all_subwindows (XWINDOW (p
->hchild
));
1109 else if (! NILP (p
->vchild
))
1110 delete_all_subwindows (XWINDOW (p
->vchild
));
1112 /* Mark this window as deleted. */
1113 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
1115 /* Adjust glyph matrices. */
1116 adjust_glyphs (frame
);
1120 extern Lisp_Object
next_frame (), prev_frame ();
1122 /* This comment supplies the doc string for `next-window',
1123 for make-docfile to see. We cannot put this in the real DEFUN
1124 due to limits in the Unix cpp.
1126 DEFUN ("next-window", Ffoo, Sfoo, 0, 3, 0,
1127 "Return next window after WINDOW in canonical ordering of windows.\n\
1128 If omitted, WINDOW defaults to the selected window.\n\
1130 Optional second arg MINIBUF t means count the minibuffer window even\n\
1131 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1132 it is active. MINIBUF neither t nor nil means not to count the\n\
1133 minibuffer even if it is active.\n\
1135 Several frames may share a single minibuffer; if the minibuffer\n\
1136 counts, all windows on all frames that share that minibuffer count\n\
1137 too. Therefore, `next-window' can be used to iterate through the\n\
1138 set of windows even when the minibuffer is on another frame. If the\n\
1139 minibuffer does not count, only windows from WINDOW's frame count.\n\
1141 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1142 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1143 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1144 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1145 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1146 Anything else means restrict to WINDOW's frame.\n\
1148 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1149 `next-window' to iterate through the entire cycle of acceptable\n\
1150 windows, eventually ending up back at the window you started with.\n\
1151 `previous-window' traverses the same cycle, in the reverse order.")
1152 (window, minibuf, all_frames) */
1154 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
1156 (window
, minibuf
, all_frames
)
1157 register Lisp_Object window
, minibuf
, all_frames
;
1159 register Lisp_Object tem
;
1160 Lisp_Object start_window
;
1163 window
= selected_window
;
1165 CHECK_LIVE_WINDOW (window
, 0);
1167 start_window
= window
;
1169 /* minibuf == nil may or may not include minibuffers.
1170 Decide if it does. */
1172 minibuf
= (minibuf_level
? minibuf_window
: Qlambda
);
1173 else if (! EQ (minibuf
, Qt
))
1175 /* Now minibuf can be t => count all minibuffer windows,
1176 lambda => count none of them,
1177 or a specific minibuffer window (the active one) to count. */
1179 /* all_frames == nil doesn't specify which frames to include. */
1180 if (NILP (all_frames
))
1181 all_frames
= (! EQ (minibuf
, Qlambda
)
1182 ? (FRAME_MINIBUF_WINDOW
1185 (XWINDOW (window
)))))
1187 else if (EQ (all_frames
, Qvisible
))
1189 else if (XFASTINT (all_frames
) == 0)
1191 else if (FRAMEP (all_frames
) && ! EQ (all_frames
, Fwindow_frame (window
)))
1192 /* If all_frames is a frame and window arg isn't on that frame, just
1193 return the first window on the frame. */
1194 return Fframe_first_window (all_frames
);
1195 else if (! EQ (all_frames
, Qt
))
1197 /* Now all_frames is t meaning search all frames,
1198 nil meaning search just current frame,
1199 visible meaning search just visible frames,
1200 0 meaning search visible and iconified frames,
1201 or a window, meaning search the frame that window belongs to. */
1203 /* Do this loop at least once, to get the next window, and perhaps
1204 again, if we hit the minibuffer and that is not acceptable. */
1207 /* Find a window that actually has a next one. This loop
1208 climbs up the tree. */
1209 while (tem
= XWINDOW (window
)->next
, NILP (tem
))
1210 if (tem
= XWINDOW (window
)->parent
, !NILP (tem
))
1214 /* We've reached the end of this frame.
1215 Which other frames are acceptable? */
1216 tem
= WINDOW_FRAME (XWINDOW (window
));
1217 if (! NILP (all_frames
))
1222 tem
= next_frame (tem
, all_frames
);
1223 /* In the case where the minibuffer is active,
1224 and we include its frame as well as the selected one,
1225 next_frame may get stuck in that frame.
1226 If that happens, go back to the selected frame
1227 so we can complete the cycle. */
1229 tem
= selected_frame
;
1231 tem
= FRAME_ROOT_WINDOW (XFRAME (tem
));
1238 /* If we're in a combination window, find its first child and
1239 recurse on that. Otherwise, we've found the window we want. */
1242 if (!NILP (XWINDOW (window
)->hchild
))
1243 window
= XWINDOW (window
)->hchild
;
1244 else if (!NILP (XWINDOW (window
)->vchild
))
1245 window
= XWINDOW (window
)->vchild
;
1251 /* Which windows are acceptable?
1252 Exit the loop and accept this window if
1253 this isn't a minibuffer window,
1254 or we're accepting all minibuffer windows,
1255 or this is the active minibuffer and we are accepting that one, or
1256 we've come all the way around and we're back at the original window. */
1257 while (MINI_WINDOW_P (XWINDOW (window
))
1258 && ! EQ (minibuf
, Qt
)
1259 && ! EQ (minibuf
, window
)
1260 && ! EQ (window
, start_window
));
1265 /* This comment supplies the doc string for `previous-window',
1266 for make-docfile to see. We cannot put this in the real DEFUN
1267 due to limits in the Unix cpp.
1269 DEFUN ("previous-window", Ffoo, Sfoo, 0, 3, 0,
1270 "Return the window preceding WINDOW in canonical ordering of windows.\n\
1271 If omitted, WINDOW defaults to the selected window.\n\
1273 Optional second arg MINIBUF t means count the minibuffer window even\n\
1274 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1275 it is active. MINIBUF neither t nor nil means not to count the\n\
1276 minibuffer even if it is active.\n\
1278 Several frames may share a single minibuffer; if the minibuffer\n\
1279 counts, all windows on all frames that share that minibuffer count\n\
1280 too. Therefore, `previous-window' can be used to iterate through\n\
1281 the set of windows even when the minibuffer is on another frame. If\n\
1282 the minibuffer does not count, only windows from WINDOW's frame count\n\
1284 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1285 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1286 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1287 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1288 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1289 Anything else means restrict to WINDOW's frame.\n\
1291 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1292 `previous-window' to iterate through the entire cycle of acceptable\n\
1293 windows, eventually ending up back at the window you started with.\n\
1294 `next-window' traverses the same cycle, in the reverse order.")
1295 (window, minibuf, all_frames) */
1298 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
1300 (window
, minibuf
, all_frames
)
1301 register Lisp_Object window
, minibuf
, all_frames
;
1303 register Lisp_Object tem
;
1304 Lisp_Object start_window
;
1307 window
= selected_window
;
1309 CHECK_LIVE_WINDOW (window
, 0);
1311 start_window
= window
;
1313 /* minibuf == nil may or may not include minibuffers.
1314 Decide if it does. */
1316 minibuf
= (minibuf_level
? minibuf_window
: Qlambda
);
1317 else if (! EQ (minibuf
, Qt
))
1319 /* Now minibuf can be t => count all minibuffer windows,
1320 lambda => count none of them,
1321 or a specific minibuffer window (the active one) to count. */
1323 /* all_frames == nil doesn't specify which frames to include.
1324 Decide which frames it includes. */
1325 if (NILP (all_frames
))
1326 all_frames
= (! EQ (minibuf
, Qlambda
)
1327 ? (FRAME_MINIBUF_WINDOW
1330 (XWINDOW (window
)))))
1332 else if (EQ (all_frames
, Qvisible
))
1334 else if (XFASTINT (all_frames
) == 0)
1336 else if (FRAMEP (all_frames
) && ! EQ (all_frames
, Fwindow_frame (window
)))
1337 /* If all_frames is a frame and window arg isn't on that frame, just
1338 return the first window on the frame. */
1339 return Fframe_first_window (all_frames
);
1340 else if (! EQ (all_frames
, Qt
))
1342 /* Now all_frames is t meaning search all frames,
1343 nil meaning search just current frame,
1344 visible meaning search just visible frames,
1345 0 meaning search visible and iconified frames,
1346 or a window, meaning search the frame that window belongs to. */
1348 /* Do this loop at least once, to get the previous window, and perhaps
1349 again, if we hit the minibuffer and that is not acceptable. */
1352 /* Find a window that actually has a previous one. This loop
1353 climbs up the tree. */
1354 while (tem
= XWINDOW (window
)->prev
, NILP (tem
))
1355 if (tem
= XWINDOW (window
)->parent
, !NILP (tem
))
1359 /* We have found the top window on the frame.
1360 Which frames are acceptable? */
1361 tem
= WINDOW_FRAME (XWINDOW (window
));
1362 if (! NILP (all_frames
))
1363 /* It's actually important that we use prev_frame here,
1364 rather than next_frame. All the windows acceptable
1365 according to the given parameters should form a ring;
1366 Fnext_window and Fprevious_window should go back and
1367 forth around the ring. If we use next_frame here,
1368 then Fnext_window and Fprevious_window take different
1369 paths through the set of acceptable windows.
1370 window_loop assumes that these `ring' requirement are
1376 tem
= prev_frame (tem
, all_frames
);
1377 /* In the case where the minibuffer is active,
1378 and we include its frame as well as the selected one,
1379 next_frame may get stuck in that frame.
1380 If that happens, go back to the selected frame
1381 so we can complete the cycle. */
1383 tem
= selected_frame
;
1385 /* If this frame has a minibuffer, find that window first,
1386 because it is conceptually the last window in that frame. */
1387 if (FRAME_HAS_MINIBUF_P (XFRAME (tem
)))
1388 tem
= FRAME_MINIBUF_WINDOW (XFRAME (tem
));
1390 tem
= FRAME_ROOT_WINDOW (XFRAME (tem
));
1396 /* If we're in a combination window, find its last child and
1397 recurse on that. Otherwise, we've found the window we want. */
1400 if (!NILP (XWINDOW (window
)->hchild
))
1401 window
= XWINDOW (window
)->hchild
;
1402 else if (!NILP (XWINDOW (window
)->vchild
))
1403 window
= XWINDOW (window
)->vchild
;
1405 while (tem
= XWINDOW (window
)->next
, !NILP (tem
))
1409 /* Which windows are acceptable?
1410 Exit the loop and accept this window if
1411 this isn't a minibuffer window,
1412 or we're accepting all minibuffer windows,
1413 or this is the active minibuffer and we are accepting that one, or
1414 we've come all the way around and we're back at the original window. */
1415 while (MINI_WINDOW_P (XWINDOW (window
))
1416 && ! EQ (minibuf
, Qt
)
1417 && ! EQ (minibuf
, window
)
1418 && ! EQ (window
, start_window
));
1423 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1424 "Select the ARG'th different window on this frame.\n\
1425 All windows on current frame are arranged in a cyclic order.\n\
1426 This command selects the window ARG steps away in that order.\n\
1427 A negative ARG moves in the opposite order. If the optional second\n\
1428 argument ALL_FRAMES is non-nil, cycle through all frames.")
1430 register Lisp_Object arg
, all_frames
;
1433 register Lisp_Object w
;
1435 CHECK_NUMBER (arg
, 0);
1436 w
= selected_window
;
1441 w
= Fnext_window (w
, Qnil
, all_frames
);
1446 w
= Fprevious_window (w
, Qnil
, all_frames
);
1453 /* Look at all windows, performing an operation specified by TYPE
1455 If FRAMES is Qt, look at all frames;
1456 Qnil, look at just the selected frame;
1457 Qvisible, look at visible frames;
1458 a frame, just look at windows on that frame.
1459 If MINI is non-zero, perform the operation on minibuffer windows too.
1465 GET_BUFFER_WINDOW
, /* Arg is buffer */
1466 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1467 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1468 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1470 UNSHOW_BUFFER
, /* Arg is buffer */
1475 window_loop (type
, obj
, mini
, frames
)
1476 enum window_loop type
;
1477 register Lisp_Object obj
, frames
;
1480 register Lisp_Object w
;
1481 register Lisp_Object best_window
;
1482 register Lisp_Object next_window
;
1483 register Lisp_Object last_window
;
1485 Lisp_Object frame_arg
;
1488 /* If we're only looping through windows on a particular frame,
1489 frame points to that frame. If we're looping through windows
1490 on all frames, frame is 0. */
1491 if (FRAMEP (frames
))
1492 frame
= XFRAME (frames
);
1493 else if (NILP (frames
))
1494 frame
= SELECTED_FRAME ();
1498 frame_arg
= Qlambda
;
1499 else if (XFASTINT (frames
) == 0)
1501 else if (EQ (frames
, Qvisible
))
1504 /* frame_arg is Qlambda to stick to one frame,
1505 Qvisible to consider all visible frames,
1508 /* Pick a window to start with. */
1512 w
= FRAME_SELECTED_WINDOW (frame
);
1514 w
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
1516 /* Figure out the last window we're going to mess with. Since
1517 Fnext_window, given the same options, is guaranteed to go in a
1518 ring, we can just use Fprevious_window to find the last one.
1520 We can't just wait until we hit the first window again, because
1521 it might be deleted. */
1523 last_window
= Fprevious_window (w
, mini
? Qt
: Qnil
, frame_arg
);
1528 /* Pick the next window now, since some operations will delete
1529 the current window. */
1530 next_window
= Fnext_window (w
, mini
? Qt
: Qnil
, frame_arg
);
1532 /* Note that we do not pay attention here to whether
1533 the frame is visible, since Fnext_window skips non-visible frames
1534 if that is desired, under the control of frame_arg. */
1535 if (! MINI_WINDOW_P (XWINDOW (w
))
1536 /* For UNSHOW_BUFFER, we must always consider all windows. */
1537 || type
== UNSHOW_BUFFER
1538 || (mini
&& minibuf_level
> 0))
1541 case GET_BUFFER_WINDOW
:
1542 if (XBUFFER (XWINDOW (w
)->buffer
) == XBUFFER (obj
)
1543 /* Don't find any minibuffer window
1544 except the one that is currently in use. */
1545 && (MINI_WINDOW_P (XWINDOW (w
))
1546 ? EQ (w
, minibuf_window
) : 1))
1550 case GET_LRU_WINDOW
:
1551 /* t as arg means consider only full-width windows */
1552 if (!NILP (obj
) && !WINDOW_FULL_WIDTH_P (XWINDOW (w
)))
1554 /* Ignore dedicated windows and minibuffers. */
1555 if (MINI_WINDOW_P (XWINDOW (w
))
1556 || !NILP (XWINDOW (w
)->dedicated
))
1558 if (NILP (best_window
)
1559 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1560 > XFASTINT (XWINDOW (w
)->use_time
)))
1564 case DELETE_OTHER_WINDOWS
:
1565 if (XWINDOW (w
) != XWINDOW (obj
))
1569 case DELETE_BUFFER_WINDOWS
:
1570 if (EQ (XWINDOW (w
)->buffer
, obj
))
1572 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (w
)));
1574 /* If this window is dedicated, and in a frame of its own,
1576 if (EQ (w
, FRAME_ROOT_WINDOW (f
))
1577 && !NILP (XWINDOW (w
)->dedicated
)
1578 && other_visible_frames (f
))
1580 /* Skip the other windows on this frame.
1581 There might be one, the minibuffer! */
1582 if (! EQ (w
, last_window
))
1583 while (f
== XFRAME (WINDOW_FRAME (XWINDOW (next_window
))))
1585 /* As we go, check for the end of the loop.
1586 We mustn't start going around a second time. */
1587 if (EQ (next_window
, last_window
))
1592 next_window
= Fnext_window (next_window
,
1596 /* Now we can safely delete the frame. */
1597 Fdelete_frame (WINDOW_FRAME (XWINDOW (w
)), Qnil
);
1600 /* If we're deleting the buffer displayed in the only window
1601 on the frame, find a new buffer to display there. */
1602 if (NILP (XWINDOW (w
)->parent
))
1604 Lisp_Object new_buffer
;
1605 new_buffer
= Fother_buffer (obj
, Qnil
,
1606 XWINDOW (w
)->frame
);
1607 if (NILP (new_buffer
))
1609 = Fget_buffer_create (build_string ("*scratch*"));
1610 Fset_window_buffer (w
, new_buffer
);
1611 if (EQ (w
, selected_window
))
1612 Fset_buffer (XWINDOW (w
)->buffer
);
1619 case GET_LARGEST_WINDOW
:
1620 /* Ignore dedicated windows and minibuffers. */
1621 if (MINI_WINDOW_P (XWINDOW (w
))
1622 || !NILP (XWINDOW (w
)->dedicated
))
1625 struct window
*best_window_ptr
= XWINDOW (best_window
);
1626 struct window
*w_ptr
= XWINDOW (w
);
1627 if (NILP (best_window
)
1628 || (XFASTINT (w_ptr
->height
) * XFASTINT (w_ptr
->width
)
1629 > (XFASTINT (best_window_ptr
->height
)
1630 * XFASTINT (best_window_ptr
->width
))))
1636 if (EQ (XWINDOW (w
)->buffer
, obj
))
1638 /* Find another buffer to show in this window. */
1639 Lisp_Object another_buffer
;
1640 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (w
)));
1641 another_buffer
= Fother_buffer (obj
, Qnil
, XWINDOW (w
)->frame
);
1642 if (NILP (another_buffer
))
1644 = Fget_buffer_create (build_string ("*scratch*"));
1645 /* If this window is dedicated, and in a frame of its own,
1647 if (EQ (w
, FRAME_ROOT_WINDOW (f
))
1648 && !NILP (XWINDOW (w
)->dedicated
)
1649 && other_visible_frames (f
))
1651 /* Skip the other windows on this frame.
1652 There might be one, the minibuffer! */
1653 if (! EQ (w
, last_window
))
1654 while (f
== XFRAME (WINDOW_FRAME (XWINDOW (next_window
))))
1656 /* As we go, check for the end of the loop.
1657 We mustn't start going around a second time. */
1658 if (EQ (next_window
, last_window
))
1663 next_window
= Fnext_window (next_window
,
1667 /* Now we can safely delete the frame. */
1668 Fdelete_frame (WINDOW_FRAME (XWINDOW (w
)), Qnil
);
1672 /* Otherwise show a different buffer in the window. */
1673 XWINDOW (w
)->dedicated
= Qnil
;
1674 Fset_window_buffer (w
, another_buffer
);
1675 if (EQ (w
, selected_window
))
1676 Fset_buffer (XWINDOW (w
)->buffer
);
1681 /* Check for a window that has a killed buffer. */
1682 case CHECK_ALL_WINDOWS
:
1683 if (! NILP (XWINDOW (w
)->buffer
)
1684 && NILP (XBUFFER (XWINDOW (w
)->buffer
)->name
))
1688 if (EQ (w
, last_window
))
1697 /* Used for debugging. Abort if any window has a dead buffer. */
1700 check_all_windows ()
1702 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
1705 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1706 "Return the window least recently selected or used for display.\n\
1707 If optional argument FRAME is `visible', search all visible frames.\n\
1708 If FRAME is 0, search all visible and iconified frames.\n\
1709 If FRAME is t, search all frames.\n\
1710 If FRAME is nil, search only the selected frame.\n\
1711 If FRAME is a frame, search only that frame.")
1715 register Lisp_Object w
;
1716 /* First try for a window that is full-width */
1717 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frame
);
1718 if (!NILP (w
) && !EQ (w
, selected_window
))
1720 /* If none of them, try the rest */
1721 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frame
);
1724 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1725 "Return the largest window in area.\n\
1726 If optional argument FRAME is `visible', search all visible frames.\n\
1727 If FRAME is 0, search all visible and iconified frames.\n\
1728 If FRAME is t, search all frames.\n\
1729 If FRAME is nil, search only the selected frame.\n\
1730 If FRAME is a frame, search only that frame.")
1734 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
1738 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
1739 "Return a window currently displaying BUFFER, or nil if none.\n\
1740 If optional argument FRAME is `visible', search all visible frames.\n\
1741 If optional argument FRAME is 0, search all visible and iconified frames.\n\
1742 If FRAME is t, search all frames.\n\
1743 If FRAME is nil, search only the selected frame.\n\
1744 If FRAME is a frame, search only that frame.")
1746 Lisp_Object buffer
, frame
;
1748 buffer
= Fget_buffer (buffer
);
1749 if (BUFFERP (buffer
))
1750 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
1755 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
1757 "Make WINDOW (or the selected window) fill its frame.\n\
1758 Only the frame WINDOW is on is affected.\n\
1759 This function tries to reduce display jumps\n\
1760 by keeping the text previously visible in WINDOW\n\
1761 in the same place on the frame. Doing this depends on\n\
1762 the value of (window-start WINDOW), so if calling this function\n\
1763 in a program gives strange scrolling, make sure the window-start\n\
1764 value is reasonable when this function is called.")
1773 window
= selected_window
;
1775 CHECK_LIVE_WINDOW (window
, 0);
1777 w
= XWINDOW (window
);
1779 startpos
= marker_position (w
->start
);
1780 top
= XFASTINT (w
->top
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
1782 if (MINI_WINDOW_P (w
) && top
> 0)
1783 error ("Can't expand minibuffer to full frame");
1785 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
1787 /* Try to minimize scrolling, by setting the window start to the point
1788 will cause the text at the old window start to be at the same place
1789 on the frame. But don't try to do this if the window start is
1790 outside the visible portion (as might happen when the display is
1791 not current, due to typeahead). */
1792 if (startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
1793 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
1795 struct position pos
;
1796 struct buffer
*obuf
= current_buffer
;
1798 Fset_buffer (w
->buffer
);
1799 /* This computation used to temporarily move point, but that can
1800 have unwanted side effects due to text properties. */
1801 pos
= *vmotion (startpos
, -top
, w
);
1803 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
1804 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
1805 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
1807 /* We need to do this, so that the window-scroll-functions
1809 w
->optional_new_start
= Qt
;
1811 set_buffer_internal (obuf
);
1817 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
1818 1, 2, "bDelete windows on (buffer): ",
1819 "Delete all windows showing BUFFER.\n\
1820 Optional second argument FRAME controls which frames are affected.\n\
1821 If optional argument FRAME is `visible', search all visible frames.\n\
1822 If FRAME is 0, search all visible and iconified frames.\n\
1823 If FRAME is nil, search all frames.\n\
1824 If FRAME is t, search only the selected frame.\n\
1825 If FRAME is a frame, search only that frame.")
1827 Lisp_Object buffer
, frame
;
1829 /* FRAME uses t and nil to mean the opposite of what window_loop
1833 else if (EQ (frame
, Qt
))
1838 buffer
= Fget_buffer (buffer
);
1839 CHECK_BUFFER (buffer
, 0);
1840 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
1846 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
1847 Sreplace_buffer_in_windows
,
1848 1, 1, "bReplace buffer in windows: ",
1849 "Replace BUFFER with some other buffer in all windows showing it.")
1855 buffer
= Fget_buffer (buffer
);
1856 CHECK_BUFFER (buffer
, 0);
1857 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
1862 /* Replace BUFFER with some other buffer in all windows
1863 of all frames, even those on other keyboards. */
1866 replace_buffer_in_all_windows (buffer
)
1870 Lisp_Object tail
, frame
;
1872 /* A single call to window_loop won't do the job
1873 because it only considers frames on the current keyboard.
1874 So loop manually over frames, and handle each one. */
1875 FOR_EACH_FRAME (tail
, frame
)
1876 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
1878 window_loop (UNSHOW_BUFFER
, buffer
, 1, Qt
);
1882 /* Set the height of WINDOW and all its inferiors. */
1884 /* The smallest acceptable dimensions for a window. Anything smaller
1885 might crash Emacs. */
1887 #define MIN_SAFE_WINDOW_WIDTH (2)
1888 #define MIN_SAFE_WINDOW_HEIGHT (2)
1890 /* Make sure that window_min_height and window_min_width are
1891 not too small; if they are, set them to safe minima. */
1894 check_min_window_sizes ()
1896 /* Smaller values might permit a crash. */
1897 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
1898 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
1899 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
1900 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
1903 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
1904 minimum allowable size. */
1907 check_frame_size (frame
, rows
, cols
)
1911 /* For height, we have to see:
1912 whether the frame has a minibuffer,
1913 whether it wants a mode line, and
1914 whether it has a menu bar. */
1916 (FRAME_MINIBUF_ONLY_P (frame
) ? MIN_SAFE_WINDOW_HEIGHT
- 1
1917 : (! FRAME_HAS_MINIBUF_P (frame
)) ? MIN_SAFE_WINDOW_HEIGHT
1918 : 2 * MIN_SAFE_WINDOW_HEIGHT
- 1);
1920 if (FRAME_TOP_MARGIN (frame
) > 0)
1921 min_height
+= FRAME_TOP_MARGIN (frame
);
1923 if (*rows
< min_height
)
1925 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
1926 *cols
= MIN_SAFE_WINDOW_WIDTH
;
1930 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
1931 check if W's width can be changed, otherwise check W's height.
1932 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
1933 siblings, too. If none of the siblings is resizable, WINDOW isn't
1937 window_fixed_size_p (w
, width_p
, check_siblings_p
)
1939 int width_p
, check_siblings_p
;
1944 if (!NILP (w
->hchild
))
1946 c
= XWINDOW (w
->hchild
);
1950 /* A horiz. combination is fixed-width if all of if its
1952 while (c
&& window_fixed_size_p (c
, width_p
, 0))
1953 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
1954 fixed_p
= c
== NULL
;
1958 /* A horiz. combination is fixed-height 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
;
1965 else if (!NILP (w
->vchild
))
1967 c
= XWINDOW (w
->vchild
);
1971 /* A vert. combination is fixed-width if one of if its
1973 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
1974 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
1975 fixed_p
= c
!= NULL
;
1979 /* A vert. combination is fixed-height if all of if its
1981 while (c
&& window_fixed_size_p (c
, width_p
, 0))
1982 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
1983 fixed_p
= c
== NULL
;
1986 else if (BUFFERP (w
->buffer
))
1988 if (w
->height_fixed_p
&& !width_p
)
1992 struct buffer
*old
= current_buffer
;
1995 current_buffer
= XBUFFER (w
->buffer
);
1996 val
= find_symbol_value (Qwindow_size_fixed
);
1997 current_buffer
= old
;
2000 if (!EQ (val
, Qunbound
))
2002 fixed_p
= !NILP (val
);
2005 && ((EQ (val
, Qheight
) && width_p
)
2006 || (EQ (val
, Qwidth
) && !width_p
)))
2011 /* Can't tell if this one is resizable without looking at
2012 siblings. If all siblings are fixed-size this one is too. */
2013 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
2017 for (child
= w
->prev
; !NILP (child
); child
= XWINDOW (child
)->prev
)
2018 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2022 for (child
= w
->next
; !NILP (child
); child
= XWINDOW (child
)->next
)
2023 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2037 /* Return the minimum size of window W, not taking fixed-width windows
2038 into account. WIDTH_P non-zero means return the minimum width,
2039 otherwise return the minimum height. If W is a combination window,
2040 compute the minimum size from the minimum sizes of W's children. */
2043 window_min_size_1 (w
, width_p
)
2050 if (!NILP (w
->hchild
))
2052 c
= XWINDOW (w
->hchild
);
2057 /* The min width of a horizontal combination is
2058 the sum of the min widths of its children. */
2061 size
+= window_min_size_1 (c
, width_p
);
2062 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2067 /* The min height a horizontal combination equals
2068 the maximum of all min height of its children. */
2071 int min_size
= window_min_size_1 (c
, width_p
);
2072 size
= max (min_size
, size
);
2073 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2077 else if (!NILP (w
->vchild
))
2079 c
= XWINDOW (w
->vchild
);
2084 /* The min width of a vertical combination is
2085 the maximum of the min widths of its children. */
2088 int min_size
= window_min_size_1 (c
, width_p
);
2089 size
= max (min_size
, size
);
2090 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2095 /* The min height of a vertical combination equals
2096 the sum of the min height of its children. */
2099 size
+= window_min_size_1 (c
, width_p
);
2100 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2107 size
= window_min_width
;
2110 if (MINI_WINDOW_P (w
)
2111 || (!WINDOW_WANTS_MODELINE_P (w
)
2112 && !WINDOW_WANTS_HEADER_LINE_P (w
)))
2115 size
= window_min_height
;
2123 /* Return the minimum size of window W, taking fixed-size windows into
2124 account. WIDTH_P non-zero means return the minimum width,
2125 otherwise return the minimum height. IGNORE_FIXED_P non-zero means
2126 ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size
2127 unless FIXED is null. */
2130 window_min_size (w
, width_p
, ignore_fixed_p
, fixed
)
2132 int width_p
, ignore_fixed_p
, *fixed
;
2139 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
2145 size
= width_p
? XFASTINT (w
->width
) : XFASTINT (w
->height
);
2147 size
= window_min_size_1 (w
, width_p
);
2153 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
2154 WINDOW's width. Resize WINDOW's children, if any, so that they
2155 keep their proportionate size relative to WINDOW. Propagate
2156 WINDOW's top or left edge position to children. Delete windows
2157 that become too small unless NODELETE_P is non-zero. */
2160 size_window (window
, size
, width_p
, nodelete_p
)
2162 int size
, width_p
, nodelete_p
;
2164 struct window
*w
= XWINDOW (window
);
2166 Lisp_Object child
, *forward
, *sideward
;
2167 int old_size
, min_size
;
2169 check_min_window_sizes ();
2171 /* If the window has been "too small" at one point,
2172 don't delete it for being "too small" in the future.
2173 Preserve it as long as that is at all possible. */
2176 old_size
= XFASTINT (w
->width
);
2177 min_size
= window_min_width
;
2181 old_size
= XFASTINT (w
->height
);
2182 min_size
= window_min_height
;
2185 if (old_size
< window_min_width
)
2186 w
->too_small_ok
= Qt
;
2188 /* Maybe delete WINDOW if it's too small. */
2189 if (!nodelete_p
&& !NILP (w
->parent
))
2193 if (!MINI_WINDOW_P (w
) && !NILP (w
->too_small_ok
))
2194 min_size
= width_p
? MIN_SAFE_WINDOW_WIDTH
: MIN_SAFE_WINDOW_HEIGHT
;
2196 min_size
= width_p
? window_min_width
: window_min_height
;
2198 if (size
< min_size
)
2200 delete_window (window
);
2205 /* Set redisplay hints. */
2206 XSETFASTINT (w
->last_modified
, 0);
2207 XSETFASTINT (w
->last_overlay_modified
, 0);
2208 windows_or_buffers_changed
++;
2209 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
2213 sideward
= &w
->vchild
;
2214 forward
= &w
->hchild
;
2215 XSETFASTINT (w
->width
, size
);
2219 sideward
= &w
->hchild
;
2220 forward
= &w
->vchild
;
2221 XSETFASTINT (w
->height
, size
);
2224 if (!NILP (*sideward
))
2226 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
2228 c
= XWINDOW (child
);
2233 size_window (child
, size
, width_p
, nodelete_p
);
2236 else if (!NILP (*forward
))
2238 int fixed_size
, each
, extra
, n
;
2239 int resize_fixed_p
, nfixed
;
2240 int last_pos
, first_pos
, nchildren
;
2242 /* Determine the fixed-size portion of the this window, and the
2243 number of child windows. */
2244 fixed_size
= nchildren
= nfixed
= 0;
2245 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
2247 c
= XWINDOW (child
);
2248 if (window_fixed_size_p (c
, width_p
, 0))
2250 fixed_size
+= (width_p
2251 ? XFASTINT (c
->width
) : XFASTINT (c
->height
));
2256 /* If the new size is smaller than fixed_size, or if there
2257 aren't any resizable windows, allow resizing fixed-size
2259 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
2261 /* Compute how many lines/columns to add to each child. The
2262 value of extra takes care of rounding errors. */
2263 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
2264 each
= (size
- old_size
) / n
;
2265 extra
= (size
- old_size
) - n
* each
;
2267 /* Compute new children heights and edge positions. */
2268 first_pos
= width_p
? XFASTINT (w
->left
) : XFASTINT (w
->top
);
2269 last_pos
= first_pos
;
2270 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2272 int new_size
, old_size
;
2274 c
= XWINDOW (child
);
2275 old_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2276 new_size
= old_size
;
2278 /* The top or left edge position of this child equals the
2279 bottom or right edge of its predecessor. */
2281 c
->left
= make_number (last_pos
);
2283 c
->top
= make_number (last_pos
);
2285 /* If this child can be resized, do it. */
2286 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
2288 new_size
= old_size
+ each
+ extra
;
2292 /* Set new height. Note that size_window also propagates
2293 edge positions to children, so it's not a no-op if we
2294 didn't change the child's size. */
2295 size_window (child
, new_size
, width_p
, 1);
2297 /* Remember the bottom/right edge position of this child; it
2298 will be used to set the top/left edge of the next child. */
2299 last_pos
+= new_size
;
2302 /* We should have covered the parent exactly with child windows. */
2303 xassert (size
== last_pos
- first_pos
);
2305 /* Now delete any children that became too small. */
2307 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2310 c
= XWINDOW (child
);
2311 child_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2312 size_window (child
, child_size
, width_p
, 0);
2317 /* Set WINDOW's height to HEIGHT, and recursively change the height of
2318 WINDOW's children. NODELETE non-zero means don't delete windows
2319 that become too small in the process. (The caller should check
2320 later and do so if appropriate.) */
2323 set_window_height (window
, height
, nodelete
)
2328 size_window (window
, height
, 0, nodelete
);
2332 /* Set WINDOW's width to WIDTH, and recursively change the width of
2333 WINDOW's children. NODELETE non-zero means don't delete windows
2334 that become too small in the process. (The caller should check
2335 later and do so if appropriate.) */
2338 set_window_width (window
, width
, nodelete
)
2343 size_window (window
, width
, 1, nodelete
);
2347 int window_select_count
;
2350 Fset_window_buffer_unwind (obuf
)
2358 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
2359 means it's allowed to run hooks. See make_frame for a case where
2360 it's not allowed. */
2363 set_window_buffer (window
, buffer
, run_hooks_p
)
2364 Lisp_Object window
, buffer
;
2367 struct window
*w
= XWINDOW (window
);
2368 struct buffer
*b
= XBUFFER (buffer
);
2369 int count
= specpdl_ptr
- specpdl
;
2373 if (EQ (window
, selected_window
))
2374 b
->last_selected_window
= window
;
2376 /* Update time stamps of buffer display. */
2377 if (INTEGERP (b
->display_count
))
2378 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
2379 b
->display_time
= Fcurrent_time ();
2381 XSETFASTINT (w
->window_end_pos
, 0);
2382 XSETFASTINT (w
->window_end_vpos
, 0);
2383 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
2384 w
->window_end_valid
= Qnil
;
2385 XSETFASTINT (w
->hscroll
, 0);
2386 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
2387 set_marker_restricted (w
->start
,
2388 make_number (b
->last_window_start
),
2390 w
->start_at_line_beg
= Qnil
;
2391 w
->force_start
= Qnil
;
2392 XSETFASTINT (w
->last_modified
, 0);
2393 XSETFASTINT (w
->last_overlay_modified
, 0);
2394 windows_or_buffers_changed
++;
2396 /* We must select BUFFER for running the window-scroll-functions.
2397 If WINDOW is selected, switch permanently.
2398 Otherwise, switch but go back to the ambient buffer afterward. */
2399 if (EQ (window
, selected_window
))
2400 Fset_buffer (buffer
);
2401 /* We can't check ! NILP (Vwindow_scroll_functions) here
2402 because that might itself be a local variable. */
2403 else if (window_initialized
)
2405 record_unwind_protect (Fset_window_buffer_unwind
, Fcurrent_buffer ());
2406 Fset_buffer (buffer
);
2409 /* Set left and right marginal area width from buffer. */
2410 Fset_window_margins (window
, b
->left_margin_width
, b
->right_margin_width
);
2414 if (! NILP (Vwindow_scroll_functions
))
2415 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2416 Fmarker_position (w
->start
));
2418 if (! NILP (Vwindow_configuration_change_hook
)
2419 && ! NILP (Vrun_hooks
))
2420 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
2423 unbind_to (count
, Qnil
);
2427 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 2, 0,
2428 "Make WINDOW display BUFFER as its contents.\n\
2429 BUFFER can be a buffer or buffer name.")
2431 register Lisp_Object window
, buffer
;
2433 register Lisp_Object tem
;
2434 register struct window
*w
= decode_window (window
);
2436 buffer
= Fget_buffer (buffer
);
2437 CHECK_BUFFER (buffer
, 1);
2439 if (NILP (XBUFFER (buffer
)->name
))
2440 error ("Attempt to display deleted buffer");
2444 error ("Window is deleted");
2445 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
2446 is first being set up. */
2448 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
2449 error ("Window is dedicated to `%s'",
2450 XSTRING (XBUFFER (tem
)->name
)->data
);
2455 set_window_buffer (window
, buffer
, 1);
2459 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 1, 0,
2460 "Select WINDOW. Most editing will apply to WINDOW's buffer.\n\
2461 If WINDOW is not already selected, also make WINDOW's buffer current.\n\
2462 Note that the main editor command loop\n\
2463 selects the buffer of the selected window before each command.")
2465 register Lisp_Object window
;
2467 return select_window_1 (window
, 1);
2471 select_window_1 (window
, recordflag
)
2472 register Lisp_Object window
;
2475 register struct window
*w
;
2476 register struct window
*ow
= XWINDOW (selected_window
);
2479 CHECK_LIVE_WINDOW (window
, 0);
2481 w
= XWINDOW (window
);
2483 if (NILP (w
->buffer
))
2484 error ("Trying to select deleted window or non-leaf window");
2486 XSETFASTINT (w
->use_time
, ++window_select_count
);
2487 if (EQ (window
, selected_window
))
2490 if (! NILP (ow
->buffer
))
2491 set_marker_both (ow
->pointm
, ow
->buffer
,
2492 BUF_PT (XBUFFER (ow
->buffer
)),
2493 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
2495 selected_window
= window
;
2496 sf
= SELECTED_FRAME ();
2497 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
2499 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
2500 /* Use this rather than Fhandle_switch_frame
2501 so that FRAME_FOCUS_FRAME is moved appropriately as we
2502 move around in the state where a minibuffer in a separate
2504 Fselect_frame (WINDOW_FRAME (w
), Qnil
);
2507 sf
->selected_window
= window
;
2510 record_buffer (w
->buffer
);
2511 Fset_buffer (w
->buffer
);
2513 XBUFFER (w
->buffer
)->last_selected_window
= window
;
2515 /* Go to the point recorded in the window.
2516 This is important when the buffer is in more
2517 than one window. It also matters when
2518 redisplay_window has altered point after scrolling,
2519 because it makes the change only in the window. */
2521 register int new_point
= marker_position (w
->pointm
);
2522 if (new_point
< BEGV
)
2524 else if (new_point
> ZV
)
2530 windows_or_buffers_changed
++;
2534 /* Deiconify the frame containing the window WINDOW,
2535 unless it is the selected frame;
2538 The reason for the exception for the selected frame
2539 is that it seems better not to change the selected frames visibility
2540 merely because of displaying a different buffer in it.
2541 The deiconification is useful when a buffer gets shown in
2542 another frame that you were not using lately. */
2545 display_buffer_1 (window
)
2548 Lisp_Object frame
= XWINDOW (window
)->frame
;
2549 FRAME_PTR f
= XFRAME (frame
);
2551 FRAME_SAMPLE_VISIBILITY (f
);
2553 if (!EQ (frame
, selected_frame
))
2555 if (FRAME_ICONIFIED_P (f
))
2556 Fmake_frame_visible (frame
);
2557 else if (FRAME_VISIBLE_P (f
))
2558 Fraise_frame (frame
);
2564 DEFUN ("special-display-p", Fspecial_display_p
, Sspecial_display_p
, 1, 1, 0,
2565 "Returns non-nil if a buffer named BUFFER-NAME would be created specially.\n\
2566 The value is actually t if the frame should be called with default frame\n\
2567 parameters, and a list of frame parameters if they were specified.\n\
2568 See `special-display-buffer-names', and `special-display-regexps'.")
2570 Lisp_Object buffer_name
;
2574 CHECK_STRING (buffer_name
, 1);
2576 tem
= Fmember (buffer_name
, Vspecial_display_buffer_names
);
2580 tem
= Fassoc (buffer_name
, Vspecial_display_buffer_names
);
2584 for (tem
= Vspecial_display_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2586 Lisp_Object car
= XCAR (tem
);
2588 && fast_string_match (car
, buffer_name
) >= 0)
2590 else if (CONSP (car
)
2591 && STRINGP (XCAR (car
))
2592 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2598 DEFUN ("same-window-p", Fsame_window_p
, Ssame_window_p
, 1, 1, 0,
2599 "Returns non-nil if a new buffer named BUFFER-NAME would use the same window.\n\
2600 See `same-window-buffer-names' and `same-window-regexps'.")
2602 Lisp_Object buffer_name
;
2606 CHECK_STRING (buffer_name
, 1);
2608 tem
= Fmember (buffer_name
, Vsame_window_buffer_names
);
2612 tem
= Fassoc (buffer_name
, Vsame_window_buffer_names
);
2616 for (tem
= Vsame_window_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2618 Lisp_Object car
= XCAR (tem
);
2620 && fast_string_match (car
, buffer_name
) >= 0)
2622 else if (CONSP (car
)
2623 && STRINGP (XCAR (car
))
2624 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2630 /* Use B so the default is (other-buffer). */
2631 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 3,
2632 "BDisplay buffer: \nP",
2633 "Make BUFFER appear in some window but don't select it.\n\
2634 BUFFER can be a buffer or a buffer name.\n\
2635 If BUFFER is shown already in some window, just use that one,\n\
2636 unless the window is the selected window and the optional second\n\
2637 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).\n\
2638 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.\n\
2639 Returns the window displaying BUFFER.\n\
2641 The variables `special-display-buffer-names', `special-display-regexps',\n\
2642 `same-window-buffer-names', and `same-window-regexps' customize how certain\n\
2643 buffer names are handled.\n\
2645 If optional argument FRAME is `visible', search all visible frames.\n\
2646 If FRAME is 0, search all visible and iconified frames.\n\
2647 If FRAME is t, search all frames.\n\
2648 If FRAME is a frame, search only that frame.\n\
2649 If FRAME is nil, search only the selected frame\n\
2650 (actually the last nonminibuffer frame),\n\
2651 unless `pop-up-frames' is non-nil,\n\
2652 which means search visible and iconified frames.")
2653 (buffer
, not_this_window
, frame
)
2654 register Lisp_Object buffer
, not_this_window
, frame
;
2656 register Lisp_Object window
, tem
, swp
;
2660 buffer
= Fget_buffer (buffer
);
2661 CHECK_BUFFER (buffer
, 0);
2663 if (!NILP (Vdisplay_buffer_function
))
2664 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
2666 if (NILP (not_this_window
)
2667 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
2668 return display_buffer_1 (selected_window
);
2670 /* See if the user has specified this buffer should appear
2671 in the selected window. */
2672 if (NILP (not_this_window
))
2674 swp
= Fsame_window_p (XBUFFER (buffer
)->name
);
2675 if (!NILP (swp
) && !no_switch_window (selected_window
))
2677 Fswitch_to_buffer (buffer
, Qnil
);
2678 return display_buffer_1 (selected_window
);
2682 /* If pop_up_frames,
2683 look for a window showing BUFFER on any visible or iconified frame.
2684 Otherwise search only the current frame. */
2687 else if (pop_up_frames
|| last_nonminibuf_frame
== 0)
2688 XSETFASTINT (tem
, 0);
2690 XSETFRAME (tem
, last_nonminibuf_frame
);
2691 window
= Fget_buffer_window (buffer
, tem
);
2693 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
2695 return display_buffer_1 (window
);
2698 /* Certain buffer names get special handling. */
2699 if (!NILP (Vspecial_display_function
) && NILP (swp
))
2701 tem
= Fspecial_display_p (XBUFFER (buffer
)->name
);
2703 return call1 (Vspecial_display_function
, buffer
);
2705 return call2 (Vspecial_display_function
, buffer
, tem
);
2708 /* If there are no frames open that have more than a minibuffer,
2709 we need to create a new frame. */
2710 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
2712 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2713 Fset_window_buffer (window
, buffer
);
2714 return display_buffer_1 (window
);
2717 f
= SELECTED_FRAME ();
2719 || FRAME_MINIBUF_ONLY_P (f
)
2720 /* If the current frame is a special display frame,
2721 don't try to reuse its windows. */
2722 || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f
))->dedicated
))
2727 if (FRAME_MINIBUF_ONLY_P (f
))
2728 XSETFRAME (frames
, last_nonminibuf_frame
);
2729 /* Don't try to create a window if would get an error */
2730 if (split_height_threshold
< window_min_height
<< 1)
2731 split_height_threshold
= window_min_height
<< 1;
2733 /* Note that both Fget_largest_window and Fget_lru_window
2734 ignore minibuffers and dedicated windows.
2735 This means they can return nil. */
2737 /* If the frame we would try to split cannot be split,
2738 try other frames. */
2739 if (FRAME_NO_SPLIT_P (NILP (frames
) ? f
: last_nonminibuf_frame
))
2741 /* Try visible frames first. */
2742 window
= Fget_largest_window (Qvisible
);
2743 /* If that didn't work, try iconified frames. */
2745 window
= Fget_largest_window (make_number (0));
2747 window
= Fget_largest_window (Qt
);
2750 window
= Fget_largest_window (frames
);
2752 /* If we got a tall enough full-width window that can be split,
2755 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2756 && window_height (window
) >= split_height_threshold
2757 && WINDOW_FULL_WIDTH_P (XWINDOW (window
)))
2758 window
= Fsplit_window (window
, Qnil
, Qnil
);
2761 Lisp_Object upper
, lower
, other
;
2763 window
= Fget_lru_window (frames
);
2764 /* If the LRU window is selected, and big enough,
2765 and can be split, split it. */
2767 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2768 && (EQ (window
, selected_window
)
2769 || EQ (XWINDOW (window
)->parent
, Qnil
))
2770 && window_height (window
) >= window_min_height
<< 1)
2771 window
= Fsplit_window (window
, Qnil
, Qnil
);
2772 /* If Fget_lru_window returned nil, try other approaches. */
2774 /* Try visible frames first. */
2776 window
= Fget_buffer_window (buffer
, Qvisible
);
2778 window
= Fget_largest_window (Qvisible
);
2779 /* If that didn't work, try iconified frames. */
2781 window
= Fget_buffer_window (buffer
, make_number (0));
2783 window
= Fget_largest_window (make_number (0));
2784 /* Try invisible frames. */
2786 window
= Fget_buffer_window (buffer
, Qt
);
2788 window
= Fget_largest_window (Qt
);
2789 /* As a last resort, make a new frame. */
2791 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2792 /* If window appears above or below another,
2793 even out their heights. */
2794 other
= upper
= lower
= Qnil
;
2795 if (!NILP (XWINDOW (window
)->prev
))
2796 other
= upper
= XWINDOW (window
)->prev
, lower
= window
;
2797 if (!NILP (XWINDOW (window
)->next
))
2798 other
= lower
= XWINDOW (window
)->next
, upper
= window
;
2800 /* Check that OTHER and WINDOW are vertically arrayed. */
2801 && !EQ (XWINDOW (other
)->top
, XWINDOW (window
)->top
)
2802 && (XFASTINT (XWINDOW (other
)->height
)
2803 > XFASTINT (XWINDOW (window
)->height
)))
2805 int total
= (XFASTINT (XWINDOW (other
)->height
)
2806 + XFASTINT (XWINDOW (window
)->height
));
2807 enlarge_window (upper
,
2808 total
/ 2 - XFASTINT (XWINDOW (upper
)->height
),
2814 window
= Fget_lru_window (Qnil
);
2816 Fset_window_buffer (window
, buffer
);
2817 return display_buffer_1 (window
);
2821 temp_output_buffer_show (buf
)
2822 register Lisp_Object buf
;
2824 register struct buffer
*old
= current_buffer
;
2825 register Lisp_Object window
;
2826 register struct window
*w
;
2828 XBUFFER (buf
)->directory
= current_buffer
->directory
;
2831 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
2835 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
2836 set_buffer_internal (old
);
2838 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
2839 call1 (Vtemp_buffer_show_function
, buf
);
2842 window
= Fdisplay_buffer (buf
, Qnil
, Qnil
);
2844 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
2845 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
2846 Vminibuf_scroll_window
= window
;
2847 w
= XWINDOW (window
);
2848 XSETFASTINT (w
->hscroll
, 0);
2849 set_marker_restricted_both (w
->start
, buf
, 1, 1);
2850 set_marker_restricted_both (w
->pointm
, buf
, 1, 1);
2852 /* Run temp-buffer-show-hook, with the chosen window selected
2853 and it sbuffer current. */
2854 if (!NILP (Vrun_hooks
))
2857 tem
= Fboundp (Qtemp_buffer_show_hook
);
2860 tem
= Fsymbol_value (Qtemp_buffer_show_hook
);
2863 int count
= specpdl_ptr
- specpdl
;
2864 Lisp_Object prev_window
;
2865 prev_window
= selected_window
;
2867 /* Select the window that was chosen, for running the hook. */
2868 record_unwind_protect (Fselect_window
, prev_window
);
2869 select_window_1 (window
, 0);
2870 Fset_buffer (w
->buffer
);
2871 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
2872 select_window_1 (prev_window
, 0);
2873 unbind_to (count
, Qnil
);
2881 make_dummy_parent (window
)
2885 register struct window
*o
, *p
;
2886 register struct Lisp_Vector
*vec
;
2889 o
= XWINDOW (window
);
2890 vec
= allocate_vectorlike ((EMACS_INT
)VECSIZE (struct window
));
2891 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
2892 vec
->contents
[i
] = ((struct Lisp_Vector
*)o
)->contents
[i
];
2893 vec
->size
= VECSIZE (struct window
);
2894 p
= (struct window
*)vec
;
2895 XSETWINDOW (new, p
);
2897 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
2899 /* Put new into window structure in place of window */
2900 replace_window (window
, new);
2913 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
2914 "Split WINDOW, putting SIZE lines in the first of the pair.\n\
2915 WINDOW defaults to selected one and SIZE to half its size.\n\
2916 If optional third arg HORFLAG is non-nil, split side by side\n\
2917 and put SIZE columns in the first of the pair. In that case,\n\
2918 SIZE includes that window's scroll bar, or the divider column to its right.")
2919 (window
, size
, horflag
)
2920 Lisp_Object window
, size
, horflag
;
2922 register Lisp_Object
new;
2923 register struct window
*o
, *p
;
2925 register int size_int
;
2928 window
= selected_window
;
2930 CHECK_LIVE_WINDOW (window
, 0);
2932 o
= XWINDOW (window
);
2933 fo
= XFRAME (WINDOW_FRAME (o
));
2937 if (!NILP (horflag
))
2938 /* Calculate the size of the left-hand window, by dividing
2939 the usable space in columns by two.
2940 We round up, since the left-hand window may include
2941 a dividing line, while the right-hand may not. */
2942 size_int
= (XFASTINT (o
->width
) + 1) >> 1;
2944 size_int
= XFASTINT (o
->height
) >> 1;
2948 CHECK_NUMBER (size
, 1);
2949 size_int
= XINT (size
);
2952 if (MINI_WINDOW_P (o
))
2953 error ("Attempt to split minibuffer window");
2954 else if (window_fixed_size_p (o
, !NILP (horflag
), 0))
2955 error ("Attempt to split fixed-size window");
2957 check_min_window_sizes ();
2961 if (size_int
< window_min_height
)
2962 error ("Window height %d too small (after splitting)", size_int
);
2963 if (size_int
+ window_min_height
> XFASTINT (o
->height
))
2964 error ("Window height %d too small (after splitting)",
2965 XFASTINT (o
->height
) - size_int
);
2966 if (NILP (o
->parent
)
2967 || NILP (XWINDOW (o
->parent
)->vchild
))
2969 make_dummy_parent (window
);
2971 XWINDOW (new)->vchild
= window
;
2976 if (size_int
< window_min_width
)
2977 error ("Window width %d too small (after splitting)", size_int
);
2979 if (size_int
+ window_min_width
> XFASTINT (o
->width
))
2980 error ("Window width %d too small (after splitting)",
2981 XFASTINT (o
->width
) - size_int
);
2982 if (NILP (o
->parent
)
2983 || NILP (XWINDOW (o
->parent
)->hchild
))
2985 make_dummy_parent (window
);
2987 XWINDOW (new)->hchild
= window
;
2991 /* Now we know that window's parent is a vertical combination
2992 if we are dividing vertically, or a horizontal combination
2993 if we are making side-by-side windows */
2995 windows_or_buffers_changed
++;
2996 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
2997 new = make_window ();
3000 p
->frame
= o
->frame
;
3002 if (!NILP (p
->next
))
3003 XWINDOW (p
->next
)->prev
= new;
3006 p
->parent
= o
->parent
;
3008 p
->window_end_valid
= Qnil
;
3009 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
3011 /* Apportion the available frame space among the two new windows */
3013 if (!NILP (horflag
))
3015 p
->height
= o
->height
;
3017 XSETFASTINT (p
->width
, XFASTINT (o
->width
) - size_int
);
3018 XSETFASTINT (o
->width
, size_int
);
3019 XSETFASTINT (p
->left
, XFASTINT (o
->left
) + size_int
);
3024 p
->width
= o
->width
;
3025 XSETFASTINT (p
->height
, XFASTINT (o
->height
) - size_int
);
3026 XSETFASTINT (o
->height
, size_int
);
3027 XSETFASTINT (p
->top
, XFASTINT (o
->top
) + size_int
);
3030 /* Adjust glyph matrices. */
3032 Fset_window_buffer (new, o
->buffer
);
3036 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
3037 "Make current window ARG lines bigger.\n\
3038 From program, optional second arg non-nil means grow sideways ARG columns.")
3040 register Lisp_Object arg
, side
;
3042 CHECK_NUMBER (arg
, 0);
3043 enlarge_window (selected_window
, XINT (arg
), !NILP (side
));
3045 if (! NILP (Vwindow_configuration_change_hook
))
3046 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3051 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
3052 "Make current window ARG lines smaller.\n\
3053 From program, optional second arg non-nil means shrink sideways arg columns.")
3055 register Lisp_Object arg
, side
;
3057 CHECK_NUMBER (arg
, 0);
3058 enlarge_window (selected_window
, -XINT (arg
), !NILP (side
));
3060 if (! NILP (Vwindow_configuration_change_hook
))
3061 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3067 window_height (window
)
3070 register struct window
*p
= XWINDOW (window
);
3071 return XFASTINT (p
->height
);
3075 window_width (window
)
3078 register struct window
*p
= XWINDOW (window
);
3079 return XFASTINT (p
->width
);
3084 *(widthflag ? (int *) &(XWINDOW (w)->left) : (int *) &(XWINDOW (w)->top))
3086 #define CURSIZE(w) \
3087 *(widthflag ? (int *) &(XWINDOW (w)->width) : (int *) &(XWINDOW (w)->height))
3090 /* Enlarge selected_window by DELTA. WIDTHFLAG non-zero means
3091 increase its width. Siblings of the selected window are resized to
3092 fullfil the size request. If they become too small in the process,
3093 they will be deleted. */
3096 enlarge_window (window
, delta
, widthflag
)
3098 int delta
, widthflag
;
3100 Lisp_Object parent
, next
, prev
;
3102 int *sizep
, maximum
;
3103 int (*sizefun
) P_ ((Lisp_Object
))
3104 = widthflag
? window_width
: window_height
;
3105 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
3106 = (widthflag
? set_window_width
: set_window_height
);
3108 /* Check values of window_min_width and window_min_height for
3110 check_min_window_sizes ();
3112 /* Give up if this window cannot be resized. */
3113 if (window_fixed_size_p (XWINDOW (window
), widthflag
, 1))
3114 error ("Window is not resizable");
3116 /* Find the parent of the selected window. */
3119 p
= XWINDOW (window
);
3125 error ("No other window to side of this one");
3130 ? !NILP (XWINDOW (parent
)->hchild
)
3131 : !NILP (XWINDOW (parent
)->vchild
))
3137 sizep
= &CURSIZE (window
);
3140 register int maxdelta
;
3142 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - *sizep
3143 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3144 - window_min_size (XWINDOW (p
->next
),
3146 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
3147 - window_min_size (XWINDOW (p
->prev
),
3149 /* This is a frame with only one window, a minibuffer-only
3150 or a minibufferless frame. */
3153 if (delta
> maxdelta
)
3154 /* This case traps trying to make the minibuffer
3155 the full frame, or make the only window aside from the
3156 minibuffer the full frame. */
3160 if (*sizep
+ delta
< window_min_size (XWINDOW (window
), widthflag
, 0, 0))
3162 delete_window (window
);
3169 /* Find the total we can get from other siblings. */
3171 for (next
= p
->next
; ! NILP (next
); next
= XWINDOW (next
)->next
)
3172 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
3174 for (prev
= p
->prev
; ! NILP (prev
); prev
= XWINDOW (prev
)->prev
)
3175 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
3178 /* If we can get it all from them, do so. */
3179 if (delta
<= maximum
)
3181 Lisp_Object first_unaffected
;
3182 Lisp_Object first_affected
;
3187 first_affected
= window
;
3188 /* Look at one sibling at a time,
3189 moving away from this window in both directions alternately,
3190 and take as much as we can get without deleting that sibling. */
3191 while (delta
!= 0 && (!NILP (next
) || !NILP (prev
)))
3195 int this_one
= ((*sizefun
) (next
)
3196 - window_min_size (XWINDOW (next
),
3197 widthflag
, 0, &fixed_p
));
3200 if (this_one
> delta
)
3203 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
3204 (*setsizefun
) (window
, *sizep
+ this_one
, 0);
3209 next
= XWINDOW (next
)->next
;
3217 int this_one
= ((*sizefun
) (prev
)
3218 - window_min_size (XWINDOW (prev
),
3219 widthflag
, 0, &fixed_p
));
3222 if (this_one
> delta
)
3225 first_affected
= prev
;
3227 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
3228 (*setsizefun
) (window
, *sizep
+ this_one
, 0);
3233 prev
= XWINDOW (prev
)->prev
;
3237 xassert (delta
== 0);
3239 /* Now recalculate the edge positions of all the windows affected,
3240 based on the new sizes. */
3241 first_unaffected
= next
;
3242 prev
= first_affected
;
3243 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
3244 prev
= next
, next
= XWINDOW (next
)->next
)
3246 CURBEG (next
) = CURBEG (prev
) + (*sizefun
) (prev
);
3247 /* This does not change size of NEXT,
3248 but it propagates the new top edge to its children */
3249 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
3254 register int delta1
;
3255 register int opht
= (*sizefun
) (parent
);
3257 /* If trying to grow this window to or beyond size of the parent,
3258 make delta1 so big that, on shrinking back down,
3259 all the siblings end up with less than one line and are deleted. */
3260 if (opht
<= *sizep
+ delta
)
3261 delta1
= opht
* opht
* 2;
3264 /* Otherwise, make delta1 just right so that if we add
3265 delta1 lines to this window and to the parent, and then
3266 shrink the parent back to its original size, the new
3267 proportional size of this window will increase by delta.
3269 The function size_window will compute the new height h'
3270 of the window from delta1 as:
3273 x = delta1 - delta1/n * n for the 1st resizable child
3276 where n is the number of children that can be resized.
3277 We can ignore x by choosing a delta1 that is a multiple of
3278 n. We want the height of this window to come out as
3288 The number of children n rquals the number of resizable
3289 children of this window + 1 because we know window itself
3290 is resizable (otherwise we would have signalled an error. */
3292 struct window
*w
= XWINDOW (window
);
3296 for (s
= w
->next
; !NILP (s
); s
= XWINDOW (s
)->next
)
3297 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3299 for (s
= w
->prev
; !NILP (s
); s
= XWINDOW (s
)->prev
)
3300 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3306 /* Add delta1 lines or columns to this window, and to the parent,
3307 keeping things consistent while not affecting siblings. */
3308 CURSIZE (parent
) = opht
+ delta1
;
3309 (*setsizefun
) (window
, *sizep
+ delta1
, 0);
3311 /* Squeeze out delta1 lines or columns from our parent,
3312 shriking this window and siblings proportionately.
3313 This brings parent back to correct size.
3314 Delta1 was calculated so this makes this window the desired size,
3315 taking it all out of the siblings. */
3316 (*setsizefun
) (parent
, opht
, 0);
3319 XSETFASTINT (p
->last_modified
, 0);
3320 XSETFASTINT (p
->last_overlay_modified
, 0);
3322 /* Adjust glyph matrices. */
3323 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
3331 /***********************************************************************
3332 Resizing Mini-Windows
3333 ***********************************************************************/
3335 static void shrink_window_lowest_first
P_ ((struct window
*, int));
3337 enum save_restore_action
3344 static int save_restore_orig_size
P_ ((struct window
*,
3345 enum save_restore_action
));
3347 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
3348 from lowest windows first. */
3351 shrink_window_lowest_first (w
, height
)
3359 xassert (!MINI_WINDOW_P (w
));
3361 /* Set redisplay hints. */
3362 XSETFASTINT (w
->last_modified
, 0);
3363 XSETFASTINT (w
->last_overlay_modified
, 0);
3364 windows_or_buffers_changed
++;
3365 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
3367 old_height
= XFASTINT (w
->height
);
3368 XSETFASTINT (w
->height
, height
);
3370 if (!NILP (w
->hchild
))
3372 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
3374 c
= XWINDOW (child
);
3376 shrink_window_lowest_first (c
, height
);
3379 else if (!NILP (w
->vchild
))
3381 Lisp_Object last_child
;
3382 int delta
= old_height
- height
;
3385 /* Find the last child. We are taking space from lowest windows
3386 first, so we iterate over children from the last child
3388 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
3391 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
3392 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
3396 c
= XWINDOW (child
);
3397 this_one
= XFASTINT (c
->height
) - MIN_SAFE_WINDOW_HEIGHT
;
3399 if (this_one
> delta
)
3402 shrink_window_lowest_first (c
, XFASTINT (c
->height
) - this_one
);
3406 /* Compute new positions. */
3408 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
3410 c
= XWINDOW (child
);
3411 c
->top
= make_number (last_top
);
3412 shrink_window_lowest_first (c
, XFASTINT (c
->height
));
3413 last_top
+= XFASTINT (c
->height
);
3419 /* Save, restore, or check positions and sizes in the window tree
3420 rooted at W. ACTION says what to do.
3422 If ACTION is CHECK_ORIG_SIZES, check if orig_top and orig_height
3423 members are valid for all windows in the window tree. Value is
3424 non-zero if they are valid.
3426 If ACTION is SAVE_ORIG_SIZES, save members top and height in
3427 orig_top and orig_height for all windows in the tree.
3429 If ACTION is RESTORE_ORIG_SIZES, restore top and height from
3430 values stored in orig_top and orig_height for all windows. */
3433 save_restore_orig_size (w
, action
)
3435 enum save_restore_action action
;
3441 if (!NILP (w
->hchild
))
3443 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
3446 else if (!NILP (w
->vchild
))
3448 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
3454 case CHECK_ORIG_SIZES
:
3455 if (!INTEGERP (w
->orig_top
) || !INTEGERP (w
->orig_height
))
3459 case SAVE_ORIG_SIZES
:
3460 w
->orig_top
= w
->top
;
3461 w
->orig_height
= w
->height
;
3462 XSETFASTINT (w
->last_modified
, 0);
3463 XSETFASTINT (w
->last_overlay_modified
, 0);
3466 case RESTORE_ORIG_SIZES
:
3467 xassert (INTEGERP (w
->orig_top
) && INTEGERP (w
->orig_height
));
3468 w
->top
= w
->orig_top
;
3469 w
->height
= w
->orig_height
;
3470 w
->orig_height
= w
->orig_top
= Qnil
;
3471 XSETFASTINT (w
->last_modified
, 0);
3472 XSETFASTINT (w
->last_overlay_modified
, 0);
3479 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
3486 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
3487 without deleting other windows. */
3490 grow_mini_window (w
, delta
)
3494 struct frame
*f
= XFRAME (w
->frame
);
3495 struct window
*root
;
3497 xassert (MINI_WINDOW_P (w
));
3498 xassert (delta
>= 0);
3500 /* Check values of window_min_width and window_min_height for
3502 check_min_window_sizes ();
3504 /* Compute how much we can enlarge the mini-window without deleting
3506 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3509 int min_height
= window_min_size (root
, 0, 0, 0);
3510 if (XFASTINT (root
->height
) - delta
< min_height
)
3511 delta
= XFASTINT (root
->height
) - min_height
;
3516 /* Save original window sizes and positions, if not already done. */
3517 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3518 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
3520 /* Shrink other windows. */
3521 shrink_window_lowest_first (root
, XFASTINT (root
->height
) - delta
);
3523 /* Grow the mini-window. */
3524 w
->top
= make_number (XFASTINT (root
->top
) + XFASTINT (root
)->height
);
3525 w
->height
= make_number (XFASTINT (w
->height
) + delta
);
3526 XSETFASTINT (w
->last_modified
, 0);
3527 XSETFASTINT (w
->last_overlay_modified
, 0);
3534 /* Shrink mini-window W. If there is recorded info about window sizes
3535 before a call to grow_mini_window, restore recorded window sizes.
3536 Otherwise, if the mini-window is higher than 1 line, resize it to 1
3540 shrink_mini_window (w
)
3543 struct frame
*f
= XFRAME (w
->frame
);
3544 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3546 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3548 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
3550 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
3551 windows_or_buffers_changed
= 1;
3553 else if (XFASTINT (w
->height
) > 1)
3556 XSETWINDOW (window
, w
);
3557 enlarge_window (window
, 1 - XFASTINT (w
->height
), 0);
3563 /* Mark window cursors off for all windows in the window tree rooted
3564 at W by setting their phys_cursor_on_p flag to zero. Called from
3565 xterm.c, e.g. when a frame is cleared and thereby all cursors on
3566 the frame are cleared. */
3569 mark_window_cursors_off (w
)
3574 if (!NILP (w
->hchild
))
3575 mark_window_cursors_off (XWINDOW (w
->hchild
));
3576 else if (!NILP (w
->vchild
))
3577 mark_window_cursors_off (XWINDOW (w
->vchild
));
3579 w
->phys_cursor_on_p
= 0;
3581 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
3586 /* Return number of lines of text (not counting mode line) in W. */
3589 window_internal_height (w
)
3592 int ht
= XFASTINT (w
->height
);
3594 if (MINI_WINDOW_P (w
))
3597 if (!NILP (w
->parent
) || !NILP (w
->vchild
) || !NILP (w
->hchild
)
3598 || !NILP (w
->next
) || !NILP (w
->prev
)
3599 || FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (w
))))
3606 /* Return the number of columns in W.
3607 Don't count columns occupied by scroll bars or the vertical bar
3608 separating W from the sibling to its right. */
3611 window_internal_width (w
)
3614 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
3615 int width
= XINT (w
->width
);
3617 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
3618 /* Scroll bars occupy a few columns. */
3619 width
-= FRAME_SCROLL_BAR_COLS (f
);
3620 else if (!WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
3621 /* The column of `|' characters separating side-by-side windows
3622 occupies one column only. */
3625 /* On window-systems, areas to the left and right of the window
3626 are used to display bitmaps there. */
3627 if (FRAME_WINDOW_P (f
))
3628 width
-= FRAME_FLAGS_AREA_COLS (f
);
3634 /************************************************************************
3636 ***********************************************************************/
3638 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
3639 one screen-full, which is defined as the height of the window minus
3640 next_screen_context_lines. If WHOLE is zero, scroll up N lines
3641 instead. Negative values of N mean scroll down. NOERROR non-zero
3642 means don't signal an error if we try to move over BEGV or ZV,
3646 window_scroll (window
, n
, whole
, noerror
)
3652 /* If we must, use the pixel-based version which is much slower than
3653 the line-based one but can handle varying line heights. */
3654 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
3655 window_scroll_pixel_based (window
, n
, whole
, noerror
);
3657 window_scroll_line_based (window
, n
, whole
, noerror
);
3661 /* Implementation of window_scroll that works based on pixel line
3662 heights. See the comment of window_scroll for parameter
3666 window_scroll_pixel_based (window
, n
, whole
, noerror
)
3673 struct window
*w
= XWINDOW (window
);
3674 struct text_pos start
;
3676 int this_scroll_margin
;
3679 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
3681 /* If PT is not visible in WINDOW, move back one half of
3683 XSETFASTINT (tem
, PT
);
3684 tem
= Fpos_visible_in_window_p (tem
, window
);
3687 /* Move backward half the height of the window. Performance note:
3688 vmotion used here is about 10% faster, but would give wrong
3689 results for variable height lines. */
3690 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3691 it
.current_y
= it
.last_visible_y
;
3692 move_it_vertically (&it
, -it
.last_visible_y
/ 2);
3694 /* The function move_iterator_vertically may move over more than
3695 the specified y-distance. If it->w is small, e.g. a
3696 mini-buffer window, we may end up in front of the window's
3697 display area. This is the case when Start displaying at the
3698 start of the line containing PT in this case. */
3699 if (it
.current_y
<= 0)
3701 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3702 move_it_vertically (&it
, 0);
3706 start
= it
.current
.pos
;
3709 /* If scroll_preserve_screen_position is non-zero, we try to set
3710 point in the same window line as it is now, so get that line. */
3711 if (!NILP (Vscroll_preserve_screen_position
))
3713 start_display (&it
, w
, start
);
3714 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3715 preserve_y
= it
.current_y
;
3720 /* Move iterator it from start the specified distance forward or
3721 backward. The result is the new window start. */
3722 start_display (&it
, w
, start
);
3725 int screen_full
= (it
.last_visible_y
3726 - next_screen_context_lines
* CANON_Y_UNIT (it
.f
));
3727 int direction
= n
< 0 ? -1 : 1;
3728 move_it_vertically (&it
, direction
* screen_full
);
3731 move_it_by_lines (&it
, n
, 1);
3733 /* End if we end up at ZV or BEGV. */
3734 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
3735 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
3739 else if (IT_CHARPOS (it
) == ZV
)
3740 Fsignal (Qend_of_buffer
, Qnil
);
3742 Fsignal (Qbeginning_of_buffer
, Qnil
);
3745 /* Set the window start, and set up the window for redisplay. */
3746 set_marker_restricted (w
->start
, make_number (IT_CHARPOS (it
)), w
->buffer
);
3747 w
->start_at_line_beg
= Fbolp ();
3748 w
->update_mode_line
= Qt
;
3749 XSETFASTINT (w
->last_modified
, 0);
3750 XSETFASTINT (w
->last_overlay_modified
, 0);
3751 /* Set force_start so that redisplay_window will run the
3752 window-scroll-functions. */
3753 w
->force_start
= Qt
;
3755 it
.current_y
= it
.vpos
= 0;
3757 /* Preserve the screen position if we must. */
3758 if (preserve_y
>= 0)
3760 move_it_to (&it
, -1, -1, preserve_y
, -1, MOVE_TO_Y
);
3761 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3765 /* Move PT out of scroll margins. */
3766 this_scroll_margin
= max (0, scroll_margin
);
3767 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->height
) / 4);
3768 this_scroll_margin
*= CANON_Y_UNIT (it
.f
);
3772 /* We moved the window start towards ZV, so PT may be now
3773 in the scroll margin at the top. */
3774 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3775 while (it
.current_y
< this_scroll_margin
)
3776 move_it_by_lines (&it
, 1, 1);
3777 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3781 /* We moved the window start towards BEGV, so PT may be now
3782 in the scroll margin at the bottom. */
3783 move_it_to (&it
, PT
, -1,
3784 it
.last_visible_y
- this_scroll_margin
- 1, -1,
3785 MOVE_TO_POS
| MOVE_TO_Y
);
3787 /* Don't put point on a partially visible line at the end. */
3788 if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
3789 > it
.last_visible_y
)
3790 move_it_by_lines (&it
, -1, 0);
3792 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3798 /* Implementation of window_scroll that works based on screen lines.
3799 See the comment of window_scroll for parameter descriptions. */
3802 window_scroll_line_based (window
, n
, whole
, noerror
)
3808 register struct window
*w
= XWINDOW (window
);
3809 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
3810 register int pos
, pos_byte
;
3811 register int ht
= window_internal_height (w
);
3812 register Lisp_Object tem
;
3816 struct position posit
;
3819 startpos
= marker_position (w
->start
);
3821 posit
= *compute_motion (startpos
, 0, 0, 0,
3823 window_internal_width (w
), XINT (w
->hscroll
),
3825 original_vpos
= posit
.vpos
;
3827 XSETFASTINT (tem
, PT
);
3828 tem
= Fpos_visible_in_window_p (tem
, window
);
3832 Fvertical_motion (make_number (- (ht
/ 2)), window
);
3837 lose
= n
< 0 && PT
== BEGV
;
3838 Fvertical_motion (make_number (n
), window
);
3842 SET_PT_BOTH (opoint
, opoint_byte
);
3849 Fsignal (Qbeginning_of_buffer
, Qnil
);
3854 int this_scroll_margin
= scroll_margin
;
3856 /* Don't use a scroll margin that is negative or too large. */
3857 if (this_scroll_margin
< 0)
3858 this_scroll_margin
= 0;
3860 if (XINT (w
->height
) < 4 * scroll_margin
)
3861 this_scroll_margin
= XINT (w
->height
) / 4;
3863 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
3864 w
->start_at_line_beg
= bolp
;
3865 w
->update_mode_line
= Qt
;
3866 XSETFASTINT (w
->last_modified
, 0);
3867 XSETFASTINT (w
->last_overlay_modified
, 0);
3868 /* Set force_start so that redisplay_window will run
3869 the window-scroll-functions. */
3870 w
->force_start
= Qt
;
3872 if (whole
&& !NILP (Vscroll_preserve_screen_position
))
3874 SET_PT_BOTH (pos
, pos_byte
);
3875 Fvertical_motion (make_number (original_vpos
), window
);
3877 /* If we scrolled forward, put point enough lines down
3878 that it is outside the scroll margin. */
3883 if (this_scroll_margin
> 0)
3885 SET_PT_BOTH (pos
, pos_byte
);
3886 Fvertical_motion (make_number (this_scroll_margin
), window
);
3892 if (top_margin
<= opoint
)
3893 SET_PT_BOTH (opoint
, opoint_byte
);
3894 else if (!NILP (Vscroll_preserve_screen_position
))
3896 SET_PT_BOTH (pos
, pos_byte
);
3897 Fvertical_motion (make_number (original_vpos
), window
);
3900 SET_PT (top_margin
);
3906 /* If we scrolled backward, put point near the end of the window
3907 but not within the scroll margin. */
3908 SET_PT_BOTH (pos
, pos_byte
);
3909 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
3910 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
3913 bottom_margin
= PT
+ 1;
3915 if (bottom_margin
> opoint
)
3916 SET_PT_BOTH (opoint
, opoint_byte
);
3919 if (!NILP (Vscroll_preserve_screen_position
))
3921 SET_PT_BOTH (pos
, pos_byte
);
3922 Fvertical_motion (make_number (original_vpos
), window
);
3925 Fvertical_motion (make_number (-1), window
);
3934 Fsignal (Qend_of_buffer
, Qnil
);
3939 /* Scroll selected_window up or down. If N is nil, scroll a
3940 screen-full which is defined as the height of the window minus
3941 next_screen_context_lines. If N is the symbol `-', scroll.
3942 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
3943 up. This is the guts of Fscroll_up and Fscroll_down. */
3946 scroll_command (n
, direction
)
3950 register int defalt
;
3951 int count
= specpdl_ptr
- specpdl
;
3953 xassert (abs (direction
) == 1);
3955 /* If selected window's buffer isn't current, make it current for
3956 the moment. But don't screw up if window_scroll gets an error. */
3957 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
3959 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
3960 Fset_buffer (XWINDOW (selected_window
)->buffer
);
3962 /* Make redisplay consider other windows than just selected_window. */
3963 ++windows_or_buffers_changed
;
3966 defalt
= (window_internal_height (XWINDOW (selected_window
))
3967 - next_screen_context_lines
);
3968 defalt
= direction
* (defalt
< 1 ? 1 : defalt
);
3971 window_scroll (selected_window
, defalt
, 1, 0);
3972 else if (EQ (n
, Qminus
))
3973 window_scroll (selected_window
, - defalt
, 1, 0);
3976 n
= Fprefix_numeric_value (n
);
3977 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
3980 unbind_to (count
, Qnil
);
3983 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
3984 "Scroll text of current window upward 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 downward.\n\
3987 If ARG is the atom `-', scroll downward 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 ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
3997 "Scroll text of current window down ARG lines; or near full screen if no ARG.\n\
3998 A near full screen is `next-screen-context-lines' less than a full screen.\n\
3999 Negative ARG means scroll upward.\n\
4000 If ARG is the atom `-', scroll upward by nearly full screen.\n\
4001 When calling from a program, supply as argument a number, nil, or `-'.")
4005 scroll_command (arg
, -1);
4009 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
4010 "Return the other window for \"other window scroll\" commands.\n\
4011 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4012 specifies the window.\n\
4013 If `other-window-scroll-buffer' is non-nil, a window\n\
4014 showing that buffer is used.")
4019 if (MINI_WINDOW_P (XWINDOW (selected_window
))
4020 && !NILP (Vminibuf_scroll_window
))
4021 window
= Vminibuf_scroll_window
;
4022 /* If buffer is specified, scroll that buffer. */
4023 else if (!NILP (Vother_window_scroll_buffer
))
4025 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
4027 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
4031 /* Nothing specified; look for a neighboring window on the same
4033 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
4035 if (EQ (window
, selected_window
))
4036 /* That didn't get us anywhere; look for a window on another
4039 window
= Fnext_window (window
, Qnil
, Qt
);
4040 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
4041 && ! EQ (window
, selected_window
));
4044 CHECK_LIVE_WINDOW (window
, 0);
4046 if (EQ (window
, selected_window
))
4047 error ("There is no other window");
4052 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
4053 "Scroll next window upward ARG lines; or near full screen if no ARG.\n\
4054 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4055 The next window is the one below the current one; or the one at the top\n\
4056 if the current one is at the bottom. Negative ARG means scroll downward.\n\
4057 If ARG is the atom `-', scroll downward by nearly full screen.\n\
4058 When calling from a program, supply as argument a number, nil, or `-'.\n\
4060 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4061 specifies the window to scroll.\n\
4062 If `other-window-scroll-buffer' is non-nil, scroll the window\n\
4063 showing that buffer, popping the buffer up if necessary.")
4065 register Lisp_Object arg
;
4067 register Lisp_Object window
;
4068 register int defalt
;
4069 register struct window
*w
;
4070 register int count
= specpdl_ptr
- specpdl
;
4072 window
= Fother_window_for_scrolling ();
4074 w
= XWINDOW (window
);
4075 defalt
= window_internal_height (w
) - next_screen_context_lines
;
4076 if (defalt
< 1) defalt
= 1;
4078 /* Don't screw up if window_scroll gets an error. */
4079 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4080 ++windows_or_buffers_changed
;
4082 Fset_buffer (w
->buffer
);
4083 SET_PT (marker_position (w
->pointm
));
4086 window_scroll (window
, defalt
, 1, 1);
4087 else if (EQ (arg
, Qminus
))
4088 window_scroll (window
, -defalt
, 1, 1);
4093 CHECK_NUMBER (arg
, 0);
4094 window_scroll (window
, XINT (arg
), 0, 1);
4097 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
4098 unbind_to (count
, Qnil
);
4103 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 1, "P",
4104 "Scroll selected window display ARG columns left.\n\
4105 Default for ARG is window width minus 2.")
4107 register Lisp_Object arg
;
4111 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4113 arg
= Fprefix_numeric_value (arg
);
4116 Fset_window_hscroll (selected_window
,
4117 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4121 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 1, "P",
4122 "Scroll selected window display ARG columns right.\n\
4123 Default for ARG is window width minus 2.")
4125 register Lisp_Object arg
;
4128 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4130 arg
= Fprefix_numeric_value (arg
);
4133 Fset_window_hscroll (selected_window
,
4134 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4138 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
4139 "Center point in window and redisplay frame. With ARG, put point on line ARG.\n\
4140 The desired position of point is always relative to the current window.\n\
4141 Just C-u as prefix means put point in the center of the window.\n\
4142 If ARG is omitted or nil, erases the entire frame and then\n\
4143 redraws with point in the center of the current window.")
4145 register Lisp_Object arg
;
4147 register struct window
*w
= XWINDOW (selected_window
);
4148 register int ht
= window_internal_height (w
);
4149 struct position pos
;
4150 struct buffer
*buf
= XBUFFER (w
->buffer
);
4151 struct buffer
*obuf
= current_buffer
;
4155 extern int frame_garbaged
;
4157 Fredraw_frame (w
->frame
);
4158 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
4159 XSETFASTINT (arg
, ht
/ 2);
4161 else if (CONSP (arg
)) /* Just C-u. */
4163 XSETFASTINT (arg
, ht
/ 2);
4167 arg
= Fprefix_numeric_value (arg
);
4168 CHECK_NUMBER (arg
, 0);
4172 XSETINT (arg
, XINT (arg
) + ht
);
4174 set_buffer_internal (buf
);
4175 pos
= *vmotion (PT
, - XINT (arg
), w
);
4177 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
4178 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
4179 || FETCH_BYTE (pos
.bytepos
- 1) == '\n')
4181 w
->force_start
= Qt
;
4182 set_buffer_internal (obuf
);
4187 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
4189 "Position point relative to window.\n\
4190 With no argument, position point at center of window.\n\
4191 An argument specifies vertical position within the window;\n\
4192 zero means top of window, negative means relative to bottom of window.")
4194 register Lisp_Object arg
;
4196 register struct window
*w
= XWINDOW (selected_window
);
4197 register int height
= window_internal_height (w
);
4202 XSETFASTINT (arg
, height
/ 2);
4205 arg
= Fprefix_numeric_value (arg
);
4207 XSETINT (arg
, XINT (arg
) + height
);
4210 start
= marker_position (w
->start
);
4211 XSETWINDOW (window
, w
);
4212 if (start
< BEGV
|| start
> ZV
)
4214 Fvertical_motion (make_number (- (height
/ 2)), window
);
4215 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
4216 w
->start_at_line_beg
= Fbolp ();
4217 w
->force_start
= Qt
;
4220 Fgoto_char (w
->start
);
4222 return Fvertical_motion (arg
, window
);
4227 /***********************************************************************
4228 Window Configuration
4229 ***********************************************************************/
4231 struct save_window_data
4233 EMACS_INT size_from_Lisp_Vector_struct
;
4234 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4235 Lisp_Object frame_width
, frame_height
, frame_menu_bar_lines
;
4236 Lisp_Object frame_tool_bar_lines
;
4237 Lisp_Object selected_frame
;
4238 Lisp_Object current_window
;
4239 Lisp_Object current_buffer
;
4240 Lisp_Object minibuf_scroll_window
;
4241 Lisp_Object root_window
;
4242 Lisp_Object focus_frame
;
4243 /* Record the values of window-min-width and window-min-height
4244 so that window sizes remain consistent with them. */
4245 Lisp_Object min_width
, min_height
;
4246 /* A vector, each of whose elements is a struct saved_window
4248 Lisp_Object saved_windows
;
4251 /* This is saved as a Lisp_Vector */
4254 /* these first two must agree with struct Lisp_Vector in lisp.h */
4255 EMACS_INT size_from_Lisp_Vector_struct
;
4256 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4259 Lisp_Object buffer
, start
, pointm
, mark
;
4260 Lisp_Object left
, top
, width
, height
, hscroll
;
4261 Lisp_Object parent
, prev
;
4262 Lisp_Object start_at_line_beg
;
4263 Lisp_Object display_table
;
4265 #define SAVED_WINDOW_VECTOR_SIZE 14 /* Arg to Fmake_vector */
4267 #define SAVED_WINDOW_N(swv,n) \
4268 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
4270 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
4271 "Return t if OBJECT is a window-configuration object.")
4275 if (WINDOW_CONFIGURATIONP (object
))
4280 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
4281 "Return the frame that CONFIG, a window-configuration object, is about.")
4285 register struct save_window_data
*data
;
4286 struct Lisp_Vector
*saved_windows
;
4288 if (! WINDOW_CONFIGURATIONP (config
))
4289 wrong_type_argument (Qwindow_configuration_p
, config
);
4291 data
= (struct save_window_data
*) XVECTOR (config
);
4292 saved_windows
= XVECTOR (data
->saved_windows
);
4293 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4296 DEFUN ("set-window-configuration", Fset_window_configuration
,
4297 Sset_window_configuration
, 1, 1, 0,
4298 "Set the configuration of windows and buffers as specified by CONFIGURATION.\n\
4299 CONFIGURATION must be a value previously returned\n\
4300 by `current-window-configuration' (which see).\n\
4301 If CONFIGURATION was made from a frame that is now deleted,\n\
4302 only frame-independent values can be restored. In this case,\n\
4303 the return value is nil. Otherwise the value is t.")
4305 Lisp_Object configuration
;
4307 register struct save_window_data
*data
;
4308 struct Lisp_Vector
*saved_windows
;
4309 Lisp_Object new_current_buffer
;
4314 while (!WINDOW_CONFIGURATIONP (configuration
))
4315 wrong_type_argument (Qwindow_configuration_p
, configuration
);
4317 data
= (struct save_window_data
*) XVECTOR (configuration
);
4318 saved_windows
= XVECTOR (data
->saved_windows
);
4320 new_current_buffer
= data
->current_buffer
;
4321 if (NILP (XBUFFER (new_current_buffer
)->name
))
4322 new_current_buffer
= Qnil
;
4325 if (XBUFFER (new_current_buffer
) == current_buffer
)
4330 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4333 /* If f is a dead frame, don't bother rebuilding its window tree.
4334 However, there is other stuff we should still try to do below. */
4335 if (FRAME_LIVE_P (f
))
4337 register struct window
*w
;
4338 register struct saved_window
*p
;
4339 struct window
*root_window
;
4340 struct window
**leaf_windows
;
4344 /* If the frame has been resized since this window configuration was
4345 made, we change the frame to the size specified in the
4346 configuration, restore the configuration, and then resize it
4347 back. We keep track of the prevailing height in these variables. */
4348 int previous_frame_height
= FRAME_HEIGHT (f
);
4349 int previous_frame_width
= FRAME_WIDTH (f
);
4350 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
4351 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
4353 /* The mouse highlighting code could get screwed up
4354 if it runs during this. */
4357 if (XFASTINT (data
->frame_height
) != previous_frame_height
4358 || XFASTINT (data
->frame_width
) != previous_frame_width
)
4359 change_frame_size (f
, XFASTINT (data
->frame_height
),
4360 XFASTINT (data
->frame_width
), 0, 0, 0);
4361 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4362 if (XFASTINT (data
->frame_menu_bar_lines
)
4363 != previous_frame_menu_bar_lines
)
4364 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, make_number (0));
4365 #ifdef HAVE_WINDOW_SYSTEM
4366 if (XFASTINT (data
->frame_tool_bar_lines
)
4367 != previous_frame_tool_bar_lines
)
4368 x_set_tool_bar_lines (f
, data
->frame_tool_bar_lines
, make_number (0));
4372 if (! NILP (XWINDOW (selected_window
)->buffer
))
4374 w
= XWINDOW (selected_window
);
4375 set_marker_both (w
->pointm
,
4377 BUF_PT (XBUFFER (w
->buffer
)),
4378 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4381 windows_or_buffers_changed
++;
4382 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4384 /* Problem: Freeing all matrices and later allocating them again
4385 is a serious redisplay flickering problem. What we would
4386 really like to do is to free only those matrices not reused
4388 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4390 = (struct window
**) alloca (count_windows (root_window
)
4391 * sizeof (struct window
*));
4392 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
4394 /* Temporarily avoid any problems with windows that are smaller
4395 than they are supposed to be. */
4396 window_min_height
= 1;
4397 window_min_width
= 1;
4400 Mark all windows now on frame as "deleted".
4401 Restoring the new configuration "undeletes" any that are in it.
4403 Save their current buffers in their height fields, since we may
4404 need it later, if a buffer saved in the configuration is now
4406 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4408 for (k
= 0; k
< saved_windows
->size
; k
++)
4410 p
= SAVED_WINDOW_N (saved_windows
, k
);
4411 w
= XWINDOW (p
->window
);
4414 if (!NILP (p
->parent
))
4415 w
->parent
= SAVED_WINDOW_N (saved_windows
,
4416 XFASTINT (p
->parent
))->window
;
4420 if (!NILP (p
->prev
))
4422 w
->prev
= SAVED_WINDOW_N (saved_windows
,
4423 XFASTINT (p
->prev
))->window
;
4424 XWINDOW (w
->prev
)->next
= p
->window
;
4429 if (!NILP (w
->parent
))
4431 if (EQ (p
->width
, XWINDOW (w
->parent
)->width
))
4433 XWINDOW (w
->parent
)->vchild
= p
->window
;
4434 XWINDOW (w
->parent
)->hchild
= Qnil
;
4438 XWINDOW (w
->parent
)->hchild
= p
->window
;
4439 XWINDOW (w
->parent
)->vchild
= Qnil
;
4444 /* If we squirreled away the buffer in the window's height,
4446 if (BUFFERP (w
->height
))
4447 w
->buffer
= w
->height
;
4450 w
->width
= p
->width
;
4451 w
->height
= p
->height
;
4452 w
->hscroll
= p
->hscroll
;
4453 w
->display_table
= p
->display_table
;
4454 XSETFASTINT (w
->last_modified
, 0);
4455 XSETFASTINT (w
->last_overlay_modified
, 0);
4457 /* Reinstall the saved buffer and pointers into it. */
4458 if (NILP (p
->buffer
))
4459 w
->buffer
= p
->buffer
;
4462 if (!NILP (XBUFFER (p
->buffer
)->name
))
4463 /* If saved buffer is alive, install it. */
4465 w
->buffer
= p
->buffer
;
4466 w
->start_at_line_beg
= p
->start_at_line_beg
;
4467 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
4468 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
4469 Fset_marker (XBUFFER (w
->buffer
)->mark
,
4470 p
->mark
, w
->buffer
);
4472 /* As documented in Fcurrent_window_configuration, don't
4473 save the location of point in the buffer which was current
4474 when the window configuration was recorded. */
4475 if (!EQ (p
->buffer
, new_current_buffer
)
4476 && XBUFFER (p
->buffer
) == current_buffer
)
4477 Fgoto_char (w
->pointm
);
4479 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
4480 /* Else unless window has a live buffer, get one. */
4482 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
4483 /* This will set the markers to beginning of visible
4485 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
4486 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
4487 w
->start_at_line_beg
= Qt
;
4490 /* Keeping window's old buffer; make sure the markers
4493 /* Set window markers at start of visible range. */
4494 if (XMARKER (w
->start
)->buffer
== 0)
4495 set_marker_restricted (w
->start
, make_number (0),
4497 if (XMARKER (w
->pointm
)->buffer
== 0)
4498 set_marker_restricted_both (w
->pointm
, w
->buffer
,
4499 BUF_PT (XBUFFER (w
->buffer
)),
4500 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4501 w
->start_at_line_beg
= Qt
;
4506 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
4507 Fselect_window (data
->current_window
);
4508 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
4511 if (NILP (data
->focus_frame
)
4512 || (FRAMEP (data
->focus_frame
)
4513 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
4514 Fredirect_frame_focus (frame
, data
->focus_frame
);
4516 #if 0 /* I don't understand why this is needed, and it causes problems
4517 when the frame's old selected window has been deleted. */
4518 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
4519 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
4523 /* Set the screen height to the value it had before this function. */
4524 if (previous_frame_height
!= FRAME_HEIGHT (f
)
4525 || previous_frame_width
!= FRAME_WIDTH (f
))
4526 change_frame_size (f
, previous_frame_height
, previous_frame_width
,
4528 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4529 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
4530 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
4532 #ifdef HAVE_WINDOW_SYSTEM
4533 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
4534 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
4539 /* Now, free glyph matrices in windows that were not reused. */
4540 for (i
= 0; i
< n_leaf_windows
; ++i
)
4541 if (NILP (leaf_windows
[i
]->buffer
))
4543 /* Assert it's not reused as a combination. */
4544 xassert (NILP (leaf_windows
[i
]->hchild
)
4545 && NILP (leaf_windows
[i
]->vchild
));
4546 free_window_matrices (leaf_windows
[i
]);
4547 SET_FRAME_GARBAGED (f
);
4554 /* Fselect_window will have made f the selected frame, so we
4555 reselect the proper frame here. Fhandle_switch_frame will change the
4556 selected window too, but that doesn't make the call to
4557 Fselect_window above totally superfluous; it still sets f's
4559 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
4560 do_switch_frame (data
->selected_frame
, Qnil
, 0);
4562 if (! NILP (Vwindow_configuration_change_hook
)
4563 && ! NILP (Vrun_hooks
))
4564 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
4567 if (!NILP (new_current_buffer
))
4569 Fset_buffer (new_current_buffer
);
4571 /* If the buffer that is current now is the same
4572 that was current before setting the window configuration,
4573 don't alter its PT. */
4578 /* Restore the minimum heights recorded in the configuration. */
4579 window_min_height
= XINT (data
->min_height
);
4580 window_min_width
= XINT (data
->min_width
);
4582 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
4584 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
4587 /* Mark all windows now on frame as deleted
4588 by setting their buffers to nil. */
4591 delete_all_subwindows (w
)
4592 register struct window
*w
;
4594 if (!NILP (w
->next
))
4595 delete_all_subwindows (XWINDOW (w
->next
));
4596 if (!NILP (w
->vchild
))
4597 delete_all_subwindows (XWINDOW (w
->vchild
));
4598 if (!NILP (w
->hchild
))
4599 delete_all_subwindows (XWINDOW (w
->hchild
));
4601 w
->height
= w
->buffer
; /* See Fset_window_configuration for excuse. */
4603 if (!NILP (w
->buffer
))
4606 /* We set all three of these fields to nil, to make sure that we can
4607 distinguish this dead window from any live window. Live leaf
4608 windows will have buffer set, and combination windows will have
4609 vchild or hchild set. */
4616 count_windows (window
)
4617 register struct window
*window
;
4619 register int count
= 1;
4620 if (!NILP (window
->next
))
4621 count
+= count_windows (XWINDOW (window
->next
));
4622 if (!NILP (window
->vchild
))
4623 count
+= count_windows (XWINDOW (window
->vchild
));
4624 if (!NILP (window
->hchild
))
4625 count
+= count_windows (XWINDOW (window
->hchild
));
4630 /* Fill vector FLAT with leaf windows under W, starting at index I.
4631 Value is last index + 1. */
4634 get_leaf_windows (w
, flat
, i
)
4636 struct window
**flat
;
4641 if (!NILP (w
->hchild
))
4642 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
4643 else if (!NILP (w
->vchild
))
4644 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
4648 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4655 /* Return a pointer to the glyph W's physical cursor is on. Value is
4656 null if W's current matrix is invalid, so that no meaningfull glyph
4660 get_phys_cursor_glyph (w
)
4663 struct glyph_row
*row
;
4664 struct glyph
*glyph
;
4666 if (w
->phys_cursor
.vpos
>= 0
4667 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
4668 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
4670 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
4671 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
4680 save_window_save (window
, vector
, i
)
4682 struct Lisp_Vector
*vector
;
4685 register struct saved_window
*p
;
4686 register struct window
*w
;
4687 register Lisp_Object tem
;
4689 for (;!NILP (window
); window
= w
->next
)
4691 p
= SAVED_WINDOW_N (vector
, i
);
4692 w
= XWINDOW (window
);
4694 XSETFASTINT (w
->temslot
, i
++);
4696 p
->buffer
= w
->buffer
;
4699 p
->width
= w
->width
;
4700 p
->height
= w
->height
;
4701 p
->hscroll
= w
->hscroll
;
4702 p
->display_table
= w
->display_table
;
4703 if (!NILP (w
->buffer
))
4705 /* Save w's value of point in the window configuration.
4706 If w is the selected window, then get the value of point
4707 from the buffer; pointm is garbage in the selected window. */
4708 if (EQ (window
, selected_window
))
4710 p
->pointm
= Fmake_marker ();
4711 set_marker_both (p
->pointm
, w
->buffer
,
4712 BUF_PT (XBUFFER (w
->buffer
)),
4713 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4716 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
4718 p
->start
= Fcopy_marker (w
->start
, Qnil
);
4719 p
->start_at_line_beg
= w
->start_at_line_beg
;
4721 tem
= XBUFFER (w
->buffer
)->mark
;
4722 p
->mark
= Fcopy_marker (tem
, Qnil
);
4729 p
->start_at_line_beg
= Qnil
;
4732 if (NILP (w
->parent
))
4735 p
->parent
= XWINDOW (w
->parent
)->temslot
;
4740 p
->prev
= XWINDOW (w
->prev
)->temslot
;
4742 if (!NILP (w
->vchild
))
4743 i
= save_window_save (w
->vchild
, vector
, i
);
4744 if (!NILP (w
->hchild
))
4745 i
= save_window_save (w
->hchild
, vector
, i
);
4751 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
4752 Scurrent_window_configuration
, 0, 1, 0,
4753 "Return an object representing the current window configuration of FRAME.\n\
4754 If FRAME is nil or omitted, use the selected frame.\n\
4755 This describes the number of windows, their sizes and current buffers,\n\
4756 and for each displayed buffer, where display starts, and the positions of\n\
4757 point and mark. An exception is made for point in the current buffer:\n\
4758 its value is -not- saved.\n\
4759 This also records the currently selected frame, and FRAME's focus\n\
4760 redirection (see `redirect-frame-focus').")
4764 register Lisp_Object tem
;
4765 register int n_windows
;
4766 register struct save_window_data
*data
;
4767 register struct Lisp_Vector
*vec
;
4772 frame
= selected_frame
;
4773 CHECK_LIVE_FRAME (frame
, 0);
4776 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4777 vec
= allocate_vectorlike (VECSIZE (struct save_window_data
));
4778 for (i
= 0; i
< VECSIZE (struct save_window_data
); i
++)
4779 vec
->contents
[i
] = Qnil
;
4780 vec
->size
= VECSIZE (struct save_window_data
);
4781 data
= (struct save_window_data
*)vec
;
4783 XSETFASTINT (data
->frame_width
, FRAME_WIDTH (f
));
4784 XSETFASTINT (data
->frame_height
, FRAME_HEIGHT (f
));
4785 XSETFASTINT (data
->frame_menu_bar_lines
, FRAME_MENU_BAR_LINES (f
));
4786 XSETFASTINT (data
->frame_tool_bar_lines
, FRAME_TOOL_BAR_LINES (f
));
4787 data
->selected_frame
= selected_frame
;
4788 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
4789 XSETBUFFER (data
->current_buffer
, current_buffer
);
4790 data
->minibuf_scroll_window
= Vminibuf_scroll_window
;
4791 data
->root_window
= FRAME_ROOT_WINDOW (f
);
4792 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
4793 XSETINT (data
->min_height
, window_min_height
);
4794 XSETINT (data
->min_width
, window_min_width
);
4795 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
4796 data
->saved_windows
= tem
;
4797 for (i
= 0; i
< n_windows
; i
++)
4798 XVECTOR (tem
)->contents
[i
]
4799 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
4800 save_window_save (FRAME_ROOT_WINDOW (f
),
4802 XSETWINDOW_CONFIGURATION (tem
, data
);
4806 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
4808 "Execute body, preserving window sizes and contents.\n\
4809 Restore which buffer appears in which window, where display starts,\n\
4810 and the value of point and mark for each window.\n\
4811 Also restore which buffer is current.\n\
4812 But do not preserve point in the current buffer.\n\
4813 Does not restore the value of point in current buffer.")
4817 register Lisp_Object val
;
4818 register int count
= specpdl_ptr
- specpdl
;
4820 record_unwind_protect (Fset_window_configuration
,
4821 Fcurrent_window_configuration (Qnil
));
4822 val
= Fprogn (args
);
4823 return unbind_to (count
, val
);
4827 /***********************************************************************
4829 ***********************************************************************/
4831 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
4833 "Set width of marginal areas of window WINDOW.\n\
4834 If window is nil or omitted, set margins of the currently selected window.\n\
4835 First parameter LEFT-WIDTH specifies the number of character\n\
4836 cells to reserve for the left marginal area. Second parameter\n\
4837 RIGHT-WIDTH does the same for the right marginal area.\n\
4838 A nil width parameter means no margin.")
4839 (window
, left
, right
)
4840 Lisp_Object window
, left
, right
;
4842 struct window
*w
= decode_window (window
);
4845 CHECK_NUMBER_OR_FLOAT (left
, 1);
4847 CHECK_NUMBER_OR_FLOAT (right
, 2);
4849 /* Check widths < 0 and translate a zero width to nil.
4850 Margins that are too wide have to be checked elsewhere. */
4851 if ((INTEGERP (left
) && XINT (left
) < 0)
4852 || (FLOATP (left
) && XFLOAT_DATA (left
) <= 0))
4853 XSETFASTINT (left
, 0);
4854 if (INTEGERP (left
) && XFASTINT (left
) == 0)
4857 if ((INTEGERP (right
) && XINT (right
) < 0)
4858 || (FLOATP (right
) && XFLOAT_DATA (right
) <= 0))
4859 XSETFASTINT (right
, 0);
4860 if (INTEGERP (right
) && XFASTINT (right
) == 0)
4863 w
->left_margin_width
= left
;
4864 w
->right_margin_width
= right
;
4866 ++windows_or_buffers_changed
;
4867 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
4872 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
4874 "Get width of marginal areas of window WINDOW.\n\
4875 If WINDOW is omitted or nil, use the currently selected window.\n\
4876 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).\n\
4877 If a marginal area does not exist, its width will be returned\n\
4882 struct window
*w
= decode_window (window
);
4883 return Fcons (w
->left_margin_width
, w
->right_margin_width
);
4888 /***********************************************************************
4890 ***********************************************************************/
4892 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 1, 0,
4893 "Return the amount by which WINDOW is scrolled vertically.\n\
4894 Use the selected window if WINDOW is nil or omitted.\n\
4895 Value is a multiple of the canonical character height of WINDOW.")
4904 window
= selected_window
;
4906 CHECK_WINDOW (window
, 0);
4907 w
= XWINDOW (window
);
4908 f
= XFRAME (w
->frame
);
4910 if (FRAME_WINDOW_P (f
))
4911 result
= CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
);
4913 result
= make_number (0);
4918 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
4920 "Set amount by which WINDOW should be scrolled vertically to VSCROLL.\n\
4921 WINDOW nil or omitted means use the selected window. VSCROLL is a\n\
4922 non-negative multiple of the canonical character height of WINDOW.")
4924 Lisp_Object window
, vscroll
;
4930 window
= selected_window
;
4932 CHECK_WINDOW (window
, 0);
4933 CHECK_NUMBER_OR_FLOAT (vscroll
, 1);
4935 w
= XWINDOW (window
);
4936 f
= XFRAME (w
->frame
);
4938 if (FRAME_WINDOW_P (f
))
4940 int old_dy
= w
->vscroll
;
4942 w
->vscroll
= - CANON_Y_UNIT (f
) * XFLOATINT (vscroll
);
4943 w
->vscroll
= min (w
->vscroll
, 0);
4945 /* Adjust glyph matrix of the frame if the virtual display
4946 area becomes larger than before. */
4947 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
4950 /* Prevent redisplay shortcuts. */
4951 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
4954 return Fwindow_vscroll (window
);
4958 /* Call FN for all leaf windows on frame F. FN is called with the
4959 first argument being a pointer to the leaf window, and with
4960 additional arguments A1..A4. */
4963 foreach_window (f
, fn
, a1
, a2
, a3
, a4
)
4968 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, a1
, a2
, a3
, a4
);
4972 /* Helper function for foreach_window. Call FN for all leaf windows
4973 reachable from W. FN is called with the first argument being a
4974 pointer to the leaf window, and with additional arguments A1..A4. */
4977 foreach_window_1 (w
, fn
, a1
, a2
, a3
, a4
)
4984 if (!NILP (w
->hchild
))
4985 foreach_window_1 (XWINDOW (w
->hchild
), fn
, a1
, a2
, a3
, a4
);
4986 else if (!NILP (w
->vchild
))
4987 foreach_window_1 (XWINDOW (w
->vchild
), fn
, a1
, a2
, a3
, a4
);
4989 fn (w
, a1
, a2
, a3
, a4
);
4991 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4996 /* Freeze or unfreeze the window start of W if unless it is a
4997 mini-window or the selected window. FREEZE_P non-zero means freeze
4998 the window start. */
5001 freeze_window_start (w
, freeze_p
)
5005 if (w
== XWINDOW (selected_window
)
5006 || MINI_WINDOW_P (w
)
5007 || (MINI_WINDOW_P (XWINDOW (selected_window
))
5008 && w
== XWINDOW (Vminibuf_scroll_window
)))
5011 w
->frozen_window_start_p
= freeze_p
;
5015 /* Freeze or unfreeze the window starts of all leaf windows on frame
5016 F, except the selected window and a mini-window. FREEZE_P non-zero
5017 means freeze the window start. */
5020 freeze_window_starts (f
, freeze_p
)
5024 foreach_window (f
, freeze_window_start
, freeze_p
);
5028 /***********************************************************************
5030 ***********************************************************************/
5032 /* Return 1 if window configurations C1 and C2
5033 describe the same state of affairs. This is used by Fequal. */
5036 compare_window_configurations (c1
, c2
, ignore_positions
)
5038 int ignore_positions
;
5040 register struct save_window_data
*d1
, *d2
;
5041 struct Lisp_Vector
*sw1
, *sw2
;
5044 d1
= (struct save_window_data
*) XVECTOR (c1
);
5045 d2
= (struct save_window_data
*) XVECTOR (c2
);
5046 sw1
= XVECTOR (d1
->saved_windows
);
5047 sw2
= XVECTOR (d2
->saved_windows
);
5049 if (! EQ (d1
->frame_width
, d2
->frame_width
))
5051 if (! EQ (d1
->frame_height
, d2
->frame_height
))
5053 if (! EQ (d1
->frame_menu_bar_lines
, d2
->frame_menu_bar_lines
))
5055 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
5057 /* Don't compare the current_window field directly.
5058 Instead see w1_is_current and w2_is_current, below. */
5059 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
5061 if (! ignore_positions
)
5062 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
5064 /* Don't compare the root_window field.
5065 We don't require the two configurations
5066 to use the same window object,
5067 and the two root windows must be equivalent
5068 if everything else compares equal. */
5069 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
5071 if (! EQ (d1
->min_width
, d2
->min_width
))
5073 if (! EQ (d1
->min_height
, d2
->min_height
))
5076 /* Verify that the two confis have the same number of windows. */
5077 if (sw1
->size
!= sw2
->size
)
5080 for (i
= 0; i
< sw1
->size
; i
++)
5082 struct saved_window
*p1
, *p2
;
5083 int w1_is_current
, w2_is_current
;
5085 p1
= SAVED_WINDOW_N (sw1
, i
);
5086 p2
= SAVED_WINDOW_N (sw2
, i
);
5088 /* Verify that the current windows in the two
5089 configurations correspond to each other. */
5090 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
5091 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
5093 if (w1_is_current
!= w2_is_current
)
5096 /* Verify that the corresponding windows do match. */
5097 if (! EQ (p1
->buffer
, p2
->buffer
))
5099 if (! EQ (p1
->left
, p2
->left
))
5101 if (! EQ (p1
->top
, p2
->top
))
5103 if (! EQ (p1
->width
, p2
->width
))
5105 if (! EQ (p1
->height
, p2
->height
))
5107 if (! EQ (p1
->display_table
, p2
->display_table
))
5109 if (! EQ (p1
->parent
, p2
->parent
))
5111 if (! EQ (p1
->prev
, p2
->prev
))
5113 if (! ignore_positions
)
5115 if (! EQ (p1
->hscroll
, p2
->hscroll
))
5117 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
5119 if (NILP (Fequal (p1
->start
, p2
->start
)))
5121 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
5123 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
5131 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
5132 Scompare_window_configurations
, 2, 2, 0,
5133 "Compare two window configurations as regards the structure of windows.\n\
5134 This function ignores details such as the values of point and mark\n\
5135 and scrolling positions.")
5139 if (compare_window_configurations (x
, y
, 1))
5147 struct frame
*f
= make_terminal_frame ();
5148 XSETFRAME (selected_frame
, f
);
5149 Vterminal_frame
= selected_frame
;
5150 minibuf_window
= f
->minibuffer_window
;
5151 selected_window
= f
->selected_window
;
5152 last_nonminibuf_frame
= f
;
5154 window_initialized
= 1;
5160 Qleft_bitmap_area
= intern ("left-bitmap-area");
5161 staticpro (&Qleft_bitmap_area
);
5162 Qright_bitmap_area
= intern ("right-bitmap-area");
5163 staticpro (&Qright_bitmap_area
);
5165 Qwindow_size_fixed
= intern ("window-size-fixed");
5166 staticpro (&Qwindow_size_fixed
);
5168 staticpro (&Qwindow_configuration_change_hook
);
5169 Qwindow_configuration_change_hook
5170 = intern ("window-configuration-change-hook");
5172 Qwindowp
= intern ("windowp");
5173 staticpro (&Qwindowp
);
5175 Qwindow_configuration_p
= intern ("window-configuration-p");
5176 staticpro (&Qwindow_configuration_p
);
5178 Qwindow_live_p
= intern ("window-live-p");
5179 staticpro (&Qwindow_live_p
);
5181 Qtemp_buffer_show_hook
= intern ("temp-buffer-show-hook");
5182 staticpro (&Qtemp_buffer_show_hook
);
5184 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
5185 "Non-nil means call as function to display a help buffer.\n\
5186 The function is called with one argument, the buffer to be displayed.\n\
5187 Used by `with-output-to-temp-buffer'.\n\
5188 If this function is used, then it must do the entire job of showing\n\
5189 the buffer; `temp-buffer-show-hook' is not run unless this function runs it.");
5190 Vtemp_buffer_show_function
= Qnil
;
5192 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
5193 "If non-nil, function to call to handle `display-buffer'.\n\
5194 It will receive two args, the buffer and a flag which if non-nil means\n\
5195 that the currently selected window is not acceptable.\n\
5196 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
5197 work using this function.");
5198 Vdisplay_buffer_function
= Qnil
;
5200 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
5201 "Non-nil means it is the window that C-M-v in minibuffer should scroll.");
5202 Vminibuf_scroll_window
= Qnil
;
5204 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
5205 "If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.");
5206 Vother_window_scroll_buffer
= Qnil
;
5208 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
5209 "*Non-nil means `display-buffer' should make a separate frame.");
5212 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
5213 "Function to call to handle automatic new frame creation.\n\
5214 It is called with no arguments and should return a newly created frame.\n\
5216 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'\n\
5217 where `pop-up-frame-alist' would hold the default frame parameters.");
5218 Vpop_up_frame_function
= Qnil
;
5220 DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names
,
5221 "*List of buffer names that should have their own special frames.\n\
5222 Displaying a buffer whose name is in this list makes a special frame for it\n\
5223 using `special-display-function'. See also `special-display-regexps'.\n\
5225 An element of the list can be a list instead of just a string.\n\
5226 There are two ways to use a list as an element:\n\
5227 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)\n\
5228 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5229 In the latter case, FUNCTION is called with BUFFER as the first argument,\n\
5230 followed by OTHER-ARGS--it can display BUFFER in any way it likes.\n\
5231 All this is done by the function found in `special-display-function'.\n\
5233 If this variable appears \"not to work\", because you add a name to it\n\
5234 but that buffer still appears in the selected window, look at the\n\
5235 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5236 Those variables take precedence over this one.");
5237 Vspecial_display_buffer_names
= Qnil
;
5239 DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps
,
5240 "*List of regexps saying which buffers should have their own special frames.\n\
5241 If a buffer name matches one of these regexps, it gets its own frame.\n\
5242 Displaying a buffer whose name is in this list makes a special frame for it\n\
5243 using `special-display-function'.\n\
5245 An element of the list can be a list instead of just a string.\n\
5246 There are two ways to use a list as an element:\n\
5247 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)\n\
5248 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5249 In the latter case, FUNCTION is called with the buffer as first argument,\n\
5250 followed by OTHER-ARGS--it can display the buffer in any way it likes.\n\
5251 All this is done by the function found in `special-display-function'.\n\
5253 If this variable appears \"not to work\", because you add a regexp to it\n\
5254 but the matching buffers still appear in the selected window, look at the\n\
5255 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5256 Those variables take precedence over this one.");
5257 Vspecial_display_regexps
= Qnil
;
5259 DEFVAR_LISP ("special-display-function", &Vspecial_display_function
,
5260 "Function to call to make a new frame for a special buffer.\n\
5261 It is called with two arguments, the buffer and optional buffer specific\n\
5262 data, and should return a window displaying that buffer.\n\
5263 The default value makes a separate frame for the buffer,\n\
5264 using `special-display-frame-alist' to specify the frame parameters.\n\
5266 A buffer is special if its is listed in `special-display-buffer-names'\n\
5267 or matches a regexp in `special-display-regexps'.");
5268 Vspecial_display_function
= Qnil
;
5270 DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names
,
5271 "*List of buffer names that should appear in the selected window.\n\
5272 Displaying one of these buffers using `display-buffer' or `pop-to-buffer'\n\
5273 switches to it in the selected window, rather than making it appear\n\
5274 in some other window.\n\
5276 An element of the list can be a cons cell instead of just a string.\n\
5277 Then the car must be a string, which specifies the buffer name.\n\
5278 This is for compatibility with `special-display-buffer-names';\n\
5279 the cdr of the cons cell is ignored.\n\
5281 See also `same-window-regexps'.");
5282 Vsame_window_buffer_names
= Qnil
;
5284 DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps
,
5285 "*List of regexps saying which buffers should appear in the selected window.\n\
5286 If a buffer name matches one of these regexps, then displaying it\n\
5287 using `display-buffer' or `pop-to-buffer' switches to it\n\
5288 in the selected window, rather than making it appear in some other window.\n\
5290 An element of the list can be a cons cell instead of just a string.\n\
5291 Then the car must be a string, which specifies the buffer name.\n\
5292 This is for compatibility with `special-display-buffer-names';\n\
5293 the cdr of the cons cell is ignored.\n\
5295 See also `same-window-buffer-names'.");
5296 Vsame_window_regexps
= Qnil
;
5298 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
5299 "*Non-nil means display-buffer should make new windows.");
5302 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
5303 "*Number of lines of continuity when scrolling by screenfuls.");
5304 next_screen_context_lines
= 2;
5306 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
5307 "*display-buffer would prefer to split the largest window if this large.\n\
5308 If there is only one window, it is split regardless of this value.");
5309 split_height_threshold
= 500;
5311 DEFVAR_INT ("window-min-height", &window_min_height
,
5312 "*Delete any window less than this tall (including its mode line).");
5313 window_min_height
= 4;
5315 DEFVAR_INT ("window-min-width", &window_min_width
,
5316 "*Delete any window less than this wide.");
5317 window_min_width
= 10;
5319 DEFVAR_LISP ("scroll-preserve-screen-position",
5320 &Vscroll_preserve_screen_position
,
5321 "*Nonzero means scroll commands move point to keep its screen line unchanged.");
5322 Vscroll_preserve_screen_position
= Qnil
;
5324 DEFVAR_LISP ("window-configuration-change-hook",
5325 &Vwindow_configuration_change_hook
,
5326 "Functions to call when window configuration changes.\n\
5327 The selected frame is the one whose configuration has changed.");
5328 Vwindow_configuration_change_hook
= Qnil
;
5330 defsubr (&Sselected_window
);
5331 defsubr (&Sminibuffer_window
);
5332 defsubr (&Swindow_minibuffer_p
);
5333 defsubr (&Swindowp
);
5334 defsubr (&Swindow_live_p
);
5335 defsubr (&Spos_visible_in_window_p
);
5336 defsubr (&Swindow_buffer
);
5337 defsubr (&Swindow_height
);
5338 defsubr (&Swindow_width
);
5339 defsubr (&Swindow_hscroll
);
5340 defsubr (&Sset_window_hscroll
);
5341 defsubr (&Swindow_redisplay_end_trigger
);
5342 defsubr (&Sset_window_redisplay_end_trigger
);
5343 defsubr (&Swindow_edges
);
5344 defsubr (&Scoordinates_in_window_p
);
5345 defsubr (&Swindow_at
);
5346 defsubr (&Swindow_point
);
5347 defsubr (&Swindow_start
);
5348 defsubr (&Swindow_end
);
5349 defsubr (&Sset_window_point
);
5350 defsubr (&Sset_window_start
);
5351 defsubr (&Swindow_dedicated_p
);
5352 defsubr (&Sset_window_dedicated_p
);
5353 defsubr (&Swindow_display_table
);
5354 defsubr (&Sset_window_display_table
);
5355 defsubr (&Snext_window
);
5356 defsubr (&Sprevious_window
);
5357 defsubr (&Sother_window
);
5358 defsubr (&Sget_lru_window
);
5359 defsubr (&Sget_largest_window
);
5360 defsubr (&Sget_buffer_window
);
5361 defsubr (&Sdelete_other_windows
);
5362 defsubr (&Sdelete_windows_on
);
5363 defsubr (&Sreplace_buffer_in_windows
);
5364 defsubr (&Sdelete_window
);
5365 defsubr (&Sset_window_buffer
);
5366 defsubr (&Sselect_window
);
5367 defsubr (&Sspecial_display_p
);
5368 defsubr (&Ssame_window_p
);
5369 defsubr (&Sdisplay_buffer
);
5370 defsubr (&Ssplit_window
);
5371 defsubr (&Senlarge_window
);
5372 defsubr (&Sshrink_window
);
5373 defsubr (&Sscroll_up
);
5374 defsubr (&Sscroll_down
);
5375 defsubr (&Sscroll_left
);
5376 defsubr (&Sscroll_right
);
5377 defsubr (&Sother_window_for_scrolling
);
5378 defsubr (&Sscroll_other_window
);
5379 defsubr (&Srecenter
);
5380 defsubr (&Smove_to_window_line
);
5381 defsubr (&Swindow_configuration_p
);
5382 defsubr (&Swindow_configuration_frame
);
5383 defsubr (&Sset_window_configuration
);
5384 defsubr (&Scurrent_window_configuration
);
5385 defsubr (&Ssave_window_excursion
);
5386 defsubr (&Sset_window_margins
);
5387 defsubr (&Swindow_margins
);
5388 defsubr (&Swindow_vscroll
);
5389 defsubr (&Sset_window_vscroll
);
5390 defsubr (&Scompare_window_configurations
);
5396 initial_define_key (control_x_map
, '1', "delete-other-windows");
5397 initial_define_key (control_x_map
, '2', "split-window");
5398 initial_define_key (control_x_map
, '0', "delete-window");
5399 initial_define_key (control_x_map
, 'o', "other-window");
5400 initial_define_key (control_x_map
, '^', "enlarge-window");
5401 initial_define_key (control_x_map
, '<', "scroll-left");
5402 initial_define_key (control_x_map
, '>', "scroll-right");
5404 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
5405 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
5406 initial_define_key (meta_map
, 'v', "scroll-down");
5408 initial_define_key (global_map
, Ctl('L'), "recenter");
5409 initial_define_key (meta_map
, 'r', "move-to-window-line");