comparison src/window.c @ 90261:7beb78bc1f8e

Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-97 Merge from emacs--cvs-trunk--0 Patches applied: * emacs--cvs-trunk--0 (patch 616-696) - Add lisp/mh-e/.arch-inventory - Update from CVS - Merge from gnus--rel--5.10 - Update from CVS: lisp/smerge-mode.el: Add 'tools' to file keywords. - lisp/gnus/ChangeLog: Remove duplicate entry * gnus--rel--5.10 (patch 147-181) - Update from CVS - Merge from emacs--cvs-trunk--0 - Update from CVS: lisp/mml.el (mml-preview): Doc fix. - Update from CVS: texi/message.texi: Fix default values. - Update from CVS: texi/gnus.texi (RSS): Addition.
author Miles Bader <miles@gnu.org>
date Mon, 16 Jan 2006 08:37:27 +0000
parents 0ca0d9181b5e 97a5b7b69235
children 7432ca837c8d
comparison
equal deleted inserted replaced
90260:0ca0d9181b5e 90261:7beb78bc1f8e
63 static int window_min_size_1 P_ ((struct window *, int)); 63 static int window_min_size_1 P_ ((struct window *, int));
64 static int window_min_size P_ ((struct window *, int, int, int *)); 64 static int window_min_size P_ ((struct window *, int, int, int *));
65 static void size_window P_ ((Lisp_Object, int, int, int)); 65 static void size_window P_ ((Lisp_Object, int, int, int));
66 static int freeze_window_start P_ ((struct window *, void *)); 66 static int freeze_window_start P_ ((struct window *, void *));
67 static int window_fixed_size_p P_ ((struct window *, int, int)); 67 static int window_fixed_size_p P_ ((struct window *, int, int));
68 static void enlarge_window P_ ((Lisp_Object, int, int, int)); 68 static void enlarge_window P_ ((Lisp_Object, int, int));
69 static Lisp_Object window_list P_ ((void)); 69 static Lisp_Object window_list P_ ((void));
70 static int add_window_to_list P_ ((struct window *, void *)); 70 static int add_window_to_list P_ ((struct window *, void *));
71 static int candidate_window_p P_ ((Lisp_Object, Lisp_Object, Lisp_Object, 71 static int candidate_window_p P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
72 Lisp_Object)); 72 Lisp_Object));
73 static Lisp_Object next_window P_ ((Lisp_Object, Lisp_Object, 73 static Lisp_Object next_window P_ ((Lisp_Object, Lisp_Object,
207 207
208 /* Non-nil means scroll commands try to put point 208 /* Non-nil means scroll commands try to put point
209 at the same screen height as previously. */ 209 at the same screen height as previously. */
210 210
211 Lisp_Object Vscroll_preserve_screen_position; 211 Lisp_Object Vscroll_preserve_screen_position;
212
213 /* Incremented by 1 whenever a window is deleted. */
214
215 int window_deletion_count;
212 216
213 #if 0 /* This isn't used anywhere. */ 217 #if 0 /* This isn't used anywhere. */
214 /* Nonzero means we can split a frame even if it is "unsplittable". */ 218 /* Nonzero means we can split a frame even if it is "unsplittable". */
215 static int inhibit_frame_unsplittable; 219 static int inhibit_frame_unsplittable;
216 #endif /* 0 */ 220 #endif /* 0 */
1331 window = selected_window; 1335 window = selected_window;
1332 else 1336 else
1333 CHECK_WINDOW (window); 1337 CHECK_WINDOW (window);
1334 p = XWINDOW (window); 1338 p = XWINDOW (window);
1335 1339
1336 /* It's okay to delete an already-deleted window. */ 1340 /* It's a no-op to delete an already-deleted window. */
1337 if (NILP (p->buffer) 1341 if (NILP (p->buffer)
1338 && NILP (p->hchild) 1342 && NILP (p->hchild)
1339 && NILP (p->vchild)) 1343 && NILP (p->vchild))
1340 return; 1344 return;
1341 1345
1394 Fselect_window (swindow, Qnil); 1398 Fselect_window (swindow, Qnil);
1395 else 1399 else
1396 FRAME_SELECTED_WINDOW (f) = swindow; 1400 FRAME_SELECTED_WINDOW (f) = swindow;
1397 } 1401 }
1398 } 1402 }
1403
1404 /* Now we know we can delete this one. */
1405 window_deletion_count++;
1399 1406
1400 tem = p->buffer; 1407 tem = p->buffer;
1401 /* tem is null for dummy parent windows 1408 /* tem is null for dummy parent windows
1402 (which have inferiors but not any contents themselves) */ 1409 (which have inferiors but not any contents themselves) */
1403 if (!NILP (tem)) 1410 if (!NILP (tem))
1960 1967
1961 windows = window_list_1 (window, mini ? Qt : Qnil, frame_arg); 1968 windows = window_list_1 (window, mini ? Qt : Qnil, frame_arg);
1962 GCPRO1 (windows); 1969 GCPRO1 (windows);
1963 best_window = Qnil; 1970 best_window = Qnil;
1964 1971
1965 for (; CONSP (windows); windows = CDR (windows)) 1972 for (; CONSP (windows); windows = XCDR (windows))
1966 { 1973 {
1967 struct window *w; 1974 struct window *w;
1968 1975
1969 window = XCAR (windows); 1976 window = XCAR (windows);
1970 w = XWINDOW (window); 1977 w = XWINDOW (window);
1994 best_window = window; 2001 best_window = window;
1995 } 2002 }
1996 break; 2003 break;
1997 2004
1998 case GET_LRU_WINDOW: 2005 case GET_LRU_WINDOW:
1999 /* t as arg means consider only full-width windows */ 2006 /* `obj' is an integer encoding a bitvector.
2000 if (!NILP (obj) && !WINDOW_FULL_WIDTH_P (w)) 2007 `obj & 1' means consider only full-width windows.
2001 break; 2008 `obj & 2' means consider also dedicated windows. */
2002 /* Ignore dedicated windows and minibuffers. */ 2009 if (((XINT (obj) & 1) && !WINDOW_FULL_WIDTH_P (w))
2003 if (MINI_WINDOW_P (w) || EQ (w->dedicated, Qt)) 2010 || (!(XINT (obj) & 2) && EQ (w->dedicated, Qt))
2011 /* Minibuffer windows are always ignored. */
2012 || MINI_WINDOW_P (w))
2004 break; 2013 break;
2005 if (NILP (best_window) 2014 if (NILP (best_window)
2006 || (XFASTINT (XWINDOW (best_window)->use_time) 2015 || (XFASTINT (XWINDOW (best_window)->use_time)
2007 > XFASTINT (w->use_time))) 2016 > XFASTINT (w->use_time)))
2008 best_window = window; 2017 best_window = window;
2049 Fdelete_window (window); 2058 Fdelete_window (window);
2050 } 2059 }
2051 break; 2060 break;
2052 2061
2053 case GET_LARGEST_WINDOW: 2062 case GET_LARGEST_WINDOW:
2054 { 2063 { /* nil `obj' means to ignore dedicated windows. */
2055 /* Ignore dedicated windows and minibuffers. */ 2064 /* Ignore dedicated windows and minibuffers. */
2056 if (MINI_WINDOW_P (w) || EQ (w->dedicated, Qt)) 2065 if (MINI_WINDOW_P (w) || (NILP (obj) && EQ (w->dedicated, Qt)))
2057 break; 2066 break;
2058 2067
2059 if (NILP (best_window)) 2068 if (NILP (best_window))
2060 best_window = window; 2069 best_window = window;
2061 else 2070 else
2145 check_all_windows () 2154 check_all_windows ()
2146 { 2155 {
2147 window_loop (CHECK_ALL_WINDOWS, Qnil, 1, Qt); 2156 window_loop (CHECK_ALL_WINDOWS, Qnil, 1, Qt);
2148 } 2157 }
2149 2158
2150 DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 1, 0, 2159 DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 2, 0,
2151 doc: /* Return the window least recently selected or used for display. 2160 doc: /* Return the window least recently selected or used for display.
2152 Return a full-width window if possible. 2161 Return a full-width window if possible.
2153 A minibuffer window is never a candidate. 2162 A minibuffer window is never a candidate.
2154 A dedicated window is never a candidate, so if all windows are dedicated, 2163 A dedicated window is never a candidate, unless DEDICATED is non-nil,
2155 the value is nil. 2164 so if all windows are dedicated, the value is nil.
2156 If optional argument FRAME is `visible', search all visible frames. 2165 If optional argument FRAME is `visible', search all visible frames.
2157 If FRAME is 0, search all visible and iconified frames. 2166 If FRAME is 0, search all visible and iconified frames.
2158 If FRAME is t, search all frames. 2167 If FRAME is t, search all frames.
2159 If FRAME is nil, search only the selected frame. 2168 If FRAME is nil, search only the selected frame.
2160 If FRAME is a frame, search only that frame. */) 2169 If FRAME is a frame, search only that frame. */)
2161 (frame) 2170 (frame, dedicated)
2162 Lisp_Object frame; 2171 Lisp_Object frame, dedicated;
2163 { 2172 {
2164 register Lisp_Object w; 2173 register Lisp_Object w;
2165 /* First try for a window that is full-width */ 2174 /* First try for a window that is full-width */
2166 w = window_loop (GET_LRU_WINDOW, Qt, 0, frame); 2175 w = window_loop (GET_LRU_WINDOW,
2176 NILP (dedicated) ? make_number (1) : make_number (3),
2177 0, frame);
2167 if (!NILP (w) && !EQ (w, selected_window)) 2178 if (!NILP (w) && !EQ (w, selected_window))
2168 return w; 2179 return w;
2169 /* If none of them, try the rest */ 2180 /* If none of them, try the rest */
2170 return window_loop (GET_LRU_WINDOW, Qnil, 0, frame); 2181 return window_loop (GET_LRU_WINDOW,
2171 } 2182 NILP (dedicated) ? make_number (0) : make_number (2),
2172 2183 0, frame);
2173 DEFUN ("get-largest-window", Fget_largest_window, Sget_largest_window, 0, 1, 0, 2184 }
2185
2186 DEFUN ("get-largest-window", Fget_largest_window, Sget_largest_window, 0, 2, 0,
2174 doc: /* Return the largest window in area. 2187 doc: /* Return the largest window in area.
2175 A minibuffer window is never a candidate. 2188 A minibuffer window is never a candidate.
2176 A dedicated window is never a candidate, so if all windows are dedicated, 2189 A dedicated window is never a candidate unless DEDICATED is non-nil,
2177 the value is nil. 2190 so if all windows are dedicated, the value is nil.
2178 If optional argument FRAME is `visible', search all visible frames. 2191 If optional argument FRAME is `visible', search all visible frames.
2179 If FRAME is 0, search all visible and iconified frames. 2192 If FRAME is 0, search all visible and iconified frames.
2180 If FRAME is t, search all frames. 2193 If FRAME is t, search all frames.
2181 If FRAME is nil, search only the selected frame. 2194 If FRAME is nil, search only the selected frame.
2182 If FRAME is a frame, search only that frame. */) 2195 If FRAME is a frame, search only that frame. */)
2183 (frame) 2196 (frame, dedicated)
2184 Lisp_Object frame; 2197 Lisp_Object frame, dedicated;
2185 { 2198 {
2186 return window_loop (GET_LARGEST_WINDOW, Qnil, 0, 2199 return window_loop (GET_LARGEST_WINDOW, dedicated, 0,
2187 frame); 2200 frame);
2188 } 2201 }
2189 2202
2190 DEFUN ("get-buffer-window", Fget_buffer_window, Sget_buffer_window, 1, 2, 0, 2203 DEFUN ("get-buffer-window", Fget_buffer_window, Sget_buffer_window, 1, 2, 0,
2191 doc: /* Return a window currently displaying BUFFER, or nil if none. 2204 doc: /* Return a window currently displaying BUFFER, or nil if none.
3501 /* If the frame we would try to split cannot be split, 3514 /* If the frame we would try to split cannot be split,
3502 try other frames. */ 3515 try other frames. */
3503 if (FRAME_NO_SPLIT_P (NILP (frames) ? f : last_nonminibuf_frame)) 3516 if (FRAME_NO_SPLIT_P (NILP (frames) ? f : last_nonminibuf_frame))
3504 { 3517 {
3505 /* Try visible frames first. */ 3518 /* Try visible frames first. */
3506 window = Fget_largest_window (Qvisible); 3519 window = Fget_largest_window (Qvisible, Qt);
3507 /* If that didn't work, try iconified frames. */ 3520 /* If that didn't work, try iconified frames. */
3508 if (NILP (window)) 3521 if (NILP (window))
3509 window = Fget_largest_window (make_number (0)); 3522 window = Fget_largest_window (make_number (0), Qt);
3523 #if 0 /* Don't try windows on other displays. */
3510 if (NILP (window)) 3524 if (NILP (window))
3511 window = Fget_largest_window (Qt); 3525 window = Fget_largest_window (Qt, Qt);
3526 #endif
3512 } 3527 }
3513 else 3528 else
3514 window = Fget_largest_window (frames); 3529 window = Fget_largest_window (frames, Qt);
3515 3530
3516 /* If we got a tall enough full-width window that can be split, 3531 /* If we got a tall enough full-width window that can be split,
3517 split it. */ 3532 split it. */
3518 if (!NILP (window) 3533 if (!NILP (window)
3519 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame)) 3534 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame))
3522 window = Fsplit_window (window, Qnil, Qnil); 3537 window = Fsplit_window (window, Qnil, Qnil);
3523 else 3538 else
3524 { 3539 {
3525 Lisp_Object upper, other; 3540 Lisp_Object upper, other;
3526 3541
3527 window = Fget_lru_window (frames); 3542 window = Fget_lru_window (frames, Qt);
3528 /* If the LRU window is selected, and big enough, 3543 /* If the LRU window is selected, and big enough,
3529 and can be split, split it. */ 3544 and can be split, split it. */
3530 if (!NILP (window) 3545 if (!NILP (window)
3531 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame)) 3546 && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame))
3532 && (EQ (window, selected_window) 3547 && (EQ (window, selected_window)
3533 || EQ (XWINDOW (window)->parent, Qnil)) 3548 || EQ (XWINDOW (window)->parent, Qnil))
3534 && window_height (window) >= window_min_height << 1) 3549 && window_height (window) >= window_min_height << 1)
3535 window = Fsplit_window (window, Qnil, Qnil); 3550 window = Fsplit_window (window, Qnil, Qnil);
3551 else
3552 window = Fget_lru_window (frames, Qnil);
3536 /* If Fget_lru_window returned nil, try other approaches. */ 3553 /* If Fget_lru_window returned nil, try other approaches. */
3537 3554
3538 /* Try visible frames first. */ 3555 /* Try visible frames first. */
3539 if (NILP (window)) 3556 if (NILP (window))
3540 window = Fget_buffer_window (buffer, Qvisible); 3557 window = Fget_buffer_window (buffer, Qvisible);
3541 if (NILP (window)) 3558 if (NILP (window))
3542 window = Fget_largest_window (Qvisible); 3559 window = Fget_largest_window (Qvisible, Qnil);
3543 /* If that didn't work, try iconified frames. */ 3560 /* If that didn't work, try iconified frames. */
3544 if (NILP (window)) 3561 if (NILP (window))
3545 window = Fget_buffer_window (buffer, make_number (0)); 3562 window = Fget_buffer_window (buffer, make_number (0));
3546 if (NILP (window)) 3563 if (NILP (window))
3547 window = Fget_largest_window (make_number (0)); 3564 window = Fget_largest_window (make_number (0), Qnil);
3548 /* Try invisible frames. */ 3565
3566 #if 0 /* Don't try frames on other displays. */
3549 if (NILP (window)) 3567 if (NILP (window))
3550 window = Fget_buffer_window (buffer, Qt); 3568 window = Fget_buffer_window (buffer, Qt);
3551 if (NILP (window)) 3569 if (NILP (window))
3552 window = Fget_largest_window (Qt); 3570 window = Fget_largest_window (Qt, Qnil);
3571 #endif
3553 /* As a last resort, make a new frame. */ 3572 /* As a last resort, make a new frame. */
3554 if (NILP (window)) 3573 if (NILP (window))
3555 window = Fframe_selected_window (call0 (Vpop_up_frame_function)); 3574 window = Fframe_selected_window (call0 (Vpop_up_frame_function));
3556 /* If window appears above or below another, 3575 /* If window appears above or below another,
3557 even out their heights. */ 3576 even out their heights. */
3569 { 3588 {
3570 int total = (XFASTINT (XWINDOW (other)->total_lines) 3589 int total = (XFASTINT (XWINDOW (other)->total_lines)
3571 + XFASTINT (XWINDOW (window)->total_lines)); 3590 + XFASTINT (XWINDOW (window)->total_lines));
3572 enlarge_window (upper, 3591 enlarge_window (upper,
3573 total / 2 - XFASTINT (XWINDOW (upper)->total_lines), 3592 total / 2 - XFASTINT (XWINDOW (upper)->total_lines),
3574 0, 0); 3593 0);
3575 } 3594 }
3576 } 3595 }
3577 } 3596 }
3578 else 3597 else
3579 window = Fget_lru_window (Qnil); 3598 window = Fget_lru_window (Qnil, Qnil);
3580 3599
3581 Fset_window_buffer (window, buffer, Qnil); 3600 Fset_window_buffer (window, buffer, Qnil);
3582 return display_buffer_1 (window); 3601 return display_buffer_1 (window);
3583 } 3602 }
3584 3603
3646 #if 0 /* rms: there should be no reason for this. */ 3665 #if 0 /* rms: there should be no reason for this. */
3647 XBUFFER (buf)->prevent_redisplay_optimizations_p = 1; 3666 XBUFFER (buf)->prevent_redisplay_optimizations_p = 1;
3648 #endif 3667 #endif
3649 set_buffer_internal (old); 3668 set_buffer_internal (old);
3650 3669
3651 if (!EQ (Vtemp_buffer_show_function, Qnil)) 3670 if (!NILP (Vtemp_buffer_show_function))
3652 call1 (Vtemp_buffer_show_function, buf); 3671 call1 (Vtemp_buffer_show_function, buf);
3653 else 3672 else
3654 { 3673 {
3655 window = Fdisplay_buffer (buf, Qnil, Qnil); 3674 window = Fdisplay_buffer (buf, Qnil, Qnil);
3656 3675
3860 3879
3861 Fset_window_buffer (new, o->buffer, Qt); 3880 Fset_window_buffer (new, o->buffer, Qt);
3862 return new; 3881 return new;
3863 } 3882 }
3864 3883
3865 DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 3, "p", 3884 DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p",
3866 doc: /* Make current window ARG lines bigger. 3885 doc: /* Make current window ARG lines bigger.
3867 From program, optional second arg non-nil means grow sideways ARG columns. 3886 From program, optional second arg non-nil means grow sideways ARG columns.
3868 Interactively, if an argument is not given, make the window one line bigger. 3887 Interactively, if an argument is not given, make the window one line bigger.
3869 3888 If HORIZONTAL is non-nil, enlarge horizontally instead of vertically.
3870 Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size 3889 This function can delete windows, even the second window, if they get
3871 of the siblings above or to the left of the selected window. Only 3890 too small. */)
3872 siblings to the right or below are changed. */) 3891 (arg, horizontal)
3873 (arg, side, preserve_before) 3892 Lisp_Object arg, horizontal;
3874 register Lisp_Object arg, side, preserve_before;
3875 { 3893 {
3876 CHECK_NUMBER (arg); 3894 CHECK_NUMBER (arg);
3877 enlarge_window (selected_window, XINT (arg), !NILP (side), 3895 enlarge_window (selected_window, XINT (arg), !NILP (horizontal));
3878 !NILP (preserve_before));
3879 3896
3880 if (! NILP (Vwindow_configuration_change_hook)) 3897 if (! NILP (Vwindow_configuration_change_hook))
3881 call1 (Vrun_hooks, Qwindow_configuration_change_hook); 3898 call1 (Vrun_hooks, Qwindow_configuration_change_hook);
3882 3899
3883 return Qnil; 3900 return Qnil;
3884 } 3901 }
3885 3902
3886 DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 3, "p", 3903 DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p",
3887 doc: /* Make current window ARG lines smaller. 3904 doc: /* Make current window ARG lines smaller.
3888 From program, optional second arg non-nil means shrink sideways arg columns. 3905 From program, optional second arg non-nil means shrink sideways arg columns.
3889 Interactively, if an argument is not given, make the window one line smaller. 3906 Interactively, if an argument is not given, make the window one line smaller. Only
3890
3891 Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size
3892 of the siblings above or to the left of the selected window. Only
3893 siblings to the right or below are changed. */) 3907 siblings to the right or below are changed. */)
3894 (arg, side, preserve_before) 3908 (arg, side)
3895 register Lisp_Object arg, side, preserve_before; 3909 Lisp_Object arg, side;
3896 { 3910 {
3897 CHECK_NUMBER (arg); 3911 CHECK_NUMBER (arg);
3898 enlarge_window (selected_window, -XINT (arg), !NILP (side), 3912 enlarge_window (selected_window, -XINT (arg), !NILP (side));
3899 !NILP (preserve_before));
3900 3913
3901 if (! NILP (Vwindow_configuration_change_hook)) 3914 if (! NILP (Vwindow_configuration_change_hook))
3902 call1 (Vrun_hooks, Qwindow_configuration_change_hook); 3915 call1 (Vrun_hooks, Qwindow_configuration_change_hook);
3903 3916
3904 return Qnil; 3917 return Qnil;
3920 return WINDOW_TOTAL_COLS (p); 3933 return WINDOW_TOTAL_COLS (p);
3921 } 3934 }
3922 3935
3923 3936
3924 #define CURBEG(w) \ 3937 #define CURBEG(w) \
3925 *(widthflag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line)) 3938 *(horiz_flag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
3926 3939
3927 #define CURSIZE(w) \ 3940 #define CURSIZE(w) \
3928 *(widthflag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines)) 3941 *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
3929 3942
3930 3943
3931 /* Enlarge WINDOW by DELTA. WIDTHFLAG non-zero means 3944 /* Enlarge WINDOW by DELTA.
3932 increase its width. Siblings of the selected window are resized to 3945 HORIZ_FLAG nonzero means enlarge it horizontally;
3933 fulfill the size request. If they become too small in the process, 3946 zero means do it vertically.
3934 they will be deleted. 3947
3935 3948 Siblings of the selected window are resized to fulfill the size
3936 If PRESERVE_BEFORE is nonzero, that means don't alter 3949 request. If they become too small in the process, they will be
3937 the siblings to the left or above WINDOW. */ 3950 deleted. */
3938 3951
3939 static void 3952 static void
3940 enlarge_window (window, delta, widthflag, preserve_before) 3953 enlarge_window (window, delta, horiz_flag)
3941 Lisp_Object window; 3954 Lisp_Object window;
3942 int delta, widthflag, preserve_before; 3955 int delta, horiz_flag;
3943 { 3956 {
3944 Lisp_Object parent, next, prev; 3957 Lisp_Object parent, next, prev;
3945 struct window *p; 3958 struct window *p;
3946 Lisp_Object *sizep; 3959 Lisp_Object *sizep;
3947 int maximum; 3960 int maximum;
3948 int (*sizefun) P_ ((Lisp_Object)) 3961 int (*sizefun) P_ ((Lisp_Object))
3949 = widthflag ? window_width : window_height; 3962 = horiz_flag ? window_width : window_height;
3950 void (*setsizefun) P_ ((Lisp_Object, int, int)) 3963 void (*setsizefun) P_ ((Lisp_Object, int, int))
3951 = (widthflag ? set_window_width : set_window_height); 3964 = (horiz_flag ? set_window_width : set_window_height);
3952 3965
3953 /* Check values of window_min_width and window_min_height for 3966 /* Check values of window_min_width and window_min_height for
3954 validity. */ 3967 validity. */
3955 check_min_window_sizes (); 3968 check_min_window_sizes ();
3956 3969
3957 /* Give up if this window cannot be resized. */ 3970 /* Give up if this window cannot be resized. */
3958 if (window_fixed_size_p (XWINDOW (window), widthflag, 1)) 3971 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
3959 error ("Window is not resizable"); 3972 error ("Window is not resizable");
3960 3973
3961 /* Find the parent of the selected window. */ 3974 /* Find the parent of the selected window. */
3962 while (1) 3975 while (1)
3963 { 3976 {
3964 p = XWINDOW (window); 3977 p = XWINDOW (window);
3965 parent = p->parent; 3978 parent = p->parent;
3966 3979
3967 if (NILP (parent)) 3980 if (NILP (parent))
3968 { 3981 {
3969 if (widthflag) 3982 if (horiz_flag)
3970 error ("No other window to side of this one"); 3983 error ("No other window to side of this one");
3971 break; 3984 break;
3972 } 3985 }
3973 3986
3974 if (widthflag 3987 if (horiz_flag
3975 ? !NILP (XWINDOW (parent)->hchild) 3988 ? !NILP (XWINDOW (parent)->hchild)
3976 : !NILP (XWINDOW (parent)->vchild)) 3989 : !NILP (XWINDOW (parent)->vchild))
3977 break; 3990 break;
3978 3991
3979 window = parent; 3992 window = parent;
3984 { 3997 {
3985 register int maxdelta; 3998 register int maxdelta;
3986 3999
3987 /* Compute the maximum size increment this window can have. */ 4000 /* Compute the maximum size increment this window can have. */
3988 4001
3989 if (preserve_before) 4002 maxdelta = (!NILP (parent) ? (*sizefun) (parent) - XINT (*sizep)
3990 { 4003 /* This is a main window followed by a minibuffer. */
3991 if (!NILP (parent)) 4004 : !NILP (p->next) ? ((*sizefun) (p->next)
3992 { 4005 - window_min_size (XWINDOW (p->next),
3993 maxdelta = (*sizefun) (parent) - XINT (*sizep); 4006 horiz_flag, 0, 0))
3994 /* Subtract size of siblings before, since we can't take that. */ 4007 /* This is a minibuffer following a main window. */
3995 maxdelta -= XINT (CURBEG (window)) - XINT (CURBEG (parent)); 4008 : !NILP (p->prev) ? ((*sizefun) (p->prev)
3996 } 4009 - window_min_size (XWINDOW (p->prev),
3997 else 4010 horiz_flag, 0, 0))
3998 maxdelta = (!NILP (p->next) ? ((*sizefun) (p->next) 4011 /* This is a frame with only one window, a minibuffer-only
3999 - window_min_size (XWINDOW (p->next), 4012 or a minibufferless frame. */
4000 widthflag, 0, 0)) 4013 : (delta = 0));
4001 : (delta = 0));
4002 }
4003 else
4004 maxdelta = (!NILP (parent) ? (*sizefun) (parent) - XINT (*sizep)
4005 /* This is a main window followed by a minibuffer. */
4006 : !NILP (p->next) ? ((*sizefun) (p->next)
4007 - window_min_size (XWINDOW (p->next),
4008 widthflag, 0, 0))
4009 /* This is a minibuffer following a main window. */
4010 : !NILP (p->prev) ? ((*sizefun) (p->prev)
4011 - window_min_size (XWINDOW (p->prev),
4012 widthflag, 0, 0))
4013 /* This is a frame with only one window, a minibuffer-only
4014 or a minibufferless frame. */
4015 : (delta = 0));
4016 4014
4017 if (delta > maxdelta) 4015 if (delta > maxdelta)
4018 /* This case traps trying to make the minibuffer 4016 /* This case traps trying to make the minibuffer
4019 the full frame, or make the only window aside from the 4017 the full frame, or make the only window aside from the
4020 minibuffer the full frame. */ 4018 minibuffer the full frame. */
4021 delta = maxdelta; 4019 delta = maxdelta;
4022 } 4020 }
4023 4021
4024 if (XINT (*sizep) + delta < window_min_size (XWINDOW (window), widthflag, 0, 0)) 4022 if (XINT (*sizep) + delta < window_min_size (XWINDOW (window), horiz_flag, 0, 0))
4025 { 4023 {
4026 delete_window (window); 4024 delete_window (window);
4027 return; 4025 return;
4028 } 4026 }
4029 4027
4032 4030
4033 /* Find the total we can get from other siblings without deleting them. */ 4031 /* Find the total we can get from other siblings without deleting them. */
4034 maximum = 0; 4032 maximum = 0;
4035 for (next = p->next; ! NILP (next); next = XWINDOW (next)->next) 4033 for (next = p->next; ! NILP (next); next = XWINDOW (next)->next)
4036 maximum += (*sizefun) (next) - window_min_size (XWINDOW (next), 4034 maximum += (*sizefun) (next) - window_min_size (XWINDOW (next),
4037 widthflag, 0, 0); 4035 horiz_flag, 0, 0);
4038 if (! preserve_before) 4036 for (prev = p->prev; ! NILP (prev); prev = XWINDOW (prev)->prev)
4039 for (prev = p->prev; ! NILP (prev); prev = XWINDOW (prev)->prev) 4037 maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
4040 maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev), 4038 horiz_flag, 0, 0);
4041 widthflag, 0, 0);
4042 4039
4043 /* If we can get it all from them without deleting them, do so. */ 4040 /* If we can get it all from them without deleting them, do so. */
4044 if (delta <= maximum) 4041 if (delta <= maximum)
4045 { 4042 {
4046 Lisp_Object first_unaffected; 4043 Lisp_Object first_unaffected;
4052 first_affected = window; 4049 first_affected = window;
4053 /* Look at one sibling at a time, 4050 /* Look at one sibling at a time,
4054 moving away from this window in both directions alternately, 4051 moving away from this window in both directions alternately,
4055 and take as much as we can get without deleting that sibling. */ 4052 and take as much as we can get without deleting that sibling. */
4056 while (delta != 0 4053 while (delta != 0
4057 && (!NILP (next) || (!preserve_before && !NILP (prev)))) 4054 && (!NILP (next) || !NILP (prev)))
4058 { 4055 {
4059 if (! NILP (next)) 4056 if (! NILP (next))
4060 { 4057 {
4061 int this_one = ((*sizefun) (next) 4058 int this_one = ((*sizefun) (next)
4062 - window_min_size (XWINDOW (next), 4059 - window_min_size (XWINDOW (next),
4063 widthflag, 0, &fixed_p)); 4060 horiz_flag, 0, &fixed_p));
4064 if (!fixed_p) 4061 if (!fixed_p)
4065 { 4062 {
4066 if (this_one > delta) 4063 if (this_one > delta)
4067 this_one = delta; 4064 this_one = delta;
4068 4065
4076 } 4073 }
4077 4074
4078 if (delta == 0) 4075 if (delta == 0)
4079 break; 4076 break;
4080 4077
4081 if (!preserve_before && ! NILP (prev)) 4078 if (! NILP (prev))
4082 { 4079 {
4083 int this_one = ((*sizefun) (prev) 4080 int this_one = ((*sizefun) (prev)
4084 - window_min_size (XWINDOW (prev), 4081 - window_min_size (XWINDOW (prev),
4085 widthflag, 0, &fixed_p)); 4082 horiz_flag, 0, &fixed_p));
4086 if (!fixed_p) 4083 if (!fixed_p)
4087 { 4084 {
4088 if (this_one > delta) 4085 if (this_one > delta)
4089 this_one = delta; 4086 this_one = delta;
4090 4087
4183 struct window *w = XWINDOW (window); 4180 struct window *w = XWINDOW (window);
4184 Lisp_Object s; 4181 Lisp_Object s;
4185 int n = 1; 4182 int n = 1;
4186 4183
4187 for (s = w->next; !NILP (s); s = XWINDOW (s)->next) 4184 for (s = w->next; !NILP (s); s = XWINDOW (s)->next)
4188 if (!window_fixed_size_p (XWINDOW (s), widthflag, 0)) 4185 if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
4189 ++n; 4186 ++n;
4190 for (s = w->prev; !NILP (s); s = XWINDOW (s)->prev) 4187 for (s = w->prev; !NILP (s); s = XWINDOW (s)->prev)
4191 if (!window_fixed_size_p (XWINDOW (s), widthflag, 0)) 4188 if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
4192 ++n; 4189 ++n;
4193 4190
4194 delta1 = n * delta; 4191 delta1 = n * delta;
4195 4192
4196 /* Add delta1 lines or columns to this window, and to the parent, 4193 /* Add delta1 lines or columns to this window, and to the parent,
4213 4210
4214 /* Adjust glyph matrices. */ 4211 /* Adjust glyph matrices. */
4215 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window)))); 4212 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window))));
4216 } 4213 }
4217 4214
4215
4216 /* Adjust the size of WINDOW by DELTA, moving only its trailing edge.
4217 HORIZ_FLAG nonzero means adjust the width, moving the right edge.
4218 zero means adjust the height, moving the bottom edge.
4219
4220 Following siblings of the selected window are resized to fulfill
4221 the size request. If they become too small in the process, they
4222 are not deleted; instead, we signal an error. */
4223
4224 static void
4225 adjust_window_trailing_edge (window, delta, horiz_flag)
4226 Lisp_Object window;
4227 int delta, horiz_flag;
4228 {
4229 Lisp_Object parent, child;
4230 struct window *p;
4231 Lisp_Object old_config = Fcurrent_window_configuration (Qnil);
4232 int delcount = window_deletion_count;
4233
4234 /* Check values of window_min_width and window_min_height for
4235 validity. */
4236 check_min_window_sizes ();
4237
4238 if (NILP (window))
4239 window = Fselected_window ();
4240
4241 CHECK_WINDOW (window);
4242
4243 /* Give up if this window cannot be resized. */
4244 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
4245 error ("Window is not resizable");
4246
4247 while (1)
4248 {
4249 p = XWINDOW (window);
4250 parent = p->parent;
4251
4252 /* Make sure there is a following window. */
4253 if (NILP (parent)
4254 && (horiz_flag ? 1
4255 : NILP (XWINDOW (window)->next)))
4256 {
4257 Fset_window_configuration (old_config);
4258 error ("No other window following this one");
4259 }
4260
4261 /* Don't make this window too small. */
4262 if (XINT (CURSIZE (window)) + delta
4263 < (horiz_flag ? window_min_width : window_min_height))
4264 {
4265 Fset_window_configuration (old_config);
4266 error ("Cannot adjust window size as specified");
4267 }
4268
4269 /* Clear out some redisplay caches. */
4270 XSETFASTINT (p->last_modified, 0);
4271 XSETFASTINT (p->last_overlay_modified, 0);
4272
4273 /* Adjust this window's edge. */
4274 XSETINT (CURSIZE (window),
4275 XINT (CURSIZE (window)) + delta);
4276
4277 /* If this window has following siblings in the desired dimension,
4278 make them smaller.
4279 (If we reach the top of the tree and can never do this,
4280 we will fail and report an error, above.) */
4281 if (horiz_flag
4282 ? !NILP (XWINDOW (parent)->hchild)
4283 : !NILP (XWINDOW (parent)->vchild))
4284 {
4285 if (!NILP (XWINDOW (window)->next))
4286 {
4287 XSETINT (CURBEG (p->next),
4288 XINT (CURBEG (p->next)) + delta);
4289 size_window (p->next, XINT (CURSIZE (p->next)) - delta,
4290 horiz_flag, 0);
4291 break;
4292 }
4293 }
4294 else
4295 /* Here we have a chain of parallel siblings, in the other dimension.
4296 Change the size of the other siblings. */
4297 for (child = (horiz_flag
4298 ? XWINDOW (parent)->vchild
4299 : XWINDOW (parent)->hchild);
4300 ! NILP (child);
4301 child = XWINDOW (child)->next)
4302 if (! EQ (child, window))
4303 size_window (child, XINT (CURSIZE (child)) + delta,
4304 horiz_flag, 0);
4305
4306 window = parent;
4307 }
4308
4309 /* If we made a window so small it got deleted,
4310 we failed. Report failure. */
4311 if (delcount != window_deletion_count)
4312 {
4313 Fset_window_configuration (old_config);
4314 error ("Cannot adjust window size as specified");
4315 }
4316
4317 /* Adjust glyph matrices. */
4318 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window))));
4319 }
4320
4218 #undef CURBEG 4321 #undef CURBEG
4219 #undef CURSIZE 4322 #undef CURSIZE
4323
4324 DEFUN ("adjust-window-trailing-edge", Fadjust_window_trailing_edge,
4325 Sadjust_window_trailing_edge, 3, 3, 0,
4326 doc: /* Adjust the bottom or right edge of WINDOW by DELTA.
4327 If HORIZONTAL is non-nil, that means adjust the width, moving the right edge.
4328 Otherwise, adjust the height, moving the bottom edge.
4329
4330 Following siblings of the selected window are resized to fulfill
4331 the size request. If they become too small in the process, they
4332 are not deleted; instead, we signal an error. */)
4333 (window, delta, horizontal)
4334 Lisp_Object window, delta, horizontal;
4335 {
4336 CHECK_NUMBER (delta);
4337 adjust_window_trailing_edge (window, XINT (delta), !NILP (horizontal));
4338
4339 if (! NILP (Vwindow_configuration_change_hook))
4340 call1 (Vrun_hooks, Qwindow_configuration_change_hook);
4341
4342 return Qnil;
4343 }
4220 4344
4221 4345
4222 4346
4223 /*********************************************************************** 4347 /***********************************************************************
4224 Resizing Mini-Windows 4348 Resizing Mini-Windows
4450 { 4574 {
4451 /* Distribute the additional lines of the mini-window 4575 /* Distribute the additional lines of the mini-window
4452 among the other windows. */ 4576 among the other windows. */
4453 Lisp_Object window; 4577 Lisp_Object window;
4454 XSETWINDOW (window, w); 4578 XSETWINDOW (window, w);
4455 enlarge_window (window, 1 - XFASTINT (w->total_lines), 0, 0); 4579 enlarge_window (window, 1 - XFASTINT (w->total_lines), 0);
4456 } 4580 }
4457 } 4581 }
4458 4582
4459 4583
4460 4584
5679 if (NILP (XBUFFER (new_current_buffer)->name)) 5803 if (NILP (XBUFFER (new_current_buffer)->name))
5680 new_current_buffer = Qnil; 5804 new_current_buffer = Qnil;
5681 else 5805 else
5682 { 5806 {
5683 if (XBUFFER (new_current_buffer) == current_buffer) 5807 if (XBUFFER (new_current_buffer) == current_buffer)
5684 old_point = PT; 5808 /* The code further down "preserves point" by saving here PT in
5809 old_point and then setting it later back into PT. When the
5810 current-selected-window and the final-selected-window both show
5811 the current buffer, this suffers from the problem that the
5812 current PT is the window-point of the current-selected-window,
5813 while the final PT is the point of the final-selected-window, so
5814 this copy from one PT to the other would end up moving the
5815 window-point of the final-selected-window to the window-point of
5816 the current-selected-window. So we have to be careful which
5817 point of the current-buffer we copy into old_point. */
5818 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)
5819 && WINDOWP (selected_window)
5820 && EQ (XWINDOW (selected_window)->buffer, new_current_buffer)
5821 && !EQ (selected_window, data->current_window))
5822 old_point = XMARKER (XWINDOW (data->current_window)->pointm)->charpos;
5823 else
5824 old_point = PT;
5685 else 5825 else
5686 /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of 5826 /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of
5687 point in new_current_buffer as of the last time this buffer was 5827 point in new_current_buffer as of the last time this buffer was
5688 used. This can be non-deterministic since it can be changed by 5828 used. This can be non-deterministic since it can be changed by
5689 things like jit-lock by mere temporary selection of some random 5829 things like jit-lock by mere temporary selection of some random
7096 defsubr (&Sdisplay_buffer); 7236 defsubr (&Sdisplay_buffer);
7097 defsubr (&Sforce_window_update); 7237 defsubr (&Sforce_window_update);
7098 defsubr (&Ssplit_window); 7238 defsubr (&Ssplit_window);
7099 defsubr (&Senlarge_window); 7239 defsubr (&Senlarge_window);
7100 defsubr (&Sshrink_window); 7240 defsubr (&Sshrink_window);
7241 defsubr (&Sadjust_window_trailing_edge);
7101 defsubr (&Sscroll_up); 7242 defsubr (&Sscroll_up);
7102 defsubr (&Sscroll_down); 7243 defsubr (&Sscroll_down);
7103 defsubr (&Sscroll_left); 7244 defsubr (&Sscroll_left);
7104 defsubr (&Sscroll_right); 7245 defsubr (&Sscroll_right);
7105 defsubr (&Sother_window_for_scrolling); 7246 defsubr (&Sother_window_for_scrolling);