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 static 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 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
436 "Return window containing row ROW, column COLUMN on FRAME.\n\
437 If omitted, FRAME defaults to the currently selected frame.\n\
438 The top left corner of the frame is considered to be row 0,\n\
441 Lisp_Object row
, column
, frame
;
447 XSET (frame
, Lisp_Frame
, selected_frame
);
449 CHECK_LIVE_FRAME (frame
, 2);
451 CHECK_NUMBER (row
, 0);
452 CHECK_NUMBER (column
, 1);
454 return window_from_coordinates (XFRAME (frame
),
455 XINT (row
), XINT (column
),
459 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
460 "Return current value of point in WINDOW.\n\
461 For a nonselected window, this is the value point would have\n\
462 if that window were selected.\n\
464 Note that, when WINDOW is the selected window and its buffer\n\
465 is also currently selected, the value returned is the same as (point).\n\
466 It would be more strictly correct to return the `top-level' value\n\
467 of point, outside of any save-excursion forms.\n\
468 But that is hard to define.")
472 register struct window
*w
= decode_window (window
);
474 if (w
== XWINDOW (selected_window
)
475 && current_buffer
== XBUFFER (w
->buffer
))
477 return Fmarker_position (w
->pointm
);
480 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
481 "Return position at which display currently starts in WINDOW.")
485 return Fmarker_position (decode_window (window
)->start
);
488 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 1, 0,
489 "Return position at which display currently ends in WINDOW.")
494 struct window
*w
= decode_window (window
);
496 XSET (value
, Lisp_Int
,
497 BUF_Z (current_buffer
) - XFASTINT (w
->window_end_pos
));
502 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
503 "Make point value in WINDOW be at position POS in WINDOW's buffer.")
505 Lisp_Object window
, pos
;
507 register struct window
*w
= decode_window (window
);
509 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
510 if (w
== XWINDOW (selected_window
))
513 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
518 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
519 "Make display in WINDOW start at position POS in WINDOW's buffer.\n\
520 Optional third arg NOFORCE non-nil inhibits next redisplay\n\
521 from overriding motion of point in order to display at this exact start.")
522 (window
, pos
, noforce
)
523 Lisp_Object window
, pos
, noforce
;
525 register struct window
*w
= decode_window (window
);
527 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
528 set_marker_restricted (w
->start
, pos
, w
->buffer
);
529 /* this is not right, but much easier than doing what is right. */
530 w
->start_at_line_beg
= Qnil
;
533 w
->update_mode_line
= Qt
;
534 XFASTINT (w
->last_modified
) = 0;
535 if (!EQ (window
, selected_window
))
536 windows_or_buffers_changed
++;
540 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
542 "Return WINDOW's dedicated object, usually t or nil.\n\
543 See also `set-window-buffer-dedicated'.")
547 return decode_window (window
)->dedicated
;
550 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
551 Sset_window_dedicated_p
, 2, 2, 0,
552 "Control whether WINDOW is dedicated to the buffer it displays.\n\
553 If it is dedicated, Emacs will not automatically change\n\
554 which buffer appears in it.\n\
555 The second argument is the new value for the dedication flag;\n\
558 Lisp_Object window
, arg
;
560 register struct window
*w
= decode_window (window
);
570 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
572 "Return the display-table that WINDOW is using.")
576 return decode_window (window
)->display_table
;
579 /* Get the display table for use currently on window W.
580 This is either W's display table or W's buffer's display table.
581 Ignore the specified tables if they are not valid;
582 if no valid table is specified, return 0. */
585 window_display_table (w
)
589 tem
= w
->display_table
;
590 if (XTYPE (tem
) == Lisp_Vector
&& XVECTOR (tem
)->size
== DISP_TABLE_SIZE
)
591 return XVECTOR (tem
);
592 tem
= XBUFFER (w
->buffer
)->display_table
;
593 if (XTYPE (tem
) == Lisp_Vector
&& XVECTOR (tem
)->size
== DISP_TABLE_SIZE
)
594 return XVECTOR (tem
);
595 tem
= Vstandard_display_table
;
596 if (XTYPE (tem
) == Lisp_Vector
&& XVECTOR (tem
)->size
== DISP_TABLE_SIZE
)
597 return XVECTOR (tem
);
601 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
602 "Set WINDOW's display-table to TABLE.")
604 register Lisp_Object window
, table
;
606 register struct window
*w
;
607 register Lisp_Object z
; /* Return value. */
609 w
= decode_window (window
);
610 w
->display_table
= table
;
614 /* Record info on buffer window w is displaying
615 when it is about to cease to display that buffer. */
618 register struct window
*w
;
620 Lisp_Object buf
= w
->buffer
;
622 if (XBUFFER (buf
) != XMARKER (w
->pointm
)->buffer
)
625 if (w
== XWINDOW (selected_window
)
626 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
627 /* Do this except when the selected window's buffer
628 is being removed from some other window. */
629 XBUFFER (buf
)->last_window_start
= marker_position (w
->start
);
631 /* Point in the selected window's buffer
632 is actually stored in that buffer, and the window's pointm isn't used.
633 So don't clobber point in that buffer. */
634 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
))
635 BUF_PT (XBUFFER (buf
))
636 = clip_to_bounds (BUF_BEGV (XBUFFER (buf
)),
637 marker_position (w
->pointm
),
638 BUF_ZV (XBUFFER (buf
)));
641 /* Put replacement into the window structure in place of old. */
643 replace_window (old
, replacement
)
644 Lisp_Object old
, replacement
;
646 register Lisp_Object tem
;
647 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
649 /* If OLD is its frame's root_window, then replacement is the new
650 root_window for that frame. */
652 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
653 FRAME_ROOT_WINDOW (XFRAME (o
->frame
)) = replacement
;
658 p
->height
= o
->height
;
660 p
->next
= tem
= o
->next
;
662 XWINDOW (tem
)->prev
= replacement
;
664 p
->prev
= tem
= o
->prev
;
666 XWINDOW (tem
)->next
= replacement
;
668 p
->parent
= tem
= o
->parent
;
671 if (EQ (XWINDOW (tem
)->vchild
, old
))
672 XWINDOW (tem
)->vchild
= replacement
;
673 if (EQ (XWINDOW (tem
)->hchild
, old
))
674 XWINDOW (tem
)->hchild
= replacement
;
677 /*** Here, if replacement is a vertical combination
678 and so is its new parent, we should make replacement's
679 children be children of that parent instead. ***/
682 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
683 "Remove WINDOW from the display. Default is selected window.")
685 register Lisp_Object window
;
687 register Lisp_Object tem
, parent
, sib
;
688 register struct window
*p
;
689 register struct window
*par
;
691 /* Because this function is called by other C code on non-leaf
692 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
693 so we can't decode_window here. */
695 window
= selected_window
;
697 CHECK_WINDOW (window
, 0);
698 p
= XWINDOW (window
);
700 /* It's okay to delete an already-deleted window. */
708 error ("Attempt to delete minibuffer or sole ordinary window");
709 par
= XWINDOW (parent
);
711 windows_or_buffers_changed
++;
713 /* Are we trying to delete any frame's selected window? */
715 Lisp_Object frame
= WINDOW_FRAME (XWINDOW (window
));
717 if (EQ (window
, FRAME_SELECTED_WINDOW (XFRAME (frame
))))
719 Lisp_Object alternative
= Fnext_window (window
, Qlambda
, Qnil
);
721 /* If we're about to delete the selected window on the
722 selected frame, then we should use Fselect_window to select
723 the new window. On the other hand, if we're about to
724 delete the selected window on any other frame, we shouldn't do
725 anything but set the frame's selected_window slot. */
726 if (EQ (window
, selected_window
))
727 Fselect_window (alternative
);
729 FRAME_SELECTED_WINDOW (XFRAME (frame
)) = alternative
;
734 /* tem is null for dummy parent windows
735 (which have inferiors but not any contents themselves) */
739 unchain_marker (p
->pointm
);
740 unchain_marker (p
->start
);
745 XWINDOW (tem
)->prev
= p
->prev
;
749 XWINDOW (tem
)->next
= p
->next
;
751 if (EQ (window
, par
->hchild
))
752 par
->hchild
= p
->next
;
753 if (EQ (window
, par
->vchild
))
754 par
->vchild
= p
->next
;
756 /* Find one of our siblings to give our space to. */
760 /* If p gives its space to its next sibling, that sibling needs
761 to have its top/left side pulled back to where p's is.
762 set_window_{height,width} will re-position the sibling's
765 XWINDOW (sib
)->top
= p
->top
;
766 XWINDOW (sib
)->left
= p
->left
;
769 /* Stretch that sibling. */
770 if (!NILP (par
->vchild
))
771 set_window_height (sib
,
772 XFASTINT (XWINDOW (sib
)->height
) + XFASTINT (p
->height
),
774 if (!NILP (par
->hchild
))
775 set_window_width (sib
,
776 XFASTINT (XWINDOW (sib
)->width
) + XFASTINT (p
->width
),
779 /* If parent now has only one child,
780 put the child into the parent's place. */
784 if (NILP (XWINDOW (tem
)->next
))
785 replace_window (parent
, tem
);
787 /* Since we may be deleting combination windows, we must make sure that
788 not only p but all its children have been marked as deleted. */
789 if (! NILP (p
->hchild
))
790 delete_all_subwindows (XWINDOW (p
->hchild
));
791 else if (! NILP (p
->vchild
))
792 delete_all_subwindows (XWINDOW (p
->vchild
));
794 /* Mark this window as deleted. */
795 p
->buffer
= p
->hchild
= p
->vchild
= Qnil
;
801 extern Lisp_Object
next_frame (), prev_frame ();
803 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
804 "Return next window after WINDOW in canonical ordering of windows.\n\
805 If omitted, WINDOW defaults to the selected window.\n\
807 Optional second arg MINIBUF t means count the minibuffer window even\n\
808 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
809 it is active. MINIBUF neither t nor nil means not to count the\n\
810 minibuffer even if it is active.\n\
812 Several frames may share a single minibuffer; if the minibuffer\n\
813 counts, all windows on all frames that share that minibuffer count\n\
814 too. This means that next-window may be used to iterate through the\n\
815 set of windows even when the minibuffer is on another frame. If the\n\
816 minibuffer does not count, only windows from WINDOW's frame count.\n\
818 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
819 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
820 above. If neither nil nor t, restrict to WINDOW's frame.")
821 (window
, minibuf
, all_frames
)
822 register Lisp_Object window
, minibuf
, all_frames
;
824 register Lisp_Object tem
;
825 Lisp_Object start_window
;
828 window
= selected_window
;
830 CHECK_LIVE_WINDOW (window
, 0);
832 start_window
= window
;
834 /* minibuf == nil may or may not include minibuffers.
835 Decide if it does. */
837 minibuf
= (minibuf_level
? Qt
: Qlambda
);
839 /* all_frames == nil doesn't specify which frames to include.
840 Decide which frames it includes. */
841 if (NILP (all_frames
))
842 all_frames
= (EQ (minibuf
, Qt
)
843 ? (FRAME_MINIBUF_WINDOW
846 (XWINDOW (window
)))))
848 else if (! EQ (all_frames
, Qt
))
851 /* Do this loop at least once, to get the next window, and perhaps
852 again, if we hit the minibuffer and that is not acceptable. */
855 /* Find a window that actually has a next one. This loop
856 climbs up the tree. */
857 while (tem
= XWINDOW (window
)->next
, NILP (tem
))
858 if (tem
= XWINDOW (window
)->parent
, !NILP (tem
))
862 /* We've reached the end of this frame.
863 Which other frames are acceptable? */
864 tem
= WINDOW_FRAME (XWINDOW (window
));
866 if (! NILP (all_frames
))
867 tem
= next_frame (tem
, all_frames
);
869 tem
= FRAME_ROOT_WINDOW (XFRAME (tem
));
876 /* If we're in a combination window, find its first child and
877 recurse on that. Otherwise, we've found the window we want. */
880 if (!NILP (XWINDOW (window
)->hchild
))
881 window
= XWINDOW (window
)->hchild
;
882 else if (!NILP (XWINDOW (window
)->vchild
))
883 window
= XWINDOW (window
)->vchild
;
887 /* Which windows are acceptible?
888 Exit the loop and accept this window if
889 this isn't a minibuffer window, or
890 we're accepting minibuffer windows, or
891 we've come all the way around and we're back at the original window. */
892 while (MINI_WINDOW_P (XWINDOW (window
))
893 && ! EQ (minibuf
, Qt
)
894 && ! EQ (window
, start_window
));
899 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
900 "Return the window preceeding WINDOW in canonical ordering of windows.\n\
901 If omitted, WINDOW defaults to the selected window.\n\
903 Optional second arg MINIBUF t means count the minibuffer window even\n\
904 if not active. MINIBUF nil or omitted means count the minibuffer iff\n\
905 it is active. MINIBUF neither t nor nil means not to count the\n\
906 minibuffer even if it is active.\n\
908 Several frames may share a single minibuffer; if the minibuffer\n\
909 counts, all windows on all frames that share that minibuffer count\n\
910 too. This means that previous-window may be used to iterate through\n\
911 the set of windows even when the minibuffer is on another frame. If\n\
912 the minibuffer does not count, only windows from WINDOW's frame\n\
915 Optional third arg ALL-FRAMES t means include windows on all frames.\n\
916 ALL-FRAMES nil or omitted means cycle within the frames as specified\n\
917 above. If neither nil nor t, restrict to WINDOW's frame.")
918 (window
, minibuf
, all_frames
)
919 register Lisp_Object window
, minibuf
, all_frames
;
921 register Lisp_Object tem
;
922 Lisp_Object start_window
;
925 window
= selected_window
;
927 CHECK_LIVE_WINDOW (window
, 0);
929 start_window
= window
;
931 /* minibuf == nil may or may not include minibuffers.
932 Decide if it does. */
934 minibuf
= (minibuf_level
? Qt
: Qlambda
);
936 /* all_frames == nil doesn't specify which frames to include.
937 Decide which frames it includes. */
938 if (NILP (all_frames
))
939 all_frames
= (EQ (minibuf
, Qt
)
940 ? (FRAME_MINIBUF_WINDOW
943 (XWINDOW (window
)))))
945 else if (! EQ (all_frames
, Qt
))
948 /* Do this loop at least once, to get the previous window, and perhaps
949 again, if we hit the minibuffer and that is not acceptable. */
952 /* Find a window that actually has a previous one. This loop
953 climbs up the tree. */
954 while (tem
= XWINDOW (window
)->prev
, NILP (tem
))
955 if (tem
= XWINDOW (window
)->parent
, !NILP (tem
))
959 /* We have found the top window on the frame.
960 Which frames are acceptable? */
961 tem
= WINDOW_FRAME (XWINDOW (window
));
963 if (! NILP (all_frames
))
964 tem
= next_frame (tem
, all_frames
);
966 tem
= FRAME_ROOT_WINDOW (XFRAME (tem
));
972 /* If we're in a combination window, find its last child and
973 recurse on that. Otherwise, we've found the window we want. */
976 if (!NILP (XWINDOW (window
)->hchild
))
977 window
= XWINDOW (window
)->hchild
;
978 else if (!NILP (XWINDOW (window
)->vchild
))
979 window
= XWINDOW (window
)->vchild
;
981 while (tem
= XWINDOW (window
)->next
, !NILP (tem
))
985 /* Which windows are acceptable?
986 Exit the loop and accept this window if
987 this isn't a minibuffer window, or
988 we're accepting minibuffer windows, or
989 we've come all the way around and we're back at the original window. */
990 while (MINI_WINDOW_P (XWINDOW (window
))
992 && !EQ (window
, start_window
));
997 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
998 "Select the ARG'th different window on this frame.\n\
999 All windows on current frame are arranged in a cyclic order.\n\
1000 This command selects the window ARG steps away in that order.\n\
1001 A negative ARG moves in the opposite order. If the optional second\n\
1002 argument ALL_FRAMES is non-nil, cycle through all frames.")
1004 register Lisp_Object n
, all_frames
;
1007 register Lisp_Object w
;
1009 CHECK_NUMBER (n
, 0);
1010 w
= selected_window
;
1015 w
= Fnext_window (w
, Qnil
, all_frames
);
1020 w
= Fprevious_window (w
, Qnil
, all_frames
);
1027 /* Look at all windows, performing an operation specified by TYPE
1029 If FRAMES is Qt, look at all frames, if Qnil, look at just the selected
1030 frame. If FRAMES is a frame, just look at windows on that frame.
1031 If MINI is non-zero, perform the operation on minibuffer windows too.
1037 GET_BUFFER_WINDOW
, /* Arg is buffer */
1038 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
1039 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
1040 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
1042 UNSHOW_BUFFER
, /* Arg is buffer */
1046 window_loop (type
, obj
, mini
, frames
)
1047 enum window_loop type
;
1048 register Lisp_Object obj
, frames
;
1051 register Lisp_Object w
;
1052 register Lisp_Object best_window
;
1053 register Lisp_Object next_window
;
1054 register Lisp_Object last_window
;
1058 /* If we're only looping through windows on a particular frame,
1059 frame points to that frame. If we're looping through windows
1060 on all frames, frame is 0. */
1061 if (FRAMEP (frames
))
1062 frame
= XFRAME (frames
);
1063 else if (NILP (frames
))
1064 frame
= selected_frame
;
1071 /* Pick a window to start with. */
1072 if (XTYPE (obj
) == Lisp_Window
)
1075 w
= FRAME_SELECTED_WINDOW (frame
);
1077 w
= FRAME_SELECTED_WINDOW (selected_frame
);
1079 /* Figure out the last window we're going to mess with. Since
1080 Fnext_window, given the same options, is guaranteed to go in a
1081 ring, we can just use Fprevious_window to find the last one.
1083 We can't just wait until we hit the first window again, because
1084 it might be deleted. */
1088 last_window
= Fprevious_window (w
, (mini
? Qt
: Qnil
), Qlambda
);
1090 #endif /* MULTI_FRAME */
1091 /* We know frame is 0, so we're looping through all frames.
1092 Or we know this isn't a MULTI_FRAME Emacs, so who cares? */
1093 last_window
= Fprevious_window (w
, mini
? Qt
: Qnil
, Qt
);
1098 /* Pick the next window now, since some operations will delete
1099 the current window. */
1102 next_window
= Fnext_window (w
, (mini
? Qt
: Qnil
), Qlambda
);
1104 #endif /* MULTI_FRAME */
1105 /* We know frame is 0, so we're looping through all frames.
1106 Or we know this isn't a MULTI_FRAME Emacs, so who cares? */
1107 next_window
= Fnext_window (w
, mini
? Qt
: Qnil
, Qt
);
1109 if (!MINI_WINDOW_P (XWINDOW (w
))
1110 || (mini
&& minibuf_level
> 0))
1113 case GET_BUFFER_WINDOW
:
1115 /* Ignore invisible and iconified frames. */
1116 if (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (w
))))
1117 || FRAME_ICONIFIED_P (XFRAME (WINDOW_FRAME (XWINDOW (w
)))))
1120 if (XBUFFER (XWINDOW (w
)->buffer
) == XBUFFER (obj
))
1124 case GET_LRU_WINDOW
:
1125 /* t as arg means consider only full-width windows */
1126 if (!NILP (obj
) && XFASTINT (XWINDOW (w
)->width
)
1127 != FRAME_WIDTH (frame
))
1130 /* Ignore invisible and iconified frames. */
1131 if (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (w
))))
1132 || FRAME_ICONIFIED_P (XFRAME (WINDOW_FRAME (XWINDOW (w
)))))
1135 /* Ignore dedicated windows and minibuffers. */
1136 if (MINI_WINDOW_P (XWINDOW (w
))
1137 || !NILP (XWINDOW (w
)->dedicated
))
1139 if (NILP (best_window
)
1140 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1141 > XFASTINT (XWINDOW (w
)->use_time
)))
1145 case DELETE_OTHER_WINDOWS
:
1146 if (XWINDOW (w
) != XWINDOW (obj
))
1150 case DELETE_BUFFER_WINDOWS
:
1151 if (EQ (XWINDOW (w
)->buffer
, obj
))
1153 /* If we're deleting the buffer displayed in the only window
1154 on the frame, find a new buffer to display there. */
1155 if (NILP (XWINDOW (w
)->parent
))
1157 Lisp_Object new_buffer
= Fother_buffer (obj
, Qnil
);
1158 if (NILP (new_buffer
))
1160 = Fget_buffer_create (build_string ("*scratch*"));
1161 Fset_window_buffer (w
, new_buffer
);
1162 Fset_buffer (XWINDOW (w
)->buffer
);
1169 case GET_LARGEST_WINDOW
:
1171 /* Ignore invisible and iconified frames. */
1172 if (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (w
))))
1173 || FRAME_ICONIFIED_P (XFRAME (WINDOW_FRAME (XWINDOW (w
)))))
1176 /* Ignore dedicated windows and minibuffers. */
1177 if (MINI_WINDOW_P (XWINDOW (w
))
1178 || !NILP (XWINDOW (w
)->dedicated
))
1181 struct window
*best_window_ptr
= XWINDOW (best_window
);
1182 struct window
*w_ptr
= XWINDOW (w
);
1183 if (NILP (best_window
) ||
1184 (XFASTINT (w_ptr
->height
) * XFASTINT (w_ptr
->width
))
1185 > (XFASTINT (best_window_ptr
->height
)
1186 * XFASTINT (best_window_ptr
->width
)))
1192 if (EQ (XWINDOW (w
)->buffer
, obj
))
1194 /* Find another buffer to show in this window. */
1195 Lisp_Object another_buffer
= Fother_buffer (obj
, Qnil
);
1196 if (NILP (another_buffer
))
1198 = Fget_buffer_create (build_string ("*scratch*"));
1199 Fset_window_buffer (w
, another_buffer
);
1200 if (EQ (w
, selected_window
))
1201 Fset_buffer (XWINDOW (w
)->buffer
);
1206 if (EQ (w
, last_window
))
1215 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1216 "Return the window least recently selected or used for display.\n\
1217 If optional argument FRAMES is t, search all frames. If FRAME is a\n\
1218 frame, search only that frame.\n")
1222 register Lisp_Object w
;
1223 /* First try for a window that is full-width */
1224 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, frames
);
1225 if (!NILP (w
) && !EQ (w
, selected_window
))
1227 /* If none of them, try the rest */
1228 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, frames
);
1231 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1232 "Return the largest window in area.\n\
1233 If optional argument FRAMES is t, search all frames. If FRAME is a\n\
1234 frame, search only that frame.\n")
1238 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
1242 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
1243 "Return a window currently displaying BUFFER, or nil if none.\n\
1244 If optional argument FRAMES is t, search all frames. If FRAME is a\n\
1245 frame, search only that frame.\n")
1247 Lisp_Object buffer
, frame
;
1249 buffer
= Fget_buffer (buffer
);
1250 if (XTYPE (buffer
) == Lisp_Buffer
)
1251 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, frame
);
1256 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
1258 "Make WINDOW (or the selected window) fill its frame.\n\
1259 Only the frame WINDOW is on is affected.")
1265 struct buffer
*obuf
= current_buffer
;
1269 window
= selected_window
;
1271 CHECK_LIVE_WINDOW (window
, 0);
1273 w
= XWINDOW (window
);
1274 top
= XFASTINT (w
->top
);
1276 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_FRAME(w
));
1278 Fset_buffer (w
->buffer
);
1279 SET_PT (marker_position (w
->start
));
1280 Frecenter (make_number (top
));
1282 set_buffer_internal (obuf
);
1287 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
1288 1, 1, "bDelete windows on (buffer): ",
1289 "Delete all windows showing BUFFER.")
1295 buffer
= Fget_buffer (buffer
);
1296 CHECK_BUFFER (buffer
, 0);
1297 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, Qt
);
1302 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
1303 Sreplace_buffer_in_windows
,
1304 1, 1, "bReplace buffer in windows: ",
1305 "Replace BUFFER with some other buffer in all windows showing it.")
1311 buffer
= Fget_buffer (buffer
);
1312 CHECK_BUFFER (buffer
, 0);
1313 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
1318 /* Set the height of WINDOW and all its inferiors. */
1320 /* The smallest acceptable dimensions for a window. Anything smaller
1321 might crash Emacs. */
1322 #define MIN_SAFE_WINDOW_WIDTH (2)
1323 #define MIN_SAFE_WINDOW_HEIGHT (2)
1325 /* Make sure that window_min_height and window_min_width are
1326 not too small; if they are, set them to safe minima. */
1329 check_min_window_sizes ()
1331 /* Smaller values might permit a crash. */
1332 if (window_min_width
< MIN_SAFE_WINDOW_WIDTH
)
1333 window_min_width
= MIN_SAFE_WINDOW_WIDTH
;
1334 if (window_min_height
< MIN_SAFE_WINDOW_HEIGHT
)
1335 window_min_height
= MIN_SAFE_WINDOW_HEIGHT
;
1338 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
1339 minimum allowable size. */
1341 check_frame_size (frame
, rows
, cols
)
1345 /* For height, we have to see whether the frame has a minibuffer, and
1346 whether it wants a mode line. */
1348 ((FRAME_MINIBUF_ONLY_P (frame
)
1349 || ! FRAME_HAS_MINIBUF_P (frame
))
1350 ? MIN_SAFE_WINDOW_HEIGHT
1351 : 2 * MIN_SAFE_WINDOW_HEIGHT
- 1);
1353 if (*rows
< min_height
)
1355 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
1356 *cols
= MIN_SAFE_WINDOW_WIDTH
;
1359 /* Normally the window is deleted if it gets too small.
1360 nodelete nonzero means do not do this.
1361 (The caller should check later and do so if appropriate) */
1363 set_window_height (window
, height
, nodelete
)
1368 register struct window
*w
= XWINDOW (window
);
1369 register struct window
*c
;
1370 int oheight
= XFASTINT (w
->height
);
1371 int top
, pos
, lastbot
, opos
, lastobot
;
1374 check_min_window_sizes ();
1377 && ! NILP (w
->parent
)
1378 && height
< window_min_height
)
1380 Fdelete_window (window
);
1384 XFASTINT (w
->last_modified
) = 0;
1385 windows_or_buffers_changed
++;
1386 XFASTINT (w
->height
) = height
;
1387 if (!NILP (w
->hchild
))
1389 for (child
= w
->hchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
1391 XWINDOW (child
)->top
= w
->top
;
1392 set_window_height (child
, height
, nodelete
);
1395 else if (!NILP (w
->vchild
))
1397 lastbot
= top
= XFASTINT (w
->top
);
1399 for (child
= w
->vchild
; !NILP (child
); child
= c
->next
)
1401 c
= XWINDOW (child
);
1403 opos
= lastobot
+ XFASTINT (c
->height
);
1405 XFASTINT (c
->top
) = lastbot
;
1407 pos
= (((opos
* height
) << 1) + oheight
) / (oheight
<< 1);
1409 /* Avoid confusion: inhibit deletion of child if becomes too small */
1410 set_window_height (child
, pos
+ top
- lastbot
, 1);
1412 /* Now advance child to next window,
1413 and set lastbot if child was not just deleted. */
1414 lastbot
= pos
+ top
;
1417 /* Now delete any children that became too small. */
1419 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
1421 set_window_height (child
, XINT (XWINDOW (child
)->height
), 0);
1426 /* Recursively set width of WINDOW and its inferiors. */
1428 set_window_width (window
, width
, nodelete
)
1433 register struct window
*w
= XWINDOW (window
);
1434 register struct window
*c
;
1435 int owidth
= XFASTINT (w
->width
);
1436 int left
, pos
, lastright
, opos
, lastoright
;
1439 if (!nodelete
&& width
< window_min_width
)
1441 Fdelete_window (window
);
1445 XFASTINT (w
->last_modified
) = 0;
1446 windows_or_buffers_changed
++;
1447 XFASTINT (w
->width
) = width
;
1448 if (!NILP (w
->vchild
))
1450 for (child
= w
->vchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
1452 XWINDOW (child
)->left
= w
->left
;
1453 set_window_width (child
, width
, nodelete
);
1456 else if (!NILP (w
->hchild
))
1458 lastright
= left
= XFASTINT (w
->left
);
1460 for (child
= w
->hchild
; !NILP (child
); child
= c
->next
)
1462 c
= XWINDOW (child
);
1464 opos
= lastoright
+ XFASTINT (c
->width
);
1466 XFASTINT (c
->left
) = lastright
;
1468 pos
= (((opos
* width
) << 1) + owidth
) / (owidth
<< 1);
1470 /* Inhibit deletion for becoming too small */
1471 set_window_width (child
, pos
+ left
- lastright
, 1);
1473 /* Now advance child to next window,
1474 and set lastright if child was not just deleted. */
1475 lastright
= pos
+ left
, lastoright
= opos
;
1477 /* Delete children that became too small */
1479 for (child
= w
->hchild
; !NILP (child
); child
= XWINDOW (child
)->next
)
1481 set_window_width (child
, XINT (XWINDOW (child
)->width
), 0);
1486 int window_select_count
;
1488 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 2, 0,
1489 "Make WINDOW display BUFFER as its contents.\n\
1490 BUFFER can be a buffer or buffer name.")
1492 register Lisp_Object window
, buffer
;
1494 register Lisp_Object tem
;
1495 register struct window
*w
= decode_window (window
);
1497 buffer
= Fget_buffer (buffer
);
1498 CHECK_BUFFER (buffer
, 1);
1500 if (NILP (XBUFFER (buffer
)->name
))
1501 error ("Attempt to display deleted buffer");
1505 error ("Window is deleted");
1506 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
1507 is first being set up. */
1509 if (!NILP (w
->dedicated
) && !EQ (tem
, buffer
))
1510 error ("Window is dedicated to %s\n", tem
);
1516 Fset_marker (w
->pointm
,
1517 make_number (BUF_PT (XBUFFER (buffer
))),
1519 set_marker_restricted (w
->start
,
1520 make_number (XBUFFER (buffer
)->last_window_start
),
1522 w
->start_at_line_beg
= Qnil
;
1523 XFASTINT (w
->last_modified
) = 0;
1524 windows_or_buffers_changed
++;
1525 if (EQ (window
, selected_window
))
1526 Fset_buffer (buffer
);
1531 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 1, 0,
1532 "Select WINDOW. Most editing will apply to WINDOW's buffer.\n\
1533 The main editor command loop selects the buffer of the selected window\n\
1534 before each command.")
1536 register Lisp_Object window
;
1538 register struct window
*w
;
1539 register struct window
*ow
= XWINDOW (selected_window
);
1541 CHECK_LIVE_WINDOW (window
, 0);
1543 w
= XWINDOW (window
);
1545 if (NILP (w
->buffer
))
1546 error ("Trying to select deleted window or non-leaf window");
1548 XFASTINT (w
->use_time
) = ++window_select_count
;
1549 if (EQ (window
, selected_window
))
1552 Fset_marker (ow
->pointm
, make_number (BUF_PT (XBUFFER (ow
->buffer
))),
1555 selected_window
= window
;
1557 if (XFRAME (WINDOW_FRAME (w
)) != selected_frame
)
1559 XFRAME (WINDOW_FRAME (w
))->selected_window
= window
;
1560 Fselect_frame (WINDOW_FRAME (w
), Qnil
);
1563 selected_frame
->selected_window
= window
;
1566 record_buffer (w
->buffer
);
1567 Fset_buffer (w
->buffer
);
1569 /* Go to the point recorded in the window.
1570 This is important when the buffer is in more
1571 than one window. It also matters when
1572 redisplay_window has altered point after scrolling,
1573 because it makes the change only in the window. */
1575 register int new_point
= marker_position (w
->pointm
);
1576 if (new_point
< BEGV
)
1584 windows_or_buffers_changed
++;
1588 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 2,
1589 "BDisplay buffer:\nP",
1590 "Make BUFFER appear in some window but don't select it.\n\
1591 BUFFER can be a buffer or a buffer name.\n\
1592 If BUFFER is shown already in some window, just use that one,\n\
1593 unless the window is the selected window and the optional second\n\
1594 argument NOT_THIS_WINDOW is non-nil.\n\
1595 Returns the window displaying BUFFER.")
1596 (buffer
, not_this_window
)
1597 register Lisp_Object buffer
, not_this_window
;
1599 register Lisp_Object window
;
1601 buffer
= Fget_buffer (buffer
);
1602 CHECK_BUFFER (buffer
, 0);
1604 if (!NILP (Vdisplay_buffer_function
))
1605 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
1607 if (NILP (not_this_window
)
1608 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
1609 return selected_window
;
1611 window
= Fget_buffer_window (buffer
, Qnil
);
1613 && (NILP (not_this_window
) || !EQ (window
, selected_window
)))
1617 /* If there are no frames open that have more than a minibuffer,
1618 we need to create a new frame. */
1619 if (pop_up_frames
|| last_nonminibuf_frame
== 0)
1622 = Fframe_selected_window (call0 (Vpop_up_frame_function
));
1623 Fset_window_buffer (window
, buffer
);
1625 Fselect_frame (XWINDOW (window
)->frame
, Qnil
);
1629 #endif /* MULTI_FRAME */
1633 || FRAME_MINIBUF_ONLY_P (selected_frame
)
1637 Lisp_Object frames
= Qnil
;
1640 if (FRAME_MINIBUF_ONLY_P (selected_frame
))
1641 XSET (frames
, Lisp_Frame
, last_nonminibuf_frame
);
1643 /* Don't try to create a window if would get an error */
1644 if (split_height_threshold
< window_min_height
<< 1)
1645 split_height_threshold
= window_min_height
<< 1;
1647 window
= Fget_largest_window (frames
);
1650 && window_height (window
) >= split_height_threshold
1652 (XFASTINT (XWINDOW (window
)->width
)
1653 == FRAME_WIDTH (XFRAME (WINDOW_FRAME (XWINDOW (window
))))))
1654 window
= Fsplit_window (window
, Qnil
, Qnil
);
1657 window
= Fget_lru_window (frames
);
1658 if ((EQ (window
, selected_window
)
1659 || EQ (XWINDOW (window
)->parent
, Qnil
))
1660 && window_height (window
) >= window_min_height
<< 1)
1661 window
= Fsplit_window (window
, Qnil
, Qnil
);
1665 window
= Fget_lru_window (Qnil
);
1667 Fset_window_buffer (window
, buffer
);
1672 temp_output_buffer_show (buf
)
1673 register Lisp_Object buf
;
1675 register struct buffer
*old
= current_buffer
;
1676 register Lisp_Object window
;
1677 register struct window
*w
;
1680 XBUFFER (buf
)->save_modified
= MODIFF
;
1685 set_buffer_internal (old
);
1687 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
1688 call1 (Vtemp_buffer_show_function
, buf
);
1691 window
= Fdisplay_buffer (buf
, Qnil
);
1694 if (XFRAME (XWINDOW (window
)->frame
) != selected_frame
)
1695 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
1696 #endif /* MULTI_FRAME */
1697 Vminibuf_scroll_window
= window
;
1698 w
= XWINDOW (window
);
1699 XFASTINT (w
->hscroll
) = 0;
1700 set_marker_restricted (w
->start
, make_number (1), buf
);
1701 set_marker_restricted (w
->pointm
, make_number (1), buf
);
1706 make_dummy_parent (window
)
1709 register Lisp_Object old
, new;
1710 register struct window
*o
, *p
;
1713 XSETTYPE (old
, Lisp_Vector
);
1714 new = Fcopy_sequence (old
);
1715 XSETTYPE (new, Lisp_Window
);
1719 XFASTINT (p
->sequence_number
) = ++sequence_number
;
1721 /* Put new into window structure in place of window */
1722 replace_window (window
, new);
1735 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
1736 "Split WINDOW, putting SIZE lines in the first of the pair.\n\
1737 WINDOW defaults to selected one and SIZE to half its size.\n\
1738 If optional third arg HOR-FLAG is non-nil, split side by side\n\
1739 and put SIZE columns in the first of the pair.")
1740 (window
, chsize
, horflag
)
1741 Lisp_Object window
, chsize
, horflag
;
1743 register Lisp_Object
new;
1744 register struct window
*o
, *p
;
1748 window
= selected_window
;
1750 CHECK_LIVE_WINDOW (window
, 0);
1752 o
= XWINDOW (window
);
1756 if (!NILP (horflag
))
1757 /* Round odd size up, since this is for the left-hand window,
1758 and it will lose a column for the separators. */
1759 size
= ((XFASTINT (o
->width
) + 1) & -2) >> 1;
1761 size
= XFASTINT (o
->height
) >> 1;
1765 CHECK_NUMBER (chsize
, 1);
1766 size
= XINT (chsize
);
1769 if (MINI_WINDOW_P (o
))
1770 error ("Attempt to split minibuffer window");
1771 else if (FRAME_NO_SPLIT_P (XFRAME (WINDOW_FRAME (o
))))
1772 error ("Attempt to split unsplittable frame");
1774 check_min_window_sizes ();
1778 if (size
< window_min_height
1779 || size
+ window_min_height
> XFASTINT (o
->height
))
1780 args_out_of_range_3 (window
, chsize
, horflag
);
1781 if (NILP (o
->parent
)
1782 || NILP (XWINDOW (o
->parent
)->vchild
))
1784 make_dummy_parent (window
);
1786 XWINDOW (new)->vchild
= window
;
1791 if (size
< window_min_width
1792 || size
+ window_min_width
> XFASTINT (o
->width
))
1793 args_out_of_range_3 (window
, chsize
, horflag
);
1794 if (NILP (o
->parent
)
1795 || NILP (XWINDOW (o
->parent
)->hchild
))
1797 make_dummy_parent (window
);
1799 XWINDOW (new)->hchild
= window
;
1803 /* Now we know that window's parent is a vertical combination
1804 if we are dividing vertically, or a horizontal combination
1805 if we are making side-by-side windows */
1807 windows_or_buffers_changed
++;
1808 new = make_window ();
1811 p
->frame
= o
->frame
;
1813 if (!NILP (p
->next
))
1814 XWINDOW (p
->next
)->prev
= new;
1817 p
->parent
= o
->parent
;
1820 Fset_window_buffer (new, o
->buffer
);
1822 /* Apportion the available frame space among the two new windows */
1824 if (!NILP (horflag
))
1826 p
->height
= o
->height
;
1828 XFASTINT (p
->width
) = XFASTINT (o
->width
) - size
;
1829 XFASTINT (o
->width
) = size
;
1830 XFASTINT (p
->left
) = XFASTINT (o
->left
) + size
;
1835 p
->width
= o
->width
;
1836 XFASTINT (p
->height
) = XFASTINT (o
->height
) - size
;
1837 XFASTINT (o
->height
) = size
;
1838 XFASTINT (p
->top
) = XFASTINT (o
->top
) + size
;
1844 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
1845 "Make current window ARG lines bigger.\n\
1846 From program, optional second arg non-nil means grow sideways ARG columns.")
1848 register Lisp_Object n
, side
;
1850 CHECK_NUMBER (n
, 0);
1851 change_window_height (XINT (n
), !NILP (side
));
1855 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
1856 "Make current window ARG lines smaller.\n\
1857 From program, optional second arg non-nil means shrink sideways ARG columns.")
1859 register Lisp_Object n
, side
;
1861 CHECK_NUMBER (n
, 0);
1862 change_window_height (-XINT (n
), !NILP (side
));
1867 window_height (window
)
1870 register struct window
*p
= XWINDOW (window
);
1871 return XFASTINT (p
->height
);
1875 window_width (window
)
1878 register struct window
*p
= XWINDOW (window
);
1879 return XFASTINT (p
->width
);
1882 #define MINSIZE(w) \
1884 ? window_min_width \
1885 : (MINI_WINDOW_P (XWINDOW (w)) ? 1 : window_min_height))
1888 *(widthflag ? (int *) &(XWINDOW (w)->left) : (int *) &(XWINDOW (w)->top))
1890 #define CURSIZE(w) \
1891 *(widthflag ? (int *) &(XWINDOW (w)->width) : (int *) &(XWINDOW (w)->height))
1893 /* Unlike set_window_height, this function
1894 also changes the heights of the siblings so as to
1895 keep everything consistent. */
1897 change_window_height (delta
, widthflag
)
1901 register Lisp_Object parent
;
1903 register struct window
*p
;
1905 int (*sizefun
) () = widthflag
? window_width
: window_height
;
1906 register int (*setsizefun
) () = (widthflag
1908 : set_window_height
);
1910 check_min_window_sizes ();
1912 window
= selected_window
;
1915 p
= XWINDOW (window
);
1920 error ("No other window to side of this one");
1923 if (widthflag
? !NILP (XWINDOW (parent
)->hchild
)
1924 : !NILP (XWINDOW (parent
)->vchild
))
1929 sizep
= &CURSIZE (window
);
1931 if (*sizep
+ delta
< MINSIZE (window
))
1933 Fdelete_window (window
);
1938 register int maxdelta
;
1940 maxdelta
= (!NILP (parent
) ? (*sizefun
) (parent
) - *sizep
1941 : !NILP (p
->next
) ? (*sizefun
) (p
->next
) - MINSIZE (p
->next
)
1942 : !NILP (p
->prev
) ? (*sizefun
) (p
->prev
) - MINSIZE (p
->prev
)
1943 /* This is a frame with only one window, a minibuffer-only
1944 or a minibufferless frame. */
1947 if (delta
> maxdelta
)
1948 /* This case traps trying to make the minibuffer
1949 the full frame, or make the only window aside from the
1950 minibuffer the full frame. */
1957 if (!NILP (p
->next
) &&
1958 (*sizefun
) (p
->next
) - delta
>= MINSIZE (p
->next
))
1960 (*setsizefun
) (p
->next
, (*sizefun
) (p
->next
) - delta
, 0);
1961 (*setsizefun
) (window
, *sizep
+ delta
, 0);
1962 CURBEG (p
->next
) += delta
;
1963 /* This does not change size of p->next,
1964 but it propagates the new top edge to its children */
1965 (*setsizefun
) (p
->next
, (*sizefun
) (p
->next
), 0);
1967 else if (!NILP (p
->prev
) &&
1968 (*sizefun
) (p
->prev
) - delta
>= MINSIZE (p
->prev
))
1970 (*setsizefun
) (p
->prev
, (*sizefun
) (p
->prev
) - delta
, 0);
1971 CURBEG (window
) -= delta
;
1972 (*setsizefun
) (window
, *sizep
+ delta
, 0);
1976 register int delta1
;
1977 register int opht
= (*sizefun
) (parent
);
1979 /* If trying to grow this window to or beyond size of the parent,
1980 make delta1 so big that, on shrinking back down,
1981 all the siblings end up with less than one line and are deleted. */
1982 if (opht
<= *sizep
+ delta
)
1983 delta1
= opht
* opht
* 2;
1984 /* Otherwise, make delta1 just right so that if we add delta1
1985 lines to this window and to the parent, and then shrink
1986 the parent back to its original size, the new proportional
1987 size of this window will increase by delta. */
1989 delta1
= (delta
* opht
* 100) / ((opht
- *sizep
- delta
) * 100);
1991 /* Add delta1 lines or columns to this window, and to the parent,
1992 keeping things consistent while not affecting siblings. */
1993 CURSIZE (parent
) = opht
+ delta1
;
1994 (*setsizefun
) (window
, *sizep
+ delta1
, 0);
1996 /* Squeeze out delta1 lines or columns from our parent,
1997 shriking this window and siblings proportionately.
1998 This brings parent back to correct size.
1999 Delta1 was calculated so this makes this window the desired size,
2000 taking it all out of the siblings. */
2001 (*setsizefun
) (parent
, opht
, 0);
2004 XFASTINT (p
->last_modified
) = 0;
2011 /* Return number of lines of text (not counting mode line) in W. */
2014 window_internal_height (w
)
2017 int ht
= XFASTINT (w
->height
);
2019 if (MINI_WINDOW_P (w
))
2022 if (!NILP (w
->parent
) || !NILP (w
->vchild
) || !NILP (w
->hchild
)
2023 || !NILP (w
->next
) || !NILP (w
->prev
)
2024 || FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (w
))))
2030 /* Scroll contents of window WINDOW up N lines. */
2033 window_scroll (window
, n
, noerror
)
2038 register struct window
*w
= XWINDOW (window
);
2039 register int opoint
= point
;
2041 register int ht
= window_internal_height (w
);
2042 register Lisp_Object tem
;
2044 Lisp_Object bolp
, nmoved
;
2046 XFASTINT (tem
) = point
;
2047 tem
= Fpos_visible_in_window_p (tem
, window
);
2051 Fvertical_motion (make_number (- ht
/ 2));
2052 XFASTINT (tem
) = point
;
2053 Fset_marker (w
->start
, tem
, w
->buffer
);
2054 w
->force_start
= Qt
;
2057 SET_PT (marker_position (w
->start
));
2058 lose
= n
< 0 && point
== BEGV
;
2059 Fvertical_motion (make_number (n
));
2069 Fsignal (Qbeginning_of_buffer
, Qnil
);
2074 set_marker_restricted (w
->start
, make_number (pos
), w
->buffer
);
2075 w
->start_at_line_beg
= bolp
;
2076 w
->update_mode_line
= Qt
;
2077 XFASTINT (w
->last_modified
) = 0;
2083 tem
= Fvertical_motion (make_number (ht
));
2084 if (point
> opoint
|| XFASTINT (tem
) < ht
)
2087 Fvertical_motion (make_number (-1));
2095 Fsignal (Qend_of_buffer
, Qnil
);
2099 /* This is the guts of Fscroll_up and Fscroll_down. */
2102 scroll_command (n
, direction
)
2103 register Lisp_Object n
;
2106 register int defalt
;
2107 int count
= specpdl_ptr
- specpdl
;
2109 /* If selected window's buffer isn't current, make it current for the moment.
2110 But don't screw up if window_scroll gets an error. */
2111 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
2113 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
2114 Fset_buffer (XWINDOW (selected_window
)->buffer
);
2117 defalt
= (window_internal_height (XWINDOW (selected_window
))
2118 - next_screen_context_lines
);
2119 defalt
= direction
* (defalt
< 1 ? 1 : defalt
);
2122 window_scroll (selected_window
, defalt
, 0);
2123 else if (EQ (n
, Qminus
))
2124 window_scroll (selected_window
, - defalt
, 0);
2127 n
= Fprefix_numeric_value (n
);
2128 window_scroll (selected_window
, XINT (n
) * direction
, 0);
2131 unbind_to (count
, Qnil
);
2134 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
2135 "Scroll text of current window upward ARG lines; or near full screen if no ARG.\n\
2136 A near full screen is `next-screen-context-lines' less than a full screen.\n\
2137 When calling from a program, supply a number as argument or nil.")
2141 scroll_command (n
, 1);
2145 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
2146 "Scroll text of current window downward ARG lines; or near full screen if no ARG.\n\
2147 A near full screen is `next-screen-context-lines' less than a full screen.\n\
2148 When calling from a program, supply a number as argument or nil.")
2152 scroll_command (n
, -1);
2156 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
2157 "Scroll next window upward ARG lines; or near full screen if no ARG.\n\
2158 The next window is the one below the current one; or the one at the top\n\
2159 if the current one is at the bottom.\n\
2160 When calling from a program, supply a number as argument or nil.\n\
2162 If in the minibuffer, `minibuf-scroll-window' if non-nil\n\
2163 specifies the window to scroll.\n\
2164 If `other-window-scroll-buffer' is non-nil, scroll the window\n\
2165 showing that buffer, popping the buffer up if necessary.")
2167 register Lisp_Object n
;
2169 register Lisp_Object window
;
2171 register struct window
*w
;
2172 register int count
= specpdl_ptr
- specpdl
;
2174 if (MINI_WINDOW_P (XWINDOW (selected_window
))
2175 && !NILP (Vminibuf_scroll_window
))
2176 window
= Vminibuf_scroll_window
;
2177 /* If buffer is specified, scroll that buffer. */
2178 else if (!NILP (Vother_window_scroll_buffer
))
2180 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
2182 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
);
2185 /* Nothing specified; pick a neighboring window. */
2186 window
= Fnext_window (selected_window
, Qnil
, Qt
);
2187 CHECK_LIVE_WINDOW (window
, 0);
2189 if (EQ (window
, selected_window
))
2190 error ("There is no other window");
2192 w
= XWINDOW (window
);
2193 ht
= window_internal_height (w
);
2195 /* Don't screw up if window_scroll gets an error. */
2196 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
2198 Fset_buffer (w
->buffer
);
2199 SET_PT (marker_position (w
->pointm
));
2202 window_scroll (window
, ht
- next_screen_context_lines
, 1);
2203 else if (EQ (n
, Qminus
))
2204 window_scroll (window
, next_screen_context_lines
- ht
, 1);
2207 if (XTYPE (n
) == Lisp_Cons
)
2209 CHECK_NUMBER (n
, 0);
2210 window_scroll (window
, XINT (n
), 1);
2213 Fset_marker (w
->pointm
, make_number (point
), Qnil
);
2219 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 1, 1, "P",
2220 "Scroll selected window display ARG columns left.\n\
2221 Default for ARG is window width minus 2.")
2223 register Lisp_Object arg
;
2227 XFASTINT (arg
) = XFASTINT (XWINDOW (selected_window
)->width
) - 2;
2229 arg
= Fprefix_numeric_value (arg
);
2232 Fset_window_hscroll (selected_window
,
2233 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
2237 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 1, 1, "P",
2238 "Scroll selected window display ARG columns right.\n\
2239 Default for ARG is window width minus 2.")
2241 register Lisp_Object arg
;
2244 XFASTINT (arg
) = XFASTINT (XWINDOW (selected_window
)->width
) - 2;
2246 arg
= Fprefix_numeric_value (arg
);
2249 Fset_window_hscroll (selected_window
,
2250 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
2254 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
2255 "Center point in window and redisplay frame. With ARG, put point on line ARG.\n\
2256 The desired position of point is always relative to the current window.\n\
2257 Just C-u as prefix means put point in the center of the window.\n\
2258 No arg (i.e., it is nil) erases the entire frame and then\n\
2259 redraws with point in the center of the current window.")
2261 register Lisp_Object n
;
2263 register struct window
*w
= XWINDOW (selected_window
);
2264 register int ht
= window_internal_height (w
);
2265 register int opoint
= point
;
2269 extern int frame_garbaged
;
2271 SET_FRAME_GARBAGED (XFRAME (WINDOW_FRAME (w
)));
2272 XFASTINT (n
) = ht
/ 2;
2274 else if (XTYPE (n
) == Lisp_Cons
) /* Just C-u. */
2276 XFASTINT (n
) = ht
/ 2;
2280 n
= Fprefix_numeric_value (n
);
2281 CHECK_NUMBER (n
, 0);
2285 XSETINT (n
, XINT (n
) + ht
);
2287 XSETINT (n
, - XINT (n
));
2289 Fvertical_motion (n
);
2290 Fset_marker (w
->start
, make_number (point
), w
->buffer
);
2291 w
->start_at_line_beg
= Fbolp ();
2294 w
->force_start
= Qt
;
2299 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
2301 "Position point relative to window.\n\
2302 With no argument, position text at center of window.\n\
2303 An argument specifies frame line; zero means top of window,\n\
2304 negative means relative to bottom of window.")
2306 register Lisp_Object arg
;
2308 register struct window
*w
= XWINDOW (selected_window
);
2309 register int height
= window_internal_height (w
);
2313 XFASTINT (arg
) = height
/ 2;
2316 arg
= Fprefix_numeric_value (arg
);
2318 XSETINT (arg
, XINT (arg
) + height
);
2321 start
= marker_position (w
->start
);
2322 if (start
< BEGV
|| start
> ZV
)
2324 Fvertical_motion (make_number (- height
/ 2));
2325 Fset_marker (w
->start
, make_number (point
), w
->buffer
);
2326 w
->start_at_line_beg
= Fbolp ();
2327 w
->force_start
= Qt
;
2332 return Fvertical_motion (arg
);
2335 struct save_window_data
2337 int size_from_Lisp_Vector_struct
;
2338 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
2339 Lisp_Object frame_width
, frame_height
;
2340 Lisp_Object selected_frame
;
2341 Lisp_Object current_window
;
2342 Lisp_Object current_buffer
;
2343 Lisp_Object minibuf_scroll_window
;
2344 Lisp_Object root_window
;
2345 Lisp_Object focus_frame
;
2346 /* A vector, interpreted as a struct saved_window */
2347 Lisp_Object saved_windows
;
2350 /* Arg to Fmake_vector */
2351 #define SAVE_WINDOW_DATA_SIZE \
2352 ((sizeof (struct save_window_data) \
2353 - (sizeof (struct Lisp_Vector) \
2354 /* Don't count the contents member of the struct Lisp_Vector */ \
2355 - sizeof (Lisp_Object))) \
2356 / sizeof (Lisp_Object))
2358 /* This is saved as a Lisp_Vector */
2361 /* these first two must agree with struct Lisp_Vector in lisp.h */
2362 int size_from_Lisp_Vector_struct
;
2363 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
2366 Lisp_Object buffer
, start
, pointm
, mark
;
2367 Lisp_Object left
, top
, width
, height
, hscroll
;
2368 Lisp_Object parent
, prev
;
2369 Lisp_Object start_at_line_beg
;
2370 Lisp_Object display_table
;
2372 #define SAVED_WINDOW_VECTOR_SIZE 14 /* Arg to Fmake_vector */
2374 #define SAVED_WINDOW_N(swv,n) \
2375 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
2377 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
2378 "T if OBJECT is a window-configration object.")
2382 if (XTYPE (obj
) == Lisp_Window_Configuration
)
2388 DEFUN ("set-window-configuration",
2389 Fset_window_configuration
, Sset_window_configuration
,
2391 "Set the configuration of windows and buffers as specified by CONFIGURATION.\n\
2392 CONFIGURATION must be a value previously returned\n\
2393 by `current-window-configuration' (which see).")
2395 Lisp_Object configuration
;
2397 register struct window
*w
;
2398 register struct save_window_data
*data
;
2399 struct Lisp_Vector
*saved_windows
;
2400 register struct saved_window
*p
;
2401 register Lisp_Object tem
;
2402 Lisp_Object new_current_buffer
;
2406 /* If the frame has been resized since this window configuration was
2407 made, we change the frame to the size specified in the
2408 configuration, restore the configuration, and then resize it
2409 back. We keep track of the prevailing height in these variables. */
2410 int previous_frame_height
;
2411 int previous_frame_width
;
2413 while (XTYPE (configuration
) != Lisp_Window_Configuration
)
2415 configuration
= wrong_type_argument (intern ("window-configuration-p"),
2419 data
= (struct save_window_data
*) XVECTOR (configuration
);
2420 saved_windows
= XVECTOR (data
->saved_windows
);
2422 f
= XFRAME (XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
);
2424 previous_frame_height
= FRAME_HEIGHT (f
);
2425 previous_frame_width
= FRAME_WIDTH (f
);
2426 if (XFASTINT (data
->frame_height
) != previous_frame_height
2427 || XFASTINT (data
->frame_width
) != previous_frame_width
)
2428 change_frame_size (f
, data
->frame_height
, data
->frame_width
, 0, 0);
2430 windows_or_buffers_changed
++;
2431 new_current_buffer
= data
->current_buffer
;
2432 if (NILP (XBUFFER (new_current_buffer
)->name
))
2433 new_current_buffer
= Qnil
;
2436 Mark all windows now on frame as "deleted".
2437 Restoring the new configuration "undeletes" any that are in it.
2439 Save their current buffers in their height fields, since we may
2440 need it later, if a buffer saved in the configuration is now
2442 delete_all_subwindows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
2444 for (k
= 0; k
< saved_windows
->size
; k
++)
2446 p
= SAVED_WINDOW_N (saved_windows
, k
);
2447 w
= XWINDOW (p
->window
);
2450 if (!NILP (p
->parent
))
2451 w
->parent
= SAVED_WINDOW_N (saved_windows
, XFASTINT (p
->parent
))->window
;
2455 if (!NILP (p
->prev
))
2457 w
->prev
= SAVED_WINDOW_N (saved_windows
, XFASTINT (p
->prev
))->window
;
2458 XWINDOW (w
->prev
)->next
= p
->window
;
2463 if (!NILP (w
->parent
))
2465 if (EQ (p
->width
, XWINDOW (w
->parent
)->width
))
2467 XWINDOW (w
->parent
)->vchild
= p
->window
;
2468 XWINDOW (w
->parent
)->hchild
= Qnil
;
2472 XWINDOW (w
->parent
)->hchild
= p
->window
;
2473 XWINDOW (w
->parent
)->vchild
= Qnil
;
2478 /* If we squirreled away the buffer in the window's height,
2480 if (XTYPE (w
->height
) == Lisp_Buffer
)
2481 w
->buffer
= w
->height
;
2484 w
->width
= p
->width
;
2485 w
->height
= p
->height
;
2486 w
->hscroll
= p
->hscroll
;
2487 w
->display_table
= p
->display_table
;
2488 XFASTINT (w
->last_modified
) = 0;
2490 /* Reinstall the saved buffer and pointers into it. */
2491 if (NILP (p
->buffer
))
2492 w
->buffer
= p
->buffer
;
2495 if (!NILP (XBUFFER (p
->buffer
)->name
))
2496 /* If saved buffer is alive, install it. */
2498 w
->buffer
= p
->buffer
;
2499 w
->start_at_line_beg
= p
->start_at_line_beg
;
2500 set_marker_restricted (w
->start
, Fmarker_position (p
->start
), w
->buffer
);
2501 set_marker_restricted (w
->pointm
, Fmarker_position (p
->pointm
), w
->buffer
);
2502 Fset_marker (XBUFFER (w
->buffer
)->mark
,
2503 Fmarker_position (p
->mark
), w
->buffer
);
2505 /* As documented in Fcurrent_window_configuration, don't
2506 save the location of point in the buffer which was current
2507 when the window configuration was recorded. */
2508 if (!EQ (p
->buffer
, new_current_buffer
) &&
2509 XBUFFER (p
->buffer
) == current_buffer
)
2510 Fgoto_char (w
->pointm
);
2512 else if (NILP (XBUFFER (w
->buffer
)->name
))
2513 /* Else if window's old buffer is dead too, get a live one. */
2515 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
2516 /* This will set the markers to beginning of visible range. */
2517 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
2518 set_marker_restricted (w
->pointm
, make_number (0), w
->buffer
);
2519 w
->start_at_line_beg
= Qt
;
2522 /* Keeping window's old buffer; make sure the markers are real. */
2523 /* Else if window's old buffer is dead too, get a live one. */
2525 /* Set window markers at start of visible range. */
2526 if (XMARKER (w
->start
)->buffer
== 0)
2527 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
2528 if (XMARKER (w
->pointm
)->buffer
== 0)
2529 set_marker_restricted (w
->pointm
,
2530 make_number (BUF_PT (XBUFFER (w
->buffer
))),
2532 w
->start_at_line_beg
= Qt
;
2537 FRAME_ROOT_WINDOW (f
) = data
->root_window
;
2538 Fselect_window (data
->current_window
);
2540 /* Fselect_window will have made f the selected frame, so we
2541 reselect the proper frame here. Fselect_frame will change the
2542 selected window too, but that doesn't make the call to
2543 Fselect_window above totally superfluous; it still sets f's
2545 Fselect_frame (data
->selected_frame
);
2547 if (!NILP (new_current_buffer
))
2548 Fset_buffer (new_current_buffer
);
2554 XSET (frame
, Lisp_Frame
, f
);
2555 Fredirect_frame_focus (frame
, data
->focus_frame
);
2559 #if 0 /* I don't understand why this is needed, and it causes
2560 problems when the frame's old selected window has been
2563 if (f
!= selected_frame
&& ! FRAME_TERMCAP_P (f
))
2564 Fselect_frame (WINDOW_FRAME (XWINDOW (data
->root_window
)), Qnil
);
2568 /* Set the screen height to the value it had before this function. */
2569 if (previous_frame_height
!= FRAME_HEIGHT (f
)
2570 || previous_frame_width
!= FRAME_WIDTH (f
))
2571 change_frame_size (f
, previous_frame_height
, previous_frame_width
, 0, 0);
2573 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
2577 /* Mark all windows now on frame as deleted
2578 by setting their buffers to nil. */
2581 delete_all_subwindows (w
)
2582 register struct window
*w
;
2584 if (!NILP (w
->next
))
2585 delete_all_subwindows (XWINDOW (w
->next
));
2586 if (!NILP (w
->vchild
))
2587 delete_all_subwindows (XWINDOW (w
->vchild
));
2588 if (!NILP (w
->hchild
))
2589 delete_all_subwindows (XWINDOW (w
->hchild
));
2591 w
->height
= w
->buffer
; /* See Fset_window_configuration for excuse. */
2593 /* We set all three of these fields to nil, to make sure that we can
2594 distinguish this dead window from any live window. Live leaf
2595 windows will have buffer set, and combination windows will have
2596 vchild or hchild set. */
2603 count_windows (window
)
2604 register struct window
*window
;
2606 register int count
= 1;
2607 if (!NILP (window
->next
))
2608 count
+= count_windows (XWINDOW (window
->next
));
2609 if (!NILP (window
->vchild
))
2610 count
+= count_windows (XWINDOW (window
->vchild
));
2611 if (!NILP (window
->hchild
))
2612 count
+= count_windows (XWINDOW (window
->hchild
));
2617 save_window_save (window
, vector
, i
)
2619 struct Lisp_Vector
*vector
;
2622 register struct saved_window
*p
;
2623 register struct window
*w
;
2624 register Lisp_Object tem
;
2626 for (;!NILP (window
); window
= w
->next
)
2628 p
= SAVED_WINDOW_N (vector
, i
);
2629 w
= XWINDOW (window
);
2631 XFASTINT (w
->temslot
) = i
++;
2633 p
->buffer
= w
->buffer
;
2636 p
->width
= w
->width
;
2637 p
->height
= w
->height
;
2638 p
->hscroll
= w
->hscroll
;
2639 p
->display_table
= w
->display_table
;
2640 if (!NILP (w
->buffer
))
2642 /* Save w's value of point in the window configuration.
2643 If w is the selected window, then get the value of point
2644 from the buffer; pointm is garbage in the selected window. */
2645 if (EQ (window
, selected_window
))
2647 p
->pointm
= Fmake_marker ();
2648 Fset_marker (p
->pointm
, BUF_PT (XBUFFER (w
->buffer
)),
2652 p
->pointm
= Fcopy_marker (w
->pointm
);
2654 p
->start
= Fcopy_marker (w
->start
);
2655 p
->start_at_line_beg
= w
->start_at_line_beg
;
2657 tem
= XBUFFER (w
->buffer
)->mark
;
2658 p
->mark
= Fcopy_marker (tem
);
2665 p
->start_at_line_beg
= Qnil
;
2668 if (NILP (w
->parent
))
2671 p
->parent
= XWINDOW (w
->parent
)->temslot
;
2676 p
->prev
= XWINDOW (w
->prev
)->temslot
;
2678 if (!NILP (w
->vchild
))
2679 i
= save_window_save (w
->vchild
, vector
, i
);
2680 if (!NILP (w
->hchild
))
2681 i
= save_window_save (w
->hchild
, vector
, i
);
2687 DEFUN ("current-window-configuration",
2688 Fcurrent_window_configuration
, Scurrent_window_configuration
, 0, 1, 0,
2689 "Return an object representing the current window configuration of FRAME.\n\
2690 If FRAME is nil or omitted, use the selected frame.\n\
2691 This describes the number of windows, their sizes and current buffers,\n\
2692 and for each displayed buffer, where display starts, and the positions of\n\
2693 point and mark. An exception is made for point in the current buffer:\n\
2694 its value is -not- saved.\n\
2695 This also records the currently selected frame, and FRAME's focus\n\
2696 redirection (see `redirect-frame-focus').")
2700 register Lisp_Object tem
;
2701 register int n_windows
;
2702 register struct save_window_data
*data
;
2710 CHECK_LIVE_FRAME (frame
, 0);
2714 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
2715 data
= (struct save_window_data
*)
2716 XVECTOR (Fmake_vector (make_number (SAVE_WINDOW_DATA_SIZE
),
2718 XFASTINT (data
->frame_width
) = FRAME_WIDTH (f
);
2719 XFASTINT (data
->frame_height
) = FRAME_HEIGHT (f
);
2720 XSET (data
->selected_frame
, Lisp_Frame
, selected_frame
);
2721 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
2722 XSET (data
->current_buffer
, Lisp_Buffer
, current_buffer
);
2723 data
->minibuf_scroll_window
= Vminibuf_scroll_window
;
2724 data
->root_window
= FRAME_ROOT_WINDOW (f
);
2725 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
2726 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
2727 data
->saved_windows
= tem
;
2728 for (i
= 0; i
< n_windows
; i
++)
2729 XVECTOR (tem
)->contents
[i
]
2730 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
2731 save_window_save (FRAME_ROOT_WINDOW (f
),
2733 XSET (tem
, Lisp_Window_Configuration
, data
);
2737 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
2739 "Execute body, preserving window sizes and contents.\n\
2740 Restores which buffer appears in which window, where display starts,\n\
2741 as well as the current buffer.\n\
2742 Does not restore the value of point in current buffer.")
2746 register Lisp_Object val
;
2747 register int count
= specpdl_ptr
- specpdl
;
2749 record_unwind_protect (Fset_window_configuration
,
2750 Fcurrent_window_configuration (Qnil
));
2751 val
= Fprogn (args
);
2752 return unbind_to (count
, val
);
2758 selected_frame
= make_terminal_frame ();
2759 minibuf_window
= selected_frame
->minibuffer_window
;
2760 selected_window
= selected_frame
->selected_window
;
2761 last_nonminibuf_frame
= selected_frame
;
2762 #else /* not MULTI_FRAME */
2763 extern Lisp_Object
get_minibuffer ();
2765 minibuf_window
= make_window ();
2766 FRAME_ROOT_WINDOW (selected_frame
) = make_window ();
2768 XWINDOW (FRAME_ROOT_WINDOW (selected_frame
))->next
= minibuf_window
;
2769 XWINDOW (minibuf_window
)->prev
= FRAME_ROOT_WINDOW (selected_frame
);
2770 XWINDOW (minibuf_window
)->mini_p
= Qt
;
2772 /* These values 9 and 10 are arbitrary,
2773 just so that there is "something there."
2774 Correct values are put in in init_xdisp */
2776 XFASTINT (XWINDOW (FRAME_ROOT_WINDOW (selected_frame
))->width
) = 10;
2777 XFASTINT (XWINDOW (minibuf_window
)->width
) = 10;
2779 XFASTINT (XWINDOW (FRAME_ROOT_WINDOW (selected_frame
))->height
) = 9;
2780 XFASTINT (XWINDOW (minibuf_window
)->top
) = 9;
2781 XFASTINT (XWINDOW (minibuf_window
)->height
) = 1;
2783 /* Prevent error in Fset_window_buffer. */
2784 XWINDOW (FRAME_ROOT_WINDOW (selected_frame
))->buffer
= Qt
;
2785 XWINDOW (minibuf_window
)->buffer
= Qt
;
2787 /* Now set them up for real. */
2788 Fset_window_buffer (FRAME_ROOT_WINDOW (selected_frame
),
2789 Fcurrent_buffer ());
2790 Fset_window_buffer (minibuf_window
, get_minibuffer (0));
2792 selected_window
= FRAME_ROOT_WINDOW (selected_frame
);
2793 /* Make sure this window seems more recently used than
2794 a newly-created, never-selected window. Increment
2795 window_select_count so the first selection ever will get
2796 something newer than this. */
2797 XFASTINT (XWINDOW (selected_window
)->use_time
) = ++window_select_count
;
2798 #endif /* not MULTI_FRAME */
2803 Qwindowp
= intern ("windowp");
2804 staticpro (&Qwindowp
);
2806 Qlive_window_p
= intern ("live-window-p");
2807 staticpro (&Qlive_window_p
);
2810 /* Make sure all windows get marked */
2811 staticpro (&minibuf_window
);
2814 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
2815 "Non-nil means call as function to display a help buffer.\n\
2816 Used by `with-output-to-temp-buffer'.");
2817 Vtemp_buffer_show_function
= Qnil
;
2819 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
2820 "If non-nil, function to call to handle `display-buffer'.\n\
2821 It will receive two args, the buffer and a flag which if non-nil means\n\
2822 that the currently selected window is not acceptable.\n\
2823 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
2824 work using this function.");
2825 Vdisplay_buffer_function
= Qnil
;
2827 DEFVAR_LISP ("mouse-window", &Vmouse_window
,
2828 "Window that the last mouse click occurred on.");
2829 Vmouse_window
= Qnil
;
2831 DEFVAR_LISP ("mouse-event", &Vmouse_event
,
2832 "The last mouse-event object. A list of four elements:\n\
2833 ((X-POS Y-POS) WINDOW FRAME-PART KEYSEQ).\n\
2834 KEYSEQ is a string, the key sequence to be looked up in the mouse maps.\n\
2835 WINDOW is the window that the click applies do.\n\
2836 If FRAME-PART is non-nil, the event was on a scrollbar;\n\
2837 then Y-POS is really the total length of the scrollbar, while X-POS is\n\
2838 the relative position of the scrollbar's value within that total length.\n\
2839 FRAME-PART is one of the following symbols:\n\
2840 `vertical-scrollbar', `vertical-slider',\n\
2841 `vertical-thumbup', `vertical-thumbdown',\n\
2842 `horizontal-scrollbar', `horizontal-slider',\n\
2843 `horizontal-thumbleft', `horizontal-thumbright'");
2844 Vmouse_event
= Qnil
;
2846 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
2847 "Non-nil means it is the window that C-M-v in minibuffer should scroll.");
2848 Vminibuf_scroll_window
= Qnil
;
2850 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
2851 "If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.");
2852 Vother_window_scroll_buffer
= Qnil
;
2855 DEFVAR_BOOL ("pop-up-frames", &pop_up_frames
,
2856 "*Non-nil means `display-buffer' should make a separate frame.");
2859 DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function
,
2860 "*If non-nil, function to call to handle automatic new frame creation.\n\
2861 It is called with no arguments and should return a newly created frame.\n\
2863 A typical value might be `(lambda () (new-frame pop-up-frame-alist))'\n\
2864 where `pop-up-frame-alist' would hold the default frame parameters.");
2865 Vpop_up_frame_function
= Qnil
;
2868 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
2869 "*Non-nil means display-buffer should make new windows.");
2872 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
2873 "*Number of lines of continuity when scrolling by screenfuls.");
2874 next_screen_context_lines
= 2;
2876 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
2877 "*display-buffer would prefer to split the largest window if this large.\n\
2878 If there is only one window, it is split regardless of this value.");
2879 split_height_threshold
= 500;
2881 DEFVAR_INT ("window-min-height", &window_min_height
,
2882 "*Delete any window less than this tall (including its mode line).");
2883 window_min_height
= 4;
2885 DEFVAR_INT ("window-min-width", &window_min_width
,
2886 "*Delete any window less than this wide.");
2887 window_min_width
= 10;
2889 defsubr (&Sselected_window
);
2890 defsubr (&Sminibuffer_window
);
2891 defsubr (&Swindow_minibuffer_p
);
2892 defsubr (&Swindowp
);
2893 defsubr (&Slive_window_p
);
2894 defsubr (&Spos_visible_in_window_p
);
2895 defsubr (&Swindow_buffer
);
2896 defsubr (&Swindow_height
);
2897 defsubr (&Swindow_width
);
2898 defsubr (&Swindow_hscroll
);
2899 defsubr (&Sset_window_hscroll
);
2900 defsubr (&Swindow_edges
);
2901 defsubr (&Scoordinates_in_window_p
);
2902 defsubr (&Swindow_at
);
2903 defsubr (&Swindow_point
);
2904 defsubr (&Swindow_start
);
2905 defsubr (&Swindow_end
);
2906 defsubr (&Sset_window_point
);
2907 defsubr (&Sset_window_start
);
2908 defsubr (&Swindow_dedicated_p
);
2909 defsubr (&Sset_window_dedicated_p
);
2910 defsubr (&Swindow_display_table
);
2911 defsubr (&Sset_window_display_table
);
2912 defsubr (&Snext_window
);
2913 defsubr (&Sprevious_window
);
2914 defsubr (&Sother_window
);
2915 defsubr (&Sget_lru_window
);
2916 defsubr (&Sget_largest_window
);
2917 defsubr (&Sget_buffer_window
);
2918 defsubr (&Sdelete_other_windows
);
2919 defsubr (&Sdelete_windows_on
);
2920 defsubr (&Sreplace_buffer_in_windows
);
2921 defsubr (&Sdelete_window
);
2922 defsubr (&Sset_window_buffer
);
2923 defsubr (&Sselect_window
);
2924 defsubr (&Sdisplay_buffer
);
2925 defsubr (&Ssplit_window
);
2926 defsubr (&Senlarge_window
);
2927 defsubr (&Sshrink_window
);
2928 defsubr (&Sscroll_up
);
2929 defsubr (&Sscroll_down
);
2930 defsubr (&Sscroll_left
);
2931 defsubr (&Sscroll_right
);
2932 defsubr (&Sscroll_other_window
);
2933 defsubr (&Srecenter
);
2934 defsubr (&Smove_to_window_line
);
2935 defsubr (&Swindow_configuration_p
);
2936 defsubr (&Sset_window_configuration
);
2937 defsubr (&Scurrent_window_configuration
);
2938 defsubr (&Ssave_window_excursion
);
2943 initial_define_key (control_x_map
, '1', "delete-other-windows");
2944 initial_define_key (control_x_map
, '2', "split-window");
2945 initial_define_key (control_x_map
, '0', "delete-window");
2946 initial_define_key (control_x_map
, 'o', "other-window");
2947 initial_define_key (control_x_map
, '^', "enlarge-window");
2948 initial_define_key (control_x_map
, '<', "scroll-left");
2949 initial_define_key (control_x_map
, '>', "scroll-right");
2951 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
2952 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
2953 initial_define_key (meta_map
, 'v', "scroll-down");
2955 initial_define_key (global_map
, Ctl('L'), "recenter");
2956 initial_define_key (meta_map
, 'r', "move-to-window-line");