1 /* Window creation, deletion and examination for GNU Emacs.
2 Does not include redisplay.
3 Copyright (C) 1985-1987, 1993-1998, 2000-2012
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26 #include "character.h"
36 #include "dispextern.h"
37 #include "blockinput.h"
38 #include "intervals.h"
39 #include "termhooks.h" /* For FRAME_TERMINAL. */
43 #endif /* HAVE_X_WINDOWS */
54 Lisp_Object Qwindowp
, Qwindow_live_p
, Qwindow_valid_p
;
55 static Lisp_Object Qwindow_configuration_p
, Qrecord_window_buffer
;
56 static Lisp_Object Qwindow_deletable_p
, Qdelete_window
, Qdisplay_buffer
;
57 static Lisp_Object Qreplace_buffer_in_windows
, Qget_mru_window
;
58 static Lisp_Object Qwindow_resize_root_window
, Qwindow_resize_root_window_vertically
;
59 static Lisp_Object Qscroll_up
, Qscroll_down
, Qscroll_command
;
60 static Lisp_Object Qsafe
, Qabove
, Qbelow
;
61 static Lisp_Object Qauto_buffer_name
, Qclone_of
;
63 static int displayed_window_lines (struct window
*);
64 static int count_windows (struct window
*);
65 static int get_leaf_windows (struct window
*, struct window
**, int);
66 static void window_scroll (Lisp_Object
, EMACS_INT
, int, int);
67 static void window_scroll_pixel_based (Lisp_Object
, int, int, int);
68 static void window_scroll_line_based (Lisp_Object
, int, int, int);
69 static int freeze_window_start (struct window
*, void *);
70 static Lisp_Object
window_list (void);
71 static int add_window_to_list (struct window
*, void *);
72 static int candidate_window_p (Lisp_Object
, Lisp_Object
, Lisp_Object
,
74 static Lisp_Object
next_window (Lisp_Object
, Lisp_Object
,
76 static void decode_next_window_args (Lisp_Object
*, Lisp_Object
*,
78 static void foreach_window (struct frame
*,
79 int (* fn
) (struct window
*, void *),
81 static int foreach_window_1 (struct window
*,
82 int (* fn
) (struct window
*, void *),
84 static Lisp_Object
window_list_1 (Lisp_Object
, Lisp_Object
, Lisp_Object
);
85 static int window_resize_check (struct window
*, int);
86 static void window_resize_apply (struct window
*, int);
87 static Lisp_Object
select_window (Lisp_Object
, Lisp_Object
, int);
89 /* This is the window in which the terminal's cursor should
90 be left when nothing is being done with it. This must
91 always be a leaf window, and its buffer is selected by
92 the top level editing loop at the end of each command.
94 This value is always the same as
95 FRAME_SELECTED_WINDOW (selected_frame). */
96 Lisp_Object selected_window
;
98 /* A list of all windows for use by next_window and Fwindow_list.
99 Functions creating or deleting windows should invalidate this cache
100 by setting it to nil. */
101 Lisp_Object Vwindow_list
;
103 /* The mini-buffer window of the selected frame.
104 Note that you cannot test for mini-bufferness of an arbitrary window
105 by comparing against this; but you can test for mini-bufferness of
106 the selected window. */
107 Lisp_Object minibuf_window
;
109 /* Non-nil means it is the window whose mode line should be
110 shown as the selected window when the minibuffer is selected. */
111 Lisp_Object minibuf_selected_window
;
113 /* Hook run at end of temp_output_buffer_show. */
114 static Lisp_Object Qtemp_buffer_show_hook
;
116 /* Incremented for each window created. */
117 static int sequence_number
;
119 /* Nonzero after init_window_once has finished. */
120 static int window_initialized
;
122 /* Hook to run when window config changes. */
123 static Lisp_Object Qwindow_configuration_change_hook
;
125 /* Used by the function window_scroll_pixel_based */
126 static int window_scroll_pixel_based_preserve_x
;
127 static int window_scroll_pixel_based_preserve_y
;
129 /* Same for window_scroll_line_based. */
130 static EMACS_INT window_scroll_preserve_hpos
;
131 static EMACS_INT window_scroll_preserve_vpos
;
134 decode_live_window (register Lisp_Object window
)
137 return XWINDOW (selected_window
);
139 CHECK_LIVE_WINDOW (window
);
140 return XWINDOW (window
);
143 static struct window
*
144 decode_any_window (register Lisp_Object window
)
149 return XWINDOW (selected_window
);
151 CHECK_WINDOW (window
);
152 w
= XWINDOW (window
);
157 decode_valid_window (register Lisp_Object window
)
162 return XWINDOW (selected_window
);
164 CHECK_VALID_WINDOW (window
);
165 w
= XWINDOW (window
);
169 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
170 doc
: /* Return t if OBJECT is a window and nil otherwise. */)
173 return WINDOWP (object
) ? Qt
: Qnil
;
176 DEFUN ("window-valid-p", Fwindow_valid_p
, Swindow_valid_p
, 1, 1, 0,
177 doc
: /* Return t if OBJECT is a valid window and nil otherwise.
178 A valid window is either a window that displays a buffer or an internal
179 window. Deleted windows are not live. */)
182 return WINDOW_VALID_P (object
) ? Qt
: Qnil
;
185 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
186 doc
: /* Return t if OBJECT is a live window and nil otherwise.
187 A live window is a window that displays a buffer.
188 Internal windows and deleted windows are not live. */)
191 return WINDOW_LIVE_P (object
) ? Qt
: Qnil
;
194 /* Frames and windows. */
195 DEFUN ("window-frame", Fwindow_frame
, Swindow_frame
, 1, 1, 0,
196 doc
: /* Return the frame that window WINDOW is on.
197 WINDOW must be a valid window and defaults to the selected one. */)
200 return decode_valid_window (window
)->frame
;
203 DEFUN ("frame-root-window", Fframe_root_window
, Sframe_root_window
, 0, 1, 0,
204 doc
: /* Return the root window of FRAME-OR-WINDOW.
205 If omitted, FRAME-OR-WINDOW defaults to the currently selected frame.
206 With a frame argument, return that frame's root window.
207 With a window argument, return the root window of that window's frame. */)
208 (Lisp_Object frame_or_window
)
212 if (NILP (frame_or_window
))
213 window
= SELECTED_FRAME ()->root_window
;
214 else if (WINDOW_VALID_P (frame_or_window
))
215 window
= XFRAME (XWINDOW (frame_or_window
)->frame
)->root_window
;
218 CHECK_LIVE_FRAME (frame_or_window
);
219 window
= XFRAME (frame_or_window
)->root_window
;
225 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
226 doc
: /* Return the minibuffer window for frame FRAME.
227 If FRAME is omitted or nil, it defaults to the selected frame. */)
231 frame
= selected_frame
;
232 CHECK_LIVE_FRAME (frame
);
233 return FRAME_MINIBUF_WINDOW (XFRAME (frame
));
236 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
,
237 Swindow_minibuffer_p
, 0, 1, 0,
238 doc
: /* Return non-nil if WINDOW is a minibuffer window.
239 WINDOW must be a valid window and defaults to the selected one. */)
242 return MINI_WINDOW_P (decode_valid_window (window
)) ? Qt
: Qnil
;
245 /* Don't move this to window.el - this must be a safe routine. */
246 DEFUN ("frame-first-window", Fframe_first_window
, Sframe_first_window
, 0, 1, 0,
247 doc
: /* Return the topmost, leftmost live window on FRAME-OR-WINDOW.
248 If omitted, FRAME-OR-WINDOW defaults to the currently selected frame.
249 Else if FRAME-OR-WINDOW denotes a valid window, return the first window
250 of that window's frame. If FRAME-OR-WINDOW denotes a live frame, return
251 the first window of that frame. */)
252 (Lisp_Object frame_or_window
)
256 if (NILP (frame_or_window
))
257 window
= SELECTED_FRAME ()->root_window
;
258 else if (WINDOW_VALID_P (frame_or_window
))
259 window
= XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window
)))->root_window
;
262 CHECK_LIVE_FRAME (frame_or_window
);
263 window
= XFRAME (frame_or_window
)->root_window
;
266 while (NILP (XWINDOW (window
)->buffer
))
268 if (! NILP (XWINDOW (window
)->hchild
))
269 window
= XWINDOW (window
)->hchild
;
270 else if (! NILP (XWINDOW (window
)->vchild
))
271 window
= XWINDOW (window
)->vchild
;
279 DEFUN ("frame-selected-window", Fframe_selected_window
,
280 Sframe_selected_window
, 0, 1, 0,
281 doc
: /* Return the selected window of FRAME-OR-WINDOW.
282 If omitted, FRAME-OR-WINDOW defaults to the currently selected frame.
283 Else if FRAME-OR-WINDOW denotes a valid window, return the selected
284 window of that window's frame. If FRAME-OR-WINDOW denotes a live frame,
285 return the selected window of that frame. */)
286 (Lisp_Object frame_or_window
)
290 if (NILP (frame_or_window
))
291 window
= SELECTED_FRAME ()->selected_window
;
292 else if (WINDOW_VALID_P (frame_or_window
))
293 window
= XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window
)))->selected_window
;
296 CHECK_LIVE_FRAME (frame_or_window
);
297 window
= XFRAME (frame_or_window
)->selected_window
;
303 DEFUN ("set-frame-selected-window", Fset_frame_selected_window
,
304 Sset_frame_selected_window
, 2, 3, 0,
305 doc
: /* Set selected window of FRAME to WINDOW.
306 FRAME must be a live frame and defaults to the selected one. If FRAME
307 is the selected frame, this makes WINDOW the selected window. Optional
308 argument NORECORD non-nil means to neither change the order of recently
309 selected windows nor the buffer list. WINDOW must denote a live window.
311 (Lisp_Object frame
, Lisp_Object window
, Lisp_Object norecord
)
314 frame
= selected_frame
;
316 CHECK_LIVE_FRAME (frame
);
317 CHECK_LIVE_WINDOW (window
);
319 if (! EQ (frame
, WINDOW_FRAME (XWINDOW (window
))))
320 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
322 if (EQ (frame
, selected_frame
))
323 return Fselect_window (window
, norecord
);
326 fset_selected_window (XFRAME (frame
), window
);
331 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
332 doc
: /* Return the selected window.
333 The selected window is the window in which the standard cursor for
334 selected windows appears and to which many commands apply. */)
337 return selected_window
;
340 int window_select_count
;
342 /* If select_window is called with inhibit_point_swap non-zero it will
343 not store point of the old selected window's buffer back into that
344 window's pointm slot. This is needed by Fset_window_configuration to
345 avoid that the display routine is called with selected_window set to
346 Qnil causing a subsequent crash. */
348 select_window (Lisp_Object window
, Lisp_Object norecord
, int inhibit_point_swap
)
350 register struct window
*w
;
351 register struct window
*ow
;
354 CHECK_LIVE_WINDOW (window
);
356 w
= XWINDOW (window
);
357 w
->frozen_window_start_p
= 0;
361 w
->use_time
= ++window_select_count
;
362 record_buffer (w
->buffer
);
365 if (EQ (window
, selected_window
) && !inhibit_point_swap
)
368 sf
= SELECTED_FRAME ();
369 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
371 fset_selected_window (XFRAME (WINDOW_FRAME (w
)), window
);
372 /* Use this rather than Fhandle_switch_frame
373 so that FRAME_FOCUS_FRAME is moved appropriately as we
374 move around in the state where a minibuffer in a separate
376 Fselect_frame (WINDOW_FRAME (w
), norecord
);
377 /* Fselect_frame called us back so we've done all the work already. */
378 eassert (EQ (window
, selected_window
));
382 fset_selected_window (sf
, window
);
384 /* Store the current buffer's actual point into the
385 old selected window. It belongs to that window,
386 and when the window is not selected, must be in the window. */
387 if (!inhibit_point_swap
)
389 ow
= XWINDOW (selected_window
);
390 if (! NILP (ow
->buffer
))
391 set_marker_both (ow
->pointm
, ow
->buffer
,
392 BUF_PT (XBUFFER (ow
->buffer
)),
393 BUF_PT_BYTE (XBUFFER (ow
->buffer
)));
396 selected_window
= window
;
398 Fset_buffer (w
->buffer
);
400 BSET (XBUFFER (w
->buffer
), last_selected_window
, window
);
402 /* Go to the point recorded in the window.
403 This is important when the buffer is in more
404 than one window. It also matters when
405 redisplay_window has altered point after scrolling,
406 because it makes the change only in the window. */
408 register ptrdiff_t new_point
= marker_position (w
->pointm
);
409 if (new_point
< BEGV
)
411 else if (new_point
> ZV
)
417 windows_or_buffers_changed
++;
421 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 2, 0,
422 doc
: /* Select WINDOW. Most editing will apply to WINDOW's buffer.
423 Also make WINDOW's buffer current and make WINDOW the frame's selected
424 window. Return WINDOW.
426 Optional second arg NORECORD non-nil means do not put this buffer at the
427 front of the buffer list and do not make this window the most recently
430 Note that the main editor command loop sets the current buffer to the
431 buffer of the selected window before each command. */)
432 (register Lisp_Object window
, Lisp_Object norecord
)
434 return select_window (window
, norecord
, 0);
437 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
438 doc
: /* Return the buffer displayed in window WINDOW.
439 If WINDOW is omitted or nil, it defaults to the selected window.
440 Return nil for an internal window or a deleted window. */)
443 return decode_any_window (window
)->buffer
;
446 DEFUN ("window-parent", Fwindow_parent
, Swindow_parent
, 0, 1, 0,
447 doc
: /* Return the parent window of window WINDOW.
448 WINDOW must be a valid window and defaults to the selected one.
449 Return nil for a window with no parent (e.g. a root window). */)
452 return decode_valid_window (window
)->parent
;
455 DEFUN ("window-top-child", Fwindow_top_child
, Swindow_top_child
, 1, 1, 0,
456 doc
: /* Return the topmost child window of window WINDOW.
457 WINDOW must be a valid window and defaults to the selected one.
458 Return nil if WINDOW is a live window (live windows have no children).
459 Return nil if WINDOW is an internal window whose children form a
460 horizontal combination. */)
463 CHECK_WINDOW (window
);
464 return decode_valid_window (window
)->vchild
;
467 DEFUN ("window-left-child", Fwindow_left_child
, Swindow_left_child
, 1, 1, 0,
468 doc
: /* Return the leftmost child window of window WINDOW.
469 WINDOW must be a valid window and defaults to the selected one.
470 Return nil if WINDOW is a live window (live windows have no children).
471 Return nil if WINDOW is an internal window whose children form a
472 vertical combination. */)
475 CHECK_WINDOW (window
);
476 return decode_valid_window (window
)->hchild
;
479 DEFUN ("window-next-sibling", Fwindow_next_sibling
, Swindow_next_sibling
, 0, 1, 0,
480 doc
: /* Return the next sibling window of window WINDOW.
481 WINDOW must be a valid window and defaults to the selected one.
482 Return nil if WINDOW has no next sibling. */)
485 return decode_valid_window (window
)->next
;
488 DEFUN ("window-prev-sibling", Fwindow_prev_sibling
, Swindow_prev_sibling
, 0, 1, 0,
489 doc
: /* Return the previous sibling window of window WINDOW.
490 WINDOW must be a valid window and defaults to the selected one.
491 Return nil if WINDOW has no previous sibling. */)
494 return decode_valid_window (window
)->prev
;
497 DEFUN ("window-combination-limit", Fwindow_combination_limit
, Swindow_combination_limit
, 1, 1, 0,
498 doc
: /* Return combination limit of window WINDOW.
499 WINDOW must be a valid window and defaults to the selected one.
500 If the return value is nil, child windows of WINDOW can be recombined with
501 WINDOW's siblings. A return value of t means that child windows of
502 WINDOW are never \(re-)combined with WINDOW's siblings. */)
505 return decode_valid_window (window
)->combination_limit
;
508 DEFUN ("set-window-combination-limit", Fset_window_combination_limit
, Sset_window_combination_limit
, 2, 2, 0,
509 doc
: /* Set combination limit of window WINDOW to LIMIT; return LIMIT.
510 WINDOW must be a valid window and defaults to the selected one.
511 If LIMIT is nil, child windows of WINDOW can be recombined with
512 WINDOW's siblings. LIMIT t means that child windows of WINDOW are
513 never \(re-)combined with WINDOW's siblings. Other values are reserved
515 (Lisp_Object window
, Lisp_Object limit
)
517 return WSET (decode_valid_window (window
), combination_limit
, limit
);
520 DEFUN ("window-use-time", Fwindow_use_time
, Swindow_use_time
, 0, 1, 0,
521 doc
: /* Return the use time of window WINDOW.
522 WINDOW must be a live window and defaults to the selected one.
523 The window with the highest use time is the most recently selected
524 one. The window with the lowest use time is the least recently
528 return make_number (decode_live_window (window
)->use_time
);
531 DEFUN ("window-total-height", Fwindow_total_height
, Swindow_total_height
, 0, 1, 0,
532 doc
: /* Return the total height, in lines, of window WINDOW.
533 WINDOW must be a valid window and defaults to the selected one.
535 The return value includes the mode line and header line, if any.
536 If WINDOW is an internal window, the total height is the height
537 of the screen areas spanned by its children.
539 On a graphical display, this total height is reported as an
540 integer multiple of the default character height. */)
543 return decode_valid_window (window
)->total_lines
;
546 DEFUN ("window-total-width", Fwindow_total_width
, Swindow_total_width
, 0, 1, 0,
547 doc
: /* Return the total width, in columns, of window WINDOW.
548 WINDOW must be a valid window and defaults to the selected one.
550 The return value includes any vertical dividers or scroll bars
551 belonging to WINDOW. If WINDOW is an internal window, the total width
552 is the width of the screen areas spanned by its children.
554 On a graphical display, this total width is reported as an
555 integer multiple of the default character width. */)
558 return decode_valid_window (window
)->total_cols
;
561 DEFUN ("window-new-total", Fwindow_new_total
, Swindow_new_total
, 0, 1, 0,
562 doc
: /* Return the new total size of window WINDOW.
563 WINDOW must be a valid window and defaults to the selected one. */)
566 return decode_valid_window (window
)->new_total
;
569 DEFUN ("window-normal-size", Fwindow_normal_size
, Swindow_normal_size
, 0, 2, 0,
570 doc
: /* Return the normal height of window WINDOW.
571 WINDOW must be a valid window and defaults to the selected one.
572 If HORIZONTAL is non-nil, return the normal width of WINDOW. */)
573 (Lisp_Object window
, Lisp_Object horizontal
)
575 struct window
*w
= decode_valid_window (window
);
577 return NILP (horizontal
) ? w
->normal_lines
: w
->normal_cols
;
580 DEFUN ("window-new-normal", Fwindow_new_normal
, Swindow_new_normal
, 0, 1, 0,
581 doc
: /* Return new normal size of window WINDOW.
582 WINDOW must be a valid window and defaults to the selected one. */)
585 return decode_valid_window (window
)->new_normal
;
588 DEFUN ("window-left-column", Fwindow_left_column
, Swindow_left_column
, 0, 1, 0,
589 doc
: /* Return left column of window WINDOW.
590 This is the distance, in columns, between the left edge of WINDOW and
591 the left edge of the frame's window area. For instance, the return
592 value is 0 if there is no window to the left of WINDOW.
594 WINDOW must be a valid window and defaults to the selected one. */)
597 return decode_valid_window (window
)->left_col
;
600 DEFUN ("window-top-line", Fwindow_top_line
, Swindow_top_line
, 0, 1, 0,
601 doc
: /* Return top line of window WINDOW.
602 This is the distance, in lines, between the top of WINDOW and the top
603 of the frame's window area. For instance, the return value is 0 if
604 there is no window above WINDOW.
606 WINDOW must be a valid window and defaults to the selected one. */)
609 return decode_valid_window (window
)->top_line
;
612 /* Return the number of lines of W's body. Don't count any mode or
616 window_body_lines (struct window
*w
)
618 int height
= XFASTINT (w
->total_lines
);
620 if (!MINI_WINDOW_P (w
))
622 if (WINDOW_WANTS_MODELINE_P (w
))
624 if (WINDOW_WANTS_HEADER_LINE_P (w
))
631 /* Return the number of columns of W's body. Don't count columns
632 occupied by the scroll bar or the vertical bar separating W from its
633 right sibling. On window-systems don't count fringes or display
637 window_body_cols (struct window
*w
)
639 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
640 int width
= XINT (w
->total_cols
);
642 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
643 /* Scroll bars occupy a few columns. */
644 width
-= WINDOW_CONFIG_SCROLL_BAR_COLS (w
);
645 else if (!FRAME_WINDOW_P (f
)
646 && !WINDOW_RIGHTMOST_P (w
) && !WINDOW_FULL_WIDTH_P (w
))
647 /* The column of `|' characters separating side-by-side windows
648 occupies one column only. */
651 if (FRAME_WINDOW_P (f
))
652 /* On window-systems, fringes and display margins cannot be
653 used for normal text. */
654 width
-= (WINDOW_FRINGE_COLS (w
)
655 + WINDOW_LEFT_MARGIN_COLS (w
)
656 + WINDOW_RIGHT_MARGIN_COLS (w
));
661 DEFUN ("window-body-height", Fwindow_body_height
, Swindow_body_height
, 0, 1, 0,
662 doc
: /* Return the height, in lines, of WINDOW's text area.
663 WINDOW must be a live window and defaults to the selected one.
665 The returned height does not include the mode line or header line.
666 On a graphical display, the height is expressed as an integer multiple
667 of the default character height. If a line at the bottom of the text
668 area is only partially visible, that counts as a whole line; to
669 exclude partially-visible lines, use `window-text-height'. */)
672 struct window
*w
= decode_live_window (window
);
673 return make_number (window_body_lines (w
));
676 DEFUN ("window-body-width", Fwindow_body_width
, Swindow_body_width
, 0, 1, 0,
677 doc
: /* Return the width, in columns, of WINDOW's text area.
678 WINDOW must be a live window and defaults to the selected one.
680 The return value does not include any vertical dividers, fringe or
681 marginal areas, or scroll bars. On a graphical display, the width is
682 expressed as an integer multiple of the default character width. */)
685 struct window
*w
= decode_live_window (window
);
686 return make_number (window_body_cols (w
));
689 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
690 doc
: /* Return the number of columns by which WINDOW is scrolled from left margin.
691 WINDOW must be a live window and defaults to the selected one. */)
694 return make_number (decode_live_window (window
)->hscroll
);
697 /* Set W's horizontal scroll amount to HSCROLL clipped to a reasonable
698 range, returning the new amount as a fixnum. */
700 set_window_hscroll (struct window
*w
, EMACS_INT hscroll
)
702 /* Horizontal scrolling has problems with large scroll amounts.
703 It's too slow with long lines, and even with small lines the
704 display can be messed up. For now, though, impose only the limits
705 required by the internal representation: horizontal scrolling must
706 fit in fixnum (since it's visible to Elisp) and into ptrdiff_t
707 (since it's stored in a ptrdiff_t). */
708 ptrdiff_t hscroll_max
= min (MOST_POSITIVE_FIXNUM
, PTRDIFF_MAX
);
709 ptrdiff_t new_hscroll
= clip_to_bounds (0, hscroll
, hscroll_max
);
711 /* Prevent redisplay shortcuts when changing the hscroll. */
712 if (w
->hscroll
!= new_hscroll
)
713 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
715 w
->hscroll
= new_hscroll
;
716 return make_number (new_hscroll
);
719 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
720 doc
: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
721 WINDOW must be a live window and defaults to the selected one.
722 Clip the number to a reasonable value if out of range.
723 Return the new number. NCOL should be zero or positive.
725 Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
726 window so that the location of point moves off-window. */)
727 (Lisp_Object window
, Lisp_Object ncol
)
729 struct window
*w
= decode_live_window (window
);
732 return set_window_hscroll (w
, XINT (ncol
));
735 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
736 Swindow_redisplay_end_trigger
, 0, 1, 0,
737 doc
: /* Return WINDOW's redisplay end trigger value.
738 WINDOW must be a live window and defaults to the selected one.
739 See `set-window-redisplay-end-trigger' for more information. */)
742 return decode_live_window (window
)->redisplay_end_trigger
;
745 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
746 Sset_window_redisplay_end_trigger
, 2, 2, 0,
747 doc
: /* Set WINDOW's redisplay end trigger value to VALUE.
748 WINDOW must be a live window and defaults to the selected one. VALUE
749 should be a buffer position (typically a marker) or nil. If it is a
750 buffer position, then if redisplay in WINDOW reaches a position beyond
751 VALUE, the functions in `redisplay-end-trigger-functions' are called
752 with two arguments: WINDOW, and the end trigger value. Afterwards the
753 end-trigger value is reset to nil. */)
754 (register Lisp_Object window
, Lisp_Object value
)
756 return WSET (decode_live_window (window
), redisplay_end_trigger
, value
);
759 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
760 doc
: /* Return a list of the edge coordinates of WINDOW.
761 WINDOW must be a valid window and defaults to the selected one.
763 The returned list has the form (LEFT TOP RIGHT BOTTOM). TOP and BOTTOM
764 count by lines, and LEFT and RIGHT count by columns, all relative to 0,
765 0 at top left corner of frame.
767 RIGHT is one more than the rightmost column occupied by WINDOW. BOTTOM
768 is one more than the bottommost row occupied by WINDOW. The edges
769 include the space used by WINDOW's scroll bar, display margins, fringes,
770 header line, and/or mode line. For the edges of just the text area, use
771 `window-inside-edges'. */)
774 register struct window
*w
= decode_valid_window (window
);
776 return Fcons (make_number (WINDOW_LEFT_EDGE_COL (w
)),
777 Fcons (make_number (WINDOW_TOP_EDGE_LINE (w
)),
778 Fcons (make_number (WINDOW_RIGHT_EDGE_COL (w
)),
779 Fcons (make_number (WINDOW_BOTTOM_EDGE_LINE (w
)),
783 DEFUN ("window-pixel-edges", Fwindow_pixel_edges
, Swindow_pixel_edges
, 0, 1, 0,
784 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
785 WINDOW must be a valid window and defaults to the selected one.
787 The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
788 0, 0 at the top left corner of the frame.
790 RIGHT is one more than the rightmost x position occupied by WINDOW.
791 BOTTOM is one more than the bottommost y position occupied by WINDOW.
792 The pixel edges include the space used by WINDOW's scroll bar, display
793 margins, fringes, header line, and/or mode line. For the pixel edges
794 of just the text area, use `window-inside-pixel-edges'. */)
797 register struct window
*w
= decode_valid_window (window
);
799 return Fcons (make_number (WINDOW_LEFT_EDGE_X (w
)),
800 Fcons (make_number (WINDOW_TOP_EDGE_Y (w
)),
801 Fcons (make_number (WINDOW_RIGHT_EDGE_X (w
)),
802 Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w
)),
807 calc_absolute_offset (struct window
*w
, int *add_x
, int *add_y
)
809 struct frame
*f
= XFRAME (w
->frame
);
811 #ifdef FRAME_MENUBAR_HEIGHT
812 *add_y
+= FRAME_MENUBAR_HEIGHT (f
);
814 #ifdef FRAME_TOOLBAR_TOP_HEIGHT
815 *add_y
+= FRAME_TOOLBAR_TOP_HEIGHT (f
);
816 #elif FRAME_TOOLBAR_HEIGHT
817 *add_y
+= FRAME_TOOLBAR_HEIGHT (f
);
819 #ifdef FRAME_NS_TITLEBAR_HEIGHT
820 *add_y
+= FRAME_NS_TITLEBAR_HEIGHT (f
);
822 *add_x
= f
->left_pos
;
823 #ifdef FRAME_TOOLBAR_LEFT_WIDTH
824 *add_x
+= FRAME_TOOLBAR_LEFT_WIDTH (f
);
828 DEFUN ("window-absolute-pixel-edges", Fwindow_absolute_pixel_edges
,
829 Swindow_absolute_pixel_edges
, 0, 1, 0,
830 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
831 WINDOW must be a valid window and defaults to the selected one.
833 The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
834 0, 0 at the top left corner of the display.
836 RIGHT is one more than the rightmost x position occupied by WINDOW.
837 BOTTOM is one more than the bottommost y position occupied by WINDOW.
838 The pixel edges include the space used by WINDOW's scroll bar, display
839 margins, fringes, header line, and/or mode line. For the pixel edges
840 of just the text area, use `window-inside-absolute-pixel-edges'. */)
843 register struct window
*w
= decode_valid_window (window
);
845 calc_absolute_offset (w
, &add_x
, &add_y
);
847 return Fcons (make_number (WINDOW_LEFT_EDGE_X (w
) + add_x
),
848 Fcons (make_number (WINDOW_TOP_EDGE_Y (w
) + add_y
),
849 Fcons (make_number (WINDOW_RIGHT_EDGE_X (w
) + add_x
),
850 Fcons (make_number (WINDOW_BOTTOM_EDGE_Y (w
) + add_y
),
854 DEFUN ("window-inside-edges", Fwindow_inside_edges
, Swindow_inside_edges
, 0, 1, 0,
855 doc
: /* Return a list of the edge coordinates of WINDOW.
856 WINDOW must be a live window and defaults to the selected one.
858 The returned list has the form (LEFT TOP RIGHT BOTTOM). TOP and BOTTOM
859 count by lines, and LEFT and RIGHT count by columns, all relative to 0,
860 0 at top left corner of frame.
862 RIGHT is one more than the rightmost column of WINDOW's text area.
863 BOTTOM is one more than the bottommost row of WINDOW's text area. The
864 inside edges do not include the space used by the WINDOW's scroll bar,
865 display margins, fringes, header line, and/or mode line. */)
868 register struct window
*w
= decode_live_window (window
);
870 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_COL (w
)
871 + WINDOW_LEFT_MARGIN_COLS (w
)
872 + WINDOW_LEFT_FRINGE_COLS (w
)),
873 make_number (WINDOW_TOP_EDGE_LINE (w
)
874 + WINDOW_HEADER_LINE_LINES (w
)),
875 make_number (WINDOW_BOX_RIGHT_EDGE_COL (w
)
876 - WINDOW_RIGHT_MARGIN_COLS (w
)
877 - WINDOW_RIGHT_FRINGE_COLS (w
)),
878 make_number (WINDOW_BOTTOM_EDGE_LINE (w
)
879 - WINDOW_MODE_LINE_LINES (w
)));
882 DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges
, Swindow_inside_pixel_edges
, 0, 1, 0,
883 doc
: /* Return a list of the edge pixel coordinates of WINDOW's text area.
884 WINDOW must be a live window and defaults to the selected one.
886 The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
887 (0,0) at the top left corner of the frame's window area.
889 RIGHT is one more than the rightmost x position of WINDOW's text area.
890 BOTTOM is one more than the bottommost y position of WINDOW's text area.
891 The inside edges do not include the space used by WINDOW's scroll bar,
892 display margins, fringes, header line, and/or mode line. */)
895 register struct window
*w
= decode_live_window (window
);
897 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w
)
898 + WINDOW_LEFT_MARGIN_WIDTH (w
)
899 + WINDOW_LEFT_FRINGE_WIDTH (w
)),
900 make_number (WINDOW_TOP_EDGE_Y (w
)
901 + WINDOW_HEADER_LINE_HEIGHT (w
)),
902 make_number (WINDOW_BOX_RIGHT_EDGE_X (w
)
903 - WINDOW_RIGHT_MARGIN_WIDTH (w
)
904 - WINDOW_RIGHT_FRINGE_WIDTH (w
)),
905 make_number (WINDOW_BOTTOM_EDGE_Y (w
)
906 - WINDOW_MODE_LINE_HEIGHT (w
)));
909 DEFUN ("window-inside-absolute-pixel-edges",
910 Fwindow_inside_absolute_pixel_edges
,
911 Swindow_inside_absolute_pixel_edges
, 0, 1, 0,
912 doc
: /* Return a list of the edge pixel coordinates of WINDOW's text area.
913 WINDOW must be a live window and defaults to the selected one.
915 The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
916 (0,0) at the top left corner of the frame's window area.
918 RIGHT is one more than the rightmost x position of WINDOW's text area.
919 BOTTOM is one more than the bottommost y position of WINDOW's text area.
920 The inside edges do not include the space used by WINDOW's scroll bar,
921 display margins, fringes, header line, and/or mode line. */)
924 register struct window
*w
= decode_live_window (window
);
926 calc_absolute_offset (w
, &add_x
, &add_y
);
928 return list4 (make_number (WINDOW_BOX_LEFT_EDGE_X (w
)
929 + WINDOW_LEFT_MARGIN_WIDTH (w
)
930 + WINDOW_LEFT_FRINGE_WIDTH (w
) + add_x
),
931 make_number (WINDOW_TOP_EDGE_Y (w
)
932 + WINDOW_HEADER_LINE_HEIGHT (w
) + add_y
),
933 make_number (WINDOW_BOX_RIGHT_EDGE_X (w
)
934 - WINDOW_RIGHT_MARGIN_WIDTH (w
)
935 - WINDOW_RIGHT_FRINGE_WIDTH (w
) + add_x
),
936 make_number (WINDOW_BOTTOM_EDGE_Y (w
)
937 - WINDOW_MODE_LINE_HEIGHT (w
) + add_y
));
940 /* Test if the character at column X, row Y is within window W.
941 If it is not, return ON_NOTHING;
942 if it is in the window's text area, return ON_TEXT;
943 if it is on the window's modeline, return ON_MODE_LINE;
944 if it is on the border between the window and its right sibling,
945 return ON_VERTICAL_BORDER.
946 if it is on a scroll bar, return ON_SCROLL_BAR.
947 if it is on the window's top line, return ON_HEADER_LINE;
948 if it is in left or right fringe of the window,
949 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE;
950 if it is in the marginal area to the left/right of the window,
951 return ON_LEFT_MARGIN or ON_RIGHT_MARGIN.
953 X and Y are frame relative pixel coordinates. */
955 static enum window_part
956 coordinates_in_window (register struct window
*w
, int x
, int y
)
958 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
959 enum window_part part
;
960 int ux
= FRAME_COLUMN_WIDTH (f
);
961 int left_x
= WINDOW_LEFT_EDGE_X (w
);
962 int right_x
= WINDOW_RIGHT_EDGE_X (w
);
963 int top_y
= WINDOW_TOP_EDGE_Y (w
);
964 int bottom_y
= WINDOW_BOTTOM_EDGE_Y (w
);
965 /* The width of the area where the vertical line can be dragged.
966 (Between mode lines for instance. */
967 int grabbable_width
= ux
;
968 int lmargin_width
, rmargin_width
, text_left
, text_right
;
970 /* Outside any interesting row or column? */
971 if (y
< top_y
|| y
>= bottom_y
|| x
< left_x
|| x
>= right_x
)
974 /* On the mode line or header line? */
975 if ((WINDOW_WANTS_MODELINE_P (w
)
976 && y
>= bottom_y
- CURRENT_MODE_LINE_HEIGHT (w
)
977 && (part
= ON_MODE_LINE
))
978 || (WINDOW_WANTS_HEADER_LINE_P (w
)
979 && y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
)
980 && (part
= ON_HEADER_LINE
)))
982 /* If it's under/over the scroll bar portion of the mode/header
983 line, say it's on the vertical line. That's to be able to
984 resize windows horizontally in case we're using toolkit scroll
985 bars. Note: If scrollbars are on the left, the window that
986 must be eventually resized is that on the left of WINDOW. */
987 if ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
988 && !WINDOW_LEFTMOST_P (w
)
989 && eabs (x
- left_x
) < grabbable_width
)
990 || (!WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
991 && !WINDOW_RIGHTMOST_P (w
)
992 && eabs (x
- right_x
) < grabbable_width
))
993 return ON_VERTICAL_BORDER
;
998 /* In what's below, we subtract 1 when computing right_x because we
999 want the rightmost pixel, which is given by left_pixel+width-1. */
1000 if (w
->pseudo_window_p
)
1003 right_x
= WINDOW_TOTAL_WIDTH (w
) - 1;
1007 left_x
= WINDOW_BOX_LEFT_EDGE_X (w
);
1008 right_x
= WINDOW_BOX_RIGHT_EDGE_X (w
) - 1;
1011 /* Outside any interesting column? */
1012 if (x
< left_x
|| x
> right_x
)
1013 return ON_SCROLL_BAR
;
1015 lmargin_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
1016 rmargin_width
= window_box_width (w
, RIGHT_MARGIN_AREA
);
1018 text_left
= window_box_left (w
, TEXT_AREA
);
1019 text_right
= text_left
+ window_box_width (w
, TEXT_AREA
);
1021 if (FRAME_WINDOW_P (f
))
1023 if (!w
->pseudo_window_p
1024 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
)
1025 && !WINDOW_RIGHTMOST_P (w
)
1026 && (eabs (x
- right_x
) < grabbable_width
))
1027 return ON_VERTICAL_BORDER
;
1029 /* Need to say "x > right_x" rather than >=, since on character
1030 terminals, the vertical line's x coordinate is right_x. */
1031 else if (!w
->pseudo_window_p
1032 && !WINDOW_RIGHTMOST_P (w
)
1033 && x
> right_x
- ux
)
1034 return ON_VERTICAL_BORDER
;
1038 if (lmargin_width
> 0
1039 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1040 ? (x
>= left_x
+ WINDOW_LEFT_FRINGE_WIDTH (w
))
1041 : (x
< left_x
+ lmargin_width
)))
1042 return ON_LEFT_MARGIN
;
1044 return ON_LEFT_FRINGE
;
1047 if (x
>= text_right
)
1049 if (rmargin_width
> 0
1050 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1051 ? (x
< right_x
- WINDOW_RIGHT_FRINGE_WIDTH (w
))
1052 : (x
>= right_x
- rmargin_width
)))
1053 return ON_RIGHT_MARGIN
;
1055 return ON_RIGHT_FRINGE
;
1058 /* Everything special ruled out - must be on text area */
1062 /* Take X is the frame-relative pixel x-coordinate, and return the
1063 x-coordinate relative to part PART of window W. */
1065 window_relative_x_coord (struct window
*w
, enum window_part part
, int x
)
1067 int left_x
= (w
->pseudo_window_p
) ? 0 : WINDOW_BOX_LEFT_EDGE_X (w
);
1072 return x
- window_box_left (w
, TEXT_AREA
);
1074 case ON_LEFT_FRINGE
:
1077 case ON_RIGHT_FRINGE
:
1078 return x
- left_x
- WINDOW_LEFT_FRINGE_WIDTH (w
);
1080 case ON_LEFT_MARGIN
:
1082 - ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1083 ? WINDOW_LEFT_FRINGE_WIDTH (w
) : 0));
1085 case ON_RIGHT_MARGIN
:
1087 - ((w
->pseudo_window_p
)
1088 ? WINDOW_TOTAL_WIDTH (w
)
1089 : WINDOW_BOX_RIGHT_EDGE_X (w
))
1090 + window_box_width (w
, RIGHT_MARGIN_AREA
)
1091 + ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1092 ? WINDOW_RIGHT_FRINGE_WIDTH (w
) : 0));
1095 /* ON_SCROLL_BAR, ON_NOTHING, and ON_VERTICAL_BORDER: */
1100 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
1101 Scoordinates_in_window_p
, 2, 2, 0,
1102 doc
: /* Return non-nil if COORDINATES are in WINDOW.
1103 WINDOW must be a live window and defaults to the selected one.
1104 COORDINATES is a cons of the form (X . Y), X and Y being distances
1105 measured in characters from the upper-left corner of the frame.
1106 \(0 . 0) denotes the character in the upper left corner of the
1108 If COORDINATES are in the text portion of WINDOW,
1109 the coordinates relative to the window are returned.
1110 If they are in the mode line of WINDOW, `mode-line' is returned.
1111 If they are in the top mode line of WINDOW, `header-line' is returned.
1112 If they are in the left fringe of WINDOW, `left-fringe' is returned.
1113 If they are in the right fringe of WINDOW, `right-fringe' is returned.
1114 If they are on the border between WINDOW and its right sibling,
1115 `vertical-line' is returned.
1116 If they are in the windows's left or right marginal areas, `left-margin'\n\
1117 or `right-margin' is returned. */)
1118 (register Lisp_Object coordinates
, Lisp_Object window
)
1125 w
= decode_live_window (window
);
1126 f
= XFRAME (w
->frame
);
1127 CHECK_CONS (coordinates
);
1128 lx
= Fcar (coordinates
);
1129 ly
= Fcdr (coordinates
);
1130 CHECK_NUMBER_OR_FLOAT (lx
);
1131 CHECK_NUMBER_OR_FLOAT (ly
);
1132 x
= FRAME_PIXEL_X_FROM_CANON_X (f
, lx
) + FRAME_INTERNAL_BORDER_WIDTH (f
);
1133 y
= FRAME_PIXEL_Y_FROM_CANON_Y (f
, ly
) + FRAME_INTERNAL_BORDER_WIDTH (f
);
1135 switch (coordinates_in_window (w
, x
, y
))
1141 /* Convert X and Y to window relative pixel coordinates, and
1142 return the canonical char units. */
1143 x
-= window_box_left (w
, TEXT_AREA
);
1144 y
-= WINDOW_TOP_EDGE_Y (w
);
1145 return Fcons (FRAME_CANON_X_FROM_PIXEL_X (f
, x
),
1146 FRAME_CANON_Y_FROM_PIXEL_Y (f
, y
));
1151 case ON_VERTICAL_BORDER
:
1152 return Qvertical_line
;
1154 case ON_HEADER_LINE
:
1155 return Qheader_line
;
1157 case ON_LEFT_FRINGE
:
1158 return Qleft_fringe
;
1160 case ON_RIGHT_FRINGE
:
1161 return Qright_fringe
;
1163 case ON_LEFT_MARGIN
:
1164 return Qleft_margin
;
1166 case ON_RIGHT_MARGIN
:
1167 return Qright_margin
;
1170 /* Historically we are supposed to return nil in this case. */
1179 /* Callback for foreach_window, used in window_from_coordinates.
1180 Check if window W contains coordinates specified by USER_DATA which
1181 is actually a pointer to a struct check_window_data CW.
1183 Check if window W contains coordinates *CW->x and *CW->y. If it
1184 does, return W in *CW->window, as Lisp_Object, and return in
1185 *CW->part the part of the window under coordinates *X,*Y. Return
1186 zero from this function to stop iterating over windows. */
1188 struct check_window_data
1190 Lisp_Object
*window
;
1192 enum window_part
*part
;
1196 check_window_containing (struct window
*w
, void *user_data
)
1198 struct check_window_data
*cw
= (struct check_window_data
*) user_data
;
1199 enum window_part found
;
1202 found
= coordinates_in_window (w
, cw
->x
, cw
->y
);
1203 if (found
!= ON_NOTHING
)
1206 XSETWINDOW (*cw
->window
, w
);
1214 /* Find the window containing frame-relative pixel position X/Y and
1215 return it as a Lisp_Object.
1217 If X, Y is on one of the window's special `window_part' elements,
1218 set *PART to the id of that element.
1220 If there is no window under X, Y return nil and leave *PART
1221 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows.
1223 This function was previously implemented with a loop cycling over
1224 windows with Fnext_window, and starting with the frame's selected
1225 window. It turned out that this doesn't work with an
1226 implementation of next_window using Vwindow_list, because
1227 FRAME_SELECTED_WINDOW (F) is not always contained in the window
1228 tree of F when this function is called asynchronously from
1229 note_mouse_highlight. The original loop didn't terminate in this
1233 window_from_coordinates (struct frame
*f
, int x
, int y
,
1234 enum window_part
*part
, int tool_bar_p
)
1237 struct check_window_data cw
;
1238 enum window_part dummy
;
1244 cw
.window
= &window
, cw
.x
= x
, cw
.y
= y
; cw
.part
= part
;
1245 foreach_window (f
, check_window_containing
, &cw
);
1247 /* If not found above, see if it's in the tool bar window, if a tool
1251 && WINDOWP (f
->tool_bar_window
)
1252 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0
1253 && (coordinates_in_window (XWINDOW (f
->tool_bar_window
), x
, y
)
1257 window
= f
->tool_bar_window
;
1263 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
1264 doc
: /* Return window containing coordinates X and Y on FRAME.
1265 FRAME must be a live frame and defaults to the selected one.
1266 The top left corner of the frame is considered to be row 0,
1268 (Lisp_Object x
, Lisp_Object y
, Lisp_Object frame
)
1273 frame
= selected_frame
;
1274 CHECK_LIVE_FRAME (frame
);
1277 /* Check that arguments are integers or floats. */
1278 CHECK_NUMBER_OR_FLOAT (x
);
1279 CHECK_NUMBER_OR_FLOAT (y
);
1281 return window_from_coordinates (f
,
1282 (FRAME_PIXEL_X_FROM_CANON_X (f
, x
)
1283 + FRAME_INTERNAL_BORDER_WIDTH (f
)),
1284 (FRAME_PIXEL_Y_FROM_CANON_Y (f
, y
)
1285 + FRAME_INTERNAL_BORDER_WIDTH (f
)),
1289 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
1290 doc
: /* Return current value of point in WINDOW.
1291 WINDOW must be a live window and defaults to the selected one.
1293 For a nonselected window, this is the value point would have
1294 if that window were selected.
1296 Note that, when WINDOW is the selected window and its buffer
1297 is also currently selected, the value returned is the same as (point).
1298 It would be more strictly correct to return the `top-level' value
1299 of point, outside of any save-excursion forms.
1300 But that is hard to define. */)
1301 (Lisp_Object window
)
1303 register struct window
*w
= decode_live_window (window
);
1305 if (w
== XWINDOW (selected_window
)
1306 && current_buffer
== XBUFFER (w
->buffer
))
1308 return Fmarker_position (w
->pointm
);
1311 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
1312 doc
: /* Return position at which display currently starts in WINDOW.
1313 WINDOW must be a live window and defaults to the selected one.
1314 This is updated by redisplay or by calling `set-window-start'. */)
1315 (Lisp_Object window
)
1317 return Fmarker_position (decode_live_window (window
)->start
);
1320 /* This is text temporarily removed from the doc string below.
1322 This function returns nil if the position is not currently known.
1323 That happens when redisplay is preempted and doesn't finish.
1324 If in that case you want to compute where the end of the window would
1325 have been if redisplay had finished, do this:
1327 (goto-char (window-start window))
1328 (vertical-motion (1- (window-height window)) window)
1331 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
1332 doc
: /* Return position at which display currently ends in WINDOW.
1333 WINDOW must be a live window and defaults to the selected one.
1334 This is updated by redisplay, when it runs to completion.
1335 Simply changing the buffer text or setting `window-start'
1336 does not update this value.
1337 Return nil if there is no recorded value. (This can happen if the
1338 last redisplay of WINDOW was preempted, and did not finish.)
1339 If UPDATE is non-nil, compute the up-to-date position
1340 if it isn't already recorded. */)
1341 (Lisp_Object window
, Lisp_Object update
)
1344 struct window
*w
= decode_live_window (window
);
1352 #if 0 /* This change broke some things. We should make it later. */
1353 /* If we don't know the end position, return nil.
1354 The user can compute it with vertical-motion if he wants to.
1355 It would be nicer to do it automatically,
1356 but that's so slow that it would probably bother people. */
1357 if (NILP (w
->window_end_valid
))
1362 && ! (! NILP (w
->window_end_valid
)
1363 && w
->last_modified
>= BUF_MODIFF (b
)
1364 && w
->last_overlay_modified
>= BUF_OVERLAY_MODIFF (b
))
1367 struct text_pos startp
;
1369 struct buffer
*old_buffer
= NULL
;
1370 void *itdata
= NULL
;
1372 /* Cannot use Fvertical_motion because that function doesn't
1373 cope with variable-height lines. */
1374 if (b
!= current_buffer
)
1376 old_buffer
= current_buffer
;
1377 set_buffer_internal (b
);
1380 /* In case W->start is out of the range, use something
1381 reasonable. This situation occurred when loading a file with
1382 `-l' containing a call to `rmail' with subsequent other
1383 commands. At the end, W->start happened to be BEG, while
1384 rmail had already narrowed the buffer. */
1385 if (XMARKER (w
->start
)->charpos
< BEGV
)
1386 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
1387 else if (XMARKER (w
->start
)->charpos
> ZV
)
1388 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
1390 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
1392 itdata
= bidi_shelve_cache ();
1393 start_display (&it
, w
, startp
);
1394 move_it_vertically (&it
, window_box_height (w
));
1395 if (it
.current_y
< it
.last_visible_y
)
1396 move_it_past_eol (&it
);
1397 value
= make_number (IT_CHARPOS (it
));
1398 bidi_unshelve_cache (itdata
, 0);
1401 set_buffer_internal (old_buffer
);
1404 XSETINT (value
, BUF_Z (b
) - XFASTINT (w
->window_end_pos
));
1409 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
1410 doc
: /* Make point value in WINDOW be at position POS in WINDOW's buffer.
1411 WINDOW must be a live window and defaults to the selected one.
1413 (Lisp_Object window
, Lisp_Object pos
)
1415 register struct window
*w
= decode_live_window (window
);
1417 CHECK_NUMBER_COERCE_MARKER (pos
);
1418 if (w
== XWINDOW (selected_window
)
1419 && XBUFFER (w
->buffer
) == current_buffer
)
1422 set_marker_restricted (w
->pointm
, pos
, w
->buffer
);
1424 /* We have to make sure that redisplay updates the window to show
1425 the new value of point. */
1426 if (!EQ (window
, selected_window
))
1427 ++windows_or_buffers_changed
;
1432 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
1433 doc
: /* Make display in WINDOW start at position POS in WINDOW's buffer.
1434 WINDOW must be a live window and defaults to the selected one. Return
1435 POS. Optional third arg NOFORCE non-nil inhibits next redisplay from
1436 overriding motion of point in order to display at this exact start. */)
1437 (Lisp_Object window
, Lisp_Object pos
, Lisp_Object noforce
)
1439 register struct window
*w
= decode_live_window (window
);
1441 CHECK_NUMBER_COERCE_MARKER (pos
);
1442 set_marker_restricted (w
->start
, pos
, w
->buffer
);
1443 /* this is not right, but much easier than doing what is right. */
1444 w
->start_at_line_beg
= 0;
1447 w
->update_mode_line
= 1;
1448 w
->last_modified
= 0;
1449 w
->last_overlay_modified
= 0;
1450 if (!EQ (window
, selected_window
))
1451 windows_or_buffers_changed
++;
1456 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
1457 Spos_visible_in_window_p
, 0, 3, 0,
1458 doc
: /* Return non-nil if position POS is currently on the frame in WINDOW.
1459 WINDOW must be a live window and defaults to the selected one.
1461 Return nil if that position is scrolled vertically out of view. If a
1462 character is only partially visible, nil is returned, unless the
1463 optional argument PARTIALLY is non-nil. If POS is only out of view
1464 because of horizontal scrolling, return non-nil. If POS is t, it
1465 specifies the position of the last visible glyph in WINDOW. POS
1466 defaults to point in WINDOW; WINDOW defaults to the selected window.
1468 If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
1469 return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
1470 where X and Y are the pixel coordinates relative to the top left corner
1471 of the window. The remaining elements are omitted if the character after
1472 POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
1473 off-window at the top and bottom of the row, ROWH is the height of the
1474 display row, and VPOS is the row number (0-based) containing POS. */)
1475 (Lisp_Object pos
, Lisp_Object window
, Lisp_Object partially
)
1477 register struct window
*w
;
1478 register EMACS_INT posint
;
1479 register struct buffer
*buf
;
1480 struct text_pos top
;
1481 Lisp_Object in_window
= Qnil
;
1482 int rtop
, rbot
, rowh
, vpos
, fully_p
= 1;
1485 w
= decode_live_window (window
);
1486 buf
= XBUFFER (w
->buffer
);
1487 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1491 else if (!NILP (pos
))
1493 CHECK_NUMBER_COERCE_MARKER (pos
);
1494 posint
= XINT (pos
);
1496 else if (w
== XWINDOW (selected_window
))
1499 posint
= XMARKER (w
->pointm
)->charpos
;
1501 /* If position is above window start or outside buffer boundaries,
1502 or if window start is out of range, position is not visible. */
1504 || (posint
>= CHARPOS (top
) && posint
<= BUF_ZV (buf
)))
1505 && CHARPOS (top
) >= BUF_BEGV (buf
)
1506 && CHARPOS (top
) <= BUF_ZV (buf
)
1507 && pos_visible_p (w
, posint
, &x
, &y
, &rtop
, &rbot
, &rowh
, &vpos
)
1508 && (fully_p
= !rtop
&& !rbot
, (!NILP (partially
) || fully_p
)))
1511 if (!NILP (in_window
) && !NILP (partially
))
1513 Lisp_Object part
= Qnil
;
1515 part
= list4 (make_number (rtop
), make_number (rbot
),
1516 make_number (rowh
), make_number (vpos
));
1517 in_window
= Fcons (make_number (x
),
1518 Fcons (make_number (y
), part
));
1524 DEFUN ("window-line-height", Fwindow_line_height
,
1525 Swindow_line_height
, 0, 2, 0,
1526 doc
: /* Return height in pixels of text line LINE in window WINDOW.
1527 WINDOW must be a live window and defaults to the selected one.
1529 Return height of current line if LINE is omitted or nil. Return height of
1530 header or mode line if LINE is `header-line' or `mode-line'.
1531 Otherwise, LINE is a text line number starting from 0. A negative number
1532 counts from the end of the window.
1534 Value is a list (HEIGHT VPOS YPOS OFFBOT), where HEIGHT is the height
1535 in pixels of the visible part of the line, VPOS and YPOS are the
1536 vertical position in lines and pixels of the line, relative to the top
1537 of the first text line, and OFFBOT is the number of off-window pixels at
1538 the bottom of the text line. If there are off-window pixels at the top
1539 of the (first) text line, YPOS is negative.
1541 Return nil if window display is not up-to-date. In that case, use
1542 `pos-visible-in-window-p' to obtain the information. */)
1543 (Lisp_Object line
, Lisp_Object window
)
1545 register struct window
*w
;
1546 register struct buffer
*b
;
1547 struct glyph_row
*row
, *end_row
;
1551 w
= decode_live_window (window
);
1553 if (noninteractive
|| w
->pseudo_window_p
)
1556 CHECK_BUFFER (w
->buffer
);
1557 b
= XBUFFER (w
->buffer
);
1559 /* Fail if current matrix is not up-to-date. */
1560 if (NILP (w
->window_end_valid
)
1561 || current_buffer
->clip_changed
1562 || current_buffer
->prevent_redisplay_optimizations_p
1563 || w
->last_modified
< BUF_MODIFF (b
)
1564 || w
->last_overlay_modified
< BUF_OVERLAY_MODIFF (b
))
1570 if (i
< 0 || i
>= w
->current_matrix
->nrows
1571 || (row
= MATRIX_ROW (w
->current_matrix
, i
), !row
->enabled_p
))
1573 max_y
= window_text_bottom_y (w
);
1577 if (EQ (line
, Qheader_line
))
1579 if (!WINDOW_WANTS_HEADER_LINE_P (w
))
1581 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
1582 if (!row
->enabled_p
)
1584 return list4 (make_number (row
->height
),
1585 make_number (0), make_number (0),
1589 if (EQ (line
, Qmode_line
))
1591 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
1592 if (!row
->enabled_p
)
1594 return list4 (make_number (row
->height
),
1595 make_number (0), /* not accurate */
1596 make_number (WINDOW_HEADER_LINE_HEIGHT (w
)
1597 + window_text_bottom_y (w
)),
1601 CHECK_NUMBER (line
);
1604 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
1605 end_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
1606 max_y
= window_text_bottom_y (w
);
1609 while ((n
< 0 || i
< n
)
1610 && row
<= end_row
&& row
->enabled_p
1611 && row
->y
+ row
->height
< max_y
)
1614 if (row
> end_row
|| !row
->enabled_p
)
1626 crop
= max (0, (row
->y
+ row
->height
) - max_y
);
1627 return list4 (make_number (row
->height
+ min (0, row
->y
) - crop
),
1629 make_number (row
->y
),
1630 make_number (crop
));
1633 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
1635 doc
: /* Return non-nil when WINDOW is dedicated to its buffer.
1636 More precisely, return the value assigned by the last call of
1637 `set-window-dedicated-p' for WINDOW. Return nil if that function was
1638 never called with WINDOW as its argument, or the value set by that
1639 function was internally reset since its last call. WINDOW must be a
1640 live window and defaults to the selected one.
1642 When a window is dedicated to its buffer, `display-buffer' will refrain
1643 from displaying another buffer in it. `get-lru-window' and
1644 `get-largest-window' treat dedicated windows specially.
1645 `delete-windows-on', `replace-buffer-in-windows', `quit-window' and
1646 `kill-buffer' can delete a dedicated window and the containing frame.
1648 Functions like `set-window-buffer' may change the buffer displayed by a
1649 window, unless that window is "strongly" dedicated to its buffer, that
1650 is the value returned by `window-dedicated-p' is t. */)
1651 (Lisp_Object window
)
1653 return decode_live_window (window
)->dedicated
;
1656 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
1657 Sset_window_dedicated_p
, 2, 2, 0,
1658 doc
: /* Mark WINDOW as dedicated according to FLAG.
1659 WINDOW must be a live window and defaults to the selected one. FLAG
1660 non-nil means mark WINDOW as dedicated to its buffer. FLAG nil means
1661 mark WINDOW as non-dedicated. Return FLAG.
1663 When a window is dedicated to its buffer, `display-buffer' will refrain
1664 from displaying another buffer in it. `get-lru-window' and
1665 `get-largest-window' treat dedicated windows specially.
1666 `delete-windows-on', `replace-buffer-in-windows', `quit-window',
1667 `quit-restore-window' and `kill-buffer' can delete a dedicated window
1668 and the containing frame.
1670 As a special case, if FLAG is t, mark WINDOW as "strongly" dedicated to
1671 its buffer. Functions like `set-window-buffer' may change the buffer
1672 displayed by a window, unless that window is strongly dedicated to its
1673 buffer. If and when `set-window-buffer' displays another buffer in a
1674 window, it also makes sure that the window is no more dedicated. */)
1675 (Lisp_Object window
, Lisp_Object flag
)
1677 return WSET (decode_live_window (window
), dedicated
, flag
);
1680 DEFUN ("window-prev-buffers", Fwindow_prev_buffers
, Swindow_prev_buffers
,
1682 doc
: /* Return buffers previously shown in WINDOW.
1683 WINDOW must be a live window and defaults to the selected one.
1685 The return value is a list of elements (BUFFER WINDOW-START POS),
1686 where BUFFER is a buffer, WINDOW-START is the start position of the
1687 window for that buffer, and POS is a window-specific point value. */)
1688 (Lisp_Object window
)
1690 return decode_live_window (window
)->prev_buffers
;
1693 DEFUN ("set-window-prev-buffers", Fset_window_prev_buffers
,
1694 Sset_window_prev_buffers
, 2, 2, 0,
1695 doc
: /* Set WINDOW's previous buffers to PREV-BUFFERS.
1696 WINDOW must be a live window and defaults to the selected one.
1698 PREV-BUFFERS should be a list of elements (BUFFER WINDOW-START POS),
1699 where BUFFER is a buffer, WINDOW-START is the start position of the
1700 window for that buffer, and POS is a window-specific point value. */)
1701 (Lisp_Object window
, Lisp_Object prev_buffers
)
1703 return WSET (decode_live_window (window
), prev_buffers
, prev_buffers
);
1706 DEFUN ("window-next-buffers", Fwindow_next_buffers
, Swindow_next_buffers
,
1708 doc
: /* Return list of buffers recently re-shown in WINDOW.
1709 WINDOW must be a live window and defaults to the selected one. */)
1710 (Lisp_Object window
)
1712 return decode_live_window (window
)->next_buffers
;
1715 DEFUN ("set-window-next-buffers", Fset_window_next_buffers
,
1716 Sset_window_next_buffers
, 2, 2, 0,
1717 doc
: /* Set WINDOW's next buffers to NEXT-BUFFERS.
1718 WINDOW must be a live window and defaults to the selected one.
1719 NEXT-BUFFERS should be a list of buffers. */)
1720 (Lisp_Object window
, Lisp_Object next_buffers
)
1722 return WSET (decode_live_window (window
), next_buffers
, next_buffers
);
1725 DEFUN ("window-parameters", Fwindow_parameters
, Swindow_parameters
,
1727 doc
: /* Return the parameters of WINDOW and their values.
1728 WINDOW must be a valid window and defaults to the selected one. The
1729 return value is a list of elements of the form (PARAMETER . VALUE). */)
1730 (Lisp_Object window
)
1732 return Fcopy_alist (decode_valid_window (window
)->window_parameters
);
1735 DEFUN ("window-parameter", Fwindow_parameter
, Swindow_parameter
,
1737 doc
: /* Return WINDOW's value for PARAMETER.
1738 WINDOW must be a valid window and defaults to the selected one. */)
1739 (Lisp_Object window
, Lisp_Object parameter
)
1743 result
= Fassq (parameter
, decode_valid_window (window
)->window_parameters
);
1744 return CDR_SAFE (result
);
1747 DEFUN ("set-window-parameter", Fset_window_parameter
,
1748 Sset_window_parameter
, 3, 3, 0,
1749 doc
: /* Set WINDOW's value of PARAMETER to VALUE.
1750 WINDOW must be a valid window and defaults to the selected one.
1752 (Lisp_Object window
, Lisp_Object parameter
, Lisp_Object value
)
1754 register struct window
*w
= decode_valid_window (window
);
1755 Lisp_Object old_alist_elt
;
1757 old_alist_elt
= Fassq (parameter
, w
->window_parameters
);
1758 if (NILP (old_alist_elt
))
1759 WSET (w
, window_parameters
,
1760 Fcons (Fcons (parameter
, value
), w
->window_parameters
));
1762 Fsetcdr (old_alist_elt
, value
);
1766 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
1768 doc
: /* Return the display-table that WINDOW is using.
1769 WINDOW must be a live window and defaults to the selected one. */)
1770 (Lisp_Object window
)
1772 return decode_live_window (window
)->display_table
;
1775 /* Get the display table for use on window W. This is either W's
1776 display table or W's buffer's display table. Ignore the specified
1777 tables if they are not valid; if no valid table is specified,
1780 struct Lisp_Char_Table
*
1781 window_display_table (struct window
*w
)
1783 struct Lisp_Char_Table
*dp
= NULL
;
1785 if (DISP_TABLE_P (w
->display_table
))
1786 dp
= XCHAR_TABLE (w
->display_table
);
1787 else if (BUFFERP (w
->buffer
))
1789 struct buffer
*b
= XBUFFER (w
->buffer
);
1791 if (DISP_TABLE_P (BVAR (b
, display_table
)))
1792 dp
= XCHAR_TABLE (BVAR (b
, display_table
));
1793 else if (DISP_TABLE_P (Vstandard_display_table
))
1794 dp
= XCHAR_TABLE (Vstandard_display_table
);
1800 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
1801 doc
: /* Set WINDOW's display-table to TABLE.
1802 WINDOW must be a live window and defaults to the selected one. */)
1803 (register Lisp_Object window
, Lisp_Object table
)
1805 return WSET (decode_live_window (window
), display_table
, table
);
1808 /* Record info on buffer window W is displaying
1809 when it is about to cease to display that buffer. */
1811 unshow_buffer (register struct window
*w
)
1818 if (b
!= XMARKER (w
->pointm
)->buffer
)
1822 if (w
== XWINDOW (selected_window
)
1823 || ! EQ (buf
, XWINDOW (selected_window
)->buffer
))
1824 /* Do this except when the selected window's buffer
1825 is being removed from some other window. */
1827 /* last_window_start records the start position that this buffer
1828 had in the last window to be disconnected from it.
1829 Now that this statement is unconditional,
1830 it is possible for the buffer to be displayed in the
1831 selected window, while last_window_start reflects another
1832 window which was recently showing the same buffer.
1833 Some people might say that might be a good thing. Let's see. */
1834 b
->last_window_start
= marker_position (w
->start
);
1836 /* Point in the selected window's buffer
1837 is actually stored in that buffer, and the window's pointm isn't used.
1838 So don't clobber point in that buffer. */
1839 if (! EQ (buf
, XWINDOW (selected_window
)->buffer
)
1840 /* This line helps to fix Horsley's testbug.el bug. */
1841 && !(WINDOWP (BVAR (b
, last_selected_window
))
1842 && w
!= XWINDOW (BVAR (b
, last_selected_window
))
1843 && EQ (buf
, XWINDOW (BVAR (b
, last_selected_window
))->buffer
)))
1844 temp_set_point_both (b
,
1845 clip_to_bounds (BUF_BEGV (b
),
1846 XMARKER (w
->pointm
)->charpos
,
1848 clip_to_bounds (BUF_BEGV_BYTE (b
),
1849 marker_byte_position (w
->pointm
),
1852 if (WINDOWP (BVAR (b
, last_selected_window
))
1853 && w
== XWINDOW (BVAR (b
, last_selected_window
)))
1854 BSET (b
, last_selected_window
, Qnil
);
1857 /* Put NEW into the window structure in place of OLD. SETFLAG zero
1858 means change window structure only. Otherwise store geometry and
1859 other settings as well. */
1861 replace_window (Lisp_Object old
, Lisp_Object
new, int setflag
)
1863 register Lisp_Object tem
;
1864 register struct window
*o
= XWINDOW (old
), *n
= XWINDOW (new);
1866 /* If OLD is its frame's root window, then NEW is the new
1867 root window for that frame. */
1868 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
1869 fset_root_window (XFRAME (o
->frame
), new);
1873 WSET (n
, left_col
, o
->left_col
);
1874 WSET (n
, top_line
, o
->top_line
);
1875 WSET (n
, total_cols
, o
->total_cols
);
1876 WSET (n
, total_lines
, o
->total_lines
);
1877 WSET (n
, normal_cols
, o
->normal_cols
);
1878 WSET (o
, normal_cols
, make_float (1.0));
1879 WSET (n
, normal_lines
, o
->normal_lines
);
1880 WSET (o
, normal_lines
, make_float (1.0));
1881 n
->desired_matrix
= n
->current_matrix
= 0;
1883 memset (&n
->cursor
, 0, sizeof (n
->cursor
));
1884 memset (&n
->last_cursor
, 0, sizeof (n
->last_cursor
));
1885 memset (&n
->phys_cursor
, 0, sizeof (n
->phys_cursor
));
1886 n
->phys_cursor_type
= -1;
1887 n
->phys_cursor_width
= -1;
1888 n
->must_be_updated_p
= 0;
1889 n
->pseudo_window_p
= 0;
1890 WSET (n
, window_end_vpos
, make_number (0));
1891 WSET (n
, window_end_pos
, make_number (0));
1892 WSET (n
, window_end_valid
, Qnil
);
1893 n
->frozen_window_start_p
= 0;
1897 WSET (n
, next
, tem
);
1899 WSET (XWINDOW (tem
), prev
, new);
1902 WSET (n
, prev
, tem
);
1904 WSET (XWINDOW (tem
), next
, new);
1907 WSET (n
, parent
, tem
);
1910 if (EQ (XWINDOW (tem
)->vchild
, old
))
1911 WSET (XWINDOW (tem
), vchild
, new);
1912 if (EQ (XWINDOW (tem
)->hchild
, old
))
1913 WSET (XWINDOW (tem
), hchild
, new);
1917 /* If window WINDOW and its parent window are iso-combined, merge
1918 WINDOW's children into those of its parent window and mark WINDOW as
1922 recombine_windows (Lisp_Object window
)
1924 struct window
*w
, *p
, *c
;
1925 Lisp_Object parent
, child
;
1928 w
= XWINDOW (window
);
1930 if (!NILP (parent
) && NILP (w
->combination_limit
))
1932 p
= XWINDOW (parent
);
1933 if (((!NILP (p
->vchild
) && !NILP (w
->vchild
))
1934 || (!NILP (p
->hchild
) && !NILP (w
->hchild
))))
1935 /* WINDOW and PARENT are both either a vertical or a horizontal
1938 horflag
= NILP (w
->vchild
);
1939 child
= horflag
? w
->hchild
: w
->vchild
;
1940 c
= XWINDOW (child
);
1942 /* Splice WINDOW's children into its parent's children and
1943 assign new normal sizes. */
1946 WSET (p
, hchild
, child
);
1948 WSET (p
, vchild
, child
);
1951 WSET (c
, prev
, w
->prev
);
1952 WSET (XWINDOW (w
->prev
), next
, child
);
1957 WSET (c
, parent
, parent
);
1960 WSET (c
, normal_cols
,
1961 make_float (XFLOATINT (c
->total_cols
)
1962 / XFLOATINT (p
->total_cols
)));
1964 WSET (c
, normal_lines
,
1965 make_float (XFLOATINT (c
->total_lines
)
1966 / XFLOATINT (p
->total_lines
)));
1970 if (!NILP (w
->next
))
1972 WSET (c
, next
, w
->next
);
1973 WSET (XWINDOW (c
->next
), prev
, child
);
1981 c
= XWINDOW (child
);
1985 /* WINDOW can be deleted now. */
1986 WSET (w
, vchild
, Qnil
);
1987 WSET (w
, hchild
, Qnil
);
1992 /* If WINDOW can be deleted, delete it. */
1994 delete_deletable_window (Lisp_Object window
)
1996 if (!NILP (call1 (Qwindow_deletable_p
, window
)))
1997 call1 (Qdelete_window
, window
);
2000 /***********************************************************************
2002 ***********************************************************************/
2004 /* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object
2005 pointer. This is a callback function for foreach_window, used in
2006 the window_list function. */
2009 add_window_to_list (struct window
*w
, void *user_data
)
2011 Lisp_Object
*list
= (Lisp_Object
*) user_data
;
2013 XSETWINDOW (window
, w
);
2014 *list
= Fcons (window
, *list
);
2019 /* Return a list of all windows, for use by next_window. If
2020 Vwindow_list is a list, return that list. Otherwise, build a new
2021 list, cache it in Vwindow_list, and return that. */
2026 if (!CONSP (Vwindow_list
))
2030 Vwindow_list
= Qnil
;
2031 for (tail
= Vframe_list
; CONSP (tail
); tail
= XCDR (tail
))
2033 Lisp_Object args
[2];
2035 /* We are visiting windows in canonical order, and add
2036 new windows at the front of args[1], which means we
2037 have to reverse this list at the end. */
2039 foreach_window (XFRAME (XCAR (tail
)), add_window_to_list
, &args
[1]);
2040 args
[0] = Vwindow_list
;
2041 args
[1] = Fnreverse (args
[1]);
2042 Vwindow_list
= Fnconc (2, args
);
2046 return Vwindow_list
;
2050 /* Value is non-zero if WINDOW satisfies the constraints given by
2051 OWINDOW, MINIBUF and ALL_FRAMES.
2053 MINIBUF t means WINDOW may be minibuffer windows.
2054 `lambda' means WINDOW may not be a minibuffer window.
2055 a window means a specific minibuffer window
2057 ALL_FRAMES t means search all frames,
2058 nil means search just current frame,
2059 `visible' means search just visible frames on the
2061 0 means search visible and iconified frames on the
2063 a window means search the frame that window belongs to,
2064 a frame means consider windows on that frame, only. */
2067 candidate_window_p (Lisp_Object window
, Lisp_Object owindow
, Lisp_Object minibuf
, Lisp_Object all_frames
)
2069 struct window
*w
= XWINDOW (window
);
2070 struct frame
*f
= XFRAME (w
->frame
);
2071 int candidate_p
= 1;
2073 if (!BUFFERP (w
->buffer
))
2075 else if (MINI_WINDOW_P (w
)
2076 && (EQ (minibuf
, Qlambda
)
2077 || (WINDOWP (minibuf
) && !EQ (minibuf
, window
))))
2079 /* If MINIBUF is `lambda' don't consider any mini-windows.
2080 If it is a window, consider only that one. */
2083 else if (EQ (all_frames
, Qt
))
2085 else if (NILP (all_frames
))
2087 eassert (WINDOWP (owindow
));
2088 candidate_p
= EQ (w
->frame
, XWINDOW (owindow
)->frame
);
2090 else if (EQ (all_frames
, Qvisible
))
2092 FRAME_SAMPLE_VISIBILITY (f
);
2093 candidate_p
= FRAME_VISIBLE_P (f
)
2094 && (FRAME_TERMINAL (XFRAME (w
->frame
))
2095 == FRAME_TERMINAL (XFRAME (selected_frame
)));
2098 else if (INTEGERP (all_frames
) && XINT (all_frames
) == 0)
2100 FRAME_SAMPLE_VISIBILITY (f
);
2101 candidate_p
= (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)
2102 #ifdef HAVE_X_WINDOWS
2103 /* Yuck!! If we've just created the frame and the
2104 window-manager requested the user to place it
2105 manually, the window may still not be considered
2106 `visible'. I'd argue it should be at least
2107 something like `iconified', but don't know how to do
2109 || (FRAME_X_P (f
) && f
->output_data
.x
->asked_for_visible
2110 && !f
->output_data
.x
->has_been_visible
)
2113 && (FRAME_TERMINAL (XFRAME (w
->frame
))
2114 == FRAME_TERMINAL (XFRAME (selected_frame
)));
2116 else if (WINDOWP (all_frames
))
2117 candidate_p
= (EQ (FRAME_MINIBUF_WINDOW (f
), all_frames
)
2118 || EQ (XWINDOW (all_frames
)->frame
, w
->frame
)
2119 || EQ (XWINDOW (all_frames
)->frame
, FRAME_FOCUS_FRAME (f
)));
2120 else if (FRAMEP (all_frames
))
2121 candidate_p
= EQ (all_frames
, w
->frame
);
2127 /* Decode arguments as allowed by Fnext_window, Fprevious_window, and
2128 Fwindow_list. See candidate_window_p for the meaning of WINDOW,
2129 MINIBUF, and ALL_FRAMES. */
2132 decode_next_window_args (Lisp_Object
*window
, Lisp_Object
*minibuf
, Lisp_Object
*all_frames
)
2135 *window
= selected_window
;
2137 CHECK_LIVE_WINDOW (*window
);
2139 /* MINIBUF nil may or may not include minibuffers. Decide if it
2141 if (NILP (*minibuf
))
2142 *minibuf
= minibuf_level
? minibuf_window
: Qlambda
;
2143 else if (!EQ (*minibuf
, Qt
))
2146 /* Now *MINIBUF can be t => count all minibuffer windows, `lambda'
2147 => count none of them, or a specific minibuffer window (the
2148 active one) to count. */
2150 /* ALL_FRAMES nil doesn't specify which frames to include. */
2151 if (NILP (*all_frames
))
2153 = (!EQ (*minibuf
, Qlambda
)
2154 ? FRAME_MINIBUF_WINDOW (XFRAME (XWINDOW (*window
)->frame
))
2156 else if (EQ (*all_frames
, Qvisible
))
2158 else if (EQ (*all_frames
, make_number (0)))
2160 else if (FRAMEP (*all_frames
))
2162 else if (!EQ (*all_frames
, Qt
))
2167 /* Return the next or previous window of WINDOW in cyclic ordering
2168 of windows. NEXT_P non-zero means return the next window. See the
2169 documentation string of next-window for the meaning of MINIBUF and
2173 next_window (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
, int next_p
)
2175 decode_next_window_args (&window
, &minibuf
, &all_frames
);
2177 /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just
2178 return the first window on the frame. */
2179 if (FRAMEP (all_frames
)
2180 && !EQ (all_frames
, XWINDOW (window
)->frame
))
2181 return Fframe_first_window (all_frames
);
2187 /* Find WINDOW in the list of all windows. */
2188 list
= Fmemq (window
, window_list ());
2190 /* Scan forward from WINDOW to the end of the window list. */
2192 for (list
= XCDR (list
); CONSP (list
); list
= XCDR (list
))
2193 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
2196 /* Scan from the start of the window list up to WINDOW. */
2198 for (list
= Vwindow_list
;
2199 CONSP (list
) && !EQ (XCAR (list
), window
);
2201 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
2205 window
= XCAR (list
);
2209 Lisp_Object candidate
, list
;
2211 /* Scan through the list of windows for candidates. If there are
2212 candidate windows in front of WINDOW, the last one of these
2213 is the one we want. If there are candidates following WINDOW
2214 in the list, again the last one of these is the one we want. */
2216 for (list
= window_list (); CONSP (list
); list
= XCDR (list
))
2218 if (EQ (XCAR (list
), window
))
2220 if (WINDOWP (candidate
))
2223 else if (candidate_window_p (XCAR (list
), window
, minibuf
,
2225 candidate
= XCAR (list
);
2228 if (WINDOWP (candidate
))
2236 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
2237 doc
: /* Return live window after WINDOW in the cyclic ordering of windows.
2238 WINDOW must be a live window and defaults to the selected one. The
2239 optional arguments MINIBUF and ALL-FRAMES specify the set of windows to
2242 MINIBUF nil or omitted means consider the minibuffer window only if the
2243 minibuffer is active. MINIBUF t means consider the minibuffer window
2244 even if the minibuffer is not active. Any other value means do not
2245 consider the minibuffer window even if the minibuffer is active.
2247 ALL-FRAMES nil or omitted means consider all windows on WINDOW's frame,
2248 plus the minibuffer window if specified by the MINIBUF argument. If the
2249 minibuffer counts, consider all windows on all frames that share that
2250 minibuffer too. The following non-nil values of ALL-FRAMES have special
2253 - t means consider all windows on all existing frames.
2255 - `visible' means consider all windows on all visible frames.
2257 - 0 (the number zero) means consider all windows on all visible and
2260 - A frame means consider all windows on that frame only.
2262 Anything else means consider all windows on WINDOW's frame and no
2265 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
2266 `next-window' to iterate through the entire cycle of acceptable
2267 windows, eventually ending up back at the window you started with.
2268 `previous-window' traverses the same cycle, in the reverse order. */)
2269 (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
)
2271 return next_window (window
, minibuf
, all_frames
, 1);
2275 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
2276 doc
: /* Return live window before WINDOW in the cyclic ordering of windows.
2277 WINDOW must be a live window and defaults to the selected one. The
2278 optional arguments MINIBUF and ALL-FRAMES specify the set of windows to
2281 MINIBUF nil or omitted means consider the minibuffer window only if the
2282 minibuffer is active. MINIBUF t means consider the minibuffer window
2283 even if the minibuffer is not active. Any other value means do not
2284 consider the minibuffer window even if the minibuffer is active.
2286 ALL-FRAMES nil or omitted means consider all windows on WINDOW's frame,
2287 plus the minibuffer window if specified by the MINIBUF argument. If the
2288 minibuffer counts, consider all windows on all frames that share that
2289 minibuffer too. The following non-nil values of ALL-FRAMES have special
2292 - t means consider all windows on all existing frames.
2294 - `visible' means consider all windows on all visible frames.
2296 - 0 (the number zero) means consider all windows on all visible and
2299 - A frame means consider all windows on that frame only.
2301 Anything else means consider all windows on WINDOW's frame and no
2304 If you use consistent values for MINIBUF and ALL-FRAMES, you can
2305 use `previous-window' to iterate through the entire cycle of
2306 acceptable windows, eventually ending up back at the window you
2307 started with. `next-window' traverses the same cycle, in the
2309 (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
)
2311 return next_window (window
, minibuf
, all_frames
, 0);
2315 /* Return a list of windows in cyclic ordering. Arguments are like
2316 for `next-window'. */
2319 window_list_1 (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
)
2321 Lisp_Object tail
, list
, rest
;
2323 decode_next_window_args (&window
, &minibuf
, &all_frames
);
2326 for (tail
= window_list (); CONSP (tail
); tail
= XCDR (tail
))
2327 if (candidate_window_p (XCAR (tail
), window
, minibuf
, all_frames
))
2328 list
= Fcons (XCAR (tail
), list
);
2330 /* Rotate the list to start with WINDOW. */
2331 list
= Fnreverse (list
);
2332 rest
= Fmemq (window
, list
);
2333 if (!NILP (rest
) && !EQ (rest
, list
))
2335 for (tail
= list
; !EQ (XCDR (tail
), rest
); tail
= XCDR (tail
))
2337 XSETCDR (tail
, Qnil
);
2338 list
= nconc2 (rest
, list
);
2344 DEFUN ("window-list", Fwindow_list
, Swindow_list
, 0, 3, 0,
2345 doc
: /* Return a list of windows on FRAME, starting with WINDOW.
2346 FRAME nil or omitted means use the selected frame.
2347 WINDOW nil or omitted means use the window selected within FRAME.
2348 MINIBUF t means include the minibuffer window, even if it isn't active.
2349 MINIBUF nil or omitted means include the minibuffer window only
2351 MINIBUF neither nil nor t means never include the minibuffer window. */)
2352 (Lisp_Object frame
, Lisp_Object minibuf
, Lisp_Object window
)
2355 window
= FRAMEP (frame
) ? XFRAME (frame
)->selected_window
: selected_window
;
2356 CHECK_WINDOW (window
);
2358 frame
= selected_frame
;
2360 if (!EQ (frame
, XWINDOW (window
)->frame
))
2361 error ("Window is on a different frame");
2363 return window_list_1 (window
, minibuf
, frame
);
2367 DEFUN ("window-list-1", Fwindow_list_1
, Swindow_list_1
, 0, 3, 0,
2368 doc
: /* Return a list of all live windows.
2369 WINDOW specifies the first window to list and defaults to the selected
2372 Optional argument MINIBUF nil or omitted means consider the minibuffer
2373 window only if the minibuffer is active. MINIBUF t means consider the
2374 minibuffer window even if the minibuffer is not active. Any other value
2375 means do not consider the minibuffer window even if the minibuffer is
2378 Optional argument ALL-FRAMES nil or omitted means consider all windows
2379 on WINDOW's frame, plus the minibuffer window if specified by the
2380 MINIBUF argument. If the minibuffer counts, consider all windows on all
2381 frames that share that minibuffer too. The following non-nil values of
2382 ALL-FRAMES have special meanings:
2384 - t means consider all windows on all existing frames.
2386 - `visible' means consider all windows on all visible frames.
2388 - 0 (the number zero) means consider all windows on all visible and
2391 - A frame means consider all windows on that frame only.
2393 Anything else means consider all windows on WINDOW's frame and no
2396 If WINDOW is not on the list of windows returned, some other window will
2397 be listed first but no error is signaled. */)
2398 (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
)
2400 return window_list_1 (window
, minibuf
, all_frames
);
2403 /* Look at all windows, performing an operation specified by TYPE
2405 If FRAMES is Qt, look at all frames;
2406 Qnil, look at just the selected frame;
2407 Qvisible, look at visible frames;
2408 a frame, just look at windows on that frame.
2409 If MINI is non-zero, perform the operation on minibuffer windows too. */
2414 GET_BUFFER_WINDOW
, /* Arg is buffer */
2415 REPLACE_BUFFER_IN_WINDOWS_SAFELY
, /* Arg is buffer */
2416 REDISPLAY_BUFFER_WINDOWS
, /* Arg is buffer */
2421 window_loop (enum window_loop type
, Lisp_Object obj
, int mini
, Lisp_Object frames
)
2423 Lisp_Object window
, windows
, best_window
, frame_arg
;
2424 int frame_best_window_flag
= 0;
2426 struct gcpro gcpro1
;
2428 /* If we're only looping through windows on a particular frame,
2429 frame points to that frame. If we're looping through windows
2430 on all frames, frame is 0. */
2431 if (FRAMEP (frames
))
2432 f
= XFRAME (frames
);
2433 else if (NILP (frames
))
2434 f
= SELECTED_FRAME ();
2439 frame_arg
= Qlambda
;
2440 else if (EQ (frames
, make_number (0)))
2442 else if (EQ (frames
, Qvisible
))
2447 /* frame_arg is Qlambda to stick to one frame,
2448 Qvisible to consider all visible frames,
2451 /* Pick a window to start with. */
2455 window
= FRAME_SELECTED_WINDOW (f
);
2457 window
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
2459 windows
= window_list_1 (window
, mini
? Qt
: Qnil
, frame_arg
);
2463 for (; CONSP (windows
); windows
= XCDR (windows
))
2467 window
= XCAR (windows
);
2468 w
= XWINDOW (window
);
2470 /* Note that we do not pay attention here to whether the frame
2471 is visible, since Fwindow_list skips non-visible frames if
2472 that is desired, under the control of frame_arg. */
2473 if (!MINI_WINDOW_P (w
)
2474 /* For REPLACE_BUFFER_IN_WINDOWS_SAFELY, we must always
2475 consider all windows. */
2476 || type
== REPLACE_BUFFER_IN_WINDOWS_SAFELY
2477 || (mini
&& minibuf_level
> 0))
2480 case GET_BUFFER_WINDOW
:
2481 if (EQ (w
->buffer
, obj
)
2482 /* Don't find any minibuffer window except the one that
2483 is currently in use. */
2484 && (MINI_WINDOW_P (w
) ? EQ (window
, minibuf_window
) : 1))
2486 if (EQ (window
, selected_window
))
2487 /* Preferably return the selected window. */
2488 RETURN_UNGCPRO (window
);
2489 else if (EQ (XWINDOW (window
)->frame
, selected_frame
)
2490 && !frame_best_window_flag
)
2491 /* Prefer windows on the current frame (but don't
2492 choose another one if we have one already). */
2494 best_window
= window
;
2495 frame_best_window_flag
= 1;
2497 else if (NILP (best_window
))
2498 best_window
= window
;
2502 case REPLACE_BUFFER_IN_WINDOWS_SAFELY
:
2503 /* We could simply check whether the buffer shown by window
2504 is live, and show another buffer in case it isn't. */
2505 if (EQ (w
->buffer
, obj
))
2507 /* Undedicate WINDOW. */
2508 WSET (w
, dedicated
, Qnil
);
2509 /* Make WINDOW show the buffer returned by
2510 other_buffer_safely, don't run any hooks. */
2512 (window
, other_buffer_safely (w
->buffer
), 0, 0);
2513 /* If WINDOW is the selected window, make its buffer
2514 current. But do so only if the window shows the
2515 current buffer (Bug#6454). */
2516 if (EQ (window
, selected_window
)
2517 && XBUFFER (w
->buffer
) == current_buffer
)
2518 Fset_buffer (w
->buffer
);
2522 case REDISPLAY_BUFFER_WINDOWS
:
2523 if (EQ (w
->buffer
, obj
))
2525 mark_window_display_accurate (window
, 0);
2526 w
->update_mode_line
= 1;
2527 XBUFFER (obj
)->prevent_redisplay_optimizations_p
= 1;
2528 ++update_mode_lines
;
2529 best_window
= window
;
2533 /* Check for a window that has a killed buffer. */
2534 case CHECK_ALL_WINDOWS
:
2535 if (! NILP (w
->buffer
)
2536 && NILP (BVAR (XBUFFER (w
->buffer
), name
)))
2540 case WINDOW_LOOP_UNUSED
:
2549 /* Used for debugging. Abort if any window has a dead buffer. */
2551 extern void check_all_windows (void) EXTERNALLY_VISIBLE
;
2553 check_all_windows (void)
2555 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
2558 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 0, 2, 0,
2559 doc
: /* Return a window currently displaying BUFFER-OR-NAME, or nil if none.
2560 BUFFER-OR-NAME may be a buffer or a buffer name and defaults to
2563 The optional argument ALL-FRAMES specifies the frames to consider:
2565 - t means consider all windows on all existing frames.
2567 - `visible' means consider all windows on all visible frames.
2569 - 0 (the number zero) means consider all windows on all visible
2570 and iconified frames.
2572 - A frame means consider all windows on that frame only.
2574 Any other value of ALL-FRAMES means consider all windows on the
2575 selected frame and no others. */)
2576 (Lisp_Object buffer_or_name
, Lisp_Object all_frames
)
2580 if (NILP (buffer_or_name
))
2581 buffer
= Fcurrent_buffer ();
2583 buffer
= Fget_buffer (buffer_or_name
);
2585 if (BUFFERP (buffer
))
2586 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, all_frames
);
2592 resize_root_window (Lisp_Object window
, Lisp_Object delta
, Lisp_Object horizontal
, Lisp_Object ignore
)
2594 return call4 (Qwindow_resize_root_window
, window
, delta
, horizontal
, ignore
);
2598 DEFUN ("delete-other-windows-internal", Fdelete_other_windows_internal
,
2599 Sdelete_other_windows_internal
, 0, 2, "",
2600 doc
: /* Make WINDOW fill its frame.
2601 Only the frame WINDOW is on is affected. WINDOW must be a valid window
2602 and defaults to the selected one.
2604 Optional argument ROOT, if non-nil, must specify an internal window such
2605 that WINDOW is in its window subtree. If this is the case, replace ROOT
2606 by WINDOW and leave alone any windows not part of ROOT's subtree.
2608 When WINDOW is live try to reduce display jumps by keeping the text
2609 previously visible in WINDOW in the same place on the frame. Doing this
2610 depends on the value of (window-start WINDOW), so if calling this
2611 function in a program gives strange scrolling, make sure the
2612 window-start value is reasonable when this function is called. */)
2613 (Lisp_Object window
, Lisp_Object root
)
2615 struct window
*w
, *r
, *s
;
2617 Lisp_Object sibling
, pwindow
, swindow
IF_LINT (= Qnil
), delta
;
2618 ptrdiff_t startpos
IF_LINT (= 0);
2619 int top
IF_LINT (= 0), new_top
, resize_failed
;
2621 w
= decode_valid_window (window
);
2622 XSETWINDOW (window
, w
);
2623 f
= XFRAME (w
->frame
);
2626 /* ROOT is the frame's root window. */
2628 root
= FRAME_ROOT_WINDOW (f
);
2632 /* ROOT must be an ancestor of WINDOW. */
2634 r
= decode_valid_window (root
);
2635 pwindow
= XWINDOW (window
)->parent
;
2636 while (!NILP (pwindow
))
2637 if (EQ (pwindow
, root
))
2640 pwindow
= XWINDOW (pwindow
)->parent
;
2641 if (!EQ (pwindow
, root
))
2642 error ("Specified root is not an ancestor of specified window");
2645 if (EQ (window
, root
))
2648 /* I don't understand the "top > 0" part below. If we deal with a
2649 standalone minibuffer it would have been caught by the preceding
2651 else if (MINI_WINDOW_P (w
)) /* && top > 0) */
2652 error ("Can't expand minibuffer to full frame");
2654 if (!NILP (w
->buffer
))
2656 startpos
= marker_position (w
->start
);
2657 top
= WINDOW_TOP_EDGE_LINE (w
)
2658 - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2659 /* Make sure WINDOW is the frame's selected window. */
2660 if (!EQ (window
, FRAME_SELECTED_WINDOW (f
)))
2662 if (EQ (selected_frame
, w
->frame
))
2663 Fselect_window (window
, Qnil
);
2665 fset_selected_window (f
, window
);
2670 /* See if the frame's selected window is a part of the window
2671 subtree rooted at WINDOW, by finding all the selected window's
2672 parents and comparing each one with WINDOW. If it isn't we
2673 need a new selected window for this frame. */
2674 swindow
= FRAME_SELECTED_WINDOW (f
);
2678 while (!NILP (pwindow
) && !EQ (window
, pwindow
))
2679 pwindow
= XWINDOW (pwindow
)->parent
;
2681 if (EQ (window
, pwindow
))
2682 /* If WINDOW is an ancestor of SWINDOW, then SWINDOW is ok
2683 as the new selected window. */
2686 /* Else try the previous window of SWINDOW. */
2687 swindow
= Fprevious_window (swindow
, Qlambda
, Qnil
);
2690 if (!EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
2692 if (EQ (selected_frame
, w
->frame
))
2693 Fselect_window (swindow
, Qnil
);
2695 fset_selected_window (f
, swindow
);
2700 if (!FRAME_INITIAL_P (f
))
2702 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
2704 /* We are going to free the glyph matrices of WINDOW, and with
2705 that we might lose any information about glyph rows that have
2706 some of their glyphs highlighted in mouse face. (These rows
2707 are marked with a non-zero mouse_face_p flag.) If WINDOW
2708 indeed has some glyphs highlighted in mouse face, signal to
2709 frame's up-to-date hook that mouse highlight was overwritten,
2710 so that it will arrange for redisplaying the highlight. */
2711 if (EQ (hlinfo
->mouse_face_window
, window
))
2713 hlinfo
->mouse_face_beg_row
= hlinfo
->mouse_face_beg_col
= -1;
2714 hlinfo
->mouse_face_end_row
= hlinfo
->mouse_face_end_col
= -1;
2715 hlinfo
->mouse_face_window
= Qnil
;
2718 free_window_matrices (r
);
2720 windows_or_buffers_changed
++;
2721 Vwindow_list
= Qnil
;
2722 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
2725 if (NILP (w
->buffer
))
2727 /* Resize child windows vertically. */
2728 XSETINT (delta
, XINT (r
->total_lines
)
2729 - XINT (w
->total_lines
));
2730 WSET (w
, top_line
, r
->top_line
);
2731 resize_root_window (window
, delta
, Qnil
, Qnil
);
2732 if (window_resize_check (w
, 0))
2733 window_resize_apply (w
, 0);
2736 resize_root_window (window
, delta
, Qnil
, Qt
);
2737 if (window_resize_check (w
, 0))
2738 window_resize_apply (w
, 0);
2743 /* Resize child windows horizontally. */
2746 WSET (w
, left_col
, r
->left_col
);
2748 XINT (r
->total_cols
) - XINT (w
->total_cols
));
2749 WSET (w
, left_col
, r
->left_col
);
2750 resize_root_window (window
, delta
, Qt
, Qnil
);
2751 if (window_resize_check (w
, 1))
2752 window_resize_apply (w
, 1);
2755 resize_root_window (window
, delta
, Qt
, Qt
);
2756 if (window_resize_check (w
, 1))
2757 window_resize_apply (w
, 1);
2764 /* Play safe, if we still can ... */
2767 w
= XWINDOW (window
);
2771 /* Cleanly unlink WINDOW from window-tree. */
2772 if (!NILP (w
->prev
))
2773 /* Get SIBLING above (on the left of) WINDOW. */
2776 s
= XWINDOW (sibling
);
2777 WSET (s
, next
, w
->next
);
2778 if (!NILP (s
->next
))
2779 WSET (XWINDOW (s
->next
), prev
, sibling
);
2782 /* Get SIBLING below (on the right of) WINDOW. */
2785 s
= XWINDOW (sibling
);
2786 WSET (s
, prev
, Qnil
);
2787 if (!NILP (XWINDOW (w
->parent
)->vchild
))
2788 WSET (XWINDOW (w
->parent
), vchild
, sibling
);
2790 WSET (XWINDOW (w
->parent
), hchild
, sibling
);
2793 /* Delete ROOT and all child windows of ROOT. */
2794 if (!NILP (r
->vchild
))
2796 delete_all_child_windows (r
->vchild
);
2797 WSET (r
, vchild
, Qnil
);
2799 else if (!NILP (r
->hchild
))
2801 delete_all_child_windows (r
->hchild
);
2802 WSET (r
, hchild
, Qnil
);
2805 replace_window (root
, window
, 1);
2807 /* This must become SWINDOW anyway ....... */
2808 if (!NILP (w
->buffer
) && !resize_failed
)
2810 /* Try to minimize scrolling, by setting the window start to the
2811 point will cause the text at the old window start to be at the
2812 same place on the frame. But don't try to do this if the
2813 window start is outside the visible portion (as might happen
2814 when the display is not current, due to typeahead). */
2815 new_top
= WINDOW_TOP_EDGE_LINE (w
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
2817 && startpos
>= BUF_BEGV (XBUFFER (w
->buffer
))
2818 && startpos
<= BUF_ZV (XBUFFER (w
->buffer
)))
2820 struct position pos
;
2821 struct buffer
*obuf
= current_buffer
;
2823 Fset_buffer (w
->buffer
);
2824 /* This computation used to temporarily move point, but that
2825 can have unwanted side effects due to text properties. */
2826 pos
= *vmotion (startpos
, -top
, w
);
2828 set_marker_both (w
->start
, w
->buffer
, pos
.bufpos
, pos
.bytepos
);
2829 WSET (w
, window_end_valid
, Qnil
);
2830 w
->start_at_line_beg
= (pos
.bytepos
== BEGV_BYTE
2831 || FETCH_BYTE (pos
.bytepos
- 1) == '\n');
2832 /* We need to do this, so that the window-scroll-functions
2834 w
->optional_new_start
= 1;
2836 set_buffer_internal (obuf
);
2843 run_window_configuration_change_hook (f
);
2850 replace_buffer_in_windows (Lisp_Object buffer
)
2852 call1 (Qreplace_buffer_in_windows
, buffer
);
2856 /* Safely replace BUFFER with some other buffer in all windows of all
2857 frames, even those on other keyboards. */
2860 replace_buffer_in_windows_safely (Lisp_Object buffer
)
2862 Lisp_Object tail
, frame
;
2864 /* A single call to window_loop won't do the job because it only
2865 considers frames on the current keyboard. So loop manually over
2866 frames, and handle each one. */
2867 FOR_EACH_FRAME (tail
, frame
)
2868 window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY
, buffer
, 1, frame
);
2871 /* If *ROWS or *COLS are too small a size for FRAME, set them to the
2872 minimum allowable size. */
2875 check_frame_size (FRAME_PTR frame
, int *rows
, int *cols
)
2877 /* For height, we have to see:
2878 how many windows the frame has at minimum (one or two),
2879 and whether it has a menu bar or other special stuff at the top. */
2881 = ((FRAME_MINIBUF_ONLY_P (frame
) || ! FRAME_HAS_MINIBUF_P (frame
))
2882 ? MIN_SAFE_WINDOW_HEIGHT
2883 : 2 * MIN_SAFE_WINDOW_HEIGHT
);
2885 if (FRAME_TOP_MARGIN (frame
) > 0)
2886 min_height
+= FRAME_TOP_MARGIN (frame
);
2888 if (*rows
< min_height
)
2890 if (*cols
< MIN_SAFE_WINDOW_WIDTH
)
2891 *cols
= MIN_SAFE_WINDOW_WIDTH
;
2894 /* Adjust the margins of window W if text area is too small.
2895 Return 1 if window width is ok after adjustment; 0 if window
2896 is still too narrow. */
2899 adjust_window_margins (struct window
*w
)
2901 int box_cols
= (WINDOW_TOTAL_COLS (w
)
2902 - WINDOW_FRINGE_COLS (w
)
2903 - WINDOW_SCROLL_BAR_COLS (w
));
2904 int margin_cols
= (WINDOW_LEFT_MARGIN_COLS (w
)
2905 + WINDOW_RIGHT_MARGIN_COLS (w
));
2907 if (box_cols
- margin_cols
>= MIN_SAFE_WINDOW_WIDTH
)
2910 if (margin_cols
< 0 || box_cols
< MIN_SAFE_WINDOW_WIDTH
)
2913 /* Window's text area is too narrow, but reducing the window
2914 margins will fix that. */
2915 margin_cols
= box_cols
- MIN_SAFE_WINDOW_WIDTH
;
2916 if (WINDOW_RIGHT_MARGIN_COLS (w
) > 0)
2918 if (WINDOW_LEFT_MARGIN_COLS (w
) > 0)
2920 WSET (w
, left_margin_cols
, make_number (margin_cols
/ 2));
2921 WSET (w
, right_margin_cols
, make_number (margin_cols
/ 2));
2924 WSET (w
, right_margin_cols
, make_number (margin_cols
));
2927 WSET (w
, left_margin_cols
, make_number (margin_cols
));
2931 /* The following three routines are needed for running a window's
2932 configuration change hook. */
2934 run_funs (Lisp_Object funs
)
2936 for (; CONSP (funs
); funs
= XCDR (funs
))
2937 if (!EQ (XCAR (funs
), Qt
))
2938 call0 (XCAR (funs
));
2942 select_window_norecord (Lisp_Object window
)
2944 return WINDOW_LIVE_P (window
)
2945 ? Fselect_window (window
, Qt
) : selected_window
;
2949 select_frame_norecord (Lisp_Object frame
)
2951 return FRAME_LIVE_P (XFRAME (frame
))
2952 ? Fselect_frame (frame
, Qt
) : selected_frame
;
2956 run_window_configuration_change_hook (struct frame
*f
)
2958 ptrdiff_t count
= SPECPDL_INDEX ();
2959 Lisp_Object frame
, global_wcch
2960 = Fdefault_value (Qwindow_configuration_change_hook
);
2961 XSETFRAME (frame
, f
);
2963 if (NILP (Vrun_hooks
) || !NILP (inhibit_lisp_code
))
2966 /* Use the right buffer. Matters when running the local hooks. */
2967 if (current_buffer
!= XBUFFER (Fwindow_buffer (Qnil
)))
2969 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
2970 Fset_buffer (Fwindow_buffer (Qnil
));
2973 if (SELECTED_FRAME () != f
)
2975 record_unwind_protect (select_frame_norecord
, Fselected_frame ());
2976 select_frame_norecord (frame
);
2979 /* Look for buffer-local values. */
2981 Lisp_Object windows
= Fwindow_list (frame
, Qlambda
, Qnil
);
2982 for (; CONSP (windows
); windows
= XCDR (windows
))
2984 Lisp_Object window
= XCAR (windows
);
2985 Lisp_Object buffer
= Fwindow_buffer (window
);
2986 if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook
,
2989 ptrdiff_t inner_count
= SPECPDL_INDEX ();
2990 record_unwind_protect (select_window_norecord
, Fselected_window ());
2991 select_window_norecord (window
);
2992 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook
,
2994 unbind_to (inner_count
, Qnil
);
2999 run_funs (global_wcch
);
3000 unbind_to (count
, Qnil
);
3003 DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook
,
3004 Srun_window_configuration_change_hook
, 1, 1, 0,
3005 doc
: /* Run `window-configuration-change-hook' for FRAME. */)
3008 CHECK_LIVE_FRAME (frame
);
3009 run_window_configuration_change_hook (XFRAME (frame
));
3013 /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
3014 means it's allowed to run hooks. See make_frame for a case where
3015 it's not allowed. KEEP_MARGINS_P non-zero means that the current
3016 margins, fringes, and scroll-bar settings of the window are not
3017 reset from the buffer's local settings. */
3020 set_window_buffer (Lisp_Object window
, Lisp_Object buffer
, int run_hooks_p
, int keep_margins_p
)
3022 struct window
*w
= XWINDOW (window
);
3023 struct buffer
*b
= XBUFFER (buffer
);
3024 ptrdiff_t count
= SPECPDL_INDEX ();
3025 int samebuf
= EQ (buffer
, w
->buffer
);
3027 WSET (w
, buffer
, buffer
);
3029 if (EQ (window
, selected_window
))
3030 BSET (b
, last_selected_window
, window
);
3032 /* Let redisplay errors through. */
3033 b
->display_error_modiff
= 0;
3035 /* Update time stamps of buffer display. */
3036 if (INTEGERP (BVAR (b
, display_count
)))
3037 BSET (b
, display_count
, make_number (XINT (BVAR (b
, display_count
)) + 1));
3038 BSET (b
, display_time
, Fcurrent_time ());
3040 WSET (w
, window_end_pos
, make_number (0));
3041 WSET (w
, window_end_vpos
, make_number (0));
3042 memset (&w
->last_cursor
, 0, sizeof w
->last_cursor
);
3043 WSET (w
, window_end_valid
, Qnil
);
3044 if (!(keep_margins_p
&& samebuf
))
3045 { /* If we're not actually changing the buffer, don't reset hscroll and
3046 vscroll. This case happens for example when called from
3047 change_frame_size_1, where we use a dummy call to
3048 Fset_window_buffer on the frame's selected window (and no other)
3049 just in order to run window-configuration-change-hook.
3050 Resetting hscroll and vscroll here is problematic for things like
3051 image-mode and doc-view-mode since it resets the image's position
3052 whenever we resize the frame. */
3053 w
->hscroll
= w
->min_hscroll
= 0;
3055 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
3056 set_marker_restricted (w
->start
,
3057 make_number (b
->last_window_start
),
3059 w
->start_at_line_beg
= 0;
3061 w
->last_modified
= 0;
3062 w
->last_overlay_modified
= 0;
3064 /* Maybe we could move this into the `if' but it's not obviously safe and
3065 I doubt it's worth the trouble. */
3066 windows_or_buffers_changed
++;
3068 /* We must select BUFFER for running the window-scroll-functions. */
3069 /* We can't check ! NILP (Vwindow_scroll_functions) here
3070 because that might itself be a local variable. */
3071 if (window_initialized
)
3073 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
3074 Fset_buffer (buffer
);
3077 XMARKER (w
->pointm
)->insertion_type
= !NILP (Vwindow_point_insertion_type
);
3079 if (!keep_margins_p
)
3081 /* Set left and right marginal area width etc. from buffer. */
3083 /* This may call adjust_window_margins three times, so
3084 temporarily disable window margins. */
3085 Lisp_Object save_left
= w
->left_margin_cols
;
3086 Lisp_Object save_right
= w
->right_margin_cols
;
3088 WSET (w
, left_margin_cols
, Qnil
);
3089 WSET (w
, right_margin_cols
, Qnil
);
3091 Fset_window_fringes (window
,
3092 BVAR (b
, left_fringe_width
), BVAR (b
, right_fringe_width
),
3093 BVAR (b
, fringes_outside_margins
));
3095 Fset_window_scroll_bars (window
,
3096 BVAR (b
, scroll_bar_width
),
3097 BVAR (b
, vertical_scroll_bar_type
), Qnil
);
3099 WSET (w
, left_margin_cols
, save_left
);
3100 WSET (w
, right_margin_cols
, save_right
);
3102 Fset_window_margins (window
,
3103 BVAR (b
, left_margin_cols
), BVAR (b
, right_margin_cols
));
3108 if (! NILP (Vwindow_scroll_functions
))
3109 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
3110 Fmarker_position (w
->start
));
3111 run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w
)));
3114 unbind_to (count
, Qnil
);
3117 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 3, 0,
3118 doc
: /* Make WINDOW display BUFFER-OR-NAME as its contents.
3119 WINDOW must be a live window and defaults to the selected one.
3120 BUFFER-OR-NAME must be a buffer or the name of an existing buffer.
3122 Optional third argument KEEP-MARGINS non-nil means that WINDOW's current
3123 display margins, fringe widths, and scroll bar settings are preserved;
3124 the default is to reset these from the local settings for BUFFER-OR-NAME
3125 or the frame defaults. Return nil.
3127 This function throws an error when WINDOW is strongly dedicated to its
3128 buffer (that is `window-dedicated-p' returns t for WINDOW) and does not
3129 already display BUFFER-OR-NAME.
3131 This function runs `window-scroll-functions' before running
3132 `window-configuration-change-hook'. */)
3133 (register Lisp_Object window
, Lisp_Object buffer_or_name
, Lisp_Object keep_margins
)
3135 register Lisp_Object tem
, buffer
;
3136 register struct window
*w
= decode_live_window (window
);
3138 XSETWINDOW (window
, w
);
3139 buffer
= Fget_buffer (buffer_or_name
);
3140 CHECK_BUFFER (buffer
);
3141 if (NILP (BVAR (XBUFFER (buffer
), name
)))
3142 error ("Attempt to display deleted buffer");
3146 error ("Window is deleted");
3147 else if (!EQ (tem
, Qt
))
3148 /* w->buffer is t when the window is first being set up. */
3150 if (!EQ (tem
, buffer
))
3152 if (EQ (w
->dedicated
, Qt
))
3153 /* WINDOW is strongly dedicated to its buffer, signal an
3155 error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem
), name
)));
3157 /* WINDOW is weakly dedicated to its buffer, reset
3159 WSET (w
, dedicated
, Qnil
);
3161 call1 (Qrecord_window_buffer
, window
);
3167 set_window_buffer (window
, buffer
, 1, !NILP (keep_margins
));
3173 display_buffer (Lisp_Object buffer
, Lisp_Object not_this_window_p
, Lisp_Object override_frame
)
3175 return call3 (Qdisplay_buffer
, buffer
, not_this_window_p
, override_frame
);
3178 DEFUN ("force-window-update", Fforce_window_update
, Sforce_window_update
,
3180 doc
: /* Force all windows to be updated on next redisplay.
3181 If optional arg OBJECT is a window, force redisplay of that window only.
3182 If OBJECT is a buffer or buffer name, force redisplay of all windows
3183 displaying that buffer. */)
3184 (Lisp_Object object
)
3188 windows_or_buffers_changed
++;
3189 update_mode_lines
++;
3193 if (WINDOWP (object
))
3195 struct window
*w
= XWINDOW (object
);
3196 mark_window_display_accurate (object
, 0);
3197 w
->update_mode_line
= 1;
3198 if (BUFFERP (w
->buffer
))
3199 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
3200 ++update_mode_lines
;
3204 if (STRINGP (object
))
3205 object
= Fget_buffer (object
);
3206 if (BUFFERP (object
) && !NILP (BVAR (XBUFFER (object
), name
)))
3208 /* Walk all windows looking for buffer, and force update
3209 of each of those windows. */
3211 object
= window_loop (REDISPLAY_BUFFER_WINDOWS
, object
, 0, Qvisible
);
3212 return NILP (object
) ? Qnil
: Qt
;
3215 /* If nothing suitable was found, just return.
3216 We could signal an error, but this feature will typically be used
3217 asynchronously in timers or process sentinels, so we don't. */
3223 temp_output_buffer_show (register Lisp_Object buf
)
3225 register struct buffer
*old
= current_buffer
;
3226 register Lisp_Object window
;
3227 register struct window
*w
;
3229 BSET (XBUFFER (buf
), directory
, BVAR (current_buffer
, directory
));
3232 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
3236 set_buffer_internal (old
);
3238 if (!NILP (Vtemp_buffer_show_function
))
3239 call1 (Vtemp_buffer_show_function
, buf
);
3242 window
= display_buffer (buf
, Qnil
, Qnil
);
3244 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
3245 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
3246 Vminibuf_scroll_window
= window
;
3247 w
= XWINDOW (window
);
3250 set_marker_restricted_both (w
->start
, buf
, BEG
, BEG
);
3251 set_marker_restricted_both (w
->pointm
, buf
, BEG
, BEG
);
3253 /* Run temp-buffer-show-hook, with the chosen window selected
3254 and its buffer current. */
3256 ptrdiff_t count
= SPECPDL_INDEX ();
3257 Lisp_Object prev_window
, prev_buffer
;
3258 prev_window
= selected_window
;
3259 XSETBUFFER (prev_buffer
, old
);
3261 /* Select the window that was chosen, for running the hook.
3262 Note: Both Fselect_window and select_window_norecord may
3263 set-buffer to the buffer displayed in the window,
3264 so we need to save the current buffer. --stef */
3265 record_unwind_protect (Fset_buffer
, prev_buffer
);
3266 record_unwind_protect (select_window_norecord
, prev_window
);
3267 Fselect_window (window
, Qt
);
3268 Fset_buffer (w
->buffer
);
3269 Frun_hooks (1, &Qtemp_buffer_show_hook
);
3270 unbind_to (count
, Qnil
);
3275 DEFUN ("internal-temp-output-buffer-show",
3276 Ftemp_output_buffer_show
, Stemp_output_buffer_show
,
3278 doc
: /* Internal function for `with-output-to-temp-buffer'. */)
3281 temp_output_buffer_show (buf
);
3285 /* Make new window, have it replace WINDOW in window-tree, and make
3286 WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only
3287 horizontal child). */
3289 make_parent_window (Lisp_Object window
, int horflag
)
3292 register struct window
*o
, *p
;
3294 o
= XWINDOW (window
);
3295 p
= allocate_window ();
3296 memcpy ((char *) p
+ sizeof (struct vectorlike_header
),
3297 (char *) o
+ sizeof (struct vectorlike_header
),
3298 word_size
* VECSIZE (struct window
));
3299 XSETWINDOW (parent
, p
);
3301 p
->sequence_number
= ++sequence_number
;
3303 replace_window (window
, parent
, 1);
3305 WSET (o
, next
, Qnil
);
3306 WSET (o
, prev
, Qnil
);
3307 WSET (o
, parent
, parent
);
3309 WSET (p
, hchild
, horflag
? window
: Qnil
);
3310 WSET (p
, vchild
, horflag
? Qnil
: window
);
3311 WSET (p
, start
, Qnil
);
3312 WSET (p
, pointm
, Qnil
);
3313 WSET (p
, buffer
, Qnil
);
3314 WSET (p
, combination_limit
, Qnil
);
3315 WSET (p
, window_parameters
, Qnil
);
3318 /* Make new window from scratch. */
3323 register struct window
*w
;
3325 w
= allocate_window ();
3326 /* Initialize Lisp data. Note that allocate_window initializes all
3327 Lisp data to nil, so do it only for slots which should not be nil. */
3328 WSET (w
, left_col
, make_number (0));
3329 WSET (w
, top_line
, make_number (0));
3330 WSET (w
, total_lines
, make_number (0));
3331 WSET (w
, total_cols
, make_number (0));
3332 WSET (w
, normal_lines
, make_float (1.0));
3333 WSET (w
, normal_cols
, make_float (1.0));
3334 WSET (w
, new_total
, make_number (0));
3335 WSET (w
, new_normal
, make_number (0));
3336 WSET (w
, start
, Fmake_marker ());
3337 WSET (w
, pointm
, Fmake_marker ());
3338 WSET (w
, vertical_scroll_bar_type
, Qt
);
3339 WSET (w
, window_end_pos
, make_number (0));
3340 WSET (w
, window_end_vpos
, make_number (0));
3342 /* Initialize non-Lisp data. Note that allocate_window zeroes out all
3343 non-Lisp data, so do it only for slots which should not be zero. */
3344 w
->nrows_scale_factor
= w
->ncols_scale_factor
= 1;
3345 w
->phys_cursor_type
= -1;
3346 w
->phys_cursor_width
= -1;
3347 w
->sequence_number
= ++sequence_number
;
3349 /* Reset window_list. */
3350 Vwindow_list
= Qnil
;
3351 /* Return window. */
3352 XSETWINDOW (window
, w
);
3356 DEFUN ("set-window-new-total", Fset_window_new_total
, Sset_window_new_total
, 2, 3, 0,
3357 doc
: /* Set new total size of WINDOW to SIZE.
3358 WINDOW must be a valid window and defaults to the selected one.
3361 Optional argument ADD non-nil means add SIZE to the new total size of
3362 WINDOW and return the sum.
3364 Note: This function does not operate on any child windows of WINDOW. */)
3365 (Lisp_Object window
, Lisp_Object size
, Lisp_Object add
)
3367 struct window
*w
= decode_valid_window (window
);
3369 CHECK_NUMBER (size
);
3371 WSET (w
, new_total
, size
);
3373 WSET (w
, new_total
, make_number (XINT (w
->new_total
) + XINT (size
)));
3375 return w
->new_total
;
3378 DEFUN ("set-window-new-normal", Fset_window_new_normal
, Sset_window_new_normal
, 1, 2, 0,
3379 doc
: /* Set new normal size of WINDOW to SIZE.
3380 WINDOW must be a valid window and defaults to the selected one.
3383 Note: This function does not operate on any child windows of WINDOW. */)
3384 (Lisp_Object window
, Lisp_Object size
)
3386 return WSET (decode_valid_window (window
), new_normal
, size
);
3389 /* Return 1 if setting w->total_lines (w->total_cols if HORFLAG is
3390 non-zero) to w->new_total would result in correct heights (widths)
3391 for window W and recursively all child windows of W.
3393 Note: This function does not check any of `window-fixed-size-p',
3394 `window-min-height' or `window-min-width'. It does check that window
3395 sizes do not drop below one line (two columns). */
3397 window_resize_check (struct window
*w
, int horflag
)
3401 if (!NILP (w
->vchild
))
3402 /* W is a vertical combination. */
3404 c
= XWINDOW (w
->vchild
);
3406 /* All child windows of W must have the same width as W. */
3410 if ((XINT (c
->new_total
) != XINT (w
->new_total
))
3411 || !window_resize_check (c
, horflag
))
3413 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
3418 /* The sum of the heights of the child windows of W must equal
3421 int sum_of_sizes
= 0;
3424 if (!window_resize_check (c
, horflag
))
3426 sum_of_sizes
= sum_of_sizes
+ XINT (c
->new_total
);
3427 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
3429 return (sum_of_sizes
== XINT (w
->new_total
));
3432 else if (!NILP (w
->hchild
))
3433 /* W is a horizontal combination. */
3435 c
= XWINDOW (w
->hchild
);
3437 /* The sum of the widths of the child windows of W must equal W's
3440 int sum_of_sizes
= 0;
3443 if (!window_resize_check (c
, horflag
))
3445 sum_of_sizes
= sum_of_sizes
+ XINT (c
->new_total
);
3446 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
3448 return (sum_of_sizes
== XINT (w
->new_total
));
3451 /* All child windows of W must have the same height as W. */
3455 if ((XINT (c
->new_total
) != XINT (w
->new_total
))
3456 || !window_resize_check (c
, horflag
))
3458 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
3464 /* A leaf window. Make sure it's not too small. The following
3465 hardcodes the values of `window-safe-min-width' (2) and
3466 `window-safe-min-height' (1) which are defined in window.el. */
3467 return XINT (w
->new_total
) >= (horflag
? 2 : 1);
3470 /* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to
3471 w->new_total for window W and recursively all child windows of W.
3472 Also calculate and assign the new vertical (horizontal) start
3473 positions of each of these windows.
3475 This function does not perform any error checks. Make sure you have
3476 run window_resize_check on W before applying this function. */
3478 window_resize_apply (struct window
*w
, int horflag
)
3483 /* Note: Assigning new_normal requires that the new total size of the
3484 parent window has been set *before*. */
3487 WSET (w
, total_cols
, w
->new_total
);
3488 if (NUMBERP (w
->new_normal
))
3489 WSET (w
, normal_cols
, w
->new_normal
);
3491 pos
= XINT (w
->left_col
);
3495 WSET (w
, total_lines
, w
->new_total
);
3496 if (NUMBERP (w
->new_normal
))
3497 WSET (w
, normal_lines
, w
->new_normal
);
3499 pos
= XINT (w
->top_line
);
3502 if (!NILP (w
->vchild
))
3503 /* W is a vertical combination. */
3505 c
= XWINDOW (w
->vchild
);
3509 WSET (c
, left_col
, make_number (pos
));
3511 WSET (c
, top_line
, make_number (pos
));
3512 window_resize_apply (c
, horflag
);
3514 pos
= pos
+ XINT (c
->total_lines
);
3515 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
3518 else if (!NILP (w
->hchild
))
3519 /* W is a horizontal combination. */
3521 c
= XWINDOW (w
->hchild
);
3525 WSET (c
, left_col
, make_number (pos
));
3527 WSET (c
, top_line
, make_number (pos
));
3528 window_resize_apply (c
, horflag
);
3530 pos
= pos
+ XINT (c
->total_cols
);
3531 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
3535 /* Clear out some redisplay caches. */
3536 w
->last_modified
= 0;
3537 w
->last_overlay_modified
= 0;
3541 DEFUN ("window-resize-apply", Fwindow_resize_apply
, Swindow_resize_apply
, 1, 2, 0,
3542 doc
: /* Apply requested size values for window-tree of FRAME.
3543 Optional argument HORIZONTAL omitted or nil means apply requested height
3544 values. HORIZONTAL non-nil means apply requested width values.
3546 This function checks whether the requested values sum up to a valid
3547 window layout, recursively assigns the new sizes of all child windows
3548 and calculates and assigns the new start positions of these windows.
3550 Note: This function does not check any of `window-fixed-size-p',
3551 `window-min-height' or `window-min-width'. All these checks have to
3552 be applied on the Elisp level. */)
3553 (Lisp_Object frame
, Lisp_Object horizontal
)
3557 int horflag
= !NILP (horizontal
);
3560 frame
= selected_frame
;
3561 CHECK_LIVE_FRAME (frame
);
3564 r
= XWINDOW (FRAME_ROOT_WINDOW (f
));
3566 if (!window_resize_check (r
, horflag
)
3567 || ! EQ (r
->new_total
,
3568 (horflag
? r
->total_cols
: r
->total_lines
)))
3572 window_resize_apply (r
, horflag
);
3574 windows_or_buffers_changed
++;
3575 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
3580 run_window_configuration_change_hook (f
);
3586 /* Resize frame F's windows when number of lines of F is set to SIZE.
3587 HORFLAG 1 means resize windows when number of columns of F is set to
3590 This function can delete all windows but the selected one in order to
3591 satisfy the request. The result will be meaningful if and only if
3592 F's windows have meaningful sizes when you call this. */
3594 resize_frame_windows (struct frame
*f
, int size
, int horflag
)
3596 Lisp_Object root
= f
->root_window
;
3597 struct window
*r
= XWINDOW (root
);
3598 Lisp_Object mini
= f
->minibuffer_window
;
3600 /* new_size is the new size of the frame's root window. */
3601 int new_size
= (horflag
3604 - FRAME_TOP_MARGIN (f
)
3605 - ((FRAME_HAS_MINIBUF_P (f
) && !FRAME_MINIBUF_ONLY_P (f
))
3608 WSET (r
, top_line
, make_number (FRAME_TOP_MARGIN (f
)));
3609 if (NILP (r
->vchild
) && NILP (r
->hchild
))
3610 /* For a leaf root window just set the size. */
3612 WSET (r
, total_cols
, make_number (new_size
));
3614 WSET (r
, total_lines
, make_number (new_size
));
3617 /* old_size is the old size of the frame's root window. */
3618 int old_size
= XFASTINT (horflag
? r
->total_cols
3622 XSETINT (delta
, new_size
- old_size
);
3623 /* Try a "normal" resize first. */
3624 resize_root_window (root
, delta
, horflag
? Qt
: Qnil
, Qnil
);
3625 if (window_resize_check (r
, horflag
)
3626 && new_size
== XINT (r
->new_total
))
3627 window_resize_apply (r
, horflag
);
3630 /* Try with "reasonable" minimum sizes next. */
3631 resize_root_window (root
, delta
, horflag
? Qt
: Qnil
, Qt
);
3632 if (window_resize_check (r
, horflag
)
3633 && new_size
== XINT (r
->new_total
))
3634 window_resize_apply (r
, horflag
);
3637 /* Finally, try with "safe" minimum sizes. */
3638 resize_root_window (root
, delta
, horflag
? Qt
: Qnil
, Qsafe
);
3639 if (window_resize_check (r
, horflag
)
3640 && new_size
== XINT (r
->new_total
))
3641 window_resize_apply (r
, horflag
);
3644 /* We lost. Delete all windows but the frame's
3646 root
= f
->selected_window
;
3647 Fdelete_other_windows_internal (root
, Qnil
);
3649 WSET (XWINDOW (root
), total_cols
, make_number (new_size
));
3651 WSET (XWINDOW (root
), total_lines
, make_number (new_size
));
3657 if (FRAME_HAS_MINIBUF_P (f
) && !FRAME_MINIBUF_ONLY_P (f
))
3661 WSET (m
, total_cols
, make_number (size
));
3664 /* Are we sure we always want 1 line here? */
3665 WSET (m
, total_lines
, make_number (1));
3667 make_number (XINT (r
->top_line
) + XINT (r
->total_lines
)));
3673 DEFUN ("split-window-internal", Fsplit_window_internal
, Ssplit_window_internal
, 4, 4, 0,
3674 doc
: /* Split window OLD.
3675 Second argument TOTAL-SIZE specifies the number of lines or columns of the
3676 new window. In any case TOTAL-SIZE must be a positive integer.
3678 Third argument SIDE nil (or `below') specifies that the new window shall
3679 be located below WINDOW. SIDE `above' means the new window shall be
3680 located above WINDOW. In both cases TOTAL-SIZE specifies the number of
3681 lines of the new window including space reserved for the mode and/or
3684 SIDE t (or `right') specifies that the new window shall be located on
3685 the right side of WINDOW. SIDE `left' means the new window shall be
3686 located on the left of WINDOW. In both cases TOTAL-SIZE specifies the
3687 number of columns of the new window including space reserved for fringes
3688 and the scrollbar or a divider column.
3690 Fourth argument NORMAL-SIZE specifies the normal size of the new window
3691 according to the SIDE argument.
3693 The new total and normal sizes of all involved windows must have been
3694 set correctly. See the code of `split-window' for how this is done. */)
3695 (Lisp_Object old
, Lisp_Object total_size
, Lisp_Object side
, Lisp_Object normal_size
)
3697 /* OLD (*o) is the window we have to split. (*p) is either OLD's
3698 parent window or an internal window we have to install as OLD's new
3699 parent. REFERENCE (*r) must denote a live window, or is set to OLD
3700 provided OLD is a leaf window, or to the frame's selected window.
3701 NEW (*n) is the new window created with some parameters taken from
3703 register Lisp_Object
new, frame
, reference
;
3704 register struct window
*o
, *p
, *n
, *r
;
3707 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */
3708 = EQ (side
, Qt
) || EQ (side
, Qleft
) || EQ (side
, Qright
);
3709 int combination_limit
= 0;
3713 frame
= WINDOW_FRAME (o
);
3716 CHECK_NUMBER (total_size
);
3718 /* Set combination_limit to 1 if we have to make a new parent window.
3719 We do that if either `window-combination-limit' is t, or OLD has no
3720 parent, or OLD is ortho-combined. */
3722 !NILP (Vwindow_combination_limit
)
3725 ? (XWINDOW (o
->parent
)->hchild
)
3726 : (XWINDOW (o
->parent
)->vchild
));
3728 /* We need a live reference window to initialize some parameters. */
3729 if (WINDOW_LIVE_P (old
))
3730 /* OLD is live, use it as reference window. */
3733 /* Use the frame's selected window as reference window. */
3734 reference
= FRAME_SELECTED_WINDOW (f
);
3735 r
= XWINDOW (reference
);
3737 /* The following bugs are caught by `split-window'. */
3738 if (MINI_WINDOW_P (o
))
3739 error ("Attempt to split minibuffer window");
3740 else if (XINT (total_size
) < (horflag
? 2 : 1))
3741 error ("Size of new window too small (after split)");
3742 else if (!combination_limit
&& !NILP (Vwindow_combination_resize
))
3743 /* `window-combination-resize' non-nil means try to resize OLD's siblings
3746 p
= XWINDOW (o
->parent
);
3747 /* Temporarily pretend we split the parent window. */
3749 make_number (XINT (horflag
? p
->total_cols
: p
->total_lines
)
3750 - XINT (total_size
)));
3751 if (!window_resize_check (p
, horflag
))
3752 error ("Window sizes don't fit");
3754 /* Undo the temporary pretension. */
3756 horflag
? p
->total_cols
: p
->total_lines
);
3760 if (!window_resize_check (o
, horflag
))
3761 error ("Resizing old window failed");
3762 else if (XINT (total_size
) + XINT (o
->new_total
)
3763 != XINT (horflag
? o
->total_cols
: o
->total_lines
))
3764 error ("Sum of sizes of old and new window don't fit");
3767 /* This is our point of no return. */
3768 if (combination_limit
)
3770 /* Save the old value of o->normal_cols/lines. It gets corrupted
3771 by make_parent_window and we need it below for assigning it to
3773 Lisp_Object new_normal
3774 = horflag
? o
->normal_cols
: o
->normal_lines
;
3776 make_parent_window (old
, horflag
);
3777 p
= XWINDOW (o
->parent
);
3778 /* Store value of `window-combination-limit' in new parent's
3779 combination_limit slot. */
3780 WSET (p
, combination_limit
, Vwindow_combination_limit
);
3781 /* These get applied below. */
3782 WSET (p
, new_total
, horflag
? o
->total_cols
: o
->total_lines
);
3783 WSET (p
, new_normal
, new_normal
);
3786 p
= XWINDOW (o
->parent
);
3788 windows_or_buffers_changed
++;
3789 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
3790 new = make_window ();
3792 WSET (n
, frame
, frame
);
3793 WSET (n
, parent
, o
->parent
);
3794 WSET (n
, vchild
, Qnil
);
3795 WSET (n
, hchild
, Qnil
);
3797 if (EQ (side
, Qabove
) || EQ (side
, Qleft
))
3799 WSET (n
, prev
, o
->prev
);
3802 WSET (p
, hchild
, new);
3804 WSET (p
, vchild
, new);
3806 WSET (XWINDOW (n
->prev
), next
, new);
3807 WSET (n
, next
, old
);
3808 WSET (o
, prev
, new);
3812 WSET (n
, next
, o
->next
);
3813 if (!NILP (n
->next
))
3814 WSET (XWINDOW (n
->next
), prev
, new);
3815 WSET (n
, prev
, old
);
3816 WSET (o
, next
, new);
3819 WSET (n
, buffer
, Qt
);
3820 WSET (n
, window_end_valid
, Qnil
);
3821 memset (&n
->last_cursor
, 0, sizeof n
->last_cursor
);
3823 /* Get special geometry settings from reference window. */
3824 WSET (n
, left_margin_cols
, r
->left_margin_cols
);
3825 WSET (n
, right_margin_cols
, r
->right_margin_cols
);
3826 WSET (n
, left_fringe_width
, r
->left_fringe_width
);
3827 WSET (n
, right_fringe_width
, r
->right_fringe_width
);
3828 n
->fringes_outside_margins
= r
->fringes_outside_margins
;
3829 WSET (n
, scroll_bar_width
, r
->scroll_bar_width
);
3830 WSET (n
, vertical_scroll_bar_type
, r
->vertical_scroll_bar_type
);
3832 /* Directly assign orthogonal coordinates and sizes. */
3835 WSET (n
, top_line
, o
->top_line
);
3836 WSET (n
, total_lines
, o
->total_lines
);
3840 WSET (n
, left_col
, o
->left_col
);
3841 WSET (n
, total_cols
, o
->total_cols
);
3844 /* Iso-coordinates and sizes are assigned by window_resize_apply,
3845 get them ready here. */
3846 WSET (n
, new_total
, total_size
);
3847 WSET (n
, new_normal
, normal_size
);
3850 window_resize_apply (p
, horflag
);
3852 /* Set buffer of NEW to buffer of reference window. Don't run
3854 set_window_buffer (new, r
->buffer
, 0, 1);
3857 /* Maybe we should run the scroll functions in Elisp (which already
3858 runs the configuration change hook). */
3859 if (! NILP (Vwindow_scroll_functions
))
3860 run_hook_with_args_2 (Qwindow_scroll_functions
, new,
3861 Fmarker_position (n
->start
));
3867 DEFUN ("delete-window-internal", Fdelete_window_internal
, Sdelete_window_internal
, 1, 1, 0,
3868 doc
: /* Remove WINDOW from its frame.
3869 WINDOW defaults to the selected window. Return nil.
3870 Signal an error when WINDOW is the only window on its frame. */)
3871 (register Lisp_Object window
)
3873 register Lisp_Object parent
, sibling
, frame
, root
;
3874 struct window
*w
, *p
, *s
, *r
;
3877 int before_sibling
= 0;
3879 w
= decode_any_window (window
);
3880 XSETWINDOW (window
, w
);
3881 if (NILP (w
->buffer
)
3882 && NILP (w
->hchild
) && NILP (w
->vchild
))
3883 /* It's a no-op to delete an already deleted window. */
3888 /* Never delete a minibuffer or frame root window. */
3889 error ("Attempt to delete minibuffer or sole ordinary window");
3890 else if (NILP (w
->prev
) && NILP (w
->next
))
3891 /* Rather bow out here, this case should be handled on the Elisp
3893 error ("Attempt to delete sole window of parent");
3895 p
= XWINDOW (parent
);
3896 horflag
= NILP (p
->vchild
);
3898 frame
= WINDOW_FRAME (w
);
3901 root
= FRAME_ROOT_WINDOW (f
);
3904 /* Unlink WINDOW from window tree. */
3906 /* Get SIBLING below (on the right of) WINDOW. */
3908 /* before_sibling 1 means WINDOW is the first child of its
3909 parent and thus before the sibling. */
3912 s
= XWINDOW (sibling
);
3913 WSET (s
, prev
, Qnil
);
3915 WSET (p
, hchild
, sibling
);
3917 WSET (p
, vchild
, sibling
);
3920 /* Get SIBLING above (on the left of) WINDOW. */
3923 s
= XWINDOW (sibling
);
3924 WSET (s
, next
, w
->next
);
3925 if (!NILP (s
->next
))
3926 WSET (XWINDOW (s
->next
), prev
, sibling
);
3929 if (window_resize_check (r
, horflag
)
3930 && EQ (r
->new_total
,
3931 (horflag
? r
->total_cols
: r
->total_lines
)))
3932 /* We can delete WINDOW now. */
3937 window_resize_apply (p
, horflag
);
3939 /* If this window is referred to by the dpyinfo's mouse
3940 highlight, invalidate that slot to be safe (Bug#9904). */
3941 if (!FRAME_INITIAL_P (f
))
3943 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
3945 if (EQ (hlinfo
->mouse_face_window
, window
))
3946 hlinfo
->mouse_face_window
= Qnil
;
3949 windows_or_buffers_changed
++;
3950 Vwindow_list
= Qnil
;
3951 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
3953 WSET (w
, next
, Qnil
); /* Don't delete w->next too. */
3954 free_window_matrices (w
);
3956 if (!NILP (w
->vchild
))
3958 delete_all_child_windows (w
->vchild
);
3959 WSET (w
, vchild
, Qnil
);
3961 else if (!NILP (w
->hchild
))
3963 delete_all_child_windows (w
->hchild
);
3964 WSET (w
, hchild
, Qnil
);
3966 else if (!NILP (w
->buffer
))
3969 unchain_marker (XMARKER (w
->pointm
));
3970 unchain_marker (XMARKER (w
->start
));
3971 WSET (w
, buffer
, Qnil
);
3974 if (NILP (s
->prev
) && NILP (s
->next
))
3975 /* A matrjoshka where SIBLING has become the only child of
3978 /* Put SIBLING into PARENT's place. */
3979 replace_window (parent
, sibling
, 0);
3980 /* Have SIBLING inherit the following three slot values from
3981 PARENT (the combination_limit slot is not inherited). */
3982 WSET (s
, normal_cols
, p
->normal_cols
);
3983 WSET (s
, normal_lines
, p
->normal_lines
);
3984 /* Mark PARENT as deleted. */
3985 WSET (p
, vchild
, Qnil
);
3986 WSET (p
, hchild
, Qnil
);
3987 /* Try to merge SIBLING into its new parent. */
3988 recombine_windows (sibling
);
3993 if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f
)))
3994 /* We deleted the frame's selected window. */
3996 /* Use the frame's first window as fallback ... */
3997 Lisp_Object new_selected_window
= Fframe_first_window (frame
);
3998 /* ... but preferably use its most recently used window. */
3999 Lisp_Object mru_window
;
4001 /* `get-mru-window' might fail for some reason so play it safe
4002 - promote the first window _without recording it_ first. */
4003 if (EQ (FRAME_SELECTED_WINDOW (f
), selected_window
))
4004 Fselect_window (new_selected_window
, Qt
);
4006 fset_selected_window (f
, new_selected_window
);
4010 /* Now look whether `get-mru-window' gets us something. */
4011 mru_window
= call1 (Qget_mru_window
, frame
);
4012 if (WINDOW_LIVE_P (mru_window
)
4013 && EQ (XWINDOW (mru_window
)->frame
, frame
))
4014 new_selected_window
= mru_window
;
4016 /* If all ended up well, we now promote the mru window. */
4017 if (EQ (FRAME_SELECTED_WINDOW (f
), selected_window
))
4018 Fselect_window (new_selected_window
, Qnil
);
4020 fset_selected_window (f
, new_selected_window
);
4025 /* Must be run by the caller:
4026 run_window_configuration_change_hook (f); */
4029 /* We failed: Relink WINDOW into window tree. */
4033 WSET (s
, prev
, window
);
4035 WSET (p
, hchild
, window
);
4037 WSET (p
, vchild
, window
);
4041 WSET (s
, next
, window
);
4042 if (!NILP (w
->next
))
4043 WSET (XWINDOW (w
->next
), prev
, window
);
4045 error ("Deletion failed");
4051 /***********************************************************************
4052 Resizing Mini-Windows
4053 ***********************************************************************/
4055 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we
4058 grow_mini_window (struct window
*w
, int delta
)
4060 struct frame
*f
= XFRAME (w
->frame
);
4062 Lisp_Object root
, value
;
4064 eassert (MINI_WINDOW_P (w
));
4065 eassert (delta
>= 0);
4067 root
= FRAME_ROOT_WINDOW (f
);
4069 value
= call2 (Qwindow_resize_root_window_vertically
,
4070 root
, make_number (- delta
));
4071 if (INTEGERP (value
) && window_resize_check (r
, 0))
4074 window_resize_apply (r
, 0);
4076 /* Grow the mini-window. */
4078 make_number (XFASTINT (r
->top_line
) + XFASTINT (r
->total_lines
)));
4079 WSET (w
, total_lines
,
4080 make_number (XFASTINT (w
->total_lines
) - XINT (value
)));
4081 w
->last_modified
= 0;
4082 w
->last_overlay_modified
= 0;
4090 /* Shrink mini-window W. */
4092 shrink_mini_window (struct window
*w
)
4094 struct frame
*f
= XFRAME (w
->frame
);
4096 Lisp_Object root
, value
;
4099 eassert (MINI_WINDOW_P (w
));
4101 size
= XINT (w
->total_lines
);
4104 root
= FRAME_ROOT_WINDOW (f
);
4106 value
= call2 (Qwindow_resize_root_window_vertically
,
4107 root
, make_number (size
- 1));
4108 if (INTEGERP (value
) && window_resize_check (r
, 0))
4111 window_resize_apply (r
, 0);
4113 /* Shrink the mini-window. */
4115 make_number (XFASTINT (r
->top_line
) + XFASTINT (r
->total_lines
)));
4116 WSET (w
, total_lines
, make_number (1));
4118 w
->last_modified
= 0;
4119 w
->last_overlay_modified
= 0;
4124 /* If the above failed for whatever strange reason we must make a
4125 one window frame here. The same routine will be needed when
4126 shrinking the frame (and probably when making the initial
4127 *scratch* window). For the moment leave things as they are. */
4131 DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal
, Sresize_mini_window_internal
, 1, 1, 0,
4132 doc
: /* Resize minibuffer window WINDOW. */)
4133 (Lisp_Object window
)
4135 struct window
*w
= XWINDOW (window
);
4140 CHECK_WINDOW (window
);
4141 f
= XFRAME (w
->frame
);
4143 if (!EQ (FRAME_MINIBUF_WINDOW (XFRAME (w
->frame
)), window
))
4144 error ("Not a valid minibuffer window");
4145 else if (FRAME_MINIBUF_ONLY_P (f
))
4146 error ("Cannot resize a minibuffer-only frame");
4148 r
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4149 height
= XINT (r
->total_lines
) + XINT (w
->total_lines
);
4150 if (window_resize_check (r
, 0)
4151 && XINT (w
->new_total
) > 0
4152 && height
== XINT (r
->new_total
) + XINT (w
->new_total
))
4155 window_resize_apply (r
, 0);
4157 WSET (w
, total_lines
, w
->new_total
);
4159 make_number (XINT (r
->top_line
) + XINT (r
->total_lines
)));
4161 windows_or_buffers_changed
++;
4162 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4166 run_window_configuration_change_hook (f
);
4169 else error ("Failed to resize minibuffer window");
4172 /* Mark window cursors off for all windows in the window tree rooted
4173 at W by setting their phys_cursor_on_p flag to zero. Called from
4174 xterm.c, e.g. when a frame is cleared and thereby all cursors on
4175 the frame are cleared. */
4178 mark_window_cursors_off (struct window
*w
)
4182 if (!NILP (w
->hchild
))
4183 mark_window_cursors_off (XWINDOW (w
->hchild
));
4184 else if (!NILP (w
->vchild
))
4185 mark_window_cursors_off (XWINDOW (w
->vchild
));
4187 w
->phys_cursor_on_p
= 0;
4189 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4194 /* Return number of lines of text (not counting mode lines) in W. */
4197 window_internal_height (struct window
*w
)
4199 int ht
= XFASTINT (w
->total_lines
);
4201 if (!MINI_WINDOW_P (w
))
4203 if (!NILP (w
->parent
)
4204 || !NILP (w
->vchild
)
4205 || !NILP (w
->hchild
)
4208 || WINDOW_WANTS_MODELINE_P (w
))
4211 if (WINDOW_WANTS_HEADER_LINE_P (w
))
4218 /************************************************************************
4220 ***********************************************************************/
4222 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
4223 N screen-fulls, which is defined as the height of the window minus
4224 next_screen_context_lines. If WHOLE is zero, scroll up N lines
4225 instead. Negative values of N mean scroll down. NOERROR non-zero
4226 means don't signal an error if we try to move over BEGV or ZV,
4230 window_scroll (Lisp_Object window
, EMACS_INT n
, int whole
, int noerror
)
4233 n
= clip_to_bounds (INT_MIN
, n
, INT_MAX
);
4235 /* If we must, use the pixel-based version which is much slower than
4236 the line-based one but can handle varying line heights. */
4237 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
4238 window_scroll_pixel_based (window
, n
, whole
, noerror
);
4240 window_scroll_line_based (window
, n
, whole
, noerror
);
4246 /* Implementation of window_scroll that works based on pixel line
4247 heights. See the comment of window_scroll for parameter
4251 window_scroll_pixel_based (Lisp_Object window
, int n
, int whole
, int noerror
)
4254 struct window
*w
= XWINDOW (window
);
4255 struct text_pos start
;
4256 int this_scroll_margin
;
4257 /* True if we fiddled the window vscroll field without really scrolling. */
4259 int x
, y
, rtop
, rbot
, rowh
, vpos
;
4260 void *itdata
= NULL
;
4262 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4263 /* Scrolling a minibuffer window via scroll bar when the echo area
4264 shows long text sometimes resets the minibuffer contents behind
4266 if (CHARPOS (start
) > ZV
)
4267 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
4269 /* If PT is not visible in WINDOW, move back one half of
4270 the screen. Allow PT to be partially visible, otherwise
4271 something like (scroll-down 1) with PT in the line before
4272 the partially visible one would recenter. */
4274 if (!pos_visible_p (w
, PT
, &x
, &y
, &rtop
, &rbot
, &rowh
, &vpos
))
4276 itdata
= bidi_shelve_cache ();
4277 /* Move backward half the height of the window. Performance note:
4278 vmotion used here is about 10% faster, but would give wrong
4279 results for variable height lines. */
4280 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4281 it
.current_y
= it
.last_visible_y
;
4282 move_it_vertically_backward (&it
, window_box_height (w
) / 2);
4284 /* The function move_iterator_vertically may move over more than
4285 the specified y-distance. If it->w is small, e.g. a
4286 mini-buffer window, we may end up in front of the window's
4287 display area. This is the case when Start displaying at the
4288 start of the line containing PT in this case. */
4289 if (it
.current_y
<= 0)
4291 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4292 move_it_vertically_backward (&it
, 0);
4296 start
= it
.current
.pos
;
4297 bidi_unshelve_cache (itdata
, 0);
4299 else if (auto_window_vscroll_p
)
4301 if (rtop
|| rbot
) /* partially visible */
4304 int dy
= WINDOW_FRAME_LINE_HEIGHT (w
);
4306 dy
= max ((window_box_height (w
)
4307 - next_screen_context_lines
* dy
),
4313 /* Only vscroll backwards if already vscrolled forwards. */
4314 if (w
->vscroll
< 0 && rtop
> 0)
4316 px
= max (0, -w
->vscroll
- min (rtop
, -dy
));
4317 Fset_window_vscroll (window
, make_number (px
), Qt
);
4323 /* Do vscroll if already vscrolled or only display line. */
4324 if (rbot
> 0 && (w
->vscroll
< 0 || vpos
== 0))
4326 px
= max (0, -w
->vscroll
+ min (rbot
, dy
));
4327 Fset_window_vscroll (window
, make_number (px
), Qt
);
4331 /* Maybe modify window start instead of scrolling. */
4332 if (rbot
> 0 || w
->vscroll
< 0)
4336 Fset_window_vscroll (window
, make_number (0), Qt
);
4337 /* If there are other text lines above the current row,
4338 move window start to current row. Else to next row. */
4340 spos
= XINT (Fline_beginning_position (Qnil
));
4342 spos
= min (XINT (Fline_end_position (Qnil
)) + 1, ZV
);
4343 set_marker_restricted (w
->start
, make_number (spos
),
4345 w
->start_at_line_beg
= 1;
4346 w
->update_mode_line
= 1;
4347 w
->last_modified
= 0;
4348 w
->last_overlay_modified
= 0;
4349 /* Set force_start so that redisplay_window will run the
4350 window-scroll-functions. */
4356 /* Cancel previous vscroll. */
4357 Fset_window_vscroll (window
, make_number (0), Qt
);
4360 itdata
= bidi_shelve_cache ();
4361 /* If scroll_preserve_screen_position is non-nil, we try to set
4362 point in the same window line as it is now, so get that line. */
4363 if (!NILP (Vscroll_preserve_screen_position
))
4365 /* We preserve the goal pixel coordinate across consecutive
4366 calls to scroll-up, scroll-down and other commands that
4367 have the `scroll-command' property. This avoids the
4368 possibility of point becoming "stuck" on a tall line when
4369 scrolling by one line. */
4370 if (window_scroll_pixel_based_preserve_y
< 0
4371 || !SYMBOLP (KVAR (current_kboard
, Vlast_command
))
4372 || NILP (Fget (KVAR (current_kboard
, Vlast_command
), Qscroll_command
)))
4374 start_display (&it
, w
, start
);
4375 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
4376 window_scroll_pixel_based_preserve_y
= it
.current_y
;
4377 window_scroll_pixel_based_preserve_x
= it
.current_x
;
4381 window_scroll_pixel_based_preserve_y
4382 = window_scroll_pixel_based_preserve_x
= -1;
4384 /* Move iterator it from start the specified distance forward or
4385 backward. The result is the new window start. */
4386 start_display (&it
, w
, start
);
4389 ptrdiff_t start_pos
= IT_CHARPOS (it
);
4390 int dy
= WINDOW_FRAME_LINE_HEIGHT (w
);
4391 dy
= max ((window_box_height (w
)
4392 - next_screen_context_lines
* dy
),
4395 /* Note that move_it_vertically always moves the iterator to the
4396 start of a line. So, if the last line doesn't have a newline,
4397 we would end up at the start of the line ending at ZV. */
4400 move_it_vertically_backward (&it
, -dy
);
4401 /* Ensure we actually do move, e.g. in case we are currently
4402 looking at an image that is taller that the window height. */
4403 while (start_pos
== IT_CHARPOS (it
)
4404 && start_pos
> BEGV
)
4405 move_it_by_lines (&it
, -1);
4409 move_it_to (&it
, ZV
, -1, it
.current_y
+ dy
, -1,
4410 MOVE_TO_POS
| MOVE_TO_Y
);
4411 /* Ensure we actually do move, e.g. in case we are currently
4412 looking at an image that is taller that the window height. */
4413 while (start_pos
== IT_CHARPOS (it
)
4415 move_it_by_lines (&it
, 1);
4419 move_it_by_lines (&it
, n
);
4421 /* We failed if we find ZV is already on the screen (scrolling up,
4422 means there's nothing past the end), or if we can't start any
4423 earlier (scrolling down, means there's nothing past the top). */
4424 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
4425 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
4427 if (IT_CHARPOS (it
) == ZV
)
4429 if (it
.current_y
< it
.last_visible_y
4430 && (it
.current_y
+ it
.max_ascent
+ it
.max_descent
4431 > it
.last_visible_y
))
4433 /* The last line was only partially visible, make it fully
4435 w
->vscroll
= (it
.last_visible_y
4436 - it
.current_y
+ it
.max_ascent
+ it
.max_descent
);
4437 adjust_glyphs (it
.f
);
4441 bidi_unshelve_cache (itdata
, 0);
4444 else if (n
< 0) /* could happen with empty buffers */
4445 xsignal0 (Qbeginning_of_buffer
);
4447 xsignal0 (Qend_of_buffer
);
4452 if (w
->vscroll
!= 0)
4453 /* The first line was only partially visible, make it fully
4458 bidi_unshelve_cache (itdata
, 0);
4462 xsignal0 (Qbeginning_of_buffer
);
4466 /* If control gets here, then we vscrolled. */
4468 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
4470 /* Don't try to change the window start below. */
4476 ptrdiff_t pos
= IT_CHARPOS (it
);
4479 /* If in the middle of a multi-glyph character move forward to
4480 the next character. */
4481 if (in_display_vector_p (&it
))
4484 move_it_to (&it
, pos
, -1, -1, -1, MOVE_TO_POS
);
4487 /* Set the window start, and set up the window for redisplay. */
4488 set_marker_restricted (w
->start
, make_number (pos
),
4490 bytepos
= XMARKER (w
->start
)->bytepos
;
4491 w
->start_at_line_beg
= (pos
== BEGV
|| FETCH_BYTE (bytepos
- 1) == '\n');
4492 w
->update_mode_line
= 1;
4493 w
->last_modified
= 0;
4494 w
->last_overlay_modified
= 0;
4495 /* Set force_start so that redisplay_window will run the
4496 window-scroll-functions. */
4500 /* The rest of this function uses current_y in a nonstandard way,
4501 not including the height of the header line if any. */
4502 it
.current_y
= it
.vpos
= 0;
4504 /* Move PT out of scroll margins.
4505 This code wants current_y to be zero at the window start position
4506 even if there is a header line. */
4507 this_scroll_margin
= max (0, scroll_margin
);
4509 = min (this_scroll_margin
, XFASTINT (w
->total_lines
) / 4);
4510 this_scroll_margin
*= FRAME_LINE_HEIGHT (it
.f
);
4514 /* We moved the window start towards ZV, so PT may be now
4515 in the scroll margin at the top. */
4516 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
4517 if (IT_CHARPOS (it
) == PT
&& it
.current_y
>= this_scroll_margin
4518 && (NILP (Vscroll_preserve_screen_position
)
4519 || EQ (Vscroll_preserve_screen_position
, Qt
)))
4520 /* We found PT at a legitimate height. Leave it alone. */
4522 else if (window_scroll_pixel_based_preserve_y
>= 0)
4524 /* If we have a header line, take account of it.
4525 This is necessary because we set it.current_y to 0, above. */
4526 move_it_to (&it
, -1,
4527 window_scroll_pixel_based_preserve_x
,
4528 window_scroll_pixel_based_preserve_y
4529 - (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0 ),
4530 -1, MOVE_TO_Y
| MOVE_TO_X
);
4531 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4535 while (it
.current_y
< this_scroll_margin
)
4537 int prev
= it
.current_y
;
4538 move_it_by_lines (&it
, 1);
4539 if (prev
== it
.current_y
)
4542 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4547 ptrdiff_t charpos
, bytepos
;
4550 /* Save our position, for the
4551 window_scroll_pixel_based_preserve_y case. */
4552 charpos
= IT_CHARPOS (it
);
4553 bytepos
= IT_BYTEPOS (it
);
4555 /* We moved the window start towards BEGV, so PT may be now
4556 in the scroll margin at the bottom. */
4557 move_it_to (&it
, PT
, -1,
4558 (it
.last_visible_y
- CURRENT_HEADER_LINE_HEIGHT (w
)
4559 - this_scroll_margin
- 1),
4561 MOVE_TO_POS
| MOVE_TO_Y
);
4563 /* Save our position, in case it's correct. */
4564 charpos
= IT_CHARPOS (it
);
4565 bytepos
= IT_BYTEPOS (it
);
4567 /* See if point is on a partially visible line at the end. */
4568 if (it
.what
== IT_EOB
)
4569 partial_p
= it
.current_y
+ it
.ascent
+ it
.descent
> it
.last_visible_y
;
4572 move_it_by_lines (&it
, 1);
4573 partial_p
= it
.current_y
> it
.last_visible_y
;
4576 if (charpos
== PT
&& !partial_p
4577 && (NILP (Vscroll_preserve_screen_position
)
4578 || EQ (Vscroll_preserve_screen_position
, Qt
)))
4579 /* We found PT before we found the display margin, so PT is ok. */
4581 else if (window_scroll_pixel_based_preserve_y
>= 0)
4583 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4584 start_display (&it
, w
, start
);
4585 /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT
4586 here because we called start_display again and did not
4587 alter it.current_y this time. */
4588 move_it_to (&it
, -1, window_scroll_pixel_based_preserve_x
,
4589 window_scroll_pixel_based_preserve_y
, -1,
4590 MOVE_TO_Y
| MOVE_TO_X
);
4591 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4596 /* The last line was only partially visible, so back up two
4597 lines to make sure we're on a fully visible line. */
4599 move_it_by_lines (&it
, -2);
4600 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
4603 /* No, the position we saved is OK, so use it. */
4604 SET_PT_BOTH (charpos
, bytepos
);
4607 bidi_unshelve_cache (itdata
, 0);
4611 /* Implementation of window_scroll that works based on screen lines.
4612 See the comment of window_scroll for parameter descriptions. */
4615 window_scroll_line_based (Lisp_Object window
, int n
, int whole
, int noerror
)
4617 register struct window
*w
= XWINDOW (window
);
4618 /* Fvertical_motion enters redisplay, which can trigger
4619 fontification, which in turn can modify buffer text (e.g., if the
4620 fontification functions replace escape sequences with faces, as
4621 in `grep-mode-font-lock-keywords'). So we use a marker to record
4622 the old point position, to prevent crashes in SET_PT_BOTH. */
4623 Lisp_Object opoint_marker
= Fpoint_marker ();
4624 register ptrdiff_t pos
, pos_byte
;
4625 register int ht
= window_internal_height (w
);
4626 register Lisp_Object tem
;
4630 Lisp_Object original_pos
= Qnil
;
4632 /* If scrolling screen-fulls, compute the number of lines to
4633 scroll from the window's height. */
4635 n
*= max (1, ht
- next_screen_context_lines
);
4637 startpos
= marker_position (w
->start
);
4639 if (!NILP (Vscroll_preserve_screen_position
))
4641 if (window_scroll_preserve_vpos
<= 0
4642 || !SYMBOLP (KVAR (current_kboard
, Vlast_command
))
4643 || NILP (Fget (KVAR (current_kboard
, Vlast_command
), Qscroll_command
)))
4645 struct position posit
4646 = *compute_motion (startpos
, 0, 0, 0,
4650 window_scroll_preserve_vpos
= posit
.vpos
;
4651 window_scroll_preserve_hpos
= posit
.hpos
+ w
->hscroll
;
4654 original_pos
= Fcons (make_number (window_scroll_preserve_hpos
),
4655 make_number (window_scroll_preserve_vpos
));
4658 XSETFASTINT (tem
, PT
);
4659 tem
= Fpos_visible_in_window_p (tem
, window
, Qnil
);
4663 Fvertical_motion (make_number (- (ht
/ 2)), window
);
4668 lose
= n
< 0 && PT
== BEGV
;
4669 Fvertical_motion (make_number (n
), window
);
4673 SET_PT_BOTH (marker_position (opoint_marker
),
4674 marker_byte_position (opoint_marker
));
4681 xsignal0 (Qbeginning_of_buffer
);
4686 /* Don't use a scroll margin that is negative or too large. */
4687 int this_scroll_margin
=
4688 max (0, min (scroll_margin
, XINT (w
->total_lines
) / 4));
4690 set_marker_restricted_both (w
->start
, w
->buffer
, pos
, pos_byte
);
4691 w
->start_at_line_beg
= !NILP (bolp
);
4692 w
->update_mode_line
= 1;
4693 w
->last_modified
= 0;
4694 w
->last_overlay_modified
= 0;
4695 /* Set force_start so that redisplay_window will run
4696 the window-scroll-functions. */
4699 if (!NILP (Vscroll_preserve_screen_position
)
4700 && (whole
|| !EQ (Vscroll_preserve_screen_position
, Qt
)))
4702 SET_PT_BOTH (pos
, pos_byte
);
4703 Fvertical_motion (original_pos
, window
);
4705 /* If we scrolled forward, put point enough lines down
4706 that it is outside the scroll margin. */
4711 if (this_scroll_margin
> 0)
4713 SET_PT_BOTH (pos
, pos_byte
);
4714 Fvertical_motion (make_number (this_scroll_margin
), window
);
4720 if (top_margin
<= marker_position (opoint_marker
))
4721 SET_PT_BOTH (marker_position (opoint_marker
),
4722 marker_byte_position (opoint_marker
));
4723 else if (!NILP (Vscroll_preserve_screen_position
))
4725 SET_PT_BOTH (pos
, pos_byte
);
4726 Fvertical_motion (original_pos
, window
);
4729 SET_PT (top_margin
);
4735 /* If we scrolled backward, put point near the end of the window
4736 but not within the scroll margin. */
4737 SET_PT_BOTH (pos
, pos_byte
);
4738 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
4739 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
4742 bottom_margin
= PT
+ 1;
4744 if (bottom_margin
> marker_position (opoint_marker
))
4745 SET_PT_BOTH (marker_position (opoint_marker
),
4746 marker_byte_position (opoint_marker
));
4749 if (!NILP (Vscroll_preserve_screen_position
))
4751 SET_PT_BOTH (pos
, pos_byte
);
4752 Fvertical_motion (original_pos
, window
);
4755 Fvertical_motion (make_number (-1), window
);
4764 xsignal0 (Qend_of_buffer
);
4769 /* Scroll selected_window up or down. If N is nil, scroll a
4770 screen-full which is defined as the height of the window minus
4771 next_screen_context_lines. If N is the symbol `-', scroll.
4772 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
4773 up. This is the guts of Fscroll_up and Fscroll_down. */
4776 scroll_command (Lisp_Object n
, int direction
)
4778 ptrdiff_t count
= SPECPDL_INDEX ();
4780 eassert (eabs (direction
) == 1);
4782 /* If selected window's buffer isn't current, make it current for
4783 the moment. But don't screw up if window_scroll gets an error. */
4784 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
4786 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4787 Fset_buffer (XWINDOW (selected_window
)->buffer
);
4789 /* Make redisplay consider other windows than just selected_window. */
4790 ++windows_or_buffers_changed
;
4794 window_scroll (selected_window
, direction
, 1, 0);
4795 else if (EQ (n
, Qminus
))
4796 window_scroll (selected_window
, -direction
, 1, 0);
4799 n
= Fprefix_numeric_value (n
);
4800 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
4803 unbind_to (count
, Qnil
);
4806 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "^P",
4807 doc
: /* Scroll text of selected window upward ARG lines.
4808 If ARG is omitted or nil, scroll upward by a near full screen.
4809 A near full screen is `next-screen-context-lines' less than a full screen.
4810 Negative ARG means scroll downward.
4811 If ARG is the atom `-', scroll downward by nearly full screen.
4812 When calling from a program, supply as argument a number, nil, or `-'. */)
4815 scroll_command (arg
, 1);
4819 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "^P",
4820 doc
: /* Scroll text of selected window down ARG lines.
4821 If ARG is omitted or nil, scroll down by a near full screen.
4822 A near full screen is `next-screen-context-lines' less than a full screen.
4823 Negative ARG means scroll upward.
4824 If ARG is the atom `-', scroll upward by nearly full screen.
4825 When calling from a program, supply as argument a number, nil, or `-'. */)
4828 scroll_command (arg
, -1);
4832 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
4833 doc
: /* Return the other window for \"other window scroll\" commands.
4834 If `other-window-scroll-buffer' is non-nil, a window
4835 showing that buffer is used.
4836 If in the minibuffer, `minibuffer-scroll-window' if non-nil
4837 specifies the window. This takes precedence over
4838 `other-window-scroll-buffer'. */)
4843 if (MINI_WINDOW_P (XWINDOW (selected_window
))
4844 && !NILP (Vminibuf_scroll_window
))
4845 window
= Vminibuf_scroll_window
;
4846 /* If buffer is specified, scroll that buffer. */
4847 else if (!NILP (Vother_window_scroll_buffer
))
4849 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
4851 window
= display_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
4855 /* Nothing specified; look for a neighboring window on the same
4857 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
4859 if (EQ (window
, selected_window
))
4860 /* That didn't get us anywhere; look for a window on another
4863 window
= Fnext_window (window
, Qnil
, Qt
);
4864 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
4865 && ! EQ (window
, selected_window
));
4868 CHECK_LIVE_WINDOW (window
);
4870 if (EQ (window
, selected_window
))
4871 error ("There is no other window");
4876 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
4877 doc
: /* Scroll next window upward ARG lines; or near full screen if no ARG.
4878 A near full screen is `next-screen-context-lines' less than a full screen.
4879 The next window is the one below the current one; or the one at the top
4880 if the current one is at the bottom. Negative ARG means scroll downward.
4881 If ARG is the atom `-', scroll downward by nearly full screen.
4882 When calling from a program, supply as argument a number, nil, or `-'.
4884 If `other-window-scroll-buffer' is non-nil, scroll the window
4885 showing that buffer, popping the buffer up if necessary.
4886 If in the minibuffer, `minibuffer-scroll-window' if non-nil
4887 specifies the window to scroll. This takes precedence over
4888 `other-window-scroll-buffer'. */)
4893 ptrdiff_t count
= SPECPDL_INDEX ();
4895 window
= Fother_window_for_scrolling ();
4896 w
= XWINDOW (window
);
4898 /* Don't screw up if window_scroll gets an error. */
4899 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
4900 ++windows_or_buffers_changed
;
4902 Fset_buffer (w
->buffer
);
4903 SET_PT (marker_position (w
->pointm
));
4906 window_scroll (window
, 1, 1, 1);
4907 else if (EQ (arg
, Qminus
))
4908 window_scroll (window
, -1, 1, 1);
4914 window_scroll (window
, XINT (arg
), 0, 1);
4917 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
4918 unbind_to (count
, Qnil
);
4923 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 2, "^P\np",
4924 doc
: /* Scroll selected window display ARG columns left.
4925 Default for ARG is window width minus 2.
4926 Value is the total amount of leftward horizontal scrolling in
4927 effect after the change.
4928 If SET-MINIMUM is non-nil, the new scroll amount becomes the
4929 lower bound for automatic scrolling, i.e. automatic scrolling
4930 will not scroll a window to a column less than the value returned
4931 by this function. This happens in an interactive call. */)
4932 (register Lisp_Object arg
, Lisp_Object set_minimum
)
4934 struct window
*w
= XWINDOW (selected_window
);
4935 EMACS_INT requested_arg
= (NILP (arg
)
4936 ? window_body_cols (w
) - 2
4937 : XINT (Fprefix_numeric_value (arg
)));
4938 Lisp_Object result
= set_window_hscroll (w
, w
->hscroll
+ requested_arg
);
4940 if (!NILP (set_minimum
))
4941 w
->min_hscroll
= w
->hscroll
;
4946 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 2, "^P\np",
4947 doc
: /* Scroll selected window display ARG columns right.
4948 Default for ARG is window width minus 2.
4949 Value is the total amount of leftward horizontal scrolling in
4950 effect after the change.
4951 If SET-MINIMUM is non-nil, the new scroll amount becomes the
4952 lower bound for automatic scrolling, i.e. automatic scrolling
4953 will not scroll a window to a column less than the value returned
4954 by this function. This happens in an interactive call. */)
4955 (register Lisp_Object arg
, Lisp_Object set_minimum
)
4957 struct window
*w
= XWINDOW (selected_window
);
4958 EMACS_INT requested_arg
= (NILP (arg
)
4959 ? window_body_cols (w
) - 2
4960 : XINT (Fprefix_numeric_value (arg
)));
4961 Lisp_Object result
= set_window_hscroll (w
, w
->hscroll
- requested_arg
);
4963 if (!NILP (set_minimum
))
4964 w
->min_hscroll
= w
->hscroll
;
4969 DEFUN ("minibuffer-selected-window", Fminibuffer_selected_window
, Sminibuffer_selected_window
, 0, 0, 0,
4970 doc
: /* Return the window which was selected when entering the minibuffer.
4971 Returns nil, if selected window is not a minibuffer window. */)
4974 if (minibuf_level
> 0
4975 && MINI_WINDOW_P (XWINDOW (selected_window
))
4976 && WINDOW_LIVE_P (minibuf_selected_window
))
4977 return minibuf_selected_window
;
4982 /* Value is the number of lines actually displayed in window W,
4983 as opposed to its height. */
4986 displayed_window_lines (struct window
*w
)
4989 struct text_pos start
;
4990 int height
= window_box_height (w
);
4991 struct buffer
*old_buffer
;
4993 void *itdata
= NULL
;
4995 if (XBUFFER (w
->buffer
) != current_buffer
)
4997 old_buffer
= current_buffer
;
4998 set_buffer_internal (XBUFFER (w
->buffer
));
5003 /* In case W->start is out of the accessible range, do something
5004 reasonable. This happens in Info mode when Info-scroll-down
5005 calls (recenter -1) while W->start is 1. */
5006 if (XMARKER (w
->start
)->charpos
< BEGV
)
5007 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
5008 else if (XMARKER (w
->start
)->charpos
> ZV
)
5009 SET_TEXT_POS (start
, ZV
, ZV_BYTE
);
5011 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
5013 itdata
= bidi_shelve_cache ();
5014 start_display (&it
, w
, start
);
5015 move_it_vertically (&it
, height
);
5016 bottom_y
= line_bottom_y (&it
);
5017 bidi_unshelve_cache (itdata
, 0);
5019 /* rms: On a non-window display,
5020 the value of it.vpos at the bottom of the screen
5021 seems to be 1 larger than window_box_height (w).
5022 This kludge fixes a bug whereby (move-to-window-line -1)
5023 when ZV is on the last screen line
5024 moves to the previous screen line instead of the last one. */
5025 if (! FRAME_WINDOW_P (XFRAME (w
->frame
)))
5028 /* Add in empty lines at the bottom of the window. */
5029 if (bottom_y
< height
)
5031 int uy
= FRAME_LINE_HEIGHT (it
.f
);
5032 it
.vpos
+= (height
- bottom_y
+ uy
- 1) / uy
;
5036 set_buffer_internal (old_buffer
);
5042 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
5043 doc
: /* Center point in selected window and maybe redisplay frame.
5044 With prefix argument ARG, recenter putting point on screen line ARG
5045 relative to the selected window. If ARG is negative, it counts up from the
5046 bottom of the window. (ARG should be less than the height of the window.)
5048 If ARG is omitted or nil, then recenter with point on the middle line of
5049 the selected window; if the variable `recenter-redisplay' is non-nil,
5050 also erase the entire frame and redraw it (when `auto-resize-tool-bars'
5051 is set to `grow-only', this resets the tool-bar's height to the minimum
5052 height needed); if `recenter-redisplay' has the special value `tty',
5053 then only tty frames are redrawn.
5055 Just C-u as prefix means put point in the center of the window
5056 and redisplay normally--don't erase and redraw the frame. */)
5057 (register Lisp_Object arg
)
5059 struct window
*w
= XWINDOW (selected_window
);
5060 struct buffer
*buf
= XBUFFER (w
->buffer
);
5061 struct buffer
*obuf
= current_buffer
;
5063 ptrdiff_t charpos
, bytepos
;
5064 EMACS_INT iarg
IF_LINT (= 0);
5065 int this_scroll_margin
;
5067 /* If redisplay is suppressed due to an error, try again. */
5068 obuf
->display_error_modiff
= 0;
5072 if (!NILP (Vrecenter_redisplay
)
5073 && (!EQ (Vrecenter_redisplay
, Qtty
)
5074 || !NILP (Ftty_type (selected_frame
))))
5078 /* Invalidate pixel data calculated for all compositions. */
5079 for (i
= 0; i
< n_compositions
; i
++)
5080 composition_table
[i
]->font
= NULL
;
5082 WINDOW_XFRAME (w
)->minimize_tool_bar_window_p
= 1;
5084 Fredraw_frame (WINDOW_FRAME (w
));
5085 SET_FRAME_GARBAGED (WINDOW_XFRAME (w
));
5090 else if (CONSP (arg
)) /* Just C-u. */
5094 arg
= Fprefix_numeric_value (arg
);
5099 set_buffer_internal (buf
);
5101 /* Do this after making BUF current
5102 in case scroll_margin is buffer-local. */
5103 this_scroll_margin
=
5104 max (0, min (scroll_margin
, XFASTINT (w
->total_lines
) / 4));
5106 /* Handle centering on a graphical frame specially. Such frames can
5107 have variable-height lines and centering point on the basis of
5108 line counts would lead to strange effects. */
5109 if (FRAME_WINDOW_P (XFRAME (w
->frame
)))
5115 void *itdata
= bidi_shelve_cache ();
5117 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
5118 start_display (&it
, w
, pt
);
5119 move_it_vertically_backward (&it
, window_box_height (w
) / 2);
5120 charpos
= IT_CHARPOS (it
);
5121 bytepos
= IT_BYTEPOS (it
);
5122 bidi_unshelve_cache (itdata
, 0);
5128 ptrdiff_t nlines
= min (PTRDIFF_MAX
, -iarg
);
5129 int extra_line_spacing
;
5130 int h
= window_box_height (w
);
5131 void *itdata
= bidi_shelve_cache ();
5133 iarg
= - max (-iarg
, this_scroll_margin
);
5135 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
5136 start_display (&it
, w
, pt
);
5138 /* Be sure we have the exact height of the full line containing PT. */
5139 move_it_by_lines (&it
, 0);
5141 /* The amount of pixels we have to move back is the window
5142 height minus what's displayed in the line containing PT,
5143 and the lines below. */
5146 move_it_by_lines (&it
, nlines
);
5148 if (it
.vpos
== nlines
)
5152 /* Last line has no newline */
5153 h
-= line_bottom_y (&it
);
5157 /* Don't reserve space for extra line spacing of last line. */
5158 extra_line_spacing
= it
.max_extra_line_spacing
;
5160 /* If we can't move down NLINES lines because we hit
5161 the end of the buffer, count in some empty lines. */
5162 if (it
.vpos
< nlines
)
5165 extra_line_spacing
= it
.extra_line_spacing
;
5166 h
-= nlines
* (FRAME_LINE_HEIGHT (it
.f
) + extra_line_spacing
);
5170 bidi_unshelve_cache (itdata
, 0);
5174 /* Now find the new top line (starting position) of the window. */
5175 start_display (&it
, w
, pt
);
5177 move_it_vertically_backward (&it
, h
);
5179 /* If extra line spacing is present, we may move too far
5180 back. This causes the last line to be only partially
5181 visible (which triggers redisplay to recenter that line
5182 in the middle), so move forward.
5183 But ignore extra line spacing on last line, as it is not
5184 considered to be part of the visible height of the line.
5186 h
+= extra_line_spacing
;
5187 while (-it
.current_y
> h
)
5188 move_it_by_lines (&it
, 1);
5190 charpos
= IT_CHARPOS (it
);
5191 bytepos
= IT_BYTEPOS (it
);
5193 bidi_unshelve_cache (itdata
, 0);
5197 struct position pos
;
5199 iarg
= max (iarg
, this_scroll_margin
);
5201 pos
= *vmotion (PT
, -iarg
, w
);
5202 charpos
= pos
.bufpos
;
5203 bytepos
= pos
.bytepos
;
5208 struct position pos
;
5209 int ht
= window_internal_height (w
);
5216 /* Don't let it get into the margin at either top or bottom. */
5217 iarg
= max (iarg
, this_scroll_margin
);
5218 iarg
= min (iarg
, ht
- this_scroll_margin
- 1);
5220 pos
= *vmotion (PT
, - iarg
, w
);
5221 charpos
= pos
.bufpos
;
5222 bytepos
= pos
.bytepos
;
5225 /* Set the new window start. */
5226 set_marker_both (w
->start
, w
->buffer
, charpos
, bytepos
);
5227 WSET (w
, window_end_valid
, Qnil
);
5229 w
->optional_new_start
= 1;
5231 w
->start_at_line_beg
= (bytepos
== BEGV_BYTE
||
5232 FETCH_BYTE (bytepos
- 1) == '\n');
5234 set_buffer_internal (obuf
);
5238 DEFUN ("window-text-height", Fwindow_text_height
, Swindow_text_height
,
5240 doc
: /* Return the height in lines of the text display area of WINDOW.
5241 WINDOW must be a live window and defaults to the selected one.
5243 The returned height does not include the mode line, any header line,
5244 nor any partial-height lines at the bottom of the text area. */)
5245 (Lisp_Object window
)
5247 struct window
*w
= decode_live_window (window
);
5248 int pixel_height
= window_box_height (w
);
5249 int line_height
= pixel_height
/ FRAME_LINE_HEIGHT (XFRAME (w
->frame
));
5250 return make_number (line_height
);
5255 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
5257 doc
: /* Position point relative to window.
5258 ARG nil means position point at center of window.
5259 Else, ARG specifies vertical position within the window;
5260 zero means top of window, negative means relative to bottom of window. */)
5263 struct window
*w
= XWINDOW (selected_window
);
5267 int this_scroll_margin
;
5270 if (!(BUFFERP (w
->buffer
)
5271 && XBUFFER (w
->buffer
) == current_buffer
))
5272 /* This test is needed to make sure PT/PT_BYTE make sense in w->buffer
5273 when passed below to set_marker_both. */
5274 error ("move-to-window-line called from unrelated buffer");
5276 window
= selected_window
;
5277 start
= marker_position (w
->start
);
5278 if (start
< BEGV
|| start
> ZV
)
5280 int height
= window_internal_height (w
);
5281 Fvertical_motion (make_number (- (height
/ 2)), window
);
5282 set_marker_both (w
->start
, w
->buffer
, PT
, PT_BYTE
);
5283 w
->start_at_line_beg
= !NILP (Fbolp ());
5287 Fgoto_char (w
->start
);
5289 lines
= displayed_window_lines (w
);
5292 this_scroll_margin
= max (0, min (scroll_margin
, lines
/ 4));
5296 XSETFASTINT (arg
, lines
/ 2);
5299 EMACS_INT iarg
= XINT (Fprefix_numeric_value (arg
));
5302 iarg
= iarg
+ lines
;
5304 #if 0 /* This code would prevent move-to-window-line from moving point
5305 to a place inside the scroll margins (which would cause the
5306 next redisplay to scroll). I wrote this code, but then concluded
5307 it is probably better not to install it. However, it is here
5308 inside #if 0 so as not to lose it. -- rms. */
5310 /* Don't let it get into the margin at either top or bottom. */
5311 iarg
= max (iarg
, this_scroll_margin
);
5312 iarg
= min (iarg
, lines
- this_scroll_margin
- 1);
5315 arg
= make_number (iarg
);
5318 /* Skip past a partially visible first line. */
5320 XSETINT (arg
, XINT (arg
) + 1);
5322 return Fvertical_motion (arg
, window
);
5327 /***********************************************************************
5328 Window Configuration
5329 ***********************************************************************/
5331 struct save_window_data
5333 struct vectorlike_header header
;
5334 Lisp_Object selected_frame
;
5335 Lisp_Object current_window
;
5336 Lisp_Object current_buffer
;
5337 Lisp_Object minibuf_scroll_window
;
5338 Lisp_Object minibuf_selected_window
;
5339 Lisp_Object root_window
;
5340 Lisp_Object focus_frame
;
5341 /* A vector, each of whose elements is a struct saved_window
5343 Lisp_Object saved_windows
;
5345 /* All fields above are traced by the GC.
5346 From `fame-cols' down, the fields are ignored by the GC. */
5348 int frame_cols
, frame_lines
, frame_menu_bar_lines
;
5349 int frame_tool_bar_lines
;
5352 /* This is saved as a Lisp_Vector */
5355 struct vectorlike_header header
;
5357 Lisp_Object window
, buffer
, start
, pointm
, mark
;
5358 Lisp_Object left_col
, top_line
, total_cols
, total_lines
;
5359 Lisp_Object normal_cols
, normal_lines
;
5360 Lisp_Object hscroll
, min_hscroll
;
5361 Lisp_Object parent
, prev
;
5362 Lisp_Object start_at_line_beg
;
5363 Lisp_Object display_table
;
5364 Lisp_Object left_margin_cols
, right_margin_cols
;
5365 Lisp_Object left_fringe_width
, right_fringe_width
, fringes_outside_margins
;
5366 Lisp_Object scroll_bar_width
, vertical_scroll_bar_type
, dedicated
;
5367 Lisp_Object combination_limit
, window_parameters
;
5370 #define SAVED_WINDOW_N(swv,n) \
5371 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
5373 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
5374 doc
: /* Return t if OBJECT is a window-configuration object. */)
5375 (Lisp_Object object
)
5377 return WINDOW_CONFIGURATIONP (object
) ? Qt
: Qnil
;
5380 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
5381 doc
: /* Return the frame that CONFIG, a window-configuration object, is about. */)
5382 (Lisp_Object config
)
5384 register struct save_window_data
*data
;
5385 struct Lisp_Vector
*saved_windows
;
5387 CHECK_WINDOW_CONFIGURATION (config
);
5389 data
= (struct save_window_data
*) XVECTOR (config
);
5390 saved_windows
= XVECTOR (data
->saved_windows
);
5391 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
5394 DEFUN ("set-window-configuration", Fset_window_configuration
,
5395 Sset_window_configuration
, 1, 1, 0,
5396 doc
: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
5397 CONFIGURATION must be a value previously returned
5398 by `current-window-configuration' (which see).
5399 If CONFIGURATION was made from a frame that is now deleted,
5400 only frame-independent values can be restored. In this case,
5401 the return value is nil. Otherwise the value is t. */)
5402 (Lisp_Object configuration
)
5404 register struct save_window_data
*data
;
5405 struct Lisp_Vector
*saved_windows
;
5406 Lisp_Object new_current_buffer
;
5408 Lisp_Object auto_buffer_name
;
5410 ptrdiff_t old_point
= -1;
5412 CHECK_WINDOW_CONFIGURATION (configuration
);
5414 data
= (struct save_window_data
*) XVECTOR (configuration
);
5415 saved_windows
= XVECTOR (data
->saved_windows
);
5417 new_current_buffer
= data
->current_buffer
;
5418 if (NILP (BVAR (XBUFFER (new_current_buffer
), name
)))
5419 new_current_buffer
= Qnil
;
5422 if (XBUFFER (new_current_buffer
) == current_buffer
)
5423 /* The code further down "preserves point" by saving here PT in
5424 old_point and then setting it later back into PT. When the
5425 current-selected-window and the final-selected-window both show
5426 the current buffer, this suffers from the problem that the
5427 current PT is the window-point of the current-selected-window,
5428 while the final PT is the point of the final-selected-window, so
5429 this copy from one PT to the other would end up moving the
5430 window-point of the final-selected-window to the window-point of
5431 the current-selected-window. So we have to be careful which
5432 point of the current-buffer we copy into old_point. */
5433 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
)
5434 && WINDOWP (selected_window
)
5435 && EQ (XWINDOW (selected_window
)->buffer
, new_current_buffer
)
5436 && !EQ (selected_window
, data
->current_window
))
5437 old_point
= XMARKER (XWINDOW (data
->current_window
)->pointm
)->charpos
;
5441 /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of
5442 point in new_current_buffer as of the last time this buffer was
5443 used. This can be non-deterministic since it can be changed by
5444 things like jit-lock by mere temporary selection of some random
5445 window that happens to show this buffer.
5446 So if possible we want this arbitrary choice of "which point" to
5447 be the one from the to-be-selected-window so as to prevent this
5448 window's cursor from being copied from another window. */
5449 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
)
5450 /* If current_window = selected_window, its point is in BUF_PT. */
5451 && !EQ (selected_window
, data
->current_window
))
5452 old_point
= XMARKER (XWINDOW (data
->current_window
)->pointm
)->charpos
;
5454 old_point
= BUF_PT (XBUFFER (new_current_buffer
));
5457 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
5460 /* If f is a dead frame, don't bother rebuilding its window tree.
5461 However, there is other stuff we should still try to do below. */
5462 if (FRAME_LIVE_P (f
))
5465 Lisp_Object dead_windows
= Qnil
;
5466 register Lisp_Object tem
, par
, pers
;
5467 register struct window
*w
;
5468 register struct saved_window
*p
;
5469 struct window
*root_window
;
5470 struct window
**leaf_windows
;
5475 /* If the frame has been resized since this window configuration was
5476 made, we change the frame to the size specified in the
5477 configuration, restore the configuration, and then resize it
5478 back. We keep track of the prevailing height in these variables. */
5479 int previous_frame_lines
= FRAME_LINES (f
);
5480 int previous_frame_cols
= FRAME_COLS (f
);
5481 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
5482 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
5484 /* The mouse highlighting code could get screwed up
5485 if it runs during this. */
5488 if (data
->frame_lines
!= previous_frame_lines
5489 || data
->frame_cols
!= previous_frame_cols
)
5490 change_frame_size (f
, data
->frame_lines
,
5491 data
->frame_cols
, 0, 0, 0);
5492 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
5493 if (data
->frame_menu_bar_lines
5494 != previous_frame_menu_bar_lines
)
5495 x_set_menu_bar_lines (f
, make_number (data
->frame_menu_bar_lines
),
5497 #ifdef HAVE_WINDOW_SYSTEM
5498 if (data
->frame_tool_bar_lines
5499 != previous_frame_tool_bar_lines
)
5500 x_set_tool_bar_lines (f
, make_number (data
->frame_tool_bar_lines
),
5505 /* "Swap out" point from the selected window's buffer
5506 into the window itself. (Normally the pointm of the selected
5507 window holds garbage.) We do this now, before
5508 restoring the window contents, and prevent it from
5509 being done later on when we select a new window. */
5510 if (! NILP (XWINDOW (selected_window
)->buffer
))
5512 w
= XWINDOW (selected_window
);
5513 set_marker_both (w
->pointm
,
5515 BUF_PT (XBUFFER (w
->buffer
)),
5516 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5519 windows_or_buffers_changed
++;
5520 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
5522 /* Problem: Freeing all matrices and later allocating them again
5523 is a serious redisplay flickering problem. What we would
5524 really like to do is to free only those matrices not reused
5526 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
5527 leaf_windows
= alloca (count_windows (root_window
)
5528 * sizeof *leaf_windows
);
5529 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
5532 Mark all windows now on frame as "deleted".
5533 Restoring the new configuration "undeletes" any that are in it.
5535 Save their current buffers in their height fields, since we may
5536 need it later, if a buffer saved in the configuration is now
5538 delete_all_child_windows (FRAME_ROOT_WINDOW (f
));
5540 for (k
= 0; k
< saved_windows
->header
.size
; k
++)
5542 p
= SAVED_WINDOW_N (saved_windows
, k
);
5544 w
= XWINDOW (window
);
5545 WSET (w
, next
, Qnil
);
5547 if (!NILP (p
->parent
))
5548 WSET (w
, parent
, SAVED_WINDOW_N
5549 (saved_windows
, XFASTINT (p
->parent
))->window
);
5551 WSET (w
, parent
, Qnil
);
5553 if (!NILP (p
->prev
))
5555 WSET (w
, prev
, SAVED_WINDOW_N
5556 (saved_windows
, XFASTINT (p
->prev
))->window
);
5557 WSET (XWINDOW (w
->prev
), next
, p
->window
);
5561 WSET (w
, prev
, Qnil
);
5562 if (!NILP (w
->parent
))
5564 if (EQ (p
->total_cols
, XWINDOW (w
->parent
)->total_cols
))
5566 WSET (XWINDOW (w
->parent
), vchild
, p
->window
);
5567 WSET (XWINDOW (w
->parent
), hchild
, Qnil
);
5571 WSET (XWINDOW (w
->parent
), hchild
, p
->window
);
5572 WSET (XWINDOW (w
->parent
), vchild
, Qnil
);
5577 /* If we squirreled away the buffer in the window's height,
5579 if (BUFFERP (w
->total_lines
))
5580 WSET (w
, buffer
, w
->total_lines
);
5581 WSET (w
, left_col
, p
->left_col
);
5582 WSET (w
, top_line
, p
->top_line
);
5583 WSET (w
, total_cols
, p
->total_cols
);
5584 WSET (w
, total_lines
, p
->total_lines
);
5585 WSET (w
, normal_cols
, p
->normal_cols
);
5586 WSET (w
, normal_lines
, p
->normal_lines
);
5587 w
->hscroll
= XFASTINT (p
->hscroll
);
5588 w
->min_hscroll
= XFASTINT (p
->min_hscroll
);
5589 WSET (w
, display_table
, p
->display_table
);
5590 WSET (w
, left_margin_cols
, p
->left_margin_cols
);
5591 WSET (w
, right_margin_cols
, p
->right_margin_cols
);
5592 WSET (w
, left_fringe_width
, p
->left_fringe_width
);
5593 WSET (w
, right_fringe_width
, p
->right_fringe_width
);
5594 w
->fringes_outside_margins
= !NILP (p
->fringes_outside_margins
);
5595 WSET (w
, scroll_bar_width
, p
->scroll_bar_width
);
5596 WSET (w
, vertical_scroll_bar_type
, p
->vertical_scroll_bar_type
);
5597 WSET (w
, dedicated
, p
->dedicated
);
5598 WSET (w
, combination_limit
, p
->combination_limit
);
5599 /* Restore any window parameters that have been saved.
5600 Parameters that have not been saved are left alone. */
5601 for (tem
= p
->window_parameters
; CONSP (tem
); tem
= XCDR (tem
))
5606 if (NILP (XCDR (pers
)))
5608 par
= Fassq (XCAR (pers
), w
->window_parameters
);
5609 if (CONSP (par
) && !NILP (XCDR (par
)))
5610 /* Reset a parameter to nil if and only if it
5611 has a non-nil association. Don't make new
5613 Fsetcdr (par
, Qnil
);
5616 /* Always restore a non-nil value. */
5617 Fset_window_parameter (window
, XCAR (pers
), XCDR (pers
));
5621 w
->last_modified
= 0;
5622 w
->last_overlay_modified
= 0;
5624 /* Reinstall the saved buffer and pointers into it. */
5625 if (NILP (p
->buffer
))
5626 /* An internal window. */
5627 WSET (w
, buffer
, p
->buffer
);
5628 else if (!NILP (BVAR (XBUFFER (p
->buffer
), name
)))
5629 /* If saved buffer is alive, install it. */
5631 WSET (w
, buffer
, p
->buffer
);
5632 w
->start_at_line_beg
= !NILP (p
->start_at_line_beg
);
5633 set_marker_restricted (w
->start
, p
->start
, w
->buffer
);
5634 set_marker_restricted (w
->pointm
, p
->pointm
,
5636 Fset_marker (BVAR (XBUFFER (w
->buffer
), mark
),
5637 p
->mark
, w
->buffer
);
5639 /* As documented in Fcurrent_window_configuration, don't
5640 restore the location of point in the buffer which was
5641 current when the window configuration was recorded. */
5642 if (!EQ (p
->buffer
, new_current_buffer
)
5643 && XBUFFER (p
->buffer
) == current_buffer
)
5644 Fgoto_char (w
->pointm
);
5646 else if (!NILP (w
->buffer
)
5647 && !NILP (BVAR (XBUFFER (w
->buffer
), name
)))
5648 /* Keep window's old buffer; make sure the markers are
5651 /* Set window markers at start of visible range. */
5652 if (XMARKER (w
->start
)->buffer
== 0)
5653 set_marker_restricted (w
->start
, make_number (0),
5655 if (XMARKER (w
->pointm
)->buffer
== 0)
5656 set_marker_restricted_both
5657 (w
->pointm
, w
->buffer
,
5658 BUF_PT (XBUFFER (w
->buffer
)),
5659 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5660 w
->start_at_line_beg
= 1;
5662 else if (STRINGP (auto_buffer_name
=
5663 Fwindow_parameter (window
, Qauto_buffer_name
))
5664 && SCHARS (auto_buffer_name
) != 0
5665 && !NILP (WSET (w
, buffer
, Fget_buffer_create (auto_buffer_name
))))
5667 set_marker_restricted (w
->start
,
5668 make_number (0), w
->buffer
);
5669 set_marker_restricted (w
->pointm
,
5670 make_number (0), w
->buffer
);
5671 w
->start_at_line_beg
= 1;
5674 /* Window has no live buffer, get one. */
5676 /* Get the buffer via other_buffer_safely in order to
5677 avoid showing an unimportant buffer and, if necessary, to
5678 recreate *scratch* in the course (part of Juanma's bs-show
5679 scenario from March 2011). */
5680 WSET (w
, buffer
, other_buffer_safely (Fcurrent_buffer ()));
5681 /* This will set the markers to beginning of visible
5683 set_marker_restricted (w
->start
,
5684 make_number (0), w
->buffer
);
5685 set_marker_restricted (w
->pointm
,
5686 make_number (0), w
->buffer
);
5687 w
->start_at_line_beg
= 1;
5688 if (!NILP (w
->dedicated
))
5689 /* Record this window as dead. */
5690 dead_windows
= Fcons (window
, dead_windows
);
5691 /* Make sure window is no more dedicated. */
5692 WSET (w
, dedicated
, Qnil
);
5696 fset_root_window (f
, data
->root_window
);
5697 /* Arrange *not* to restore point in the buffer that was
5698 current when the window configuration was saved. */
5699 if (EQ (XWINDOW (data
->current_window
)->buffer
, new_current_buffer
))
5700 set_marker_restricted (XWINDOW (data
->current_window
)->pointm
,
5701 make_number (old_point
),
5702 XWINDOW (data
->current_window
)->buffer
);
5704 /* In the following call to `select-window', prevent "swapping out
5705 point" in the old selected window using the buffer that has
5706 been restored into it. We already swapped out that point from
5707 that window's old buffer. */
5708 select_window (data
->current_window
, Qnil
, 1);
5709 BVAR (XBUFFER (XWINDOW (selected_window
)->buffer
), last_selected_window
)
5712 if (NILP (data
->focus_frame
)
5713 || (FRAMEP (data
->focus_frame
)
5714 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
5715 Fredirect_frame_focus (frame
, data
->focus_frame
);
5717 /* Set the screen height to the value it had before this function. */
5718 if (previous_frame_lines
!= FRAME_LINES (f
)
5719 || previous_frame_cols
!= FRAME_COLS (f
))
5720 change_frame_size (f
, previous_frame_lines
, previous_frame_cols
,
5722 #if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
5723 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
5724 x_set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
5726 #ifdef HAVE_WINDOW_SYSTEM
5727 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
5728 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
5733 /* Now, free glyph matrices in windows that were not reused. */
5734 for (i
= n
= 0; i
< n_leaf_windows
; ++i
)
5736 if (NILP (leaf_windows
[i
]->buffer
))
5738 /* Assert it's not reused as a combination. */
5739 eassert (NILP (leaf_windows
[i
]->hchild
)
5740 && NILP (leaf_windows
[i
]->vchild
));
5741 free_window_matrices (leaf_windows
[i
]);
5743 else if (EQ (leaf_windows
[i
]->buffer
, new_current_buffer
))
5750 /* Scan dead buffer windows. */
5751 for (; CONSP (dead_windows
); dead_windows
= XCDR (dead_windows
))
5753 window
= XCAR (dead_windows
);
5754 if (WINDOW_LIVE_P (window
) && !EQ (window
, FRAME_ROOT_WINDOW (f
)))
5755 delete_deletable_window (window
);
5758 /* Fselect_window will have made f the selected frame, so we
5759 reselect the proper frame here. Fhandle_switch_frame will change the
5760 selected window too, but that doesn't make the call to
5761 Fselect_window above totally superfluous; it still sets f's
5763 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
5764 do_switch_frame (data
->selected_frame
, 0, 0, Qnil
);
5766 run_window_configuration_change_hook (f
);
5769 if (!NILP (new_current_buffer
))
5770 Fset_buffer (new_current_buffer
);
5772 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
5773 minibuf_selected_window
= data
->minibuf_selected_window
;
5775 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
5779 /* Recursively delete all child windows reachable via the next, vchild,
5780 and hchild slots of WINDOW. */
5782 delete_all_child_windows (Lisp_Object window
)
5784 register struct window
*w
;
5786 w
= XWINDOW (window
);
5788 if (!NILP (w
->next
))
5789 /* Delete WINDOW's siblings (we traverse postorderly). */
5790 delete_all_child_windows (w
->next
);
5792 WSET (w
, total_lines
, w
->buffer
); /* See Fset_window_configuration for excuse. */
5794 if (!NILP (w
->vchild
))
5796 delete_all_child_windows (w
->vchild
);
5797 WSET (w
, vchild
, Qnil
);
5799 else if (!NILP (w
->hchild
))
5801 delete_all_child_windows (w
->hchild
);
5802 WSET (w
, hchild
, Qnil
);
5804 else if (!NILP (w
->buffer
))
5807 unchain_marker (XMARKER (w
->pointm
));
5808 unchain_marker (XMARKER (w
->start
));
5809 WSET (w
, buffer
, Qnil
);
5812 Vwindow_list
= Qnil
;
5816 count_windows (register struct window
*window
)
5818 register int count
= 1;
5819 if (!NILP (window
->next
))
5820 count
+= count_windows (XWINDOW (window
->next
));
5821 if (!NILP (window
->vchild
))
5822 count
+= count_windows (XWINDOW (window
->vchild
));
5823 if (!NILP (window
->hchild
))
5824 count
+= count_windows (XWINDOW (window
->hchild
));
5829 /* Fill vector FLAT with leaf windows under W, starting at index I.
5830 Value is last index + 1. */
5832 get_leaf_windows (struct window
*w
, struct window
**flat
, int i
)
5836 if (!NILP (w
->hchild
))
5837 i
= get_leaf_windows (XWINDOW (w
->hchild
), flat
, i
);
5838 else if (!NILP (w
->vchild
))
5839 i
= get_leaf_windows (XWINDOW (w
->vchild
), flat
, i
);
5843 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
5850 /* Return a pointer to the glyph W's physical cursor is on. Value is
5851 null if W's current matrix is invalid, so that no meaningful glyph
5854 get_phys_cursor_glyph (struct window
*w
)
5856 struct glyph_row
*row
;
5857 struct glyph
*glyph
;
5858 int hpos
= w
->phys_cursor
.hpos
;
5860 if (!(w
->phys_cursor
.vpos
>= 0
5861 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
))
5864 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
5865 if (!row
->enabled_p
)
5870 /* When the window is hscrolled, cursor hpos can legitimately be
5871 out of bounds, but we draw the cursor at the corresponding
5872 window margin in that case. */
5873 if (!row
->reversed_p
&& hpos
< 0)
5875 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
5876 hpos
= row
->used
[TEXT_AREA
] - 1;
5879 if (row
->used
[TEXT_AREA
] > hpos
5881 glyph
= row
->glyphs
[TEXT_AREA
] + hpos
;
5890 save_window_save (Lisp_Object window
, struct Lisp_Vector
*vector
, int i
)
5892 register struct saved_window
*p
;
5893 register struct window
*w
;
5894 register Lisp_Object tem
, pers
, par
;
5896 for (;!NILP (window
); window
= w
->next
)
5898 p
= SAVED_WINDOW_N (vector
, i
);
5899 w
= XWINDOW (window
);
5901 WSET (w
, temslot
, make_number (i
)); i
++;
5903 p
->buffer
= w
->buffer
;
5904 p
->left_col
= w
->left_col
;
5905 p
->top_line
= w
->top_line
;
5906 p
->total_cols
= w
->total_cols
;
5907 p
->total_lines
= w
->total_lines
;
5908 p
->normal_cols
= w
->normal_cols
;
5909 p
->normal_lines
= w
->normal_lines
;
5910 XSETFASTINT (p
->hscroll
, w
->hscroll
);
5911 XSETFASTINT (p
->min_hscroll
, w
->min_hscroll
);
5912 p
->display_table
= w
->display_table
;
5913 p
->left_margin_cols
= w
->left_margin_cols
;
5914 p
->right_margin_cols
= w
->right_margin_cols
;
5915 p
->left_fringe_width
= w
->left_fringe_width
;
5916 p
->right_fringe_width
= w
->right_fringe_width
;
5917 p
->fringes_outside_margins
= w
->fringes_outside_margins
? Qt
: Qnil
;
5918 p
->scroll_bar_width
= w
->scroll_bar_width
;
5919 p
->vertical_scroll_bar_type
= w
->vertical_scroll_bar_type
;
5920 p
->dedicated
= w
->dedicated
;
5921 p
->combination_limit
= w
->combination_limit
;
5922 p
->window_parameters
= Qnil
;
5924 if (!NILP (Vwindow_persistent_parameters
))
5926 /* Run cycle detection on Vwindow_persistent_parameters. */
5927 Lisp_Object tortoise
, hare
;
5929 hare
= tortoise
= Vwindow_persistent_parameters
;
5930 while (CONSP (hare
))
5937 tortoise
= XCDR (tortoise
);
5939 if (EQ (hare
, tortoise
))
5940 /* Reset Vwindow_persistent_parameters to Qnil. */
5942 Vwindow_persistent_parameters
= Qnil
;
5947 for (tem
= Vwindow_persistent_parameters
; CONSP (tem
);
5951 /* Save values for persistent window parameters. */
5952 if (CONSP (pers
) && !NILP (XCDR (pers
)))
5954 par
= Fassq (XCAR (pers
), w
->window_parameters
);
5956 /* If the window has no value for the parameter,
5958 p
->window_parameters
= Fcons (Fcons (XCAR (pers
), Qnil
),
5959 p
->window_parameters
);
5961 /* If the window has a value for the parameter,
5963 p
->window_parameters
= Fcons (Fcons (XCAR (par
),
5965 p
->window_parameters
);
5970 if (!NILP (w
->buffer
))
5972 /* Save w's value of point in the window configuration. If w
5973 is the selected window, then get the value of point from
5974 the buffer; pointm is garbage in the selected window. */
5975 if (EQ (window
, selected_window
))
5976 p
->pointm
= build_marker (XBUFFER (w
->buffer
),
5977 BUF_PT (XBUFFER (w
->buffer
)),
5978 BUF_PT_BYTE (XBUFFER (w
->buffer
)));
5980 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
5981 XMARKER (p
->pointm
)->insertion_type
5982 = !NILP (Vwindow_point_insertion_type
);
5984 p
->start
= Fcopy_marker (w
->start
, Qnil
);
5985 p
->start_at_line_beg
= w
->start_at_line_beg
? Qt
: Qnil
;
5987 tem
= BVAR (XBUFFER (w
->buffer
), mark
);
5988 p
->mark
= Fcopy_marker (tem
, Qnil
);
5995 p
->start_at_line_beg
= Qnil
;
5998 if (NILP (w
->parent
))
6001 p
->parent
= XWINDOW (w
->parent
)->temslot
;
6006 p
->prev
= XWINDOW (w
->prev
)->temslot
;
6008 if (!NILP (w
->vchild
))
6009 i
= save_window_save (w
->vchild
, vector
, i
);
6010 if (!NILP (w
->hchild
))
6011 i
= save_window_save (w
->hchild
, vector
, i
);
6017 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
6018 Scurrent_window_configuration
, 0, 1, 0,
6019 doc
: /* Return an object representing the current window configuration of FRAME.
6020 If FRAME is nil or omitted, use the selected frame.
6021 This describes the number of windows, their sizes and current buffers,
6022 and for each displayed buffer, where display starts, and the positions of
6023 point and mark. An exception is made for point in the current buffer:
6024 its value is -not- saved.
6025 This also records the currently selected frame, and FRAME's focus
6026 redirection (see `redirect-frame-focus'). The variable
6027 `window-persistent-parameters' specifies which window parameters are
6028 saved by this function. */)
6031 register Lisp_Object tem
;
6032 register int n_windows
;
6033 register struct save_window_data
*data
;
6038 frame
= selected_frame
;
6039 CHECK_LIVE_FRAME (frame
);
6042 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
6043 data
= ALLOCATE_PSEUDOVECTOR (struct save_window_data
, frame_cols
,
6044 PVEC_WINDOW_CONFIGURATION
);
6046 data
->frame_cols
= FRAME_COLS (f
);
6047 data
->frame_lines
= FRAME_LINES (f
);
6048 data
->frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
6049 data
->frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
6050 data
->selected_frame
= selected_frame
;
6051 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
6052 XSETBUFFER (data
->current_buffer
, current_buffer
);
6053 data
->minibuf_scroll_window
= minibuf_level
> 0 ? Vminibuf_scroll_window
: Qnil
;
6054 data
->minibuf_selected_window
= minibuf_level
> 0 ? minibuf_selected_window
: Qnil
;
6055 data
->root_window
= FRAME_ROOT_WINDOW (f
);
6056 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
6057 tem
= Fmake_vector (make_number (n_windows
), Qnil
);
6058 data
->saved_windows
= tem
;
6059 for (i
= 0; i
< n_windows
; i
++)
6061 Fmake_vector (make_number (VECSIZE (struct saved_window
)), Qnil
));
6062 save_window_save (FRAME_ROOT_WINDOW (f
), XVECTOR (tem
), 0);
6063 XSETWINDOW_CONFIGURATION (tem
, data
);
6067 /***********************************************************************
6069 ***********************************************************************/
6071 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
6073 doc
: /* Set width of marginal areas of window WINDOW.
6074 WINDOW must be a live window and defaults to the selected one.
6076 Second arg LEFT-WIDTH specifies the number of character cells to
6077 reserve for the left marginal area. Optional third arg RIGHT-WIDTH
6078 does the same for the right marginal area. A nil width parameter
6079 means no margin. */)
6080 (Lisp_Object window
, Lisp_Object left_width
, Lisp_Object right_width
)
6082 struct window
*w
= decode_live_window (window
);
6084 /* Translate negative or zero widths to nil.
6085 Margins that are too wide have to be checked elsewhere. */
6087 if (!NILP (left_width
))
6089 CHECK_NUMBER (left_width
);
6090 if (XINT (left_width
) <= 0)
6094 if (!NILP (right_width
))
6096 CHECK_NUMBER (right_width
);
6097 if (XINT (right_width
) <= 0)
6101 if (!EQ (w
->left_margin_cols
, left_width
)
6102 || !EQ (w
->right_margin_cols
, right_width
))
6104 WSET (w
, left_margin_cols
, left_width
);
6105 WSET (w
, right_margin_cols
, right_width
);
6107 adjust_window_margins (w
);
6109 ++windows_or_buffers_changed
;
6110 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
6117 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
6119 doc
: /* Get width of marginal areas of window WINDOW.
6120 WINDOW must be a live window and defaults to the selected one.
6122 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).
6123 If a marginal area does not exist, its width will be returned
6125 (Lisp_Object window
)
6127 struct window
*w
= decode_live_window (window
);
6128 return Fcons (w
->left_margin_cols
, w
->right_margin_cols
);
6133 /***********************************************************************
6135 ***********************************************************************/
6137 DEFUN ("set-window-fringes", Fset_window_fringes
, Sset_window_fringes
,
6139 doc
: /* Set the fringe widths of window WINDOW.
6140 WINDOW must be a live window and defaults to the selected one.
6142 Second arg LEFT-WIDTH specifies the number of pixels to reserve for
6143 the left fringe. Optional third arg RIGHT-WIDTH specifies the right
6144 fringe width. If a fringe width arg is nil, that means to use the
6145 frame's default fringe width. Default fringe widths can be set with
6146 the command `set-fringe-style'.
6147 If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes
6148 outside of the display margins. By default, fringes are drawn between
6149 display marginal areas and the text area. */)
6150 (Lisp_Object window
, Lisp_Object left_width
, Lisp_Object right_width
, Lisp_Object outside_margins
)
6152 struct window
*w
= decode_live_window (window
);
6153 int outside
= !NILP (outside_margins
);
6155 if (!NILP (left_width
))
6156 CHECK_NATNUM (left_width
);
6157 if (!NILP (right_width
))
6158 CHECK_NATNUM (right_width
);
6160 /* Do nothing on a tty. */
6161 if (FRAME_WINDOW_P (WINDOW_XFRAME (w
))
6162 && (!EQ (w
->left_fringe_width
, left_width
)
6163 || !EQ (w
->right_fringe_width
, right_width
)
6164 || w
->fringes_outside_margins
!= outside
))
6166 WSET (w
, left_fringe_width
, left_width
);
6167 WSET (w
, right_fringe_width
, right_width
);
6168 w
->fringes_outside_margins
= outside
;
6170 adjust_window_margins (w
);
6172 clear_glyph_matrix (w
->current_matrix
);
6173 WSET (w
, window_end_valid
, Qnil
);
6175 ++windows_or_buffers_changed
;
6176 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
6183 DEFUN ("window-fringes", Fwindow_fringes
, Swindow_fringes
,
6185 doc
: /* Get width of fringes of window WINDOW.
6186 WINDOW must be a live window and defaults to the selected one.
6188 Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
6189 (Lisp_Object window
)
6191 struct window
*w
= decode_live_window (window
);
6193 return Fcons (make_number (WINDOW_LEFT_FRINGE_WIDTH (w
)),
6194 Fcons (make_number (WINDOW_RIGHT_FRINGE_WIDTH (w
)),
6195 Fcons ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
6196 ? Qt
: Qnil
), Qnil
)));
6201 /***********************************************************************
6203 ***********************************************************************/
6205 DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars
,
6206 Sset_window_scroll_bars
, 2, 4, 0,
6207 doc
: /* Set width and type of scroll bars of window WINDOW.
6208 WINDOW must be a live window and defaults to the selected one.
6210 Second parameter WIDTH specifies the pixel width for the scroll bar;
6211 this is automatically adjusted to a multiple of the frame column width.
6212 Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
6213 bar: left, right, or nil.
6214 If WIDTH is nil, use the frame's scroll-bar width.
6215 If VERTICAL-TYPE is t, use the frame's scroll-bar type.
6216 Fourth parameter HORIZONTAL-TYPE is currently unused. */)
6217 (Lisp_Object window
, Lisp_Object width
, Lisp_Object vertical_type
, Lisp_Object horizontal_type
)
6219 struct window
*w
= decode_live_window (window
);
6223 CHECK_RANGED_INTEGER (width
, 0, INT_MAX
);
6225 if (XINT (width
) == 0)
6226 vertical_type
= Qnil
;
6229 if (!(NILP (vertical_type
)
6230 || EQ (vertical_type
, Qleft
)
6231 || EQ (vertical_type
, Qright
)
6232 || EQ (vertical_type
, Qt
)))
6233 error ("Invalid type of vertical scroll bar");
6235 if (!EQ (w
->scroll_bar_width
, width
)
6236 || !EQ (w
->vertical_scroll_bar_type
, vertical_type
))
6238 WSET (w
, scroll_bar_width
, width
);
6239 WSET (w
, vertical_scroll_bar_type
, vertical_type
);
6241 adjust_window_margins (w
);
6243 clear_glyph_matrix (w
->current_matrix
);
6244 WSET (w
, window_end_valid
, Qnil
);
6246 ++windows_or_buffers_changed
;
6247 adjust_glyphs (XFRAME (WINDOW_FRAME (w
)));
6254 DEFUN ("window-scroll-bars", Fwindow_scroll_bars
, Swindow_scroll_bars
,
6256 doc
: /* Get width and type of scroll bars of window WINDOW.
6257 WINDOW must be a live window and defaults to the selected one.
6259 Value is a list of the form (WIDTH COLS VERTICAL-TYPE HORIZONTAL-TYPE).
6260 If WIDTH is nil or TYPE is t, the window is using the frame's corresponding
6262 (Lisp_Object window
)
6264 struct window
*w
= decode_live_window (window
);
6265 return Fcons (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
)
6266 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
)
6267 : WINDOW_SCROLL_BAR_AREA_WIDTH (w
))),
6268 Fcons (make_number (WINDOW_SCROLL_BAR_COLS (w
)),
6269 Fcons (w
->vertical_scroll_bar_type
,
6270 Fcons (Qnil
, Qnil
))));
6275 /***********************************************************************
6277 ***********************************************************************/
6279 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 2, 0,
6280 doc
: /* Return the amount by which WINDOW is scrolled vertically.
6281 If WINDOW is omitted or nil, it defaults to the selected window.
6282 Normally, value is a multiple of the canonical character height of WINDOW;
6283 optional second arg PIXELS-P means value is measured in pixels. */)
6284 (Lisp_Object window
, Lisp_Object pixels_p
)
6291 window
= selected_window
;
6293 CHECK_WINDOW (window
);
6294 w
= XWINDOW (window
);
6295 f
= XFRAME (w
->frame
);
6297 if (FRAME_WINDOW_P (f
))
6298 result
= (NILP (pixels_p
)
6299 ? FRAME_CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
)
6300 : make_number (-w
->vscroll
));
6302 result
= make_number (0);
6307 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
6309 doc
: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL.
6310 WINDOW nil means use the selected window. Normally, VSCROLL is a
6311 non-negative multiple of the canonical character height of WINDOW;
6312 optional third arg PIXELS-P non-nil means that VSCROLL is in pixels.
6313 If PIXELS-P is nil, VSCROLL may have to be rounded so that it
6314 corresponds to an integral number of pixels. The return value is the
6315 result of this rounding.
6316 If PIXELS-P is non-nil, the return value is VSCROLL. */)
6317 (Lisp_Object window
, Lisp_Object vscroll
, Lisp_Object pixels_p
)
6323 window
= selected_window
;
6325 CHECK_WINDOW (window
);
6326 CHECK_NUMBER_OR_FLOAT (vscroll
);
6328 w
= XWINDOW (window
);
6329 f
= XFRAME (w
->frame
);
6331 if (FRAME_WINDOW_P (f
))
6333 int old_dy
= w
->vscroll
;
6335 w
->vscroll
= - (NILP (pixels_p
)
6336 ? FRAME_LINE_HEIGHT (f
) * XFLOATINT (vscroll
)
6337 : XFLOATINT (vscroll
));
6338 w
->vscroll
= min (w
->vscroll
, 0);
6340 if (w
->vscroll
!= old_dy
)
6342 /* Adjust glyph matrix of the frame if the virtual display
6343 area becomes larger than before. */
6344 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
6347 /* Prevent redisplay shortcuts. */
6348 XBUFFER (w
->buffer
)->prevent_redisplay_optimizations_p
= 1;
6352 return Fwindow_vscroll (window
, pixels_p
);
6356 /* Call FN for all leaf windows on frame F. FN is called with the
6357 first argument being a pointer to the leaf window, and with
6358 additional argument USER_DATA. Stops when FN returns 0. */
6361 foreach_window (struct frame
*f
, int (*fn
) (struct window
*, void *),
6364 /* delete_frame may set FRAME_ROOT_WINDOW (f) to Qnil. */
6365 if (WINDOWP (FRAME_ROOT_WINDOW (f
)))
6366 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, user_data
);
6370 /* Helper function for foreach_window. Call FN for all leaf windows
6371 reachable from W. FN is called with the first argument being a
6372 pointer to the leaf window, and with additional argument USER_DATA.
6373 Stop when FN returns 0. Value is 0 if stopped by FN. */
6376 foreach_window_1 (struct window
*w
, int (*fn
) (struct window
*, void *), void *user_data
)
6380 for (cont
= 1; w
&& cont
;)
6382 if (!NILP (w
->hchild
))
6383 cont
= foreach_window_1 (XWINDOW (w
->hchild
), fn
, user_data
);
6384 else if (!NILP (w
->vchild
))
6385 cont
= foreach_window_1 (XWINDOW (w
->vchild
), fn
, user_data
);
6387 cont
= fn (w
, user_data
);
6389 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
6396 /* Freeze or unfreeze the window start of W unless it is a
6397 mini-window or the selected window. FREEZE_P non-null means freeze
6398 the window start. */
6401 freeze_window_start (struct window
*w
, void *freeze_p
)
6403 if (MINI_WINDOW_P (w
)
6404 || (WINDOWP (selected_window
) /* Can be nil in corner cases. */
6405 && (w
== XWINDOW (selected_window
)
6406 || (MINI_WINDOW_P (XWINDOW (selected_window
))
6407 && ! NILP (Vminibuf_scroll_window
)
6408 && w
== XWINDOW (Vminibuf_scroll_window
)))))
6411 w
->frozen_window_start_p
= freeze_p
!= NULL
;
6416 /* Freeze or unfreeze the window starts of all leaf windows on frame
6417 F, except the selected window and a mini-window. FREEZE_P non-zero
6418 means freeze the window start. */
6421 freeze_window_starts (struct frame
*f
, int freeze_p
)
6423 foreach_window (f
, freeze_window_start
, (void *) (freeze_p
? f
: 0));
6427 /***********************************************************************
6429 ***********************************************************************/
6431 /* Return 1 if window configurations CONFIGURATION1 and CONFIGURATION2
6432 describe the same state of affairs. This is used by Fequal.
6434 ignore_positions non-zero means ignore non-matching scroll positions
6437 This ignores a couple of things like the dedication status of
6438 window, combination_limit and the like. This might have to be
6442 compare_window_configurations (Lisp_Object configuration1
, Lisp_Object configuration2
, int ignore_positions
)
6444 register struct save_window_data
*d1
, *d2
;
6445 struct Lisp_Vector
*sws1
, *sws2
;
6448 CHECK_WINDOW_CONFIGURATION (configuration1
);
6449 CHECK_WINDOW_CONFIGURATION (configuration2
);
6451 d1
= (struct save_window_data
*) XVECTOR (configuration1
);
6452 d2
= (struct save_window_data
*) XVECTOR (configuration2
);
6453 sws1
= XVECTOR (d1
->saved_windows
);
6454 sws2
= XVECTOR (d2
->saved_windows
);
6456 /* Frame settings must match. */
6457 if (d1
->frame_cols
!= d2
->frame_cols
6458 || d1
->frame_lines
!= d2
->frame_lines
6459 || d1
->frame_menu_bar_lines
!= d2
->frame_menu_bar_lines
6460 || !EQ (d1
->selected_frame
, d2
->selected_frame
)
6461 || !EQ (d1
->current_buffer
, d2
->current_buffer
)
6462 || (!ignore_positions
6463 && (!EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
)
6464 || !EQ (d1
->minibuf_selected_window
, d2
->minibuf_selected_window
)))
6465 || !EQ (d1
->focus_frame
, d2
->focus_frame
)
6466 /* Verify that the two configurations have the same number of windows. */
6467 || sws1
->header
.size
!= sws2
->header
.size
)
6470 for (i
= 0; i
< sws1
->header
.size
; i
++)
6472 struct saved_window
*sw1
, *sw2
;
6474 sw1
= SAVED_WINDOW_N (sws1
, i
);
6475 sw2
= SAVED_WINDOW_N (sws2
, i
);
6478 /* The "current" windows in the two configurations must
6479 correspond to each other. */
6480 EQ (d1
->current_window
, sw1
->window
)
6481 != EQ (d2
->current_window
, sw2
->window
)
6482 /* Windows' buffers must match. */
6483 || !EQ (sw1
->buffer
, sw2
->buffer
)
6484 || !EQ (sw1
->left_col
, sw2
->left_col
)
6485 || !EQ (sw1
->top_line
, sw2
->top_line
)
6486 || !EQ (sw1
->total_cols
, sw2
->total_cols
)
6487 || !EQ (sw1
->total_lines
, sw2
->total_lines
)
6488 || !EQ (sw1
->display_table
, sw2
->display_table
)
6489 /* The next two disjuncts check the window structure for
6491 || !EQ (sw1
->parent
, sw2
->parent
)
6492 || !EQ (sw1
->prev
, sw2
->prev
)
6493 || (!ignore_positions
6494 && (!EQ (sw1
->hscroll
, sw2
->hscroll
)
6495 || !EQ (sw1
->min_hscroll
, sw2
->min_hscroll
)
6496 || !EQ (sw1
->start_at_line_beg
, sw2
->start_at_line_beg
)
6497 || NILP (Fequal (sw1
->start
, sw2
->start
))
6498 || NILP (Fequal (sw1
->pointm
, sw2
->pointm
))
6499 || NILP (Fequal (sw1
->mark
, sw2
->mark
))))
6500 || !EQ (sw1
->left_margin_cols
, sw2
->left_margin_cols
)
6501 || !EQ (sw1
->right_margin_cols
, sw2
->right_margin_cols
)
6502 || !EQ (sw1
->left_fringe_width
, sw2
->left_fringe_width
)
6503 || !EQ (sw1
->right_fringe_width
, sw2
->right_fringe_width
)
6504 || !EQ (sw1
->fringes_outside_margins
, sw2
->fringes_outside_margins
)
6505 || !EQ (sw1
->scroll_bar_width
, sw2
->scroll_bar_width
)
6506 || !EQ (sw1
->vertical_scroll_bar_type
, sw2
->vertical_scroll_bar_type
))
6513 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
6514 Scompare_window_configurations
, 2, 2, 0,
6515 doc
: /* Compare two window configurations as regards the structure of windows.
6516 This function ignores details such as the values of point and mark
6517 and scrolling positions. */)
6518 (Lisp_Object x
, Lisp_Object y
)
6520 if (compare_window_configurations (x
, y
, 1))
6526 init_window_once (void)
6528 struct frame
*f
= make_initial_frame ();
6529 XSETFRAME (selected_frame
, f
);
6530 Vterminal_frame
= selected_frame
;
6531 minibuf_window
= f
->minibuffer_window
;
6532 selected_window
= f
->selected_window
;
6533 last_nonminibuf_frame
= f
;
6535 window_initialized
= 1;
6541 Vwindow_list
= Qnil
;
6545 syms_of_window (void)
6547 DEFSYM (Qscroll_up
, "scroll-up");
6548 DEFSYM (Qscroll_down
, "scroll-down");
6549 DEFSYM (Qscroll_command
, "scroll-command");
6551 Fput (Qscroll_up
, Qscroll_command
, Qt
);
6552 Fput (Qscroll_down
, Qscroll_command
, Qt
);
6554 DEFSYM (Qwindow_configuration_change_hook
, "window-configuration-change-hook");
6555 DEFSYM (Qwindowp
, "windowp");
6556 DEFSYM (Qwindow_configuration_p
, "window-configuration-p");
6557 DEFSYM (Qwindow_live_p
, "window-live-p");
6558 DEFSYM (Qwindow_valid_p
, "window-valid-p");
6559 DEFSYM (Qwindow_deletable_p
, "window-deletable-p");
6560 DEFSYM (Qdelete_window
, "delete-window");
6561 DEFSYM (Qwindow_resize_root_window
, "window--resize-root-window");
6562 DEFSYM (Qwindow_resize_root_window_vertically
, "window--resize-root-window-vertically");
6563 DEFSYM (Qsafe
, "safe");
6564 DEFSYM (Qdisplay_buffer
, "display-buffer");
6565 DEFSYM (Qreplace_buffer_in_windows
, "replace-buffer-in-windows");
6566 DEFSYM (Qrecord_window_buffer
, "record-window-buffer");
6567 DEFSYM (Qget_mru_window
, "get-mru-window");
6568 DEFSYM (Qtemp_buffer_show_hook
, "temp-buffer-show-hook");
6569 DEFSYM (Qabove
, "above");
6570 DEFSYM (Qbelow
, "below");
6571 DEFSYM (Qauto_buffer_name
, "auto-buffer-name");
6572 DEFSYM (Qclone_of
, "clone-of");
6574 staticpro (&Vwindow_list
);
6576 minibuf_selected_window
= Qnil
;
6577 staticpro (&minibuf_selected_window
);
6579 window_scroll_pixel_based_preserve_x
= -1;
6580 window_scroll_pixel_based_preserve_y
= -1;
6581 window_scroll_preserve_hpos
= -1;
6582 window_scroll_preserve_vpos
= -1;
6584 DEFVAR_LISP ("temp-buffer-show-function", Vtemp_buffer_show_function
,
6585 doc
: /* Non-nil means call as function to display a help buffer.
6586 The function is called with one argument, the buffer to be displayed.
6587 Used by `with-output-to-temp-buffer'.
6588 If this function is used, then it must do the entire job of showing
6589 the buffer; `temp-buffer-show-hook' is not run unless this function runs it. */);
6590 Vtemp_buffer_show_function
= Qnil
;
6592 DEFVAR_LISP ("minibuffer-scroll-window", Vminibuf_scroll_window
,
6593 doc
: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */);
6594 Vminibuf_scroll_window
= Qnil
;
6596 DEFVAR_BOOL ("mode-line-in-non-selected-windows", mode_line_in_non_selected_windows
,
6597 doc
: /* Non-nil means to use `mode-line-inactive' face in non-selected windows.
6598 If the minibuffer is active, the `minibuffer-scroll-window' mode line
6599 is displayed in the `mode-line' face. */);
6600 mode_line_in_non_selected_windows
= 1;
6602 DEFVAR_LISP ("other-window-scroll-buffer", Vother_window_scroll_buffer
,
6603 doc
: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. */);
6604 Vother_window_scroll_buffer
= Qnil
;
6606 DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p
,
6607 doc
: /* Non-nil means to automatically adjust `window-vscroll' to view tall lines. */);
6608 auto_window_vscroll_p
= 1;
6610 DEFVAR_INT ("next-screen-context-lines", next_screen_context_lines
,
6611 doc
: /* Number of lines of continuity when scrolling by screenfuls. */);
6612 next_screen_context_lines
= 2;
6614 DEFVAR_LISP ("scroll-preserve-screen-position",
6615 Vscroll_preserve_screen_position
,
6616 doc
: /* Controls if scroll commands move point to keep its screen position unchanged.
6617 A value of nil means point does not keep its screen position except
6618 at the scroll margin or window boundary respectively.
6619 A value of t means point keeps its screen position if the scroll
6620 command moved it vertically out of the window, e.g. when scrolling
6622 Any other value means point always keeps its screen position.
6623 Scroll commands should have the `scroll-command' property
6624 on their symbols to be controlled by this variable. */);
6625 Vscroll_preserve_screen_position
= Qnil
;
6627 DEFVAR_LISP ("window-point-insertion-type", Vwindow_point_insertion_type
,
6628 doc
: /* Type of marker to use for `window-point'. */);
6629 Vwindow_point_insertion_type
= Qnil
;
6631 DEFVAR_LISP ("window-configuration-change-hook",
6632 Vwindow_configuration_change_hook
,
6633 doc
: /* Functions to call when window configuration changes.
6634 The buffer-local part is run once per window, with the relevant window
6635 selected; while the global part is run only once for the modified frame,
6636 with the relevant frame selected. */);
6637 Vwindow_configuration_change_hook
= Qnil
;
6639 DEFVAR_LISP ("recenter-redisplay", Vrecenter_redisplay
,
6640 doc
: /* Non-nil means `recenter' redraws entire frame.
6641 If this option is non-nil, then the `recenter' command with a nil
6642 argument will redraw the entire frame; the special value `tty' causes
6643 the frame to be redrawn only if it is a tty frame. */);
6644 Vrecenter_redisplay
= Qtty
;
6646 DEFVAR_LISP ("window-combination-resize", Vwindow_combination_resize
,
6647 doc
: /* If t, resize window combinations proportionally.
6648 If this variable is nil, splitting a window gets the entire screen space
6649 for displaying the new window from the window to split. Deleting and
6650 resizing a window preferably resizes one adjacent window only.
6652 If this variable is t, splitting a window tries to get the space
6653 proportionally from all windows in the same combination. This also
6654 allows to split a window that is otherwise too small or of fixed size.
6655 Resizing and deleting a window proportionally resize all windows in the
6658 Other values are reserved for future use.
6660 This variable takes no effect if `window-combination-limit' is non-nil. */);
6661 Vwindow_combination_resize
= Qnil
;
6663 DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit
,
6664 doc
: /* If t, splitting a window makes a new parent window.
6665 If this variable is nil, splitting a window will create a new parent
6666 window only if the window has no parent window or the window shall
6667 become a combination orthogonal to the one it is part of.
6669 If this variable is t, splitting a window always creates a new parent
6670 window. If all splits behave this way, each frame's window tree is a
6671 binary tree and every window but the frame's root window has exactly one
6674 Other values are reserved for future use.
6676 The value of this variable is also assigned to the combination limit of
6677 the new parent window. The combination limit of a window can be
6678 retrieved via the function `window-combination-limit' and altered by the
6679 function `set-window-combination-limit'. */);
6680 Vwindow_combination_limit
= Qnil
;
6682 DEFVAR_LISP ("window-persistent-parameters", Vwindow_persistent_parameters
,
6683 doc
: /* Alist of persistent window parameters.
6684 This alist specifies which window parameters shall get saved by
6685 `current-window-configuration' and `window-state-get' and subsequently
6686 restored to their previous values by `set-window-configuration' and
6689 The car of each entry of this alist is the symbol specifying the
6690 parameter. The cdr is one of the following:
6692 nil means the parameter is neither saved by `window-state-get' nor by
6693 `current-window-configuration'.
6695 t means the parameter is saved by `current-window-configuration' and,
6696 provided its WRITABLE argument is nil, by `window-state-get'.
6698 The symbol `writable' means the parameter is saved unconditionally by
6699 both `current-window-configuration' and `window-state-get'. Do not use
6700 this value for parameters without read syntax (like windows or frames).
6702 Parameters not saved by `current-window-configuration' or
6703 `window-state-get' are left alone by `set-window-configuration'
6704 respectively are not installed by `window-state-put'. */);
6705 Vwindow_persistent_parameters
= list1 (Fcons (Qclone_of
, Qt
));
6707 defsubr (&Sselected_window
);
6708 defsubr (&Sminibuffer_window
);
6709 defsubr (&Swindow_minibuffer_p
);
6710 defsubr (&Swindowp
);
6711 defsubr (&Swindow_valid_p
);
6712 defsubr (&Swindow_live_p
);
6713 defsubr (&Swindow_frame
);
6714 defsubr (&Sframe_root_window
);
6715 defsubr (&Sframe_first_window
);
6716 defsubr (&Sframe_selected_window
);
6717 defsubr (&Sset_frame_selected_window
);
6718 defsubr (&Spos_visible_in_window_p
);
6719 defsubr (&Swindow_line_height
);
6720 defsubr (&Swindow_buffer
);
6721 defsubr (&Swindow_parent
);
6722 defsubr (&Swindow_top_child
);
6723 defsubr (&Swindow_left_child
);
6724 defsubr (&Swindow_next_sibling
);
6725 defsubr (&Swindow_prev_sibling
);
6726 defsubr (&Swindow_combination_limit
);
6727 defsubr (&Sset_window_combination_limit
);
6728 defsubr (&Swindow_use_time
);
6729 defsubr (&Swindow_top_line
);
6730 defsubr (&Swindow_left_column
);
6731 defsubr (&Swindow_total_height
);
6732 defsubr (&Swindow_total_width
);
6733 defsubr (&Swindow_normal_size
);
6734 defsubr (&Swindow_new_total
);
6735 defsubr (&Swindow_new_normal
);
6736 defsubr (&Sset_window_new_total
);
6737 defsubr (&Sset_window_new_normal
);
6738 defsubr (&Swindow_resize_apply
);
6739 defsubr (&Swindow_body_height
);
6740 defsubr (&Swindow_body_width
);
6741 defsubr (&Swindow_hscroll
);
6742 defsubr (&Sset_window_hscroll
);
6743 defsubr (&Swindow_redisplay_end_trigger
);
6744 defsubr (&Sset_window_redisplay_end_trigger
);
6745 defsubr (&Swindow_edges
);
6746 defsubr (&Swindow_pixel_edges
);
6747 defsubr (&Swindow_absolute_pixel_edges
);
6748 defsubr (&Swindow_inside_edges
);
6749 defsubr (&Swindow_inside_pixel_edges
);
6750 defsubr (&Swindow_inside_absolute_pixel_edges
);
6751 defsubr (&Scoordinates_in_window_p
);
6752 defsubr (&Swindow_at
);
6753 defsubr (&Swindow_point
);
6754 defsubr (&Swindow_start
);
6755 defsubr (&Swindow_end
);
6756 defsubr (&Sset_window_point
);
6757 defsubr (&Sset_window_start
);
6758 defsubr (&Swindow_dedicated_p
);
6759 defsubr (&Sset_window_dedicated_p
);
6760 defsubr (&Swindow_display_table
);
6761 defsubr (&Sset_window_display_table
);
6762 defsubr (&Snext_window
);
6763 defsubr (&Sprevious_window
);
6764 defsubr (&Sget_buffer_window
);
6765 defsubr (&Sdelete_other_windows_internal
);
6766 defsubr (&Sdelete_window_internal
);
6767 defsubr (&Sresize_mini_window_internal
);
6768 defsubr (&Sset_window_buffer
);
6769 defsubr (&Srun_window_configuration_change_hook
);
6770 defsubr (&Sselect_window
);
6771 defsubr (&Sforce_window_update
);
6772 defsubr (&Stemp_output_buffer_show
);
6773 defsubr (&Ssplit_window_internal
);
6774 defsubr (&Sscroll_up
);
6775 defsubr (&Sscroll_down
);
6776 defsubr (&Sscroll_left
);
6777 defsubr (&Sscroll_right
);
6778 defsubr (&Sother_window_for_scrolling
);
6779 defsubr (&Sscroll_other_window
);
6780 defsubr (&Sminibuffer_selected_window
);
6781 defsubr (&Srecenter
);
6782 defsubr (&Swindow_text_height
);
6783 defsubr (&Smove_to_window_line
);
6784 defsubr (&Swindow_configuration_p
);
6785 defsubr (&Swindow_configuration_frame
);
6786 defsubr (&Sset_window_configuration
);
6787 defsubr (&Scurrent_window_configuration
);
6788 defsubr (&Sset_window_margins
);
6789 defsubr (&Swindow_margins
);
6790 defsubr (&Sset_window_fringes
);
6791 defsubr (&Swindow_fringes
);
6792 defsubr (&Sset_window_scroll_bars
);
6793 defsubr (&Swindow_scroll_bars
);
6794 defsubr (&Swindow_vscroll
);
6795 defsubr (&Sset_window_vscroll
);
6796 defsubr (&Scompare_window_configurations
);
6797 defsubr (&Swindow_list
);
6798 defsubr (&Swindow_list_1
);
6799 defsubr (&Swindow_prev_buffers
);
6800 defsubr (&Sset_window_prev_buffers
);
6801 defsubr (&Swindow_next_buffers
);
6802 defsubr (&Sset_window_next_buffers
);
6803 defsubr (&Swindow_parameters
);
6804 defsubr (&Swindow_parameter
);
6805 defsubr (&Sset_window_parameter
);
6809 keys_of_window (void)
6811 initial_define_key (control_x_map
, '<', "scroll-left");
6812 initial_define_key (control_x_map
, '>', "scroll-right");
6814 initial_define_key (global_map
, Ctl ('V'), "scroll-up-command");
6815 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
6816 initial_define_key (meta_map
, 'v', "scroll-down-command");