1 /* Window creation, deletion and examination for GNU Emacs.
2 Does not include redisplay.
3 Copyright (C) 1985, 1986, 1987, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
32 Lisp_Object Qwindowp
, Qlive_window_p
;
34 Lisp_Object
Fnext_window (), Fdelete_window (), Fselect_window ();
35 Lisp_Object
Fset_window_buffer (), Fsplit_window (), Frecenter ();
37 void delete_all_subwindows ();
38 static struct window
*decode_window();
40 /* This is the window in which the terminal's cursor should
41 be left when nothing is being done with it. This must
42 always be a leaf window, and its buffer is selected by
43 the top level editing loop at the end of each command.
45 This value is always the same as
46 FRAME_SELECTED_WINDOW (selected_frame). */
48 Lisp_Object selected_window
;
50 /* The minibuffer window of the selected frame.
51 Note that you cannot test for minibufferness of an arbitrary window
52 by comparing against this; but you can test for minibufferness of
53 the selected window. */
54 Lisp_Object minibuf_window
;
56 /* Non-nil means it is the window for C-M-v to scroll
57 when the minibuffer is selected. */
58 Lisp_Object Vminibuf_scroll_window
;
60 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
61 Lisp_Object Vother_window_scroll_buffer
;
63 /* Window that the mouse is over (nil if no mouse support). */
64 Lisp_Object Vmouse_window
;
66 /* Last mouse click data structure (nil if no mouse support). */
67 Lisp_Object Vmouse_event
;
69 /* Non-nil means it's function to call to display temp buffers. */
70 Lisp_Object Vtemp_buffer_show_function
;
72 /* If a window gets smaller than either of these, it is removed. */
73 int window_min_height
;
76 /* Nonzero implies Fdisplay_buffer should create windows. */
79 /* Nonzero implies make new frames for Fdisplay_buffer. */
82 /* Non-nil means use this function instead of default */
83 Lisp_Object Vpop_up_frame_function
;
85 /* Function to call to handle Fdisplay_buffer. */
86 Lisp_Object Vdisplay_buffer_function
;
88 /* Fdisplay_buffer always splits the largest window
89 if that window is more than this high. */
90 int split_height_threshold
;
92 /* Number of lines of continuity in scrolling by screenfuls. */
93 int next_screen_context_lines
;
95 /* Incremented for each window created. */
96 static int sequence_number
;
98 #define min(a, b) ((a) < (b) ? (a) : (b))
100 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
101 "Returns t if OBJ is a window.")
105 return XTYPE (obj
) == Lisp_Window
? Qt
: Qnil
;
108 DEFUN ("live-window-p", Flive_window_p
, Slive_window_p
, 1, 1, 0,
109 "Returns t if OBJ is a window which is currently visible.")
113 return ((XTYPE (obj
) == Lisp_Window
114 && ! NILP (XWINDOW (obj
)->buffer
))
121 register Lisp_Object val
;
122 register struct window
*p
;
124 /* Add sizeof (Lisp_Object) here because sizeof (struct Lisp_Vector)
125 includes the first element. */
127 make_number ((sizeof (struct window
) - sizeof (struct Lisp_Vector
)
128 + sizeof (Lisp_Object
))
129 / sizeof (Lisp_Object
)),
131 XSETTYPE (val
, Lisp_Window
);
133 XFASTINT (p
->sequence_number
) = ++sequence_number
;
134 XFASTINT (p
->left
) = XFASTINT (p
->top
)
135 = XFASTINT (p
->height
) = XFASTINT (p
->width
)
136 = XFASTINT (p
->hscroll
) = 0;
137 XFASTINT (p
->last_point_x
) = XFASTINT (p
->last_point_y
) = 0;
138 p
->start
= Fmake_marker ();
139 p
->pointm
= Fmake_marker ();
140 XFASTINT (p
->use_time
) = 0;
142 p
->display_table
= Qnil
;
147 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
148 "Return the window that the cursor now appears in and commands apply to.")
151 return selected_window
;
154 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
155 "Return the window used now for minibuffers.\n\
156 If the optional argument FRAME is specified, return the minibuffer window\n\
157 used by that frame.")
163 XSET (frame
, Lisp_Frame
, selected_frame
);
165 CHECK_LIVE_FRAME (frame
, 0);
168 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
171 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 0, 1, 0,
172 "Returns non-nil if WINDOW is a minibuffer window.")
176 struct window
*w
= decode_window (window
);
177 return (MINI_WINDOW_P (w
) ? Qt
: Qnil
);
180 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
181 Spos_visible_in_window_p
, 0, 2, 0,
182 "Return t if position POS is currently on the frame in WINDOW.\n\
183 Returns nil if that position is scrolled vertically out of view.\n\
184 POS defaults to point; WINDOW, to the selected window.")
186 Lisp_Object pos
, window
;
188 register struct window
*w
;
192 register struct buffer
*buf
;
193 struct position posval
;
199 CHECK_NUMBER_COERCE_MARKER (pos
, 0);
203 w
= decode_window (window
);
204 top
= marker_position (w
->start
);
209 height
= XFASTINT (w
->height
) - ! MINI_WINDOW_P (w
);
211 buf
= XBUFFER (w
->buffer
);
212 if (XFASTINT (w
->last_modified
) >= BUF_MODIFF (buf
))
214 /* If frame is up to date,
215 use the info recorded about how much text fit on it. */
216 if (posint
< BUF_Z (buf
) - XFASTINT (w
->window_end_pos
)
217 || (XFASTINT (w
->window_end_vpos
) < height
))
223 if (posint
> BUF_Z (buf
))
226 /* If that info is not correct, calculate afresh */
227 posval
= *compute_motion (top
, 0, 0, posint
, height
, 0,
228 XFASTINT (w
->width
) - 1
229 - (XFASTINT (w
->width
) + XFASTINT (w
->left
)
230 != FRAME_WIDTH (XFRAME (w
->frame
))),
231 XINT (w
->hscroll
), 0);
233 return posval
.vpos
< height
? Qt
: Qnil
;
237 static struct window
*
238 decode_window (window
)
239 register Lisp_Object window
;
242 return XWINDOW (selected_window
);
244 CHECK_LIVE_WINDOW (window
, 0);
245 return XWINDOW (window
);
248 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
249 "Return the buffer that WINDOW is displaying.")
253 return decode_window (window
)->buffer
;
256 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
257 "Return the number of lines in WINDOW (including its mode line).")
261 return decode_window (window
)->height
;
264 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
265 "Return the number of columns in WINDOW.")
269 register struct window
*w
= decode_window (window
);
270 register int width
= XFASTINT (w
->width
);
272 /* If this window does not end at the right margin,
273 must deduct one column for the border */
274 if ((width
+ XFASTINT (w
->left
)) == FRAME_WIDTH (XFRAME (WINDOW_FRAME (w
))))
275 return make_number (width
);
276 return make_number (width
- 1);
279 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
280 "Return the number of columns by which WINDOW is scrolled from left margin.")
284 return decode_window (window
)->hscroll
;
287 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
288 "Set number of columns WINDOW is scrolled from left margin to NCOL.\n\
289 NCOL should be zero or positive.")
291 register Lisp_Object window
, ncol
;
293 register struct window
*w
;
295 CHECK_NUMBER (ncol
, 1);
296 if (XINT (ncol
) < 0) XFASTINT (ncol
) = 0;
297 if (XFASTINT (ncol
) >= (1 << (SHORTBITS
- 1)))
298 args_out_of_range (ncol
, Qnil
);
299 w
= decode_window (window
);
300 if (XINT (w
->hscroll
) != XINT (ncol
))
301 clip_changed
= 1; /* Prevent redisplay shortcuts */
306 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
307 "Return a list of the edge coordinates of WINDOW.\n\
308 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of frame.\n\
309 RIGHT is one more than the rightmost column used by WINDOW,\n\
310 and BOTTOM is one more than the bottommost row used by WINDOW\n\
315 register struct window
*w
= decode_window (window
);
317 return Fcons (w
->left
, Fcons (w
->top
,
318 Fcons (make_number (XFASTINT (w
->left
) + XFASTINT (w
->width
)),
319 Fcons (make_number (XFASTINT (w
->top
)
320 + XFASTINT (w
->height
)),
324 /* Test if the character at column *x, row *y is within window *w.
325 If it is not, return 0;
326 if it is in the window's text area,
327 set *x and *y to its location relative to the upper left corner
330 if it is on the window's modeline, return 2;
331 if it is on the border between the window and its right sibling,
334 coordinates_in_window (w
, x
, y
)
335 register struct window
*w
;
338 register int left
= XINT (w
->left
);
339 register int width
= XINT (w
->width
);
340 register int window_height
= XINT (w
->height
);
341 register int top
= XFASTINT (w
->top
);
343 if ( *x
< left
|| *x
>= left
+ width
344 || *y
< top
|| *y
>= top
+ window_height
)
347 /* Is the character is the mode line? */
348 if (*y
== top
+ window_height
- 1
349 && ! MINI_WINDOW_P (w
))
352 /* Is the character in the right border? */
353 if (*x
== left
+ width
- 1
354 && left
+ width
!= FRAME_WIDTH (XFRAME (w
->frame
)))
362 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
363 Scoordinates_in_window_p
, 2, 2, 0,
364 "Return non-nil if COORDINATES are in WINDOW.\n\
365 COORDINATES is a cons of the form (X . Y), X and Y being distances\n\
366 measured in characters from the upper-left corner of the frame.\n\
367 (0 . 0) denotes the character in the upper left corner of the\n\
369 If COORDINATES are in the text portion of WINDOW,\n\
370 the coordinates relative to the window are returned.\n\
371 If they are in the mode line of WINDOW, `mode-line' is returned.\n\
372 If they are on the border between WINDOW and its right sibling,\n\
373 `vertical-line' is returned.")
374 (coordinates
, window
)
375 register Lisp_Object coordinates
, window
;
379 CHECK_LIVE_WINDOW (window
, 0);
380 CHECK_CONS (coordinates
, 1);
381 x
= XINT (Fcar (coordinates
));
382 y
= XINT (Fcdr (coordinates
));
384 switch (coordinates_in_window (XWINDOW (window
), &x
, &y
))
386 case 0: /* NOT in window at all. */
389 case 1: /* In text part of window. */
392 case 2: /* In mode line of window. */
395 case 3: /* On right border of window. */
396 return Qvertical_line
;
403 /* Find the window containing column x, row y, and return it as a
404 Lisp_Object. If x, y is on the window's modeline, set *part
405 to 1; if it is on the separating line between the window and its
406 right sibling, set it to 2; otherwise set it to 0. If there is no
407 window under x, y return nil and leave *part unmodified. */
409 window_from_coordinates (frame
, x
, y
, part
)
414 register Lisp_Object tem
, first
;
416 tem
= first
= FRAME_SELECTED_WINDOW (frame
);
420 int found
= coordinates_in_window (XWINDOW (tem
), &x
, &y
);
428 tem
= Fnext_window (tem
, Qt
, Qlambda
);
430 while (! EQ (tem
, first
));
435 /* Find the window containing the scrollbar BAR on FRAME. We need to
436 search for scrollbars, rather than just having a field in the
437 scrollbar saying what window it's attached to, because scrollbars
438 may be deallocated before the events which occurred on them are
439 dequeued. We can't dereference a scrollbar pointer until we know
440 it's live by finding it in a window structure. */
443 window_from_scrollbar (frame
, bar
)
445 struct scrollbar
*bar
;
447 register Lisp_Object tem
, first
;
449 tem
= first
= FRAME_SELECTED_WINDOW (frame
);
453 if (WINDOW_VERTICAL_SCROLLBAR (XWINDOW (tem
)) == bar
)
456 tem
= Fnext_window (tem
, Qt
, Qlambda
);
458 while (! EQ (tem
, first
));
463 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
464 "Return window containing row ROW, column COLUMN on FRAME.\n\
465 If omitted, FRAME defaults to the currently selected frame.\n\
466 The top left corner of the frame is considered to be row 0,\n\
469 Lisp_Object row
, column
, frame
;
475 XSET (frame
, Lisp_Frame
, selected_frame
);
477 CHECK_LIVE_FRAME (frame
, 2);
479 CHECK_NUMBER (row
, 0);
480 CHECK_NUMBER (column
, 1);
482 return window_from_coordinates (XFRAME (frame
),
483 XINT (row
), XINT (column
),
487 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
488 "Return current value of point in WINDOW.\n\
489 For a nonselected window, this is the value point would have\n\
490 if that window were selected.\n\
492 Note that, when WINDOW is the selected window and its buffer\n\
493 is also currently selected, the value returned is the same as (point).\n\
494 It would be more strictly correct to return the `top-level' value\n\
495 of point, outside of any save-excursion forms.\n\
496 But that is hard to define.")
500 register struct window
*w
= decode_window (window
);
502 if (w
== XWINDOW (selected_window
)
503 && current_buffer
== XBUFFER (w
->buffer
))
505 return Fmarker_position (w
->pointm
);
508 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
509 "Return position at which display currently starts in WINDOW.")
513 return Fmarker_position (decode_window (window
)->start
);
516 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 1, 0,
517 "Return position at which display currently ends in WINDOW.")
522 struct window
*w
= decode_window (window
);
524 XSET (value
, Lisp_Int
,
525 BUF_Z (current_buffer
) - XFASTINT (w
->window_end_pos
));
530 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
531 "Make point value in WINDOW be at position POS in WINDOW's buffer.")
533 Lisp_Object window
, pos
;
535 register struct window
*w
= decode_window (window
);
537 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
538 if (w
== XWINDOW (selected_window
))
541 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
546 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
547 "Make display in WINDOW start at position POS in WINDOW's buffer.\n\
548 Optional third arg NOFORCE non-nil inhibits next redisplay\n\
549 from overriding motion of point in order to display at this exact start.")
550 (window
, pos
, noforce
)
551 Lisp_Object window
, pos
, noforce
;
553 register struct window
*w
= decode_window (window
);
555 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
556 set_marker_restricted (w
->start
, pos
, w
->buffer
);
557 /* this is not right, but much easier than doing what is right. */
558 w
->start_at_line_beg
= Qnil
;
561 w
->update_mode_line
= Qt
;
562 XFASTINT (w
->last_modified
) = 0;
563 if (!EQ (window
, selected_window
))
564 windows_or_buffers_changed
++;
568 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
570 "Return WINDOW's dedicated object, usually t or nil.\n\
571 See also `set-window-buffer-dedicated'.")
575 return decode_window (window
)->dedicated
;
578 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
579 Sset_window_dedicated_p
, 2, 2, 0,
580 "Control whether WINDOW is dedicated to the buffer it displays.\n\
581 If it is dedicated, Emacs will not automatically change\n\
582 which buffer appears in it.\n\
583 The second argument is the new value for the dedication flag;\n\
586 Lisp_Object window
, arg
;
588 register struct window
*w
= decode_window (window
);
598 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
600 "Return the display-table that WINDOW is using.")
604 return decode_window (window
)->display_table
;
607 /* Get the display table for use currently on window W.
608 This is either W's display table or W's buffer's display table.
609 Ignore the specified tables if they are not valid;
610 if no valid table is specified, return 0. */
613 window_display_table (w
)
617 tem
= w
->display_table
;
618 if (XTYPE (tem
) == Lisp_Vector
&& XVECTOR (tem
)->size
== DISP_TABLE_SIZE
)
619 return XVECTOR (tem
);
620 tem
= XBUFFER (w
->buffer
)->display_table
;
621 if (XTYPE (tem
) == Lisp_Vector
&& XVECTOR (tem
)->size
== DISP_TABLE_SIZE
)
622 return XVECTOR (tem
);
623 tem
= Vstandard_display_table
;
624 if (XTYPE (tem
) == Lisp_Vector
&& XVECTOR (tem
)->size
== DISP_TABLE_SIZE
)
625 return XVECTOR (tem
);
629 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
630 "Set WINDOW's display-table to TABLE.")
632 register Lisp_Object window
, table
;
634 register struct window
*w
;
635 register Lisp_Object z
; /* Return value. */
637 w
= decode_window (window
);
638 w
->display_table
= table
;
642 /* Record info on buffer window w is displaying
643 when it is about to cease to display that buffer. */
646 register struct window
*w
;
648 Lisp_Object buf
= w
->buffer
;
650 if (XBUFFER (buf
) != XMARKER (w
->pointm
)->buffer
)
653 if (w
== XWINDOW (selected_window
)
654 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
655 /* Do this except when the selected window's buffer
656 is being removed from some other window. */
657 XBUFFER (buf
)->last_window_start
= marker_position (w
->start
);
659 /* Point in the selected window's buffer
660 is actually stored in that buffer, and the window's pointm isn't used.
661 So don't clobber point in that buffer. */
662 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
))
663 BUF_PT (XBUFFER (buf
))
664 = clip_to_bounds (BUF_BEGV (XBUFFER (buf
)),
665 marker_position (w
->pointm
),
666 BUF_ZV (XBUFFER (buf
)));
669 /* Put replacement into the window structure in place of old. */
671 replace_window (old
, replacement
)
672 Lisp_Object old
, replacement
;
674 register Lisp_Object tem
;
675 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
677 /* If OLD is its frame's root_window, then replacement is the new
678 root_window for that frame. */
680 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
681 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
686 p
->height
= o
->height
;
688 p
->next
= tem
= o
->next
;
690 XWINDOW (tem
)->prev
= replacement
;
692 p
->prev
= tem
= o
->prev
;
694 XWINDOW (tem
)->next
= replacement
;
696 p
->parent
= tem
= o
->parent
;
699 if (EQ (XWINDOW (tem
)->vchild
, old
))
700 XWINDOW (tem
)->vchild
= replacement
;
701 if (EQ (XWINDOW (tem
)->hchild
, old
))
702 XWINDOW (tem
)->hchild
= replacement
;
705 /*** Here, if replacement is a vertical combination
706 and so is its new parent, we should make replacement's
707 children be children of that parent instead. ***/
710 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
711 "Remove WINDOW from the display. Default is selected window.")
713 register Lisp_Object window
;
715 register Lisp_Object tem
, parent
, sib
;
716 register struct window
*p
;
717 register struct window
*par
;
719 /* Because this function is called by other C code on non-leaf
720 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
721 so we can't decode_window here. */
723 window
= selected_window
;
725 CHECK_WINDOW (window
, 0);
726 p
= XWINDOW (window
);
728 /* It's okay to delete an already-deleted window. */
736 error ("Attempt to delete minibuffer or sole ordinary window");
737 par
= XWINDOW (parent
);
739 windows_or_buffers_changed
++;
741 /* Are we trying to delete any frame's selected window? */
743 Lisp_Object frame
= WINDOW_FRAME (XWINDOW (window
));
745 if (EQ (window
, FRAME_SELECTED_WINDOW (XFRAME (frame
))))
747 Lisp_Object alternative
= Fnext_window (window
, Qlambda
, Qnil
);
749 /* If we're about to delete the selected window on the
750 selected frame, then we should use Fselect_window to select
751 the new window. On the other hand, if we're about to
752 delete the selected window on any other frame, we shouldn't do
753 anything but set the frame's selected_window slot. */
754 if (EQ (window
, selected_window
))
755 Fselect_window (alternative
);
757 FRAME_SELECTED_WINDOW (XFRAME (frame
)) = alternative
;
762 /* tem is null for dummy parent windows
763 (which have inferiors but not any contents themselves) */
767 unchain_marker (p
->pointm
);
768 unchain_marker (p
->start
);
773 XWINDOW (tem
)->prev
= p
->prev
;
777 XWINDOW (tem
)->next
= p
->next
;
779 if (EQ (window
, par
->hchild
))
780 par
->hchild
= p
->next
;
781 if (EQ (window
, par
->vchild
))
782 par
->vchild
= p
->next
;
784 /* Find one of our siblings to give our space to. */
788 /* If p gives its space to its next sibling, that sibling needs
789 to have its top/left side pulled back to where p's is.
790 set_window_{height,width} will re-position the sibling's
793 XWINDOW (sib
)->top
= p
->top
;
794 XWINDOW (sib
)->left
= p
->left
;
797 /* Stretch that sibling. */
798 if (!NILP (par
->vchild
))
799 set_window_height (sib
,
800 XFASTINT (XWINDOW (sib
)->height
) + XFASTINT (p
->height
),
802 if (!NILP (par
->hchild
))
803 set_window_width (sib
,
804 XFASTINT (XWINDOW (sib
)->width
) + XFASTINT (p
->width
),
807 /* If parent now has only one child,
808 put the child into the parent's place. */
812 if (NILP (XWINDOW (tem
)->next
))
813 replace_window (parent
, tem
);
815 /* Since we may be deleting combination windows, we must make sure that
816 not only p but all its children have been marked as deleted. */
817 if (! NILP (p
->hchild
))
818 delete_all_subwindows (XWINDOW (p
->hchild
));
819 else if (! NILP (p
->vchild
))
820 delete_all_subwindows (XWINDOW (p
->vchild
));
822 /* Mark this window as deleted. */
823 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
829 extern Lisp_Object
next_frame (), prev_frame ();
831 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
832 "Return next window after WINDOW in canonical ordering of windows.\n\
833 If omitted, WINDOW defaults to the selected window.\n\
835 Optional second arg MINIBUF t means count the minibuffer window even\n\
836 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
837 it is active. MINIBUF neither t nor nil means not to count the\n\
838 minibuffer even if it is active.\n\
840 Several frames may share a single minibuffer; if the minibuffer\n\
841 counts, all windows on all frames that share that minibuffer count\n\
842 too. This means that next-window may be used to iterate through the\n\
843 set of windows even when the minibuffer is on another frame. If the\n\
844 minibuffer does not count, only windows from WINDOW's frame count.\n\
846 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
847 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
848 above. If neither nil nor t, restrict to WINDOW's frame.")
849 (window
, minibuf
, all_frames
)
850 register Lisp_Object window
, minibuf
, all_frames
;
852 register Lisp_Object tem
;
853 Lisp_Object start_window
;
856 window
= selected_window
;
858 CHECK_LIVE_WINDOW (window
, 0);
860 start_window
= window
;
862 /* minibuf == nil may or may not include minibuffers.
863 Decide if it does. */
865 minibuf
= (minibuf_level
? Qt
: Qlambda
);
867 /* all_frames == nil doesn't specify which frames to include.
868 Decide which frames it includes. */
869 if (NILP (all_frames
))
870 all_frames
= (EQ (minibuf
, Qt
)
871 ? (FRAME_MINIBUF_WINDOW
874 (XWINDOW (window
)))))
876 else if (! EQ (all_frames
, Qt
))
879 /* Do this loop at least once, to get the next window, and perhaps
880 again, if we hit the minibuffer and that is not acceptable. */
883 /* Find a window that actually has a next one. This loop
884 climbs up the tree. */
885 while (tem
= XWINDOW (window
)->next
, NILP (tem
))
886 if (tem
= XWINDOW (window
)->parent
, !NILP (tem
))
890 /* We've reached the end of this frame.
891 Which other frames are acceptable? */
892 tem
= WINDOW_FRAME (XWINDOW (window
));
894 if (! NILP (all_frames
))
895 tem
= next_frame (tem
, all_frames
);
897 tem
= FRAME_ROOT_WINDOW (XFRAME (tem
));
904 /* If we're in a combination window, find its first child and
905 recurse on that. Otherwise, we've found the window we want. */
908 if (!NILP (XWINDOW (window
)->hchild
))
909 window
= XWINDOW (window
)->hchild
;
910 else if (!NILP (XWINDOW (window
)->vchild
))
911 window
= XWINDOW (window
)->vchild
;
915 /* Which windows are acceptible?
916 Exit the loop and accept this window if
917 this isn't a minibuffer window, or
918 we're accepting minibuffer windows, or
919 we've come all the way around and we're back at the original window. */
920 while (MINI_WINDOW_P (XWINDOW (window
))
921 && ! EQ (minibuf
, Qt
)
922 && ! EQ (window
, start_window
));
927 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
928 "Return the window preceeding WINDOW in canonical ordering of windows.\n\
929 If omitted, WINDOW defaults to the selected window.\n\
931 Optional second arg MINIBUF t means count the minibuffer window even\n\
932 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
933 it is active. MINIBUF neither t nor nil means not to count the\n\
934 minibuffer even if it is active.\n\
936 Several frames may share a single minibuffer; if the minibuffer\n\
937 counts, all windows on all frames that share that minibuffer count\n\
938 too. This means that previous-window may be used to iterate through\n\
939 the set of windows even when the minibuffer is on another frame. If\n\
940 the minibuffer does not count, only windows from WINDOW's frame\n\
943 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
944 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
945 above. If neither nil nor t, restrict to WINDOW's frame.")
946 (window
, minibuf
, all_frames
)
947 register Lisp_Object window
, minibuf
, all_frames
;
949 register Lisp_Object tem
;
950 Lisp_Object start_window
;
953 window
= selected_window
;
955 CHECK_LIVE_WINDOW (window
, 0);
957 start_window
= window
;
959 /* minibuf == nil may or may not include minibuffers.
960 Decide if it does. */
962 minibuf
= (minibuf_level
? Qt
: Qlambda
);
964 /* all_frames == nil doesn't specify which frames to include.
965 Decide which frames it includes. */
966 if (NILP (all_frames
))
967 all_frames
= (EQ (minibuf
, Qt
)
968 ? (FRAME_MINIBUF_WINDOW
971 (XWINDOW (window
)))))
973 else if (! EQ (all_frames
, Qt
))
976 /* Do this loop at least once, to get the previous window, and perhaps
977 again, if we hit the minibuffer and that is not acceptable. */
980 /* Find a window that actually has a previous one. This loop
981 climbs up the tree. */
982 while (tem
= XWINDOW (window
)->prev
, NILP (tem
))
983 if (tem
= XWINDOW (window
)->parent
, !NILP (tem
))
987 /* We have found the top window on the frame.
988 Which frames are acceptable? */
989 tem
= WINDOW_FRAME (XWINDOW (window
));
991 if (! NILP (all_frames
))
992 tem
= next_frame (tem
, all_frames
);
994 tem
= FRAME_ROOT_WINDOW (XFRAME (tem
));
1000 /* If we're in a combination window, find its last child and
1001 recurse on that. Otherwise, we've found the window we want. */
1004 if (!NILP (XWINDOW (window
)->hchild
))
1005 window
= XWINDOW (window
)->hchild
;
1006 else if (!NILP (XWINDOW (window
)->vchild
))
1007 window
= XWINDOW (window
)->vchild
;
1009 while (tem
= XWINDOW (window
)->next
, !NILP (tem
))
1013 /* Which windows are acceptable?
1014 Exit the loop and accept this window if
1015 this isn't a minibuffer window, or
1016 we're accepting minibuffer windows, or
1017 we've come all the way around and we're back at the original window. */
1018 while (MINI_WINDOW_P (XWINDOW (window
))
1019 && !EQ (minibuf
, Qt
)
1020 && !EQ (window
, start_window
));
1025 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
1026 "Select the ARG'th different window on this frame.\n\
1027 All windows on current frame are arranged in a cyclic order.\n\
1028 This command selects the window ARG steps away in that order.\n\
1029 A negative ARG moves in the opposite order. If the optional second\n\
1030 argument ALL_FRAMES is non-nil, cycle through all frames.")
1032 register Lisp_Object n
, all_frames
;
1035 register Lisp_Object w
;
1037 CHECK_NUMBER (n
, 0);
1038 w
= selected_window
;
1043 w
= Fnext_window (w
, Qnil
, all_frames
);
1048 w
= Fprevious_window (w
, Qnil
, all_frames
);
1055 /* Look at all windows, performing an operation specified by TYPE
1057 If FRAMES is Qt, look at all frames, if Qnil, look at just the selected
1058 frame. If FRAMES is a frame, just look at windows on that frame.
1059 If MINI is non-zero, perform the operation on minibuffer windows too.
1065 GET_BUFFER_WINDOW
, /* Arg is buffer */
1066 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1067 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1068 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1070 UNSHOW_BUFFER
, /* Arg is buffer */
1074 window_loop (type
, obj
, mini
, frames
)
1075 enum window_loop type
;
1076 register Lisp_Object obj
, frames
;
1079 register Lisp_Object w
;
1080 register Lisp_Object best_window
;
1081 register Lisp_Object next_window
;
1082 register Lisp_Object last_window
;
1086 /* If we're only looping through windows on a particular frame,
1087 frame points to that frame. If we're looping through windows
1088 on all frames, frame is 0. */
1089 if (FRAMEP (frames
))
1090 frame
= XFRAME (frames
);
1091 else if (NILP (frames
))
1092 frame
= selected_frame
;
1099 /* Pick a window to start with. */
1100 if (XTYPE (obj
) == Lisp_Window
)
1103 w
= FRAME_SELECTED_WINDOW (frame
);
1105 w
= FRAME_SELECTED_WINDOW (selected_frame
);
1107 /* Figure out the last window we're going to mess with. Since
1108 Fnext_window, given the same options, is guaranteed to go in a
1109 ring, we can just use Fprevious_window to find the last one.
1111 We can't just wait until we hit the first window again, because
1112 it might be deleted. */
1116 last_window
= Fprevious_window (w
, (mini
? Qt
: Qnil
), Qlambda
);
1118 #endif /* MULTI_FRAME */
1119 /* We know frame is 0, so we're looping through all frames.
1120 Or we know this isn't a MULTI_FRAME Emacs, so who cares? */
1121 last_window
= Fprevious_window (w
, mini
? Qt
: Qnil
, Qt
);
1126 /* Pick the next window now, since some operations will delete
1127 the current window. */
1130 next_window
= Fnext_window (w
, (mini
? Qt
: Qnil
), Qlambda
);
1132 #endif /* MULTI_FRAME */
1133 /* We know frame is 0, so we're looping through all frames.
1134 Or we know this isn't a MULTI_FRAME Emacs, so who cares? */
1135 next_window
= Fnext_window (w
, mini
? Qt
: Qnil
, Qt
);
1137 if (!MINI_WINDOW_P (XWINDOW (w
))
1138 || (mini
&& minibuf_level
> 0))
1141 case GET_BUFFER_WINDOW
:
1143 /* Ignore invisible and iconified frames. */
1144 if (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (w
))))
1145 || FRAME_ICONIFIED_P (XFRAME (WINDOW_FRAME (XWINDOW (w
)))))
1148 if (XBUFFER (XWINDOW (w
)->buffer
) == XBUFFER (obj
))
1152 case GET_LRU_WINDOW
:
1153 /* t as arg means consider only full-width windows */
1154 if (!NILP (obj
) && XFASTINT (XWINDOW (w
)->width
)
1155 != FRAME_WIDTH (frame
))
1158 /* Ignore invisible and iconified frames. */
1159 if (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (w
))))
1160 || FRAME_ICONIFIED_P (XFRAME (WINDOW_FRAME (XWINDOW (w
)))))
1163 /* Ignore dedicated windows and minibuffers. */
1164 if (MINI_WINDOW_P (XWINDOW (w
))
1165 || !NILP (XWINDOW (w
)->dedicated
))
1167 if (NILP (best_window
)
1168 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1169 > XFASTINT (XWINDOW (w
)->use_time
)))
1173 case DELETE_OTHER_WINDOWS
:
1174 if (XWINDOW (w
) != XWINDOW (obj
))
1178 case DELETE_BUFFER_WINDOWS
:
1179 if (EQ (XWINDOW (w
)->buffer
, obj
))
1181 /* If we're deleting the buffer displayed in the only window
1182 on the frame, find a new buffer to display there. */
1183 if (NILP (XWINDOW (w
)->parent
))
1185 Lisp_Object new_buffer
= Fother_buffer (obj
, Qnil
);
1186 if (NILP (new_buffer
))
1188 = Fget_buffer_create (build_string ("*scratch*"));
1189 Fset_window_buffer (w
, new_buffer
);
1190 Fset_buffer (XWINDOW (w
)->buffer
);
1197 case GET_LARGEST_WINDOW
:
1199 /* Ignore invisible and iconified frames. */
1200 if (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (w
))))
1201 || FRAME_ICONIFIED_P (XFRAME (WINDOW_FRAME (XWINDOW (w
)))))
1204 /* Ignore dedicated windows and minibuffers. */
1205 if (MINI_WINDOW_P (XWINDOW (w
))
1206 || !NILP (XWINDOW (w
)->dedicated
))
1209 struct window
*best_window_ptr
= XWINDOW (best_window
);
1210 struct window
*w_ptr
= XWINDOW (w
);
1211 if (NILP (best_window
) ||
1212 (XFASTINT (w_ptr
->height
) * XFASTINT (w_ptr
->width
))
1213 > (XFASTINT (best_window_ptr
->height
)
1214 * XFASTINT (best_window_ptr
->width
)))
1220 if (EQ (XWINDOW (w
)->buffer
, obj
))
1222 /* Find another buffer to show in this window. */
1223 Lisp_Object another_buffer
= Fother_buffer (obj
, Qnil
);
1224 if (NILP (another_buffer
))
1226 = Fget_buffer_create (build_string ("*scratch*"));
1227 Fset_window_buffer (w
, another_buffer
);
1228 if (EQ (w
, selected_window
))
1229 Fset_buffer (XWINDOW (w
)->buffer
);
1234 if (EQ (w
, last_window
))
1243 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1244 "Return the window least recently selected or used for display.\n\
1245 If optional argument FRAMES is t, search all frames. If FRAME is a\n\
1246 frame, search only that frame.\n")
1250 register Lisp_Object w
;
1251 /* First try for a window that is full-width */
1252 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frames
);
1253 if (!NILP (w
) && !EQ (w
, selected_window
))
1255 /* If none of them, try the rest */
1256 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frames
);
1259 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1260 "Return the largest window in area.\n\
1261 If optional argument FRAMES is t, search all frames. If FRAME is a\n\
1262 frame, search only that frame.\n")
1266 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
1270 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
1271 "Return a window currently displaying BUFFER, or nil if none.\n\
1272 If optional argument FRAMES is t, search all frames. If FRAME is a\n\
1273 frame, search only that frame.\n")
1275 Lisp_Object buffer
, frame
;
1277 buffer
= Fget_buffer (buffer
);
1278 if (XTYPE (buffer
) == Lisp_Buffer
)
1279 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
1284 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
1286 "Make WINDOW (or the selected window) fill its frame.\n\
1287 Only the frame WINDOW is on is affected.")
1293 struct buffer
*obuf
= current_buffer
;
1297 window
= selected_window
;
1299 CHECK_LIVE_WINDOW (window
, 0);
1301 w
= XWINDOW (window
);
1302 top
= XFASTINT (w
->top
);
1304 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME(w
));
1306 Fset_buffer (w
->buffer
);
1307 SET_PT (marker_position (w
->start
));
1308 Frecenter (make_number (top
));
1310 set_buffer_internal (obuf
);
1315 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
1316 1, 1, "bDelete windows on (buffer): ",
1317 "Delete all windows showing BUFFER.")
1323 buffer
= Fget_buffer (buffer
);
1324 CHECK_BUFFER (buffer
, 0);
1325 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, Qt
);
1330 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
1331 Sreplace_buffer_in_windows
,
1332 1, 1, "bReplace buffer in windows: ",
1333 "Replace BUFFER with some other buffer in all windows showing it.")
1339 buffer
= Fget_buffer (buffer
);
1340 CHECK_BUFFER (buffer
, 0);
1341 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
1346 /* Set the height of WINDOW and all its inferiors. */
1348 /* The smallest acceptable dimensions for a window. Anything smaller
1349 might crash Emacs. */
1350 #define MIN_SAFE_WINDOW_WIDTH (2)
1351 #define MIN_SAFE_WINDOW_HEIGHT (2)
1353 /* Make sure that window_min_height and window_min_width are
1354 not too small; if they are, set them to safe minima. */
1357 check_min_window_sizes ()
1359 /* Smaller values might permit a crash. */
1360 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
1361 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
1362 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
1363 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
1366 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
1367 minimum allowable size. */
1369 check_frame_size (frame
, rows
, cols
)
1373 /* For height, we have to see whether the frame has a minibuffer, and
1374 whether it wants a mode line. */
1376 ((FRAME_MINIBUF_ONLY_P (frame
)
1377 || ! FRAME_HAS_MINIBUF_P (frame
))
1378 ? MIN_SAFE_WINDOW_HEIGHT
1379 : 2 * MIN_SAFE_WINDOW_HEIGHT
- 1);
1381 if (*rows
< min_height
)
1383 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
1384 *cols
= MIN_SAFE_WINDOW_WIDTH
;
1387 /* Normally the window is deleted if it gets too small.
1388 nodelete nonzero means do not do this.
1389 (The caller should check later and do so if appropriate) */
1391 set_window_height (window
, height
, nodelete
)
1396 register struct window
*w
= XWINDOW (window
);
1397 register struct window
*c
;
1398 int oheight
= XFASTINT (w
->height
);
1399 int top
, pos
, lastbot
, opos
, lastobot
;
1402 check_min_window_sizes ();
1405 && ! NILP (w
->parent
)
1406 && height
< window_min_height
)
1408 Fdelete_window (window
);
1412 XFASTINT (w
->last_modified
) = 0;
1413 windows_or_buffers_changed
++;
1414 XFASTINT (w
->height
) = height
;
1415 if (!NILP (w
->hchild
))
1417 for (child
= w
->hchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
1419 XWINDOW (child
)->top
= w
->top
;
1420 set_window_height (child
, height
, nodelete
);
1423 else if (!NILP (w
->vchild
))
1425 lastbot
= top
= XFASTINT (w
->top
);
1427 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
1429 c
= XWINDOW (child
);
1431 opos
= lastobot
+ XFASTINT (c
->height
);
1433 XFASTINT (c
->top
) = lastbot
;
1435 pos
= (((opos
* height
) << 1) + oheight
) / (oheight
<< 1);
1437 /* Avoid confusion: inhibit deletion of child if becomes too small */
1438 set_window_height (child
, pos
+ top
- lastbot
, 1);
1440 /* Now advance child to next window,
1441 and set lastbot if child was not just deleted. */
1442 lastbot
= pos
+ top
;
1445 /* Now delete any children that became too small. */
1447 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
1449 set_window_height (child
, XINT (XWINDOW (child
)->height
), 0);
1454 /* Recursively set width of WINDOW and its inferiors. */
1456 set_window_width (window
, width
, nodelete
)
1461 register struct window
*w
= XWINDOW (window
);
1462 register struct window
*c
;
1463 int owidth
= XFASTINT (w
->width
);
1464 int left
, pos
, lastright
, opos
, lastoright
;
1467 if (!nodelete
&& width
< window_min_width
)
1469 Fdelete_window (window
);
1473 XFASTINT (w
->last_modified
) = 0;
1474 windows_or_buffers_changed
++;
1475 XFASTINT (w
->width
) = width
;
1476 if (!NILP (w
->vchild
))
1478 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
1480 XWINDOW (child
)->left
= w
->left
;
1481 set_window_width (child
, width
, nodelete
);
1484 else if (!NILP (w
->hchild
))
1486 lastright
= left
= XFASTINT (w
->left
);
1488 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
1490 c
= XWINDOW (child
);
1492 opos
= lastoright
+ XFASTINT (c
->width
);
1494 XFASTINT (c
->left
) = lastright
;
1496 pos
= (((opos
* width
) << 1) + owidth
) / (owidth
<< 1);
1498 /* Inhibit deletion for becoming too small */
1499 set_window_width (child
, pos
+ left
- lastright
, 1);
1501 /* Now advance child to next window,
1502 and set lastright if child was not just deleted. */
1503 lastright
= pos
+ left
, lastoright
= opos
;
1505 /* Delete children that became too small */
1507 for (child
= w
->hchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
1509 set_window_width (child
, XINT (XWINDOW (child
)->width
), 0);
1514 int window_select_count
;
1516 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 2, 0,
1517 "Make WINDOW display BUFFER as its contents.\n\
1518 BUFFER can be a buffer or buffer name.")
1520 register Lisp_Object window
, buffer
;
1522 register Lisp_Object tem
;
1523 register struct window
*w
= decode_window (window
);
1525 buffer
= Fget_buffer (buffer
);
1526 CHECK_BUFFER (buffer
, 1);
1528 if (NILP (XBUFFER (buffer
)->name
))
1529 error ("Attempt to display deleted buffer");
1533 error ("Window is deleted");
1534 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
1535 is first being set up. */
1537 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
1538 error ("Window is dedicated to %s\n", tem
);
1544 Fset_marker (w
->pointm
,
1545 make_number (BUF_PT (XBUFFER (buffer
))),
1547 set_marker_restricted (w
->start
,
1548 make_number (XBUFFER (buffer
)->last_window_start
),
1550 w
->start_at_line_beg
= Qnil
;
1551 XFASTINT (w
->last_modified
) = 0;
1552 windows_or_buffers_changed
++;
1553 if (EQ (window
, selected_window
))
1554 Fset_buffer (buffer
);
1559 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 1, 0,
1560 "Select WINDOW. Most editing will apply to WINDOW's buffer.\n\
1561 The main editor command loop selects the buffer of the selected window\n\
1562 before each command.")
1564 register Lisp_Object window
;
1566 register struct window
*w
;
1567 register struct window
*ow
= XWINDOW (selected_window
);
1569 CHECK_LIVE_WINDOW (window
, 0);
1571 w
= XWINDOW (window
);
1573 if (NILP (w
->buffer
))
1574 error ("Trying to select deleted window or non-leaf window");
1576 XFASTINT (w
->use_time
) = ++window_select_count
;
1577 if (EQ (window
, selected_window
))
1580 Fset_marker (ow
->pointm
, make_number (BUF_PT (XBUFFER (ow
->buffer
))),
1583 selected_window
= window
;
1585 if (XFRAME (WINDOW_FRAME (w
)) != selected_frame
)
1587 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
1588 Fselect_frame (WINDOW_FRAME (w
), Qnil
);
1591 selected_frame
->selected_window
= window
;
1594 record_buffer (w
->buffer
);
1595 Fset_buffer (w
->buffer
);
1597 /* Go to the point recorded in the window.
1598 This is important when the buffer is in more
1599 than one window. It also matters when
1600 redisplay_window has altered point after scrolling,
1601 because it makes the change only in the window. */
1603 register int new_point
= marker_position (w
->pointm
);
1604 if (new_point
< BEGV
)
1612 windows_or_buffers_changed
++;
1616 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 2,
1617 "BDisplay buffer:\nP",
1618 "Make BUFFER appear in some window but don't select it.\n\
1619 BUFFER can be a buffer or a buffer name.\n\
1620 If BUFFER is shown already in some window, just use that one,\n\
1621 unless the window is the selected window and the optional second\n\
1622 argument NOT_THIS_WINDOW is non-nil.\n\
1623 Returns the window displaying BUFFER.")
1624 (buffer
, not_this_window
)
1625 register Lisp_Object buffer
, not_this_window
;
1627 register Lisp_Object window
;
1629 buffer
= Fget_buffer (buffer
);
1630 CHECK_BUFFER (buffer
, 0);
1632 if (!NILP (Vdisplay_buffer_function
))
1633 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
1635 if (NILP (not_this_window
)
1636 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
1637 return selected_window
;
1639 window
= Fget_buffer_window (buffer
, Qnil
);
1641 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
1645 /* If there are no frames open that have more than a minibuffer,
1646 we need to create a new frame. */
1647 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
1650 = Fframe_selected_window (call0 (Vpop_up_frame_function
));
1651 Fset_window_buffer (window
, buffer
);
1653 Fselect_frame (XWINDOW (window
)->frame
, Qnil
);
1657 #endif /* MULTI_FRAME */
1661 || FRAME_MINIBUF_ONLY_P (selected_frame
)
1665 Lisp_Object frames
= Qnil
;
1668 if (FRAME_MINIBUF_ONLY_P (selected_frame
))
1669 XSET (frames
, Lisp_Frame
, last_nonminibuf_frame
);
1671 /* Don't try to create a window if would get an error */
1672 if (split_height_threshold
< window_min_height
<< 1)
1673 split_height_threshold
= window_min_height
<< 1;
1675 window
= Fget_largest_window (frames
);
1678 && window_height (window
) >= split_height_threshold
1680 (XFASTINT (XWINDOW (window
)->width
)
1681 == FRAME_WIDTH (XFRAME (WINDOW_FRAME (XWINDOW (window
))))))
1682 window
= Fsplit_window (window
, Qnil
, Qnil
);
1685 window
= Fget_lru_window (frames
);
1686 if ((EQ (window
, selected_window
)
1687 || EQ (XWINDOW (window
)->parent
, Qnil
))
1688 && window_height (window
) >= window_min_height
<< 1)
1689 window
= Fsplit_window (window
, Qnil
, Qnil
);
1693 window
= Fget_lru_window (Qnil
);
1695 Fset_window_buffer (window
, buffer
);
1700 temp_output_buffer_show (buf
)
1701 register Lisp_Object buf
;
1703 register struct buffer
*old
= current_buffer
;
1704 register Lisp_Object window
;
1705 register struct window
*w
;
1708 XBUFFER (buf
)->save_modified
= MODIFF
;
1713 set_buffer_internal (old
);
1715 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
1716 call1 (Vtemp_buffer_show_function
, buf
);
1719 window
= Fdisplay_buffer (buf
, Qnil
);
1722 if (XFRAME (XWINDOW (window
)->frame
) != selected_frame
)
1723 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
1724 #endif /* MULTI_FRAME */
1725 Vminibuf_scroll_window
= window
;
1726 w
= XWINDOW (window
);
1727 XFASTINT (w
->hscroll
) = 0;
1728 set_marker_restricted (w
->start
, make_number (1), buf
);
1729 set_marker_restricted (w
->pointm
, make_number (1), buf
);
1734 make_dummy_parent (window
)
1737 register Lisp_Object old
, new;
1738 register struct window
*o
, *p
;
1741 XSETTYPE (old
, Lisp_Vector
);
1742 new = Fcopy_sequence (old
);
1743 XSETTYPE (new, Lisp_Window
);
1747 XFASTINT (p
->sequence_number
) = ++sequence_number
;
1749 /* Put new into window structure in place of window */
1750 replace_window (window
, new);
1763 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
1764 "Split WINDOW, putting SIZE lines in the first of the pair.\n\
1765 WINDOW defaults to selected one and SIZE to half its size.\n\
1766 If optional third arg HOR-FLAG is non-nil, split side by side\n\
1767 and put SIZE columns in the first of the pair.")
1768 (window
, chsize
, horflag
)
1769 Lisp_Object window
, chsize
, horflag
;
1771 register Lisp_Object
new;
1772 register struct window
*o
, *p
;
1776 window
= selected_window
;
1778 CHECK_LIVE_WINDOW (window
, 0);
1780 o
= XWINDOW (window
);
1784 if (!NILP (horflag
))
1785 /* Round odd size up, since this is for the left-hand window,
1786 and it will lose a column for the separators. */
1787 size
= ((XFASTINT (o
->width
) + 1) & -2) >> 1;
1789 size
= XFASTINT (o
->height
) >> 1;
1793 CHECK_NUMBER (chsize
, 1);
1794 size
= XINT (chsize
);
1797 if (MINI_WINDOW_P (o
))
1798 error ("Attempt to split minibuffer window");
1799 else if (FRAME_NO_SPLIT_P (XFRAME (WINDOW_FRAME (o
))))
1800 error ("Attempt to split unsplittable frame");
1802 check_min_window_sizes ();
1806 if (size
< window_min_height
1807 || size
+ window_min_height
> XFASTINT (o
->height
))
1808 args_out_of_range_3 (window
, chsize
, horflag
);
1809 if (NILP (o
->parent
)
1810 || NILP (XWINDOW (o
->parent
)->vchild
))
1812 make_dummy_parent (window
);
1814 XWINDOW (new)->vchild
= window
;
1819 if (size
< window_min_width
1820 || size
+ window_min_width
> XFASTINT (o
->width
))
1821 args_out_of_range_3 (window
, chsize
, horflag
);
1822 if (NILP (o
->parent
)
1823 || NILP (XWINDOW (o
->parent
)->hchild
))
1825 make_dummy_parent (window
);
1827 XWINDOW (new)->hchild
= window
;
1831 /* Now we know that window's parent is a vertical combination
1832 if we are dividing vertically, or a horizontal combination
1833 if we are making side-by-side windows */
1835 windows_or_buffers_changed
++;
1836 new = make_window ();
1839 p
->frame
= o
->frame
;
1841 if (!NILP (p
->next
))
1842 XWINDOW (p
->next
)->prev
= new;
1845 p
->parent
= o
->parent
;
1848 Fset_window_buffer (new, o
->buffer
);
1850 /* Apportion the available frame space among the two new windows */
1852 if (!NILP (horflag
))
1854 p
->height
= o
->height
;
1856 XFASTINT (p
->width
) = XFASTINT (o
->width
) - size
;
1857 XFASTINT (o
->width
) = size
;
1858 XFASTINT (p
->left
) = XFASTINT (o
->left
) + size
;
1863 p
->width
= o
->width
;
1864 XFASTINT (p
->height
) = XFASTINT (o
->height
) - size
;
1865 XFASTINT (o
->height
) = size
;
1866 XFASTINT (p
->top
) = XFASTINT (o
->top
) + size
;
1872 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
1873 "Make current window ARG lines bigger.\n\
1874 From program, optional second arg non-nil means grow sideways ARG columns.")
1876 register Lisp_Object n
, side
;
1878 CHECK_NUMBER (n
, 0);
1879 change_window_height (XINT (n
), !NILP (side
));
1883 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
1884 "Make current window ARG lines smaller.\n\
1885 From program, optional second arg non-nil means shrink sideways ARG columns.")
1887 register Lisp_Object n
, side
;
1889 CHECK_NUMBER (n
, 0);
1890 change_window_height (-XINT (n
), !NILP (side
));
1895 window_height (window
)
1898 register struct window
*p
= XWINDOW (window
);
1899 return XFASTINT (p
->height
);
1903 window_width (window
)
1906 register struct window
*p
= XWINDOW (window
);
1907 return XFASTINT (p
->width
);
1910 #define MINSIZE(w) \
1912 ? window_min_width \
1913 : (MINI_WINDOW_P (XWINDOW (w)) ? 1 : window_min_height))
1916 *(widthflag ? (int *) &(XWINDOW (w)->left) : (int *) &(XWINDOW (w)->top))
1918 #define CURSIZE(w) \
1919 *(widthflag ? (int *) &(XWINDOW (w)->width) : (int *) &(XWINDOW (w)->height))
1921 /* Unlike set_window_height, this function
1922 also changes the heights of the siblings so as to
1923 keep everything consistent. */
1925 change_window_height (delta
, widthflag
)
1929 register Lisp_Object parent
;
1931 register struct window
*p
;
1933 int (*sizefun
) () = widthflag
? window_width
: window_height
;
1934 register int (*setsizefun
) () = (widthflag
1936 : set_window_height
);
1938 check_min_window_sizes ();
1940 window
= selected_window
;
1943 p
= XWINDOW (window
);
1948 error ("No other window to side of this one");
1951 if (widthflag
? !NILP (XWINDOW (parent
)->hchild
)
1952 : !NILP (XWINDOW (parent
)->vchild
))
1957 sizep
= &CURSIZE (window
);
1959 if (*sizep
+ delta
< MINSIZE (window
))
1961 Fdelete_window (window
);
1966 register int maxdelta
;
1968 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - *sizep
1969 : !NILP (p
->next
) ? (*sizefun
) (p
->next
) - MINSIZE (p
->next
)
1970 : !NILP (p
->prev
) ? (*sizefun
) (p
->prev
) - MINSIZE (p
->prev
)
1971 /* This is a frame with only one window, a minibuffer-only
1972 or a minibufferless frame. */
1975 if (delta
> maxdelta
)
1976 /* This case traps trying to make the minibuffer
1977 the full frame, or make the only window aside from the
1978 minibuffer the full frame. */
1985 if (!NILP (p
->next
) &&
1986 (*sizefun
) (p
->next
) - delta
>= MINSIZE (p
->next
))
1988 (*setsizefun
) (p
->next
, (*sizefun
) (p
->next
) - delta
, 0);
1989 (*setsizefun
) (window
, *sizep
+ delta
, 0);
1990 CURBEG (p
->next
) += delta
;
1991 /* This does not change size of p->next,
1992 but it propagates the new top edge to its children */
1993 (*setsizefun
) (p
->next
, (*sizefun
) (p
->next
), 0);
1995 else if (!NILP (p
->prev
) &&
1996 (*sizefun
) (p
->prev
) - delta
>= MINSIZE (p
->prev
))
1998 (*setsizefun
) (p
->prev
, (*sizefun
) (p
->prev
) - delta
, 0);
1999 CURBEG (window
) -= delta
;
2000 (*setsizefun
) (window
, *sizep
+ delta
, 0);
2004 register int delta1
;
2005 register int opht
= (*sizefun
) (parent
);
2007 /* If trying to grow this window to or beyond size of the parent,
2008 make delta1 so big that, on shrinking back down,
2009 all the siblings end up with less than one line and are deleted. */
2010 if (opht
<= *sizep
+ delta
)
2011 delta1
= opht
* opht
* 2;
2012 /* Otherwise, make delta1 just right so that if we add delta1
2013 lines to this window and to the parent, and then shrink
2014 the parent back to its original size, the new proportional
2015 size of this window will increase by delta. */
2017 delta1
= (delta
* opht
* 100) / ((opht
- *sizep
- delta
) * 100);
2019 /* Add delta1 lines or columns to this window, and to the parent,
2020 keeping things consistent while not affecting siblings. */
2021 CURSIZE (parent
) = opht
+ delta1
;
2022 (*setsizefun
) (window
, *sizep
+ delta1
, 0);
2024 /* Squeeze out delta1 lines or columns from our parent,
2025 shriking this window and siblings proportionately.
2026 This brings parent back to correct size.
2027 Delta1 was calculated so this makes this window the desired size,
2028 taking it all out of the siblings. */
2029 (*setsizefun
) (parent
, opht
, 0);
2032 XFASTINT (p
->last_modified
) = 0;
2039 /* Return number of lines of text (not counting mode line) in W. */
2042 window_internal_height (w
)
2045 int ht
= XFASTINT (w
->height
);
2047 if (MINI_WINDOW_P (w
))
2050 if (!NILP (w
->parent
) || !NILP (w
->vchild
) || !NILP (w
->hchild
)
2051 || !NILP (w
->next
) || !NILP (w
->prev
)
2052 || FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (w
))))
2058 /* Scroll contents of window WINDOW up N lines. */
2061 window_scroll (window
, n
, noerror
)
2066 register struct window
*w
= XWINDOW (window
);
2067 register int opoint
= point
;
2069 register int ht
= window_internal_height (w
);
2070 register Lisp_Object tem
;
2072 Lisp_Object bolp
, nmoved
;
2074 XFASTINT (tem
) = point
;
2075 tem
= Fpos_visible_in_window_p (tem
, window
);
2079 Fvertical_motion (make_number (- ht
/ 2));
2080 XFASTINT (tem
) = point
;
2081 Fset_marker (w
->start
, tem
, w
->buffer
);
2082 w
->force_start
= Qt
;
2085 SET_PT (marker_position (w
->start
));
2086 lose
= n
< 0 && point
== BEGV
;
2087 Fvertical_motion (make_number (n
));
2097 Fsignal (Qbeginning_of_buffer
, Qnil
);
2102 set_marker_restricted (w
->start
, make_number (pos
), w
->buffer
);
2103 w
->start_at_line_beg
= bolp
;
2104 w
->update_mode_line
= Qt
;
2105 XFASTINT (w
->last_modified
) = 0;
2111 tem
= Fvertical_motion (make_number (ht
));
2112 if (point
> opoint
|| XFASTINT (tem
) < ht
)
2115 Fvertical_motion (make_number (-1));
2123 Fsignal (Qend_of_buffer
, Qnil
);
2127 /* This is the guts of Fscroll_up and Fscroll_down. */
2130 scroll_command (n
, direction
)
2131 register Lisp_Object n
;
2134 register int defalt
;
2135 int count
= specpdl_ptr
- specpdl
;
2137 /* If selected window's buffer isn't current, make it current for the moment.
2138 But don't screw up if window_scroll gets an error. */
2139 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
2141 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
2142 Fset_buffer (XWINDOW (selected_window
)->buffer
);
2145 defalt
= (window_internal_height (XWINDOW (selected_window
))
2146 - next_screen_context_lines
);
2147 defalt
= direction
* (defalt
< 1 ? 1 : defalt
);
2150 window_scroll (selected_window
, defalt
, 0);
2151 else if (EQ (n
, Qminus
))
2152 window_scroll (selected_window
, - defalt
, 0);
2155 n
= Fprefix_numeric_value (n
);
2156 window_scroll (selected_window
, XINT (n
) * direction
, 0);
2159 unbind_to (count
, Qnil
);
2162 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
2163 "Scroll text of current window upward ARG lines; or near full screen if no ARG.\n\
2164 A near full screen is `next-screen-context-lines' less than a full screen.\n\
2165 When calling from a program, supply a number as argument or nil.")
2169 scroll_command (n
, 1);
2173 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
2174 "Scroll text of current window downward ARG lines; or near full screen if no ARG.\n\
2175 A near full screen is `next-screen-context-lines' less than a full screen.\n\
2176 When calling from a program, supply a number as argument or nil.")
2180 scroll_command (n
, -1);
2184 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
2185 "Scroll next window upward ARG lines; or near full screen if no ARG.\n\
2186 The next window is the one below the current one; or the one at the top\n\
2187 if the current one is at the bottom.\n\
2188 When calling from a program, supply a number as argument or nil.\n\
2190 If in the minibuffer, `minibuf-scroll-window' if non-nil\n\
2191 specifies the window to scroll.\n\
2192 If `other-window-scroll-buffer' is non-nil, scroll the window\n\
2193 showing that buffer, popping the buffer up if necessary.")
2195 register Lisp_Object n
;
2197 register Lisp_Object window
;
2199 register struct window
*w
;
2200 register int count
= specpdl_ptr
- specpdl
;
2202 if (MINI_WINDOW_P (XWINDOW (selected_window
))
2203 && !NILP (Vminibuf_scroll_window
))
2204 window
= Vminibuf_scroll_window
;
2205 /* If buffer is specified, scroll that buffer. */
2206 else if (!NILP (Vother_window_scroll_buffer
))
2208 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
2210 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
);
2213 /* Nothing specified; pick a neighboring window. */
2214 window
= Fnext_window (selected_window
, Qnil
, Qt
);
2215 CHECK_LIVE_WINDOW (window
, 0);
2217 if (EQ (window
, selected_window
))
2218 error ("There is no other window");
2220 w
= XWINDOW (window
);
2221 ht
= window_internal_height (w
);
2223 /* Don't screw up if window_scroll gets an error. */
2224 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
2226 Fset_buffer (w
->buffer
);
2227 SET_PT (marker_position (w
->pointm
));
2230 window_scroll (window
, ht
- next_screen_context_lines
, 1);
2231 else if (EQ (n
, Qminus
))
2232 window_scroll (window
, next_screen_context_lines
- ht
, 1);
2235 if (XTYPE (n
) == Lisp_Cons
)
2237 CHECK_NUMBER (n
, 0);
2238 window_scroll (window
, XINT (n
), 1);
2241 Fset_marker (w
->pointm
, make_number (point
), Qnil
);
2247 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 1, 1, "P",
2248 "Scroll selected window display ARG columns left.\n\
2249 Default for ARG is window width minus 2.")
2251 register Lisp_Object arg
;
2255 XFASTINT (arg
) = XFASTINT (XWINDOW (selected_window
)->width
) - 2;
2257 arg
= Fprefix_numeric_value (arg
);
2260 Fset_window_hscroll (selected_window
,
2261 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
2265 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 1, 1, "P",
2266 "Scroll selected window display ARG columns right.\n\
2267 Default for ARG is window width minus 2.")
2269 register Lisp_Object arg
;
2272 XFASTINT (arg
) = XFASTINT (XWINDOW (selected_window
)->width
) - 2;
2274 arg
= Fprefix_numeric_value (arg
);
2277 Fset_window_hscroll (selected_window
,
2278 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
2282 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
2283 "Center point in window and redisplay frame. With ARG, put point on line ARG.\n\
2284 The desired position of point is always relative to the current window.\n\
2285 Just C-u as prefix means put point in the center of the window.\n\
2286 No arg (i.e., it is nil) erases the entire frame and then\n\
2287 redraws with point in the center of the current window.")
2289 register Lisp_Object n
;
2291 register struct window
*w
= XWINDOW (selected_window
);
2292 register int ht
= window_internal_height (w
);
2293 register int opoint
= point
;
2297 extern int frame_garbaged
;
2299 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
2300 XFASTINT (n
) = ht
/ 2;
2302 else if (XTYPE (n
) == Lisp_Cons
) /* Just C-u. */
2304 XFASTINT (n
) = ht
/ 2;
2308 n
= Fprefix_numeric_value (n
);
2309 CHECK_NUMBER (n
, 0);
2313 XSETINT (n
, XINT (n
) + ht
);
2315 XSETINT (n
, - XINT (n
));
2317 Fvertical_motion (n
);
2318 Fset_marker (w
->start
, make_number (point
), w
->buffer
);
2319 w
->start_at_line_beg
= Fbolp ();
2322 w
->force_start
= Qt
;
2327 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
2329 "Position point relative to window.\n\
2330 With no argument, position text at center of window.\n\
2331 An argument specifies frame line; zero means top of window,\n\
2332 negative means relative to bottom of window.")
2334 register Lisp_Object arg
;
2336 register struct window
*w
= XWINDOW (selected_window
);
2337 register int height
= window_internal_height (w
);
2341 XFASTINT (arg
) = height
/ 2;
2344 arg
= Fprefix_numeric_value (arg
);
2346 XSETINT (arg
, XINT (arg
) + height
);
2349 start
= marker_position (w
->start
);
2350 if (start
< BEGV
|| start
> ZV
)
2352 Fvertical_motion (make_number (- height
/ 2));
2353 Fset_marker (w
->start
, make_number (point
), w
->buffer
);
2354 w
->start_at_line_beg
= Fbolp ();
2355 w
->force_start
= Qt
;
2360 return Fvertical_motion (arg
);
2363 struct save_window_data
2365 int size_from_Lisp_Vector_struct
;
2366 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
2367 Lisp_Object frame_width
, frame_height
;
2368 Lisp_Object selected_frame
;
2369 Lisp_Object current_window
;
2370 Lisp_Object current_buffer
;
2371 Lisp_Object minibuf_scroll_window
;
2372 Lisp_Object root_window
;
2373 Lisp_Object focus_frame
;
2374 /* A vector, interpreted as a struct saved_window */
2375 Lisp_Object saved_windows
;
2378 /* Arg to Fmake_vector */
2379 #define SAVE_WINDOW_DATA_SIZE \
2380 ((sizeof (struct save_window_data) \
2381 - (sizeof (struct Lisp_Vector) \
2382 /* Don't count the contents member of the struct Lisp_Vector */ \
2383 - sizeof (Lisp_Object))) \
2384 / sizeof (Lisp_Object))
2386 /* This is saved as a Lisp_Vector */
2389 /* these first two must agree with struct Lisp_Vector in lisp.h */
2390 int size_from_Lisp_Vector_struct
;
2391 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
2394 Lisp_Object buffer
, start
, pointm
, mark
;
2395 Lisp_Object left
, top
, width
, height
, hscroll
;
2396 Lisp_Object parent
, prev
;
2397 Lisp_Object start_at_line_beg
;
2398 Lisp_Object display_table
;
2400 #define SAVED_WINDOW_VECTOR_SIZE 14 /* Arg to Fmake_vector */
2402 #define SAVED_WINDOW_N(swv,n) \
2403 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
2405 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
2406 "T if OBJECT is a window-configration object.")
2410 if (XTYPE (obj
) == Lisp_Window_Configuration
)
2416 DEFUN ("set-window-configuration",
2417 Fset_window_configuration
, Sset_window_configuration
,
2419 "Set the configuration of windows and buffers as specified by CONFIGURATION.\n\
2420 CONFIGURATION must be a value previously returned\n\
2421 by `current-window-configuration' (which see).")
2423 Lisp_Object configuration
;
2425 register struct save_window_data
*data
;
2426 struct Lisp_Vector
*saved_windows
;
2427 Lisp_Object new_current_buffer
;
2431 while (XTYPE (configuration
) != Lisp_Window_Configuration
)
2433 configuration
= wrong_type_argument (intern ("window-configuration-p"),
2437 data
= (struct save_window_data
*) XVECTOR (configuration
);
2438 saved_windows
= XVECTOR (data
->saved_windows
);
2440 new_current_buffer
= data
->current_buffer
;
2441 if (NILP (XBUFFER (new_current_buffer
)->name
))
2442 new_current_buffer
= Qnil
;
2444 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
2447 /* If f is a dead frame, don't bother rebuilding its window tree.
2448 However, there is other stuff we should still try to do below. */
2449 if (FRAME_LIVE_P (f
))
2451 register struct window
*w
;
2452 register struct saved_window
*p
;
2455 /* If the frame has been resized since this window configuration was
2456 made, we change the frame to the size specified in the
2457 configuration, restore the configuration, and then resize it
2458 back. We keep track of the prevailing height in these variables. */
2459 int previous_frame_height
= FRAME_HEIGHT (f
);
2460 int previous_frame_width
= FRAME_WIDTH (f
);
2462 if (XFASTINT (data
->frame_height
) != previous_frame_height
2463 || XFASTINT (data
->frame_width
) != previous_frame_width
)
2464 change_frame_size (f
, data
->frame_height
, data
->frame_width
, 0, 0);
2466 windows_or_buffers_changed
++;
2469 Mark all windows now on frame as "deleted".
2470 Restoring the new configuration "undeletes" any that are in it.
2472 Save their current buffers in their height fields, since we may
2473 need it later, if a buffer saved in the configuration is now
2475 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
2477 for (k
= 0; k
< saved_windows
->size
; k
++)
2479 p
= SAVED_WINDOW_N (saved_windows
, k
);
2480 w
= XWINDOW (p
->window
);
2483 if (!NILP (p
->parent
))
2484 w
->parent
= SAVED_WINDOW_N (saved_windows
,
2485 XFASTINT (p
->parent
))->window
;
2489 if (!NILP (p
->prev
))
2491 w
->prev
= SAVED_WINDOW_N (saved_windows
,
2492 XFASTINT (p
->prev
))->window
;
2493 XWINDOW (w
->prev
)->next
= p
->window
;
2498 if (!NILP (w
->parent
))
2500 if (EQ (p
->width
, XWINDOW (w
->parent
)->width
))
2502 XWINDOW (w
->parent
)->vchild
= p
->window
;
2503 XWINDOW (w
->parent
)->hchild
= Qnil
;
2507 XWINDOW (w
->parent
)->hchild
= p
->window
;
2508 XWINDOW (w
->parent
)->vchild
= Qnil
;
2513 /* If we squirreled away the buffer in the window's height,
2515 if (XTYPE (w
->height
) == Lisp_Buffer
)
2516 w
->buffer
= w
->height
;
2519 w
->width
= p
->width
;
2520 w
->height
= p
->height
;
2521 w
->hscroll
= p
->hscroll
;
2522 w
->display_table
= p
->display_table
;
2523 XFASTINT (w
->last_modified
) = 0;
2525 /* Reinstall the saved buffer and pointers into it. */
2526 if (NILP (p
->buffer
))
2527 w
->buffer
= p
->buffer
;
2530 if (!NILP (XBUFFER (p
->buffer
)->name
))
2531 /* If saved buffer is alive, install it. */
2533 w
->buffer
= p
->buffer
;
2534 w
->start_at_line_beg
= p
->start_at_line_beg
;
2535 set_marker_restricted (w
->start
,
2536 Fmarker_position (p
->start
),
2538 set_marker_restricted (w
->pointm
,
2539 Fmarker_position (p
->pointm
),
2541 Fset_marker (XBUFFER (w
->buffer
)->mark
,
2542 Fmarker_position (p
->mark
), w
->buffer
);
2544 /* As documented in Fcurrent_window_configuration, don't
2545 save the location of point in the buffer which was current
2546 when the window configuration was recorded. */
2547 if (!EQ (p
->buffer
, new_current_buffer
) &&
2548 XBUFFER (p
->buffer
) == current_buffer
)
2549 Fgoto_char (w
->pointm
);
2551 else if (NILP (XBUFFER (w
->buffer
)->name
))
2552 /* Else if window's old buffer is dead too, get a live one. */
2554 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
2555 /* This will set the markers to beginning of visible
2557 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
2558 set_marker_restricted (w
->pointm
, make_number (0),w
->buffer
);
2559 w
->start_at_line_beg
= Qt
;
2562 /* Keeping window's old buffer; make sure the markers
2563 are real. Else if window's old buffer is dead too,
2566 /* Set window markers at start of visible range. */
2567 if (XMARKER (w
->start
)->buffer
== 0)
2568 set_marker_restricted (w
->start
, make_number (0),
2570 if (XMARKER (w
->pointm
)->buffer
== 0)
2571 set_marker_restricted (w
->pointm
,
2573 (BUF_PT (XBUFFER (w
->buffer
)))),
2575 w
->start_at_line_beg
= Qt
;
2580 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
2581 Fselect_window (data
->current_window
);
2584 if (NILP (data
->focus_frame
)
2585 || (XTYPE (data
->focus_frame
) == Lisp_Frame
2586 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
2587 Fredirect_frame_focus (frame
, data
->focus_frame
);
2590 #if 0 /* I don't understand why this is needed, and it causes problems
2591 when the frame's old selected window has been deleted. */
2593 if (f
!= selected_frame
&& ! FRAME_TERMCAP_P (f
))
2594 Fselect_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)), Qnil
);
2598 /* Set the screen height to the value it had before this function. */
2599 if (previous_frame_height
!= FRAME_HEIGHT (f
)
2600 || previous_frame_width
!= FRAME_WIDTH (f
))
2601 change_frame_size (f
, previous_frame_height
, previous_frame_width
,
2606 /* Fselect_window will have made f the selected frame, so we
2607 reselect the proper frame here. Fselect_frame will change the
2608 selected window too, but that doesn't make the call to
2609 Fselect_window above totally superfluous; it still sets f's
2611 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
2612 Fselect_frame (data
->selected_frame
);
2615 if (!NILP (new_current_buffer
))
2616 Fset_buffer (new_current_buffer
);
2618 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
2622 /* Mark all windows now on frame as deleted
2623 by setting their buffers to nil. */
2626 delete_all_subwindows (w
)
2627 register struct window
*w
;
2629 if (!NILP (w
->next
))
2630 delete_all_subwindows (XWINDOW (w
->next
));
2631 if (!NILP (w
->vchild
))
2632 delete_all_subwindows (XWINDOW (w
->vchild
));
2633 if (!NILP (w
->hchild
))
2634 delete_all_subwindows (XWINDOW (w
->hchild
));
2636 w
->height
= w
->buffer
; /* See Fset_window_configuration for excuse. */
2638 /* We set all three of these fields to nil, to make sure that we can
2639 distinguish this dead window from any live window. Live leaf
2640 windows will have buffer set, and combination windows will have
2641 vchild or hchild set. */
2648 count_windows (window
)
2649 register struct window
*window
;
2651 register int count
= 1;
2652 if (!NILP (window
->next
))
2653 count
+= count_windows (XWINDOW (window
->next
));
2654 if (!NILP (window
->vchild
))
2655 count
+= count_windows (XWINDOW (window
->vchild
));
2656 if (!NILP (window
->hchild
))
2657 count
+= count_windows (XWINDOW (window
->hchild
));
2662 save_window_save (window
, vector
, i
)
2664 struct Lisp_Vector
*vector
;
2667 register struct saved_window
*p
;
2668 register struct window
*w
;
2669 register Lisp_Object tem
;
2671 for (;!NILP (window
); window
= w
->next
)
2673 p
= SAVED_WINDOW_N (vector
, i
);
2674 w
= XWINDOW (window
);
2676 XFASTINT (w
->temslot
) = i
++;
2678 p
->buffer
= w
->buffer
;
2681 p
->width
= w
->width
;
2682 p
->height
= w
->height
;
2683 p
->hscroll
= w
->hscroll
;
2684 p
->display_table
= w
->display_table
;
2685 if (!NILP (w
->buffer
))
2687 /* Save w's value of point in the window configuration.
2688 If w is the selected window, then get the value of point
2689 from the buffer; pointm is garbage in the selected window. */
2690 if (EQ (window
, selected_window
))
2692 p
->pointm
= Fmake_marker ();
2693 Fset_marker (p
->pointm
, BUF_PT (XBUFFER (w
->buffer
)),
2697 p
->pointm
= Fcopy_marker (w
->pointm
);
2699 p
->start
= Fcopy_marker (w
->start
);
2700 p
->start_at_line_beg
= w
->start_at_line_beg
;
2702 tem
= XBUFFER (w
->buffer
)->mark
;
2703 p
->mark
= Fcopy_marker (tem
);
2710 p
->start_at_line_beg
= Qnil
;
2713 if (NILP (w
->parent
))
2716 p
->parent
= XWINDOW (w
->parent
)->temslot
;
2721 p
->prev
= XWINDOW (w
->prev
)->temslot
;
2723 if (!NILP (w
->vchild
))
2724 i
= save_window_save (w
->vchild
, vector
, i
);
2725 if (!NILP (w
->hchild
))
2726 i
= save_window_save (w
->hchild
, vector
, i
);
2732 DEFUN ("current-window-configuration",
2733 Fcurrent_window_configuration
, Scurrent_window_configuration
, 0, 1, 0,
2734 "Return an object representing the current window configuration of FRAME.\n\
2735 If FRAME is nil or omitted, use the selected frame.\n\
2736 This describes the number of windows, their sizes and current buffers,\n\
2737 and for each displayed buffer, where display starts, and the positions of\n\
2738 point and mark. An exception is made for point in the current buffer:\n\
2739 its value is -not- saved.\n\
2740 This also records the currently selected frame, and FRAME's focus\n\
2741 redirection (see `redirect-frame-focus').")
2745 register Lisp_Object tem
;
2746 register int n_windows
;
2747 register struct save_window_data
*data
;
2755 CHECK_LIVE_FRAME (frame
, 0);
2759 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
2760 data
= (struct save_window_data
*)
2761 XVECTOR (Fmake_vector (make_number (SAVE_WINDOW_DATA_SIZE
),
2763 XFASTINT (data
->frame_width
) = FRAME_WIDTH (f
);
2764 XFASTINT (data
->frame_height
) = FRAME_HEIGHT (f
);
2766 XSET (data
->selected_frame
, Lisp_Frame
, selected_frame
);
2768 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
2769 XSET (data
->current_buffer
, Lisp_Buffer
, current_buffer
);
2770 data
->minibuf_scroll_window
= Vminibuf_scroll_window
;
2771 data
->root_window
= FRAME_ROOT_WINDOW (f
);
2772 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
2773 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
2774 data
->saved_windows
= tem
;
2775 for (i
= 0; i
< n_windows
; i
++)
2776 XVECTOR (tem
)->contents
[i
]
2777 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
2778 save_window_save (FRAME_ROOT_WINDOW (f
),
2780 XSET (tem
, Lisp_Window_Configuration
, data
);
2784 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
2786 "Execute body, preserving window sizes and contents.\n\
2787 Restores which buffer appears in which window, where display starts,\n\
2788 as well as the current buffer.\n\
2789 Does not restore the value of point in current buffer.")
2793 register Lisp_Object val
;
2794 register int count
= specpdl_ptr
- specpdl
;
2796 record_unwind_protect (Fset_window_configuration
,
2797 Fcurrent_window_configuration (Qnil
));
2798 val
= Fprogn (args
);
2799 return unbind_to (count
, val
);
2805 selected_frame
= make_terminal_frame ();
2806 minibuf_window
= selected_frame
->minibuffer_window
;
2807 selected_window
= selected_frame
->selected_window
;
2808 last_nonminibuf_frame
= selected_frame
;
2809 #else /* not MULTI_FRAME */
2810 extern Lisp_Object
get_minibuffer ();
2812 minibuf_window
= make_window ();
2813 FRAME_ROOT_WINDOW (selected_frame
) = make_window ();
2815 XWINDOW (FRAME_ROOT_WINDOW (selected_frame
))->next
= minibuf_window
;
2816 XWINDOW (minibuf_window
)->prev
= FRAME_ROOT_WINDOW (selected_frame
);
2817 XWINDOW (minibuf_window
)->mini_p
= Qt
;
2819 /* These values 9 and 10 are arbitrary,
2820 just so that there is "something there."
2821 Correct values are put in in init_xdisp */
2823 XFASTINT (XWINDOW (FRAME_ROOT_WINDOW (selected_frame
))->width
) = 10;
2824 XFASTINT (XWINDOW (minibuf_window
)->width
) = 10;
2826 XFASTINT (XWINDOW (FRAME_ROOT_WINDOW (selected_frame
))->height
) = 9;
2827 XFASTINT (XWINDOW (minibuf_window
)->top
) = 9;
2828 XFASTINT (XWINDOW (minibuf_window
)->height
) = 1;
2830 /* Prevent error in Fset_window_buffer. */
2831 XWINDOW (FRAME_ROOT_WINDOW (selected_frame
))->buffer
= Qt
;
2832 XWINDOW (minibuf_window
)->buffer
= Qt
;
2834 /* Now set them up for real. */
2835 Fset_window_buffer (FRAME_ROOT_WINDOW (selected_frame
),
2836 Fcurrent_buffer ());
2837 Fset_window_buffer (minibuf_window
, get_minibuffer (0));
2839 selected_window
= FRAME_ROOT_WINDOW (selected_frame
);
2840 /* Make sure this window seems more recently used than
2841 a newly-created, never-selected window. Increment
2842 window_select_count so the first selection ever will get
2843 something newer than this. */
2844 XFASTINT (XWINDOW (selected_window
)->use_time
) = ++window_select_count
;
2845 #endif /* not MULTI_FRAME */
2850 Qwindowp
= intern ("windowp");
2851 staticpro (&Qwindowp
);
2853 Qlive_window_p
= intern ("live-window-p");
2854 staticpro (&Qlive_window_p
);
2857 /* Make sure all windows get marked */
2858 staticpro (&minibuf_window
);
2861 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
2862 "Non-nil means call as function to display a help buffer.\n\
2863 Used by `with-output-to-temp-buffer'.");
2864 Vtemp_buffer_show_function
= Qnil
;
2866 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
2867 "If non-nil, function to call to handle `display-buffer'.\n\
2868 It will receive two args, the buffer and a flag which if non-nil means\n\
2869 that the currently selected window is not acceptable.\n\
2870 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
2871 work using this function.");
2872 Vdisplay_buffer_function
= Qnil
;
2874 DEFVAR_LISP ("mouse-window", &Vmouse_window
,
2875 "Window that the last mouse click occurred on.");
2876 Vmouse_window
= Qnil
;
2878 DEFVAR_LISP ("mouse-event", &Vmouse_event
,
2879 "The last mouse-event object. A list of four elements:\n\
2880 ((X-POS Y-POS) WINDOW FRAME-PART KEYSEQ).\n\
2881 KEYSEQ is a string, the key sequence to be looked up in the mouse maps.\n\
2882 WINDOW is the window that the click applies do.\n\
2883 If FRAME-PART is non-nil, the event was on a scrollbar;\n\
2884 then Y-POS is really the total length of the scrollbar, while X-POS is\n\
2885 the relative position of the scrollbar's value within that total length.\n\
2886 FRAME-PART is one of the following symbols:\n\
2887 `vertical-scrollbar', `vertical-slider',\n\
2888 `vertical-thumbup', `vertical-thumbdown',\n\
2889 `horizontal-scrollbar', `horizontal-slider',\n\
2890 `horizontal-thumbleft', `horizontal-thumbright'");
2891 Vmouse_event
= Qnil
;
2893 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
2894 "Non-nil means it is the window that C-M-v in minibuffer should scroll.");
2895 Vminibuf_scroll_window
= Qnil
;
2897 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
2898 "If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.");
2899 Vother_window_scroll_buffer
= Qnil
;
2902 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
2903 "*Non-nil means `display-buffer' should make a separate frame.");
2906 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
2907 "*If non-nil, function to call to handle automatic new frame creation.\n\
2908 It is called with no arguments and should return a newly created frame.\n\
2910 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'\n\
2911 where `pop-up-frame-alist' would hold the default frame parameters.");
2912 Vpop_up_frame_function
= Qnil
;
2915 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
2916 "*Non-nil means display-buffer should make new windows.");
2919 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
2920 "*Number of lines of continuity when scrolling by screenfuls.");
2921 next_screen_context_lines
= 2;
2923 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
2924 "*display-buffer would prefer to split the largest window if this large.\n\
2925 If there is only one window, it is split regardless of this value.");
2926 split_height_threshold
= 500;
2928 DEFVAR_INT ("window-min-height", &window_min_height
,
2929 "*Delete any window less than this tall (including its mode line).");
2930 window_min_height
= 4;
2932 DEFVAR_INT ("window-min-width", &window_min_width
,
2933 "*Delete any window less than this wide.");
2934 window_min_width
= 10;
2936 defsubr (&Sselected_window
);
2937 defsubr (&Sminibuffer_window
);
2938 defsubr (&Swindow_minibuffer_p
);
2939 defsubr (&Swindowp
);
2940 defsubr (&Slive_window_p
);
2941 defsubr (&Spos_visible_in_window_p
);
2942 defsubr (&Swindow_buffer
);
2943 defsubr (&Swindow_height
);
2944 defsubr (&Swindow_width
);
2945 defsubr (&Swindow_hscroll
);
2946 defsubr (&Sset_window_hscroll
);
2947 defsubr (&Swindow_edges
);
2948 defsubr (&Scoordinates_in_window_p
);
2949 defsubr (&Swindow_at
);
2950 defsubr (&Swindow_point
);
2951 defsubr (&Swindow_start
);
2952 defsubr (&Swindow_end
);
2953 defsubr (&Sset_window_point
);
2954 defsubr (&Sset_window_start
);
2955 defsubr (&Swindow_dedicated_p
);
2956 defsubr (&Sset_window_dedicated_p
);
2957 defsubr (&Swindow_display_table
);
2958 defsubr (&Sset_window_display_table
);
2959 defsubr (&Snext_window
);
2960 defsubr (&Sprevious_window
);
2961 defsubr (&Sother_window
);
2962 defsubr (&Sget_lru_window
);
2963 defsubr (&Sget_largest_window
);
2964 defsubr (&Sget_buffer_window
);
2965 defsubr (&Sdelete_other_windows
);
2966 defsubr (&Sdelete_windows_on
);
2967 defsubr (&Sreplace_buffer_in_windows
);
2968 defsubr (&Sdelete_window
);
2969 defsubr (&Sset_window_buffer
);
2970 defsubr (&Sselect_window
);
2971 defsubr (&Sdisplay_buffer
);
2972 defsubr (&Ssplit_window
);
2973 defsubr (&Senlarge_window
);
2974 defsubr (&Sshrink_window
);
2975 defsubr (&Sscroll_up
);
2976 defsubr (&Sscroll_down
);
2977 defsubr (&Sscroll_left
);
2978 defsubr (&Sscroll_right
);
2979 defsubr (&Sscroll_other_window
);
2980 defsubr (&Srecenter
);
2981 defsubr (&Smove_to_window_line
);
2982 defsubr (&Swindow_configuration_p
);
2983 defsubr (&Sset_window_configuration
);
2984 defsubr (&Scurrent_window_configuration
);
2985 defsubr (&Ssave_window_excursion
);
2990 initial_define_key (control_x_map
, '1', "delete-other-windows");
2991 initial_define_key (control_x_map
, '2', "split-window");
2992 initial_define_key (control_x_map
, '0', "delete-window");
2993 initial_define_key (control_x_map
, 'o', "other-window");
2994 initial_define_key (control_x_map
, '^', "enlarge-window");
2995 initial_define_key (control_x_map
, '<', "scroll-left");
2996 initial_define_key (control_x_map
, '>', "scroll-right");
2998 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
2999 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
3000 initial_define_key (meta_map
, 'v', "scroll-down");
3002 initial_define_key (global_map
, Ctl('L'), "recenter");
3003 initial_define_key (meta_map
, 'r', "move-to-window-line");