aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c916
1 files changed, 435 insertions, 481 deletions
diff --git a/src/window.c b/src/window.c
index 9f3474fcd53..b66111a5605 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1,7 +1,7 @@
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-2012 3 Copyright (C) 1985-1987, 1993-1998, 2000-2013 Free Software
4 Free Software Foundation, Inc. 4 Foundation, Inc.
5 5
6This file is part of GNU Emacs. 6This file is part of GNU Emacs.
7 7
@@ -84,9 +84,10 @@ static int foreach_window_1 (struct window *,
84 int (* fn) (struct window *, void *), 84 int (* fn) (struct window *, void *),
85 void *); 85 void *);
86static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object); 86static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
87static int window_resize_check (struct window *, int); 87static int window_resize_check (struct window *, bool);
88static void window_resize_apply (struct window *, int); 88static void window_resize_apply (struct window *, bool);
89static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); 89static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
90static void select_window_1 (Lisp_Object, bool);
90 91
91/* This is the window in which the terminal's cursor should 92/* This is the window in which the terminal's cursor should
92 be left when nothing is being done with it. This must 93 be left when nothing is being done with it. This must
@@ -115,9 +116,6 @@ Lisp_Object minibuf_selected_window;
115/* Hook run at end of temp_output_buffer_show. */ 116/* Hook run at end of temp_output_buffer_show. */
116static Lisp_Object Qtemp_buffer_show_hook; 117static Lisp_Object Qtemp_buffer_show_hook;
117 118
118/* Incremented for each window created. */
119static int sequence_number;
120
121/* Nonzero after init_window_once has finished. */ 119/* Nonzero after init_window_once has finished. */
122static int window_initialized; 120static int window_initialized;
123 121
@@ -149,11 +147,6 @@ wset_display_table (struct window *w, Lisp_Object val)
149 w->display_table = val; 147 w->display_table = val;
150} 148}
151static void 149static void
152wset_hchild (struct window *w, Lisp_Object val)
153{
154 w->hchild = val;
155}
156static void
157wset_left_fringe_width (struct window *w, Lisp_Object val) 150wset_left_fringe_width (struct window *w, Lisp_Object val)
158{ 151{
159 w->left_fringe_width = val; 152 w->left_fringe_width = val;
@@ -219,11 +212,6 @@ wset_temslot (struct window *w, Lisp_Object val)
219 w->temslot = val; 212 w->temslot = val;
220} 213}
221static void 214static void
222wset_vchild (struct window *w, Lisp_Object val)
223{
224 w->vchild = val;
225}
226static void
227wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val) 215wset_vertical_scroll_bar_type (struct window *w, Lisp_Object val)
228{ 216{
229 w->vertical_scroll_bar_type = val; 217 w->vertical_scroll_bar_type = val;
@@ -233,6 +221,18 @@ wset_window_parameters (struct window *w, Lisp_Object val)
233{ 221{
234 w->window_parameters = val; 222 w->window_parameters = val;
235} 223}
224static void
225wset_combination (struct window *w, bool horflag, Lisp_Object val)
226{
227 /* Since leaf windows never becomes non-leaf, there should
228 be no buffer and markers in start and pointm fields of W. */
229 eassert (!BUFFERP (w->contents) && NILP (w->start) && NILP (w->pointm));
230 w->contents = val;
231 /* When an internal window is deleted and VAL is nil, HORFLAG
232 is meaningless. */
233 if (!NILP (val))
234 w->horizontal = horflag;
235}
236 236
237struct window * 237struct window *
238decode_live_window (register Lisp_Object window) 238decode_live_window (register Lisp_Object window)
@@ -270,13 +270,40 @@ decode_valid_window (register Lisp_Object window)
270 return w; 270 return w;
271} 271}
272 272
273/* Build a frequently used 4-integer (X Y W H) list. */ 273/* Called when W's buffer slot is changed. ARG -1 means that W is about to
274 cease its buffer, and 1 means that W is about to set up the new one. */
274 275
275static Lisp_Object 276static void
276list4i (EMACS_INT x, EMACS_INT y, EMACS_INT w, EMACS_INT h) 277adjust_window_count (struct window *w, int arg)
277{ 278{
278 return list4 (make_number (x), make_number (y), 279 eassert (eabs (arg) == 1);
279 make_number (w), make_number (h)); 280 if (BUFFERP (w->contents))
281 {
282 struct buffer *b = XBUFFER (w->contents);
283
284 if (b->base_buffer)
285 b = b->base_buffer;
286 b->window_count += arg;
287 eassert (b->window_count >= 0);
288 /* These should be recalculated by redisplay code. */
289 w->window_end_valid = 0;
290 w->base_line_pos = 0;
291 }
292}
293
294/* Set W's buffer slot to VAL and recompute number
295 of windows showing VAL if it is a buffer. */
296
297void
298wset_buffer (struct window *w, Lisp_Object val)
299{
300 adjust_window_count (w, -1);
301 if (BUFFERP (val))
302 /* Make sure that we do not assign the buffer
303 to an internal window. */
304 eassert (MARKERP (w->start) && MARKERP (w->pointm));
305 w->contents = val;
306 adjust_window_count (w, 1);
280} 307}
281 308
282DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0, 309DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0,
@@ -373,15 +400,8 @@ the first window of that frame. */)
373 window = XFRAME (frame_or_window)->root_window; 400 window = XFRAME (frame_or_window)->root_window;
374 } 401 }
375 402
376 while (NILP (XWINDOW (window)->buffer)) 403 while (WINDOWP (XWINDOW (window)->contents))
377 { 404 window = XWINDOW (window)->contents;
378 if (! NILP (XWINDOW (window)->hchild))
379 window = XWINDOW (window)->hchild;
380 else if (! NILP (XWINDOW (window)->vchild))
381 window = XWINDOW (window)->vchild;
382 else
383 emacs_abort ();
384 }
385 405
386 return window; 406 return window;
387} 407}
@@ -458,7 +478,6 @@ static Lisp_Object
458select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap) 478select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
459{ 479{
460 register struct window *w; 480 register struct window *w;
461 register struct window *ow;
462 struct frame *sf; 481 struct frame *sf;
463 482
464 CHECK_LIVE_WINDOW (window); 483 CHECK_LIVE_WINDOW (window);
@@ -469,11 +488,11 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
469 if (NILP (norecord)) 488 if (NILP (norecord))
470 { 489 {
471 w->use_time = ++window_select_count; 490 w->use_time = ++window_select_count;
472 record_buffer (w->buffer); 491 record_buffer (w->contents);
473 } 492 }
474 493
475 /* Make the selected window's buffer current. */ 494 /* Make the selected window's buffer current. */
476 Fset_buffer (w->buffer); 495 Fset_buffer (w->contents);
477 496
478 if (EQ (window, selected_window) && !inhibit_point_swap) 497 if (EQ (window, selected_window) && !inhibit_point_swap)
479 return window; 498 return window;
@@ -494,20 +513,32 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
494 else 513 else
495 fset_selected_window (sf, window); 514 fset_selected_window (sf, window);
496 515
516 select_window_1 (window, inhibit_point_swap);
517
518 bset_last_selected_window (XBUFFER (w->contents), window);
519 windows_or_buffers_changed++;
520 return window;
521}
522
523/* Select window with a minimum of fuss, i.e. don't record the change anywhere
524 (not even for redisplay's benefit), and assume that the window's frame is
525 already selected. */
526static void
527select_window_1 (Lisp_Object window, bool inhibit_point_swap)
528{
497 /* Store the old selected window's buffer's point in pointm of the old 529 /* Store the old selected window's buffer's point in pointm of the old
498 selected window. It belongs to that window, and when the window is 530 selected window. It belongs to that window, and when the window is
499 not selected, must be in the window. */ 531 not selected, must be in the window. */
500 if (!inhibit_point_swap) 532 if (!inhibit_point_swap)
501 { 533 {
502 ow = XWINDOW (selected_window); 534 struct window *ow = XWINDOW (selected_window);
503 if (! NILP (ow->buffer)) 535 if (BUFFERP (ow->contents))
504 set_marker_both (ow->pointm, ow->buffer, 536 set_marker_both (ow->pointm, ow->contents,
505 BUF_PT (XBUFFER (ow->buffer)), 537 BUF_PT (XBUFFER (ow->contents)),
506 BUF_PT_BYTE (XBUFFER (ow->buffer))); 538 BUF_PT_BYTE (XBUFFER (ow->contents)));
507 } 539 }
508 540
509 selected_window = window; 541 selected_window = window;
510 bset_last_selected_window (XBUFFER (w->buffer), window);
511 542
512 /* Go to the point recorded in the window. 543 /* Go to the point recorded in the window.
513 This is important when the buffer is in more 544 This is important when the buffer is in more
@@ -515,7 +546,7 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
515 redisplay_window has altered point after scrolling, 546 redisplay_window has altered point after scrolling,
516 because it makes the change only in the window. */ 547 because it makes the change only in the window. */
517 { 548 {
518 register ptrdiff_t new_point = marker_position (w->pointm); 549 register ptrdiff_t new_point = marker_position (XWINDOW (window)->pointm);
519 if (new_point < BEGV) 550 if (new_point < BEGV)
520 SET_PT (BEGV); 551 SET_PT (BEGV);
521 else if (new_point > ZV) 552 else if (new_point > ZV)
@@ -523,15 +554,14 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
523 else 554 else
524 SET_PT (new_point); 555 SET_PT (new_point);
525 } 556 }
526
527 windows_or_buffers_changed++;
528 return window;
529} 557}
530 558
531DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0, 559DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
532 doc: /* Select WINDOW. Most editing will apply to WINDOW's buffer. 560 doc: /* Select WINDOW which must be a live window.
533Also make WINDOW's buffer current and make WINDOW the frame's selected 561Also make WINDOW's frame the selected frame and WINDOW that frame's
534window. Return WINDOW. 562selected window. In addition, make WINDOW's buffer current and set that
563buffer's value of `point' to the value of WINDOW's `window-point'.
564Return WINDOW.
535 565
536Optional second arg NORECORD non-nil means do not put this buffer at the 566Optional second arg NORECORD non-nil means do not put this buffer at the
537front of the buffer list and do not make this window the most recently 567front of the buffer list and do not make this window the most recently
@@ -550,7 +580,8 @@ If WINDOW is omitted or nil, it defaults to the selected window.
550Return nil for an internal window or a deleted window. */) 580Return nil for an internal window or a deleted window. */)
551 (Lisp_Object window) 581 (Lisp_Object window)
552{ 582{
553 return decode_any_window (window)->buffer; 583 struct window *w = decode_any_window (window);
584 return WINDOW_LEAF_P (w) ? w->contents : Qnil;
554} 585}
555 586
556DEFUN ("window-parent", Fwindow_parent, Swindow_parent, 0, 1, 0, 587DEFUN ("window-parent", Fwindow_parent, Swindow_parent, 0, 1, 0,
@@ -570,7 +601,8 @@ Return nil if WINDOW is an internal window whose children form a
570horizontal combination. */) 601horizontal combination. */)
571 (Lisp_Object window) 602 (Lisp_Object window)
572{ 603{
573 return decode_valid_window (window)->vchild; 604 struct window *w = decode_valid_window (window);
605 return WINDOW_VERTICAL_COMBINATION_P (w) ? w->contents : Qnil;
574} 606}
575 607
576DEFUN ("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,
@@ -581,7 +613,8 @@ Return nil if WINDOW is an internal window whose children form a
581vertical combination. */) 613vertical combination. */)
582 (Lisp_Object window) 614 (Lisp_Object window)
583{ 615{
584 return decode_valid_window (window)->hchild; 616 struct window *w = decode_valid_window (window);
617 return WINDOW_HORIZONTAL_COMBINATION_P (w) ? w->contents : Qnil;
585} 618}
586 619
587DEFUN ("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,
@@ -604,30 +637,37 @@ Return nil if WINDOW has no previous sibling. */)
604 637
605DEFUN ("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,
606 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.
607If 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
608WINDOW'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
609WINDOW are never \(re-)combined with WINDOW's siblings. 643WINDOW are never \(re-)combined with WINDOW's siblings. */)
610
611WINDOW must be a valid window. The return value is meaningful for
612internal windows only. */)
613 (Lisp_Object window) 644 (Lisp_Object window)
614{ 645{
646 struct window *w;
647
615 CHECK_VALID_WINDOW (window); 648 CHECK_VALID_WINDOW (window);
616 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;
617} 653}
618 654
619DEFUN ("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,
620 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.
621If 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
622siblings. LIMIT t means that child windows of WINDOW are never 659siblings. LIMIT t means that child windows of WINDOW are never
623\(re-)combined with WINDOW's siblings. Other values are reserved for 660\(re-)combined with WINDOW's siblings. Other values are reserved for
624future use. 661future use. */)
625
626WINDOW must be a valid window. Setting the combination limit is
627meaningful for internal windows only. */)
628 (Lisp_Object window, Lisp_Object limit) 662 (Lisp_Object window, Lisp_Object limit)
629{ 663{
630 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);
631 return limit; 671 return limit;
632} 672}
633 673
@@ -654,7 +694,7 @@ On a graphical display, this total height is reported as an
654integer multiple of the default character height. */) 694integer multiple of the default character height. */)
655 (Lisp_Object window) 695 (Lisp_Object window)
656{ 696{
657 return decode_valid_window (window)->total_lines; 697 return make_number (decode_valid_window (window)->total_lines);
658} 698}
659 699
660DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 1, 0, 700DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 1, 0,
@@ -669,7 +709,7 @@ On a graphical display, this total width is reported as an
669integer multiple of the default character width. */) 709integer multiple of the default character width. */)
670 (Lisp_Object window) 710 (Lisp_Object window)
671{ 711{
672 return decode_valid_window (window)->total_cols; 712 return make_number (decode_valid_window (window)->total_cols);
673} 713}
674 714
675DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0, 715DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0,
@@ -708,7 +748,7 @@ value is 0 if there is no window to the left of WINDOW.
708WINDOW must be a valid window and defaults to the selected one. */) 748WINDOW must be a valid window and defaults to the selected one. */)
709 (Lisp_Object window) 749 (Lisp_Object window)
710{ 750{
711 return decode_valid_window (window)->left_col; 751 return make_number (decode_valid_window (window)->left_col);
712} 752}
713 753
714DEFUN ("window-top-line", Fwindow_top_line, Swindow_top_line, 0, 1, 0, 754DEFUN ("window-top-line", Fwindow_top_line, Swindow_top_line, 0, 1, 0,
@@ -720,7 +760,7 @@ there is no window above WINDOW.
720WINDOW must be a valid window and defaults to the selected one. */) 760WINDOW must be a valid window and defaults to the selected one. */)
721 (Lisp_Object window) 761 (Lisp_Object window)
722{ 762{
723 return decode_valid_window (window)->top_line; 763 return make_number (decode_valid_window (window)->top_line);
724} 764}
725 765
726/* Return the number of lines of W's body. Don't count any mode or 766/* Return the number of lines of W's body. Don't count any mode or
@@ -729,7 +769,7 @@ WINDOW must be a valid window and defaults to the selected one. */)
729static int 769static int
730window_body_lines (struct window *w) 770window_body_lines (struct window *w)
731{ 771{
732 int height = XFASTINT (w->total_lines); 772 int height = w->total_lines;
733 773
734 if (!MINI_WINDOW_P (w)) 774 if (!MINI_WINDOW_P (w))
735 { 775 {
@@ -751,7 +791,7 @@ int
751window_body_cols (struct window *w) 791window_body_cols (struct window *w)
752{ 792{
753 struct frame *f = XFRAME (WINDOW_FRAME (w)); 793 struct frame *f = XFRAME (WINDOW_FRAME (w));
754 int width = XINT (w->total_cols); 794 int width = w->total_cols;
755 795
756 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)) 796 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
757 /* Scroll bars occupy a few columns. */ 797 /* Scroll bars occupy a few columns. */
@@ -762,12 +802,12 @@ window_body_cols (struct window *w)
762 occupies one column only. */ 802 occupies one column only. */
763 width -= 1; 803 width -= 1;
764 804
805 /* Display margins cannot be used for normal text. */
806 width -= WINDOW_LEFT_MARGIN_COLS (w) + WINDOW_RIGHT_MARGIN_COLS (w);
807
765 if (FRAME_WINDOW_P (f)) 808 if (FRAME_WINDOW_P (f))
766 /* On window-systems, fringes and display margins cannot be 809 /* On window-systems, fringes cannot be used for normal text. */
767 used for normal text. */ 810 width -= WINDOW_FRINGE_COLS (w);
768 width -= (WINDOW_FRINGE_COLS (w)
769 + WINDOW_LEFT_MARGIN_COLS (w)
770 + WINDOW_RIGHT_MARGIN_COLS (w));
771 811
772 return width; 812 return width;
773} 813}
@@ -822,7 +862,7 @@ set_window_hscroll (struct window *w, EMACS_INT hscroll)
822 862
823 /* Prevent redisplay shortcuts when changing the hscroll. */ 863 /* Prevent redisplay shortcuts when changing the hscroll. */
824 if (w->hscroll != new_hscroll) 864 if (w->hscroll != new_hscroll)
825 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 865 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
826 866
827 w->hscroll = new_hscroll; 867 w->hscroll = new_hscroll;
828 return make_number (new_hscroll); 868 return make_number (new_hscroll);
@@ -1337,7 +1377,7 @@ check_window_containing (struct window *w, void *user_data)
1337 1377
1338Lisp_Object 1378Lisp_Object
1339window_from_coordinates (struct frame *f, int x, int y, 1379window_from_coordinates (struct frame *f, int x, int y,
1340 enum window_part *part, int tool_bar_p) 1380 enum window_part *part, bool tool_bar_p)
1341{ 1381{
1342 Lisp_Object window; 1382 Lisp_Object window;
1343 struct check_window_data cw; 1383 struct check_window_data cw;
@@ -1396,14 +1436,14 @@ window were selected.
1396 1436
1397Note that, when WINDOW is selected, the value returned is the same as 1437Note that, when WINDOW is selected, the value returned is the same as
1398that returned by `point' for WINDOW's buffer. It would be more strictly 1438that returned by `point' for WINDOW's buffer. It would be more strictly
1399correct to return the `top-level' value of `point', outside of any 1439correct to return the top-level value of `point', outside of any
1400`save-excursion' forms. But that is hard to define. */) 1440`save-excursion' forms. But that is hard to define. */)
1401 (Lisp_Object window) 1441 (Lisp_Object window)
1402{ 1442{
1403 register struct window *w = decode_live_window (window); 1443 register struct window *w = decode_live_window (window);
1404 1444
1405 if (w == XWINDOW (selected_window)) 1445 if (w == XWINDOW (selected_window))
1406 return make_number (BUF_PT (XBUFFER (w->buffer))); 1446 return make_number (BUF_PT (XBUFFER (w->contents)));
1407 else 1447 else
1408 return Fmarker_position (w->pointm); 1448 return Fmarker_position (w->pointm);
1409} 1449}
@@ -1445,24 +1485,16 @@ if it isn't already recorded. */)
1445 Lisp_Object buf; 1485 Lisp_Object buf;
1446 struct buffer *b; 1486 struct buffer *b;
1447 1487
1448 buf = w->buffer; 1488 buf = w->contents;
1449 CHECK_BUFFER (buf); 1489 CHECK_BUFFER (buf);
1450 b = XBUFFER (buf); 1490 b = XBUFFER (buf);
1451 1491
1452#if 0 /* This change broke some things. We should make it later. */
1453 /* If we don't know the end position, return nil.
1454 The user can compute it with vertical-motion if he wants to.
1455 It would be nicer to do it automatically,
1456 but that's so slow that it would probably bother people. */
1457 if (NILP (w->window_end_valid))
1458 return Qnil;
1459#endif
1460
1461 if (! NILP (update) 1492 if (! NILP (update)
1462 && (windows_or_buffers_changed || NILP (w->window_end_valid)) 1493 && (windows_or_buffers_changed || !w->window_end_valid)
1463 && !noninteractive) 1494 && !noninteractive)
1464 { 1495 {
1465 struct text_pos startp; 1496 struct text_pos startp;
1497 ptrdiff_t charpos = marker_position (w->start);
1466 struct it it; 1498 struct it it;
1467 struct buffer *old_buffer = NULL; 1499 struct buffer *old_buffer = NULL;
1468 void *itdata = NULL; 1500 void *itdata = NULL;
@@ -1480,9 +1512,9 @@ if it isn't already recorded. */)
1480 `-l' containing a call to `rmail' with subsequent other 1512 `-l' containing a call to `rmail' with subsequent other
1481 commands. At the end, W->start happened to be BEG, while 1513 commands. At the end, W->start happened to be BEG, while
1482 rmail had already narrowed the buffer. */ 1514 rmail had already narrowed the buffer. */
1483 if (XMARKER (w->start)->charpos < BEGV) 1515 if (charpos < BEGV)
1484 SET_TEXT_POS (startp, BEGV, BEGV_BYTE); 1516 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
1485 else if (XMARKER (w->start)->charpos > ZV) 1517 else if (charpos > ZV)
1486 SET_TEXT_POS (startp, ZV, ZV_BYTE); 1518 SET_TEXT_POS (startp, ZV, ZV_BYTE);
1487 else 1519 else
1488 SET_TEXT_POS_FROM_MARKER (startp, w->start); 1520 SET_TEXT_POS_FROM_MARKER (startp, w->start);
@@ -1512,24 +1544,26 @@ Return POS. */)
1512{ 1544{
1513 register struct window *w = decode_live_window (window); 1545 register struct window *w = decode_live_window (window);
1514 1546
1515 CHECK_NUMBER_COERCE_MARKER (pos); 1547 /* Type of POS is checked by Fgoto_char or set_marker_restricted ... */
1516 1548
1517 if (w == XWINDOW (selected_window)) 1549 if (w == XWINDOW (selected_window))
1518 { 1550 {
1519 if (XBUFFER (w->buffer) == current_buffer) 1551 if (XBUFFER (w->contents) == current_buffer)
1520 Fgoto_char (pos); 1552 Fgoto_char (pos);
1521 else 1553 else
1522 { 1554 {
1523 struct buffer *old_buffer = current_buffer; 1555 struct buffer *old_buffer = current_buffer;
1524 1556
1525 set_buffer_internal (XBUFFER (w->buffer)); 1557 /* ... but here we want to catch type error before buffer change. */
1558 CHECK_NUMBER_COERCE_MARKER (pos);
1559 set_buffer_internal (XBUFFER (w->contents));
1526 Fgoto_char (pos); 1560 Fgoto_char (pos);
1527 set_buffer_internal (old_buffer); 1561 set_buffer_internal (old_buffer);
1528 } 1562 }
1529 } 1563 }
1530 else 1564 else
1531 { 1565 {
1532 set_marker_restricted (w->pointm, pos, w->buffer); 1566 set_marker_restricted (w->pointm, pos, w->contents);
1533 /* We have to make sure that redisplay updates the window to show 1567 /* We have to make sure that redisplay updates the window to show
1534 the new value of point. */ 1568 the new value of point. */
1535 ++windows_or_buffers_changed; 1569 ++windows_or_buffers_changed;
@@ -1547,9 +1581,8 @@ overriding motion of point in order to display at this exact start. */)
1547{ 1581{
1548 register struct window *w = decode_live_window (window); 1582 register struct window *w = decode_live_window (window);
1549 1583
1550 CHECK_NUMBER_COERCE_MARKER (pos); 1584 set_marker_restricted (w->start, pos, w->contents);
1551 set_marker_restricted (w->start, pos, w->buffer); 1585 /* This is not right, but much easier than doing what is right. */
1552 /* this is not right, but much easier than doing what is right. */
1553 w->start_at_line_beg = 0; 1586 w->start_at_line_beg = 0;
1554 if (NILP (noforce)) 1587 if (NILP (noforce))
1555 w->force_start = 1; 1588 w->force_start = 1;
@@ -1592,7 +1625,7 @@ display row, and VPOS is the row number (0-based) containing POS. */)
1592 int x, y; 1625 int x, y;
1593 1626
1594 w = decode_live_window (window); 1627 w = decode_live_window (window);
1595 buf = XBUFFER (w->buffer); 1628 buf = XBUFFER (w->contents);
1596 SET_TEXT_POS_FROM_MARKER (top, w->start); 1629 SET_TEXT_POS_FROM_MARKER (top, w->start);
1597 1630
1598 if (EQ (pos, Qt)) 1631 if (EQ (pos, Qt))
@@ -1605,7 +1638,7 @@ display row, and VPOS is the row number (0-based) containing POS. */)
1605 else if (w == XWINDOW (selected_window)) 1638 else if (w == XWINDOW (selected_window))
1606 posint = PT; 1639 posint = PT;
1607 else 1640 else
1608 posint = XMARKER (w->pointm)->charpos; 1641 posint = marker_position (w->pointm);
1609 1642
1610 /* If position is above window start or outside buffer boundaries, 1643 /* If position is above window start or outside buffer boundaries,
1611 or if window start is out of range, position is not visible. */ 1644 or if window start is out of range, position is not visible. */
@@ -1661,11 +1694,11 @@ Return nil if window display is not up-to-date. In that case, use
1661 if (noninteractive || w->pseudo_window_p) 1694 if (noninteractive || w->pseudo_window_p)
1662 return Qnil; 1695 return Qnil;
1663 1696
1664 CHECK_BUFFER (w->buffer); 1697 CHECK_BUFFER (w->contents);
1665 b = XBUFFER (w->buffer); 1698 b = XBUFFER (w->contents);
1666 1699
1667 /* Fail if current matrix is not up-to-date. */ 1700 /* Fail if current matrix is not up-to-date. */
1668 if (NILP (w->window_end_valid) 1701 if (!w->window_end_valid
1669 || current_buffer->clip_changed 1702 || current_buffer->clip_changed
1670 || current_buffer->prevent_redisplay_optimizations_p 1703 || current_buffer->prevent_redisplay_optimizations_p
1671 || w->last_modified < BUF_MODIFF (b) 1704 || w->last_modified < BUF_MODIFF (b)
@@ -1888,9 +1921,9 @@ window_display_table (struct window *w)
1888 1921
1889 if (DISP_TABLE_P (w->display_table)) 1922 if (DISP_TABLE_P (w->display_table))
1890 dp = XCHAR_TABLE (w->display_table); 1923 dp = XCHAR_TABLE (w->display_table);
1891 else if (BUFFERP (w->buffer)) 1924 else if (BUFFERP (w->contents))
1892 { 1925 {
1893 struct buffer *b = XBUFFER (w->buffer); 1926 struct buffer *b = XBUFFER (w->contents);
1894 1927
1895 if (DISP_TABLE_P (BVAR (b, display_table))) 1928 if (DISP_TABLE_P (BVAR (b, display_table)))
1896 dp = XCHAR_TABLE (BVAR (b, display_table)); 1929 dp = XCHAR_TABLE (BVAR (b, display_table));
@@ -1915,17 +1948,14 @@ WINDOW must be a live window and defaults to the selected one. */)
1915static void 1948static void
1916unshow_buffer (register struct window *w) 1949unshow_buffer (register struct window *w)
1917{ 1950{
1918 Lisp_Object buf; 1951 Lisp_Object buf = w->contents;
1919 struct buffer *b; 1952 struct buffer *b = XBUFFER (buf);
1920 1953
1921 buf = w->buffer; 1954 eassert (b == XMARKER (w->pointm)->buffer);
1922 b = XBUFFER (buf);
1923 if (b != XMARKER (w->pointm)->buffer)
1924 emacs_abort ();
1925 1955
1926#if 0 1956#if 0
1927 if (w == XWINDOW (selected_window) 1957 if (w == XWINDOW (selected_window)
1928 || ! EQ (buf, XWINDOW (selected_window)->buffer)) 1958 || ! EQ (buf, XWINDOW (selected_window)->contents))
1929 /* Do this except when the selected window's buffer 1959 /* Do this except when the selected window's buffer
1930 is being removed from some other window. */ 1960 is being removed from some other window. */
1931#endif 1961#endif
@@ -1941,17 +1971,17 @@ unshow_buffer (register struct window *w)
1941 /* Point in the selected window's buffer 1971 /* Point in the selected window's buffer
1942 is actually stored in that buffer, and the window's pointm isn't used. 1972 is actually stored in that buffer, and the window's pointm isn't used.
1943 So don't clobber point in that buffer. */ 1973 So don't clobber point in that buffer. */
1944 if (! EQ (buf, XWINDOW (selected_window)->buffer) 1974 if (! EQ (buf, XWINDOW (selected_window)->contents)
1945 /* Don't clobber point in current buffer either (this could be 1975 /* Don't clobber point in current buffer either (this could be
1946 useful in connection with bug#12208). 1976 useful in connection with bug#12208).
1947 && XBUFFER (buf) != current_buffer */ 1977 && XBUFFER (buf) != current_buffer */
1948 /* This line helps to fix Horsley's testbug.el bug. */ 1978 /* This line helps to fix Horsley's testbug.el bug. */
1949 && !(WINDOWP (BVAR (b, last_selected_window)) 1979 && !(WINDOWP (BVAR (b, last_selected_window))
1950 && w != XWINDOW (BVAR (b, last_selected_window)) 1980 && w != XWINDOW (BVAR (b, last_selected_window))
1951 && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->buffer))) 1981 && EQ (buf, XWINDOW (BVAR (b, last_selected_window))->contents)))
1952 temp_set_point_both (b, 1982 temp_set_point_both (b,
1953 clip_to_bounds (BUF_BEGV (b), 1983 clip_to_bounds (BUF_BEGV (b),
1954 XMARKER (w->pointm)->charpos, 1984 marker_position (w->pointm),
1955 BUF_ZV (b)), 1985 BUF_ZV (b)),
1956 clip_to_bounds (BUF_BEGV_BYTE (b), 1986 clip_to_bounds (BUF_BEGV_BYTE (b),
1957 marker_byte_position (w->pointm), 1987 marker_byte_position (w->pointm),
@@ -1976,12 +2006,12 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
1976 if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame)))) 2006 if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame))))
1977 fset_root_window (XFRAME (o->frame), new); 2007 fset_root_window (XFRAME (o->frame), new);
1978 2008
1979 if (setflag) 2009 if (setflag)
1980 { 2010 {
1981 wset_left_col (n, o->left_col); 2011 n->left_col = o->left_col;
1982 wset_top_line (n, o->top_line); 2012 n->top_line = o->top_line;
1983 wset_total_cols (n, o->total_cols); 2013 n->total_cols = o->total_cols;
1984 wset_total_lines (n, o->total_lines); 2014 n->total_lines = o->total_lines;
1985 wset_normal_cols (n, o->normal_cols); 2015 wset_normal_cols (n, o->normal_cols);
1986 wset_normal_cols (o, make_float (1.0)); 2016 wset_normal_cols (o, make_float (1.0));
1987 wset_normal_lines (n, o->normal_lines); 2017 wset_normal_lines (n, o->normal_lines);
@@ -1997,7 +2027,7 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
1997 n->pseudo_window_p = 0; 2027 n->pseudo_window_p = 0;
1998 wset_window_end_vpos (n, make_number (0)); 2028 wset_window_end_vpos (n, make_number (0));
1999 wset_window_end_pos (n, make_number (0)); 2029 wset_window_end_pos (n, make_number (0));
2000 wset_window_end_valid (n, Qnil); 2030 n->window_end_valid = 0;
2001 n->frozen_window_start_p = 0; 2031 n->frozen_window_start_p = 0;
2002 } 2032 }
2003 2033
@@ -2013,13 +2043,8 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
2013 2043
2014 tem = o->parent; 2044 tem = o->parent;
2015 wset_parent (n, tem); 2045 wset_parent (n, tem);
2016 if (!NILP (tem)) 2046 if (!NILP (tem) && EQ (XWINDOW (tem)->contents, old))
2017 { 2047 wset_combination (XWINDOW (tem), XWINDOW (tem)->horizontal, new);
2018 if (EQ (XWINDOW (tem)->vchild, old))
2019 wset_vchild (XWINDOW (tem), new);
2020 if (EQ (XWINDOW (tem)->hchild, old))
2021 wset_hchild (XWINDOW (tem), new);
2022 }
2023} 2048}
2024 2049
2025/* If window WINDOW and its parent window are iso-combined, merge 2050/* If window WINDOW and its parent window are iso-combined, merge
@@ -2031,29 +2056,26 @@ recombine_windows (Lisp_Object window)
2031{ 2056{
2032 struct window *w, *p, *c; 2057 struct window *w, *p, *c;
2033 Lisp_Object parent, child; 2058 Lisp_Object parent, child;
2034 int horflag; 2059 bool horflag;
2035 2060
2036 w = XWINDOW (window); 2061 w = XWINDOW (window);
2037 parent = w->parent; 2062 parent = w->parent;
2038 if (!NILP (parent) && NILP (w->combination_limit)) 2063 if (!NILP (parent) && NILP (w->combination_limit))
2039 { 2064 {
2040 p = XWINDOW (parent); 2065 p = XWINDOW (parent);
2041 if (((!NILP (p->vchild) && !NILP (w->vchild)) 2066 if (WINDOWP (p->contents) && WINDOWP (w->contents)
2042 || (!NILP (p->hchild) && !NILP (w->hchild)))) 2067 && p->horizontal == w->horizontal)
2043 /* WINDOW and PARENT are both either a vertical or a horizontal 2068 /* WINDOW and PARENT are both either a vertical or a horizontal
2044 combination. */ 2069 combination. */
2045 { 2070 {
2046 horflag = NILP (w->vchild); 2071 horflag = WINDOW_HORIZONTAL_COMBINATION_P (w);
2047 child = horflag ? w->hchild : w->vchild; 2072 child = w->contents;
2048 c = XWINDOW (child); 2073 c = XWINDOW (child);
2049 2074
2050 /* Splice WINDOW's children into its parent's children and 2075 /* Splice WINDOW's children into its parent's children and
2051 assign new normal sizes. */ 2076 assign new normal sizes. */
2052 if (NILP (w->prev)) 2077 if (NILP (w->prev))
2053 if (horflag) 2078 wset_combination (p, horflag, child);
2054 wset_hchild (p, child);
2055 else
2056 wset_vchild (p, child);
2057 else 2079 else
2058 { 2080 {
2059 wset_prev (c, w->prev); 2081 wset_prev (c, w->prev);
@@ -2066,12 +2088,12 @@ recombine_windows (Lisp_Object window)
2066 2088
2067 if (horflag) 2089 if (horflag)
2068 wset_normal_cols (c, 2090 wset_normal_cols (c,
2069 make_float (XFLOATINT (c->total_cols) 2091 make_float ((double) c->total_cols
2070 / XFLOATINT (p->total_cols))); 2092 / (double) p->total_cols));
2071 else 2093 else
2072 wset_normal_lines (c, 2094 wset_normal_lines (c,
2073 make_float (XFLOATINT (c->total_lines) 2095 make_float ((double) c->total_lines
2074 / XFLOATINT (p->total_lines))); 2096 / (double) p->total_lines));
2075 2097
2076 if (NILP (c->next)) 2098 if (NILP (c->next))
2077 { 2099 {
@@ -2091,8 +2113,7 @@ recombine_windows (Lisp_Object window)
2091 } 2113 }
2092 2114
2093 /* WINDOW can be deleted now. */ 2115 /* WINDOW can be deleted now. */
2094 wset_vchild (w, Qnil); 2116 wset_combination (w, 0, Qnil);
2095 wset_hchild (w, Qnil);
2096 } 2117 }
2097 } 2118 }
2098} 2119}
@@ -2178,7 +2199,7 @@ candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf
2178 struct frame *f = XFRAME (w->frame); 2199 struct frame *f = XFRAME (w->frame);
2179 int candidate_p = 1; 2200 int candidate_p = 1;
2180 2201
2181 if (!BUFFERP (w->buffer)) 2202 if (!BUFFERP (w->contents))
2182 candidate_p = 0; 2203 candidate_p = 0;
2183 else if (MINI_WINDOW_P (w) 2204 else if (MINI_WINDOW_P (w)
2184 && (EQ (minibuf, Qlambda) 2205 && (EQ (minibuf, Qlambda)
@@ -2197,7 +2218,6 @@ candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf
2197 } 2218 }
2198 else if (EQ (all_frames, Qvisible)) 2219 else if (EQ (all_frames, Qvisible))
2199 { 2220 {
2200 FRAME_SAMPLE_VISIBILITY (f);
2201 candidate_p = FRAME_VISIBLE_P (f) 2221 candidate_p = FRAME_VISIBLE_P (f)
2202 && (FRAME_TERMINAL (XFRAME (w->frame)) 2222 && (FRAME_TERMINAL (XFRAME (w->frame))
2203 == FRAME_TERMINAL (XFRAME (selected_frame))); 2223 == FRAME_TERMINAL (XFRAME (selected_frame)));
@@ -2205,7 +2225,6 @@ candidate_window_p (Lisp_Object window, Lisp_Object owindow, Lisp_Object minibuf
2205 } 2225 }
2206 else if (INTEGERP (all_frames) && XINT (all_frames) == 0) 2226 else if (INTEGERP (all_frames) && XINT (all_frames) == 0)
2207 { 2227 {
2208 FRAME_SAMPLE_VISIBILITY (f);
2209 candidate_p = (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f) 2228 candidate_p = (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)
2210#ifdef HAVE_X_WINDOWS 2229#ifdef HAVE_X_WINDOWS
2211 /* Yuck!! If we've just created the frame and the 2230 /* Yuck!! If we've just created the frame and the
@@ -2520,7 +2539,7 @@ enum window_loop
2520 GET_BUFFER_WINDOW, /* Arg is buffer */ 2539 GET_BUFFER_WINDOW, /* Arg is buffer */
2521 REPLACE_BUFFER_IN_WINDOWS_SAFELY, /* Arg is buffer */ 2540 REPLACE_BUFFER_IN_WINDOWS_SAFELY, /* Arg is buffer */
2522 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */ 2541 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
2523 CHECK_ALL_WINDOWS 2542 CHECK_ALL_WINDOWS /* Arg is ignored */
2524}; 2543};
2525 2544
2526static Lisp_Object 2545static Lisp_Object
@@ -2584,7 +2603,7 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2584 switch (type) 2603 switch (type)
2585 { 2604 {
2586 case GET_BUFFER_WINDOW: 2605 case GET_BUFFER_WINDOW:
2587 if (EQ (w->buffer, obj) 2606 if (EQ (w->contents, obj)
2588 /* Don't find any minibuffer window except the one that 2607 /* Don't find any minibuffer window except the one that
2589 is currently in use. */ 2608 is currently in use. */
2590 && (MINI_WINDOW_P (w) ? EQ (window, minibuf_window) : 1)) 2609 && (MINI_WINDOW_P (w) ? EQ (window, minibuf_window) : 1))
@@ -2608,25 +2627,25 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2608 case REPLACE_BUFFER_IN_WINDOWS_SAFELY: 2627 case REPLACE_BUFFER_IN_WINDOWS_SAFELY:
2609 /* We could simply check whether the buffer shown by window 2628 /* We could simply check whether the buffer shown by window
2610 is live, and show another buffer in case it isn't. */ 2629 is live, and show another buffer in case it isn't. */
2611 if (EQ (w->buffer, obj)) 2630 if (EQ (w->contents, obj))
2612 { 2631 {
2613 /* Undedicate WINDOW. */ 2632 /* Undedicate WINDOW. */
2614 wset_dedicated (w, Qnil); 2633 wset_dedicated (w, Qnil);
2615 /* Make WINDOW show the buffer returned by 2634 /* Make WINDOW show the buffer returned by
2616 other_buffer_safely, don't run any hooks. */ 2635 other_buffer_safely, don't run any hooks. */
2617 set_window_buffer 2636 set_window_buffer
2618 (window, other_buffer_safely (w->buffer), 0, 0); 2637 (window, other_buffer_safely (w->contents), 0, 0);
2619 /* If WINDOW is the selected window, make its buffer 2638 /* If WINDOW is the selected window, make its buffer
2620 current. But do so only if the window shows the 2639 current. But do so only if the window shows the
2621 current buffer (Bug#6454). */ 2640 current buffer (Bug#6454). */
2622 if (EQ (window, selected_window) 2641 if (EQ (window, selected_window)
2623 && XBUFFER (w->buffer) == current_buffer) 2642 && XBUFFER (w->contents) == current_buffer)
2624 Fset_buffer (w->buffer); 2643 Fset_buffer (w->contents);
2625 } 2644 }
2626 break; 2645 break;
2627 2646
2628 case REDISPLAY_BUFFER_WINDOWS: 2647 case REDISPLAY_BUFFER_WINDOWS:
2629 if (EQ (w->buffer, obj)) 2648 if (EQ (w->contents, obj))
2630 { 2649 {
2631 mark_window_display_accurate (window, 0); 2650 mark_window_display_accurate (window, 0);
2632 w->update_mode_line = 1; 2651 w->update_mode_line = 1;
@@ -2636,11 +2655,20 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2636 } 2655 }
2637 break; 2656 break;
2638 2657
2639 /* Check for a window that has a killed buffer. */ 2658 /* Check for a leaf window that has a killed buffer
2659 or broken markers. */
2640 case CHECK_ALL_WINDOWS: 2660 case CHECK_ALL_WINDOWS:
2641 if (! NILP (w->buffer) 2661 if (BUFFERP (w->contents))
2642 && !BUFFER_LIVE_P (XBUFFER (w->buffer))) 2662 {
2643 emacs_abort (); 2663 struct buffer *b = XBUFFER (w->contents);
2664
2665 if (!BUFFER_LIVE_P (b))
2666 emacs_abort ();
2667 if (!MARKERP (w->start) || XMARKER (w->start)->buffer != b)
2668 emacs_abort ();
2669 if (!MARKERP (w->pointm) || XMARKER (w->pointm)->buffer != b)
2670 emacs_abort ();
2671 }
2644 break; 2672 break;
2645 2673
2646 case WINDOW_LOOP_UNUSED: 2674 case WINDOW_LOOP_UNUSED:
@@ -2721,7 +2749,7 @@ window-start value is reasonable when this function is called. */)
2721 struct window *w, *r, *s; 2749 struct window *w, *r, *s;
2722 struct frame *f; 2750 struct frame *f;
2723 Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta; 2751 Lisp_Object sibling, pwindow, swindow IF_LINT (= Qnil), delta;
2724 ptrdiff_t startpos IF_LINT (= 0); 2752 ptrdiff_t startpos IF_LINT (= 0), startbyte IF_LINT (= 0);
2725 int top IF_LINT (= 0), new_top, resize_failed; 2753 int top IF_LINT (= 0), new_top, resize_failed;
2726 2754
2727 w = decode_valid_window (window); 2755 w = decode_valid_window (window);
@@ -2757,9 +2785,10 @@ window-start value is reasonable when this function is called. */)
2757 else if (MINI_WINDOW_P (w)) /* && top > 0) */ 2785 else if (MINI_WINDOW_P (w)) /* && top > 0) */
2758 error ("Can't expand minibuffer to full frame"); 2786 error ("Can't expand minibuffer to full frame");
2759 2787
2760 if (!NILP (w->buffer)) 2788 if (BUFFERP (w->contents))
2761 { 2789 {
2762 startpos = marker_position (w->start); 2790 startpos = marker_position (w->start);
2791 startbyte = marker_byte_position (w->start);
2763 top = WINDOW_TOP_EDGE_LINE (w) 2792 top = WINDOW_TOP_EDGE_LINE (w)
2764 - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); 2793 - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
2765 /* Make sure WINDOW is the frame's selected window. */ 2794 /* Make sure WINDOW is the frame's selected window. */
@@ -2828,12 +2857,11 @@ window-start value is reasonable when this function is called. */)
2828 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 2857 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
2829 resize_failed = 0; 2858 resize_failed = 0;
2830 2859
2831 if (NILP (w->buffer)) 2860 if (!WINDOW_LEAF_P (w))
2832 { 2861 {
2833 /* Resize child windows vertically. */ 2862 /* Resize child windows vertically. */
2834 XSETINT (delta, XINT (r->total_lines) 2863 XSETINT (delta, r->total_lines - w->total_lines);
2835 - XINT (w->total_lines)); 2864 w->top_line = r->top_line;
2836 wset_top_line (w, r->top_line);
2837 resize_root_window (window, delta, Qnil, Qnil); 2865 resize_root_window (window, delta, Qnil, Qnil);
2838 if (window_resize_check (w, 0)) 2866 if (window_resize_check (w, 0))
2839 window_resize_apply (w, 0); 2867 window_resize_apply (w, 0);
@@ -2849,10 +2877,8 @@ window-start value is reasonable when this function is called. */)
2849 /* Resize child windows horizontally. */ 2877 /* Resize child windows horizontally. */
2850 if (!resize_failed) 2878 if (!resize_failed)
2851 { 2879 {
2852 wset_left_col (w, r->left_col); 2880 w->left_col = r->left_col;
2853 XSETINT (delta, 2881 XSETINT (delta, r->total_cols - w->total_cols);
2854 XINT (r->total_cols) - XINT (w->total_cols));
2855 wset_left_col (w, r->left_col);
2856 resize_root_window (window, delta, Qt, Qnil); 2882 resize_root_window (window, delta, Qt, Qnil);
2857 if (window_resize_check (w, 1)) 2883 if (window_resize_check (w, 1))
2858 window_resize_apply (w, 1); 2884 window_resize_apply (w, 1);
@@ -2890,28 +2916,21 @@ window-start value is reasonable when this function is called. */)
2890 sibling = w->next; 2916 sibling = w->next;
2891 s = XWINDOW (sibling); 2917 s = XWINDOW (sibling);
2892 wset_prev (s, Qnil); 2918 wset_prev (s, Qnil);
2893 if (!NILP (XWINDOW (w->parent)->vchild)) 2919 wset_combination (XWINDOW (w->parent),
2894 wset_vchild (XWINDOW (w->parent), sibling); 2920 XWINDOW (w->parent)->horizontal, sibling);
2895 else
2896 wset_hchild (XWINDOW (w->parent), sibling);
2897 } 2921 }
2898 2922
2899 /* Delete ROOT and all child windows of ROOT. */ 2923 /* Delete ROOT and all child windows of ROOT. */
2900 if (!NILP (r->vchild)) 2924 if (WINDOWP (r->contents))
2901 {
2902 delete_all_child_windows (r->vchild);
2903 wset_vchild (r, Qnil);
2904 }
2905 else if (!NILP (r->hchild))
2906 { 2925 {
2907 delete_all_child_windows (r->hchild); 2926 delete_all_child_windows (r->contents);
2908 wset_hchild (r, Qnil); 2927 wset_combination (r, 0, Qnil);
2909 } 2928 }
2910 2929
2911 replace_window (root, window, 1); 2930 replace_window (root, window, 1);
2912 2931
2913 /* This must become SWINDOW anyway ....... */ 2932 /* This must become SWINDOW anyway ....... */
2914 if (!NILP (w->buffer) && !resize_failed) 2933 if (BUFFERP (w->contents) && !resize_failed)
2915 { 2934 {
2916 /* Try to minimize scrolling, by setting the window start to the 2935 /* Try to minimize scrolling, by setting the window start to the
2917 point will cause the text at the old window start to be at the 2936 point will cause the text at the old window start to be at the
@@ -2920,19 +2939,19 @@ window-start value is reasonable when this function is called. */)
2920 when the display is not current, due to typeahead). */ 2939 when the display is not current, due to typeahead). */
2921 new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); 2940 new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
2922 if (new_top != top 2941 if (new_top != top
2923 && startpos >= BUF_BEGV (XBUFFER (w->buffer)) 2942 && startpos >= BUF_BEGV (XBUFFER (w->contents))
2924 && startpos <= BUF_ZV (XBUFFER (w->buffer))) 2943 && startpos <= BUF_ZV (XBUFFER (w->contents)))
2925 { 2944 {
2926 struct position pos; 2945 struct position pos;
2927 struct buffer *obuf = current_buffer; 2946 struct buffer *obuf = current_buffer;
2928 2947
2929 Fset_buffer (w->buffer); 2948 Fset_buffer (w->contents);
2930 /* This computation used to temporarily move point, but that 2949 /* This computation used to temporarily move point, but that
2931 can have unwanted side effects due to text properties. */ 2950 can have unwanted side effects due to text properties. */
2932 pos = *vmotion (startpos, -top, w); 2951 pos = *vmotion (startpos, startbyte, -top, w);
2933 2952
2934 set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos); 2953 set_marker_both (w->start, w->contents, pos.bufpos, pos.bytepos);
2935 wset_window_end_valid (w, Qnil); 2954 w->window_end_valid = 0;
2936 w->start_at_line_beg = (pos.bytepos == BEGV_BYTE 2955 w->start_at_line_beg = (pos.bytepos == BEGV_BYTE
2937 || FETCH_BYTE (pos.bytepos - 1) == '\n'); 2956 || FETCH_BYTE (pos.bytepos - 1) == '\n');
2938 /* We need to do this, so that the window-scroll-functions 2957 /* We need to do this, so that the window-scroll-functions
@@ -2958,22 +2977,24 @@ replace_buffer_in_windows (Lisp_Object buffer)
2958 call1 (Qreplace_buffer_in_windows, buffer); 2977 call1 (Qreplace_buffer_in_windows, buffer);
2959} 2978}
2960 2979
2961 2980/* If BUFFER is shown in a window, safely replace it with some other
2962/* Safely replace BUFFER with some other buffer in all windows of all 2981 buffer in all windows of all frames, even those on other keyboards. */
2963 frames, even those on other keyboards. */
2964 2982
2965void 2983void
2966replace_buffer_in_windows_safely (Lisp_Object buffer) 2984replace_buffer_in_windows_safely (Lisp_Object buffer)
2967{ 2985{
2968 Lisp_Object tail, frame; 2986 if (buffer_window_count (XBUFFER (buffer)))
2987 {
2988 Lisp_Object tail, frame;
2969 2989
2970 /* A single call to window_loop won't do the job because it only 2990 /* A single call to window_loop won't do the job because it only
2971 considers frames on the current keyboard. So loop manually over 2991 considers frames on the current keyboard. So loop manually over
2972 frames, and handle each one. */ 2992 frames, and handle each one. */
2973 FOR_EACH_FRAME (tail, frame) 2993 FOR_EACH_FRAME (tail, frame)
2974 window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame); 2994 window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame);
2995 }
2975} 2996}
2976 2997
2977/* If *ROWS or *COLS are too small a size for FRAME, set them to the 2998/* If *ROWS or *COLS are too small a size for FRAME, set them to the
2978 minimum allowable size. */ 2999 minimum allowable size. */
2979 3000
@@ -3123,12 +3144,13 @@ If FRAME is omitted or nil, it defaults to the selected frame. */)
3123 reset from the buffer's local settings. */ 3144 reset from the buffer's local settings. */
3124 3145
3125void 3146void
3126set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int keep_margins_p) 3147set_window_buffer (Lisp_Object window, Lisp_Object buffer,
3148 bool run_hooks_p, bool keep_margins_p)
3127{ 3149{
3128 struct window *w = XWINDOW (window); 3150 struct window *w = XWINDOW (window);
3129 struct buffer *b = XBUFFER (buffer); 3151 struct buffer *b = XBUFFER (buffer);
3130 ptrdiff_t count = SPECPDL_INDEX (); 3152 ptrdiff_t count = SPECPDL_INDEX ();
3131 int samebuf = EQ (buffer, w->buffer); 3153 int samebuf = EQ (buffer, w->contents);
3132 3154
3133 wset_buffer (w, buffer); 3155 wset_buffer (w, buffer);
3134 3156
@@ -3146,7 +3168,7 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int
3146 wset_window_end_pos (w, make_number (0)); 3168 wset_window_end_pos (w, make_number (0));
3147 wset_window_end_vpos (w, make_number (0)); 3169 wset_window_end_vpos (w, make_number (0));
3148 memset (&w->last_cursor, 0, sizeof w->last_cursor); 3170 memset (&w->last_cursor, 0, sizeof w->last_cursor);
3149 wset_window_end_valid (w, Qnil); 3171
3150 if (!(keep_margins_p && samebuf)) 3172 if (!(keep_margins_p && samebuf))
3151 { /* If we're not actually changing the buffer, don't reset hscroll and 3173 { /* If we're not actually changing the buffer, don't reset hscroll and
3152 vscroll. This case happens for example when called from 3174 vscroll. This case happens for example when called from
@@ -3247,11 +3269,10 @@ This function runs `window-scroll-functions' before running
3247 if (!BUFFER_LIVE_P (XBUFFER (buffer))) 3269 if (!BUFFER_LIVE_P (XBUFFER (buffer)))
3248 error ("Attempt to display deleted buffer"); 3270 error ("Attempt to display deleted buffer");
3249 3271
3250 tem = w->buffer; 3272 tem = w->contents;
3251 if (NILP (tem)) 3273 if (NILP (tem))
3252 error ("Window is deleted"); 3274 error ("Window is deleted");
3253 else if (!EQ (tem, Qt)) 3275 else
3254 /* w->buffer is t when the window is first being set up. */
3255 { 3276 {
3256 if (!EQ (tem, buffer)) 3277 if (!EQ (tem, buffer))
3257 { 3278 {
@@ -3301,19 +3322,19 @@ displaying that buffer. */)
3301 struct window *w = XWINDOW (object); 3322 struct window *w = XWINDOW (object);
3302 mark_window_display_accurate (object, 0); 3323 mark_window_display_accurate (object, 0);
3303 w->update_mode_line = 1; 3324 w->update_mode_line = 1;
3304 if (BUFFERP (w->buffer)) 3325 if (BUFFERP (w->contents))
3305 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 3326 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
3306 ++update_mode_lines; 3327 ++update_mode_lines;
3307 return Qt; 3328 return Qt;
3308 } 3329 }
3309 3330
3310 if (STRINGP (object)) 3331 if (STRINGP (object))
3311 object = Fget_buffer (object); 3332 object = Fget_buffer (object);
3312 if (BUFFERP (object) && BUFFER_LIVE_P (XBUFFER (object))) 3333 if (BUFFERP (object) && BUFFER_LIVE_P (XBUFFER (object))
3334 && buffer_window_count (XBUFFER (object)))
3313 { 3335 {
3314 /* Walk all windows looking for buffer, and force update 3336 /* If buffer is live and shown in at least one window, find
3315 of each of those windows. */ 3337 all windows showing this buffer and force update of them. */
3316
3317 object = window_loop (REDISPLAY_BUFFER_WINDOWS, object, 0, Qvisible); 3338 object = window_loop (REDISPLAY_BUFFER_WINDOWS, object, 0, Qvisible);
3318 return NILP (object) ? Qnil : Qt; 3339 return NILP (object) ? Qnil : Qt;
3319 } 3340 }
@@ -3371,7 +3392,7 @@ temp_output_buffer_show (register Lisp_Object buf)
3371 record_unwind_protect (Fset_buffer, prev_buffer); 3392 record_unwind_protect (Fset_buffer, prev_buffer);
3372 record_unwind_protect (select_window_norecord, prev_window); 3393 record_unwind_protect (select_window_norecord, prev_window);
3373 Fselect_window (window, Qt); 3394 Fselect_window (window, Qt);
3374 Fset_buffer (w->buffer); 3395 Fset_buffer (w->contents);
3375 Frun_hooks (1, &Qtemp_buffer_show_hook); 3396 Frun_hooks (1, &Qtemp_buffer_show_hook);
3376 unbind_to (count, Qnil); 3397 unbind_to (count, Qnil);
3377 } 3398 }
@@ -3382,7 +3403,7 @@ temp_output_buffer_show (register Lisp_Object buf)
3382 WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only 3403 WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only
3383 horizontal child). */ 3404 horizontal child). */
3384static void 3405static void
3385make_parent_window (Lisp_Object window, int horflag) 3406make_parent_window (Lisp_Object window, bool horflag)
3386{ 3407{
3387 Lisp_Object parent; 3408 Lisp_Object parent;
3388 register struct window *o, *p; 3409 register struct window *o, *p;
@@ -3392,21 +3413,20 @@ make_parent_window (Lisp_Object window, int horflag)
3392 memcpy ((char *) p + sizeof (struct vectorlike_header), 3413 memcpy ((char *) p + sizeof (struct vectorlike_header),
3393 (char *) o + sizeof (struct vectorlike_header), 3414 (char *) o + sizeof (struct vectorlike_header),
3394 word_size * VECSIZE (struct window)); 3415 word_size * VECSIZE (struct window));
3416 /* P's buffer slot may change from nil to a buffer... */
3417 adjust_window_count (p, 1);
3395 XSETWINDOW (parent, p); 3418 XSETWINDOW (parent, p);
3396 3419
3397 p->sequence_number = ++sequence_number;
3398
3399 replace_window (window, parent, 1); 3420 replace_window (window, parent, 1);
3400 3421
3401 wset_next (o, Qnil); 3422 wset_next (o, Qnil);
3402 wset_prev (o, Qnil); 3423 wset_prev (o, Qnil);
3403 wset_parent (o, parent); 3424 wset_parent (o, parent);
3404 3425 /* ...but now P becomes an internal window. */
3405 wset_hchild (p, horflag ? window : Qnil);
3406 wset_vchild (p, horflag ? Qnil : window);
3407 wset_start (p, Qnil); 3426 wset_start (p, Qnil);
3408 wset_pointm (p, Qnil); 3427 wset_pointm (p, Qnil);
3409 wset_buffer (p, Qnil); 3428 wset_buffer (p, Qnil);
3429 wset_combination (p, horflag, window);
3410 wset_combination_limit (p, Qnil); 3430 wset_combination_limit (p, Qnil);
3411 wset_window_parameters (p, Qnil); 3431 wset_window_parameters (p, Qnil);
3412} 3432}
@@ -3421,10 +3441,6 @@ make_window (void)
3421 w = allocate_window (); 3441 w = allocate_window ();
3422 /* Initialize Lisp data. Note that allocate_window initializes all 3442 /* Initialize Lisp data. Note that allocate_window initializes all
3423 Lisp data to nil, so do it only for slots which should not be nil. */ 3443 Lisp data to nil, so do it only for slots which should not be nil. */
3424 wset_left_col (w, make_number (0));
3425 wset_top_line (w, make_number (0));
3426 wset_total_lines (w, make_number (0));
3427 wset_total_cols (w, make_number (0));
3428 wset_normal_lines (w, make_float (1.0)); 3444 wset_normal_lines (w, make_float (1.0));
3429 wset_normal_cols (w, make_float (1.0)); 3445 wset_normal_cols (w, make_float (1.0));
3430 wset_new_total (w, make_number (0)); 3446 wset_new_total (w, make_number (0));
@@ -3444,7 +3460,7 @@ make_window (void)
3444 w->nrows_scale_factor = w->ncols_scale_factor = 1; 3460 w->nrows_scale_factor = w->ncols_scale_factor = 1;
3445 w->phys_cursor_type = -1; 3461 w->phys_cursor_type = -1;
3446 w->phys_cursor_width = -1; 3462 w->phys_cursor_width = -1;
3447 w->sequence_number = ++sequence_number; 3463 w->column_number_displayed = -1;
3448 3464
3449 /* Reset window_list. */ 3465 /* Reset window_list. */
3450 Vwindow_list = Qnil; 3466 Vwindow_list = Qnil;
@@ -3495,14 +3511,14 @@ Note: This function does not operate on any child windows of WINDOW. */)
3495 `window-min-height' or `window-min-width'. It does check that window 3511 `window-min-height' or `window-min-width'. It does check that window
3496 sizes do not drop below one line (two columns). */ 3512 sizes do not drop below one line (two columns). */
3497static int 3513static int
3498window_resize_check (struct window *w, int horflag) 3514window_resize_check (struct window *w, bool horflag)
3499{ 3515{
3500 struct window *c; 3516 struct window *c;
3501 3517
3502 if (!NILP (w->vchild)) 3518 if (WINDOW_VERTICAL_COMBINATION_P (w))
3503 /* W is a vertical combination. */ 3519 /* W is a vertical combination. */
3504 { 3520 {
3505 c = XWINDOW (w->vchild); 3521 c = XWINDOW (w->contents);
3506 if (horflag) 3522 if (horflag)
3507 /* All child windows of W must have the same width as W. */ 3523 /* All child windows of W must have the same width as W. */
3508 { 3524 {
@@ -3530,10 +3546,10 @@ window_resize_check (struct window *w, int horflag)
3530 return (sum_of_sizes == XINT (w->new_total)); 3546 return (sum_of_sizes == XINT (w->new_total));
3531 } 3547 }
3532 } 3548 }
3533 else if (!NILP (w->hchild)) 3549 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
3534 /* W is a horizontal combination. */ 3550 /* W is a horizontal combination. */
3535 { 3551 {
3536 c = XWINDOW (w->hchild); 3552 c = XWINDOW (w->contents);
3537 if (horflag) 3553 if (horflag)
3538 /* The sum of the widths of the child windows of W must equal W's 3554 /* The sum of the widths of the child windows of W must equal W's
3539 width. */ 3555 width. */
@@ -3576,7 +3592,7 @@ window_resize_check (struct window *w, int horflag)
3576 This function does not perform any error checks. Make sure you have 3592 This function does not perform any error checks. Make sure you have
3577 run window_resize_check on W before applying this function. */ 3593 run window_resize_check on W before applying this function. */
3578static void 3594static void
3579window_resize_apply (struct window *w, int horflag) 3595window_resize_apply (struct window *w, bool horflag)
3580{ 3596{
3581 struct window *c; 3597 struct window *c;
3582 int pos; 3598 int pos;
@@ -3585,50 +3601,50 @@ window_resize_apply (struct window *w, int horflag)
3585 parent window has been set *before*. */ 3601 parent window has been set *before*. */
3586 if (horflag) 3602 if (horflag)
3587 { 3603 {
3588 wset_total_cols (w, w->new_total); 3604 w->total_cols = XFASTINT (w->new_total);
3589 if (NUMBERP (w->new_normal)) 3605 if (NUMBERP (w->new_normal))
3590 wset_normal_cols (w, w->new_normal); 3606 wset_normal_cols (w, w->new_normal);
3591 3607
3592 pos = XINT (w->left_col); 3608 pos = w->left_col;
3593 } 3609 }
3594 else 3610 else
3595 { 3611 {
3596 wset_total_lines (w, w->new_total); 3612 w->total_lines = XFASTINT (w->new_total);
3597 if (NUMBERP (w->new_normal)) 3613 if (NUMBERP (w->new_normal))
3598 wset_normal_lines (w, w->new_normal); 3614 wset_normal_lines (w, w->new_normal);
3599 3615
3600 pos = XINT (w->top_line); 3616 pos = w->top_line;
3601 } 3617 }
3602 3618
3603 if (!NILP (w->vchild)) 3619 if (WINDOW_VERTICAL_COMBINATION_P (w))
3604 /* W is a vertical combination. */ 3620 /* W is a vertical combination. */
3605 { 3621 {
3606 c = XWINDOW (w->vchild); 3622 c = XWINDOW (w->contents);
3607 while (c) 3623 while (c)
3608 { 3624 {
3609 if (horflag) 3625 if (horflag)
3610 wset_left_col (c, make_number (pos)); 3626 c->left_col = pos;
3611 else 3627 else
3612 wset_top_line (c, make_number (pos)); 3628 c->top_line = pos;
3613 window_resize_apply (c, horflag); 3629 window_resize_apply (c, horflag);
3614 if (!horflag) 3630 if (!horflag)
3615 pos = pos + XINT (c->total_lines); 3631 pos = pos + c->total_lines;
3616 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3632 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3617 } 3633 }
3618 } 3634 }
3619 else if (!NILP (w->hchild)) 3635 else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
3620 /* W is a horizontal combination. */ 3636 /* W is a horizontal combination. */
3621 { 3637 {
3622 c = XWINDOW (w->hchild); 3638 c = XWINDOW (w->contents);
3623 while (c) 3639 while (c)
3624 { 3640 {
3625 if (horflag) 3641 if (horflag)
3626 wset_left_col (c, make_number (pos)); 3642 c->left_col = pos;
3627 else 3643 else
3628 wset_top_line (c, make_number (pos)); 3644 c->top_line = pos;
3629 window_resize_apply (c, horflag); 3645 window_resize_apply (c, horflag);
3630 if (horflag) 3646 if (horflag)
3631 pos = pos + XINT (c->total_cols); 3647 pos = pos + c->total_cols;
3632 c = NILP (c->next) ? 0 : XWINDOW (c->next); 3648 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3633 } 3649 }
3634 } 3650 }
@@ -3657,11 +3673,11 @@ be applied on the Elisp level. */)
3657{ 3673{
3658 struct frame *f = decode_live_frame (frame); 3674 struct frame *f = decode_live_frame (frame);
3659 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f)); 3675 struct window *r = XWINDOW (FRAME_ROOT_WINDOW (f));
3660 int horflag = !NILP (horizontal); 3676 bool horflag = !NILP (horizontal);
3661 3677
3662 if (!window_resize_check (r, horflag) 3678 if (!window_resize_check (r, horflag)
3663 || ! EQ (r->new_total, 3679 || (XINT (r->new_total)
3664 (horflag ? r->total_cols : r->total_lines))) 3680 != (horflag ? r->total_cols : r->total_lines)))
3665 return Qnil; 3681 return Qnil;
3666 3682
3667 block_input (); 3683 block_input ();
@@ -3687,7 +3703,7 @@ be applied on the Elisp level. */)
3687 satisfy the request. The result will be meaningful if and only if 3703 satisfy the request. The result will be meaningful if and only if
3688 F's windows have meaningful sizes when you call this. */ 3704 F's windows have meaningful sizes when you call this. */
3689void 3705void
3690resize_frame_windows (struct frame *f, int size, int horflag) 3706resize_frame_windows (struct frame *f, int size, bool horflag)
3691{ 3707{
3692 Lisp_Object root = f->root_window; 3708 Lisp_Object root = f->root_window;
3693 struct window *r = XWINDOW (root); 3709 struct window *r = XWINDOW (root);
@@ -3701,18 +3717,17 @@ resize_frame_windows (struct frame *f, int size, int horflag)
3701 - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) 3717 - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
3702 ? 1 : 0))); 3718 ? 1 : 0)));
3703 3719
3704 wset_top_line (r, make_number (FRAME_TOP_MARGIN (f))); 3720 r->top_line = FRAME_TOP_MARGIN (f);
3705 if (NILP (r->vchild) && NILP (r->hchild)) 3721 if (WINDOW_LEAF_P (r))
3706 /* For a leaf root window just set the size. */ 3722 /* For a leaf root window just set the size. */
3707 if (horflag) 3723 if (horflag)
3708 wset_total_cols (r, make_number (new_size)); 3724 r->total_cols = new_size;
3709 else 3725 else
3710 wset_total_lines (r, make_number (new_size)); 3726 r->total_lines = new_size;
3711 else 3727 else
3712 { 3728 {
3713 /* old_size is the old size of the frame's root window. */ 3729 /* old_size is the old size of the frame's root window. */
3714 int old_size = XFASTINT (horflag ? r->total_cols 3730 int old_size = horflag ? r->total_cols : r->total_lines;
3715 : r->total_lines);
3716 Lisp_Object delta; 3731 Lisp_Object delta;
3717 3732
3718 XSETINT (delta, new_size - old_size); 3733 XSETINT (delta, new_size - old_size);
@@ -3742,9 +3757,9 @@ resize_frame_windows (struct frame *f, int size, int horflag)
3742 root = f->selected_window; 3757 root = f->selected_window;
3743 Fdelete_other_windows_internal (root, Qnil); 3758 Fdelete_other_windows_internal (root, Qnil);
3744 if (horflag) 3759 if (horflag)
3745 wset_total_cols (XWINDOW (root), make_number (new_size)); 3760 XWINDOW (root)->total_cols = new_size;
3746 else 3761 else
3747 wset_total_lines (XWINDOW (root), make_number (new_size)); 3762 XWINDOW (root)->total_lines = new_size;
3748 } 3763 }
3749 } 3764 }
3750 } 3765 }
@@ -3754,13 +3769,12 @@ resize_frame_windows (struct frame *f, int size, int horflag)
3754 { 3769 {
3755 m = XWINDOW (mini); 3770 m = XWINDOW (mini);
3756 if (horflag) 3771 if (horflag)
3757 wset_total_cols (m, make_number (size)); 3772 m->total_cols = size;
3758 else 3773 else
3759 { 3774 {
3760 /* Are we sure we always want 1 line here? */ 3775 /* Are we sure we always want 1 line here? */
3761 wset_total_lines (m, make_number (1)); 3776 m->total_lines = 1;
3762 wset_top_line 3777 m->top_line = r->top_line + r->total_lines;
3763 (m, make_number (XINT (r->top_line) + XINT (r->total_lines)));
3764 } 3778 }
3765 } 3779 }
3766 3780
@@ -3801,7 +3815,7 @@ set correctly. See the code of `split-window' for how this is done. */)
3801 register Lisp_Object new, frame, reference; 3815 register Lisp_Object new, frame, reference;
3802 register struct window *o, *p, *n, *r; 3816 register struct window *o, *p, *n, *r;
3803 struct frame *f; 3817 struct frame *f;
3804 int horflag 3818 bool horflag
3805 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */ 3819 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */
3806 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright); 3820 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
3807 int combination_limit = 0; 3821 int combination_limit = 0;
@@ -3819,9 +3833,9 @@ set correctly. See the code of `split-window' for how this is done. */)
3819 combination_limit = 3833 combination_limit =
3820 EQ (Vwindow_combination_limit, Qt) 3834 EQ (Vwindow_combination_limit, Qt)
3821 || NILP (o->parent) 3835 || NILP (o->parent)
3822 || NILP (horflag 3836 || (horflag
3823 ? (XWINDOW (o->parent)->hchild) 3837 ? WINDOW_VERTICAL_COMBINATION_P (XWINDOW (o->parent))
3824 : (XWINDOW (o->parent)->vchild)); 3838 : WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (o->parent)));
3825 3839
3826 /* We need a live reference window to initialize some parameters. */ 3840 /* We need a live reference window to initialize some parameters. */
3827 if (WINDOW_LIVE_P (old)) 3841 if (WINDOW_LIVE_P (old))
@@ -3844,20 +3858,21 @@ set correctly. See the code of `split-window' for how this is done. */)
3844 p = XWINDOW (o->parent); 3858 p = XWINDOW (o->parent);
3845 /* Temporarily pretend we split the parent window. */ 3859 /* Temporarily pretend we split the parent window. */
3846 wset_new_total 3860 wset_new_total
3847 (p, make_number (XINT (horflag ? p->total_cols : p->total_lines) 3861 (p, make_number ((horflag ? p->total_cols : p->total_lines)
3848 - XINT (total_size))); 3862 - XINT (total_size)));
3849 if (!window_resize_check (p, horflag)) 3863 if (!window_resize_check (p, horflag))
3850 error ("Window sizes don't fit"); 3864 error ("Window sizes don't fit");
3851 else 3865 else
3852 /* Undo the temporary pretension. */ 3866 /* Undo the temporary pretension. */
3853 wset_new_total (p, horflag ? p->total_cols : p->total_lines); 3867 wset_new_total (p, make_number
3868 (horflag ? p->total_cols : p->total_lines));
3854 } 3869 }
3855 else 3870 else
3856 { 3871 {
3857 if (!window_resize_check (o, horflag)) 3872 if (!window_resize_check (o, horflag))
3858 error ("Resizing old window failed"); 3873 error ("Resizing old window failed");
3859 else if (XINT (total_size) + XINT (o->new_total) 3874 else if (XINT (total_size) + XINT (o->new_total)
3860 != XINT (horflag ? o->total_cols : o->total_lines)) 3875 != (horflag ? o->total_cols : o->total_lines))
3861 error ("Sum of sizes of old and new window don't fit"); 3876 error ("Sum of sizes of old and new window don't fit");
3862 } 3877 }
3863 3878
@@ -3877,7 +3892,8 @@ set correctly. See the code of `split-window' for how this is done. */)
3877 that its children get merged into another window. */ 3892 that its children get merged into another window. */
3878 wset_combination_limit (p, Qt); 3893 wset_combination_limit (p, Qt);
3879 /* These get applied below. */ 3894 /* These get applied below. */
3880 wset_new_total (p, horflag ? o->total_cols : o->total_lines); 3895 wset_new_total (p, make_number
3896 (horflag ? o->total_cols : o->total_lines));
3881 wset_new_normal (p, new_normal); 3897 wset_new_normal (p, new_normal);
3882 } 3898 }
3883 else 3899 else
@@ -3889,17 +3905,12 @@ set correctly. See the code of `split-window' for how this is done. */)
3889 n = XWINDOW (new); 3905 n = XWINDOW (new);
3890 wset_frame (n, frame); 3906 wset_frame (n, frame);
3891 wset_parent (n, o->parent); 3907 wset_parent (n, o->parent);
3892 wset_vchild (n, Qnil);
3893 wset_hchild (n, Qnil);
3894 3908
3895 if (EQ (side, Qabove) || EQ (side, Qleft)) 3909 if (EQ (side, Qabove) || EQ (side, Qleft))
3896 { 3910 {
3897 wset_prev (n, o->prev); 3911 wset_prev (n, o->prev);
3898 if (NILP (n->prev)) 3912 if (NILP (n->prev))
3899 if (horflag) 3913 wset_combination (p, horflag, new);
3900 wset_hchild (p, new);
3901 else
3902 wset_vchild (p, new);
3903 else 3914 else
3904 wset_next (XWINDOW (n->prev), new); 3915 wset_next (XWINDOW (n->prev), new);
3905 wset_next (n, old); 3916 wset_next (n, old);
@@ -3914,8 +3925,7 @@ set correctly. See the code of `split-window' for how this is done. */)
3914 wset_next (o, new); 3925 wset_next (o, new);
3915 } 3926 }
3916 3927
3917 wset_buffer (n, Qt); 3928 n->window_end_valid = 0;
3918 wset_window_end_valid (n, Qnil);
3919 memset (&n->last_cursor, 0, sizeof n->last_cursor); 3929 memset (&n->last_cursor, 0, sizeof n->last_cursor);
3920 3930
3921 /* Get special geometry settings from reference window. */ 3931 /* Get special geometry settings from reference window. */
@@ -3930,13 +3940,13 @@ set correctly. See the code of `split-window' for how this is done. */)
3930 /* Directly assign orthogonal coordinates and sizes. */ 3940 /* Directly assign orthogonal coordinates and sizes. */
3931 if (horflag) 3941 if (horflag)
3932 { 3942 {
3933 wset_top_line (n, o->top_line); 3943 n->top_line = o->top_line;
3934 wset_total_lines (n, o->total_lines); 3944 n->total_lines = o->total_lines;
3935 } 3945 }
3936 else 3946 else
3937 { 3947 {
3938 wset_left_col (n, o->left_col); 3948 n->left_col = o->left_col;
3939 wset_total_cols (n, o->total_cols); 3949 n->total_cols = o->total_cols;
3940 } 3950 }
3941 3951
3942 /* Iso-coordinates and sizes are assigned by window_resize_apply, 3952 /* Iso-coordinates and sizes are assigned by window_resize_apply,
@@ -3949,7 +3959,7 @@ set correctly. See the code of `split-window' for how this is done. */)
3949 adjust_glyphs (f); 3959 adjust_glyphs (f);
3950 /* Set buffer of NEW to buffer of reference window. Don't run 3960 /* Set buffer of NEW to buffer of reference window. Don't run
3951 any hooks. */ 3961 any hooks. */
3952 set_window_buffer (new, r->buffer, 0, 1); 3962 set_window_buffer (new, r->contents, 0, 1);
3953 unblock_input (); 3963 unblock_input ();
3954 3964
3955 /* Maybe we should run the scroll functions in Elisp (which already 3965 /* Maybe we should run the scroll functions in Elisp (which already
@@ -3971,13 +3981,11 @@ Signal an error when WINDOW is the only window on its frame. */)
3971 register Lisp_Object parent, sibling, frame, root; 3981 register Lisp_Object parent, sibling, frame, root;
3972 struct window *w, *p, *s, *r; 3982 struct window *w, *p, *s, *r;
3973 struct frame *f; 3983 struct frame *f;
3974 int horflag; 3984 bool horflag, before_sibling = 0;
3975 int before_sibling = 0;
3976 3985
3977 w = decode_any_window (window); 3986 w = decode_any_window (window);
3978 XSETWINDOW (window, w); 3987 XSETWINDOW (window, w);
3979 if (NILP (w->buffer) 3988 if (NILP (w->contents))
3980 && NILP (w->hchild) && NILP (w->vchild))
3981 /* It's a no-op to delete an already deleted window. */ 3989 /* It's a no-op to delete an already deleted window. */
3982 return Qnil; 3990 return Qnil;
3983 3991
@@ -3991,7 +3999,7 @@ Signal an error when WINDOW is the only window on its frame. */)
3991 error ("Attempt to delete sole window of parent"); 3999 error ("Attempt to delete sole window of parent");
3992 4000
3993 p = XWINDOW (parent); 4001 p = XWINDOW (parent);
3994 horflag = NILP (p->vchild); 4002 horflag = WINDOW_HORIZONTAL_COMBINATION_P (p);
3995 4003
3996 frame = WINDOW_FRAME (w); 4004 frame = WINDOW_FRAME (w);
3997 f = XFRAME (frame); 4005 f = XFRAME (frame);
@@ -4009,10 +4017,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4009 sibling = w->next; 4017 sibling = w->next;
4010 s = XWINDOW (sibling); 4018 s = XWINDOW (sibling);
4011 wset_prev (s, Qnil); 4019 wset_prev (s, Qnil);
4012 if (horflag) 4020 wset_combination (p, horflag, sibling);
4013 wset_hchild (p, sibling);
4014 else
4015 wset_vchild (p, sibling);
4016 } 4021 }
4017 else 4022 else
4018 /* Get SIBLING above (on the left of) WINDOW. */ 4023 /* Get SIBLING above (on the left of) WINDOW. */
@@ -4025,8 +4030,8 @@ Signal an error when WINDOW is the only window on its frame. */)
4025 } 4030 }
4026 4031
4027 if (window_resize_check (r, horflag) 4032 if (window_resize_check (r, horflag)
4028 && EQ (r->new_total, 4033 && (XINT (r->new_total)
4029 (horflag ? r->total_cols : r->total_lines))) 4034 == (horflag ? r->total_cols : r->total_lines)))
4030 /* We can delete WINDOW now. */ 4035 /* We can delete WINDOW now. */
4031 { 4036 {
4032 4037
@@ -4051,17 +4056,12 @@ Signal an error when WINDOW is the only window on its frame. */)
4051 wset_next (w, Qnil); /* Don't delete w->next too. */ 4056 wset_next (w, Qnil); /* Don't delete w->next too. */
4052 free_window_matrices (w); 4057 free_window_matrices (w);
4053 4058
4054 if (!NILP (w->vchild)) 4059 if (WINDOWP (w->contents))
4055 { 4060 {
4056 delete_all_child_windows (w->vchild); 4061 delete_all_child_windows (w->contents);
4057 wset_vchild (w, Qnil); 4062 wset_combination (w, 0, Qnil);
4058 } 4063 }
4059 else if (!NILP (w->hchild)) 4064 else
4060 {
4061 delete_all_child_windows (w->hchild);
4062 wset_hchild (w, Qnil);
4063 }
4064 else if (!NILP (w->buffer))
4065 { 4065 {
4066 unshow_buffer (w); 4066 unshow_buffer (w);
4067 unchain_marker (XMARKER (w->pointm)); 4067 unchain_marker (XMARKER (w->pointm));
@@ -4080,8 +4080,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4080 wset_normal_cols (s, p->normal_cols); 4080 wset_normal_cols (s, p->normal_cols);
4081 wset_normal_lines (s, p->normal_lines); 4081 wset_normal_lines (s, p->normal_lines);
4082 /* Mark PARENT as deleted. */ 4082 /* Mark PARENT as deleted. */
4083 wset_vchild (p, Qnil); 4083 wset_combination (p, 0, Qnil);
4084 wset_hchild (p, Qnil);
4085 /* Try to merge SIBLING into its new parent. */ 4084 /* Try to merge SIBLING into its new parent. */
4086 recombine_windows (sibling); 4085 recombine_windows (sibling);
4087 } 4086 }
@@ -4129,10 +4128,7 @@ Signal an error when WINDOW is the only window on its frame. */)
4129 if (before_sibling) 4128 if (before_sibling)
4130 { 4129 {
4131 wset_prev (s, window); 4130 wset_prev (s, window);
4132 if (horflag) 4131 wset_combination (p, horflag, window);
4133 wset_hchild (p, window);
4134 else
4135 wset_vchild (p, window);
4136 } 4132 }
4137 else 4133 else
4138 { 4134 {
@@ -4172,10 +4168,8 @@ grow_mini_window (struct window *w, int delta)
4172 window_resize_apply (r, 0); 4168 window_resize_apply (r, 0);
4173 4169
4174 /* Grow the mini-window. */ 4170 /* Grow the mini-window. */
4175 wset_top_line 4171 w->top_line = r->top_line + r->total_lines;
4176 (w, make_number (XFASTINT (r->top_line) + XFASTINT (r->total_lines))); 4172 w->total_lines -= XINT (value);
4177 wset_total_lines
4178 (w, make_number (XFASTINT (w->total_lines) - XINT (value)));
4179 w->last_modified = 0; 4173 w->last_modified = 0;
4180 w->last_overlay_modified = 0; 4174 w->last_overlay_modified = 0;
4181 4175
@@ -4197,7 +4191,7 @@ shrink_mini_window (struct window *w)
4197 4191
4198 eassert (MINI_WINDOW_P (w)); 4192 eassert (MINI_WINDOW_P (w));
4199 4193
4200 size = XINT (w->total_lines); 4194 size = w->total_lines;
4201 if (size > 1) 4195 if (size > 1)
4202 { 4196 {
4203 root = FRAME_ROOT_WINDOW (f); 4197 root = FRAME_ROOT_WINDOW (f);
@@ -4210,9 +4204,8 @@ shrink_mini_window (struct window *w)
4210 window_resize_apply (r, 0); 4204 window_resize_apply (r, 0);
4211 4205
4212 /* Shrink the mini-window. */ 4206 /* Shrink the mini-window. */
4213 wset_top_line (w, make_number (XFASTINT (r->top_line) 4207 w->top_line = r->top_line + r->total_lines;
4214 + XFASTINT (r->total_lines))); 4208 w->total_lines = 1;
4215 wset_total_lines (w, make_number (1));
4216 4209
4217 w->last_modified = 0; 4210 w->last_modified = 0;
4218 w->last_overlay_modified = 0; 4211 w->last_overlay_modified = 0;
@@ -4246,7 +4239,7 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
4246 error ("Cannot resize a minibuffer-only frame"); 4239 error ("Cannot resize a minibuffer-only frame");
4247 4240
4248 r = XWINDOW (FRAME_ROOT_WINDOW (f)); 4241 r = XWINDOW (FRAME_ROOT_WINDOW (f));
4249 height = XINT (r->total_lines) + XINT (w->total_lines); 4242 height = r->total_lines + w->total_lines;
4250 if (window_resize_check (r, 0) 4243 if (window_resize_check (r, 0)
4251 && XINT (w->new_total) > 0 4244 && XINT (w->new_total) > 0
4252 && height == XINT (r->new_total) + XINT (w->new_total)) 4245 && height == XINT (r->new_total) + XINT (w->new_total))
@@ -4254,9 +4247,8 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
4254 block_input (); 4247 block_input ();
4255 window_resize_apply (r, 0); 4248 window_resize_apply (r, 0);
4256 4249
4257 wset_total_lines (w, w->new_total); 4250 w->total_lines = XFASTINT (w->new_total);
4258 wset_top_line (w, make_number (XINT (r->top_line) 4251 w->top_line = r->top_line + r->total_lines;
4259 + XINT (r->total_lines)));
4260 4252
4261 windows_or_buffers_changed++; 4253 windows_or_buffers_changed++;
4262 FRAME_WINDOW_SIZES_CHANGED (f) = 1; 4254 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
@@ -4279,10 +4271,8 @@ mark_window_cursors_off (struct window *w)
4279{ 4271{
4280 while (w) 4272 while (w)
4281 { 4273 {
4282 if (!NILP (w->hchild)) 4274 if (WINDOWP (w->contents))
4283 mark_window_cursors_off (XWINDOW (w->hchild)); 4275 mark_window_cursors_off (XWINDOW (w->contents));
4284 else if (!NILP (w->vchild))
4285 mark_window_cursors_off (XWINDOW (w->vchild));
4286 else 4276 else
4287 w->phys_cursor_on_p = 0; 4277 w->phys_cursor_on_p = 0;
4288 4278
@@ -4296,13 +4286,12 @@ mark_window_cursors_off (struct window *w)
4296int 4286int
4297window_internal_height (struct window *w) 4287window_internal_height (struct window *w)
4298{ 4288{
4299 int ht = XFASTINT (w->total_lines); 4289 int ht = w->total_lines;
4300 4290
4301 if (!MINI_WINDOW_P (w)) 4291 if (!MINI_WINDOW_P (w))
4302 { 4292 {
4303 if (!NILP (w->parent) 4293 if (!NILP (w->parent)
4304 || !NILP (w->vchild) 4294 || WINDOWP (w->contents)
4305 || !NILP (w->hchild)
4306 || !NILP (w->next) 4295 || !NILP (w->next)
4307 || !NILP (w->prev) 4296 || !NILP (w->prev)
4308 || WINDOW_WANTS_MODELINE_P (w)) 4297 || WINDOW_WANTS_MODELINE_P (w))
@@ -4441,7 +4430,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4441 else 4430 else
4442 spos = min (XINT (Fline_end_position (Qnil)) + 1, ZV); 4431 spos = min (XINT (Fline_end_position (Qnil)) + 1, ZV);
4443 set_marker_restricted (w->start, make_number (spos), 4432 set_marker_restricted (w->start, make_number (spos),
4444 w->buffer); 4433 w->contents);
4445 w->start_at_line_beg = 1; 4434 w->start_at_line_beg = 1;
4446 w->update_mode_line = 1; 4435 w->update_mode_line = 1;
4447 w->last_modified = 0; 4436 w->last_modified = 0;
@@ -4565,7 +4554,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4565 4554
4566 /* If control gets here, then we vscrolled. */ 4555 /* If control gets here, then we vscrolled. */
4567 4556
4568 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 4557 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
4569 4558
4570 /* Don't try to change the window start below. */ 4559 /* Don't try to change the window start below. */
4571 vscrolled = 1; 4560 vscrolled = 1;
@@ -4585,9 +4574,9 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4585 } 4574 }
4586 4575
4587 /* Set the window start, and set up the window for redisplay. */ 4576 /* Set the window start, and set up the window for redisplay. */
4588 set_marker_restricted (w->start, make_number (pos), 4577 set_marker_restricted_both (w->start, w->contents, IT_CHARPOS (it),
4589 w->buffer); 4578 IT_BYTEPOS (it));
4590 bytepos = XMARKER (w->start)->bytepos; 4579 bytepos = marker_byte_position (w->start);
4591 w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n'); 4580 w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n');
4592 w->update_mode_line = 1; 4581 w->update_mode_line = 1;
4593 w->last_modified = 0; 4582 w->last_modified = 0;
@@ -4606,7 +4595,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4606 even if there is a header line. */ 4595 even if there is a header line. */
4607 this_scroll_margin = max (0, scroll_margin); 4596 this_scroll_margin = max (0, scroll_margin);
4608 this_scroll_margin 4597 this_scroll_margin
4609 = min (this_scroll_margin, XFASTINT (w->total_lines) / 4); 4598 = min (this_scroll_margin, w->total_lines / 4);
4610 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f); 4599 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
4611 4600
4612 if (n > 0) 4601 if (n > 0)
@@ -4726,7 +4715,8 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
4726 register Lisp_Object tem; 4715 register Lisp_Object tem;
4727 int lose; 4716 int lose;
4728 Lisp_Object bolp; 4717 Lisp_Object bolp;
4729 ptrdiff_t startpos; 4718 ptrdiff_t startpos = marker_position (w->start);
4719 ptrdiff_t startbyte = marker_byte_position (w->start);
4730 Lisp_Object original_pos = Qnil; 4720 Lisp_Object original_pos = Qnil;
4731 4721
4732 /* If scrolling screen-fulls, compute the number of lines to 4722 /* If scrolling screen-fulls, compute the number of lines to
@@ -4734,8 +4724,6 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
4734 if (whole) 4724 if (whole)
4735 n *= max (1, ht - next_screen_context_lines); 4725 n *= max (1, ht - next_screen_context_lines);
4736 4726
4737 startpos = marker_position (w->start);
4738
4739 if (!NILP (Vscroll_preserve_screen_position)) 4727 if (!NILP (Vscroll_preserve_screen_position))
4740 { 4728 {
4741 if (window_scroll_preserve_vpos <= 0 4729 if (window_scroll_preserve_vpos <= 0
@@ -4743,10 +4731,8 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
4743 || NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command))) 4731 || NILP (Fget (KVAR (current_kboard, Vlast_command), Qscroll_command)))
4744 { 4732 {
4745 struct position posit 4733 struct position posit
4746 = *compute_motion (startpos, 0, 0, 0, 4734 = *compute_motion (startpos, startbyte, 0, 0, 0,
4747 PT, ht, 0, 4735 PT, ht, 0, -1, w->hscroll, 0, w);
4748 -1, w->hscroll,
4749 0, w);
4750 window_scroll_preserve_vpos = posit.vpos; 4736 window_scroll_preserve_vpos = posit.vpos;
4751 window_scroll_preserve_hpos = posit.hpos + w->hscroll; 4737 window_scroll_preserve_hpos = posit.hpos + w->hscroll;
4752 } 4738 }
@@ -4762,9 +4748,10 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
4762 { 4748 {
4763 Fvertical_motion (make_number (- (ht / 2)), window); 4749 Fvertical_motion (make_number (- (ht / 2)), window);
4764 startpos = PT; 4750 startpos = PT;
4751 startbyte = PT_BYTE;
4765 } 4752 }
4766 4753
4767 SET_PT (startpos); 4754 SET_PT_BOTH (startpos, startbyte);
4768 lose = n < 0 && PT == BEGV; 4755 lose = n < 0 && PT == BEGV;
4769 Fvertical_motion (make_number (n), window); 4756 Fvertical_motion (make_number (n), window);
4770 pos = PT; 4757 pos = PT;
@@ -4785,9 +4772,9 @@ window_scroll_line_based (Lisp_Object window, int n, int whole, int noerror)
4785 { 4772 {
4786 /* Don't use a scroll margin that is negative or too large. */ 4773 /* Don't use a scroll margin that is negative or too large. */
4787 int this_scroll_margin = 4774 int this_scroll_margin =
4788 max (0, min (scroll_margin, XINT (w->total_lines) / 4)); 4775 max (0, min (scroll_margin, w->total_lines / 4));
4789 4776
4790 set_marker_restricted_both (w->start, w->buffer, pos, pos_byte); 4777 set_marker_restricted_both (w->start, w->contents, pos, pos_byte);
4791 w->start_at_line_beg = !NILP (bolp); 4778 w->start_at_line_beg = !NILP (bolp);
4792 w->update_mode_line = 1; 4779 w->update_mode_line = 1;
4793 w->last_modified = 0; 4780 w->last_modified = 0;
@@ -4881,10 +4868,10 @@ scroll_command (Lisp_Object n, int direction)
4881 4868
4882 /* If selected window's buffer isn't current, make it current for 4869 /* If selected window's buffer isn't current, make it current for
4883 the moment. But don't screw up if window_scroll gets an error. */ 4870 the moment. But don't screw up if window_scroll gets an error. */
4884 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer) 4871 if (XBUFFER (XWINDOW (selected_window)->contents) != current_buffer)
4885 { 4872 {
4886 record_unwind_protect (save_excursion_restore, save_excursion_save ()); 4873 record_unwind_protect (save_excursion_restore, save_excursion_save ());
4887 Fset_buffer (XWINDOW (selected_window)->buffer); 4874 Fset_buffer (XWINDOW (selected_window)->contents);
4888 4875
4889 /* Make redisplay consider other windows than just selected_window. */ 4876 /* Make redisplay consider other windows than just selected_window. */
4890 ++windows_or_buffers_changed; 4877 ++windows_or_buffers_changed;
@@ -4999,8 +4986,8 @@ specifies the window to scroll. This takes precedence over
4999 record_unwind_protect (save_excursion_restore, save_excursion_save ()); 4986 record_unwind_protect (save_excursion_restore, save_excursion_save ());
5000 ++windows_or_buffers_changed; 4987 ++windows_or_buffers_changed;
5001 4988
5002 Fset_buffer (w->buffer); 4989 Fset_buffer (w->contents);
5003 SET_PT (marker_position (w->pointm)); 4990 SET_PT_BOTH (marker_position (w->pointm), marker_byte_position (w->pointm));
5004 4991
5005 if (NILP (arg)) 4992 if (NILP (arg))
5006 window_scroll (window, 1, 1, 1); 4993 window_scroll (window, 1, 1, 1);
@@ -5087,15 +5074,16 @@ displayed_window_lines (struct window *w)
5087{ 5074{
5088 struct it it; 5075 struct it it;
5089 struct text_pos start; 5076 struct text_pos start;
5077 ptrdiff_t charpos = marker_position (w->start);
5090 int height = window_box_height (w); 5078 int height = window_box_height (w);
5091 struct buffer *old_buffer; 5079 struct buffer *old_buffer;
5092 int bottom_y; 5080 int bottom_y;
5093 void *itdata = NULL; 5081 void *itdata = NULL;
5094 5082
5095 if (XBUFFER (w->buffer) != current_buffer) 5083 if (XBUFFER (w->contents) != current_buffer)
5096 { 5084 {
5097 old_buffer = current_buffer; 5085 old_buffer = current_buffer;
5098 set_buffer_internal (XBUFFER (w->buffer)); 5086 set_buffer_internal (XBUFFER (w->contents));
5099 } 5087 }
5100 else 5088 else
5101 old_buffer = NULL; 5089 old_buffer = NULL;
@@ -5103,9 +5091,9 @@ displayed_window_lines (struct window *w)
5103 /* In case W->start is out of the accessible range, do something 5091 /* In case W->start is out of the accessible range, do something
5104 reasonable. This happens in Info mode when Info-scroll-down 5092 reasonable. This happens in Info mode when Info-scroll-down
5105 calls (recenter -1) while W->start is 1. */ 5093 calls (recenter -1) while W->start is 1. */
5106 if (XMARKER (w->start)->charpos < BEGV) 5094 if (charpos < BEGV)
5107 SET_TEXT_POS (start, BEGV, BEGV_BYTE); 5095 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
5108 else if (XMARKER (w->start)->charpos > ZV) 5096 else if (charpos > ZV)
5109 SET_TEXT_POS (start, ZV, ZV_BYTE); 5097 SET_TEXT_POS (start, ZV, ZV_BYTE);
5110 else 5098 else
5111 SET_TEXT_POS_FROM_MARKER (start, w->start); 5099 SET_TEXT_POS_FROM_MARKER (start, w->start);
@@ -5141,7 +5129,7 @@ displayed_window_lines (struct window *w)
5141 5129
5142DEFUN ("recenter", Frecenter, Srecenter, 0, 1, "P", 5130DEFUN ("recenter", Frecenter, Srecenter, 0, 1, "P",
5143 doc: /* Center point in selected window and maybe redisplay frame. 5131 doc: /* Center point in selected window and maybe redisplay frame.
5144With prefix argument ARG, recenter putting point on screen line ARG 5132With a numeric prefix argument ARG, recenter putting point on screen line ARG
5145relative to the selected window. If ARG is negative, it counts up from the 5133relative to the selected window. If ARG is negative, it counts up from the
5146bottom of the window. (ARG should be less than the height of the window.) 5134bottom of the window. (ARG should be less than the height of the window.)
5147 5135
@@ -5157,7 +5145,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5157 (register Lisp_Object arg) 5145 (register Lisp_Object arg)
5158{ 5146{
5159 struct window *w = XWINDOW (selected_window); 5147 struct window *w = XWINDOW (selected_window);
5160 struct buffer *buf = XBUFFER (w->buffer); 5148 struct buffer *buf = XBUFFER (w->contents);
5161 struct buffer *obuf = current_buffer; 5149 struct buffer *obuf = current_buffer;
5162 int center_p = 0; 5150 int center_p = 0;
5163 ptrdiff_t charpos, bytepos; 5151 ptrdiff_t charpos, bytepos;
@@ -5201,7 +5189,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5201 /* Do this after making BUF current 5189 /* Do this after making BUF current
5202 in case scroll_margin is buffer-local. */ 5190 in case scroll_margin is buffer-local. */
5203 this_scroll_margin = 5191 this_scroll_margin =
5204 max (0, min (scroll_margin, XFASTINT (w->total_lines) / 4)); 5192 max (0, min (scroll_margin, w->total_lines / 4));
5205 5193
5206 /* Handle centering on a graphical frame specially. Such frames can 5194 /* Handle centering on a graphical frame specially. Such frames can
5207 have variable-height lines and centering point on the basis of 5195 have variable-height lines and centering point on the basis of
@@ -5298,7 +5286,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5298 5286
5299 iarg = max (iarg, this_scroll_margin); 5287 iarg = max (iarg, this_scroll_margin);
5300 5288
5301 pos = *vmotion (PT, -iarg, w); 5289 pos = *vmotion (PT, PT_BYTE, -iarg, w);
5302 charpos = pos.bufpos; 5290 charpos = pos.bufpos;
5303 bytepos = pos.bytepos; 5291 bytepos = pos.bytepos;
5304 } 5292 }
@@ -5314,17 +5302,17 @@ and redisplay normally--don't erase and redraw the frame. */)
5314 iarg += ht; 5302 iarg += ht;
5315 5303
5316 /* Don't let it get into the margin at either top or bottom. */ 5304 /* Don't let it get into the margin at either top or bottom. */
5317 iarg = max (iarg, this_scroll_margin); 5305 iarg = clip_to_bounds (this_scroll_margin, iarg,
5318 iarg = min (iarg, ht - this_scroll_margin - 1); 5306 ht - this_scroll_margin - 1);
5319 5307
5320 pos = *vmotion (PT, - iarg, w); 5308 pos = *vmotion (PT, PT_BYTE, - iarg, w);
5321 charpos = pos.bufpos; 5309 charpos = pos.bufpos;
5322 bytepos = pos.bytepos; 5310 bytepos = pos.bytepos;
5323 } 5311 }
5324 5312
5325 /* Set the new window start. */ 5313 /* Set the new window start. */
5326 set_marker_both (w->start, w->buffer, charpos, bytepos); 5314 set_marker_both (w->start, w->contents, charpos, bytepos);
5327 wset_window_end_valid (w, Qnil); 5315 w->window_end_valid = 0;
5328 5316
5329 w->optional_new_start = 1; 5317 w->optional_new_start = 1;
5330 5318
@@ -5367,9 +5355,8 @@ zero means top of window, negative means relative to bottom of window. */)
5367 int this_scroll_margin; 5355 int this_scroll_margin;
5368#endif 5356#endif
5369 5357
5370 if (!(BUFFERP (w->buffer) 5358 if (!(BUFFERP (w->contents) && XBUFFER (w->contents) == current_buffer))
5371 && XBUFFER (w->buffer) == current_buffer)) 5359 /* This test is needed to make sure PT/PT_BYTE make sense in w->contents
5372 /* This test is needed to make sure PT/PT_BYTE make sense in w->buffer
5373 when passed below to set_marker_both. */ 5360 when passed below to set_marker_both. */
5374 error ("move-to-window-line called from unrelated buffer"); 5361 error ("move-to-window-line called from unrelated buffer");
5375 5362
@@ -5379,7 +5366,7 @@ zero means top of window, negative means relative to bottom of window. */)
5379 { 5366 {
5380 int height = window_internal_height (w); 5367 int height = window_internal_height (w);
5381 Fvertical_motion (make_number (- (height / 2)), window); 5368 Fvertical_motion (make_number (- (height / 2)), window);
5382 set_marker_both (w->start, w->buffer, PT, PT_BYTE); 5369 set_marker_both (w->start, w->contents, PT, PT_BYTE);
5383 w->start_at_line_beg = !NILP (Fbolp ()); 5370 w->start_at_line_beg = !NILP (Fbolp ());
5384 w->force_start = 1; 5371 w->force_start = 1;
5385 } 5372 }
@@ -5529,11 +5516,11 @@ the return value is nil. Otherwise the value is t. */)
5529 window-point of the final-selected-window to the window-point of 5516 window-point of the final-selected-window to the window-point of
5530 the current-selected-window. So we have to be careful which 5517 the current-selected-window. So we have to be careful which
5531 point of the current-buffer we copy into old_point. */ 5518 point of the current-buffer we copy into old_point. */
5532 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer) 5519 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
5533 && WINDOWP (selected_window) 5520 && WINDOWP (selected_window)
5534 && EQ (XWINDOW (selected_window)->buffer, new_current_buffer) 5521 && EQ (XWINDOW (selected_window)->contents, new_current_buffer)
5535 && !EQ (selected_window, data->current_window)) 5522 && !EQ (selected_window, data->current_window))
5536 old_point = XMARKER (XWINDOW (data->current_window)->pointm)->charpos; 5523 old_point = marker_position (XWINDOW (data->current_window)->pointm);
5537 else 5524 else
5538 old_point = PT; 5525 old_point = PT;
5539 else 5526 else
@@ -5545,10 +5532,10 @@ the return value is nil. Otherwise the value is t. */)
5545 So if possible we want this arbitrary choice of "which point" to 5532 So if possible we want this arbitrary choice of "which point" to
5546 be the one from the to-be-selected-window so as to prevent this 5533 be the one from the to-be-selected-window so as to prevent this
5547 window's cursor from being copied from another window. */ 5534 window's cursor from being copied from another window. */
5548 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer) 5535 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)
5549 /* If current_window = selected_window, its point is in BUF_PT. */ 5536 /* If current_window = selected_window, its point is in BUF_PT. */
5550 && !EQ (selected_window, data->current_window)) 5537 && !EQ (selected_window, data->current_window))
5551 old_point = XMARKER (XWINDOW (data->current_window)->pointm)->charpos; 5538 old_point = marker_position (XWINDOW (data->current_window)->pointm);
5552 else 5539 else
5553 old_point = BUF_PT (XBUFFER (new_current_buffer)); 5540 old_point = BUF_PT (XBUFFER (new_current_buffer));
5554 } 5541 }
@@ -5587,8 +5574,8 @@ the return value is nil. Otherwise the value is t. */)
5587 p = SAVED_WINDOW_N (saved_windows, k); 5574 p = SAVED_WINDOW_N (saved_windows, k);
5588 window = p->window; 5575 window = p->window;
5589 w = XWINDOW (window); 5576 w = XWINDOW (window);
5590 if (!NILP (w->buffer) 5577 if (BUFFERP (w->contents)
5591 && !EQ (w->buffer, p->buffer) 5578 && !EQ (w->contents, p->buffer)
5592 && BUFFER_LIVE_P (XBUFFER (p->buffer))) 5579 && BUFFER_LIVE_P (XBUFFER (p->buffer)))
5593 /* If a window we restore gets another buffer, record the 5580 /* If a window we restore gets another buffer, record the
5594 window's old buffer. */ 5581 window's old buffer. */
@@ -5621,13 +5608,13 @@ the return value is nil. Otherwise the value is t. */)
5621 window holds garbage.) We do this now, before 5608 window holds garbage.) We do this now, before
5622 restoring the window contents, and prevent it from 5609 restoring the window contents, and prevent it from
5623 being done later on when we select a new window. */ 5610 being done later on when we select a new window. */
5624 if (! NILP (XWINDOW (selected_window)->buffer)) 5611 if (! NILP (XWINDOW (selected_window)->contents))
5625 { 5612 {
5626 w = XWINDOW (selected_window); 5613 w = XWINDOW (selected_window);
5627 set_marker_both (w->pointm, 5614 set_marker_both (w->pointm,
5628 w->buffer, 5615 w->contents,
5629 BUF_PT (XBUFFER (w->buffer)), 5616 BUF_PT (XBUFFER (w->contents)),
5630 BUF_PT_BYTE (XBUFFER (w->buffer))); 5617 BUF_PT_BYTE (XBUFFER (w->contents)));
5631 } 5618 }
5632 5619
5633 windows_or_buffers_changed++; 5620 windows_or_buffers_changed++;
@@ -5674,28 +5661,19 @@ the return value is nil. Otherwise the value is t. */)
5674 { 5661 {
5675 wset_prev (w, Qnil); 5662 wset_prev (w, Qnil);
5676 if (!NILP (w->parent)) 5663 if (!NILP (w->parent))
5677 { 5664 wset_combination (XWINDOW (w->parent),
5678 if (EQ (p->total_cols, XWINDOW (w->parent)->total_cols)) 5665 (XINT (p->total_cols)
5679 { 5666 != XWINDOW (w->parent)->total_cols),
5680 wset_vchild (XWINDOW (w->parent), p->window); 5667 p->window);
5681 wset_hchild (XWINDOW (w->parent), Qnil);
5682 }
5683 else
5684 {
5685 wset_hchild (XWINDOW (w->parent), p->window);
5686 wset_vchild (XWINDOW (w->parent), Qnil);
5687 }
5688 }
5689 } 5668 }
5690 5669
5691 /* If we squirreled away the buffer in the window's height, 5670 /* If we squirreled away the buffer, restore it now. */
5692 restore it now. */ 5671 if (BUFFERP (w->combination_limit))
5693 if (BUFFERP (w->total_lines)) 5672 wset_buffer (w, w->combination_limit);
5694 wset_buffer (w, w->total_lines); 5673 w->left_col = XFASTINT (p->left_col);
5695 wset_left_col (w, p->left_col); 5674 w->top_line = XFASTINT (p->top_line);
5696 wset_top_line (w, p->top_line); 5675 w->total_cols = XFASTINT (p->total_cols);
5697 wset_total_cols (w, p->total_cols); 5676 w->total_lines = XFASTINT (p->total_lines);
5698 wset_total_lines (w, p->total_lines);
5699 wset_normal_cols (w, p->normal_cols); 5677 wset_normal_cols (w, p->normal_cols);
5700 wset_normal_lines (w, p->normal_lines); 5678 wset_normal_lines (w, p->normal_lines);
5701 w->hscroll = XFASTINT (p->hscroll); 5679 w->hscroll = XFASTINT (p->hscroll);
@@ -5735,20 +5713,16 @@ the return value is nil. Otherwise the value is t. */)
5735 w->last_modified = 0; 5713 w->last_modified = 0;
5736 w->last_overlay_modified = 0; 5714 w->last_overlay_modified = 0;
5737 5715
5738 /* Reinstall the saved buffer and pointers into it. */ 5716 if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer)))
5739 if (NILP (p->buffer))
5740 /* An internal window. */
5741 wset_buffer (w, p->buffer);
5742 else if (BUFFER_LIVE_P (XBUFFER (p->buffer)))
5743 /* If saved buffer is alive, install it. */ 5717 /* If saved buffer is alive, install it. */
5744 { 5718 {
5745 wset_buffer (w, p->buffer); 5719 wset_buffer (w, p->buffer);
5746 w->start_at_line_beg = !NILP (p->start_at_line_beg); 5720 w->start_at_line_beg = !NILP (p->start_at_line_beg);
5747 set_marker_restricted (w->start, p->start, w->buffer); 5721 set_marker_restricted (w->start, p->start, w->contents);
5748 set_marker_restricted (w->pointm, p->pointm, 5722 set_marker_restricted (w->pointm, p->pointm,
5749 w->buffer); 5723 w->contents);
5750 Fset_marker (BVAR (XBUFFER (w->buffer), mark), 5724 Fset_marker (BVAR (XBUFFER (w->contents), mark),
5751 p->mark, w->buffer); 5725 p->mark, w->contents);
5752 5726
5753 /* As documented in Fcurrent_window_configuration, don't 5727 /* As documented in Fcurrent_window_configuration, don't
5754 restore the location of point in the buffer which was 5728 restore the location of point in the buffer which was
@@ -5757,24 +5731,21 @@ the return value is nil. Otherwise the value is t. */)
5757 && XBUFFER (p->buffer) == current_buffer) 5731 && XBUFFER (p->buffer) == current_buffer)
5758 Fgoto_char (w->pointm); 5732 Fgoto_char (w->pointm);
5759 } 5733 }
5760 else if (!NILP (w->buffer) 5734 else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents)))
5761 && BUFFER_LIVE_P (XBUFFER (w->buffer))) 5735 /* Keep window's old buffer; make sure the markers are real. */
5762 /* Keep window's old buffer; make sure the markers are 5736 {
5763 real. */ 5737 /* Set window markers at start of visible range. */
5764 { 5738 if (XMARKER (w->start)->buffer == 0)
5765 /* Set window markers at start of visible range. */ 5739 set_marker_restricted_both (w->start, w->contents, 0, 0);
5766 if (XMARKER (w->start)->buffer == 0) 5740 if (XMARKER (w->pointm)->buffer == 0)
5767 set_marker_restricted (w->start, make_number (0), 5741 set_marker_restricted_both
5768 w->buffer); 5742 (w->pointm, w->contents,
5769 if (XMARKER (w->pointm)->buffer == 0) 5743 BUF_PT (XBUFFER (w->contents)),
5770 set_marker_restricted_both 5744 BUF_PT_BYTE (XBUFFER (w->contents)));
5771 (w->pointm, w->buffer, 5745 w->start_at_line_beg = 1;
5772 BUF_PT (XBUFFER (w->buffer)), 5746 }
5773 BUF_PT_BYTE (XBUFFER (w->buffer))); 5747 else if (!NILP (w->start))
5774 w->start_at_line_beg = 1; 5748 /* Leaf window has no live buffer, get one. */
5775 }
5776 else
5777 /* Window has no live buffer, get one. */
5778 { 5749 {
5779 /* Get the buffer via other_buffer_safely in order to 5750 /* Get the buffer via other_buffer_safely in order to
5780 avoid showing an unimportant buffer and, if necessary, to 5751 avoid showing an unimportant buffer and, if necessary, to
@@ -5783,10 +5754,8 @@ the return value is nil. Otherwise the value is t. */)
5783 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ())); 5754 wset_buffer (w, other_buffer_safely (Fcurrent_buffer ()));
5784 /* This will set the markers to beginning of visible 5755 /* This will set the markers to beginning of visible
5785 range. */ 5756 range. */
5786 set_marker_restricted (w->start, 5757 set_marker_restricted_both (w->start, w->contents, 0, 0);
5787 make_number (0), w->buffer); 5758 set_marker_restricted_both (w->pointm, w->contents, 0, 0);
5788 set_marker_restricted (w->pointm,
5789 make_number (0), w->buffer);
5790 w->start_at_line_beg = 1; 5759 w->start_at_line_beg = 1;
5791 if (!NILP (w->dedicated)) 5760 if (!NILP (w->dedicated))
5792 /* Record this window as dead. */ 5761 /* Record this window as dead. */
@@ -5799,17 +5768,17 @@ the return value is nil. Otherwise the value is t. */)
5799 fset_root_window (f, data->root_window); 5768 fset_root_window (f, data->root_window);
5800 /* Arrange *not* to restore point in the buffer that was 5769 /* Arrange *not* to restore point in the buffer that was
5801 current when the window configuration was saved. */ 5770 current when the window configuration was saved. */
5802 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)) 5771 if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
5803 set_marker_restricted (XWINDOW (data->current_window)->pointm, 5772 set_marker_restricted (XWINDOW (data->current_window)->pointm,
5804 make_number (old_point), 5773 make_number (old_point),
5805 XWINDOW (data->current_window)->buffer); 5774 XWINDOW (data->current_window)->contents);
5806 5775
5807 /* In the following call to `select-window', prevent "swapping out 5776 /* In the following call to `select-window', prevent "swapping out
5808 point" in the old selected window using the buffer that has 5777 point" in the old selected window using the buffer that has
5809 been restored into it. We already swapped out that point from 5778 been restored into it. We already swapped out that point from
5810 that window's old buffer. */ 5779 that window's old buffer. */
5811 select_window (data->current_window, Qnil, 1); 5780 select_window (data->current_window, Qnil, 1);
5812 BVAR (XBUFFER (XWINDOW (selected_window)->buffer), last_selected_window) 5781 BVAR (XBUFFER (XWINDOW (selected_window)->contents), last_selected_window)
5813 = selected_window; 5782 = selected_window;
5814 5783
5815 if (NILP (data->focus_frame) 5784 if (NILP (data->focus_frame)
@@ -5836,14 +5805,9 @@ the return value is nil. Otherwise the value is t. */)
5836 /* Now, free glyph matrices in windows that were not reused. */ 5805 /* Now, free glyph matrices in windows that were not reused. */
5837 for (i = n = 0; i < n_leaf_windows; ++i) 5806 for (i = n = 0; i < n_leaf_windows; ++i)
5838 { 5807 {
5839 if (NILP (leaf_windows[i]->buffer)) 5808 if (NILP (leaf_windows[i]->contents))
5840 { 5809 free_window_matrices (leaf_windows[i]);
5841 /* Assert it's not reused as a combination. */ 5810 else if (EQ (leaf_windows[i]->contents, new_current_buffer))
5842 eassert (NILP (leaf_windows[i]->hchild)
5843 && NILP (leaf_windows[i]->vchild));
5844 free_window_matrices (leaf_windows[i]);
5845 }
5846 else if (EQ (leaf_windows[i]->buffer, new_current_buffer))
5847 ++n; 5811 ++n;
5848 } 5812 }
5849 5813
@@ -5874,7 +5838,7 @@ the return value is nil. Otherwise the value is t. */)
5874 Fset_buffer (new_current_buffer); 5838 Fset_buffer (new_current_buffer);
5875 /* If the new current buffer doesn't appear in the selected 5839 /* If the new current buffer doesn't appear in the selected
5876 window, go to its old point (see bug#12208). */ 5840 window, go to its old point (see bug#12208). */
5877 if (!EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)) 5841 if (!EQ (XWINDOW (data->current_window)->contents, new_current_buffer))
5878 Fgoto_char (make_number (old_point)); 5842 Fgoto_char (make_number (old_point));
5879 } 5843 }
5880 5844
@@ -5885,8 +5849,10 @@ the return value is nil. Otherwise the value is t. */)
5885} 5849}
5886 5850
5887 5851
5888/* Recursively delete all child windows reachable via the next, vchild, 5852/* If WINDOW is an internal window, recursively delete all child windows
5889 and hchild slots of WINDOW. */ 5853 reachable via the next and contents slots of WINDOW. Otherwise setup
5854 WINDOW to not show any buffer. */
5855
5890void 5856void
5891delete_all_child_windows (Lisp_Object window) 5857delete_all_child_windows (Lisp_Object window)
5892{ 5858{
@@ -5898,24 +5864,20 @@ delete_all_child_windows (Lisp_Object window)
5898 /* Delete WINDOW's siblings (we traverse postorderly). */ 5864 /* Delete WINDOW's siblings (we traverse postorderly). */
5899 delete_all_child_windows (w->next); 5865 delete_all_child_windows (w->next);
5900 5866
5901 /* See Fset_window_configuration for excuse. */ 5867 if (WINDOWP (w->contents))
5902 wset_total_lines (w, w->buffer);
5903
5904 if (!NILP (w->vchild))
5905 {
5906 delete_all_child_windows (w->vchild);
5907 wset_vchild (w, Qnil);
5908 }
5909 else if (!NILP (w->hchild))
5910 { 5868 {
5911 delete_all_child_windows (w->hchild); 5869 delete_all_child_windows (w->contents);
5912 wset_hchild (w, Qnil); 5870 wset_combination (w, 0, Qnil);
5913 } 5871 }
5914 else if (!NILP (w->buffer)) 5872 else if (BUFFERP (w->contents))
5915 { 5873 {
5916 unshow_buffer (w); 5874 unshow_buffer (w);
5917 unchain_marker (XMARKER (w->pointm)); 5875 unchain_marker (XMARKER (w->pointm));
5918 unchain_marker (XMARKER (w->start)); 5876 unchain_marker (XMARKER (w->start));
5877 /* Since combination limit makes sense for an internal windows
5878 only, we use this slot to save the buffer for the sake of
5879 possible resurrection in Fset_window_configuration. */
5880 wset_combination_limit (w, w->contents);
5919 wset_buffer (w, Qnil); 5881 wset_buffer (w, Qnil);
5920 } 5882 }
5921 5883
@@ -5928,10 +5890,8 @@ count_windows (register struct window *window)
5928 register int count = 1; 5890 register int count = 1;
5929 if (!NILP (window->next)) 5891 if (!NILP (window->next))
5930 count += count_windows (XWINDOW (window->next)); 5892 count += count_windows (XWINDOW (window->next));
5931 if (!NILP (window->vchild)) 5893 if (WINDOWP (window->contents))
5932 count += count_windows (XWINDOW (window->vchild)); 5894 count += count_windows (XWINDOW (window->contents));
5933 if (!NILP (window->hchild))
5934 count += count_windows (XWINDOW (window->hchild));
5935 return count; 5895 return count;
5936} 5896}
5937 5897
@@ -5943,10 +5903,8 @@ get_leaf_windows (struct window *w, struct window **flat, int i)
5943{ 5903{
5944 while (w) 5904 while (w)
5945 { 5905 {
5946 if (!NILP (w->hchild)) 5906 if (WINDOWP (w->contents))
5947 i = get_leaf_windows (XWINDOW (w->hchild), flat, i); 5907 i = get_leaf_windows (XWINDOW (w->contents), flat, i);
5948 else if (!NILP (w->vchild))
5949 i = get_leaf_windows (XWINDOW (w->vchild), flat, i);
5950 else 5908 else
5951 flat[i++] = w; 5909 flat[i++] = w;
5952 5910
@@ -5986,8 +5944,7 @@ get_phys_cursor_glyph (struct window *w)
5986 hpos = row->used[TEXT_AREA] - 1; 5944 hpos = row->used[TEXT_AREA] - 1;
5987 } 5945 }
5988 5946
5989 if (row->used[TEXT_AREA] > hpos 5947 if (hpos >= 0 && hpos < row->used[TEXT_AREA])
5990 && 0 <= hpos)
5991 glyph = row->glyphs[TEXT_AREA] + hpos; 5948 glyph = row->glyphs[TEXT_AREA] + hpos;
5992 else 5949 else
5993 glyph = NULL; 5950 glyph = NULL;
@@ -6003,18 +5960,18 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6003 register struct window *w; 5960 register struct window *w;
6004 register Lisp_Object tem, pers, par; 5961 register Lisp_Object tem, pers, par;
6005 5962
6006 for (;!NILP (window); window = w->next) 5963 for (; !NILP (window); window = w->next)
6007 { 5964 {
6008 p = SAVED_WINDOW_N (vector, i); 5965 p = SAVED_WINDOW_N (vector, i);
6009 w = XWINDOW (window); 5966 w = XWINDOW (window);
6010 5967
6011 wset_temslot (w, make_number (i)); i++; 5968 wset_temslot (w, make_number (i)); i++;
6012 p->window = window; 5969 p->window = window;
6013 p->buffer = w->buffer; 5970 p->buffer = (WINDOW_LEAF_P (w) ? w->contents : Qnil);
6014 p->left_col = w->left_col; 5971 p->left_col = make_number (w->left_col);
6015 p->top_line = w->top_line; 5972 p->top_line = make_number (w->top_line);
6016 p->total_cols = w->total_cols; 5973 p->total_cols = make_number (w->total_cols);
6017 p->total_lines = w->total_lines; 5974 p->total_lines = make_number (w->total_lines);
6018 p->normal_cols = w->normal_cols; 5975 p->normal_cols = w->normal_cols;
6019 p->normal_lines = w->normal_lines; 5976 p->normal_lines = w->normal_lines;
6020 XSETFASTINT (p->hscroll, w->hscroll); 5977 XSETFASTINT (p->hscroll, w->hscroll);
@@ -6077,15 +6034,15 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6077 } 6034 }
6078 } 6035 }
6079 6036
6080 if (!NILP (w->buffer)) 6037 if (BUFFERP (w->contents))
6081 { 6038 {
6082 /* Save w's value of point in the window configuration. If w 6039 /* Save w's value of point in the window configuration. If w
6083 is the selected window, then get the value of point from 6040 is the selected window, then get the value of point from
6084 the buffer; pointm is garbage in the selected window. */ 6041 the buffer; pointm is garbage in the selected window. */
6085 if (EQ (window, selected_window)) 6042 if (EQ (window, selected_window))
6086 p->pointm = build_marker (XBUFFER (w->buffer), 6043 p->pointm = build_marker (XBUFFER (w->contents),
6087 BUF_PT (XBUFFER (w->buffer)), 6044 BUF_PT (XBUFFER (w->contents)),
6088 BUF_PT_BYTE (XBUFFER (w->buffer))); 6045 BUF_PT_BYTE (XBUFFER (w->contents)));
6089 else 6046 else
6090 p->pointm = Fcopy_marker (w->pointm, Qnil); 6047 p->pointm = Fcopy_marker (w->pointm, Qnil);
6091 XMARKER (p->pointm)->insertion_type 6048 XMARKER (p->pointm)->insertion_type
@@ -6094,7 +6051,7 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6094 p->start = Fcopy_marker (w->start, Qnil); 6051 p->start = Fcopy_marker (w->start, Qnil);
6095 p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil; 6052 p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
6096 6053
6097 tem = BVAR (XBUFFER (w->buffer), mark); 6054 tem = BVAR (XBUFFER (w->contents), mark);
6098 p->mark = Fcopy_marker (tem, Qnil); 6055 p->mark = Fcopy_marker (tem, Qnil);
6099 } 6056 }
6100 else 6057 else
@@ -6115,10 +6072,8 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6115 else 6072 else
6116 p->prev = XWINDOW (w->prev)->temslot; 6073 p->prev = XWINDOW (w->prev)->temslot;
6117 6074
6118 if (!NILP (w->vchild)) 6075 if (WINDOWP (w->contents))
6119 i = save_window_save (w->vchild, vector, i); 6076 i = save_window_save (w->contents, vector, i);
6120 if (!NILP (w->hchild))
6121 i = save_window_save (w->hchild, vector, i);
6122 } 6077 }
6123 6078
6124 return i; 6079 return i;
@@ -6159,11 +6114,11 @@ saved by this function. */)
6159 data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil; 6114 data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil;
6160 data->root_window = FRAME_ROOT_WINDOW (f); 6115 data->root_window = FRAME_ROOT_WINDOW (f);
6161 data->focus_frame = FRAME_FOCUS_FRAME (f); 6116 data->focus_frame = FRAME_FOCUS_FRAME (f);
6162 tem = Fmake_vector (make_number (n_windows), Qnil); 6117 tem = make_uninit_vector (n_windows);
6163 data->saved_windows = tem; 6118 data->saved_windows = tem;
6164 for (i = 0; i < n_windows; i++) 6119 for (i = 0; i < n_windows; i++)
6165 ASET (tem, i, 6120 ASET (tem, i,
6166 Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil)); 6121 Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil));
6167 save_window_save (FRAME_ROOT_WINDOW (f), XVECTOR (tem), 0); 6122 save_window_save (FRAME_ROOT_WINDOW (f), XVECTOR (tem), 0);
6168 XSETWINDOW_CONFIGURATION (tem, data); 6123 XSETWINDOW_CONFIGURATION (tem, data);
6169 return (tem); 6124 return (tem);
@@ -6275,7 +6230,7 @@ display marginal areas and the text area. */)
6275 adjust_window_margins (w); 6230 adjust_window_margins (w);
6276 6231
6277 clear_glyph_matrix (w->current_matrix); 6232 clear_glyph_matrix (w->current_matrix);
6278 wset_window_end_valid (w, Qnil); 6233 w->window_end_valid = 0;
6279 6234
6280 ++windows_or_buffers_changed; 6235 ++windows_or_buffers_changed;
6281 adjust_glyphs (XFRAME (WINDOW_FRAME (w))); 6236 adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
@@ -6345,7 +6300,7 @@ Fourth parameter HORIZONTAL-TYPE is currently unused. */)
6345 adjust_window_margins (w); 6300 adjust_window_margins (w);
6346 6301
6347 clear_glyph_matrix (w->current_matrix); 6302 clear_glyph_matrix (w->current_matrix);
6348 wset_window_end_valid (w, Qnil); 6303 w->window_end_valid = 0;
6349 6304
6350 ++windows_or_buffers_changed; 6305 ++windows_or_buffers_changed;
6351 adjust_glyphs (XFRAME (WINDOW_FRAME (w))); 6306 adjust_glyphs (XFRAME (WINDOW_FRAME (w)));
@@ -6435,7 +6390,7 @@ If PIXELS-P is non-nil, the return value is VSCROLL. */)
6435 adjust_glyphs (f); 6390 adjust_glyphs (f);
6436 6391
6437 /* Prevent redisplay shortcuts. */ 6392 /* Prevent redisplay shortcuts. */
6438 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1; 6393 XBUFFER (w->contents)->prevent_redisplay_optimizations_p = 1;
6439 } 6394 }
6440 } 6395 }
6441 6396
@@ -6469,10 +6424,8 @@ foreach_window_1 (struct window *w, int (*fn) (struct window *, void *), void *u
6469 6424
6470 for (cont = 1; w && cont;) 6425 for (cont = 1; w && cont;)
6471 { 6426 {
6472 if (!NILP (w->hchild)) 6427 if (WINDOWP (w->contents))
6473 cont = foreach_window_1 (XWINDOW (w->hchild), fn, user_data); 6428 cont = foreach_window_1 (XWINDOW (w->contents), fn, user_data);
6474 else if (!NILP (w->vchild))
6475 cont = foreach_window_1 (XWINDOW (w->vchild), fn, user_data);
6476 else 6429 else
6477 cont = fn (w, user_data); 6430 cont = fn (w, user_data);
6478 6431
@@ -6508,7 +6461,7 @@ freeze_window_start (struct window *w, void *freeze_p)
6508 means freeze the window start. */ 6461 means freeze the window start. */
6509 6462
6510void 6463void
6511freeze_window_starts (struct frame *f, int freeze_p) 6464freeze_window_starts (struct frame *f, bool freeze_p)
6512{ 6465{
6513 foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0)); 6466 foreach_window (f, freeze_window_start, (void *) (freeze_p ? f : 0));
6514} 6467}
@@ -6749,7 +6702,8 @@ same combination.
6749 6702
6750Other values are reserved for future use. 6703Other values are reserved for future use.
6751 6704
6752This variable takes no effect if `window-combination-limit' is non-nil. */); 6705This variable takes no effect if the variable `window-combination-limit' is
6706non-nil. */);
6753 Vwindow_combination_resize = Qnil; 6707 Vwindow_combination_resize = Qnil;
6754 6708
6755 DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit, 6709 DEFVAR_LISP ("window-combination-limit", Vwindow_combination_limit,