1 /* Window creation, deletion and examination for GNU Emacs.
2 Does not include redisplay.
3 Copyright (C) 1985,86,87,93,94,95,96,97,1998 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
32 #include "dispextern.h"
33 #include "blockinput.h"
34 #include "intervals.h"
38 #endif /* HAVE_X_WINDOWS */
47 #define max(a, b) ((a) < (b) ? (b) : (a))
51 Lisp_Object Qwindowp
, Qwindow_live_p
, Qwindow_configuration_p
;
52 Lisp_Object Qwindow_size_fixed
, Qleft_bitmap_area
, Qright_bitmap_area
;
53 extern Lisp_Object Qheight
, Qwidth
;
55 static struct window
*decode_window
P_ ((Lisp_Object
));
56 static Lisp_Object select_window_1
P_ ((Lisp_Object
, int));
57 static int count_windows
P_ ((struct window
*));
58 static int get_leaf_windows
P_ ((struct window
*, struct window
**, int));
59 static void window_scroll
P_ ((Lisp_Object
, int, int, int));
60 static void window_scroll_pixel_based
P_ ((Lisp_Object
, int, int, int));
61 static void window_scroll_line_based
P_ ((Lisp_Object
, int, int, int));
62 static int window_min_size_1
P_ ((struct window
*, int));
63 static int window_min_size
P_ ((struct window
*, int, int, int *));
64 static void size_window
P_ ((Lisp_Object
, int, int, int));
65 static void foreach_window_1
P_ ((struct window
*, void (*fn
) (), int, int,
67 static void freeze_window_start
P_ ((struct window
*, int));
68 static int window_fixed_size_p
P_ ((struct window
*, int, int));
69 static void enlarge_window
P_ ((Lisp_Object
, int, int));
72 /* This is the window in which the terminal's cursor should
73 be left when nothing is being done with it. This must
74 always be a leaf window, and its buffer is selected by
75 the top level editing loop at the end of each command.
77 This value is always the same as
78 FRAME_SELECTED_WINDOW (selected_frame). */
80 Lisp_Object selected_window
;
82 /* The mini-buffer window of the selected frame.
83 Note that you cannot test for mini-bufferness of an arbitrary window
84 by comparing against this; but you can test for mini-bufferness of
85 the selected window. */
87 Lisp_Object minibuf_window
;
89 /* Non-nil means it is the window for C-M-v to scroll
90 when the mini-buffer is selected. */
92 Lisp_Object Vminibuf_scroll_window
;
94 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
96 Lisp_Object Vother_window_scroll_buffer
;
98 /* Non-nil means it's function to call to display temp buffers. */
100 Lisp_Object Vtemp_buffer_show_function
;
102 /* If a window gets smaller than either of these, it is removed. */
104 int window_min_height
;
105 int window_min_width
;
107 /* Nonzero implies Fdisplay_buffer should create windows. */
111 /* Nonzero implies make new frames for Fdisplay_buffer. */
115 /* Non-nil means use this function instead of default */
117 Lisp_Object Vpop_up_frame_function
;
119 /* Function to call to handle Fdisplay_buffer. */
121 Lisp_Object Vdisplay_buffer_function
;
123 /* List of buffer *names* for buffers that should have their own frames. */
125 Lisp_Object Vspecial_display_buffer_names
;
127 /* List of regexps for buffer names that should have their own frames. */
129 Lisp_Object Vspecial_display_regexps
;
131 /* Function to pop up a special frame. */
133 Lisp_Object Vspecial_display_function
;
135 /* List of buffer *names* for buffers to appear in selected window. */
137 Lisp_Object Vsame_window_buffer_names
;
139 /* List of regexps for buffer names to appear in selected window. */
141 Lisp_Object Vsame_window_regexps
;
143 /* Hook run at end of temp_output_buffer_show. */
145 Lisp_Object Qtemp_buffer_show_hook
;
147 /* Fdisplay_buffer always splits the largest window
148 if that window is more than this high. */
150 int split_height_threshold
;
152 /* Number of lines of continuity in scrolling by screenfuls. */
154 int next_screen_context_lines
;
156 /* Incremented for each window created. */
158 static int sequence_number
;
160 /* Nonzero after init_window_once has finished. */
162 static int window_initialized
;
164 /* Hook to run when window config changes. */
166 Lisp_Object Qwindow_configuration_change_hook
;
167 Lisp_Object Vwindow_configuration_change_hook
;
169 /* Nonzero means scroll commands try to put point
170 at the same screen height as previously. */
172 Lisp_Object Vscroll_preserve_screen_position
;
174 #if 0 /* This isn't used anywhere. */
175 /* Nonzero means we can split a frame even if it is "unsplittable". */
176 static int inhibit_frame_unsplittable
;
179 #define min(a, b) ((a) < (b) ? (a) : (b))
181 extern int scroll_margin
;
183 extern Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
185 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
186 "Returns t if OBJECT is a window.")
190 return WINDOWP (object
) ? Qt
: Qnil
;
193 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
194 "Returns t if OBJECT is a window which is currently visible.")
198 return (WINDOWP (object
) && ! NILP (XWINDOW (object
)->buffer
) ? Qt
: Qnil
);
205 register struct window
*p
;
206 register struct Lisp_Vector
*vec
;
209 vec
= allocate_vectorlike ((EMACS_INT
) VECSIZE (struct window
));
210 for (i
= 0; i
< VECSIZE (struct window
); i
++)
211 vec
->contents
[i
] = Qnil
;
212 vec
->size
= VECSIZE (struct window
);
213 p
= (struct window
*) vec
;
214 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
215 XSETFASTINT (p
->left
, 0);
216 XSETFASTINT (p
->top
, 0);
217 XSETFASTINT (p
->height
, 0);
218 XSETFASTINT (p
->width
, 0);
219 XSETFASTINT (p
->hscroll
, 0);
220 p
->orig_top
= p
->orig_height
= Qnil
;
221 p
->start
= Fmake_marker ();
222 p
->pointm
= Fmake_marker ();
223 XSETFASTINT (p
->use_time
, 0);
225 p
->display_table
= Qnil
;
227 p
->pseudo_window_p
= 0;
228 bzero (&p
->cursor
, sizeof (p
->cursor
));
229 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
230 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
231 p
->desired_matrix
= p
->current_matrix
= 0;
232 p
->phys_cursor_type
= -1;
233 p
->must_be_updated_p
= 0;
234 XSETFASTINT (p
->window_end_vpos
, 0);
235 XSETFASTINT (p
->window_end_pos
, 0);
236 p
->window_end_valid
= Qnil
;
239 XSETFASTINT (p
->last_point
, 0);
240 p
->frozen_window_start_p
= 0;
244 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
245 "Return the window that the cursor now appears in and commands apply to.")
248 return selected_window
;
251 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
252 "Return the window used now for minibuffers.\n\
253 If the optional argument FRAME is specified, return the minibuffer window\n\
254 used by that frame.")
259 frame
= selected_frame
;
260 CHECK_LIVE_FRAME (frame
, 0);
261 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
264 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 0, 1, 0,
265 "Returns non-nil if WINDOW is a minibuffer window.")
269 struct window
*w
= decode_window (window
);
270 return (MINI_WINDOW_P (w
) ? Qt
: Qnil
);
273 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
274 Spos_visible_in_window_p
, 0, 2, 0,
275 "Return t if position POS is currently on the frame in WINDOW.\n\
276 Returns nil if that position is scrolled vertically out of view.\n\
277 POS defaults to point; WINDOW, to the selected window.")
279 Lisp_Object pos
, window
;
281 register struct window
*w
;
283 register struct buffer
*buf
;
285 Lisp_Object in_window
;
291 CHECK_NUMBER_COERCE_MARKER (pos
, 0);
295 w
= decode_window (window
);
296 buf
= XBUFFER (w
->buffer
);
297 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
299 /* If position above window, it's not visible. */
300 if (posint
< CHARPOS (top
))
302 else if (XFASTINT (w
->last_modified
) >= BUF_MODIFF (buf
)
303 && XFASTINT (w
->last_overlay_modified
) >= BUF_OVERLAY_MODIFF (buf
)
304 && posint
< BUF_Z (buf
) - XFASTINT (w
->window_end_pos
))
305 /* If frame is up to date, and POSINT is < window end pos, use
306 that info. This doesn't work for POSINT == end pos, because
307 the window end pos is actually the position _after_ the last
308 char in the window. */
310 else if (posint
> BUF_ZV (buf
))
312 else if (CHARPOS (top
) < BUF_BEGV (buf
) || CHARPOS (top
) > BUF_ZV (buf
))
313 /* If window start is out of range, do something reasonable. */
318 start_display (&it
, w
, top
);
319 move_it_to (&it
, posint
, 0, it
.last_visible_y
, -1,
320 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
321 in_window
= IT_CHARPOS (it
) == posint
? Qt
: Qnil
;
327 static struct window
*
328 decode_window (window
)
329 register Lisp_Object window
;
332 return XWINDOW (selected_window
);
334 CHECK_LIVE_WINDOW (window
, 0);
335 return XWINDOW (window
);
338 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
339 "Return the buffer that WINDOW is displaying.")
343 return decode_window (window
)->buffer
;
346 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
347 "Return the number of lines in WINDOW (including its mode line).")
351 return decode_window (window
)->height
;
354 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
355 "Return the number of display columns in WINDOW.\n\
356 This is the width that is usable columns available for text in WINDOW.\n\
357 If you want to find out how many columns WINDOW takes up,\n\
358 use (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))).")
362 return make_number (window_internal_width (decode_window (window
)));
365 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
366 "Return the number of columns by which WINDOW is scrolled from left margin.")
370 return decode_window (window
)->hscroll
;
373 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
374 "Set number of columns WINDOW is scrolled from left margin to NCOL.\n\
375 NCOL should be zero or positive.")
377 register Lisp_Object window
, ncol
;
379 register struct window
*w
;
381 CHECK_NUMBER (ncol
, 1);
382 if (XINT (ncol
) < 0) XSETFASTINT (ncol
, 0);
383 w
= decode_window (window
);
384 if (XINT (w
->hscroll
) != XINT (ncol
))
385 /* Prevent redisplay shortcuts */
386 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
391 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
392 Swindow_redisplay_end_trigger
, 0, 1, 0,
393 "Return WINDOW's redisplay end trigger value.\n\
394 See `set-window-redisplay-end-trigger' for more information.")
398 return decode_window (window
)->redisplay_end_trigger
;
401 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
402 Sset_window_redisplay_end_trigger
, 2, 2, 0,
403 "Set WINDOW's redisplay end trigger value to VALUE.\n\
404 VALUE should be a buffer position (typically a marker) or nil.\n\
405 If it is a buffer position, then if redisplay in WINDOW reaches a position\n\
406 beyond VALUE, the functions in `redisplay-end-trigger-functions' are called\n\
407 with two arguments: WINDOW, and the end trigger value.\n\
408 Afterwards the end-trigger value is reset to nil.")
410 register Lisp_Object window
, value
;
412 register struct window
*w
;
414 w
= decode_window (window
);
415 w
->redisplay_end_trigger
= value
;
419 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
420 "Return a list of the edge coordinates of WINDOW.\n\
421 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.\n\
422 RIGHT is one more than the rightmost column used by WINDOW,\n\
423 and BOTTOM is one more than the bottommost row used by WINDOW\n\
428 register struct window
*w
= decode_window (window
);
430 return Fcons (w
->left
, Fcons (w
->top
,
431 Fcons (make_number (WINDOW_RIGHT_EDGE (w
)),
432 Fcons (make_number (XFASTINT (w
->top
)
433 + XFASTINT (w
->height
)),
437 /* Test if the character at column *X, row *Y is within window W.
438 If it is not, return 0;
439 if it is in the window's text area,
440 set *x and *y to its location relative to the upper left corner
443 if it is on the window's modeline, return 2;
444 if it is on the border between the window and its right sibling,
446 if it is on the window's top line, return 4;
447 if it is in the bitmap area to the left/right of the window,
448 return 5 or 6, and convert *X and *Y to window-relative corrdinates.
450 X and Y are frame relative pixel coordinates. */
453 coordinates_in_window (w
, x
, y
)
454 register struct window
*w
;
457 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
458 int left_x
, right_x
, top_y
, bottom_y
;
459 int flags_area_width
= FRAME_LEFT_FLAGS_AREA_WIDTH (f
);
461 if (w
->pseudo_window_p
)
464 right_x
= XFASTINT (w
->width
) * CANON_Y_UNIT (f
);
465 top_y
= WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
);
466 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
470 left_x
= (WINDOW_DISPLAY_LEFT_EDGE_PIXEL_X (w
)
471 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
472 right_x
= WINDOW_DISPLAY_RIGHT_EDGE_PIXEL_X (w
);
473 top_y
= (WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
)
474 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
475 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
482 - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
)
484 || *x
> right_x
+ flags_area_width
)
485 /* Completely outside anything interesting. */
487 else if (WINDOW_WANTS_MODELINE_P (w
)
488 && *y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
))
489 /* On the mode line. */
491 else if (WINDOW_WANTS_HEADER_LINE_P (w
)
492 && *y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
))
493 /* On the top line. */
495 else if (*x
< left_x
|| *x
>= right_x
)
497 /* Other lines than the mode line don't include flags areas and
498 scroll bars on the left. */
500 /* Convert X and Y to window-relative pixel coordinates. */
503 return *x
< left_x
? 5 : 6;
505 else if (!w
->pseudo_window_p
506 && !WINDOW_RIGHTMOST_P (w
)
507 && *x
>= right_x
- CANON_X_UNIT (f
))
508 /* On the border on the right side of the window? Assume that
509 this area begins at RIGHT_X minus a canonical char width. */
513 /* Convert X and Y to window-relative pixel coordinates. */
520 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
521 Scoordinates_in_window_p
, 2, 2, 0,
522 "Return non-nil if COORDINATES are in WINDOW.\n\
523 COORDINATES is a cons of the form (X . Y), X and Y being distances\n\
524 measured in characters from the upper-left corner of the frame.\n\
525 (0 . 0) denotes the character in the upper left corner of the\n\
527 If COORDINATES are in the text portion of WINDOW,\n\
528 the coordinates relative to the window are returned.\n\
529 If they are in the mode line of WINDOW, `mode-line' is returned.\n\
530 If they are in the top mode line of WINDOW, `header-line' is returned.\n\
531 If they are in the bitmap-area to the left of the window,\n\
532 `left-bitmap-area' is returned, if they are in the area on the right of\n\
533 the window, `right-bitmap-area' is returned.\n\
534 If they are on the border between WINDOW and its right sibling,\n\
535 `vertical-line' is returned.")
536 (coordinates
, window
)
537 register Lisp_Object coordinates
, window
;
544 CHECK_LIVE_WINDOW (window
, 0);
545 w
= XWINDOW (window
);
546 f
= XFRAME (w
->frame
);
547 CHECK_CONS (coordinates
, 1);
548 lx
= Fcar (coordinates
);
549 ly
= Fcdr (coordinates
);
550 CHECK_NUMBER_OR_FLOAT (lx
, 1);
551 CHECK_NUMBER_OR_FLOAT (ly
, 1);
552 x
= PIXEL_X_FROM_CANON_X (f
, lx
);
553 y
= PIXEL_Y_FROM_CANON_Y (f
, ly
);
555 switch (coordinates_in_window (w
, &x
, &y
))
557 case 0: /* NOT in window at all. */
560 case 1: /* In text part of window. */
561 /* X and Y are now window relative pixel coordinates.
562 Convert them to canonical char units before returning
564 return Fcons (CANON_X_FROM_PIXEL_X (f
, x
),
565 CANON_Y_FROM_PIXEL_Y (f
, y
));
567 case 2: /* In mode line of window. */
570 case 3: /* On right border of window. */
571 return Qvertical_line
;
577 return Qleft_bitmap_area
;
580 return Qright_bitmap_area
;
587 /* Find the window containing frame-relative pixel position X/Y and
588 return it as a Lisp_Object. If X, Y is on the window's modeline,
589 set *PART to 1; if it is on the separating line between the window
590 and its right sibling, set it to 2; otherwise set it to 0. If
591 there is no window under X, Y return nil and leave *PART
592 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows. */
595 window_from_coordinates (frame
, x
, y
, part
, tool_bar_p
)
601 register Lisp_Object tem
, first
;
604 tem
= first
= FRAME_SELECTED_WINDOW (frame
);
608 found
= coordinates_in_window (XWINDOW (tem
), &x
, &y
);
616 tem
= Fnext_window (tem
, Qt
, Qlambda
);
618 while (!EQ (tem
, first
));
620 /* See if it's in the tool bar window, if a tool bar exists. */
622 && WINDOWP (frame
->tool_bar_window
)
623 && XFASTINT (XWINDOW (frame
->tool_bar_window
)->height
)
624 && coordinates_in_window (XWINDOW (frame
->tool_bar_window
), &x
, &y
))
627 return frame
->tool_bar_window
;
633 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
634 "Return window containing coordinates X and Y on FRAME.\n\
635 If omitted, FRAME defaults to the currently selected frame.\n\
636 The top left corner of the frame is considered to be row 0,\n\
639 Lisp_Object x
, y
, frame
;
645 frame
= selected_frame
;
646 CHECK_LIVE_FRAME (frame
, 2);
649 /* Check that arguments are integers or floats. */
650 CHECK_NUMBER_OR_FLOAT (x
, 0);
651 CHECK_NUMBER_OR_FLOAT (y
, 1);
653 return window_from_coordinates (f
,
654 PIXEL_X_FROM_CANON_X (f
, x
),
655 PIXEL_Y_FROM_CANON_Y (f
, y
),
659 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
660 "Return current value of point in WINDOW.\n\
661 For a nonselected window, this is the value point would have\n\
662 if that window were selected.\n\
664 Note that, when WINDOW is the selected window and its buffer\n\
665 is also currently selected, the value returned is the same as (point).\n\
666 It would be more strictly correct to return the `top-level' value\n\
667 of point, outside of any save-excursion forms.\n\
668 But that is hard to define.")
672 register struct window
*w
= decode_window (window
);
674 if (w
== XWINDOW (selected_window
)
675 && current_buffer
== XBUFFER (w
->buffer
))
677 return Fmarker_position (w
->pointm
);
680 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
681 "Return position at which display currently starts in WINDOW.\n\
682 This is updated by redisplay or by calling `set-window-start'.")
686 return Fmarker_position (decode_window (window
)->start
);
689 /* This is text temporarily removed from the doc string below.
691 This function returns nil if the position is not currently known.\n\
692 That happens when redisplay is preempted and doesn't finish.\n\
693 If in that case you want to compute where the end of the window would\n\
694 have been if redisplay had finished, do this:\n\
696 (goto-char (window-start window))\n\
697 (vertical-motion (1- (window-height window)) window)\n\
700 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
701 "Return position at which display currently ends in WINDOW.\n\
702 This is updated by redisplay, when it runs to completion.\n\
703 Simply changing the buffer text or setting `window-start'\n\
704 does not update this value.\n\
705 If UP-TO-DATE is non-nil, compute the up-to-date position\n\
706 if it isn't already recorded.")
708 Lisp_Object window
, update
;
711 struct window
*w
= decode_window (window
);
715 CHECK_BUFFER (buf
, 0);
717 #if 0 /* This change broke some things. We should make it later. */
718 /* If we don't know the end position, return nil.
719 The user can compute it with vertical-motion if he wants to.
720 It would be nicer to do it automatically,
721 but that's so slow that it would probably bother people. */
722 if (NILP (w
->window_end_valid
))
727 && ! (! NILP (w
->window_end_valid
)
728 && XFASTINT (w
->last_modified
) >= MODIFF
))
730 int opoint
= PT
, opoint_byte
= PT_BYTE
;
732 /* In case W->start is out of the range, use something
733 reasonable. This situation occured when loading a file with
734 `-l' containing a call to `rmail' with subsequent other
735 commands. At the end, W->start happened to be BEG, while
736 rmail had already narrowed the buffer. This leads to an
737 abort in temp_set_pt_both. */
738 if (XMARKER (w
->start
)->charpos
< BEGV
)
739 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
740 else if (XMARKER (w
->start
)->charpos
> ZV
)
741 TEMP_SET_PT_BOTH (ZV
, ZV_BYTE
);
743 TEMP_SET_PT_BOTH (XMARKER (w
->start
)->charpos
,
744 XMARKER (w
->start
)->bytepos
);
746 Fvertical_motion (make_number (window_internal_height (w
)), Qnil
);
748 TEMP_SET_PT_BOTH (opoint
, opoint_byte
);
752 BUF_Z (XBUFFER (buf
)) - XFASTINT (w
->window_end_pos
));
757 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
758 "Make point value in WINDOW be at position POS in WINDOW's buffer.")
760 Lisp_Object window
, pos
;
762 register struct window
*w
= decode_window (window
);
764 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
765 if (w
== XWINDOW (selected_window
)
766 && XBUFFER (w
->buffer
) == current_buffer
)
769 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
774 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
775 "Make display in WINDOW start at position POS in WINDOW's buffer.\n\
776 Optional third arg NOFORCE non-nil inhibits next redisplay\n\
777 from overriding motion of point in order to display at this exact start.")
778 (window
, pos
, noforce
)
779 Lisp_Object window
, pos
, noforce
;
781 register struct window
*w
= decode_window (window
);
783 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
784 set_marker_restricted (w
->start
, pos
, w
->buffer
);
785 /* this is not right, but much easier than doing what is right. */
786 w
->start_at_line_beg
= Qnil
;
789 w
->update_mode_line
= Qt
;
790 XSETFASTINT (w
->last_modified
, 0);
791 XSETFASTINT (w
->last_overlay_modified
, 0);
792 if (!EQ (window
, selected_window
))
793 windows_or_buffers_changed
++;
798 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
800 "Return WINDOW's dedicated object, usually t or nil.\n\
801 See also `set-window-dedicated-p'.")
805 return decode_window (window
)->dedicated
;
808 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
809 Sset_window_dedicated_p
, 2, 2, 0,
810 "Control whether WINDOW is dedicated to the buffer it displays.\n\
811 If it is dedicated, Emacs will not automatically change\n\
812 which buffer appears in it.\n\
813 The second argument is the new value for the dedication flag;\n\
816 Lisp_Object window
, arg
;
818 register struct window
*w
= decode_window (window
);
828 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
830 "Return the display-table that WINDOW is using.")
834 return decode_window (window
)->display_table
;
837 /* Get the display table for use on window W. This is either W's
838 display table or W's buffer's display table. Ignore the specified
839 tables if they are not valid; if no valid table is specified,
842 struct Lisp_Char_Table
*
843 window_display_table (w
)
847 tem
= w
->display_table
;
848 if (DISP_TABLE_P (tem
))
849 return XCHAR_TABLE (tem
);
850 if (NILP (w
->buffer
))
853 tem
= XBUFFER (w
->buffer
)->display_table
;
854 if (DISP_TABLE_P (tem
))
855 return XCHAR_TABLE (tem
);
856 tem
= Vstandard_display_table
;
857 if (DISP_TABLE_P (tem
))
858 return XCHAR_TABLE (tem
);
862 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
863 "Set WINDOW's display-table to TABLE.")
865 register Lisp_Object window
, table
;
867 register struct window
*w
;
869 w
= decode_window (window
);
870 w
->display_table
= table
;
874 /* Record info on buffer window w is displaying
875 when it is about to cease to display that buffer. */
878 register struct window
*w
;
885 if (b
!= XMARKER (w
->pointm
)->buffer
)
889 if (w
== XWINDOW (selected_window
)
890 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
891 /* Do this except when the selected window's buffer
892 is being removed from some other window. */
894 /* last_window_start records the start position that this buffer
895 had in the last window to be disconnected from it.
896 Now that this statement is unconditional,
897 it is possible for the buffer to be displayed in the
898 selected window, while last_window_start reflects another
899 window which was recently showing the same buffer.
900 Some people might say that might be a good thing. Let's see. */
901 b
->last_window_start
= marker_position (w
->start
);
903 /* Point in the selected window's buffer
904 is actually stored in that buffer, and the window's pointm isn't used.
905 So don't clobber point in that buffer. */
906 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
)
907 /* This line helps to fix Horsley's testbug.el bug. */
908 && !(w
!= XWINDOW (b
->last_selected_window
)
909 && EQ (buf
, XWINDOW (b
->last_selected_window
)->buffer
)))
910 temp_set_point_both (b
,
911 clip_to_bounds (BUF_BEGV (b
),
912 XMARKER (w
->pointm
)->charpos
,
914 clip_to_bounds (BUF_BEGV_BYTE (b
),
915 marker_byte_position (w
->pointm
),
918 if (w
== XWINDOW (b
->last_selected_window
))
919 b
->last_selected_window
= Qnil
;
922 /* Put replacement into the window structure in place of old. */
924 replace_window (old
, replacement
)
925 Lisp_Object old
, replacement
;
927 register Lisp_Object tem
;
928 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
930 /* If OLD is its frame's root_window, then replacement is the new
931 root_window for that frame. */
933 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
934 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
939 p
->height
= o
->height
;
940 p
->desired_matrix
= p
->current_matrix
= 0;
942 bzero (&p
->cursor
, sizeof (p
->cursor
));
943 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
944 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
945 p
->phys_cursor_type
= -1;
946 p
->must_be_updated_p
= 0;
947 p
->pseudo_window_p
= 0;
948 XSETFASTINT (p
->window_end_vpos
, 0);
949 XSETFASTINT (p
->window_end_pos
, 0);
950 p
->window_end_valid
= Qnil
;
951 p
->frozen_window_start_p
= 0;
952 p
->orig_top
= p
->orig_height
= Qnil
;
954 p
->next
= tem
= o
->next
;
956 XWINDOW (tem
)->prev
= replacement
;
958 p
->prev
= tem
= o
->prev
;
960 XWINDOW (tem
)->next
= replacement
;
962 p
->parent
= tem
= o
->parent
;
965 if (EQ (XWINDOW (tem
)->vchild
, old
))
966 XWINDOW (tem
)->vchild
= replacement
;
967 if (EQ (XWINDOW (tem
)->hchild
, old
))
968 XWINDOW (tem
)->hchild
= replacement
;
971 /*** Here, if replacement is a vertical combination
972 and so is its new parent, we should make replacement's
973 children be children of that parent instead. ***/
976 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
977 "Remove WINDOW from the display. Default is selected window.")
979 register Lisp_Object window
;
981 delete_window (window
);
983 if (! NILP (Vwindow_configuration_change_hook
)
984 && ! NILP (Vrun_hooks
))
985 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
991 delete_window (window
)
992 register Lisp_Object window
;
994 register Lisp_Object tem
, parent
, sib
;
995 register struct window
*p
;
996 register struct window
*par
;
999 /* Because this function is called by other C code on non-leaf
1000 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1001 so we can't decode_window here. */
1003 window
= selected_window
;
1005 CHECK_WINDOW (window
, 0);
1006 p
= XWINDOW (window
);
1008 /* It's okay to delete an already-deleted window. */
1009 if (NILP (p
->buffer
)
1011 && NILP (p
->vchild
))
1016 error ("Attempt to delete minibuffer or sole ordinary window");
1017 par
= XWINDOW (parent
);
1019 windows_or_buffers_changed
++;
1020 frame
= XFRAME (WINDOW_FRAME (p
));
1021 FRAME_WINDOW_SIZES_CHANGED (frame
) = 1;
1023 /* Are we trying to delete any frame's selected window? */
1025 Lisp_Object frame
, pwindow
;
1027 /* See if the frame's selected window is either WINDOW
1028 or any subwindow of it, by finding all that window's parents
1029 and comparing each one with WINDOW. */
1030 frame
= WINDOW_FRAME (XWINDOW (window
));
1031 pwindow
= FRAME_SELECTED_WINDOW (XFRAME (frame
));
1033 while (!NILP (pwindow
))
1035 if (EQ (window
, pwindow
))
1037 pwindow
= XWINDOW (pwindow
)->parent
;
1040 if (EQ (window
, pwindow
))
1042 Lisp_Object alternative
;
1043 alternative
= Fnext_window (window
, Qlambda
, Qnil
);
1045 /* If we're about to delete the selected window on the
1046 selected frame, then we should use Fselect_window to select
1047 the new window. On the other hand, if we're about to
1048 delete the selected window on any other frame, we shouldn't do
1049 anything but set the frame's selected_window slot. */
1050 if (EQ (window
, selected_window
))
1051 Fselect_window (alternative
);
1053 FRAME_SELECTED_WINDOW (XFRAME (frame
)) = alternative
;
1058 /* tem is null for dummy parent windows
1059 (which have inferiors but not any contents themselves) */
1063 unchain_marker (p
->pointm
);
1064 unchain_marker (p
->start
);
1067 /* Free window glyph matrices. It is sure that they are allocated
1068 again when ADJUST_GLYPHS is called. Block input so that expose
1069 events and other events that access glyph matrices are not
1070 processed while we are changing them. */
1072 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (frame
)));
1076 XWINDOW (tem
)->prev
= p
->prev
;
1080 XWINDOW (tem
)->next
= p
->next
;
1082 if (EQ (window
, par
->hchild
))
1083 par
->hchild
= p
->next
;
1084 if (EQ (window
, par
->vchild
))
1085 par
->vchild
= p
->next
;
1087 /* Find one of our siblings to give our space to. */
1091 /* If p gives its space to its next sibling, that sibling needs
1092 to have its top/left side pulled back to where p's is.
1093 set_window_{height,width} will re-position the sibling's
1096 XWINDOW (sib
)->top
= p
->top
;
1097 XWINDOW (sib
)->left
= p
->left
;
1100 /* Stretch that sibling. */
1101 if (!NILP (par
->vchild
))
1102 set_window_height (sib
,
1103 XFASTINT (XWINDOW (sib
)->height
) + XFASTINT (p
->height
),
1105 if (!NILP (par
->hchild
))
1106 set_window_width (sib
,
1107 XFASTINT (XWINDOW (sib
)->width
) + XFASTINT (p
->width
),
1110 /* If parent now has only one child,
1111 put the child into the parent's place. */
1115 if (NILP (XWINDOW (tem
)->next
))
1116 replace_window (parent
, tem
);
1118 /* Since we may be deleting combination windows, we must make sure that
1119 not only p but all its children have been marked as deleted. */
1120 if (! NILP (p
->hchild
))
1121 delete_all_subwindows (XWINDOW (p
->hchild
));
1122 else if (! NILP (p
->vchild
))
1123 delete_all_subwindows (XWINDOW (p
->vchild
));
1125 /* Mark this window as deleted. */
1126 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
1128 /* Adjust glyph matrices. */
1129 adjust_glyphs (frame
);
1134 extern Lisp_Object
next_frame (), prev_frame ();
1136 /* This comment supplies the doc string for `next-window',
1137 for make-docfile to see. We cannot put this in the real DEFUN
1138 due to limits in the Unix cpp.
1140 DEFUN ("next-window", Ffoo, Sfoo, 0, 3, 0,
1141 "Return next window after WINDOW in canonical ordering of windows.\n\
1142 If omitted, WINDOW defaults to the selected window.\n\
1144 Optional second arg MINIBUF t means count the minibuffer window even\n\
1145 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1146 it is active. MINIBUF neither t nor nil means not to count the\n\
1147 minibuffer even if it is active.\n\
1149 Several frames may share a single minibuffer; if the minibuffer\n\
1150 counts, all windows on all frames that share that minibuffer count\n\
1151 too. Therefore, `next-window' can be used to iterate through the\n\
1152 set of windows even when the minibuffer is on another frame. If the\n\
1153 minibuffer does not count, only windows from WINDOW's frame count.\n\
1155 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1156 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1157 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1158 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1159 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1160 Anything else means restrict to WINDOW's frame.\n\
1162 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1163 `next-window' to iterate through the entire cycle of acceptable\n\
1164 windows, eventually ending up back at the window you started with.\n\
1165 `previous-window' traverses the same cycle, in the reverse order.")
1166 (window, minibuf, all_frames) */
1168 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
1170 (window
, minibuf
, all_frames
)
1171 register Lisp_Object window
, minibuf
, all_frames
;
1173 register Lisp_Object tem
;
1174 Lisp_Object start_window
;
1177 window
= selected_window
;
1179 CHECK_LIVE_WINDOW (window
, 0);
1181 start_window
= window
;
1183 /* minibuf == nil may or may not include minibuffers.
1184 Decide if it does. */
1186 minibuf
= (minibuf_level
? minibuf_window
: Qlambda
);
1187 else if (! EQ (minibuf
, Qt
))
1189 /* Now minibuf can be t => count all minibuffer windows,
1190 lambda => count none of them,
1191 or a specific minibuffer window (the active one) to count. */
1193 /* all_frames == nil doesn't specify which frames to include. */
1194 if (NILP (all_frames
))
1195 all_frames
= (! EQ (minibuf
, Qlambda
)
1196 ? (FRAME_MINIBUF_WINDOW
1199 (XWINDOW (window
)))))
1201 else if (EQ (all_frames
, Qvisible
))
1203 else if (XFASTINT (all_frames
) == 0)
1205 else if (FRAMEP (all_frames
) && ! EQ (all_frames
, Fwindow_frame (window
)))
1206 /* If all_frames is a frame and window arg isn't on that frame, just
1207 return the first window on the frame. */
1208 return Fframe_first_window (all_frames
);
1209 else if (! EQ (all_frames
, Qt
))
1211 /* Now all_frames is t meaning search all frames,
1212 nil meaning search just current frame,
1213 visible meaning search just visible frames,
1214 0 meaning search visible and iconified frames,
1215 or a window, meaning search the frame that window belongs to. */
1217 /* Do this loop at least once, to get the next window, and perhaps
1218 again, if we hit the minibuffer and that is not acceptable. */
1221 /* Find a window that actually has a next one. This loop
1222 climbs up the tree. */
1223 while (tem
= XWINDOW (window
)->next
, NILP (tem
))
1224 if (tem
= XWINDOW (window
)->parent
, !NILP (tem
))
1228 /* We've reached the end of this frame.
1229 Which other frames are acceptable? */
1230 tem
= WINDOW_FRAME (XWINDOW (window
));
1231 if (! NILP (all_frames
))
1236 tem
= next_frame (tem
, all_frames
);
1237 /* In the case where the minibuffer is active,
1238 and we include its frame as well as the selected one,
1239 next_frame may get stuck in that frame.
1240 If that happens, go back to the selected frame
1241 so we can complete the cycle. */
1243 tem
= selected_frame
;
1245 tem
= FRAME_ROOT_WINDOW (XFRAME (tem
));
1252 /* If we're in a combination window, find its first child and
1253 recurse on that. Otherwise, we've found the window we want. */
1256 if (!NILP (XWINDOW (window
)->hchild
))
1257 window
= XWINDOW (window
)->hchild
;
1258 else if (!NILP (XWINDOW (window
)->vchild
))
1259 window
= XWINDOW (window
)->vchild
;
1265 /* Which windows are acceptable?
1266 Exit the loop and accept this window if
1267 this isn't a minibuffer window,
1268 or we're accepting all minibuffer windows,
1269 or this is the active minibuffer and we are accepting that one, or
1270 we've come all the way around and we're back at the original window. */
1271 while (MINI_WINDOW_P (XWINDOW (window
))
1272 && ! EQ (minibuf
, Qt
)
1273 && ! EQ (minibuf
, window
)
1274 && ! EQ (window
, start_window
));
1279 /* This comment supplies the doc string for `previous-window',
1280 for make-docfile to see. We cannot put this in the real DEFUN
1281 due to limits in the Unix cpp.
1283 DEFUN ("previous-window", Ffoo, Sfoo, 0, 3, 0,
1284 "Return the window preceding WINDOW in canonical ordering of windows.\n\
1285 If omitted, WINDOW defaults to the selected window.\n\
1287 Optional second arg MINIBUF t means count the minibuffer window even\n\
1288 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1289 it is active. MINIBUF neither t nor nil means not to count the\n\
1290 minibuffer even if it is active.\n\
1292 Several frames may share a single minibuffer; if the minibuffer\n\
1293 counts, all windows on all frames that share that minibuffer count\n\
1294 too. Therefore, `previous-window' can be used to iterate through\n\
1295 the set of windows even when the minibuffer is on another frame. If\n\
1296 the minibuffer does not count, only windows from WINDOW's frame count\n\
1298 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1299 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1300 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1301 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1302 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1303 Anything else means restrict to WINDOW's frame.\n\
1305 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1306 `previous-window' to iterate through the entire cycle of acceptable\n\
1307 windows, eventually ending up back at the window you started with.\n\
1308 `next-window' traverses the same cycle, in the reverse order.")
1309 (window, minibuf, all_frames) */
1312 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
1314 (window
, minibuf
, all_frames
)
1315 register Lisp_Object window
, minibuf
, all_frames
;
1317 register Lisp_Object tem
;
1318 Lisp_Object start_window
;
1321 window
= selected_window
;
1323 CHECK_LIVE_WINDOW (window
, 0);
1325 start_window
= window
;
1327 /* minibuf == nil may or may not include minibuffers.
1328 Decide if it does. */
1330 minibuf
= (minibuf_level
? minibuf_window
: Qlambda
);
1331 else if (! EQ (minibuf
, Qt
))
1333 /* Now minibuf can be t => count all minibuffer windows,
1334 lambda => count none of them,
1335 or a specific minibuffer window (the active one) to count. */
1337 /* all_frames == nil doesn't specify which frames to include.
1338 Decide which frames it includes. */
1339 if (NILP (all_frames
))
1340 all_frames
= (! EQ (minibuf
, Qlambda
)
1341 ? (FRAME_MINIBUF_WINDOW
1344 (XWINDOW (window
)))))
1346 else if (EQ (all_frames
, Qvisible
))
1348 else if (XFASTINT (all_frames
) == 0)
1350 else if (FRAMEP (all_frames
) && ! EQ (all_frames
, Fwindow_frame (window
)))
1351 /* If all_frames is a frame and window arg isn't on that frame, just
1352 return the first window on the frame. */
1353 return Fframe_first_window (all_frames
);
1354 else if (! EQ (all_frames
, Qt
))
1356 /* Now all_frames is t meaning search all frames,
1357 nil meaning search just current frame,
1358 visible meaning search just visible frames,
1359 0 meaning search visible and iconified frames,
1360 or a window, meaning search the frame that window belongs to. */
1362 /* Do this loop at least once, to get the previous window, and perhaps
1363 again, if we hit the minibuffer and that is not acceptable. */
1366 /* Find a window that actually has a previous one. This loop
1367 climbs up the tree. */
1368 while (tem
= XWINDOW (window
)->prev
, NILP (tem
))
1369 if (tem
= XWINDOW (window
)->parent
, !NILP (tem
))
1373 /* We have found the top window on the frame.
1374 Which frames are acceptable? */
1375 tem
= WINDOW_FRAME (XWINDOW (window
));
1376 if (! NILP (all_frames
))
1377 /* It's actually important that we use prev_frame here,
1378 rather than next_frame. All the windows acceptable
1379 according to the given parameters should form a ring;
1380 Fnext_window and Fprevious_window should go back and
1381 forth around the ring. If we use next_frame here,
1382 then Fnext_window and Fprevious_window take different
1383 paths through the set of acceptable windows.
1384 window_loop assumes that these `ring' requirement are
1390 tem
= prev_frame (tem
, all_frames
);
1391 /* In the case where the minibuffer is active,
1392 and we include its frame as well as the selected one,
1393 next_frame may get stuck in that frame.
1394 If that happens, go back to the selected frame
1395 so we can complete the cycle. */
1397 tem
= selected_frame
;
1399 /* If this frame has a minibuffer, find that window first,
1400 because it is conceptually the last window in that frame. */
1401 if (FRAME_HAS_MINIBUF_P (XFRAME (tem
)))
1402 tem
= FRAME_MINIBUF_WINDOW (XFRAME (tem
));
1404 tem
= FRAME_ROOT_WINDOW (XFRAME (tem
));
1410 /* If we're in a combination window, find its last child and
1411 recurse on that. Otherwise, we've found the window we want. */
1414 if (!NILP (XWINDOW (window
)->hchild
))
1415 window
= XWINDOW (window
)->hchild
;
1416 else if (!NILP (XWINDOW (window
)->vchild
))
1417 window
= XWINDOW (window
)->vchild
;
1419 while (tem
= XWINDOW (window
)->next
, !NILP (tem
))
1423 /* Which windows are acceptable?
1424 Exit the loop and accept this window if
1425 this isn't a minibuffer window,
1426 or we're accepting all minibuffer windows,
1427 or this is the active minibuffer and we are accepting that one, or
1428 we've come all the way around and we're back at the original window. */
1429 while (MINI_WINDOW_P (XWINDOW (window
))
1430 && ! EQ (minibuf
, Qt
)
1431 && ! EQ (minibuf
, window
)
1432 && ! EQ (window
, start_window
));
1437 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1438 "Select the ARG'th different window on this frame.\n\
1439 All windows on current frame are arranged in a cyclic order.\n\
1440 This command selects the window ARG steps away in that order.\n\
1441 A negative ARG moves in the opposite order. If the optional second\n\
1442 argument ALL_FRAMES is non-nil, cycle through all frames.")
1444 register Lisp_Object arg
, all_frames
;
1447 register Lisp_Object w
;
1449 CHECK_NUMBER (arg
, 0);
1450 w
= selected_window
;
1455 w
= Fnext_window (w
, Qnil
, all_frames
);
1460 w
= Fprevious_window (w
, Qnil
, all_frames
);
1467 /* Look at all windows, performing an operation specified by TYPE
1469 If FRAMES is Qt, look at all frames;
1470 Qnil, look at just the selected frame;
1471 Qvisible, look at visible frames;
1472 a frame, just look at windows on that frame.
1473 If MINI is non-zero, perform the operation on minibuffer windows too.
1479 GET_BUFFER_WINDOW
, /* Arg is buffer */
1480 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1481 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1482 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1484 UNSHOW_BUFFER
, /* Arg is buffer */
1489 window_loop (type
, obj
, mini
, frames
)
1490 enum window_loop type
;
1491 register Lisp_Object obj
, frames
;
1494 register Lisp_Object w
;
1495 register Lisp_Object best_window
;
1496 register Lisp_Object next_window
;
1497 register Lisp_Object last_window
;
1499 Lisp_Object frame_arg
;
1502 /* If we're only looping through windows on a particular frame,
1503 frame points to that frame. If we're looping through windows
1504 on all frames, frame is 0. */
1505 if (FRAMEP (frames
))
1506 frame
= XFRAME (frames
);
1507 else if (NILP (frames
))
1508 frame
= SELECTED_FRAME ();
1512 frame_arg
= Qlambda
;
1513 else if (XFASTINT (frames
) == 0)
1515 else if (EQ (frames
, Qvisible
))
1518 /* frame_arg is Qlambda to stick to one frame,
1519 Qvisible to consider all visible frames,
1522 /* Pick a window to start with. */
1526 w
= FRAME_SELECTED_WINDOW (frame
);
1528 w
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
1530 /* Figure out the last window we're going to mess with. Since
1531 Fnext_window, given the same options, is guaranteed to go in a
1532 ring, we can just use Fprevious_window to find the last one.
1534 We can't just wait until we hit the first window again, because
1535 it might be deleted. */
1537 last_window
= Fprevious_window (w
, mini
? Qt
: Qnil
, frame_arg
);
1542 /* Pick the next window now, since some operations will delete
1543 the current window. */
1544 next_window
= Fnext_window (w
, mini
? Qt
: Qnil
, frame_arg
);
1546 /* Note that we do not pay attention here to whether
1547 the frame is visible, since Fnext_window skips non-visible frames
1548 if that is desired, under the control of frame_arg. */
1549 if (! MINI_WINDOW_P (XWINDOW (w
))
1550 /* For UNSHOW_BUFFER, we must always consider all windows. */
1551 || type
== UNSHOW_BUFFER
1552 || (mini
&& minibuf_level
> 0))
1555 case GET_BUFFER_WINDOW
:
1556 if (XBUFFER (XWINDOW (w
)->buffer
) == XBUFFER (obj
)
1557 /* Don't find any minibuffer window
1558 except the one that is currently in use. */
1559 && (MINI_WINDOW_P (XWINDOW (w
))
1560 ? EQ (w
, minibuf_window
) : 1))
1564 case GET_LRU_WINDOW
:
1565 /* t as arg means consider only full-width windows */
1566 if (!NILP (obj
) && !WINDOW_FULL_WIDTH_P (XWINDOW (w
)))
1568 /* Ignore dedicated windows and minibuffers. */
1569 if (MINI_WINDOW_P (XWINDOW (w
))
1570 || !NILP (XWINDOW (w
)->dedicated
))
1572 if (NILP (best_window
)
1573 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1574 > XFASTINT (XWINDOW (w
)->use_time
)))
1578 case DELETE_OTHER_WINDOWS
:
1579 if (XWINDOW (w
) != XWINDOW (obj
))
1583 case DELETE_BUFFER_WINDOWS
:
1584 if (EQ (XWINDOW (w
)->buffer
, obj
))
1586 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (w
)));
1588 /* If this window is dedicated, and in a frame of its own,
1590 if (EQ (w
, FRAME_ROOT_WINDOW (f
))
1591 && !NILP (XWINDOW (w
)->dedicated
)
1592 && other_visible_frames (f
))
1594 /* Skip the other windows on this frame.
1595 There might be one, the minibuffer! */
1596 if (! EQ (w
, last_window
))
1597 while (f
== XFRAME (WINDOW_FRAME (XWINDOW (next_window
))))
1599 /* As we go, check for the end of the loop.
1600 We mustn't start going around a second time. */
1601 if (EQ (next_window
, last_window
))
1606 next_window
= Fnext_window (next_window
,
1610 /* Now we can safely delete the frame. */
1611 Fdelete_frame (WINDOW_FRAME (XWINDOW (w
)), Qnil
);
1614 /* If we're deleting the buffer displayed in the only window
1615 on the frame, find a new buffer to display there. */
1616 if (NILP (XWINDOW (w
)->parent
))
1618 Lisp_Object new_buffer
;
1619 new_buffer
= Fother_buffer (obj
, Qnil
,
1620 XWINDOW (w
)->frame
);
1621 if (NILP (new_buffer
))
1623 = Fget_buffer_create (build_string ("*scratch*"));
1624 Fset_window_buffer (w
, new_buffer
);
1625 if (EQ (w
, selected_window
))
1626 Fset_buffer (XWINDOW (w
)->buffer
);
1633 case GET_LARGEST_WINDOW
:
1634 /* Ignore dedicated windows and minibuffers. */
1635 if (MINI_WINDOW_P (XWINDOW (w
))
1636 || !NILP (XWINDOW (w
)->dedicated
))
1639 struct window
*best_window_ptr
= XWINDOW (best_window
);
1640 struct window
*w_ptr
= XWINDOW (w
);
1641 if (NILP (best_window
)
1642 || (XFASTINT (w_ptr
->height
) * XFASTINT (w_ptr
->width
)
1643 > (XFASTINT (best_window_ptr
->height
)
1644 * XFASTINT (best_window_ptr
->width
))))
1650 if (EQ (XWINDOW (w
)->buffer
, obj
))
1652 /* Find another buffer to show in this window. */
1653 Lisp_Object another_buffer
;
1654 FRAME_PTR f
= XFRAME (WINDOW_FRAME (XWINDOW (w
)));
1655 another_buffer
= Fother_buffer (obj
, Qnil
, XWINDOW (w
)->frame
);
1656 if (NILP (another_buffer
))
1658 = Fget_buffer_create (build_string ("*scratch*"));
1659 /* If this window is dedicated, and in a frame of its own,
1661 if (EQ (w
, FRAME_ROOT_WINDOW (f
))
1662 && !NILP (XWINDOW (w
)->dedicated
)
1663 && other_visible_frames (f
))
1665 /* Skip the other windows on this frame.
1666 There might be one, the minibuffer! */
1667 if (! EQ (w
, last_window
))
1668 while (f
== XFRAME (WINDOW_FRAME (XWINDOW (next_window
))))
1670 /* As we go, check for the end of the loop.
1671 We mustn't start going around a second time. */
1672 if (EQ (next_window
, last_window
))
1677 next_window
= Fnext_window (next_window
,
1681 /* Now we can safely delete the frame. */
1682 Fdelete_frame (WINDOW_FRAME (XWINDOW (w
)), Qnil
);
1686 /* Otherwise show a different buffer in the window. */
1687 XWINDOW (w
)->dedicated
= Qnil
;
1688 Fset_window_buffer (w
, another_buffer
);
1689 if (EQ (w
, selected_window
))
1690 Fset_buffer (XWINDOW (w
)->buffer
);
1695 /* Check for a window that has a killed buffer. */
1696 case CHECK_ALL_WINDOWS
:
1697 if (! NILP (XWINDOW (w
)->buffer
)
1698 && NILP (XBUFFER (XWINDOW (w
)->buffer
)->name
))
1702 if (EQ (w
, last_window
))
1711 /* Used for debugging. Abort if any window has a dead buffer. */
1714 check_all_windows ()
1716 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
1719 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1720 "Return the window least recently selected or used for display.\n\
1721 If optional argument FRAME is `visible', search all visible frames.\n\
1722 If FRAME is 0, search all visible and iconified frames.\n\
1723 If FRAME is t, search all frames.\n\
1724 If FRAME is nil, search only the selected frame.\n\
1725 If FRAME is a frame, search only that frame.")
1729 register Lisp_Object w
;
1730 /* First try for a window that is full-width */
1731 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frame
);
1732 if (!NILP (w
) && !EQ (w
, selected_window
))
1734 /* If none of them, try the rest */
1735 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frame
);
1738 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1739 "Return the largest window in area.\n\
1740 If optional argument FRAME is `visible', search all visible frames.\n\
1741 If 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.")
1748 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
1752 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
1753 "Return a window currently displaying BUFFER, or nil if none.\n\
1754 If optional argument FRAME is `visible', search all visible frames.\n\
1755 If optional argument FRAME is 0, search all visible and iconified frames.\n\
1756 If FRAME is t, search all frames.\n\
1757 If FRAME is nil, search only the selected frame.\n\
1758 If FRAME is a frame, search only that frame.")
1760 Lisp_Object buffer
, frame
;
1762 buffer
= Fget_buffer (buffer
);
1763 if (BUFFERP (buffer
))
1764 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
1769 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
1771 "Make WINDOW (or the selected window) fill its frame.\n\
1772 Only the frame WINDOW is on is affected.\n\
1773 This function tries to reduce display jumps\n\
1774 by keeping the text previously visible in WINDOW\n\
1775 in the same place on the frame. Doing this depends on\n\
1776 the value of (window-start WINDOW), so if calling this function\n\
1777 in a program gives strange scrolling, make sure the window-start\n\
1778 value is reasonable when this function is called.")
1787 window
= selected_window
;
1789 CHECK_LIVE_WINDOW (window
, 0);
1791 w
= XWINDOW (window
);
1793 startpos
= marker_position (w
->start
);
1794 top
= XFASTINT (w
->top
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
1796 if (MINI_WINDOW_P (w
) && top
> 0)
1797 error ("Can't expand minibuffer to full frame");
1799 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
1801 /* Try to minimize scrolling, by setting the window start to the point
1802 will cause the text at the old window start to be at the same place
1803 on the frame. But don't try to do this if the window start is
1804 outside the visible portion (as might happen when the display is
1805 not current, due to typeahead). */
1806 if (startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
1807 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
1809 struct position pos
;
1810 struct buffer
*obuf
= current_buffer
;
1812 Fset_buffer (w
->buffer
);
1813 /* This computation used to temporarily move point, but that can
1814 have unwanted side effects due to text properties. */
1815 pos
= *vmotion (startpos
, -top
, w
);
1817 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
1818 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
1819 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
1821 /* We need to do this, so that the window-scroll-functions
1823 w
->optional_new_start
= Qt
;
1825 set_buffer_internal (obuf
);
1831 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
1832 1, 2, "bDelete windows on (buffer): ",
1833 "Delete all windows showing BUFFER.\n\
1834 Optional second argument FRAME controls which frames are affected.\n\
1835 If optional argument FRAME is `visible', search all visible frames.\n\
1836 If FRAME is 0, search all visible and iconified frames.\n\
1837 If FRAME is nil, search all frames.\n\
1838 If FRAME is t, search only the selected frame.\n\
1839 If FRAME is a frame, search only that frame.")
1841 Lisp_Object buffer
, frame
;
1843 /* FRAME uses t and nil to mean the opposite of what window_loop
1847 else if (EQ (frame
, Qt
))
1852 buffer
= Fget_buffer (buffer
);
1853 CHECK_BUFFER (buffer
, 0);
1854 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
1860 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
1861 Sreplace_buffer_in_windows
,
1862 1, 1, "bReplace buffer in windows: ",
1863 "Replace BUFFER with some other buffer in all windows showing it.")
1869 buffer
= Fget_buffer (buffer
);
1870 CHECK_BUFFER (buffer
, 0);
1871 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
1876 /* Replace BUFFER with some other buffer in all windows
1877 of all frames, even those on other keyboards. */
1880 replace_buffer_in_all_windows (buffer
)
1884 Lisp_Object tail
, frame
;
1886 /* A single call to window_loop won't do the job
1887 because it only considers frames on the current keyboard.
1888 So loop manually over frames, and handle each one. */
1889 FOR_EACH_FRAME (tail
, frame
)
1890 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
1892 window_loop (UNSHOW_BUFFER
, buffer
, 1, Qt
);
1896 /* Set the height of WINDOW and all its inferiors. */
1898 /* The smallest acceptable dimensions for a window. Anything smaller
1899 might crash Emacs. */
1901 #define MIN_SAFE_WINDOW_WIDTH (2)
1902 #define MIN_SAFE_WINDOW_HEIGHT (2)
1904 /* Make sure that window_min_height and window_min_width are
1905 not too small; if they are, set them to safe minima. */
1908 check_min_window_sizes ()
1910 /* Smaller values might permit a crash. */
1911 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
1912 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
1913 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
1914 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
1917 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
1918 minimum allowable size. */
1921 check_frame_size (frame
, rows
, cols
)
1925 /* For height, we have to see:
1926 whether the frame has a minibuffer,
1927 whether it wants a mode line, and
1928 whether it has a menu bar. */
1930 (FRAME_MINIBUF_ONLY_P (frame
) ? MIN_SAFE_WINDOW_HEIGHT
- 1
1931 : (! FRAME_HAS_MINIBUF_P (frame
)) ? MIN_SAFE_WINDOW_HEIGHT
1932 : 2 * MIN_SAFE_WINDOW_HEIGHT
- 1);
1934 if (FRAME_TOP_MARGIN (frame
) > 0)
1935 min_height
+= FRAME_TOP_MARGIN (frame
);
1937 if (*rows
< min_height
)
1939 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
1940 *cols
= MIN_SAFE_WINDOW_WIDTH
;
1944 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
1945 check if W's width can be changed, otherwise check W's height.
1946 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
1947 siblings, too. If none of the siblings is resizable, WINDOW isn't
1951 window_fixed_size_p (w
, width_p
, check_siblings_p
)
1953 int width_p
, check_siblings_p
;
1958 if (!NILP (w
->hchild
))
1960 c
= XWINDOW (w
->hchild
);
1964 /* A horiz. combination is fixed-width if all of if its
1966 while (c
&& window_fixed_size_p (c
, width_p
, 0))
1967 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
1968 fixed_p
= c
== NULL
;
1972 /* A horiz. combination is fixed-height if one of if its
1974 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
1975 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
1976 fixed_p
= c
!= NULL
;
1979 else if (!NILP (w
->vchild
))
1981 c
= XWINDOW (w
->vchild
);
1985 /* A vert. combination is fixed-width if one of if its
1987 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
1988 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
1989 fixed_p
= c
!= NULL
;
1993 /* A vert. combination is fixed-height if all of if its
1995 while (c
&& window_fixed_size_p (c
, width_p
, 0))
1996 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
1997 fixed_p
= c
== NULL
;
2000 else if (BUFFERP (w
->buffer
))
2002 if (w
->height_fixed_p
&& !width_p
)
2006 struct buffer
*old
= current_buffer
;
2009 current_buffer
= XBUFFER (w
->buffer
);
2010 val
= find_symbol_value (Qwindow_size_fixed
);
2011 current_buffer
= old
;
2014 if (!EQ (val
, Qunbound
))
2016 fixed_p
= !NILP (val
);
2019 && ((EQ (val
, Qheight
) && width_p
)
2020 || (EQ (val
, Qwidth
) && !width_p
)))
2025 /* Can't tell if this one is resizable without looking at
2026 siblings. If all siblings are fixed-size this one is too. */
2027 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
2031 for (child
= w
->prev
; !NILP (child
); child
= XWINDOW (child
)->prev
)
2032 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2036 for (child
= w
->next
; !NILP (child
); child
= XWINDOW (child
)->next
)
2037 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2051 /* Return the minimum size of window W, not taking fixed-width windows
2052 into account. WIDTH_P non-zero means return the minimum width,
2053 otherwise return the minimum height. If W is a combination window,
2054 compute the minimum size from the minimum sizes of W's children. */
2057 window_min_size_1 (w
, width_p
)
2064 if (!NILP (w
->hchild
))
2066 c
= XWINDOW (w
->hchild
);
2071 /* The min width of a horizontal combination is
2072 the sum of the min widths of its children. */
2075 size
+= window_min_size_1 (c
, width_p
);
2076 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2081 /* The min height a horizontal combination equals
2082 the maximum of all min height of its children. */
2085 int min_size
= window_min_size_1 (c
, width_p
);
2086 size
= max (min_size
, size
);
2087 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2091 else if (!NILP (w
->vchild
))
2093 c
= XWINDOW (w
->vchild
);
2098 /* The min width of a vertical combination is
2099 the maximum of the min widths of its children. */
2102 int min_size
= window_min_size_1 (c
, width_p
);
2103 size
= max (min_size
, size
);
2104 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2109 /* The min height of a vertical combination equals
2110 the sum of the min height of its children. */
2113 size
+= window_min_size_1 (c
, width_p
);
2114 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2121 size
= window_min_width
;
2124 if (MINI_WINDOW_P (w
)
2125 || (!WINDOW_WANTS_MODELINE_P (w
)
2126 && !WINDOW_WANTS_HEADER_LINE_P (w
)))
2129 size
= window_min_height
;
2137 /* Return the minimum size of window W, taking fixed-size windows into
2138 account. WIDTH_P non-zero means return the minimum width,
2139 otherwise return the minimum height. IGNORE_FIXED_P non-zero means
2140 ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size
2141 unless FIXED is null. */
2144 window_min_size (w
, width_p
, ignore_fixed_p
, fixed
)
2146 int width_p
, ignore_fixed_p
, *fixed
;
2153 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
2159 size
= width_p
? XFASTINT (w
->width
) : XFASTINT (w
->height
);
2161 size
= window_min_size_1 (w
, width_p
);
2167 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
2168 WINDOW's width. Resize WINDOW's children, if any, so that they
2169 keep their proportionate size relative to WINDOW. Propagate
2170 WINDOW's top or left edge position to children. Delete windows
2171 that become too small unless NODELETE_P is non-zero. */
2174 size_window (window
, size
, width_p
, nodelete_p
)
2176 int size
, width_p
, nodelete_p
;
2178 struct window
*w
= XWINDOW (window
);
2180 Lisp_Object child
, *forward
, *sideward
;
2181 int old_size
, min_size
;
2183 check_min_window_sizes ();
2185 /* If the window has been "too small" at one point,
2186 don't delete it for being "too small" in the future.
2187 Preserve it as long as that is at all possible. */
2190 old_size
= XFASTINT (w
->width
);
2191 min_size
= window_min_width
;
2195 old_size
= XFASTINT (w
->height
);
2196 min_size
= window_min_height
;
2199 if (old_size
< window_min_width
)
2200 w
->too_small_ok
= Qt
;
2202 /* Maybe delete WINDOW if it's too small. */
2203 if (!nodelete_p
&& !NILP (w
->parent
))
2207 if (!MINI_WINDOW_P (w
) && !NILP (w
->too_small_ok
))
2208 min_size
= width_p
? MIN_SAFE_WINDOW_WIDTH
: MIN_SAFE_WINDOW_HEIGHT
;
2210 min_size
= width_p
? window_min_width
: window_min_height
;
2212 if (size
< min_size
)
2214 delete_window (window
);
2219 /* Set redisplay hints. */
2220 XSETFASTINT (w
->last_modified
, 0);
2221 XSETFASTINT (w
->last_overlay_modified
, 0);
2222 windows_or_buffers_changed
++;
2223 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
2227 sideward
= &w
->vchild
;
2228 forward
= &w
->hchild
;
2229 XSETFASTINT (w
->width
, size
);
2233 sideward
= &w
->hchild
;
2234 forward
= &w
->vchild
;
2235 XSETFASTINT (w
->height
, size
);
2238 if (!NILP (*sideward
))
2240 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
2242 c
= XWINDOW (child
);
2247 size_window (child
, size
, width_p
, nodelete_p
);
2250 else if (!NILP (*forward
))
2252 int fixed_size
, each
, extra
, n
;
2253 int resize_fixed_p
, nfixed
;
2254 int last_pos
, first_pos
, nchildren
;
2256 /* Determine the fixed-size portion of the this window, and the
2257 number of child windows. */
2258 fixed_size
= nchildren
= nfixed
= 0;
2259 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
2261 c
= XWINDOW (child
);
2262 if (window_fixed_size_p (c
, width_p
, 0))
2264 fixed_size
+= (width_p
2265 ? XFASTINT (c
->width
) : XFASTINT (c
->height
));
2270 /* If the new size is smaller than fixed_size, or if there
2271 aren't any resizable windows, allow resizing fixed-size
2273 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
2275 /* Compute how many lines/columns to add to each child. The
2276 value of extra takes care of rounding errors. */
2277 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
2278 each
= (size
- old_size
) / n
;
2279 extra
= (size
- old_size
) - n
* each
;
2281 /* Compute new children heights and edge positions. */
2282 first_pos
= width_p
? XFASTINT (w
->left
) : XFASTINT (w
->top
);
2283 last_pos
= first_pos
;
2284 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2286 int new_size
, old_size
;
2288 c
= XWINDOW (child
);
2289 old_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2290 new_size
= old_size
;
2292 /* The top or left edge position of this child equals the
2293 bottom or right edge of its predecessor. */
2295 c
->left
= make_number (last_pos
);
2297 c
->top
= make_number (last_pos
);
2299 /* If this child can be resized, do it. */
2300 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
2302 new_size
= old_size
+ each
+ extra
;
2306 /* Set new height. Note that size_window also propagates
2307 edge positions to children, so it's not a no-op if we
2308 didn't change the child's size. */
2309 size_window (child
, new_size
, width_p
, 1);
2311 /* Remember the bottom/right edge position of this child; it
2312 will be used to set the top/left edge of the next child. */
2313 last_pos
+= new_size
;
2316 /* We should have covered the parent exactly with child windows. */
2317 xassert (size
== last_pos
- first_pos
);
2319 /* Now delete any children that became too small. */
2321 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2324 c
= XWINDOW (child
);
2325 child_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2326 size_window (child
, child_size
, width_p
, 0);
2331 /* Set WINDOW's height to HEIGHT, and recursively change the height of
2332 WINDOW's children. NODELETE non-zero means don't delete windows
2333 that become too small in the process. (The caller should check
2334 later and do so if appropriate.) */
2337 set_window_height (window
, height
, nodelete
)
2342 size_window (window
, height
, 0, nodelete
);
2346 /* Set WINDOW's width to WIDTH, and recursively change the width of
2347 WINDOW's children. NODELETE non-zero means don't delete windows
2348 that become too small in the process. (The caller should check
2349 later and do so if appropriate.) */
2352 set_window_width (window
, width
, nodelete
)
2357 size_window (window
, width
, 1, nodelete
);
2361 int window_select_count
;
2364 Fset_window_buffer_unwind (obuf
)
2372 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
2373 means it's allowed to run hooks. See make_frame for a case where
2374 it's not allowed. */
2377 set_window_buffer (window
, buffer
, run_hooks_p
)
2378 Lisp_Object window
, buffer
;
2381 struct window
*w
= XWINDOW (window
);
2382 struct buffer
*b
= XBUFFER (buffer
);
2383 int count
= specpdl_ptr
- specpdl
;
2387 if (EQ (window
, selected_window
))
2388 b
->last_selected_window
= window
;
2390 /* Update time stamps of buffer display. */
2391 if (INTEGERP (b
->display_count
))
2392 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
2393 b
->display_time
= Fcurrent_time ();
2395 XSETFASTINT (w
->window_end_pos
, 0);
2396 XSETFASTINT (w
->window_end_vpos
, 0);
2397 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
2398 w
->window_end_valid
= Qnil
;
2399 XSETFASTINT (w
->hscroll
, 0);
2400 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
2401 set_marker_restricted (w
->start
,
2402 make_number (b
->last_window_start
),
2404 w
->start_at_line_beg
= Qnil
;
2405 w
->force_start
= Qnil
;
2406 XSETFASTINT (w
->last_modified
, 0);
2407 XSETFASTINT (w
->last_overlay_modified
, 0);
2408 windows_or_buffers_changed
++;
2410 /* We must select BUFFER for running the window-scroll-functions.
2411 If WINDOW is selected, switch permanently.
2412 Otherwise, switch but go back to the ambient buffer afterward. */
2413 if (EQ (window
, selected_window
))
2414 Fset_buffer (buffer
);
2415 /* We can't check ! NILP (Vwindow_scroll_functions) here
2416 because that might itself be a local variable. */
2417 else if (window_initialized
)
2419 record_unwind_protect (Fset_window_buffer_unwind
, Fcurrent_buffer ());
2420 Fset_buffer (buffer
);
2423 /* Set left and right marginal area width from buffer. */
2424 Fset_window_margins (window
, b
->left_margin_width
, b
->right_margin_width
);
2428 if (! NILP (Vwindow_scroll_functions
))
2429 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2430 Fmarker_position (w
->start
));
2432 if (! NILP (Vwindow_configuration_change_hook
)
2433 && ! NILP (Vrun_hooks
))
2434 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
2437 unbind_to (count
, Qnil
);
2441 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 2, 0,
2442 "Make WINDOW display BUFFER as its contents.\n\
2443 BUFFER can be a buffer or buffer name.")
2445 register Lisp_Object window
, buffer
;
2447 register Lisp_Object tem
;
2448 register struct window
*w
= decode_window (window
);
2450 XSETWINDOW (window
, w
);
2451 buffer
= Fget_buffer (buffer
);
2452 CHECK_BUFFER (buffer
, 1);
2454 if (NILP (XBUFFER (buffer
)->name
))
2455 error ("Attempt to display deleted buffer");
2459 error ("Window is deleted");
2460 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
2461 is first being set up. */
2463 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
2464 error ("Window is dedicated to `%s'",
2465 XSTRING (XBUFFER (tem
)->name
)->data
);
2470 set_window_buffer (window
, buffer
, 1);
2474 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 1, 0,
2475 "Select WINDOW. Most editing will apply to WINDOW's buffer.\n\
2476 If WINDOW is not already selected, also make WINDOW's buffer current.\n\
2477 Note that the main editor command loop\n\
2478 selects the buffer of the selected window before each command.")
2480 register Lisp_Object window
;
2482 return select_window_1 (window
, 1);
2485 /* Note that selected_window can be nil
2486 when this is called from Fset_window_configuration. */
2489 select_window_1 (window
, recordflag
)
2490 register Lisp_Object window
;
2493 register struct window
*w
;
2494 register struct window
*ow
;
2497 CHECK_LIVE_WINDOW (window
, 0);
2499 w
= XWINDOW (window
);
2501 if (NILP (w
->buffer
))
2502 error ("Trying to select deleted window or non-leaf window");
2504 XSETFASTINT (w
->use_time
, ++window_select_count
);
2505 if (EQ (window
, selected_window
))
2508 if (!NILP (selected_window
))
2510 ow
= XWINDOW (selected_window
);
2511 if (! NILP (ow
->buffer
))
2512 set_marker_both (ow
->pointm
, ow
->buffer
,
2513 BUF_PT (XBUFFER (ow
->buffer
)),
2514 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
2517 selected_window
= window
;
2518 sf
= SELECTED_FRAME ();
2519 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
2521 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
2522 /* Use this rather than Fhandle_switch_frame
2523 so that FRAME_FOCUS_FRAME is moved appropriately as we
2524 move around in the state where a minibuffer in a separate
2526 Fselect_frame (WINDOW_FRAME (w
), Qnil
);
2529 sf
->selected_window
= window
;
2532 record_buffer (w
->buffer
);
2533 Fset_buffer (w
->buffer
);
2535 XBUFFER (w
->buffer
)->last_selected_window
= window
;
2537 /* Go to the point recorded in the window.
2538 This is important when the buffer is in more
2539 than one window. It also matters when
2540 redisplay_window has altered point after scrolling,
2541 because it makes the change only in the window. */
2543 register int new_point
= marker_position (w
->pointm
);
2544 if (new_point
< BEGV
)
2546 else if (new_point
> ZV
)
2552 windows_or_buffers_changed
++;
2556 /* Deiconify the frame containing the window WINDOW,
2557 unless it is the selected frame;
2560 The reason for the exception for the selected frame
2561 is that it seems better not to change the selected frames visibility
2562 merely because of displaying a different buffer in it.
2563 The deiconification is useful when a buffer gets shown in
2564 another frame that you were not using lately. */
2567 display_buffer_1 (window
)
2570 Lisp_Object frame
= XWINDOW (window
)->frame
;
2571 FRAME_PTR f
= XFRAME (frame
);
2573 FRAME_SAMPLE_VISIBILITY (f
);
2575 if (!EQ (frame
, selected_frame
))
2577 if (FRAME_ICONIFIED_P (f
))
2578 Fmake_frame_visible (frame
);
2579 else if (FRAME_VISIBLE_P (f
))
2580 Fraise_frame (frame
);
2586 DEFUN ("special-display-p", Fspecial_display_p
, Sspecial_display_p
, 1, 1, 0,
2587 "Returns non-nil if a buffer named BUFFER-NAME would be created specially.\n\
2588 The value is actually t if the frame should be called with default frame\n\
2589 parameters, and a list of frame parameters if they were specified.\n\
2590 See `special-display-buffer-names', and `special-display-regexps'.")
2592 Lisp_Object buffer_name
;
2596 CHECK_STRING (buffer_name
, 1);
2598 tem
= Fmember (buffer_name
, Vspecial_display_buffer_names
);
2602 tem
= Fassoc (buffer_name
, Vspecial_display_buffer_names
);
2606 for (tem
= Vspecial_display_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2608 Lisp_Object car
= XCAR (tem
);
2610 && fast_string_match (car
, buffer_name
) >= 0)
2612 else if (CONSP (car
)
2613 && STRINGP (XCAR (car
))
2614 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2620 DEFUN ("same-window-p", Fsame_window_p
, Ssame_window_p
, 1, 1, 0,
2621 "Returns non-nil if a new buffer named BUFFER-NAME would use the same window.\n\
2622 See `same-window-buffer-names' and `same-window-regexps'.")
2624 Lisp_Object buffer_name
;
2628 CHECK_STRING (buffer_name
, 1);
2630 tem
= Fmember (buffer_name
, Vsame_window_buffer_names
);
2634 tem
= Fassoc (buffer_name
, Vsame_window_buffer_names
);
2638 for (tem
= Vsame_window_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2640 Lisp_Object car
= XCAR (tem
);
2642 && fast_string_match (car
, buffer_name
) >= 0)
2644 else if (CONSP (car
)
2645 && STRINGP (XCAR (car
))
2646 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2652 /* Use B so the default is (other-buffer). */
2653 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 3,
2654 "BDisplay buffer: \nP",
2655 "Make BUFFER appear in some window but don't select it.\n\
2656 BUFFER can be a buffer or a buffer name.\n\
2657 If BUFFER is shown already in some window, just use that one,\n\
2658 unless the window is the selected window and the optional second\n\
2659 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).\n\
2660 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.\n\
2661 Returns the window displaying BUFFER.\n\
2663 The variables `special-display-buffer-names', `special-display-regexps',\n\
2664 `same-window-buffer-names', and `same-window-regexps' customize how certain\n\
2665 buffer names are handled.\n\
2667 If optional argument FRAME is `visible', search all visible frames.\n\
2668 If FRAME is 0, search all visible and iconified frames.\n\
2669 If FRAME is t, search all frames.\n\
2670 If FRAME is a frame, search only that frame.\n\
2671 If FRAME is nil, search only the selected frame\n\
2672 (actually the last nonminibuffer frame),\n\
2673 unless `pop-up-frames' is non-nil,\n\
2674 which means search visible and iconified frames.")
2675 (buffer
, not_this_window
, frame
)
2676 register Lisp_Object buffer
, not_this_window
, frame
;
2678 register Lisp_Object window
, tem
, swp
;
2682 buffer
= Fget_buffer (buffer
);
2683 CHECK_BUFFER (buffer
, 0);
2685 if (!NILP (Vdisplay_buffer_function
))
2686 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
2688 if (NILP (not_this_window
)
2689 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
2690 return display_buffer_1 (selected_window
);
2692 /* See if the user has specified this buffer should appear
2693 in the selected window. */
2694 if (NILP (not_this_window
))
2696 swp
= Fsame_window_p (XBUFFER (buffer
)->name
);
2697 if (!NILP (swp
) && !no_switch_window (selected_window
))
2699 Fswitch_to_buffer (buffer
, Qnil
);
2700 return display_buffer_1 (selected_window
);
2704 /* If pop_up_frames,
2705 look for a window showing BUFFER on any visible or iconified frame.
2706 Otherwise search only the current frame. */
2709 else if (pop_up_frames
|| last_nonminibuf_frame
== 0)
2710 XSETFASTINT (tem
, 0);
2712 XSETFRAME (tem
, last_nonminibuf_frame
);
2713 window
= Fget_buffer_window (buffer
, tem
);
2715 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
2717 return display_buffer_1 (window
);
2720 /* Certain buffer names get special handling. */
2721 if (!NILP (Vspecial_display_function
) && NILP (swp
))
2723 tem
= Fspecial_display_p (XBUFFER (buffer
)->name
);
2725 return call1 (Vspecial_display_function
, buffer
);
2727 return call2 (Vspecial_display_function
, buffer
, tem
);
2730 /* If there are no frames open that have more than a minibuffer,
2731 we need to create a new frame. */
2732 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
2734 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2735 Fset_window_buffer (window
, buffer
);
2736 return display_buffer_1 (window
);
2739 f
= SELECTED_FRAME ();
2741 || FRAME_MINIBUF_ONLY_P (f
)
2742 /* If the current frame is a special display frame,
2743 don't try to reuse its windows. */
2744 || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f
))->dedicated
))
2749 if (FRAME_MINIBUF_ONLY_P (f
))
2750 XSETFRAME (frames
, last_nonminibuf_frame
);
2751 /* Don't try to create a window if would get an error */
2752 if (split_height_threshold
< window_min_height
<< 1)
2753 split_height_threshold
= window_min_height
<< 1;
2755 /* Note that both Fget_largest_window and Fget_lru_window
2756 ignore minibuffers and dedicated windows.
2757 This means they can return nil. */
2759 /* If the frame we would try to split cannot be split,
2760 try other frames. */
2761 if (FRAME_NO_SPLIT_P (NILP (frames
) ? f
: last_nonminibuf_frame
))
2763 /* Try visible frames first. */
2764 window
= Fget_largest_window (Qvisible
);
2765 /* If that didn't work, try iconified frames. */
2767 window
= Fget_largest_window (make_number (0));
2769 window
= Fget_largest_window (Qt
);
2772 window
= Fget_largest_window (frames
);
2774 /* If we got a tall enough full-width window that can be split,
2777 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2778 && window_height (window
) >= split_height_threshold
2779 && WINDOW_FULL_WIDTH_P (XWINDOW (window
)))
2780 window
= Fsplit_window (window
, Qnil
, Qnil
);
2783 Lisp_Object upper
, lower
, other
;
2785 window
= Fget_lru_window (frames
);
2786 /* If the LRU window is selected, and big enough,
2787 and can be split, split it. */
2789 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2790 && (EQ (window
, selected_window
)
2791 || EQ (XWINDOW (window
)->parent
, Qnil
))
2792 && window_height (window
) >= window_min_height
<< 1)
2793 window
= Fsplit_window (window
, Qnil
, Qnil
);
2794 /* If Fget_lru_window returned nil, try other approaches. */
2796 /* Try visible frames first. */
2798 window
= Fget_buffer_window (buffer
, Qvisible
);
2800 window
= Fget_largest_window (Qvisible
);
2801 /* If that didn't work, try iconified frames. */
2803 window
= Fget_buffer_window (buffer
, make_number (0));
2805 window
= Fget_largest_window (make_number (0));
2806 /* Try invisible frames. */
2808 window
= Fget_buffer_window (buffer
, Qt
);
2810 window
= Fget_largest_window (Qt
);
2811 /* As a last resort, make a new frame. */
2813 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2814 /* If window appears above or below another,
2815 even out their heights. */
2816 other
= upper
= lower
= Qnil
;
2817 if (!NILP (XWINDOW (window
)->prev
))
2818 other
= upper
= XWINDOW (window
)->prev
, lower
= window
;
2819 if (!NILP (XWINDOW (window
)->next
))
2820 other
= lower
= XWINDOW (window
)->next
, upper
= window
;
2822 /* Check that OTHER and WINDOW are vertically arrayed. */
2823 && !EQ (XWINDOW (other
)->top
, XWINDOW (window
)->top
)
2824 && (XFASTINT (XWINDOW (other
)->height
)
2825 > XFASTINT (XWINDOW (window
)->height
)))
2827 int total
= (XFASTINT (XWINDOW (other
)->height
)
2828 + XFASTINT (XWINDOW (window
)->height
));
2829 enlarge_window (upper
,
2830 total
/ 2 - XFASTINT (XWINDOW (upper
)->height
),
2836 window
= Fget_lru_window (Qnil
);
2838 Fset_window_buffer (window
, buffer
);
2839 return display_buffer_1 (window
);
2843 temp_output_buffer_show (buf
)
2844 register Lisp_Object buf
;
2846 register struct buffer
*old
= current_buffer
;
2847 register Lisp_Object window
;
2848 register struct window
*w
;
2850 XBUFFER (buf
)->directory
= current_buffer
->directory
;
2853 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
2857 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
2858 set_buffer_internal (old
);
2860 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
2861 call1 (Vtemp_buffer_show_function
, buf
);
2864 window
= Fdisplay_buffer (buf
, Qnil
, Qnil
);
2866 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
2867 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
2868 Vminibuf_scroll_window
= window
;
2869 w
= XWINDOW (window
);
2870 XSETFASTINT (w
->hscroll
, 0);
2871 set_marker_restricted_both (w
->start
, buf
, 1, 1);
2872 set_marker_restricted_both (w
->pointm
, buf
, 1, 1);
2874 /* Run temp-buffer-show-hook, with the chosen window selected
2875 and it sbuffer current. */
2876 if (!NILP (Vrun_hooks
))
2879 tem
= Fboundp (Qtemp_buffer_show_hook
);
2882 tem
= Fsymbol_value (Qtemp_buffer_show_hook
);
2885 int count
= specpdl_ptr
- specpdl
;
2886 Lisp_Object prev_window
;
2887 prev_window
= selected_window
;
2889 /* Select the window that was chosen, for running the hook. */
2890 record_unwind_protect (Fselect_window
, prev_window
);
2891 select_window_1 (window
, 0);
2892 Fset_buffer (w
->buffer
);
2893 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
2894 select_window_1 (prev_window
, 0);
2895 unbind_to (count
, Qnil
);
2903 make_dummy_parent (window
)
2907 register struct window
*o
, *p
;
2908 register struct Lisp_Vector
*vec
;
2911 o
= XWINDOW (window
);
2912 vec
= allocate_vectorlike ((EMACS_INT
)VECSIZE (struct window
));
2913 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
2914 vec
->contents
[i
] = ((struct Lisp_Vector
*)o
)->contents
[i
];
2915 vec
->size
= VECSIZE (struct window
);
2916 p
= (struct window
*)vec
;
2917 XSETWINDOW (new, p
);
2919 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
2921 /* Put new into window structure in place of window */
2922 replace_window (window
, new);
2935 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
2936 "Split WINDOW, putting SIZE lines in the first of the pair.\n\
2937 WINDOW defaults to selected one and SIZE to half its size.\n\
2938 If optional third arg HORFLAG is non-nil, split side by side\n\
2939 and put SIZE columns in the first of the pair. In that case,\n\
2940 SIZE includes that window's scroll bar, or the divider column to its right.")
2941 (window
, size
, horflag
)
2942 Lisp_Object window
, size
, horflag
;
2944 register Lisp_Object
new;
2945 register struct window
*o
, *p
;
2947 register int size_int
;
2950 window
= selected_window
;
2952 CHECK_LIVE_WINDOW (window
, 0);
2954 o
= XWINDOW (window
);
2955 fo
= XFRAME (WINDOW_FRAME (o
));
2959 if (!NILP (horflag
))
2960 /* Calculate the size of the left-hand window, by dividing
2961 the usable space in columns by two.
2962 We round up, since the left-hand window may include
2963 a dividing line, while the right-hand may not. */
2964 size_int
= (XFASTINT (o
->width
) + 1) >> 1;
2966 size_int
= XFASTINT (o
->height
) >> 1;
2970 CHECK_NUMBER (size
, 1);
2971 size_int
= XINT (size
);
2974 if (MINI_WINDOW_P (o
))
2975 error ("Attempt to split minibuffer window");
2976 else if (window_fixed_size_p (o
, !NILP (horflag
), 0))
2977 error ("Attempt to split fixed-size window");
2979 check_min_window_sizes ();
2983 if (size_int
< window_min_height
)
2984 error ("Window height %d too small (after splitting)", size_int
);
2985 if (size_int
+ window_min_height
> XFASTINT (o
->height
))
2986 error ("Window height %d too small (after splitting)",
2987 XFASTINT (o
->height
) - size_int
);
2988 if (NILP (o
->parent
)
2989 || NILP (XWINDOW (o
->parent
)->vchild
))
2991 make_dummy_parent (window
);
2993 XWINDOW (new)->vchild
= window
;
2998 if (size_int
< window_min_width
)
2999 error ("Window width %d too small (after splitting)", size_int
);
3001 if (size_int
+ window_min_width
> XFASTINT (o
->width
))
3002 error ("Window width %d too small (after splitting)",
3003 XFASTINT (o
->width
) - size_int
);
3004 if (NILP (o
->parent
)
3005 || NILP (XWINDOW (o
->parent
)->hchild
))
3007 make_dummy_parent (window
);
3009 XWINDOW (new)->hchild
= window
;
3013 /* Now we know that window's parent is a vertical combination
3014 if we are dividing vertically, or a horizontal combination
3015 if we are making side-by-side windows */
3017 windows_or_buffers_changed
++;
3018 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
3019 new = make_window ();
3022 p
->frame
= o
->frame
;
3024 if (!NILP (p
->next
))
3025 XWINDOW (p
->next
)->prev
= new;
3028 p
->parent
= o
->parent
;
3030 p
->window_end_valid
= Qnil
;
3031 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
3033 /* Apportion the available frame space among the two new windows */
3035 if (!NILP (horflag
))
3037 p
->height
= o
->height
;
3039 XSETFASTINT (p
->width
, XFASTINT (o
->width
) - size_int
);
3040 XSETFASTINT (o
->width
, size_int
);
3041 XSETFASTINT (p
->left
, XFASTINT (o
->left
) + size_int
);
3046 p
->width
= o
->width
;
3047 XSETFASTINT (p
->height
, XFASTINT (o
->height
) - size_int
);
3048 XSETFASTINT (o
->height
, size_int
);
3049 XSETFASTINT (p
->top
, XFASTINT (o
->top
) + size_int
);
3052 /* Adjust glyph matrices. */
3054 Fset_window_buffer (new, o
->buffer
);
3058 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
3059 "Make current window ARG lines bigger.\n\
3060 From program, optional second arg non-nil means grow sideways ARG columns.")
3062 register Lisp_Object arg
, side
;
3064 CHECK_NUMBER (arg
, 0);
3065 enlarge_window (selected_window
, XINT (arg
), !NILP (side
));
3067 if (! NILP (Vwindow_configuration_change_hook
))
3068 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3073 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
3074 "Make current window ARG lines smaller.\n\
3075 From program, optional second arg non-nil means shrink sideways arg columns.")
3077 register Lisp_Object arg
, side
;
3079 CHECK_NUMBER (arg
, 0);
3080 enlarge_window (selected_window
, -XINT (arg
), !NILP (side
));
3082 if (! NILP (Vwindow_configuration_change_hook
))
3083 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3089 window_height (window
)
3092 register struct window
*p
= XWINDOW (window
);
3093 return XFASTINT (p
->height
);
3097 window_width (window
)
3100 register struct window
*p
= XWINDOW (window
);
3101 return XFASTINT (p
->width
);
3106 *(widthflag ? (int *) &(XWINDOW (w)->left) : (int *) &(XWINDOW (w)->top))
3108 #define CURSIZE(w) \
3109 *(widthflag ? (int *) &(XWINDOW (w)->width) : (int *) &(XWINDOW (w)->height))
3112 /* Enlarge selected_window by DELTA. WIDTHFLAG non-zero means
3113 increase its width. Siblings of the selected window are resized to
3114 fullfil the size request. If they become too small in the process,
3115 they will be deleted. */
3118 enlarge_window (window
, delta
, widthflag
)
3120 int delta
, widthflag
;
3122 Lisp_Object parent
, next
, prev
;
3124 int *sizep
, maximum
;
3125 int (*sizefun
) P_ ((Lisp_Object
))
3126 = widthflag
? window_width
: window_height
;
3127 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
3128 = (widthflag
? set_window_width
: set_window_height
);
3130 /* Check values of window_min_width and window_min_height for
3132 check_min_window_sizes ();
3134 /* Give up if this window cannot be resized. */
3135 if (window_fixed_size_p (XWINDOW (window
), widthflag
, 1))
3136 error ("Window is not resizable");
3138 /* Find the parent of the selected window. */
3141 p
= XWINDOW (window
);
3147 error ("No other window to side of this one");
3152 ? !NILP (XWINDOW (parent
)->hchild
)
3153 : !NILP (XWINDOW (parent
)->vchild
))
3159 sizep
= &CURSIZE (window
);
3162 register int maxdelta
;
3164 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - *sizep
3165 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3166 - window_min_size (XWINDOW (p
->next
),
3168 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
3169 - window_min_size (XWINDOW (p
->prev
),
3171 /* This is a frame with only one window, a minibuffer-only
3172 or a minibufferless frame. */
3175 if (delta
> maxdelta
)
3176 /* This case traps trying to make the minibuffer
3177 the full frame, or make the only window aside from the
3178 minibuffer the full frame. */
3182 if (*sizep
+ delta
< window_min_size (XWINDOW (window
), widthflag
, 0, 0))
3184 delete_window (window
);
3191 /* Find the total we can get from other siblings. */
3193 for (next
= p
->next
; ! NILP (next
); next
= XWINDOW (next
)->next
)
3194 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
3196 for (prev
= p
->prev
; ! NILP (prev
); prev
= XWINDOW (prev
)->prev
)
3197 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
3200 /* If we can get it all from them, do so. */
3201 if (delta
<= maximum
)
3203 Lisp_Object first_unaffected
;
3204 Lisp_Object first_affected
;
3209 first_affected
= window
;
3210 /* Look at one sibling at a time,
3211 moving away from this window in both directions alternately,
3212 and take as much as we can get without deleting that sibling. */
3213 while (delta
!= 0 && (!NILP (next
) || !NILP (prev
)))
3217 int this_one
= ((*sizefun
) (next
)
3218 - window_min_size (XWINDOW (next
),
3219 widthflag
, 0, &fixed_p
));
3222 if (this_one
> delta
)
3225 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
3226 (*setsizefun
) (window
, *sizep
+ this_one
, 0);
3231 next
= XWINDOW (next
)->next
;
3239 int this_one
= ((*sizefun
) (prev
)
3240 - window_min_size (XWINDOW (prev
),
3241 widthflag
, 0, &fixed_p
));
3244 if (this_one
> delta
)
3247 first_affected
= prev
;
3249 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
3250 (*setsizefun
) (window
, *sizep
+ this_one
, 0);
3255 prev
= XWINDOW (prev
)->prev
;
3259 xassert (delta
== 0);
3261 /* Now recalculate the edge positions of all the windows affected,
3262 based on the new sizes. */
3263 first_unaffected
= next
;
3264 prev
= first_affected
;
3265 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
3266 prev
= next
, next
= XWINDOW (next
)->next
)
3268 CURBEG (next
) = CURBEG (prev
) + (*sizefun
) (prev
);
3269 /* This does not change size of NEXT,
3270 but it propagates the new top edge to its children */
3271 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
3276 register int delta1
;
3277 register int opht
= (*sizefun
) (parent
);
3279 /* If trying to grow this window to or beyond size of the parent,
3280 make delta1 so big that, on shrinking back down,
3281 all the siblings end up with less than one line and are deleted. */
3282 if (opht
<= *sizep
+ delta
)
3283 delta1
= opht
* opht
* 2;
3286 /* Otherwise, make delta1 just right so that if we add
3287 delta1 lines to this window and to the parent, and then
3288 shrink the parent back to its original size, the new
3289 proportional size of this window will increase by delta.
3291 The function size_window will compute the new height h'
3292 of the window from delta1 as:
3295 x = delta1 - delta1/n * n for the 1st resizable child
3298 where n is the number of children that can be resized.
3299 We can ignore x by choosing a delta1 that is a multiple of
3300 n. We want the height of this window to come out as
3310 The number of children n rquals the number of resizable
3311 children of this window + 1 because we know window itself
3312 is resizable (otherwise we would have signalled an error. */
3314 struct window
*w
= XWINDOW (window
);
3318 for (s
= w
->next
; !NILP (s
); s
= XWINDOW (s
)->next
)
3319 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3321 for (s
= w
->prev
; !NILP (s
); s
= XWINDOW (s
)->prev
)
3322 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3328 /* Add delta1 lines or columns to this window, and to the parent,
3329 keeping things consistent while not affecting siblings. */
3330 CURSIZE (parent
) = opht
+ delta1
;
3331 (*setsizefun
) (window
, *sizep
+ delta1
, 0);
3333 /* Squeeze out delta1 lines or columns from our parent,
3334 shriking this window and siblings proportionately.
3335 This brings parent back to correct size.
3336 Delta1 was calculated so this makes this window the desired size,
3337 taking it all out of the siblings. */
3338 (*setsizefun
) (parent
, opht
, 0);
3341 XSETFASTINT (p
->last_modified
, 0);
3342 XSETFASTINT (p
->last_overlay_modified
, 0);
3344 /* Adjust glyph matrices. */
3345 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
3353 /***********************************************************************
3354 Resizing Mini-Windows
3355 ***********************************************************************/
3357 static void shrink_window_lowest_first
P_ ((struct window
*, int));
3359 enum save_restore_action
3366 static int save_restore_orig_size
P_ ((struct window
*,
3367 enum save_restore_action
));
3369 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
3370 from lowest windows first. */
3373 shrink_window_lowest_first (w
, height
)
3381 xassert (!MINI_WINDOW_P (w
));
3383 /* Set redisplay hints. */
3384 XSETFASTINT (w
->last_modified
, 0);
3385 XSETFASTINT (w
->last_overlay_modified
, 0);
3386 windows_or_buffers_changed
++;
3387 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
3389 old_height
= XFASTINT (w
->height
);
3390 XSETFASTINT (w
->height
, height
);
3392 if (!NILP (w
->hchild
))
3394 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
3396 c
= XWINDOW (child
);
3398 shrink_window_lowest_first (c
, height
);
3401 else if (!NILP (w
->vchild
))
3403 Lisp_Object last_child
;
3404 int delta
= old_height
- height
;
3407 /* Find the last child. We are taking space from lowest windows
3408 first, so we iterate over children from the last child
3410 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
3413 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
3414 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
3418 c
= XWINDOW (child
);
3419 this_one
= XFASTINT (c
->height
) - MIN_SAFE_WINDOW_HEIGHT
;
3421 if (this_one
> delta
)
3424 shrink_window_lowest_first (c
, XFASTINT (c
->height
) - this_one
);
3428 /* Compute new positions. */
3430 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
3432 c
= XWINDOW (child
);
3433 c
->top
= make_number (last_top
);
3434 shrink_window_lowest_first (c
, XFASTINT (c
->height
));
3435 last_top
+= XFASTINT (c
->height
);
3441 /* Save, restore, or check positions and sizes in the window tree
3442 rooted at W. ACTION says what to do.
3444 If ACTION is CHECK_ORIG_SIZES, check if orig_top and orig_height
3445 members are valid for all windows in the window tree. Value is
3446 non-zero if they are valid.
3448 If ACTION is SAVE_ORIG_SIZES, save members top and height in
3449 orig_top and orig_height for all windows in the tree.
3451 If ACTION is RESTORE_ORIG_SIZES, restore top and height from
3452 values stored in orig_top and orig_height for all windows. */
3455 save_restore_orig_size (w
, action
)
3457 enum save_restore_action action
;
3463 if (!NILP (w
->hchild
))
3465 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
3468 else if (!NILP (w
->vchild
))
3470 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
3476 case CHECK_ORIG_SIZES
:
3477 if (!INTEGERP (w
->orig_top
) || !INTEGERP (w
->orig_height
))
3481 case SAVE_ORIG_SIZES
:
3482 w
->orig_top
= w
->top
;
3483 w
->orig_height
= w
->height
;
3484 XSETFASTINT (w
->last_modified
, 0);
3485 XSETFASTINT (w
->last_overlay_modified
, 0);
3488 case RESTORE_ORIG_SIZES
:
3489 xassert (INTEGERP (w
->orig_top
) && INTEGERP (w
->orig_height
));
3490 w
->top
= w
->orig_top
;
3491 w
->height
= w
->orig_height
;
3492 w
->orig_height
= w
->orig_top
= Qnil
;
3493 XSETFASTINT (w
->last_modified
, 0);
3494 XSETFASTINT (w
->last_overlay_modified
, 0);
3501 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
3508 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
3509 without deleting other windows. */
3512 grow_mini_window (w
, delta
)
3516 struct frame
*f
= XFRAME (w
->frame
);
3517 struct window
*root
;
3519 xassert (MINI_WINDOW_P (w
));
3520 xassert (delta
>= 0);
3522 /* Check values of window_min_width and window_min_height for
3524 check_min_window_sizes ();
3526 /* Compute how much we can enlarge the mini-window without deleting
3528 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3531 int min_height
= window_min_size (root
, 0, 0, 0);
3532 if (XFASTINT (root
->height
) - delta
< min_height
)
3533 delta
= XFASTINT (root
->height
) - min_height
;
3538 /* Save original window sizes and positions, if not already done. */
3539 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3540 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
3542 /* Shrink other windows. */
3543 shrink_window_lowest_first (root
, XFASTINT (root
->height
) - delta
);
3545 /* Grow the mini-window. */
3546 w
->top
= make_number (XFASTINT (root
->top
) + XFASTINT (root
)->height
);
3547 w
->height
= make_number (XFASTINT (w
->height
) + delta
);
3548 XSETFASTINT (w
->last_modified
, 0);
3549 XSETFASTINT (w
->last_overlay_modified
, 0);
3556 /* Shrink mini-window W. If there is recorded info about window sizes
3557 before a call to grow_mini_window, restore recorded window sizes.
3558 Otherwise, if the mini-window is higher than 1 line, resize it to 1
3562 shrink_mini_window (w
)
3565 struct frame
*f
= XFRAME (w
->frame
);
3566 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3568 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3570 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
3572 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
3573 windows_or_buffers_changed
= 1;
3575 else if (XFASTINT (w
->height
) > 1)
3578 XSETWINDOW (window
, w
);
3579 enlarge_window (window
, 1 - XFASTINT (w
->height
), 0);
3585 /* Mark window cursors off for all windows in the window tree rooted
3586 at W by setting their phys_cursor_on_p flag to zero. Called from
3587 xterm.c, e.g. when a frame is cleared and thereby all cursors on
3588 the frame are cleared. */
3591 mark_window_cursors_off (w
)
3596 if (!NILP (w
->hchild
))
3597 mark_window_cursors_off (XWINDOW (w
->hchild
));
3598 else if (!NILP (w
->vchild
))
3599 mark_window_cursors_off (XWINDOW (w
->vchild
));
3601 w
->phys_cursor_on_p
= 0;
3603 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
3608 /* Return number of lines of text (not counting mode line) in W. */
3611 window_internal_height (w
)
3614 int ht
= XFASTINT (w
->height
);
3616 if (MINI_WINDOW_P (w
))
3619 if (!NILP (w
->parent
) || !NILP (w
->vchild
) || !NILP (w
->hchild
)
3620 || !NILP (w
->next
) || !NILP (w
->prev
)
3621 || FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (w
))))
3628 /* Return the number of columns in W.
3629 Don't count columns occupied by scroll bars or the vertical bar
3630 separating W from the sibling to its right. */
3633 window_internal_width (w
)
3636 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
3637 int width
= XINT (w
->width
);
3639 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
3640 /* Scroll bars occupy a few columns. */
3641 width
-= FRAME_SCROLL_BAR_COLS (f
);
3642 else if (!WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
3643 /* The column of `|' characters separating side-by-side windows
3644 occupies one column only. */
3647 /* On window-systems, areas to the left and right of the window
3648 are used to display bitmaps there. */
3649 if (FRAME_WINDOW_P (f
))
3650 width
-= FRAME_FLAGS_AREA_COLS (f
);
3656 /************************************************************************
3658 ***********************************************************************/
3660 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
3661 one screen-full, which is defined as the height of the window minus
3662 next_screen_context_lines. If WHOLE is zero, scroll up N lines
3663 instead. Negative values of N mean scroll down. NOERROR non-zero
3664 means don't signal an error if we try to move over BEGV or ZV,
3668 window_scroll (window
, n
, whole
, noerror
)
3674 /* If we must, use the pixel-based version which is much slower than
3675 the line-based one but can handle varying line heights. */
3676 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
3677 window_scroll_pixel_based (window
, n
, whole
, noerror
);
3679 window_scroll_line_based (window
, n
, whole
, noerror
);
3683 /* Implementation of window_scroll that works based on pixel line
3684 heights. See the comment of window_scroll for parameter
3688 window_scroll_pixel_based (window
, n
, whole
, noerror
)
3695 struct window
*w
= XWINDOW (window
);
3696 struct text_pos start
;
3698 int this_scroll_margin
;
3701 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
3703 /* If PT is not visible in WINDOW, move back one half of
3705 XSETFASTINT (tem
, PT
);
3706 tem
= Fpos_visible_in_window_p (tem
, window
);
3709 /* Move backward half the height of the window. Performance note:
3710 vmotion used here is about 10% faster, but would give wrong
3711 results for variable height lines. */
3712 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3713 it
.current_y
= it
.last_visible_y
;
3714 move_it_vertically (&it
, -it
.last_visible_y
/ 2);
3716 /* The function move_iterator_vertically may move over more than
3717 the specified y-distance. If it->w is small, e.g. a
3718 mini-buffer window, we may end up in front of the window's
3719 display area. This is the case when Start displaying at the
3720 start of the line containing PT in this case. */
3721 if (it
.current_y
<= 0)
3723 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3724 move_it_vertically (&it
, 0);
3728 start
= it
.current
.pos
;
3731 /* If scroll_preserve_screen_position is non-zero, we try to set
3732 point in the same window line as it is now, so get that line. */
3733 if (!NILP (Vscroll_preserve_screen_position
))
3735 start_display (&it
, w
, start
);
3736 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3737 preserve_y
= it
.current_y
;
3742 /* Move iterator it from start the specified distance forward or
3743 backward. The result is the new window start. */
3744 start_display (&it
, w
, start
);
3747 int screen_full
= (it
.last_visible_y
3748 - next_screen_context_lines
* CANON_Y_UNIT (it
.f
));
3749 int direction
= n
< 0 ? -1 : 1;
3750 move_it_vertically (&it
, direction
* screen_full
);
3753 move_it_by_lines (&it
, n
, 1);
3755 /* End if we end up at ZV or BEGV. */
3756 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
3757 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
3761 else if (IT_CHARPOS (it
) == ZV
)
3762 Fsignal (Qend_of_buffer
, Qnil
);
3764 Fsignal (Qbeginning_of_buffer
, Qnil
);
3767 /* Set the window start, and set up the window for redisplay. */
3768 set_marker_restricted (w
->start
, make_number (IT_CHARPOS (it
)), w
->buffer
);
3769 w
->start_at_line_beg
= Fbolp ();
3770 w
->update_mode_line
= Qt
;
3771 XSETFASTINT (w
->last_modified
, 0);
3772 XSETFASTINT (w
->last_overlay_modified
, 0);
3773 /* Set force_start so that redisplay_window will run the
3774 window-scroll-functions. */
3775 w
->force_start
= Qt
;
3777 it
.current_y
= it
.vpos
= 0;
3779 /* Preserve the screen position if we must. */
3780 if (preserve_y
>= 0)
3782 move_it_to (&it
, -1, -1, preserve_y
, -1, MOVE_TO_Y
);
3783 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3787 /* Move PT out of scroll margins. */
3788 this_scroll_margin
= max (0, scroll_margin
);
3789 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->height
) / 4);
3790 this_scroll_margin
*= CANON_Y_UNIT (it
.f
);
3794 /* We moved the window start towards ZV, so PT may be now
3795 in the scroll margin at the top. */
3796 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3797 while (it
.current_y
< this_scroll_margin
)
3798 move_it_by_lines (&it
, 1, 1);
3799 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3803 /* We moved the window start towards BEGV, so PT may be now
3804 in the scroll margin at the bottom. */
3805 move_it_to (&it
, PT
, -1,
3806 it
.last_visible_y
- this_scroll_margin
- 1, -1,
3807 MOVE_TO_POS
| MOVE_TO_Y
);
3809 /* Don't put point on a partially visible line at the end. */
3810 if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
3811 > it
.last_visible_y
)
3812 move_it_by_lines (&it
, -1, 0);
3814 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3820 /* Implementation of window_scroll that works based on screen lines.
3821 See the comment of window_scroll for parameter descriptions. */
3824 window_scroll_line_based (window
, n
, whole
, noerror
)
3830 register struct window
*w
= XWINDOW (window
);
3831 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
3832 register int pos
, pos_byte
;
3833 register int ht
= window_internal_height (w
);
3834 register Lisp_Object tem
;
3838 struct position posit
;
3841 startpos
= marker_position (w
->start
);
3843 posit
= *compute_motion (startpos
, 0, 0, 0,
3845 window_internal_width (w
), XINT (w
->hscroll
),
3847 original_vpos
= posit
.vpos
;
3849 XSETFASTINT (tem
, PT
);
3850 tem
= Fpos_visible_in_window_p (tem
, window
);
3854 Fvertical_motion (make_number (- (ht
/ 2)), window
);
3859 lose
= n
< 0 && PT
== BEGV
;
3860 Fvertical_motion (make_number (n
), window
);
3864 SET_PT_BOTH (opoint
, opoint_byte
);
3871 Fsignal (Qbeginning_of_buffer
, Qnil
);
3876 int this_scroll_margin
= scroll_margin
;
3878 /* Don't use a scroll margin that is negative or too large. */
3879 if (this_scroll_margin
< 0)
3880 this_scroll_margin
= 0;
3882 if (XINT (w
->height
) < 4 * scroll_margin
)
3883 this_scroll_margin
= XINT (w
->height
) / 4;
3885 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
3886 w
->start_at_line_beg
= bolp
;
3887 w
->update_mode_line
= Qt
;
3888 XSETFASTINT (w
->last_modified
, 0);
3889 XSETFASTINT (w
->last_overlay_modified
, 0);
3890 /* Set force_start so that redisplay_window will run
3891 the window-scroll-functions. */
3892 w
->force_start
= Qt
;
3894 if (whole
&& !NILP (Vscroll_preserve_screen_position
))
3896 SET_PT_BOTH (pos
, pos_byte
);
3897 Fvertical_motion (make_number (original_vpos
), window
);
3899 /* If we scrolled forward, put point enough lines down
3900 that it is outside the scroll margin. */
3905 if (this_scroll_margin
> 0)
3907 SET_PT_BOTH (pos
, pos_byte
);
3908 Fvertical_motion (make_number (this_scroll_margin
), window
);
3914 if (top_margin
<= opoint
)
3915 SET_PT_BOTH (opoint
, opoint_byte
);
3916 else if (!NILP (Vscroll_preserve_screen_position
))
3918 SET_PT_BOTH (pos
, pos_byte
);
3919 Fvertical_motion (make_number (original_vpos
), window
);
3922 SET_PT (top_margin
);
3928 /* If we scrolled backward, put point near the end of the window
3929 but not within the scroll margin. */
3930 SET_PT_BOTH (pos
, pos_byte
);
3931 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
3932 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
3935 bottom_margin
= PT
+ 1;
3937 if (bottom_margin
> opoint
)
3938 SET_PT_BOTH (opoint
, opoint_byte
);
3941 if (!NILP (Vscroll_preserve_screen_position
))
3943 SET_PT_BOTH (pos
, pos_byte
);
3944 Fvertical_motion (make_number (original_vpos
), window
);
3947 Fvertical_motion (make_number (-1), window
);
3956 Fsignal (Qend_of_buffer
, Qnil
);
3961 /* Scroll selected_window up or down. If N is nil, scroll a
3962 screen-full which is defined as the height of the window minus
3963 next_screen_context_lines. If N is the symbol `-', scroll.
3964 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
3965 up. This is the guts of Fscroll_up and Fscroll_down. */
3968 scroll_command (n
, direction
)
3972 register int defalt
;
3973 int count
= specpdl_ptr
- specpdl
;
3975 xassert (abs (direction
) == 1);
3977 /* If selected window's buffer isn't current, make it current for
3978 the moment. But don't screw up if window_scroll gets an error. */
3979 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
3981 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
3982 Fset_buffer (XWINDOW (selected_window
)->buffer
);
3984 /* Make redisplay consider other windows than just selected_window. */
3985 ++windows_or_buffers_changed
;
3988 defalt
= (window_internal_height (XWINDOW (selected_window
))
3989 - next_screen_context_lines
);
3990 defalt
= direction
* (defalt
< 1 ? 1 : defalt
);
3993 window_scroll (selected_window
, defalt
, 1, 0);
3994 else if (EQ (n
, Qminus
))
3995 window_scroll (selected_window
, - defalt
, 1, 0);
3998 n
= Fprefix_numeric_value (n
);
3999 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
4002 unbind_to (count
, Qnil
);
4005 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
4006 "Scroll text of current window upward ARG lines; or near full screen if no ARG.\n\
4007 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4008 Negative ARG means scroll downward.\n\
4009 If ARG is the atom `-', scroll downward by nearly full screen.\n\
4010 When calling from a program, supply as argument a number, nil, or `-'.")
4014 scroll_command (arg
, 1);
4018 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
4019 "Scroll text of current window down ARG lines; or near full screen if no ARG.\n\
4020 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4021 Negative ARG means scroll upward.\n\
4022 If ARG is the atom `-', scroll upward by nearly full screen.\n\
4023 When calling from a program, supply as argument a number, nil, or `-'.")
4027 scroll_command (arg
, -1);
4031 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
4032 "Return the other window for \"other window scroll\" commands.\n\
4033 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4034 specifies the window.\n\
4035 If `other-window-scroll-buffer' is non-nil, a window\n\
4036 showing that buffer is used.")
4041 if (MINI_WINDOW_P (XWINDOW (selected_window
))
4042 && !NILP (Vminibuf_scroll_window
))
4043 window
= Vminibuf_scroll_window
;
4044 /* If buffer is specified, scroll that buffer. */
4045 else if (!NILP (Vother_window_scroll_buffer
))
4047 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
4049 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
4053 /* Nothing specified; look for a neighboring window on the same
4055 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
4057 if (EQ (window
, selected_window
))
4058 /* That didn't get us anywhere; look for a window on another
4061 window
= Fnext_window (window
, Qnil
, Qt
);
4062 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
4063 && ! EQ (window
, selected_window
));
4066 CHECK_LIVE_WINDOW (window
, 0);
4068 if (EQ (window
, selected_window
))
4069 error ("There is no other window");
4074 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
4075 "Scroll next window upward ARG lines; or near full screen if no ARG.\n\
4076 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4077 The next window is the one below the current one; or the one at the top\n\
4078 if the current one is at the bottom. Negative ARG means scroll downward.\n\
4079 If ARG is the atom `-', scroll downward by nearly full screen.\n\
4080 When calling from a program, supply as argument a number, nil, or `-'.\n\
4082 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4083 specifies the window to scroll.\n\
4084 If `other-window-scroll-buffer' is non-nil, scroll the window\n\
4085 showing that buffer, popping the buffer up if necessary.")
4087 register Lisp_Object arg
;
4089 register Lisp_Object window
;
4090 register int defalt
;
4091 register struct window
*w
;
4092 register int count
= specpdl_ptr
- specpdl
;
4094 window
= Fother_window_for_scrolling ();
4096 w
= XWINDOW (window
);
4097 defalt
= window_internal_height (w
) - next_screen_context_lines
;
4098 if (defalt
< 1) defalt
= 1;
4100 /* Don't screw up if window_scroll gets an error. */
4101 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4102 ++windows_or_buffers_changed
;
4104 Fset_buffer (w
->buffer
);
4105 SET_PT (marker_position (w
->pointm
));
4108 window_scroll (window
, defalt
, 1, 1);
4109 else if (EQ (arg
, Qminus
))
4110 window_scroll (window
, -defalt
, 1, 1);
4115 CHECK_NUMBER (arg
, 0);
4116 window_scroll (window
, XINT (arg
), 0, 1);
4119 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
4120 unbind_to (count
, Qnil
);
4125 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 1, "P",
4126 "Scroll selected window display ARG columns left.\n\
4127 Default for ARG is window width minus 2.")
4129 register Lisp_Object arg
;
4133 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4135 arg
= Fprefix_numeric_value (arg
);
4138 Fset_window_hscroll (selected_window
,
4139 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4143 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 1, "P",
4144 "Scroll selected window display ARG columns right.\n\
4145 Default for ARG is window width minus 2.")
4147 register Lisp_Object arg
;
4150 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4152 arg
= Fprefix_numeric_value (arg
);
4155 Fset_window_hscroll (selected_window
,
4156 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4160 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
4161 "Center point in window and redisplay frame. With ARG, put point on line ARG.\n\
4162 The desired position of point is always relative to the current window.\n\
4163 Just C-u as prefix means put point in the center of the window.\n\
4164 If ARG is omitted or nil, erases the entire frame and then\n\
4165 redraws with point in the center of the current window.")
4167 register Lisp_Object arg
;
4169 register struct window
*w
= XWINDOW (selected_window
);
4170 register int ht
= window_internal_height (w
);
4171 struct position pos
;
4172 struct buffer
*buf
= XBUFFER (w
->buffer
);
4173 struct buffer
*obuf
= current_buffer
;
4177 extern int frame_garbaged
;
4180 /* Invalidate pixel data calculated for all compositions. */
4181 for (i
= 0; i
< n_compositions
; i
++)
4182 composition_table
[i
]->font
= NULL
;
4184 Fredraw_frame (w
->frame
);
4185 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
4186 XSETFASTINT (arg
, ht
/ 2);
4188 else if (CONSP (arg
)) /* Just C-u. */
4190 XSETFASTINT (arg
, ht
/ 2);
4194 arg
= Fprefix_numeric_value (arg
);
4195 CHECK_NUMBER (arg
, 0);
4199 XSETINT (arg
, XINT (arg
) + ht
);
4201 set_buffer_internal (buf
);
4202 pos
= *vmotion (PT
, - XINT (arg
), w
);
4204 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
4205 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
4206 || FETCH_BYTE (pos
.bytepos
- 1) == '\n')
4208 w
->force_start
= Qt
;
4209 set_buffer_internal (obuf
);
4214 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
4216 "Position point relative to window.\n\
4217 With no argument, position point at center of window.\n\
4218 An argument specifies vertical position within the window;\n\
4219 zero means top of window, negative means relative to bottom of window.")
4221 register Lisp_Object arg
;
4223 register struct window
*w
= XWINDOW (selected_window
);
4224 register int height
= window_internal_height (w
);
4229 XSETFASTINT (arg
, height
/ 2);
4232 arg
= Fprefix_numeric_value (arg
);
4234 XSETINT (arg
, XINT (arg
) + height
);
4237 start
= marker_position (w
->start
);
4238 XSETWINDOW (window
, w
);
4239 if (start
< BEGV
|| start
> ZV
)
4241 Fvertical_motion (make_number (- (height
/ 2)), window
);
4242 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
4243 w
->start_at_line_beg
= Fbolp ();
4244 w
->force_start
= Qt
;
4247 Fgoto_char (w
->start
);
4249 return Fvertical_motion (arg
, window
);
4254 /***********************************************************************
4255 Window Configuration
4256 ***********************************************************************/
4258 struct save_window_data
4260 EMACS_INT size_from_Lisp_Vector_struct
;
4261 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4262 Lisp_Object frame_width
, frame_height
, frame_menu_bar_lines
;
4263 Lisp_Object frame_tool_bar_lines
;
4264 Lisp_Object selected_frame
;
4265 Lisp_Object current_window
;
4266 Lisp_Object current_buffer
;
4267 Lisp_Object minibuf_scroll_window
;
4268 Lisp_Object root_window
;
4269 Lisp_Object focus_frame
;
4270 /* Record the values of window-min-width and window-min-height
4271 so that window sizes remain consistent with them. */
4272 Lisp_Object min_width
, min_height
;
4273 /* A vector, each of whose elements is a struct saved_window
4275 Lisp_Object saved_windows
;
4278 /* This is saved as a Lisp_Vector */
4281 /* these first two must agree with struct Lisp_Vector in lisp.h */
4282 EMACS_INT size_from_Lisp_Vector_struct
;
4283 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4286 Lisp_Object buffer
, start
, pointm
, mark
;
4287 Lisp_Object left
, top
, width
, height
, hscroll
;
4288 Lisp_Object parent
, prev
;
4289 Lisp_Object start_at_line_beg
;
4290 Lisp_Object display_table
;
4292 #define SAVED_WINDOW_VECTOR_SIZE 14 /* Arg to Fmake_vector */
4294 #define SAVED_WINDOW_N(swv,n) \
4295 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
4297 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
4298 "Return t if OBJECT is a window-configuration object.")
4302 if (WINDOW_CONFIGURATIONP (object
))
4307 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
4308 "Return the frame that CONFIG, a window-configuration object, is about.")
4312 register struct save_window_data
*data
;
4313 struct Lisp_Vector
*saved_windows
;
4315 if (! WINDOW_CONFIGURATIONP (config
))
4316 wrong_type_argument (Qwindow_configuration_p
, config
);
4318 data
= (struct save_window_data
*) XVECTOR (config
);
4319 saved_windows
= XVECTOR (data
->saved_windows
);
4320 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4323 DEFUN ("set-window-configuration", Fset_window_configuration
,
4324 Sset_window_configuration
, 1, 1, 0,
4325 "Set the configuration of windows and buffers as specified by CONFIGURATION.\n\
4326 CONFIGURATION must be a value previously returned\n\
4327 by `current-window-configuration' (which see).\n\
4328 If CONFIGURATION was made from a frame that is now deleted,\n\
4329 only frame-independent values can be restored. In this case,\n\
4330 the return value is nil. Otherwise the value is t.")
4332 Lisp_Object configuration
;
4334 register struct save_window_data
*data
;
4335 struct Lisp_Vector
*saved_windows
;
4336 Lisp_Object new_current_buffer
;
4341 while (!WINDOW_CONFIGURATIONP (configuration
))
4342 wrong_type_argument (Qwindow_configuration_p
, configuration
);
4344 data
= (struct save_window_data
*) XVECTOR (configuration
);
4345 saved_windows
= XVECTOR (data
->saved_windows
);
4347 new_current_buffer
= data
->current_buffer
;
4348 if (NILP (XBUFFER (new_current_buffer
)->name
))
4349 new_current_buffer
= Qnil
;
4352 if (XBUFFER (new_current_buffer
) == current_buffer
)
4357 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4360 /* If f is a dead frame, don't bother rebuilding its window tree.
4361 However, there is other stuff we should still try to do below. */
4362 if (FRAME_LIVE_P (f
))
4364 register struct window
*w
;
4365 register struct saved_window
*p
;
4366 struct window
*root_window
;
4367 struct window
**leaf_windows
;
4371 /* If the frame has been resized since this window configuration was
4372 made, we change the frame to the size specified in the
4373 configuration, restore the configuration, and then resize it
4374 back. We keep track of the prevailing height in these variables. */
4375 int previous_frame_height
= FRAME_HEIGHT (f
);
4376 int previous_frame_width
= FRAME_WIDTH (f
);
4377 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
4378 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
4380 /* The mouse highlighting code could get screwed up
4381 if it runs during this. */
4384 if (XFASTINT (data
->frame_height
) != previous_frame_height
4385 || XFASTINT (data
->frame_width
) != previous_frame_width
)
4386 change_frame_size (f
, XFASTINT (data
->frame_height
),
4387 XFASTINT (data
->frame_width
), 0, 0, 0);
4388 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4389 if (XFASTINT (data
->frame_menu_bar_lines
)
4390 != previous_frame_menu_bar_lines
)
4391 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, make_number (0));
4392 #ifdef HAVE_WINDOW_SYSTEM
4393 if (XFASTINT (data
->frame_tool_bar_lines
)
4394 != previous_frame_tool_bar_lines
)
4395 x_set_tool_bar_lines (f
, data
->frame_tool_bar_lines
, make_number (0));
4399 /* "Swap out" point from the selected window
4400 into its buffer. We do this now, before
4401 restoring the window contents, and prevent it from
4402 being done later on when we select a new window. */
4403 if (! NILP (XWINDOW (selected_window
)->buffer
))
4405 w
= XWINDOW (selected_window
);
4406 set_marker_both (w
->pointm
,
4408 BUF_PT (XBUFFER (w
->buffer
)),
4409 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4412 windows_or_buffers_changed
++;
4413 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4415 /* Problem: Freeing all matrices and later allocating them again
4416 is a serious redisplay flickering problem. What we would
4417 really like to do is to free only those matrices not reused
4419 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4421 = (struct window
**) alloca (count_windows (root_window
)
4422 * sizeof (struct window
*));
4423 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
4425 /* Temporarily avoid any problems with windows that are smaller
4426 than they are supposed to be. */
4427 window_min_height
= 1;
4428 window_min_width
= 1;
4431 Mark all windows now on frame as "deleted".
4432 Restoring the new configuration "undeletes" any that are in it.
4434 Save their current buffers in their height fields, since we may
4435 need it later, if a buffer saved in the configuration is now
4437 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4439 for (k
= 0; k
< saved_windows
->size
; k
++)
4441 p
= SAVED_WINDOW_N (saved_windows
, k
);
4442 w
= XWINDOW (p
->window
);
4445 if (!NILP (p
->parent
))
4446 w
->parent
= SAVED_WINDOW_N (saved_windows
,
4447 XFASTINT (p
->parent
))->window
;
4451 if (!NILP (p
->prev
))
4453 w
->prev
= SAVED_WINDOW_N (saved_windows
,
4454 XFASTINT (p
->prev
))->window
;
4455 XWINDOW (w
->prev
)->next
= p
->window
;
4460 if (!NILP (w
->parent
))
4462 if (EQ (p
->width
, XWINDOW (w
->parent
)->width
))
4464 XWINDOW (w
->parent
)->vchild
= p
->window
;
4465 XWINDOW (w
->parent
)->hchild
= Qnil
;
4469 XWINDOW (w
->parent
)->hchild
= p
->window
;
4470 XWINDOW (w
->parent
)->vchild
= Qnil
;
4475 /* If we squirreled away the buffer in the window's height,
4477 if (BUFFERP (w
->height
))
4478 w
->buffer
= w
->height
;
4481 w
->width
= p
->width
;
4482 w
->height
= p
->height
;
4483 w
->hscroll
= p
->hscroll
;
4484 w
->display_table
= p
->display_table
;
4485 XSETFASTINT (w
->last_modified
, 0);
4486 XSETFASTINT (w
->last_overlay_modified
, 0);
4488 /* Reinstall the saved buffer and pointers into it. */
4489 if (NILP (p
->buffer
))
4490 w
->buffer
= p
->buffer
;
4493 if (!NILP (XBUFFER (p
->buffer
)->name
))
4494 /* If saved buffer is alive, install it. */
4496 w
->buffer
= p
->buffer
;
4497 w
->start_at_line_beg
= p
->start_at_line_beg
;
4498 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
4499 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
4500 Fset_marker (XBUFFER (w
->buffer
)->mark
,
4501 p
->mark
, w
->buffer
);
4503 /* As documented in Fcurrent_window_configuration, don't
4504 save the location of point in the buffer which was current
4505 when the window configuration was recorded. */
4506 if (!EQ (p
->buffer
, new_current_buffer
)
4507 && XBUFFER (p
->buffer
) == current_buffer
)
4508 Fgoto_char (w
->pointm
);
4510 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
4511 /* Else unless window has a live buffer, get one. */
4513 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
4514 /* This will set the markers to beginning of visible
4516 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
4517 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
4518 w
->start_at_line_beg
= Qt
;
4521 /* Keeping window's old buffer; make sure the markers
4524 /* Set window markers at start of visible range. */
4525 if (XMARKER (w
->start
)->buffer
== 0)
4526 set_marker_restricted (w
->start
, make_number (0),
4528 if (XMARKER (w
->pointm
)->buffer
== 0)
4529 set_marker_restricted_both (w
->pointm
, w
->buffer
,
4530 BUF_PT (XBUFFER (w
->buffer
)),
4531 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4532 w
->start_at_line_beg
= Qt
;
4537 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
4538 /* Prevent "swapping out point" in the old selected window
4539 using the buffer that has been restored into it.
4540 That swapping out has already been done,
4541 near the beginning of this function. */
4542 selected_window
= Qnil
;
4543 Fselect_window (data
->current_window
);
4544 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
4547 if (NILP (data
->focus_frame
)
4548 || (FRAMEP (data
->focus_frame
)
4549 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
4550 Fredirect_frame_focus (frame
, data
->focus_frame
);
4552 #if 0 /* I don't understand why this is needed, and it causes problems
4553 when the frame's old selected window has been deleted. */
4554 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
4555 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
4559 /* Set the screen height to the value it had before this function. */
4560 if (previous_frame_height
!= FRAME_HEIGHT (f
)
4561 || previous_frame_width
!= FRAME_WIDTH (f
))
4562 change_frame_size (f
, previous_frame_height
, previous_frame_width
,
4564 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4565 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
4566 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
4568 #ifdef HAVE_WINDOW_SYSTEM
4569 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
4570 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
4575 /* Now, free glyph matrices in windows that were not reused. */
4576 for (i
= 0; i
< n_leaf_windows
; ++i
)
4577 if (NILP (leaf_windows
[i
]->buffer
))
4579 /* Assert it's not reused as a combination. */
4580 xassert (NILP (leaf_windows
[i
]->hchild
)
4581 && NILP (leaf_windows
[i
]->vchild
));
4582 free_window_matrices (leaf_windows
[i
]);
4583 SET_FRAME_GARBAGED (f
);
4590 /* Fselect_window will have made f the selected frame, so we
4591 reselect the proper frame here. Fhandle_switch_frame will change the
4592 selected window too, but that doesn't make the call to
4593 Fselect_window above totally superfluous; it still sets f's
4595 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
4596 do_switch_frame (data
->selected_frame
, Qnil
, 0);
4598 if (! NILP (Vwindow_configuration_change_hook
)
4599 && ! NILP (Vrun_hooks
))
4600 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
4603 if (!NILP (new_current_buffer
))
4605 Fset_buffer (new_current_buffer
);
4607 /* If the buffer that is current now is the same
4608 that was current before setting the window configuration,
4609 don't alter its PT. */
4614 /* Restore the minimum heights recorded in the configuration. */
4615 window_min_height
= XINT (data
->min_height
);
4616 window_min_width
= XINT (data
->min_width
);
4618 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
4620 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
4623 /* Mark all windows now on frame as deleted
4624 by setting their buffers to nil. */
4627 delete_all_subwindows (w
)
4628 register struct window
*w
;
4630 if (!NILP (w
->next
))
4631 delete_all_subwindows (XWINDOW (w
->next
));
4632 if (!NILP (w
->vchild
))
4633 delete_all_subwindows (XWINDOW (w
->vchild
));
4634 if (!NILP (w
->hchild
))
4635 delete_all_subwindows (XWINDOW (w
->hchild
));
4637 w
->height
= w
->buffer
; /* See Fset_window_configuration for excuse. */
4639 if (!NILP (w
->buffer
))
4642 /* We set all three of these fields to nil, to make sure that we can
4643 distinguish this dead window from any live window. Live leaf
4644 windows will have buffer set, and combination windows will have
4645 vchild or hchild set. */
4652 count_windows (window
)
4653 register struct window
*window
;
4655 register int count
= 1;
4656 if (!NILP (window
->next
))
4657 count
+= count_windows (XWINDOW (window
->next
));
4658 if (!NILP (window
->vchild
))
4659 count
+= count_windows (XWINDOW (window
->vchild
));
4660 if (!NILP (window
->hchild
))
4661 count
+= count_windows (XWINDOW (window
->hchild
));
4666 /* Fill vector FLAT with leaf windows under W, starting at index I.
4667 Value is last index + 1. */
4670 get_leaf_windows (w
, flat
, i
)
4672 struct window
**flat
;
4677 if (!NILP (w
->hchild
))
4678 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
4679 else if (!NILP (w
->vchild
))
4680 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
4684 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4691 /* Return a pointer to the glyph W's physical cursor is on. Value is
4692 null if W's current matrix is invalid, so that no meaningfull glyph
4696 get_phys_cursor_glyph (w
)
4699 struct glyph_row
*row
;
4700 struct glyph
*glyph
;
4702 if (w
->phys_cursor
.vpos
>= 0
4703 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
4704 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
4706 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
4707 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
4716 save_window_save (window
, vector
, i
)
4718 struct Lisp_Vector
*vector
;
4721 register struct saved_window
*p
;
4722 register struct window
*w
;
4723 register Lisp_Object tem
;
4725 for (;!NILP (window
); window
= w
->next
)
4727 p
= SAVED_WINDOW_N (vector
, i
);
4728 w
= XWINDOW (window
);
4730 XSETFASTINT (w
->temslot
, i
++);
4732 p
->buffer
= w
->buffer
;
4735 p
->width
= w
->width
;
4736 p
->height
= w
->height
;
4737 p
->hscroll
= w
->hscroll
;
4738 p
->display_table
= w
->display_table
;
4739 if (!NILP (w
->buffer
))
4741 /* Save w's value of point in the window configuration.
4742 If w is the selected window, then get the value of point
4743 from the buffer; pointm is garbage in the selected window. */
4744 if (EQ (window
, selected_window
))
4746 p
->pointm
= Fmake_marker ();
4747 set_marker_both (p
->pointm
, w
->buffer
,
4748 BUF_PT (XBUFFER (w
->buffer
)),
4749 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4752 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
4754 p
->start
= Fcopy_marker (w
->start
, Qnil
);
4755 p
->start_at_line_beg
= w
->start_at_line_beg
;
4757 tem
= XBUFFER (w
->buffer
)->mark
;
4758 p
->mark
= Fcopy_marker (tem
, Qnil
);
4765 p
->start_at_line_beg
= Qnil
;
4768 if (NILP (w
->parent
))
4771 p
->parent
= XWINDOW (w
->parent
)->temslot
;
4776 p
->prev
= XWINDOW (w
->prev
)->temslot
;
4778 if (!NILP (w
->vchild
))
4779 i
= save_window_save (w
->vchild
, vector
, i
);
4780 if (!NILP (w
->hchild
))
4781 i
= save_window_save (w
->hchild
, vector
, i
);
4787 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
4788 Scurrent_window_configuration
, 0, 1, 0,
4789 "Return an object representing the current window configuration of FRAME.\n\
4790 If FRAME is nil or omitted, use the selected frame.\n\
4791 This describes the number of windows, their sizes and current buffers,\n\
4792 and for each displayed buffer, where display starts, and the positions of\n\
4793 point and mark. An exception is made for point in the current buffer:\n\
4794 its value is -not- saved.\n\
4795 This also records the currently selected frame, and FRAME's focus\n\
4796 redirection (see `redirect-frame-focus').")
4800 register Lisp_Object tem
;
4801 register int n_windows
;
4802 register struct save_window_data
*data
;
4803 register struct Lisp_Vector
*vec
;
4808 frame
= selected_frame
;
4809 CHECK_LIVE_FRAME (frame
, 0);
4812 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4813 vec
= allocate_vectorlike (VECSIZE (struct save_window_data
));
4814 for (i
= 0; i
< VECSIZE (struct save_window_data
); i
++)
4815 vec
->contents
[i
] = Qnil
;
4816 vec
->size
= VECSIZE (struct save_window_data
);
4817 data
= (struct save_window_data
*)vec
;
4819 XSETFASTINT (data
->frame_width
, FRAME_WIDTH (f
));
4820 XSETFASTINT (data
->frame_height
, FRAME_HEIGHT (f
));
4821 XSETFASTINT (data
->frame_menu_bar_lines
, FRAME_MENU_BAR_LINES (f
));
4822 XSETFASTINT (data
->frame_tool_bar_lines
, FRAME_TOOL_BAR_LINES (f
));
4823 data
->selected_frame
= selected_frame
;
4824 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
4825 XSETBUFFER (data
->current_buffer
, current_buffer
);
4826 data
->minibuf_scroll_window
= Vminibuf_scroll_window
;
4827 data
->root_window
= FRAME_ROOT_WINDOW (f
);
4828 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
4829 XSETINT (data
->min_height
, window_min_height
);
4830 XSETINT (data
->min_width
, window_min_width
);
4831 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
4832 data
->saved_windows
= tem
;
4833 for (i
= 0; i
< n_windows
; i
++)
4834 XVECTOR (tem
)->contents
[i
]
4835 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
4836 save_window_save (FRAME_ROOT_WINDOW (f
),
4838 XSETWINDOW_CONFIGURATION (tem
, data
);
4842 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
4844 "Execute body, preserving window sizes and contents.\n\
4845 Restore which buffer appears in which window, where display starts,\n\
4846 and the value of point and mark for each window.\n\
4847 Also restore the choice of selected window.\n\
4848 Also restore which buffer is current.\n\
4849 Does not restore the value of point in current buffer.")
4853 register Lisp_Object val
;
4854 register int count
= specpdl_ptr
- specpdl
;
4856 record_unwind_protect (Fset_window_configuration
,
4857 Fcurrent_window_configuration (Qnil
));
4858 val
= Fprogn (args
);
4859 return unbind_to (count
, val
);
4863 /***********************************************************************
4865 ***********************************************************************/
4867 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
4869 "Set width of marginal areas of window WINDOW.\n\
4870 If window is nil, set margins of the currently selected window.\n\
4871 First parameter LEFT-WIDTH specifies the number of character\n\
4872 cells to reserve for the left marginal area. Second parameter\n\
4873 RIGHT-WIDTH does the same for the right marginal area.\n\
4874 A nil width parameter means no margin.")
4875 (window
, left
, right
)
4876 Lisp_Object window
, left
, right
;
4878 struct window
*w
= decode_window (window
);
4881 CHECK_NUMBER_OR_FLOAT (left
, 1);
4883 CHECK_NUMBER_OR_FLOAT (right
, 2);
4885 /* Check widths < 0 and translate a zero width to nil.
4886 Margins that are too wide have to be checked elsewhere. */
4887 if ((INTEGERP (left
) && XINT (left
) < 0)
4888 || (FLOATP (left
) && XFLOAT_DATA (left
) <= 0))
4889 XSETFASTINT (left
, 0);
4890 if (INTEGERP (left
) && XFASTINT (left
) == 0)
4893 if ((INTEGERP (right
) && XINT (right
) < 0)
4894 || (FLOATP (right
) && XFLOAT_DATA (right
) <= 0))
4895 XSETFASTINT (right
, 0);
4896 if (INTEGERP (right
) && XFASTINT (right
) == 0)
4899 w
->left_margin_width
= left
;
4900 w
->right_margin_width
= right
;
4902 ++windows_or_buffers_changed
;
4903 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
4908 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
4910 "Get width of marginal areas of window WINDOW.\n\
4911 If WINDOW is omitted or nil, use the currently selected window.\n\
4912 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).\n\
4913 If a marginal area does not exist, its width will be returned\n\
4918 struct window
*w
= decode_window (window
);
4919 return Fcons (w
->left_margin_width
, w
->right_margin_width
);
4924 /***********************************************************************
4926 ***********************************************************************/
4928 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 1, 0,
4929 "Return the amount by which WINDOW is scrolled vertically.\n\
4930 Use the selected window if WINDOW is nil or omitted.\n\
4931 Value is a multiple of the canonical character height of WINDOW.")
4940 window
= selected_window
;
4942 CHECK_WINDOW (window
, 0);
4943 w
= XWINDOW (window
);
4944 f
= XFRAME (w
->frame
);
4946 if (FRAME_WINDOW_P (f
))
4947 result
= CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
);
4949 result
= make_number (0);
4954 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
4956 "Set amount by which WINDOW should be scrolled vertically to VSCROLL.\n\
4957 WINDOW nil or omitted means use the selected window. VSCROLL is a\n\
4958 non-negative multiple of the canonical character height of WINDOW.")
4960 Lisp_Object window
, vscroll
;
4966 window
= selected_window
;
4968 CHECK_WINDOW (window
, 0);
4969 CHECK_NUMBER_OR_FLOAT (vscroll
, 1);
4971 w
= XWINDOW (window
);
4972 f
= XFRAME (w
->frame
);
4974 if (FRAME_WINDOW_P (f
))
4976 int old_dy
= w
->vscroll
;
4978 w
->vscroll
= - CANON_Y_UNIT (f
) * XFLOATINT (vscroll
);
4979 w
->vscroll
= min (w
->vscroll
, 0);
4981 /* Adjust glyph matrix of the frame if the virtual display
4982 area becomes larger than before. */
4983 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
4986 /* Prevent redisplay shortcuts. */
4987 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
4990 return Fwindow_vscroll (window
);
4994 /* Call FN for all leaf windows on frame F. FN is called with the
4995 first argument being a pointer to the leaf window, and with
4996 additional arguments A1..A4. */
4999 foreach_window (f
, fn
, a1
, a2
, a3
, a4
)
5004 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, a1
, a2
, a3
, a4
);
5008 /* Helper function for foreach_window. Call FN for all leaf windows
5009 reachable from W. FN is called with the first argument being a
5010 pointer to the leaf window, and with additional arguments A1..A4. */
5013 foreach_window_1 (w
, fn
, a1
, a2
, a3
, a4
)
5020 if (!NILP (w
->hchild
))
5021 foreach_window_1 (XWINDOW (w
->hchild
), fn
, a1
, a2
, a3
, a4
);
5022 else if (!NILP (w
->vchild
))
5023 foreach_window_1 (XWINDOW (w
->vchild
), fn
, a1
, a2
, a3
, a4
);
5025 fn (w
, a1
, a2
, a3
, a4
);
5027 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5032 /* Freeze or unfreeze the window start of W if unless it is a
5033 mini-window or the selected window. FREEZE_P non-zero means freeze
5034 the window start. */
5037 freeze_window_start (w
, freeze_p
)
5041 if (w
== XWINDOW (selected_window
)
5042 || MINI_WINDOW_P (w
)
5043 || (MINI_WINDOW_P (XWINDOW (selected_window
))
5044 && w
== XWINDOW (Vminibuf_scroll_window
)))
5047 w
->frozen_window_start_p
= freeze_p
;
5051 /* Freeze or unfreeze the window starts of all leaf windows on frame
5052 F, except the selected window and a mini-window. FREEZE_P non-zero
5053 means freeze the window start. */
5056 freeze_window_starts (f
, freeze_p
)
5060 foreach_window (f
, freeze_window_start
, freeze_p
);
5064 /***********************************************************************
5066 ***********************************************************************/
5068 /* Return 1 if window configurations C1 and C2
5069 describe the same state of affairs. This is used by Fequal. */
5072 compare_window_configurations (c1
, c2
, ignore_positions
)
5074 int ignore_positions
;
5076 register struct save_window_data
*d1
, *d2
;
5077 struct Lisp_Vector
*sw1
, *sw2
;
5080 d1
= (struct save_window_data
*) XVECTOR (c1
);
5081 d2
= (struct save_window_data
*) XVECTOR (c2
);
5082 sw1
= XVECTOR (d1
->saved_windows
);
5083 sw2
= XVECTOR (d2
->saved_windows
);
5085 if (! EQ (d1
->frame_width
, d2
->frame_width
))
5087 if (! EQ (d1
->frame_height
, d2
->frame_height
))
5089 if (! EQ (d1
->frame_menu_bar_lines
, d2
->frame_menu_bar_lines
))
5091 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
5093 /* Don't compare the current_window field directly.
5094 Instead see w1_is_current and w2_is_current, below. */
5095 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
5097 if (! ignore_positions
)
5098 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
5100 /* Don't compare the root_window field.
5101 We don't require the two configurations
5102 to use the same window object,
5103 and the two root windows must be equivalent
5104 if everything else compares equal. */
5105 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
5107 if (! EQ (d1
->min_width
, d2
->min_width
))
5109 if (! EQ (d1
->min_height
, d2
->min_height
))
5112 /* Verify that the two confis have the same number of windows. */
5113 if (sw1
->size
!= sw2
->size
)
5116 for (i
= 0; i
< sw1
->size
; i
++)
5118 struct saved_window
*p1
, *p2
;
5119 int w1_is_current
, w2_is_current
;
5121 p1
= SAVED_WINDOW_N (sw1
, i
);
5122 p2
= SAVED_WINDOW_N (sw2
, i
);
5124 /* Verify that the current windows in the two
5125 configurations correspond to each other. */
5126 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
5127 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
5129 if (w1_is_current
!= w2_is_current
)
5132 /* Verify that the corresponding windows do match. */
5133 if (! EQ (p1
->buffer
, p2
->buffer
))
5135 if (! EQ (p1
->left
, p2
->left
))
5137 if (! EQ (p1
->top
, p2
->top
))
5139 if (! EQ (p1
->width
, p2
->width
))
5141 if (! EQ (p1
->height
, p2
->height
))
5143 if (! EQ (p1
->display_table
, p2
->display_table
))
5145 if (! EQ (p1
->parent
, p2
->parent
))
5147 if (! EQ (p1
->prev
, p2
->prev
))
5149 if (! ignore_positions
)
5151 if (! EQ (p1
->hscroll
, p2
->hscroll
))
5153 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
5155 if (NILP (Fequal (p1
->start
, p2
->start
)))
5157 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
5159 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
5167 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
5168 Scompare_window_configurations
, 2, 2, 0,
5169 "Compare two window configurations as regards the structure of windows.\n\
5170 This function ignores details such as the values of point and mark\n\
5171 and scrolling positions.")
5175 if (compare_window_configurations (x
, y
, 1))
5183 struct frame
*f
= make_terminal_frame ();
5184 XSETFRAME (selected_frame
, f
);
5185 Vterminal_frame
= selected_frame
;
5186 minibuf_window
= f
->minibuffer_window
;
5187 selected_window
= f
->selected_window
;
5188 last_nonminibuf_frame
= f
;
5190 window_initialized
= 1;
5196 Qleft_bitmap_area
= intern ("left-bitmap-area");
5197 staticpro (&Qleft_bitmap_area
);
5198 Qright_bitmap_area
= intern ("right-bitmap-area");
5199 staticpro (&Qright_bitmap_area
);
5201 Qwindow_size_fixed
= intern ("window-size-fixed");
5202 staticpro (&Qwindow_size_fixed
);
5204 staticpro (&Qwindow_configuration_change_hook
);
5205 Qwindow_configuration_change_hook
5206 = intern ("window-configuration-change-hook");
5208 Qwindowp
= intern ("windowp");
5209 staticpro (&Qwindowp
);
5211 Qwindow_configuration_p
= intern ("window-configuration-p");
5212 staticpro (&Qwindow_configuration_p
);
5214 Qwindow_live_p
= intern ("window-live-p");
5215 staticpro (&Qwindow_live_p
);
5217 Qtemp_buffer_show_hook
= intern ("temp-buffer-show-hook");
5218 staticpro (&Qtemp_buffer_show_hook
);
5220 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
5221 "Non-nil means call as function to display a help buffer.\n\
5222 The function is called with one argument, the buffer to be displayed.\n\
5223 Used by `with-output-to-temp-buffer'.\n\
5224 If this function is used, then it must do the entire job of showing\n\
5225 the buffer; `temp-buffer-show-hook' is not run unless this function runs it.");
5226 Vtemp_buffer_show_function
= Qnil
;
5228 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
5229 "If non-nil, function to call to handle `display-buffer'.\n\
5230 It will receive two args, the buffer and a flag which if non-nil means\n\
5231 that the currently selected window is not acceptable.\n\
5232 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
5233 work using this function.");
5234 Vdisplay_buffer_function
= Qnil
;
5236 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
5237 "Non-nil means it is the window that C-M-v in minibuffer should scroll.");
5238 Vminibuf_scroll_window
= Qnil
;
5240 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
5241 "If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.");
5242 Vother_window_scroll_buffer
= Qnil
;
5244 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
5245 "*Non-nil means `display-buffer' should make a separate frame.");
5248 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
5249 "Function to call to handle automatic new frame creation.\n\
5250 It is called with no arguments and should return a newly created frame.\n\
5252 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'\n\
5253 where `pop-up-frame-alist' would hold the default frame parameters.");
5254 Vpop_up_frame_function
= Qnil
;
5256 DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names
,
5257 "*List of buffer names that should have their own special frames.\n\
5258 Displaying a buffer whose name is in this list makes a special frame for it\n\
5259 using `special-display-function'. See also `special-display-regexps'.\n\
5261 An element of the list can be a list instead of just a string.\n\
5262 There are two ways to use a list as an element:\n\
5263 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)\n\
5264 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5265 In the latter case, FUNCTION is called with BUFFER as the first argument,\n\
5266 followed by OTHER-ARGS--it can display BUFFER in any way it likes.\n\
5267 All this is done by the function found in `special-display-function'.\n\
5269 If this variable appears \"not to work\", because you add a name to it\n\
5270 but that buffer still appears in the selected window, look at the\n\
5271 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5272 Those variables take precedence over this one.");
5273 Vspecial_display_buffer_names
= Qnil
;
5275 DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps
,
5276 "*List of regexps saying which buffers should have their own special frames.\n\
5277 If a buffer name matches one of these regexps, it gets its own frame.\n\
5278 Displaying a buffer whose name is in this list makes a special frame for it\n\
5279 using `special-display-function'.\n\
5281 An element of the list can be a list instead of just a string.\n\
5282 There are two ways to use a list as an element:\n\
5283 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)\n\
5284 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5285 In the latter case, FUNCTION is called with the buffer as first argument,\n\
5286 followed by OTHER-ARGS--it can display the buffer in any way it likes.\n\
5287 All this is done by the function found in `special-display-function'.\n\
5289 If this variable appears \"not to work\", because you add a regexp to it\n\
5290 but the matching buffers still appear in the selected window, look at the\n\
5291 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5292 Those variables take precedence over this one.");
5293 Vspecial_display_regexps
= Qnil
;
5295 DEFVAR_LISP ("special-display-function", &Vspecial_display_function
,
5296 "Function to call to make a new frame for a special buffer.\n\
5297 It is called with two arguments, the buffer and optional buffer specific\n\
5298 data, and should return a window displaying that buffer.\n\
5299 The default value makes a separate frame for the buffer,\n\
5300 using `special-display-frame-alist' to specify the frame parameters.\n\
5302 A buffer is special if its is listed in `special-display-buffer-names'\n\
5303 or matches a regexp in `special-display-regexps'.");
5304 Vspecial_display_function
= Qnil
;
5306 DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names
,
5307 "*List of buffer names that should appear in the selected window.\n\
5308 Displaying one of these buffers using `display-buffer' or `pop-to-buffer'\n\
5309 switches to it in the selected window, rather than making it appear\n\
5310 in some other window.\n\
5312 An element of the list can be a cons cell instead of just a string.\n\
5313 Then the car must be a string, which specifies the buffer name.\n\
5314 This is for compatibility with `special-display-buffer-names';\n\
5315 the cdr of the cons cell is ignored.\n\
5317 See also `same-window-regexps'.");
5318 Vsame_window_buffer_names
= Qnil
;
5320 DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps
,
5321 "*List of regexps saying which buffers should appear in the selected window.\n\
5322 If a buffer name matches one of these regexps, then displaying it\n\
5323 using `display-buffer' or `pop-to-buffer' switches to it\n\
5324 in the selected window, rather than making it appear in some other window.\n\
5326 An element of the list can be a cons cell instead of just a string.\n\
5327 Then the car must be a string, which specifies the buffer name.\n\
5328 This is for compatibility with `special-display-buffer-names';\n\
5329 the cdr of the cons cell is ignored.\n\
5331 See also `same-window-buffer-names'.");
5332 Vsame_window_regexps
= Qnil
;
5334 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
5335 "*Non-nil means display-buffer should make new windows.");
5338 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
5339 "*Number of lines of continuity when scrolling by screenfuls.");
5340 next_screen_context_lines
= 2;
5342 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
5343 "*display-buffer would prefer to split the largest window if this large.\n\
5344 If there is only one window, it is split regardless of this value.");
5345 split_height_threshold
= 500;
5347 DEFVAR_INT ("window-min-height", &window_min_height
,
5348 "*Delete any window less than this tall (including its mode line).");
5349 window_min_height
= 4;
5351 DEFVAR_INT ("window-min-width", &window_min_width
,
5352 "*Delete any window less than this wide.");
5353 window_min_width
= 10;
5355 DEFVAR_LISP ("scroll-preserve-screen-position",
5356 &Vscroll_preserve_screen_position
,
5357 "*Nonzero means scroll commands move point to keep its screen line unchanged.");
5358 Vscroll_preserve_screen_position
= Qnil
;
5360 DEFVAR_LISP ("window-configuration-change-hook",
5361 &Vwindow_configuration_change_hook
,
5362 "Functions to call when window configuration changes.\n\
5363 The selected frame is the one whose configuration has changed.");
5364 Vwindow_configuration_change_hook
= Qnil
;
5366 defsubr (&Sselected_window
);
5367 defsubr (&Sminibuffer_window
);
5368 defsubr (&Swindow_minibuffer_p
);
5369 defsubr (&Swindowp
);
5370 defsubr (&Swindow_live_p
);
5371 defsubr (&Spos_visible_in_window_p
);
5372 defsubr (&Swindow_buffer
);
5373 defsubr (&Swindow_height
);
5374 defsubr (&Swindow_width
);
5375 defsubr (&Swindow_hscroll
);
5376 defsubr (&Sset_window_hscroll
);
5377 defsubr (&Swindow_redisplay_end_trigger
);
5378 defsubr (&Sset_window_redisplay_end_trigger
);
5379 defsubr (&Swindow_edges
);
5380 defsubr (&Scoordinates_in_window_p
);
5381 defsubr (&Swindow_at
);
5382 defsubr (&Swindow_point
);
5383 defsubr (&Swindow_start
);
5384 defsubr (&Swindow_end
);
5385 defsubr (&Sset_window_point
);
5386 defsubr (&Sset_window_start
);
5387 defsubr (&Swindow_dedicated_p
);
5388 defsubr (&Sset_window_dedicated_p
);
5389 defsubr (&Swindow_display_table
);
5390 defsubr (&Sset_window_display_table
);
5391 defsubr (&Snext_window
);
5392 defsubr (&Sprevious_window
);
5393 defsubr (&Sother_window
);
5394 defsubr (&Sget_lru_window
);
5395 defsubr (&Sget_largest_window
);
5396 defsubr (&Sget_buffer_window
);
5397 defsubr (&Sdelete_other_windows
);
5398 defsubr (&Sdelete_windows_on
);
5399 defsubr (&Sreplace_buffer_in_windows
);
5400 defsubr (&Sdelete_window
);
5401 defsubr (&Sset_window_buffer
);
5402 defsubr (&Sselect_window
);
5403 defsubr (&Sspecial_display_p
);
5404 defsubr (&Ssame_window_p
);
5405 defsubr (&Sdisplay_buffer
);
5406 defsubr (&Ssplit_window
);
5407 defsubr (&Senlarge_window
);
5408 defsubr (&Sshrink_window
);
5409 defsubr (&Sscroll_up
);
5410 defsubr (&Sscroll_down
);
5411 defsubr (&Sscroll_left
);
5412 defsubr (&Sscroll_right
);
5413 defsubr (&Sother_window_for_scrolling
);
5414 defsubr (&Sscroll_other_window
);
5415 defsubr (&Srecenter
);
5416 defsubr (&Smove_to_window_line
);
5417 defsubr (&Swindow_configuration_p
);
5418 defsubr (&Swindow_configuration_frame
);
5419 defsubr (&Sset_window_configuration
);
5420 defsubr (&Scurrent_window_configuration
);
5421 defsubr (&Ssave_window_excursion
);
5422 defsubr (&Sset_window_margins
);
5423 defsubr (&Swindow_margins
);
5424 defsubr (&Swindow_vscroll
);
5425 defsubr (&Sset_window_vscroll
);
5426 defsubr (&Scompare_window_configurations
);
5432 initial_define_key (control_x_map
, '1', "delete-other-windows");
5433 initial_define_key (control_x_map
, '2', "split-window");
5434 initial_define_key (control_x_map
, '0', "delete-window");
5435 initial_define_key (control_x_map
, 'o', "other-window");
5436 initial_define_key (control_x_map
, '^', "enlarge-window");
5437 initial_define_key (control_x_map
, '<', "scroll-left");
5438 initial_define_key (control_x_map
, '>', "scroll-right");
5440 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
5441 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
5442 initial_define_key (meta_map
, 'v', "scroll-down");
5444 initial_define_key (global_map
, Ctl('L'), "recenter");
5445 initial_define_key (meta_map
, 'r', "move-to-window-line");