1 /* Window creation, deletion and examination for GNU Emacs.
2 Does not include redisplay.
3 Copyright (C) 1985-1987, 1993-1998, 2000-2014 Free Software
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. */
40 #ifdef HAVE_WINDOW_SYSTEM
42 #endif /* HAVE_WINDOW_SYSTEM */
47 Lisp_Object Qwindowp
, Qwindow_live_p
;
48 static Lisp_Object Qwindow_valid_p
;
49 static Lisp_Object Qwindow_configuration_p
;
50 static Lisp_Object Qrecord_window_buffer
;
51 static Lisp_Object Qwindow_deletable_p
, Qdelete_window
, Qdisplay_buffer
;
52 static Lisp_Object Qreplace_buffer_in_windows
, Qget_mru_window
;
53 static Lisp_Object Qwindow_resize_root_window
, Qwindow_resize_root_window_vertically
;
54 static Lisp_Object Qwindow_pixel_to_total
;
55 static Lisp_Object Qscroll_up
, Qscroll_down
, Qscroll_command
;
56 static Lisp_Object Qsafe
, Qabove
, Qbelow
, Qwindow_size
, Qclone_of
;
57 static Lisp_Object Qfloor
, Qceiling
;
59 static int displayed_window_lines (struct window
*);
60 static int count_windows (struct window
*);
61 static int get_leaf_windows (struct window
*, struct window
**, int);
62 static void window_scroll (Lisp_Object
, EMACS_INT
, bool, int);
63 static void window_scroll_pixel_based (Lisp_Object
, int, bool, int);
64 static void window_scroll_line_based (Lisp_Object
, int, bool, int);
65 static int add_window_to_list (struct window
*, void *);
66 static Lisp_Object
next_window (Lisp_Object
, Lisp_Object
,
68 static void decode_next_window_args (Lisp_Object
*, Lisp_Object
*,
70 static void foreach_window (struct frame
*,
71 int (* fn
) (struct window
*, void *),
73 static int foreach_window_1 (struct window
*,
74 int (* fn
) (struct window
*, void *),
76 static Lisp_Object
window_list_1 (Lisp_Object
, Lisp_Object
, Lisp_Object
);
77 static int window_resize_check (struct window
*, bool);
78 static void window_resize_apply (struct window
*, bool);
79 static void window_resize_apply_total (struct window
*, bool);
80 static Lisp_Object
select_window (Lisp_Object
, Lisp_Object
, int);
81 static void select_window_1 (Lisp_Object
, bool);
83 static struct window
*set_window_fringes (struct window
*, Lisp_Object
,
84 Lisp_Object
, Lisp_Object
);
85 static struct window
*set_window_margins (struct window
*, Lisp_Object
,
87 static struct window
*set_window_scroll_bars (struct window
*, Lisp_Object
,
88 Lisp_Object
, Lisp_Object
);
89 static void apply_window_adjustment (struct window
*);
91 /* This is the window in which the terminal's cursor should
92 be left when nothing is being done with it. This must
93 always be a leaf window, and its buffer is selected by
94 the top level editing loop at the end of each command.
96 This value is always the same as
97 FRAME_SELECTED_WINDOW (selected_frame). */
98 Lisp_Object selected_window
;
100 /* A list of all windows for use by next_window and Fwindow_list.
101 Functions creating or deleting windows should invalidate this cache
102 by setting it to nil. */
103 Lisp_Object Vwindow_list
;
105 /* The mini-buffer window of the selected frame.
106 Note that you cannot test for mini-bufferness of an arbitrary window
107 by comparing against this; but you can test for mini-bufferness of
108 the selected window. */
109 Lisp_Object minibuf_window
;
111 /* Non-nil means it is the window whose mode line should be
112 shown as the selected window when the minibuffer is selected. */
113 Lisp_Object minibuf_selected_window
;
115 /* Hook run at end of temp_output_buffer_show. */
116 static Lisp_Object Qtemp_buffer_show_hook
;
118 /* Incremented for each window created. */
119 static int sequence_number
;
121 /* Nonzero after init_window_once has finished. */
122 static int window_initialized
;
124 /* Hook to run when window config changes. */
125 static Lisp_Object Qwindow_configuration_change_hook
;
127 /* Used by the function window_scroll_pixel_based */
128 static int window_scroll_pixel_based_preserve_x
;
129 static int window_scroll_pixel_based_preserve_y
;
131 /* Same for window_scroll_line_based. */
132 static EMACS_INT window_scroll_preserve_hpos
;
133 static EMACS_INT window_scroll_preserve_vpos
;
136 CHECK_WINDOW_CONFIGURATION (Lisp_Object x
)
138 CHECK_TYPE (WINDOW_CONFIGURATIONP (x
), Qwindow_configuration_p
, x
);
141 /* These setters are used only in this file, so they can be private. */
143 wset_combination_limit (struct window
*w
, Lisp_Object val
)
145 w
->combination_limit
= val
;
148 wset_dedicated (struct window
*w
, Lisp_Object val
)
153 wset_display_table (struct window
*w
, Lisp_Object val
)
155 w
->display_table
= val
;
158 wset_new_normal (struct window
*w
, Lisp_Object val
)
163 wset_new_total (struct window
*w
, Lisp_Object val
)
168 wset_normal_cols (struct window
*w
, Lisp_Object val
)
170 w
->normal_cols
= val
;
173 wset_normal_lines (struct window
*w
, Lisp_Object val
)
175 w
->normal_lines
= val
;
178 wset_parent (struct window
*w
, Lisp_Object val
)
183 wset_pointm (struct window
*w
, Lisp_Object val
)
188 wset_start (struct window
*w
, Lisp_Object val
)
193 wset_temslot (struct window
*w
, Lisp_Object val
)
198 wset_vertical_scroll_bar_type (struct window
*w
, Lisp_Object val
)
200 w
->vertical_scroll_bar_type
= val
;
203 wset_window_parameters (struct window
*w
, Lisp_Object val
)
205 w
->window_parameters
= val
;
208 wset_combination (struct window
*w
, bool horflag
, Lisp_Object val
)
210 /* Since leaf windows never becomes non-leaf, there should
211 be no buffer and markers in start and pointm fields of W. */
212 eassert (!BUFFERP (w
->contents
) && NILP (w
->start
) && NILP (w
->pointm
));
214 /* When an internal window is deleted and VAL is nil, HORFLAG
217 w
->horizontal
= horflag
;
220 /* Nonzero if leaf window W doesn't reflect the actual state
221 of displayed buffer due to its text or overlays change. */
224 window_outdated (struct window
*w
)
226 struct buffer
*b
= XBUFFER (w
->contents
);
227 return (w
->last_modified
< BUF_MODIFF (b
)
228 || w
->last_overlay_modified
< BUF_OVERLAY_MODIFF (b
));
232 decode_live_window (register Lisp_Object window
)
235 return XWINDOW (selected_window
);
237 CHECK_LIVE_WINDOW (window
);
238 return XWINDOW (window
);
242 decode_any_window (register Lisp_Object window
)
247 return XWINDOW (selected_window
);
249 CHECK_WINDOW (window
);
250 w
= XWINDOW (window
);
254 static struct window
*
255 decode_valid_window (register Lisp_Object window
)
260 return XWINDOW (selected_window
);
262 CHECK_VALID_WINDOW (window
);
263 w
= XWINDOW (window
);
267 /* Called when W's buffer slot is changed. ARG -1 means that W is about to
268 cease its buffer, and 1 means that W is about to set up the new one. */
271 adjust_window_count (struct window
*w
, int arg
)
273 eassert (eabs (arg
) == 1);
274 if (BUFFERP (w
->contents
))
276 struct buffer
*b
= XBUFFER (w
->contents
);
280 b
->window_count
+= arg
;
281 eassert (b
->window_count
>= 0);
282 /* These should be recalculated by redisplay code. */
283 w
->window_end_valid
= 0;
284 w
->base_line_pos
= 0;
288 /* Set W's buffer slot to VAL and recompute number
289 of windows showing VAL if it is a buffer. */
292 wset_buffer (struct window
*w
, Lisp_Object val
)
294 adjust_window_count (w
, -1);
296 /* Make sure that we do not assign the buffer
297 to an internal window. */
298 eassert (MARKERP (w
->start
) && MARKERP (w
->pointm
));
300 adjust_window_count (w
, 1);
303 DEFUN ("windowp", Fwindowp
, Swindowp
, 1, 1, 0,
304 doc
: /* Return t if OBJECT is a window and nil otherwise. */)
307 return WINDOWP (object
) ? Qt
: Qnil
;
310 DEFUN ("window-valid-p", Fwindow_valid_p
, Swindow_valid_p
, 1, 1, 0,
311 doc
: /* Return t if OBJECT is a valid window and nil otherwise.
312 A valid window is either a window that displays a buffer or an internal
313 window. Deleted windows are not live. */)
316 return WINDOW_VALID_P (object
) ? Qt
: Qnil
;
319 DEFUN ("window-live-p", Fwindow_live_p
, Swindow_live_p
, 1, 1, 0,
320 doc
: /* Return t if OBJECT is a live window and nil otherwise.
321 A live window is a window that displays a buffer.
322 Internal windows and deleted windows are not live. */)
325 return WINDOW_LIVE_P (object
) ? Qt
: Qnil
;
328 /* Frames and windows. */
329 DEFUN ("window-frame", Fwindow_frame
, Swindow_frame
, 0, 1, 0,
330 doc
: /* Return the frame that window WINDOW is on.
331 WINDOW must be a valid window and defaults to the selected one. */)
334 return decode_valid_window (window
)->frame
;
337 DEFUN ("frame-root-window", Fframe_root_window
, Sframe_root_window
, 0, 1, 0,
338 doc
: /* Return the root window of FRAME-OR-WINDOW.
339 If omitted, FRAME-OR-WINDOW defaults to the currently selected frame.
340 With a frame argument, return that frame's root window.
341 With a window argument, return the root window of that window's frame. */)
342 (Lisp_Object frame_or_window
)
346 if (NILP (frame_or_window
))
347 window
= SELECTED_FRAME ()->root_window
;
348 else if (WINDOW_VALID_P (frame_or_window
))
349 window
= XFRAME (XWINDOW (frame_or_window
)->frame
)->root_window
;
352 CHECK_LIVE_FRAME (frame_or_window
);
353 window
= XFRAME (frame_or_window
)->root_window
;
359 DEFUN ("minibuffer-window", Fminibuffer_window
, Sminibuffer_window
, 0, 1, 0,
360 doc
: /* Return the minibuffer window for frame FRAME.
361 If FRAME is omitted or nil, it defaults to the selected frame. */)
364 return FRAME_MINIBUF_WINDOW (decode_live_frame (frame
));
367 DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p
,
368 Swindow_minibuffer_p
, 0, 1, 0,
369 doc
: /* Return non-nil if WINDOW is a minibuffer window.
370 WINDOW must be a valid window and defaults to the selected one. */)
373 return MINI_WINDOW_P (decode_valid_window (window
)) ? Qt
: Qnil
;
376 /* Don't move this to window.el - this must be a safe routine. */
377 DEFUN ("frame-first-window", Fframe_first_window
, Sframe_first_window
, 0, 1, 0,
378 doc
: /* Return the topmost, leftmost live window on FRAME-OR-WINDOW.
379 If omitted, FRAME-OR-WINDOW defaults to the currently selected frame.
380 Else if FRAME-OR-WINDOW denotes a valid window, return the first window
381 of that window's frame. If FRAME-OR-WINDOW denotes a live frame, return
382 the first window of that frame. */)
383 (Lisp_Object frame_or_window
)
387 if (NILP (frame_or_window
))
388 window
= SELECTED_FRAME ()->root_window
;
389 else if (WINDOW_VALID_P (frame_or_window
))
390 window
= XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window
)))->root_window
;
393 CHECK_LIVE_FRAME (frame_or_window
);
394 window
= XFRAME (frame_or_window
)->root_window
;
397 while (WINDOWP (XWINDOW (window
)->contents
))
398 window
= XWINDOW (window
)->contents
;
403 DEFUN ("frame-selected-window", Fframe_selected_window
,
404 Sframe_selected_window
, 0, 1, 0,
405 doc
: /* Return the selected window of FRAME-OR-WINDOW.
406 If omitted, FRAME-OR-WINDOW defaults to the currently selected frame.
407 Else if FRAME-OR-WINDOW denotes a valid window, return the selected
408 window of that window's frame. If FRAME-OR-WINDOW denotes a live frame,
409 return the selected window of that frame. */)
410 (Lisp_Object frame_or_window
)
414 if (NILP (frame_or_window
))
415 window
= SELECTED_FRAME ()->selected_window
;
416 else if (WINDOW_VALID_P (frame_or_window
))
417 window
= XFRAME (WINDOW_FRAME (XWINDOW (frame_or_window
)))->selected_window
;
420 CHECK_LIVE_FRAME (frame_or_window
);
421 window
= XFRAME (frame_or_window
)->selected_window
;
427 DEFUN ("set-frame-selected-window", Fset_frame_selected_window
,
428 Sset_frame_selected_window
, 2, 3, 0,
429 doc
: /* Set selected window of FRAME to WINDOW.
430 FRAME must be a live frame and defaults to the selected one. If FRAME
431 is the selected frame, this makes WINDOW the selected window. Optional
432 argument NORECORD non-nil means to neither change the order of recently
433 selected windows nor the buffer list. WINDOW must denote a live window.
435 (Lisp_Object frame
, Lisp_Object window
, Lisp_Object norecord
)
438 frame
= selected_frame
;
440 CHECK_LIVE_FRAME (frame
);
441 CHECK_LIVE_WINDOW (window
);
443 if (! EQ (frame
, WINDOW_FRAME (XWINDOW (window
))))
444 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
446 if (EQ (frame
, selected_frame
))
447 return Fselect_window (window
, norecord
);
450 fset_selected_window (XFRAME (frame
), window
);
455 DEFUN ("selected-window", Fselected_window
, Sselected_window
, 0, 0, 0,
456 doc
: /* Return the selected window.
457 The selected window is the window in which the standard cursor for
458 selected windows appears and to which many commands apply. */)
461 return selected_window
;
464 int window_select_count
;
466 /* If select_window is called with inhibit_point_swap non-zero it will
467 not store point of the old selected window's buffer back into that
468 window's pointm slot. This is needed by Fset_window_configuration to
469 avoid that the display routine is called with selected_window set to
470 Qnil causing a subsequent crash. */
472 select_window (Lisp_Object window
, Lisp_Object norecord
, int inhibit_point_swap
)
474 register struct window
*w
;
477 CHECK_LIVE_WINDOW (window
);
479 w
= XWINDOW (window
);
481 /* Make the selected window's buffer current. */
482 Fset_buffer (w
->contents
);
484 if (EQ (window
, selected_window
) && !inhibit_point_swap
)
485 /* `switch-to-buffer' uses (select-window (selected-window)) as a "clever"
486 way to call record_buffer from Elisp, so it's important that we call
487 record_buffer before returning here. */
488 goto record_and_return
;
491 { /* Mark the window for redisplay since the selected-window has
492 a different mode-line. */
493 wset_redisplay (XWINDOW (selected_window
));
497 redisplay_other_windows ();
499 sf
= SELECTED_FRAME ();
500 if (XFRAME (WINDOW_FRAME (w
)) != sf
)
502 fset_selected_window (XFRAME (WINDOW_FRAME (w
)), window
);
503 /* Use this rather than Fhandle_switch_frame
504 so that FRAME_FOCUS_FRAME is moved appropriately as we
505 move around in the state where a minibuffer in a separate
507 Fselect_frame (WINDOW_FRAME (w
), norecord
);
508 /* Fselect_frame called us back so we've done all the work already. */
509 eassert (EQ (window
, selected_window
));
513 fset_selected_window (sf
, window
);
515 select_window_1 (window
, inhibit_point_swap
);
516 bset_last_selected_window (XBUFFER (w
->contents
), window
);
519 /* record_buffer can run QUIT, so make sure it is run only after we have
520 re-established the invariant between selected_window and selected_frame,
521 otherwise the temporary broken invariant might "escape" (bug#14161). */
524 w
->use_time
= ++window_select_count
;
525 record_buffer (w
->contents
);
531 /* Select window with a minimum of fuss, i.e. don't record the change anywhere
532 (not even for redisplay's benefit), and assume that the window's frame is
535 select_window_1 (Lisp_Object window
, bool inhibit_point_swap
)
537 /* Store the old selected window's buffer's point in pointm of the old
538 selected window. It belongs to that window, and when the window is
539 not selected, must be in the window. */
540 if (!inhibit_point_swap
)
542 struct window
*ow
= XWINDOW (selected_window
);
543 if (BUFFERP (ow
->contents
))
544 set_marker_both (ow
->pointm
, ow
->contents
,
545 BUF_PT (XBUFFER (ow
->contents
)),
546 BUF_PT_BYTE (XBUFFER (ow
->contents
)));
549 selected_window
= window
;
551 /* Go to the point recorded in the window.
552 This is important when the buffer is in more
553 than one window. It also matters when
554 redisplay_window has altered point after scrolling,
555 because it makes the change only in the window. */
556 set_point_from_marker (XWINDOW (window
)->pointm
);
559 DEFUN ("select-window", Fselect_window
, Sselect_window
, 1, 2, 0,
560 doc
: /* Select WINDOW which must be a live window.
561 Also make WINDOW's frame the selected frame and WINDOW that frame's
562 selected window. In addition, make WINDOW's buffer current and set that
563 buffer's value of `point' to the value of WINDOW's `window-point'.
566 Optional second arg NORECORD non-nil means do not put this buffer at the
567 front of the buffer list and do not make this window the most recently
570 Note that the main editor command loop sets the current buffer to the
571 buffer of the selected window before each command. */)
572 (register Lisp_Object window
, Lisp_Object norecord
)
574 return select_window (window
, norecord
, 0);
577 DEFUN ("window-buffer", Fwindow_buffer
, Swindow_buffer
, 0, 1, 0,
578 doc
: /* Return the buffer displayed in window WINDOW.
579 If WINDOW is omitted or nil, it defaults to the selected window.
580 Return nil for an internal window or a deleted window. */)
583 struct window
*w
= decode_any_window (window
);
584 return WINDOW_LEAF_P (w
) ? w
->contents
: Qnil
;
587 DEFUN ("window-parent", Fwindow_parent
, Swindow_parent
, 0, 1, 0,
588 doc
: /* Return the parent window of window WINDOW.
589 WINDOW must be a valid window and defaults to the selected one.
590 Return nil for a window with no parent (e.g. a root window). */)
593 return decode_valid_window (window
)->parent
;
596 DEFUN ("window-top-child", Fwindow_top_child
, Swindow_top_child
, 0, 1, 0,
597 doc
: /* Return the topmost child window of window WINDOW.
598 WINDOW must be a valid window and defaults to the selected one.
599 Return nil if WINDOW is a live window (live windows have no children).
600 Return nil if WINDOW is an internal window whose children form a
601 horizontal combination. */)
604 struct window
*w
= decode_valid_window (window
);
605 return WINDOW_VERTICAL_COMBINATION_P (w
) ? w
->contents
: Qnil
;
608 DEFUN ("window-left-child", Fwindow_left_child
, Swindow_left_child
, 0, 1, 0,
609 doc
: /* Return the leftmost child window of window WINDOW.
610 WINDOW must be a valid window and defaults to the selected one.
611 Return nil if WINDOW is a live window (live windows have no children).
612 Return nil if WINDOW is an internal window whose children form a
613 vertical combination. */)
616 struct window
*w
= decode_valid_window (window
);
617 return WINDOW_HORIZONTAL_COMBINATION_P (w
) ? w
->contents
: Qnil
;
620 DEFUN ("window-next-sibling", Fwindow_next_sibling
, Swindow_next_sibling
, 0, 1, 0,
621 doc
: /* Return the next sibling window of window WINDOW.
622 WINDOW must be a valid window and defaults to the selected one.
623 Return nil if WINDOW has no next sibling. */)
626 return decode_valid_window (window
)->next
;
629 DEFUN ("window-prev-sibling", Fwindow_prev_sibling
, Swindow_prev_sibling
, 0, 1, 0,
630 doc
: /* Return the previous sibling window of window WINDOW.
631 WINDOW must be a valid window and defaults to the selected one.
632 Return nil if WINDOW has no previous sibling. */)
635 return decode_valid_window (window
)->prev
;
638 DEFUN ("window-combination-limit", Fwindow_combination_limit
, Swindow_combination_limit
, 1, 1, 0,
639 doc
: /* Return combination limit of window WINDOW.
640 WINDOW must be a valid window used in horizontal or vertical combination.
641 If the return value is nil, child windows of WINDOW can be recombined with
642 WINDOW's siblings. A return value of t means that child windows of
643 WINDOW are never \(re-)combined with WINDOW's siblings. */)
648 CHECK_VALID_WINDOW (window
);
649 w
= XWINDOW (window
);
650 if (WINDOW_LEAF_P (w
))
651 error ("Combination limit is meaningful for internal windows only");
652 return w
->combination_limit
;
655 DEFUN ("set-window-combination-limit", Fset_window_combination_limit
, Sset_window_combination_limit
, 2, 2, 0,
656 doc
: /* Set combination limit of window WINDOW to LIMIT; return LIMIT.
657 WINDOW must be a valid window used in horizontal or vertical combination.
658 If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's
659 siblings. LIMIT t means that child windows of WINDOW are never
660 \(re-)combined with WINDOW's siblings. Other values are reserved for
662 (Lisp_Object window
, Lisp_Object limit
)
666 CHECK_VALID_WINDOW (window
);
667 w
= XWINDOW (window
);
668 if (WINDOW_LEAF_P (w
))
669 error ("Combination limit is meaningful for internal windows only");
670 wset_combination_limit (w
, limit
);
674 DEFUN ("window-use-time", Fwindow_use_time
, Swindow_use_time
, 0, 1, 0,
675 doc
: /* Return the use time of window WINDOW.
676 WINDOW must be a live window and defaults to the selected one.
677 The window with the highest use time is the most recently selected
678 one. The window with the lowest use time is the least recently
682 return make_number (decode_live_window (window
)->use_time
);
685 DEFUN ("window-pixel-width", Fwindow_pixel_width
, Swindow_pixel_width
, 0, 1, 0,
686 doc
: /* Return the width of window WINDOW in pixels.
687 WINDOW must be a valid window and defaults to the selected one.
689 The return value includes the fringes and margins of WINDOW as well as
690 any vertical dividers or scroll bars belonging to WINDOW. If WINDOW is
691 an internal window, its pixel width is the width of the screen areas
692 spanned by its children. */)
695 return make_number (decode_valid_window (window
)->pixel_width
);
698 DEFUN ("window-pixel-height", Fwindow_pixel_height
, Swindow_pixel_height
, 0, 1, 0,
699 doc
: /* Return the height of window WINDOW in pixels.
700 WINDOW must be a valid window and defaults to the selected one.
702 The return value includes the mode line and header line, if any. If
703 WINDOW is an internal window, its pixel height is the height of the
704 screen areas spanned by its children. */)
707 return make_number (decode_valid_window (window
)->pixel_height
);
710 DEFUN ("window-total-height", Fwindow_total_height
, Swindow_total_height
, 0, 2, 0,
711 doc
: /* Return the height of window WINDOW in lines.
712 WINDOW must be a valid window and defaults to the selected one.
714 The return value includes the heights of WINDOW's mode and header line
715 and its bottom divider, if any. If WINDOW is an internal window, the
716 total height is the height of the screen areas spanned by its children.
718 If WINDOW's pixel height is not an integral multiple of its frame's
719 character height, the number of lines occupied by WINDOW is rounded
720 internally. This is done in a way such that, if WINDOW is a parent
721 window, the sum of the total heights of all its children internally
722 equals the total height of WINDOW.
724 If the optional argument ROUND is `ceiling', return the smallest integer
725 larger than WINDOW's pixel height divided by the character height of
726 WINDOW's frame. ROUND `floor' means to return the largest integer
727 smaller than WINDOW's pixel height divided by the character height of
728 WINDOW's frame. Any other value of ROUND means to return the internal
729 total height of WINDOW. */)
730 (Lisp_Object window
, Lisp_Object round
)
732 struct window
*w
= decode_valid_window (window
);
734 if (! EQ (round
, Qfloor
) && ! EQ (round
, Qceiling
))
735 return make_number (w
->total_lines
);
738 int unit
= FRAME_LINE_HEIGHT (WINDOW_XFRAME (w
));
740 return make_number (EQ (round
, Qceiling
)
741 ? ((w
->pixel_height
+ unit
- 1) /unit
)
742 : (w
->pixel_height
/ unit
));
746 DEFUN ("window-total-width", Fwindow_total_width
, Swindow_total_width
, 0, 2, 0,
747 doc
: /* Return the total width of window WINDOW in columns.
748 WINDOW must be a valid window and defaults to the selected one.
750 The return value includes the widths of WINDOW's fringes, margins,
751 scroll bars and its right divider, if any. If WINDOW is an internal
752 window, the total width is the width of the screen areas spanned by its
755 If WINDOW's pixel width is not an integral multiple of its frame's
756 character width, the number of lines occupied by WINDOW is rounded
757 internally. This is done in a way such that, if WINDOW is a parent
758 window, the sum of the total widths of all its children internally
759 equals the total width of WINDOW.
761 If the optional argument ROUND is `ceiling', return the smallest integer
762 larger than WINDOW's pixel width divided by the character width of
763 WINDOW's frame. ROUND `floor' means to return the largest integer
764 smaller than WINDOW's pixel width divided by the character width of
765 WINDOW's frame. Any other value of ROUND means to return the internal
766 total width of WINDOW. */)
767 (Lisp_Object window
, Lisp_Object round
)
769 struct window
*w
= decode_valid_window (window
);
771 if (! EQ (round
, Qfloor
) && ! EQ (round
, Qceiling
))
772 return make_number (w
->total_cols
);
775 int unit
= FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w
));
777 return make_number (EQ (round
, Qceiling
)
778 ? ((w
->pixel_width
+ unit
- 1) /unit
)
779 : (w
->pixel_width
/ unit
));
783 DEFUN ("window-new-total", Fwindow_new_total
, Swindow_new_total
, 0, 1, 0,
784 doc
: /* Return the new total size of window WINDOW.
785 WINDOW must be a valid window and defaults to the selected one. */)
788 return decode_valid_window (window
)->new_total
;
791 DEFUN ("window-normal-size", Fwindow_normal_size
, Swindow_normal_size
, 0, 2, 0,
792 doc
: /* Return the normal height of window WINDOW.
793 WINDOW must be a valid window and defaults to the selected one.
794 If HORIZONTAL is non-nil, return the normal width of WINDOW. */)
795 (Lisp_Object window
, Lisp_Object horizontal
)
797 struct window
*w
= decode_valid_window (window
);
799 return NILP (horizontal
) ? w
->normal_lines
: w
->normal_cols
;
802 DEFUN ("window-new-normal", Fwindow_new_normal
, Swindow_new_normal
, 0, 1, 0,
803 doc
: /* Return new normal size of window WINDOW.
804 WINDOW must be a valid window and defaults to the selected one. */)
807 return decode_valid_window (window
)->new_normal
;
810 DEFUN ("window-new-pixel", Fwindow_new_pixel
, Swindow_new_pixel
, 0, 1, 0,
811 doc
: /* Return new pixel size of window WINDOW.
812 WINDOW must be a valid window and defaults to the selected one. */)
815 return decode_valid_window (window
)->new_pixel
;
818 DEFUN ("window-pixel-left", Fwindow_pixel_left
, Swindow_pixel_left
, 0, 1, 0,
819 doc
: /* Return left pixel edge of window WINDOW.
820 WINDOW must be a valid window and defaults to the selected one. */)
823 return make_number (decode_valid_window (window
)->pixel_left
);
826 DEFUN ("window-pixel-top", Fwindow_pixel_top
, Swindow_pixel_top
, 0, 1, 0,
827 doc
: /* Return top pixel edge of window WINDOW.
828 WINDOW must be a valid window and defaults to the selected one. */)
831 return make_number (decode_valid_window (window
)->pixel_top
);
834 DEFUN ("window-left-column", Fwindow_left_column
, Swindow_left_column
, 0, 1, 0,
835 doc
: /* Return left column of window WINDOW.
836 This is the distance, in columns, between the left edge of WINDOW and
837 the left edge of the frame's window area. For instance, the return
838 value is 0 if there is no window to the left of WINDOW.
840 WINDOW must be a valid window and defaults to the selected one. */)
843 return make_number (decode_valid_window (window
)->left_col
);
846 DEFUN ("window-top-line", Fwindow_top_line
, Swindow_top_line
, 0, 1, 0,
847 doc
: /* Return top line of window WINDOW.
848 This is the distance, in lines, between the top of WINDOW and the top
849 of the frame's window area. For instance, the return value is 0 if
850 there is no window above WINDOW.
852 WINDOW must be a valid window and defaults to the selected one. */)
855 return make_number (decode_valid_window (window
)->top_line
);
858 /* Return the number of lines/pixels of W's body. Don't count any mode
859 or header line or horizontal divider of W. Rounds down to nearest
860 integer when not working pixelwise. */
862 window_body_height (struct window
*w
, bool pixelwise
)
864 int height
= (w
->pixel_height
865 - WINDOW_HEADER_LINE_HEIGHT (w
)
866 - WINDOW_MODE_LINE_HEIGHT (w
)
867 - WINDOW_BOTTOM_DIVIDER_WIDTH (w
));
869 return pixelwise
? height
: height
/ FRAME_LINE_HEIGHT (WINDOW_XFRAME (w
));
872 /* Return the number of columns/pixels of W's body. Don't count columns
873 occupied by the scroll bar or the divider/vertical bar separating W
874 from its right sibling or margins. On window-systems don't count
875 fringes either. Round down to nearest integer when not working
878 window_body_width (struct window
*w
, bool pixelwise
)
880 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
882 int width
= (w
->pixel_width
883 - WINDOW_RIGHT_DIVIDER_WIDTH (w
)
884 - (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
)
885 ? WINDOW_SCROLL_BAR_AREA_WIDTH (w
)
886 : ((!FRAME_WINDOW_P (f
)
887 && !WINDOW_RIGHTMOST_P (w
)
888 && !WINDOW_RIGHT_DIVIDER_WIDTH (w
))
889 /* A vertical bar is either 1 or 0. */
891 - WINDOW_MARGINS_WIDTH (w
)
892 - (FRAME_WINDOW_P (f
)
893 ? WINDOW_FRINGES_WIDTH (w
)
896 return pixelwise
? width
: width
/ FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w
));
899 DEFUN ("window-body-height", Fwindow_body_height
, Swindow_body_height
, 0, 2, 0,
900 doc
: /* Return the height of WINDOW's text area.
901 WINDOW must be a live window and defaults to the selected one. Optional
902 argument PIXELWISE non-nil means return the height of WINDOW's text area
903 in pixels. The return value does not include the mode line or header
904 line or any horizontal divider.
906 If PIXELWISE is nil, return the largest integer smaller than WINDOW's
907 pixel height divided by the character height of WINDOW's frame. This
908 means that if a line at the bottom of the text area is only partially
909 visible, that line is not counted. */)
910 (Lisp_Object window
, Lisp_Object pixelwise
)
912 return make_number (window_body_height (decode_live_window (window
),
913 NILP (pixelwise
) ? 0 : 1));
916 DEFUN ("window-body-width", Fwindow_body_width
, Swindow_body_width
, 0, 2, 0,
917 doc
: /* Return the width of WINDOW's text area.
918 WINDOW must be a live window and defaults to the selected one. Optional
919 argument PIXELWISE non-nil means return the width in pixels. The return
920 value does not include any vertical dividers, fringes or marginal areas,
923 If PIXELWISE is nil, return the largest integer smaller than WINDOW's
924 pixel width divided by the character width of WINDOW's frame. This
925 means that if a column at the right of the text area is only partially
926 visible, that column is not counted. */)
927 (Lisp_Object window
, Lisp_Object pixelwise
)
929 return make_number (window_body_width (decode_live_window (window
),
930 NILP (pixelwise
) ? 0 : 1));
933 DEFUN ("window-mode-line-height", Fwindow_mode_line_height
,
934 Swindow_mode_line_height
, 0, 1, 0,
935 doc
: /* Return the height in pixels of WINDOW's mode-line.
936 WINDOW must be a live window and defaults to the selected one. */)
939 return (make_number (WINDOW_MODE_LINE_HEIGHT (decode_live_window (window
))));
942 DEFUN ("window-header-line-height", Fwindow_header_line_height
,
943 Swindow_header_line_height
, 0, 1, 0,
944 doc
: /* Return the height in pixels of WINDOW's header-line.
945 WINDOW must be a live window and defaults to the selected one. */)
948 return (make_number (WINDOW_HEADER_LINE_HEIGHT (decode_live_window (window
))));
951 DEFUN ("window-right-divider-width", Fwindow_right_divider_width
,
952 Swindow_right_divider_width
, 0, 1, 0,
953 doc
: /* Return the width in pixels of WINDOW's right divider.
954 WINDOW must be a live window and defaults to the selected one. */)
957 return (make_number (WINDOW_RIGHT_DIVIDER_WIDTH (decode_live_window (window
))));
960 DEFUN ("window-bottom-divider-width", Fwindow_bottom_divider_width
,
961 Swindow_bottom_divider_width
, 0, 1, 0,
962 doc
: /* Return the width in pixels of WINDOW's bottom divider.
963 WINDOW must be a live window and defaults to the selected one. */)
966 return (make_number (WINDOW_BOTTOM_DIVIDER_WIDTH (decode_live_window (window
))));
969 DEFUN ("window-hscroll", Fwindow_hscroll
, Swindow_hscroll
, 0, 1, 0,
970 doc
: /* Return the number of columns by which WINDOW is scrolled from left margin.
971 WINDOW must be a live window and defaults to the selected one. */)
974 return make_number (decode_live_window (window
)->hscroll
);
977 /* Set W's horizontal scroll amount to HSCROLL clipped to a reasonable
978 range, returning the new amount as a fixnum. */
980 set_window_hscroll (struct window
*w
, EMACS_INT hscroll
)
982 /* Horizontal scrolling has problems with large scroll amounts.
983 It's too slow with long lines, and even with small lines the
984 display can be messed up. For now, though, impose only the limits
985 required by the internal representation: horizontal scrolling must
986 fit in fixnum (since it's visible to Elisp) and into ptrdiff_t
987 (since it's stored in a ptrdiff_t). */
988 ptrdiff_t hscroll_max
= min (MOST_POSITIVE_FIXNUM
, PTRDIFF_MAX
);
989 ptrdiff_t new_hscroll
= clip_to_bounds (0, hscroll
, hscroll_max
);
991 /* Prevent redisplay shortcuts when changing the hscroll. */
992 if (w
->hscroll
!= new_hscroll
)
993 XBUFFER (w
->contents
)->prevent_redisplay_optimizations_p
= 1;
995 w
->hscroll
= new_hscroll
;
996 return make_number (new_hscroll
);
999 DEFUN ("set-window-hscroll", Fset_window_hscroll
, Sset_window_hscroll
, 2, 2, 0,
1000 doc
: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
1001 WINDOW must be a live window and defaults to the selected one.
1002 Clip the number to a reasonable value if out of range.
1003 Return the new number. NCOL should be zero or positive.
1005 Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
1006 window so that the location of point moves off-window. */)
1007 (Lisp_Object window
, Lisp_Object ncol
)
1009 CHECK_NUMBER (ncol
);
1010 return set_window_hscroll (decode_live_window (window
), XINT (ncol
));
1013 DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger
,
1014 Swindow_redisplay_end_trigger
, 0, 1, 0,
1015 doc
: /* Return WINDOW's redisplay end trigger value.
1016 WINDOW must be a live window and defaults to the selected one.
1017 See `set-window-redisplay-end-trigger' for more information. */)
1018 (Lisp_Object window
)
1020 return decode_live_window (window
)->redisplay_end_trigger
;
1023 DEFUN ("set-window-redisplay-end-trigger", Fset_window_redisplay_end_trigger
,
1024 Sset_window_redisplay_end_trigger
, 2, 2, 0,
1025 doc
: /* Set WINDOW's redisplay end trigger value to VALUE.
1026 WINDOW must be a live window and defaults to the selected one. VALUE
1027 should be a buffer position (typically a marker) or nil. If it is a
1028 buffer position, then if redisplay in WINDOW reaches a position beyond
1029 VALUE, the functions in `redisplay-end-trigger-functions' are called
1030 with two arguments: WINDOW, and the end trigger value. Afterwards the
1031 end-trigger value is reset to nil. */)
1032 (register Lisp_Object window
, Lisp_Object value
)
1034 wset_redisplay_end_trigger (decode_live_window (window
), value
);
1038 DEFUN ("window-edges", Fwindow_edges
, Swindow_edges
, 0, 1, 0,
1039 doc
: /* Return a list of the edge coordinates of WINDOW.
1040 WINDOW must be a valid window and defaults to the selected one.
1042 The returned list has the form (LEFT TOP RIGHT BOTTOM). TOP and BOTTOM
1043 count by lines, and LEFT and RIGHT count by columns, all relative to 0,
1044 0 at top left corner of frame.
1046 RIGHT is one more than the rightmost column occupied by WINDOW. BOTTOM
1047 is one more than the bottommost row occupied by WINDOW. The edges
1048 include the space used by WINDOW's scroll bar, display margins, fringes,
1049 header line, and/or mode line. For the edges of just the text area, use
1050 `window-inside-edges'. */)
1051 (Lisp_Object window
)
1053 register struct window
*w
= decode_valid_window (window
);
1055 return list4i (WINDOW_LEFT_EDGE_COL (w
), WINDOW_TOP_EDGE_LINE (w
),
1056 WINDOW_RIGHT_EDGE_COL (w
), WINDOW_BOTTOM_EDGE_LINE (w
));
1059 DEFUN ("window-pixel-edges", Fwindow_pixel_edges
, Swindow_pixel_edges
, 0, 1, 0,
1060 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
1061 WINDOW must be a valid window and defaults to the selected one.
1063 The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
1064 0, 0 at the top left corner of the frame.
1066 RIGHT is one more than the rightmost x position occupied by WINDOW.
1067 BOTTOM is one more than the bottommost y position occupied by WINDOW.
1068 The pixel edges include the space used by WINDOW's scroll bar, display
1069 margins, fringes, header line, and/or mode line. For the pixel edges
1070 of just the text area, use `window-inside-pixel-edges'. */)
1071 (Lisp_Object window
)
1073 register struct window
*w
= decode_valid_window (window
);
1075 return list4i (WINDOW_LEFT_EDGE_X (w
), WINDOW_TOP_EDGE_Y (w
),
1076 WINDOW_RIGHT_EDGE_X (w
), WINDOW_BOTTOM_EDGE_Y (w
));
1080 calc_absolute_offset (struct window
*w
, int *add_x
, int *add_y
)
1082 struct frame
*f
= XFRAME (w
->frame
);
1083 *add_y
= f
->top_pos
;
1084 #ifdef FRAME_MENUBAR_HEIGHT
1085 *add_y
+= FRAME_MENUBAR_HEIGHT (f
);
1087 #ifdef FRAME_TOOLBAR_TOP_HEIGHT
1088 *add_y
+= FRAME_TOOLBAR_TOP_HEIGHT (f
);
1089 #elif defined (FRAME_TOOLBAR_HEIGHT)
1090 *add_y
+= FRAME_TOOLBAR_HEIGHT (f
);
1092 #ifdef FRAME_NS_TITLEBAR_HEIGHT
1093 *add_y
+= FRAME_NS_TITLEBAR_HEIGHT (f
);
1095 *add_x
= f
->left_pos
;
1096 #ifdef FRAME_TOOLBAR_LEFT_WIDTH
1097 *add_x
+= FRAME_TOOLBAR_LEFT_WIDTH (f
);
1101 DEFUN ("window-absolute-pixel-edges", Fwindow_absolute_pixel_edges
,
1102 Swindow_absolute_pixel_edges
, 0, 1, 0,
1103 doc
: /* Return a list of the edge pixel coordinates of WINDOW.
1104 WINDOW must be a valid window and defaults to the selected one.
1106 The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
1107 0, 0 at the top left corner of the display.
1109 RIGHT is one more than the rightmost x position occupied by WINDOW.
1110 BOTTOM is one more than the bottommost y position occupied by WINDOW.
1111 The pixel edges include the space used by WINDOW's scroll bar, display
1112 margins, fringes, header line, and/or mode line. For the pixel edges
1113 of just the text area, use `window-inside-absolute-pixel-edges'. */)
1114 (Lisp_Object window
)
1116 register struct window
*w
= decode_valid_window (window
);
1119 calc_absolute_offset (w
, &add_x
, &add_y
);
1121 return list4i (WINDOW_LEFT_EDGE_X (w
) + add_x
,
1122 WINDOW_TOP_EDGE_Y (w
) + add_y
,
1123 WINDOW_RIGHT_EDGE_X (w
) + add_x
,
1124 WINDOW_BOTTOM_EDGE_Y (w
) + add_y
);
1127 DEFUN ("window-inside-edges", Fwindow_inside_edges
, Swindow_inside_edges
, 0, 1, 0,
1128 doc
: /* Return a list of the edge coordinates of WINDOW.
1129 WINDOW must be a live window and defaults to the selected one.
1131 The returned list has the form (LEFT TOP RIGHT BOTTOM). TOP and BOTTOM
1132 count by lines, and LEFT and RIGHT count by columns, all relative to 0,
1133 0 at top left corner of frame.
1135 RIGHT is one more than the rightmost column of WINDOW's text area.
1136 BOTTOM is one more than the bottommost row of WINDOW's text area. The
1137 inside edges do not include the space used by the WINDOW's scroll bar,
1138 display margins, fringes, header line, and/or mode line. */)
1139 (Lisp_Object window
)
1141 register struct window
*w
= decode_live_window (window
);
1143 return list4i ((WINDOW_BOX_LEFT_EDGE_COL (w
)
1144 + WINDOW_LEFT_MARGIN_COLS (w
)
1145 + WINDOW_LEFT_FRINGE_COLS (w
)),
1146 (WINDOW_TOP_EDGE_LINE (w
)
1147 + WINDOW_HEADER_LINE_LINES (w
)),
1148 (WINDOW_BOX_RIGHT_EDGE_COL (w
)
1149 - WINDOW_RIGHT_MARGIN_COLS (w
)
1150 - WINDOW_RIGHT_FRINGE_COLS (w
)),
1151 (WINDOW_BOTTOM_EDGE_LINE (w
)
1152 - WINDOW_MODE_LINE_LINES (w
)));
1155 DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges
, Swindow_inside_pixel_edges
, 0, 1, 0,
1156 doc
: /* Return a list of the edge pixel coordinates of WINDOW's text area.
1157 WINDOW must be a live window and defaults to the selected one.
1159 The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
1160 (0,0) at the top left corner of the frame's window area.
1162 RIGHT is one more than the rightmost x position of WINDOW's text area.
1163 BOTTOM is one more than the bottommost y position of WINDOW's text area.
1164 The inside edges do not include the space used by WINDOW's scroll bar,
1165 display margins, fringes, header line, and/or mode line. */)
1166 (Lisp_Object window
)
1168 register struct window
*w
= decode_live_window (window
);
1170 return list4i ((WINDOW_BOX_LEFT_EDGE_X (w
)
1171 + WINDOW_LEFT_MARGIN_WIDTH (w
)
1172 + WINDOW_LEFT_FRINGE_WIDTH (w
)),
1173 (WINDOW_TOP_EDGE_Y (w
)
1174 + WINDOW_HEADER_LINE_HEIGHT (w
)),
1175 (WINDOW_BOX_RIGHT_EDGE_X (w
)
1176 - WINDOW_RIGHT_MARGIN_WIDTH (w
)
1177 - WINDOW_RIGHT_FRINGE_WIDTH (w
)),
1178 (WINDOW_BOTTOM_EDGE_Y (w
)
1179 - WINDOW_MODE_LINE_HEIGHT (w
)));
1182 DEFUN ("window-inside-absolute-pixel-edges",
1183 Fwindow_inside_absolute_pixel_edges
,
1184 Swindow_inside_absolute_pixel_edges
, 0, 1, 0,
1185 doc
: /* Return a list of the edge pixel coordinates of WINDOW's text area.
1186 WINDOW must be a live window and defaults to the selected one.
1188 The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
1189 (0,0) at the top left corner of the frame's window area.
1191 RIGHT is one more than the rightmost x position of WINDOW's text area.
1192 BOTTOM is one more than the bottommost y position of WINDOW's text area.
1193 The inside edges do not include the space used by WINDOW's scroll bar,
1194 display margins, fringes, header line, and/or mode line. */)
1195 (Lisp_Object window
)
1197 register struct window
*w
= decode_live_window (window
);
1200 calc_absolute_offset (w
, &add_x
, &add_y
);
1202 return list4i ((WINDOW_BOX_LEFT_EDGE_X (w
)
1203 + WINDOW_LEFT_MARGIN_WIDTH (w
)
1204 + WINDOW_LEFT_FRINGE_WIDTH (w
) + add_x
),
1205 (WINDOW_TOP_EDGE_Y (w
)
1206 + WINDOW_HEADER_LINE_HEIGHT (w
) + add_y
),
1207 (WINDOW_BOX_RIGHT_EDGE_X (w
)
1208 - WINDOW_RIGHT_MARGIN_WIDTH (w
)
1209 - WINDOW_RIGHT_FRINGE_WIDTH (w
) + add_x
),
1210 (WINDOW_BOTTOM_EDGE_Y (w
)
1211 - WINDOW_MODE_LINE_HEIGHT (w
) + add_y
));
1214 /* Test if the character at column X, row Y is within window W.
1215 If it is not, return ON_NOTHING;
1216 if it is on the window's vertical divider, return
1218 if it is on the window's horizontal divider, return
1220 if it is in the window's text area, return ON_TEXT;
1221 if it is on the window's modeline, return ON_MODE_LINE;
1222 if it is on the border between the window and its right sibling,
1223 return ON_VERTICAL_BORDER;
1224 if it is on a scroll bar, return ON_SCROLL_BAR;
1225 if it is on the window's top line, return ON_HEADER_LINE;
1226 if it is in left or right fringe of the window,
1227 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE;
1228 if it is in the marginal area to the left/right of the window,
1229 return ON_LEFT_MARGIN or ON_RIGHT_MARGIN.
1231 X and Y are frame relative pixel coordinates. */
1233 static enum window_part
1234 coordinates_in_window (register struct window
*w
, int x
, int y
)
1236 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1237 enum window_part part
;
1238 int ux
= FRAME_COLUMN_WIDTH (f
);
1239 int left_x
= WINDOW_LEFT_EDGE_X (w
);
1240 int right_x
= WINDOW_RIGHT_EDGE_X (w
);
1241 int top_y
= WINDOW_TOP_EDGE_Y (w
);
1242 int bottom_y
= WINDOW_BOTTOM_EDGE_Y (w
);
1243 /* The width of the area where the vertical line can be dragged.
1244 (Between mode lines for instance. */
1245 int grabbable_width
= ux
;
1246 int lmargin_width
, rmargin_width
, text_left
, text_right
;
1248 /* Outside any interesting row or column? */
1249 if (y
< top_y
|| y
>= bottom_y
|| x
< left_x
|| x
>= right_x
)
1252 /* On vertical window divider (which prevails horizontal
1254 if (!WINDOW_RIGHTMOST_P (w
)
1255 && WINDOW_RIGHT_DIVIDER_WIDTH (w
)
1256 && x
>= right_x
- WINDOW_RIGHT_DIVIDER_WIDTH (w
)
1258 return ON_RIGHT_DIVIDER
;
1259 /* On the horizontal window divider? */
1260 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w
)
1261 && y
>= (bottom_y
- WINDOW_BOTTOM_DIVIDER_WIDTH (w
))
1263 return ON_BOTTOM_DIVIDER
;
1264 /* On the mode or header line? */
1265 else if ((WINDOW_WANTS_MODELINE_P (w
)
1267 - CURRENT_MODE_LINE_HEIGHT (w
)
1268 - WINDOW_BOTTOM_DIVIDER_WIDTH (w
))
1269 && y
<= bottom_y
- WINDOW_BOTTOM_DIVIDER_WIDTH (w
)
1270 && (part
= ON_MODE_LINE
))
1271 || (WINDOW_WANTS_HEADER_LINE_P (w
)
1272 && y
< top_y
+ CURRENT_HEADER_LINE_HEIGHT (w
)
1273 && (part
= ON_HEADER_LINE
)))
1275 /* If it's under/over the scroll bar portion of the mode/header
1276 line, say it's on the vertical line. That's to be able to
1277 resize windows horizontally in case we're using toolkit scroll
1278 bars. Note: If scrollbars are on the left, the window that
1279 must be eventually resized is that on the left of WINDOW. */
1280 if ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
1281 && !WINDOW_LEFTMOST_P (w
)
1282 && eabs (x
- left_x
) < grabbable_width
)
1283 || (!WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
1284 && !WINDOW_RIGHTMOST_P (w
)
1285 && eabs (x
- right_x
) < grabbable_width
))
1286 return ON_VERTICAL_BORDER
;
1291 /* In what's below, we subtract 1 when computing right_x because we
1292 want the rightmost pixel, which is given by left_pixel+width-1. */
1293 if (w
->pseudo_window_p
)
1296 right_x
= WINDOW_PIXEL_WIDTH (w
) - 1;
1300 left_x
= WINDOW_BOX_LEFT_EDGE_X (w
);
1301 right_x
= WINDOW_BOX_RIGHT_EDGE_X (w
) - 1;
1304 /* Outside any interesting column? */
1305 if (x
< left_x
|| x
> right_x
)
1306 return ON_SCROLL_BAR
;
1308 lmargin_width
= window_box_width (w
, LEFT_MARGIN_AREA
);
1309 rmargin_width
= window_box_width (w
, RIGHT_MARGIN_AREA
);
1311 text_left
= window_box_left (w
, TEXT_AREA
);
1312 text_right
= text_left
+ window_box_width (w
, TEXT_AREA
);
1314 if (FRAME_WINDOW_P (f
))
1316 if (!w
->pseudo_window_p
1317 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
)
1318 && !WINDOW_RIGHTMOST_P (w
)
1319 && (eabs (x
- right_x
) < grabbable_width
))
1320 return ON_VERTICAL_BORDER
;
1322 /* Need to say "x > right_x" rather than >=, since on character
1323 terminals, the vertical line's x coordinate is right_x. */
1324 else if (!w
->pseudo_window_p
1325 && !WINDOW_RIGHTMOST_P (w
)
1326 /* Why check ux if we are not the rightmost window? Also
1327 shouldn't a pseudo window always be rightmost? */
1328 && x
> right_x
- ux
)
1329 return ON_VERTICAL_BORDER
;
1333 if (lmargin_width
> 0
1334 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1335 ? (x
>= left_x
+ WINDOW_LEFT_FRINGE_WIDTH (w
))
1336 : (x
< left_x
+ lmargin_width
)))
1337 return ON_LEFT_MARGIN
;
1339 return ON_LEFT_FRINGE
;
1342 if (x
>= text_right
)
1344 if (rmargin_width
> 0
1345 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
1346 ? (x
< right_x
- WINDOW_RIGHT_FRINGE_WIDTH (w
))
1347 : (x
>= right_x
- rmargin_width
)))
1348 return ON_RIGHT_MARGIN
;
1350 return ON_RIGHT_FRINGE
;
1353 /* Everything special ruled out - must be on text area */
1357 /* Take X is the frame-relative pixel x-coordinate, and return the
1358 x-coordinate relative to part PART of window W. */
1360 window_relative_x_coord (struct window
*w
, enum window_part part
, int x
)
1362 int left_x
= (w
->pseudo_window_p
) ? 0 : WINDOW_BOX_LEFT_EDGE_X (w
);
1367 return x
- window_box_left (w
, TEXT_AREA
);
1369 case ON_LEFT_FRINGE
:
1372 case ON_RIGHT_FRINGE
:
1373 return x
- left_x
- WINDOW_LEFT_FRINGE_WIDTH (w
);
1375 case ON_LEFT_MARGIN
:
1377 - ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1378 ? WINDOW_LEFT_FRINGE_WIDTH (w
) : 0));
1380 case ON_RIGHT_MARGIN
:
1382 - ((w
->pseudo_window_p
)
1383 ? WINDOW_PIXEL_WIDTH (w
)
1384 : WINDOW_BOX_RIGHT_EDGE_X (w
))
1385 + window_box_width (w
, RIGHT_MARGIN_AREA
)
1386 + ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
))
1387 ? WINDOW_RIGHT_FRINGE_WIDTH (w
) : 0));
1390 /* ON_SCROLL_BAR, ON_NOTHING, and ON_VERTICAL_BORDER: */
1395 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p
,
1396 Scoordinates_in_window_p
, 2, 2, 0,
1397 doc
: /* Return non-nil if COORDINATES are in WINDOW.
1398 WINDOW must be a live window and defaults to the selected one.
1399 COORDINATES is a cons of the form (X . Y), X and Y being distances
1400 measured in characters from the upper-left corner of the frame.
1401 \(0 . 0) denotes the character in the upper left corner of the
1403 If COORDINATES are in the text portion of WINDOW,
1404 the coordinates relative to the window are returned.
1405 If they are in the mode line of WINDOW, `mode-line' is returned.
1406 If they are in the top mode line of WINDOW, `header-line' is returned.
1407 If they are in the left fringe of WINDOW, `left-fringe' is returned.
1408 If they are in the right fringe of WINDOW, `right-fringe' is returned.
1409 If they are on the border between WINDOW and its right sibling,
1410 `vertical-line' is returned.
1411 If they are in the windows's left or right marginal areas, `left-margin'\n\
1412 or `right-margin' is returned. */)
1413 (register Lisp_Object coordinates
, Lisp_Object window
)
1420 w
= decode_live_window (window
);
1421 f
= XFRAME (w
->frame
);
1422 CHECK_CONS (coordinates
);
1423 lx
= Fcar (coordinates
);
1424 ly
= Fcdr (coordinates
);
1425 CHECK_NUMBER_OR_FLOAT (lx
);
1426 CHECK_NUMBER_OR_FLOAT (ly
);
1427 x
= FRAME_PIXEL_X_FROM_CANON_X (f
, lx
) + FRAME_INTERNAL_BORDER_WIDTH (f
);
1428 y
= FRAME_PIXEL_Y_FROM_CANON_Y (f
, ly
) + FRAME_INTERNAL_BORDER_WIDTH (f
);
1430 switch (coordinates_in_window (w
, x
, y
))
1436 /* Convert X and Y to window relative pixel coordinates, and
1437 return the canonical char units. */
1438 x
-= window_box_left (w
, TEXT_AREA
);
1439 y
-= WINDOW_TOP_EDGE_Y (w
);
1440 return Fcons (FRAME_CANON_X_FROM_PIXEL_X (f
, x
),
1441 FRAME_CANON_Y_FROM_PIXEL_Y (f
, y
));
1446 case ON_VERTICAL_BORDER
:
1447 return Qvertical_line
;
1449 case ON_HEADER_LINE
:
1450 return Qheader_line
;
1452 case ON_LEFT_FRINGE
:
1453 return Qleft_fringe
;
1455 case ON_RIGHT_FRINGE
:
1456 return Qright_fringe
;
1458 case ON_LEFT_MARGIN
:
1459 return Qleft_margin
;
1461 case ON_RIGHT_MARGIN
:
1462 return Qright_margin
;
1465 /* Historically we are supposed to return nil in this case. */
1468 case ON_RIGHT_DIVIDER
:
1469 return Qright_divider
;
1471 case ON_BOTTOM_DIVIDER
:
1472 return Qbottom_divider
;
1480 /* Callback for foreach_window, used in window_from_coordinates.
1481 Check if window W contains coordinates specified by USER_DATA which
1482 is actually a pointer to a struct check_window_data CW.
1484 Check if window W contains coordinates *CW->x and *CW->y. If it
1485 does, return W in *CW->window, as Lisp_Object, and return in
1486 *CW->part the part of the window under coordinates *X,*Y. Return
1487 zero from this function to stop iterating over windows. */
1489 struct check_window_data
1491 Lisp_Object
*window
;
1493 enum window_part
*part
;
1497 check_window_containing (struct window
*w
, void *user_data
)
1499 struct check_window_data
*cw
= user_data
;
1500 enum window_part found
;
1503 found
= coordinates_in_window (w
, cw
->x
, cw
->y
);
1504 if (found
!= ON_NOTHING
)
1507 XSETWINDOW (*cw
->window
, w
);
1515 /* Find the window containing frame-relative pixel position X/Y and
1516 return it as a Lisp_Object.
1518 If X, Y is on one of the window's special `window_part' elements,
1519 set *PART to the id of that element.
1521 If there is no window under X, Y return nil and leave *PART
1522 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows.
1524 This function was previously implemented with a loop cycling over
1525 windows with Fnext_window, and starting with the frame's selected
1526 window. It turned out that this doesn't work with an
1527 implementation of next_window using Vwindow_list, because
1528 FRAME_SELECTED_WINDOW (F) is not always contained in the window
1529 tree of F when this function is called asynchronously from
1530 note_mouse_highlight. The original loop didn't terminate in this
1534 window_from_coordinates (struct frame
*f
, int x
, int y
,
1535 enum window_part
*part
, bool tool_bar_p
)
1538 struct check_window_data cw
;
1539 enum window_part dummy
;
1545 cw
.window
= &window
, cw
.x
= x
, cw
.y
= y
; cw
.part
= part
;
1546 foreach_window (f
, check_window_containing
, &cw
);
1548 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
1549 /* If not found above, see if it's in the tool bar window, if a tool
1553 && WINDOWP (f
->tool_bar_window
)
1554 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0
1555 && (coordinates_in_window (XWINDOW (f
->tool_bar_window
), x
, y
)
1559 window
= f
->tool_bar_window
;
1566 DEFUN ("window-at", Fwindow_at
, Swindow_at
, 2, 3, 0,
1567 doc
: /* Return window containing coordinates X and Y on FRAME.
1568 FRAME must be a live frame and defaults to the selected one.
1569 The top left corner of the frame is considered to be row 0,
1571 (Lisp_Object x
, Lisp_Object y
, Lisp_Object frame
)
1573 struct frame
*f
= decode_live_frame (frame
);
1575 /* Check that arguments are integers or floats. */
1576 CHECK_NUMBER_OR_FLOAT (x
);
1577 CHECK_NUMBER_OR_FLOAT (y
);
1579 return window_from_coordinates (f
,
1580 (FRAME_PIXEL_X_FROM_CANON_X (f
, x
)
1581 + FRAME_INTERNAL_BORDER_WIDTH (f
)),
1582 (FRAME_PIXEL_Y_FROM_CANON_Y (f
, y
)
1583 + FRAME_INTERNAL_BORDER_WIDTH (f
)),
1587 DEFUN ("window-point", Fwindow_point
, Swindow_point
, 0, 1, 0,
1588 doc
: /* Return current value of point in WINDOW.
1589 WINDOW must be a live window and defaults to the selected one.
1591 For a nonselected window, this is the value point would have if that
1592 window were selected.
1594 Note that, when WINDOW is selected, the value returned is the same as
1595 that returned by `point' for WINDOW's buffer. It would be more strictly
1596 correct to return the top-level value of `point', outside of any
1597 `save-excursion' forms. But that is hard to define. */)
1598 (Lisp_Object window
)
1600 register struct window
*w
= decode_live_window (window
);
1602 if (w
== XWINDOW (selected_window
))
1603 return make_number (BUF_PT (XBUFFER (w
->contents
)));
1605 return Fmarker_position (w
->pointm
);
1608 DEFUN ("window-start", Fwindow_start
, Swindow_start
, 0, 1, 0,
1609 doc
: /* Return position at which display currently starts in WINDOW.
1610 WINDOW must be a live window and defaults to the selected one.
1611 This is updated by redisplay or by calling `set-window-start'. */)
1612 (Lisp_Object window
)
1614 return Fmarker_position (decode_live_window (window
)->start
);
1617 /* This is text temporarily removed from the doc string below.
1619 This function returns nil if the position is not currently known.
1620 That happens when redisplay is preempted and doesn't finish.
1621 If in that case you want to compute where the end of the window would
1622 have been if redisplay had finished, do this:
1624 (goto-char (window-start window))
1625 (vertical-motion (1- (window-height window)) window)
1628 DEFUN ("window-end", Fwindow_end
, Swindow_end
, 0, 2, 0,
1629 doc
: /* Return position at which display currently ends in WINDOW.
1630 WINDOW must be a live window and defaults to the selected one.
1631 This is updated by redisplay, when it runs to completion.
1632 Simply changing the buffer text or setting `window-start'
1633 does not update this value.
1634 Return nil if there is no recorded value. (This can happen if the
1635 last redisplay of WINDOW was preempted, and did not finish.)
1636 If UPDATE is non-nil, compute the up-to-date position
1637 if it isn't already recorded. */)
1638 (Lisp_Object window
, Lisp_Object update
)
1641 struct window
*w
= decode_live_window (window
);
1650 && (windows_or_buffers_changed
1651 || !w
->window_end_valid
1653 || b
->prevent_redisplay_optimizations_p
1654 || window_outdated (w
))
1657 struct text_pos startp
;
1659 struct buffer
*old_buffer
= NULL
;
1660 void *itdata
= NULL
;
1662 /* Cannot use Fvertical_motion because that function doesn't
1663 cope with variable-height lines. */
1664 if (b
!= current_buffer
)
1666 old_buffer
= current_buffer
;
1667 set_buffer_internal (b
);
1670 /* In case W->start is out of the range, use something
1671 reasonable. This situation occurred when loading a file with
1672 `-l' containing a call to `rmail' with subsequent other
1673 commands. At the end, W->start happened to be BEG, while
1674 rmail had already narrowed the buffer. */
1675 CLIP_TEXT_POS_FROM_MARKER (startp
, w
->start
);
1677 itdata
= bidi_shelve_cache ();
1678 start_display (&it
, w
, startp
);
1679 move_it_vertically (&it
, window_box_height (w
));
1680 if (it
.current_y
< it
.last_visible_y
)
1681 move_it_past_eol (&it
);
1682 value
= make_number (IT_CHARPOS (it
));
1683 bidi_unshelve_cache (itdata
, 0);
1686 set_buffer_internal (old_buffer
);
1689 XSETINT (value
, BUF_Z (b
) - w
->window_end_pos
);
1694 DEFUN ("set-window-point", Fset_window_point
, Sset_window_point
, 2, 2, 0,
1695 doc
: /* Make point value in WINDOW be at position POS in WINDOW's buffer.
1696 WINDOW must be a live window and defaults to the selected one.
1698 (Lisp_Object window
, Lisp_Object pos
)
1700 register struct window
*w
= decode_live_window (window
);
1702 /* Type of POS is checked by Fgoto_char or set_marker_restricted ... */
1704 if (w
== XWINDOW (selected_window
))
1706 if (XBUFFER (w
->contents
) == current_buffer
)
1710 struct buffer
*old_buffer
= current_buffer
;
1712 /* ... but here we want to catch type error before buffer change. */
1713 CHECK_NUMBER_COERCE_MARKER (pos
);
1714 set_buffer_internal (XBUFFER (w
->contents
));
1716 set_buffer_internal (old_buffer
);
1721 set_marker_restricted (w
->pointm
, pos
, w
->contents
);
1722 /* We have to make sure that redisplay updates the window to show
1723 the new value of point. */
1730 DEFUN ("set-window-start", Fset_window_start
, Sset_window_start
, 2, 3, 0,
1731 doc
: /* Make display in WINDOW start at position POS in WINDOW's buffer.
1732 WINDOW must be a live window and defaults to the selected one. Return
1733 POS. Optional third arg NOFORCE non-nil inhibits next redisplay from
1734 overriding motion of point in order to display at this exact start. */)
1735 (Lisp_Object window
, Lisp_Object pos
, Lisp_Object noforce
)
1737 register struct window
*w
= decode_live_window (window
);
1739 set_marker_restricted (w
->start
, pos
, w
->contents
);
1740 /* This is not right, but much easier than doing what is right. */
1741 w
->start_at_line_beg
= 0;
1744 w
->update_mode_line
= 1;
1746 w
->window_end_valid
= 0;
1752 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p
,
1753 Spos_visible_in_window_p
, 0, 3, 0,
1754 doc
: /* Return non-nil if position POS is currently on the frame in WINDOW.
1755 WINDOW must be a live window and defaults to the selected one.
1757 Return nil if that position is scrolled vertically out of view. If a
1758 character is only partially visible, nil is returned, unless the
1759 optional argument PARTIALLY is non-nil. If POS is only out of view
1760 because of horizontal scrolling, return non-nil. If POS is t, it
1761 specifies the position of the last visible glyph in WINDOW. POS
1762 defaults to point in WINDOW; WINDOW defaults to the selected window.
1764 If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
1765 the return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
1766 where X and Y are the pixel coordinates relative to the top left corner
1767 of the window. The remaining elements are omitted if the character after
1768 POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
1769 off-window at the top and bottom of the screen line ("row") containing
1770 POS, ROWH is the visible height of that row, and VPOS is the row number
1772 (Lisp_Object pos
, Lisp_Object window
, Lisp_Object partially
)
1774 register struct window
*w
;
1775 register EMACS_INT posint
;
1776 register struct buffer
*buf
;
1777 struct text_pos top
;
1778 Lisp_Object in_window
= Qnil
;
1779 int rtop
, rbot
, rowh
, vpos
, fully_p
= 1;
1782 w
= decode_live_window (window
);
1783 buf
= XBUFFER (w
->contents
);
1784 SET_TEXT_POS_FROM_MARKER (top
, w
->start
);
1788 else if (!NILP (pos
))
1790 CHECK_NUMBER_COERCE_MARKER (pos
);
1791 posint
= XINT (pos
);
1793 else if (w
== XWINDOW (selected_window
))
1796 posint
= marker_position (w
->pointm
);
1798 /* If position is above window start or outside buffer boundaries,
1799 or if window start is out of range, position is not visible. */
1801 || (posint
>= CHARPOS (top
) && posint
<= BUF_ZV (buf
)))
1802 && CHARPOS (top
) >= BUF_BEGV (buf
)
1803 && CHARPOS (top
) <= BUF_ZV (buf
)
1804 && pos_visible_p (w
, posint
, &x
, &y
, &rtop
, &rbot
, &rowh
, &vpos
)
1805 && (fully_p
= !rtop
&& !rbot
, (!NILP (partially
) || fully_p
)))
1808 if (!NILP (in_window
) && !NILP (partially
))
1810 Lisp_Object part
= Qnil
;
1812 part
= list4i (rtop
, rbot
, rowh
, vpos
);
1813 in_window
= Fcons (make_number (x
),
1814 Fcons (make_number (y
), part
));
1820 DEFUN ("window-line-height", Fwindow_line_height
,
1821 Swindow_line_height
, 0, 2, 0,
1822 doc
: /* Return height in pixels of text line LINE in window WINDOW.
1823 WINDOW must be a live window and defaults to the selected one.
1825 Return height of current line if LINE is omitted or nil. Return height of
1826 header or mode line if LINE is `header-line' or `mode-line'.
1827 Otherwise, LINE is a text line number starting from 0. A negative number
1828 counts from the end of the window.
1830 Value is a list (HEIGHT VPOS YPOS OFFBOT), where HEIGHT is the height
1831 in pixels of the visible part of the line, VPOS and YPOS are the
1832 vertical position in lines and pixels of the line, relative to the top
1833 of the first text line, and OFFBOT is the number of off-window pixels at
1834 the bottom of the text line. If there are off-window pixels at the top
1835 of the (first) text line, YPOS is negative.
1837 Return nil if window display is not up-to-date. In that case, use
1838 `pos-visible-in-window-p' to obtain the information. */)
1839 (Lisp_Object line
, Lisp_Object window
)
1841 register struct window
*w
;
1842 register struct buffer
*b
;
1843 struct glyph_row
*row
, *end_row
;
1847 w
= decode_live_window (window
);
1849 if (noninteractive
|| w
->pseudo_window_p
)
1852 CHECK_BUFFER (w
->contents
);
1853 b
= XBUFFER (w
->contents
);
1855 /* Fail if current matrix is not up-to-date. */
1856 if (!w
->window_end_valid
1857 || windows_or_buffers_changed
1859 || b
->prevent_redisplay_optimizations_p
1860 || window_outdated (w
))
1866 if (i
< 0 || i
>= w
->current_matrix
->nrows
1867 || (row
= MATRIX_ROW (w
->current_matrix
, i
), !row
->enabled_p
))
1869 max_y
= window_text_bottom_y (w
);
1873 if (EQ (line
, Qheader_line
))
1875 if (!WINDOW_WANTS_HEADER_LINE_P (w
))
1877 row
= MATRIX_HEADER_LINE_ROW (w
->current_matrix
);
1878 return row
->enabled_p
? list4i (row
->height
, 0, 0, 0) : Qnil
;
1881 if (EQ (line
, Qmode_line
))
1883 row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
);
1884 return (row
->enabled_p
?
1885 list4i (row
->height
,
1886 0, /* not accurate */
1887 (WINDOW_HEADER_LINE_HEIGHT (w
)
1888 + window_text_bottom_y (w
)),
1893 CHECK_NUMBER (line
);
1896 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
1897 end_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
1898 max_y
= window_text_bottom_y (w
);
1901 while ((n
< 0 || i
< n
)
1902 && row
<= end_row
&& row
->enabled_p
1903 && row
->y
+ row
->height
< max_y
)
1906 if (row
> end_row
|| !row
->enabled_p
)
1918 crop
= max (0, (row
->y
+ row
->height
) - max_y
);
1919 return list4i (row
->height
+ min (0, row
->y
) - crop
, i
, row
->y
, crop
);
1922 DEFUN ("window-dedicated-p", Fwindow_dedicated_p
, Swindow_dedicated_p
,
1924 doc
: /* Return non-nil when WINDOW is dedicated to its buffer.
1925 More precisely, return the value assigned by the last call of
1926 `set-window-dedicated-p' for WINDOW. Return nil if that function was
1927 never called with WINDOW as its argument, or the value set by that
1928 function was internally reset since its last call. WINDOW must be a
1929 live window and defaults to the selected one.
1931 When a window is dedicated to its buffer, `display-buffer' will refrain
1932 from displaying another buffer in it. `get-lru-window' and
1933 `get-largest-window' treat dedicated windows specially.
1934 `delete-windows-on', `replace-buffer-in-windows', `quit-window' and
1935 `kill-buffer' can delete a dedicated window and the containing frame.
1937 Functions like `set-window-buffer' may change the buffer displayed by a
1938 window, unless that window is "strongly" dedicated to its buffer, that
1939 is the value returned by `window-dedicated-p' is t. */)
1940 (Lisp_Object window
)
1942 return decode_live_window (window
)->dedicated
;
1945 DEFUN ("set-window-dedicated-p", Fset_window_dedicated_p
,
1946 Sset_window_dedicated_p
, 2, 2, 0,
1947 doc
: /* Mark WINDOW as dedicated according to FLAG.
1948 WINDOW must be a live window and defaults to the selected one. FLAG
1949 non-nil means mark WINDOW as dedicated to its buffer. FLAG nil means
1950 mark WINDOW as non-dedicated. Return FLAG.
1952 When a window is dedicated to its buffer, `display-buffer' will refrain
1953 from displaying another buffer in it. `get-lru-window' and
1954 `get-largest-window' treat dedicated windows specially.
1955 `delete-windows-on', `replace-buffer-in-windows', `quit-window',
1956 `quit-restore-window' and `kill-buffer' can delete a dedicated window
1957 and the containing frame.
1959 As a special case, if FLAG is t, mark WINDOW as "strongly" dedicated to
1960 its buffer. Functions like `set-window-buffer' may change the buffer
1961 displayed by a window, unless that window is strongly dedicated to its
1962 buffer. If and when `set-window-buffer' displays another buffer in a
1963 window, it also makes sure that the window is no more dedicated. */)
1964 (Lisp_Object window
, Lisp_Object flag
)
1966 wset_dedicated (decode_live_window (window
), flag
);
1970 DEFUN ("window-prev-buffers", Fwindow_prev_buffers
, Swindow_prev_buffers
,
1972 doc
: /* Return buffers previously shown in WINDOW.
1973 WINDOW must be a live window and defaults to the selected one.
1975 The return value is a list of elements (BUFFER WINDOW-START POS),
1976 where BUFFER is a buffer, WINDOW-START is the start position of the
1977 window for that buffer, and POS is a window-specific point value. */)
1978 (Lisp_Object window
)
1980 return decode_live_window (window
)->prev_buffers
;
1983 DEFUN ("set-window-prev-buffers", Fset_window_prev_buffers
,
1984 Sset_window_prev_buffers
, 2, 2, 0,
1985 doc
: /* Set WINDOW's previous buffers to PREV-BUFFERS.
1986 WINDOW must be a live window and defaults to the selected one.
1988 PREV-BUFFERS should be a list of elements (BUFFER WINDOW-START POS),
1989 where BUFFER is a buffer, WINDOW-START is the start position of the
1990 window for that buffer, and POS is a window-specific point value. */)
1991 (Lisp_Object window
, Lisp_Object prev_buffers
)
1993 wset_prev_buffers (decode_live_window (window
), prev_buffers
);
1994 return prev_buffers
;
1997 DEFUN ("window-next-buffers", Fwindow_next_buffers
, Swindow_next_buffers
,
1999 doc
: /* Return list of buffers recently re-shown in WINDOW.
2000 WINDOW must be a live window and defaults to the selected one. */)
2001 (Lisp_Object window
)
2003 return decode_live_window (window
)->next_buffers
;
2006 DEFUN ("set-window-next-buffers", Fset_window_next_buffers
,
2007 Sset_window_next_buffers
, 2, 2, 0,
2008 doc
: /* Set WINDOW's next buffers to NEXT-BUFFERS.
2009 WINDOW must be a live window and defaults to the selected one.
2010 NEXT-BUFFERS should be a list of buffers. */)
2011 (Lisp_Object window
, Lisp_Object next_buffers
)
2013 wset_next_buffers (decode_live_window (window
), next_buffers
);
2014 return next_buffers
;
2017 DEFUN ("window-parameters", Fwindow_parameters
, Swindow_parameters
,
2019 doc
: /* Return the parameters of WINDOW and their values.
2020 WINDOW must be a valid window and defaults to the selected one. The
2021 return value is a list of elements of the form (PARAMETER . VALUE). */)
2022 (Lisp_Object window
)
2024 return Fcopy_alist (decode_valid_window (window
)->window_parameters
);
2027 DEFUN ("window-parameter", Fwindow_parameter
, Swindow_parameter
,
2029 doc
: /* Return WINDOW's value for PARAMETER.
2030 WINDOW can be any window and defaults to the selected one. */)
2031 (Lisp_Object window
, Lisp_Object parameter
)
2035 result
= Fassq (parameter
, decode_any_window (window
)->window_parameters
);
2036 return CDR_SAFE (result
);
2039 DEFUN ("set-window-parameter", Fset_window_parameter
,
2040 Sset_window_parameter
, 3, 3, 0,
2041 doc
: /* Set WINDOW's value of PARAMETER to VALUE.
2042 WINDOW can be any window and defaults to the selected one.
2044 (Lisp_Object window
, Lisp_Object parameter
, Lisp_Object value
)
2046 register struct window
*w
= decode_any_window (window
);
2047 Lisp_Object old_alist_elt
;
2049 old_alist_elt
= Fassq (parameter
, w
->window_parameters
);
2050 if (NILP (old_alist_elt
))
2051 wset_window_parameters
2052 (w
, Fcons (Fcons (parameter
, value
), w
->window_parameters
));
2054 Fsetcdr (old_alist_elt
, value
);
2058 DEFUN ("window-display-table", Fwindow_display_table
, Swindow_display_table
,
2060 doc
: /* Return the display-table that WINDOW is using.
2061 WINDOW must be a live window and defaults to the selected one. */)
2062 (Lisp_Object window
)
2064 return decode_live_window (window
)->display_table
;
2067 /* Get the display table for use on window W. This is either W's
2068 display table or W's buffer's display table. Ignore the specified
2069 tables if they are not valid; if no valid table is specified,
2072 struct Lisp_Char_Table
*
2073 window_display_table (struct window
*w
)
2075 struct Lisp_Char_Table
*dp
= NULL
;
2077 if (DISP_TABLE_P (w
->display_table
))
2078 dp
= XCHAR_TABLE (w
->display_table
);
2079 else if (BUFFERP (w
->contents
))
2081 struct buffer
*b
= XBUFFER (w
->contents
);
2083 if (DISP_TABLE_P (BVAR (b
, display_table
)))
2084 dp
= XCHAR_TABLE (BVAR (b
, display_table
));
2085 else if (DISP_TABLE_P (Vstandard_display_table
))
2086 dp
= XCHAR_TABLE (Vstandard_display_table
);
2092 DEFUN ("set-window-display-table", Fset_window_display_table
, Sset_window_display_table
, 2, 2, 0,
2093 doc
: /* Set WINDOW's display-table to TABLE.
2094 WINDOW must be a live window and defaults to the selected one. */)
2095 (register Lisp_Object window
, Lisp_Object table
)
2097 wset_display_table (decode_live_window (window
), table
);
2101 /* Record info on buffer window W is displaying
2102 when it is about to cease to display that buffer. */
2104 unshow_buffer (register struct window
*w
)
2106 Lisp_Object buf
= w
->contents
;
2107 struct buffer
*b
= XBUFFER (buf
);
2109 eassert (b
== XMARKER (w
->pointm
)->buffer
);
2112 if (w
== XWINDOW (selected_window
)
2113 || ! EQ (buf
, XWINDOW (selected_window
)->contents
))
2114 /* Do this except when the selected window's buffer
2115 is being removed from some other window. */
2117 /* last_window_start records the start position that this buffer
2118 had in the last window to be disconnected from it.
2119 Now that this statement is unconditional,
2120 it is possible for the buffer to be displayed in the
2121 selected window, while last_window_start reflects another
2122 window which was recently showing the same buffer.
2123 Some people might say that might be a good thing. Let's see. */
2124 b
->last_window_start
= marker_position (w
->start
);
2126 /* Point in the selected window's buffer
2127 is actually stored in that buffer, and the window's pointm isn't used.
2128 So don't clobber point in that buffer. */
2129 if (! EQ (buf
, XWINDOW (selected_window
)->contents
)
2130 /* Don't clobber point in current buffer either (this could be
2131 useful in connection with bug#12208).
2132 && XBUFFER (buf) != current_buffer */
2133 /* This line helps to fix Horsley's testbug.el bug. */
2134 && !(WINDOWP (BVAR (b
, last_selected_window
))
2135 && w
!= XWINDOW (BVAR (b
, last_selected_window
))
2136 && EQ (buf
, XWINDOW (BVAR (b
, last_selected_window
))->contents
)))
2137 temp_set_point_both (b
,
2138 clip_to_bounds (BUF_BEGV (b
),
2139 marker_position (w
->pointm
),
2141 clip_to_bounds (BUF_BEGV_BYTE (b
),
2142 marker_byte_position (w
->pointm
),
2145 if (WINDOWP (BVAR (b
, last_selected_window
))
2146 && w
== XWINDOW (BVAR (b
, last_selected_window
)))
2147 bset_last_selected_window (b
, Qnil
);
2150 /* Put NEW into the window structure in place of OLD. SETFLAG zero
2151 means change window structure only. Otherwise store geometry and
2152 other settings as well. */
2154 replace_window (Lisp_Object old
, Lisp_Object
new, int setflag
)
2156 register Lisp_Object tem
;
2157 register struct window
*o
= XWINDOW (old
), *n
= XWINDOW (new);
2159 /* If OLD is its frame's root window, then NEW is the new
2160 root window for that frame. */
2161 if (EQ (old
, FRAME_ROOT_WINDOW (XFRAME (o
->frame
))))
2162 fset_root_window (XFRAME (o
->frame
), new);
2166 n
->pixel_left
= o
->pixel_left
;
2167 n
->pixel_top
= o
->pixel_top
;
2168 n
->pixel_width
= o
->pixel_width
;
2169 n
->pixel_height
= o
->pixel_height
;
2170 n
->left_col
= o
->left_col
;
2171 n
->top_line
= o
->top_line
;
2172 n
->total_cols
= o
->total_cols
;
2173 n
->total_lines
= o
->total_lines
;
2174 wset_normal_cols (n
, o
->normal_cols
);
2175 wset_normal_cols (o
, make_float (1.0));
2176 wset_normal_lines (n
, o
->normal_lines
);
2177 wset_normal_lines (o
, make_float (1.0));
2178 n
->desired_matrix
= n
->current_matrix
= 0;
2180 memset (&n
->cursor
, 0, sizeof (n
->cursor
));
2181 memset (&n
->phys_cursor
, 0, sizeof (n
->phys_cursor
));
2182 n
->last_cursor_vpos
= 0;
2183 #ifdef HAVE_WINDOW_SYSTEM
2184 n
->phys_cursor_type
= NO_CURSOR
;
2185 n
->phys_cursor_width
= -1;
2187 n
->must_be_updated_p
= 0;
2188 n
->pseudo_window_p
= 0;
2189 n
->window_end_vpos
= 0;
2190 n
->window_end_pos
= 0;
2191 n
->window_end_valid
= 0;
2197 wset_prev (XWINDOW (tem
), new);
2202 wset_next (XWINDOW (tem
), new);
2205 wset_parent (n
, tem
);
2206 if (!NILP (tem
) && EQ (XWINDOW (tem
)->contents
, old
))
2207 wset_combination (XWINDOW (tem
), XWINDOW (tem
)->horizontal
, new);
2210 /* If window WINDOW and its parent window are iso-combined, merge
2211 WINDOW's children into those of its parent window and mark WINDOW as
2215 recombine_windows (Lisp_Object window
)
2217 struct window
*w
, *p
, *c
;
2218 Lisp_Object parent
, child
;
2221 w
= XWINDOW (window
);
2223 if (!NILP (parent
) && NILP (w
->combination_limit
))
2225 p
= XWINDOW (parent
);
2226 if (WINDOWP (p
->contents
) && WINDOWP (w
->contents
)
2227 && p
->horizontal
== w
->horizontal
)
2228 /* WINDOW and PARENT are both either a vertical or a horizontal
2231 horflag
= WINDOW_HORIZONTAL_COMBINATION_P (w
);
2232 child
= w
->contents
;
2233 c
= XWINDOW (child
);
2235 /* Splice WINDOW's children into its parent's children and
2236 assign new normal sizes. */
2238 wset_combination (p
, horflag
, child
);
2241 wset_prev (c
, w
->prev
);
2242 wset_next (XWINDOW (w
->prev
), child
);
2247 wset_parent (c
, parent
);
2251 (c
, make_float ((double) c
->pixel_width
2252 / (double) p
->pixel_width
));
2255 (c
, make_float ((double) c
->pixel_height
2256 / (double) p
->pixel_height
));
2260 if (!NILP (w
->next
))
2262 wset_next (c
, w
->next
);
2263 wset_prev (XWINDOW (c
->next
), child
);
2271 c
= XWINDOW (child
);
2275 /* WINDOW can be deleted now. */
2276 wset_combination (w
, 0, Qnil
);
2281 /* If WINDOW can be deleted, delete it. */
2283 delete_deletable_window (Lisp_Object window
)
2285 if (!NILP (call1 (Qwindow_deletable_p
, window
)))
2286 call1 (Qdelete_window
, window
);
2289 /***********************************************************************
2291 ***********************************************************************/
2293 /* Add window W to *USER_DATA. USER_DATA is actually a Lisp_Object
2294 pointer. This is a callback function for foreach_window, used in
2295 the window_list function. */
2298 add_window_to_list (struct window
*w
, void *user_data
)
2300 Lisp_Object
*list
= user_data
;
2302 XSETWINDOW (window
, w
);
2303 *list
= Fcons (window
, *list
);
2308 /* Return a list of all windows, for use by next_window. If
2309 Vwindow_list is a list, return that list. Otherwise, build a new
2310 list, cache it in Vwindow_list, and return that. */
2315 if (!CONSP (Vwindow_list
))
2317 Lisp_Object tail
, frame
;
2319 Vwindow_list
= Qnil
;
2320 FOR_EACH_FRAME (tail
, frame
)
2322 Lisp_Object args
[2];
2324 /* We are visiting windows in canonical order, and add
2325 new windows at the front of args[1], which means we
2326 have to reverse this list at the end. */
2328 foreach_window (XFRAME (frame
), add_window_to_list
, &args
[1]);
2329 args
[0] = Vwindow_list
;
2330 args
[1] = Fnreverse (args
[1]);
2331 Vwindow_list
= Fnconc (2, args
);
2335 return Vwindow_list
;
2339 /* Value is non-zero if WINDOW satisfies the constraints given by
2340 OWINDOW, MINIBUF and ALL_FRAMES.
2342 MINIBUF t means WINDOW may be minibuffer windows.
2343 `lambda' means WINDOW may not be a minibuffer window.
2344 a window means a specific minibuffer window
2346 ALL_FRAMES t means search all frames,
2347 nil means search just current frame,
2348 `visible' means search just visible frames on the
2350 0 means search visible and iconified frames on the
2352 a window means search the frame that window belongs to,
2353 a frame means consider windows on that frame, only. */
2356 candidate_window_p (Lisp_Object window
, Lisp_Object owindow
,
2357 Lisp_Object minibuf
, Lisp_Object all_frames
)
2359 struct window
*w
= XWINDOW (window
);
2360 struct frame
*f
= XFRAME (w
->frame
);
2361 bool candidate_p
= 1;
2363 if (!BUFFERP (w
->contents
))
2365 else if (MINI_WINDOW_P (w
)
2366 && (EQ (minibuf
, Qlambda
)
2367 || (WINDOWP (minibuf
) && !EQ (minibuf
, window
))))
2369 /* If MINIBUF is `lambda' don't consider any mini-windows.
2370 If it is a window, consider only that one. */
2373 else if (EQ (all_frames
, Qt
))
2375 else if (NILP (all_frames
))
2377 eassert (WINDOWP (owindow
));
2378 candidate_p
= EQ (w
->frame
, XWINDOW (owindow
)->frame
);
2380 else if (EQ (all_frames
, Qvisible
))
2382 candidate_p
= FRAME_VISIBLE_P (f
)
2383 && (FRAME_TERMINAL (XFRAME (w
->frame
))
2384 == FRAME_TERMINAL (XFRAME (selected_frame
)));
2387 else if (INTEGERP (all_frames
) && XINT (all_frames
) == 0)
2389 candidate_p
= (FRAME_VISIBLE_P (f
) || FRAME_ICONIFIED_P (f
)
2390 #ifdef HAVE_X_WINDOWS
2391 /* Yuck!! If we've just created the frame and the
2392 window-manager requested the user to place it
2393 manually, the window may still not be considered
2394 `visible'. I'd argue it should be at least
2395 something like `iconified', but don't know how to do
2397 || (FRAME_X_P (f
) && f
->output_data
.x
->asked_for_visible
2398 && !f
->output_data
.x
->has_been_visible
)
2401 && (FRAME_TERMINAL (XFRAME (w
->frame
))
2402 == FRAME_TERMINAL (XFRAME (selected_frame
)));
2404 else if (WINDOWP (all_frames
))
2405 candidate_p
= (EQ (FRAME_MINIBUF_WINDOW (f
), all_frames
)
2406 || EQ (XWINDOW (all_frames
)->frame
, w
->frame
)
2407 || EQ (XWINDOW (all_frames
)->frame
, FRAME_FOCUS_FRAME (f
)));
2408 else if (FRAMEP (all_frames
))
2409 candidate_p
= EQ (all_frames
, w
->frame
);
2415 /* Decode arguments as allowed by Fnext_window, Fprevious_window, and
2416 Fwindow_list. See candidate_window_p for the meaning of WINDOW,
2417 MINIBUF, and ALL_FRAMES. */
2420 decode_next_window_args (Lisp_Object
*window
, Lisp_Object
*minibuf
, Lisp_Object
*all_frames
)
2422 struct window
*w
= decode_live_window (*window
);
2424 XSETWINDOW (*window
, w
);
2425 /* MINIBUF nil may or may not include minibuffers. Decide if it
2427 if (NILP (*minibuf
))
2428 *minibuf
= minibuf_level
? minibuf_window
: Qlambda
;
2429 else if (!EQ (*minibuf
, Qt
))
2432 /* Now *MINIBUF can be t => count all minibuffer windows, `lambda'
2433 => count none of them, or a specific minibuffer window (the
2434 active one) to count. */
2436 /* ALL_FRAMES nil doesn't specify which frames to include. */
2437 if (NILP (*all_frames
))
2439 = (!EQ (*minibuf
, Qlambda
)
2440 ? FRAME_MINIBUF_WINDOW (XFRAME (w
->frame
))
2442 else if (EQ (*all_frames
, Qvisible
))
2444 else if (EQ (*all_frames
, make_number (0)))
2446 else if (FRAMEP (*all_frames
))
2448 else if (!EQ (*all_frames
, Qt
))
2453 /* Return the next or previous window of WINDOW in cyclic ordering
2454 of windows. NEXT_P non-zero means return the next window. See the
2455 documentation string of next-window for the meaning of MINIBUF and
2459 next_window (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
, int next_p
)
2461 decode_next_window_args (&window
, &minibuf
, &all_frames
);
2463 /* If ALL_FRAMES is a frame, and WINDOW isn't on that frame, just
2464 return the first window on the frame. */
2465 if (FRAMEP (all_frames
)
2466 && !EQ (all_frames
, XWINDOW (window
)->frame
))
2467 return Fframe_first_window (all_frames
);
2473 /* Find WINDOW in the list of all windows. */
2474 list
= Fmemq (window
, window_list ());
2476 /* Scan forward from WINDOW to the end of the window list. */
2478 for (list
= XCDR (list
); CONSP (list
); list
= XCDR (list
))
2479 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
2482 /* Scan from the start of the window list up to WINDOW. */
2484 for (list
= Vwindow_list
;
2485 CONSP (list
) && !EQ (XCAR (list
), window
);
2487 if (candidate_window_p (XCAR (list
), window
, minibuf
, all_frames
))
2491 window
= XCAR (list
);
2495 Lisp_Object candidate
, list
;
2497 /* Scan through the list of windows for candidates. If there are
2498 candidate windows in front of WINDOW, the last one of these
2499 is the one we want. If there are candidates following WINDOW
2500 in the list, again the last one of these is the one we want. */
2502 for (list
= window_list (); CONSP (list
); list
= XCDR (list
))
2504 if (EQ (XCAR (list
), window
))
2506 if (WINDOWP (candidate
))
2509 else if (candidate_window_p (XCAR (list
), window
, minibuf
,
2511 candidate
= XCAR (list
);
2514 if (WINDOWP (candidate
))
2522 DEFUN ("next-window", Fnext_window
, Snext_window
, 0, 3, 0,
2523 doc
: /* Return live window after WINDOW in the cyclic ordering of windows.
2524 WINDOW must be a live window and defaults to the selected one. The
2525 optional arguments MINIBUF and ALL-FRAMES specify the set of windows to
2528 MINIBUF nil or omitted means consider the minibuffer window only if the
2529 minibuffer is active. MINIBUF t means consider the minibuffer window
2530 even if the minibuffer is not active. Any other value means do not
2531 consider the minibuffer window even if the minibuffer is active.
2533 ALL-FRAMES nil or omitted means consider all windows on WINDOW's frame,
2534 plus the minibuffer window if specified by the MINIBUF argument. If the
2535 minibuffer counts, consider all windows on all frames that share that
2536 minibuffer too. The following non-nil values of ALL-FRAMES have special
2539 - t means consider all windows on all existing frames.
2541 - `visible' means consider all windows on all visible frames.
2543 - 0 (the number zero) means consider all windows on all visible and
2546 - A frame means consider all windows on that frame only.
2548 Anything else means consider all windows on WINDOW's frame and no
2551 If you use consistent values for MINIBUF and ALL-FRAMES, you can use
2552 `next-window' to iterate through the entire cycle of acceptable
2553 windows, eventually ending up back at the window you started with.
2554 `previous-window' traverses the same cycle, in the reverse order. */)
2555 (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
)
2557 return next_window (window
, minibuf
, all_frames
, 1);
2561 DEFUN ("previous-window", Fprevious_window
, Sprevious_window
, 0, 3, 0,
2562 doc
: /* Return live window before WINDOW in the cyclic ordering of windows.
2563 WINDOW must be a live window and defaults to the selected one. The
2564 optional arguments MINIBUF and ALL-FRAMES specify the set of windows to
2567 MINIBUF nil or omitted means consider the minibuffer window only if the
2568 minibuffer is active. MINIBUF t means consider the minibuffer window
2569 even if the minibuffer is not active. Any other value means do not
2570 consider the minibuffer window even if the minibuffer is active.
2572 ALL-FRAMES nil or omitted means consider all windows on WINDOW's frame,
2573 plus the minibuffer window if specified by the MINIBUF argument. If the
2574 minibuffer counts, consider all windows on all frames that share that
2575 minibuffer too. The following non-nil values of ALL-FRAMES have special
2578 - t means consider all windows on all existing frames.
2580 - `visible' means consider all windows on all visible frames.
2582 - 0 (the number zero) means consider all windows on all visible and
2585 - A frame means consider all windows on that frame only.
2587 Anything else means consider all windows on WINDOW's frame and no
2590 If you use consistent values for MINIBUF and ALL-FRAMES, you can
2591 use `previous-window' to iterate through the entire cycle of
2592 acceptable windows, eventually ending up back at the window you
2593 started with. `next-window' traverses the same cycle, in the
2595 (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
)
2597 return next_window (window
, minibuf
, all_frames
, 0);
2601 /* Return a list of windows in cyclic ordering. Arguments are like
2602 for `next-window'. */
2605 window_list_1 (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
)
2607 Lisp_Object tail
, list
, rest
;
2609 decode_next_window_args (&window
, &minibuf
, &all_frames
);
2612 for (tail
= window_list (); CONSP (tail
); tail
= XCDR (tail
))
2613 if (candidate_window_p (XCAR (tail
), window
, minibuf
, all_frames
))
2614 list
= Fcons (XCAR (tail
), list
);
2616 /* Rotate the list to start with WINDOW. */
2617 list
= Fnreverse (list
);
2618 rest
= Fmemq (window
, list
);
2619 if (!NILP (rest
) && !EQ (rest
, list
))
2621 for (tail
= list
; !EQ (XCDR (tail
), rest
); tail
= XCDR (tail
))
2623 XSETCDR (tail
, Qnil
);
2624 list
= nconc2 (rest
, list
);
2630 DEFUN ("window-list", Fwindow_list
, Swindow_list
, 0, 3, 0,
2631 doc
: /* Return a list of windows on FRAME, starting with WINDOW.
2632 FRAME nil or omitted means use the selected frame.
2633 WINDOW nil or omitted means use the window selected within FRAME.
2634 MINIBUF t means include the minibuffer window, even if it isn't active.
2635 MINIBUF nil or omitted means include the minibuffer window only
2637 MINIBUF neither nil nor t means never include the minibuffer window. */)
2638 (Lisp_Object frame
, Lisp_Object minibuf
, Lisp_Object window
)
2641 window
= FRAMEP (frame
) ? XFRAME (frame
)->selected_window
: selected_window
;
2642 CHECK_WINDOW (window
);
2644 frame
= selected_frame
;
2646 if (!EQ (frame
, XWINDOW (window
)->frame
))
2647 error ("Window is on a different frame");
2649 return window_list_1 (window
, minibuf
, frame
);
2653 DEFUN ("window-list-1", Fwindow_list_1
, Swindow_list_1
, 0, 3, 0,
2654 doc
: /* Return a list of all live windows.
2655 WINDOW specifies the first window to list and defaults to the selected
2658 Optional argument MINIBUF nil or omitted means consider the minibuffer
2659 window only if the minibuffer is active. MINIBUF t means consider the
2660 minibuffer window even if the minibuffer is not active. Any other value
2661 means do not consider the minibuffer window even if the minibuffer is
2664 Optional argument ALL-FRAMES nil or omitted means consider all windows
2665 on WINDOW's frame, plus the minibuffer window if specified by the
2666 MINIBUF argument. If the minibuffer counts, consider all windows on all
2667 frames that share that minibuffer too. The following non-nil values of
2668 ALL-FRAMES have special meanings:
2670 - t means consider all windows on all existing frames.
2672 - `visible' means consider all windows on all visible frames.
2674 - 0 (the number zero) means consider all windows on all visible and
2677 - A frame means consider all windows on that frame only.
2679 Anything else means consider all windows on WINDOW's frame and no
2682 If WINDOW is not on the list of windows returned, some other window will
2683 be listed first but no error is signaled. */)
2684 (Lisp_Object window
, Lisp_Object minibuf
, Lisp_Object all_frames
)
2686 return window_list_1 (window
, minibuf
, all_frames
);
2689 /* Look at all windows, performing an operation specified by TYPE
2691 If FRAMES is Qt, look at all frames;
2692 Qnil, look at just the selected frame;
2693 Qvisible, look at visible frames;
2694 a frame, just look at windows on that frame.
2695 If MINI is non-zero, perform the operation on minibuffer windows too. */
2700 GET_BUFFER_WINDOW
, /* Arg is buffer */
2701 REPLACE_BUFFER_IN_WINDOWS_SAFELY
, /* Arg is buffer */
2702 REDISPLAY_BUFFER_WINDOWS
, /* Arg is buffer */
2703 CHECK_ALL_WINDOWS
/* Arg is ignored */
2707 window_loop (enum window_loop type
, Lisp_Object obj
, int mini
, Lisp_Object frames
)
2709 Lisp_Object window
, windows
, best_window
, frame_arg
;
2710 int frame_best_window_flag
= 0;
2712 struct gcpro gcpro1
;
2714 /* If we're only looping through windows on a particular frame,
2715 frame points to that frame. If we're looping through windows
2716 on all frames, frame is 0. */
2717 if (FRAMEP (frames
))
2718 f
= XFRAME (frames
);
2719 else if (NILP (frames
))
2720 f
= SELECTED_FRAME ();
2725 frame_arg
= Qlambda
;
2726 else if (EQ (frames
, make_number (0)))
2728 else if (EQ (frames
, Qvisible
))
2733 /* frame_arg is Qlambda to stick to one frame,
2734 Qvisible to consider all visible frames,
2737 /* Pick a window to start with. */
2741 window
= FRAME_SELECTED_WINDOW (f
);
2743 window
= FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
2745 windows
= window_list_1 (window
, mini
? Qt
: Qnil
, frame_arg
);
2749 for (; CONSP (windows
); windows
= XCDR (windows
))
2753 window
= XCAR (windows
);
2754 w
= XWINDOW (window
);
2756 /* Note that we do not pay attention here to whether the frame
2757 is visible, since Fwindow_list skips non-visible frames if
2758 that is desired, under the control of frame_arg. */
2759 if (!MINI_WINDOW_P (w
)
2760 /* For REPLACE_BUFFER_IN_WINDOWS_SAFELY, we must always
2761 consider all windows. */
2762 || type
== REPLACE_BUFFER_IN_WINDOWS_SAFELY
2763 || (mini
&& minibuf_level
> 0))
2766 case GET_BUFFER_WINDOW
:
2767 if (EQ (w
->contents
, obj
)
2768 /* Don't find any minibuffer window except the one that
2769 is currently in use. */
2770 && (MINI_WINDOW_P (w
) ? EQ (window
, minibuf_window
) : 1))
2772 if (EQ (window
, selected_window
))
2773 /* Preferably return the selected window. */
2774 RETURN_UNGCPRO (window
);
2775 else if (EQ (XWINDOW (window
)->frame
, selected_frame
)
2776 && !frame_best_window_flag
)
2777 /* Prefer windows on the current frame (but don't
2778 choose another one if we have one already). */
2780 best_window
= window
;
2781 frame_best_window_flag
= 1;
2783 else if (NILP (best_window
))
2784 best_window
= window
;
2788 case REPLACE_BUFFER_IN_WINDOWS_SAFELY
:
2789 /* We could simply check whether the buffer shown by window
2790 is live, and show another buffer in case it isn't. */
2791 if (EQ (w
->contents
, obj
))
2793 /* Undedicate WINDOW. */
2794 wset_dedicated (w
, Qnil
);
2795 /* Make WINDOW show the buffer returned by
2796 other_buffer_safely, don't run any hooks. */
2798 (window
, other_buffer_safely (w
->contents
), 0, 0);
2799 /* If WINDOW is the selected window, make its buffer
2800 current. But do so only if the window shows the
2801 current buffer (Bug#6454). */
2802 if (EQ (window
, selected_window
)
2803 && XBUFFER (w
->contents
) == current_buffer
)
2804 Fset_buffer (w
->contents
);
2808 case REDISPLAY_BUFFER_WINDOWS
:
2809 if (EQ (w
->contents
, obj
))
2811 mark_window_display_accurate (window
, 0);
2812 w
->update_mode_line
= 1;
2813 XBUFFER (obj
)->prevent_redisplay_optimizations_p
= 1;
2814 update_mode_lines
= 27;
2815 best_window
= window
;
2819 /* Check for a leaf window that has a killed buffer
2820 or broken markers. */
2821 case CHECK_ALL_WINDOWS
:
2822 if (BUFFERP (w
->contents
))
2824 struct buffer
*b
= XBUFFER (w
->contents
);
2826 if (!BUFFER_LIVE_P (b
))
2828 if (!MARKERP (w
->start
) || XMARKER (w
->start
)->buffer
!= b
)
2830 if (!MARKERP (w
->pointm
) || XMARKER (w
->pointm
)->buffer
!= b
)
2835 case WINDOW_LOOP_UNUSED
:
2844 /* Used for debugging. Abort if any window has a dead buffer. */
2846 extern void check_all_windows (void) EXTERNALLY_VISIBLE
;
2848 check_all_windows (void)
2850 window_loop (CHECK_ALL_WINDOWS
, Qnil
, 1, Qt
);
2853 DEFUN ("get-buffer-window", Fget_buffer_window
, Sget_buffer_window
, 0, 2, 0,
2854 doc
: /* Return a window currently displaying BUFFER-OR-NAME, or nil if none.
2855 BUFFER-OR-NAME may be a buffer or a buffer name and defaults to
2858 The optional argument ALL-FRAMES specifies the frames to consider:
2860 - t means consider all windows on all existing frames.
2862 - `visible' means consider all windows on all visible frames.
2864 - 0 (the number zero) means consider all windows on all visible
2865 and iconified frames.
2867 - A frame means consider all windows on that frame only.
2869 Any other value of ALL-FRAMES means consider all windows on the
2870 selected frame and no others. */)
2871 (Lisp_Object buffer_or_name
, Lisp_Object all_frames
)
2875 if (NILP (buffer_or_name
))
2876 buffer
= Fcurrent_buffer ();
2878 buffer
= Fget_buffer (buffer_or_name
);
2880 if (BUFFERP (buffer
))
2881 return window_loop (GET_BUFFER_WINDOW
, buffer
, 1, all_frames
);
2887 resize_root_window (Lisp_Object window
, Lisp_Object delta
, Lisp_Object horizontal
, Lisp_Object ignore
, Lisp_Object pixelwise
)
2889 return call5 (Qwindow_resize_root_window
, window
, delta
, horizontal
, ignore
, pixelwise
);
2894 window_pixel_to_total (Lisp_Object frame
, Lisp_Object horizontal
)
2896 return call2(Qwindow_pixel_to_total
, frame
, horizontal
);
2900 DEFUN ("delete-other-windows-internal", Fdelete_other_windows_internal
,
2901 Sdelete_other_windows_internal
, 0, 2, "",
2902 doc
: /* Make WINDOW fill its frame.
2903 Only the frame WINDOW is on is affected. WINDOW must be a valid window
2904 and defaults to the selected one.
2906 Optional argument ROOT, if non-nil, must specify an internal window such
2907 that WINDOW is in its window subtree. If this is the case, replace ROOT
2908 by WINDOW and leave alone any windows not part of ROOT's subtree.
2910 When WINDOW is live try to reduce display jumps by keeping the text
2911 previously visible in WINDOW in the same place on the frame. Doing this
2912 depends on the value of (window-start WINDOW), so if calling this
2913 function in a program gives strange scrolling, make sure the
2914 window-start value is reasonable when this function is called. */)
2915 (Lisp_Object window
, Lisp_Object root
)
2917 struct window
*w
, *r
, *s
;
2919 Lisp_Object sibling
, pwindow
, swindow
IF_LINT (= Qnil
), delta
;
2920 ptrdiff_t startpos
IF_LINT (= 0), startbyte
IF_LINT (= 0);
2921 int top
IF_LINT (= 0), new_top
, resize_failed
;
2923 w
= decode_valid_window (window
);
2924 XSETWINDOW (window
, w
);
2925 f
= XFRAME (w
->frame
);
2928 /* ROOT is the frame's root window. */
2930 root
= FRAME_ROOT_WINDOW (f
);
2934 /* ROOT must be an ancestor of WINDOW. */
2936 r
= decode_valid_window (root
);
2937 pwindow
= XWINDOW (window
)->parent
;
2938 while (!NILP (pwindow
))
2939 if (EQ (pwindow
, root
))
2942 pwindow
= XWINDOW (pwindow
)->parent
;
2943 if (!EQ (pwindow
, root
))
2944 error ("Specified root is not an ancestor of specified window");
2947 if (EQ (window
, root
))
2950 /* I don't understand the "top > 0" part below. If we deal with a
2951 standalone minibuffer it would have been caught by the preceding
2953 else if (MINI_WINDOW_P (w
)) /* && top > 0) */
2954 error ("Can't expand minibuffer to full frame");
2956 if (BUFFERP (w
->contents
))
2958 startpos
= marker_position (w
->start
);
2959 startbyte
= marker_byte_position (w
->start
);
2960 top
= (WINDOW_TOP_EDGE_LINE (w
)
2961 - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
))));
2962 /* Make sure WINDOW is the frame's selected window. */
2963 if (!EQ (window
, FRAME_SELECTED_WINDOW (f
)))
2965 if (EQ (selected_frame
, w
->frame
))
2966 Fselect_window (window
, Qnil
);
2968 fset_selected_window (f
, window
);
2973 /* See if the frame's selected window is a part of the window
2974 subtree rooted at WINDOW, by finding all the selected window's
2975 parents and comparing each one with WINDOW. If it isn't we
2976 need a new selected window for this frame. */
2977 swindow
= FRAME_SELECTED_WINDOW (f
);
2981 while (!NILP (pwindow
) && !EQ (window
, pwindow
))
2982 pwindow
= XWINDOW (pwindow
)->parent
;
2984 if (EQ (window
, pwindow
))
2985 /* If WINDOW is an ancestor of SWINDOW, then SWINDOW is ok
2986 as the new selected window. */
2989 /* Else try the previous window of SWINDOW. */
2990 swindow
= Fprevious_window (swindow
, Qlambda
, Qnil
);
2993 if (!EQ (swindow
, FRAME_SELECTED_WINDOW (f
)))
2995 if (EQ (selected_frame
, w
->frame
))
2996 Fselect_window (swindow
, Qnil
);
2998 fset_selected_window (f
, swindow
);
3003 if (!FRAME_INITIAL_P (f
))
3005 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
3007 /* We are going to free the glyph matrices of WINDOW, and with
3008 that we might lose any information about glyph rows that have
3009 some of their glyphs highlighted in mouse face. (These rows
3010 are marked with a non-zero mouse_face_p flag.) If WINDOW
3011 indeed has some glyphs highlighted in mouse face, signal to
3012 frame's up-to-date hook that mouse highlight was overwritten,
3013 so that it will arrange for redisplaying the highlight. */
3014 if (EQ (hlinfo
->mouse_face_window
, window
))
3015 reset_mouse_highlight (hlinfo
);
3017 free_window_matrices (r
);
3020 Vwindow_list
= Qnil
;
3021 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
3024 if (!WINDOW_LEAF_P (w
))
3026 /* Resize child windows vertically. */
3027 XSETINT (delta
, r
->pixel_height
- w
->pixel_height
);
3028 w
->pixel_top
= r
->pixel_top
;
3029 w
->top_line
= r
->top_line
;
3030 resize_root_window (window
, delta
, Qnil
, Qnil
, Qt
);
3031 if (window_resize_check (w
, 0))
3033 window_resize_apply (w
, 0);
3034 window_pixel_to_total (w
->frame
, Qnil
);
3038 resize_root_window (window
, delta
, Qnil
, Qt
, Qt
);
3039 if (window_resize_check (w
, 0))
3041 window_resize_apply (w
, 0);
3042 window_pixel_to_total (w
->frame
, Qnil
);
3048 /* Resize child windows horizontally. */
3051 w
->left_col
= r
->left_col
;
3052 w
->pixel_left
= r
->pixel_left
;
3053 XSETINT (delta
, r
->pixel_width
- w
->pixel_width
);
3054 resize_root_window (window
, delta
, Qt
, Qnil
, Qt
);
3055 if (window_resize_check (w
, 1))
3057 window_resize_apply (w
, 1);
3058 window_pixel_to_total (w
->frame
, Qt
);
3062 resize_root_window (window
, delta
, Qt
, Qt
, Qt
);
3063 if (window_resize_check (w
, 1))
3065 window_resize_apply (w
, 1);
3066 window_pixel_to_total (w
->frame
, Qt
);
3074 /* Play safe, if we still can ... */
3077 w
= XWINDOW (window
);
3081 /* Cleanly unlink WINDOW from window-tree. */
3082 if (!NILP (w
->prev
))
3083 /* Get SIBLING above (on the left of) WINDOW. */
3086 s
= XWINDOW (sibling
);
3087 wset_next (s
, w
->next
);
3088 if (!NILP (s
->next
))
3089 wset_prev (XWINDOW (s
->next
), sibling
);
3092 /* Get SIBLING below (on the right of) WINDOW. */
3095 s
= XWINDOW (sibling
);
3096 wset_prev (s
, Qnil
);
3097 wset_combination (XWINDOW (w
->parent
),
3098 XWINDOW (w
->parent
)->horizontal
, sibling
);
3101 /* Delete ROOT and all child windows of ROOT. */
3102 if (WINDOWP (r
->contents
))
3104 delete_all_child_windows (r
->contents
);
3105 wset_combination (r
, 0, Qnil
);
3108 replace_window (root
, window
, 1);
3110 /* This must become SWINDOW anyway ....... */
3111 if (BUFFERP (w
->contents
) && !resize_failed
)
3113 /* Try to minimize scrolling, by setting the window start to the
3114 point will cause the text at the old window start to be at the
3115 same place on the frame. But don't try to do this if the
3116 window start is outside the visible portion (as might happen
3117 when the display is not current, due to typeahead). */
3118 new_top
= WINDOW_TOP_EDGE_LINE (w
) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w
)));
3120 && startpos
>= BUF_BEGV (XBUFFER (w
->contents
))
3121 && startpos
<= BUF_ZV (XBUFFER (w
->contents
)))
3123 struct position pos
;
3124 struct buffer
*obuf
= current_buffer
;
3126 Fset_buffer (w
->contents
);
3127 /* This computation used to temporarily move point, but that
3128 can have unwanted side effects due to text properties. */
3129 pos
= *vmotion (startpos
, startbyte
, -top
, w
);
3131 set_marker_both (w
->start
, w
->contents
, pos
.bufpos
, pos
.bytepos
);
3132 w
->window_end_valid
= 0;
3133 w
->start_at_line_beg
= (pos
.bytepos
== BEGV_BYTE
3134 || FETCH_BYTE (pos
.bytepos
- 1) == '\n');
3135 /* We need to do this, so that the window-scroll-functions
3137 w
->optional_new_start
= 1;
3139 set_buffer_internal (obuf
);
3143 adjust_frame_glyphs (f
);
3146 run_window_configuration_change_hook (f
);
3153 replace_buffer_in_windows (Lisp_Object buffer
)
3155 call1 (Qreplace_buffer_in_windows
, buffer
);
3158 /* If BUFFER is shown in a window, safely replace it with some other
3159 buffer in all windows of all frames, even those on other keyboards. */
3162 replace_buffer_in_windows_safely (Lisp_Object buffer
)
3164 if (buffer_window_count (XBUFFER (buffer
)))
3166 Lisp_Object tail
, frame
;
3168 /* A single call to window_loop won't do the job because it only
3169 considers frames on the current keyboard. So loop manually over
3170 frames, and handle each one. */
3171 FOR_EACH_FRAME (tail
, frame
)
3172 window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY
, buffer
, 1, frame
);
3176 /* If *HEIGHT or *WIDTH are too small a size for FRAME, set them to the
3177 minimum allowable size. PIXELWISE means interpret these as pixel
3181 check_frame_size (struct frame
*frame
, int *width
, int *height
, bool pixelwise
)
3183 /* For height, we have to see:
3184 how many windows the frame has at minimum (one or two),
3185 and whether it has a menu bar or other special stuff at the top. */
3188 int min_height
= MIN_SAFE_WINDOW_HEIGHT
* FRAME_LINE_HEIGHT (frame
);
3189 int min_width
= MIN_SAFE_WINDOW_WIDTH
* FRAME_COLUMN_WIDTH (frame
);
3191 if (!FRAME_MINIBUF_ONLY_P (frame
) && FRAME_HAS_MINIBUF_P (frame
))
3192 min_height
= 2 * min_height
;
3194 min_height
+= FRAME_TOP_MARGIN_HEIGHT (frame
);
3195 min_height
+= FRAME_INTERNAL_BORDER_WIDTH (frame
);
3197 if (*height
< min_height
)
3198 *height
= min_height
;
3199 if (*width
< min_width
)
3205 = ((FRAME_MINIBUF_ONLY_P (frame
) || ! FRAME_HAS_MINIBUF_P (frame
))
3206 ? MIN_SAFE_WINDOW_HEIGHT
3207 : 2 * MIN_SAFE_WINDOW_HEIGHT
);
3209 if (FRAME_TOP_MARGIN (frame
) > 0)
3210 min_height
+= FRAME_TOP_MARGIN (frame
);
3212 if (*height
< min_height
)
3213 *height
= min_height
;
3214 if (*width
< MIN_SAFE_WINDOW_WIDTH
)
3215 *width
= MIN_SAFE_WINDOW_WIDTH
;
3219 /* Adjust the margins of window W if text area is too small.
3220 Return 1 if window width is ok after adjustment; 0 if window
3221 is still too narrow. */
3224 adjust_window_margins (struct window
*w
)
3226 int box_width
= (WINDOW_PIXEL_WIDTH (w
)
3227 - WINDOW_FRINGES_WIDTH (w
)
3228 - WINDOW_SCROLL_BAR_AREA_WIDTH (w
));
3229 int margin_width
= WINDOW_MARGINS_WIDTH (w
);
3231 if (box_width
- margin_width
>= MIN_SAFE_WINDOW_PIXEL_WIDTH (w
))
3234 if (margin_width
< 0 || box_width
< MIN_SAFE_WINDOW_PIXEL_WIDTH (w
))
3237 /* Window's text area is too narrow, but reducing the window
3238 margins will fix that. */
3240 int unit
= WINDOW_FRAME_COLUMN_WIDTH (w
);
3242 margin_width
= box_width
- MIN_SAFE_WINDOW_PIXEL_WIDTH (w
);
3244 if (WINDOW_RIGHT_MARGIN_WIDTH (w
) > 0)
3246 if (WINDOW_LEFT_MARGIN_WIDTH (w
) > 0)
3247 w
->left_margin_cols
= w
->right_margin_cols
=
3248 margin_width
/ (2 * unit
);
3250 w
->right_margin_cols
= margin_width
/ unit
;
3253 w
->left_margin_cols
= margin_width
/ unit
;
3259 /* The following three routines are needed for running a window's
3260 configuration change hook. */
3262 run_funs (Lisp_Object funs
)
3264 for (; CONSP (funs
); funs
= XCDR (funs
))
3265 if (!EQ (XCAR (funs
), Qt
))
3266 call0 (XCAR (funs
));
3270 select_window_norecord (Lisp_Object window
)
3272 if (WINDOW_LIVE_P (window
))
3273 Fselect_window (window
, Qt
);
3277 select_frame_norecord (Lisp_Object frame
)
3279 if (FRAME_LIVE_P (XFRAME (frame
)))
3280 Fselect_frame (frame
, Qt
);
3284 run_window_configuration_change_hook (struct frame
*f
)
3286 ptrdiff_t count
= SPECPDL_INDEX ();
3287 Lisp_Object frame
, global_wcch
3288 = Fdefault_value (Qwindow_configuration_change_hook
);
3289 XSETFRAME (frame
, f
);
3291 if (NILP (Vrun_hooks
) || !NILP (inhibit_lisp_code
))
3294 /* Use the right buffer. Matters when running the local hooks. */
3295 if (current_buffer
!= XBUFFER (Fwindow_buffer (Qnil
)))
3297 record_unwind_current_buffer ();
3298 Fset_buffer (Fwindow_buffer (Qnil
));
3301 if (SELECTED_FRAME () != f
)
3303 record_unwind_protect (select_frame_norecord
, selected_frame
);
3304 select_frame_norecord (frame
);
3307 /* Look for buffer-local values. */
3309 Lisp_Object windows
= Fwindow_list (frame
, Qlambda
, Qnil
);
3310 for (; CONSP (windows
); windows
= XCDR (windows
))
3312 Lisp_Object window
= XCAR (windows
);
3313 Lisp_Object buffer
= Fwindow_buffer (window
);
3314 if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook
,
3317 ptrdiff_t inner_count
= SPECPDL_INDEX ();
3318 record_unwind_protect (select_window_norecord
, selected_window
);
3319 select_window_norecord (window
);
3320 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook
,
3322 unbind_to (inner_count
, Qnil
);
3327 run_funs (global_wcch
);
3328 unbind_to (count
, Qnil
);
3331 DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook
,
3332 Srun_window_configuration_change_hook
, 0, 1, 0,
3333 doc
: /* Run `window-configuration-change-hook' for FRAME.
3334 If FRAME is omitted or nil, it defaults to the selected frame. */)
3337 run_window_configuration_change_hook (decode_live_frame (frame
));
3341 DEFUN ("run-window-scroll-functions", Frun_window_scroll_functions
,
3342 Srun_window_scroll_functions
, 0, 1, 0,
3343 doc
: /* Run `window-scroll-functions' for WINDOW.
3344 If WINDOW is omitted or nil, it defaults to the selected window. */)
3345 (Lisp_Object window
)
3347 if (! NILP (Vwindow_scroll_functions
))
3348 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
3349 Fmarker_position (decode_live_window (window
)->start
));
3353 /* Make WINDOW display BUFFER. RUN_HOOKS_P non-zero means it's allowed
3354 to run hooks. See make_frame for a case where it's not allowed.
3355 KEEP_MARGINS_P non-zero means that the current margins, fringes, and
3356 scroll-bar settings of the window are not reset from the buffer's
3360 set_window_buffer (Lisp_Object window
, Lisp_Object buffer
,
3361 bool run_hooks_p
, bool keep_margins_p
)
3363 struct window
*w
= XWINDOW (window
);
3364 struct buffer
*b
= XBUFFER (buffer
);
3365 ptrdiff_t count
= SPECPDL_INDEX ();
3366 bool samebuf
= EQ (buffer
, w
->contents
);
3368 wset_buffer (w
, buffer
);
3370 if (EQ (window
, selected_window
))
3371 bset_last_selected_window (b
, window
);
3373 /* Let redisplay errors through. */
3374 b
->display_error_modiff
= 0;
3376 /* Update time stamps of buffer display. */
3377 if (INTEGERP (BVAR (b
, display_count
)))
3378 bset_display_count (b
, make_number (XINT (BVAR (b
, display_count
)) + 1));
3379 bset_display_time (b
, Fcurrent_time ());
3381 w
->window_end_pos
= 0;
3382 w
->window_end_vpos
= 0;
3383 w
->last_cursor_vpos
= 0;
3385 if (!(keep_margins_p
&& samebuf
))
3386 { /* If we're not actually changing the buffer, don't reset hscroll and
3387 vscroll. This case happens for example when called from
3388 change_frame_size_1, where we use a dummy call to
3389 Fset_window_buffer on the frame's selected window (and no other)
3390 just in order to run window-configuration-change-hook.
3391 Resetting hscroll and vscroll here is problematic for things like
3392 image-mode and doc-view-mode since it resets the image's position
3393 whenever we resize the frame. */
3394 w
->hscroll
= w
->min_hscroll
= 0;
3396 set_marker_both (w
->pointm
, buffer
, BUF_PT (b
), BUF_PT_BYTE (b
));
3397 set_marker_restricted (w
->start
,
3398 make_number (b
->last_window_start
),
3400 w
->start_at_line_beg
= 0;
3403 /* Maybe we could move this into the `if' but it's not obviously safe and
3404 I doubt it's worth the trouble. */
3406 w
->update_mode_line
= true;
3408 /* We must select BUFFER for running the window-scroll-functions. */
3409 /* We can't check ! NILP (Vwindow_scroll_functions) here
3410 because that might itself be a local variable. */
3411 if (window_initialized
)
3413 record_unwind_current_buffer ();
3414 Fset_buffer (buffer
);
3417 XMARKER (w
->pointm
)->insertion_type
= !NILP (Vwindow_point_insertion_type
);
3419 if (!keep_margins_p
)
3421 /* Set left and right marginal area width etc. from buffer. */
3422 set_window_fringes (w
, BVAR (b
, left_fringe_width
),
3423 BVAR (b
, right_fringe_width
),
3424 BVAR (b
, fringes_outside_margins
));
3425 set_window_scroll_bars (w
, BVAR (b
, scroll_bar_width
),
3426 BVAR (b
, vertical_scroll_bar_type
), Qnil
);
3427 set_window_margins (w
, BVAR (b
, left_margin_cols
),
3428 BVAR (b
, right_margin_cols
));
3429 apply_window_adjustment (w
);
3434 if (! NILP (Vwindow_scroll_functions
))
3435 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
3436 Fmarker_position (w
->start
));
3438 run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w
)));
3441 unbind_to (count
, Qnil
);
3444 DEFUN ("set-window-buffer", Fset_window_buffer
, Sset_window_buffer
, 2, 3, 0,
3445 doc
: /* Make WINDOW display BUFFER-OR-NAME.
3446 WINDOW must be a live window and defaults to the selected one.
3447 BUFFER-OR-NAME must be a buffer or the name of an existing buffer.
3449 Optional third argument KEEP-MARGINS non-nil means that WINDOW's current
3450 display margins, fringe widths, and scroll bar settings are preserved;
3451 the default is to reset these from the local settings for BUFFER-OR-NAME
3452 or the frame defaults. Return nil.
3454 This function throws an error when WINDOW is strongly dedicated to its
3455 buffer (that is `window-dedicated-p' returns t for WINDOW) and does not
3456 already display BUFFER-OR-NAME.
3458 This function runs `window-scroll-functions' before running
3459 `window-configuration-change-hook'. */)
3460 (register Lisp_Object window
, Lisp_Object buffer_or_name
, Lisp_Object keep_margins
)
3462 register Lisp_Object tem
, buffer
;
3463 register struct window
*w
= decode_live_window (window
);
3465 XSETWINDOW (window
, w
);
3466 buffer
= Fget_buffer (buffer_or_name
);
3467 CHECK_BUFFER (buffer
);
3468 if (!BUFFER_LIVE_P (XBUFFER (buffer
)))
3469 error ("Attempt to display deleted buffer");
3473 error ("Window is deleted");
3476 if (!EQ (tem
, buffer
))
3478 if (EQ (w
->dedicated
, Qt
))
3479 /* WINDOW is strongly dedicated to its buffer, signal an
3481 error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem
), name
)));
3483 /* WINDOW is weakly dedicated to its buffer, reset
3485 wset_dedicated (w
, Qnil
);
3487 call1 (Qrecord_window_buffer
, window
);
3493 set_window_buffer (window
, buffer
, 1, !NILP (keep_margins
));
3499 display_buffer (Lisp_Object buffer
, Lisp_Object not_this_window_p
, Lisp_Object override_frame
)
3501 return call3 (Qdisplay_buffer
, buffer
, not_this_window_p
, override_frame
);
3504 DEFUN ("force-window-update", Fforce_window_update
, Sforce_window_update
,
3506 doc
: /* Force all windows to be updated on next redisplay.
3507 If optional arg OBJECT is a window, force redisplay of that window only.
3508 If OBJECT is a buffer or buffer name, force redisplay of all windows
3509 displaying that buffer. */)
3510 (Lisp_Object object
)
3514 windows_or_buffers_changed
= 29;
3515 update_mode_lines
= 28;
3519 if (WINDOWP (object
))
3521 struct window
*w
= XWINDOW (object
);
3522 mark_window_display_accurate (object
, 0);
3523 w
->update_mode_line
= 1;
3524 if (BUFFERP (w
->contents
))
3525 XBUFFER (w
->contents
)->prevent_redisplay_optimizations_p
= 1;
3526 update_mode_lines
= 29;
3530 if (STRINGP (object
))
3531 object
= Fget_buffer (object
);
3532 if (BUFFERP (object
) && BUFFER_LIVE_P (XBUFFER (object
))
3533 && buffer_window_count (XBUFFER (object
)))
3535 /* If buffer is live and shown in at least one window, find
3536 all windows showing this buffer and force update of them. */
3537 object
= window_loop (REDISPLAY_BUFFER_WINDOWS
, object
, 0, Qvisible
);
3538 return NILP (object
) ? Qnil
: Qt
;
3541 /* If nothing suitable was found, just return.
3542 We could signal an error, but this feature will typically be used
3543 asynchronously in timers or process sentinels, so we don't. */
3547 /* Obsolete since 24.3. */
3549 temp_output_buffer_show (register Lisp_Object buf
)
3551 register struct buffer
*old
= current_buffer
;
3552 register Lisp_Object window
;
3553 register struct window
*w
;
3555 bset_directory (XBUFFER (buf
), BVAR (current_buffer
, directory
));
3558 BUF_SAVE_MODIFF (XBUFFER (buf
)) = MODIFF
;
3562 set_buffer_internal (old
);
3564 if (!NILP (Vtemp_buffer_show_function
))
3565 call1 (Vtemp_buffer_show_function
, buf
);
3566 else if (WINDOW_LIVE_P (window
= display_buffer (buf
, Qnil
, Qnil
)))
3568 if (!EQ (XWINDOW (window
)->frame
, selected_frame
))
3569 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window
)));
3570 Vminibuf_scroll_window
= window
;
3571 w
= XWINDOW (window
);
3574 set_marker_restricted_both (w
->start
, buf
, BEG
, BEG
);
3575 set_marker_restricted_both (w
->pointm
, buf
, BEG
, BEG
);
3577 /* Run temp-buffer-show-hook, with the chosen window selected
3578 and its buffer current. */
3580 ptrdiff_t count
= SPECPDL_INDEX ();
3581 Lisp_Object prev_window
, prev_buffer
;
3582 prev_window
= selected_window
;
3583 XSETBUFFER (prev_buffer
, old
);
3585 /* Select the window that was chosen, for running the hook.
3586 Note: Both Fselect_window and select_window_norecord may
3587 set-buffer to the buffer displayed in the window,
3588 so we need to save the current buffer. --stef */
3589 record_unwind_protect (restore_buffer
, prev_buffer
);
3590 record_unwind_protect (select_window_norecord
, prev_window
);
3591 Fselect_window (window
, Qt
);
3592 Fset_buffer (w
->contents
);
3593 Frun_hooks (1, &Qtemp_buffer_show_hook
);
3594 unbind_to (count
, Qnil
);
3599 /* Make new window, have it replace WINDOW in window-tree, and make
3600 WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only
3601 horizontal child). */
3603 make_parent_window (Lisp_Object window
, bool horflag
)
3606 register struct window
*o
, *p
;
3608 o
= XWINDOW (window
);
3609 p
= allocate_window ();
3610 memcpy ((char *) p
+ sizeof (struct vectorlike_header
),
3611 (char *) o
+ sizeof (struct vectorlike_header
),
3612 word_size
* VECSIZE (struct window
));
3613 /* P's buffer slot may change from nil to a buffer... */
3614 adjust_window_count (p
, 1);
3615 XSETWINDOW (parent
, p
);
3617 p
->sequence_number
= ++sequence_number
;
3619 replace_window (window
, parent
, 1);
3621 wset_next (o
, Qnil
);
3622 wset_prev (o
, Qnil
);
3623 wset_parent (o
, parent
);
3624 /* ...but now P becomes an internal window. */
3625 wset_start (p
, Qnil
);
3626 wset_pointm (p
, Qnil
);
3627 wset_buffer (p
, Qnil
);
3628 wset_combination (p
, horflag
, window
);
3629 wset_combination_limit (p
, Qnil
);
3630 wset_window_parameters (p
, Qnil
);
3633 /* Make new window from scratch. */
3638 register struct window
*w
;
3640 w
= allocate_window ();
3641 /* Initialize Lisp data. Note that allocate_window initializes all
3642 Lisp data to nil, so do it only for slots which should not be nil. */
3643 wset_normal_lines (w
, make_float (1.0));
3644 wset_normal_cols (w
, make_float (1.0));
3645 wset_new_total (w
, make_number (0));
3646 wset_new_normal (w
, make_number (0));
3647 wset_new_pixel (w
, make_number (0));
3648 wset_start (w
, Fmake_marker ());
3649 wset_pointm (w
, Fmake_marker ());
3650 wset_vertical_scroll_bar_type (w
, Qt
);
3651 /* These Lisp fields are marked specially so they're not set to nil by
3653 wset_prev_buffers (w
, Qnil
);
3654 wset_next_buffers (w
, Qnil
);
3656 /* Initialize non-Lisp data. Note that allocate_window zeroes out all
3657 non-Lisp data, so do it only for slots which should not be zero. */
3658 w
->nrows_scale_factor
= w
->ncols_scale_factor
= 1;
3659 w
->left_fringe_width
= w
->right_fringe_width
= -1;
3660 w
->mode_line_height
= w
->header_line_height
= -1;
3661 #ifdef HAVE_WINDOW_SYSTEM
3662 w
->phys_cursor_type
= NO_CURSOR
;
3663 w
->phys_cursor_width
= -1;
3665 w
->sequence_number
= ++sequence_number
;
3666 w
->scroll_bar_width
= -1;
3667 w
->column_number_displayed
= -1;
3669 /* Reset window_list. */
3670 Vwindow_list
= Qnil
;
3671 /* Return window. */
3672 XSETWINDOW (window
, w
);
3676 DEFUN ("set-window-new-pixel", Fset_window_new_pixel
, Sset_window_new_pixel
, 2, 3, 0,
3677 doc
: /* Set new pixel size of WINDOW to SIZE.
3678 WINDOW must be a valid window and defaults to the selected one.
3681 Optional argument ADD non-nil means add SIZE to the new pixel size of
3682 WINDOW and return the sum.
3684 Note: This function does not operate on any child windows of WINDOW. */)
3685 (Lisp_Object window
, Lisp_Object size
, Lisp_Object add
)
3687 struct window
*w
= decode_valid_window (window
);
3688 EMACS_INT size_min
= NILP (add
) ? 0 : - XINT (w
->new_pixel
);
3689 EMACS_INT size_max
= size_min
+ min (INT_MAX
, MOST_POSITIVE_FIXNUM
);
3691 CHECK_RANGED_INTEGER (size
, size_min
, size_max
);
3693 wset_new_pixel (w
, size
);
3695 wset_new_pixel (w
, make_number (XINT (w
->new_pixel
) + XINT (size
)));
3697 return w
->new_pixel
;
3700 DEFUN ("set-window-new-total", Fset_window_new_total
, Sset_window_new_total
, 2, 3, 0,
3701 doc
: /* Set new total size of WINDOW to SIZE.
3702 WINDOW must be a valid window and defaults to the selected one.
3705 Optional argument ADD non-nil means add SIZE to the new total size of
3706 WINDOW and return the sum.
3708 Note: This function does not operate on any child windows of WINDOW. */)
3709 (Lisp_Object window
, Lisp_Object size
, Lisp_Object add
)
3711 struct window
*w
= decode_valid_window (window
);
3713 CHECK_NUMBER (size
);
3715 wset_new_total (w
, size
);
3717 wset_new_total (w
, make_number (XINT (w
->new_total
) + XINT (size
)));
3719 return w
->new_total
;
3722 DEFUN ("set-window-new-normal", Fset_window_new_normal
, Sset_window_new_normal
, 1, 2, 0,
3723 doc
: /* Set new normal size of WINDOW to SIZE.
3724 WINDOW must be a valid window and defaults to the selected one.
3727 Note: This function does not operate on any child windows of WINDOW. */)
3728 (Lisp_Object window
, Lisp_Object size
)
3730 wset_new_normal (decode_valid_window (window
), size
);
3734 /* Return 1 if setting w->pixel_height (w->pixel_width if HORFLAG is
3735 non-zero) to w->new_pixel would result in correct heights (widths)
3736 for window W and recursively all child windows of W.
3738 Note: This function does not check any of `window-fixed-size-p',
3739 `window-min-height' or `window-min-width'. It does check that window
3740 sizes do not drop below one line (two columns). */
3742 window_resize_check (struct window
*w
, bool horflag
)
3744 struct frame
*f
= XFRAME (w
->frame
);
3747 if (WINDOW_VERTICAL_COMBINATION_P (w
))
3748 /* W is a vertical combination. */
3750 c
= XWINDOW (w
->contents
);
3752 /* All child windows of W must have the same width as W. */
3756 if (XINT (c
->new_pixel
) != XINT (w
->new_pixel
)
3757 || !window_resize_check (c
, horflag
))
3760 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
3766 /* The sum of the heights of the child windows of W must equal
3769 int remaining_pixels
= XINT (w
->new_pixel
);
3773 if (!window_resize_check (c
, horflag
))
3776 remaining_pixels
-= XINT (c
->new_pixel
);
3777 if (remaining_pixels
< 0)
3779 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
3782 return remaining_pixels
== 0;
3785 else if (WINDOW_HORIZONTAL_COMBINATION_P (w
))
3786 /* W is a horizontal combination. */
3788 c
= XWINDOW (w
->contents
);
3790 /* The sum of the widths of the child windows of W must equal W's
3793 int remaining_pixels
= XINT (w
->new_pixel
);
3797 if (!window_resize_check (c
, horflag
))
3800 remaining_pixels
-= XINT (c
->new_pixel
);
3801 if (remaining_pixels
< 0)
3803 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
3806 return remaining_pixels
== 0;
3809 /* All child windows of W must have the same height as W. */
3813 if (XINT (c
->new_pixel
) != XINT (w
->new_pixel
)
3814 || !window_resize_check (c
, horflag
))
3817 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
3824 /* A leaf window. Make sure it's not too small. The following
3825 hardcodes the values of `window-safe-min-width' (2) and
3826 `window-safe-min-height' (1) which are defined in window.el. */
3827 return (XINT (w
->new_pixel
) >= (horflag
3828 ? (2 * FRAME_COLUMN_WIDTH (f
))
3829 : FRAME_LINE_HEIGHT (f
)));
3833 /* Set w->pixel_height (w->pixel_height if HORIZONTAL is non-zero) to
3834 w->new_pixel for window W and recursively all child windows of W.
3835 Also calculate and assign the new vertical (horizontal) pixel start
3836 positions of each of these windows.
3838 This function does not perform any error checks. Make sure you have
3839 run window_resize_check on W before applying this function. */
3841 window_resize_apply (struct window
*w
, bool horflag
)
3846 ? FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w
))
3847 : FRAME_LINE_HEIGHT (WINDOW_XFRAME (w
)));
3849 /* Note: Assigning new_normal requires that the new total size of the
3850 parent window has been set *before*. */
3853 w
->pixel_width
= XFASTINT (w
->new_pixel
);
3854 w
->total_cols
= w
->pixel_width
/ unit
;
3855 if (NUMBERP (w
->new_normal
))
3856 wset_normal_cols (w
, w
->new_normal
);
3858 edge
= w
->pixel_left
;
3862 w
->pixel_height
= XFASTINT (w
->new_pixel
);
3863 w
->total_lines
= w
->pixel_height
/ unit
;
3864 if (NUMBERP (w
->new_normal
))
3865 wset_normal_lines (w
, w
->new_normal
);
3867 edge
= w
->pixel_top
;
3870 if (WINDOW_VERTICAL_COMBINATION_P (w
))
3871 /* W is a vertical combination. */
3873 c
= XWINDOW (w
->contents
);
3878 c
->pixel_left
= edge
;
3879 c
->left_col
= edge
/ unit
;
3883 c
->pixel_top
= edge
;
3884 c
->top_line
= edge
/ unit
;
3886 window_resize_apply (c
, horflag
);
3888 edge
= edge
+ c
->pixel_height
;
3890 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
3893 else if (WINDOW_HORIZONTAL_COMBINATION_P (w
))
3894 /* W is a horizontal combination. */
3896 c
= XWINDOW (w
->contents
);
3901 c
->pixel_left
= edge
;
3902 c
->left_col
= edge
/ unit
;
3906 c
->pixel_top
= edge
;
3907 c
->top_line
= edge
/ unit
;
3910 window_resize_apply (c
, horflag
);
3912 edge
= edge
+ c
->pixel_width
;
3914 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
3919 w
->window_end_valid
= 0;
3923 /* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to
3924 w->new_total for window W and recursively all child windows of W.
3925 Also calculate and assign the new vertical (horizontal) start
3926 positions of each of these windows. */
3928 window_resize_apply_total (struct window
*w
, bool horflag
)
3933 /* Note: Assigning new_normal requires that the new total size of the
3934 parent window has been set *before*. */
3937 w
->total_cols
= XFASTINT (w
->new_total
);
3942 w
->total_lines
= XFASTINT (w
->new_total
);
3946 if (WINDOW_VERTICAL_COMBINATION_P (w
))
3947 /* W is a vertical combination. */
3949 c
= XWINDOW (w
->contents
);
3957 window_resize_apply_total (c
, horflag
);
3959 edge
= edge
+ c
->total_lines
;
3961 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
3964 else if (WINDOW_HORIZONTAL_COMBINATION_P (w
))
3965 /* W is a horizontal combination. */
3967 c
= XWINDOW (w
->contents
);
3975 window_resize_apply_total (c
, horflag
);
3977 edge
= edge
+ c
->total_cols
;
3979 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
3984 DEFUN ("window-resize-apply", Fwindow_resize_apply
, Swindow_resize_apply
, 0, 2, 0,
3985 doc
: /* Apply requested size values for window-tree of FRAME.
3986 If FRAME is omitted or nil, it defaults to the selected frame.
3988 Optional argument HORIZONTAL omitted or nil means apply requested
3989 height values. HORIZONTAL non-nil means apply requested width values.
3991 This function checks whether the requested values sum up to a valid
3992 window layout, recursively assigns the new sizes of all child windows
3993 and calculates and assigns the new start positions of these windows.
3995 Note: This function does not check any of `window-fixed-size-p',
3996 `window-min-height' or `window-min-width'. All these checks have to
3997 be applied on the Elisp level. */)
3998 (Lisp_Object frame
, Lisp_Object horizontal
)
4000 struct frame
*f
= decode_live_frame (frame
);
4001 struct window
*r
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4002 bool horflag
= !NILP (horizontal
);
4004 if (!window_resize_check (r
, horflag
)
4005 || (XINT (r
->new_pixel
)
4006 != (horflag
? r
->pixel_width
: r
->pixel_height
)))
4010 window_resize_apply (r
, horflag
);
4013 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4015 adjust_frame_glyphs (f
);
4022 DEFUN ("window-resize-apply-total", Fwindow_resize_apply_total
, Swindow_resize_apply_total
, 0, 2, 0,
4023 doc
: /* Apply requested total size values for window-tree of FRAME.
4024 If FRAME is omitted or nil, it defaults to the selected frame.
4026 This function does not assign pixel or normal size values. You should
4027 have run `window-resize-apply' before running this.
4029 Optional argument HORIZONTAL omitted or nil means apply requested
4030 height values. HORIZONTAL non-nil means apply requested width
4032 (Lisp_Object frame
, Lisp_Object horizontal
)
4034 struct frame
*f
= decode_live_frame (frame
);
4035 struct window
*r
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4038 /* Necessary when deleting the top-/or leftmost window. */
4040 r
->top_line
= FRAME_TOP_MARGIN (f
);
4041 window_resize_apply_total (r
, !NILP (horizontal
));
4042 /* Handle the mini window. */
4043 if (FRAME_HAS_MINIBUF_P (f
) && !FRAME_MINIBUF_ONLY_P (f
))
4045 struct window
*m
= XWINDOW (f
->minibuffer_window
);
4047 if (NILP (horizontal
))
4049 m
->top_line
= r
->top_line
+ r
->total_lines
;
4050 m
->total_lines
= XFASTINT (m
->new_total
);
4053 m
->total_cols
= XFASTINT (m
->new_total
);
4062 /* Resize frame F's windows when number of lines of F is set to SIZE.
4063 HORFLAG 1 means resize windows when number of columns of F is set to
4064 SIZE. PIXELWISE 1 means to interpret SIZE as pixels.
4066 This function can delete all windows but the selected one in order to
4067 satisfy the request. The result will be meaningful if and only if
4068 F's windows have meaningful sizes when you call this. */
4070 resize_frame_windows (struct frame
*f
, int size
, bool horflag
, bool pixelwise
)
4072 Lisp_Object root
= f
->root_window
;
4073 struct window
*r
= XWINDOW (root
);
4074 Lisp_Object mini
= f
->minibuffer_window
;
4076 /* old_size is the old size of the frame's root window. */
4077 int old_size
= horflag
? r
->total_cols
: r
->total_lines
;
4078 int old_pixel_size
= horflag
? r
->pixel_width
: r
->pixel_height
;
4079 /* new_size is the new size of the frame's root window. */
4080 int new_size
, new_pixel_size
;
4081 int unit
= horflag
? FRAME_COLUMN_WIDTH (f
) : FRAME_LINE_HEIGHT (f
);
4083 /* Don't let the size drop below one unit. This is more comforting
4084 when we are called from x_set_tool_bar_lines since the latter may
4085 have implicitly given us a zero or negative height. */
4088 /* Note: This does not include the size for internal borders
4089 since these are not part of the frame's text area. */
4090 new_pixel_size
= max (horflag
4093 - FRAME_TOP_MARGIN_HEIGHT (f
)
4094 - ((FRAME_HAS_MINIBUF_P (f
)
4095 && !FRAME_MINIBUF_ONLY_P (f
))
4096 ? FRAME_LINE_HEIGHT (f
) : 0)),
4098 new_size
= new_pixel_size
/ unit
;
4102 new_size
= max (horflag
4105 - FRAME_TOP_MARGIN (f
)
4106 - ((FRAME_HAS_MINIBUF_P (f
)
4107 && !FRAME_MINIBUF_ONLY_P (f
))
4110 new_pixel_size
= new_size
* unit
;
4113 r
->top_line
= FRAME_TOP_MARGIN (f
);
4114 r
->pixel_top
= FRAME_TOP_MARGIN_HEIGHT (f
);
4116 if (new_pixel_size
== old_pixel_size
)
4118 else if (WINDOW_LEAF_P (r
))
4119 /* For a leaf root window just set the size. */
4122 r
->total_cols
= new_size
;
4123 r
->pixel_width
= new_pixel_size
;
4127 r
->total_lines
= new_size
;
4128 r
->pixel_height
= new_pixel_size
;
4135 XSETINT (delta
, new_pixel_size
- old_pixel_size
);
4137 XSETINT (delta
, new_size
- old_size
);
4139 /* Try a "normal" resize first. */
4140 resize_root_window (root
, delta
, horflag
? Qt
: Qnil
, Qnil
,
4141 pixelwise
? Qt
: Qnil
);
4142 if (window_resize_check (r
, horflag
)
4143 && new_pixel_size
== XINT (r
->new_pixel
))
4145 window_resize_apply (r
, horflag
);
4146 window_pixel_to_total (r
->frame
, horflag
? Qt
: Qnil
);
4150 /* Try with "reasonable" minimum sizes next. */
4151 resize_root_window (root
, delta
, horflag
? Qt
: Qnil
, Qt
,
4152 pixelwise
? Qt
: Qnil
);
4153 if (window_resize_check (r
, horflag
)
4154 && new_pixel_size
== XINT (r
->new_pixel
))
4156 window_resize_apply (r
, horflag
);
4157 window_pixel_to_total (r
->frame
, horflag
? Qt
: Qnil
);
4161 /* Finally, try with "safe" minimum sizes. */
4162 resize_root_window (root
, delta
, horflag
? Qt
: Qnil
, Qsafe
,
4163 pixelwise
? Qt
: Qnil
);
4164 if (window_resize_check (r
, horflag
)
4165 && new_pixel_size
== XINT (r
->new_pixel
))
4167 window_resize_apply (r
, horflag
);
4168 window_pixel_to_total (r
->frame
, horflag
? Qt
: Qnil
);
4170 #if 0 /* Let's try without killing other windows. */
4173 /* We lost. Delete all windows but the frame's
4175 root
= f
->selected_window
;
4176 Fdelete_other_windows_internal (root
, Qnil
);
4179 XWINDOW (root
)->total_cols
= new_size
;
4180 XWINDOW (root
)->pixel_width
= new_pixel_size
;
4184 XWINDOW (root
)->total_lines
= new_size
;
4185 XWINDOW (root
)->pixel_height
= new_pixel_size
;
4193 if (FRAME_HAS_MINIBUF_P (f
) && !FRAME_MINIBUF_ONLY_P (f
))
4198 m
->total_cols
= size
;
4199 m
->pixel_width
= new_pixel_size
;
4203 /* Are we sure we always want 1 line here? */
4205 m
->pixel_height
= FRAME_LINE_HEIGHT (f
);
4206 m
->top_line
= r
->top_line
+ r
->total_lines
;
4207 m
->pixel_top
= r
->pixel_top
+ r
->pixel_height
;
4215 DEFUN ("split-window-internal", Fsplit_window_internal
, Ssplit_window_internal
, 4, 4, 0,
4216 doc
: /* Split window OLD.
4217 Second argument PIXEL-SIZE specifies the number of pixels of the
4218 new window. In any case TOTAL-SIZE must be a positive integer.
4220 Third argument SIDE nil (or `below') specifies that the new window shall
4221 be located below WINDOW. SIDE `above' means the new window shall be
4222 located above WINDOW. In both cases PIXEL-SIZE specifies the pixel
4223 height of the new window including space reserved for the mode and/or
4226 SIDE t (or `right') specifies that the new window shall be located on
4227 the right side of WINDOW. SIDE `left' means the new window shall be
4228 located on the left of WINDOW. In both cases PIXEL-SIZE specifies the
4229 width of the new window including space reserved for fringes and the
4230 scrollbar or a divider column.
4232 Fourth argument NORMAL-SIZE specifies the normal size of the new window
4233 according to the SIDE argument.
4235 The new pixel and normal sizes of all involved windows must have been
4236 set correctly. See the code of `split-window' for how this is done. */)
4237 (Lisp_Object old
, Lisp_Object pixel_size
, Lisp_Object side
, Lisp_Object normal_size
)
4239 /* OLD (*o) is the window we have to split. (*p) is either OLD's
4240 parent window or an internal window we have to install as OLD's new
4241 parent. REFERENCE (*r) must denote a live window, or is set to OLD
4242 provided OLD is a leaf window, or to the frame's selected window.
4243 NEW (*n) is the new window created with some parameters taken from
4245 register Lisp_Object
new, frame
, reference
;
4246 register struct window
*o
, *p
, *n
, *r
, *c
;
4249 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */
4250 = EQ (side
, Qt
) || EQ (side
, Qleft
) || EQ (side
, Qright
);
4251 int combination_limit
= 0, sum
= 0;
4256 frame
= WINDOW_FRAME (o
);
4259 CHECK_NUMBER (pixel_size
);
4261 = XINT (pixel_size
) / (horflag
4262 ? FRAME_COLUMN_WIDTH (f
)
4263 : FRAME_LINE_HEIGHT (f
));
4265 /* Set combination_limit to 1 if we have to make a new parent window.
4266 We do that if either `window-combination-limit' is t, or OLD has no
4267 parent, or OLD is ortho-combined. */
4269 EQ (Vwindow_combination_limit
, Qt
)
4272 ? WINDOW_VERTICAL_COMBINATION_P (XWINDOW (o
->parent
))
4273 : WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (o
->parent
)));
4275 /* We need a live reference window to initialize some parameters. */
4276 if (WINDOW_LIVE_P (old
))
4277 /* OLD is live, use it as reference window. */
4280 /* Use the frame's selected window as reference window. */
4281 reference
= FRAME_SELECTED_WINDOW (f
);
4282 r
= XWINDOW (reference
);
4284 /* The following bugs are caught by `split-window'. */
4285 if (MINI_WINDOW_P (o
))
4286 error ("Attempt to split minibuffer window");
4287 else if (total_size
< (horflag
? 2 : 1))
4288 error ("Size of new window too small (after split)");
4289 else if (!combination_limit
&& !NILP (Vwindow_combination_resize
))
4290 /* `window-combination-resize' non-nil means try to resize OLD's siblings
4293 p
= XWINDOW (o
->parent
);
4294 /* Temporarily pretend we split the parent window. */
4296 (p
, make_number ((horflag
? p
->pixel_width
: p
->pixel_height
)
4297 - XINT (pixel_size
)));
4298 if (!window_resize_check (p
, horflag
))
4299 error ("Window sizes don't fit");
4301 /* Undo the temporary pretension. */
4302 wset_new_pixel (p
, make_number (horflag
? p
->pixel_width
: p
->pixel_height
));
4306 if (!window_resize_check (o
, horflag
))
4307 error ("Resizing old window failed");
4308 else if (XINT (pixel_size
) + XINT (o
->new_pixel
)
4309 != (horflag
? o
->pixel_width
: o
->pixel_height
))
4310 error ("Sum of sizes of old and new window don't fit");
4313 /* This is our point of no return. */
4314 if (combination_limit
)
4316 /* Save the old value of o->normal_cols/lines. It gets corrupted
4317 by make_parent_window and we need it below for assigning it to
4319 Lisp_Object new_normal
4320 = horflag
? o
->normal_cols
: o
->normal_lines
;
4322 make_parent_window (old
, horflag
);
4323 p
= XWINDOW (o
->parent
);
4324 if (EQ (Vwindow_combination_limit
, Qt
))
4325 /* Store t in the new parent's combination_limit slot to avoid
4326 that its children get merged into another window. */
4327 wset_combination_limit (p
, Qt
);
4328 /* These get applied below. */
4330 (p
, make_number (horflag
? o
->pixel_width
: o
->pixel_height
));
4332 (p
, make_number (horflag
? o
->total_cols
: o
->total_lines
));
4333 wset_new_normal (p
, new_normal
);
4336 p
= XWINDOW (o
->parent
);
4339 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4340 new = make_window ();
4342 wset_frame (n
, frame
);
4343 wset_parent (n
, o
->parent
);
4345 if (EQ (side
, Qabove
) || EQ (side
, Qleft
))
4347 wset_prev (n
, o
->prev
);
4349 wset_combination (p
, horflag
, new);
4351 wset_next (XWINDOW (n
->prev
), new);
4357 wset_next (n
, o
->next
);
4358 if (!NILP (n
->next
))
4359 wset_prev (XWINDOW (n
->next
), new);
4364 n
->window_end_valid
= 0;
4365 n
->last_cursor_vpos
= 0;
4367 /* Get special geometry settings from reference window. */
4368 n
->left_margin_cols
= r
->left_margin_cols
;
4369 n
->right_margin_cols
= r
->right_margin_cols
;
4370 n
->left_fringe_width
= r
->left_fringe_width
;
4371 n
->right_fringe_width
= r
->right_fringe_width
;
4372 n
->fringes_outside_margins
= r
->fringes_outside_margins
;
4373 n
->scroll_bar_width
= r
->scroll_bar_width
;
4374 wset_vertical_scroll_bar_type (n
, r
->vertical_scroll_bar_type
);
4376 /* Directly assign orthogonal coordinates and sizes. */
4379 n
->pixel_top
= o
->pixel_top
;
4380 n
->top_line
= o
->top_line
;
4381 n
->pixel_height
= o
->pixel_height
;
4382 n
->total_lines
= o
->total_lines
;
4386 n
->pixel_left
= o
->pixel_left
;
4387 n
->left_col
= o
->left_col
;
4388 n
->pixel_width
= o
->pixel_width
;
4389 n
->total_cols
= o
->total_cols
;
4392 /* Iso-coordinates and sizes are assigned by window_resize_apply,
4393 get them ready here. */
4394 wset_new_pixel (n
, pixel_size
);
4395 c
= XWINDOW (p
->contents
);
4399 sum
= sum
+ XINT (c
->new_total
);
4400 c
= NILP (c
->next
) ? 0 : XWINDOW (c
->next
);
4402 wset_new_total (n
, make_number ((horflag
4406 wset_new_normal (n
, normal_size
);
4409 window_resize_apply (p
, horflag
);
4410 adjust_frame_glyphs (f
);
4411 /* Set buffer of NEW to buffer of reference window. Don't run
4413 set_window_buffer (new, r
->contents
, 0, 1);
4416 /* Maybe we should run the scroll functions in Elisp (which already
4417 runs the configuration change hook). */
4418 if (! NILP (Vwindow_scroll_functions
))
4419 run_hook_with_args_2 (Qwindow_scroll_functions
, new,
4420 Fmarker_position (n
->start
));
4426 DEFUN ("delete-window-internal", Fdelete_window_internal
, Sdelete_window_internal
, 1, 1, 0,
4427 doc
: /* Remove WINDOW from its frame.
4428 WINDOW defaults to the selected window. Return nil.
4429 Signal an error when WINDOW is the only window on its frame. */)
4430 (register Lisp_Object window
)
4432 register Lisp_Object parent
, sibling
, frame
, root
;
4433 struct window
*w
, *p
, *s
, *r
;
4435 bool horflag
, before_sibling
= 0;
4437 w
= decode_any_window (window
);
4438 XSETWINDOW (window
, w
);
4439 if (NILP (w
->contents
))
4440 /* It's a no-op to delete an already deleted window. */
4445 /* Never delete a minibuffer or frame root window. */
4446 error ("Attempt to delete minibuffer or sole ordinary window");
4447 else if (NILP (w
->prev
) && NILP (w
->next
))
4448 /* Rather bow out here, this case should be handled on the Elisp
4450 error ("Attempt to delete sole window of parent");
4452 p
= XWINDOW (parent
);
4453 horflag
= WINDOW_HORIZONTAL_COMBINATION_P (p
);
4455 frame
= WINDOW_FRAME (w
);
4458 root
= FRAME_ROOT_WINDOW (f
);
4461 /* Unlink WINDOW from window tree. */
4463 /* Get SIBLING below (on the right of) WINDOW. */
4465 /* before_sibling 1 means WINDOW is the first child of its
4466 parent and thus before the sibling. */
4469 s
= XWINDOW (sibling
);
4470 wset_prev (s
, Qnil
);
4471 wset_combination (p
, horflag
, sibling
);
4474 /* Get SIBLING above (on the left of) WINDOW. */
4477 s
= XWINDOW (sibling
);
4478 wset_next (s
, w
->next
);
4479 if (!NILP (s
->next
))
4480 wset_prev (XWINDOW (s
->next
), sibling
);
4483 if (window_resize_check (r
, horflag
)
4484 && (XINT (r
->new_pixel
)
4485 == (horflag
? r
->pixel_width
: r
->pixel_height
)))
4486 /* We can delete WINDOW now. */
4491 window_resize_apply (p
, horflag
);
4492 /* If this window is referred to by the dpyinfo's mouse
4493 highlight, invalidate that slot to be safe (Bug#9904). */
4494 if (!FRAME_INITIAL_P (f
))
4496 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
4498 if (EQ (hlinfo
->mouse_face_window
, window
))
4499 hlinfo
->mouse_face_window
= Qnil
;
4503 Vwindow_list
= Qnil
;
4504 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4506 wset_next (w
, Qnil
); /* Don't delete w->next too. */
4507 free_window_matrices (w
);
4509 if (WINDOWP (w
->contents
))
4511 delete_all_child_windows (w
->contents
);
4512 wset_combination (w
, 0, Qnil
);
4517 unchain_marker (XMARKER (w
->pointm
));
4518 unchain_marker (XMARKER (w
->start
));
4519 wset_buffer (w
, Qnil
);
4522 if (NILP (s
->prev
) && NILP (s
->next
))
4523 /* A matrjoshka where SIBLING has become the only child of
4526 /* Put SIBLING into PARENT's place. */
4527 replace_window (parent
, sibling
, 0);
4528 /* Have SIBLING inherit the following three slot values from
4529 PARENT (the combination_limit slot is not inherited). */
4530 wset_normal_cols (s
, p
->normal_cols
);
4531 wset_normal_lines (s
, p
->normal_lines
);
4532 /* Mark PARENT as deleted. */
4533 wset_combination (p
, 0, Qnil
);
4534 /* Try to merge SIBLING into its new parent. */
4535 recombine_windows (sibling
);
4538 adjust_frame_glyphs (f
);
4540 if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f
)))
4541 /* We deleted the frame's selected window. */
4543 /* Use the frame's first window as fallback ... */
4544 Lisp_Object new_selected_window
= Fframe_first_window (frame
);
4545 /* ... but preferably use its most recently used window. */
4546 Lisp_Object mru_window
;
4548 /* `get-mru-window' might fail for some reason so play it safe
4549 - promote the first window _without recording it_ first. */
4550 if (EQ (FRAME_SELECTED_WINDOW (f
), selected_window
))
4551 Fselect_window (new_selected_window
, Qt
);
4553 fset_selected_window (f
, new_selected_window
);
4557 /* Now look whether `get-mru-window' gets us something. */
4558 mru_window
= call1 (Qget_mru_window
, frame
);
4559 if (WINDOW_LIVE_P (mru_window
)
4560 && EQ (XWINDOW (mru_window
)->frame
, frame
))
4561 new_selected_window
= mru_window
;
4563 /* If all ended up well, we now promote the mru window. */
4564 if (EQ (FRAME_SELECTED_WINDOW (f
), selected_window
))
4565 Fselect_window (new_selected_window
, Qnil
);
4567 fset_selected_window (f
, new_selected_window
);
4572 /* Must be run by the caller:
4573 run_window_configuration_change_hook (f); */
4576 /* We failed: Relink WINDOW into window tree. */
4580 wset_prev (s
, window
);
4581 wset_combination (p
, horflag
, window
);
4585 wset_next (s
, window
);
4586 if (!NILP (w
->next
))
4587 wset_prev (XWINDOW (w
->next
), window
);
4589 error ("Deletion failed");
4595 /***********************************************************************
4596 Resizing Mini-Windows
4597 ***********************************************************************/
4599 /* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we
4602 grow_mini_window (struct window
*w
, int delta
, bool pixelwise
)
4604 struct frame
*f
= XFRAME (w
->frame
);
4606 Lisp_Object root
, height
;
4607 int line_height
, pixel_height
;
4609 eassert (MINI_WINDOW_P (w
));
4610 eassert (delta
>= 0);
4614 root
= FRAME_ROOT_WINDOW (f
);
4616 height
= call3 (Qwindow_resize_root_window_vertically
,
4617 root
, make_number (- delta
), pixelwise
? Qt
: Qnil
);
4618 if (INTEGERP (height
) && window_resize_check (r
, 0))
4621 window_resize_apply (r
, 0);
4625 pixel_height
= min (-XINT (height
), INT_MAX
- w
->pixel_height
);
4626 line_height
= pixel_height
/ FRAME_LINE_HEIGHT (f
);
4630 line_height
= min (-XINT (height
),
4631 ((INT_MAX
- w
->pixel_height
)
4632 / FRAME_LINE_HEIGHT (f
)));
4633 pixel_height
= line_height
* FRAME_LINE_HEIGHT (f
);
4636 /* Grow the mini-window. */
4637 w
->pixel_top
= r
->pixel_top
+ r
->pixel_height
;
4638 w
->top_line
= r
->top_line
+ r
->total_lines
;
4639 /* Make sure the mini-window has always at least one line. */
4640 w
->pixel_height
= max (w
->pixel_height
+ pixel_height
,
4641 FRAME_LINE_HEIGHT (f
));
4642 w
->total_lines
= max (w
->total_lines
+ line_height
, 1);
4644 /* Enforce full redisplay of the frame. */
4645 /* FIXME: Shouldn't window--resize-root-window-vertically do it? */
4647 adjust_frame_glyphs (f
);
4653 /* Shrink mini-window W to one line. */
4655 shrink_mini_window (struct window
*w
, bool pixelwise
)
4657 struct frame
*f
= XFRAME (w
->frame
);
4659 Lisp_Object root
, delta
;
4660 EMACS_INT height
, unit
;
4662 eassert (MINI_WINDOW_P (w
));
4664 height
= pixelwise
? w
->pixel_height
: w
->total_lines
;
4665 unit
= pixelwise
? FRAME_LINE_HEIGHT (f
) : 1;
4668 root
= FRAME_ROOT_WINDOW (f
);
4670 delta
= call3 (Qwindow_resize_root_window_vertically
,
4671 root
, make_number (height
- unit
),
4672 pixelwise
? Qt
: Qnil
);
4673 if (INTEGERP (delta
) && window_resize_check (r
, 0))
4676 window_resize_apply (r
, 0);
4678 /* Shrink the mini-window. */
4679 w
->top_line
= r
->top_line
+ r
->total_lines
;
4681 w
->pixel_top
= r
->pixel_top
+ r
->pixel_height
;
4682 w
->pixel_height
= FRAME_LINE_HEIGHT (f
);
4683 /* Enforce full redisplay of the frame. */
4684 /* FIXME: Shouldn't window--resize-root-window-vertically do it? */
4686 adjust_frame_glyphs (f
);
4689 /* If the above failed for whatever strange reason we must make a
4690 one window frame here. The same routine will be needed when
4691 shrinking the frame (and probably when making the initial
4692 *scratch* window). For the moment leave things as they are. */
4696 DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal
, Sresize_mini_window_internal
, 1, 1, 0,
4697 doc
: /* Resize minibuffer window WINDOW. */)
4698 (Lisp_Object window
)
4700 struct window
*w
= XWINDOW (window
);
4705 CHECK_WINDOW (window
);
4706 f
= XFRAME (w
->frame
);
4708 if (!EQ (FRAME_MINIBUF_WINDOW (XFRAME (w
->frame
)), window
))
4709 error ("Not a valid minibuffer window");
4710 else if (FRAME_MINIBUF_ONLY_P (f
))
4711 error ("Cannot resize a minibuffer-only frame");
4713 r
= XWINDOW (FRAME_ROOT_WINDOW (f
));
4714 height
= r
->pixel_height
+ w
->pixel_height
;
4715 if (window_resize_check (r
, 0)
4716 && XINT (w
->new_pixel
) > 0
4717 && height
== XINT (r
->new_pixel
) + XINT (w
->new_pixel
))
4720 window_resize_apply (r
, 0);
4722 w
->total_lines
= XFASTINT (w
->new_total
);
4723 w
->top_line
= r
->top_line
+ r
->total_lines
;
4724 w
->pixel_height
= XFASTINT (w
->new_pixel
);
4725 w
->pixel_top
= r
->pixel_top
+ r
->pixel_height
;
4728 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
4729 adjust_frame_glyphs (f
);
4734 error ("Failed to resize minibuffer window");
4737 /* Mark window cursors off for all windows in the window tree rooted
4738 at W by setting their phys_cursor_on_p flag to zero. Called from
4739 xterm.c, e.g. when a frame is cleared and thereby all cursors on
4740 the frame are cleared. */
4743 mark_window_cursors_off (struct window
*w
)
4747 if (WINDOWP (w
->contents
))
4748 mark_window_cursors_off (XWINDOW (w
->contents
));
4750 w
->phys_cursor_on_p
= 0;
4752 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
4757 /* Return number of lines of text (not counting mode lines) in W. */
4760 window_internal_height (struct window
*w
)
4762 int ht
= w
->total_lines
;
4764 if (!MINI_WINDOW_P (w
))
4766 if (!NILP (w
->parent
)
4767 || WINDOWP (w
->contents
)
4770 || WINDOW_WANTS_MODELINE_P (w
))
4773 if (WINDOW_WANTS_HEADER_LINE_P (w
))
4780 /************************************************************************
4782 ***********************************************************************/
4784 /* Scroll contents of window WINDOW up. If WHOLE is non-zero, scroll
4785 N screen-fulls, which is defined as the height of the window minus
4786 next_screen_context_lines. If WHOLE is zero, scroll up N lines
4787 instead. Negative values of N mean scroll down. NOERROR non-zero
4788 means don't signal an error if we try to move over BEGV or ZV,
4792 window_scroll (Lisp_Object window
, EMACS_INT n
, bool whole
, int noerror
)
4795 n
= clip_to_bounds (INT_MIN
, n
, INT_MAX
);
4797 wset_redisplay (XWINDOW (window
));
4799 /* If we must, use the pixel-based version which is much slower than
4800 the line-based one but can handle varying line heights. */
4801 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window
)->frame
)))
4802 window_scroll_pixel_based (window
, n
, whole
, noerror
);
4804 window_scroll_line_based (window
, n
, whole
, noerror
);
4807 XWINDOW (window
)->window_end_valid
= 0;
4812 /* Implementation of window_scroll that works based on pixel line
4813 heights. See the comment of window_scroll for parameter
4817 window_scroll_pixel_based (Lisp_Object window
, int n
, bool whole
, int noerror
)
4820 struct window
*w
= XWINDOW (window
);
4821 struct text_pos start
;
4822 int this_scroll_margin
;
4823 /* True if we fiddled the window vscroll field without really scrolling. */
4825 int x
, y
, rtop
, rbot
, rowh
, vpos
;
4826 void *itdata
= NULL
;
4827 int window_total_lines
;
4828 int frame_line_height
= default_line_pixel_height (w
);
4830 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
4831 /* Scrolling a minibuffer window via scroll bar when the echo area
4832 shows long text sometimes resets the minibuffer contents behind
4834 if (CHARPOS (start
) > ZV
)
4835 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
4837 /* If PT is not visible in WINDOW, move back one half of
4838 the screen. Allow PT to be partially visible, otherwise
4839 something like (scroll-down 1) with PT in the line before
4840 the partially visible one would recenter. */
4842 if (!pos_visible_p (w
, PT
, &x
, &y
, &rtop
, &rbot
, &rowh
, &vpos
))
4844 itdata
= bidi_shelve_cache ();
4845 /* Move backward half the height of the window. Performance note:
4846 vmotion used here is about 10% faster, but would give wrong
4847 results for variable height lines. */
4848 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4849 it
.current_y
= it
.last_visible_y
;
4850 move_it_vertically_backward (&it
, window_box_height (w
) / 2);
4852 /* The function move_iterator_vertically may move over more than
4853 the specified y-distance. If it->w is small, e.g. a
4854 mini-buffer window, we may end up in front of the window's
4855 display area. This is the case when Start displaying at the
4856 start of the line containing PT in this case. */
4857 if (it
.current_y
<= 0)
4859 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
4860 move_it_vertically_backward (&it
, 0);
4864 start
= it
.current
.pos
;
4865 bidi_unshelve_cache (itdata
, 0);
4867 else if (auto_window_vscroll_p
)
4869 if (rtop
|| rbot
) /* partially visible */
4872 int dy
= frame_line_height
;
4874 dy
= max ((window_box_height (w
)
4875 - next_screen_context_lines
* dy
),
4881 /* Only vscroll backwards if already vscrolled forwards. */
4882 if (w
->vscroll
< 0 && rtop
> 0)
4884 px
= max (0, -w
->vscroll
- min (rtop
, -dy
));
4885 Fset_window_vscroll (window
, make_number (px
), Qt
);
4891 /* Do vscroll if already vscrolled or only display line. */
4892 if (rbot
> 0 && (w
->vscroll
< 0 || vpos
== 0))
4894 px
= max (0, -w
->vscroll
+ min (rbot
, dy
));
4895 Fset_window_vscroll (window
, make_number (px
), Qt
);
4899 /* Maybe modify window start instead of scrolling. */
4900 if (rbot
> 0 || w
->vscroll
< 0)
4904 Fset_window_vscroll (window
, make_number (0), Qt
);
4905 /* If there are other text lines above the current row,
4906 move window start to current row. Else to next row. */
4908 spos
= XINT (Fline_beginning_position (Qnil
));
4910 spos
= min (XINT (Fline_end_position (Qnil
)) + 1, ZV
);
4911 set_marker_restricted (w
->start
, make_number (spos
),
4913 w
->start_at_line_beg
= 1;
4914 w
->update_mode_line
= 1;
4915 /* Set force_start so that redisplay_window will run the
4916 window-scroll-functions. */
4922 /* Cancel previous vscroll. */
4923 Fset_window_vscroll (window
, make_number (0), Qt
);
4926 itdata
= bidi_shelve_cache ();
4927 /* If scroll_preserve_screen_position is non-nil, we try to set
4928 point in the same window line as it is now, so get that line. */
4929 if (!NILP (Vscroll_preserve_screen_position
))
4931 /* We preserve the goal pixel coordinate across consecutive
4932 calls to scroll-up, scroll-down and other commands that
4933 have the `scroll-command' property. This avoids the
4934 possibility of point becoming "stuck" on a tall line when
4935 scrolling by one line. */
4936 if (window_scroll_pixel_based_preserve_y
< 0
4937 || !SYMBOLP (KVAR (current_kboard
, Vlast_command
))
4938 || NILP (Fget (KVAR (current_kboard
, Vlast_command
), Qscroll_command
)))
4940 start_display (&it
, w
, start
);
4941 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
4942 window_scroll_pixel_based_preserve_y
= it
.current_y
;
4943 window_scroll_pixel_based_preserve_x
= it
.current_x
;
4947 window_scroll_pixel_based_preserve_y
4948 = window_scroll_pixel_based_preserve_x
= -1;
4950 /* Move iterator it from start the specified distance forward or
4951 backward. The result is the new window start. */
4952 start_display (&it
, w
, start
);
4955 ptrdiff_t start_pos
= IT_CHARPOS (it
);
4956 int dy
= frame_line_height
;
4957 dy
= max ((window_box_height (w
)
4958 - next_screen_context_lines
* dy
),
4961 /* Note that move_it_vertically always moves the iterator to the
4962 start of a line. So, if the last line doesn't have a newline,
4963 we would end up at the start of the line ending at ZV. */
4966 move_it_vertically_backward (&it
, -dy
);
4967 /* Ensure we actually do move, e.g. in case we are currently
4968 looking at an image that is taller that the window height. */
4969 while (start_pos
== IT_CHARPOS (it
)
4970 && start_pos
> BEGV
)
4971 move_it_by_lines (&it
, -1);
4975 move_it_to (&it
, ZV
, -1, it
.current_y
+ dy
, -1,
4976 MOVE_TO_POS
| MOVE_TO_Y
);
4977 /* Ensure we actually do move, e.g. in case we are currently
4978 looking at an image that is taller that the window height. */
4979 while (start_pos
== IT_CHARPOS (it
)
4981 move_it_by_lines (&it
, 1);
4985 move_it_by_lines (&it
, n
);
4987 /* We failed if we find ZV is already on the screen (scrolling up,
4988 means there's nothing past the end), or if we can't start any
4989 earlier (scrolling down, means there's nothing past the top). */
4990 if ((n
> 0 && IT_CHARPOS (it
) == ZV
)
4991 || (n
< 0 && IT_CHARPOS (it
) == CHARPOS (start
)))
4993 if (IT_CHARPOS (it
) == ZV
)
4995 if (it
.current_y
< it
.last_visible_y
4996 && (it
.current_y
+ it
.max_ascent
+ it
.max_descent
4997 > it
.last_visible_y
))
4999 /* The last line was only partially visible, make it fully
5001 w
->vscroll
= (it
.last_visible_y
5002 - it
.current_y
+ it
.max_ascent
+ it
.max_descent
);
5003 adjust_frame_glyphs (it
.f
);
5007 bidi_unshelve_cache (itdata
, 0);
5010 else if (n
< 0) /* could happen with empty buffers */
5011 xsignal0 (Qbeginning_of_buffer
);
5013 xsignal0 (Qend_of_buffer
);
5018 if (w
->vscroll
!= 0)
5019 /* The first line was only partially visible, make it fully
5024 bidi_unshelve_cache (itdata
, 0);
5028 xsignal0 (Qbeginning_of_buffer
);
5032 /* If control gets here, then we vscrolled. */
5034 XBUFFER (w
->contents
)->prevent_redisplay_optimizations_p
= 1;
5036 /* Don't try to change the window start below. */
5042 ptrdiff_t pos
= IT_CHARPOS (it
);
5045 /* If in the middle of a multi-glyph character move forward to
5046 the next character. */
5047 if (in_display_vector_p (&it
))
5050 move_it_to (&it
, pos
, -1, -1, -1, MOVE_TO_POS
);
5053 /* Set the window start, and set up the window for redisplay. */
5054 set_marker_restricted_both (w
->start
, w
->contents
, IT_CHARPOS (it
),
5056 bytepos
= marker_byte_position (w
->start
);
5057 w
->start_at_line_beg
= (pos
== BEGV
|| FETCH_BYTE (bytepos
- 1) == '\n');
5058 w
->update_mode_line
= 1;
5059 /* Set force_start so that redisplay_window will run the
5060 window-scroll-functions. */
5064 /* The rest of this function uses current_y in a nonstandard way,
5065 not including the height of the header line if any. */
5066 it
.current_y
= it
.vpos
= 0;
5068 /* Move PT out of scroll margins.
5069 This code wants current_y to be zero at the window start position
5070 even if there is a header line. */
5072 = w
->total_lines
* WINDOW_FRAME_LINE_HEIGHT (w
) / frame_line_height
;
5073 this_scroll_margin
= max (0, scroll_margin
);
5075 = min (this_scroll_margin
, window_total_lines
/ 4);
5076 this_scroll_margin
*= frame_line_height
;
5080 /* We moved the window start towards ZV, so PT may be now
5081 in the scroll margin at the top. */
5082 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
5083 if (IT_CHARPOS (it
) == PT
&& it
.current_y
>= this_scroll_margin
5084 && (NILP (Vscroll_preserve_screen_position
)
5085 || EQ (Vscroll_preserve_screen_position
, Qt
)))
5086 /* We found PT at a legitimate height. Leave it alone. */
5088 else if (window_scroll_pixel_based_preserve_y
>= 0)
5090 /* If we have a header line, take account of it.
5091 This is necessary because we set it.current_y to 0, above. */
5092 move_it_to (&it
, -1,
5093 window_scroll_pixel_based_preserve_x
,
5094 window_scroll_pixel_based_preserve_y
5095 - (WINDOW_WANTS_HEADER_LINE_P (w
) ? 1 : 0 ),
5096 -1, MOVE_TO_Y
| MOVE_TO_X
);
5097 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5101 while (it
.current_y
< this_scroll_margin
)
5103 int prev
= it
.current_y
;
5104 move_it_by_lines (&it
, 1);
5105 if (prev
== it
.current_y
)
5108 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5113 ptrdiff_t charpos
, bytepos
;
5116 /* Save our position, for the
5117 window_scroll_pixel_based_preserve_y case. */
5118 charpos
= IT_CHARPOS (it
);
5119 bytepos
= IT_BYTEPOS (it
);
5121 /* We moved the window start towards BEGV, so PT may be now
5122 in the scroll margin at the bottom. */
5123 move_it_to (&it
, PT
, -1,
5124 (it
.last_visible_y
- CURRENT_HEADER_LINE_HEIGHT (w
)
5125 - this_scroll_margin
- 1),
5127 MOVE_TO_POS
| MOVE_TO_Y
);
5129 /* Save our position, in case it's correct. */
5130 charpos
= IT_CHARPOS (it
);
5131 bytepos
= IT_BYTEPOS (it
);
5133 /* See if point is on a partially visible line at the end. */
5134 if (it
.what
== IT_EOB
)
5135 partial_p
= it
.current_y
+ it
.ascent
+ it
.descent
> it
.last_visible_y
;
5138 move_it_by_lines (&it
, 1);
5139 partial_p
= it
.current_y
> it
.last_visible_y
;
5142 if (charpos
== PT
&& !partial_p
5143 && (NILP (Vscroll_preserve_screen_position
)
5144 || EQ (Vscroll_preserve_screen_position
, Qt
)))
5145 /* We found PT before we found the display margin, so PT is ok. */
5147 else if (window_scroll_pixel_based_preserve_y
>= 0)
5149 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
5150 start_display (&it
, w
, start
);
5151 /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT
5152 here because we called start_display again and did not
5153 alter it.current_y this time. */
5154 move_it_to (&it
, -1, window_scroll_pixel_based_preserve_x
,
5155 window_scroll_pixel_based_preserve_y
, -1,
5156 MOVE_TO_Y
| MOVE_TO_X
);
5157 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5162 /* The last line was only partially visible, so back up two
5163 lines to make sure we're on a fully visible line. */
5165 move_it_by_lines (&it
, -2);
5166 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
5169 /* No, the position we saved is OK, so use it. */
5170 SET_PT_BOTH (charpos
, bytepos
);
5173 bidi_unshelve_cache (itdata
, 0);
5177 /* Implementation of window_scroll that works based on screen lines.
5178 See the comment of window_scroll for parameter descriptions. */
5181 window_scroll_line_based (Lisp_Object window
, int n
, bool whole
, int noerror
)
5183 register struct window
*w
= XWINDOW (window
);
5184 /* Fvertical_motion enters redisplay, which can trigger
5185 fontification, which in turn can modify buffer text (e.g., if the
5186 fontification functions replace escape sequences with faces, as
5187 in `grep-mode-font-lock-keywords'). So we use a marker to record
5188 the old point position, to prevent crashes in SET_PT_BOTH. */
5189 Lisp_Object opoint_marker
= Fpoint_marker ();
5190 register ptrdiff_t pos
, pos_byte
;
5191 register int ht
= window_internal_height (w
);
5192 register Lisp_Object tem
;
5195 ptrdiff_t startpos
= marker_position (w
->start
);
5196 ptrdiff_t startbyte
= marker_byte_position (w
->start
);
5197 Lisp_Object original_pos
= Qnil
;
5199 /* If scrolling screen-fulls, compute the number of lines to
5200 scroll from the window's height. */
5202 n
*= max (1, ht
- next_screen_context_lines
);
5204 if (!NILP (Vscroll_preserve_screen_position
))
5206 if (window_scroll_preserve_vpos
<= 0
5207 || !SYMBOLP (KVAR (current_kboard
, Vlast_command
))
5208 || NILP (Fget (KVAR (current_kboard
, Vlast_command
), Qscroll_command
)))
5210 struct position posit
5211 = *compute_motion (startpos
, startbyte
, 0, 0, 0,
5212 PT
, ht
, 0, -1, w
->hscroll
, 0, w
);
5213 window_scroll_preserve_vpos
= posit
.vpos
;
5214 window_scroll_preserve_hpos
= posit
.hpos
+ w
->hscroll
;
5217 original_pos
= Fcons (make_number (window_scroll_preserve_hpos
),
5218 make_number (window_scroll_preserve_vpos
));
5221 XSETFASTINT (tem
, PT
);
5222 tem
= Fpos_visible_in_window_p (tem
, window
, Qnil
);
5226 Fvertical_motion (make_number (- (ht
/ 2)), window
);
5228 startbyte
= PT_BYTE
;
5231 SET_PT_BOTH (startpos
, startbyte
);
5232 lose
= n
< 0 && PT
== BEGV
;
5233 Fvertical_motion (make_number (n
), window
);
5237 SET_PT_BOTH (marker_position (opoint_marker
),
5238 marker_byte_position (opoint_marker
));
5245 xsignal0 (Qbeginning_of_buffer
);
5250 /* Don't use a scroll margin that is negative or too large. */
5251 int this_scroll_margin
=
5252 max (0, min (scroll_margin
, w
->total_lines
/ 4));
5254 set_marker_restricted_both (w
->start
, w
->contents
, pos
, pos_byte
);
5255 w
->start_at_line_beg
= !NILP (bolp
);
5256 w
->update_mode_line
= 1;
5257 /* Set force_start so that redisplay_window will run
5258 the window-scroll-functions. */
5261 if (!NILP (Vscroll_preserve_screen_position
)
5262 && (whole
|| !EQ (Vscroll_preserve_screen_position
, Qt
)))
5264 SET_PT_BOTH (pos
, pos_byte
);
5265 Fvertical_motion (original_pos
, window
);
5267 /* If we scrolled forward, put point enough lines down
5268 that it is outside the scroll margin. */
5273 if (this_scroll_margin
> 0)
5275 SET_PT_BOTH (pos
, pos_byte
);
5276 Fvertical_motion (make_number (this_scroll_margin
), window
);
5282 if (top_margin
<= marker_position (opoint_marker
))
5283 SET_PT_BOTH (marker_position (opoint_marker
),
5284 marker_byte_position (opoint_marker
));
5285 else if (!NILP (Vscroll_preserve_screen_position
))
5287 SET_PT_BOTH (pos
, pos_byte
);
5288 Fvertical_motion (original_pos
, window
);
5291 SET_PT (top_margin
);
5297 /* If we scrolled backward, put point near the end of the window
5298 but not within the scroll margin. */
5299 SET_PT_BOTH (pos
, pos_byte
);
5300 tem
= Fvertical_motion (make_number (ht
- this_scroll_margin
), window
);
5301 if (XFASTINT (tem
) == ht
- this_scroll_margin
)
5304 bottom_margin
= PT
+ 1;
5306 if (bottom_margin
> marker_position (opoint_marker
))
5307 SET_PT_BOTH (marker_position (opoint_marker
),
5308 marker_byte_position (opoint_marker
));
5311 if (!NILP (Vscroll_preserve_screen_position
))
5313 SET_PT_BOTH (pos
, pos_byte
);
5314 Fvertical_motion (original_pos
, window
);
5317 Fvertical_motion (make_number (-1), window
);
5326 xsignal0 (Qend_of_buffer
);
5331 /* Scroll selected_window up or down. If N is nil, scroll a
5332 screen-full which is defined as the height of the window minus
5333 next_screen_context_lines. If N is the symbol `-', scroll.
5334 DIRECTION may be 1 meaning to scroll down, or -1 meaning to scroll
5335 up. This is the guts of Fscroll_up and Fscroll_down. */
5338 scroll_command (Lisp_Object n
, int direction
)
5340 ptrdiff_t count
= SPECPDL_INDEX ();
5342 eassert (eabs (direction
) == 1);
5344 /* If selected window's buffer isn't current, make it current for
5345 the moment. But don't screw up if window_scroll gets an error. */
5346 if (XBUFFER (XWINDOW (selected_window
)->contents
) != current_buffer
)
5348 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
5349 Fset_buffer (XWINDOW (selected_window
)->contents
);
5353 window_scroll (selected_window
, direction
, 1, 0);
5354 else if (EQ (n
, Qminus
))
5355 window_scroll (selected_window
, -direction
, 1, 0);
5358 n
= Fprefix_numeric_value (n
);
5359 window_scroll (selected_window
, XINT (n
) * direction
, 0, 0);
5362 unbind_to (count
, Qnil
);
5365 DEFUN ("scroll-up", Fscroll_up
, Sscroll_up
, 0, 1, "^P",
5366 doc
: /* Scroll text of selected window upward ARG lines.
5367 If ARG is omitted or nil, scroll upward by a near full screen.
5368 A near full screen is `next-screen-context-lines' less than a full screen.
5369 Negative ARG means scroll downward.
5370 If ARG is the atom `-', scroll downward by nearly full screen.
5371 When calling from a program, supply as argument a number, nil, or `-'. */)
5374 scroll_command (arg
, 1);
5378 DEFUN ("scroll-down", Fscroll_down
, Sscroll_down
, 0, 1, "^P",
5379 doc
: /* Scroll text of selected window down ARG lines.
5380 If ARG is omitted or nil, scroll down by a near full screen.
5381 A near full screen is `next-screen-context-lines' less than a full screen.
5382 Negative ARG means scroll upward.
5383 If ARG is the atom `-', scroll upward by nearly full screen.
5384 When calling from a program, supply as argument a number, nil, or `-'. */)
5387 scroll_command (arg
, -1);
5391 DEFUN ("other-window-for-scrolling", Fother_window_for_scrolling
, Sother_window_for_scrolling
, 0, 0, 0,
5392 doc
: /* Return the other window for \"other window scroll\" commands.
5393 If `other-window-scroll-buffer' is non-nil, a window
5394 showing that buffer is used.
5395 If in the minibuffer, `minibuffer-scroll-window' if non-nil
5396 specifies the window. This takes precedence over
5397 `other-window-scroll-buffer'. */)
5402 if (MINI_WINDOW_P (XWINDOW (selected_window
))
5403 && !NILP (Vminibuf_scroll_window
))
5404 window
= Vminibuf_scroll_window
;
5405 /* If buffer is specified, scroll that buffer. */
5406 else if (!NILP (Vother_window_scroll_buffer
))
5408 window
= Fget_buffer_window (Vother_window_scroll_buffer
, Qnil
);
5410 window
= display_buffer (Vother_window_scroll_buffer
, Qt
, Qnil
);
5414 /* Nothing specified; look for a neighboring window on the same
5416 window
= Fnext_window (selected_window
, Qnil
, Qnil
);
5418 if (EQ (window
, selected_window
))
5419 /* That didn't get us anywhere; look for a window on another
5422 window
= Fnext_window (window
, Qnil
, Qt
);
5423 while (! FRAME_VISIBLE_P (XFRAME (WINDOW_FRAME (XWINDOW (window
))))
5424 && ! EQ (window
, selected_window
));
5427 CHECK_LIVE_WINDOW (window
);
5429 if (EQ (window
, selected_window
))
5430 error ("There is no other window");
5435 DEFUN ("scroll-other-window", Fscroll_other_window
, Sscroll_other_window
, 0, 1, "P",
5436 doc
: /* Scroll next window upward ARG lines; or near full screen if no ARG.
5437 A near full screen is `next-screen-context-lines' less than a full screen.
5438 The next window is the one below the current one; or the one at the top
5439 if the current one is at the bottom. Negative ARG means scroll downward.
5440 If ARG is the atom `-', scroll downward by nearly full screen.
5441 When calling from a program, supply as argument a number, nil, or `-'.
5443 If `other-window-scroll-buffer' is non-nil, scroll the window
5444 showing that buffer, popping the buffer up if necessary.
5445 If in the minibuffer, `minibuffer-scroll-window' if non-nil
5446 specifies the window to scroll. This takes precedence over
5447 `other-window-scroll-buffer'. */)
5452 ptrdiff_t count
= SPECPDL_INDEX ();
5454 window
= Fother_window_for_scrolling ();
5455 w
= XWINDOW (window
);
5457 /* Don't screw up if window_scroll gets an error. */
5458 record_unwind_protect (save_excursion_restore
, save_excursion_save ());
5460 Fset_buffer (w
->contents
);
5461 SET_PT_BOTH (marker_position (w
->pointm
), marker_byte_position (w
->pointm
));
5464 window_scroll (window
, 1, 1, 1);
5465 else if (EQ (arg
, Qminus
))
5466 window_scroll (window
, -1, 1, 1);
5472 window_scroll (window
, XINT (arg
), 0, 1);
5475 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
5476 unbind_to (count
, Qnil
);
5481 DEFUN ("scroll-left", Fscroll_left
, Sscroll_left
, 0, 2, "^P\np",
5482 doc
: /* Scroll selected window display ARG columns left.
5483 Default for ARG is window width minus 2.
5484 Value is the total amount of leftward horizontal scrolling in
5485 effect after the change.
5486 If SET-MINIMUM is non-nil, the new scroll amount becomes the
5487 lower bound for automatic scrolling, i.e. automatic scrolling
5488 will not scroll a window to a column less than the value returned
5489 by this function. This happens in an interactive call. */)
5490 (register Lisp_Object arg
, Lisp_Object set_minimum
)
5492 struct window
*w
= XWINDOW (selected_window
);
5493 EMACS_INT requested_arg
= (NILP (arg
)
5494 ? window_body_width (w
, 0) - 2
5495 : XINT (Fprefix_numeric_value (arg
)));
5496 Lisp_Object result
= set_window_hscroll (w
, w
->hscroll
+ requested_arg
);
5498 if (!NILP (set_minimum
))
5499 w
->min_hscroll
= w
->hscroll
;
5504 DEFUN ("scroll-right", Fscroll_right
, Sscroll_right
, 0, 2, "^P\np",
5505 doc
: /* Scroll selected window display ARG columns right.
5506 Default for ARG is window width minus 2.
5507 Value is the total amount of leftward horizontal scrolling in
5508 effect after the change.
5509 If SET-MINIMUM is non-nil, the new scroll amount becomes the
5510 lower bound for automatic scrolling, i.e. automatic scrolling
5511 will not scroll a window to a column less than the value returned
5512 by this function. This happens in an interactive call. */)
5513 (register Lisp_Object arg
, Lisp_Object set_minimum
)
5515 struct window
*w
= XWINDOW (selected_window
);
5516 EMACS_INT requested_arg
= (NILP (arg
)
5517 ? window_body_width (w
, 0) - 2
5518 : XINT (Fprefix_numeric_value (arg
)));
5519 Lisp_Object result
= set_window_hscroll (w
, w
->hscroll
- requested_arg
);
5521 if (!NILP (set_minimum
))
5522 w
->min_hscroll
= w
->hscroll
;
5527 DEFUN ("minibuffer-selected-window", Fminibuffer_selected_window
, Sminibuffer_selected_window
, 0, 0, 0,
5528 doc
: /* Return the window which was selected when entering the minibuffer.
5529 Returns nil, if selected window is not a minibuffer window. */)
5532 if (minibuf_level
> 0
5533 && MINI_WINDOW_P (XWINDOW (selected_window
))
5534 && WINDOW_LIVE_P (minibuf_selected_window
))
5535 return minibuf_selected_window
;
5540 /* Value is the number of lines actually displayed in window W,
5541 as opposed to its height. */
5544 displayed_window_lines (struct window
*w
)
5547 struct text_pos start
;
5548 int height
= window_box_height (w
);
5549 struct buffer
*old_buffer
;
5551 void *itdata
= NULL
;
5553 if (XBUFFER (w
->contents
) != current_buffer
)
5555 old_buffer
= current_buffer
;
5556 set_buffer_internal (XBUFFER (w
->contents
));
5561 /* In case W->start is out of the accessible range, do something
5562 reasonable. This happens in Info mode when Info-scroll-down
5563 calls (recenter -1) while W->start is 1. */
5564 CLIP_TEXT_POS_FROM_MARKER (start
, w
->start
);
5566 itdata
= bidi_shelve_cache ();
5567 start_display (&it
, w
, start
);
5568 move_it_vertically (&it
, height
);
5569 bottom_y
= line_bottom_y (&it
);
5570 bidi_unshelve_cache (itdata
, 0);
5572 /* rms: On a non-window display,
5573 the value of it.vpos at the bottom of the screen
5574 seems to be 1 larger than window_box_height (w).
5575 This kludge fixes a bug whereby (move-to-window-line -1)
5576 when ZV is on the last screen line
5577 moves to the previous screen line instead of the last one. */
5578 if (! FRAME_WINDOW_P (XFRAME (w
->frame
)))
5581 /* Add in empty lines at the bottom of the window. */
5582 if (bottom_y
< height
)
5584 int uy
= FRAME_LINE_HEIGHT (it
.f
);
5585 it
.vpos
+= (height
- bottom_y
+ uy
- 1) / uy
;
5589 set_buffer_internal (old_buffer
);
5595 DEFUN ("recenter", Frecenter
, Srecenter
, 0, 1, "P",
5596 doc
: /* Center point in selected window and maybe redisplay frame.
5597 With a numeric prefix argument ARG, recenter putting point on screen line ARG
5598 relative to the selected window. If ARG is negative, it counts up from the
5599 bottom of the window. (ARG should be less than the height of the window.)
5601 If ARG is omitted or nil, then recenter with point on the middle line of
5602 the selected window; if the variable `recenter-redisplay' is non-nil,
5603 also erase the entire frame and redraw it (when `auto-resize-tool-bars'
5604 is set to `grow-only', this resets the tool-bar's height to the minimum
5605 height needed); if `recenter-redisplay' has the special value `tty',
5606 then only tty frames are redrawn.
5608 Just C-u as prefix means put point in the center of the window
5609 and redisplay normally--don't erase and redraw the frame. */)
5610 (register Lisp_Object arg
)
5612 struct window
*w
= XWINDOW (selected_window
);
5613 struct buffer
*buf
= XBUFFER (w
->contents
);
5614 struct buffer
*obuf
= current_buffer
;
5616 ptrdiff_t charpos
, bytepos
;
5617 EMACS_INT iarg
IF_LINT (= 0);
5618 int this_scroll_margin
;
5620 /* If redisplay is suppressed due to an error, try again. */
5621 obuf
->display_error_modiff
= 0;
5625 if (!NILP (Vrecenter_redisplay
)
5626 && (!EQ (Vrecenter_redisplay
, Qtty
)
5627 || !NILP (Ftty_type (selected_frame
))))
5631 /* Invalidate pixel data calculated for all compositions. */
5632 for (i
= 0; i
< n_compositions
; i
++)
5633 composition_table
[i
]->font
= NULL
;
5634 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
5635 WINDOW_XFRAME (w
)->minimize_tool_bar_window_p
= 1;
5637 Fredraw_frame (WINDOW_FRAME (w
));
5638 SET_FRAME_GARBAGED (WINDOW_XFRAME (w
));
5643 else if (CONSP (arg
)) /* Just C-u. */
5647 arg
= Fprefix_numeric_value (arg
);
5652 set_buffer_internal (buf
);
5654 /* Do this after making BUF current
5655 in case scroll_margin is buffer-local. */
5656 this_scroll_margin
=
5657 max (0, min (scroll_margin
, w
->total_lines
/ 4));
5659 /* Handle centering on a graphical frame specially. Such frames can
5660 have variable-height lines and centering point on the basis of
5661 line counts would lead to strange effects. */
5662 if (FRAME_WINDOW_P (XFRAME (w
->frame
)))
5668 void *itdata
= bidi_shelve_cache ();
5670 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
5671 start_display (&it
, w
, pt
);
5672 move_it_vertically_backward (&it
, window_box_height (w
) / 2);
5673 charpos
= IT_CHARPOS (it
);
5674 bytepos
= IT_BYTEPOS (it
);
5675 bidi_unshelve_cache (itdata
, 0);
5681 ptrdiff_t nlines
= min (PTRDIFF_MAX
, -iarg
);
5682 int extra_line_spacing
;
5683 int h
= window_box_height (w
);
5684 void *itdata
= bidi_shelve_cache ();
5686 iarg
= - max (-iarg
, this_scroll_margin
);
5688 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
5689 start_display (&it
, w
, pt
);
5691 /* Be sure we have the exact height of the full line containing PT. */
5692 move_it_by_lines (&it
, 0);
5694 /* The amount of pixels we have to move back is the window
5695 height minus what's displayed in the line containing PT,
5696 and the lines below. */
5699 move_it_by_lines (&it
, nlines
);
5701 if (it
.vpos
== nlines
)
5705 /* Last line has no newline */
5706 h
-= line_bottom_y (&it
);
5710 /* Don't reserve space for extra line spacing of last line. */
5711 extra_line_spacing
= it
.max_extra_line_spacing
;
5713 /* If we can't move down NLINES lines because we hit
5714 the end of the buffer, count in some empty lines. */
5715 if (it
.vpos
< nlines
)
5718 extra_line_spacing
= it
.extra_line_spacing
;
5719 h
-= nlines
* (FRAME_LINE_HEIGHT (it
.f
) + extra_line_spacing
);
5723 bidi_unshelve_cache (itdata
, 0);
5727 /* Now find the new top line (starting position) of the window. */
5728 start_display (&it
, w
, pt
);
5730 move_it_vertically_backward (&it
, h
);
5732 /* If extra line spacing is present, we may move too far
5733 back. This causes the last line to be only partially
5734 visible (which triggers redisplay to recenter that line
5735 in the middle), so move forward.
5736 But ignore extra line spacing on last line, as it is not
5737 considered to be part of the visible height of the line.
5739 h
+= extra_line_spacing
;
5740 while (-it
.current_y
> h
)
5741 move_it_by_lines (&it
, 1);
5743 charpos
= IT_CHARPOS (it
);
5744 bytepos
= IT_BYTEPOS (it
);
5746 bidi_unshelve_cache (itdata
, 0);
5750 struct position pos
;
5752 iarg
= max (iarg
, this_scroll_margin
);
5754 pos
= *vmotion (PT
, PT_BYTE
, -iarg
, w
);
5755 charpos
= pos
.bufpos
;
5756 bytepos
= pos
.bytepos
;
5761 struct position pos
;
5762 int ht
= window_internal_height (w
);
5769 /* Don't let it get into the margin at either top or bottom. */
5770 iarg
= clip_to_bounds (this_scroll_margin
, iarg
,
5771 ht
- this_scroll_margin
- 1);
5773 pos
= *vmotion (PT
, PT_BYTE
, - iarg
, w
);
5774 charpos
= pos
.bufpos
;
5775 bytepos
= pos
.bytepos
;
5778 /* Set the new window start. */
5779 set_marker_both (w
->start
, w
->contents
, charpos
, bytepos
);
5780 w
->window_end_valid
= 0;
5782 w
->optional_new_start
= 1;
5784 w
->start_at_line_beg
= (bytepos
== BEGV_BYTE
||
5785 FETCH_BYTE (bytepos
- 1) == '\n');
5787 set_buffer_internal (obuf
);
5791 DEFUN ("window-text-width", Fwindow_text_width
, Swindow_text_width
,
5793 doc
: /* Return the width in columns of the text display area of WINDOW.
5794 WINDOW must be a live window and defaults to the selected one.
5796 The returned width does not include dividers, scrollbars, margins,
5797 fringes, nor any partial-width columns at the right of the text
5799 (Lisp_Object window
)
5801 struct window
*w
= decode_live_window (window
);
5803 return make_number (window_box_width (w
, TEXT_AREA
)
5804 / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w
)));
5807 DEFUN ("window-text-height", Fwindow_text_height
, Swindow_text_height
,
5809 doc
: /* Return the height in lines of the text display area of WINDOW.
5810 WINDOW must be a live window and defaults to the selected one.
5812 The returned height does not include dividers, the mode line, any header
5813 line, nor any partial-height lines at the bottom of the text area. */)
5814 (Lisp_Object window
)
5816 struct window
*w
= decode_live_window (window
);
5818 return make_number (window_box_height (w
)
5819 / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w
)));
5822 DEFUN ("move-to-window-line", Fmove_to_window_line
, Smove_to_window_line
,
5824 doc
: /* Position point relative to window.
5825 ARG nil means position point at center of window.
5826 Else, ARG specifies vertical position within the window;
5827 zero means top of window, negative means relative to bottom of window. */)
5830 struct window
*w
= XWINDOW (selected_window
);
5834 int this_scroll_margin
;
5837 if (!(BUFFERP (w
->contents
) && XBUFFER (w
->contents
) == current_buffer
))
5838 /* This test is needed to make sure PT/PT_BYTE make sense in w->contents
5839 when passed below to set_marker_both. */
5840 error ("move-to-window-line called from unrelated buffer");
5842 window
= selected_window
;
5843 start
= marker_position (w
->start
);
5844 if (start
< BEGV
|| start
> ZV
)
5846 int height
= window_internal_height (w
);
5847 Fvertical_motion (make_number (- (height
/ 2)), window
);
5848 set_marker_both (w
->start
, w
->contents
, PT
, PT_BYTE
);
5849 w
->start_at_line_beg
= !NILP (Fbolp ());
5853 Fgoto_char (w
->start
);
5855 lines
= displayed_window_lines (w
);
5858 this_scroll_margin
= max (0, min (scroll_margin
, lines
/ 4));
5862 XSETFASTINT (arg
, lines
/ 2);
5865 EMACS_INT iarg
= XINT (Fprefix_numeric_value (arg
));
5868 iarg
= iarg
+ lines
;
5870 #if 0 /* This code would prevent move-to-window-line from moving point
5871 to a place inside the scroll margins (which would cause the
5872 next redisplay to scroll). I wrote this code, but then concluded
5873 it is probably better not to install it. However, it is here
5874 inside #if 0 so as not to lose it. -- rms. */
5876 /* Don't let it get into the margin at either top or bottom. */
5877 iarg
= max (iarg
, this_scroll_margin
);
5878 iarg
= min (iarg
, lines
- this_scroll_margin
- 1);
5881 arg
= make_number (iarg
);
5884 /* Skip past a partially visible first line. */
5886 XSETINT (arg
, XINT (arg
) + 1);
5888 return Fvertical_motion (arg
, window
);
5893 /***********************************************************************
5894 Window Configuration
5895 ***********************************************************************/
5897 struct save_window_data
5899 struct vectorlike_header header
;
5900 Lisp_Object selected_frame
;
5901 Lisp_Object current_window
;
5902 Lisp_Object current_buffer
;
5903 Lisp_Object minibuf_scroll_window
;
5904 Lisp_Object minibuf_selected_window
;
5905 Lisp_Object root_window
;
5906 Lisp_Object focus_frame
;
5907 /* A vector, each of whose elements is a struct saved_window
5909 Lisp_Object saved_windows
;
5911 /* All fields above are traced by the GC.
5912 From `frame-cols' down, the fields are ignored by the GC. */
5913 /* We should be able to do without the following two. */
5914 int frame_cols
, frame_lines
;
5915 /* These two should get eventually replaced by their pixel
5917 int frame_menu_bar_lines
, frame_tool_bar_lines
;
5918 int frame_text_width
, frame_text_height
;
5919 /* These are currently unused. We need them as soon as we convert
5921 int frame_menu_bar_height
, frame_tool_bar_height
;
5924 /* This is saved as a Lisp_Vector */
5927 struct vectorlike_header header
;
5929 Lisp_Object window
, buffer
, start
, pointm
, mark
;
5930 Lisp_Object pixel_left
, pixel_top
, pixel_height
, pixel_width
;
5931 Lisp_Object left_col
, top_line
, total_cols
, total_lines
;
5932 Lisp_Object normal_cols
, normal_lines
;
5933 Lisp_Object hscroll
, min_hscroll
;
5934 Lisp_Object parent
, prev
;
5935 Lisp_Object start_at_line_beg
;
5936 Lisp_Object display_table
;
5937 Lisp_Object left_margin_cols
, right_margin_cols
;
5938 Lisp_Object left_fringe_width
, right_fringe_width
, fringes_outside_margins
;
5939 Lisp_Object scroll_bar_width
, vertical_scroll_bar_type
, dedicated
;
5940 Lisp_Object combination_limit
, window_parameters
;
5943 #define SAVED_WINDOW_N(swv,n) \
5944 ((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
5946 DEFUN ("window-configuration-p", Fwindow_configuration_p
, Swindow_configuration_p
, 1, 1, 0,
5947 doc
: /* Return t if OBJECT is a window-configuration object. */)
5948 (Lisp_Object object
)
5950 return WINDOW_CONFIGURATIONP (object
) ? Qt
: Qnil
;
5953 DEFUN ("window-configuration-frame", Fwindow_configuration_frame
, Swindow_configuration_frame
, 1, 1, 0,
5954 doc
: /* Return the frame that CONFIG, a window-configuration object, is about. */)
5955 (Lisp_Object config
)
5957 register struct save_window_data
*data
;
5958 struct Lisp_Vector
*saved_windows
;
5960 CHECK_WINDOW_CONFIGURATION (config
);
5962 data
= (struct save_window_data
*) XVECTOR (config
);
5963 saved_windows
= XVECTOR (data
->saved_windows
);
5964 return XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
5967 /* From Chong's unwind_create_frame_1. */
5969 unwind_change_frame (Lisp_Object val
)
5971 inhibit_lisp_code
= val
;
5974 DEFUN ("set-window-configuration", Fset_window_configuration
,
5975 Sset_window_configuration
, 1, 1, 0,
5976 doc
: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
5977 CONFIGURATION must be a value previously returned
5978 by `current-window-configuration' (which see).
5979 If CONFIGURATION was made from a frame that is now deleted,
5980 only frame-independent values can be restored. In this case,
5981 the return value is nil. Otherwise the value is t. */)
5982 (Lisp_Object configuration
)
5984 register struct save_window_data
*data
;
5985 struct Lisp_Vector
*saved_windows
;
5986 Lisp_Object new_current_buffer
;
5989 ptrdiff_t old_point
= -1;
5991 CHECK_WINDOW_CONFIGURATION (configuration
);
5993 data
= (struct save_window_data
*) XVECTOR (configuration
);
5994 saved_windows
= XVECTOR (data
->saved_windows
);
5996 new_current_buffer
= data
->current_buffer
;
5997 if (!BUFFER_LIVE_P (XBUFFER (new_current_buffer
)))
5998 new_current_buffer
= Qnil
;
6001 if (XBUFFER (new_current_buffer
) == current_buffer
)
6002 /* The code further down "preserves point" by saving here PT in
6003 old_point and then setting it later back into PT. When the
6004 current-selected-window and the final-selected-window both show
6005 the current buffer, this suffers from the problem that the
6006 current PT is the window-point of the current-selected-window,
6007 while the final PT is the point of the final-selected-window, so
6008 this copy from one PT to the other would end up moving the
6009 window-point of the final-selected-window to the window-point of
6010 the current-selected-window. So we have to be careful which
6011 point of the current-buffer we copy into old_point. */
6012 if (EQ (XWINDOW (data
->current_window
)->contents
, new_current_buffer
)
6013 && WINDOWP (selected_window
)
6014 && EQ (XWINDOW (selected_window
)->contents
, new_current_buffer
)
6015 && !EQ (selected_window
, data
->current_window
))
6016 old_point
= marker_position (XWINDOW (data
->current_window
)->pointm
);
6020 /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of
6021 point in new_current_buffer as of the last time this buffer was
6022 used. This can be non-deterministic since it can be changed by
6023 things like jit-lock by mere temporary selection of some random
6024 window that happens to show this buffer.
6025 So if possible we want this arbitrary choice of "which point" to
6026 be the one from the to-be-selected-window so as to prevent this
6027 window's cursor from being copied from another window. */
6028 if (EQ (XWINDOW (data
->current_window
)->contents
, new_current_buffer
)
6029 /* If current_window = selected_window, its point is in BUF_PT. */
6030 && !EQ (selected_window
, data
->current_window
))
6031 old_point
= marker_position (XWINDOW (data
->current_window
)->pointm
);
6033 old_point
= BUF_PT (XBUFFER (new_current_buffer
));
6036 frame
= XWINDOW (SAVED_WINDOW_N (saved_windows
, 0)->window
)->frame
;
6039 /* If f is a dead frame, don't bother rebuilding its window tree.
6040 However, there is other stuff we should still try to do below. */
6041 if (FRAME_LIVE_P (f
))
6044 Lisp_Object dead_windows
= Qnil
;
6045 register Lisp_Object tem
, par
, pers
;
6046 register struct window
*w
;
6047 register struct saved_window
*p
;
6048 struct window
*root_window
;
6049 struct window
**leaf_windows
;
6053 ptrdiff_t count
= SPECPDL_INDEX ();
6054 /* If the frame has been resized since this window configuration was
6055 made, we change the frame to the size specified in the
6056 configuration, restore the configuration, and then resize it
6057 back. We keep track of the prevailing height in these variables. */
6058 int previous_frame_text_height
= FRAME_TEXT_HEIGHT (f
);
6059 int previous_frame_text_width
= FRAME_TEXT_WIDTH (f
);
6060 /* int previous_frame_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f); */
6061 /* int previous_frame_tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f); */
6062 /* int previous_frame_lines = FRAME_LINES (f); */
6063 /* int previous_frame_cols = FRAME_COLS (f); */
6064 int previous_frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
6065 int previous_frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
6067 /* Don't do this within the main loop below: This may call Lisp
6068 code and is thus potentially unsafe while input is blocked. */
6069 for (k
= 0; k
< saved_windows
->header
.size
; k
++)
6071 p
= SAVED_WINDOW_N (saved_windows
, k
);
6073 w
= XWINDOW (window
);
6074 if (BUFFERP (w
->contents
)
6075 && !EQ (w
->contents
, p
->buffer
)
6076 && BUFFER_LIVE_P (XBUFFER (p
->buffer
)))
6077 /* If a window we restore gets another buffer, record the
6078 window's old buffer. */
6079 call1 (Qrecord_window_buffer
, window
);
6082 /* Don't run lisp in the following segment since the frame is in a
6083 completely inconsistent state. See Bug#16207. */
6084 record_unwind_protect (unwind_change_frame
, inhibit_lisp_code
);
6085 inhibit_lisp_code
= Qt
;
6086 /* The mouse highlighting code could get screwed up
6087 if it runs during this. */
6090 if (data
->frame_text_width
!= previous_frame_text_width
6091 || data
->frame_text_height
!= previous_frame_text_height
)
6092 change_frame_size (f
, data
->frame_text_width
,
6093 data
->frame_text_height
, 0, 0, 0, 1);
6095 if (data
->frame_menu_bar_lines
!= previous_frame_menu_bar_lines
)
6097 #ifdef HAVE_WINDOW_SYSTEM
6098 if (FRAME_WINDOW_P (f
))
6099 x_set_menu_bar_lines (f
, make_number (data
->frame_menu_bar_lines
),
6101 else /* TTY or MSDOS */
6103 set_menu_bar_lines (f
, make_number (data
->frame_menu_bar_lines
),
6106 #ifdef HAVE_WINDOW_SYSTEM
6107 if (data
->frame_tool_bar_lines
!= previous_frame_tool_bar_lines
)
6108 x_set_tool_bar_lines (f
, make_number (data
->frame_tool_bar_lines
),
6112 /* "Swap out" point from the selected window's buffer
6113 into the window itself. (Normally the pointm of the selected
6114 window holds garbage.) We do this now, before
6115 restoring the window contents, and prevent it from
6116 being done later on when we select a new window. */
6117 if (! NILP (XWINDOW (selected_window
)->contents
))
6119 w
= XWINDOW (selected_window
);
6120 set_marker_both (w
->pointm
,
6122 BUF_PT (XBUFFER (w
->contents
)),
6123 BUF_PT_BYTE (XBUFFER (w
->contents
)));
6127 FRAME_WINDOW_SIZES_CHANGED (f
) = 1;
6129 /* Problem: Freeing all matrices and later allocating them again
6130 is a serious redisplay flickering problem. What we would
6131 really like to do is to free only those matrices not reused
6133 root_window
= XWINDOW (FRAME_ROOT_WINDOW (f
));
6134 leaf_windows
= alloca (count_windows (root_window
)
6135 * sizeof *leaf_windows
);
6136 n_leaf_windows
= get_leaf_windows (root_window
, leaf_windows
, 0);
6139 Mark all windows now on frame as "deleted".
6140 Restoring the new configuration "undeletes" any that are in it.
6142 Save their current buffers in their height fields, since we may
6143 need it later, if a buffer saved in the configuration is now
6145 delete_all_child_windows (FRAME_ROOT_WINDOW (f
));
6147 for (k
= 0; k
< saved_windows
->header
.size
; k
++)
6149 p
= SAVED_WINDOW_N (saved_windows
, k
);
6151 w
= XWINDOW (window
);
6152 wset_next (w
, Qnil
);
6154 if (!NILP (p
->parent
))
6156 (w
, SAVED_WINDOW_N (saved_windows
, XFASTINT (p
->parent
))->window
);
6158 wset_parent (w
, Qnil
);
6160 if (!NILP (p
->prev
))
6163 (w
, SAVED_WINDOW_N (saved_windows
, XFASTINT (p
->prev
))->window
);
6164 wset_next (XWINDOW (w
->prev
), p
->window
);
6168 wset_prev (w
, Qnil
);
6169 if (!NILP (w
->parent
))
6170 wset_combination (XWINDOW (w
->parent
),
6171 (XINT (p
->total_cols
)
6172 != XWINDOW (w
->parent
)->total_cols
),
6176 /* If we squirreled away the buffer, restore it now. */
6177 if (BUFFERP (w
->combination_limit
))
6178 wset_buffer (w
, w
->combination_limit
);
6179 w
->pixel_left
= XFASTINT (p
->pixel_left
);
6180 w
->pixel_top
= XFASTINT (p
->pixel_top
);
6181 w
->pixel_width
= XFASTINT (p
->pixel_width
);
6182 w
->pixel_height
= XFASTINT (p
->pixel_height
);
6183 w
->left_col
= XFASTINT (p
->left_col
);
6184 w
->top_line
= XFASTINT (p
->top_line
);
6185 w
->total_cols
= XFASTINT (p
->total_cols
);
6186 w
->total_lines
= XFASTINT (p
->total_lines
);
6187 wset_normal_cols (w
, p
->normal_cols
);
6188 wset_normal_lines (w
, p
->normal_lines
);
6189 w
->hscroll
= XFASTINT (p
->hscroll
);
6190 w
->min_hscroll
= XFASTINT (p
->min_hscroll
);
6191 wset_display_table (w
, p
->display_table
);
6192 w
->left_margin_cols
= XINT (p
->left_margin_cols
);
6193 w
->right_margin_cols
= XINT (p
->right_margin_cols
);
6194 w
->left_fringe_width
= XINT (p
->left_fringe_width
);
6195 w
->right_fringe_width
= XINT (p
->right_fringe_width
);
6196 w
->fringes_outside_margins
= !NILP (p
->fringes_outside_margins
);
6197 w
->scroll_bar_width
= XINT (p
->scroll_bar_width
);
6198 wset_vertical_scroll_bar_type (w
, p
->vertical_scroll_bar_type
);
6199 wset_dedicated (w
, p
->dedicated
);
6200 wset_combination_limit (w
, p
->combination_limit
);
6201 /* Restore any window parameters that have been saved.
6202 Parameters that have not been saved are left alone. */
6203 for (tem
= p
->window_parameters
; CONSP (tem
); tem
= XCDR (tem
))
6208 if (NILP (XCDR (pers
)))
6210 par
= Fassq (XCAR (pers
), w
->window_parameters
);
6211 if (CONSP (par
) && !NILP (XCDR (par
)))
6212 /* Reset a parameter to nil if and only if it
6213 has a non-nil association. Don't make new
6215 Fsetcdr (par
, Qnil
);
6218 /* Always restore a non-nil value. */
6219 Fset_window_parameter (window
, XCAR (pers
), XCDR (pers
));
6223 if (BUFFERP (p
->buffer
) && BUFFER_LIVE_P (XBUFFER (p
->buffer
)))
6224 /* If saved buffer is alive, install it. */
6226 wset_buffer (w
, p
->buffer
);
6227 w
->start_at_line_beg
= !NILP (p
->start_at_line_beg
);
6228 set_marker_restricted (w
->start
, p
->start
, w
->contents
);
6229 set_marker_restricted (w
->pointm
, p
->pointm
,
6231 Fset_marker (BVAR (XBUFFER (w
->contents
), mark
),
6232 p
->mark
, w
->contents
);
6234 /* As documented in Fcurrent_window_configuration, don't
6235 restore the location of point in the buffer which was
6236 current when the window configuration was recorded. */
6237 if (!EQ (p
->buffer
, new_current_buffer
)
6238 && XBUFFER (p
->buffer
) == current_buffer
)
6239 Fgoto_char (w
->pointm
);
6241 else if (BUFFERP (w
->contents
) && BUFFER_LIVE_P (XBUFFER (w
->contents
)))
6242 /* Keep window's old buffer; make sure the markers are real. */
6244 /* Set window markers at start of visible range. */
6245 if (XMARKER (w
->start
)->buffer
== 0)
6246 set_marker_restricted_both (w
->start
, w
->contents
, 0, 0);
6247 if (XMARKER (w
->pointm
)->buffer
== 0)
6248 set_marker_restricted_both
6249 (w
->pointm
, w
->contents
,
6250 BUF_PT (XBUFFER (w
->contents
)),
6251 BUF_PT_BYTE (XBUFFER (w
->contents
)));
6252 w
->start_at_line_beg
= 1;
6254 else if (!NILP (w
->start
))
6255 /* Leaf window has no live buffer, get one. */
6257 /* Get the buffer via other_buffer_safely in order to
6258 avoid showing an unimportant buffer and, if necessary, to
6259 recreate *scratch* in the course (part of Juanma's bs-show
6260 scenario from March 2011). */
6261 wset_buffer (w
, other_buffer_safely (Fcurrent_buffer ()));
6262 /* This will set the markers to beginning of visible
6264 set_marker_restricted_both (w
->start
, w
->contents
, 0, 0);
6265 set_marker_restricted_both (w
->pointm
, w
->contents
, 0, 0);
6266 w
->start_at_line_beg
= 1;
6267 if (!NILP (w
->dedicated
))
6268 /* Record this window as dead. */
6269 dead_windows
= Fcons (window
, dead_windows
);
6270 /* Make sure window is no more dedicated. */
6271 wset_dedicated (w
, Qnil
);
6275 fset_root_window (f
, data
->root_window
);
6276 /* Arrange *not* to restore point in the buffer that was
6277 current when the window configuration was saved. */
6278 if (EQ (XWINDOW (data
->current_window
)->contents
, new_current_buffer
))
6279 set_marker_restricted (XWINDOW (data
->current_window
)->pointm
,
6280 make_number (old_point
),
6281 XWINDOW (data
->current_window
)->contents
);
6283 /* In the following call to `select-window', prevent "swapping out
6284 point" in the old selected window using the buffer that has
6285 been restored into it. We already swapped out that point from
6286 that window's old buffer.
6288 Do not record the buffer here. We do that in a separate call
6289 to select_window below. See also Bug#16207. */
6290 select_window (data
->current_window
, Qt
, 1);
6291 BVAR (XBUFFER (XWINDOW (selected_window
)->contents
),
6292 last_selected_window
)
6295 if (NILP (data
->focus_frame
)
6296 || (FRAMEP (data
->focus_frame
)
6297 && FRAME_LIVE_P (XFRAME (data
->focus_frame
))))
6298 Fredirect_frame_focus (frame
, data
->focus_frame
);
6300 /* Set the frame size to the value it had before this function. */
6301 if (previous_frame_text_width
!= FRAME_TEXT_WIDTH (f
)
6302 || previous_frame_text_height
!= FRAME_TEXT_HEIGHT (f
))
6303 change_frame_size (f
, previous_frame_text_width
,
6304 previous_frame_text_height
, 0, 0, 0, 1);
6306 if (previous_frame_menu_bar_lines
!= FRAME_MENU_BAR_LINES (f
))
6308 #ifdef HAVE_WINDOW_SYSTEM
6309 if (FRAME_WINDOW_P (f
))
6310 x_set_menu_bar_lines (f
,
6311 make_number (previous_frame_menu_bar_lines
),
6313 else /* TTY or MSDOS */
6315 set_menu_bar_lines (f
, make_number (previous_frame_menu_bar_lines
),
6318 #ifdef HAVE_WINDOW_SYSTEM
6319 if (previous_frame_tool_bar_lines
!= FRAME_TOOL_BAR_LINES (f
))
6320 x_set_tool_bar_lines (f
, make_number (previous_frame_tool_bar_lines
),
6324 /* Now, free glyph matrices in windows that were not reused. */
6325 for (i
= n
= 0; i
< n_leaf_windows
; ++i
)
6327 if (NILP (leaf_windows
[i
]->contents
))
6328 free_window_matrices (leaf_windows
[i
]);
6329 else if (EQ (leaf_windows
[i
]->contents
, new_current_buffer
))
6333 adjust_frame_glyphs (f
);
6335 unbind_to (count
, Qnil
);
6337 /* Scan dead buffer windows. */
6338 for (; CONSP (dead_windows
); dead_windows
= XCDR (dead_windows
))
6340 window
= XCAR (dead_windows
);
6341 if (WINDOW_LIVE_P (window
) && !EQ (window
, FRAME_ROOT_WINDOW (f
)))
6342 delete_deletable_window (window
);
6345 /* Record the selected window's buffer here. The window should
6346 already be the selected one from the call above. */
6347 select_window (data
->current_window
, Qnil
, 0);
6349 /* Fselect_window will have made f the selected frame, so we
6350 reselect the proper frame here. Fhandle_switch_frame will change the
6351 selected window too, but that doesn't make the call to
6352 Fselect_window above totally superfluous; it still sets f's
6354 if (FRAME_LIVE_P (XFRAME (data
->selected_frame
)))
6355 do_switch_frame (data
->selected_frame
, 0, 0, Qnil
);
6357 run_window_configuration_change_hook (f
);
6360 if (!NILP (new_current_buffer
))
6362 Fset_buffer (new_current_buffer
);
6363 /* If the new current buffer doesn't appear in the selected
6364 window, go to its old point (see bug#12208). */
6365 if (!EQ (XWINDOW (data
->current_window
)->contents
, new_current_buffer
))
6366 Fgoto_char (make_number (old_point
));
6369 Vminibuf_scroll_window
= data
->minibuf_scroll_window
;
6370 minibuf_selected_window
= data
->minibuf_selected_window
;
6372 return (FRAME_LIVE_P (f
) ? Qt
: Qnil
);
6376 restore_window_configuration (Lisp_Object configuration
)
6378 Fset_window_configuration (configuration
);
6382 /* If WINDOW is an internal window, recursively delete all child windows
6383 reachable via the next and contents slots of WINDOW. Otherwise setup
6384 WINDOW to not show any buffer. */
6387 delete_all_child_windows (Lisp_Object window
)
6389 register struct window
*w
;
6391 w
= XWINDOW (window
);
6393 if (!NILP (w
->next
))
6394 /* Delete WINDOW's siblings (we traverse postorderly). */
6395 delete_all_child_windows (w
->next
);
6397 if (WINDOWP (w
->contents
))
6399 delete_all_child_windows (w
->contents
);
6400 wset_combination (w
, 0, Qnil
);
6402 else if (BUFFERP (w
->contents
))
6405 unchain_marker (XMARKER (w
->pointm
));
6406 unchain_marker (XMARKER (w
->start
));
6407 /* Since combination limit makes sense for an internal windows
6408 only, we use this slot to save the buffer for the sake of
6409 possible resurrection in Fset_window_configuration. */
6410 wset_combination_limit (w
, w
->contents
);
6411 wset_buffer (w
, Qnil
);
6414 Vwindow_list
= Qnil
;
6418 count_windows (register struct window
*window
)
6420 register int count
= 1;
6421 if (!NILP (window
->next
))
6422 count
+= count_windows (XWINDOW (window
->next
));
6423 if (WINDOWP (window
->contents
))
6424 count
+= count_windows (XWINDOW (window
->contents
));
6429 /* Fill vector FLAT with leaf windows under W, starting at index I.
6430 Value is last index + 1. */
6432 get_leaf_windows (struct window
*w
, struct window
**flat
, int i
)
6436 if (WINDOWP (w
->contents
))
6437 i
= get_leaf_windows (XWINDOW (w
->contents
), flat
, i
);
6441 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
6448 /* Return a pointer to the glyph W's physical cursor is on. Value is
6449 null if W's current matrix is invalid, so that no meaningful glyph
6452 get_phys_cursor_glyph (struct window
*w
)
6454 struct glyph_row
*row
;
6455 struct glyph
*glyph
;
6456 int hpos
= w
->phys_cursor
.hpos
;
6458 if (!(w
->phys_cursor
.vpos
>= 0
6459 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
))
6462 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
6463 if (!row
->enabled_p
)
6468 /* When the window is hscrolled, cursor hpos can legitimately be
6469 out of bounds, but we draw the cursor at the corresponding
6470 window margin in that case. */
6471 if (!row
->reversed_p
&& hpos
< 0)
6473 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
6474 hpos
= row
->used
[TEXT_AREA
] - 1;
6477 if (0 <= hpos
&& hpos
< row
->used
[TEXT_AREA
])
6478 glyph
= row
->glyphs
[TEXT_AREA
] + hpos
;
6487 save_window_save (Lisp_Object window
, struct Lisp_Vector
*vector
, int i
)
6489 register struct saved_window
*p
;
6490 register struct window
*w
;
6491 register Lisp_Object tem
, pers
, par
;
6493 for (; !NILP (window
); window
= w
->next
)
6495 p
= SAVED_WINDOW_N (vector
, i
);
6496 w
= XWINDOW (window
);
6498 wset_temslot (w
, make_number (i
)); i
++;
6500 p
->buffer
= (WINDOW_LEAF_P (w
) ? w
->contents
: Qnil
);
6501 p
->pixel_left
= make_number (w
->pixel_left
);
6502 p
->pixel_top
= make_number (w
->pixel_top
);
6503 p
->pixel_width
= make_number (w
->pixel_width
);
6504 p
->pixel_height
= make_number (w
->pixel_height
);
6505 p
->left_col
= make_number (w
->left_col
);
6506 p
->top_line
= make_number (w
->top_line
);
6507 p
->total_cols
= make_number (w
->total_cols
);
6508 p
->total_lines
= make_number (w
->total_lines
);
6509 p
->normal_cols
= w
->normal_cols
;
6510 p
->normal_lines
= w
->normal_lines
;
6511 XSETFASTINT (p
->hscroll
, w
->hscroll
);
6512 XSETFASTINT (p
->min_hscroll
, w
->min_hscroll
);
6513 p
->display_table
= w
->display_table
;
6514 p
->left_margin_cols
= make_number (w
->left_margin_cols
);
6515 p
->right_margin_cols
= make_number (w
->right_margin_cols
);
6516 p
->left_fringe_width
= make_number (w
->left_fringe_width
);
6517 p
->right_fringe_width
= make_number (w
->right_fringe_width
);
6518 p
->fringes_outside_margins
= w
->fringes_outside_margins
? Qt
: Qnil
;
6519 p
->scroll_bar_width
= make_number (w
->scroll_bar_width
);
6520 p
->vertical_scroll_bar_type
= w
->vertical_scroll_bar_type
;
6521 p
->dedicated
= w
->dedicated
;
6522 p
->combination_limit
= w
->combination_limit
;
6523 p
->window_parameters
= Qnil
;
6525 if (!NILP (Vwindow_persistent_parameters
))
6527 /* Run cycle detection on Vwindow_persistent_parameters. */
6528 Lisp_Object tortoise
, hare
;
6530 hare
= tortoise
= Vwindow_persistent_parameters
;
6531 while (CONSP (hare
))
6538 tortoise
= XCDR (tortoise
);
6540 if (EQ (hare
, tortoise
))
6541 /* Reset Vwindow_persistent_parameters to Qnil. */
6543 Vwindow_persistent_parameters
= Qnil
;
6548 for (tem
= Vwindow_persistent_parameters
; CONSP (tem
);
6552 /* Save values for persistent window parameters. */
6553 if (CONSP (pers
) && !NILP (XCDR (pers
)))
6555 par
= Fassq (XCAR (pers
), w
->window_parameters
);
6557 /* If the window has no value for the parameter,
6559 p
->window_parameters
= Fcons (Fcons (XCAR (pers
), Qnil
),
6560 p
->window_parameters
);
6562 /* If the window has a value for the parameter,
6564 p
->window_parameters
= Fcons (Fcons (XCAR (par
),
6566 p
->window_parameters
);
6571 if (BUFFERP (w
->contents
))
6573 /* Save w's value of point in the window configuration. If w
6574 is the selected window, then get the value of point from
6575 the buffer; pointm is garbage in the selected window. */
6576 if (EQ (window
, selected_window
))
6577 p
->pointm
= build_marker (XBUFFER (w
->contents
),
6578 BUF_PT (XBUFFER (w
->contents
)),
6579 BUF_PT_BYTE (XBUFFER (w
->contents
)));
6581 p
->pointm
= Fcopy_marker (w
->pointm
, Qnil
);
6582 XMARKER (p
->pointm
)->insertion_type
6583 = !NILP (Vwindow_point_insertion_type
);
6585 p
->start
= Fcopy_marker (w
->start
, Qnil
);
6586 p
->start_at_line_beg
= w
->start_at_line_beg
? Qt
: Qnil
;
6588 tem
= BVAR (XBUFFER (w
->contents
), mark
);
6589 p
->mark
= Fcopy_marker (tem
, Qnil
);
6596 p
->start_at_line_beg
= Qnil
;
6599 if (NILP (w
->parent
))
6602 p
->parent
= XWINDOW (w
->parent
)->temslot
;
6607 p
->prev
= XWINDOW (w
->prev
)->temslot
;
6609 if (WINDOWP (w
->contents
))
6610 i
= save_window_save (w
->contents
, vector
, i
);
6616 DEFUN ("current-window-configuration", Fcurrent_window_configuration
,
6617 Scurrent_window_configuration
, 0, 1, 0,
6618 doc
: /* Return an object representing the current window configuration of FRAME.
6619 If FRAME is nil or omitted, use the selected frame.
6620 This describes the number of windows, their sizes and current buffers,
6621 and for each displayed buffer, where display starts, and the positions of
6622 point and mark. An exception is made for point in the current buffer:
6623 its value is -not- saved.
6624 This also records the currently selected frame, and FRAME's focus
6625 redirection (see `redirect-frame-focus'). The variable
6626 `window-persistent-parameters' specifies which window parameters are
6627 saved by this function. */)
6630 register Lisp_Object tem
;
6631 register int n_windows
;
6632 register struct save_window_data
*data
;
6634 struct frame
*f
= decode_live_frame (frame
);
6636 n_windows
= count_windows (XWINDOW (FRAME_ROOT_WINDOW (f
)));
6637 data
= ALLOCATE_PSEUDOVECTOR (struct save_window_data
, frame_cols
,
6638 PVEC_WINDOW_CONFIGURATION
);
6640 data
->frame_cols
= FRAME_COLS (f
);
6641 data
->frame_lines
= FRAME_LINES (f
);
6642 data
->frame_menu_bar_lines
= FRAME_MENU_BAR_LINES (f
);
6643 data
->frame_tool_bar_lines
= FRAME_TOOL_BAR_LINES (f
);
6644 data
->frame_text_width
= FRAME_TEXT_WIDTH (f
);
6645 data
->frame_text_height
= FRAME_TEXT_HEIGHT (f
);
6646 data
->frame_menu_bar_height
= FRAME_MENU_BAR_HEIGHT (f
);
6647 data
->frame_tool_bar_height
= FRAME_TOOL_BAR_HEIGHT (f
);
6648 data
->selected_frame
= selected_frame
;
6649 data
->current_window
= FRAME_SELECTED_WINDOW (f
);
6650 XSETBUFFER (data
->current_buffer
, current_buffer
);
6651 data
->minibuf_scroll_window
= minibuf_level
> 0 ? Vminibuf_scroll_window
: Qnil
;
6652 data
->minibuf_selected_window
= minibuf_level
> 0 ? minibuf_selected_window
: Qnil
;
6653 data
->root_window
= FRAME_ROOT_WINDOW (f
);
6654 data
->focus_frame
= FRAME_FOCUS_FRAME (f
);
6655 tem
= make_uninit_vector (n_windows
);
6656 data
->saved_windows
= tem
;
6657 for (i
= 0; i
< n_windows
; i
++)
6659 Fmake_vector (make_number (VECSIZE (struct saved_window
)), Qnil
));
6660 save_window_save (FRAME_ROOT_WINDOW (f
), XVECTOR (tem
), 0);
6661 XSETWINDOW_CONFIGURATION (tem
, data
);
6665 /* Called after W's margins, fringes or scroll bars was adjusted. */
6668 apply_window_adjustment (struct window
*w
)
6671 adjust_window_margins (w
);
6672 clear_glyph_matrix (w
->current_matrix
);
6673 w
->window_end_valid
= 0;
6674 windows_or_buffers_changed
= 30;
6676 adjust_frame_glyphs (XFRAME (WINDOW_FRAME (w
)));
6680 /***********************************************************************
6682 ***********************************************************************/
6684 static struct window
*
6685 set_window_margins (struct window
*w
, Lisp_Object left_width
,
6686 Lisp_Object right_width
)
6690 /* FIXME: what about margins that are too wide? */
6691 left
= (NILP (left_width
) ? 0
6692 : (CHECK_NATNUM (left_width
), XINT (left_width
)));
6693 right
= (NILP (right_width
) ? 0
6694 : (CHECK_NATNUM (right_width
), XINT (right_width
)));
6696 if (w
->left_margin_cols
!= left
|| w
->right_margin_cols
!= right
)
6698 w
->left_margin_cols
= left
;
6699 w
->right_margin_cols
= right
;
6705 DEFUN ("set-window-margins", Fset_window_margins
, Sset_window_margins
,
6707 doc
: /* Set width of marginal areas of window WINDOW.
6708 WINDOW must be a live window and defaults to the selected one.
6710 Second arg LEFT-WIDTH specifies the number of character cells to
6711 reserve for the left marginal area. Optional third arg RIGHT-WIDTH
6712 does the same for the right marginal area. A nil width parameter
6715 Return t if any margin was actually changed and nil otherwise. */)
6716 (Lisp_Object window
, Lisp_Object left_width
, Lisp_Object right_width
)
6718 struct window
*w
= set_window_margins (decode_live_window (window
),
6719 left_width
, right_width
);
6720 return w
? (apply_window_adjustment (w
), Qt
) : Qnil
;
6724 DEFUN ("window-margins", Fwindow_margins
, Swindow_margins
,
6726 doc
: /* Get width of marginal areas of window WINDOW.
6727 WINDOW must be a live window and defaults to the selected one.
6729 Value is a cons of the form (LEFT-WIDTH . RIGHT-WIDTH).
6730 If a marginal area does not exist, its width will be returned
6732 (Lisp_Object window
)
6734 struct window
*w
= decode_live_window (window
);
6735 return Fcons (w
->left_margin_cols
6736 ? make_number (w
->left_margin_cols
) : Qnil
,
6737 w
->right_margin_cols
6738 ? make_number (w
->right_margin_cols
) : Qnil
);
6743 /***********************************************************************
6745 ***********************************************************************/
6747 static struct window
*
6748 set_window_fringes (struct window
*w
, Lisp_Object left_width
,
6749 Lisp_Object right_width
, Lisp_Object outside_margins
)
6751 int left
, right
, outside
= !NILP (outside_margins
);
6753 left
= (NILP (left_width
) ? -1
6754 : (CHECK_NATNUM (left_width
), XINT (left_width
)));
6755 right
= (NILP (right_width
) ? -1
6756 : (CHECK_NATNUM (right_width
), XINT (right_width
)));
6758 /* Do nothing on a tty or if nothing to actually change. */
6759 if (FRAME_WINDOW_P (WINDOW_XFRAME (w
))
6760 && (w
->left_fringe_width
!= left
6761 || w
->right_fringe_width
!= right
6762 || w
->fringes_outside_margins
!= outside
))
6764 w
->left_fringe_width
= left
;
6765 w
->right_fringe_width
= right
;
6766 w
->fringes_outside_margins
= outside
;
6772 DEFUN ("set-window-fringes", Fset_window_fringes
, Sset_window_fringes
,
6774 doc
: /* Set the fringe widths of window WINDOW.
6775 WINDOW must be a live window and defaults to the selected one.
6777 Second arg LEFT-WIDTH specifies the number of pixels to reserve for
6778 the left fringe. Optional third arg RIGHT-WIDTH specifies the right
6779 fringe width. If a fringe width arg is nil, that means to use the
6780 frame's default fringe width. Default fringe widths can be set with
6781 the command `set-fringe-style'.
6782 If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes
6783 outside of the display margins. By default, fringes are drawn between
6784 display marginal areas and the text area.
6786 Return t if any fringe was actually changed and nil otherwise. */)
6787 (Lisp_Object window
, Lisp_Object left_width
,
6788 Lisp_Object right_width
, Lisp_Object outside_margins
)
6791 = set_window_fringes (decode_live_window (window
),
6792 left_width
, right_width
, outside_margins
);
6793 return w
? (apply_window_adjustment (w
), Qt
) : Qnil
;
6797 DEFUN ("window-fringes", Fwindow_fringes
, Swindow_fringes
,
6799 doc
: /* Get width of fringes of window WINDOW.
6800 WINDOW must be a live window and defaults to the selected one.
6802 Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
6803 (Lisp_Object window
)
6805 struct window
*w
= decode_live_window (window
);
6807 return list3 (make_number (WINDOW_LEFT_FRINGE_WIDTH (w
)),
6808 make_number (WINDOW_RIGHT_FRINGE_WIDTH (w
)),
6809 WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
) ? Qt
: Qnil
);
6814 /***********************************************************************
6816 ***********************************************************************/
6818 static struct window
*
6819 set_window_scroll_bars (struct window
*w
, Lisp_Object width
,
6820 Lisp_Object vertical_type
, Lisp_Object horizontal_type
)
6822 int iwidth
= (NILP (width
) ? -1 : (CHECK_NATNUM (width
), XINT (width
)));
6825 vertical_type
= Qnil
;
6827 if (!(NILP (vertical_type
)
6828 || EQ (vertical_type
, Qleft
)
6829 || EQ (vertical_type
, Qright
)
6830 || EQ (vertical_type
, Qt
)))
6831 error ("Invalid type of vertical scroll bar");
6833 if (w
->scroll_bar_width
!= iwidth
6834 || !EQ (w
->vertical_scroll_bar_type
, vertical_type
))
6836 w
->scroll_bar_width
= iwidth
;
6837 wset_vertical_scroll_bar_type (w
, vertical_type
);
6843 DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars
,
6844 Sset_window_scroll_bars
, 2, 4, 0,
6845 doc
: /* Set width and type of scroll bars of window WINDOW.
6846 WINDOW must be a live window and defaults to the selected one.
6848 Second parameter WIDTH specifies the pixel width for the scroll bar.
6849 Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
6850 bar: left, right, or nil.
6851 If WIDTH is nil, use the frame's scroll-bar width.
6852 If VERTICAL-TYPE is t, use the frame's scroll-bar type.
6853 Fourth parameter HORIZONTAL-TYPE is currently unused.
6855 Return t if scroll bars were actually changed and nil otherwise. */)
6856 (Lisp_Object window
, Lisp_Object width
,
6857 Lisp_Object vertical_type
, Lisp_Object horizontal_type
)
6860 = set_window_scroll_bars (decode_live_window (window
),
6861 width
, vertical_type
, horizontal_type
);
6862 return w
? (apply_window_adjustment (w
), Qt
) : Qnil
;
6866 DEFUN ("window-scroll-bars", Fwindow_scroll_bars
, Swindow_scroll_bars
,
6868 doc
: /* Get width and type of scroll bars of window WINDOW.
6869 WINDOW must be a live window and defaults to the selected one.
6871 Value is a list of the form (WIDTH COLS VERTICAL-TYPE HORIZONTAL-TYPE).
6872 If WIDTH is nil or TYPE is t, the window is using the frame's corresponding
6874 (Lisp_Object window
)
6876 struct window
*w
= decode_live_window (window
);
6878 return list4 (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (w
)),
6879 make_number (WINDOW_SCROLL_BAR_COLS (w
)),
6880 w
->vertical_scroll_bar_type
, Qnil
);
6885 /***********************************************************************
6887 ***********************************************************************/
6889 DEFUN ("window-vscroll", Fwindow_vscroll
, Swindow_vscroll
, 0, 2, 0,
6890 doc
: /* Return the amount by which WINDOW is scrolled vertically.
6891 If WINDOW is omitted or nil, it defaults to the selected window.
6892 Normally, value is a multiple of the canonical character height of WINDOW;
6893 optional second arg PIXELS-P means value is measured in pixels. */)
6894 (Lisp_Object window
, Lisp_Object pixels_p
)
6897 struct window
*w
= decode_live_window (window
);
6898 struct frame
*f
= XFRAME (w
->frame
);
6900 if (FRAME_WINDOW_P (f
))
6901 result
= (NILP (pixels_p
)
6902 ? FRAME_CANON_Y_FROM_PIXEL_Y (f
, -w
->vscroll
)
6903 : make_number (-w
->vscroll
));
6905 result
= make_number (0);
6910 DEFUN ("set-window-vscroll", Fset_window_vscroll
, Sset_window_vscroll
,
6912 doc
: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL.
6913 WINDOW nil means use the selected window. Normally, VSCROLL is a
6914 non-negative multiple of the canonical character height of WINDOW;
6915 optional third arg PIXELS-P non-nil means that VSCROLL is in pixels.
6916 If PIXELS-P is nil, VSCROLL may have to be rounded so that it
6917 corresponds to an integral number of pixels. The return value is the
6918 result of this rounding.
6919 If PIXELS-P is non-nil, the return value is VSCROLL. */)
6920 (Lisp_Object window
, Lisp_Object vscroll
, Lisp_Object pixels_p
)
6922 struct window
*w
= decode_live_window (window
);
6923 struct frame
*f
= XFRAME (w
->frame
);
6925 CHECK_NUMBER_OR_FLOAT (vscroll
);
6927 if (FRAME_WINDOW_P (f
))
6929 int old_dy
= w
->vscroll
;
6931 w
->vscroll
= - (NILP (pixels_p
)
6932 ? FRAME_LINE_HEIGHT (f
) * XFLOATINT (vscroll
)
6933 : XFLOATINT (vscroll
));
6934 w
->vscroll
= min (w
->vscroll
, 0);
6936 if (w
->vscroll
!= old_dy
)
6938 /* Adjust glyph matrix of the frame if the virtual display
6939 area becomes larger than before. */
6940 if (w
->vscroll
< 0 && w
->vscroll
< old_dy
)
6941 adjust_frame_glyphs (f
);
6943 /* Prevent redisplay shortcuts. */
6944 XBUFFER (w
->contents
)->prevent_redisplay_optimizations_p
= 1;
6948 return Fwindow_vscroll (window
, pixels_p
);
6952 /* Call FN for all leaf windows on frame F. FN is called with the
6953 first argument being a pointer to the leaf window, and with
6954 additional argument USER_DATA. Stops when FN returns 0. */
6957 foreach_window (struct frame
*f
, int (*fn
) (struct window
*, void *),
6960 /* delete_frame may set FRAME_ROOT_WINDOW (f) to Qnil. */
6961 if (WINDOWP (FRAME_ROOT_WINDOW (f
)))
6962 foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f
)), fn
, user_data
);
6966 /* Helper function for foreach_window. Call FN for all leaf windows
6967 reachable from W. FN is called with the first argument being a
6968 pointer to the leaf window, and with additional argument USER_DATA.
6969 Stop when FN returns 0. Value is 0 if stopped by FN. */
6972 foreach_window_1 (struct window
*w
, int (*fn
) (struct window
*, void *), void *user_data
)
6976 for (cont
= 1; w
&& cont
;)
6978 if (WINDOWP (w
->contents
))
6979 cont
= foreach_window_1 (XWINDOW (w
->contents
), fn
, user_data
);
6981 cont
= fn (w
, user_data
);
6983 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
6989 /***********************************************************************
6991 ***********************************************************************/
6993 /* Return 1 if window configurations CONFIGURATION1 and CONFIGURATION2
6994 describe the same state of affairs. This is used by Fequal.
6996 IGNORE_POSITIONS means ignore non-matching scroll positions
6999 This ignores a couple of things like the dedication status of
7000 window, combination_limit and the like. This might have to be
7004 compare_window_configurations (Lisp_Object configuration1
,
7005 Lisp_Object configuration2
,
7006 bool ignore_positions
)
7008 register struct save_window_data
*d1
, *d2
;
7009 struct Lisp_Vector
*sws1
, *sws2
;
7012 CHECK_WINDOW_CONFIGURATION (configuration1
);
7013 CHECK_WINDOW_CONFIGURATION (configuration2
);
7015 d1
= (struct save_window_data
*) XVECTOR (configuration1
);
7016 d2
= (struct save_window_data
*) XVECTOR (configuration2
);
7017 sws1
= XVECTOR (d1
->saved_windows
);
7018 sws2
= XVECTOR (d2
->saved_windows
);
7020 /* Frame settings must match. */
7021 if (d1
->frame_cols
!= d2
->frame_cols
7022 || d1
->frame_lines
!= d2
->frame_lines
7023 || d1
->frame_menu_bar_lines
!= d2
->frame_menu_bar_lines
7024 || !EQ (d1
->selected_frame
, d2
->selected_frame
)
7025 || !EQ (d1
->current_buffer
, d2
->current_buffer
)
7026 || (!ignore_positions
7027 && (!EQ (d1
->minibuf_scroll_window
, d2
->minibuf_scroll_window
)
7028 || !EQ (d1
->minibuf_selected_window
, d2
->minibuf_selected_window
)))
7029 || !EQ (d1
->focus_frame
, d2
->focus_frame
)
7030 /* Verify that the two configurations have the same number of windows. */
7031 || sws1
->header
.size
!= sws2
->header
.size
)
7034 for (i
= 0; i
< sws1
->header
.size
; i
++)
7036 struct saved_window
*sw1
, *sw2
;
7038 sw1
= SAVED_WINDOW_N (sws1
, i
);
7039 sw2
= SAVED_WINDOW_N (sws2
, i
);
7042 /* The "current" windows in the two configurations must
7043 correspond to each other. */
7044 EQ (d1
->current_window
, sw1
->window
)
7045 != EQ (d2
->current_window
, sw2
->window
)
7046 /* Windows' buffers must match. */
7047 || !EQ (sw1
->buffer
, sw2
->buffer
)
7048 || !EQ (sw1
->pixel_left
, sw2
->pixel_left
)
7049 || !EQ (sw1
->pixel_top
, sw2
->pixel_top
)
7050 || !EQ (sw1
->pixel_height
, sw2
->pixel_height
)
7051 || !EQ (sw1
->pixel_width
, sw2
->pixel_width
)
7052 || !EQ (sw1
->left_col
, sw2
->left_col
)
7053 || !EQ (sw1
->top_line
, sw2
->top_line
)
7054 || !EQ (sw1
->total_cols
, sw2
->total_cols
)
7055 || !EQ (sw1
->total_lines
, sw2
->total_lines
)
7056 || !EQ (sw1
->display_table
, sw2
->display_table
)
7057 /* The next two disjuncts check the window structure for
7059 || !EQ (sw1
->parent
, sw2
->parent
)
7060 || !EQ (sw1
->prev
, sw2
->prev
)
7061 || (!ignore_positions
7062 && (!EQ (sw1
->hscroll
, sw2
->hscroll
)
7063 || !EQ (sw1
->min_hscroll
, sw2
->min_hscroll
)
7064 || !EQ (sw1
->start_at_line_beg
, sw2
->start_at_line_beg
)
7065 || NILP (Fequal (sw1
->start
, sw2
->start
))
7066 || NILP (Fequal (sw1
->pointm
, sw2
->pointm
))
7067 || NILP (Fequal (sw1
->mark
, sw2
->mark
))))
7068 || !EQ (sw1
->left_margin_cols
, sw2
->left_margin_cols
)
7069 || !EQ (sw1
->right_margin_cols
, sw2
->right_margin_cols
)
7070 || !EQ (sw1
->left_fringe_width
, sw2
->left_fringe_width
)
7071 || !EQ (sw1
->right_fringe_width
, sw2
->right_fringe_width
)
7072 || !EQ (sw1
->fringes_outside_margins
, sw2
->fringes_outside_margins
)
7073 || !EQ (sw1
->scroll_bar_width
, sw2
->scroll_bar_width
)
7074 || !EQ (sw1
->vertical_scroll_bar_type
, sw2
->vertical_scroll_bar_type
))
7081 DEFUN ("compare-window-configurations", Fcompare_window_configurations
,
7082 Scompare_window_configurations
, 2, 2, 0,
7083 doc
: /* Compare two window configurations as regards the structure of windows.
7084 This function ignores details such as the values of point and mark
7085 and scrolling positions. */)
7086 (Lisp_Object x
, Lisp_Object y
)
7088 if (compare_window_configurations (x
, y
, 1))
7094 init_window_once (void)
7096 struct frame
*f
= make_initial_frame ();
7097 XSETFRAME (selected_frame
, f
);
7098 Vterminal_frame
= selected_frame
;
7099 minibuf_window
= f
->minibuffer_window
;
7100 selected_window
= f
->selected_window
;
7102 window_initialized
= 1;
7108 Vwindow_list
= Qnil
;
7112 syms_of_window (void)
7114 DEFSYM (Qscroll_up
, "scroll-up");
7115 DEFSYM (Qscroll_down
, "scroll-down");
7116 DEFSYM (Qscroll_command
, "scroll-command");
7118 Fput (Qscroll_up
, Qscroll_command
, Qt
);
7119 Fput (Qscroll_down
, Qscroll_command
, Qt
);
7121 DEFSYM (Qwindow_configuration_change_hook
, "window-configuration-change-hook");
7122 DEFSYM (Qwindowp
, "windowp");
7123 DEFSYM (Qwindow_configuration_p
, "window-configuration-p");
7124 DEFSYM (Qwindow_live_p
, "window-live-p");
7125 DEFSYM (Qwindow_valid_p
, "window-valid-p");
7126 DEFSYM (Qwindow_deletable_p
, "window-deletable-p");
7127 DEFSYM (Qdelete_window
, "delete-window");
7128 DEFSYM (Qwindow_resize_root_window
, "window--resize-root-window");
7129 DEFSYM (Qwindow_resize_root_window_vertically
, "window--resize-root-window-vertically");
7130 DEFSYM (Qwindow_pixel_to_total
, "window--pixel-to-total");
7131 DEFSYM (Qsafe
, "safe");
7132 DEFSYM (Qdisplay_buffer
, "display-buffer");
7133 DEFSYM (Qreplace_buffer_in_windows
, "replace-buffer-in-windows");
7134 DEFSYM (Qrecord_window_buffer
, "record-window-buffer");
7135 DEFSYM (Qget_mru_window
, "get-mru-window");
7136 DEFSYM (Qwindow_size
, "window-size");
7137 DEFSYM (Qtemp_buffer_show_hook
, "temp-buffer-show-hook");
7138 DEFSYM (Qabove
, "above");
7139 DEFSYM (Qbelow
, "below");
7140 DEFSYM (Qclone_of
, "clone-of");
7141 DEFSYM (Qfloor
, "floor");
7142 DEFSYM (Qceiling
, "ceiling");
7144 staticpro (&Vwindow_list
);
7146 minibuf_selected_window
= Qnil
;
7147 staticpro (&minibuf_selected_window
);
7149 window_scroll_pixel_based_preserve_x
= -1;
7150 window_scroll_pixel_based_preserve_y
= -1;
7151 window_scroll_preserve_hpos
= -1;
7152 window_scroll_preserve_vpos
= -1;
7154 DEFVAR_LISP ("temp-buffer-show-function", Vtemp_buffer_show_function
,
7155 doc
: /* Non-nil means call as function to display a help buffer.
7156 The function is called with one argument, the buffer to be displayed.
7157 Used by `with-output-to-temp-buffer'.
7158 If this function is used, then it must do the entire job of showing
7159 the buffer; `temp-buffer-show-hook' is not run unless this function runs it. */);
7160 Vtemp_buffer_show_function
= Qnil
;
7162 DEFVAR_LISP ("minibuffer-scroll-window", Vminibuf_scroll_window
,
7163 doc
: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */);
7164 Vminibuf_scroll_window
= Qnil
;
7166 DEFVAR_BOOL ("mode-line-in-non-selected-windows", mode_line_in_non_selected_windows
,
7167 doc
: /* Non-nil means to use `mode-line-inactive' face in non-selected windows.
7168 If the minibuffer is active, the `minibuffer-scroll-window' mode line
7169 is displayed in the `mode-line' face. */);
7170 mode_line_in_non_selected_windows
= 1;
7172 DEFVAR_LISP ("other-window-scroll-buffer", Vother_window_scroll_buffer
,
7173 doc
: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. */);
7174 Vother_window_scroll_buffer
= Qnil
;
7176 DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p
,
7177 doc
: /* Non-nil means to automatically adjust `window-vscroll' to view tall lines. */);
7178 auto_window_vscroll_p
= 1;
7180 DEFVAR_INT ("next-screen-context-lines", next_screen_context_lines
,
7181 doc
: /* Number of lines of continuity when scrolling by screenfuls. */);
7182 next_screen_context_lines
= 2;
7184 DEFVAR_LISP ("scroll-preserve-screen-position",
7185 Vscroll_preserve_screen_position
,
7186 doc
: /* Controls if scroll commands move point to keep its screen position unchanged.
7187 A value of nil means point does not keep its screen position except
7188 at the scroll margin or window boundary respectively.
7189 A value of t means point keeps its screen position if the scroll
7190 command moved it vertically out of the window, e.g. when scrolling
7192 Any other value means point always keeps its screen position.
7193 Scroll commands should have the `scroll-command' property
7194 on their symbols to be controlled by this variable. */);
7195 Vscroll_preserve_screen_position
= Qnil
;
7197 DEFVAR_LISP ("window-point-insertion-type", Vwindow_point_insertion_type
,
7198 doc
: /* Type of marker to use for `window-point'. */);
7199 Vwindow_point_insertion_type
= Qnil
;
7201 DEFVAR_LISP ("window-configuration-change-hook",
7202 Vwindow_configuration_change_hook
,
7203 doc
: /* Functions to call when window configuration changes.
7204 The buffer-local part is run once per window, with the relevant window
7205 selected; while the global part is run only once for the modified frame,
7206 with the relevant frame selected. */);
7207 Vwindow_configuration_change_hook
= Qnil
;
7209 DEFVAR_LISP ("recenter-redisplay", Vrecenter_redisplay
,
7210 doc
: /* Non-nil means `recenter' redraws entire frame.
7211 If this option is non-nil, then the `recenter' command with a nil
7212 argument will redraw the entire frame; the special value `tty' causes
7213 the frame to be redrawn only if it is a tty frame. */);
7214 Vrecenter_redisplay
= Qtty
;
7216 DEFVAR_LISP ("window-combination-resize", Vwindow_combination_resize
,
7217 doc
: /* If t, resize window combinations proportionally.
7218 If this variable is nil, splitting a window gets the entire screen space
7219 for displaying the new window from the window to split. Deleting and
7220 resizing a window preferably resizes one adjacent window only.
7222 If this variable is t, splitting a window tries to get the space
7223 proportionally from all windows in the same combination. This also
7224 allows to split a window that is otherwise too small or of fixed size.
7225 Resizing and deleting a window proportionally resize all windows in the
7228 Other values are reserved for future use.
7230 This variable takes no effect if the variable `window-combination-limit' is
7232 Vwindow_combination_resize
= Qnil
;
7234 DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit
,
7235 doc
: /* If non-nil, splitting a window makes a new parent window.
7236 The following values are recognized:
7238 nil means splitting a window will create a new parent window only if the
7239 window has no parent window or the window shall become part of a
7240 combination orthogonal to the one it is part of.
7242 `window-size' means that splitting a window for displaying a buffer
7243 makes a new parent window provided `display-buffer' is supposed to
7244 explicitly set the window's size due to the presence of a
7245 `window-height' or `window-width' entry in the alist used by
7246 `display-buffer'. Otherwise, this value is handled like nil.
7248 `temp-buffer' means that splitting a window for displaying a temporary
7249 buffer always makes a new parent window. Otherwise, this value is
7252 `display-buffer' means that splitting a window for displaying a buffer
7253 always makes a new parent window. Since temporary buffers are
7254 displayed by the function `display-buffer', this value is stronger
7255 than `temp-buffer'. Splitting a window for other purpose makes a
7256 new parent window only if needed.
7258 t means that splitting a window always creates a new parent window. If
7259 all splits behave this way, each frame's window tree is a binary
7260 tree and every window but the frame's root window has exactly one
7263 Other values are reserved for future use. */);
7264 Vwindow_combination_limit
= Qwindow_size
;
7266 DEFVAR_LISP ("window-persistent-parameters", Vwindow_persistent_parameters
,
7267 doc
: /* Alist of persistent window parameters.
7268 This alist specifies which window parameters shall get saved by
7269 `current-window-configuration' and `window-state-get' and subsequently
7270 restored to their previous values by `set-window-configuration' and
7273 The car of each entry of this alist is the symbol specifying the
7274 parameter. The cdr is one of the following:
7276 nil means the parameter is neither saved by `window-state-get' nor by
7277 `current-window-configuration'.
7279 t means the parameter is saved by `current-window-configuration' and,
7280 provided its WRITABLE argument is nil, by `window-state-get'.
7282 The symbol `writable' means the parameter is saved unconditionally by
7283 both `current-window-configuration' and `window-state-get'. Do not use
7284 this value for parameters without read syntax (like windows or frames).
7286 Parameters not saved by `current-window-configuration' or
7287 `window-state-get' are left alone by `set-window-configuration'
7288 respectively are not installed by `window-state-put'. */);
7289 Vwindow_persistent_parameters
= list1 (Fcons (Qclone_of
, Qt
));
7291 DEFVAR_BOOL ("window-resize-pixelwise", window_resize_pixelwise
,
7292 doc
: /* Non-nil means resizing windows works pixelwise.
7293 Functions currently affected by this option are `split-window',
7294 `maximize-window', `minimize-window', `fit-window-to-buffer' and
7295 `fit-frame-to-buffer' and all functions symmetrically resizing a
7298 Note that when a frame's pixel size is not a multiple of the
7299 frame's character size, at least one window may get resized
7300 pixelwise even if this option is nil. */);
7301 window_resize_pixelwise
= 0;
7303 defsubr (&Sselected_window
);
7304 defsubr (&Sminibuffer_window
);
7305 defsubr (&Swindow_minibuffer_p
);
7306 defsubr (&Swindowp
);
7307 defsubr (&Swindow_valid_p
);
7308 defsubr (&Swindow_live_p
);
7309 defsubr (&Swindow_frame
);
7310 defsubr (&Sframe_root_window
);
7311 defsubr (&Sframe_first_window
);
7312 defsubr (&Sframe_selected_window
);
7313 defsubr (&Sset_frame_selected_window
);
7314 defsubr (&Spos_visible_in_window_p
);
7315 defsubr (&Swindow_line_height
);
7316 defsubr (&Swindow_buffer
);
7317 defsubr (&Swindow_parent
);
7318 defsubr (&Swindow_top_child
);
7319 defsubr (&Swindow_left_child
);
7320 defsubr (&Swindow_next_sibling
);
7321 defsubr (&Swindow_prev_sibling
);
7322 defsubr (&Swindow_combination_limit
);
7323 defsubr (&Sset_window_combination_limit
);
7324 defsubr (&Swindow_use_time
);
7325 defsubr (&Swindow_pixel_width
);
7326 defsubr (&Swindow_pixel_height
);
7327 defsubr (&Swindow_total_width
);
7328 defsubr (&Swindow_total_height
);
7329 defsubr (&Swindow_normal_size
);
7330 defsubr (&Swindow_new_pixel
);
7331 defsubr (&Swindow_new_total
);
7332 defsubr (&Swindow_new_normal
);
7333 defsubr (&Swindow_pixel_left
);
7334 defsubr (&Swindow_pixel_top
);
7335 defsubr (&Swindow_left_column
);
7336 defsubr (&Swindow_top_line
);
7337 defsubr (&Sset_window_new_pixel
);
7338 defsubr (&Sset_window_new_total
);
7339 defsubr (&Sset_window_new_normal
);
7340 defsubr (&Swindow_resize_apply
);
7341 defsubr (&Swindow_resize_apply_total
);
7342 defsubr (&Swindow_body_height
);
7343 defsubr (&Swindow_body_width
);
7344 defsubr (&Swindow_hscroll
);
7345 defsubr (&Sset_window_hscroll
);
7346 defsubr (&Swindow_redisplay_end_trigger
);
7347 defsubr (&Sset_window_redisplay_end_trigger
);
7348 defsubr (&Swindow_edges
);
7349 defsubr (&Swindow_pixel_edges
);
7350 defsubr (&Swindow_absolute_pixel_edges
);
7351 defsubr (&Swindow_mode_line_height
);
7352 defsubr (&Swindow_header_line_height
);
7353 defsubr (&Swindow_right_divider_width
);
7354 defsubr (&Swindow_bottom_divider_width
);
7355 defsubr (&Swindow_inside_edges
);
7356 defsubr (&Swindow_inside_pixel_edges
);
7357 defsubr (&Swindow_inside_absolute_pixel_edges
);
7358 defsubr (&Scoordinates_in_window_p
);
7359 defsubr (&Swindow_at
);
7360 defsubr (&Swindow_point
);
7361 defsubr (&Swindow_start
);
7362 defsubr (&Swindow_end
);
7363 defsubr (&Sset_window_point
);
7364 defsubr (&Sset_window_start
);
7365 defsubr (&Swindow_dedicated_p
);
7366 defsubr (&Sset_window_dedicated_p
);
7367 defsubr (&Swindow_display_table
);
7368 defsubr (&Sset_window_display_table
);
7369 defsubr (&Snext_window
);
7370 defsubr (&Sprevious_window
);
7371 defsubr (&Sget_buffer_window
);
7372 defsubr (&Sdelete_other_windows_internal
);
7373 defsubr (&Sdelete_window_internal
);
7374 defsubr (&Sresize_mini_window_internal
);
7375 defsubr (&Sset_window_buffer
);
7376 defsubr (&Srun_window_configuration_change_hook
);
7377 defsubr (&Srun_window_scroll_functions
);
7378 defsubr (&Sselect_window
);
7379 defsubr (&Sforce_window_update
);
7380 defsubr (&Ssplit_window_internal
);
7381 defsubr (&Sscroll_up
);
7382 defsubr (&Sscroll_down
);
7383 defsubr (&Sscroll_left
);
7384 defsubr (&Sscroll_right
);
7385 defsubr (&Sother_window_for_scrolling
);
7386 defsubr (&Sscroll_other_window
);
7387 defsubr (&Sminibuffer_selected_window
);
7388 defsubr (&Srecenter
);
7389 defsubr (&Swindow_text_width
);
7390 defsubr (&Swindow_text_height
);
7391 defsubr (&Smove_to_window_line
);
7392 defsubr (&Swindow_configuration_p
);
7393 defsubr (&Swindow_configuration_frame
);
7394 defsubr (&Sset_window_configuration
);
7395 defsubr (&Scurrent_window_configuration
);
7396 defsubr (&Sset_window_margins
);
7397 defsubr (&Swindow_margins
);
7398 defsubr (&Sset_window_fringes
);
7399 defsubr (&Swindow_fringes
);
7400 defsubr (&Sset_window_scroll_bars
);
7401 defsubr (&Swindow_scroll_bars
);
7402 defsubr (&Swindow_vscroll
);
7403 defsubr (&Sset_window_vscroll
);
7404 defsubr (&Scompare_window_configurations
);
7405 defsubr (&Swindow_list
);
7406 defsubr (&Swindow_list_1
);
7407 defsubr (&Swindow_prev_buffers
);
7408 defsubr (&Sset_window_prev_buffers
);
7409 defsubr (&Swindow_next_buffers
);
7410 defsubr (&Sset_window_next_buffers
);
7411 defsubr (&Swindow_parameters
);
7412 defsubr (&Swindow_parameter
);
7413 defsubr (&Sset_window_parameter
);
7417 keys_of_window (void)
7419 initial_define_key (control_x_map
, '<', "scroll-left");
7420 initial_define_key (control_x_map
, '>', "scroll-right");
7422 initial_define_key (global_map
, Ctl ('V'), "scroll-up-command");
7423 initial_define_key (meta_map
, Ctl ('V'), "scroll-other-window");
7424 initial_define_key (meta_map
, 'v', "scroll-down-command");