aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
authorBill Wohler2014-02-23 18:04:35 -0800
committerBill Wohler2014-02-23 18:04:35 -0800
commit3e93bafb95608467e438ba7f725fd1f020669f8c (patch)
treef2f90109f283e06a18caea3cb2a2623abcfb3a92 /src/window.c
parent791c0d7634e44bb92ca85af605be84ff2ae08963 (diff)
parente918e27fdf331e89268fc2c9d7cf838d3ecf7aa7 (diff)
downloademacs-3e93bafb95608467e438ba7f725fd1f020669f8c.tar.gz
emacs-3e93bafb95608467e438ba7f725fd1f020669f8c.zip
Merge from trunk; up to 2014-02-23T23:41:17Z!lekktu@gmail.com.
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c2522
1 files changed, 1508 insertions, 1014 deletions
diff --git a/src/window.c b/src/window.c
index c2da2e8637a..0ec1aa96324 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1,6 +1,6 @@
1/* Window creation, deletion and examination for GNU Emacs. 1/* Window creation, deletion and examination for GNU Emacs.
2 Does not include redisplay. 2 Does not include redisplay.
3 Copyright (C) 1985-1987, 1993-1998, 2000-2013 Free Software 3 Copyright (C) 1985-1987, 1993-1998, 2000-2014 Free Software
4 Foundation, Inc. 4 Foundation, Inc.
5 5
6This file is part of GNU Emacs. 6This file is part of GNU Emacs.
@@ -20,8 +20,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20 20
21#include <config.h> 21#include <config.h>
22 22
23#define WINDOW_INLINE EXTERN_INLINE
24
25#include <stdio.h> 23#include <stdio.h>
26 24
27#include "lisp.h" 25#include "lisp.h"
@@ -39,40 +37,32 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
39#include "blockinput.h" 37#include "blockinput.h"
40#include "intervals.h" 38#include "intervals.h"
41#include "termhooks.h" /* For FRAME_TERMINAL. */ 39#include "termhooks.h" /* For FRAME_TERMINAL. */
42 40#ifdef HAVE_WINDOW_SYSTEM
43#ifdef HAVE_X_WINDOWS 41#include TERM_HEADER
44#include "xterm.h" 42#endif /* HAVE_WINDOW_SYSTEM */
45#endif /* HAVE_X_WINDOWS */
46#ifdef HAVE_NTGUI
47#include "w32term.h"
48#endif
49#ifdef MSDOS 43#ifdef MSDOS
50#include "msdos.h" 44#include "msdos.h"
51#endif 45#endif
52#ifdef HAVE_NS
53#include "nsterm.h"
54#endif
55 46
56Lisp_Object Qwindowp, Qwindow_live_p; 47Lisp_Object Qwindowp, Qwindow_live_p;
57static Lisp_Object Qwindow_valid_p; 48static Lisp_Object Qwindow_valid_p;
58static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer; 49static Lisp_Object Qwindow_configuration_p;
50static Lisp_Object Qrecord_window_buffer;
59static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; 51static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
60static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; 52static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
61static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically; 53static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically;
54static Lisp_Object Qwindow_pixel_to_total;
62static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; 55static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
63static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of; 56static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
57static Lisp_Object Qfloor, Qceiling;
64 58
65static int displayed_window_lines (struct window *); 59static int displayed_window_lines (struct window *);
66static int count_windows (struct window *); 60static int count_windows (struct window *);
67static int get_leaf_windows (struct window *, struct window **, int); 61static int get_leaf_windows (struct window *, struct window **, int);
68static void window_scroll (Lisp_Object, EMACS_INT, int, int); 62static void window_scroll (Lisp_Object, EMACS_INT, bool, int);
69static void window_scroll_pixel_based (Lisp_Object, int, int, int); 63static void window_scroll_pixel_based (Lisp_Object, int, bool, int);
70static void window_scroll_line_based (Lisp_Object, int, int, int); 64static void window_scroll_line_based (Lisp_Object, int, bool, int);
71static int freeze_window_start (struct window *, void *);
72static Lisp_Object window_list (void);
73static int add_window_to_list (struct window *, void *); 65static int add_window_to_list (struct window *, void *);
74static int candidate_window_p (Lisp_Object, Lisp_Object, Lisp_Object,
75 Lisp_Object);
76static Lisp_Object next_window (Lisp_Object, Lisp_Object, 66static Lisp_Object next_window (Lisp_Object, Lisp_Object,
77 Lisp_Object, int); 67 Lisp_Object, int);
78static void decode_next_window_args (Lisp_Object *, Lisp_Object *, 68static void decode_next_window_args (Lisp_Object *, Lisp_Object *,
@@ -84,11 +74,20 @@ static int foreach_window_1 (struct window *,
84 int (* fn) (struct window *, void *), 74 int (* fn) (struct window *, void *),
85 void *); 75 void *);
86static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object); 76static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
87static int window_resize_check (struct window *, int); 77static int window_resize_check (struct window *, bool);
88static void window_resize_apply (struct window *, int); 78static void window_resize_apply (struct window *, bool);
79static void window_resize_apply_total (struct window *, bool);
89static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); 80static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
90static void select_window_1 (Lisp_Object, bool); 81static void select_window_1 (Lisp_Object, bool);
91 82
83static struct window *set_window_fringes (struct window *, Lisp_Object,
84 Lisp_Object, Lisp_Object);
85static struct window *set_window_margins (struct window *, Lisp_Object,
86 Lisp_Object);
87static struct window *set_window_scroll_bars (struct window *, Lisp_Object,
88 Lisp_Object, Lisp_Object);
89static void apply_window_adjustment (struct window *);
90
92/* This is the window in which the terminal's cursor should 91/* This is the window in which the terminal's cursor should
93 be left when nothing is being done with it. This must 92 be left when nothing is being done with it. This must
94 always be a leaf window, and its buffer is selected by 93 always be a leaf window, and its buffer is selected by
@@ -116,6 +115,9 @@ Lisp_Object minibuf_selected_window;
116/* Hook run at end of temp_output_buffer_show. */ 115/* Hook run at end of temp_output_buffer_show. */
117static Lisp_Object Qtemp_buffer_show_hook; 116static Lisp_Object Qtemp_buffer_show_hook;
118 117
118/* Incremented for each window created. */
119static int sequence_number;
120
119/* Nonzero after init_window_once has finished. */ 121/* Nonzero after init_window_once has finished. */
120static int window_initialized; 122static int window_initialized;
121 123
@@ -130,6 +132,12 @@ static int window_scroll_pixel_based_preserve_y;
130static EMACS_INT window_scroll_preserve_hpos; 132static EMACS_INT window_scroll_preserve_hpos;
131static EMACS_INT window_scroll_preserve_vpos; 133static EMACS_INT window_scroll_preserve_vpos;
132 134
135static void
136CHECK_WINDOW_CONFIGURATION (Lisp_Object x)
137{
138 CHECK_TYPE (WINDOW_CONFIGURATIONP (x), Qwindow_configuration_p, x);
139}
140
133/* These setters are used only in this file, so they can be private. */ 141/* These setters are used only in this file, so they can be private. */
134static void 142static void
135wset_combination_limit (struct window *w, Lisp_Object val) 143wset_combination_limit (struct window *w, Lisp_Object val)
@@ -147,21 +155,6 @@ wset_display_table (struct window *w, Lisp_Object val)
147 w->display_table = val; 155 w->display_table = val;
148} 156}
149static void 157static void
150wset_hchild (struct window *w, Lisp_Object val)
151{
152 w->hchild = val;
153}
154static void
155wset_left_fringe_width (struct window *w, Lisp_Object val)
156{
157 w->left_fringe_width = val;
158}
159static void
160wset_left_margin_cols (struct window *w, Lisp_Object val)
161{
162 w->left_margin_cols = val;
163}
164static void
165wset_new_normal (struct window *w, Lisp_Object val) 158wset_new_normal (struct window *w, Lisp_Object val)
166{ 159{
167 w->new_normal = val; 160 w->new_normal = val;
@@ -192,21 +185,6 @@ wset_pointm (struct window *w, Lisp_Object val)
192 w->pointm = val; 185 w->pointm = val;
193} 186}
194static void 187static void
195wset_right_fringe_width (struct window *w, Lisp_Object val)
196{
197 w->right_fringe_width = val;
198}
199static void
200wset_right_margin_cols (struct window *w, Lisp_Object val)
201{
202 w->right_margin_cols = val;
203}
204static void
205wset_scroll_bar_width (struct window *w, Lisp_Object val)
206{
207 w->scroll_bar_width = val;
208}
209static void
210wset_start (struct window *w, Lisp_Object val) 188wset_start (struct window *w, Lisp_Object val)
211{ 189{
212 w->start = val; 190 w->start = val;
@@ -217,11 +195,6 @@ wset_temslot (struct window *w, Lisp_Object val)
217 w->temslot = val; 195 w->temslot = val;
218} 196}
219static void 197static void
220wset_vchild (struct window *w, Lisp_Object val)
221{
222 w->vchild = val;
223}
224static void
225wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val) 198wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val)
226{ 199{
227 w->vertical_scroll_bar_type = val; 200 w->vertical_scroll_bar_type = val;
@@ -231,6 +204,29 @@ wset_window_parameters (struct window *w, Lisp_Object val)
231{ 204{
232 w->window_parameters = val; 205 w->window_parameters = val;
233} 206}
207static void
208wset_combination (struct window *w, bool horflag, Lisp_Object val)
209{
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));
213 w->contents = val;
214 /* When an internal window is deleted and VAL is nil, HORFLAG
215 is meaningless. */
216 if (!NILP (val))
217 w->horizontal = horflag;
218}
219
220/* Nonzero if leaf window W doesn't reflect the actual state
221 of displayed buffer due to its text or overlays change. */
222
223bool
224window_outdated (struct window *w)
225{
226 struct buffer *b = XBUFFER (w->contents);
227 return (w->last_modified < BUF_MODIFF (b)
228 || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b));
229}
234 230
235struct window * 231struct window *
236decode_live_window (register Lisp_Object window) 232decode_live_window (register Lisp_Object window)
@@ -275,9 +271,9 @@ static void
275adjust_window_count (struct window *w, int arg) 271adjust_window_count (struct window *w, int arg)
276{ 272{
277 eassert (eabs (arg) == 1); 273 eassert (eabs (arg) == 1);
278 if (BUFFERP (w->buffer)) 274 if (BUFFERP (w->contents))
279 { 275 {
280 struct buffer *b = XBUFFER (w->buffer); 276 struct buffer *b = XBUFFER (w->contents);
281 277
282 if (b->base_buffer) 278 if (b->base_buffer)
283 b = b->base_buffer; 279 b = b->base_buffer;
@@ -296,19 +292,14 @@ void
296wset_buffer (struct window *w, Lisp_Object val) 292wset_buffer (struct window *w, Lisp_Object val)
297{ 293{
298 adjust_window_count (w, -1); 294 adjust_window_count (w, -1);
299 w->buffer = val; 295 if (BUFFERP (val))
296 /* Make sure that we do not assign the buffer
297 to an internal window. */
298 eassert (MARKERP (w->start) && MARKERP (w->pointm));
299 w->contents = val;
300 adjust_window_count (w, 1); 300 adjust_window_count (w, 1);
301} 301}
302 302
303/* Build a frequently used 4-integer (X Y W H) list. */
304
305static Lisp_Object
306list4i (EMACS_INT x, EMACS_INT y, EMACS_INT w, EMACS_INT h)
307{
308 return list4 (make_number (x), make_number (y),
309 make_number (w), make_number (h));
310}
311
312DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0, 303DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
313 doc: /* Return t if OBJECT is a window and nil otherwise. */) 304 doc: /* Return t if OBJECT is a window and nil otherwise. */)
314 (Lisp_Object object) 305 (Lisp_Object object)
@@ -403,15 +394,8 @@ the first window of that frame. */)
403 window = XFRAME (frame_or_window)->root_window; 394 window = XFRAME (frame_or_window)->root_window;
404 } 395 }
405 396
406 while (NILP (XWINDOW (window)->buffer)) 397 while (WINDOWP (XWINDOW (window)->contents))
407 { 398 window = XWINDOW (window)->contents;
408 if (! NILP (XWINDOW (window)->hchild))
409 window = XWINDOW (window)->hchild;
410 else if (! NILP (XWINDOW (window)->vchild))
411 window = XWINDOW (window)->vchild;
412 else
413 emacs_abort ();
414 }
415 399
416 return window; 400 return window;
417} 401}
@@ -493,19 +477,24 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
493 CHECK_LIVE_WINDOW (window); 477 CHECK_LIVE_WINDOW (window);
494 478
495 w = XWINDOW (window); 479 w = XWINDOW (window);
496 w->frozen_window_start_p = 0;
497
498 if (NILP (norecord))
499 {
500 w->use_time = ++window_select_count;
501 record_buffer (w->buffer);
502 }
503 480
504 /* Make the selected window's buffer current. */ 481 /* Make the selected window's buffer current. */
505 Fset_buffer (w->buffer); 482 Fset_buffer (w->contents);
506 483
507 if (EQ (window, selected_window) && !inhibit_point_swap) 484 if (EQ (window, selected_window) && !inhibit_point_swap)
508 return window; 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;
489
490 if (NILP (norecord))
491 { /* Mark the window for redisplay since the selected-window has
492 a different mode-line. */
493 wset_redisplay (XWINDOW (selected_window));
494 wset_redisplay (w);
495 }
496 else
497 redisplay_other_windows ();
509 498
510 sf = SELECTED_FRAME (); 499 sf = SELECTED_FRAME ();
511 if (XFRAME (WINDOW_FRAME (w)) != sf) 500 if (XFRAME (WINDOW_FRAME (w)) != sf)
@@ -524,9 +513,18 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
524 fset_selected_window (sf, window); 513 fset_selected_window (sf, window);
525 514
526 select_window_1 (window, inhibit_point_swap); 515 select_window_1 (window, inhibit_point_swap);
516 bset_last_selected_window (XBUFFER (w->contents), window);
517
518 record_and_return:
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). */
522 if (NILP (norecord))
523 {
524 w->use_time = ++window_select_count;
525 record_buffer (w->contents);
526 }
527 527
528 bset_last_selected_window (XBUFFER (w->buffer), window);
529 windows_or_buffers_changed++;
530 return window; 528 return window;
531} 529}
532 530
@@ -542,10 +540,10 @@ select_window_1 (Lisp_Object window, bool inhibit_point_swap)
542 if (!inhibit_point_swap) 540 if (!inhibit_point_swap)
543 { 541 {
544 struct window *ow = XWINDOW (selected_window); 542 struct window *ow = XWINDOW (selected_window);
545 if (! NILP (ow->buffer)) 543 if (BUFFERP (ow->contents))
546 set_marker_both (ow->pointm, ow->buffer, 544 set_marker_both (ow->pointm, ow->contents,
547 BUF_PT (XBUFFER (ow->buffer)), 545 BUF_PT (XBUFFER (ow->contents)),
548 BUF_PT_BYTE (XBUFFER (ow->buffer))); 546 BUF_PT_BYTE (XBUFFER (ow->contents)));
549 } 547 }
550 548
551 selected_window = window; 549 selected_window = window;
@@ -555,15 +553,7 @@ select_window_1 (Lisp_Object window, bool inhibit_point_swap)
555 than one window. It also matters when 553 than one window. It also matters when
556 redisplay_window has altered point after scrolling, 554 redisplay_window has altered point after scrolling,
557 because it makes the change only in the window. */ 555 because it makes the change only in the window. */
558 { 556 set_point_from_marker (XWINDOW (window)->pointm);
559 register ptrdiff_t new_point = marker_position (XWINDOW (window)->pointm);
560 if (new_point < BEGV)
561 SET_PT (BEGV);
562 else if (new_point > ZV)
563 SET_PT (ZV);
564 else
565 SET_PT (new_point);
566 }
567} 557}
568 558
569DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0, 559DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
@@ -590,7 +580,8 @@ If WINDOW is omitted or nil, it defaults to the selected window.
590Return nil for an internal window or a deleted window. */) 580Return nil for an internal window or a deleted window. */)
591 (Lisp_Object window) 581 (Lisp_Object window)
592{ 582{
593 return decode_any_window (window)->buffer; 583 struct window *w = decode_any_window (window);
584 return WINDOW_LEAF_P (w) ? w->contents : Qnil;
594} 585}
595 586
596DEFUN ("window-parent", Fwindow_parent, Swindow_parent, 0, 1, 0, 587DEFUN ("window-parent", Fwindow_parent, Swindow_parent, 0, 1, 0,
@@ -610,7 +601,8 @@ Return nil if WINDOW is an internal window whose children form a
610horizontal combination. */) 601horizontal combination. */)
611 (Lisp_Object window) 602 (Lisp_Object window)
612{ 603{
613 return decode_valid_window (window)->vchild; 604 struct window *w = decode_valid_window (window);
605 return WINDOW_VERTICAL_COMBINATION_P (w) ? w->contents : Qnil;
614} 606}
615 607
616DEFUN ("window-left-child", Fwindow_left_child, Swindow_left_child, 0, 1, 0, 608DEFUN ("window-left-child", Fwindow_left_child, Swindow_left_child, 0, 1, 0,
@@ -621,7 +613,8 @@ Return nil if WINDOW is an internal window whose children form a
621vertical combination. */) 613vertical combination. */)
622 (Lisp_Object window) 614 (Lisp_Object window)
623{ 615{
624 return decode_valid_window (window)->hchild; 616 struct window *w = decode_valid_window (window);
617 return WINDOW_HORIZONTAL_COMBINATION_P (w) ? w->contents : Qnil;
625} 618}
626 619
627DEFUN ("window-next-sibling", Fwindow_next_sibling, Swindow_next_sibling, 0, 1, 0, 620DEFUN ("window-next-sibling", Fwindow_next_sibling, Swindow_next_sibling, 0, 1, 0,
@@ -644,30 +637,37 @@ Return nil if WINDOW has no previous sibling. */)
644 637
645DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combination_limit, 1, 1, 0, 638DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combination_limit, 1, 1, 0,
646 doc: /* Return combination limit of window WINDOW. 639 doc: /* Return combination limit of window WINDOW.
640WINDOW must be a valid window used in horizontal or vertical combination.
647If the return value is nil, child windows of WINDOW can be recombined with 641If the return value is nil, child windows of WINDOW can be recombined with
648WINDOW's siblings. A return value of t means that child windows of 642WINDOW's siblings. A return value of t means that child windows of
649WINDOW are never \(re-)combined with WINDOW's siblings. 643WINDOW are never \(re-)combined with WINDOW's siblings. */)
650
651WINDOW must be a valid window. The return value is meaningful for
652internal windows only. */)
653 (Lisp_Object window) 644 (Lisp_Object window)
654{ 645{
646 struct window *w;
647
655 CHECK_VALID_WINDOW (window); 648 CHECK_VALID_WINDOW (window);
656 return XWINDOW (window)->combination_limit; 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;
657} 653}
658 654
659DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0, 655DEFUN ("set-window-combination-limit", Fset_window_combination_limit, Sset_window_combination_limit, 2, 2, 0,
660 doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT. 656 doc: /* Set combination limit of window WINDOW to LIMIT; return LIMIT.
657WINDOW must be a valid window used in horizontal or vertical combination.
661If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's 658If LIMIT is nil, child windows of WINDOW can be recombined with WINDOW's
662siblings. LIMIT t means that child windows of WINDOW are never 659siblings. LIMIT t means that child windows of WINDOW are never
663\(re-)combined with WINDOW's siblings. Other values are reserved for 660\(re-)combined with WINDOW's siblings. Other values are reserved for
664future use. 661future use. */)
665
666WINDOW must be a valid window. Setting the combination limit is
667meaningful for internal windows only. */)
668 (Lisp_Object window, Lisp_Object limit) 662 (Lisp_Object window, Lisp_Object limit)
669{ 663{
670 wset_combination_limit (decode_valid_window (window), limit); 664 struct window *w;
665
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);
671 return limit; 671 return limit;
672} 672}
673 673
@@ -682,34 +682,102 @@ selected one. */)
682 return make_number (decode_live_window (window)->use_time); 682 return make_number (decode_live_window (window)->use_time);
683} 683}
684 684
685DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 1, 0, 685DEFUN ("window-pixel-width", Fwindow_pixel_width, Swindow_pixel_width, 0, 1, 0,
686 doc: /* Return the total height, in lines, of window WINDOW. 686 doc: /* Return the width of window WINDOW in pixels.
687WINDOW must be a valid window and defaults to the selected one. 687WINDOW must be a valid window and defaults to the selected one.
688 688
689The return value includes the mode line and header line, if any. 689The return value includes the fringes and margins of WINDOW as well as
690If WINDOW is an internal window, the total height is the height 690any vertical dividers or scroll bars belonging to WINDOW. If WINDOW is
691of the screen areas spanned by its children. 691an internal window, its pixel width is the width of the screen areas
692spanned by its children. */)
693 (Lisp_Object window)
694{
695 return make_number (decode_valid_window (window)->pixel_width);
696}
697
698DEFUN ("window-pixel-height", Fwindow_pixel_height, Swindow_pixel_height, 0, 1, 0,
699 doc: /* Return the height of window WINDOW in pixels.
700WINDOW must be a valid window and defaults to the selected one.
692 701
693On a graphical display, this total height is reported as an 702The return value includes the mode line and header line, if any. If
694integer multiple of the default character height. */) 703WINDOW is an internal window, its pixel height is the height of the
704screen areas spanned by its children. */)
695 (Lisp_Object window) 705 (Lisp_Object window)
696{ 706{
697 return decode_valid_window (window)->total_lines; 707 return make_number (decode_valid_window (window)->pixel_height);
698} 708}
699 709
700DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 1, 0, 710DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 2, 0,
701 doc: /* Return the total width, in columns, of window WINDOW. 711 doc: /* Return the height of window WINDOW in lines.
702WINDOW must be a valid window and defaults to the selected one. 712WINDOW must be a valid window and defaults to the selected one.
703 713
704The return value includes any vertical dividers or scroll bars 714The return value includes the heights of WINDOW's mode and header line
705belonging to WINDOW. If WINDOW is an internal window, the total width 715and its bottom divider, if any. If WINDOW is an internal window, the
706is the width of the screen areas spanned by its children. 716total height is the height of the screen areas spanned by its children.
707 717
708On a graphical display, this total width is reported as an 718If WINDOW's pixel height is not an integral multiple of its frame's
709integer multiple of the default character width. */) 719character height, the number of lines occupied by WINDOW is rounded
710 (Lisp_Object window) 720internally. This is done in a way such that, if WINDOW is a parent
721window, the sum of the total heights of all its children internally
722equals the total height of WINDOW.
723
724If the optional argument ROUND is `ceiling', return the smallest integer
725larger than WINDOW's pixel height divided by the character height of
726WINDOW's frame. ROUND `floor' means to return the largest integer
727smaller than WINDOW's pixel height divided by the character height of
728WINDOW's frame. Any other value of ROUND means to return the internal
729total height of WINDOW. */)
730 (Lisp_Object window, Lisp_Object round)
731{
732 struct window *w = decode_valid_window (window);
733
734 if (! EQ (round, Qfloor) && ! EQ (round, Qceiling))
735 return make_number (w->total_lines);
736 else
737 {
738 int unit = FRAME_LINE_HEIGHT (WINDOW_XFRAME (w));
739
740 return make_number (EQ (round, Qceiling)
741 ? ((w->pixel_height + unit - 1) /unit)
742 : (w->pixel_height / unit));
743 }
744}
745
746DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 2, 0,
747 doc: /* Return the total width of window WINDOW in columns.
748WINDOW must be a valid window and defaults to the selected one.
749
750The return value includes the widths of WINDOW's fringes, margins,
751scroll bars and its right divider, if any. If WINDOW is an internal
752window, the total width is the width of the screen areas spanned by its
753children.
754
755If WINDOW's pixel width is not an integral multiple of its frame's
756character width, the number of lines occupied by WINDOW is rounded
757internally. This is done in a way such that, if WINDOW is a parent
758window, the sum of the total widths of all its children internally
759equals the total width of WINDOW.
760
761If the optional argument ROUND is `ceiling', return the smallest integer
762larger than WINDOW's pixel width divided by the character width of
763WINDOW's frame. ROUND `floor' means to return the largest integer
764smaller than WINDOW's pixel width divided by the character width of
765WINDOW's frame. Any other value of ROUND means to return the internal
766total width of WINDOW. */)
767 (Lisp_Object window, Lisp_Object round)
711{ 768{
712 return decode_valid_window (window)->total_cols; 769 struct window *w = decode_valid_window (window);
770
771 if (! EQ (round, Qfloor) && ! EQ (round, Qceiling))
772 return make_number (w->total_cols);
773 else
774 {
775 int unit = FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
776
777 return make_number (EQ (round, Qceiling)
778 ? ((w->pixel_width + unit - 1) /unit)
779 : (w->pixel_width / unit));
780 }
713} 781}
714 782
715DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0, 783DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0,
@@ -739,6 +807,30 @@ WINDOW must be a valid window and defaults to the selected one. */)
739 return decode_valid_window (window)->new_normal; 807 return decode_valid_window (window)->new_normal;
740} 808}
741 809
810DEFUN ("window-new-pixel", Fwindow_new_pixel, Swindow_new_pixel, 0, 1, 0,
811 doc: /* Return new pixel size of window WINDOW.
812WINDOW must be a valid window and defaults to the selected one. */)
813 (Lisp_Object window)
814{
815 return decode_valid_window (window)->new_pixel;
816}
817
818DEFUN ("window-pixel-left", Fwindow_pixel_left, Swindow_pixel_left, 0, 1, 0,
819 doc: /* Return left pixel edge of window WINDOW.
820WINDOW must be a valid window and defaults to the selected one. */)
821 (Lisp_Object window)
822{
823 return make_number (decode_valid_window (window)->pixel_left);
824}
825
826DEFUN ("window-pixel-top", Fwindow_pixel_top, Swindow_pixel_top, 0, 1, 0,
827 doc: /* Return top pixel edge of window WINDOW.
828WINDOW must be a valid window and defaults to the selected one. */)
829 (Lisp_Object window)
830{
831 return make_number (decode_valid_window (window)->pixel_top);
832}
833
742DEFUN ("window-left-column", Fwindow_left_column, Swindow_left_column, 0, 1, 0, 834DEFUN ("window-left-column", Fwindow_left_column, Swindow_left_column, 0, 1, 0,
743 doc: /* Return left column of window WINDOW. 835 doc: /* Return left column of window WINDOW.
744This is the distance, in columns, between the left edge of WINDOW and 836This is the distance, in columns, between the left edge of WINDOW and
@@ -748,7 +840,7 @@ value is 0 if there is no window to the left of WINDOW.
748WINDOW must be a valid window and defaults to the selected one. */) 840WINDOW must be a valid window and defaults to the selected one. */)
749 (Lisp_Object window) 841 (Lisp_Object window)
750{ 842{
751 return decode_valid_window (window)->left_col; 843 return make_number (decode_valid_window (window)->left_col);
752} 844}
753 845
754DEFUN ("window-top-line", Fwindow_top_line, Swindow_top_line, 0, 1, 0, 846DEFUN ("window-top-line", Fwindow_top_line, Swindow_top_line, 0, 1, 0,
@@ -760,82 +852,135 @@ there is no window above WINDOW.
760WINDOW must be a valid window and defaults to the selected one. */) 852WINDOW must be a valid window and defaults to the selected one. */)
761 (Lisp_Object window) 853 (Lisp_Object window)
762{ 854{
763 return decode_valid_window (window)->top_line; 855 return make_number (decode_valid_window (window)->top_line);
764} 856}
765 857
766/* Return the number of lines of W's body. Don't count any mode or 858/* Return the number of lines/pixels of W's body. Don't count any mode
767 header line of W. */ 859 or header line or horizontal divider of W. Rounds down to nearest
768 860 integer when not working pixelwise. */
769static int 861static int
770window_body_lines (struct window *w) 862window_body_height (struct window *w, bool pixelwise)
771{ 863{
772 int height = XFASTINT (w->total_lines); 864 int height = (w->pixel_height
865 - WINDOW_HEADER_LINE_HEIGHT (w)
866 - WINDOW_MODE_LINE_HEIGHT (w)
867 - WINDOW_BOTTOM_DIVIDER_WIDTH (w));
773 868
774 if (!MINI_WINDOW_P (w)) 869 /* Don't return a negative value. */
775 { 870 return max (pixelwise
776 if (WINDOW_WANTS_MODELINE_P (w)) 871 ? height
777 --height; 872 : height / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)),
778 if (WINDOW_WANTS_HEADER_LINE_P (w)) 873 0);
779 --height;
780 }
781
782 return height;
783} 874}
784 875
785/* Return the number of columns of W's body. Don't count columns 876/* Return the number of columns/pixels of W's body. Don't count columns
786 occupied by the scroll bar or the vertical bar separating W from its 877 occupied by the scroll bar or the divider/vertical bar separating W
787 right sibling. On window-systems don't count fringes or display 878 from its right sibling or margins. On window-systems don't count
788 margins either. */ 879 fringes either. Round down to nearest integer when not working
789 880 pixelwise. */
790int 881int
791window_body_cols (struct window *w) 882window_body_width (struct window *w, bool pixelwise)
792{ 883{
793 struct frame *f = XFRAME (WINDOW_FRAME (w)); 884 struct frame *f = XFRAME (WINDOW_FRAME (w));
794 int width = XINT (w->total_cols);
795
796 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
797 /* Scroll bars occupy a few columns. */
798 width -= WINDOW_CONFIG_SCROLL_BAR_COLS (w);
799 else if (!FRAME_WINDOW_P (f)
800 && !WINDOW_RIGHTMOST_P (w) && !WINDOW_FULL_WIDTH_P (w))
801 /* The column of `|' characters separating side-by-side windows
802 occupies one column only. */
803 width -= 1;
804
805 /* Display margins cannot be used for normal text. */
806 width -= WINDOW_LEFT_MARGIN_COLS (w) + WINDOW_RIGHT_MARGIN_COLS (w);
807 885
808 if (FRAME_WINDOW_P (f)) 886 int width = (w->pixel_width
809 /* On window-systems, fringes cannot be used for normal text. */ 887 - WINDOW_RIGHT_DIVIDER_WIDTH (w)
810 width -= WINDOW_FRINGE_COLS (w); 888 - (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
811 889 ? WINDOW_SCROLL_BAR_AREA_WIDTH (w)
812 return width; 890 : ((!FRAME_WINDOW_P (f)
891 && !WINDOW_RIGHTMOST_P (w)
892 && !WINDOW_RIGHT_DIVIDER_WIDTH (w))
893 /* A vertical bar is either 1 or 0. */
894 ? 1 : 0))
895 - WINDOW_MARGINS_WIDTH (w)
896 - (FRAME_WINDOW_P (f)
897 ? WINDOW_FRINGES_WIDTH (w)
898 : 0));
899
900 /* Don't return a negative value. */
901 return max (pixelwise
902 ? width
903 : width / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w)),
904 0);
905}
906
907DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 2, 0,
908 doc: /* Return the height of WINDOW's text area.
909WINDOW must be a live window and defaults to the selected one. Optional
910argument PIXELWISE non-nil means return the height of WINDOW's text area
911in pixels. The return value does not include the mode line or header
912line or any horizontal divider.
913
914If PIXELWISE is nil, return the largest integer smaller than WINDOW's
915pixel height divided by the character height of WINDOW's frame. This
916means that if a line at the bottom of the text area is only partially
917visible, that line is not counted. */)
918 (Lisp_Object window, Lisp_Object pixelwise)
919{
920 return make_number (window_body_height (decode_live_window (window),
921 NILP (pixelwise) ? 0 : 1));
922}
923
924DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 2, 0,
925 doc: /* Return the width of WINDOW's text area.
926WINDOW must be a live window and defaults to the selected one. Optional
927argument PIXELWISE non-nil means return the width in pixels. The return
928value does not include any vertical dividers, fringes or marginal areas,
929or scroll bars.
930
931If PIXELWISE is nil, return the largest integer smaller than WINDOW's
932pixel width divided by the character width of WINDOW's frame. This
933means that if a column at the right of the text area is only partially
934visible, that column is not counted. */)
935 (Lisp_Object window, Lisp_Object pixelwise)
936{
937 return make_number (window_body_width (decode_live_window (window),
938 NILP (pixelwise) ? 0 : 1));
939}
940
941DEFUN ("window-mode-line-height", Fwindow_mode_line_height,
942 Swindow_mode_line_height, 0, 1, 0,
943 doc: /* Return the height in pixels of WINDOW's mode-line.
944WINDOW must be a live window and defaults to the selected one. */)
945 (Lisp_Object window)
946{
947 return (make_number (WINDOW_MODE_LINE_HEIGHT (decode_live_window (window))));
813} 948}
814 949
815DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 1, 0, 950DEFUN ("window-header-line-height", Fwindow_header_line_height,
816 doc: /* Return the height, in lines, of WINDOW's text area. 951 Swindow_header_line_height, 0, 1, 0,
817WINDOW must be a live window and defaults to the selected one. 952 doc: /* Return the height in pixels of WINDOW's header-line.
953WINDOW must be a live window and defaults to the selected one. */)
954 (Lisp_Object window)
955{
956 return (make_number (WINDOW_HEADER_LINE_HEIGHT (decode_live_window (window))));
957}
818 958
819The returned height does not include the mode line or header line. 959DEFUN ("window-right-divider-width", Fwindow_right_divider_width,
820On a graphical display, the height is expressed as an integer multiple 960 Swindow_right_divider_width, 0, 1, 0,
821of the default character height. If a line at the bottom of the text 961 doc: /* Return the width in pixels of WINDOW's right divider.
822area is only partially visible, that counts as a whole line; to 962WINDOW must be a live window and defaults to the selected one. */)
823exclude partially-visible lines, use `window-text-height'. */)
824 (Lisp_Object window) 963 (Lisp_Object window)
825{ 964{
826 return make_number (window_body_lines (decode_live_window (window))); 965 return (make_number (WINDOW_RIGHT_DIVIDER_WIDTH (decode_live_window (window))));
827} 966}
828 967
829DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 1, 0, 968DEFUN ("window-bottom-divider-width", Fwindow_bottom_divider_width,
830 doc: /* Return the width, in columns, of WINDOW's text area. 969 Swindow_bottom_divider_width, 0, 1, 0,
831WINDOW must be a live window and defaults to the selected one. 970 doc: /* Return the width in pixels of WINDOW's bottom divider.
971WINDOW must be a live window and defaults to the selected one. */)
972 (Lisp_Object window)
973{
974 return (make_number (WINDOW_BOTTOM_DIVIDER_WIDTH (decode_live_window (window))));
975}
832 976
833The return value does not include any vertical dividers, fringe or 977DEFUN ("window-scroll-bar-width", Fwindow_scroll_bar_width,
834marginal areas, or scroll bars. On a graphical display, the width is 978 Swindow_scroll_bar_width, 0, 1, 0,
835expressed as an integer multiple of the default character width. */) 979 doc: /* Return the width in pixels of WINDOW's vertical scrollbar.
980WINDOW must be a live window and defaults to the selected one. */)
836 (Lisp_Object window) 981 (Lisp_Object window)
837{ 982{
838 return make_number (window_body_cols (decode_live_window (window))); 983 return (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (decode_live_window (window))));
839} 984}
840 985
841DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0, 986DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
@@ -862,7 +1007,7 @@ set_window_hscroll (struct window *w, EMACS_INT hscroll)
862 1007
863 /* Prevent redisplay shortcuts when changing the hscroll. */ 1008 /* Prevent redisplay shortcuts when changing the hscroll. */
864 if (w->hscroll != new_hscroll) 1009 if (w->hscroll != new_hscroll)
865 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 1010 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
866 1011
867 w->hscroll = new_hscroll; 1012 w->hscroll = new_hscroll;
868 return make_number (new_hscroll); 1013 return make_number (new_hscroll);
@@ -958,7 +1103,7 @@ calc_absolute_offset (struct window *w, int *add_x, int *add_y)
958#endif 1103#endif
959#ifdef FRAME_TOOLBAR_TOP_HEIGHT 1104#ifdef FRAME_TOOLBAR_TOP_HEIGHT
960 *add_y += FRAME_TOOLBAR_TOP_HEIGHT (f); 1105 *add_y += FRAME_TOOLBAR_TOP_HEIGHT (f);
961#elif FRAME_TOOLBAR_HEIGHT 1106#elif defined (FRAME_TOOLBAR_HEIGHT)
962 *add_y += FRAME_TOOLBAR_HEIGHT (f); 1107 *add_y += FRAME_TOOLBAR_HEIGHT (f);
963#endif 1108#endif
964#ifdef FRAME_NS_TITLEBAR_HEIGHT 1109#ifdef FRAME_NS_TITLEBAR_HEIGHT
@@ -1085,11 +1230,15 @@ display margins, fringes, header line, and/or mode line. */)
1085 1230
1086/* Test if the character at column X, row Y is within window W. 1231/* Test if the character at column X, row Y is within window W.
1087 If it is not, return ON_NOTHING; 1232 If it is not, return ON_NOTHING;
1233 if it is on the window's vertical divider, return
1234 ON_RIGHT_DIVIDER;
1235 if it is on the window's horizontal divider, return
1236 ON_BOTTOM_DIVIDER;
1088 if it is in the window's text area, return ON_TEXT; 1237 if it is in the window's text area, return ON_TEXT;
1089 if it is on the window's modeline, return ON_MODE_LINE; 1238 if it is on the window's modeline, return ON_MODE_LINE;
1090 if it is on the border between the window and its right sibling, 1239 if it is on the border between the window and its right sibling,
1091 return ON_VERTICAL_BORDER. 1240 return ON_VERTICAL_BORDER;
1092 if it is on a scroll bar, return ON_SCROLL_BAR. 1241 if it is on a scroll bar, return ON_SCROLL_BAR;
1093 if it is on the window's top line, return ON_HEADER_LINE; 1242 if it is on the window's top line, return ON_HEADER_LINE;
1094 if it is in left or right fringe of the window, 1243 if it is in left or right fringe of the window,
1095 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE; 1244 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE;
@@ -1117,13 +1266,28 @@ coordinates_in_window (register struct window *w, int x, int y)
1117 if (y < top_y || y >= bottom_y || x < left_x || x >= right_x) 1266 if (y < top_y || y >= bottom_y || x < left_x || x >= right_x)
1118 return ON_NOTHING; 1267 return ON_NOTHING;
1119 1268
1120 /* On the mode line or header line? */ 1269 /* On vertical window divider (which prevails horizontal
1121 if ((WINDOW_WANTS_MODELINE_P (w) 1270 dividers)? */
1122 && y >= bottom_y - CURRENT_MODE_LINE_HEIGHT (w) 1271 if (!WINDOW_RIGHTMOST_P (w)
1123 && (part = ON_MODE_LINE)) 1272 && WINDOW_RIGHT_DIVIDER_WIDTH (w)
1124 || (WINDOW_WANTS_HEADER_LINE_P (w) 1273 && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w)
1125 && y < top_y + CURRENT_HEADER_LINE_HEIGHT (w) 1274 && x <= right_x)
1126 && (part = ON_HEADER_LINE))) 1275 return ON_RIGHT_DIVIDER;
1276 /* On the horizontal window divider? */
1277 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w)
1278 && y >= (bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
1279 && y <= bottom_y)
1280 return ON_BOTTOM_DIVIDER;
1281 /* On the mode or header line? */
1282 else if ((WINDOW_WANTS_MODELINE_P (w)
1283 && y >= (bottom_y
1284 - CURRENT_MODE_LINE_HEIGHT (w)
1285 - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
1286 && y <= bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
1287 && (part = ON_MODE_LINE))
1288 || (WINDOW_WANTS_HEADER_LINE_P (w)
1289 && y < top_y + CURRENT_HEADER_LINE_HEIGHT (w)
1290 && (part = ON_HEADER_LINE)))
1127 { 1291 {
1128 /* If it's under/over the scroll bar portion of the mode/header 1292 /* If it's under/over the scroll bar portion of the mode/header
1129 line, say it's on the vertical line. That's to be able to 1293 line, say it's on the vertical line. That's to be able to
@@ -1146,7 +1310,7 @@ coordinates_in_window (register struct window *w, int x, int y)
1146 if (w->pseudo_window_p) 1310 if (w->pseudo_window_p)
1147 { 1311 {
1148 left_x = 0; 1312 left_x = 0;
1149 right_x = WINDOW_TOTAL_WIDTH (w) - 1; 1313 right_x = WINDOW_PIXEL_WIDTH (w) - 1;
1150 } 1314 }
1151 else 1315 else
1152 { 1316 {
@@ -1176,6 +1340,8 @@ coordinates_in_window (register struct window *w, int x, int y)
1176 terminals, the vertical line's x coordinate is right_x. */ 1340 terminals, the vertical line's x coordinate is right_x. */
1177 else if (!w->pseudo_window_p 1341 else if (!w->pseudo_window_p
1178 && !WINDOW_RIGHTMOST_P (w) 1342 && !WINDOW_RIGHTMOST_P (w)
1343 /* Why check ux if we are not the rightmost window? Also
1344 shouldn't a pseudo window always be rightmost? */
1179 && x > right_x - ux) 1345 && x > right_x - ux)
1180 return ON_VERTICAL_BORDER; 1346 return ON_VERTICAL_BORDER;
1181 1347
@@ -1231,7 +1397,7 @@ window_relative_x_coord (struct window *w, enum window_part part, int x)
1231 case ON_RIGHT_MARGIN: 1397 case ON_RIGHT_MARGIN:
1232 return (x + 1 1398 return (x + 1
1233 - ((w->pseudo_window_p) 1399 - ((w->pseudo_window_p)
1234 ? WINDOW_TOTAL_WIDTH (w) 1400 ? WINDOW_PIXEL_WIDTH (w)
1235 : WINDOW_BOX_RIGHT_EDGE_X (w)) 1401 : WINDOW_BOX_RIGHT_EDGE_X (w))
1236 + window_box_width (w, RIGHT_MARGIN_AREA) 1402 + window_box_width (w, RIGHT_MARGIN_AREA)
1237 + ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)) 1403 + ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
@@ -1316,6 +1482,12 @@ If they are in the windows's left or right marginal areas, `left-margin'\n\
1316 /* Historically we are supposed to return nil in this case. */ 1482 /* Historically we are supposed to return nil in this case. */
1317 return Qnil; 1483 return Qnil;
1318 1484
1485 case ON_RIGHT_DIVIDER:
1486 return Qright_divider;
1487
1488 case ON_BOTTOM_DIVIDER:
1489 return Qbottom_divider;
1490
1319 default: 1491 default:
1320 emacs_abort (); 1492 emacs_abort ();
1321 } 1493 }
@@ -1341,7 +1513,7 @@ struct check_window_data
1341static int 1513static int
1342check_window_containing (struct window *w, void *user_data) 1514check_window_containing (struct window *w, void *user_data)
1343{ 1515{
1344 struct check_window_data *cw = (struct check_window_data *) user_data; 1516 struct check_window_data *cw = user_data;
1345 enum window_part found; 1517 enum window_part found;
1346 int continue_p = 1; 1518 int continue_p = 1;
1347 1519
@@ -1377,7 +1549,7 @@ check_window_containing (struct window *w, void *user_data)
1377 1549
1378Lisp_Object 1550Lisp_Object
1379window_from_coordinates (struct frame *f, int x, int y, 1551window_from_coordinates (struct frame *f, int x, int y,
1380 enum window_part *part, int tool_bar_p) 1552 enum window_part *part, bool tool_bar_p)
1381{ 1553{
1382 Lisp_Object window; 1554 Lisp_Object window;
1383 struct check_window_data cw; 1555 struct check_window_data cw;
@@ -1390,6 +1562,7 @@ window_from_coordinates (struct frame *f, int x, int y,
1390 cw.window = &window, cw.x = x, cw.y = y; cw.part = part; 1562 cw.window = &window, cw.x = x, cw.y = y; cw.part = part;
1391 foreach_window (f, check_window_containing, &cw); 1563 foreach_window (f, check_window_containing, &cw);
1392 1564
1565#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
1393 /* If not found above, see if it's in the tool bar window, if a tool 1566 /* If not found above, see if it's in the tool bar window, if a tool
1394 bar exists. */ 1567 bar exists. */
1395 if (NILP (window) 1568 if (NILP (window)
@@ -1402,6 +1575,7 @@ window_from_coordinates (struct frame *f, int x, int y,
1402 *part = ON_TEXT; 1575 *part = ON_TEXT;
1403 window = f->tool_bar_window; 1576 window = f->tool_bar_window;
1404 } 1577 }
1578#endif
1405 1579
1406 return window; 1580 return window;
1407} 1581}
@@ -1443,7 +1617,7 @@ correct to return the top-level value of `point', outside of any
1443 register struct window *w = decode_live_window (window); 1617 register struct window *w = decode_live_window (window);
1444 1618
1445 if (w == XWINDOW (selected_window)) 1619 if (w == XWINDOW (selected_window))
1446 return make_number (BUF_PT (XBUFFER (w->buffer))); 1620 return make_number (BUF_PT (XBUFFER (w->contents)));
1447 else 1621 else
1448 return Fmarker_position (w->pointm); 1622 return Fmarker_position (w->pointm);
1449} 1623}
@@ -1485,16 +1659,19 @@ if it isn't already recorded. */)
1485 Lisp_Object buf; 1659 Lisp_Object buf;
1486 struct buffer *b; 1660 struct buffer *b;
1487 1661
1488 buf = w->buffer; 1662 buf = w->contents;
1489 CHECK_BUFFER (buf); 1663 CHECK_BUFFER (buf);
1490 b = XBUFFER (buf); 1664 b = XBUFFER (buf);
1491 1665
1492 if (! NILP (update) 1666 if (! NILP (update)
1493 && (windows_or_buffers_changed || !w->window_end_valid) 1667 && (windows_or_buffers_changed
1668 || !w->window_end_valid
1669 || b->clip_changed
1670 || b->prevent_redisplay_optimizations_p
1671 || window_outdated (w))
1494 && !noninteractive) 1672 && !noninteractive)
1495 { 1673 {
1496 struct text_pos startp; 1674 struct text_pos startp;
1497 ptrdiff_t charpos = marker_position (w->start);
1498 struct it it; 1675 struct it it;
1499 struct buffer *old_buffer = NULL; 1676 struct buffer *old_buffer = NULL;
1500 void *itdata = NULL; 1677 void *itdata = NULL;
@@ -1512,12 +1689,7 @@ if it isn't already recorded. */)
1512 `-l' containing a call to `rmail' with subsequent other 1689 `-l' containing a call to `rmail' with subsequent other
1513 commands. At the end, W->start happened to be BEG, while 1690 commands. At the end, W->start happened to be BEG, while
1514 rmail had already narrowed the buffer. */ 1691 rmail had already narrowed the buffer. */
1515 if (charpos < BEGV) 1692 CLIP_TEXT_POS_FROM_MARKER (startp, w->start);
1516 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
1517 else if (charpos > ZV)
1518 SET_TEXT_POS (startp, ZV, ZV_BYTE);
1519 else
1520 SET_TEXT_POS_FROM_MARKER (startp, w->start);
1521 1693
1522 itdata = bidi_shelve_cache (); 1694 itdata = bidi_shelve_cache ();
1523 start_display (&it, w, startp); 1695 start_display (&it, w, startp);
@@ -1531,7 +1703,7 @@ if it isn't already recorded. */)
1531 set_buffer_internal (old_buffer); 1703 set_buffer_internal (old_buffer);
1532 } 1704 }
1533 else 1705 else
1534 XSETINT (value, BUF_Z (b) - XFASTINT (w->window_end_pos)); 1706 XSETINT (value, BUF_Z (b) - w->window_end_pos);
1535 1707
1536 return value; 1708 return value;
1537} 1709}
@@ -1548,7 +1720,7 @@ Return POS. */)
1548 1720
1549 if (w == XWINDOW (selected_window)) 1721 if (w == XWINDOW (selected_window))
1550 { 1722 {
1551 if (XBUFFER (w->buffer) == current_buffer) 1723 if (XBUFFER (w->contents) == current_buffer)
1552 Fgoto_char (pos); 1724 Fgoto_char (pos);
1553 else 1725 else
1554 { 1726 {
@@ -1556,17 +1728,17 @@ Return POS. */)
1556 1728
1557 /* ... but here we want to catch type error before buffer change. */ 1729 /* ... but here we want to catch type error before buffer change. */
1558 CHECK_NUMBER_COERCE_MARKER (pos); 1730 CHECK_NUMBER_COERCE_MARKER (pos);
1559 set_buffer_internal (XBUFFER (w->buffer)); 1731 set_buffer_internal (XBUFFER (w->contents));
1560 Fgoto_char (pos); 1732 Fgoto_char (pos);
1561 set_buffer_internal (old_buffer); 1733 set_buffer_internal (old_buffer);
1562 } 1734 }
1563 } 1735 }
1564 else 1736 else
1565 { 1737 {
1566 set_marker_restricted (w->pointm, pos, w->buffer); 1738 set_marker_restricted (w->pointm, pos, w->contents);
1567 /* We have to make sure that redisplay updates the window to show 1739 /* We have to make sure that redisplay updates the window to show
1568 the new value of point. */ 1740 the new value of point. */
1569 ++windows_or_buffers_changed; 1741 wset_redisplay (w);
1570 } 1742 }
1571 1743
1572 return pos; 1744 return pos;
@@ -1581,16 +1753,15 @@ overriding motion of point in order to display at this exact start. */)
1581{ 1753{
1582 register struct window *w = decode_live_window (window); 1754 register struct window *w = decode_live_window (window);
1583 1755
1584 set_marker_restricted (w->start, pos, w->buffer); 1756 set_marker_restricted (w->start, pos, w->contents);
1585 /* This is not right, but much easier than doing what is right. */ 1757 /* This is not right, but much easier than doing what is right. */
1586 w->start_at_line_beg = 0; 1758 w->start_at_line_beg = 0;
1587 if (NILP (noforce)) 1759 if (NILP (noforce))
1588 w->force_start = 1; 1760 w->force_start = 1;
1589 w->update_mode_line = 1; 1761 w->update_mode_line = 1;
1590 w->last_modified = 0; 1762 /* Bug#15957. */
1591 w->last_overlay_modified = 0; 1763 w->window_end_valid = 0;
1592 if (!EQ (window, selected_window)) 1764 wset_redisplay (w);
1593 windows_or_buffers_changed++;
1594 1765
1595 return pos; 1766 return pos;
1596} 1767}
@@ -1608,12 +1779,13 @@ specifies the position of the last visible glyph in WINDOW. POS
1608defaults to point in WINDOW; WINDOW defaults to the selected window. 1779defaults to point in WINDOW; WINDOW defaults to the selected window.
1609 1780
1610If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil, 1781If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
1611return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]), 1782the return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
1612where X and Y are the pixel coordinates relative to the top left corner 1783where X and Y are the pixel coordinates relative to the top left corner
1613of the window. The remaining elements are omitted if the character after 1784of the window. The remaining elements are omitted if the character after
1614POS is fully visible; otherwise, RTOP and RBOT are the number of pixels 1785POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
1615off-window at the top and bottom of the row, ROWH is the height of the 1786off-window at the top and bottom of the screen line ("row") containing
1616display row, and VPOS is the row number (0-based) containing POS. */) 1787POS, ROWH is the visible height of that row, and VPOS is the row number
1788\(zero-based). */)
1617 (Lisp_Object pos, Lisp_Object window, Lisp_Object partially) 1789 (Lisp_Object pos, Lisp_Object window, Lisp_Object partially)
1618{ 1790{
1619 register struct window *w; 1791 register struct window *w;
@@ -1625,7 +1797,7 @@ display row, and VPOS is the row number (0-based) containing POS. */)
1625 int x, y; 1797 int x, y;
1626 1798
1627 w = decode_live_window (window); 1799 w = decode_live_window (window);
1628 buf = XBUFFER (w->buffer); 1800 buf = XBUFFER (w->contents);
1629 SET_TEXT_POS_FROM_MARKER (top, w->start); 1801 SET_TEXT_POS_FROM_MARKER (top, w->start);
1630 1802
1631 if (EQ (pos, Qt)) 1803 if (EQ (pos, Qt))
@@ -1694,15 +1866,15 @@ Return nil if window display is not up-to-date. In that case, use
1694 if (noninteractive || w->pseudo_window_p) 1866 if (noninteractive || w->pseudo_window_p)
1695 return Qnil; 1867 return Qnil;
1696 1868
1697 CHECK_BUFFER (w->buffer); 1869 CHECK_BUFFER (w->contents);
1698 b = XBUFFER (w->buffer); 1870 b = XBUFFER (w->contents);
1699 1871
1700 /* Fail if current matrix is not up-to-date. */ 1872 /* Fail if current matrix is not up-to-date. */
1701 if (!w->window_end_valid 1873 if (!w->window_end_valid
1702 || current_buffer->clip_changed 1874 || windows_or_buffers_changed
1703 || current_buffer->prevent_redisplay_optimizations_p 1875 || b->clip_changed
1704 || w->last_modified < BUF_MODIFF (b) 1876 || b->prevent_redisplay_optimizations_p
1705 || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)) 1877 || window_outdated (w))
1706 return Qnil; 1878 return Qnil;
1707 1879
1708 if (NILP (line)) 1880 if (NILP (line))
@@ -1921,9 +2093,9 @@ window_display_table (struct window *w)
1921 2093
1922 if (DISP_TABLE_P (w->display_table)) 2094 if (DISP_TABLE_P (w->display_table))
1923 dp = XCHAR_TABLE (w->display_table); 2095 dp = XCHAR_TABLE (w->display_table);
1924 else if (BUFFERP (w->buffer)) 2096 else if (BUFFERP (w->contents))
1925 { 2097 {
1926 struct buffer *b = XBUFFER (w->buffer); 2098 struct buffer *b = XBUFFER (w->contents);
1927 2099
1928 if (DISP_TABLE_P (BVAR (b, display_table))) 2100 if (DISP_TABLE_P (BVAR (b, display_table)))
1929 dp = XCHAR_TABLE (BVAR (b, display_table)); 2101 dp = XCHAR_TABLE (BVAR (b, display_table));
@@ -1948,17 +2120,14 @@ WINDOW must be a live window and defaults to the selected one. */)
1948static void 2120static void
1949unshow_buffer (register struct window *w) 2121unshow_buffer (register struct window *w)
1950{ 2122{
1951 Lisp_Object buf; 2123 Lisp_Object buf = w->contents;
1952 struct buffer *b; 2124 struct buffer *b = XBUFFER (buf);
1953 2125
1954 buf = w->buffer; 2126 eassert (b == XMARKER (w->pointm)->buffer);
1955 b = XBUFFER (buf);
1956 if (b != XMARKER (w->pointm)->buffer)
1957 emacs_abort ();
1958 2127
1959#if 0 2128#if 0
1960 if (w == XWINDOW (selected_window) 2129 if (w == XWINDOW (selected_window)
1961 || ! EQ (buf, XWINDOW (selected_window)->buffer)) 2130 || ! EQ (buf, XWINDOW (selected_window)->contents))
1962 /* Do this except when the selected window's buffer 2131 /* Do this except when the selected window's buffer
1963 is being removed from some other window. */ 2132 is being removed from some other window. */
1964#endif 2133#endif
@@ -1974,14 +2143,14 @@ unshow_buffer (register struct window *w)
1974 /* Point in the selected window's buffer 2143 /* Point in the selected window's buffer
1975 is actually stored in that buffer, and the window's pointm isn't used. 2144 is actually stored in that buffer, and the window's pointm isn't used.
1976 So don't clobber point in that buffer. */ 2145 So don't clobber point in that buffer. */
1977 if (! EQ (buf, XWINDOW (selected_window)->buffer) 2146 if (! EQ (buf, XWINDOW (selected_window)->contents)
1978 /* Don't clobber point in current buffer either (this could be 2147 /* Don't clobber point in current buffer either (this could be
1979 useful in connection with bug#12208). 2148 useful in connection with bug#12208).
1980 && XBUFFER (buf) != current_buffer */ 2149 && XBUFFER (buf) != current_buffer */
1981 /* This line helps to fix Horsley's testbug.el bug. */ 2150 /* This line helps to fix Horsley's testbug.el bug. */
1982 && !(WINDOWP (BVAR (b, last_selected_window)) 2151 && !(WINDOWP (BVAR (b, last_selected_window))
1983 && w != XWINDOW (BVAR (b, last_selected_window)) 2152 && w != XWINDOW (BVAR (b, last_selected_window))
1984 && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->buffer))) 2153 && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->contents)))
1985 temp_set_point_both (b, 2154 temp_set_point_both (b,
1986 clip_to_bounds (BUF_BEGV (b), 2155 clip_to_bounds (BUF_BEGV (b),
1987 marker_position (w->pointm), 2156 marker_position (w->pointm),
@@ -2009,12 +2178,16 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
2009 if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame)))) 2178 if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame))))
2010 fset_root_window (XFRAME (o->frame), new); 2179 fset_root_window (XFRAME (o->frame), new);
2011 2180
2012 if (setflag) 2181 if (setflag)
2013 { 2182 {
2014 wset_left_col (n, o->left_col); 2183 n->pixel_left = o->pixel_left;
2015 wset_top_line (n, o->top_line); 2184 n->pixel_top = o->pixel_top;
2016 wset_total_cols (n, o->total_cols); 2185 n->pixel_width = o->pixel_width;
2017 wset_total_lines (n, o->total_lines); 2186 n->pixel_height = o->pixel_height;
2187 n->left_col = o->left_col;
2188 n->top_line = o->top_line;
2189 n->total_cols = o->total_cols;
2190 n->total_lines = o->total_lines;
2018 wset_normal_cols (n, o->normal_cols); 2191 wset_normal_cols (n, o->normal_cols);
2019 wset_normal_cols (o, make_float (1.0)); 2192 wset_normal_cols (o, make_float (1.0));
2020 wset_normal_lines (n, o->normal_lines); 2193 wset_normal_lines (n, o->normal_lines);
@@ -2022,16 +2195,17 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
2022 n->desired_matrix = n->current_matrix = 0; 2195 n->desired_matrix = n->current_matrix = 0;
2023 n->vscroll = 0; 2196 n->vscroll = 0;
2024 memset (&n->cursor, 0, sizeof (n->cursor)); 2197 memset (&n->cursor, 0, sizeof (n->cursor));
2025 memset (&n->last_cursor, 0, sizeof (n->last_cursor));
2026 memset (&n->phys_cursor, 0, sizeof (n->phys_cursor)); 2198 memset (&n->phys_cursor, 0, sizeof (n->phys_cursor));
2027 n->phys_cursor_type = -1; 2199 n->last_cursor_vpos = 0;
2200#ifdef HAVE_WINDOW_SYSTEM
2201 n->phys_cursor_type = NO_CURSOR;
2028 n->phys_cursor_width = -1; 2202 n->phys_cursor_width = -1;
2203#endif
2029 n->must_be_updated_p = 0; 2204 n->must_be_updated_p = 0;
2030 n->pseudo_window_p = 0; 2205 n->pseudo_window_p = 0;
2031 wset_window_end_vpos (n, make_number (0)); 2206 n->window_end_vpos = 0;
2032 wset_window_end_pos (n, make_number (0)); 2207 n->window_end_pos = 0;
2033 n->window_end_valid = 0; 2208 n->window_end_valid = 0;
2034 n->frozen_window_start_p = 0;
2035 } 2209 }
2036 2210
2037 tem = o->next; 2211 tem = o->next;
@@ -2046,13 +2220,8 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
2046 2220
2047 tem = o->parent; 2221 tem = o->parent;
2048 wset_parent (n, tem); 2222 wset_parent (n, tem);
2049 if (!NILP (tem)) 2223 if (!NILP (tem) && EQ (XWINDOW (tem)->contents, old))
2050 { 2224 wset_combination (XWINDOW (tem), XWINDOW (tem)->horizontal, new);
2051 if (EQ (XWINDOW (tem)->vchild, old))
2052 wset_vchild (XWINDOW (tem), new);
2053 if (EQ (XWINDOW (tem)->hchild, old))
2054 wset_hchild (XWINDOW (tem), new);
2055 }
2056} 2225}
2057 2226
2058/* If window WINDOW and its parent window are iso-combined, merge 2227/* If window WINDOW and its parent window are iso-combined, merge
@@ -2064,29 +2233,26 @@ recombine_windows (Lisp_Object window)
2064{ 2233{
2065 struct window *w, *p, *c; 2234 struct window *w, *p, *c;
2066 Lisp_Object parent, child; 2235 Lisp_Object parent, child;
2067 int horflag; 2236 bool horflag;
2068 2237
2069 w = XWINDOW (window); 2238 w = XWINDOW (window);
2070 parent = w->parent; 2239 parent = w->parent;
2071 if (!NILP (parent) && NILP (w->combination_limit)) 2240 if (!NILP (parent) && NILP (w->combination_limit))
2072 { 2241 {
2073 p = XWINDOW (parent); 2242 p = XWINDOW (parent);
2074 if (((!NILP (p->vchild) && !NILP (w->vchild)) 2243 if (WINDOWP (p->contents) && WINDOWP (w->contents)
2075 || (!NILP (p->hchild) && !NILP (w->hchild)))) 2244 && p->horizontal == w->horizontal)
2076 /* WINDOW and PARENT are both either a vertical or a horizontal 2245 /* WINDOW and PARENT are both either a vertical or a horizontal
2077 combination. */ 2246 combination. */
2078 { 2247 {
2079 horflag = NILP (w->vchild); 2248 horflag = WINDOW_HORIZONTAL_COMBINATION_P (w);
2080 child = horflag ? w->hchild : w->vchild; 2249 child = w->contents;
2081 c = XWINDOW (child); 2250 c = XWINDOW (child);
2082 2251
2083 /* Splice WINDOW's children into its parent's children and 2252 /* Splice WINDOW's children into its parent's children and
2084 assign new normal sizes. */ 2253 assign new normal sizes. */
2085 if (NILP (w->prev)) 2254 if (NILP (w->prev))
2086 if (horflag) 2255 wset_combination (p, horflag, child);
2087 wset_hchild (p, child);
2088 else
2089 wset_vchild (p, child);
2090 else 2256 else
2091 { 2257 {
2092 wset_prev (c, w->prev); 2258 wset_prev (c, w->prev);
@@ -2098,13 +2264,13 @@ recombine_windows (Lisp_Object window)
2098 wset_parent (c, parent); 2264 wset_parent (c, parent);
2099 2265
2100 if (horflag) 2266 if (horflag)
2101 wset_normal_cols (c, 2267 wset_normal_cols
2102 make_float (XFLOATINT (c->total_cols) 2268 (c, make_float ((double) c->pixel_width
2103 / XFLOATINT (p->total_cols))); 2269 / (double) p->pixel_width));
2104 else 2270 else
2105 wset_normal_lines (c, 2271 wset_normal_lines
2106 make_float (XFLOATINT (c->total_lines) 2272 (c, make_float ((double) c->pixel_height
2107 / XFLOATINT (p->total_lines))); 2273 / (double) p->pixel_height));
2108 2274
2109 if (NILP (c->next)) 2275 if (NILP (c->next))
2110 { 2276 {
@@ -2124,8 +2290,7 @@ recombine_windows (Lisp_Object window)
2124 } 2290 }
2125 2291
2126 /* WINDOW can be deleted now. */ 2292 /* WINDOW can be deleted now. */
2127 wset_vchild (w, Qnil); 2293 wset_combination (w, 0, Qnil);
2128 wset_hchild (w, Qnil);
2129 } 2294 }
2130 } 2295 }
2131} 2296}
@@ -2149,7 +2314,7 @@ delete_deletable_window (Lisp_Object window)
2149static int 2314static int
2150add_window_to_list (struct window *w, void *user_data) 2315add_window_to_list (struct window *w, void *user_data)
2151{ 2316{
2152 Lisp_Object *list = (Lisp_Object *) user_data; 2317 Lisp_Object *list = user_data;
2153 Lisp_Object window; 2318 Lisp_Object window;
2154 XSETWINDOW (window, w); 2319 XSETWINDOW (window, w);
2155 *list = Fcons (window, *list); 2320 *list = Fcons (window, *list);
@@ -2161,7 +2326,7 @@ add_window_to_list (struct window *w, void *user_data)
2161 Vwindow_list is a list, return that list. Otherwise, build a new 2326 Vwindow_list is a list, return that list. Otherwise, build a new
2162 list, cache it in Vwindow_list, and return that. */ 2327 list, cache it in Vwindow_list, and return that. */
2163 2328
2164static Lisp_Object 2329Lisp_Object
2165window_list (void) 2330window_list (void)
2166{ 2331{
2167 if (!CONSP (Vwindow_list)) 2332 if (!CONSP (Vwindow_list))
@@ -2204,14 +2369,15 @@ window_list (void)
2204 a window means search the frame that window belongs to, 2369 a window means search the frame that window belongs to,
2205 a frame means consider windows on that frame, only. */ 2370 a frame means consider windows on that frame, only. */
2206 2371
2207static int 2372static bool
2208candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf, Lisp_Object all_frames) 2373candidate_window_p (Lisp_Object window, Lisp_Object owindow,
2374 Lisp_Object minibuf, Lisp_Object all_frames)
2209{ 2375{
2210 struct window *w = XWINDOW (window); 2376 struct window *w = XWINDOW (window);
2211 struct frame *f = XFRAME (w->frame); 2377 struct frame *f = XFRAME (w->frame);
2212 int candidate_p = 1; 2378 bool candidate_p = 1;
2213 2379
2214 if (!BUFFERP (w->buffer)) 2380 if (!BUFFERP (w->contents))
2215 candidate_p = 0; 2381 candidate_p = 0;
2216 else if (MINI_WINDOW_P (w) 2382 else if (MINI_WINDOW_P (w)
2217 && (EQ (minibuf, Qlambda) 2383 && (EQ (minibuf, Qlambda)
@@ -2551,7 +2717,7 @@ enum window_loop
2551 GET_BUFFER_WINDOW, /* Arg is buffer */ 2717 GET_BUFFER_WINDOW, /* Arg is buffer */
2552 REPLACE_BUFFER_IN_WINDOWS_SAFELY, /* Arg is buffer */ 2718 REPLACE_BUFFER_IN_WINDOWS_SAFELY, /* Arg is buffer */
2553 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */ 2719 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
2554 CHECK_ALL_WINDOWS 2720 CHECK_ALL_WINDOWS /* Arg is ignored */
2555}; 2721};
2556 2722
2557static Lisp_Object 2723static Lisp_Object
@@ -2615,7 +2781,7 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2615 switch (type) 2781 switch (type)
2616 { 2782 {
2617 case GET_BUFFER_WINDOW: 2783 case GET_BUFFER_WINDOW:
2618 if (EQ (w->buffer, obj) 2784 if (EQ (w->contents, obj)
2619 /* Don't find any minibuffer window except the one that 2785 /* Don't find any minibuffer window except the one that
2620 is currently in use. */ 2786 is currently in use. */
2621 && (MINI_WINDOW_P (w) ? EQ (window, minibuf_window) : 1)) 2787 && (MINI_WINDOW_P (w) ? EQ (window, minibuf_window) : 1))
@@ -2639,39 +2805,48 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2639 case REPLACE_BUFFER_IN_WINDOWS_SAFELY: 2805 case REPLACE_BUFFER_IN_WINDOWS_SAFELY:
2640 /* We could simply check whether the buffer shown by window 2806 /* We could simply check whether the buffer shown by window
2641 is live, and show another buffer in case it isn't. */ 2807 is live, and show another buffer in case it isn't. */
2642 if (EQ (w->buffer, obj)) 2808 if (EQ (w->contents, obj))
2643 { 2809 {
2644 /* Undedicate WINDOW. */ 2810 /* Undedicate WINDOW. */
2645 wset_dedicated (w, Qnil); 2811 wset_dedicated (w, Qnil);
2646 /* Make WINDOW show the buffer returned by 2812 /* Make WINDOW show the buffer returned by
2647 other_buffer_safely, don't run any hooks. */ 2813 other_buffer_safely, don't run any hooks. */
2648 set_window_buffer 2814 set_window_buffer
2649 (window, other_buffer_safely (w->buffer), 0, 0); 2815 (window, other_buffer_safely (w->contents), 0, 0);
2650 /* If WINDOW is the selected window, make its buffer 2816 /* If WINDOW is the selected window, make its buffer
2651 current. But do so only if the window shows the 2817 current. But do so only if the window shows the
2652 current buffer (Bug#6454). */ 2818 current buffer (Bug#6454). */
2653 if (EQ (window, selected_window) 2819 if (EQ (window, selected_window)
2654 && XBUFFER (w->buffer) == current_buffer) 2820 && XBUFFER (w->contents) == current_buffer)
2655 Fset_buffer (w->buffer); 2821 Fset_buffer (w->contents);
2656 } 2822 }
2657 break; 2823 break;
2658 2824
2659 case REDISPLAY_BUFFER_WINDOWS: 2825 case REDISPLAY_BUFFER_WINDOWS:
2660 if (EQ (w->buffer, obj)) 2826 if (EQ (w->contents, obj))
2661 { 2827 {
2662 mark_window_display_accurate (window, 0); 2828 mark_window_display_accurate (window, 0);
2663 w->update_mode_line = 1; 2829 w->update_mode_line = 1;
2664 XBUFFER (obj)->prevent_redisplay_optimizations_p = 1; 2830 XBUFFER (obj)->prevent_redisplay_optimizations_p = 1;
2665 ++update_mode_lines; 2831 update_mode_lines = 27;
2666 best_window = window; 2832 best_window = window;
2667 } 2833 }
2668 break; 2834 break;
2669 2835
2670 /* Check for a window that has a killed buffer. */ 2836 /* Check for a leaf window that has a killed buffer
2837 or broken markers. */
2671 case CHECK_ALL_WINDOWS: 2838 case CHECK_ALL_WINDOWS:
2672 if (! NILP (w->buffer) 2839 if (BUFFERP (w->contents))
2673 && !BUFFER_LIVE_P (XBUFFER (w->buffer))) 2840 {
2674 emacs_abort (); 2841 struct buffer *b = XBUFFER (w->contents);
2842
2843 if (!BUFFER_LIVE_P (b))
2844 emacs_abort ();
2845 if (!MARKERP (w->start) || XMARKER (w->start)->buffer != b)
2846 emacs_abort ();
2847 if (!MARKERP (w->pointm) || XMARKER (w->pointm)->buffer != b)
2848 emacs_abort ();
2849 }
2675 break; 2850 break;
2676 2851
2677 case WINDOW_LOOP_UNUSED: 2852 case WINDOW_LOOP_UNUSED:
@@ -2726,9 +2901,16 @@ selected frame and no others. */)
2726} 2901}
2727 2902
2728static Lisp_Object 2903static Lisp_Object
2729resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore) 2904resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore, Lisp_Object pixelwise)
2730{ 2905{
2731 return call4 (Qwindow_resize_root_window, window, delta, horizontal, ignore); 2906 return call5 (Qwindow_resize_root_window, window, delta, horizontal, ignore, pixelwise);
2907}
2908
2909
2910static Lisp_Object
2911window_pixel_to_total (Lisp_Object frame, Lisp_Object horizontal)
2912{
2913 return call2(Qwindow_pixel_to_total, frame, horizontal);
2732} 2914}
2733 2915
2734 2916
@@ -2752,7 +2934,7 @@ window-start value is reasonable when this function is called. */)
2752 struct window *w, *r, *s; 2934 struct window *w, *r, *s;
2753 struct frame *f; 2935 struct frame *f;
2754 Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta; 2936 Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta;
2755 ptrdiff_t startpos IF_LINT (= 0); 2937 ptrdiff_t startpos IF_LINT (= 0), startbyte IF_LINT (= 0);
2756 int top IF_LINT (= 0), new_top, resize_failed; 2938 int top IF_LINT (= 0), new_top, resize_failed;
2757 2939
2758 w = decode_valid_window (window); 2940 w = decode_valid_window (window);
@@ -2788,11 +2970,12 @@ window-start value is reasonable when this function is called. */)
2788 else if (MINI_WINDOW_P (w)) /* && top > 0) */ 2970 else if (MINI_WINDOW_P (w)) /* && top > 0) */
2789 error ("Can't expand minibuffer to full frame"); 2971 error ("Can't expand minibuffer to full frame");
2790 2972
2791 if (!NILP (w->buffer)) 2973 if (BUFFERP (w->contents))
2792 { 2974 {
2793 startpos = marker_position (w->start); 2975 startpos = marker_position (w->start);
2794 top = WINDOW_TOP_EDGE_LINE (w) 2976 startbyte = marker_byte_position (w->start);
2795 - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); 2977 top = (WINDOW_TOP_EDGE_LINE (w)
2978 - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))));
2796 /* Make sure WINDOW is the frame's selected window. */ 2979 /* Make sure WINDOW is the frame's selected window. */
2797 if (!EQ (window, FRAME_SELECTED_WINDOW (f))) 2980 if (!EQ (window, FRAME_SELECTED_WINDOW (f)))
2798 { 2981 {
@@ -2836,7 +3019,7 @@ window-start value is reasonable when this function is called. */)
2836 block_input (); 3019 block_input ();
2837 if (!FRAME_INITIAL_P (f)) 3020 if (!FRAME_INITIAL_P (f))
2838 { 3021 {
2839 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); 3022 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
2840 3023
2841 /* We are going to free the glyph matrices of WINDOW, and with 3024 /* We are going to free the glyph matrices of WINDOW, and with
2842 that we might lose any information about glyph rows that have 3025 that we might lose any information about glyph rows that have
@@ -2846,33 +3029,35 @@ window-start value is reasonable when this function is called. */)
2846 frame's up-to-date hook that mouse highlight was overwritten, 3029 frame's up-to-date hook that mouse highlight was overwritten,
2847 so that it will arrange for redisplaying the highlight. */ 3030 so that it will arrange for redisplaying the highlight. */
2848 if (EQ (hlinfo->mouse_face_window, window)) 3031 if (EQ (hlinfo->mouse_face_window, window))
2849 { 3032 reset_mouse_highlight (hlinfo);
2850 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
2851 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
2852 hlinfo->mouse_face_window = Qnil;
2853 }
2854 } 3033 }
2855 free_window_matrices (r); 3034 free_window_matrices (r);
2856 3035
2857 windows_or_buffers_changed++; 3036 fset_redisplay (f);
2858 Vwindow_list = Qnil; 3037 Vwindow_list = Qnil;
2859 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 3038 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
2860 resize_failed = 0; 3039 resize_failed = 0;
2861 3040
2862 if (NILP (w->buffer)) 3041 if (!WINDOW_LEAF_P (w))
2863 { 3042 {
2864 /* Resize child windows vertically. */ 3043 /* Resize child windows vertically. */
2865 XSETINT (delta, XINT (r->total_lines) 3044 XSETINT (delta, r->pixel_height - w->pixel_height);
2866 - XINT (w->total_lines)); 3045 w->pixel_top = r->pixel_top;
2867 wset_top_line (w, r->top_line); 3046 w->top_line = r->top_line;
2868 resize_root_window (window, delta, Qnil, Qnil); 3047 resize_root_window (window, delta, Qnil, Qnil, Qt);
2869 if (window_resize_check (w, 0)) 3048 if (window_resize_check (w, 0))
2870 window_resize_apply (w, 0); 3049 {
3050 window_resize_apply (w, 0);
3051 window_pixel_to_total (w->frame, Qnil);
3052 }
2871 else 3053 else
2872 { 3054 {
2873 resize_root_window (window, delta, Qnil, Qt); 3055 resize_root_window (window, delta, Qnil, Qt, Qt);
2874 if (window_resize_check (w, 0)) 3056 if (window_resize_check (w, 0))
2875 window_resize_apply (w, 0); 3057 {
3058 window_resize_apply (w, 0);
3059 window_pixel_to_total (w->frame, Qnil);
3060 }
2876 else 3061 else
2877 resize_failed = 1; 3062 resize_failed = 1;
2878 } 3063 }
@@ -2880,18 +3065,23 @@ window-start value is reasonable when this function is called. */)
2880 /* Resize child windows horizontally. */ 3065 /* Resize child windows horizontally. */
2881 if (!resize_failed) 3066 if (!resize_failed)
2882 { 3067 {
2883 wset_left_col (w, r->left_col); 3068 w->left_col = r->left_col;
2884 XSETINT (delta, 3069 w->pixel_left = r->pixel_left;
2885 XINT (r->total_cols) - XINT (w->total_cols)); 3070 XSETINT (delta, r->pixel_width - w->pixel_width);
2886 wset_left_col (w, r->left_col); 3071 resize_root_window (window, delta, Qt, Qnil, Qt);
2887 resize_root_window (window, delta, Qt, Qnil);
2888 if (window_resize_check (w, 1)) 3072 if (window_resize_check (w, 1))
2889 window_resize_apply (w, 1); 3073 {
3074 window_resize_apply (w, 1);
3075 window_pixel_to_total (w->frame, Qt);
3076 }
2890 else 3077 else
2891 { 3078 {
2892 resize_root_window (window, delta, Qt, Qt); 3079 resize_root_window (window, delta, Qt, Qt, Qt);
2893 if (window_resize_check (w, 1)) 3080 if (window_resize_check (w, 1))
2894 window_resize_apply (w, 1); 3081 {
3082 window_resize_apply (w, 1);
3083 window_pixel_to_total (w->frame, Qt);
3084 }
2895 else 3085 else
2896 resize_failed = 1; 3086 resize_failed = 1;
2897 } 3087 }
@@ -2921,28 +3111,21 @@ window-start value is reasonable when this function is called. */)
2921 sibling = w->next; 3111 sibling = w->next;
2922 s = XWINDOW (sibling); 3112 s = XWINDOW (sibling);
2923 wset_prev (s, Qnil); 3113 wset_prev (s, Qnil);
2924 if (!NILP (XWINDOW (w->parent)->vchild)) 3114 wset_combination (XWINDOW (w->parent),
2925 wset_vchild (XWINDOW (w->parent), sibling); 3115 XWINDOW (w->parent)->horizontal, sibling);
2926 else
2927 wset_hchild (XWINDOW (w->parent), sibling);
2928 } 3116 }
2929 3117
2930 /* Delete ROOT and all child windows of ROOT. */ 3118 /* Delete ROOT and all child windows of ROOT. */
2931 if (!NILP (r->vchild)) 3119 if (WINDOWP (r->contents))
2932 { 3120 {
2933 delete_all_child_windows (r->vchild); 3121 delete_all_child_windows (r->contents);
2934 wset_vchild (r, Qnil); 3122 wset_combination (r, 0, Qnil);
2935 }
2936 else if (!NILP (r->hchild))
2937 {
2938 delete_all_child_windows (r->hchild);
2939 wset_hchild (r, Qnil);
2940 } 3123 }
2941 3124
2942 replace_window (root, window, 1); 3125 replace_window (root, window, 1);
2943 3126
2944 /* This must become SWINDOW anyway ....... */ 3127 /* This must become SWINDOW anyway ....... */
2945 if (!NILP (w->buffer) && !resize_failed) 3128 if (BUFFERP (w->contents) && !resize_failed)
2946 { 3129 {
2947 /* Try to minimize scrolling, by setting the window start to the 3130 /* Try to minimize scrolling, by setting the window start to the
2948 point will cause the text at the old window start to be at the 3131 point will cause the text at the old window start to be at the
@@ -2951,18 +3134,18 @@ window-start value is reasonable when this function is called. */)
2951 when the display is not current, due to typeahead). */ 3134 when the display is not current, due to typeahead). */
2952 new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); 3135 new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
2953 if (new_top != top 3136 if (new_top != top
2954 && startpos >= BUF_BEGV (XBUFFER (w->buffer)) 3137 && startpos >= BUF_BEGV (XBUFFER (w->contents))
2955 && startpos <= BUF_ZV (XBUFFER (w->buffer))) 3138 && startpos <= BUF_ZV (XBUFFER (w->contents)))
2956 { 3139 {
2957 struct position pos; 3140 struct position pos;
2958 struct buffer *obuf = current_buffer; 3141 struct buffer *obuf = current_buffer;
2959 3142
2960 Fset_buffer (w->buffer); 3143 Fset_buffer (w->contents);
2961 /* This computation used to temporarily move point, but that 3144 /* This computation used to temporarily move point, but that
2962 can have unwanted side effects due to text properties. */ 3145 can have unwanted side effects due to text properties. */
2963 pos = *vmotion (startpos, -top, w); 3146 pos = *vmotion (startpos, startbyte, -top, w);
2964 3147
2965 set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos); 3148 set_marker_both (w->start, w->contents, pos.bufpos, pos.bytepos);
2966 w->window_end_valid = 0; 3149 w->window_end_valid = 0;
2967 w->start_at_line_beg = (pos.bytepos == BEGV_BYTE 3150 w->start_at_line_beg = (pos.bytepos == BEGV_BYTE
2968 || FETCH_BYTE (pos.bytepos - 1) == '\n'); 3151 || FETCH_BYTE (pos.bytepos - 1) == '\n');
@@ -2974,7 +3157,7 @@ window-start value is reasonable when this function is called. */)
2974 } 3157 }
2975 } 3158 }
2976 3159
2977 adjust_glyphs (f); 3160 adjust_frame_glyphs (f);
2978 unblock_input (); 3161 unblock_input ();
2979 3162
2980 run_window_configuration_change_hook (f); 3163 run_window_configuration_change_hook (f);
@@ -3007,27 +3190,47 @@ replace_buffer_in_windows_safely (Lisp_Object buffer)
3007 } 3190 }
3008} 3191}
3009 3192
3010/* If *ROWS or *COLS are too small a size for FRAME, set them to the 3193/* If *HEIGHT or *WIDTH are too small a size for FRAME, set them to the
3011 minimum allowable size. */ 3194 minimum allowable size. PIXELWISE means interpret these as pixel
3195 sizes. */
3012 3196
3013void 3197void
3014check_frame_size (FRAME_PTR frame, int *rows, int *cols) 3198check_frame_size (struct frame *frame, int *width, int *height, bool pixelwise)
3015{ 3199{
3016 /* For height, we have to see: 3200 /* For height, we have to see:
3017 how many windows the frame has at minimum (one or two), 3201 how many windows the frame has at minimum (one or two),
3018 and whether it has a menu bar or other special stuff at the top. */ 3202 and whether it has a menu bar or other special stuff at the top. */
3019 int min_height 3203 if (pixelwise)
3020 = ((FRAME_MINIBUF_ONLY_P (frame) || ! FRAME_HAS_MINIBUF_P (frame)) 3204 {
3021 ? MIN_SAFE_WINDOW_HEIGHT 3205 int min_height = MIN_SAFE_WINDOW_HEIGHT * FRAME_LINE_HEIGHT (frame);
3022 : 2 * MIN_SAFE_WINDOW_HEIGHT); 3206 int min_width = MIN_SAFE_WINDOW_WIDTH * FRAME_COLUMN_WIDTH (frame);
3207
3208 if (!FRAME_MINIBUF_ONLY_P (frame) && FRAME_HAS_MINIBUF_P (frame))
3209 min_height = 2 * min_height;
3023 3210
3024 if (FRAME_TOP_MARGIN (frame) > 0) 3211 min_height += FRAME_TOP_MARGIN_HEIGHT (frame);
3025 min_height += FRAME_TOP_MARGIN (frame); 3212 min_height += FRAME_INTERNAL_BORDER_WIDTH (frame);
3026 3213
3027 if (*rows < min_height) 3214 if (*height < min_height)
3028 *rows = min_height; 3215 *height = min_height;
3029 if (*cols < MIN_SAFE_WINDOW_WIDTH) 3216 if (*width < min_width)
3030 *cols = MIN_SAFE_WINDOW_WIDTH; 3217 *width = min_width;
3218 }
3219 else
3220 {
3221 int min_height
3222 = ((FRAME_MINIBUF_ONLY_P (frame) || ! FRAME_HAS_MINIBUF_P (frame))
3223 ? MIN_SAFE_WINDOW_HEIGHT
3224 : 2 * MIN_SAFE_WINDOW_HEIGHT);
3225
3226 if (FRAME_TOP_MARGIN (frame) > 0)
3227 min_height += FRAME_TOP_MARGIN (frame);
3228
3229 if (*height < min_height)
3230 *height = min_height;
3231 if (*width < MIN_SAFE_WINDOW_WIDTH)
3232 *width = MIN_SAFE_WINDOW_WIDTH;
3233 }
3031} 3234}
3032 3235
3033/* Adjust the margins of window W if text area is too small. 3236/* Adjust the margins of window W if text area is too small.
@@ -3037,34 +3240,37 @@ check_frame_size (FRAME_PTR frame, int *rows, int *cols)
3037static int 3240static int
3038adjust_window_margins (struct window *w) 3241adjust_window_margins (struct window *w)
3039{ 3242{
3040 int box_cols = (WINDOW_TOTAL_COLS (w) 3243 int box_width = (WINDOW_PIXEL_WIDTH (w)
3041 - WINDOW_FRINGE_COLS (w) 3244 - WINDOW_FRINGES_WIDTH (w)
3042 - WINDOW_SCROLL_BAR_COLS (w)); 3245 - WINDOW_SCROLL_BAR_AREA_WIDTH (w));
3043 int margin_cols = (WINDOW_LEFT_MARGIN_COLS (w) 3246 int margin_width = WINDOW_MARGINS_WIDTH (w);
3044 + WINDOW_RIGHT_MARGIN_COLS (w));
3045 3247
3046 if (box_cols - margin_cols >= MIN_SAFE_WINDOW_WIDTH) 3248 if (box_width - margin_width >= MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
3047 return 1; 3249 return 1;
3048 3250
3049 if (margin_cols < 0 || box_cols < MIN_SAFE_WINDOW_WIDTH) 3251 if (margin_width < 0 || box_width < MIN_SAFE_WINDOW_PIXEL_WIDTH (w))
3050 return 0; 3252 return 0;
3051 3253 else
3052 /* Window's text area is too narrow, but reducing the window 3254 /* Window's text area is too narrow, but reducing the window
3053 margins will fix that. */ 3255 margins will fix that. */
3054 margin_cols = box_cols - MIN_SAFE_WINDOW_WIDTH;
3055 if (WINDOW_RIGHT_MARGIN_COLS (w) > 0)
3056 { 3256 {
3057 if (WINDOW_LEFT_MARGIN_COLS (w) > 0) 3257 int unit = WINDOW_FRAME_COLUMN_WIDTH (w);
3258
3259 margin_width = box_width - MIN_SAFE_WINDOW_PIXEL_WIDTH (w);
3260
3261 if (WINDOW_RIGHT_MARGIN_WIDTH (w) > 0)
3058 { 3262 {
3059 wset_left_margin_cols (w, make_number (margin_cols / 2)); 3263 if (WINDOW_LEFT_MARGIN_WIDTH (w) > 0)
3060 wset_right_margin_cols (w, make_number (margin_cols / 2)); 3264 w->left_margin_cols = w->right_margin_cols =
3265 margin_width / (2 * unit);
3266 else
3267 w->right_margin_cols = margin_width / unit;
3061 } 3268 }
3062 else 3269 else
3063 wset_right_margin_cols (w, make_number (margin_cols)); 3270 w->left_margin_cols = margin_width / unit;
3271
3272 return 1;
3064 } 3273 }
3065 else
3066 wset_left_margin_cols (w, make_number (margin_cols));
3067 return 1;
3068} 3274}
3069 3275
3070/* The following three routines are needed for running a window's 3276/* The following three routines are needed for running a window's
@@ -3077,18 +3283,18 @@ run_funs (Lisp_Object funs)
3077 call0 (XCAR (funs)); 3283 call0 (XCAR (funs));
3078} 3284}
3079 3285
3080static Lisp_Object 3286static void
3081select_window_norecord (Lisp_Object window) 3287select_window_norecord (Lisp_Object window)
3082{ 3288{
3083 return WINDOW_LIVE_P (window) 3289 if (WINDOW_LIVE_P (window))
3084 ? Fselect_window (window, Qt) : selected_window; 3290 Fselect_window (window, Qt);
3085} 3291}
3086 3292
3087static Lisp_Object 3293static void
3088select_frame_norecord (Lisp_Object frame) 3294select_frame_norecord (Lisp_Object frame)
3089{ 3295{
3090 return FRAME_LIVE_P (XFRAME (frame)) 3296 if (FRAME_LIVE_P (XFRAME (frame)))
3091 ? Fselect_frame (frame, Qt) : selected_frame; 3297 Fselect_frame (frame, Qt);
3092} 3298}
3093 3299
3094void 3300void
@@ -3111,7 +3317,7 @@ run_window_configuration_change_hook (struct frame *f)
3111 3317
3112 if (SELECTED_FRAME () != f) 3318 if (SELECTED_FRAME () != f)
3113 { 3319 {
3114 record_unwind_protect (select_frame_norecord, Fselected_frame ()); 3320 record_unwind_protect (select_frame_norecord, selected_frame);
3115 select_frame_norecord (frame); 3321 select_frame_norecord (frame);
3116 } 3322 }
3117 3323
@@ -3126,7 +3332,7 @@ run_window_configuration_change_hook (struct frame *f)
3126 buffer))) 3332 buffer)))
3127 { 3333 {
3128 ptrdiff_t inner_count = SPECPDL_INDEX (); 3334 ptrdiff_t inner_count = SPECPDL_INDEX ();
3129 record_unwind_protect (select_window_norecord, Fselected_window ()); 3335 record_unwind_protect (select_window_norecord, selected_window);
3130 select_window_norecord (window); 3336 select_window_norecord (window);
3131 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook, 3337 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
3132 buffer)); 3338 buffer));
@@ -3149,19 +3355,32 @@ If FRAME is omitted or nil, it defaults to the selected frame. */)
3149 return Qnil; 3355 return Qnil;
3150} 3356}
3151 3357
3152/* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero 3358DEFUN ("run-window-scroll-functions", Frun_window_scroll_functions,
3153 means it's allowed to run hooks. See make_frame for a case where 3359 Srun_window_scroll_functions, 0, 1, 0,
3154 it's not allowed. KEEP_MARGINS_P non-zero means that the current 3360 doc: /* Run `window-scroll-functions' for WINDOW.
3155 margins, fringes, and scroll-bar settings of the window are not 3361If WINDOW is omitted or nil, it defaults to the selected window. */)
3156 reset from the buffer's local settings. */ 3362 (Lisp_Object window)
3363{
3364 if (! NILP (Vwindow_scroll_functions))
3365 run_hook_with_args_2 (Qwindow_scroll_functions, window,
3366 Fmarker_position (decode_live_window (window)->start));
3367 return Qnil;
3368}
3369
3370/* Make WINDOW display BUFFER. RUN_HOOKS_P non-zero means it's allowed
3371 to run hooks. See make_frame for a case where it's not allowed.
3372 KEEP_MARGINS_P non-zero means that the current margins, fringes, and
3373 scroll-bar settings of the window are not reset from the buffer's
3374 local settings. */
3157 3375
3158void 3376void
3159set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int keep_margins_p) 3377set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3378 bool run_hooks_p, bool keep_margins_p)
3160{ 3379{
3161 struct window *w = XWINDOW (window); 3380 struct window *w = XWINDOW (window);
3162 struct buffer *b = XBUFFER (buffer); 3381 struct buffer *b = XBUFFER (buffer);
3163 ptrdiff_t count = SPECPDL_INDEX (); 3382 ptrdiff_t count = SPECPDL_INDEX ();
3164 int samebuf = EQ (buffer, w->buffer); 3383 bool samebuf = EQ (buffer, w->contents);
3165 3384
3166 wset_buffer (w, buffer); 3385 wset_buffer (w, buffer);
3167 3386
@@ -3176,9 +3395,9 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
3176 bset_display_count (b, make_number (XINT (BVAR (b, display_count)) + 1)); 3395 bset_display_count (b, make_number (XINT (BVAR (b, display_count)) + 1));
3177 bset_display_time (b, Fcurrent_time ()); 3396 bset_display_time (b, Fcurrent_time ());
3178 3397
3179 wset_window_end_pos (w, make_number (0)); 3398 w->window_end_pos = 0;
3180 wset_window_end_vpos (w, make_number (0)); 3399 w->window_end_vpos = 0;
3181 memset (&w->last_cursor, 0, sizeof w->last_cursor); 3400 w->last_cursor_vpos = 0;
3182 3401
3183 if (!(keep_margins_p && samebuf)) 3402 if (!(keep_margins_p && samebuf))
3184 { /* If we're not actually changing the buffer, don't reset hscroll and 3403 { /* If we're not actually changing the buffer, don't reset hscroll and
@@ -3197,12 +3416,11 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
3197 buffer); 3416 buffer);
3198 w->start_at_line_beg = 0; 3417 w->start_at_line_beg = 0;
3199 w->force_start = 0; 3418 w->force_start = 0;
3200 w->last_modified = 0;
3201 w->last_overlay_modified = 0;
3202 } 3419 }
3203 /* Maybe we could move this into the `if' but it's not obviously safe and 3420 /* Maybe we could move this into the `if' but it's not obviously safe and
3204 I doubt it's worth the trouble. */ 3421 I doubt it's worth the trouble. */
3205 windows_or_buffers_changed++; 3422 wset_redisplay (w);
3423 w->update_mode_line = true;
3206 3424
3207 /* We must select BUFFER for running the window-scroll-functions. */ 3425 /* We must select BUFFER for running the window-scroll-functions. */
3208 /* We can't check ! NILP (Vwindow_scroll_functions) here 3426 /* We can't check ! NILP (Vwindow_scroll_functions) here
@@ -3218,28 +3436,14 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
3218 if (!keep_margins_p) 3436 if (!keep_margins_p)
3219 { 3437 {
3220 /* Set left and right marginal area width etc. from buffer. */ 3438 /* Set left and right marginal area width etc. from buffer. */
3221 3439 set_window_fringes (w, BVAR (b, left_fringe_width),
3222 /* This may call adjust_window_margins three times, so 3440 BVAR (b, right_fringe_width),
3223 temporarily disable window margins. */ 3441 BVAR (b, fringes_outside_margins));
3224 Lisp_Object save_left = w->left_margin_cols; 3442 set_window_scroll_bars (w, BVAR (b, scroll_bar_width),
3225 Lisp_Object save_right = w->right_margin_cols; 3443 BVAR (b, vertical_scroll_bar_type), Qnil);
3226 3444 set_window_margins (w, BVAR (b, left_margin_cols),
3227 wset_left_margin_cols (w, Qnil); 3445 BVAR (b, right_margin_cols));
3228 wset_right_margin_cols (w, Qnil); 3446 apply_window_adjustment (w);
3229
3230 Fset_window_fringes (window,
3231 BVAR (b, left_fringe_width), BVAR (b, right_fringe_width),
3232 BVAR (b, fringes_outside_margins));
3233
3234 Fset_window_scroll_bars (window,
3235 BVAR (b, scroll_bar_width),
3236 BVAR (b, vertical_scroll_bar_type), Qnil);
3237
3238 wset_left_margin_cols (w, save_left);
3239 wset_right_margin_cols (w, save_right);
3240
3241 Fset_window_margins (window,
3242 BVAR (b, left_margin_cols), BVAR (b, right_margin_cols));
3243 } 3447 }
3244 3448
3245 if (run_hooks_p) 3449 if (run_hooks_p)
@@ -3247,14 +3451,15 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
3247 if (! NILP (Vwindow_scroll_functions)) 3451 if (! NILP (Vwindow_scroll_functions))
3248 run_hook_with_args_2 (Qwindow_scroll_functions, window, 3452 run_hook_with_args_2 (Qwindow_scroll_functions, window,
3249 Fmarker_position (w->start)); 3453 Fmarker_position (w->start));
3250 run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w))); 3454 if (!samebuf)
3455 run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w)));
3251 } 3456 }
3252 3457
3253 unbind_to (count, Qnil); 3458 unbind_to (count, Qnil);
3254} 3459}
3255 3460
3256DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0, 3461DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0,
3257 doc: /* Make WINDOW display BUFFER-OR-NAME as its contents. 3462 doc: /* Make WINDOW display BUFFER-OR-NAME.
3258WINDOW must be a live window and defaults to the selected one. 3463WINDOW must be a live window and defaults to the selected one.
3259BUFFER-OR-NAME must be a buffer or the name of an existing buffer. 3464BUFFER-OR-NAME must be a buffer or the name of an existing buffer.
3260 3465
@@ -3280,7 +3485,7 @@ This function runs `window-scroll-functions' before running
3280 if (!BUFFER_LIVE_P (XBUFFER (buffer))) 3485 if (!BUFFER_LIVE_P (XBUFFER (buffer)))
3281 error ("Attempt to display deleted buffer"); 3486 error ("Attempt to display deleted buffer");
3282 3487
3283 tem = w->buffer; 3488 tem = w->contents;
3284 if (NILP (tem)) 3489 if (NILP (tem))
3285 error ("Window is deleted"); 3490 error ("Window is deleted");
3286 else 3491 else
@@ -3323,8 +3528,8 @@ displaying that buffer. */)
3323{ 3528{
3324 if (NILP (object)) 3529 if (NILP (object))
3325 { 3530 {
3326 windows_or_buffers_changed++; 3531 windows_or_buffers_changed = 29;
3327 update_mode_lines++; 3532 update_mode_lines = 28;
3328 return Qt; 3533 return Qt;
3329 } 3534 }
3330 3535
@@ -3333,9 +3538,9 @@ displaying that buffer. */)
3333 struct window *w = XWINDOW (object); 3538 struct window *w = XWINDOW (object);
3334 mark_window_display_accurate (object, 0); 3539 mark_window_display_accurate (object, 0);
3335 w->update_mode_line = 1; 3540 w->update_mode_line = 1;
3336 if (BUFFERP (w->buffer)) 3541 if (BUFFERP (w->contents))
3337 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 3542 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
3338 ++update_mode_lines; 3543 update_mode_lines = 29;
3339 return Qt; 3544 return Qt;
3340 } 3545 }
3341 3546
@@ -3375,10 +3580,8 @@ temp_output_buffer_show (register Lisp_Object buf)
3375 3580
3376 if (!NILP (Vtemp_buffer_show_function)) 3581 if (!NILP (Vtemp_buffer_show_function))
3377 call1 (Vtemp_buffer_show_function, buf); 3582 call1 (Vtemp_buffer_show_function, buf);
3378 else 3583 else if (WINDOW_LIVE_P (window = display_buffer (buf, Qnil, Qnil)))
3379 { 3584 {
3380 window = display_buffer (buf, Qnil, Qnil);
3381
3382 if (!EQ (XWINDOW (window)->frame, selected_frame)) 3585 if (!EQ (XWINDOW (window)->frame, selected_frame))
3383 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window))); 3586 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
3384 Vminibuf_scroll_window = window; 3587 Vminibuf_scroll_window = window;
@@ -3400,10 +3603,10 @@ temp_output_buffer_show (register Lisp_Object buf)
3400 Note: Both Fselect_window and select_window_norecord may 3603 Note: Both Fselect_window and select_window_norecord may
3401 set-buffer to the buffer displayed in the window, 3604 set-buffer to the buffer displayed in the window,
3402 so we need to save the current buffer. --stef */ 3605 so we need to save the current buffer. --stef */
3403 record_unwind_protect (Fset_buffer, prev_buffer); 3606 record_unwind_protect (restore_buffer, prev_buffer);
3404 record_unwind_protect (select_window_norecord, prev_window); 3607 record_unwind_protect (select_window_norecord, prev_window);
3405 Fselect_window (window, Qt); 3608 Fselect_window (window, Qt);
3406 Fset_buffer (w->buffer); 3609 Fset_buffer (w->contents);
3407 Frun_hooks (1, &Qtemp_buffer_show_hook); 3610 Frun_hooks (1, &Qtemp_buffer_show_hook);
3408 unbind_to (count, Qnil); 3611 unbind_to (count, Qnil);
3409 } 3612 }
@@ -3414,7 +3617,7 @@ temp_output_buffer_show (register Lisp_Object buf)
3414 WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only 3617 WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only
3415 horizontal child). */ 3618 horizontal child). */
3416static void 3619static void
3417make_parent_window (Lisp_Object window, int horflag) 3620make_parent_window (Lisp_Object window, bool horflag)
3418{ 3621{
3419 Lisp_Object parent; 3622 Lisp_Object parent;
3420 register struct window *o, *p; 3623 register struct window *o, *p;
@@ -3424,21 +3627,22 @@ make_parent_window (Lisp_Object window, int horflag)
3424 memcpy ((char *) p + sizeof (struct vectorlike_header), 3627 memcpy ((char *) p + sizeof (struct vectorlike_header),
3425 (char *) o + sizeof (struct vectorlike_header), 3628 (char *) o + sizeof (struct vectorlike_header),
3426 word_size * VECSIZE (struct window)); 3629 word_size * VECSIZE (struct window));
3427 /* P's buffer slot may change from nil to a buffer. */ 3630 /* P's buffer slot may change from nil to a buffer... */
3428 adjust_window_count (p, 1); 3631 adjust_window_count (p, 1);
3429 XSETWINDOW (parent, p); 3632 XSETWINDOW (parent, p);
3430 3633
3634 p->sequence_number = ++sequence_number;
3635
3431 replace_window (window, parent, 1); 3636 replace_window (window, parent, 1);
3432 3637
3433 wset_next (o, Qnil); 3638 wset_next (o, Qnil);
3434 wset_prev (o, Qnil); 3639 wset_prev (o, Qnil);
3435 wset_parent (o, parent); 3640 wset_parent (o, parent);
3436 3641 /* ...but now P becomes an internal window. */
3437 wset_hchild (p, horflag ? window : Qnil);
3438 wset_vchild (p, horflag ? Qnil : window);
3439 wset_start (p, Qnil); 3642 wset_start (p, Qnil);
3440 wset_pointm (p, Qnil); 3643 wset_pointm (p, Qnil);
3441 wset_buffer (p, Qnil); 3644 wset_buffer (p, Qnil);
3645 wset_combination (p, horflag, window);
3442 wset_combination_limit (p, Qnil); 3646 wset_combination_limit (p, Qnil);
3443 wset_window_parameters (p, Qnil); 3647 wset_window_parameters (p, Qnil);
3444} 3648}
@@ -3453,19 +3657,14 @@ make_window (void)
3453 w = allocate_window (); 3657 w = allocate_window ();
3454 /* Initialize Lisp data. Note that allocate_window initializes all 3658 /* Initialize Lisp data. Note that allocate_window initializes all
3455 Lisp data to nil, so do it only for slots which should not be nil. */ 3659 Lisp data to nil, so do it only for slots which should not be nil. */
3456 wset_left_col (w, make_number (0));
3457 wset_top_line (w, make_number (0));
3458 wset_total_lines (w, make_number (0));
3459 wset_total_cols (w, make_number (0));
3460 wset_normal_lines (w, make_float (1.0)); 3660 wset_normal_lines (w, make_float (1.0));
3461 wset_normal_cols (w, make_float (1.0)); 3661 wset_normal_cols (w, make_float (1.0));
3462 wset_new_total (w, make_number (0)); 3662 wset_new_total (w, make_number (0));
3463 wset_new_normal (w, make_number (0)); 3663 wset_new_normal (w, make_number (0));
3664 wset_new_pixel (w, make_number (0));
3464 wset_start (w, Fmake_marker ()); 3665 wset_start (w, Fmake_marker ());
3465 wset_pointm (w, Fmake_marker ()); 3666 wset_pointm (w, Fmake_marker ());
3466 wset_vertical_scroll_bar_type (w, Qt); 3667 wset_vertical_scroll_bar_type (w, Qt);
3467 wset_window_end_pos (w, make_number (0));
3468 wset_window_end_vpos (w, make_number (0));
3469 /* These Lisp fields are marked specially so they're not set to nil by 3668 /* These Lisp fields are marked specially so they're not set to nil by
3470 allocate_window. */ 3669 allocate_window. */
3471 wset_prev_buffers (w, Qnil); 3670 wset_prev_buffers (w, Qnil);
@@ -3474,8 +3673,14 @@ make_window (void)
3474 /* Initialize non-Lisp data. Note that allocate_window zeroes out all 3673 /* Initialize non-Lisp data. Note that allocate_window zeroes out all
3475 non-Lisp data, so do it only for slots which should not be zero. */ 3674 non-Lisp data, so do it only for slots which should not be zero. */
3476 w->nrows_scale_factor = w->ncols_scale_factor = 1; 3675 w->nrows_scale_factor = w->ncols_scale_factor = 1;
3477 w->phys_cursor_type = -1; 3676 w->left_fringe_width = w->right_fringe_width = -1;
3677 w->mode_line_height = w->header_line_height = -1;
3678#ifdef HAVE_WINDOW_SYSTEM
3679 w->phys_cursor_type = NO_CURSOR;
3478 w->phys_cursor_width = -1; 3680 w->phys_cursor_width = -1;
3681#endif
3682 w->sequence_number = ++sequence_number;
3683 w->scroll_bar_width = -1;
3479 w->column_number_displayed = -1; 3684 w->column_number_displayed = -1;
3480 3685
3481 /* Reset window_list. */ 3686 /* Reset window_list. */
@@ -3485,6 +3690,30 @@ make_window (void)
3485 return window; 3690 return window;
3486} 3691}
3487 3692
3693DEFUN ("set-window-new-pixel", Fset_window_new_pixel, Sset_window_new_pixel, 2, 3, 0,
3694 doc: /* Set new pixel size of WINDOW to SIZE.
3695WINDOW must be a valid window and defaults to the selected one.
3696Return SIZE.
3697
3698Optional argument ADD non-nil means add SIZE to the new pixel size of
3699WINDOW and return the sum.
3700
3701Note: This function does not operate on any child windows of WINDOW. */)
3702 (Lisp_Object window, Lisp_Object size, Lisp_Object add)
3703{
3704 struct window *w = decode_valid_window (window);
3705 EMACS_INT size_min = NILP (add) ? 0 : - XINT (w->new_pixel);
3706 EMACS_INT size_max = size_min + min (INT_MAX, MOST_POSITIVE_FIXNUM);
3707
3708 CHECK_RANGED_INTEGER (size, size_min, size_max);
3709 if (NILP (add))
3710 wset_new_pixel (w, size);
3711 else
3712 wset_new_pixel (w, make_number (XINT (w->new_pixel) + XINT (size)));
3713
3714 return w->new_pixel;
3715}
3716
3488DEFUN ("set-window-new-total", Fset_window_new_total, Sset_window_new_total, 2, 3, 0, 3717DEFUN ("set-window-new-total", Fset_window_new_total, Sset_window_new_total, 2, 3, 0,
3489 doc: /* Set new total size of WINDOW to SIZE. 3718 doc: /* Set new total size of WINDOW to SIZE.
3490WINDOW must be a valid window and defaults to the selected one. 3719WINDOW must be a valid window and defaults to the selected one.
@@ -3519,77 +3748,92 @@ Note: This function does not operate on any child windows of WINDOW. */)
3519 return size; 3748 return size;
3520} 3749}
3521 3750
3522/* Return 1 if setting w->total_lines (w->total_cols if HORFLAG is 3751/* Return 1 if setting w->pixel_height (w->pixel_width if HORFLAG is
3523 non-zero) to w->new_total would result in correct heights (widths) 3752 non-zero) to w->new_pixel would result in correct heights (widths)
3524 for window W and recursively all child windows of W. 3753 for window W and recursively all child windows of W.
3525 3754
3526 Note: This function does not check any of `window-fixed-size-p', 3755 Note: This function does not check any of `window-fixed-size-p',
3527 `window-min-height' or `window-min-width'. It does check that window 3756 `window-min-height' or `window-min-width'. It does check that window
3528 sizes do not drop below one line (two columns). */ 3757 sizes do not drop below one line (two columns). */
3529static int 3758static int
3530window_resize_check (struct window *w, int horflag) 3759window_resize_check (struct window *w, bool horflag)
3531{ 3760{
3761 struct frame *f = XFRAME (w->frame);
3532 struct window *c; 3762 struct window *c;
3533 3763
3534 if (!NILP (w->vchild)) 3764 if (WINDOW_VERTICAL_COMBINATION_P (w))
3535 /* W is a vertical combination. */ 3765 /* W is a vertical combination. */
3536 { 3766 {
3537 c = XWINDOW (w->vchild); 3767 c = XWINDOW (w->contents);
3538 if (horflag) 3768 if (horflag)
3539 /* All child windows of W must have the same width as W. */ 3769 /* All child windows of W must have the same width as W. */
3540 { 3770 {
3541 while (c) 3771 while (c)
3542 { 3772 {
3543 if ((XINT (c->new_total) != XINT (w->new_total)) 3773 if (XINT (c->new_pixel) != XINT (w->new_pixel)
3544 || !window_resize_check (c, horflag)) 3774 || !window_resize_check (c, horflag))
3545 return 0; 3775 return 0;
3776
3546 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3777 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3547 } 3778 }
3779
3548 return 1; 3780 return 1;
3549 } 3781 }
3550 else 3782 else
3551 /* The sum of the heights of the child windows of W must equal 3783 /* The sum of the heights of the child windows of W must equal
3552 W's height. */ 3784 W's height. */
3553 { 3785 {
3554 int sum_of_sizes = 0; 3786 int remaining_pixels = XINT (w->new_pixel);
3787
3555 while (c) 3788 while (c)
3556 { 3789 {
3557 if (!window_resize_check (c, horflag)) 3790 if (!window_resize_check (c, horflag))
3558 return 0; 3791 return 0;
3559 sum_of_sizes = sum_of_sizes + XINT (c->new_total); 3792
3793 remaining_pixels -= XINT (c->new_pixel);
3794 if (remaining_pixels < 0)
3795 return 0;
3560 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3796 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3561 } 3797 }
3562 return (sum_of_sizes == XINT (w->new_total)); 3798
3799 return remaining_pixels == 0;
3563 } 3800 }
3564 } 3801 }
3565 else if (!NILP (w->hchild)) 3802 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
3566 /* W is a horizontal combination. */ 3803 /* W is a horizontal combination. */
3567 { 3804 {
3568 c = XWINDOW (w->hchild); 3805 c = XWINDOW (w->contents);
3569 if (horflag) 3806 if (horflag)
3570 /* The sum of the widths of the child windows of W must equal W's 3807 /* The sum of the widths of the child windows of W must equal W's
3571 width. */ 3808 width. */
3572 { 3809 {
3573 int sum_of_sizes = 0; 3810 int remaining_pixels = XINT (w->new_pixel);
3811
3574 while (c) 3812 while (c)
3575 { 3813 {
3576 if (!window_resize_check (c, horflag)) 3814 if (!window_resize_check (c, horflag))
3577 return 0; 3815 return 0;
3578 sum_of_sizes = sum_of_sizes + XINT (c->new_total); 3816
3817 remaining_pixels -= XINT (c->new_pixel);
3818 if (remaining_pixels < 0)
3819 return 0;
3579 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3820 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3580 } 3821 }
3581 return (sum_of_sizes == XINT (w->new_total)); 3822
3823 return remaining_pixels == 0;
3582 } 3824 }
3583 else 3825 else
3584 /* All child windows of W must have the same height as W. */ 3826 /* All child windows of W must have the same height as W. */
3585 { 3827 {
3586 while (c) 3828 while (c)
3587 { 3829 {
3588 if ((XINT (c->new_total) != XINT (w->new_total)) 3830 if (XINT (c->new_pixel) != XINT (w->new_pixel)
3589 || !window_resize_check (c, horflag)) 3831 || !window_resize_check (c, horflag))
3590 return 0; 3832 return 0;
3833
3591 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3834 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3592 } 3835 }
3836
3593 return 1; 3837 return 1;
3594 } 3838 }
3595 } 3839 }
@@ -3597,80 +3841,166 @@ window_resize_check (struct window *w, int horflag)
3597 /* A leaf window. Make sure it's not too small. The following 3841 /* A leaf window. Make sure it's not too small. The following
3598 hardcodes the values of `window-safe-min-width' (2) and 3842 hardcodes the values of `window-safe-min-width' (2) and
3599 `window-safe-min-height' (1) which are defined in window.el. */ 3843 `window-safe-min-height' (1) which are defined in window.el. */
3600 return XINT (w->new_total) >= (horflag ? 2 : 1); 3844 return (XINT (w->new_pixel) >= (horflag
3845 ? (2 * FRAME_COLUMN_WIDTH (f))
3846 : FRAME_LINE_HEIGHT (f)));
3601} 3847}
3602 3848
3603/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to 3849
3604 w->new_total for window W and recursively all child windows of W. 3850/* Set w->pixel_height (w->pixel_height if HORIZONTAL is non-zero) to
3605 Also calculate and assign the new vertical (horizontal) start 3851 w->new_pixel for window W and recursively all child windows of W.
3852 Also calculate and assign the new vertical (horizontal) pixel start
3606 positions of each of these windows. 3853 positions of each of these windows.
3607 3854
3608 This function does not perform any error checks. Make sure you have 3855 This function does not perform any error checks. Make sure you have
3609 run window_resize_check on W before applying this function. */ 3856 run window_resize_check on W before applying this function. */
3610static void 3857static void
3611window_resize_apply (struct window *w, int horflag) 3858window_resize_apply (struct window *w, bool horflag)
3612{ 3859{
3613 struct window *c; 3860 struct window *c;
3614 int pos; 3861 int edge;
3862 int unit = (horflag
3863 ? FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w))
3864 : FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
3615 3865
3616 /* Note: Assigning new_normal requires that the new total size of the 3866 /* Note: Assigning new_normal requires that the new total size of the
3617 parent window has been set *before*. */ 3867 parent window has been set *before*. */
3618 if (horflag) 3868 if (horflag)
3619 { 3869 {
3620 wset_total_cols (w, w->new_total); 3870 w->pixel_width = XFASTINT (w->new_pixel);
3871 w->total_cols = w->pixel_width / unit;
3621 if (NUMBERP (w->new_normal)) 3872 if (NUMBERP (w->new_normal))
3622 wset_normal_cols (w, w->new_normal); 3873 wset_normal_cols (w, w->new_normal);
3623 3874
3624 pos = XINT (w->left_col); 3875 edge = w->pixel_left;
3625 } 3876 }
3626 else 3877 else
3627 { 3878 {
3628 wset_total_lines (w, w->new_total); 3879 w->pixel_height = XFASTINT (w->new_pixel);
3880 w->total_lines = w->pixel_height / unit;
3629 if (NUMBERP (w->new_normal)) 3881 if (NUMBERP (w->new_normal))
3630 wset_normal_lines (w, w->new_normal); 3882 wset_normal_lines (w, w->new_normal);
3631 3883
3632 pos = XINT (w->top_line); 3884 edge = w->pixel_top;
3633 } 3885 }
3634 3886
3635 if (!NILP (w->vchild)) 3887 if (WINDOW_VERTICAL_COMBINATION_P (w))
3636 /* W is a vertical combination. */ 3888 /* W is a vertical combination. */
3637 { 3889 {
3638 c = XWINDOW (w->vchild); 3890 c = XWINDOW (w->contents);
3639 while (c) 3891 while (c)
3640 { 3892 {
3641 if (horflag) 3893 if (horflag)
3642 wset_left_col (c, make_number (pos)); 3894 {
3895 c->pixel_left = edge;
3896 c->left_col = edge / unit;
3897 }
3643 else 3898 else
3644 wset_top_line (c, make_number (pos)); 3899 {
3900 c->pixel_top = edge;
3901 c->top_line = edge / unit;
3902 }
3645 window_resize_apply (c, horflag); 3903 window_resize_apply (c, horflag);
3646 if (!horflag) 3904 if (!horflag)
3647 pos = pos + XINT (c->total_lines); 3905 edge = edge + c->pixel_height;
3906
3648 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3907 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3649 } 3908 }
3650 } 3909 }
3651 else if (!NILP (w->hchild)) 3910 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
3652 /* W is a horizontal combination. */ 3911 /* W is a horizontal combination. */
3653 { 3912 {
3654 c = XWINDOW (w->hchild); 3913 c = XWINDOW (w->contents);
3655 while (c) 3914 while (c)
3656 { 3915 {
3657 if (horflag) 3916 if (horflag)
3658 wset_left_col (c, make_number (pos)); 3917 {
3918 c->pixel_left = edge;
3919 c->left_col = edge / unit;
3920 }
3659 else 3921 else
3660 wset_top_line (c, make_number (pos)); 3922 {
3923 c->pixel_top = edge;
3924 c->top_line = edge / unit;
3925 }
3926
3661 window_resize_apply (c, horflag); 3927 window_resize_apply (c, horflag);
3662 if (horflag) 3928 if (horflag)
3663 pos = pos + XINT (c->total_cols); 3929 edge = edge + c->pixel_width;
3930
3664 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3931 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3665 } 3932 }
3666 } 3933 }
3667 3934 else
3668 /* Clear out some redisplay caches. */ 3935 {
3669 w->last_modified = 0; 3936 adjust_window_margins (w);
3670 w->last_overlay_modified = 0; 3937 /* Bug#15957. */
3938 w->window_end_valid = 0;
3939 }
3671} 3940}
3672 3941
3673 3942
3943/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to
3944 w->new_total for window W and recursively all child windows of W.
3945 Also calculate and assign the new vertical (horizontal) start
3946 positions of each of these windows. */
3947static void
3948window_resize_apply_total (struct window *w, bool horflag)
3949{
3950 struct window *c;
3951 int edge;
3952
3953 /* Note: Assigning new_normal requires that the new total size of the
3954 parent window has been set *before*. */
3955 if (horflag)
3956 {
3957 w->total_cols = XFASTINT (w->new_total);
3958 edge = w->left_col;
3959 }
3960 else
3961 {
3962 w->total_lines = XFASTINT (w->new_total);
3963 edge = w->top_line;
3964 }
3965
3966 if (WINDOW_VERTICAL_COMBINATION_P (w))
3967 /* W is a vertical combination. */
3968 {
3969 c = XWINDOW (w->contents);
3970 while (c)
3971 {
3972 if (horflag)
3973 c->left_col = edge;
3974 else
3975 c->top_line = edge;
3976
3977 window_resize_apply_total (c, horflag);
3978 if (!horflag)
3979 edge = edge + c->total_lines;
3980
3981 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3982 }
3983 }
3984 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
3985 /* W is a horizontal combination. */
3986 {
3987 c = XWINDOW (w->contents);
3988 while (c)
3989 {
3990 if (horflag)
3991 c->left_col = edge;
3992 else
3993 c->top_line = edge;
3994
3995 window_resize_apply_total (c, horflag);
3996 if (horflag)
3997 edge = edge + c->total_cols;
3998
3999 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4000 }
4001 }
4002}
4003
3674DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 0, 2, 0, 4004DEFUN ("window-resize-apply", Fwindow_resize_apply, Swindow_resize_apply, 0, 2, 0,
3675 doc: /* Apply requested size values for window-tree of FRAME. 4005 doc: /* Apply requested size values for window-tree of FRAME.
3676If FRAME is omitted or nil, it defaults to the selected frame. 4006If FRAME is omitted or nil, it defaults to the selected frame.
@@ -3689,23 +4019,61 @@ be applied on the Elisp level. */)
3689{ 4019{
3690 struct frame *f = decode_live_frame (frame); 4020 struct frame *f = decode_live_frame (frame);
3691 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f)); 4021 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
3692 int horflag = !NILP (horizontal); 4022 bool horflag = !NILP (horizontal);
3693 4023
3694 if (!window_resize_check (r, horflag) 4024 if (!window_resize_check (r, horflag)
3695 || ! EQ (r->new_total, 4025 || (XINT (r->new_pixel)
3696 (horflag ? r->total_cols : r->total_lines))) 4026 != (horflag ? r->pixel_width : r->pixel_height)))
3697 return Qnil; 4027 return Qnil;
3698 4028
3699 block_input (); 4029 block_input ();
3700 window_resize_apply (r, horflag); 4030 window_resize_apply (r, horflag);
3701 4031
3702 windows_or_buffers_changed++; 4032 fset_redisplay (f);
3703 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 4033 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
3704 4034
3705 adjust_glyphs (f); 4035 adjust_frame_glyphs (f);
3706 unblock_input (); 4036 unblock_input ();
3707 4037
3708 run_window_configuration_change_hook (f); 4038 return Qt;
4039}
4040
4041
4042DEFUN ("window-resize-apply-total", Fwindow_resize_apply_total, Swindow_resize_apply_total, 0, 2, 0,
4043 doc: /* Apply requested total size values for window-tree of FRAME.
4044If FRAME is omitted or nil, it defaults to the selected frame.
4045
4046This function does not assign pixel or normal size values. You should
4047have run `window-resize-apply' before running this.
4048
4049Optional argument HORIZONTAL omitted or nil means apply requested
4050height values. HORIZONTAL non-nil means apply requested width
4051values. */)
4052 (Lisp_Object frame, Lisp_Object horizontal)
4053{
4054 struct frame *f = decode_live_frame (frame);
4055 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
4056
4057 block_input ();
4058 /* Necessary when deleting the top-/or leftmost window. */
4059 r->left_col = 0;
4060 r->top_line = FRAME_TOP_MARGIN (f);
4061 window_resize_apply_total (r, !NILP (horizontal));
4062 /* Handle the mini window. */
4063 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4064 {
4065 struct window *m = XWINDOW (f->minibuffer_window);
4066
4067 if (NILP (horizontal))
4068 {
4069 m->top_line = r->top_line + r->total_lines;
4070 m->total_lines = XFASTINT (m->new_total);
4071 }
4072 else
4073 m->total_cols = XFASTINT (m->new_total);
4074 }
4075
4076 unblock_input ();
3709 4077
3710 return Qt; 4078 return Qt;
3711} 4079}
@@ -3713,60 +4081,113 @@ be applied on the Elisp level. */)
3713 4081
3714/* Resize frame F's windows when number of lines of F is set to SIZE. 4082/* Resize frame F's windows when number of lines of F is set to SIZE.
3715 HORFLAG 1 means resize windows when number of columns of F is set to 4083 HORFLAG 1 means resize windows when number of columns of F is set to
3716 SIZE. 4084 SIZE. PIXELWISE 1 means to interpret SIZE as pixels.
3717 4085
3718 This function can delete all windows but the selected one in order to 4086 This function can delete all windows but the selected one in order to
3719 satisfy the request. The result will be meaningful if and only if 4087 satisfy the request. The result will be meaningful if and only if
3720 F's windows have meaningful sizes when you call this. */ 4088 F's windows have meaningful sizes when you call this. */
3721void 4089void
3722resize_frame_windows (struct frame *f, int size, int horflag) 4090resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
3723{ 4091{
3724 Lisp_Object root = f->root_window; 4092 Lisp_Object root = f->root_window;
3725 struct window *r = XWINDOW (root); 4093 struct window *r = XWINDOW (root);
3726 Lisp_Object mini = f->minibuffer_window; 4094 Lisp_Object mini = f->minibuffer_window;
3727 struct window *m; 4095 struct window *m;
4096 /* old_size is the old size of the frame's root window. */
4097 int old_size = horflag ? r->total_cols : r->total_lines;
4098 int old_pixel_size = horflag ? r->pixel_width : r->pixel_height;
3728 /* new_size is the new size of the frame's root window. */ 4099 /* new_size is the new size of the frame's root window. */
3729 int new_size = (horflag 4100 int new_size, new_pixel_size;
3730 ? size 4101 int unit = horflag ? FRAME_COLUMN_WIDTH (f) : FRAME_LINE_HEIGHT (f);
3731 : (size 4102
3732 - FRAME_TOP_MARGIN (f) 4103 /* Don't let the size drop below one unit. This is more comforting
3733 - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) 4104 when we are called from x_set_tool_bar_lines since the latter may
3734 ? 1 : 0))); 4105 have implicitly given us a zero or negative height. */
3735 4106 if (pixelwise)
3736 wset_top_line (r, make_number (FRAME_TOP_MARGIN (f))); 4107 {
3737 if (NILP (r->vchild) && NILP (r->hchild)) 4108 /* Note: This does not include the size for internal borders
4109 since these are not part of the frame's text area. */
4110 new_pixel_size = max (horflag
4111 ? size
4112 : (size
4113 - FRAME_TOP_MARGIN_HEIGHT (f)
4114 - ((FRAME_HAS_MINIBUF_P (f)
4115 && !FRAME_MINIBUF_ONLY_P (f))
4116 ? FRAME_LINE_HEIGHT (f) : 0)),
4117 unit);
4118 new_size = new_pixel_size / unit;
4119 }
4120 else
4121 {
4122 new_size = max (horflag
4123 ? size
4124 : (size
4125 - FRAME_TOP_MARGIN (f)
4126 - ((FRAME_HAS_MINIBUF_P (f)
4127 && !FRAME_MINIBUF_ONLY_P (f))
4128 ? 1 : 0)),
4129 1);
4130 new_pixel_size = new_size * unit;
4131 }
4132
4133 r->top_line = FRAME_TOP_MARGIN (f);
4134 r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
4135
4136 if (new_pixel_size == old_pixel_size)
4137 ;
4138 else if (WINDOW_LEAF_P (r))
3738 /* For a leaf root window just set the size. */ 4139 /* For a leaf root window just set the size. */
3739 if (horflag) 4140 if (horflag)
3740 wset_total_cols (r, make_number (new_size)); 4141 {
4142 r->total_cols = new_size;
4143 r->pixel_width = new_pixel_size;
4144 }
3741 else 4145 else
3742 wset_total_lines (r, make_number (new_size)); 4146 {
4147 r->total_lines = new_size;
4148 r->pixel_height = new_pixel_size;
4149 }
3743 else 4150 else
3744 { 4151 {
3745 /* old_size is the old size of the frame's root window. */
3746 int old_size = XFASTINT (horflag ? r->total_cols
3747 : r->total_lines);
3748 Lisp_Object delta; 4152 Lisp_Object delta;
3749 4153
3750 XSETINT (delta, new_size - old_size); 4154 if (pixelwise)
4155 XSETINT (delta, new_pixel_size - old_pixel_size);
4156 else
4157 XSETINT (delta, new_size - old_size);
4158
3751 /* Try a "normal" resize first. */ 4159 /* Try a "normal" resize first. */
3752 resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil); 4160 resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil,
4161 pixelwise ? Qt : Qnil);
3753 if (window_resize_check (r, horflag) 4162 if (window_resize_check (r, horflag)
3754 && new_size == XINT (r->new_total)) 4163 && new_pixel_size == XINT (r->new_pixel))
3755 window_resize_apply (r, horflag); 4164 {
4165 window_resize_apply (r, horflag);
4166 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4167 }
3756 else 4168 else
3757 { 4169 {
3758 /* Try with "reasonable" minimum sizes next. */ 4170 /* Try with "reasonable" minimum sizes next. */
3759 resize_root_window (root, delta, horflag ? Qt : Qnil, Qt); 4171 resize_root_window (root, delta, horflag ? Qt : Qnil, Qt,
4172 pixelwise ? Qt : Qnil);
3760 if (window_resize_check (r, horflag) 4173 if (window_resize_check (r, horflag)
3761 && new_size == XINT (r->new_total)) 4174 && new_pixel_size == XINT (r->new_pixel))
3762 window_resize_apply (r, horflag); 4175 {
4176 window_resize_apply (r, horflag);
4177 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4178 }
3763 else 4179 else
3764 { 4180 {
3765 /* Finally, try with "safe" minimum sizes. */ 4181 /* Finally, try with "safe" minimum sizes. */
3766 resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe); 4182 resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe,
4183 pixelwise ? Qt : Qnil);
3767 if (window_resize_check (r, horflag) 4184 if (window_resize_check (r, horflag)
3768 && new_size == XINT (r->new_total)) 4185 && new_pixel_size == XINT (r->new_pixel))
3769 window_resize_apply (r, horflag); 4186 {
4187 window_resize_apply (r, horflag);
4188 window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
4189 }
4190#if 0 /* Let's try without killing other windows. */
3770 else 4191 else
3771 { 4192 {
3772 /* We lost. Delete all windows but the frame's 4193 /* We lost. Delete all windows but the frame's
@@ -3774,10 +4195,17 @@ resize_frame_windows (struct frame *f, int size, int horflag)
3774 root = f->selected_window; 4195 root = f->selected_window;
3775 Fdelete_other_windows_internal (root, Qnil); 4196 Fdelete_other_windows_internal (root, Qnil);
3776 if (horflag) 4197 if (horflag)
3777 wset_total_cols (XWINDOW (root), make_number (new_size)); 4198 {
4199 XWINDOW (root)->total_cols = new_size;
4200 XWINDOW (root)->pixel_width = new_pixel_size;
4201 }
3778 else 4202 else
3779 wset_total_lines (XWINDOW (root), make_number (new_size)); 4203 {
4204 XWINDOW (root)->total_lines = new_size;
4205 XWINDOW (root)->pixel_height = new_pixel_size;
4206 }
3780 } 4207 }
4208#endif /* 0 */
3781 } 4209 }
3782 } 4210 }
3783 } 4211 }
@@ -3786,43 +4214,47 @@ resize_frame_windows (struct frame *f, int size, int horflag)
3786 { 4214 {
3787 m = XWINDOW (mini); 4215 m = XWINDOW (mini);
3788 if (horflag) 4216 if (horflag)
3789 wset_total_cols (m, make_number (size)); 4217 {
4218 m->total_cols = size;
4219 m->pixel_width = new_pixel_size;
4220 }
3790 else 4221 else
3791 { 4222 {
3792 /* Are we sure we always want 1 line here? */ 4223 /* Are we sure we always want 1 line here? */
3793 wset_total_lines (m, make_number (1)); 4224 m->total_lines = 1;
3794 wset_top_line 4225 m->pixel_height = FRAME_LINE_HEIGHT (f);
3795 (m, make_number (XINT (r->top_line) + XINT (r->total_lines))); 4226 m->top_line = r->top_line + r->total_lines;
4227 m->pixel_top = r->pixel_top + r->pixel_height;
3796 } 4228 }
3797 } 4229 }
3798 4230
3799 windows_or_buffers_changed++; 4231 fset_redisplay (f);
3800} 4232}
3801 4233
3802 4234
3803DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0, 4235DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
3804 doc: /* Split window OLD. 4236 doc: /* Split window OLD.
3805Second argument TOTAL-SIZE specifies the number of lines or columns of the 4237Second argument PIXEL-SIZE specifies the number of pixels of the
3806new window. In any case TOTAL-SIZE must be a positive integer. 4238new window. In any case TOTAL-SIZE must be a positive integer.
3807 4239
3808Third argument SIDE nil (or `below') specifies that the new window shall 4240Third argument SIDE nil (or `below') specifies that the new window shall
3809be located below WINDOW. SIDE `above' means the new window shall be 4241be located below WINDOW. SIDE `above' means the new window shall be
3810located above WINDOW. In both cases TOTAL-SIZE specifies the number of 4242located above WINDOW. In both cases PIXEL-SIZE specifies the pixel
3811lines of the new window including space reserved for the mode and/or 4243height of the new window including space reserved for the mode and/or
3812header line. 4244header line.
3813 4245
3814SIDE t (or `right') specifies that the new window shall be located on 4246SIDE t (or `right') specifies that the new window shall be located on
3815the right side of WINDOW. SIDE `left' means the new window shall be 4247the right side of WINDOW. SIDE `left' means the new window shall be
3816located on the left of WINDOW. In both cases TOTAL-SIZE specifies the 4248located on the left of WINDOW. In both cases PIXEL-SIZE specifies the
3817number of columns of the new window including space reserved for fringes 4249width of the new window including space reserved for fringes and the
3818and the scrollbar or a divider column. 4250scrollbar or a divider column.
3819 4251
3820Fourth argument NORMAL-SIZE specifies the normal size of the new window 4252Fourth argument NORMAL-SIZE specifies the normal size of the new window
3821according to the SIDE argument. 4253according to the SIDE argument.
3822 4254
3823The new total and normal sizes of all involved windows must have been 4255The new pixel and normal sizes of all involved windows must have been
3824set correctly. See the code of `split-window' for how this is done. */) 4256set correctly. See the code of `split-window' for how this is done. */)
3825 (Lisp_Object old, Lisp_Object total_size, Lisp_Object side, Lisp_Object normal_size) 4257 (Lisp_Object old, Lisp_Object pixel_size, Lisp_Object side, Lisp_Object normal_size)
3826{ 4258{
3827 /* OLD (*o) is the window we have to split. (*p) is either OLD's 4259 /* OLD (*o) is the window we have to split. (*p) is either OLD's
3828 parent window or an internal window we have to install as OLD's new 4260 parent window or an internal window we have to install as OLD's new
@@ -3831,19 +4263,24 @@ set correctly. See the code of `split-window' for how this is done. */)
3831 NEW (*n) is the new window created with some parameters taken from 4263 NEW (*n) is the new window created with some parameters taken from
3832 REFERENCE (*r). */ 4264 REFERENCE (*r). */
3833 register Lisp_Object new, frame, reference; 4265 register Lisp_Object new, frame, reference;
3834 register struct window *o, *p, *n, *r; 4266 register struct window *o, *p, *n, *r, *c;
3835 struct frame *f; 4267 struct frame *f;
3836 int horflag 4268 bool horflag
3837 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */ 4269 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */
3838 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright); 4270 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
3839 int combination_limit = 0; 4271 int combination_limit = 0, sum = 0;
4272 int total_size;
3840 4273
3841 CHECK_WINDOW (old); 4274 CHECK_WINDOW (old);
3842 o = XWINDOW (old); 4275 o = XWINDOW (old);
3843 frame = WINDOW_FRAME (o); 4276 frame = WINDOW_FRAME (o);
3844 f = XFRAME (frame); 4277 f = XFRAME (frame);
3845 4278
3846 CHECK_NUMBER (total_size); 4279 CHECK_NUMBER (pixel_size);
4280 total_size
4281 = XINT (pixel_size) / (horflag
4282 ? FRAME_COLUMN_WIDTH (f)
4283 : FRAME_LINE_HEIGHT (f));
3847 4284
3848 /* Set combination_limit to 1 if we have to make a new parent window. 4285 /* Set combination_limit to 1 if we have to make a new parent window.
3849 We do that if either `window-combination-limit' is t, or OLD has no 4286 We do that if either `window-combination-limit' is t, or OLD has no
@@ -3851,9 +4288,9 @@ set correctly. See the code of `split-window' for how this is done. */)
3851 combination_limit = 4288 combination_limit =
3852 EQ (Vwindow_combination_limit, Qt) 4289 EQ (Vwindow_combination_limit, Qt)
3853 || NILP (o->parent) 4290 || NILP (o->parent)
3854 || NILP (horflag 4291 || (horflag
3855 ? (XWINDOW (o->parent)->hchild) 4292 ? WINDOW_VERTICAL_COMBINATION_P (XWINDOW (o->parent))
3856 : (XWINDOW (o->parent)->vchild)); 4293 : WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (o->parent)));
3857 4294
3858 /* We need a live reference window to initialize some parameters. */ 4295 /* We need a live reference window to initialize some parameters. */
3859 if (WINDOW_LIVE_P (old)) 4296 if (WINDOW_LIVE_P (old))
@@ -3867,7 +4304,7 @@ set correctly. See the code of `split-window' for how this is done. */)
3867 /* The following bugs are caught by `split-window'. */ 4304 /* The following bugs are caught by `split-window'. */
3868 if (MINI_WINDOW_P (o)) 4305 if (MINI_WINDOW_P (o))
3869 error ("Attempt to split minibuffer window"); 4306 error ("Attempt to split minibuffer window");
3870 else if (XINT (total_size) < (horflag ? 2 : 1)) 4307 else if (total_size < (horflag ? 2 : 1))
3871 error ("Size of new window too small (after split)"); 4308 error ("Size of new window too small (after split)");
3872 else if (!combination_limit && !NILP (Vwindow_combination_resize)) 4309 else if (!combination_limit && !NILP (Vwindow_combination_resize))
3873 /* `window-combination-resize' non-nil means try to resize OLD's siblings 4310 /* `window-combination-resize' non-nil means try to resize OLD's siblings
@@ -3875,25 +4312,25 @@ set correctly. See the code of `split-window' for how this is done. */)
3875 { 4312 {
3876 p = XWINDOW (o->parent); 4313 p = XWINDOW (o->parent);
3877 /* Temporarily pretend we split the parent window. */ 4314 /* Temporarily pretend we split the parent window. */
3878 wset_new_total 4315 wset_new_pixel
3879 (p, make_number (XINT (horflag ? p->total_cols : p->total_lines) 4316 (p, make_number ((horflag ? p->pixel_width : p->pixel_height)
3880 - XINT (total_size))); 4317 - XINT (pixel_size)));
3881 if (!window_resize_check (p, horflag)) 4318 if (!window_resize_check (p, horflag))
3882 error ("Window sizes don't fit"); 4319 error ("Window sizes don't fit");
3883 else 4320 else
3884 /* Undo the temporary pretension. */ 4321 /* Undo the temporary pretension. */
3885 wset_new_total (p, horflag ? p->total_cols : p->total_lines); 4322 wset_new_pixel (p, make_number (horflag ? p->pixel_width : p->pixel_height));
3886 } 4323 }
3887 else 4324 else
3888 { 4325 {
3889 if (!window_resize_check (o, horflag)) 4326 if (!window_resize_check (o, horflag))
3890 error ("Resizing old window failed"); 4327 error ("Resizing old window failed");
3891 else if (XINT (total_size) + XINT (o->new_total) 4328 else if (XINT (pixel_size) + XINT (o->new_pixel)
3892 != XINT (horflag ? o->total_cols : o->total_lines)) 4329 != (horflag ? o->pixel_width : o->pixel_height))
3893 error ("Sum of sizes of old and new window don't fit"); 4330 error ("Sum of sizes of old and new window don't fit");
3894 } 4331 }
3895 4332
3896 /* This is our point of no return. */ 4333 /* This is our point of no return. */
3897 if (combination_limit) 4334 if (combination_limit)
3898 { 4335 {
3899 /* Save the old value of o->normal_cols/lines. It gets corrupted 4336 /* Save the old value of o->normal_cols/lines. It gets corrupted
@@ -3909,29 +4346,27 @@ set correctly. See the code of `split-window' for how this is done. */)
3909 that its children get merged into another window. */ 4346 that its children get merged into another window. */
3910 wset_combination_limit (p, Qt); 4347 wset_combination_limit (p, Qt);
3911 /* These get applied below. */ 4348 /* These get applied below. */
3912 wset_new_total (p, horflag ? o->total_cols : o->total_lines); 4349 wset_new_pixel
4350 (p, make_number (horflag ? o->pixel_width : o->pixel_height));
4351 wset_new_total
4352 (p, make_number (horflag ? o->total_cols : o->total_lines));
3913 wset_new_normal (p, new_normal); 4353 wset_new_normal (p, new_normal);
3914 } 4354 }
3915 else 4355 else
3916 p = XWINDOW (o->parent); 4356 p = XWINDOW (o->parent);
3917 4357
3918 windows_or_buffers_changed++; 4358 fset_redisplay (f);
3919 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 4359 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
3920 new = make_window (); 4360 new = make_window ();
3921 n = XWINDOW (new); 4361 n = XWINDOW (new);
3922 wset_frame (n, frame); 4362 wset_frame (n, frame);
3923 wset_parent (n, o->parent); 4363 wset_parent (n, o->parent);
3924 wset_vchild (n, Qnil);
3925 wset_hchild (n, Qnil);
3926 4364
3927 if (EQ (side, Qabove) || EQ (side, Qleft)) 4365 if (EQ (side, Qabove) || EQ (side, Qleft))
3928 { 4366 {
3929 wset_prev (n, o->prev); 4367 wset_prev (n, o->prev);
3930 if (NILP (n->prev)) 4368 if (NILP (n->prev))
3931 if (horflag) 4369 wset_combination (p, horflag, new);
3932 wset_hchild (p, new);
3933 else
3934 wset_vchild (p, new);
3935 else 4370 else
3936 wset_next (XWINDOW (n->prev), new); 4371 wset_next (XWINDOW (n->prev), new);
3937 wset_next (n, old); 4372 wset_next (n, old);
@@ -3947,40 +4382,55 @@ set correctly. See the code of `split-window' for how this is done. */)
3947 } 4382 }
3948 4383
3949 n->window_end_valid = 0; 4384 n->window_end_valid = 0;
3950 memset (&n->last_cursor, 0, sizeof n->last_cursor); 4385 n->last_cursor_vpos = 0;
3951 4386
3952 /* Get special geometry settings from reference window. */ 4387 /* Get special geometry settings from reference window. */
3953 wset_left_margin_cols (n, r->left_margin_cols); 4388 n->left_margin_cols = r->left_margin_cols;
3954 wset_right_margin_cols (n, r->right_margin_cols); 4389 n->right_margin_cols = r->right_margin_cols;
3955 wset_left_fringe_width (n, r->left_fringe_width); 4390 n->left_fringe_width = r->left_fringe_width;
3956 wset_right_fringe_width (n, r->right_fringe_width); 4391 n->right_fringe_width = r->right_fringe_width;
3957 n->fringes_outside_margins = r->fringes_outside_margins; 4392 n->fringes_outside_margins = r->fringes_outside_margins;
3958 wset_scroll_bar_width (n, r->scroll_bar_width); 4393 n->scroll_bar_width = r->scroll_bar_width;
3959 wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type); 4394 wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type);
3960 4395
3961 /* Directly assign orthogonal coordinates and sizes. */ 4396 /* Directly assign orthogonal coordinates and sizes. */
3962 if (horflag) 4397 if (horflag)
3963 { 4398 {
3964 wset_top_line (n, o->top_line); 4399 n->pixel_top = o->pixel_top;
3965 wset_total_lines (n, o->total_lines); 4400 n->top_line = o->top_line;
4401 n->pixel_height = o->pixel_height;
4402 n->total_lines = o->total_lines;
3966 } 4403 }
3967 else 4404 else
3968 { 4405 {
3969 wset_left_col (n, o->left_col); 4406 n->pixel_left = o->pixel_left;
3970 wset_total_cols (n, o->total_cols); 4407 n->left_col = o->left_col;
4408 n->pixel_width = o->pixel_width;
4409 n->total_cols = o->total_cols;
3971 } 4410 }
3972 4411
3973 /* Iso-coordinates and sizes are assigned by window_resize_apply, 4412 /* Iso-coordinates and sizes are assigned by window_resize_apply,
3974 get them ready here. */ 4413 get them ready here. */
3975 wset_new_total (n, total_size); 4414 wset_new_pixel (n, pixel_size);
4415 c = XWINDOW (p->contents);
4416 while (c)
4417 {
4418 if (c != n)
4419 sum = sum + XINT (c->new_total);
4420 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4421 }
4422 wset_new_total (n, make_number ((horflag
4423 ? p->total_cols
4424 : p->total_lines)
4425 - sum));
3976 wset_new_normal (n, normal_size); 4426 wset_new_normal (n, normal_size);
3977 4427
3978 block_input (); 4428 block_input ();
3979 window_resize_apply (p, horflag); 4429 window_resize_apply (p, horflag);
3980 adjust_glyphs (f); 4430 adjust_frame_glyphs (f);
3981 /* Set buffer of NEW to buffer of reference window. Don't run 4431 /* Set buffer of NEW to buffer of reference window. Don't run
3982 any hooks. */ 4432 any hooks. */
3983 set_window_buffer (new, r->buffer, 0, 1); 4433 set_window_buffer (new, r->contents, 0, 1);
3984 unblock_input (); 4434 unblock_input ();
3985 4435
3986 /* Maybe we should run the scroll functions in Elisp (which already 4436 /* Maybe we should run the scroll functions in Elisp (which already
@@ -4002,13 +4452,11 @@ Signal an error when WINDOW is the only window on its frame. */)
4002 register Lisp_Object parent, sibling, frame, root; 4452 register Lisp_Object parent, sibling, frame, root;
4003 struct window *w, *p, *s, *r; 4453 struct window *w, *p, *s, *r;
4004 struct frame *f; 4454 struct frame *f;
4005 int horflag; 4455 bool horflag, before_sibling = 0;
4006 int before_sibling = 0;
4007 4456
4008 w = decode_any_window (window); 4457 w = decode_any_window (window);
4009 XSETWINDOW (window, w); 4458 XSETWINDOW (window, w);
4010 if (NILP (w->buffer) 4459 if (NILP (w->contents))
4011 && NILP (w->hchild) && NILP (w->vchild))
4012 /* It's a no-op to delete an already deleted window. */ 4460 /* It's a no-op to delete an already deleted window. */
4013 return Qnil; 4461 return Qnil;
4014 4462
@@ -4022,7 +4470,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4022 error ("Attempt to delete sole window of parent"); 4470 error ("Attempt to delete sole window of parent");
4023 4471
4024 p = XWINDOW (parent); 4472 p = XWINDOW (parent);
4025 horflag = NILP (p->vchild); 4473 horflag = WINDOW_HORIZONTAL_COMBINATION_P (p);
4026 4474
4027 frame = WINDOW_FRAME (w); 4475 frame = WINDOW_FRAME (w);
4028 f = XFRAME (frame); 4476 f = XFRAME (frame);
@@ -4040,10 +4488,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4040 sibling = w->next; 4488 sibling = w->next;
4041 s = XWINDOW (sibling); 4489 s = XWINDOW (sibling);
4042 wset_prev (s, Qnil); 4490 wset_prev (s, Qnil);
4043 if (horflag) 4491 wset_combination (p, horflag, sibling);
4044 wset_hchild (p, sibling);
4045 else
4046 wset_vchild (p, sibling);
4047 } 4492 }
4048 else 4493 else
4049 /* Get SIBLING above (on the left of) WINDOW. */ 4494 /* Get SIBLING above (on the left of) WINDOW. */
@@ -4056,15 +4501,14 @@ Signal an error when WINDOW is the only window on its frame. */)
4056 } 4501 }
4057 4502
4058 if (window_resize_check (r, horflag) 4503 if (window_resize_check (r, horflag)
4059 && EQ (r->new_total, 4504 && (XINT (r->new_pixel)
4060 (horflag ? r->total_cols : r->total_lines))) 4505 == (horflag ? r->pixel_width : r->pixel_height)))
4061 /* We can delete WINDOW now. */ 4506 /* We can delete WINDOW now. */
4062 { 4507 {
4063 4508
4064 /* Block input. */ 4509 /* Block input. */
4065 block_input (); 4510 block_input ();
4066 window_resize_apply (p, horflag); 4511 window_resize_apply (p, horflag);
4067
4068 /* If this window is referred to by the dpyinfo's mouse 4512 /* If this window is referred to by the dpyinfo's mouse
4069 highlight, invalidate that slot to be safe (Bug#9904). */ 4513 highlight, invalidate that slot to be safe (Bug#9904). */
4070 if (!FRAME_INITIAL_P (f)) 4514 if (!FRAME_INITIAL_P (f))
@@ -4075,24 +4519,19 @@ Signal an error when WINDOW is the only window on its frame. */)
4075 hlinfo->mouse_face_window = Qnil; 4519 hlinfo->mouse_face_window = Qnil;
4076 } 4520 }
4077 4521
4078 windows_or_buffers_changed++; 4522 fset_redisplay (f);
4079 Vwindow_list = Qnil; 4523 Vwindow_list = Qnil;
4080 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 4524 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4081 4525
4082 wset_next (w, Qnil); /* Don't delete w->next too. */ 4526 wset_next (w, Qnil); /* Don't delete w->next too. */
4083 free_window_matrices (w); 4527 free_window_matrices (w);
4084 4528
4085 if (!NILP (w->vchild)) 4529 if (WINDOWP (w->contents))
4086 {
4087 delete_all_child_windows (w->vchild);
4088 wset_vchild (w, Qnil);
4089 }
4090 else if (!NILP (w->hchild))
4091 { 4530 {
4092 delete_all_child_windows (w->hchild); 4531 delete_all_child_windows (w->contents);
4093 wset_hchild (w, Qnil); 4532 wset_combination (w, 0, Qnil);
4094 } 4533 }
4095 else if (!NILP (w->buffer)) 4534 else
4096 { 4535 {
4097 unshow_buffer (w); 4536 unshow_buffer (w);
4098 unchain_marker (XMARKER (w->pointm)); 4537 unchain_marker (XMARKER (w->pointm));
@@ -4111,13 +4550,12 @@ Signal an error when WINDOW is the only window on its frame. */)
4111 wset_normal_cols (s, p->normal_cols); 4550 wset_normal_cols (s, p->normal_cols);
4112 wset_normal_lines (s, p->normal_lines); 4551 wset_normal_lines (s, p->normal_lines);
4113 /* Mark PARENT as deleted. */ 4552 /* Mark PARENT as deleted. */
4114 wset_vchild (p, Qnil); 4553 wset_combination (p, 0, Qnil);
4115 wset_hchild (p, Qnil);
4116 /* Try to merge SIBLING into its new parent. */ 4554 /* Try to merge SIBLING into its new parent. */
4117 recombine_windows (sibling); 4555 recombine_windows (sibling);
4118 } 4556 }
4119 4557
4120 adjust_glyphs (f); 4558 adjust_frame_glyphs (f);
4121 4559
4122 if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f))) 4560 if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f)))
4123 /* We deleted the frame's selected window. */ 4561 /* We deleted the frame's selected window. */
@@ -4160,10 +4598,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4160 if (before_sibling) 4598 if (before_sibling)
4161 { 4599 {
4162 wset_prev (s, window); 4600 wset_prev (s, window);
4163 if (horflag) 4601 wset_combination (p, horflag, window);
4164 wset_hchild (p, window);
4165 else
4166 wset_vchild (p, window);
4167 } 4602 }
4168 else 4603 else
4169 { 4604 {
@@ -4184,72 +4619,91 @@ Signal an error when WINDOW is the only window on its frame. */)
4184/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we 4619/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we
4185 can. */ 4620 can. */
4186void 4621void
4187grow_mini_window (struct window *w, int delta) 4622grow_mini_window (struct window *w, int delta, bool pixelwise)
4188{ 4623{
4189 struct frame *f = XFRAME (w->frame); 4624 struct frame *f = XFRAME (w->frame);
4190 struct window *r; 4625 struct window *r;
4191 Lisp_Object root, value; 4626 Lisp_Object root, height;
4627 int line_height, pixel_height;
4192 4628
4193 eassert (MINI_WINDOW_P (w)); 4629 eassert (MINI_WINDOW_P (w));
4194 eassert (delta >= 0); 4630 eassert (delta >= 0);
4195 4631
4196 root = FRAME_ROOT_WINDOW (f); 4632 if (delta > 0)
4197 r = XWINDOW (root);
4198 value = call2 (Qwindow_resize_root_window_vertically,
4199 root, make_number (- delta));
4200 if (INTEGERP (value) && window_resize_check (r, 0))
4201 { 4633 {
4202 block_input (); 4634 root = FRAME_ROOT_WINDOW (f);
4203 window_resize_apply (r, 0); 4635 r = XWINDOW (root);
4636 height = call3 (Qwindow_resize_root_window_vertically,
4637 root, make_number (- delta), pixelwise ? Qt : Qnil);
4638 if (INTEGERP (height) && window_resize_check (r, 0))
4639 {
4640 block_input ();
4641 window_resize_apply (r, 0);
4204 4642
4205 /* Grow the mini-window. */ 4643 if (pixelwise)
4206 wset_top_line 4644 {
4207 (w, make_number (XFASTINT (r->top_line) + XFASTINT (r->total_lines))); 4645 pixel_height = min (-XINT (height), INT_MAX - w->pixel_height);
4208 wset_total_lines 4646 line_height = pixel_height / FRAME_LINE_HEIGHT (f);
4209 (w, make_number (XFASTINT (w->total_lines) - XINT (value))); 4647 }
4210 w->last_modified = 0; 4648 else
4211 w->last_overlay_modified = 0; 4649 {
4650 line_height = min (-XINT (height),
4651 ((INT_MAX - w->pixel_height)
4652 / FRAME_LINE_HEIGHT (f)));
4653 pixel_height = line_height * FRAME_LINE_HEIGHT (f);
4654 }
4212 4655
4213 windows_or_buffers_changed++; 4656 /* Grow the mini-window. */
4214 adjust_glyphs (f); 4657 w->pixel_top = r->pixel_top + r->pixel_height;
4215 unblock_input (); 4658 w->top_line = r->top_line + r->total_lines;
4659 /* Make sure the mini-window has always at least one line. */
4660 w->pixel_height = max (w->pixel_height + pixel_height,
4661 FRAME_LINE_HEIGHT (f));
4662 w->total_lines = max (w->total_lines + line_height, 1);
4663
4664 /* Enforce full redisplay of the frame. */
4665 /* FIXME: Shouldn't window--resize-root-window-vertically do it? */
4666 fset_redisplay (f);
4667 adjust_frame_glyphs (f);
4668 unblock_input ();
4669 }
4216 } 4670 }
4217} 4671}
4218 4672
4219 4673/* Shrink mini-window W to one line. */
4220/* Shrink mini-window W. */
4221void 4674void
4222shrink_mini_window (struct window *w) 4675shrink_mini_window (struct window *w, bool pixelwise)
4223{ 4676{
4224 struct frame *f = XFRAME (w->frame); 4677 struct frame *f = XFRAME (w->frame);
4225 struct window *r; 4678 struct window *r;
4226 Lisp_Object root, value; 4679 Lisp_Object root, delta;
4227 EMACS_INT size; 4680 EMACS_INT height, unit;
4228 4681
4229 eassert (MINI_WINDOW_P (w)); 4682 eassert (MINI_WINDOW_P (w));
4230 4683
4231 size = XINT (w->total_lines); 4684 height = pixelwise ? w->pixel_height : w->total_lines;
4232 if (size > 1) 4685 unit = pixelwise ? FRAME_LINE_HEIGHT (f) : 1;
4686 if (height > unit)
4233 { 4687 {
4234 root = FRAME_ROOT_WINDOW (f); 4688 root = FRAME_ROOT_WINDOW (f);
4235 r = XWINDOW (root); 4689 r = XWINDOW (root);
4236 value = call2 (Qwindow_resize_root_window_vertically, 4690 delta = call3 (Qwindow_resize_root_window_vertically,
4237 root, make_number (size - 1)); 4691 root, make_number (height - unit),
4238 if (INTEGERP (value) && window_resize_check (r, 0)) 4692 pixelwise ? Qt : Qnil);
4693 if (INTEGERP (delta) && window_resize_check (r, 0))
4239 { 4694 {
4240 block_input (); 4695 block_input ();
4241 window_resize_apply (r, 0); 4696 window_resize_apply (r, 0);
4242 4697
4243 /* Shrink the mini-window. */ 4698 /* Shrink the mini-window. */
4244 wset_top_line (w, make_number (XFASTINT (r->top_line) 4699 w->top_line = r->top_line + r->total_lines;
4245 + XFASTINT (r->total_lines))); 4700 w->total_lines = 1;
4246 wset_total_lines (w, make_number (1)); 4701 w->pixel_top = r->pixel_top + r->pixel_height;
4247 4702 w->pixel_height = FRAME_LINE_HEIGHT (f);
4248 w->last_modified = 0; 4703 /* Enforce full redisplay of the frame. */
4249 w->last_overlay_modified = 0; 4704 /* FIXME: Shouldn't window--resize-root-window-vertically do it? */
4250 4705 fset_redisplay (f);
4251 windows_or_buffers_changed++; 4706 adjust_frame_glyphs (f);
4252 adjust_glyphs (f);
4253 unblock_input (); 4707 unblock_input ();
4254 } 4708 }
4255 /* If the above failed for whatever strange reason we must make a 4709 /* If the above failed for whatever strange reason we must make a
@@ -4277,27 +4731,27 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
4277 error ("Cannot resize a minibuffer-only frame"); 4731 error ("Cannot resize a minibuffer-only frame");
4278 4732
4279 r = XWINDOW (FRAME_ROOT_WINDOW (f)); 4733 r = XWINDOW (FRAME_ROOT_WINDOW (f));
4280 height = XINT (r->total_lines) + XINT (w->total_lines); 4734 height = r->pixel_height + w->pixel_height;
4281 if (window_resize_check (r, 0) 4735 if (window_resize_check (r, 0)
4282 && XINT (w->new_total) > 0 4736 && XINT (w->new_pixel) > 0
4283 && height == XINT (r->new_total) + XINT (w->new_total)) 4737 && height == XINT (r->new_pixel) + XINT (w->new_pixel))
4284 { 4738 {
4285 block_input (); 4739 block_input ();
4286 window_resize_apply (r, 0); 4740 window_resize_apply (r, 0);
4287 4741
4288 wset_total_lines (w, w->new_total); 4742 w->total_lines = XFASTINT (w->new_total);
4289 wset_top_line (w, make_number (XINT (r->top_line) 4743 w->top_line = r->top_line + r->total_lines;
4290 + XINT (r->total_lines))); 4744 w->pixel_height = XFASTINT (w->new_pixel);
4745 w->pixel_top = r->pixel_top + r->pixel_height;
4291 4746
4292 windows_or_buffers_changed++; 4747 fset_redisplay (f);
4293 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 4748 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4294 adjust_glyphs (f); 4749 adjust_frame_glyphs (f);
4295 unblock_input (); 4750 unblock_input ();
4296
4297 run_window_configuration_change_hook (f);
4298 return Qt; 4751 return Qt;
4299 } 4752 }
4300 else error ("Failed to resize minibuffer window"); 4753 else
4754 error ("Failed to resize minibuffer window");
4301} 4755}
4302 4756
4303/* Mark window cursors off for all windows in the window tree rooted 4757/* Mark window cursors off for all windows in the window tree rooted
@@ -4310,10 +4764,8 @@ mark_window_cursors_off (struct window *w)
4310{ 4764{
4311 while (w) 4765 while (w)
4312 { 4766 {
4313 if (!NILP (w->hchild)) 4767 if (WINDOWP (w->contents))
4314 mark_window_cursors_off (XWINDOW (w->hchild)); 4768 mark_window_cursors_off (XWINDOW (w->contents));
4315 else if (!NILP (w->vchild))
4316 mark_window_cursors_off (XWINDOW (w->vchild));
4317 else 4769 else
4318 w->phys_cursor_on_p = 0; 4770 w->phys_cursor_on_p = 0;
4319 4771
@@ -4327,13 +4779,12 @@ mark_window_cursors_off (struct window *w)
4327int 4779int
4328window_internal_height (struct window *w) 4780window_internal_height (struct window *w)
4329{ 4781{
4330 int ht = XFASTINT (w->total_lines); 4782 int ht = w->total_lines;
4331 4783
4332 if (!MINI_WINDOW_P (w)) 4784 if (!MINI_WINDOW_P (w))
4333 { 4785 {
4334 if (!NILP (w->parent) 4786 if (!NILP (w->parent)
4335 || !NILP (w->vchild) 4787 || WINDOWP (w->contents)
4336 || !NILP (w->hchild)
4337 || !NILP (w->next) 4788 || !NILP (w->next)
4338 || !NILP (w->prev) 4789 || !NILP (w->prev)
4339 || WINDOW_WANTS_MODELINE_P (w)) 4790 || WINDOW_WANTS_MODELINE_P (w))
@@ -4358,11 +4809,13 @@ window_internal_height (struct window *w)
4358 respectively. */ 4809 respectively. */
4359 4810
4360static void 4811static void
4361window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror) 4812window_scroll (Lisp_Object window, EMACS_INT n, bool whole, int noerror)
4362{ 4813{
4363 immediate_quit = 1; 4814 immediate_quit = 1;
4364 n = clip_to_bounds (INT_MIN, n, INT_MAX); 4815 n = clip_to_bounds (INT_MIN, n, INT_MAX);
4365 4816
4817 wset_redisplay (XWINDOW (window));
4818
4366 /* If we must, use the pixel-based version which is much slower than 4819 /* If we must, use the pixel-based version which is much slower than
4367 the line-based one but can handle varying line heights. */ 4820 the line-based one but can handle varying line heights. */
4368 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame))) 4821 if (FRAME_WINDOW_P (XFRAME (XWINDOW (window)->frame)))
@@ -4370,6 +4823,8 @@ window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror)
4370 else 4823 else
4371 window_scroll_line_based (window, n, whole, noerror); 4824 window_scroll_line_based (window, n, whole, noerror);
4372 4825
4826 /* Bug#15957. */
4827 XWINDOW (window)->window_end_valid = 0;
4373 immediate_quit = 0; 4828 immediate_quit = 0;
4374} 4829}
4375 4830
@@ -4379,7 +4834,7 @@ window_scroll (Lisp_Object window, EMACS_INT n, int whole, int noerror)
4379 descriptions. */ 4834 descriptions. */
4380 4835
4381static void 4836static void
4382window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror) 4837window_scroll_pixel_based (Lisp_Object window, int n, bool whole, int noerror)
4383{ 4838{
4384 struct it it; 4839 struct it it;
4385 struct window *w = XWINDOW (window); 4840 struct window *w = XWINDOW (window);
@@ -4389,6 +4844,8 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4389 int vscrolled = 0; 4844 int vscrolled = 0;
4390 int x, y, rtop, rbot, rowh, vpos; 4845 int x, y, rtop, rbot, rowh, vpos;
4391 void *itdata = NULL; 4846 void *itdata = NULL;
4847 int window_total_lines;
4848 int frame_line_height = default_line_pixel_height (w);
4392 4849
4393 SET_TEXT_POS_FROM_MARKER (start, w->start); 4850 SET_TEXT_POS_FROM_MARKER (start, w->start);
4394 /* Scrolling a minibuffer window via scroll bar when the echo area 4851 /* Scrolling a minibuffer window via scroll bar when the echo area
@@ -4432,7 +4889,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4432 if (rtop || rbot) /* partially visible */ 4889 if (rtop || rbot) /* partially visible */
4433 { 4890 {
4434 int px; 4891 int px;
4435 int dy = WINDOW_FRAME_LINE_HEIGHT (w); 4892 int dy = frame_line_height;
4436 if (whole) 4893 if (whole)
4437 dy = max ((window_box_height (w) 4894 dy = max ((window_box_height (w)
4438 - next_screen_context_lines * dy), 4895 - next_screen_context_lines * dy),
@@ -4472,11 +4929,9 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4472 else 4929 else
4473 spos = min (XINT (Fline_end_position (Qnil)) + 1, ZV); 4930 spos = min (XINT (Fline_end_position (Qnil)) + 1, ZV);
4474 set_marker_restricted (w->start, make_number (spos), 4931 set_marker_restricted (w->start, make_number (spos),
4475 w->buffer); 4932 w->contents);
4476 w->start_at_line_beg = 1; 4933 w->start_at_line_beg = 1;
4477 w->update_mode_line = 1; 4934 w->update_mode_line = 1;
4478 w->last_modified = 0;
4479 w->last_overlay_modified = 0;
4480 /* Set force_start so that redisplay_window will run the 4935 /* Set force_start so that redisplay_window will run the
4481 window-scroll-functions. */ 4936 window-scroll-functions. */
4482 w->force_start = 1; 4937 w->force_start = 1;
@@ -4518,7 +4973,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4518 if (whole) 4973 if (whole)
4519 { 4974 {
4520 ptrdiff_t start_pos = IT_CHARPOS (it); 4975 ptrdiff_t start_pos = IT_CHARPOS (it);
4521 int dy = WINDOW_FRAME_LINE_HEIGHT (w); 4976 int dy = frame_line_height;
4522 dy = max ((window_box_height (w) 4977 dy = max ((window_box_height (w)
4523 - next_screen_context_lines * dy), 4978 - next_screen_context_lines * dy),
4524 dy) * n; 4979 dy) * n;
@@ -4565,7 +5020,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4565 visible. */ 5020 visible. */
4566 w->vscroll = (it.last_visible_y 5021 w->vscroll = (it.last_visible_y
4567 - it.current_y + it.max_ascent + it.max_descent); 5022 - it.current_y + it.max_ascent + it.max_descent);
4568 adjust_glyphs (it.f); 5023 adjust_frame_glyphs (it.f);
4569 } 5024 }
4570 else 5025 else
4571 { 5026 {
@@ -4596,7 +5051,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4596 5051
4597 /* If control gets here, then we vscrolled. */ 5052 /* If control gets here, then we vscrolled. */
4598 5053
4599 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 5054 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
4600 5055
4601 /* Don't try to change the window start below. */ 5056 /* Don't try to change the window start below. */
4602 vscrolled = 1; 5057 vscrolled = 1;
@@ -4616,13 +5071,11 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4616 } 5071 }
4617 5072
4618 /* Set the window start, and set up the window for redisplay. */ 5073 /* Set the window start, and set up the window for redisplay. */
4619 set_marker_restricted_both (w->start, w->buffer, IT_CHARPOS (it), 5074 set_marker_restricted_both (w->start, w->contents, IT_CHARPOS (it),
4620 IT_BYTEPOS (it)); 5075 IT_BYTEPOS (it));
4621 bytepos = marker_byte_position (w->start); 5076 bytepos = marker_byte_position (w->start);
4622 w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n'); 5077 w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n');
4623 w->update_mode_line = 1; 5078 w->update_mode_line = 1;
4624 w->last_modified = 0;
4625 w->last_overlay_modified = 0;
4626 /* Set force_start so that redisplay_window will run the 5079 /* Set force_start so that redisplay_window will run the
4627 window-scroll-functions. */ 5080 window-scroll-functions. */
4628 w->force_start = 1; 5081 w->force_start = 1;
@@ -4635,10 +5088,12 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4635 /* Move PT out of scroll margins. 5088 /* Move PT out of scroll margins.
4636 This code wants current_y to be zero at the window start position 5089 This code wants current_y to be zero at the window start position
4637 even if there is a header line. */ 5090 even if there is a header line. */
5091 window_total_lines
5092 = w->total_lines * WINDOW_FRAME_LINE_HEIGHT (w) / frame_line_height;
4638 this_scroll_margin = max (0, scroll_margin); 5093 this_scroll_margin = max (0, scroll_margin);
4639 this_scroll_margin 5094 this_scroll_margin
4640 = min (this_scroll_margin, XFASTINT (w->total_lines) / 4); 5095 = min (this_scroll_margin, window_total_lines / 4);
4641 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f); 5096 this_scroll_margin *= frame_line_height;
4642 5097
4643 if (n > 0) 5098 if (n > 0)
4644 { 5099 {
@@ -4743,7 +5198,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4743 See the comment of window_scroll for parameter descriptions. */ 5198 See the comment of window_scroll for parameter descriptions. */
4744 5199
4745static void 5200static void
4746window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror) 5201window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
4747{ 5202{
4748 register struct window *w = XWINDOW (window); 5203 register struct window *w = XWINDOW (window);
4749 /* Fvertical_motion enters redisplay, which can trigger 5204 /* Fvertical_motion enters redisplay, which can trigger
@@ -4755,9 +5210,10 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
4755 register ptrdiff_t pos, pos_byte; 5210 register ptrdiff_t pos, pos_byte;
4756 register int ht = window_internal_height (w); 5211 register int ht = window_internal_height (w);
4757 register Lisp_Object tem; 5212 register Lisp_Object tem;
4758 int lose; 5213 bool lose;
4759 Lisp_Object bolp; 5214 Lisp_Object bolp;
4760 ptrdiff_t startpos; 5215 ptrdiff_t startpos = marker_position (w->start);
5216 ptrdiff_t startbyte = marker_byte_position (w->start);
4761 Lisp_Object original_pos = Qnil; 5217 Lisp_Object original_pos = Qnil;
4762 5218
4763 /* If scrolling screen-fulls, compute the number of lines to 5219 /* If scrolling screen-fulls, compute the number of lines to
@@ -4765,8 +5221,6 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
4765 if (whole) 5221 if (whole)
4766 n *= max (1, ht - next_screen_context_lines); 5222 n *= max (1, ht - next_screen_context_lines);
4767 5223
4768 startpos = marker_position (w->start);
4769
4770 if (!NILP (Vscroll_preserve_screen_position)) 5224 if (!NILP (Vscroll_preserve_screen_position))
4771 { 5225 {
4772 if (window_scroll_preserve_vpos <= 0 5226 if (window_scroll_preserve_vpos <= 0
@@ -4774,10 +5228,8 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
4774 || NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command))) 5228 || NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command)))
4775 { 5229 {
4776 struct position posit 5230 struct position posit
4777 = *compute_motion (startpos, 0, 0, 0, 5231 = *compute_motion (startpos, startbyte, 0, 0, 0,
4778 PT, ht, 0, 5232 PT, ht, 0, -1, w->hscroll, 0, w);
4779 -1, w->hscroll,
4780 0, w);
4781 window_scroll_preserve_vpos = posit.vpos; 5233 window_scroll_preserve_vpos = posit.vpos;
4782 window_scroll_preserve_hpos = posit.hpos + w->hscroll; 5234 window_scroll_preserve_hpos = posit.hpos + w->hscroll;
4783 } 5235 }
@@ -4793,9 +5245,10 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
4793 { 5245 {
4794 Fvertical_motion (make_number (- (ht / 2)), window); 5246 Fvertical_motion (make_number (- (ht / 2)), window);
4795 startpos = PT; 5247 startpos = PT;
5248 startbyte = PT_BYTE;
4796 } 5249 }
4797 5250
4798 SET_PT (startpos); 5251 SET_PT_BOTH (startpos, startbyte);
4799 lose = n < 0 && PT == BEGV; 5252 lose = n < 0 && PT == BEGV;
4800 Fvertical_motion (make_number (n), window); 5253 Fvertical_motion (make_number (n), window);
4801 pos = PT; 5254 pos = PT;
@@ -4816,13 +5269,11 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
4816 { 5269 {
4817 /* Don't use a scroll margin that is negative or too large. */ 5270 /* Don't use a scroll margin that is negative or too large. */
4818 int this_scroll_margin = 5271 int this_scroll_margin =
4819 max (0, min (scroll_margin, XINT (w->total_lines) / 4)); 5272 max (0, min (scroll_margin, w->total_lines / 4));
4820 5273
4821 set_marker_restricted_both (w->start, w->buffer, pos, pos_byte); 5274 set_marker_restricted_both (w->start, w->contents, pos, pos_byte);
4822 w->start_at_line_beg = !NILP (bolp); 5275 w->start_at_line_beg = !NILP (bolp);
4823 w->update_mode_line = 1; 5276 w->update_mode_line = 1;
4824 w->last_modified = 0;
4825 w->last_overlay_modified = 0;
4826 /* Set force_start so that redisplay_window will run 5277 /* Set force_start so that redisplay_window will run
4827 the window-scroll-functions. */ 5278 the window-scroll-functions. */
4828 w->force_start = 1; 5279 w->force_start = 1;
@@ -4912,13 +5363,10 @@ scroll_command (Lisp_Object n, int direction)
4912 5363
4913 /* If selected window's buffer isn't current, make it current for 5364 /* If selected window's buffer isn't current, make it current for
4914 the moment. But don't screw up if window_scroll gets an error. */ 5365 the moment. But don't screw up if window_scroll gets an error. */
4915 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer) 5366 if (XBUFFER (XWINDOW (selected_window)->contents) != current_buffer)
4916 { 5367 {
4917 record_unwind_protect (save_excursion_restore, save_excursion_save ()); 5368 record_unwind_protect (save_excursion_restore, save_excursion_save ());
4918 Fset_buffer (XWINDOW (selected_window)->buffer); 5369 Fset_buffer (XWINDOW (selected_window)->contents);
4919
4920 /* Make redisplay consider other windows than just selected_window. */
4921 ++windows_or_buffers_changed;
4922 } 5370 }
4923 5371
4924 if (NILP (n)) 5372 if (NILP (n))
@@ -5028,10 +5476,9 @@ specifies the window to scroll. This takes precedence over
5028 5476
5029 /* Don't screw up if window_scroll gets an error. */ 5477 /* Don't screw up if window_scroll gets an error. */
5030 record_unwind_protect (save_excursion_restore, save_excursion_save ()); 5478 record_unwind_protect (save_excursion_restore, save_excursion_save ());
5031 ++windows_or_buffers_changed;
5032 5479
5033 Fset_buffer (w->buffer); 5480 Fset_buffer (w->contents);
5034 SET_PT (marker_position (w->pointm)); 5481 SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm));
5035 5482
5036 if (NILP (arg)) 5483 if (NILP (arg))
5037 window_scroll (window, 1, 1, 1); 5484 window_scroll (window, 1, 1, 1);
@@ -5064,7 +5511,7 @@ by this function. This happens in an interactive call. */)
5064{ 5511{
5065 struct window *w = XWINDOW (selected_window); 5512 struct window *w = XWINDOW (selected_window);
5066 EMACS_INT requested_arg = (NILP (arg) 5513 EMACS_INT requested_arg = (NILP (arg)
5067 ? window_body_cols (w) - 2 5514 ? window_body_width (w, 0) - 2
5068 : XINT (Fprefix_numeric_value (arg))); 5515 : XINT (Fprefix_numeric_value (arg)));
5069 Lisp_Object result = set_window_hscroll (w, w->hscroll + requested_arg); 5516 Lisp_Object result = set_window_hscroll (w, w->hscroll + requested_arg);
5070 5517
@@ -5087,7 +5534,7 @@ by this function. This happens in an interactive call. */)
5087{ 5534{
5088 struct window *w = XWINDOW (selected_window); 5535 struct window *w = XWINDOW (selected_window);
5089 EMACS_INT requested_arg = (NILP (arg) 5536 EMACS_INT requested_arg = (NILP (arg)
5090 ? window_body_cols (w) - 2 5537 ? window_body_width (w, 0) - 2
5091 : XINT (Fprefix_numeric_value (arg))); 5538 : XINT (Fprefix_numeric_value (arg)));
5092 Lisp_Object result = set_window_hscroll (w, w->hscroll - requested_arg); 5539 Lisp_Object result = set_window_hscroll (w, w->hscroll - requested_arg);
5093 5540
@@ -5118,16 +5565,15 @@ displayed_window_lines (struct window *w)
5118{ 5565{
5119 struct it it; 5566 struct it it;
5120 struct text_pos start; 5567 struct text_pos start;
5121 ptrdiff_t charpos = marker_position (w->start);
5122 int height = window_box_height (w); 5568 int height = window_box_height (w);
5123 struct buffer *old_buffer; 5569 struct buffer *old_buffer;
5124 int bottom_y; 5570 int bottom_y;
5125 void *itdata = NULL; 5571 void *itdata = NULL;
5126 5572
5127 if (XBUFFER (w->buffer) != current_buffer) 5573 if (XBUFFER (w->contents) != current_buffer)
5128 { 5574 {
5129 old_buffer = current_buffer; 5575 old_buffer = current_buffer;
5130 set_buffer_internal (XBUFFER (w->buffer)); 5576 set_buffer_internal (XBUFFER (w->contents));
5131 } 5577 }
5132 else 5578 else
5133 old_buffer = NULL; 5579 old_buffer = NULL;
@@ -5135,12 +5581,7 @@ displayed_window_lines (struct window *w)
5135 /* In case W->start is out of the accessible range, do something 5581 /* In case W->start is out of the accessible range, do something
5136 reasonable. This happens in Info mode when Info-scroll-down 5582 reasonable. This happens in Info mode when Info-scroll-down
5137 calls (recenter -1) while W->start is 1. */ 5583 calls (recenter -1) while W->start is 1. */
5138 if (charpos < BEGV) 5584 CLIP_TEXT_POS_FROM_MARKER (start, w->start);
5139 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
5140 else if (charpos > ZV)
5141 SET_TEXT_POS (start, ZV, ZV_BYTE);
5142 else
5143 SET_TEXT_POS_FROM_MARKER (start, w->start);
5144 5585
5145 itdata = bidi_shelve_cache (); 5586 itdata = bidi_shelve_cache ();
5146 start_display (&it, w, start); 5587 start_display (&it, w, start);
@@ -5189,9 +5630,9 @@ and redisplay normally--don't erase and redraw the frame. */)
5189 (register Lisp_Object arg) 5630 (register Lisp_Object arg)
5190{ 5631{
5191 struct window *w = XWINDOW (selected_window); 5632 struct window *w = XWINDOW (selected_window);
5192 struct buffer *buf = XBUFFER (w->buffer); 5633 struct buffer *buf = XBUFFER (w->contents);
5193 struct buffer *obuf = current_buffer; 5634 struct buffer *obuf = current_buffer;
5194 int center_p = 0; 5635 bool center_p = 0;
5195 ptrdiff_t charpos, bytepos; 5636 ptrdiff_t charpos, bytepos;
5196 EMACS_INT iarg IF_LINT (= 0); 5637 EMACS_INT iarg IF_LINT (= 0);
5197 int this_scroll_margin; 5638 int this_scroll_margin;
@@ -5210,9 +5651,9 @@ and redisplay normally--don't erase and redraw the frame. */)
5210 /* Invalidate pixel data calculated for all compositions. */ 5651 /* Invalidate pixel data calculated for all compositions. */
5211 for (i = 0; i < n_compositions; i++) 5652 for (i = 0; i < n_compositions; i++)
5212 composition_table[i]->font = NULL; 5653 composition_table[i]->font = NULL;
5213 5654#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
5214 WINDOW_XFRAME (w)->minimize_tool_bar_window_p = 1; 5655 WINDOW_XFRAME (w)->minimize_tool_bar_window_p = 1;
5215 5656#endif
5216 Fredraw_frame (WINDOW_FRAME (w)); 5657 Fredraw_frame (WINDOW_FRAME (w));
5217 SET_FRAME_GARBAGED (WINDOW_XFRAME (w)); 5658 SET_FRAME_GARBAGED (WINDOW_XFRAME (w));
5218 } 5659 }
@@ -5233,7 +5674,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5233 /* Do this after making BUF current 5674 /* Do this after making BUF current
5234 in case scroll_margin is buffer-local. */ 5675 in case scroll_margin is buffer-local. */
5235 this_scroll_margin = 5676 this_scroll_margin =
5236 max (0, min (scroll_margin, XFASTINT (w->total_lines) / 4)); 5677 max (0, min (scroll_margin, w->total_lines / 4));
5237 5678
5238 /* Handle centering on a graphical frame specially. Such frames can 5679 /* Handle centering on a graphical frame specially. Such frames can
5239 have variable-height lines and centering point on the basis of 5680 have variable-height lines and centering point on the basis of
@@ -5330,7 +5771,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5330 5771
5331 iarg = max (iarg, this_scroll_margin); 5772 iarg = max (iarg, this_scroll_margin);
5332 5773
5333 pos = *vmotion (PT, -iarg, w); 5774 pos = *vmotion (PT, PT_BYTE, -iarg, w);
5334 charpos = pos.bufpos; 5775 charpos = pos.bufpos;
5335 bytepos = pos.bytepos; 5776 bytepos = pos.bytepos;
5336 } 5777 }
@@ -5349,13 +5790,13 @@ and redisplay normally--don't erase and redraw the frame. */)
5349 iarg = clip_to_bounds (this_scroll_margin, iarg, 5790 iarg = clip_to_bounds (this_scroll_margin, iarg,
5350 ht - this_scroll_margin - 1); 5791 ht - this_scroll_margin - 1);
5351 5792
5352 pos = *vmotion (PT, - iarg, w); 5793 pos = *vmotion (PT, PT_BYTE, - iarg, w);
5353 charpos = pos.bufpos; 5794 charpos = pos.bufpos;
5354 bytepos = pos.bytepos; 5795 bytepos = pos.bytepos;
5355 } 5796 }
5356 5797
5357 /* Set the new window start. */ 5798 /* Set the new window start. */
5358 set_marker_both (w->start, w->buffer, charpos, bytepos); 5799 set_marker_both (w->start, w->contents, charpos, bytepos);
5359 w->window_end_valid = 0; 5800 w->window_end_valid = 0;
5360 5801
5361 w->optional_new_start = 1; 5802 w->optional_new_start = 1;
@@ -5367,22 +5808,36 @@ and redisplay normally--don't erase and redraw the frame. */)
5367 return Qnil; 5808 return Qnil;
5368} 5809}
5369 5810
5370DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height, 5811DEFUN ("window-text-width", Fwindow_text_width, Swindow_text_width,
5371 0, 1, 0, 5812 0, 1, 0,
5372 doc: /* Return the height in lines of the text display area of WINDOW. 5813 doc: /* Return the width in columns of the text display area of WINDOW.
5373WINDOW must be a live window and defaults to the selected one. 5814WINDOW must be a live window and defaults to the selected one.
5374 5815
5375The returned height does not include the mode line, any header line, 5816The returned width does not include dividers, scrollbars, margins,
5376nor any partial-height lines at the bottom of the text area. */) 5817fringes, nor any partial-width columns at the right of the text
5818area. */)
5377 (Lisp_Object window) 5819 (Lisp_Object window)
5378{ 5820{
5379 struct window *w = decode_live_window (window); 5821 struct window *w = decode_live_window (window);
5380 int pixel_height = window_box_height (w); 5822
5381 int line_height = pixel_height / FRAME_LINE_HEIGHT (XFRAME (w->frame)); 5823 return make_number (window_box_width (w, TEXT_AREA)
5382 return make_number (line_height); 5824 / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w)));
5383} 5825}
5384 5826
5827DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
5828 0, 1, 0,
5829 doc: /* Return the height in lines of the text display area of WINDOW.
5830WINDOW must be a live window and defaults to the selected one.
5831
5832The returned height does not include dividers, the mode line, any header
5833line, nor any partial-height lines at the bottom of the text area. */)
5834 (Lisp_Object window)
5835{
5836 struct window *w = decode_live_window (window);
5385 5837
5838 return make_number (window_box_height (w)
5839 / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)));
5840}
5386 5841
5387DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line, 5842DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line,
5388 1, 1, "P", 5843 1, 1, "P",
@@ -5399,9 +5854,8 @@ zero means top of window, negative means relative to bottom of window. */)
5399 int this_scroll_margin; 5854 int this_scroll_margin;
5400#endif 5855#endif
5401 5856
5402 if (!(BUFFERP (w->buffer) 5857 if (!(BUFFERP (w->contents) && XBUFFER (w->contents) == current_buffer))
5403 && XBUFFER (w->buffer) == current_buffer)) 5858 /* This test is needed to make sure PT/PT_BYTE make sense in w->contents
5404 /* This test is needed to make sure PT/PT_BYTE make sense in w->buffer
5405 when passed below to set_marker_both. */ 5859 when passed below to set_marker_both. */
5406 error ("move-to-window-line called from unrelated buffer"); 5860 error ("move-to-window-line called from unrelated buffer");
5407 5861
@@ -5411,7 +5865,7 @@ zero means top of window, negative means relative to bottom of window. */)
5411 { 5865 {
5412 int height = window_internal_height (w); 5866 int height = window_internal_height (w);
5413 Fvertical_motion (make_number (- (height / 2)), window); 5867 Fvertical_motion (make_number (- (height / 2)), window);
5414 set_marker_both (w->start, w->buffer, PT, PT_BYTE); 5868 set_marker_both (w->start, w->contents, PT, PT_BYTE);
5415 w->start_at_line_beg = !NILP (Fbolp ()); 5869 w->start_at_line_beg = !NILP (Fbolp ());
5416 w->force_start = 1; 5870 w->force_start = 1;
5417 } 5871 }
@@ -5475,10 +5929,16 @@ struct save_window_data
5475 Lisp_Object saved_windows; 5929 Lisp_Object saved_windows;
5476 5930
5477 /* All fields above are traced by the GC. 5931 /* All fields above are traced by the GC.
5478 From `fame-cols' down, the fields are ignored by the GC. */ 5932 From `frame-cols' down, the fields are ignored by the GC. */
5479 5933 /* We should be able to do without the following two. */
5480 int frame_cols, frame_lines, frame_menu_bar_lines; 5934 int frame_cols, frame_lines;
5481 int frame_tool_bar_lines; 5935 /* These two should get eventually replaced by their pixel
5936 counterparts. */
5937 int frame_menu_bar_lines, frame_tool_bar_lines;
5938 int frame_text_width, frame_text_height;
5939 /* These are currently unused. We need them as soon as we convert
5940 to pixels. */
5941 int frame_menu_bar_height, frame_tool_bar_height;
5482 }; 5942 };
5483 5943
5484/* This is saved as a Lisp_Vector */ 5944/* This is saved as a Lisp_Vector */
@@ -5487,6 +5947,7 @@ struct saved_window
5487 struct vectorlike_header header; 5947 struct vectorlike_header header;
5488 5948
5489 Lisp_Object window, buffer, start, pointm, mark; 5949 Lisp_Object window, buffer, start, pointm, mark;
5950 Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width;
5490 Lisp_Object left_col, top_line, total_cols, total_lines; 5951 Lisp_Object left_col, top_line, total_cols, total_lines;
5491 Lisp_Object normal_cols, normal_lines; 5952 Lisp_Object normal_cols, normal_lines;
5492 Lisp_Object hscroll, min_hscroll; 5953 Lisp_Object hscroll, min_hscroll;
@@ -5523,6 +5984,13 @@ DEFUN ("window-configuration-frame", Fwindow_configuration_frame, Swindow_config
5523 return XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame; 5984 return XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame;
5524} 5985}
5525 5986
5987/* From Chong's unwind_create_frame_1. */
5988static void
5989unwind_change_frame (Lisp_Object val)
5990{
5991 inhibit_lisp_code = val;
5992}
5993
5526DEFUN ("set-window-configuration", Fset_window_configuration, 5994DEFUN ("set-window-configuration", Fset_window_configuration,
5527 Sset_window_configuration, 1, 1, 0, 5995 Sset_window_configuration, 1, 1, 0,
5528 doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION. 5996 doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
@@ -5537,7 +6005,7 @@ the return value is nil. Otherwise the value is t. */)
5537 struct Lisp_Vector *saved_windows; 6005 struct Lisp_Vector *saved_windows;
5538 Lisp_Object new_current_buffer; 6006 Lisp_Object new_current_buffer;
5539 Lisp_Object frame; 6007 Lisp_Object frame;
5540 FRAME_PTR f; 6008 struct frame *f;
5541 ptrdiff_t old_point = -1; 6009 ptrdiff_t old_point = -1;
5542 6010
5543 CHECK_WINDOW_CONFIGURATION (configuration); 6011 CHECK_WINDOW_CONFIGURATION (configuration);
@@ -5561,9 +6029,9 @@ the return value is nil. Otherwise the value is t. */)
5561 window-point of the final-selected-window to the window-point of 6029 window-point of the final-selected-window to the window-point of
5562 the current-selected-window. So we have to be careful which 6030 the current-selected-window. So we have to be careful which
5563 point of the current-buffer we copy into old_point. */ 6031 point of the current-buffer we copy into old_point. */
5564 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer) 6032 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
5565 && WINDOWP (selected_window) 6033 && WINDOWP (selected_window)
5566 && EQ (XWINDOW (selected_window)->buffer, new_current_buffer) 6034 && EQ (XWINDOW (selected_window)->contents, new_current_buffer)
5567 && !EQ (selected_window, data->current_window)) 6035 && !EQ (selected_window, data->current_window))
5568 old_point = marker_position (XWINDOW (data->current_window)->pointm); 6036 old_point = marker_position (XWINDOW (data->current_window)->pointm);
5569 else 6037 else
@@ -5577,7 +6045,7 @@ the return value is nil. Otherwise the value is t. */)
5577 So if possible we want this arbitrary choice of "which point" to 6045 So if possible we want this arbitrary choice of "which point" to
5578 be the one from the to-be-selected-window so as to prevent this 6046 be the one from the to-be-selected-window so as to prevent this
5579 window's cursor from being copied from another window. */ 6047 window's cursor from being copied from another window. */
5580 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer) 6048 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
5581 /* If current_window = selected_window, its point is in BUF_PT. */ 6049 /* If current_window = selected_window, its point is in BUF_PT. */
5582 && !EQ (selected_window, data->current_window)) 6050 && !EQ (selected_window, data->current_window))
5583 old_point = marker_position (XWINDOW (data->current_window)->pointm); 6051 old_point = marker_position (XWINDOW (data->current_window)->pointm);
@@ -5602,13 +6070,17 @@ the return value is nil. Otherwise the value is t. */)
5602 int n_leaf_windows; 6070 int n_leaf_windows;
5603 ptrdiff_t k; 6071 ptrdiff_t k;
5604 int i, n; 6072 int i, n;
5605 6073 ptrdiff_t count = SPECPDL_INDEX ();
5606 /* If the frame has been resized since this window configuration was 6074 /* If the frame has been resized since this window configuration was
5607 made, we change the frame to the size specified in the 6075 made, we change the frame to the size specified in the
5608 configuration, restore the configuration, and then resize it 6076 configuration, restore the configuration, and then resize it
5609 back. We keep track of the prevailing height in these variables. */ 6077 back. We keep track of the prevailing height in these variables. */
5610 int previous_frame_lines = FRAME_LINES (f); 6078 int previous_frame_text_height = FRAME_TEXT_HEIGHT (f);
5611 int previous_frame_cols = FRAME_COLS (f); 6079 int previous_frame_text_width = FRAME_TEXT_WIDTH (f);
6080 /* int previous_frame_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f); */
6081 /* int previous_frame_tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f); */
6082 /* int previous_frame_lines = FRAME_LINES (f); */
6083 /* int previous_frame_cols = FRAME_COLS (f); */
5612 int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f); 6084 int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
5613 int previous_frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f); 6085 int previous_frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
5614 6086
@@ -5619,50 +6091,59 @@ the return value is nil. Otherwise the value is t. */)
5619 p = SAVED_WINDOW_N (saved_windows, k); 6091 p = SAVED_WINDOW_N (saved_windows, k);
5620 window = p->window; 6092 window = p->window;
5621 w = XWINDOW (window); 6093 w = XWINDOW (window);
5622 if (!NILP (w->buffer) 6094 if (BUFFERP (w->contents)
5623 && !EQ (w->buffer, p->buffer) 6095 && !EQ (w->contents, p->buffer)
5624 && BUFFER_LIVE_P (XBUFFER (p->buffer))) 6096 && BUFFER_LIVE_P (XBUFFER (p->buffer)))
5625 /* If a window we restore gets another buffer, record the 6097 /* If a window we restore gets another buffer, record the
5626 window's old buffer. */ 6098 window's old buffer. */
5627 call1 (Qrecord_window_buffer, window); 6099 call1 (Qrecord_window_buffer, window);
5628 } 6100 }
5629 6101
6102 /* Don't run lisp in the following segment since the frame is in a
6103 completely inconsistent state. See Bug#16207. */
6104 record_unwind_protect (unwind_change_frame, inhibit_lisp_code);
6105 inhibit_lisp_code = Qt;
5630 /* The mouse highlighting code could get screwed up 6106 /* The mouse highlighting code could get screwed up
5631 if it runs during this. */ 6107 if it runs during this. */
5632 block_input (); 6108 block_input ();
5633 6109
5634 if (data->frame_lines != previous_frame_lines 6110 if (data->frame_text_width != previous_frame_text_width
5635 || data->frame_cols != previous_frame_cols) 6111 || data->frame_text_height != previous_frame_text_height)
5636 change_frame_size (f, data->frame_lines, 6112 change_frame_size (f, data->frame_text_width,
5637 data->frame_cols, 0, 0, 0); 6113 data->frame_text_height, 0, 0, 0, 1);
5638#if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS) 6114
5639 if (data->frame_menu_bar_lines 6115 if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines)
5640 != previous_frame_menu_bar_lines) 6116 {
5641 x_set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines), 6117#ifdef HAVE_WINDOW_SYSTEM
5642 make_number (0)); 6118 if (FRAME_WINDOW_P (f))
6119 x_set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines),
6120 make_number (0));
6121 else /* TTY or MSDOS */
6122#endif
6123 set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines),
6124 make_number (0));
6125 }
5643#ifdef HAVE_WINDOW_SYSTEM 6126#ifdef HAVE_WINDOW_SYSTEM
5644 if (data->frame_tool_bar_lines 6127 if (data->frame_tool_bar_lines != previous_frame_tool_bar_lines)
5645 != previous_frame_tool_bar_lines)
5646 x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines), 6128 x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines),
5647 make_number (0)); 6129 make_number (0));
5648#endif 6130#endif
5649#endif
5650 6131
5651 /* "Swap out" point from the selected window's buffer 6132 /* "Swap out" point from the selected window's buffer
5652 into the window itself. (Normally the pointm of the selected 6133 into the window itself. (Normally the pointm of the selected
5653 window holds garbage.) We do this now, before 6134 window holds garbage.) We do this now, before
5654 restoring the window contents, and prevent it from 6135 restoring the window contents, and prevent it from
5655 being done later on when we select a new window. */ 6136 being done later on when we select a new window. */
5656 if (! NILP (XWINDOW (selected_window)->buffer)) 6137 if (! NILP (XWINDOW (selected_window)->contents))
5657 { 6138 {
5658 w = XWINDOW (selected_window); 6139 w = XWINDOW (selected_window);
5659 set_marker_both (w->pointm, 6140 set_marker_both (w->pointm,
5660 w->buffer, 6141 w->contents,
5661 BUF_PT (XBUFFER (w->buffer)), 6142 BUF_PT (XBUFFER (w->contents)),
5662 BUF_PT_BYTE (XBUFFER (w->buffer))); 6143 BUF_PT_BYTE (XBUFFER (w->contents)));
5663 } 6144 }
5664 6145
5665 windows_or_buffers_changed++; 6146 fset_redisplay (f);
5666 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 6147 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
5667 6148
5668 /* Problem: Freeing all matrices and later allocating them again 6149 /* Problem: Freeing all matrices and later allocating them again
@@ -5706,39 +6187,34 @@ the return value is nil. Otherwise the value is t. */)
5706 { 6187 {
5707 wset_prev (w, Qnil); 6188 wset_prev (w, Qnil);
5708 if (!NILP (w->parent)) 6189 if (!NILP (w->parent))
5709 { 6190 wset_combination (XWINDOW (w->parent),
5710 if (EQ (p->total_cols, XWINDOW (w->parent)->total_cols)) 6191 (XINT (p->total_cols)
5711 { 6192 != XWINDOW (w->parent)->total_cols),
5712 wset_vchild (XWINDOW (w->parent), p->window); 6193 p->window);
5713 wset_hchild (XWINDOW (w->parent), Qnil);
5714 }
5715 else
5716 {
5717 wset_hchild (XWINDOW (w->parent), p->window);
5718 wset_vchild (XWINDOW (w->parent), Qnil);
5719 }
5720 }
5721 } 6194 }
5722 6195
5723 /* If we squirreled away the buffer in the window's height, 6196 /* If we squirreled away the buffer, restore it now. */
5724 restore it now. */ 6197 if (BUFFERP (w->combination_limit))
5725 if (BUFFERP (w->total_lines)) 6198 wset_buffer (w, w->combination_limit);
5726 wset_buffer (w, w->total_lines); 6199 w->pixel_left = XFASTINT (p->pixel_left);
5727 wset_left_col (w, p->left_col); 6200 w->pixel_top = XFASTINT (p->pixel_top);
5728 wset_top_line (w, p->top_line); 6201 w->pixel_width = XFASTINT (p->pixel_width);
5729 wset_total_cols (w, p->total_cols); 6202 w->pixel_height = XFASTINT (p->pixel_height);
5730 wset_total_lines (w, p->total_lines); 6203 w->left_col = XFASTINT (p->left_col);
6204 w->top_line = XFASTINT (p->top_line);
6205 w->total_cols = XFASTINT (p->total_cols);
6206 w->total_lines = XFASTINT (p->total_lines);
5731 wset_normal_cols (w, p->normal_cols); 6207 wset_normal_cols (w, p->normal_cols);
5732 wset_normal_lines (w, p->normal_lines); 6208 wset_normal_lines (w, p->normal_lines);
5733 w->hscroll = XFASTINT (p->hscroll); 6209 w->hscroll = XFASTINT (p->hscroll);
5734 w->min_hscroll = XFASTINT (p->min_hscroll); 6210 w->min_hscroll = XFASTINT (p->min_hscroll);
5735 wset_display_table (w, p->display_table); 6211 wset_display_table (w, p->display_table);
5736 wset_left_margin_cols (w, p->left_margin_cols); 6212 w->left_margin_cols = XINT (p->left_margin_cols);
5737 wset_right_margin_cols (w, p->right_margin_cols); 6213 w->right_margin_cols = XINT (p->right_margin_cols);
5738 wset_left_fringe_width (w, p->left_fringe_width); 6214 w->left_fringe_width = XINT (p->left_fringe_width);
5739 wset_right_fringe_width (w, p->right_fringe_width); 6215 w->right_fringe_width = XINT (p->right_fringe_width);
5740 w->fringes_outside_margins = !NILP (p->fringes_outside_margins); 6216 w->fringes_outside_margins = !NILP (p->fringes_outside_margins);
5741 wset_scroll_bar_width (w, p->scroll_bar_width); 6217 w->scroll_bar_width = XINT (p->scroll_bar_width);
5742 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type); 6218 wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type);
5743 wset_dedicated (w, p->dedicated); 6219 wset_dedicated (w, p->dedicated);
5744 wset_combination_limit (w, p->combination_limit); 6220 wset_combination_limit (w, p->combination_limit);
@@ -5764,23 +6240,16 @@ the return value is nil. Otherwise the value is t. */)
5764 } 6240 }
5765 } 6241 }
5766 6242
5767 w->last_modified = 0; 6243 if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
5768 w->last_overlay_modified = 0;
5769
5770 /* Reinstall the saved buffer and pointers into it. */
5771 if (NILP (p->buffer))
5772 /* An internal window. */
5773 wset_buffer (w, p->buffer);
5774 else if (BUFFER_LIVE_P (XBUFFER (p->buffer)))
5775 /* If saved buffer is alive, install it. */ 6244 /* If saved buffer is alive, install it. */
5776 { 6245 {
5777 wset_buffer (w, p->buffer); 6246 wset_buffer (w, p->buffer);
5778 w->start_at_line_beg = !NILP (p->start_at_line_beg); 6247 w->start_at_line_beg = !NILP (p->start_at_line_beg);
5779 set_marker_restricted (w->start, p->start, w->buffer); 6248 set_marker_restricted (w->start, p->start, w->contents);
5780 set_marker_restricted (w->pointm, p->pointm, 6249 set_marker_restricted (w->pointm, p->pointm,
5781 w->buffer); 6250 w->contents);
5782 Fset_marker (BVAR (XBUFFER (w->buffer), mark), 6251 Fset_marker (BVAR (XBUFFER (w->contents), mark),
5783 p->mark, w->buffer); 6252 p->mark, w->contents);
5784 6253
5785 /* As documented in Fcurrent_window_configuration, don't 6254 /* As documented in Fcurrent_window_configuration, don't
5786 restore the location of point in the buffer which was 6255 restore the location of point in the buffer which was
@@ -5789,23 +6258,21 @@ the return value is nil. Otherwise the value is t. */)
5789 && XBUFFER (p->buffer) == current_buffer) 6258 && XBUFFER (p->buffer) == current_buffer)
5790 Fgoto_char (w->pointm); 6259 Fgoto_char (w->pointm);
5791 } 6260 }
5792 else if (!NILP (w->buffer) 6261 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
5793 && BUFFER_LIVE_P (XBUFFER (w->buffer))) 6262 /* Keep window's old buffer; make sure the markers are real. */
5794 /* Keep window's old buffer; make sure the markers are 6263 {
5795 real. */ 6264 /* Set window markers at start of visible range. */
5796 { 6265 if (XMARKER (w->start)->buffer == 0)
5797 /* Set window markers at start of visible range. */ 6266 set_marker_restricted_both (w->start, w->contents, 0, 0);
5798 if (XMARKER (w->start)->buffer == 0) 6267 if (XMARKER (w->pointm)->buffer == 0)
5799 set_marker_restricted_both (w->start, w->buffer, 0, 0); 6268 set_marker_restricted_both
5800 if (XMARKER (w->pointm)->buffer == 0) 6269 (w->pointm, w->contents,
5801 set_marker_restricted_both 6270 BUF_PT (XBUFFER (w->contents)),
5802 (w->pointm, w->buffer, 6271 BUF_PT_BYTE (XBUFFER (w->contents)));
5803 BUF_PT (XBUFFER (w->buffer)), 6272 w->start_at_line_beg = 1;
5804 BUF_PT_BYTE (XBUFFER (w->buffer))); 6273 }
5805 w->start_at_line_beg = 1; 6274 else if (!NILP (w->start))
5806 } 6275 /* Leaf window has no live buffer, get one. */
5807 else
5808 /* Window has no live buffer, get one. */
5809 { 6276 {
5810 /* Get the buffer via other_buffer_safely in order to 6277 /* Get the buffer via other_buffer_safely in order to
5811 avoid showing an unimportant buffer and, if necessary, to 6278 avoid showing an unimportant buffer and, if necessary, to
@@ -5814,8 +6281,8 @@ the return value is nil. Otherwise the value is t. */)
5814 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ())); 6281 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
5815 /* This will set the markers to beginning of visible 6282 /* This will set the markers to beginning of visible
5816 range. */ 6283 range. */
5817 set_marker_restricted_both (w->start, w->buffer, 0, 0); 6284 set_marker_restricted_both (w->start, w->contents, 0, 0);
5818 set_marker_restricted_both (w->pointm, w->buffer, 0, 0); 6285 set_marker_restricted_both (w->pointm, w->contents, 0, 0);
5819 w->start_at_line_beg = 1; 6286 w->start_at_line_beg = 1;
5820 if (!NILP (w->dedicated)) 6287 if (!NILP (w->dedicated))
5821 /* Record this window as dead. */ 6288 /* Record this window as dead. */
@@ -5828,17 +6295,21 @@ the return value is nil. Otherwise the value is t. */)
5828 fset_root_window (f, data->root_window); 6295 fset_root_window (f, data->root_window);
5829 /* Arrange *not* to restore point in the buffer that was 6296 /* Arrange *not* to restore point in the buffer that was
5830 current when the window configuration was saved. */ 6297 current when the window configuration was saved. */
5831 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)) 6298 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
5832 set_marker_restricted (XWINDOW (data->current_window)->pointm, 6299 set_marker_restricted (XWINDOW (data->current_window)->pointm,
5833 make_number (old_point), 6300 make_number (old_point),
5834 XWINDOW (data->current_window)->buffer); 6301 XWINDOW (data->current_window)->contents);
5835 6302
5836 /* In the following call to `select-window', prevent "swapping out 6303 /* In the following call to `select-window', prevent "swapping out
5837 point" in the old selected window using the buffer that has 6304 point" in the old selected window using the buffer that has
5838 been restored into it. We already swapped out that point from 6305 been restored into it. We already swapped out that point from
5839 that window's old buffer. */ 6306 that window's old buffer.
5840 select_window (data->current_window, Qnil, 1); 6307
5841 BVAR (XBUFFER (XWINDOW (selected_window)->buffer), last_selected_window) 6308 Do not record the buffer here. We do that in a separate call
6309 to select_window below. See also Bug#16207. */
6310 select_window (data->current_window, Qt, 1);
6311 BVAR (XBUFFER (XWINDOW (selected_window)->contents),
6312 last_selected_window)
5842 = selected_window; 6313 = selected_window;
5843 6314
5844 if (NILP (data->focus_frame) 6315 if (NILP (data->focus_frame)
@@ -5846,38 +6317,42 @@ the return value is nil. Otherwise the value is t. */)
5846 && FRAME_LIVE_P (XFRAME (data->focus_frame)))) 6317 && FRAME_LIVE_P (XFRAME (data->focus_frame))))
5847 Fredirect_frame_focus (frame, data->focus_frame); 6318 Fredirect_frame_focus (frame, data->focus_frame);
5848 6319
5849 /* Set the screen height to the value it had before this function. */ 6320 /* Set the frame size to the value it had before this function. */
5850 if (previous_frame_lines != FRAME_LINES (f) 6321 if (previous_frame_text_width != FRAME_TEXT_WIDTH (f)
5851 || previous_frame_cols != FRAME_COLS (f)) 6322 || previous_frame_text_height != FRAME_TEXT_HEIGHT (f))
5852 change_frame_size (f, previous_frame_lines, previous_frame_cols, 6323 change_frame_size (f, previous_frame_text_width,
5853 0, 0, 0); 6324 previous_frame_text_height, 0, 0, 0, 1);
5854#if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS) 6325
5855 if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f)) 6326 if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f))
5856 x_set_menu_bar_lines (f, make_number (previous_frame_menu_bar_lines), 6327 {
5857 make_number (0)); 6328#ifdef HAVE_WINDOW_SYSTEM
6329 if (FRAME_WINDOW_P (f))
6330 x_set_menu_bar_lines (f,
6331 make_number (previous_frame_menu_bar_lines),
6332 make_number (0));
6333 else /* TTY or MSDOS */
6334#endif
6335 set_menu_bar_lines (f, make_number (previous_frame_menu_bar_lines),
6336 make_number (0));
6337 }
5858#ifdef HAVE_WINDOW_SYSTEM 6338#ifdef HAVE_WINDOW_SYSTEM
5859 if (previous_frame_tool_bar_lines != FRAME_TOOL_BAR_LINES (f)) 6339 if (previous_frame_tool_bar_lines != FRAME_TOOL_BAR_LINES (f))
5860 x_set_tool_bar_lines (f, make_number (previous_frame_tool_bar_lines), 6340 x_set_tool_bar_lines (f, make_number (previous_frame_tool_bar_lines),
5861 make_number (0)); 6341 make_number (0));
5862#endif 6342#endif
5863#endif
5864 6343
5865 /* Now, free glyph matrices in windows that were not reused. */ 6344 /* Now, free glyph matrices in windows that were not reused. */
5866 for (i = n = 0; i < n_leaf_windows; ++i) 6345 for (i = n = 0; i < n_leaf_windows; ++i)
5867 { 6346 {
5868 if (NILP (leaf_windows[i]->buffer)) 6347 if (NILP (leaf_windows[i]->contents))
5869 { 6348 free_window_matrices (leaf_windows[i]);
5870 /* Assert it's not reused as a combination. */ 6349 else if (EQ (leaf_windows[i]->contents, new_current_buffer))
5871 eassert (NILP (leaf_windows[i]->hchild)
5872 && NILP (leaf_windows[i]->vchild));
5873 free_window_matrices (leaf_windows[i]);
5874 }
5875 else if (EQ (leaf_windows[i]->buffer, new_current_buffer))
5876 ++n; 6350 ++n;
5877 } 6351 }
5878 6352
5879 adjust_glyphs (f); 6353 adjust_frame_glyphs (f);
5880 unblock_input (); 6354 unblock_input ();
6355 unbind_to (count, Qnil);
5881 6356
5882 /* Scan dead buffer windows. */ 6357 /* Scan dead buffer windows. */
5883 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows)) 6358 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
@@ -5887,6 +6362,10 @@ the return value is nil. Otherwise the value is t. */)
5887 delete_deletable_window (window); 6362 delete_deletable_window (window);
5888 } 6363 }
5889 6364
6365 /* Record the selected window's buffer here. The window should
6366 already be the selected one from the call above. */
6367 select_window (data->current_window, Qnil, 0);
6368
5890 /* Fselect_window will have made f the selected frame, so we 6369 /* Fselect_window will have made f the selected frame, so we
5891 reselect the proper frame here. Fhandle_switch_frame will change the 6370 reselect the proper frame here. Fhandle_switch_frame will change the
5892 selected window too, but that doesn't make the call to 6371 selected window too, but that doesn't make the call to
@@ -5903,7 +6382,7 @@ the return value is nil. Otherwise the value is t. */)
5903 Fset_buffer (new_current_buffer); 6382 Fset_buffer (new_current_buffer);
5904 /* If the new current buffer doesn't appear in the selected 6383 /* If the new current buffer doesn't appear in the selected
5905 window, go to its old point (see bug#12208). */ 6384 window, go to its old point (see bug#12208). */
5906 if (!EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)) 6385 if (!EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
5907 Fgoto_char (make_number (old_point)); 6386 Fgoto_char (make_number (old_point));
5908 } 6387 }
5909 6388
@@ -5913,9 +6392,17 @@ the return value is nil. Otherwise the value is t. */)
5913 return (FRAME_LIVE_P (f) ? Qt : Qnil); 6392 return (FRAME_LIVE_P (f) ? Qt : Qnil);
5914} 6393}
5915 6394
6395void
6396restore_window_configuration (Lisp_Object configuration)
6397{
6398 Fset_window_configuration (configuration);
6399}
6400
6401
6402/* If WINDOW is an internal window, recursively delete all child windows
6403 reachable via the next and contents slots of WINDOW. Otherwise setup
6404 WINDOW to not show any buffer. */
5916 6405
5917/* Recursively delete all child windows reachable via the next, vchild,
5918 and hchild slots of WINDOW. */
5919void 6406void
5920delete_all_child_windows (Lisp_Object window) 6407delete_all_child_windows (Lisp_Object window)
5921{ 6408{
@@ -5927,24 +6414,20 @@ delete_all_child_windows (Lisp_Object window)
5927 /* Delete WINDOW's siblings (we traverse postorderly). */ 6414 /* Delete WINDOW's siblings (we traverse postorderly). */
5928 delete_all_child_windows (w->next); 6415 delete_all_child_windows (w->next);
5929 6416
5930 /* See Fset_window_configuration for excuse. */ 6417 if (WINDOWP (w->contents))
5931 wset_total_lines (w, w->buffer);
5932
5933 if (!NILP (w->vchild))
5934 {
5935 delete_all_child_windows (w->vchild);
5936 wset_vchild (w, Qnil);
5937 }
5938 else if (!NILP (w->hchild))
5939 { 6418 {
5940 delete_all_child_windows (w->hchild); 6419 delete_all_child_windows (w->contents);
5941 wset_hchild (w, Qnil); 6420 wset_combination (w, 0, Qnil);
5942 } 6421 }
5943 else if (!NILP (w->buffer)) 6422 else if (BUFFERP (w->contents))
5944 { 6423 {
5945 unshow_buffer (w); 6424 unshow_buffer (w);
5946 unchain_marker (XMARKER (w->pointm)); 6425 unchain_marker (XMARKER (w->pointm));
5947 unchain_marker (XMARKER (w->start)); 6426 unchain_marker (XMARKER (w->start));
6427 /* Since combination limit makes sense for an internal windows
6428 only, we use this slot to save the buffer for the sake of
6429 possible resurrection in Fset_window_configuration. */
6430 wset_combination_limit (w, w->contents);
5948 wset_buffer (w, Qnil); 6431 wset_buffer (w, Qnil);
5949 } 6432 }
5950 6433
@@ -5957,10 +6440,8 @@ count_windows (register struct window *window)
5957 register int count = 1; 6440 register int count = 1;
5958 if (!NILP (window->next)) 6441 if (!NILP (window->next))
5959 count += count_windows (XWINDOW (window->next)); 6442 count += count_windows (XWINDOW (window->next));
5960 if (!NILP (window->vchild)) 6443 if (WINDOWP (window->contents))
5961 count += count_windows (XWINDOW (window->vchild)); 6444 count += count_windows (XWINDOW (window->contents));
5962 if (!NILP (window->hchild))
5963 count += count_windows (XWINDOW (window->hchild));
5964 return count; 6445 return count;
5965} 6446}
5966 6447
@@ -5972,10 +6453,8 @@ get_leaf_windows (struct window *w, struct window **flat, int i)
5972{ 6453{
5973 while (w) 6454 while (w)
5974 { 6455 {
5975 if (!NILP (w->hchild)) 6456 if (WINDOWP (w->contents))
5976 i = get_leaf_windows (XWINDOW (w->hchild), flat, i); 6457 i = get_leaf_windows (XWINDOW (w->contents), flat, i);
5977 else if (!NILP (w->vchild))
5978 i = get_leaf_windows (XWINDOW (w->vchild), flat, i);
5979 else 6458 else
5980 flat[i++] = w; 6459 flat[i++] = w;
5981 6460
@@ -6015,8 +6494,7 @@ get_phys_cursor_glyph (struct window *w)
6015 hpos = row->used[TEXT_AREA] - 1; 6494 hpos = row->used[TEXT_AREA] - 1;
6016 } 6495 }
6017 6496
6018 if (row->used[TEXT_AREA] > hpos 6497 if (0 <= hpos && hpos < row->used[TEXT_AREA])
6019 && 0 <= hpos)
6020 glyph = row->glyphs[TEXT_AREA] + hpos; 6498 glyph = row->glyphs[TEXT_AREA] + hpos;
6021 else 6499 else
6022 glyph = NULL; 6500 glyph = NULL;
@@ -6032,29 +6510,33 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6032 register struct window *w; 6510 register struct window *w;
6033 register Lisp_Object tem, pers, par; 6511 register Lisp_Object tem, pers, par;
6034 6512
6035 for (;!NILP (window); window = w->next) 6513 for (; !NILP (window); window = w->next)
6036 { 6514 {
6037 p = SAVED_WINDOW_N (vector, i); 6515 p = SAVED_WINDOW_N (vector, i);
6038 w = XWINDOW (window); 6516 w = XWINDOW (window);
6039 6517
6040 wset_temslot (w, make_number (i)); i++; 6518 wset_temslot (w, make_number (i)); i++;
6041 p->window = window; 6519 p->window = window;
6042 p->buffer = w->buffer; 6520 p->buffer = (WINDOW_LEAF_P (w) ? w->contents : Qnil);
6043 p->left_col = w->left_col; 6521 p->pixel_left = make_number (w->pixel_left);
6044 p->top_line = w->top_line; 6522 p->pixel_top = make_number (w->pixel_top);
6045 p->total_cols = w->total_cols; 6523 p->pixel_width = make_number (w->pixel_width);
6046 p->total_lines = w->total_lines; 6524 p->pixel_height = make_number (w->pixel_height);
6525 p->left_col = make_number (w->left_col);
6526 p->top_line = make_number (w->top_line);
6527 p->total_cols = make_number (w->total_cols);
6528 p->total_lines = make_number (w->total_lines);
6047 p->normal_cols = w->normal_cols; 6529 p->normal_cols = w->normal_cols;
6048 p->normal_lines = w->normal_lines; 6530 p->normal_lines = w->normal_lines;
6049 XSETFASTINT (p->hscroll, w->hscroll); 6531 XSETFASTINT (p->hscroll, w->hscroll);
6050 XSETFASTINT (p->min_hscroll, w->min_hscroll); 6532 XSETFASTINT (p->min_hscroll, w->min_hscroll);
6051 p->display_table = w->display_table; 6533 p->display_table = w->display_table;
6052 p->left_margin_cols = w->left_margin_cols; 6534 p->left_margin_cols = make_number (w->left_margin_cols);
6053 p->right_margin_cols = w->right_margin_cols; 6535 p->right_margin_cols = make_number (w->right_margin_cols);
6054 p->left_fringe_width = w->left_fringe_width; 6536 p->left_fringe_width = make_number (w->left_fringe_width);
6055 p->right_fringe_width = w->right_fringe_width; 6537 p->right_fringe_width = make_number (w->right_fringe_width);
6056 p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil; 6538 p->fringes_outside_margins = w->fringes_outside_margins ? Qt : Qnil;
6057 p->scroll_bar_width = w->scroll_bar_width; 6539 p->scroll_bar_width = make_number (w->scroll_bar_width);
6058 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type; 6540 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
6059 p->dedicated = w->dedicated; 6541 p->dedicated = w->dedicated;
6060 p->combination_limit = w->combination_limit; 6542 p->combination_limit = w->combination_limit;
@@ -6106,15 +6588,15 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6106 } 6588 }
6107 } 6589 }
6108 6590
6109 if (!NILP (w->buffer)) 6591 if (BUFFERP (w->contents))
6110 { 6592 {
6111 /* Save w's value of point in the window configuration. If w 6593 /* Save w's value of point in the window configuration. If w
6112 is the selected window, then get the value of point from 6594 is the selected window, then get the value of point from
6113 the buffer; pointm is garbage in the selected window. */ 6595 the buffer; pointm is garbage in the selected window. */
6114 if (EQ (window, selected_window)) 6596 if (EQ (window, selected_window))
6115 p->pointm = build_marker (XBUFFER (w->buffer), 6597 p->pointm = build_marker (XBUFFER (w->contents),
6116 BUF_PT (XBUFFER (w->buffer)), 6598 BUF_PT (XBUFFER (w->contents)),
6117 BUF_PT_BYTE (XBUFFER (w->buffer))); 6599 BUF_PT_BYTE (XBUFFER (w->contents)));
6118 else 6600 else
6119 p->pointm = Fcopy_marker (w->pointm, Qnil); 6601 p->pointm = Fcopy_marker (w->pointm, Qnil);
6120 XMARKER (p->pointm)->insertion_type 6602 XMARKER (p->pointm)->insertion_type
@@ -6123,7 +6605,7 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6123 p->start = Fcopy_marker (w->start, Qnil); 6605 p->start = Fcopy_marker (w->start, Qnil);
6124 p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil; 6606 p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
6125 6607
6126 tem = BVAR (XBUFFER (w->buffer), mark); 6608 tem = BVAR (XBUFFER (w->contents), mark);
6127 p->mark = Fcopy_marker (tem, Qnil); 6609 p->mark = Fcopy_marker (tem, Qnil);
6128 } 6610 }
6129 else 6611 else
@@ -6144,10 +6626,8 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6144 else 6626 else
6145 p->prev = XWINDOW (w->prev)->temslot; 6627 p->prev = XWINDOW (w->prev)->temslot;
6146 6628
6147 if (!NILP (w->vchild)) 6629 if (WINDOWP (w->contents))
6148 i = save_window_save (w->vchild, vector, i); 6630 i = save_window_save (w->contents, vector, i);
6149 if (!NILP (w->hchild))
6150 i = save_window_save (w->hchild, vector, i);
6151 } 6631 }
6152 6632
6153 return i; 6633 return i;
@@ -6181,6 +6661,10 @@ saved by this function. */)
6181 data->frame_lines = FRAME_LINES (f); 6661 data->frame_lines = FRAME_LINES (f);
6182 data->frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f); 6662 data->frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
6183 data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f); 6663 data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
6664 data->frame_text_width = FRAME_TEXT_WIDTH (f);
6665 data->frame_text_height = FRAME_TEXT_HEIGHT (f);
6666 data->frame_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f);
6667 data->frame_tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f);
6184 data->selected_frame = selected_frame; 6668 data->selected_frame = selected_frame;
6185 data->current_window = FRAME_SELECTED_WINDOW (f); 6669 data->current_window = FRAME_SELECTED_WINDOW (f);
6186 XSETBUFFER (data->current_buffer, current_buffer); 6670 XSETBUFFER (data->current_buffer, current_buffer);
@@ -6197,11 +6681,47 @@ saved by this function. */)
6197 XSETWINDOW_CONFIGURATION (tem, data); 6681 XSETWINDOW_CONFIGURATION (tem, data);
6198 return (tem); 6682 return (tem);
6199} 6683}
6684
6685/* Called after W's margins, fringes or scroll bars was adjusted. */
6686
6687static void
6688apply_window_adjustment (struct window *w)
6689{
6690 eassert (w);
6691 adjust_window_margins (w);
6692 clear_glyph_matrix (w->current_matrix);
6693 w->window_end_valid = 0;
6694 windows_or_buffers_changed = 30;
6695 wset_redisplay (w);
6696 adjust_frame_glyphs (XFRAME (WINDOW_FRAME (w)));
6697}
6698
6200 6699
6201/*********************************************************************** 6700/***********************************************************************
6202 Marginal Areas 6701 Marginal Areas
6203 ***********************************************************************/ 6702 ***********************************************************************/
6204 6703
6704static struct window *
6705set_window_margins (struct window *w, Lisp_Object left_width,
6706 Lisp_Object right_width)
6707{
6708 int left, right;
6709
6710 /* FIXME: what about margins that are too wide? */
6711 left = (NILP (left_width) ? 0
6712 : (CHECK_NATNUM (left_width), XINT (left_width)));
6713 right = (NILP (right_width) ? 0
6714 : (CHECK_NATNUM (right_width), XINT (right_width)));
6715
6716 if (w->left_margin_cols != left || w->right_margin_cols != right)
6717 {
6718 w->left_margin_cols = left;
6719 w->right_margin_cols = right;
6720 return w;
6721 }
6722 return NULL;
6723}
6724
6205DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins, 6725DEFUN ("set-window-margins", Fset_window_margins, Sset_window_margins,
6206 2, 3, 0, 6726 2, 3, 0,
6207 doc: /* Set width of marginal areas of window WINDOW. 6727 doc: /* Set width of marginal areas of window WINDOW.
@@ -6210,41 +6730,14 @@ WINDOW must be a live window and defaults to the selected one.
6210Second arg LEFT-WIDTH specifies the number of character cells to 6730Second arg LEFT-WIDTH specifies the number of character cells to
6211reserve for the left marginal area. Optional third arg RIGHT-WIDTH 6731reserve for the left marginal area. Optional third arg RIGHT-WIDTH
6212does the same for the right marginal area. A nil width parameter 6732does the same for the right marginal area. A nil width parameter
6213means no margin. */) 6733means no margin.
6734
6735Return t if any margin was actually changed and nil otherwise. */)
6214 (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width) 6736 (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width)
6215{ 6737{
6216 struct window *w = decode_live_window (window); 6738 struct window *w = set_window_margins (decode_live_window (window),
6217 6739 left_width, right_width);
6218 /* Translate negative or zero widths to nil. 6740 return w ? (apply_window_adjustment (w), Qt) : Qnil;
6219 Margins that are too wide have to be checked elsewhere. */
6220
6221 if (!NILP (left_width))
6222 {
6223 CHECK_NUMBER (left_width);
6224 if (XINT (left_width) <= 0)
6225 left_width = Qnil;
6226 }
6227
6228 if (!NILP (right_width))
6229 {
6230 CHECK_NUMBER (right_width);
6231 if (XINT (right_width) <= 0)
6232 right_width = Qnil;
6233 }
6234
6235 if (!EQ (w->left_margin_cols, left_width)
6236 || !EQ (w->right_margin_cols, right_width))
6237 {
6238 wset_left_margin_cols (w, left_width);
6239 wset_right_margin_cols (w, right_width);
6240
6241 adjust_window_margins (w);
6242
6243 ++windows_or_buffers_changed;
6244 adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
6245 }
6246
6247 return Qnil;
6248} 6741}
6249 6742
6250 6743
@@ -6259,7 +6752,10 @@ as nil. */)
6259 (Lisp_Object window) 6752 (Lisp_Object window)
6260{ 6753{
6261 struct window *w = decode_live_window (window); 6754 struct window *w = decode_live_window (window);
6262 return Fcons (w->left_margin_cols, w->right_margin_cols); 6755 return Fcons (w->left_margin_cols
6756 ? make_number (w->left_margin_cols) : Qnil,
6757 w->right_margin_cols
6758 ? make_number (w->right_margin_cols) : Qnil);
6263} 6759}
6264 6760
6265 6761
@@ -6268,6 +6764,31 @@ as nil. */)
6268 Fringes 6764 Fringes
6269 ***********************************************************************/ 6765 ***********************************************************************/
6270 6766
6767static struct window *
6768set_window_fringes (struct window *w, Lisp_Object left_width,
6769 Lisp_Object right_width, Lisp_Object outside_margins)
6770{
6771 int left, right, outside = !NILP (outside_margins);
6772
6773 left = (NILP (left_width) ? -1
6774 : (CHECK_NATNUM (left_width), XINT (left_width)));
6775 right = (NILP (right_width) ? -1
6776 : (CHECK_NATNUM (right_width), XINT (right_width)));
6777
6778 /* Do nothing on a tty or if nothing to actually change. */
6779 if (FRAME_WINDOW_P (WINDOW_XFRAME (w))
6780 && (w->left_fringe_width != left
6781 || w->right_fringe_width != right
6782 || w->fringes_outside_margins != outside))
6783 {
6784 w->left_fringe_width = left;
6785 w->right_fringe_width = right;
6786 w->fringes_outside_margins = outside;
6787 return w;
6788 }
6789 return NULL;
6790}
6791
6271DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes, 6792DEFUN ("set-window-fringes", Fset_window_fringes, Sset_window_fringes,
6272 2, 4, 0, 6793 2, 4, 0,
6273 doc: /* Set the fringe widths of window WINDOW. 6794 doc: /* Set the fringe widths of window WINDOW.
@@ -6280,37 +6801,16 @@ frame's default fringe width. Default fringe widths can be set with
6280the command `set-fringe-style'. 6801the command `set-fringe-style'.
6281If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes 6802If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes
6282outside of the display margins. By default, fringes are drawn between 6803outside of the display margins. By default, fringes are drawn between
6283display marginal areas and the text area. */) 6804display marginal areas and the text area.
6284 (Lisp_Object window, Lisp_Object left_width, Lisp_Object right_width, Lisp_Object outside_margins)
6285{
6286 struct window *w = decode_live_window (window);
6287 int outside = !NILP (outside_margins);
6288
6289 if (!NILP (left_width))
6290 CHECK_NATNUM (left_width);
6291 if (!NILP (right_width))
6292 CHECK_NATNUM (right_width);
6293
6294 /* Do nothing on a tty. */
6295 if (FRAME_WINDOW_P (WINDOW_XFRAME (w))
6296 && (!EQ (w->left_fringe_width, left_width)
6297 || !EQ (w->right_fringe_width, right_width)
6298 || w->fringes_outside_margins != outside))
6299 {
6300 wset_left_fringe_width (w, left_width);
6301 wset_right_fringe_width (w, right_width);
6302 w->fringes_outside_margins = outside;
6303
6304 adjust_window_margins (w);
6305
6306 clear_glyph_matrix (w->current_matrix);
6307 w->window_end_valid = 0;
6308 6805
6309 ++windows_or_buffers_changed; 6806Return t if any fringe was actually changed and nil otherwise. */)
6310 adjust_glyphs (XFRAME (WINDOW_FRAME (w))); 6807 (Lisp_Object window, Lisp_Object left_width,
6311 } 6808 Lisp_Object right_width, Lisp_Object outside_margins)
6312 6809{
6313 return Qnil; 6810 struct window *w
6811 = set_window_fringes (decode_live_window (window),
6812 left_width, right_width, outside_margins);
6813 return w ? (apply_window_adjustment (w), Qt) : Qnil;
6314} 6814}
6315 6815
6316 6816
@@ -6335,29 +6835,14 @@ Value is a list of the form (LEFT-WIDTH RIGHT-WIDTH OUTSIDE-MARGINS). */)
6335 Scroll bars 6835 Scroll bars
6336 ***********************************************************************/ 6836 ***********************************************************************/
6337 6837
6338DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars, 6838static struct window *
6339 Sset_window_scroll_bars, 2, 4, 0, 6839set_window_scroll_bars (struct window *w, Lisp_Object width,
6340 doc: /* Set width and type of scroll bars of window WINDOW. 6840 Lisp_Object vertical_type, Lisp_Object horizontal_type)
6341WINDOW must be a live window and defaults to the selected one.
6342
6343Second parameter WIDTH specifies the pixel width for the scroll bar;
6344this is automatically adjusted to a multiple of the frame column width.
6345Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
6346bar: left, right, or nil.
6347If WIDTH is nil, use the frame's scroll-bar width.
6348If VERTICAL-TYPE is t, use the frame's scroll-bar type.
6349Fourth parameter HORIZONTAL-TYPE is currently unused. */)
6350 (Lisp_Object window, Lisp_Object width, Lisp_Object vertical_type, Lisp_Object horizontal_type)
6351{ 6841{
6352 struct window *w = decode_live_window (window); 6842 int iwidth = (NILP (width) ? -1 : (CHECK_NATNUM (width), XINT (width)));
6353 6843
6354 if (!NILP (width)) 6844 if (iwidth == 0)
6355 { 6845 vertical_type = Qnil;
6356 CHECK_RANGED_INTEGER (width, 0, INT_MAX);
6357
6358 if (XINT (width) == 0)
6359 vertical_type = Qnil;
6360 }
6361 6846
6362 if (!(NILP (vertical_type) 6847 if (!(NILP (vertical_type)
6363 || EQ (vertical_type, Qleft) 6848 || EQ (vertical_type, Qleft)
@@ -6365,22 +6850,36 @@ Fourth parameter HORIZONTAL-TYPE is currently unused. */)
6365 || EQ (vertical_type, Qt))) 6850 || EQ (vertical_type, Qt)))
6366 error ("Invalid type of vertical scroll bar"); 6851 error ("Invalid type of vertical scroll bar");
6367 6852
6368 if (!EQ (w->scroll_bar_width, width) 6853 if (w->scroll_bar_width != iwidth
6369 || !EQ (w->vertical_scroll_bar_type, vertical_type)) 6854 || !EQ (w->vertical_scroll_bar_type, vertical_type))
6370 { 6855 {
6371 wset_scroll_bar_width (w, width); 6856 w->scroll_bar_width = iwidth;
6372 wset_vertical_scroll_bar_type (w, vertical_type); 6857 wset_vertical_scroll_bar_type (w, vertical_type);
6858 return w;
6859 }
6860 return NULL;
6861}
6373 6862
6374 adjust_window_margins (w); 6863DEFUN ("set-window-scroll-bars", Fset_window_scroll_bars,
6375 6864 Sset_window_scroll_bars, 2, 4, 0,
6376 clear_glyph_matrix (w->current_matrix); 6865 doc: /* Set width and type of scroll bars of window WINDOW.
6377 w->window_end_valid = 0; 6866WINDOW must be a live window and defaults to the selected one.
6378 6867
6379 ++windows_or_buffers_changed; 6868Second parameter WIDTH specifies the pixel width for the scroll bar.
6380 adjust_glyphs (XFRAME (WINDOW_FRAME (w))); 6869Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
6381 } 6870bar: left, right, or nil.
6871If WIDTH is nil, use the frame's scroll-bar width.
6872If VERTICAL-TYPE is t, use the frame's scroll-bar type.
6873Fourth parameter HORIZONTAL-TYPE is currently unused.
6382 6874
6383 return Qnil; 6875Return t if scroll bars were actually changed and nil otherwise. */)
6876 (Lisp_Object window, Lisp_Object width,
6877 Lisp_Object vertical_type, Lisp_Object horizontal_type)
6878{
6879 struct window *w
6880 = set_window_scroll_bars (decode_live_window (window),
6881 width, vertical_type, horizontal_type);
6882 return w ? (apply_window_adjustment (w), Qt) : Qnil;
6384} 6883}
6385 6884
6386 6885
@@ -6396,9 +6895,7 @@ value. */)
6396{ 6895{
6397 struct window *w = decode_live_window (window); 6896 struct window *w = decode_live_window (window);
6398 6897
6399 return list4 (make_number ((WINDOW_CONFIG_SCROLL_BAR_WIDTH (w) 6898 return list4 (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (w)),
6400 ? WINDOW_CONFIG_SCROLL_BAR_WIDTH (w)
6401 : WINDOW_SCROLL_BAR_AREA_WIDTH (w))),
6402 make_number (WINDOW_SCROLL_BAR_COLS (w)), 6899 make_number (WINDOW_SCROLL_BAR_COLS (w)),
6403 w->vertical_scroll_bar_type, Qnil); 6900 w->vertical_scroll_bar_type, Qnil);
6404} 6901}
@@ -6461,10 +6958,10 @@ If PIXELS-P is non-nil, the return value is VSCROLL. */)
6461 /* Adjust glyph matrix of the frame if the virtual display 6958 /* Adjust glyph matrix of the frame if the virtual display
6462 area becomes larger than before. */ 6959 area becomes larger than before. */
6463 if (w->vscroll < 0 && w->vscroll < old_dy) 6960 if (w->vscroll < 0 && w->vscroll < old_dy)
6464 adjust_glyphs (f); 6961 adjust_frame_glyphs (f);
6465 6962
6466 /* Prevent redisplay shortcuts. */ 6963 /* Prevent redisplay shortcuts. */
6467 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 6964 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
6468 } 6965 }
6469 } 6966 }
6470 6967
@@ -6498,10 +6995,8 @@ foreach_window_1 (struct window *w, int (*fn) (struct window *, void *), void *u
6498 6995
6499 for (cont = 1; w && cont;) 6996 for (cont = 1; w && cont;)
6500 { 6997 {
6501 if (!NILP (w->hchild)) 6998 if (WINDOWP (w->contents))
6502 cont = foreach_window_1 (XWINDOW (w->hchild), fn, user_data); 6999 cont = foreach_window_1 (XWINDOW (w->contents), fn, user_data);
6503 else if (!NILP (w->vchild))
6504 cont = foreach_window_1 (XWINDOW (w->vchild), fn, user_data);
6505 else 7000 else
6506 cont = fn (w, user_data); 7001 cont = fn (w, user_data);
6507 7002
@@ -6511,38 +7006,6 @@ foreach_window_1 (struct window *w, int (*fn) (struct window *, void *), void *u
6511 return cont; 7006 return cont;
6512} 7007}
6513 7008
6514
6515/* Freeze or unfreeze the window start of W unless it is a
6516 mini-window or the selected window. FREEZE_P non-null means freeze
6517 the window start. */
6518
6519static int
6520freeze_window_start (struct window *w, void *freeze_p)
6521{
6522 if (MINI_WINDOW_P (w)
6523 || (WINDOWP (selected_window) /* Can be nil in corner cases. */
6524 && (w == XWINDOW (selected_window)
6525 || (MINI_WINDOW_P (XWINDOW (selected_window))
6526 && ! NILP (Vminibuf_scroll_window)
6527 && w == XWINDOW (Vminibuf_scroll_window)))))
6528 freeze_p = NULL;
6529
6530 w->frozen_window_start_p = freeze_p != NULL;
6531 return 1;
6532}
6533
6534
6535/* Freeze or unfreeze the window starts of all leaf windows on frame
6536 F, except the selected window and a mini-window. FREEZE_P non-zero
6537 means freeze the window start. */
6538
6539void
6540freeze_window_starts (struct frame *f, int freeze_p)
6541{
6542 foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0));
6543}
6544
6545
6546/*********************************************************************** 7009/***********************************************************************
6547 Initialization 7010 Initialization
6548 ***********************************************************************/ 7011 ***********************************************************************/
@@ -6602,6 +7065,10 @@ compare_window_configurations (Lisp_Object configuration1,
6602 != EQ (d2->current_window, sw2->window) 7065 != EQ (d2->current_window, sw2->window)
6603 /* Windows' buffers must match. */ 7066 /* Windows' buffers must match. */
6604 || !EQ (sw1->buffer, sw2->buffer) 7067 || !EQ (sw1->buffer, sw2->buffer)
7068 || !EQ (sw1->pixel_left, sw2->pixel_left)
7069 || !EQ (sw1->pixel_top, sw2->pixel_top)
7070 || !EQ (sw1->pixel_height, sw2->pixel_height)
7071 || !EQ (sw1->pixel_width, sw2->pixel_width)
6605 || !EQ (sw1->left_col, sw2->left_col) 7072 || !EQ (sw1->left_col, sw2->left_col)
6606 || !EQ (sw1->top_line, sw2->top_line) 7073 || !EQ (sw1->top_line, sw2->top_line)
6607 || !EQ (sw1->total_cols, sw2->total_cols) 7074 || !EQ (sw1->total_cols, sw2->total_cols)
@@ -6651,7 +7118,6 @@ init_window_once (void)
6651 Vterminal_frame = selected_frame; 7118 Vterminal_frame = selected_frame;
6652 minibuf_window = f->minibuffer_window; 7119 minibuf_window = f->minibuffer_window;
6653 selected_window = f->selected_window; 7120 selected_window = f->selected_window;
6654 last_nonminibuf_frame = f;
6655 7121
6656 window_initialized = 1; 7122 window_initialized = 1;
6657} 7123}
@@ -6681,6 +7147,7 @@ syms_of_window (void)
6681 DEFSYM (Qdelete_window, "delete-window"); 7147 DEFSYM (Qdelete_window, "delete-window");
6682 DEFSYM (Qwindow_resize_root_window, "window--resize-root-window"); 7148 DEFSYM (Qwindow_resize_root_window, "window--resize-root-window");
6683 DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically"); 7149 DEFSYM (Qwindow_resize_root_window_vertically, "window--resize-root-window-vertically");
7150 DEFSYM (Qwindow_pixel_to_total, "window--pixel-to-total");
6684 DEFSYM (Qsafe, "safe"); 7151 DEFSYM (Qsafe, "safe");
6685 DEFSYM (Qdisplay_buffer, "display-buffer"); 7152 DEFSYM (Qdisplay_buffer, "display-buffer");
6686 DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows"); 7153 DEFSYM (Qreplace_buffer_in_windows, "replace-buffer-in-windows");
@@ -6691,6 +7158,8 @@ syms_of_window (void)
6691 DEFSYM (Qabove, "above"); 7158 DEFSYM (Qabove, "above");
6692 DEFSYM (Qbelow, "below"); 7159 DEFSYM (Qbelow, "below");
6693 DEFSYM (Qclone_of, "clone-of"); 7160 DEFSYM (Qclone_of, "clone-of");
7161 DEFSYM (Qfloor, "floor");
7162 DEFSYM (Qceiling, "ceiling");
6694 7163
6695 staticpro (&Vwindow_list); 7164 staticpro (&Vwindow_list);
6696 7165
@@ -6839,6 +7308,17 @@ Parameters not saved by `current-window-configuration' or
6839respectively are not installed by `window-state-put'. */); 7308respectively are not installed by `window-state-put'. */);
6840 Vwindow_persistent_parameters = list1 (Fcons (Qclone_of, Qt)); 7309 Vwindow_persistent_parameters = list1 (Fcons (Qclone_of, Qt));
6841 7310
7311 DEFVAR_BOOL ("window-resize-pixelwise", window_resize_pixelwise,
7312 doc: /* Non-nil means resize windows pixelwise.
7313This currently affects the functions: `split-window', `maximize-window',
7314`minimize-window', `fit-window-to-buffer' and `fit-frame-to-buffer', and
7315all functions that symmetrically resize a parent window.
7316
7317Note that when a frame's pixel size is not a multiple of the
7318frame's character size, at least one window may get resized
7319pixelwise even if this option is nil. */);
7320 window_resize_pixelwise = 0;
7321
6842 defsubr (&Sselected_window); 7322 defsubr (&Sselected_window);
6843 defsubr (&Sminibuffer_window); 7323 defsubr (&Sminibuffer_window);
6844 defsubr (&Swindow_minibuffer_p); 7324 defsubr (&Swindow_minibuffer_p);
@@ -6861,16 +7341,23 @@ respectively are not installed by `window-state-put'. */);
6861 defsubr (&Swindow_combination_limit); 7341 defsubr (&Swindow_combination_limit);
6862 defsubr (&Sset_window_combination_limit); 7342 defsubr (&Sset_window_combination_limit);
6863 defsubr (&Swindow_use_time); 7343 defsubr (&Swindow_use_time);
6864 defsubr (&Swindow_top_line); 7344 defsubr (&Swindow_pixel_width);
6865 defsubr (&Swindow_left_column); 7345 defsubr (&Swindow_pixel_height);
6866 defsubr (&Swindow_total_height);
6867 defsubr (&Swindow_total_width); 7346 defsubr (&Swindow_total_width);
7347 defsubr (&Swindow_total_height);
6868 defsubr (&Swindow_normal_size); 7348 defsubr (&Swindow_normal_size);
7349 defsubr (&Swindow_new_pixel);
6869 defsubr (&Swindow_new_total); 7350 defsubr (&Swindow_new_total);
6870 defsubr (&Swindow_new_normal); 7351 defsubr (&Swindow_new_normal);
7352 defsubr (&Swindow_pixel_left);
7353 defsubr (&Swindow_pixel_top);
7354 defsubr (&Swindow_left_column);
7355 defsubr (&Swindow_top_line);
7356 defsubr (&Sset_window_new_pixel);
6871 defsubr (&Sset_window_new_total); 7357 defsubr (&Sset_window_new_total);
6872 defsubr (&Sset_window_new_normal); 7358 defsubr (&Sset_window_new_normal);
6873 defsubr (&Swindow_resize_apply); 7359 defsubr (&Swindow_resize_apply);
7360 defsubr (&Swindow_resize_apply_total);
6874 defsubr (&Swindow_body_height); 7361 defsubr (&Swindow_body_height);
6875 defsubr (&Swindow_body_width); 7362 defsubr (&Swindow_body_width);
6876 defsubr (&Swindow_hscroll); 7363 defsubr (&Swindow_hscroll);
@@ -6880,6 +7367,11 @@ respectively are not installed by `window-state-put'. */);
6880 defsubr (&Swindow_edges); 7367 defsubr (&Swindow_edges);
6881 defsubr (&Swindow_pixel_edges); 7368 defsubr (&Swindow_pixel_edges);
6882 defsubr (&Swindow_absolute_pixel_edges); 7369 defsubr (&Swindow_absolute_pixel_edges);
7370 defsubr (&Swindow_mode_line_height);
7371 defsubr (&Swindow_header_line_height);
7372 defsubr (&Swindow_right_divider_width);
7373 defsubr (&Swindow_bottom_divider_width);
7374 defsubr (&Swindow_scroll_bar_width);
6883 defsubr (&Swindow_inside_edges); 7375 defsubr (&Swindow_inside_edges);
6884 defsubr (&Swindow_inside_pixel_edges); 7376 defsubr (&Swindow_inside_pixel_edges);
6885 defsubr (&Swindow_inside_absolute_pixel_edges); 7377 defsubr (&Swindow_inside_absolute_pixel_edges);
@@ -6902,6 +7394,7 @@ respectively are not installed by `window-state-put'. */);
6902 defsubr (&Sresize_mini_window_internal); 7394 defsubr (&Sresize_mini_window_internal);
6903 defsubr (&Sset_window_buffer); 7395 defsubr (&Sset_window_buffer);
6904 defsubr (&Srun_window_configuration_change_hook); 7396 defsubr (&Srun_window_configuration_change_hook);
7397 defsubr (&Srun_window_scroll_functions);
6905 defsubr (&Sselect_window); 7398 defsubr (&Sselect_window);
6906 defsubr (&Sforce_window_update); 7399 defsubr (&Sforce_window_update);
6907 defsubr (&Ssplit_window_internal); 7400 defsubr (&Ssplit_window_internal);
@@ -6913,6 +7406,7 @@ respectively are not installed by `window-state-put'. */);
6913 defsubr (&Sscroll_other_window); 7406 defsubr (&Sscroll_other_window);
6914 defsubr (&Sminibuffer_selected_window); 7407 defsubr (&Sminibuffer_selected_window);
6915 defsubr (&Srecenter); 7408 defsubr (&Srecenter);
7409 defsubr (&Swindow_text_width);
6916 defsubr (&Swindow_text_height); 7410 defsubr (&Swindow_text_height);
6917 defsubr (&Smove_to_window_line); 7411 defsubr (&Smove_to_window_line);
6918 defsubr (&Swindow_configuration_p); 7412 defsubr (&Swindow_configuration_p);