1 /* Window creation, deletion and examination for GNU Emacs.
2 Does not include redisplay.
3 Copyright (C) 1985,86,87,93,94,95,96,97,1998 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
32 #include "dispextern.h"
33 #include "blockinput.h"
34 #include "intervals.h"
38 #endif /* HAVE_X_WINDOWS */
47 #define max(a, b) ((a) < (b) ? (b) : (a))
51 Lisp_Object Qwindowp
, Qwindow_live_p
, Qwindow_configuration_p
;
52 Lisp_Object Qwindow_size_fixed
, Qleft_bitmap_area
, Qright_bitmap_area
;
53 extern Lisp_Object Qheight
, Qwidth
;
55 static struct window
*decode_window
P_ ((Lisp_Object
));
56 static Lisp_Object select_window_1
P_ ((Lisp_Object
, int));
57 static int count_windows
P_ ((struct window
*));
58 static int get_leaf_windows
P_ ((struct window
*, struct window
**, int));
59 static void window_scroll
P_ ((Lisp_Object
, int, int, int));
60 static void window_scroll_pixel_based
P_ ((Lisp_Object
, int, int, int));
61 static void window_scroll_line_based
P_ ((Lisp_Object
, int, int, int));
62 static int window_min_size_1
P_ ((struct window
*, int));
63 static int window_min_size
P_ ((struct window
*, int, int, int *));
64 static void size_window
P_ ((Lisp_Object
, int, int, int));
65 static int freeze_window_start
P_ ((struct window
*, void *));
66 static int window_fixed_size_p
P_ ((struct window
*, int, int));
67 static void enlarge_window
P_ ((Lisp_Object
, int, int));
68 static Lisp_Object window_list
P_ ((void));
69 static int add_window_to_list
P_ ((struct window
*, void *));
70 static int candidate_window_p
P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
,
72 static Lisp_Object next_window
P_ ((Lisp_Object
, Lisp_Object
,
74 static void decode_next_window_args
P_ ((Lisp_Object
*, Lisp_Object
*,
76 static int foreach_window_1
P_ ((struct window
*,
77 int (* fn
) (struct window
*, void *),
80 /* This is the window in which the terminal's cursor should
81 be left when nothing is being done with it. This must
82 always be a leaf window, and its buffer is selected by
83 the top level editing loop at the end of each command.
85 This value is always the same as
86 FRAME_SELECTED_WINDOW (selected_frame). */
88 Lisp_Object selected_window
;
90 /* A list of all windows for use by next_window and Fwindow_list.
91 Functions creating or deleting windows should invalidate this cache
92 by setting it to nil. */
94 Lisp_Object Vwindow_list
;
96 /* The mini-buffer window of the selected frame.
97 Note that you cannot test for mini-bufferness of an arbitrary window
98 by comparing against this; but you can test for mini-bufferness of
99 the selected window. */
101 Lisp_Object minibuf_window
;
103 /* Non-nil means it is the window for C-M-v to scroll
104 when the mini-buffer is selected. */
106 Lisp_Object Vminibuf_scroll_window
;
108 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
110 Lisp_Object Vother_window_scroll_buffer
;
112 /* Non-nil means it's function to call to display temp buffers. */
114 Lisp_Object Vtemp_buffer_show_function
;
116 /* If a window gets smaller than either of these, it is removed. */
118 int window_min_height
;
119 int window_min_width
;
121 /* Nonzero implies Fdisplay_buffer should create windows. */
125 /* Nonzero implies make new frames for Fdisplay_buffer. */
129 /* Nonzero means reuse existing frames for displaying buffers. */
131 int display_buffer_reuse_frames
;
133 /* Non-nil means use this function instead of default */
135 Lisp_Object Vpop_up_frame_function
;
137 /* Function to call to handle Fdisplay_buffer. */
139 Lisp_Object Vdisplay_buffer_function
;
141 /* List of buffer *names* for buffers that should have their own frames. */
143 Lisp_Object Vspecial_display_buffer_names
;
145 /* List of regexps for buffer names that should have their own frames. */
147 Lisp_Object Vspecial_display_regexps
;
149 /* Function to pop up a special frame. */
151 Lisp_Object Vspecial_display_function
;
153 /* List of buffer *names* for buffers to appear in selected window. */
155 Lisp_Object Vsame_window_buffer_names
;
157 /* List of regexps for buffer names to appear in selected window. */
159 Lisp_Object Vsame_window_regexps
;
161 /* Hook run at end of temp_output_buffer_show. */
163 Lisp_Object Qtemp_buffer_show_hook
;
165 /* Fdisplay_buffer always splits the largest window
166 if that window is more than this high. */
168 int split_height_threshold
;
170 /* Number of lines of continuity in scrolling by screenfuls. */
172 int next_screen_context_lines
;
174 /* Incremented for each window created. */
176 static int sequence_number
;
178 /* Nonzero after init_window_once has finished. */
180 static int window_initialized
;
182 /* Hook to run when window config changes. */
184 Lisp_Object Qwindow_configuration_change_hook
;
185 Lisp_Object Vwindow_configuration_change_hook
;
187 /* Nonzero means scroll commands try to put point
188 at the same screen height as previously. */
190 Lisp_Object Vscroll_preserve_screen_position
;
192 #if 0 /* This isn't used anywhere. */
193 /* Nonzero means we can split a frame even if it is "unsplittable". */
194 static int inhibit_frame_unsplittable
;
197 #define min(a, b) ((a) < (b) ? (a) : (b))
199 extern int scroll_margin
;
201 extern Lisp_Object Qwindow_scroll_functions
, Vwindow_scroll_functions
;
203 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
204 "Returns t if OBJECT is a window.")
208 return WINDOWP (object
) ? Qt
: Qnil
;
211 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
212 "Returns t if OBJECT is a window which is currently visible.")
216 return (WINDOWP (object
) && ! NILP (XWINDOW (object
)->buffer
) ? Qt
: Qnil
);
223 register struct window
*p
;
224 register struct Lisp_Vector
*vec
;
227 vec
= allocate_vectorlike ((EMACS_INT
) VECSIZE (struct window
));
228 for (i
= 0; i
< VECSIZE (struct window
); i
++)
229 vec
->contents
[i
] = Qnil
;
230 vec
->size
= VECSIZE (struct window
);
231 p
= (struct window
*) vec
;
232 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
233 XSETFASTINT (p
->left
, 0);
234 XSETFASTINT (p
->top
, 0);
235 XSETFASTINT (p
->height
, 0);
236 XSETFASTINT (p
->width
, 0);
237 XSETFASTINT (p
->hscroll
, 0);
238 p
->orig_top
= p
->orig_height
= Qnil
;
239 p
->start
= Fmake_marker ();
240 p
->pointm
= Fmake_marker ();
241 XSETFASTINT (p
->use_time
, 0);
243 p
->display_table
= Qnil
;
245 p
->pseudo_window_p
= 0;
246 bzero (&p
->cursor
, sizeof (p
->cursor
));
247 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
248 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
249 p
->desired_matrix
= p
->current_matrix
= 0;
250 p
->phys_cursor_type
= -1;
251 p
->must_be_updated_p
= 0;
252 XSETFASTINT (p
->window_end_vpos
, 0);
253 XSETFASTINT (p
->window_end_pos
, 0);
254 p
->window_end_valid
= Qnil
;
257 XSETFASTINT (p
->last_point
, 0);
258 p
->frozen_window_start_p
= 0;
264 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
265 "Return the window that the cursor now appears in and commands apply to.")
268 return selected_window
;
271 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
272 "Return the window used now for minibuffers.\n\
273 If the optional argument FRAME is specified, return the minibuffer window\n\
274 used by that frame.")
279 frame
= selected_frame
;
280 CHECK_LIVE_FRAME (frame
, 0);
281 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
284 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 0, 1, 0,
285 "Returns non-nil if WINDOW is a minibuffer window.")
289 struct window
*w
= decode_window (window
);
290 return (MINI_WINDOW_P (w
) ? Qt
: Qnil
);
293 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
294 Spos_visible_in_window_p
, 0, 2, 0,
295 "Return t if position POS is currently on the frame in WINDOW.\n\
296 Returns nil if that position is scrolled vertically out of view.\n\
297 POS defaults to point; WINDOW, to the selected window.")
299 Lisp_Object pos
, window
;
301 register struct window
*w
;
303 register struct buffer
*buf
;
305 Lisp_Object in_window
;
311 CHECK_NUMBER_COERCE_MARKER (pos
, 0);
315 w
= decode_window (window
);
316 buf
= XBUFFER (w
->buffer
);
317 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
319 /* If position above window, it's not visible. */
320 if (posint
< CHARPOS (top
))
322 else if (XFASTINT (w
->last_modified
) >= BUF_MODIFF (buf
)
323 && XFASTINT (w
->last_overlay_modified
) >= BUF_OVERLAY_MODIFF (buf
)
324 && posint
< BUF_Z (buf
) - XFASTINT (w
->window_end_pos
))
325 /* If frame is up to date, and POSINT is < window end pos, use
326 that info. This doesn't work for POSINT == end pos, because
327 the window end pos is actually the position _after_ the last
328 char in the window. */
330 else if (posint
> BUF_ZV (buf
))
332 else if (CHARPOS (top
) < BUF_BEGV (buf
) || CHARPOS (top
) > BUF_ZV (buf
))
333 /* If window start is out of range, do something reasonable. */
338 start_display (&it
, w
, top
);
339 move_it_to (&it
, posint
, 0, it
.last_visible_y
, -1,
340 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
341 in_window
= IT_CHARPOS (it
) == posint
? Qt
: Qnil
;
347 static struct window
*
348 decode_window (window
)
349 register Lisp_Object window
;
352 return XWINDOW (selected_window
);
354 CHECK_LIVE_WINDOW (window
, 0);
355 return XWINDOW (window
);
358 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
359 "Return the buffer that WINDOW is displaying.")
363 return decode_window (window
)->buffer
;
366 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
367 "Return the number of lines in WINDOW (including its mode line).")
371 return decode_window (window
)->height
;
374 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
375 "Return the number of display columns in WINDOW.\n\
376 This is the width that is usable columns available for text in WINDOW.\n\
377 If you want to find out how many columns WINDOW takes up,\n\
378 use (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))).")
382 return make_number (window_internal_width (decode_window (window
)));
385 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
386 "Return the number of columns by which WINDOW is scrolled from left margin.")
390 return decode_window (window
)->hscroll
;
393 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
394 "Set number of columns WINDOW is scrolled from left margin to NCOL.\n\
395 NCOL should be zero or positive.")
397 register Lisp_Object window
, ncol
;
399 register struct window
*w
;
401 CHECK_NUMBER (ncol
, 1);
402 if (XINT (ncol
) < 0) XSETFASTINT (ncol
, 0);
403 w
= decode_window (window
);
404 if (XINT (w
->hscroll
) != XINT (ncol
))
405 /* Prevent redisplay shortcuts */
406 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
411 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
412 Swindow_redisplay_end_trigger
, 0, 1, 0,
413 "Return WINDOW's redisplay end trigger value.\n\
414 See `set-window-redisplay-end-trigger' for more information.")
418 return decode_window (window
)->redisplay_end_trigger
;
421 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
422 Sset_window_redisplay_end_trigger
, 2, 2, 0,
423 "Set WINDOW's redisplay end trigger value to VALUE.\n\
424 VALUE should be a buffer position (typically a marker) or nil.\n\
425 If it is a buffer position, then if redisplay in WINDOW reaches a position\n\
426 beyond VALUE, the functions in `redisplay-end-trigger-functions' are called\n\
427 with two arguments: WINDOW, and the end trigger value.\n\
428 Afterwards the end-trigger value is reset to nil.")
430 register Lisp_Object window
, value
;
432 register struct window
*w
;
434 w
= decode_window (window
);
435 w
->redisplay_end_trigger
= value
;
439 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
440 "Return a list of the edge coordinates of WINDOW.\n\
441 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.\n\
442 RIGHT is one more than the rightmost column used by WINDOW,\n\
443 and BOTTOM is one more than the bottommost row used by WINDOW\n\
448 register struct window
*w
= decode_window (window
);
450 return Fcons (w
->left
, Fcons (w
->top
,
451 Fcons (make_number (WINDOW_RIGHT_EDGE (w
)),
452 Fcons (make_number (XFASTINT (w
->top
)
453 + XFASTINT (w
->height
)),
457 /* Test if the character at column *X, row *Y is within window W.
458 If it is not, return 0;
459 if it is in the window's text area,
460 set *x and *y to its location relative to the upper left corner
463 if it is on the window's modeline, return 2;
464 if it is on the border between the window and its right sibling,
466 if it is on the window's top line, return 4;
467 if it is in the bitmap area to the left/right of the window,
468 return 5 or 6, and convert *X and *Y to window-relative corrdinates.
470 X and Y are frame relative pixel coordinates. */
473 coordinates_in_window (w
, x
, y
)
474 register struct window
*w
;
477 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
478 int left_x
, right_x
, top_y
, bottom_y
;
479 int flags_area_width
= FRAME_LEFT_FLAGS_AREA_WIDTH (f
);
481 /* In what's below, we subtract 1 when computing right_x because we
482 want the rightmost pixel, which is given by left_pixel+width-1. */
483 if (w
->pseudo_window_p
)
486 right_x
= XFASTINT (w
->width
) * CANON_Y_UNIT (f
) - 1;
487 top_y
= WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
);
488 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
492 left_x
= (WINDOW_DISPLAY_LEFT_EDGE_PIXEL_X (w
)
493 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
494 right_x
= WINDOW_DISPLAY_RIGHT_EDGE_PIXEL_X (w
) - 1;
495 top_y
= (WINDOW_DISPLAY_TOP_EDGE_PIXEL_Y (w
)
496 - FRAME_INTERNAL_BORDER_WIDTH_SAFE (f
));
497 bottom_y
= WINDOW_DISPLAY_BOTTOM_EDGE_PIXEL_Y (w
);
504 - (FRAME_LEFT_SCROLL_BAR_WIDTH (f
)
506 || *x
> right_x
+ flags_area_width
)
507 /* Completely outside anything interesting. */
509 else if (WINDOW_WANTS_MODELINE_P (w
)
510 && *y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
))
511 /* On the mode line. */
513 else if (WINDOW_WANTS_HEADER_LINE_P (w
)
514 && *y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
))
515 /* On the top line. */
517 else if (*x
< left_x
|| *x
>= right_x
)
519 /* Other lines than the mode line don't include flags areas and
520 scroll bars on the left. */
522 /* Convert X and Y to window-relative pixel coordinates. */
525 return *x
< left_x
? 5 : 6;
527 else if (!w
->pseudo_window_p
528 && !WINDOW_RIGHTMOST_P (w
)
529 && *x
>= right_x
- CANON_X_UNIT (f
))
530 /* On the border on the right side of the window? Assume that
531 this area begins at RIGHT_X minus a canonical char width. */
535 /* Convert X and Y to window-relative pixel coordinates. */
542 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
543 Scoordinates_in_window_p
, 2, 2, 0,
544 "Return non-nil if COORDINATES are in WINDOW.\n\
545 COORDINATES is a cons of the form (X . Y), X and Y being distances\n\
546 measured in characters from the upper-left corner of the frame.\n\
547 (0 . 0) denotes the character in the upper left corner of the\n\
549 If COORDINATES are in the text portion of WINDOW,\n\
550 the coordinates relative to the window are returned.\n\
551 If they are in the mode line of WINDOW, `mode-line' is returned.\n\
552 If they are in the top mode line of WINDOW, `header-line' is returned.\n\
553 If they are in the bitmap-area to the left of the window,\n\
554 `left-bitmap-area' is returned, if they are in the area on the right of\n\
555 the window, `right-bitmap-area' is returned.\n\
556 If they are on the border between WINDOW and its right sibling,\n\
557 `vertical-line' is returned.")
558 (coordinates
, window
)
559 register Lisp_Object coordinates
, window
;
566 CHECK_LIVE_WINDOW (window
, 0);
567 w
= XWINDOW (window
);
568 f
= XFRAME (w
->frame
);
569 CHECK_CONS (coordinates
, 1);
570 lx
= Fcar (coordinates
);
571 ly
= Fcdr (coordinates
);
572 CHECK_NUMBER_OR_FLOAT (lx
, 1);
573 CHECK_NUMBER_OR_FLOAT (ly
, 1);
574 x
= PIXEL_X_FROM_CANON_X (f
, lx
);
575 y
= PIXEL_Y_FROM_CANON_Y (f
, ly
);
577 switch (coordinates_in_window (w
, &x
, &y
))
579 case 0: /* NOT in window at all. */
582 case 1: /* In text part of window. */
583 /* X and Y are now window relative pixel coordinates.
584 Convert them to canonical char units before returning
586 return Fcons (CANON_X_FROM_PIXEL_X (f
, x
),
587 CANON_Y_FROM_PIXEL_Y (f
, y
));
589 case 2: /* In mode line of window. */
592 case 3: /* On right border of window. */
593 return Qvertical_line
;
599 return Qleft_bitmap_area
;
602 return Qright_bitmap_area
;
610 /* Callback for foreach_window, used in window_from_coordinates.
611 Check if window W contains coordinates specified by USER_DATA which
612 is actually a pointer to a struct check_window_data CW.
614 Check if window W contains coordinates *CW->x and *CW->y. If it
615 does, return W in *CW->window, as Lisp_Object, and return in
616 *CW->part the part of the window under coordinates *X,*Y. Return
617 zero from this function to stop iterating over windows. */
619 struct check_window_data
626 check_window_containing (w
, user_data
)
630 struct check_window_data
*cw
= (struct check_window_data
*) user_data
;
633 found
= coordinates_in_window (w
, cw
->x
, cw
->y
);
636 *cw
->part
= found
- 1;
637 XSETWINDOW (*cw
->window
, w
);
644 /* Find the window containing frame-relative pixel position X/Y and
645 return it as a Lisp_Object. If X, Y is on the window's modeline,
646 set *PART to 1; if it is on the separating line between the window
647 and its right sibling, set it to 2; otherwise set it to 0. If
648 there is no window under X, Y return nil and leave *PART
649 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows.
651 This function was previously implemented with a loop cycling over
652 windows with Fnext_window, and starting with the frame's selected
653 window. It turned out that this doesn't work with an
654 implementation of next_window using Vwindow_list, because
655 FRAME_SELECTED_WINDOW (F) is not always contained in the window
656 tree of F when this function is called asynchronously from
657 note_mouse_highlight. The original loop didn't terminate in this
661 window_from_coordinates (f
, x
, y
, part
, tool_bar_p
)
668 struct check_window_data cw
;
671 cw
.window
= &window
, cw
.x
= &x
, cw
.y
= &y
; cw
.part
= part
;
672 foreach_window (f
, check_window_containing
, &cw
);
674 /* If not found above, see if it's in the tool bar window, if a tool
678 && WINDOWP (f
->tool_bar_window
)
679 && XINT (XWINDOW (f
->tool_bar_window
)->height
) > 0
680 && coordinates_in_window (XWINDOW (f
->tool_bar_window
), &x
, &y
))
683 window
= f
->tool_bar_window
;
689 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
690 "Return window containing coordinates X and Y on FRAME.\n\
691 If omitted, FRAME defaults to the currently selected frame.\n\
692 The top left corner of the frame is considered to be row 0,\n\
695 Lisp_Object x
, y
, frame
;
701 frame
= selected_frame
;
702 CHECK_LIVE_FRAME (frame
, 2);
705 /* Check that arguments are integers or floats. */
706 CHECK_NUMBER_OR_FLOAT (x
, 0);
707 CHECK_NUMBER_OR_FLOAT (y
, 1);
709 return window_from_coordinates (f
,
710 PIXEL_X_FROM_CANON_X (f
, x
),
711 PIXEL_Y_FROM_CANON_Y (f
, y
),
715 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
716 "Return current value of point in WINDOW.\n\
717 For a nonselected window, this is the value point would have\n\
718 if that window were selected.\n\
720 Note that, when WINDOW is the selected window and its buffer\n\
721 is also currently selected, the value returned is the same as (point).\n\
722 It would be more strictly correct to return the `top-level' value\n\
723 of point, outside of any save-excursion forms.\n\
724 But that is hard to define.")
728 register struct window
*w
= decode_window (window
);
730 if (w
== XWINDOW (selected_window
)
731 && current_buffer
== XBUFFER (w
->buffer
))
733 return Fmarker_position (w
->pointm
);
736 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
737 "Return position at which display currently starts in WINDOW.\n\
738 This is updated by redisplay or by calling `set-window-start'.")
742 return Fmarker_position (decode_window (window
)->start
);
745 /* This is text temporarily removed from the doc string below.
747 This function returns nil if the position is not currently known.\n\
748 That happens when redisplay is preempted and doesn't finish.\n\
749 If in that case you want to compute where the end of the window would\n\
750 have been if redisplay had finished, do this:\n\
752 (goto-char (window-start window))\n\
753 (vertical-motion (1- (window-height window)) window)\n\
756 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
757 "Return position at which display currently ends in WINDOW.\n\
758 This is updated by redisplay, when it runs to completion.\n\
759 Simply changing the buffer text or setting `window-start'\n\
760 does not update this value.\n\
761 If UP-TO-DATE is non-nil, compute the up-to-date position\n\
762 if it isn't already recorded.")
764 Lisp_Object window
, update
;
767 struct window
*w
= decode_window (window
);
771 CHECK_BUFFER (buf
, 0);
773 #if 0 /* This change broke some things. We should make it later. */
774 /* If we don't know the end position, return nil.
775 The user can compute it with vertical-motion if he wants to.
776 It would be nicer to do it automatically,
777 but that's so slow that it would probably bother people. */
778 if (NILP (w
->window_end_valid
))
783 && ! (! NILP (w
->window_end_valid
)
784 && XFASTINT (w
->last_modified
) >= MODIFF
))
786 struct text_pos startp
;
789 /* In case W->start is out of the range, use something
790 reasonable. This situation occured when loading a file with
791 `-l' containing a call to `rmail' with subsequent other
792 commands. At the end, W->start happened to be BEG, while
793 rmail had already narrowed the buffer. */
794 if (XMARKER (w
->start
)->charpos
< BEGV
)
795 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
796 else if (XMARKER (w
->start
)->charpos
> ZV
)
797 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
799 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
801 /* Cannot use Fvertical_motion because that function doesn't
802 cope with variable-height lines. */
803 start_display (&it
, w
, startp
);
804 move_it_vertically (&it
, window_box_height (w
));
805 value
= make_number (IT_CHARPOS (it
));
808 XSETINT (value
, BUF_Z (XBUFFER (buf
)) - XFASTINT (w
->window_end_pos
));
813 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
814 "Make point value in WINDOW be at position POS in WINDOW's buffer.")
816 Lisp_Object window
, pos
;
818 register struct window
*w
= decode_window (window
);
820 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
821 if (w
== XWINDOW (selected_window
)
822 && XBUFFER (w
->buffer
) == current_buffer
)
825 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
830 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
831 "Make display in WINDOW start at position POS in WINDOW's buffer.\n\
832 Optional third arg NOFORCE non-nil inhibits next redisplay\n\
833 from overriding motion of point in order to display at this exact start.")
834 (window
, pos
, noforce
)
835 Lisp_Object window
, pos
, noforce
;
837 register struct window
*w
= decode_window (window
);
839 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
840 set_marker_restricted (w
->start
, pos
, w
->buffer
);
841 /* this is not right, but much easier than doing what is right. */
842 w
->start_at_line_beg
= Qnil
;
845 w
->update_mode_line
= Qt
;
846 XSETFASTINT (w
->last_modified
, 0);
847 XSETFASTINT (w
->last_overlay_modified
, 0);
848 if (!EQ (window
, selected_window
))
849 windows_or_buffers_changed
++;
854 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
856 "Return WINDOW's dedicated object, usually t or nil.\n\
857 See also `set-window-dedicated-p'.")
861 return decode_window (window
)->dedicated
;
864 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
865 Sset_window_dedicated_p
, 2, 2, 0,
866 "Control whether WINDOW is dedicated to the buffer it displays.\n\
867 If it is dedicated, Emacs will not automatically change\n\
868 which buffer appears in it.\n\
869 The second argument is the new value for the dedication flag;\n\
872 Lisp_Object window
, arg
;
874 register struct window
*w
= decode_window (window
);
884 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
886 "Return the display-table that WINDOW is using.")
890 return decode_window (window
)->display_table
;
893 /* Get the display table for use on window W. This is either W's
894 display table or W's buffer's display table. Ignore the specified
895 tables if they are not valid; if no valid table is specified,
898 struct Lisp_Char_Table
*
899 window_display_table (w
)
902 struct Lisp_Char_Table
*dp
= NULL
;
904 if (DISP_TABLE_P (w
->display_table
))
905 dp
= XCHAR_TABLE (w
->display_table
);
906 else if (BUFFERP (w
->buffer
))
908 struct buffer
*b
= XBUFFER (w
->buffer
);
910 if (DISP_TABLE_P (b
->display_table
))
911 dp
= XCHAR_TABLE (b
->display_table
);
912 else if (DISP_TABLE_P (Vstandard_display_table
))
913 dp
= XCHAR_TABLE (Vstandard_display_table
);
919 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
920 "Set WINDOW's display-table to TABLE.")
922 register Lisp_Object window
, table
;
924 register struct window
*w
;
926 w
= decode_window (window
);
927 w
->display_table
= table
;
931 /* Record info on buffer window w is displaying
932 when it is about to cease to display that buffer. */
935 register struct window
*w
;
942 if (b
!= XMARKER (w
->pointm
)->buffer
)
946 if (w
== XWINDOW (selected_window
)
947 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
948 /* Do this except when the selected window's buffer
949 is being removed from some other window. */
951 /* last_window_start records the start position that this buffer
952 had in the last window to be disconnected from it.
953 Now that this statement is unconditional,
954 it is possible for the buffer to be displayed in the
955 selected window, while last_window_start reflects another
956 window which was recently showing the same buffer.
957 Some people might say that might be a good thing. Let's see. */
958 b
->last_window_start
= marker_position (w
->start
);
960 /* Point in the selected window's buffer
961 is actually stored in that buffer, and the window's pointm isn't used.
962 So don't clobber point in that buffer. */
963 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
)
964 /* This line helps to fix Horsley's testbug.el bug. */
965 && !(WINDOWP (b
->last_selected_window
)
966 && w
!= XWINDOW (b
->last_selected_window
)
967 && EQ (buf
, XWINDOW (b
->last_selected_window
)->buffer
)))
968 temp_set_point_both (b
,
969 clip_to_bounds (BUF_BEGV (b
),
970 XMARKER (w
->pointm
)->charpos
,
972 clip_to_bounds (BUF_BEGV_BYTE (b
),
973 marker_byte_position (w
->pointm
),
976 if (WINDOWP (b
->last_selected_window
)
977 && w
== XWINDOW (b
->last_selected_window
))
978 b
->last_selected_window
= Qnil
;
981 /* Put replacement into the window structure in place of old. */
983 replace_window (old
, replacement
)
984 Lisp_Object old
, replacement
;
986 register Lisp_Object tem
;
987 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
989 /* If OLD is its frame's root_window, then replacement is the new
990 root_window for that frame. */
992 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
993 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
998 p
->height
= o
->height
;
999 p
->desired_matrix
= p
->current_matrix
= 0;
1001 bzero (&p
->cursor
, sizeof (p
->cursor
));
1002 bzero (&p
->last_cursor
, sizeof (p
->last_cursor
));
1003 bzero (&p
->phys_cursor
, sizeof (p
->phys_cursor
));
1004 p
->phys_cursor_type
= -1;
1005 p
->must_be_updated_p
= 0;
1006 p
->pseudo_window_p
= 0;
1007 XSETFASTINT (p
->window_end_vpos
, 0);
1008 XSETFASTINT (p
->window_end_pos
, 0);
1009 p
->window_end_valid
= Qnil
;
1010 p
->frozen_window_start_p
= 0;
1011 p
->orig_top
= p
->orig_height
= Qnil
;
1013 p
->next
= tem
= o
->next
;
1015 XWINDOW (tem
)->prev
= replacement
;
1017 p
->prev
= tem
= o
->prev
;
1019 XWINDOW (tem
)->next
= replacement
;
1021 p
->parent
= tem
= o
->parent
;
1024 if (EQ (XWINDOW (tem
)->vchild
, old
))
1025 XWINDOW (tem
)->vchild
= replacement
;
1026 if (EQ (XWINDOW (tem
)->hchild
, old
))
1027 XWINDOW (tem
)->hchild
= replacement
;
1030 /*** Here, if replacement is a vertical combination
1031 and so is its new parent, we should make replacement's
1032 children be children of that parent instead. ***/
1035 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
1036 "Remove WINDOW from the display. Default is selected window.")
1038 register Lisp_Object window
;
1040 delete_window (window
);
1042 if (! NILP (Vwindow_configuration_change_hook
)
1043 && ! NILP (Vrun_hooks
))
1044 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
1050 delete_window (window
)
1051 register Lisp_Object window
;
1053 register Lisp_Object tem
, parent
, sib
;
1054 register struct window
*p
;
1055 register struct window
*par
;
1058 /* Because this function is called by other C code on non-leaf
1059 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1060 so we can't decode_window here. */
1062 window
= selected_window
;
1064 CHECK_WINDOW (window
, 0);
1065 p
= XWINDOW (window
);
1067 /* It's okay to delete an already-deleted window. */
1068 if (NILP (p
->buffer
)
1070 && NILP (p
->vchild
))
1075 error ("Attempt to delete minibuffer or sole ordinary window");
1076 par
= XWINDOW (parent
);
1078 windows_or_buffers_changed
++;
1079 Vwindow_list
= Qnil
;
1080 frame
= XFRAME (WINDOW_FRAME (p
));
1081 FRAME_WINDOW_SIZES_CHANGED (frame
) = 1;
1083 /* Are we trying to delete any frame's selected window? */
1085 Lisp_Object frame
, pwindow
;
1087 /* See if the frame's selected window is either WINDOW
1088 or any subwindow of it, by finding all that window's parents
1089 and comparing each one with WINDOW. */
1090 frame
= WINDOW_FRAME (XWINDOW (window
));
1091 pwindow
= FRAME_SELECTED_WINDOW (XFRAME (frame
));
1093 while (!NILP (pwindow
))
1095 if (EQ (window
, pwindow
))
1097 pwindow
= XWINDOW (pwindow
)->parent
;
1100 if (EQ (window
, pwindow
))
1102 Lisp_Object alternative
;
1103 alternative
= Fnext_window (window
, Qlambda
, Qnil
);
1105 /* If we're about to delete the selected window on the
1106 selected frame, then we should use Fselect_window to select
1107 the new window. On the other hand, if we're about to
1108 delete the selected window on any other frame, we shouldn't do
1109 anything but set the frame's selected_window slot. */
1110 if (EQ (window
, selected_window
))
1111 Fselect_window (alternative
);
1113 FRAME_SELECTED_WINDOW (XFRAME (frame
)) = alternative
;
1118 /* tem is null for dummy parent windows
1119 (which have inferiors but not any contents themselves) */
1123 unchain_marker (p
->pointm
);
1124 unchain_marker (p
->start
);
1127 /* Free window glyph matrices. It is sure that they are allocated
1128 again when ADJUST_GLYPHS is called. Block input so that expose
1129 events and other events that access glyph matrices are not
1130 processed while we are changing them. */
1132 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (frame
)));
1136 XWINDOW (tem
)->prev
= p
->prev
;
1140 XWINDOW (tem
)->next
= p
->next
;
1142 if (EQ (window
, par
->hchild
))
1143 par
->hchild
= p
->next
;
1144 if (EQ (window
, par
->vchild
))
1145 par
->vchild
= p
->next
;
1147 /* Find one of our siblings to give our space to. */
1151 /* If p gives its space to its next sibling, that sibling needs
1152 to have its top/left side pulled back to where p's is.
1153 set_window_{height,width} will re-position the sibling's
1156 XWINDOW (sib
)->top
= p
->top
;
1157 XWINDOW (sib
)->left
= p
->left
;
1160 /* Stretch that sibling. */
1161 if (!NILP (par
->vchild
))
1162 set_window_height (sib
,
1163 XFASTINT (XWINDOW (sib
)->height
) + XFASTINT (p
->height
),
1165 if (!NILP (par
->hchild
))
1166 set_window_width (sib
,
1167 XFASTINT (XWINDOW (sib
)->width
) + XFASTINT (p
->width
),
1170 /* If parent now has only one child,
1171 put the child into the parent's place. */
1175 if (NILP (XWINDOW (tem
)->next
))
1176 replace_window (parent
, tem
);
1178 /* Since we may be deleting combination windows, we must make sure that
1179 not only p but all its children have been marked as deleted. */
1180 if (! NILP (p
->hchild
))
1181 delete_all_subwindows (XWINDOW (p
->hchild
));
1182 else if (! NILP (p
->vchild
))
1183 delete_all_subwindows (XWINDOW (p
->vchild
));
1185 /* Mark this window as deleted. */
1186 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
1188 /* Adjust glyph matrices. */
1189 adjust_glyphs (frame
);
1195 /***********************************************************************
1197 ***********************************************************************/
1199 /* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object
1200 pointer. This is a callback function for foreach_window, used in
1201 function window_list. */
1204 add_window_to_list (w
, user_data
)
1208 Lisp_Object
*list
= (Lisp_Object
*) user_data
;
1210 XSETWINDOW (window
, w
);
1211 *list
= Fcons (window
, *list
);
1216 /* Return a list of all windows, for use by next_window. If
1217 Vwindow_list is a list, return that list. Otherwise, build a new
1218 list, cache it in Vwindow_list, and return that. */
1223 if (!CONSP (Vwindow_list
))
1227 Vwindow_list
= Qnil
;
1228 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
1230 Lisp_Object args
[2];
1232 /* We are visiting windows in canonical order, and add
1233 new windows at the front of args[1], which means we
1234 have to reverse this list at the end. */
1236 foreach_window (XFRAME (XCAR (tail
)), add_window_to_list
, &args
[1]);
1237 args
[0] = Vwindow_list
;
1238 args
[1] = Fnreverse (args
[1]);
1239 Vwindow_list
= Fnconc (2, args
);
1243 return Vwindow_list
;
1247 /* Value is non-zero if WINDOW satisfies the constraints given by
1248 OWINDOW, MINIBUF and ALL_FRAMES.
1250 MINIBUF t means WINDOW may be minibuffer windows.
1251 `lambda' means WINDOW may not be a minibuffer window.
1252 a window means a specific minibuffer window
1254 ALL_FRAMES t means search all frames,
1255 nil means search just current frame,
1256 `visible' means search just visible frames,
1257 0 means search visible and iconified frames,
1258 a window means search the frame that window belongs to,
1259 a frame means consider windows on that frame, only. */
1262 candidate_window_p (window
, owindow
, minibuf
, all_frames
)
1263 Lisp_Object window
, owindow
, minibuf
, all_frames
;
1265 struct window
*w
= XWINDOW (window
);
1266 struct frame
*f
= XFRAME (w
->frame
);
1267 int candidate_p
= 1;
1269 if (!BUFFERP (w
->buffer
))
1271 else if (MINI_WINDOW_P (w
)
1272 && (EQ (minibuf
, Qlambda
)
1273 || (WINDOWP (minibuf
) && !EQ (minibuf
, window
))))
1275 /* If MINIBUF is `lambda' don't consider any mini-windows.
1276 If it is a window, consider only that one. */
1279 else if (EQ (all_frames
, Qt
))
1281 else if (NILP (all_frames
))
1283 xassert (WINDOWP (owindow
));
1284 candidate_p
= EQ (w
->frame
, XWINDOW (owindow
)->frame
);
1286 else if (EQ (all_frames
, Qvisible
))
1288 FRAME_SAMPLE_VISIBILITY (f
);
1289 candidate_p
= FRAME_VISIBLE_P (f
);
1291 else if (INTEGERP (all_frames
) && XINT (all_frames
) == 0)
1293 FRAME_SAMPLE_VISIBILITY (f
);
1294 candidate_p
= FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
);
1296 else if (WINDOWP (all_frames
))
1297 candidate_p
= (EQ (FRAME_MINIBUF_WINDOW (f
), all_frames
)
1298 || EQ (XWINDOW (all_frames
)->frame
, w
->frame
)
1299 || EQ (XWINDOW (all_frames
)->frame
, FRAME_FOCUS_FRAME (f
)));
1300 else if (FRAMEP (all_frames
))
1301 candidate_p
= EQ (all_frames
, w
->frame
);
1307 /* Decode arguments as allowed by Fnext_window, Fprevious_window, and
1308 Fwindow_list. See there for the meaning of WINDOW, MINIBUF, and
1312 decode_next_window_args (window
, minibuf
, all_frames
)
1313 Lisp_Object
*window
, *minibuf
, *all_frames
;
1316 *window
= selected_window
;
1318 CHECK_LIVE_WINDOW (*window
, 0);
1320 /* MINIBUF nil may or may not include minibuffers. Decide if it
1322 if (NILP (*minibuf
))
1323 *minibuf
= minibuf_level
? minibuf_window
: Qlambda
;
1324 else if (!EQ (*minibuf
, Qt
))
1327 /* Now *MINIBUF can be t => count all minibuffer windows, `lambda'
1328 => count none of them, or a specific minibuffer window (the
1329 active one) to count. */
1331 /* ALL_FRAMES nil doesn't specify which frames to include. */
1332 if (NILP (*all_frames
))
1333 *all_frames
= (!EQ (*minibuf
, Qlambda
)
1334 ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window
)->frame
))
1336 else if (EQ (*all_frames
, Qvisible
))
1338 else if (XFASTINT (*all_frames
) == 0)
1340 else if (FRAMEP (*all_frames
))
1342 else if (!EQ (*all_frames
, Qt
))
1345 /* Now *ALL_FRAMES is t meaning search all frames, nil meaning
1346 search just current frame, `visible' meaning search just visible
1347 frames, 0 meaning search visible and iconified frames, or a
1348 window, meaning search the frame that window belongs to, or a
1349 frame, meaning consider windows on that frame, only. */
1353 /* Return the next or previous window of WINDOW in canonical ordering
1354 of windows. NEXT_P non-zero means return the next window. See the
1355 documentation string of next-window for the meaning of MINIBUF and
1359 next_window (window
, minibuf
, all_frames
, next_p
)
1360 Lisp_Object window
, minibuf
, all_frames
;
1363 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1365 /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just
1366 return the first window on the frame. */
1367 if (FRAMEP (all_frames
)
1368 && !EQ (all_frames
, XWINDOW (window
)->frame
))
1369 return Fframe_first_window (all_frames
);
1375 /* Find WINDOW in the list of all windows. */
1376 list
= Fmemq (window
, window_list ());
1378 /* Scan forward from WINDOW to the end of the window list. */
1380 for (list
= XCDR (list
); CONSP (list
); list
= XCDR (list
))
1381 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1384 /* Scan from the start of the window list up to WINDOW. */
1386 for (list
= Vwindow_list
;
1387 CONSP (list
) && !EQ (XCAR (list
), window
);
1389 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
1393 window
= XCAR (list
);
1397 Lisp_Object candidate
, list
;
1399 /* Scan through the list of windows for candidates. If there are
1400 candidate windows in front of WINDOW, the last one of these
1401 is the one we want. If there are candidates following WINDOW
1402 in the list, again the last one of these is the one we want. */
1404 for (list
= window_list (); CONSP (list
); list
= XCDR (list
))
1406 if (EQ (XCAR (list
), window
))
1408 if (WINDOWP (candidate
))
1411 else if (candidate_window_p (XCAR (list
), window
, minibuf
,
1413 candidate
= XCAR (list
);
1416 if (WINDOWP (candidate
))
1424 /* This comment supplies the doc string for `next-window',
1425 for make-docfile to see. We cannot put this in the real DEFUN
1426 due to limits in the Unix cpp.
1428 DEFUN ("next-window", Ffoo, Sfoo, 0, 3, 0,
1429 "Return next window after WINDOW in canonical ordering of windows.\n\
1430 If omitted, WINDOW defaults to the selected window.\n\
1432 Optional second arg MINIBUF t means count the minibuffer window even\n\
1433 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1434 it is active. MINIBUF neither t nor nil means not to count the\n\
1435 minibuffer even if it is active.\n\
1437 Several frames may share a single minibuffer; if the minibuffer\n\
1438 counts, all windows on all frames that share that minibuffer count\n\
1439 too. Therefore, `next-window' can be used to iterate through the\n\
1440 set of windows even when the minibuffer is on another frame. If the\n\
1441 minibuffer does not count, only windows from WINDOW's frame count.\n\
1443 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1444 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1445 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1446 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1447 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1448 Anything else means restrict to WINDOW's frame.\n\
1450 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1451 `next-window' to iterate through the entire cycle of acceptable\n\
1452 windows, eventually ending up back at the window you started with.\n\
1453 `previous-window' traverses the same cycle, in the reverse order.")
1454 (window, minibuf, all_frames) */
1456 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
1458 (window
, minibuf
, all_frames
)
1459 Lisp_Object window
, minibuf
, all_frames
;
1461 return next_window (window
, minibuf
, all_frames
, 1);
1465 /* This comment supplies the doc string for `previous-window',
1466 for make-docfile to see. We cannot put this in the real DEFUN
1467 due to limits in the Unix cpp.
1469 DEFUN ("previous-window", Ffoo, Sfoo, 0, 3, 0,
1470 "Return the window preceding WINDOW in canonical ordering of windows.\n\
1471 If omitted, WINDOW defaults to the selected window.\n\
1473 Optional second arg MINIBUF t means count the minibuffer window even\n\
1474 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
1475 it is active. MINIBUF neither t nor nil means not to count the\n\
1476 minibuffer even if it is active.\n\
1478 Several frames may share a single minibuffer; if the minibuffer\n\
1479 counts, all windows on all frames that share that minibuffer count\n\
1480 too. Therefore, `previous-window' can be used to iterate through\n\
1481 the set of windows even when the minibuffer is on another frame. If\n\
1482 the minibuffer does not count, only windows from WINDOW's frame count\n\
1484 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
1485 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
1486 above. ALL-FRAMES = `visible' means include windows on all visible frames.\n\
1487 ALL-FRAMES = 0 means include windows on all visible and iconified frames.\n\
1488 If ALL-FRAMES is a frame, restrict search to windows on that frame.\n\
1489 Anything else means restrict to WINDOW's frame.\n\
1491 If you use consistent values for MINIBUF and ALL-FRAMES, you can use\n\
1492 `previous-window' to iterate through the entire cycle of acceptable\n\
1493 windows, eventually ending up back at the window you started with.\n\
1494 `next-window' traverses the same cycle, in the reverse order.")
1495 (window, minibuf, all_frames) */
1498 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
1500 (window
, minibuf
, all_frames
)
1501 Lisp_Object window
, minibuf
, all_frames
;
1503 return next_window (window
, minibuf
, all_frames
, 0);
1507 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1508 "Select the ARG'th different window on this frame.\n\
1509 All windows on current frame are arranged in a cyclic order.\n\
1510 This command selects the window ARG steps away in that order.\n\
1511 A negative ARG moves in the opposite order. If the optional second\n\
1512 argument ALL_FRAMES is non-nil, cycle through all frames.")
1514 Lisp_Object arg
, all_frames
;
1519 CHECK_NUMBER (arg
, 0);
1520 window
= selected_window
;
1522 for (i
= XINT (arg
); i
> 0; --i
)
1523 window
= Fnext_window (window
, Qnil
, all_frames
);
1525 window
= Fprevious_window (window
, Qnil
, all_frames
);
1527 Fselect_window (window
);
1532 DEFUN ("window-list", Fwindow_list
, Swindow_list
, 0, 3, 0,
1533 "Return a list of windows in canonical ordering.\n\
1534 Arguments are like for `next-window'.")
1535 (window
, minibuf
, all_frames
)
1536 Lisp_Object window
, minibuf
, all_frames
;
1538 Lisp_Object tail
, list
;
1540 decode_next_window_args (&window
, &minibuf
, &all_frames
);
1543 for (tail
= window_list (); CONSP (tail
); tail
= XCDR (tail
))
1544 if (candidate_window_p (XCAR (tail
), window
, minibuf
, all_frames
))
1545 list
= Fcons (XCAR (tail
), list
);
1547 return Fnreverse (list
);
1552 /* Look at all windows, performing an operation specified by TYPE
1554 If FRAMES is Qt, look at all frames;
1555 Qnil, look at just the selected frame;
1556 Qvisible, look at visible frames;
1557 a frame, just look at windows on that frame.
1558 If MINI is non-zero, perform the operation on minibuffer windows too.
1564 GET_BUFFER_WINDOW
, /* Arg is buffer */
1565 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1566 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1567 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1569 UNSHOW_BUFFER
, /* Arg is buffer */
1574 window_loop (type
, obj
, mini
, frames
)
1575 enum window_loop type
;
1576 Lisp_Object obj
, frames
;
1579 Lisp_Object window
, windows
, best_window
, frame_arg
;
1581 struct gcpro gcpro1
;
1583 /* If we're only looping through windows on a particular frame,
1584 frame points to that frame. If we're looping through windows
1585 on all frames, frame is 0. */
1586 if (FRAMEP (frames
))
1587 f
= XFRAME (frames
);
1588 else if (NILP (frames
))
1589 f
= SELECTED_FRAME ();
1594 frame_arg
= Qlambda
;
1595 else if (XFASTINT (frames
) == 0)
1597 else if (EQ (frames
, Qvisible
))
1602 /* frame_arg is Qlambda to stick to one frame,
1603 Qvisible to consider all visible frames,
1606 /* Pick a window to start with. */
1610 window
= FRAME_SELECTED_WINDOW (f
);
1612 window
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
1614 /* Figure out the last window we're going to mess with. Since
1615 Fnext_window, given the same options, is guaranteed to go in a
1616 ring, we can just use Fprevious_window to find the last one.
1618 We can't just wait until we hit the first window again, because
1619 it might be deleted. */
1621 windows
= Fwindow_list (window
, mini
? Qt
: Qnil
, frame_arg
);
1625 for (; CONSP (windows
); windows
= CDR (windows
))
1629 window
= XCAR (windows
);
1630 w
= XWINDOW (window
);
1632 /* Note that we do not pay attention here to whether the frame
1633 is visible, since Fwindow_list skips non-visible frames if
1634 that is desired, under the control of frame_arg. */
1635 if (!MINI_WINDOW_P (w
)
1636 /* For UNSHOW_BUFFER, we must always consider all windows. */
1637 || type
== UNSHOW_BUFFER
1638 || (mini
&& minibuf_level
> 0))
1641 case GET_BUFFER_WINDOW
:
1642 if (EQ (w
->buffer
, obj
)
1643 /* Don't find any minibuffer window
1644 except the one that is currently in use. */
1645 && (MINI_WINDOW_P (w
)
1646 ? EQ (window
, minibuf_window
)
1654 case GET_LRU_WINDOW
:
1655 /* t as arg means consider only full-width windows */
1656 if (!NILP (obj
) && !WINDOW_FULL_WIDTH_P (w
))
1658 /* Ignore dedicated windows and minibuffers. */
1659 if (MINI_WINDOW_P (w
) || !NILP (w
->dedicated
))
1661 if (NILP (best_window
)
1662 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1663 > XFASTINT (w
->use_time
)))
1664 best_window
= window
;
1667 case DELETE_OTHER_WINDOWS
:
1668 if (!EQ (window
, obj
))
1669 Fdelete_window (window
);
1672 case DELETE_BUFFER_WINDOWS
:
1673 if (EQ (w
->buffer
, obj
))
1675 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1677 /* If this window is dedicated, and in a frame of its own,
1679 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
1680 && !NILP (w
->dedicated
)
1681 && other_visible_frames (f
))
1683 /* Skip the other windows on this frame.
1684 There might be one, the minibuffer! */
1685 while (CONSP (XCDR (windows
))
1686 && EQ (XWINDOW (XCAR (windows
))->frame
,
1687 XWINDOW (XCAR (XCDR (windows
)))->frame
))
1688 windows
= XCDR (windows
);
1690 /* Now we can safely delete the frame. */
1691 Fdelete_frame (w
->frame
, Qnil
);
1693 else if (NILP (w
->parent
))
1695 /* If we're deleting the buffer displayed in the
1696 only window on the frame, find a new buffer to
1699 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
1701 buffer
= Fget_buffer_create (build_string ("*scratch*"));
1702 Fset_window_buffer (window
, buffer
);
1703 if (EQ (window
, selected_window
))
1704 Fset_buffer (w
->buffer
);
1707 Fdelete_window (window
);
1711 case GET_LARGEST_WINDOW
:
1715 /* Ignore dedicated windows and minibuffers. */
1716 if (MINI_WINDOW_P (w
)
1717 || !NILP (w
->dedicated
)
1718 || NILP (best_window
))
1721 b
= XWINDOW (best_window
);
1722 if (NILP (best_window
)
1723 || (XFASTINT (w
->height
) * XFASTINT (w
->width
)
1724 > (XFASTINT (b
->height
) * XFASTINT (b
->width
))))
1725 best_window
= window
;
1730 if (EQ (w
->buffer
, obj
))
1733 struct frame
*f
= XFRAME (w
->frame
);
1735 /* Find another buffer to show in this window. */
1736 buffer
= Fother_buffer (obj
, Qnil
, w
->frame
);
1738 buffer
= Fget_buffer_create (build_string ("*scratch*"));
1740 /* If this window is dedicated, and in a frame of its own,
1742 if (EQ (window
, FRAME_ROOT_WINDOW (f
))
1743 && !NILP (w
->dedicated
)
1744 && other_visible_frames (f
))
1746 /* Skip the other windows on this frame.
1747 There might be one, the minibuffer! */
1748 while (CONSP (XCDR (windows
))
1749 && EQ (XWINDOW (XCAR (windows
))->frame
,
1750 XWINDOW (XCAR (XCDR (windows
)))->frame
))
1751 windows
= XCDR (windows
);
1753 /* Now we can safely delete the frame. */
1754 Fdelete_frame (w
->frame
, Qnil
);
1758 /* Otherwise show a different buffer in the window. */
1759 w
->dedicated
= Qnil
;
1760 Fset_window_buffer (window
, buffer
);
1761 if (EQ (window
, selected_window
))
1762 Fset_buffer (w
->buffer
);
1767 /* Check for a window that has a killed buffer. */
1768 case CHECK_ALL_WINDOWS
:
1769 if (! NILP (w
->buffer
)
1770 && NILP (XBUFFER (w
->buffer
)->name
))
1780 /* Used for debugging. Abort if any window has a dead buffer. */
1783 check_all_windows ()
1785 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
1788 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1789 "Return the window least recently selected or used for display.\n\
1790 If optional argument FRAME is `visible', search all visible frames.\n\
1791 If FRAME is 0, search all visible and iconified frames.\n\
1792 If FRAME is t, search all frames.\n\
1793 If FRAME is nil, search only the selected frame.\n\
1794 If FRAME is a frame, search only that frame.")
1798 register Lisp_Object w
;
1799 /* First try for a window that is full-width */
1800 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frame
);
1801 if (!NILP (w
) && !EQ (w
, selected_window
))
1803 /* If none of them, try the rest */
1804 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frame
);
1807 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1808 "Return the largest window in area.\n\
1809 If optional argument FRAME is `visible', search all visible frames.\n\
1810 If FRAME is 0, search all visible and iconified frames.\n\
1811 If FRAME is t, search all frames.\n\
1812 If FRAME is nil, search only the selected frame.\n\
1813 If FRAME is a frame, search only that frame.")
1817 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
1821 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
1822 "Return a window currently displaying BUFFER, or nil if none.\n\
1823 If optional argument FRAME is `visible', search all visible frames.\n\
1824 If optional argument FRAME is 0, search all visible and iconified frames.\n\
1825 If FRAME is t, search all frames.\n\
1826 If FRAME is nil, search only the selected frame.\n\
1827 If FRAME is a frame, search only that frame.")
1829 Lisp_Object buffer
, frame
;
1831 buffer
= Fget_buffer (buffer
);
1832 if (BUFFERP (buffer
))
1833 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
1838 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
1840 "Make WINDOW (or the selected window) fill its frame.\n\
1841 Only the frame WINDOW is on is affected.\n\
1842 This function tries to reduce display jumps\n\
1843 by keeping the text previously visible in WINDOW\n\
1844 in the same place on the frame. Doing this depends on\n\
1845 the value of (window-start WINDOW), so if calling this function\n\
1846 in a program gives strange scrolling, make sure the window-start\n\
1847 value is reasonable when this function is called.")
1856 window
= selected_window
;
1858 CHECK_LIVE_WINDOW (window
, 0);
1860 w
= XWINDOW (window
);
1862 startpos
= marker_position (w
->start
);
1863 top
= XFASTINT (w
->top
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
1865 if (MINI_WINDOW_P (w
) && top
> 0)
1866 error ("Can't expand minibuffer to full frame");
1868 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME (w
));
1870 /* Try to minimize scrolling, by setting the window start to the point
1871 will cause the text at the old window start to be at the same place
1872 on the frame. But don't try to do this if the window start is
1873 outside the visible portion (as might happen when the display is
1874 not current, due to typeahead). */
1875 if (startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
1876 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
1878 struct position pos
;
1879 struct buffer
*obuf
= current_buffer
;
1881 Fset_buffer (w
->buffer
);
1882 /* This computation used to temporarily move point, but that can
1883 have unwanted side effects due to text properties. */
1884 pos
= *vmotion (startpos
, -top
, w
);
1886 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
1887 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
1888 || FETCH_BYTE (pos
.bytepos
- 1) == '\n') ? Qt
1890 /* We need to do this, so that the window-scroll-functions
1892 w
->optional_new_start
= Qt
;
1894 set_buffer_internal (obuf
);
1900 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
1901 1, 2, "bDelete windows on (buffer): ",
1902 "Delete all windows showing BUFFER.\n\
1903 Optional second argument FRAME controls which frames are affected.\n\
1904 If optional argument FRAME is `visible', search all visible frames.\n\
1905 If FRAME is 0, search all visible and iconified frames.\n\
1906 If FRAME is nil, search all frames.\n\
1907 If FRAME is t, search only the selected frame.\n\
1908 If FRAME is a frame, search only that frame.")
1910 Lisp_Object buffer
, frame
;
1912 /* FRAME uses t and nil to mean the opposite of what window_loop
1916 else if (EQ (frame
, Qt
))
1921 buffer
= Fget_buffer (buffer
);
1922 CHECK_BUFFER (buffer
, 0);
1923 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, frame
);
1929 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
1930 Sreplace_buffer_in_windows
,
1931 1, 1, "bReplace buffer in windows: ",
1932 "Replace BUFFER with some other buffer in all windows showing it.")
1938 buffer
= Fget_buffer (buffer
);
1939 CHECK_BUFFER (buffer
, 0);
1940 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
1945 /* Replace BUFFER with some other buffer in all windows
1946 of all frames, even those on other keyboards. */
1949 replace_buffer_in_all_windows (buffer
)
1953 Lisp_Object tail
, frame
;
1955 /* A single call to window_loop won't do the job
1956 because it only considers frames on the current keyboard.
1957 So loop manually over frames, and handle each one. */
1958 FOR_EACH_FRAME (tail
, frame
)
1959 window_loop (UNSHOW_BUFFER
, buffer
, 1, frame
);
1961 window_loop (UNSHOW_BUFFER
, buffer
, 1, Qt
);
1965 /* Set the height of WINDOW and all its inferiors. */
1967 /* The smallest acceptable dimensions for a window. Anything smaller
1968 might crash Emacs. */
1970 #define MIN_SAFE_WINDOW_WIDTH (2)
1971 #define MIN_SAFE_WINDOW_HEIGHT (2)
1973 /* Make sure that window_min_height and window_min_width are
1974 not too small; if they are, set them to safe minima. */
1977 check_min_window_sizes ()
1979 /* Smaller values might permit a crash. */
1980 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
1981 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
1982 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
1983 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
1986 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
1987 minimum allowable size. */
1990 check_frame_size (frame
, rows
, cols
)
1994 /* For height, we have to see:
1995 whether the frame has a minibuffer,
1996 whether it wants a mode line, and
1997 whether it has a menu bar. */
1999 (FRAME_MINIBUF_ONLY_P (frame
) ? MIN_SAFE_WINDOW_HEIGHT
- 1
2000 : (! FRAME_HAS_MINIBUF_P (frame
)) ? MIN_SAFE_WINDOW_HEIGHT
2001 : 2 * MIN_SAFE_WINDOW_HEIGHT
- 1);
2003 if (FRAME_TOP_MARGIN (frame
) > 0)
2004 min_height
+= FRAME_TOP_MARGIN (frame
);
2006 if (*rows
< min_height
)
2008 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
2009 *cols
= MIN_SAFE_WINDOW_WIDTH
;
2013 /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
2014 check if W's width can be changed, otherwise check W's height.
2015 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
2016 siblings, too. If none of the siblings is resizable, WINDOW isn't
2020 window_fixed_size_p (w
, width_p
, check_siblings_p
)
2022 int width_p
, check_siblings_p
;
2027 if (!NILP (w
->hchild
))
2029 c
= XWINDOW (w
->hchild
);
2033 /* A horiz. combination is fixed-width if all of if its
2035 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2036 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2037 fixed_p
= c
== NULL
;
2041 /* A horiz. combination is fixed-height if one of if its
2043 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2044 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2045 fixed_p
= c
!= NULL
;
2048 else if (!NILP (w
->vchild
))
2050 c
= XWINDOW (w
->vchild
);
2054 /* A vert. combination is fixed-width if one of if its
2056 while (c
&& !window_fixed_size_p (c
, width_p
, 0))
2057 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2058 fixed_p
= c
!= NULL
;
2062 /* A vert. combination is fixed-height if all of if its
2064 while (c
&& window_fixed_size_p (c
, width_p
, 0))
2065 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2066 fixed_p
= c
== NULL
;
2069 else if (BUFFERP (w
->buffer
))
2071 if (w
->height_fixed_p
&& !width_p
)
2075 struct buffer
*old
= current_buffer
;
2078 current_buffer
= XBUFFER (w
->buffer
);
2079 val
= find_symbol_value (Qwindow_size_fixed
);
2080 current_buffer
= old
;
2083 if (!EQ (val
, Qunbound
))
2085 fixed_p
= !NILP (val
);
2088 && ((EQ (val
, Qheight
) && width_p
)
2089 || (EQ (val
, Qwidth
) && !width_p
)))
2094 /* Can't tell if this one is resizable without looking at
2095 siblings. If all siblings are fixed-size this one is too. */
2096 if (!fixed_p
&& check_siblings_p
&& WINDOWP (w
->parent
))
2100 for (child
= w
->prev
; !NILP (child
); child
= XWINDOW (child
)->prev
)
2101 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2105 for (child
= w
->next
; !NILP (child
); child
= XWINDOW (child
)->next
)
2106 if (!window_fixed_size_p (XWINDOW (child
), width_p
, 0))
2120 /* Return the minimum size of window W, not taking fixed-width windows
2121 into account. WIDTH_P non-zero means return the minimum width,
2122 otherwise return the minimum height. If W is a combination window,
2123 compute the minimum size from the minimum sizes of W's children. */
2126 window_min_size_1 (w
, width_p
)
2133 if (!NILP (w
->hchild
))
2135 c
= XWINDOW (w
->hchild
);
2140 /* The min width of a horizontal combination is
2141 the sum of the min widths of its children. */
2144 size
+= window_min_size_1 (c
, width_p
);
2145 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2150 /* The min height a horizontal combination equals
2151 the maximum of all min height of its children. */
2154 int min_size
= window_min_size_1 (c
, width_p
);
2155 size
= max (min_size
, size
);
2156 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2160 else if (!NILP (w
->vchild
))
2162 c
= XWINDOW (w
->vchild
);
2167 /* The min width of a vertical combination is
2168 the maximum of the min widths of its children. */
2171 int min_size
= window_min_size_1 (c
, width_p
);
2172 size
= max (min_size
, size
);
2173 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2178 /* The min height of a vertical combination equals
2179 the sum of the min height of its children. */
2182 size
+= window_min_size_1 (c
, width_p
);
2183 c
= WINDOWP (c
->next
) ? XWINDOW (c
->next
) : NULL
;
2190 size
= window_min_width
;
2193 if (MINI_WINDOW_P (w
)
2194 || (!WINDOW_WANTS_MODELINE_P (w
)
2195 && !WINDOW_WANTS_HEADER_LINE_P (w
)))
2198 size
= window_min_height
;
2206 /* Return the minimum size of window W, taking fixed-size windows into
2207 account. WIDTH_P non-zero means return the minimum width,
2208 otherwise return the minimum height. IGNORE_FIXED_P non-zero means
2209 ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size
2210 unless FIXED is null. */
2213 window_min_size (w
, width_p
, ignore_fixed_p
, fixed
)
2215 int width_p
, ignore_fixed_p
, *fixed
;
2222 fixed_p
= window_fixed_size_p (w
, width_p
, 1);
2228 size
= width_p
? XFASTINT (w
->width
) : XFASTINT (w
->height
);
2230 size
= window_min_size_1 (w
, width_p
);
2236 /* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
2237 WINDOW's width. Resize WINDOW's children, if any, so that they
2238 keep their proportionate size relative to WINDOW. Propagate
2239 WINDOW's top or left edge position to children. Delete windows
2240 that become too small unless NODELETE_P is non-zero. */
2243 size_window (window
, size
, width_p
, nodelete_p
)
2245 int size
, width_p
, nodelete_p
;
2247 struct window
*w
= XWINDOW (window
);
2249 Lisp_Object child
, *forward
, *sideward
;
2250 int old_size
, min_size
;
2252 check_min_window_sizes ();
2254 /* If the window has been "too small" at one point,
2255 don't delete it for being "too small" in the future.
2256 Preserve it as long as that is at all possible. */
2259 old_size
= XFASTINT (w
->width
);
2260 min_size
= window_min_width
;
2264 old_size
= XFASTINT (w
->height
);
2265 min_size
= window_min_height
;
2268 if (old_size
< window_min_width
)
2269 w
->too_small_ok
= Qt
;
2271 /* Maybe delete WINDOW if it's too small. */
2272 if (!nodelete_p
&& !NILP (w
->parent
))
2276 if (!MINI_WINDOW_P (w
) && !NILP (w
->too_small_ok
))
2277 min_size
= width_p
? MIN_SAFE_WINDOW_WIDTH
: MIN_SAFE_WINDOW_HEIGHT
;
2279 min_size
= width_p
? window_min_width
: window_min_height
;
2281 if (size
< min_size
)
2283 delete_window (window
);
2288 /* Set redisplay hints. */
2289 XSETFASTINT (w
->last_modified
, 0);
2290 XSETFASTINT (w
->last_overlay_modified
, 0);
2291 windows_or_buffers_changed
++;
2292 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
2296 sideward
= &w
->vchild
;
2297 forward
= &w
->hchild
;
2298 XSETFASTINT (w
->width
, size
);
2302 sideward
= &w
->hchild
;
2303 forward
= &w
->vchild
;
2304 XSETFASTINT (w
->height
, size
);
2307 if (!NILP (*sideward
))
2309 for (child
= *sideward
; !NILP (child
); child
= c
->next
)
2311 c
= XWINDOW (child
);
2316 size_window (child
, size
, width_p
, nodelete_p
);
2319 else if (!NILP (*forward
))
2321 int fixed_size
, each
, extra
, n
;
2322 int resize_fixed_p
, nfixed
;
2323 int last_pos
, first_pos
, nchildren
;
2325 /* Determine the fixed-size portion of the this window, and the
2326 number of child windows. */
2327 fixed_size
= nchildren
= nfixed
= 0;
2328 for (child
= *forward
; !NILP (child
); child
= c
->next
, ++nchildren
)
2330 c
= XWINDOW (child
);
2331 if (window_fixed_size_p (c
, width_p
, 0))
2333 fixed_size
+= (width_p
2334 ? XFASTINT (c
->width
) : XFASTINT (c
->height
));
2339 /* If the new size is smaller than fixed_size, or if there
2340 aren't any resizable windows, allow resizing fixed-size
2342 resize_fixed_p
= nfixed
== nchildren
|| size
< fixed_size
;
2344 /* Compute how many lines/columns to add to each child. The
2345 value of extra takes care of rounding errors. */
2346 n
= resize_fixed_p
? nchildren
: nchildren
- nfixed
;
2347 each
= (size
- old_size
) / n
;
2348 extra
= (size
- old_size
) - n
* each
;
2350 /* Compute new children heights and edge positions. */
2351 first_pos
= width_p
? XFASTINT (w
->left
) : XFASTINT (w
->top
);
2352 last_pos
= first_pos
;
2353 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2355 int new_size
, old_size
;
2357 c
= XWINDOW (child
);
2358 old_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2359 new_size
= old_size
;
2361 /* The top or left edge position of this child equals the
2362 bottom or right edge of its predecessor. */
2364 c
->left
= make_number (last_pos
);
2366 c
->top
= make_number (last_pos
);
2368 /* If this child can be resized, do it. */
2369 if (resize_fixed_p
|| !window_fixed_size_p (c
, width_p
, 0))
2371 new_size
= old_size
+ each
+ extra
;
2375 /* Set new height. Note that size_window also propagates
2376 edge positions to children, so it's not a no-op if we
2377 didn't change the child's size. */
2378 size_window (child
, new_size
, width_p
, 1);
2380 /* Remember the bottom/right edge position of this child; it
2381 will be used to set the top/left edge of the next child. */
2382 last_pos
+= new_size
;
2385 /* We should have covered the parent exactly with child windows. */
2386 xassert (size
== last_pos
- first_pos
);
2388 /* Now delete any children that became too small. */
2390 for (child
= *forward
; !NILP (child
); child
= c
->next
)
2393 c
= XWINDOW (child
);
2394 child_size
= width_p
? XFASTINT (c
->width
) : XFASTINT (c
->height
);
2395 size_window (child
, child_size
, width_p
, 0);
2400 /* Set WINDOW's height to HEIGHT, and recursively change the height of
2401 WINDOW's children. NODELETE non-zero means don't delete windows
2402 that become too small in the process. (The caller should check
2403 later and do so if appropriate.) */
2406 set_window_height (window
, height
, nodelete
)
2411 size_window (window
, height
, 0, nodelete
);
2415 /* Set WINDOW's width to WIDTH, and recursively change the width of
2416 WINDOW's children. NODELETE non-zero means don't delete windows
2417 that become too small in the process. (The caller should check
2418 later and do so if appropriate.) */
2421 set_window_width (window
, width
, nodelete
)
2426 size_window (window
, width
, 1, nodelete
);
2430 int window_select_count
;
2433 Fset_window_buffer_unwind (obuf
)
2441 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
2442 means it's allowed to run hooks. See make_frame for a case where
2443 it's not allowed. */
2446 set_window_buffer (window
, buffer
, run_hooks_p
)
2447 Lisp_Object window
, buffer
;
2450 struct window
*w
= XWINDOW (window
);
2451 struct buffer
*b
= XBUFFER (buffer
);
2452 int count
= specpdl_ptr
- specpdl
;
2456 if (EQ (window
, selected_window
))
2457 b
->last_selected_window
= window
;
2459 /* Update time stamps of buffer display. */
2460 if (INTEGERP (b
->display_count
))
2461 XSETINT (b
->display_count
, XINT (b
->display_count
) + 1);
2462 b
->display_time
= Fcurrent_time ();
2464 XSETFASTINT (w
->window_end_pos
, 0);
2465 XSETFASTINT (w
->window_end_vpos
, 0);
2466 bzero (&w
->last_cursor
, sizeof w
->last_cursor
);
2467 w
->window_end_valid
= Qnil
;
2468 XSETFASTINT (w
->hscroll
, 0);
2469 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
2470 set_marker_restricted (w
->start
,
2471 make_number (b
->last_window_start
),
2473 w
->start_at_line_beg
= Qnil
;
2474 w
->force_start
= Qnil
;
2475 XSETFASTINT (w
->last_modified
, 0);
2476 XSETFASTINT (w
->last_overlay_modified
, 0);
2477 windows_or_buffers_changed
++;
2479 /* We must select BUFFER for running the window-scroll-functions.
2480 If WINDOW is selected, switch permanently.
2481 Otherwise, switch but go back to the ambient buffer afterward. */
2482 if (EQ (window
, selected_window
))
2483 Fset_buffer (buffer
);
2484 /* We can't check ! NILP (Vwindow_scroll_functions) here
2485 because that might itself be a local variable. */
2486 else if (window_initialized
)
2488 record_unwind_protect (Fset_window_buffer_unwind
, Fcurrent_buffer ());
2489 Fset_buffer (buffer
);
2492 /* Set left and right marginal area width from buffer. */
2493 Fset_window_margins (window
, b
->left_margin_width
, b
->right_margin_width
);
2497 if (! NILP (Vwindow_scroll_functions
))
2498 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
2499 Fmarker_position (w
->start
));
2501 if (! NILP (Vwindow_configuration_change_hook
)
2502 && ! NILP (Vrun_hooks
))
2503 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
2506 unbind_to (count
, Qnil
);
2510 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 2, 0,
2511 "Make WINDOW display BUFFER as its contents.\n\
2512 BUFFER can be a buffer or buffer name.")
2514 register Lisp_Object window
, buffer
;
2516 register Lisp_Object tem
;
2517 register struct window
*w
= decode_window (window
);
2519 XSETWINDOW (window
, w
);
2520 buffer
= Fget_buffer (buffer
);
2521 CHECK_BUFFER (buffer
, 1);
2523 if (NILP (XBUFFER (buffer
)->name
))
2524 error ("Attempt to display deleted buffer");
2528 error ("Window is deleted");
2529 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
2530 is first being set up. */
2532 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
2533 error ("Window is dedicated to `%s'",
2534 XSTRING (XBUFFER (tem
)->name
)->data
);
2539 set_window_buffer (window
, buffer
, 1);
2543 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 1, 0,
2544 "Select WINDOW. Most editing will apply to WINDOW's buffer.\n\
2545 If WINDOW is not already selected, also make WINDOW's buffer current.\n\
2546 Note that the main editor command loop\n\
2547 selects the buffer of the selected window before each command.")
2549 register Lisp_Object window
;
2551 return select_window_1 (window
, 1);
2554 /* Note that selected_window can be nil
2555 when this is called from Fset_window_configuration. */
2558 select_window_1 (window
, recordflag
)
2559 register Lisp_Object window
;
2562 register struct window
*w
;
2563 register struct window
*ow
;
2566 CHECK_LIVE_WINDOW (window
, 0);
2568 w
= XWINDOW (window
);
2570 if (NILP (w
->buffer
))
2571 error ("Trying to select deleted window or non-leaf window");
2573 XSETFASTINT (w
->use_time
, ++window_select_count
);
2574 if (EQ (window
, selected_window
))
2577 if (!NILP (selected_window
))
2579 ow
= XWINDOW (selected_window
);
2580 if (! NILP (ow
->buffer
))
2581 set_marker_both (ow
->pointm
, ow
->buffer
,
2582 BUF_PT (XBUFFER (ow
->buffer
)),
2583 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
2586 selected_window
= window
;
2587 sf
= SELECTED_FRAME ();
2588 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
2590 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
2591 /* Use this rather than Fhandle_switch_frame
2592 so that FRAME_FOCUS_FRAME is moved appropriately as we
2593 move around in the state where a minibuffer in a separate
2595 Fselect_frame (WINDOW_FRAME (w
), Qnil
);
2598 sf
->selected_window
= window
;
2601 record_buffer (w
->buffer
);
2602 Fset_buffer (w
->buffer
);
2604 XBUFFER (w
->buffer
)->last_selected_window
= window
;
2606 /* Go to the point recorded in the window.
2607 This is important when the buffer is in more
2608 than one window. It also matters when
2609 redisplay_window has altered point after scrolling,
2610 because it makes the change only in the window. */
2612 register int new_point
= marker_position (w
->pointm
);
2613 if (new_point
< BEGV
)
2615 else if (new_point
> ZV
)
2621 windows_or_buffers_changed
++;
2625 /* Deiconify the frame containing the window WINDOW,
2626 unless it is the selected frame;
2629 The reason for the exception for the selected frame
2630 is that it seems better not to change the selected frames visibility
2631 merely because of displaying a different buffer in it.
2632 The deiconification is useful when a buffer gets shown in
2633 another frame that you were not using lately. */
2636 display_buffer_1 (window
)
2639 Lisp_Object frame
= XWINDOW (window
)->frame
;
2640 FRAME_PTR f
= XFRAME (frame
);
2642 FRAME_SAMPLE_VISIBILITY (f
);
2644 if (!EQ (frame
, selected_frame
))
2646 if (FRAME_ICONIFIED_P (f
))
2647 Fmake_frame_visible (frame
);
2648 else if (FRAME_VISIBLE_P (f
))
2649 Fraise_frame (frame
);
2655 DEFUN ("special-display-p", Fspecial_display_p
, Sspecial_display_p
, 1, 1, 0,
2656 "Returns non-nil if a buffer named BUFFER-NAME would be created specially.\n\
2657 The value is actually t if the frame should be called with default frame\n\
2658 parameters, and a list of frame parameters if they were specified.\n\
2659 See `special-display-buffer-names', and `special-display-regexps'.")
2661 Lisp_Object buffer_name
;
2665 CHECK_STRING (buffer_name
, 1);
2667 tem
= Fmember (buffer_name
, Vspecial_display_buffer_names
);
2671 tem
= Fassoc (buffer_name
, Vspecial_display_buffer_names
);
2675 for (tem
= Vspecial_display_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2677 Lisp_Object car
= XCAR (tem
);
2679 && fast_string_match (car
, buffer_name
) >= 0)
2681 else if (CONSP (car
)
2682 && STRINGP (XCAR (car
))
2683 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2689 DEFUN ("same-window-p", Fsame_window_p
, Ssame_window_p
, 1, 1, 0,
2690 "Returns non-nil if a new buffer named BUFFER-NAME would use the same window.\n\
2691 See `same-window-buffer-names' and `same-window-regexps'.")
2693 Lisp_Object buffer_name
;
2697 CHECK_STRING (buffer_name
, 1);
2699 tem
= Fmember (buffer_name
, Vsame_window_buffer_names
);
2703 tem
= Fassoc (buffer_name
, Vsame_window_buffer_names
);
2707 for (tem
= Vsame_window_regexps
; CONSP (tem
); tem
= XCDR (tem
))
2709 Lisp_Object car
= XCAR (tem
);
2711 && fast_string_match (car
, buffer_name
) >= 0)
2713 else if (CONSP (car
)
2714 && STRINGP (XCAR (car
))
2715 && fast_string_match (XCAR (car
), buffer_name
) >= 0)
2721 /* Use B so the default is (other-buffer). */
2722 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 3,
2723 "BDisplay buffer: \nP",
2724 "Make BUFFER appear in some window but don't select it.\n\
2725 BUFFER can be a buffer or a buffer name.\n\
2726 If BUFFER is shown already in some window, just use that one,\n\
2727 unless the window is the selected window and the optional second\n\
2728 argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).\n\
2729 If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.\n\
2730 Returns the window displaying BUFFER.\n\
2731 If `display-reuse-frames' is non-nil, and another frame is currently\n\
2732 displaying BUFFER, then simply raise that frame.\n\
2734 The variables `special-display-buffer-names', `special-display-regexps',\n\
2735 `same-window-buffer-names', and `same-window-regexps' customize how certain\n\
2736 buffer names are handled.\n\
2738 If optional argument FRAME is `visible', search all visible frames.\n\
2739 If FRAME is 0, search all visible and iconified frames.\n\
2740 If FRAME is t, search all frames.\n\
2741 If FRAME is a frame, search only that frame.\n\
2742 If FRAME is nil, search only the selected frame\n\
2743 (actually the last nonminibuffer frame),\n\
2744 unless `pop-up-frames' or `display-reuse-frames' is non-nil,\n\
2745 which means search visible and iconified frames.")
2746 (buffer
, not_this_window
, frame
)
2747 register Lisp_Object buffer
, not_this_window
, frame
;
2749 register Lisp_Object window
, tem
, swp
;
2753 buffer
= Fget_buffer (buffer
);
2754 CHECK_BUFFER (buffer
, 0);
2756 if (!NILP (Vdisplay_buffer_function
))
2757 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
2759 if (NILP (not_this_window
)
2760 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
2761 return display_buffer_1 (selected_window
);
2763 /* See if the user has specified this buffer should appear
2764 in the selected window. */
2765 if (NILP (not_this_window
))
2767 swp
= Fsame_window_p (XBUFFER (buffer
)->name
);
2768 if (!NILP (swp
) && !no_switch_window (selected_window
))
2770 Fswitch_to_buffer (buffer
, Qnil
);
2771 return display_buffer_1 (selected_window
);
2775 /* If the user wants pop-up-frames or display-reuse-frames, then
2776 look for a window showing BUFFER on any visible or iconified frame.
2777 Otherwise search only the current frame. */
2780 else if (pop_up_frames
2781 || display_buffer_reuse_frames
2782 || last_nonminibuf_frame
== 0)
2783 XSETFASTINT (tem
, 0);
2785 XSETFRAME (tem
, last_nonminibuf_frame
);
2787 window
= Fget_buffer_window (buffer
, tem
);
2789 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
2790 return display_buffer_1 (window
);
2792 /* Certain buffer names get special handling. */
2793 if (!NILP (Vspecial_display_function
) && NILP (swp
))
2795 tem
= Fspecial_display_p (XBUFFER (buffer
)->name
);
2797 return call1 (Vspecial_display_function
, buffer
);
2799 return call2 (Vspecial_display_function
, buffer
, tem
);
2802 /* If there are no frames open that have more than a minibuffer,
2803 we need to create a new frame. */
2804 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
2806 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2807 Fset_window_buffer (window
, buffer
);
2808 return display_buffer_1 (window
);
2811 f
= SELECTED_FRAME ();
2813 || FRAME_MINIBUF_ONLY_P (f
)
2814 /* If the current frame is a special display frame,
2815 don't try to reuse its windows. */
2816 || !NILP (XWINDOW (FRAME_ROOT_WINDOW (f
))->dedicated
))
2821 if (FRAME_MINIBUF_ONLY_P (f
))
2822 XSETFRAME (frames
, last_nonminibuf_frame
);
2823 /* Don't try to create a window if would get an error */
2824 if (split_height_threshold
< window_min_height
<< 1)
2825 split_height_threshold
= window_min_height
<< 1;
2827 /* Note that both Fget_largest_window and Fget_lru_window
2828 ignore minibuffers and dedicated windows.
2829 This means they can return nil. */
2831 /* If the frame we would try to split cannot be split,
2832 try other frames. */
2833 if (FRAME_NO_SPLIT_P (NILP (frames
) ? f
: last_nonminibuf_frame
))
2835 /* Try visible frames first. */
2836 window
= Fget_largest_window (Qvisible
);
2837 /* If that didn't work, try iconified frames. */
2839 window
= Fget_largest_window (make_number (0));
2841 window
= Fget_largest_window (Qt
);
2844 window
= Fget_largest_window (frames
);
2846 /* If we got a tall enough full-width window that can be split,
2849 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2850 && window_height (window
) >= split_height_threshold
2851 && WINDOW_FULL_WIDTH_P (XWINDOW (window
)))
2852 window
= Fsplit_window (window
, Qnil
, Qnil
);
2855 Lisp_Object upper
, lower
, other
;
2857 window
= Fget_lru_window (frames
);
2858 /* If the LRU window is selected, and big enough,
2859 and can be split, split it. */
2861 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window
)->frame
))
2862 && (EQ (window
, selected_window
)
2863 || EQ (XWINDOW (window
)->parent
, Qnil
))
2864 && window_height (window
) >= window_min_height
<< 1)
2865 window
= Fsplit_window (window
, Qnil
, Qnil
);
2866 /* If Fget_lru_window returned nil, try other approaches. */
2868 /* Try visible frames first. */
2870 window
= Fget_buffer_window (buffer
, Qvisible
);
2872 window
= Fget_largest_window (Qvisible
);
2873 /* If that didn't work, try iconified frames. */
2875 window
= Fget_buffer_window (buffer
, make_number (0));
2877 window
= Fget_largest_window (make_number (0));
2878 /* Try invisible frames. */
2880 window
= Fget_buffer_window (buffer
, Qt
);
2882 window
= Fget_largest_window (Qt
);
2883 /* As a last resort, make a new frame. */
2885 window
= Fframe_selected_window (call0 (Vpop_up_frame_function
));
2886 /* If window appears above or below another,
2887 even out their heights. */
2888 other
= upper
= lower
= Qnil
;
2889 if (!NILP (XWINDOW (window
)->prev
))
2890 other
= upper
= XWINDOW (window
)->prev
, lower
= window
;
2891 if (!NILP (XWINDOW (window
)->next
))
2892 other
= lower
= XWINDOW (window
)->next
, upper
= window
;
2894 /* Check that OTHER and WINDOW are vertically arrayed. */
2895 && !EQ (XWINDOW (other
)->top
, XWINDOW (window
)->top
)
2896 && (XFASTINT (XWINDOW (other
)->height
)
2897 > XFASTINT (XWINDOW (window
)->height
)))
2899 int total
= (XFASTINT (XWINDOW (other
)->height
)
2900 + XFASTINT (XWINDOW (window
)->height
));
2901 enlarge_window (upper
,
2902 total
/ 2 - XFASTINT (XWINDOW (upper
)->height
),
2908 window
= Fget_lru_window (Qnil
);
2910 Fset_window_buffer (window
, buffer
);
2911 return display_buffer_1 (window
);
2915 temp_output_buffer_show (buf
)
2916 register Lisp_Object buf
;
2918 register struct buffer
*old
= current_buffer
;
2919 register Lisp_Object window
;
2920 register struct window
*w
;
2922 XBUFFER (buf
)->directory
= current_buffer
->directory
;
2925 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
2929 XBUFFER (buf
)->prevent_redisplay_optimizations_p
= 1;
2930 set_buffer_internal (old
);
2932 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
2933 call1 (Vtemp_buffer_show_function
, buf
);
2936 window
= Fdisplay_buffer (buf
, Qnil
, Qnil
);
2938 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
2939 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
2940 Vminibuf_scroll_window
= window
;
2941 w
= XWINDOW (window
);
2942 XSETFASTINT (w
->hscroll
, 0);
2943 set_marker_restricted_both (w
->start
, buf
, 1, 1);
2944 set_marker_restricted_both (w
->pointm
, buf
, 1, 1);
2946 /* Run temp-buffer-show-hook, with the chosen window selected
2947 and it sbuffer current. */
2948 if (!NILP (Vrun_hooks
))
2951 tem
= Fboundp (Qtemp_buffer_show_hook
);
2954 tem
= Fsymbol_value (Qtemp_buffer_show_hook
);
2957 int count
= specpdl_ptr
- specpdl
;
2958 Lisp_Object prev_window
;
2959 prev_window
= selected_window
;
2961 /* Select the window that was chosen, for running the hook. */
2962 record_unwind_protect (Fselect_window
, prev_window
);
2963 select_window_1 (window
, 0);
2964 Fset_buffer (w
->buffer
);
2965 call1 (Vrun_hooks
, Qtemp_buffer_show_hook
);
2966 select_window_1 (prev_window
, 0);
2967 unbind_to (count
, Qnil
);
2975 make_dummy_parent (window
)
2979 register struct window
*o
, *p
;
2980 register struct Lisp_Vector
*vec
;
2983 o
= XWINDOW (window
);
2984 vec
= allocate_vectorlike ((EMACS_INT
)VECSIZE (struct window
));
2985 for (i
= 0; i
< VECSIZE (struct window
); ++i
)
2986 vec
->contents
[i
] = ((struct Lisp_Vector
*)o
)->contents
[i
];
2987 vec
->size
= VECSIZE (struct window
);
2988 p
= (struct window
*)vec
;
2989 XSETWINDOW (new, p
);
2991 XSETFASTINT (p
->sequence_number
, ++sequence_number
);
2993 /* Put new into window structure in place of window */
2994 replace_window (window
, new);
3007 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
3008 "Split WINDOW, putting SIZE lines in the first of the pair.\n\
3009 WINDOW defaults to selected one and SIZE to half its size.\n\
3010 If optional third arg HORFLAG is non-nil, split side by side\n\
3011 and put SIZE columns in the first of the pair. In that case,\n\
3012 SIZE includes that window's scroll bar, or the divider column to its right.")
3013 (window
, size
, horflag
)
3014 Lisp_Object window
, size
, horflag
;
3016 register Lisp_Object
new;
3017 register struct window
*o
, *p
;
3019 register int size_int
;
3022 window
= selected_window
;
3024 CHECK_LIVE_WINDOW (window
, 0);
3026 o
= XWINDOW (window
);
3027 fo
= XFRAME (WINDOW_FRAME (o
));
3031 if (!NILP (horflag
))
3032 /* Calculate the size of the left-hand window, by dividing
3033 the usable space in columns by two.
3034 We round up, since the left-hand window may include
3035 a dividing line, while the right-hand may not. */
3036 size_int
= (XFASTINT (o
->width
) + 1) >> 1;
3038 size_int
= XFASTINT (o
->height
) >> 1;
3042 CHECK_NUMBER (size
, 1);
3043 size_int
= XINT (size
);
3046 if (MINI_WINDOW_P (o
))
3047 error ("Attempt to split minibuffer window");
3048 else if (window_fixed_size_p (o
, !NILP (horflag
), 0))
3049 error ("Attempt to split fixed-size window");
3051 check_min_window_sizes ();
3055 if (size_int
< window_min_height
)
3056 error ("Window height %d too small (after splitting)", size_int
);
3057 if (size_int
+ window_min_height
> XFASTINT (o
->height
))
3058 error ("Window height %d too small (after splitting)",
3059 XFASTINT (o
->height
) - size_int
);
3060 if (NILP (o
->parent
)
3061 || NILP (XWINDOW (o
->parent
)->vchild
))
3063 make_dummy_parent (window
);
3065 XWINDOW (new)->vchild
= window
;
3070 if (size_int
< window_min_width
)
3071 error ("Window width %d too small (after splitting)", size_int
);
3073 if (size_int
+ window_min_width
> XFASTINT (o
->width
))
3074 error ("Window width %d too small (after splitting)",
3075 XFASTINT (o
->width
) - size_int
);
3076 if (NILP (o
->parent
)
3077 || NILP (XWINDOW (o
->parent
)->hchild
))
3079 make_dummy_parent (window
);
3081 XWINDOW (new)->hchild
= window
;
3085 /* Now we know that window's parent is a vertical combination
3086 if we are dividing vertically, or a horizontal combination
3087 if we are making side-by-side windows */
3089 windows_or_buffers_changed
++;
3090 FRAME_WINDOW_SIZES_CHANGED (fo
) = 1;
3091 new = make_window ();
3094 p
->frame
= o
->frame
;
3096 if (!NILP (p
->next
))
3097 XWINDOW (p
->next
)->prev
= new;
3100 p
->parent
= o
->parent
;
3102 p
->window_end_valid
= Qnil
;
3103 bzero (&p
->last_cursor
, sizeof p
->last_cursor
);
3105 /* Apportion the available frame space among the two new windows */
3107 if (!NILP (horflag
))
3109 p
->height
= o
->height
;
3111 XSETFASTINT (p
->width
, XFASTINT (o
->width
) - size_int
);
3112 XSETFASTINT (o
->width
, size_int
);
3113 XSETFASTINT (p
->left
, XFASTINT (o
->left
) + size_int
);
3118 p
->width
= o
->width
;
3119 XSETFASTINT (p
->height
, XFASTINT (o
->height
) - size_int
);
3120 XSETFASTINT (o
->height
, size_int
);
3121 XSETFASTINT (p
->top
, XFASTINT (o
->top
) + size_int
);
3124 /* Adjust glyph matrices. */
3126 Fset_window_buffer (new, o
->buffer
);
3130 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
3131 "Make current window ARG lines bigger.\n\
3132 From program, optional second arg non-nil means grow sideways ARG columns.")
3134 register Lisp_Object arg
, side
;
3136 CHECK_NUMBER (arg
, 0);
3137 enlarge_window (selected_window
, XINT (arg
), !NILP (side
));
3139 if (! NILP (Vwindow_configuration_change_hook
))
3140 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3145 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
3146 "Make current window ARG lines smaller.\n\
3147 From program, optional second arg non-nil means shrink sideways arg columns.")
3149 register Lisp_Object arg
, side
;
3151 CHECK_NUMBER (arg
, 0);
3152 enlarge_window (selected_window
, -XINT (arg
), !NILP (side
));
3154 if (! NILP (Vwindow_configuration_change_hook
))
3155 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
3161 window_height (window
)
3164 register struct window
*p
= XWINDOW (window
);
3165 return XFASTINT (p
->height
);
3169 window_width (window
)
3172 register struct window
*p
= XWINDOW (window
);
3173 return XFASTINT (p
->width
);
3178 *(widthflag ? &(XWINDOW (w)->left) : &(XWINDOW (w)->top))
3180 #define CURSIZE(w) \
3181 *(widthflag ? &(XWINDOW (w)->width) : &(XWINDOW (w)->height))
3184 /* Enlarge selected_window by DELTA. WIDTHFLAG non-zero means
3185 increase its width. Siblings of the selected window are resized to
3186 fullfil the size request. If they become too small in the process,
3187 they will be deleted. */
3190 enlarge_window (window
, delta
, widthflag
)
3192 int delta
, widthflag
;
3194 Lisp_Object parent
, next
, prev
;
3198 int (*sizefun
) P_ ((Lisp_Object
))
3199 = widthflag
? window_width
: window_height
;
3200 void (*setsizefun
) P_ ((Lisp_Object
, int, int))
3201 = (widthflag
? set_window_width
: set_window_height
);
3203 /* Check values of window_min_width and window_min_height for
3205 check_min_window_sizes ();
3207 /* Give up if this window cannot be resized. */
3208 if (window_fixed_size_p (XWINDOW (window
), widthflag
, 1))
3209 error ("Window is not resizable");
3211 /* Find the parent of the selected window. */
3214 p
= XWINDOW (window
);
3220 error ("No other window to side of this one");
3225 ? !NILP (XWINDOW (parent
)->hchild
)
3226 : !NILP (XWINDOW (parent
)->vchild
))
3232 sizep
= &CURSIZE (window
);
3235 register int maxdelta
;
3237 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - XINT (*sizep
)
3238 : !NILP (p
->next
) ? ((*sizefun
) (p
->next
)
3239 - window_min_size (XWINDOW (p
->next
),
3241 : !NILP (p
->prev
) ? ((*sizefun
) (p
->prev
)
3242 - window_min_size (XWINDOW (p
->prev
),
3244 /* This is a frame with only one window, a minibuffer-only
3245 or a minibufferless frame. */
3248 if (delta
> maxdelta
)
3249 /* This case traps trying to make the minibuffer
3250 the full frame, or make the only window aside from the
3251 minibuffer the full frame. */
3255 if (XINT (*sizep
) + delta
< window_min_size (XWINDOW (window
), widthflag
, 0, 0))
3257 delete_window (window
);
3264 /* Find the total we can get from other siblings. */
3266 for (next
= p
->next
; ! NILP (next
); next
= XWINDOW (next
)->next
)
3267 maximum
+= (*sizefun
) (next
) - window_min_size (XWINDOW (next
),
3269 for (prev
= p
->prev
; ! NILP (prev
); prev
= XWINDOW (prev
)->prev
)
3270 maximum
+= (*sizefun
) (prev
) - window_min_size (XWINDOW (prev
),
3273 /* If we can get it all from them, do so. */
3274 if (delta
<= maximum
)
3276 Lisp_Object first_unaffected
;
3277 Lisp_Object first_affected
;
3282 first_affected
= window
;
3283 /* Look at one sibling at a time,
3284 moving away from this window in both directions alternately,
3285 and take as much as we can get without deleting that sibling. */
3286 while (delta
!= 0 && (!NILP (next
) || !NILP (prev
)))
3290 int this_one
= ((*sizefun
) (next
)
3291 - window_min_size (XWINDOW (next
),
3292 widthflag
, 0, &fixed_p
));
3295 if (this_one
> delta
)
3298 (*setsizefun
) (next
, (*sizefun
) (next
) - this_one
, 0);
3299 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3304 next
= XWINDOW (next
)->next
;
3312 int this_one
= ((*sizefun
) (prev
)
3313 - window_min_size (XWINDOW (prev
),
3314 widthflag
, 0, &fixed_p
));
3317 if (this_one
> delta
)
3320 first_affected
= prev
;
3322 (*setsizefun
) (prev
, (*sizefun
) (prev
) - this_one
, 0);
3323 (*setsizefun
) (window
, XINT (*sizep
) + this_one
, 0);
3328 prev
= XWINDOW (prev
)->prev
;
3332 xassert (delta
== 0);
3334 /* Now recalculate the edge positions of all the windows affected,
3335 based on the new sizes. */
3336 first_unaffected
= next
;
3337 prev
= first_affected
;
3338 for (next
= XWINDOW (prev
)->next
; ! EQ (next
, first_unaffected
);
3339 prev
= next
, next
= XWINDOW (next
)->next
)
3341 XSETINT (CURBEG (next
), XINT (CURBEG (prev
)) + (*sizefun
) (prev
));
3342 /* This does not change size of NEXT,
3343 but it propagates the new top edge to its children */
3344 (*setsizefun
) (next
, (*sizefun
) (next
), 0);
3349 register int delta1
;
3350 register int opht
= (*sizefun
) (parent
);
3352 /* If trying to grow this window to or beyond size of the parent,
3353 make delta1 so big that, on shrinking back down,
3354 all the siblings end up with less than one line and are deleted. */
3355 if (opht
<= XINT (*sizep
) + delta
)
3356 delta1
= opht
* opht
* 2;
3359 /* Otherwise, make delta1 just right so that if we add
3360 delta1 lines to this window and to the parent, and then
3361 shrink the parent back to its original size, the new
3362 proportional size of this window will increase by delta.
3364 The function size_window will compute the new height h'
3365 of the window from delta1 as:
3368 x = delta1 - delta1/n * n for the 1st resizable child
3371 where n is the number of children that can be resized.
3372 We can ignore x by choosing a delta1 that is a multiple of
3373 n. We want the height of this window to come out as
3383 The number of children n rquals the number of resizable
3384 children of this window + 1 because we know window itself
3385 is resizable (otherwise we would have signalled an error. */
3387 struct window
*w
= XWINDOW (window
);
3391 for (s
= w
->next
; !NILP (s
); s
= XWINDOW (s
)->next
)
3392 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3394 for (s
= w
->prev
; !NILP (s
); s
= XWINDOW (s
)->prev
)
3395 if (!window_fixed_size_p (XWINDOW (s
), widthflag
, 0))
3401 /* Add delta1 lines or columns to this window, and to the parent,
3402 keeping things consistent while not affecting siblings. */
3403 XSETINT (CURSIZE (parent
), opht
+ delta1
);
3404 (*setsizefun
) (window
, XINT (*sizep
) + delta1
, 0);
3406 /* Squeeze out delta1 lines or columns from our parent,
3407 shriking this window and siblings proportionately.
3408 This brings parent back to correct size.
3409 Delta1 was calculated so this makes this window the desired size,
3410 taking it all out of the siblings. */
3411 (*setsizefun
) (parent
, opht
, 0);
3414 XSETFASTINT (p
->last_modified
, 0);
3415 XSETFASTINT (p
->last_overlay_modified
, 0);
3417 /* Adjust glyph matrices. */
3418 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
3426 /***********************************************************************
3427 Resizing Mini-Windows
3428 ***********************************************************************/
3430 static void shrink_window_lowest_first
P_ ((struct window
*, int));
3432 enum save_restore_action
3439 static int save_restore_orig_size
P_ ((struct window
*,
3440 enum save_restore_action
));
3442 /* Shrink windows rooted in window W to HEIGHT. Take the space needed
3443 from lowest windows first. */
3446 shrink_window_lowest_first (w
, height
)
3454 xassert (!MINI_WINDOW_P (w
));
3456 /* Set redisplay hints. */
3457 XSETFASTINT (w
->last_modified
, 0);
3458 XSETFASTINT (w
->last_overlay_modified
, 0);
3459 windows_or_buffers_changed
++;
3460 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w
))) = 1;
3462 old_height
= XFASTINT (w
->height
);
3463 XSETFASTINT (w
->height
, height
);
3465 if (!NILP (w
->hchild
))
3467 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
3469 c
= XWINDOW (child
);
3471 shrink_window_lowest_first (c
, height
);
3474 else if (!NILP (w
->vchild
))
3476 Lisp_Object last_child
;
3477 int delta
= old_height
- height
;
3480 /* Find the last child. We are taking space from lowest windows
3481 first, so we iterate over children from the last child
3483 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
3486 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
3487 for (child
= last_child
; delta
&& !NILP (child
); child
= c
->prev
)
3491 c
= XWINDOW (child
);
3492 this_one
= XFASTINT (c
->height
) - MIN_SAFE_WINDOW_HEIGHT
;
3494 if (this_one
> delta
)
3497 shrink_window_lowest_first (c
, XFASTINT (c
->height
) - this_one
);
3501 /* Compute new positions. */
3502 last_top
= XINT (w
->top
);
3503 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
3505 c
= XWINDOW (child
);
3506 c
->top
= make_number (last_top
);
3507 shrink_window_lowest_first (c
, XFASTINT (c
->height
));
3508 last_top
+= XFASTINT (c
->height
);
3514 /* Save, restore, or check positions and sizes in the window tree
3515 rooted at W. ACTION says what to do.
3517 If ACTION is CHECK_ORIG_SIZES, check if orig_top and orig_height
3518 members are valid for all windows in the window tree. Value is
3519 non-zero if they are valid.
3521 If ACTION is SAVE_ORIG_SIZES, save members top and height in
3522 orig_top and orig_height for all windows in the tree.
3524 If ACTION is RESTORE_ORIG_SIZES, restore top and height from
3525 values stored in orig_top and orig_height for all windows. */
3528 save_restore_orig_size (w
, action
)
3530 enum save_restore_action action
;
3536 if (!NILP (w
->hchild
))
3538 if (!save_restore_orig_size (XWINDOW (w
->hchild
), action
))
3541 else if (!NILP (w
->vchild
))
3543 if (!save_restore_orig_size (XWINDOW (w
->vchild
), action
))
3549 case CHECK_ORIG_SIZES
:
3550 if (!INTEGERP (w
->orig_top
) || !INTEGERP (w
->orig_height
))
3554 case SAVE_ORIG_SIZES
:
3555 w
->orig_top
= w
->top
;
3556 w
->orig_height
= w
->height
;
3557 XSETFASTINT (w
->last_modified
, 0);
3558 XSETFASTINT (w
->last_overlay_modified
, 0);
3561 case RESTORE_ORIG_SIZES
:
3562 xassert (INTEGERP (w
->orig_top
) && INTEGERP (w
->orig_height
));
3563 w
->top
= w
->orig_top
;
3564 w
->height
= w
->orig_height
;
3565 w
->orig_height
= w
->orig_top
= Qnil
;
3566 XSETFASTINT (w
->last_modified
, 0);
3567 XSETFASTINT (w
->last_overlay_modified
, 0);
3574 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
3581 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
3582 without deleting other windows. */
3585 grow_mini_window (w
, delta
)
3589 struct frame
*f
= XFRAME (w
->frame
);
3590 struct window
*root
;
3592 xassert (MINI_WINDOW_P (w
));
3593 xassert (delta
>= 0);
3595 /* Check values of window_min_width and window_min_height for
3597 check_min_window_sizes ();
3599 /* Compute how much we can enlarge the mini-window without deleting
3601 root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3604 int min_height
= window_min_size (root
, 0, 0, 0);
3605 if (XFASTINT (root
->height
) - delta
< min_height
)
3606 delta
= XFASTINT (root
->height
) - min_height
;
3611 /* Save original window sizes and positions, if not already done. */
3612 if (!save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3613 save_restore_orig_size (root
, SAVE_ORIG_SIZES
);
3615 /* Shrink other windows. */
3616 shrink_window_lowest_first (root
, XFASTINT (root
->height
) - delta
);
3618 /* Grow the mini-window. */
3619 w
->top
= make_number (XFASTINT (root
->top
) + XFASTINT (root
->height
));
3620 w
->height
= make_number (XFASTINT (w
->height
) + delta
);
3621 XSETFASTINT (w
->last_modified
, 0);
3622 XSETFASTINT (w
->last_overlay_modified
, 0);
3629 /* Shrink mini-window W. If there is recorded info about window sizes
3630 before a call to grow_mini_window, restore recorded window sizes.
3631 Otherwise, if the mini-window is higher than 1 line, resize it to 1
3635 shrink_mini_window (w
)
3638 struct frame
*f
= XFRAME (w
->frame
);
3639 struct window
*root
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3641 if (save_restore_orig_size (root
, CHECK_ORIG_SIZES
))
3643 save_restore_orig_size (root
, RESTORE_ORIG_SIZES
);
3645 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
3646 windows_or_buffers_changed
= 1;
3648 else if (XFASTINT (w
->height
) > 1)
3651 XSETWINDOW (window
, w
);
3652 enlarge_window (window
, 1 - XFASTINT (w
->height
), 0);
3658 /* Mark window cursors off for all windows in the window tree rooted
3659 at W by setting their phys_cursor_on_p flag to zero. Called from
3660 xterm.c, e.g. when a frame is cleared and thereby all cursors on
3661 the frame are cleared. */
3664 mark_window_cursors_off (w
)
3669 if (!NILP (w
->hchild
))
3670 mark_window_cursors_off (XWINDOW (w
->hchild
));
3671 else if (!NILP (w
->vchild
))
3672 mark_window_cursors_off (XWINDOW (w
->vchild
));
3674 w
->phys_cursor_on_p
= 0;
3676 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
3681 /* Return number of lines of text (not counting mode line) in W. */
3684 window_internal_height (w
)
3687 int ht
= XFASTINT (w
->height
);
3689 if (MINI_WINDOW_P (w
))
3692 if (!NILP (w
->parent
) || !NILP (w
->vchild
) || !NILP (w
->hchild
)
3693 || !NILP (w
->next
) || !NILP (w
->prev
)
3694 || FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (w
))))
3701 /* Return the number of columns in W.
3702 Don't count columns occupied by scroll bars or the vertical bar
3703 separating W from the sibling to its right. */
3706 window_internal_width (w
)
3709 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
3710 int width
= XINT (w
->width
);
3712 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
3713 /* Scroll bars occupy a few columns. */
3714 width
-= FRAME_SCROLL_BAR_COLS (f
);
3715 else if (!WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
3716 /* The column of `|' characters separating side-by-side windows
3717 occupies one column only. */
3720 /* On window-systems, areas to the left and right of the window
3721 are used to display bitmaps there. */
3722 if (FRAME_WINDOW_P (f
))
3723 width
-= FRAME_FLAGS_AREA_COLS (f
);
3729 /************************************************************************
3731 ***********************************************************************/
3733 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
3734 one screen-full, which is defined as the height of the window minus
3735 next_screen_context_lines. If WHOLE is zero, scroll up N lines
3736 instead. Negative values of N mean scroll down. NOERROR non-zero
3737 means don't signal an error if we try to move over BEGV or ZV,
3741 window_scroll (window
, n
, whole
, noerror
)
3747 /* If we must, use the pixel-based version which is much slower than
3748 the line-based one but can handle varying line heights. */
3749 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
3750 window_scroll_pixel_based (window
, n
, whole
, noerror
);
3752 window_scroll_line_based (window
, n
, whole
, noerror
);
3756 /* Implementation of window_scroll that works based on pixel line
3757 heights. See the comment of window_scroll for parameter
3761 window_scroll_pixel_based (window
, n
, whole
, noerror
)
3768 struct window
*w
= XWINDOW (window
);
3769 struct text_pos start
;
3771 int this_scroll_margin
;
3774 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
3776 /* If PT is not visible in WINDOW, move back one half of
3778 XSETFASTINT (tem
, PT
);
3779 tem
= Fpos_visible_in_window_p (tem
, window
);
3782 /* Move backward half the height of the window. Performance note:
3783 vmotion used here is about 10% faster, but would give wrong
3784 results for variable height lines. */
3785 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3786 it
.current_y
= it
.last_visible_y
;
3787 move_it_vertically (&it
, -it
.last_visible_y
/ 2);
3789 /* The function move_iterator_vertically may move over more than
3790 the specified y-distance. If it->w is small, e.g. a
3791 mini-buffer window, we may end up in front of the window's
3792 display area. This is the case when Start displaying at the
3793 start of the line containing PT in this case. */
3794 if (it
.current_y
<= 0)
3796 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
3797 move_it_vertically (&it
, 0);
3801 start
= it
.current
.pos
;
3804 /* If scroll_preserve_screen_position is non-zero, we try to set
3805 point in the same window line as it is now, so get that line. */
3806 if (!NILP (Vscroll_preserve_screen_position
))
3808 start_display (&it
, w
, start
);
3809 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3810 preserve_y
= it
.current_y
;
3815 /* Move iterator it from start the specified distance forward or
3816 backward. The result is the new window start. */
3817 start_display (&it
, w
, start
);
3820 int screen_full
= (it
.last_visible_y
3821 - next_screen_context_lines
* CANON_Y_UNIT (it
.f
));
3822 int direction
= n
< 0 ? -1 : 1;
3823 move_it_vertically (&it
, direction
* screen_full
);
3826 move_it_by_lines (&it
, n
, 1);
3828 /* End if we end up at ZV or BEGV. */
3829 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
3830 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
3834 else if (IT_CHARPOS (it
) == ZV
)
3835 Fsignal (Qend_of_buffer
, Qnil
);
3837 Fsignal (Qbeginning_of_buffer
, Qnil
);
3840 /* Set the window start, and set up the window for redisplay. */
3841 set_marker_restricted (w
->start
, make_number (IT_CHARPOS (it
)), w
->buffer
);
3842 w
->start_at_line_beg
= Fbolp ();
3843 w
->update_mode_line
= Qt
;
3844 XSETFASTINT (w
->last_modified
, 0);
3845 XSETFASTINT (w
->last_overlay_modified
, 0);
3846 /* Set force_start so that redisplay_window will run the
3847 window-scroll-functions. */
3848 w
->force_start
= Qt
;
3850 it
.current_y
= it
.vpos
= 0;
3852 /* Preserve the screen position if we must. */
3853 if (preserve_y
>= 0)
3855 move_it_to (&it
, -1, -1, preserve_y
, -1, MOVE_TO_Y
);
3856 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3860 /* Move PT out of scroll margins. */
3861 this_scroll_margin
= max (0, scroll_margin
);
3862 this_scroll_margin
= min (this_scroll_margin
, XFASTINT (w
->height
) / 4);
3863 this_scroll_margin
*= CANON_Y_UNIT (it
.f
);
3867 /* We moved the window start towards ZV, so PT may be now
3868 in the scroll margin at the top. */
3869 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
3870 while (it
.current_y
< this_scroll_margin
)
3871 move_it_by_lines (&it
, 1, 1);
3872 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3876 /* We moved the window start towards BEGV, so PT may be now
3877 in the scroll margin at the bottom. */
3878 move_it_to (&it
, PT
, -1,
3879 it
.last_visible_y
- this_scroll_margin
- 1, -1,
3880 MOVE_TO_POS
| MOVE_TO_Y
);
3882 /* Don't put point on a partially visible line at the end. */
3883 if (it
.current_y
+ it
.max_ascent
+ it
.max_descent
3884 > it
.last_visible_y
)
3885 move_it_by_lines (&it
, -1, 0);
3887 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
3893 /* Implementation of window_scroll that works based on screen lines.
3894 See the comment of window_scroll for parameter descriptions. */
3897 window_scroll_line_based (window
, n
, whole
, noerror
)
3903 register struct window
*w
= XWINDOW (window
);
3904 register int opoint
= PT
, opoint_byte
= PT_BYTE
;
3905 register int pos
, pos_byte
;
3906 register int ht
= window_internal_height (w
);
3907 register Lisp_Object tem
;
3911 struct position posit
;
3914 startpos
= marker_position (w
->start
);
3916 posit
= *compute_motion (startpos
, 0, 0, 0,
3918 window_internal_width (w
), XINT (w
->hscroll
),
3920 original_vpos
= posit
.vpos
;
3922 XSETFASTINT (tem
, PT
);
3923 tem
= Fpos_visible_in_window_p (tem
, window
);
3927 Fvertical_motion (make_number (- (ht
/ 2)), window
);
3932 lose
= n
< 0 && PT
== BEGV
;
3933 Fvertical_motion (make_number (n
), window
);
3937 SET_PT_BOTH (opoint
, opoint_byte
);
3944 Fsignal (Qbeginning_of_buffer
, Qnil
);
3949 int this_scroll_margin
= scroll_margin
;
3951 /* Don't use a scroll margin that is negative or too large. */
3952 if (this_scroll_margin
< 0)
3953 this_scroll_margin
= 0;
3955 if (XINT (w
->height
) < 4 * scroll_margin
)
3956 this_scroll_margin
= XINT (w
->height
) / 4;
3958 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
3959 w
->start_at_line_beg
= bolp
;
3960 w
->update_mode_line
= Qt
;
3961 XSETFASTINT (w
->last_modified
, 0);
3962 XSETFASTINT (w
->last_overlay_modified
, 0);
3963 /* Set force_start so that redisplay_window will run
3964 the window-scroll-functions. */
3965 w
->force_start
= Qt
;
3967 if (whole
&& !NILP (Vscroll_preserve_screen_position
))
3969 SET_PT_BOTH (pos
, pos_byte
);
3970 Fvertical_motion (make_number (original_vpos
), window
);
3972 /* If we scrolled forward, put point enough lines down
3973 that it is outside the scroll margin. */
3978 if (this_scroll_margin
> 0)
3980 SET_PT_BOTH (pos
, pos_byte
);
3981 Fvertical_motion (make_number (this_scroll_margin
), window
);
3987 if (top_margin
<= opoint
)
3988 SET_PT_BOTH (opoint
, opoint_byte
);
3989 else if (!NILP (Vscroll_preserve_screen_position
))
3991 SET_PT_BOTH (pos
, pos_byte
);
3992 Fvertical_motion (make_number (original_vpos
), window
);
3995 SET_PT (top_margin
);
4001 /* If we scrolled backward, put point near the end of the window
4002 but not within the scroll margin. */
4003 SET_PT_BOTH (pos
, pos_byte
);
4004 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
4005 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
4008 bottom_margin
= PT
+ 1;
4010 if (bottom_margin
> opoint
)
4011 SET_PT_BOTH (opoint
, opoint_byte
);
4014 if (!NILP (Vscroll_preserve_screen_position
))
4016 SET_PT_BOTH (pos
, pos_byte
);
4017 Fvertical_motion (make_number (original_vpos
), window
);
4020 Fvertical_motion (make_number (-1), window
);
4029 Fsignal (Qend_of_buffer
, Qnil
);
4034 /* Scroll selected_window up or down. If N is nil, scroll a
4035 screen-full which is defined as the height of the window minus
4036 next_screen_context_lines. If N is the symbol `-', scroll.
4037 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
4038 up. This is the guts of Fscroll_up and Fscroll_down. */
4041 scroll_command (n
, direction
)
4045 register int defalt
;
4046 int count
= specpdl_ptr
- specpdl
;
4048 xassert (abs (direction
) == 1);
4050 /* If selected window's buffer isn't current, make it current for
4051 the moment. But don't screw up if window_scroll gets an error. */
4052 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
4054 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4055 Fset_buffer (XWINDOW (selected_window
)->buffer
);
4057 /* Make redisplay consider other windows than just selected_window. */
4058 ++windows_or_buffers_changed
;
4061 defalt
= (window_internal_height (XWINDOW (selected_window
))
4062 - next_screen_context_lines
);
4063 defalt
= direction
* (defalt
< 1 ? 1 : defalt
);
4066 window_scroll (selected_window
, defalt
, 1, 0);
4067 else if (EQ (n
, Qminus
))
4068 window_scroll (selected_window
, - defalt
, 1, 0);
4071 n
= Fprefix_numeric_value (n
);
4072 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
4075 unbind_to (count
, Qnil
);
4078 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
4079 "Scroll text of current window upward ARG lines; or near full screen if no ARG.\n\
4080 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4081 Negative ARG means scroll downward.\n\
4082 If ARG is the atom `-', scroll downward by nearly full screen.\n\
4083 When calling from a program, supply as argument a number, nil, or `-'.")
4087 scroll_command (arg
, 1);
4091 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
4092 "Scroll text of current window down ARG lines; or near full screen if no ARG.\n\
4093 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4094 Negative ARG means scroll upward.\n\
4095 If ARG is the atom `-', scroll upward by nearly full screen.\n\
4096 When calling from a program, supply as argument a number, nil, or `-'.")
4100 scroll_command (arg
, -1);
4104 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
4105 "Return the other window for \"other window scroll\" commands.\n\
4106 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4107 specifies the window.\n\
4108 If `other-window-scroll-buffer' is non-nil, a window\n\
4109 showing that buffer is used.")
4114 if (MINI_WINDOW_P (XWINDOW (selected_window
))
4115 && !NILP (Vminibuf_scroll_window
))
4116 window
= Vminibuf_scroll_window
;
4117 /* If buffer is specified, scroll that buffer. */
4118 else if (!NILP (Vother_window_scroll_buffer
))
4120 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
4122 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
4126 /* Nothing specified; look for a neighboring window on the same
4128 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
4130 if (EQ (window
, selected_window
))
4131 /* That didn't get us anywhere; look for a window on another
4134 window
= Fnext_window (window
, Qnil
, Qt
);
4135 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
4136 && ! EQ (window
, selected_window
));
4139 CHECK_LIVE_WINDOW (window
, 0);
4141 if (EQ (window
, selected_window
))
4142 error ("There is no other window");
4147 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
4148 "Scroll next window upward ARG lines; or near full screen if no ARG.\n\
4149 A near full screen is `next-screen-context-lines' less than a full screen.\n\
4150 The next window is the one below the current one; or the one at the top\n\
4151 if the current one is at the bottom. Negative ARG means scroll downward.\n\
4152 If ARG is the atom `-', scroll downward by nearly full screen.\n\
4153 When calling from a program, supply as argument a number, nil, or `-'.\n\
4155 If in the minibuffer, `minibuffer-scroll-window' if non-nil\n\
4156 specifies the window to scroll.\n\
4157 If `other-window-scroll-buffer' is non-nil, scroll the window\n\
4158 showing that buffer, popping the buffer up if necessary.")
4160 register Lisp_Object arg
;
4162 register Lisp_Object window
;
4163 register int defalt
;
4164 register struct window
*w
;
4165 register int count
= specpdl_ptr
- specpdl
;
4167 window
= Fother_window_for_scrolling ();
4169 w
= XWINDOW (window
);
4170 defalt
= window_internal_height (w
) - next_screen_context_lines
;
4171 if (defalt
< 1) defalt
= 1;
4173 /* Don't screw up if window_scroll gets an error. */
4174 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4175 ++windows_or_buffers_changed
;
4177 Fset_buffer (w
->buffer
);
4178 SET_PT (marker_position (w
->pointm
));
4181 window_scroll (window
, defalt
, 1, 1);
4182 else if (EQ (arg
, Qminus
))
4183 window_scroll (window
, -defalt
, 1, 1);
4188 CHECK_NUMBER (arg
, 0);
4189 window_scroll (window
, XINT (arg
), 0, 1);
4192 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
4193 unbind_to (count
, Qnil
);
4198 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 1, "P",
4199 "Scroll selected window display ARG columns left.\n\
4200 Default for ARG is window width minus 2.")
4202 register Lisp_Object arg
;
4206 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4208 arg
= Fprefix_numeric_value (arg
);
4211 Fset_window_hscroll (selected_window
,
4212 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4216 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 1, "P",
4217 "Scroll selected window display ARG columns right.\n\
4218 Default for ARG is window width minus 2.")
4220 register Lisp_Object arg
;
4223 XSETFASTINT (arg
, window_internal_width (XWINDOW (selected_window
)) - 2);
4225 arg
= Fprefix_numeric_value (arg
);
4228 Fset_window_hscroll (selected_window
,
4229 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
4233 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
4234 "Center point in window and redisplay frame. With ARG, put point on line ARG.\n\
4235 The desired position of point is always relative to the current window.\n\
4236 Just C-u as prefix means put point in the center of the window.\n\
4237 If ARG is omitted or nil, erases the entire frame and then\n\
4238 redraws with point in the center of the current window.")
4240 register Lisp_Object arg
;
4242 register struct window
*w
= XWINDOW (selected_window
);
4243 register int ht
= window_internal_height (w
);
4244 struct position pos
;
4245 struct buffer
*buf
= XBUFFER (w
->buffer
);
4246 struct buffer
*obuf
= current_buffer
;
4250 extern int frame_garbaged
;
4253 /* Invalidate pixel data calculated for all compositions. */
4254 for (i
= 0; i
< n_compositions
; i
++)
4255 composition_table
[i
]->font
= NULL
;
4257 Fredraw_frame (w
->frame
);
4258 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
4259 XSETFASTINT (arg
, ht
/ 2);
4261 else if (CONSP (arg
)) /* Just C-u. */
4263 XSETFASTINT (arg
, ht
/ 2);
4267 arg
= Fprefix_numeric_value (arg
);
4268 CHECK_NUMBER (arg
, 0);
4272 XSETINT (arg
, XINT (arg
) + ht
);
4274 set_buffer_internal (buf
);
4275 pos
= *vmotion (PT
, - XINT (arg
), w
);
4277 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
4278 w
->start_at_line_beg
= ((pos
.bytepos
== BEGV_BYTE
4279 || FETCH_BYTE (pos
.bytepos
- 1) == '\n')
4281 w
->force_start
= Qt
;
4282 set_buffer_internal (obuf
);
4288 /* Value is the number of lines actually displayed in window W,
4289 as opposed to its height. */
4292 displayed_window_lines (w
)
4296 struct text_pos start
;
4297 int height
= window_box_height (w
);
4299 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4300 start_display (&it
, w
, start
);
4301 move_it_vertically (&it
, height
);
4303 /* Add in empty lines at the bottom of the window. */
4304 if (it
.current_y
< height
)
4306 struct frame
*f
= XFRAME (w
->frame
);
4307 int rest
= height
- it
.current_y
;
4308 int lines
= (rest
+ CANON_Y_UNIT (f
) - 1) / CANON_Y_UNIT (f
);
4317 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
4319 "Position point relative to window.\n\
4320 With no argument, position point at center of window.\n\
4321 An argument specifies vertical position within the window;\n\
4322 zero means top of window, negative means relative to bottom of window.")
4326 struct window
*w
= XWINDOW (selected_window
);
4330 window
= selected_window
;
4331 start
= marker_position (w
->start
);
4332 if (start
< BEGV
|| start
> ZV
)
4334 int height
= window_internal_height (w
);
4335 Fvertical_motion (make_number (- (height
/ 2)), window
);
4336 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
4337 w
->start_at_line_beg
= Fbolp ();
4338 w
->force_start
= Qt
;
4341 Fgoto_char (w
->start
);
4343 lines
= displayed_window_lines (w
);
4345 XSETFASTINT (arg
, lines
/ 2);
4348 arg
= Fprefix_numeric_value (arg
);
4350 XSETINT (arg
, XINT (arg
) + lines
);
4353 return Fvertical_motion (arg
, window
);
4358 /***********************************************************************
4359 Window Configuration
4360 ***********************************************************************/
4362 struct save_window_data
4364 EMACS_INT size_from_Lisp_Vector_struct
;
4365 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4366 Lisp_Object frame_width
, frame_height
, frame_menu_bar_lines
;
4367 Lisp_Object frame_tool_bar_lines
;
4368 Lisp_Object selected_frame
;
4369 Lisp_Object current_window
;
4370 Lisp_Object current_buffer
;
4371 Lisp_Object minibuf_scroll_window
;
4372 Lisp_Object root_window
;
4373 Lisp_Object focus_frame
;
4374 /* Record the values of window-min-width and window-min-height
4375 so that window sizes remain consistent with them. */
4376 Lisp_Object min_width
, min_height
;
4377 /* A vector, each of whose elements is a struct saved_window
4379 Lisp_Object saved_windows
;
4382 /* This is saved as a Lisp_Vector */
4385 /* these first two must agree with struct Lisp_Vector in lisp.h */
4386 EMACS_INT size_from_Lisp_Vector_struct
;
4387 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
4390 Lisp_Object buffer
, start
, pointm
, mark
;
4391 Lisp_Object left
, top
, width
, height
, hscroll
;
4392 Lisp_Object parent
, prev
;
4393 Lisp_Object start_at_line_beg
;
4394 Lisp_Object display_table
;
4396 #define SAVED_WINDOW_VECTOR_SIZE 14 /* Arg to Fmake_vector */
4398 #define SAVED_WINDOW_N(swv,n) \
4399 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
4401 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
4402 "Return t if OBJECT is a window-configuration object.")
4406 if (WINDOW_CONFIGURATIONP (object
))
4411 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
4412 "Return the frame that CONFIG, a window-configuration object, is about.")
4416 register struct save_window_data
*data
;
4417 struct Lisp_Vector
*saved_windows
;
4419 if (! WINDOW_CONFIGURATIONP (config
))
4420 wrong_type_argument (Qwindow_configuration_p
, config
);
4422 data
= (struct save_window_data
*) XVECTOR (config
);
4423 saved_windows
= XVECTOR (data
->saved_windows
);
4424 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4427 DEFUN ("set-window-configuration", Fset_window_configuration
,
4428 Sset_window_configuration
, 1, 1, 0,
4429 "Set the configuration of windows and buffers as specified by CONFIGURATION.\n\
4430 CONFIGURATION must be a value previously returned\n\
4431 by `current-window-configuration' (which see).\n\
4432 If CONFIGURATION was made from a frame that is now deleted,\n\
4433 only frame-independent values can be restored. In this case,\n\
4434 the return value is nil. Otherwise the value is t.")
4436 Lisp_Object configuration
;
4438 register struct save_window_data
*data
;
4439 struct Lisp_Vector
*saved_windows
;
4440 Lisp_Object new_current_buffer
;
4445 while (!WINDOW_CONFIGURATIONP (configuration
))
4446 wrong_type_argument (Qwindow_configuration_p
, configuration
);
4448 data
= (struct save_window_data
*) XVECTOR (configuration
);
4449 saved_windows
= XVECTOR (data
->saved_windows
);
4451 new_current_buffer
= data
->current_buffer
;
4452 if (NILP (XBUFFER (new_current_buffer
)->name
))
4453 new_current_buffer
= Qnil
;
4456 if (XBUFFER (new_current_buffer
) == current_buffer
)
4461 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
4464 /* If f is a dead frame, don't bother rebuilding its window tree.
4465 However, there is other stuff we should still try to do below. */
4466 if (FRAME_LIVE_P (f
))
4468 register struct window
*w
;
4469 register struct saved_window
*p
;
4470 struct window
*root_window
;
4471 struct window
**leaf_windows
;
4475 /* If the frame has been resized since this window configuration was
4476 made, we change the frame to the size specified in the
4477 configuration, restore the configuration, and then resize it
4478 back. We keep track of the prevailing height in these variables. */
4479 int previous_frame_height
= FRAME_HEIGHT (f
);
4480 int previous_frame_width
= FRAME_WIDTH (f
);
4481 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
4482 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
4484 /* The mouse highlighting code could get screwed up
4485 if it runs during this. */
4488 if (XFASTINT (data
->frame_height
) != previous_frame_height
4489 || XFASTINT (data
->frame_width
) != previous_frame_width
)
4490 change_frame_size (f
, XFASTINT (data
->frame_height
),
4491 XFASTINT (data
->frame_width
), 0, 0, 0);
4492 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4493 if (XFASTINT (data
->frame_menu_bar_lines
)
4494 != previous_frame_menu_bar_lines
)
4495 x_set_menu_bar_lines (f
, data
->frame_menu_bar_lines
, make_number (0));
4496 #ifdef HAVE_WINDOW_SYSTEM
4497 if (XFASTINT (data
->frame_tool_bar_lines
)
4498 != previous_frame_tool_bar_lines
)
4499 x_set_tool_bar_lines (f
, data
->frame_tool_bar_lines
, make_number (0));
4503 /* "Swap out" point from the selected window
4504 into its buffer. We do this now, before
4505 restoring the window contents, and prevent it from
4506 being done later on when we select a new window. */
4507 if (! NILP (XWINDOW (selected_window
)->buffer
))
4509 w
= XWINDOW (selected_window
);
4510 set_marker_both (w
->pointm
,
4512 BUF_PT (XBUFFER (w
->buffer
)),
4513 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4516 windows_or_buffers_changed
++;
4517 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4519 /* Problem: Freeing all matrices and later allocating them again
4520 is a serious redisplay flickering problem. What we would
4521 really like to do is to free only those matrices not reused
4523 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4525 = (struct window
**) alloca (count_windows (root_window
)
4526 * sizeof (struct window
*));
4527 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
4529 /* Temporarily avoid any problems with windows that are smaller
4530 than they are supposed to be. */
4531 window_min_height
= 1;
4532 window_min_width
= 1;
4535 Mark all windows now on frame as "deleted".
4536 Restoring the new configuration "undeletes" any that are in it.
4538 Save their current buffers in their height fields, since we may
4539 need it later, if a buffer saved in the configuration is now
4541 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4543 for (k
= 0; k
< saved_windows
->size
; k
++)
4545 p
= SAVED_WINDOW_N (saved_windows
, k
);
4546 w
= XWINDOW (p
->window
);
4549 if (!NILP (p
->parent
))
4550 w
->parent
= SAVED_WINDOW_N (saved_windows
,
4551 XFASTINT (p
->parent
))->window
;
4555 if (!NILP (p
->prev
))
4557 w
->prev
= SAVED_WINDOW_N (saved_windows
,
4558 XFASTINT (p
->prev
))->window
;
4559 XWINDOW (w
->prev
)->next
= p
->window
;
4564 if (!NILP (w
->parent
))
4566 if (EQ (p
->width
, XWINDOW (w
->parent
)->width
))
4568 XWINDOW (w
->parent
)->vchild
= p
->window
;
4569 XWINDOW (w
->parent
)->hchild
= Qnil
;
4573 XWINDOW (w
->parent
)->hchild
= p
->window
;
4574 XWINDOW (w
->parent
)->vchild
= Qnil
;
4579 /* If we squirreled away the buffer in the window's height,
4581 if (BUFFERP (w
->height
))
4582 w
->buffer
= w
->height
;
4585 w
->width
= p
->width
;
4586 w
->height
= p
->height
;
4587 w
->hscroll
= p
->hscroll
;
4588 w
->display_table
= p
->display_table
;
4589 XSETFASTINT (w
->last_modified
, 0);
4590 XSETFASTINT (w
->last_overlay_modified
, 0);
4592 /* Reinstall the saved buffer and pointers into it. */
4593 if (NILP (p
->buffer
))
4594 w
->buffer
= p
->buffer
;
4597 if (!NILP (XBUFFER (p
->buffer
)->name
))
4598 /* If saved buffer is alive, install it. */
4600 w
->buffer
= p
->buffer
;
4601 w
->start_at_line_beg
= p
->start_at_line_beg
;
4602 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
4603 set_marker_restricted (w
->pointm
, p
->pointm
, w
->buffer
);
4604 Fset_marker (XBUFFER (w
->buffer
)->mark
,
4605 p
->mark
, w
->buffer
);
4607 /* As documented in Fcurrent_window_configuration, don't
4608 save the location of point in the buffer which was current
4609 when the window configuration was recorded. */
4610 if (!EQ (p
->buffer
, new_current_buffer
)
4611 && XBUFFER (p
->buffer
) == current_buffer
)
4612 Fgoto_char (w
->pointm
);
4614 else if (NILP (w
->buffer
) || NILP (XBUFFER (w
->buffer
)->name
))
4615 /* Else unless window has a live buffer, get one. */
4617 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
4618 /* This will set the markers to beginning of visible
4620 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
4621 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
4622 w
->start_at_line_beg
= Qt
;
4625 /* Keeping window's old buffer; make sure the markers
4628 /* Set window markers at start of visible range. */
4629 if (XMARKER (w
->start
)->buffer
== 0)
4630 set_marker_restricted (w
->start
, make_number (0),
4632 if (XMARKER (w
->pointm
)->buffer
== 0)
4633 set_marker_restricted_both (w
->pointm
, w
->buffer
,
4634 BUF_PT (XBUFFER (w
->buffer
)),
4635 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4636 w
->start_at_line_beg
= Qt
;
4641 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
4642 /* Prevent "swapping out point" in the old selected window
4643 using the buffer that has been restored into it.
4644 That swapping out has already been done,
4645 near the beginning of this function. */
4646 selected_window
= Qnil
;
4647 Fselect_window (data
->current_window
);
4648 XBUFFER (XWINDOW (selected_window
)->buffer
)->last_selected_window
4651 if (NILP (data
->focus_frame
)
4652 || (FRAMEP (data
->focus_frame
)
4653 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
4654 Fredirect_frame_focus (frame
, data
->focus_frame
);
4656 #if 0 /* I don't understand why this is needed, and it causes problems
4657 when the frame's old selected window has been deleted. */
4658 if (f
!= selected_frame
&& FRAME_WINDOW_P (f
))
4659 do_switch_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)),
4663 /* Set the screen height to the value it had before this function. */
4664 if (previous_frame_height
!= FRAME_HEIGHT (f
)
4665 || previous_frame_width
!= FRAME_WIDTH (f
))
4666 change_frame_size (f
, previous_frame_height
, previous_frame_width
,
4668 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
4669 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
4670 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
4672 #ifdef HAVE_WINDOW_SYSTEM
4673 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
4674 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
4679 /* Now, free glyph matrices in windows that were not reused. */
4680 for (i
= 0; i
< n_leaf_windows
; ++i
)
4681 if (NILP (leaf_windows
[i
]->buffer
))
4683 /* Assert it's not reused as a combination. */
4684 xassert (NILP (leaf_windows
[i
]->hchild
)
4685 && NILP (leaf_windows
[i
]->vchild
));
4686 free_window_matrices (leaf_windows
[i
]);
4687 SET_FRAME_GARBAGED (f
);
4694 /* Fselect_window will have made f the selected frame, so we
4695 reselect the proper frame here. Fhandle_switch_frame will change the
4696 selected window too, but that doesn't make the call to
4697 Fselect_window above totally superfluous; it still sets f's
4699 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
4700 do_switch_frame (data
->selected_frame
, Qnil
, 0);
4702 if (! NILP (Vwindow_configuration_change_hook
)
4703 && ! NILP (Vrun_hooks
))
4704 call1 (Vrun_hooks
, Qwindow_configuration_change_hook
);
4707 if (!NILP (new_current_buffer
))
4709 Fset_buffer (new_current_buffer
);
4711 /* If the buffer that is current now is the same
4712 that was current before setting the window configuration,
4713 don't alter its PT. */
4718 /* Restore the minimum heights recorded in the configuration. */
4719 window_min_height
= XINT (data
->min_height
);
4720 window_min_width
= XINT (data
->min_width
);
4722 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
4724 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
4727 /* Mark all windows now on frame as deleted
4728 by setting their buffers to nil. */
4731 delete_all_subwindows (w
)
4732 register struct window
*w
;
4734 if (!NILP (w
->next
))
4735 delete_all_subwindows (XWINDOW (w
->next
));
4736 if (!NILP (w
->vchild
))
4737 delete_all_subwindows (XWINDOW (w
->vchild
));
4738 if (!NILP (w
->hchild
))
4739 delete_all_subwindows (XWINDOW (w
->hchild
));
4741 w
->height
= w
->buffer
; /* See Fset_window_configuration for excuse. */
4743 if (!NILP (w
->buffer
))
4746 /* We set all three of these fields to nil, to make sure that we can
4747 distinguish this dead window from any live window. Live leaf
4748 windows will have buffer set, and combination windows will have
4749 vchild or hchild set. */
4754 Vwindow_list
= Qnil
;
4758 count_windows (window
)
4759 register struct window
*window
;
4761 register int count
= 1;
4762 if (!NILP (window
->next
))
4763 count
+= count_windows (XWINDOW (window
->next
));
4764 if (!NILP (window
->vchild
))
4765 count
+= count_windows (XWINDOW (window
->vchild
));
4766 if (!NILP (window
->hchild
))
4767 count
+= count_windows (XWINDOW (window
->hchild
));
4772 /* Fill vector FLAT with leaf windows under W, starting at index I.
4773 Value is last index + 1. */
4776 get_leaf_windows (w
, flat
, i
)
4778 struct window
**flat
;
4783 if (!NILP (w
->hchild
))
4784 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
4785 else if (!NILP (w
->vchild
))
4786 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
4790 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4797 /* Return a pointer to the glyph W's physical cursor is on. Value is
4798 null if W's current matrix is invalid, so that no meaningfull glyph
4802 get_phys_cursor_glyph (w
)
4805 struct glyph_row
*row
;
4806 struct glyph
*glyph
;
4808 if (w
->phys_cursor
.vpos
>= 0
4809 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
4810 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
4812 && row
->used
[TEXT_AREA
] > w
->phys_cursor
.hpos
)
4813 glyph
= row
->glyphs
[TEXT_AREA
] + w
->phys_cursor
.hpos
;
4822 save_window_save (window
, vector
, i
)
4824 struct Lisp_Vector
*vector
;
4827 register struct saved_window
*p
;
4828 register struct window
*w
;
4829 register Lisp_Object tem
;
4831 for (;!NILP (window
); window
= w
->next
)
4833 p
= SAVED_WINDOW_N (vector
, i
);
4834 w
= XWINDOW (window
);
4836 XSETFASTINT (w
->temslot
, i
++);
4838 p
->buffer
= w
->buffer
;
4841 p
->width
= w
->width
;
4842 p
->height
= w
->height
;
4843 p
->hscroll
= w
->hscroll
;
4844 p
->display_table
= w
->display_table
;
4845 if (!NILP (w
->buffer
))
4847 /* Save w's value of point in the window configuration.
4848 If w is the selected window, then get the value of point
4849 from the buffer; pointm is garbage in the selected window. */
4850 if (EQ (window
, selected_window
))
4852 p
->pointm
= Fmake_marker ();
4853 set_marker_both (p
->pointm
, w
->buffer
,
4854 BUF_PT (XBUFFER (w
->buffer
)),
4855 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
4858 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
4860 p
->start
= Fcopy_marker (w
->start
, Qnil
);
4861 p
->start_at_line_beg
= w
->start_at_line_beg
;
4863 tem
= XBUFFER (w
->buffer
)->mark
;
4864 p
->mark
= Fcopy_marker (tem
, Qnil
);
4871 p
->start_at_line_beg
= Qnil
;
4874 if (NILP (w
->parent
))
4877 p
->parent
= XWINDOW (w
->parent
)->temslot
;
4882 p
->prev
= XWINDOW (w
->prev
)->temslot
;
4884 if (!NILP (w
->vchild
))
4885 i
= save_window_save (w
->vchild
, vector
, i
);
4886 if (!NILP (w
->hchild
))
4887 i
= save_window_save (w
->hchild
, vector
, i
);
4893 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
4894 Scurrent_window_configuration
, 0, 1, 0,
4895 "Return an object representing the current window configuration of FRAME.\n\
4896 If FRAME is nil or omitted, use the selected frame.\n\
4897 This describes the number of windows, their sizes and current buffers,\n\
4898 and for each displayed buffer, where display starts, and the positions of\n\
4899 point and mark. An exception is made for point in the current buffer:\n\
4900 its value is -not- saved.\n\
4901 This also records the currently selected frame, and FRAME's focus\n\
4902 redirection (see `redirect-frame-focus').")
4906 register Lisp_Object tem
;
4907 register int n_windows
;
4908 register struct save_window_data
*data
;
4909 register struct Lisp_Vector
*vec
;
4914 frame
= selected_frame
;
4915 CHECK_LIVE_FRAME (frame
, 0);
4918 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
4919 vec
= allocate_vectorlike (VECSIZE (struct save_window_data
));
4920 for (i
= 0; i
< VECSIZE (struct save_window_data
); i
++)
4921 vec
->contents
[i
] = Qnil
;
4922 vec
->size
= VECSIZE (struct save_window_data
);
4923 data
= (struct save_window_data
*)vec
;
4925 XSETFASTINT (data
->frame_width
, FRAME_WIDTH (f
));
4926 XSETFASTINT (data
->frame_height
, FRAME_HEIGHT (f
));
4927 XSETFASTINT (data
->frame_menu_bar_lines
, FRAME_MENU_BAR_LINES (f
));
4928 XSETFASTINT (data
->frame_tool_bar_lines
, FRAME_TOOL_BAR_LINES (f
));
4929 data
->selected_frame
= selected_frame
;
4930 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
4931 XSETBUFFER (data
->current_buffer
, current_buffer
);
4932 data
->minibuf_scroll_window
= Vminibuf_scroll_window
;
4933 data
->root_window
= FRAME_ROOT_WINDOW (f
);
4934 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
4935 XSETINT (data
->min_height
, window_min_height
);
4936 XSETINT (data
->min_width
, window_min_width
);
4937 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
4938 data
->saved_windows
= tem
;
4939 for (i
= 0; i
< n_windows
; i
++)
4940 XVECTOR (tem
)->contents
[i
]
4941 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
4942 save_window_save (FRAME_ROOT_WINDOW (f
),
4944 XSETWINDOW_CONFIGURATION (tem
, data
);
4948 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
4950 "Execute body, preserving window sizes and contents.\n\
4951 Restore which buffer appears in which window, where display starts,\n\
4952 and the value of point and mark for each window.\n\
4953 Also restore the choice of selected window.\n\
4954 Also restore which buffer is current.\n\
4955 Does not restore the value of point in current buffer.")
4959 register Lisp_Object val
;
4960 register int count
= specpdl_ptr
- specpdl
;
4962 record_unwind_protect (Fset_window_configuration
,
4963 Fcurrent_window_configuration (Qnil
));
4964 val
= Fprogn (args
);
4965 return unbind_to (count
, val
);
4969 /***********************************************************************
4971 ***********************************************************************/
4973 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
4975 "Set width of marginal areas of window WINDOW.\n\
4976 If window is nil, set margins of the currently selected window.\n\
4977 First parameter LEFT-WIDTH specifies the number of character\n\
4978 cells to reserve for the left marginal area. Second parameter\n\
4979 RIGHT-WIDTH does the same for the right marginal area.\n\
4980 A nil width parameter means no margin.")
4981 (window
, left
, right
)
4982 Lisp_Object window
, left
, right
;
4984 struct window
*w
= decode_window (window
);
4987 CHECK_NUMBER_OR_FLOAT (left
, 1);
4989 CHECK_NUMBER_OR_FLOAT (right
, 2);
4991 /* Check widths < 0 and translate a zero width to nil.
4992 Margins that are too wide have to be checked elsewhere. */
4993 if ((INTEGERP (left
) && XINT (left
) < 0)
4994 || (FLOATP (left
) && XFLOAT_DATA (left
) <= 0))
4995 XSETFASTINT (left
, 0);
4996 if (INTEGERP (left
) && XFASTINT (left
) == 0)
4999 if ((INTEGERP (right
) && XINT (right
) < 0)
5000 || (FLOATP (right
) && XFLOAT_DATA (right
) <= 0))
5001 XSETFASTINT (right
, 0);
5002 if (INTEGERP (right
) && XFASTINT (right
) == 0)
5005 w
->left_margin_width
= left
;
5006 w
->right_margin_width
= right
;
5008 ++windows_or_buffers_changed
;
5009 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
5014 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
5016 "Get width of marginal areas of window WINDOW.\n\
5017 If WINDOW is omitted or nil, use the currently selected window.\n\
5018 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).\n\
5019 If a marginal area does not exist, its width will be returned\n\
5024 struct window
*w
= decode_window (window
);
5025 return Fcons (w
->left_margin_width
, w
->right_margin_width
);
5030 /***********************************************************************
5032 ***********************************************************************/
5034 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 1, 0,
5035 "Return the amount by which WINDOW is scrolled vertically.\n\
5036 Use the selected window if WINDOW is nil or omitted.\n\
5037 Value is a multiple of the canonical character height of WINDOW.")
5046 window
= selected_window
;
5048 CHECK_WINDOW (window
, 0);
5049 w
= XWINDOW (window
);
5050 f
= XFRAME (w
->frame
);
5052 if (FRAME_WINDOW_P (f
))
5053 result
= CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
);
5055 result
= make_number (0);
5060 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
5062 "Set amount by which WINDOW should be scrolled vertically to VSCROLL.\n\
5063 WINDOW nil or omitted means use the selected window. VSCROLL is a\n\
5064 non-negative multiple of the canonical character height of WINDOW.")
5066 Lisp_Object window
, vscroll
;
5072 window
= selected_window
;
5074 CHECK_WINDOW (window
, 0);
5075 CHECK_NUMBER_OR_FLOAT (vscroll
, 1);
5077 w
= XWINDOW (window
);
5078 f
= XFRAME (w
->frame
);
5080 if (FRAME_WINDOW_P (f
))
5082 int old_dy
= w
->vscroll
;
5084 w
->vscroll
= - CANON_Y_UNIT (f
) * XFLOATINT (vscroll
);
5085 w
->vscroll
= min (w
->vscroll
, 0);
5087 /* Adjust glyph matrix of the frame if the virtual display
5088 area becomes larger than before. */
5089 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
5092 /* Prevent redisplay shortcuts. */
5093 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
5096 return Fwindow_vscroll (window
);
5100 /* Call FN for all leaf windows on frame F. FN is called with the
5101 first argument being a pointer to the leaf window, and with
5102 additional argument USER_DATA. Stops when FN returns 0. */
5105 foreach_window (f
, fn
, user_data
)
5107 int (* fn
) P_ ((struct window
*, void *));
5110 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, user_data
);
5114 /* Helper function for foreach_window. Call FN for all leaf windows
5115 reachable from W. FN is called with the first argument being a
5116 pointer to the leaf window, and with additional argument USER_DATA.
5117 Stop when FN returns 0. Value is 0 if stopped by FN. */
5120 foreach_window_1 (w
, fn
, user_data
)
5122 int (* fn
) P_ ((struct window
*, void *));
5127 for (cont
= 1; w
&& cont
;)
5129 if (!NILP (w
->hchild
))
5130 cont
= foreach_window_1 (XWINDOW (w
->hchild
), fn
, user_data
);
5131 else if (!NILP (w
->vchild
))
5132 cont
= foreach_window_1 (XWINDOW (w
->vchild
), fn
, user_data
);
5134 cont
= fn (w
, user_data
);
5136 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5143 /* Freeze or unfreeze the window start of W if unless it is a
5144 mini-window or the selected window. FREEZE_P non-null means freeze
5145 the window start. */
5148 freeze_window_start (w
, freeze_p
)
5152 if (w
== XWINDOW (selected_window
)
5153 || MINI_WINDOW_P (w
)
5154 || (MINI_WINDOW_P (XWINDOW (selected_window
))
5155 && ! NILP (Vminibuf_scroll_window
)
5156 && w
== XWINDOW (Vminibuf_scroll_window
)))
5159 w
->frozen_window_start_p
= freeze_p
!= NULL
;
5164 /* Freeze or unfreeze the window starts of all leaf windows on frame
5165 F, except the selected window and a mini-window. FREEZE_P non-zero
5166 means freeze the window start. */
5169 freeze_window_starts (f
, freeze_p
)
5173 foreach_window (f
, freeze_window_start
, (void *) freeze_p
);
5177 /***********************************************************************
5179 ***********************************************************************/
5181 /* Return 1 if window configurations C1 and C2
5182 describe the same state of affairs. This is used by Fequal. */
5185 compare_window_configurations (c1
, c2
, ignore_positions
)
5187 int ignore_positions
;
5189 register struct save_window_data
*d1
, *d2
;
5190 struct Lisp_Vector
*sw1
, *sw2
;
5193 if (!WINDOW_CONFIGURATIONP (c1
))
5194 wrong_type_argument (Qwindow_configuration_p
, c1
);
5195 if (!WINDOW_CONFIGURATIONP (c2
))
5196 wrong_type_argument (Qwindow_configuration_p
, c2
);
5198 d1
= (struct save_window_data
*) XVECTOR (c1
);
5199 d2
= (struct save_window_data
*) XVECTOR (c2
);
5200 sw1
= XVECTOR (d1
->saved_windows
);
5201 sw2
= XVECTOR (d2
->saved_windows
);
5203 if (! EQ (d1
->frame_width
, d2
->frame_width
))
5205 if (! EQ (d1
->frame_height
, d2
->frame_height
))
5207 if (! EQ (d1
->frame_menu_bar_lines
, d2
->frame_menu_bar_lines
))
5209 if (! EQ (d1
->selected_frame
, d2
->selected_frame
))
5211 /* Don't compare the current_window field directly.
5212 Instead see w1_is_current and w2_is_current, below. */
5213 if (! EQ (d1
->current_buffer
, d2
->current_buffer
))
5215 if (! ignore_positions
)
5216 if (! EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
))
5218 /* Don't compare the root_window field.
5219 We don't require the two configurations
5220 to use the same window object,
5221 and the two root windows must be equivalent
5222 if everything else compares equal. */
5223 if (! EQ (d1
->focus_frame
, d2
->focus_frame
))
5225 if (! EQ (d1
->min_width
, d2
->min_width
))
5227 if (! EQ (d1
->min_height
, d2
->min_height
))
5230 /* Verify that the two confis have the same number of windows. */
5231 if (sw1
->size
!= sw2
->size
)
5234 for (i
= 0; i
< sw1
->size
; i
++)
5236 struct saved_window
*p1
, *p2
;
5237 int w1_is_current
, w2_is_current
;
5239 p1
= SAVED_WINDOW_N (sw1
, i
);
5240 p2
= SAVED_WINDOW_N (sw2
, i
);
5242 /* Verify that the current windows in the two
5243 configurations correspond to each other. */
5244 w1_is_current
= EQ (d1
->current_window
, p1
->window
);
5245 w2_is_current
= EQ (d2
->current_window
, p2
->window
);
5247 if (w1_is_current
!= w2_is_current
)
5250 /* Verify that the corresponding windows do match. */
5251 if (! EQ (p1
->buffer
, p2
->buffer
))
5253 if (! EQ (p1
->left
, p2
->left
))
5255 if (! EQ (p1
->top
, p2
->top
))
5257 if (! EQ (p1
->width
, p2
->width
))
5259 if (! EQ (p1
->height
, p2
->height
))
5261 if (! EQ (p1
->display_table
, p2
->display_table
))
5263 if (! EQ (p1
->parent
, p2
->parent
))
5265 if (! EQ (p1
->prev
, p2
->prev
))
5267 if (! ignore_positions
)
5269 if (! EQ (p1
->hscroll
, p2
->hscroll
))
5271 if (! EQ (p1
->start_at_line_beg
, p2
->start_at_line_beg
))
5273 if (NILP (Fequal (p1
->start
, p2
->start
)))
5275 if (NILP (Fequal (p1
->pointm
, p2
->pointm
)))
5277 if (NILP (Fequal (p1
->mark
, p2
->mark
)))
5285 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
5286 Scompare_window_configurations
, 2, 2, 0,
5287 "Compare two window configurations as regards the structure of windows.\n\
5288 This function ignores details such as the values of point and mark\n\
5289 and scrolling positions.")
5293 if (compare_window_configurations (x
, y
, 1))
5301 struct frame
*f
= make_terminal_frame ();
5302 XSETFRAME (selected_frame
, f
);
5303 Vterminal_frame
= selected_frame
;
5304 minibuf_window
= f
->minibuffer_window
;
5305 selected_window
= f
->selected_window
;
5306 last_nonminibuf_frame
= f
;
5308 window_initialized
= 1;
5314 Vwindow_list
= Qnil
;
5320 Qleft_bitmap_area
= intern ("left-bitmap-area");
5321 staticpro (&Qleft_bitmap_area
);
5322 Qright_bitmap_area
= intern ("right-bitmap-area");
5323 staticpro (&Qright_bitmap_area
);
5325 Qwindow_size_fixed
= intern ("window-size-fixed");
5326 staticpro (&Qwindow_size_fixed
);
5328 staticpro (&Qwindow_configuration_change_hook
);
5329 Qwindow_configuration_change_hook
5330 = intern ("window-configuration-change-hook");
5332 Qwindowp
= intern ("windowp");
5333 staticpro (&Qwindowp
);
5335 Qwindow_configuration_p
= intern ("window-configuration-p");
5336 staticpro (&Qwindow_configuration_p
);
5338 Qwindow_live_p
= intern ("window-live-p");
5339 staticpro (&Qwindow_live_p
);
5341 Qtemp_buffer_show_hook
= intern ("temp-buffer-show-hook");
5342 staticpro (&Qtemp_buffer_show_hook
);
5344 staticpro (&Vwindow_list
);
5346 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
5347 "Non-nil means call as function to display a help buffer.\n\
5348 The function is called with one argument, the buffer to be displayed.\n\
5349 Used by `with-output-to-temp-buffer'.\n\
5350 If this function is used, then it must do the entire job of showing\n\
5351 the buffer; `temp-buffer-show-hook' is not run unless this function runs it.");
5352 Vtemp_buffer_show_function
= Qnil
;
5354 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
5355 "If non-nil, function to call to handle `display-buffer'.\n\
5356 It will receive two args, the buffer and a flag which if non-nil means\n\
5357 that the currently selected window is not acceptable.\n\
5358 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
5359 work using this function.");
5360 Vdisplay_buffer_function
= Qnil
;
5362 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
5363 "Non-nil means it is the window that C-M-v in minibuffer should scroll.");
5364 Vminibuf_scroll_window
= Qnil
;
5366 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
5367 "If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.");
5368 Vother_window_scroll_buffer
= Qnil
;
5370 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
5371 "*Non-nil means `display-buffer' should make a separate frame.");
5374 DEFVAR_BOOL ("display-buffer-reuse-frames", &display_buffer_reuse_frames
,
5375 "*Non-nil means `display-buffer' should reuse frames.\n\
5376 If the buffer in question is already displayed in a frame, raise that frame.");
5377 display_buffer_reuse_frames
= 0;
5379 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
5380 "Function to call to handle automatic new frame creation.\n\
5381 It is called with no arguments and should return a newly created frame.\n\
5383 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'\n\
5384 where `pop-up-frame-alist' would hold the default frame parameters.");
5385 Vpop_up_frame_function
= Qnil
;
5387 DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names
,
5388 "*List of buffer names that should have their own special frames.\n\
5389 Displaying a buffer whose name is in this list makes a special frame for it\n\
5390 using `special-display-function'. See also `special-display-regexps'.\n\
5392 An element of the list can be a list instead of just a string.\n\
5393 There are two ways to use a list as an element:\n\
5394 (BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)\n\
5395 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5396 In the latter case, FUNCTION is called with BUFFER as the first argument,\n\
5397 followed by OTHER-ARGS--it can display BUFFER in any way it likes.\n\
5398 All this is done by the function found in `special-display-function'.\n\
5400 If this variable appears \"not to work\", because you add a name to it\n\
5401 but that buffer still appears in the selected window, look at the\n\
5402 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5403 Those variables take precedence over this one.");
5404 Vspecial_display_buffer_names
= Qnil
;
5406 DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps
,
5407 "*List of regexps saying which buffers should have their own special frames.\n\
5408 If a buffer name matches one of these regexps, it gets its own frame.\n\
5409 Displaying a buffer whose name is in this list makes a special frame for it\n\
5410 using `special-display-function'.\n\
5412 An element of the list can be a list instead of just a string.\n\
5413 There are two ways to use a list as an element:\n\
5414 (REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)\n\
5415 In the first case, FRAME-PARAMETERS are used to create the frame.\n\
5416 In the latter case, FUNCTION is called with the buffer as first argument,\n\
5417 followed by OTHER-ARGS--it can display the buffer in any way it likes.\n\
5418 All this is done by the function found in `special-display-function'.\n\
5420 If this variable appears \"not to work\", because you add a regexp to it\n\
5421 but the matching buffers still appear in the selected window, look at the\n\
5422 values of `same-window-buffer-names' and `same-window-regexps'.\n\
5423 Those variables take precedence over this one.");
5424 Vspecial_display_regexps
= Qnil
;
5426 DEFVAR_LISP ("special-display-function", &Vspecial_display_function
,
5427 "Function to call to make a new frame for a special buffer.\n\
5428 It is called with two arguments, the buffer and optional buffer specific\n\
5429 data, and should return a window displaying that buffer.\n\
5430 The default value makes a separate frame for the buffer,\n\
5431 using `special-display-frame-alist' to specify the frame parameters.\n\
5433 A buffer is special if its is listed in `special-display-buffer-names'\n\
5434 or matches a regexp in `special-display-regexps'.");
5435 Vspecial_display_function
= Qnil
;
5437 DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names
,
5438 "*List of buffer names that should appear in the selected window.\n\
5439 Displaying one of these buffers using `display-buffer' or `pop-to-buffer'\n\
5440 switches to it in the selected window, rather than making it appear\n\
5441 in some other window.\n\
5443 An element of the list can be a cons cell instead of just a string.\n\
5444 Then the car must be a string, which specifies the buffer name.\n\
5445 This is for compatibility with `special-display-buffer-names';\n\
5446 the cdr of the cons cell is ignored.\n\
5448 See also `same-window-regexps'.");
5449 Vsame_window_buffer_names
= Qnil
;
5451 DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps
,
5452 "*List of regexps saying which buffers should appear in the selected window.\n\
5453 If a buffer name matches one of these regexps, then displaying it\n\
5454 using `display-buffer' or `pop-to-buffer' switches to it\n\
5455 in the selected window, rather than making it appear in some other window.\n\
5457 An element of the list can be a cons cell instead of just a string.\n\
5458 Then the car must be a string, which specifies the buffer name.\n\
5459 This is for compatibility with `special-display-buffer-names';\n\
5460 the cdr of the cons cell is ignored.\n\
5462 See also `same-window-buffer-names'.");
5463 Vsame_window_regexps
= Qnil
;
5465 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
5466 "*Non-nil means display-buffer should make new windows.");
5469 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
5470 "*Number of lines of continuity when scrolling by screenfuls.");
5471 next_screen_context_lines
= 2;
5473 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
5474 "*display-buffer would prefer to split the largest window if this large.\n\
5475 If there is only one window, it is split regardless of this value.");
5476 split_height_threshold
= 500;
5478 DEFVAR_INT ("window-min-height", &window_min_height
,
5479 "*Delete any window less than this tall (including its mode line).");
5480 window_min_height
= 4;
5482 DEFVAR_INT ("window-min-width", &window_min_width
,
5483 "*Delete any window less than this wide.");
5484 window_min_width
= 10;
5486 DEFVAR_LISP ("scroll-preserve-screen-position",
5487 &Vscroll_preserve_screen_position
,
5488 "*Nonzero means scroll commands move point to keep its screen line unchanged.");
5489 Vscroll_preserve_screen_position
= Qnil
;
5491 DEFVAR_LISP ("window-configuration-change-hook",
5492 &Vwindow_configuration_change_hook
,
5493 "Functions to call when window configuration changes.\n\
5494 The selected frame is the one whose configuration has changed.");
5495 Vwindow_configuration_change_hook
= Qnil
;
5497 defsubr (&Sselected_window
);
5498 defsubr (&Sminibuffer_window
);
5499 defsubr (&Swindow_minibuffer_p
);
5500 defsubr (&Swindowp
);
5501 defsubr (&Swindow_live_p
);
5502 defsubr (&Spos_visible_in_window_p
);
5503 defsubr (&Swindow_buffer
);
5504 defsubr (&Swindow_height
);
5505 defsubr (&Swindow_width
);
5506 defsubr (&Swindow_hscroll
);
5507 defsubr (&Sset_window_hscroll
);
5508 defsubr (&Swindow_redisplay_end_trigger
);
5509 defsubr (&Sset_window_redisplay_end_trigger
);
5510 defsubr (&Swindow_edges
);
5511 defsubr (&Scoordinates_in_window_p
);
5512 defsubr (&Swindow_at
);
5513 defsubr (&Swindow_point
);
5514 defsubr (&Swindow_start
);
5515 defsubr (&Swindow_end
);
5516 defsubr (&Sset_window_point
);
5517 defsubr (&Sset_window_start
);
5518 defsubr (&Swindow_dedicated_p
);
5519 defsubr (&Sset_window_dedicated_p
);
5520 defsubr (&Swindow_display_table
);
5521 defsubr (&Sset_window_display_table
);
5522 defsubr (&Snext_window
);
5523 defsubr (&Sprevious_window
);
5524 defsubr (&Sother_window
);
5525 defsubr (&Sget_lru_window
);
5526 defsubr (&Sget_largest_window
);
5527 defsubr (&Sget_buffer_window
);
5528 defsubr (&Sdelete_other_windows
);
5529 defsubr (&Sdelete_windows_on
);
5530 defsubr (&Sreplace_buffer_in_windows
);
5531 defsubr (&Sdelete_window
);
5532 defsubr (&Sset_window_buffer
);
5533 defsubr (&Sselect_window
);
5534 defsubr (&Sspecial_display_p
);
5535 defsubr (&Ssame_window_p
);
5536 defsubr (&Sdisplay_buffer
);
5537 defsubr (&Ssplit_window
);
5538 defsubr (&Senlarge_window
);
5539 defsubr (&Sshrink_window
);
5540 defsubr (&Sscroll_up
);
5541 defsubr (&Sscroll_down
);
5542 defsubr (&Sscroll_left
);
5543 defsubr (&Sscroll_right
);
5544 defsubr (&Sother_window_for_scrolling
);
5545 defsubr (&Sscroll_other_window
);
5546 defsubr (&Srecenter
);
5547 defsubr (&Smove_to_window_line
);
5548 defsubr (&Swindow_configuration_p
);
5549 defsubr (&Swindow_configuration_frame
);
5550 defsubr (&Sset_window_configuration
);
5551 defsubr (&Scurrent_window_configuration
);
5552 defsubr (&Ssave_window_excursion
);
5553 defsubr (&Sset_window_margins
);
5554 defsubr (&Swindow_margins
);
5555 defsubr (&Swindow_vscroll
);
5556 defsubr (&Sset_window_vscroll
);
5557 defsubr (&Scompare_window_configurations
);
5558 defsubr (&Swindow_list
);
5564 initial_define_key (control_x_map
, '1', "delete-other-windows");
5565 initial_define_key (control_x_map
, '2', "split-window");
5566 initial_define_key (control_x_map
, '0', "delete-window");
5567 initial_define_key (control_x_map
, 'o', "other-window");
5568 initial_define_key (control_x_map
, '^', "enlarge-window");
5569 initial_define_key (control_x_map
, '<', "scroll-left");
5570 initial_define_key (control_x_map
, '>', "scroll-right");
5572 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
5573 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
5574 initial_define_key (meta_map
, 'v', "scroll-down");
5576 initial_define_key (global_map
, Ctl('L'), "recenter");
5577 initial_define_key (meta_map
, 'r', "move-to-window-line");