1 /* Window creation, deletion and examination for GNU Emacs.
2 Does not include redisplay.
3 Copyright (C) 1985, 1986, 1987 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 1, 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. */
33 Lisp_Object
Fnext_window (), Fdelete_window (), Fselect_window ();
34 Lisp_Object
Fset_window_buffer (), Fsplit_window (), Frecenter ();
36 static void delete_all_subwindows ();
37 static struct window
*decode_window();
39 /* This is the window in which the terminal's cursor should
40 be left when nothing is being done with it. This must
41 always be a leaf window, and its buffer is selected by
42 the top level editing loop at the end of each command.
44 This value is always the same as
45 SCREEN_SELECTED_WINDOW (selected_screen). */
47 Lisp_Object selected_window
;
51 /* The root window for the screen.
52 This is accessed via SCREEN_ROOT_WINDOW (selected_screen). */
53 Lisp_Object root_window
;
57 /* The minibuffer window of the selected screen.
58 Note that you cannot test for minibufferness of an arbitrary window
59 by comparing against this; but you can test for minibufferness of
60 the selected window. */
61 Lisp_Object minibuf_window
;
63 /* Non-nil means it is the window for C-M-v to scroll
64 when the minibuffer is selected. */
65 Lisp_Object Vminibuf_scroll_window
;
67 /* Non-nil means this is the buffer whose window C-M-v should scroll. */
68 Lisp_Object Vother_window_scroll_buffer
;
70 /* Window that the mouse is over (nil if no mouse support). */
71 Lisp_Object Vmouse_window
;
73 /* Last mouse click data structure (nil if no mouse support). */
74 Lisp_Object Vmouse_event
;
76 /* Non-nil means it's function to call to display temp buffers. */
77 Lisp_Object Vtemp_buffer_show_function
;
79 /* If a window gets smaller than either of these, it is removed. */
80 int window_min_height
;
83 /* Nonzero implies Fdisplay_buffer should create windows. */
86 /* Nonzero implies make new X screens for Fdisplay_buffer. */
89 /* Non-nil means use this function instead of default */
90 Lisp_Object Vpop_up_screen_function
;
92 /* Function to call to handle Fdisplay_buffer. */
93 Lisp_Object Vdisplay_buffer_function
;
95 /* Fdisplay_buffer always splits the largest window
96 if that window is more than this high. */
97 int split_height_threshold
;
99 /* Number of lines of continuity in scrolling by screenfuls. */
100 int next_screen_context_lines
;
102 /* Incremented for each window created. */
103 static int sequence_number
;
105 #define min(a, b) ((a) < (b) ? (a) : (b))
107 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
108 "Returns t if OBJ is a window.")
112 return XTYPE (obj
) == Lisp_Window
? Qt
: Qnil
;
118 register Lisp_Object val
;
119 register struct window
*p
;
121 /* Add sizeof (Lisp_Object) here because sizeof (struct Lisp_Vector)
122 includes the first element. */
124 make_number ((sizeof (struct window
) - sizeof (struct Lisp_Vector
)
125 + sizeof (Lisp_Object
))
126 / sizeof (Lisp_Object
)),
128 XSETTYPE (val
, Lisp_Window
);
130 XFASTINT (p
->sequence_number
) = ++sequence_number
;
131 XFASTINT (p
->left
) = XFASTINT (p
->top
)
132 = XFASTINT (p
->height
) = XFASTINT (p
->width
)
133 = XFASTINT (p
->hscroll
) = 0;
134 XFASTINT (p
->last_point_x
) = XFASTINT (p
->last_point_y
) = 0;
135 p
->start
= Fmake_marker ();
136 p
->pointm
= Fmake_marker ();
137 XFASTINT (p
->use_time
) = 0;
139 p
->display_table
= Qnil
;
144 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
145 "Return the window that the cursor now appears in and commands apply to.")
148 return selected_window
;
151 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 0, 0,
152 "Return the window used now for minibuffers.")
156 if (minibuf_level
== 0
157 && !EQ (minibuf_window
, selected_screen
->minibuffer_window
)
158 && !EQ (Qnil
, selected_screen
->minibuffer_window
))
160 Fset_window_buffer (selected_screen
->minibuffer_window
,
161 XWINDOW (minibuf_window
)->buffer
);
162 minibuf_window
= selected_screen
->minibuffer_window
;
165 if (SCREENP (Vglobal_minibuffer_screen
))
166 minibuf_window
= XSCREEN (Vglobal_minibuffer_screen
)->minibuffer_window
;
168 minibuf_window
= selected_screen
->minibuffer_window
;
170 #endif /* MULTI_SCREEN */
171 return minibuf_window
;
174 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
, Swindow_minibuffer_p
, 1, 1, 0,
175 "Returns non-nil if WINDOW is a minibuffer window.")
179 struct window
*w
= decode_window (window
);
180 return (MINI_WINDOW_P (w
) ? Qt
: Qnil
);
183 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
184 Spos_visible_in_window_p
, 0, 2, 0,
185 "Return t if position POS is currently on the screen in WINDOW.\n\
186 Returns nil if that position is scrolled vertically out of view.\n\
187 POS defaults to point; WINDOW, to the selected window.")
189 Lisp_Object pos
, window
;
191 register struct window
*w
;
195 register struct buffer
*buf
;
196 struct position posval
;
202 CHECK_NUMBER_COERCE_MARKER (pos
, 0);
207 window
= selected_window
;
209 CHECK_WINDOW (window
, 1);
210 w
= XWINDOW (window
);
211 top
= marker_position (w
->start
);
216 height
= XFASTINT (w
->height
) - ! MINI_WINDOW_P (w
);
218 buf
= XBUFFER (w
->buffer
);
219 if (XFASTINT (w
->last_modified
) >= BUF_MODIFF (buf
))
221 /* If screen is up to date,
222 use the info recorded about how much text fit on it. */
223 if (posint
< BUF_Z (buf
) - XFASTINT (w
->window_end_pos
)
224 || (XFASTINT (w
->window_end_vpos
) < height
))
230 if (posint
> BUF_Z (buf
))
233 /* If that info is not correct, calculate afresh */
234 posval
= *compute_motion (top
, 0, 0, posint
, height
, 0,
235 XFASTINT (w
->width
) - 1
236 - (XFASTINT (w
->width
) + XFASTINT (w
->left
)
237 != XSCREEN (w
->screen
)->width
),
238 XINT (w
->hscroll
), 0);
240 return posval
.vpos
< height
? Qt
: Qnil
;
244 static struct window
*
245 decode_window (window
)
246 register Lisp_Object window
;
249 return XWINDOW (selected_window
);
251 CHECK_WINDOW (window
, 0);
252 return XWINDOW (window
);
255 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
256 "Return the buffer that WINDOW is displaying.")
260 return decode_window (window
)->buffer
;
263 DEFUN ("window-height", Fwindow_height
, Swindow_height
, 0, 1, 0,
264 "Return the number of lines in WINDOW (including its mode line).")
268 return decode_window (window
)->height
;
271 DEFUN ("window-width", Fwindow_width
, Swindow_width
, 0, 1, 0,
272 "Return the number of columns in WINDOW.")
276 register struct window
*w
= decode_window (window
);
277 register int width
= w
->width
;
279 /* If this window does not end at the right margin,
280 must deduct one column for the border */
281 if ((width
+ w
->left
) == SCREEN_WIDTH (XSCREEN (WINDOW_SCREEN (w
))))
286 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
287 "Return the number of columns by which WINDOW is scrolled from left margin.")
291 return decode_window (window
)->hscroll
;
294 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
295 "Set number of columns WINDOW is scrolled from left margin to NCOL.\n\
296 NCOL should be zero or positive.")
298 register Lisp_Object window
, ncol
;
300 register struct window
*w
;
302 CHECK_NUMBER (ncol
, 1);
303 if (XINT (ncol
) < 0) XFASTINT (ncol
) = 0;
304 if (XFASTINT (ncol
) >= (1 << (SHORTBITS
- 1)))
305 args_out_of_range (ncol
, Qnil
);
306 w
= decode_window (window
);
307 if (w
->hscroll
!= ncol
)
308 clip_changed
= 1; /* Prevent redisplay shortcuts */
313 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
314 "Return a list of the edge coordinates of WINDOW.\n\
315 \(LEFT TOP RIGHT BOTTOM), all relative to 0, 0 at top left corner of screen.\n\
316 RIGHT is one more than the rightmost column used by WINDOW,\n\
317 and BOTTOM is one more than the bottommost row used by WINDOW\n\
322 register struct window
*w
= decode_window (window
);
324 return Fcons (w
->left
, Fcons (w
->top
,
325 Fcons (make_number (XFASTINT (w
->left
) + XFASTINT (w
->width
)),
326 Fcons (make_number (XFASTINT (w
->top
)
327 + XFASTINT (w
->height
)),
331 /* Find the window containing column x, row y, and return it as a
332 Lisp_Object. If x, y is on the window's modeline, set *modeline_p
333 to 1; otherwise set it to 0. If there is no window under x, y
334 return nil and leave *modeline_p unmodified. */
336 window_from_coordinates (screen
, x
, y
, modeline_p
)
341 register Lisp_Object tem
, first
;
343 first
= SCREEN_SELECTED_WINDOW (screen
);
344 tem
= next_screen_window (screen
, first
, Qt
);
348 int found
= coordinates_in_window (XWINDOW (tem
), &x
, &y
);
352 *modeline_p
= (found
== -1);
359 tem
= next_screen_window (screen
, tem
, Qt
);
363 DEFUN ("locate-window-from-coordinates",
364 Flocate_window_from_coordinates
, Slocate_window_from_coordinates
,
366 "Return window on SCREEN containing position COORDINATES.\n\
367 COORDINATES is a list (SCREEN-X SCREEN-Y) of coordinates\n\
368 which are relative to 0,0 at the top left corner of the screen.")
369 (screen
, coordinates
)
370 Lisp_Object screen
, coordinates
;
374 CHECK_SCREEN (screen
, 0);
375 CHECK_CONS (coordinates
, 1);
377 return window_from_coordinates (XSCREEN (screen
),
378 XINT (Fcar (coordinates
)),
379 XINT (Fcar (Fcdr (coordinates
))),
383 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
384 "Return current value of point in WINDOW.\n\
385 For a nonselected window, this is the value point would have\n\
386 if that window were selected.\n\
388 Note that, when WINDOW is the selected window and its buffer\n\
389 is also currently selected, the value returned is the same as (point).\n\
390 It would be more strictly correct to return the `top-level' value\n\
391 of point, outside of any save-excursion forms.\n\
392 But that is hard to define.")
396 register struct window
*w
= decode_window (window
);
398 if (w
== XWINDOW (selected_window
)
399 && current_buffer
== XBUFFER (w
->buffer
))
401 return Fmarker_position (w
->pointm
);
404 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
405 "Return position at which display currently starts in WINDOW.")
409 return Fmarker_position (decode_window (window
)->start
);
412 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 1, 0,
413 "Return position at which display currently ends in WINDOW.")
418 struct window
*w
= decode_window (window
);
420 XSET (value
, Lisp_Int
,
421 BUF_Z (current_buffer
) - XFASTINT (w
->window_end_pos
));
426 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
427 "Make point value in WINDOW be at position POS in WINDOW's buffer.")
429 Lisp_Object window
, pos
;
431 register struct window
*w
= decode_window (window
);
433 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
434 if (w
== XWINDOW (selected_window
))
437 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
442 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
443 "Make display in WINDOW start at position POS in WINDOW's buffer.\n\
444 Optional third arg NOFORCE non-nil inhibits next redisplay\n\
445 from overriding motion of point in order to display at this exact start.")
446 (window
, pos
, noforce
)
447 Lisp_Object window
, pos
, noforce
;
449 register struct window
*w
= decode_window (window
);
451 CHECK_NUMBER_COERCE_MARKER (pos
, 1);
452 set_marker_restricted (w
->start
, pos
, w
->buffer
);
453 /* this is not right, but much easier than doing what is right. */
454 w
->start_at_line_beg
= Qnil
;
457 w
->update_mode_line
= Qt
;
458 XFASTINT (w
->last_modified
) = 0;
459 if (!EQ (window
, selected_window
))
460 windows_or_buffers_changed
++;
464 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
466 "Return WINDOW's dedicated object, usually t or nil.\n\
467 See also `set-window-buffer-dedicated'.")
471 return decode_window (window
)->dedicated
;
474 DEFUN ("set-window-buffer-dedicated", Fset_window_buffer_dedicated
,
475 Sset_window_buffer_dedicated
, 2, 2, 0,
476 "Make WINDOW display BUFFER and be dedicated to that buffer.\n\
477 Then Emacs will not automatically change which buffer appears in WINDOW.\n\
478 If BUFFER is nil, make WINDOW not be dedicated (but don't change which\n\
479 buffer appears in it currently).")
481 Lisp_Object window
, arg
;
483 register struct window
*w
= decode_window (window
);
489 Fset_window_buffer (window
, Fget_buffer_create (arg
));
496 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
498 "Return the display-table that WINDOW is using.")
502 return decode_window (window
)->display_table
;
505 /* Get the display table for use currently on window W.
506 This is either W's display table or W's buffer's display table.
507 Ignore the specified tables if they are not valid;
508 if no valid table is specified, return 0. */
511 window_display_table (w
)
515 tem
= w
->display_table
;
516 if (XTYPE (tem
) == Lisp_Vector
&& XVECTOR (tem
)->size
== DISP_TABLE_SIZE
)
517 return XVECTOR (tem
);
518 tem
= XBUFFER (w
->buffer
)->display_table
;
519 if (XTYPE (tem
) == Lisp_Vector
&& XVECTOR (tem
)->size
== DISP_TABLE_SIZE
)
520 return XVECTOR (tem
);
521 tem
= Vstandard_display_table
;
522 if (XTYPE (tem
) == Lisp_Vector
&& XVECTOR (tem
)->size
== DISP_TABLE_SIZE
)
523 return XVECTOR (tem
);
527 DEFUN ("set-window-display-table",
528 Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
529 "Set WINDOW's display-table to TABLE.")
531 register Lisp_Object window
, table
;
533 register struct window
*w
;
534 register Lisp_Object z
; /* Return value. */
536 w
= decode_window (window
);
537 w
->display_table
= table
;
541 /* Record info on buffer window w is displaying
542 when it is about to cease to display that buffer. */
545 register struct window
*w
;
547 Lisp_Object buf
= w
->buffer
;
549 if (XBUFFER (buf
) != XMARKER (w
->pointm
)->buffer
)
552 if (w
== XWINDOW (selected_window
)
553 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
554 /* Do this except when the selected window's buffer
555 is being removed from some other window. */
556 XBUFFER (buf
)->last_window_start
= marker_position (w
->start
);
558 /* Point in the selected window's buffer
559 is actually stored in that buffer, and the window's pointm isn't used.
560 So don't clobber point in that buffer. */
561 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
))
562 BUF_PT (XBUFFER (buf
))
563 = clip_to_bounds (BUF_BEGV (XBUFFER (buf
)),
564 marker_position (w
->pointm
),
565 BUF_ZV (XBUFFER (buf
)));
568 /* Put replacement into the window structure in place of old. */
570 replace_window (old
, replacement
)
571 Lisp_Object old
, replacement
;
573 register Lisp_Object tem
;
574 register struct window
*o
= XWINDOW (old
), *p
= XWINDOW (replacement
);
576 /* If OLD is its screen's root_window, then replacement is the new
577 root_window for that screen. */
579 if (old
== XSCREEN (o
->screen
)->root_window
)
580 XSCREEN (o
->screen
)->root_window
= replacement
;
585 p
->height
= o
->height
;
587 p
->next
= tem
= o
->next
;
589 XWINDOW (tem
)->prev
= replacement
;
591 p
->prev
= tem
= o
->prev
;
593 XWINDOW (tem
)->next
= replacement
;
595 p
->parent
= tem
= o
->parent
;
598 if (EQ (XWINDOW (tem
)->vchild
, old
))
599 XWINDOW (tem
)->vchild
= replacement
;
600 if (EQ (XWINDOW (tem
)->hchild
, old
))
601 XWINDOW (tem
)->hchild
= replacement
;
604 /*** Here, if replacement is a vertical combination
605 and so is its new parent, we should make replacement's
606 children be children of that parent instead. ***/
609 DEFUN ("delete-window", Fdelete_window
, Sdelete_window
, 0, 1, "",
610 "Remove WINDOW from the display. Default is selected window.")
612 register Lisp_Object window
;
614 register Lisp_Object tem
, parent
, sib
;
615 register struct window
*p
;
616 register struct window
*par
;
619 window
= selected_window
;
621 CHECK_WINDOW (window
, 0);
623 p
= XWINDOW (window
);
626 error ("Attempt to delete minibuffer or sole ordinary window");
627 par
= XWINDOW (parent
);
629 windows_or_buffers_changed
++;
631 if (EQ (window
, selected_window
))
632 Fselect_window (Fnext_window (window
, Qnil
, Qnil
));
635 /* tem is null for dummy parent windows
636 (which have inferiors but not any contents themselves) */
640 unchain_marker (p
->pointm
);
641 unchain_marker (p
->start
);
647 XWINDOW (tem
)->prev
= p
->prev
;
651 XWINDOW (tem
)->next
= p
->next
;
653 if (EQ (window
, par
->hchild
))
654 par
->hchild
= p
->next
;
655 if (EQ (window
, par
->vchild
))
656 par
->vchild
= p
->next
;
658 /* Find one of our siblings to give our space to. */
662 /* If p gives its space to its next sibling, that sibling needs
663 to have its top/left side pulled back to where p's is.
664 set_window_{height,width} will re-position the sibling's
667 XFASTINT (XWINDOW (sib
)->top
) = p
->top
;
668 XFASTINT (XWINDOW (sib
)->left
) = p
->left
;
671 /* Stretch that sibling. */
672 if (!NULL (par
->vchild
))
673 set_window_height (sib
,
674 XFASTINT (XWINDOW (sib
)->height
) + XFASTINT (p
->height
),
676 if (!NULL (par
->hchild
))
677 set_window_width (sib
,
678 XFASTINT (XWINDOW (sib
)->width
) + XFASTINT (p
->width
),
681 /* If parent now has only one child,
682 put the child into the parent's place. */
687 if (NULL (XWINDOW (tem
)->next
))
688 replace_window (parent
, tem
);
694 next_screen_window (screen
, window
, mini
)
696 Lisp_Object window
, mini
;
701 window
= SCREEN_SELECTED_WINDOW (screen
);
703 /* Do this loop at least once, to get the next window, and perhaps
704 again, if we hit the minibuffer and that is not acceptable. */
707 /* Find a window that actually has a next one. This loop
708 climbs up the tree. */
709 while (tem
= XWINDOW (window
)->next
, NULL (tem
))
710 if (tem
= XWINDOW (window
)->parent
, !NULL (tem
))
713 /* Since window's next and parent are nil, we have found
714 the minibuffer window of this screen. */
716 tem
= SCREEN_ROOT_WINDOW (screen
);
721 /* If we're in a combination window, find its first child and
722 recurse on that. Otherwise, we've found the window we want. */
725 if (!NULL (XWINDOW (window
)->hchild
))
726 window
= XWINDOW (window
)->hchild
;
727 else if (!NULL (XWINDOW (window
)->vchild
))
728 window
= XWINDOW (window
)->vchild
;
733 this isn't a minibuffer window, or
734 we're accepting all minibuffer windows, even when inactive, or
735 we're accepting active minibuffer windows and this one is. */
736 while (MINI_WINDOW_P (XWINDOW (window
))
738 && (!NULL (mini
) || !minibuf_level
));
744 extern Lisp_Object
next_screen (), prev_screen ();
746 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
747 "Return next window after WINDOW in canonical ordering of windows.\n\
748 Optional second arg MINIBUF t means count the minibuffer window\n\
749 even if not active. If MINIBUF is neither t nor nil it means\n\
750 not to count the minibuffer even if it is active.\n\
751 Optional third arg ALL-SCREENS t means include all windows in all screens;\n\
752 otherwise cycle within the selected screen, with the exception that if a\n\
753 global minibuffer screen is in use and MINIBUF is t, all screens are used.")
754 (window
, mini
, all_screens
)
755 register Lisp_Object window
, mini
, all_screens
;
757 register Lisp_Object tem
;
760 window
= selected_window
;
762 CHECK_WINDOW (window
, 0);
766 || (! NULL (mini
) && minibuf_level
))
768 if (SCREENP (Vglobal_minibuffer_screen
))
773 /* Do this loop at least once, to get the next window, and perhaps
774 again, if we hit the minibuffer and that is not acceptable. */
777 /* Find a window that actually has a next one. This loop
778 climbs up the tree. */
779 while (tem
= XWINDOW (window
)->next
, NULL (tem
))
780 if (tem
= XWINDOW (window
)->parent
, !NULL (tem
))
783 /* Since window's next and parent are nil, it must be
784 the minibuffer window of this screen. If all_screens,
785 jump to the next screen. */
787 tem
= WINDOW_SCREEN (XWINDOW (window
));
789 if (! NULL (all_screens
))
790 tem
= next_screen (tem
, NULL (mini
) ? 0 : 1);
792 tem
= SCREEN_ROOT_WINDOW (XSCREEN (tem
));
797 /* If we're in a combination window, find its first child and
798 recurse on that. Otherwise, we've found the window we want. */
801 if (!NULL (XWINDOW (window
)->hchild
))
802 window
= XWINDOW (window
)->hchild
;
803 else if (!NULL (XWINDOW (window
)->vchild
))
804 window
= XWINDOW (window
)->vchild
;
809 this isn't a minibuffer window, or
810 we're accepting all minibuffer windows, even when inactive, or
811 we're accepting active minibuffer windows and this one is, or
812 this is a screen whose only window is a minibuffer window. */
813 while (MINI_WINDOW_P (XWINDOW (window
))
815 && (!NULL (mini
) || !minibuf_level
)
816 && !EQ (SCREEN_ROOT_WINDOW (XSCREEN (XWINDOW (window
)->screen
)),
817 SCREEN_MINIBUF_WINDOW (XSCREEN (XWINDOW (window
)->screen
))));
822 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
823 "Return previous window before WINDOW in canonical ordering of windows.\n\
824 Optional second arg MINIBUF t means count the minibuffer window\n\
825 even if not active. If MINIBUF is neither t nor nil it means\n\
826 not to count the minibuffer even if it is active.\n\
827 Optional third arg ALL-SCREENS t means include all windows in all screens;\n\
828 otherwise cycle within the selected screen, with the exception that if a\n\
829 global minibuffer screen is in use and MINIBUF is t, all screens are used.")
830 (window
, mini
, all_screens
)
831 register Lisp_Object window
, mini
, all_screens
;
833 register Lisp_Object tem
;
836 window
= selected_window
;
838 CHECK_WINDOW (window
, 0);
842 || (! NULL (mini
) && minibuf_level
))
844 if (SCREENP (Vglobal_minibuffer_screen
))
849 /* Do this loop at least once, to get the previous window, and perhaps
850 again, if we hit the minibuffer and that is not acceptable. */
853 /* Find a window that actually has a previous one. This loop
854 climbs up the tree. */
855 while (tem
= XWINDOW (window
)->prev
, NULL (tem
))
856 if (tem
= XWINDOW (window
)->parent
, !NULL (tem
))
859 /* Since window's prev and parent are nil, we have found
860 the root window of this screen. If all_screens, jump
861 to the previous screen. */
863 tem
= WINDOW_SCREEN (XWINDOW (window
));
865 if (! NULL (all_screens
))
866 tem
= prev_screen (tem
, NULL (mini
) ? 0 : 1);
868 tem
= SCREEN_ROOT_WINDOW (XSCREEN (tem
));
873 /* If we're in a combination window, find its last child and
874 recurse on that. Otherwise, we've found the window we want. */
877 if (!NULL (XWINDOW (window
)->hchild
))
878 window
= XWINDOW (window
)->hchild
;
879 else if (!NULL (XWINDOW (window
)->vchild
))
880 window
= XWINDOW (window
)->vchild
;
882 while (tem
= XWINDOW (window
)->next
, !NULL (tem
))
887 this isn't a minibuffer window, or
888 we're accepting all minibuffer windows, even when inactive, or
889 we're accepting active minibuffer windows and this one is, or
890 this is a screen whose only window is a minibuffer window. */
891 while (MINI_WINDOW_P (XWINDOW (window
))
893 && (!NULL (mini
) || !minibuf_level
)
894 && !EQ (SCREEN_ROOT_WINDOW (XSCREEN (XWINDOW (window
)->screen
)),
895 SCREEN_MINIBUF_WINDOW (XSCREEN (XWINDOW (window
)->screen
))));
900 DEFUN ("other-window", Fother_window
, Sother_window
, 1, 2, "p",
901 "Select the ARG'th different window on this screen.\n\
902 All windows on current screen are arranged in a cyclic order.\n\
903 This command selects the window ARG steps away in that order.\n\
904 A negative ARG moves in the opposite order. If the optional second\n\
905 argument ALL_SCREENS is non-nil, cycle through all screens.")
907 register Lisp_Object n
, all_screens
;
910 register Lisp_Object w
;
918 w
= Fnext_window (w
, Qnil
, all_screens
);
923 w
= Fprevious_window (w
, Qnil
, all_screens
);
930 /* Look at all windows, performing an operation specified by TYPE
932 If SCREENS is Qt, look at all screens, if Qnil, look at just the selected
933 screen. If SCREENS is a screen, just look at windows on that screen.
934 If MINI is non-zero, perform the operation on minibuffer windows too.
940 GET_BUFFER_WINDOW
, /* Arg is buffer */
941 GET_LRU_WINDOW
, /* Arg is t for full-width windows only */
942 DELETE_OTHER_WINDOWS
, /* Arg is window not to delete */
943 DELETE_BUFFER_WINDOWS
, /* Arg is buffer */
945 UNSHOW_BUFFER
, /* Arg is buffer */
949 window_loop (type
, obj
, mini
, screens
)
950 enum window_loop type
;
951 register Lisp_Object obj
, screens
;
954 register Lisp_Object w
;
955 register Lisp_Object best_window
;
956 register Lisp_Object next_window
;
957 register Lisp_Object first_window
;
960 /* If we're only looping through windows on a particular screen,
961 screen points to that screen. If we're looping through windows
962 on all screens, screen is 0. */
963 if (SCREENP (screens
))
964 screen
= XSCREEN (screens
);
965 else if (NULL (screens
))
966 screen
= selected_screen
;
970 /* Pick a window to start with. */
971 if (XTYPE (obj
) == Lisp_Window
)
974 first_window
= SCREEN_SELECTED_WINDOW (screen
);
976 first_window
= SCREEN_SELECTED_WINDOW (selected_screen
);
982 /* Pick the next window now, since some operations will delete
983 the current window. */
986 next_window
= next_screen_window (screen
, w
, mini
? Qt
: Qnil
);
988 #endif /* MULTI_SCREEN */
989 /* We know screen is 0, so we're looping through all screens.
990 Or we know this isn't a MULTI_SCREEN Emacs, so who cares? */
991 next_window
= Fnext_window (w
, mini
? Qt
: Qnil
, Qt
);
993 if (!MINI_WINDOW_P (XWINDOW (w
))
994 || (mini
&& minibuf_level
> 0))
997 case GET_BUFFER_WINDOW
:
999 /* Ignore invisible and iconified screens. */
1000 if (! SCREEN_VISIBLE_P (XSCREEN (WINDOW_SCREEN (XWINDOW (w
))))
1001 || SCREEN_ICONIFIED_P (XSCREEN (WINDOW_SCREEN (XWINDOW (w
)))))
1004 if (XBUFFER (XWINDOW (w
)->buffer
) == XBUFFER (obj
))
1008 case GET_LRU_WINDOW
:
1009 /* t as arg means consider only full-width windows */
1010 if (!NULL (obj
) && XFASTINT (XWINDOW (w
)->width
) != screen
->width
)
1013 /* Ignore invisible and iconified screens. */
1014 if (! SCREEN_VISIBLE_P (XSCREEN (WINDOW_SCREEN (XWINDOW (w
))))
1015 || SCREEN_ICONIFIED_P (XSCREEN (WINDOW_SCREEN (XWINDOW (w
)))))
1018 /* Ignore dedicated windows and minibuffers. */
1019 if (MINI_WINDOW_P (XWINDOW (w
))
1020 || !NULL (XWINDOW (w
)->dedicated
))
1022 if (NULL (best_window
)
1023 || (XFASTINT (XWINDOW (best_window
)->use_time
)
1024 > XFASTINT (XWINDOW (w
)->use_time
)))
1028 case DELETE_OTHER_WINDOWS
:
1029 if (XWINDOW (w
) != XWINDOW (obj
))
1033 case DELETE_BUFFER_WINDOWS
:
1034 if (EQ (XWINDOW (w
)->buffer
, obj
))
1036 /* If we're deleting the buffer displayed in the only window
1037 on the screen, find a new buffer to display there. */
1038 if (NULL (XWINDOW (w
)->parent
))
1040 Lisp_Object new_buffer
= Fother_buffer (obj
);
1041 if (NULL (new_buffer
))
1043 = Fget_buffer_create (build_string ("*scratch*"));
1044 Fset_window_buffer (w
, new_buffer
);
1045 Fset_buffer (XWINDOW (w
)->buffer
);
1052 case GET_LARGEST_WINDOW
:
1054 /* Ignore invisible and iconified screens. */
1055 if (! SCREEN_VISIBLE_P (XSCREEN (WINDOW_SCREEN (XWINDOW (w
))))
1056 || SCREEN_ICONIFIED_P (XSCREEN (WINDOW_SCREEN (XWINDOW (w
)))))
1059 /* Ignore dedicated windows and minibuffers. */
1060 if (MINI_WINDOW_P (XWINDOW (w
))
1061 || !NULL (XWINDOW (w
)->dedicated
))
1064 struct window
*best_window_ptr
= XWINDOW (best_window
);
1065 struct window
*w_ptr
= XWINDOW (w
);
1066 if (NULL (best_window
) ||
1067 (XFASTINT (w_ptr
->height
) * XFASTINT (w_ptr
->width
))
1068 > (XFASTINT (best_window_ptr
->height
)
1069 * XFASTINT (best_window_ptr
->width
)))
1075 if (EQ (XWINDOW (w
)->buffer
, obj
))
1077 /* Find another buffer to show in this window. */
1078 Lisp_Object another_buffer
= Fother_buffer (obj
);
1079 if (NULL (another_buffer
))
1081 = Fget_buffer_create (build_string ("*scratch*"));
1082 Fset_window_buffer (w
, another_buffer
);
1083 if (EQ (w
, selected_window
))
1084 Fset_buffer (XWINDOW (w
)->buffer
);
1090 while (! EQ (w
, first_window
));
1095 DEFUN ("get-lru-window", Fget_lru_window
, Sget_lru_window
, 0, 1, 0,
1096 "Return the window least recently selected or used for display.\n\
1097 If optional argument SCREENS is t, search all screens. If SCREEN is a\n\
1098 screen, search only that screen.\n")
1100 Lisp_Object screens
;
1102 register Lisp_Object w
;
1103 /* First try for a window that is full-width */
1104 w
= window_loop (GET_LRU_WINDOW
, Qt
, 0, screens
);
1105 if (!NULL (w
) && !EQ (w
, selected_window
))
1107 /* If none of them, try the rest */
1108 return window_loop (GET_LRU_WINDOW
, Qnil
, 0, screens
);
1111 DEFUN ("get-largest-window", Fget_largest_window
, Sget_largest_window
, 0, 1, 0,
1112 "Return the largest window in area.\n\
1113 If optional argument SCREENS is t, search all screens. If SCREEN is a\n\
1114 screen, search only that screen.\n")
1118 return window_loop (GET_LARGEST_WINDOW
, Qnil
, 0,
1122 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 1, 2, 0,
1123 "Return a window currently displaying BUFFER, or nil if none.\n\
1124 If optional argument SCREENS is t, search all screens. If SCREEN is a\n\
1125 screen, search only that screen.\n")
1127 Lisp_Object buffer
, screen
;
1129 buffer
= Fget_buffer (buffer
);
1130 if (XTYPE (buffer
) == Lisp_Buffer
)
1131 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, screen
);
1136 DEFUN ("delete-other-windows", Fdelete_other_windows
, Sdelete_other_windows
,
1138 "Make WINDOW (or the selected window) fill its screen.\n\
1139 Only the screen WINDOW is on is affected.")
1145 struct buffer
*obuf
= current_buffer
;
1149 window
= selected_window
;
1151 CHECK_WINDOW (window
, 0);
1153 w
= XWINDOW (window
);
1154 top
= XFASTINT (w
->top
);
1156 window_loop (DELETE_OTHER_WINDOWS
, window
, 0, WINDOW_SCREEN(w
));
1158 Fset_buffer (w
->buffer
);
1159 SET_PT (marker_position (w
->start
));
1160 Frecenter (make_number (top
));
1162 set_buffer_internal (obuf
);
1167 DEFUN ("delete-windows-on", Fdelete_windows_on
, Sdelete_windows_on
,
1168 1, 1, "bDelete windows on (buffer): ",
1169 "Delete all windows showing BUFFER.")
1175 buffer
= Fget_buffer (buffer
);
1176 CHECK_BUFFER (buffer
, 0);
1177 window_loop (DELETE_BUFFER_WINDOWS
, buffer
, 0, Qt
);
1182 DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows
,
1183 Sreplace_buffer_in_windows
,
1184 1, 1, "bReplace buffer in windows: ",
1185 "Replace BUFFER with some other buffer in all windows showing it.")
1191 buffer
= Fget_buffer (buffer
);
1192 CHECK_BUFFER (buffer
, 0);
1193 window_loop (UNSHOW_BUFFER
, buffer
, 0, Qt
);
1198 /* Set the height of WINDOW and all its inferiors. */
1199 /* Normally the window is deleted if it gets too small.
1200 nodelete nonzero means do not do this.
1201 (The caller should check later and do so if appropriate) */
1203 set_window_height (window
, height
, nodelete
)
1208 register struct window
*w
= XWINDOW (window
);
1209 register struct window
*c
;
1210 int oheight
= XFASTINT (w
->height
);
1211 int top
, pos
, lastbot
, opos
, lastobot
;
1215 && ! NULL (w
->parent
)
1216 && height
< window_min_height
)
1218 Fdelete_window (window
);
1222 XFASTINT (w
->last_modified
) = 0;
1223 windows_or_buffers_changed
++;
1224 XFASTINT (w
->height
) = height
;
1225 if (!NULL (w
->hchild
))
1227 for (child
= w
->hchild
; !NULL (child
); child
= XWINDOW (child
)->next
)
1229 XWINDOW (child
)->top
= w
->top
;
1230 set_window_height (child
, height
, nodelete
);
1233 else if (!NULL (w
->vchild
))
1235 lastbot
= top
= XFASTINT (w
->top
);
1237 for (child
= w
->vchild
; !NULL (child
); child
= c
->next
)
1239 c
= XWINDOW (child
);
1241 opos
= lastobot
+ XFASTINT (c
->height
);
1243 XFASTINT (c
->top
) = lastbot
;
1245 pos
= (((opos
* height
) << 1) + oheight
) / (oheight
<< 1);
1247 /* Avoid confusion: inhibit deletion of child if becomes too small */
1248 set_window_height (child
, pos
+ top
- lastbot
, 1);
1250 /* Now advance child to next window,
1251 and set lastbot if child was not just deleted. */
1252 lastbot
= pos
+ top
;
1255 /* Now delete any children that became too small. */
1257 for (child
= w
->vchild
; !NULL (child
); child
= XWINDOW (child
)->next
)
1259 set_window_height (child
, XINT (XWINDOW (child
)->height
), 0);
1264 /* Recursively set width of WINDOW and its inferiors. */
1266 set_window_width (window
, width
, nodelete
)
1271 register struct window
*w
= XWINDOW (window
);
1272 register struct window
*c
;
1273 int owidth
= XFASTINT (w
->width
);
1274 int left
, pos
, lastright
, opos
, lastoright
;
1277 if (!nodelete
&& width
< window_min_width
)
1279 Fdelete_window (window
);
1283 XFASTINT (w
->last_modified
) = 0;
1284 windows_or_buffers_changed
++;
1285 XFASTINT (w
->width
) = width
;
1286 if (!NULL (w
->vchild
))
1288 for (child
= w
->vchild
; !NULL (child
); child
= XWINDOW (child
)->next
)
1290 XWINDOW (child
)->left
= w
->left
;
1291 set_window_width (child
, width
, nodelete
);
1294 else if (!NULL (w
->hchild
))
1296 lastright
= left
= XFASTINT (w
->left
);
1298 for (child
= w
->hchild
; !NULL (child
); child
= c
->next
)
1300 c
= XWINDOW (child
);
1302 opos
= lastoright
+ XFASTINT (c
->width
);
1304 XFASTINT (c
->left
) = lastright
;
1306 pos
= (((opos
* width
) << 1) + owidth
) / (owidth
<< 1);
1308 /* Inhibit deletion for becoming too small */
1309 set_window_width (child
, pos
+ left
- lastright
, 1);
1311 /* Now advance child to next window,
1312 and set lastright if child was not just deleted. */
1313 lastright
= pos
+ left
, lastoright
= opos
;
1315 /* Delete children that became too small */
1317 for (child
= w
->hchild
; !NULL (child
); child
= XWINDOW (child
)->next
)
1319 set_window_width (child
, XINT (XWINDOW (child
)->width
), 0);
1324 int window_select_count
;
1326 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 2, 0,
1327 "Make WINDOW display BUFFER as its contents.\n\
1328 BUFFER can be a buffer or buffer name.")
1330 register Lisp_Object window
, buffer
;
1332 register Lisp_Object tem
;
1333 register struct window
*w
= decode_window (window
);
1335 buffer
= Fget_buffer (buffer
);
1336 CHECK_BUFFER (buffer
, 1);
1338 if (NULL (XBUFFER (buffer
)->name
))
1339 error ("Attempt to display deleted buffer");
1343 error ("Window is deleted");
1344 else if (! EQ (tem
, Qt
)) /* w->buffer is t when the window
1345 is first being set up. */
1347 if (!NULL (w
->dedicated
) && !EQ (tem
, buffer
))
1348 error ("Window is dedicated to %s\n", tem
);
1354 Fset_marker (w
->pointm
,
1355 make_number (BUF_PT (XBUFFER (buffer
))),
1357 set_marker_restricted (w
->start
,
1358 make_number (XBUFFER (buffer
)->last_window_start
),
1360 w
->start_at_line_beg
= Qnil
;
1361 XFASTINT (w
->last_modified
) = 0;
1362 windows_or_buffers_changed
++;
1363 if (EQ (window
, selected_window
))
1364 Fset_buffer (buffer
);
1369 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 1, 0,
1370 "Select WINDOW. Most editing will apply to WINDOW's buffer.\n\
1371 The main editor command loop selects the buffer of the selected window\n\
1372 before each command.")
1374 register Lisp_Object window
;
1376 register struct window
*w
;
1377 register struct window
*ow
= XWINDOW (selected_window
);
1379 CHECK_WINDOW (window
, 0);
1381 w
= XWINDOW (window
);
1383 if (NULL (w
->buffer
))
1384 error ("Trying to select deleted window or non-leaf window");
1386 XFASTINT (w
->use_time
) = ++window_select_count
;
1387 if (EQ (window
, selected_window
))
1390 Fset_marker (ow
->pointm
, make_number (BUF_PT (XBUFFER (ow
->buffer
))),
1393 selected_window
= window
;
1395 if (XSCREEN (WINDOW_SCREEN (w
)) != selected_screen
)
1397 XSCREEN (WINDOW_SCREEN (w
))->selected_window
= window
;
1398 Fselect_screen (WINDOW_SCREEN (w
), Qnil
);
1401 selected_screen
->selected_window
= window
;
1404 record_buffer (w
->buffer
);
1405 Fset_buffer (w
->buffer
);
1407 /* Go to the point recorded in the window.
1408 This is important when the buffer is in more
1409 than one window. It also matters when
1410 redisplay_window has altered point after scrolling,
1411 because it makes the change only in the window. */
1413 register int new_point
= marker_position (w
->pointm
);
1414 if (new_point
< BEGV
)
1422 windows_or_buffers_changed
++;
1426 DEFUN ("display-buffer", Fdisplay_buffer
, Sdisplay_buffer
, 1, 2, 0,
1427 "Make BUFFER appear in some window but don't select it.\n\
1428 BUFFER can be a buffer or a buffer name.\n\
1429 If BUFFER is shown already in some window, just use that one,\n\
1430 unless the window is the selected window and the optional second\n\
1431 argument NOT_THIS_WINDOW is non-nil.\n\
1432 Returns the window displaying BUFFER.")
1433 (buffer
, not_this_window
)
1434 register Lisp_Object buffer
, not_this_window
;
1436 register Lisp_Object window
;
1438 buffer
= Fget_buffer (buffer
);
1439 CHECK_BUFFER (buffer
, 0);
1441 if (!NULL (Vdisplay_buffer_function
))
1442 return call2 (Vdisplay_buffer_function
, buffer
, not_this_window
);
1444 if (NULL (not_this_window
)
1445 && XBUFFER (XWINDOW (selected_window
)->buffer
) == XBUFFER (buffer
))
1446 return selected_window
;
1448 window
= Fget_buffer_window (buffer
, Qnil
);
1450 && (NULL (not_this_window
) || !EQ (window
, selected_window
)))
1454 /* If there are no screens open that have more than a minibuffer,
1455 we need to create a new screen. */
1456 if (pop_up_screens
|| last_nonminibuf_screen
== 0)
1459 = Fscreen_selected_window (call0 (Vpop_up_screen_function
));
1460 Fset_window_buffer (window
, buffer
);
1462 Fselect_screen (XWINDOW (window
)->screen
, Qnil
);
1466 #endif /* MULTI_SCREEN */
1470 || EQ (SCREEN_ROOT_WINDOW (selected_screen
),
1471 SCREEN_MINIBUF_WINDOW (selected_screen
))
1475 Lisp_Object screens
= Qnil
;
1478 if (EQ (SCREEN_ROOT_WINDOW (selected_screen
),
1479 SCREEN_MINIBUF_WINDOW (selected_screen
)))
1480 XSET (screens
, Lisp_Screen
, last_nonminibuf_screen
);
1482 /* Don't try to create a window if would get an error */
1483 if (split_height_threshold
< window_min_height
<< 1)
1484 split_height_threshold
= window_min_height
<< 1;
1486 window
= Fget_largest_window (screens
);
1489 && window_height (window
) >= split_height_threshold
1491 (XFASTINT (XWINDOW (window
)->width
)
1492 == SCREEN_WIDTH (XSCREEN (WINDOW_SCREEN (XWINDOW (window
))))))
1493 window
= Fsplit_window (window
, Qnil
, Qnil
);
1496 window
= Fget_lru_window (screens
);
1497 if ((EQ (window
, selected_window
)
1498 || EQ (XWINDOW (window
)->parent
, Qnil
))
1499 && window_height (window
) >= window_min_height
<< 1)
1500 window
= Fsplit_window (window
, Qnil
, Qnil
);
1504 window
= Fget_lru_window (Qnil
);
1506 Fset_window_buffer (window
, buffer
);
1511 temp_output_buffer_show (buf
)
1512 register Lisp_Object buf
;
1514 register struct buffer
*old
= current_buffer
;
1515 register Lisp_Object window
;
1516 register struct window
*w
;
1519 XBUFFER (buf
)->save_modified
= MODIFF
;
1524 set_buffer_internal (old
);
1526 if (!EQ (Vtemp_buffer_show_function
, Qnil
))
1527 call1 (Vtemp_buffer_show_function
, buf
);
1530 window
= Fdisplay_buffer (buf
, Qnil
);
1533 if (XSCREEN (XWINDOW (window
)->screen
) != selected_screen
)
1534 Fmake_screen_visible (XWINDOW (window
)->screen
);
1535 #endif /* MULTI_SCREEN */
1536 Vminibuf_scroll_window
= window
;
1537 w
= XWINDOW (window
);
1538 XFASTINT (w
->hscroll
) = 0;
1539 set_marker_restricted (w
->start
, make_number (1), buf
);
1540 set_marker_restricted (w
->pointm
, make_number (1), buf
);
1545 make_dummy_parent (window
)
1548 register Lisp_Object old
, new;
1549 register struct window
*o
, *p
;
1552 XSETTYPE (old
, Lisp_Vector
);
1553 new = Fcopy_sequence (old
);
1554 XSETTYPE (new, Lisp_Window
);
1558 XFASTINT (p
->sequence_number
) = ++sequence_number
;
1560 /* Put new into window structure in place of window */
1561 replace_window (window
, new);
1574 DEFUN ("split-window", Fsplit_window
, Ssplit_window
, 0, 3, "",
1575 "Split WINDOW, putting SIZE lines in the first of the pair.\n\
1576 WINDOW defaults to selected one and SIZE to half its size.\n\
1577 If optional third arg HOR-FLAG is non-nil, split side by side\n\
1578 and put SIZE columns in the first of the pair.")
1579 (window
, chsize
, horflag
)
1580 Lisp_Object window
, chsize
, horflag
;
1582 register Lisp_Object
new;
1583 register struct window
*o
, *p
;
1587 window
= selected_window
;
1589 CHECK_WINDOW (window
, 0);
1591 o
= XWINDOW (window
);
1595 if (!NULL (horflag
))
1596 /* Round odd size up, since this is for the left-hand window,
1597 and it will lose a column for the separators. */
1598 size
= ((XFASTINT (o
->width
) + 1) & -2) >> 1;
1600 size
= XFASTINT (o
->height
) >> 1;
1604 CHECK_NUMBER (chsize
, 1);
1605 size
= XINT (chsize
);
1608 if (MINI_WINDOW_P (o
))
1609 error ("Attempt to split minibuffer window");
1610 else if (SCREEN_NO_SPLIT_P (XSCREEN (WINDOW_SCREEN (o
))))
1611 error ("Attempt to split unsplittable screen");
1613 /* Smaller values might permit a crash. */
1614 if (window_min_width
< 2)
1615 window_min_width
= 2;
1616 if (window_min_height
< 2)
1617 window_min_height
= 2;
1621 if (size
< window_min_height
1622 || size
+ window_min_height
> XFASTINT (o
->height
))
1623 args_out_of_range_3 (window
, chsize
, horflag
);
1624 if (NULL (o
->parent
)
1625 || NULL (XWINDOW (o
->parent
)->vchild
))
1627 make_dummy_parent (window
);
1629 XWINDOW (new)->vchild
= window
;
1634 if (size
< window_min_width
1635 || size
+ window_min_width
> XFASTINT (o
->width
))
1636 args_out_of_range_3 (window
, chsize
, horflag
);
1637 if (NULL (o
->parent
)
1638 || NULL (XWINDOW (o
->parent
)->hchild
))
1640 make_dummy_parent (window
);
1642 XWINDOW (new)->hchild
= window
;
1646 /* Now we know that window's parent is a vertical combination
1647 if we are dividing vertically, or a horizontal combination
1648 if we are making side-by-side windows */
1650 windows_or_buffers_changed
++;
1651 new = make_window ();
1654 p
->screen
= o
->screen
;
1656 if (!NULL (p
->next
))
1657 XWINDOW (p
->next
)->prev
= new;
1660 p
->parent
= o
->parent
;
1663 Fset_window_buffer (new, o
->buffer
);
1665 /* Apportion the available screen space among the two new windows */
1667 if (!NULL (horflag
))
1669 p
->height
= o
->height
;
1671 XFASTINT (p
->width
) = XFASTINT (o
->width
) - size
;
1672 XFASTINT (o
->width
) = size
;
1673 XFASTINT (p
->left
) = XFASTINT (o
->left
) + size
;
1678 p
->width
= o
->width
;
1679 XFASTINT (p
->height
) = XFASTINT (o
->height
) - size
;
1680 XFASTINT (o
->height
) = size
;
1681 XFASTINT (p
->top
) = XFASTINT (o
->top
) + size
;
1687 DEFUN ("enlarge-window", Fenlarge_window
, Senlarge_window
, 1, 2, "p",
1688 "Make current window ARG lines bigger.\n\
1689 From program, optional second arg non-nil means grow sideways ARG columns.")
1691 register Lisp_Object n
, side
;
1693 CHECK_NUMBER (n
, 0);
1694 change_window_height (XINT (n
), !NULL (side
));
1698 DEFUN ("shrink-window", Fshrink_window
, Sshrink_window
, 1, 2, "p",
1699 "Make current window ARG lines smaller.\n\
1700 From program, optional second arg non-nil means shrink sideways ARG columns.")
1702 register Lisp_Object n
, side
;
1704 CHECK_NUMBER (n
, 0);
1705 change_window_height (-XINT (n
), !NULL (side
));
1710 window_height (window
)
1713 register struct window
*p
= XWINDOW (window
);
1714 return XFASTINT (p
->height
);
1718 window_width (window
)
1721 register struct window
*p
= XWINDOW (window
);
1722 return XFASTINT (p
->width
);
1725 #define MINSIZE(w) \
1726 (widthflag ? window_min_width : window_min_height)
1729 *(widthflag ? (int *) &(w)->left : (int *) &(w)->top)
1731 #define CURSIZE(w) \
1732 *(widthflag ? (int *) &(w)->width : (int *) &(w)->height)
1734 /* Unlike set_window_height, this function
1735 also changes the heights of the siblings so as to
1736 keep everything consistent. */
1738 change_window_height (delta
, widthflag
)
1742 register Lisp_Object parent
;
1744 register struct window
*p
;
1746 int (*sizefun
) () = widthflag
? window_width
: window_height
;
1747 register int (*setsizefun
) () = (widthflag
1749 : set_window_height
);
1751 /* Smaller values might permit a crash. */
1752 if (window_min_width
< 2)
1753 window_min_width
= 2;
1754 if (window_min_height
< 2)
1755 window_min_height
= 2;
1757 window
= selected_window
;
1760 p
= XWINDOW (window
);
1765 error ("No other window to side of this one");
1768 if (widthflag
? !NULL (XWINDOW (parent
)->hchild
)
1769 : !NULL (XWINDOW (parent
)->vchild
))
1774 sizep
= &CURSIZE (p
);
1776 if (*sizep
+ delta
< MINSIZE (p
)
1777 && !NULL (XWINDOW (window
)->parent
))
1779 Fdelete_window (window
);
1784 register int maxdelta
;
1785 register Lisp_Object tem
;
1787 maxdelta
= (!NULL (parent
) ? (*sizefun
) (parent
) - *sizep
1788 : (tem
= (!NULL (p
->next
) ? p
->next
: p
->prev
),
1789 (*sizefun
) (tem
) - MINSIZE (tem
)));
1791 if (delta
> maxdelta
)
1792 /* This case traps trying to make the minibuffer
1793 the full screen, or make the only window aside from the
1794 minibuffer the full screen. */
1798 if (!NULL (p
->next
) &&
1799 (*sizefun
) (p
->next
) - delta
>= MINSIZE (p
->next
))
1801 (*setsizefun
) (p
->next
, (*sizefun
) (p
->next
) - delta
, 0);
1802 (*setsizefun
) (window
, *sizep
+ delta
, 0);
1803 CURBEG (XWINDOW (p
->next
)) += delta
;
1804 /* This does not change size of p->next,
1805 but it propagates the new top edge to its children */
1806 (*setsizefun
) (p
->next
, (*sizefun
) (p
->next
), 0);
1808 else if (!NULL (p
->prev
) &&
1809 (*sizefun
) (p
->prev
) - delta
>= MINSIZE (p
->prev
))
1811 (*setsizefun
) (p
->prev
, (*sizefun
) (p
->prev
) - delta
, 0);
1812 CURBEG (p
) -= delta
;
1813 (*setsizefun
) (window
, *sizep
+ delta
, 0);
1817 register int delta1
;
1818 register int opht
= (*sizefun
) (parent
);
1820 /* If trying to grow this window to or beyond size of the parent,
1821 make delta1 so big that, on shrinking back down,
1822 all the siblings end up with less than one line and are deleted. */
1823 if (opht
<= *sizep
+ delta
)
1824 delta1
= opht
* opht
* 2;
1825 /* Otherwise, make delta1 just right so that if we add delta1
1826 lines to this window and to the parent, and then shrink
1827 the parent back to its original size, the new proportional
1828 size of this window will increase by delta. */
1830 delta1
= (delta
* opht
* 100) / ((opht
- *sizep
- delta
) * 100);
1832 /* Add delta1 lines or columns to this window, and to the parent,
1833 keeping things consistent while not affecting siblings. */
1834 CURSIZE (XWINDOW (parent
)) = opht
+ delta1
;
1835 (*setsizefun
) (window
, *sizep
+ delta1
, 0);
1837 /* Squeeze out delta1 lines or columns from our parent,
1838 shriking this window and siblings proportionately.
1839 This brings parent back to correct size.
1840 Delta1 was calculated so this makes this window the desired size,
1841 taking it all out of the siblings. */
1842 (*setsizefun
) (parent
, opht
, 0);
1845 XFASTINT (p
->last_modified
) = 0;
1852 /* Return number of lines of text (not counting mode line) in W. */
1855 window_internal_height (w
)
1858 int ht
= XFASTINT (w
->height
);
1860 if (MINI_WINDOW_P (w
))
1863 if (!NULL (w
->parent
) || !NULL (w
->vchild
) || !NULL (w
->hchild
)
1864 || !NULL (w
->next
) || !NULL (w
->prev
)
1865 || SCREEN_WANTS_MODELINE_P (XSCREEN (WINDOW_SCREEN (w
))))
1871 /* Scroll contents of window WINDOW up N lines. */
1874 window_scroll (window
, n
)
1878 register struct window
*w
= XWINDOW (window
);
1879 register int opoint
= point
;
1881 register int ht
= window_internal_height (w
);
1882 register Lisp_Object tem
;
1884 Lisp_Object bolp
, nmoved
;
1886 XFASTINT (tem
) = point
;
1887 tem
= Fpos_visible_in_window_p (tem
, window
);
1891 Fvertical_motion (make_number (- ht
/ 2));
1892 XFASTINT (tem
) = point
;
1893 Fset_marker (w
->start
, tem
, w
->buffer
);
1894 w
->force_start
= Qt
;
1897 SET_PT (marker_position (w
->start
));
1898 lose
= n
< 0 && point
== BEGV
;
1899 Fvertical_motion (make_number (n
));
1905 Fsignal (Qbeginning_of_buffer
, Qnil
);
1909 /* Allow scrolling to an empty screen (end of buffer)
1910 if that is exactly how far we wanted to go. */
1911 || XINT (nmoved
) == n
)
1914 set_marker_restricted (w
->start
, make_number (pos
), w
->buffer
);
1915 w
->start_at_line_beg
= bolp
;
1916 w
->update_mode_line
= Qt
;
1917 XFASTINT (w
->last_modified
) = 0;
1923 tem
= Fvertical_motion (make_number (ht
));
1924 if (point
> opoint
|| XFASTINT (tem
) < ht
)
1927 Fvertical_motion (make_number (-1));
1931 Fsignal (Qend_of_buffer
, Qnil
);
1934 /* This is the guts of Fscroll_up and Fscroll_down. */
1937 scroll_command (n
, direction
)
1938 register Lisp_Object n
;
1941 register int defalt
;
1942 int count
= specpdl_ptr
- specpdl
;
1944 /* If selected window's buffer isn't current, make it current for the moment.
1945 But don't screw up if window_scroll gets an error. */
1946 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
1948 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
1949 Fset_buffer (XWINDOW (selected_window
)->buffer
);
1952 defalt
= (window_internal_height (XWINDOW (selected_window
))
1953 - next_screen_context_lines
);
1954 defalt
= direction
* (defalt
< 1 ? 1 : defalt
);
1957 window_scroll (selected_window
, defalt
);
1958 else if (EQ (n
, Qminus
))
1959 window_scroll (selected_window
, - defalt
);
1962 n
= Fprefix_numeric_value (n
);
1963 window_scroll (selected_window
, XINT (n
) * direction
);
1966 unbind_to (count
, Qnil
);
1969 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "P",
1970 "Scroll text of current window upward ARG lines; or near full screen if no ARG.\n\
1971 A near full screen is `next-screen-context-lines' less than a full screen.\n\
1972 When calling from a program, supply a number as argument or nil.")
1976 scroll_command (n
, 1);
1980 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "P",
1981 "Scroll text of current window downward ARG lines; or near full screen if no ARG.\n\
1982 A near full screen is `next-screen-context-lines' less than a full screen.\n\
1983 When calling from a program, supply a number as argument or nil.")
1987 scroll_command (n
, -1);
1991 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
1992 "Scroll text of next window upward ARG lines; or near full screen if no ARG.\n\
1993 The next window is the one below the current one; or the one at the top\n\
1994 if the current one is at the bottom.\n\
1995 When calling from a program, supply a number as argument or nil.\n\
1997 If in the minibuffer, `minibuf-scroll-window' if non-nil\n\
1998 specifies the window to scroll.\n\
1999 If `other-window-scroll-buffer' is non-nil, scroll the window\n\
2000 showing that buffer, popping the buffer up if necessary.")
2002 register Lisp_Object n
;
2004 register Lisp_Object window
;
2006 register struct window
*w
;
2007 register int count
= specpdl_ptr
- specpdl
;
2009 if (MINI_WINDOW_P (XWINDOW (selected_window
))
2010 && !NULL (Vminibuf_scroll_window
))
2011 window
= Vminibuf_scroll_window
;
2012 /* If buffer is specified, scroll that buffer. */
2013 else if (!NULL (Vother_window_scroll_buffer
))
2015 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
2017 window
= Fdisplay_buffer (Vother_window_scroll_buffer
, Qt
);
2020 /* Nothing specified; pick a neighboring window. */
2021 window
= Fnext_window (selected_window
, Qnil
, Qt
);
2022 CHECK_WINDOW (window
, 0);
2024 if (EQ (window
, selected_window
))
2025 error ("There is no other window");
2027 w
= XWINDOW (window
);
2028 ht
= window_internal_height (w
);
2030 /* Don't screw up if window_scroll gets an error. */
2031 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
2033 Fset_buffer (w
->buffer
);
2034 SET_PT (marker_position (w
->pointm
));
2037 window_scroll (window
, ht
- next_screen_context_lines
);
2038 else if (EQ (n
, Qminus
))
2039 window_scroll (window
, next_screen_context_lines
- ht
);
2042 if (XTYPE (n
) == Lisp_Cons
)
2044 CHECK_NUMBER (n
, 0);
2045 window_scroll (window
, XINT (n
));
2048 Fset_marker (w
->pointm
, make_number (point
), Qnil
);
2054 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 1, 1, "P",
2055 "Scroll selected window display ARG columns left.\n\
2056 Default for ARG is window width minus 2.")
2058 register Lisp_Object arg
;
2062 XFASTINT (arg
) = XFASTINT (XWINDOW (selected_window
)->width
) - 2;
2064 arg
= Fprefix_numeric_value (arg
);
2067 Fset_window_hscroll (selected_window
,
2068 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
2072 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 1, 1, "P",
2073 "Scroll selected window display ARG columns right.\n\
2074 Default for ARG is window width minus 2.")
2076 register Lisp_Object arg
;
2079 XFASTINT (arg
) = XFASTINT (XWINDOW (selected_window
)->width
) - 2;
2081 arg
= Fprefix_numeric_value (arg
);
2084 Fset_window_hscroll (selected_window
,
2085 make_number (XINT (XWINDOW (selected_window
)->hscroll
)
2089 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
2090 "Center point in window and redisplay screen. With ARG, put point on line ARG.\n\
2091 The desired position of point is always relative to the current window.\n\
2092 Just C-u as prefix means put point in the center of the screen.\n\
2093 No arg (i.e., it is nil) erases the entire screen and then\n\
2094 redraws with point in the center.")
2096 register Lisp_Object n
;
2098 register struct window
*w
= XWINDOW (selected_window
);
2099 register int ht
= window_internal_height (w
);
2100 register int opoint
= point
;
2104 extern int screen_garbaged
;
2106 SET_SCREEN_GARBAGED (XSCREEN (WINDOW_SCREEN (w
)));
2107 XFASTINT (n
) = ht
/ 2;
2109 else if (XTYPE (n
) == Lisp_Cons
) /* Just C-u. */
2111 XFASTINT (n
) = ht
/ 2;
2115 n
= Fprefix_numeric_value (n
);
2116 CHECK_NUMBER (n
, 0);
2120 XSETINT (n
, XINT (n
) + ht
);
2122 XSETINT (n
, - XINT (n
));
2124 Fvertical_motion (n
);
2125 Fset_marker (w
->start
, make_number (point
), w
->buffer
);
2126 w
->start_at_line_beg
= Fbolp ();
2129 w
->force_start
= Qt
;
2134 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
2136 "Position point relative to window.\n\
2137 With no argument, position text at center of window.\n\
2138 An argument specifies screen line; zero means top of window,\n\
2139 negative means relative to bottom of window.")
2141 register Lisp_Object arg
;
2143 register struct window
*w
= XWINDOW (selected_window
);
2144 register int height
= window_internal_height (w
);
2148 XFASTINT (arg
) = height
/ 2;
2151 arg
= Fprefix_numeric_value (arg
);
2153 XSETINT (arg
, XINT (arg
) + height
);
2156 start
= marker_position (w
->start
);
2157 if (start
< BEGV
|| start
> ZV
)
2159 Fvertical_motion (make_number (- height
/ 2));
2160 Fset_marker (w
->start
, make_number (point
), w
->buffer
);
2161 w
->start_at_line_beg
= Fbolp ();
2162 w
->force_start
= Qt
;
2167 return Fvertical_motion (arg
);
2170 struct save_window_data
2172 int size_from_Lisp_Vector_struct
;
2173 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
2174 Lisp_Object screen_width
, screen_height
;
2175 Lisp_Object current_window
;
2176 Lisp_Object current_buffer
;
2177 Lisp_Object minibuf_scroll_window
;
2178 Lisp_Object root_window
;
2179 /* A vector, interpreted as a struct saved_window */
2180 Lisp_Object saved_windows
;
2182 #define SAVE_WINDOW_DATA_SIZE 7 /* Arg to Fmake_vector */
2184 /* This is saved as a Lisp_Vector */
2187 /* these first two must agree with struct Lisp_Vector in lisp.h */
2188 int size_from_Lisp_Vector_struct
;
2189 struct Lisp_Vector
*next_from_Lisp_Vector_struct
;
2192 Lisp_Object buffer
, start
, pointm
, mark
;
2193 Lisp_Object left
, top
, width
, height
, hscroll
;
2194 Lisp_Object parent
, prev
;
2195 Lisp_Object start_at_line_beg
;
2196 Lisp_Object display_table
;
2198 #define SAVED_WINDOW_VECTOR_SIZE 14 /* Arg to Fmake_vector */
2200 #define SAVED_WINDOW_N(swv,n) \
2201 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
2203 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
2204 "T if OBJECT is a window-configration object.")
2208 if (XTYPE (obj
) == Lisp_Window_Configuration
)
2214 DEFUN ("set-window-configuration",
2215 Fset_window_configuration
, Sset_window_configuration
,
2217 "Set the configuration of windows and buffers as specified by CONFIGURATION.\n\
2218 CONFIGURATION must be a value previously returned\n\
2219 by `current-window-configuration' (which see).")
2223 register struct window
*w
;
2224 register struct save_window_data
*data
;
2225 struct Lisp_Vector
*saved_windows
;
2226 register struct saved_window
*p
;
2227 register Lisp_Object tem
;
2228 Lisp_Object new_current_buffer
;
2232 while (XTYPE (arg
) != Lisp_Window_Configuration
)
2234 arg
= wrong_type_argument (intern ("window-configuration-p"), arg
);
2237 data
= (struct save_window_data
*) XVECTOR (arg
);
2238 saved_windows
= XVECTOR (data
->saved_windows
);
2240 s
= XSCREEN (XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->screen
);
2242 if (XFASTINT (data
->screen_height
) != SCREEN_HEIGHT (s
)
2243 || XFASTINT (data
->screen_width
) != SCREEN_WIDTH (s
))
2245 /* Presumably something clever could be done.
2246 However, it doesn't seem worth the effort */
2247 error ("Screen size %dx%d in saved window configuration mismatches screen.",
2248 XFASTINT (data
->screen_height
),
2249 XFASTINT (data
->screen_width
));
2252 windows_or_buffers_changed
++;
2253 new_current_buffer
= data
->current_buffer
;
2254 if (NULL (XBUFFER (new_current_buffer
)->name
))
2255 new_current_buffer
= Qnil
;
2257 /* Mark all windows now on screen as "deleted".
2258 Restoring the new configuration "undeletes" any that are in it. */
2260 delete_all_subwindows (XWINDOW (SCREEN_ROOT_WINDOW (s
)));
2262 /* This loses when the minibuf screen is not s. */
2263 delete_all_subwindows (XWINDOW (XWINDOW (minibuf_window
)->prev
));
2266 for (k
= 0; k
< saved_windows
->size
; k
++)
2268 p
= SAVED_WINDOW_N (saved_windows
, k
);
2269 w
= XWINDOW (p
->window
);
2272 if (!NULL (p
->parent
))
2273 w
->parent
= SAVED_WINDOW_N (saved_windows
, XFASTINT (p
->parent
))->window
;
2277 if (!NULL (p
->prev
))
2279 w
->prev
= SAVED_WINDOW_N (saved_windows
, XFASTINT (p
->prev
))->window
;
2281 /* This is true for a minibuffer-only screen. */
2282 if (w
->mini_p
&& EQ (w
->prev
, p
->window
))
2285 #endif /* MULTI_SCREEN */
2286 XWINDOW (w
->prev
)->next
= p
->window
;
2291 if (!NULL (w
->parent
))
2293 if (EQ (p
->width
, XWINDOW (w
->parent
)->width
))
2295 XWINDOW (w
->parent
)->vchild
= p
->window
;
2296 XWINDOW (w
->parent
)->hchild
= Qnil
;
2300 XWINDOW (w
->parent
)->hchild
= p
->window
;
2301 XWINDOW (w
->parent
)->vchild
= Qnil
;
2307 w
->width
= p
->width
;
2308 w
->height
= p
->height
;
2309 w
->hscroll
= p
->hscroll
;
2310 w
->display_table
= p
->display_table
;
2311 XFASTINT (w
->last_modified
) = 0;
2313 /* Reinstall the saved buffer and pointers into it. */
2314 if (NULL (p
->buffer
))
2315 w
->buffer
= p
->buffer
;
2318 if (!NULL (XBUFFER (p
->buffer
)->name
))
2319 /* If saved buffer is alive, install it. */
2321 w
->buffer
= p
->buffer
;
2322 w
->start_at_line_beg
= p
->start_at_line_beg
;
2323 set_marker_restricted (w
->start
, Fmarker_position (p
->start
), w
->buffer
);
2324 set_marker_restricted (w
->pointm
, Fmarker_position (p
->pointm
), w
->buffer
);
2325 Fset_marker (XBUFFER (w
->buffer
)->mark
,
2326 Fmarker_position (p
->mark
), w
->buffer
);
2328 if (!EQ (p
->buffer
, new_current_buffer
) &&
2329 XBUFFER (p
->buffer
) == current_buffer
)
2330 Fgoto_char (w
->pointm
);
2332 else if (NULL (XBUFFER (w
->buffer
)->name
))
2333 /* Else if window's old buffer is dead too, get a live one. */
2335 w
->buffer
= Fcdr (Fcar (Vbuffer_alist
));
2336 /* This will set the markers to beginning of visible range. */
2337 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
2338 set_marker_restricted (w
->pointm
, make_number (0), w
->buffer
);
2339 w
->start_at_line_beg
= Qt
;
2342 /* Keeping window's old buffer; make sure the markers are real. */
2343 /* Else if window's old buffer is dead too, get a live one. */
2345 /* Set window markers at start of visible range. */
2346 if (XMARKER (w
->start
)->buffer
== 0)
2347 set_marker_restricted (w
->start
, make_number (0), w
->buffer
);
2348 if (XMARKER (w
->pointm
)->buffer
== 0)
2349 set_marker_restricted (w
->pointm
,
2350 make_number (BUF_PT (XBUFFER (w
->buffer
))),
2352 w
->start_at_line_beg
= Qt
;
2357 SCREEN_ROOT_WINDOW (s
) = data
->root_window
;
2360 if (s
!= selected_screen
&& ! SCREEN_IS_TERMCAP (s
))
2361 Fselect_screen (WINDOW_SCREEN (XWINDOW (data
->root_window
)), Qnil
);
2364 if (s
== selected_screen
)
2366 Fselect_window (data
->current_window
);
2367 if (!NULL (new_current_buffer
))
2368 Fset_buffer (new_current_buffer
);
2370 Fset_buffer (XWINDOW (selected_window
)->buffer
);
2373 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
2377 /* Mark all windows now on screen as deleted
2378 by setting their buffers to nil. */
2381 delete_all_subwindows (w
)
2382 register struct window
*w
;
2384 register int count
= 1;
2386 if (!NULL (w
->next
))
2387 delete_all_subwindows (XWINDOW (w
->next
));
2388 if (!NULL (w
->vchild
))
2389 delete_all_subwindows (XWINDOW (w
->vchild
));
2390 if (!NULL (w
->hchild
))
2391 delete_all_subwindows (XWINDOW (w
->hchild
));
2395 count_windows (window
)
2396 register struct window
*window
;
2398 register int count
= 1;
2399 if (!NULL (window
->next
))
2400 count
+= count_windows (XWINDOW (window
->next
));
2401 if (!NULL (window
->vchild
))
2402 count
+= count_windows (XWINDOW (window
->vchild
));
2403 if (!NULL (window
->hchild
))
2404 count
+= count_windows (XWINDOW (window
->hchild
));
2409 save_window_save (window
, vector
, i
)
2411 struct Lisp_Vector
*vector
;
2414 register struct saved_window
*p
;
2415 register struct window
*w
;
2416 register Lisp_Object tem
;
2418 for (;!NULL (window
); window
= w
->next
)
2420 p
= SAVED_WINDOW_N (vector
, i
);
2421 w
= XWINDOW (window
);
2423 XFASTINT (w
->temslot
) = i
++;
2425 p
->buffer
= w
->buffer
;
2428 p
->width
= w
->width
;
2429 p
->height
= w
->height
;
2430 p
->hscroll
= w
->hscroll
;
2431 p
->display_table
= w
->display_table
;
2432 if (!NULL (w
->buffer
))
2434 /* Save w's value of point in the window configuration.
2435 If w is the selected window, then get the value of point
2436 from the buffer; pointm is garbage in the selected window. */
2437 if (EQ (window
, selected_window
))
2439 p
->pointm
= Fmake_marker ();
2440 Fset_marker (p
->pointm
, BUF_PT (XBUFFER (w
->buffer
)),
2444 p
->pointm
= Fcopy_marker (w
->pointm
);
2446 p
->start
= Fcopy_marker (w
->start
);
2447 p
->start_at_line_beg
= w
->start_at_line_beg
;
2449 tem
= XBUFFER (w
->buffer
)->mark
;
2450 p
->mark
= Fcopy_marker (tem
);
2457 p
->start_at_line_beg
= Qnil
;
2460 if (NULL (w
->parent
))
2463 p
->parent
= XWINDOW (w
->parent
)->temslot
;
2468 p
->prev
= XWINDOW (w
->prev
)->temslot
;
2470 if (!NULL (w
->vchild
))
2471 i
= save_window_save (w
->vchild
, vector
, i
);
2472 if (!NULL (w
->hchild
))
2473 i
= save_window_save (w
->hchild
, vector
, i
);
2479 DEFUN ("current-window-configuration",
2480 Fcurrent_window_configuration
, Scurrent_window_configuration
, 0, 1, 0,
2481 "Return an object representing the current window configuration of SCREEN.\n\
2482 If SCREEN is nil or omitted, use the selected screen.\n\
2483 This describes the number of windows, their sizes and current buffers,\n\
2484 and for each displayed buffer, where display starts, and the positions of\n\
2485 point and mark. An exception is made for point in the current buffer:\n\
2486 its value is -not- saved.")
2490 register Lisp_Object tem
;
2491 register int n_windows
;
2492 register struct save_window_data
*data
;
2497 s
= selected_screen
;
2500 CHECK_SCREEN (screen
, 0);
2501 s
= XSCREEN (screen
);
2504 n_windows
= count_windows (XWINDOW (SCREEN_ROOT_WINDOW (s
)));
2505 data
= (struct save_window_data
*)
2506 XVECTOR (Fmake_vector (make_number (SAVE_WINDOW_DATA_SIZE
),
2508 XFASTINT (data
->screen_width
) = SCREEN_WIDTH (s
);
2509 XFASTINT (data
->screen_height
) = SCREEN_HEIGHT (s
);
2510 data
->current_window
= SCREEN_SELECTED_WINDOW (s
);
2511 XSET (data
->current_buffer
, Lisp_Buffer
, current_buffer
);
2512 data
->minibuf_scroll_window
= Vminibuf_scroll_window
;
2513 data
->root_window
= SCREEN_ROOT_WINDOW (s
);
2514 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
2515 data
->saved_windows
= tem
;
2516 for (i
= 0; i
< n_windows
; i
++)
2517 XVECTOR (tem
)->contents
[i
]
2518 = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE
), Qnil
);
2519 save_window_save (SCREEN_ROOT_WINDOW (s
),
2521 XSET (tem
, Lisp_Window_Configuration
, data
);
2525 DEFUN ("save-window-excursion", Fsave_window_excursion
, Ssave_window_excursion
,
2527 "Execute body, preserving window sizes and contents.\n\
2528 Restores which buffer appears in which window, where display starts,\n\
2529 as well as the current buffer.\n\
2530 Does not restore the value of point in current buffer.")
2534 register Lisp_Object val
;
2535 register int count
= specpdl_ptr
- specpdl
;
2537 record_unwind_protect (Fset_window_configuration
,
2538 Fcurrent_window_configuration (Qnil
));
2539 val
= Fprogn (args
);
2540 return unbind_to (count
, val
);
2546 selected_screen
= make_terminal_screen ();
2547 minibuf_window
= selected_screen
->minibuffer_window
;
2548 selected_window
= selected_screen
->selected_window
;
2549 #else /* not MULTI_SCREEN */
2550 extern Lisp_Object
get_minibuffer ();
2552 root_window
= make_window (0);
2553 minibuf_window
= make_window (0);
2555 XWINDOW (root_window
)->next
= minibuf_window
;
2556 XWINDOW (minibuf_window
)->prev
= root_window
;
2558 /* These values 9 and 10 are arbitrary,
2559 just so that there is "something there."
2560 Correct values are put in in init_xdisp */
2562 XFASTINT (XWINDOW (root_window
)->width
) = 10;
2563 XFASTINT (XWINDOW (minibuf_window
)->width
) = 10;
2565 XFASTINT (XWINDOW (root_window
)->height
) = 9;
2566 XFASTINT (XWINDOW (minibuf_window
)->top
) = 9;
2567 XFASTINT (XWINDOW (minibuf_window
)->height
) = 1;
2569 /* Prevent error in Fset_window_buffer. */
2570 XWINDOW (root_window
)->buffer
= Qt
;
2571 XWINDOW (minibuf_window
)->buffer
= Qt
;
2573 /* Now set them up for real. */
2574 Fset_window_buffer (root_window
, Fcurrent_buffer ());
2575 Fset_window_buffer (minibuf_window
, get_minibuffer (0));
2577 selected_window
= root_window
;
2578 /* Make sure this window seems more recently used than
2579 a newly-created, never-selected window. Increment
2580 window_select_count so the first selection ever will get
2581 something newer than this. */
2582 XFASTINT (XWINDOW (selected_window
)->use_time
) = ++window_select_count
;
2583 #endif /* not MULTI_SCREEN */
2588 Qwindowp
= intern ("windowp");
2589 staticpro (&Qwindowp
);
2591 /* Make sure all windows get marked */
2592 staticpro (&minibuf_window
);
2594 DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function
,
2595 "Non-nil means call as function to display a help buffer.\n\
2596 Used by `with-output-to-temp-buffer'.");
2597 Vtemp_buffer_show_function
= Qnil
;
2599 DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function
,
2600 "If non-nil, function to call to handle `display-buffer'.\n\
2601 It will receive two args, the buffer and a flag which if non-nil means\n\
2602 that the currently selected window is not acceptable.\n\
2603 Commands such as `switch-to-buffer-other-window' and `find-file-other-window'\n\
2604 work using this function.");
2605 Vdisplay_buffer_function
= Qnil
;
2607 DEFVAR_LISP ("mouse-window", &Vmouse_window
,
2608 "Window that the last mouse click occurred on.");
2609 Vmouse_window
= Qnil
;
2611 DEFVAR_LISP ("mouse-event", &Vmouse_event
,
2612 "The last mouse-event object. A list of four elements:\n\
2613 ((X-POS Y-POS) WINDOW SCREEN-PART KEYSEQ).\n\
2614 KEYSEQ is a string, the key sequence to be looked up in the mouse maps.\n\
2615 WINDOW is the window that the click applies do.\n\
2616 If SCREEN-PART is non-nil, the event was on a scrollbar;\n\
2617 then Y-POS is really the total length of the scrollbar, while X-POS is\n\
2618 the relative position of the scrollbar's value within that total length.\n\
2619 SCREEN-PART is one of the following symbols:\n\
2620 `vertical-scrollbar', `vertical-slider',\n\
2621 `vertical-thumbup', `vertical-thumbdown',\n\
2622 `horizontal-scrollbar', `horizontal-slider',\n\
2623 `horizontal-thumbleft', `horizontal-thumbright'");
2624 Vmouse_event
= Qnil
;
2626 DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window
,
2627 "Non-nil means it is the window that C-M-v in minibuffer should scroll.");
2628 Vminibuf_scroll_window
= Qnil
;
2630 DEFVAR_LISP ("other-window-scroll-buffer", &Vother_window_scroll_buffer
,
2631 "If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window.");
2632 Vother_window_scroll_buffer
= Qnil
;
2635 DEFVAR_BOOL ("pop-up-screens", &pop_up_screens
,
2636 "*Non-nil means `display-buffer' should make a separate X-window.");
2639 DEFVAR_LISP ("pop-up-screen-function", &Vpop_up_screen_function
,
2640 "*If non-nil, function to call to handle automatic new screen creation.\n\
2641 It is called with no arguments and should return a newly created screen.\n\
2643 A typical value might be `(lambda () (x-create-screen auto-screen-parms))'\n\
2644 where `auto-screen-parms' would hold the default screen parameters.");
2645 Vpop_up_screen_function
= Qnil
;
2648 DEFVAR_BOOL ("pop-up-windows", &pop_up_windows
,
2649 "*Non-nil means display-buffer should make new windows.");
2652 DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines
,
2653 "*Number of lines of continuity when scrolling by screenfuls.");
2654 next_screen_context_lines
= 2;
2656 DEFVAR_INT ("split-height-threshold", &split_height_threshold
,
2657 "*display-buffer would prefer to split the largest window if this large.\n\
2658 If there is only one window, it is split regardless of this value.");
2659 split_height_threshold
= 500;
2661 DEFVAR_INT ("window-min-height", &window_min_height
,
2662 "*Delete any window less than this tall (including its mode line).");
2663 window_min_height
= 4;
2665 DEFVAR_INT ("window-min-width", &window_min_width
,
2666 "*Delete any window less than this wide.");
2667 window_min_width
= 10;
2669 defsubr (&Sselected_window
);
2670 defsubr (&Sminibuffer_window
);
2671 defsubr (&Swindow_minibuffer_p
);
2672 defsubr (&Swindowp
);
2673 defsubr (&Spos_visible_in_window_p
);
2674 defsubr (&Swindow_buffer
);
2675 defsubr (&Swindow_height
);
2676 defsubr (&Swindow_width
);
2677 defsubr (&Swindow_hscroll
);
2678 defsubr (&Sset_window_hscroll
);
2679 defsubr (&Swindow_edges
);
2680 defsubr (&Slocate_window_from_coordinates
);
2681 defsubr (&Swindow_point
);
2682 defsubr (&Swindow_start
);
2683 defsubr (&Swindow_end
);
2684 defsubr (&Sset_window_point
);
2685 defsubr (&Sset_window_start
);
2686 defsubr (&Swindow_dedicated_p
);
2687 defsubr (&Sset_window_buffer_dedicated
);
2688 defsubr (&Swindow_display_table
);
2689 defsubr (&Sset_window_display_table
);
2690 defsubr (&Snext_window
);
2691 defsubr (&Sprevious_window
);
2692 defsubr (&Sother_window
);
2693 defsubr (&Sget_lru_window
);
2694 defsubr (&Sget_largest_window
);
2695 defsubr (&Sget_buffer_window
);
2696 defsubr (&Sdelete_other_windows
);
2697 defsubr (&Sdelete_windows_on
);
2698 defsubr (&Sreplace_buffer_in_windows
);
2699 defsubr (&Sdelete_window
);
2700 defsubr (&Sset_window_buffer
);
2701 defsubr (&Sselect_window
);
2702 defsubr (&Sdisplay_buffer
);
2703 defsubr (&Ssplit_window
);
2704 defsubr (&Senlarge_window
);
2705 defsubr (&Sshrink_window
);
2706 defsubr (&Sscroll_up
);
2707 defsubr (&Sscroll_down
);
2708 defsubr (&Sscroll_left
);
2709 defsubr (&Sscroll_right
);
2710 defsubr (&Sscroll_other_window
);
2711 defsubr (&Srecenter
);
2712 defsubr (&Smove_to_window_line
);
2713 defsubr (&Swindow_configuration_p
);
2714 defsubr (&Sset_window_configuration
);
2715 defsubr (&Scurrent_window_configuration
);
2716 defsubr (&Ssave_window_excursion
);
2721 initial_define_key (control_x_map
, '1', "delete-other-windows");
2722 initial_define_key (control_x_map
, '2', "split-window");
2723 initial_define_key (control_x_map
, '0', "delete-window");
2724 initial_define_key (control_x_map
, 'o', "other-window");
2725 initial_define_key (control_x_map
, '^', "enlarge-window");
2726 initial_define_key (control_x_map
, '<', "scroll-left");
2727 initial_define_key (control_x_map
, '>', "scroll-right");
2729 initial_define_key (global_map
, Ctl ('V'), "scroll-up");
2730 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
2731 initial_define_key (meta_map
, 'v', "scroll-down");
2733 initial_define_key (global_map
, Ctl('L'), "recenter");
2734 initial_define_key (meta_map
, 'r', "move-to-window-line");