- if (width_p)
- {
- sideward = &w->vchild;
- forward = &w->hchild;
- w->total_cols = make_number (size);
- adjust_window_margins (w);
- }
- else
- {
- sideward = &w->hchild;
- forward = &w->vchild;
- w->total_lines = make_number (size);
- w->orig_total_lines = Qnil;
- }
-
- if (!NILP (*sideward))
- {
- /* We have a chain of parallel siblings whose size should all change. */
- for (child = *sideward; !NILP (child); child = c->next)
- {
- c = XWINDOW (child);
- if (width_p)
- c->left_col = w->left_col;
- else
- c->top_line = w->top_line;
- size_window (child, size, width_p, nodelete_p,
- first_only, last_only);
- }
- }
- else if (!NILP (*forward) && last_only)
- {
- /* Change the last in a series of siblings. */
- Lisp_Object last_child;
- int child_size;
-
- child = *forward;
- do
- {
- c = XWINDOW (child);
- last_child = child;
- child = c->next;
- }
- while (!NILP (child));
-
- child_size = WINDOW_TOTAL_SIZE (c, width_p);
- size_window (last_child, size - old_size + child_size,
- width_p, nodelete_p, first_only, last_only);
- }
- else if (!NILP (*forward) && first_only)
- {
- /* Change the first in a series of siblings. */
- int child_size;
-
- child = *forward;
- c = XWINDOW (child);
-
- if (width_p)
- c->left_col = w->left_col;
- else
- c->top_line = w->top_line;
-
- child_size = WINDOW_TOTAL_SIZE (c, width_p);
- size_window (child, size - old_size + child_size,
- width_p, nodelete_p, first_only, last_only);
- }
- else if (!NILP (*forward))
- {
- int fixed_size, each IF_LINT (= 0), extra IF_LINT (= 0), n;
- int resize_fixed_p, nfixed;
- int last_pos, first_pos, nchildren, total;
- int *new_sizes = NULL;
-
- /* Determine the fixed-size portion of this window, and the
- number of child windows. */
- fixed_size = nchildren = nfixed = total = 0;
- for (child = *forward; !NILP (child); child = c->next, ++nchildren)
- {
- int child_size;
-
- c = XWINDOW (child);
- child_size = WINDOW_TOTAL_SIZE (c, width_p);
- total += child_size;
-
- if (window_fixed_size_p (c, width_p, 0))
- {
- fixed_size += child_size;
- ++nfixed;
- }
- }
-
- /* If the new size is smaller than fixed_size, or if there
- aren't any resizable windows, allow resizing fixed-size
- windows. */
- resize_fixed_p = nfixed == nchildren || size < fixed_size;
-
- /* Compute how many lines/columns to add/remove to each child. The
- value of extra takes care of rounding errors. */
- n = resize_fixed_p ? nchildren : nchildren - nfixed;
- if (size < total && n > 1)
- new_sizes = shrink_windows (total, size, nchildren, n,
- resize_fixed_p, *forward, width_p,
- nodelete_p == 2);
- else
- {
- each = (size - total) / n;
- extra = (size - total) - n * each;
- }
-
- /* Compute new children heights and edge positions. */
- first_pos = width_p ? XINT (w->left_col) : XINT (w->top_line);
- last_pos = first_pos;
- for (n = 0, child = *forward; !NILP (child); child = c->next, ++n)
- {
- int new_child_size, old_child_size;
-
- c = XWINDOW (child);
- old_child_size = WINDOW_TOTAL_SIZE (c, width_p);
- new_child_size = old_child_size;
-
- /* The top or left edge position of this child equals the
- bottom or right edge of its predecessor. */
- if (width_p)
- c->left_col = make_number (last_pos);
- else
- c->top_line = make_number (last_pos);
-
- /* If this child can be resized, do it. */
- if (resize_fixed_p || !window_fixed_size_p (c, width_p, 0))
- {
- new_child_size =
- new_sizes ? new_sizes[n] : old_child_size + each + extra;
- extra = 0;
- }
-
- /* Set new size. Note that size_window also propagates
- edge positions to children, so it's not a no-op if we
- didn't change the child's size. */
- size_window (child, new_child_size, width_p, 1,
- first_only, last_only);
-
- /* Remember the bottom/right edge position of this child; it
- will be used to set the top/left edge of the next child. */
- last_pos += new_child_size;
- }
-
- xfree (new_sizes);
-
- /* We should have covered the parent exactly with child windows. */
- xassert (size == last_pos - first_pos);
-
- /* Now delete any children that became too small. */
- if (nodelete_p != 1)
- for (child = *forward; !NILP (child); child = c->next)
- {
- int child_size;
-
- c = XWINDOW (child);
- child_size = WINDOW_TOTAL_SIZE (c, width_p);
- size_window (child, child_size, width_p, nodelete_p,
- first_only, last_only);
- }
- }
-}
-
-/* Set WINDOW's height to HEIGHT, and recursively change the height of
- WINDOW's children. NODELETE zero means windows that have become
- smaller than window-min-height in the process may be deleted.
- NODELETE 1 means never delete windows that become too small in the
- process. (The caller should check later and do so if appropriate.)
- NODELETE 2 means delete only windows that have become too small to be
- displayed correctly. */
-
-void
-set_window_height (Lisp_Object window, int height, int nodelete)
-{
- size_window (window, height, 0, nodelete, 0, 0);
-}
-
-/* Set WINDOW's width to WIDTH, and recursively change the width of
- WINDOW's children. NODELETE zero means windows that have become
- smaller than window-min-width in the process may be deleted.
- NODELETE 1 means never delete windows that become too small in the
- process. (The caller should check later and do so if appropriate.)
- NODELETE 2 means delete only windows that have become too small to be
- displayed correctly. */
-
-void
-set_window_width (Lisp_Object window, int width, int nodelete)
-{
- size_window (window, width, 1, nodelete, 0, 0);
-}
-
-/* Change window heights in windows rooted in WINDOW by N lines. */
-
-void
-change_window_heights (Lisp_Object window, int n)
-{
- struct window *w = XWINDOW (window);
-
- XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
- XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
-
- if (INTEGERP (w->orig_top_line))
- XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n);
- if (INTEGERP (w->orig_total_lines))
- XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n);
-
- /* Handle just the top child in a vertical split. */
- if (!NILP (w->vchild))
- change_window_heights (w->vchild, n);
-
- /* Adjust all children in a horizontal split. */
- for (window = w->hchild; !NILP (window); window = w->next)
- {
- w = XWINDOW (window);
- change_window_heights (window, n);
- }
-}
-
-\f
-int window_select_count;
-
-static Lisp_Object Fset_window_margins (Lisp_Object, Lisp_Object, Lisp_Object);
-static Lisp_Object Fset_window_fringes (Lisp_Object, Lisp_Object, Lisp_Object,
- Lisp_Object);
-static Lisp_Object Fset_window_scroll_bars (Lisp_Object, Lisp_Object,
- Lisp_Object, Lisp_Object);
-static Lisp_Object Fset_window_vscroll (Lisp_Object, Lisp_Object, Lisp_Object);
-
-static void
-run_funs (Lisp_Object funs)
-{
- for (; CONSP (funs); funs = XCDR (funs))
- if (!EQ (XCAR (funs), Qt))
- call0 (XCAR (funs));
-}
-
-static Lisp_Object select_window_norecord (Lisp_Object window);
-static Lisp_Object select_frame_norecord (Lisp_Object frame);
-
-void
-run_window_configuration_change_hook (struct frame *f)
-{
- int count = SPECPDL_INDEX ();
- Lisp_Object frame, global_wcch
- = Fdefault_value (Qwindow_configuration_change_hook);
- XSETFRAME (frame, f);
-
- if (NILP (Vrun_hooks))
- return;
-
- if (SELECTED_FRAME () != f)
- {
- record_unwind_protect (select_frame_norecord, Fselected_frame ());
- Fselect_frame (frame, Qt);
- }
-
- /* Use the right buffer. Matters when running the local hooks. */
- if (current_buffer != XBUFFER (Fwindow_buffer (Qnil)))
- {
- record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
- Fset_buffer (Fwindow_buffer (Qnil));
- }
-
- /* Look for buffer-local values. */
- {
- Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil);
- for (; CONSP (windows); windows = XCDR (windows))
- {
- Lisp_Object window = XCAR (windows);
- Lisp_Object buffer = Fwindow_buffer (window);
- if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook,
- buffer)))
- {
- int count1 = SPECPDL_INDEX ();
- record_unwind_protect (select_window_norecord, Fselected_window ());
- select_window_norecord (window);
- run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
- buffer));
- unbind_to (count1, Qnil);
- }
- }
- }
-
- run_funs (global_wcch);
- unbind_to (count, Qnil);
-}
-
-/* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
- means it's allowed to run hooks. See make_frame for a case where
- it's not allowed. KEEP_MARGINS_P non-zero means that the current
- margins, fringes, and scroll-bar settings of the window are not
- reset from the buffer's local settings. */
-
-void
-set_window_buffer (Lisp_Object window, Lisp_Object buffer, int run_hooks_p, int keep_margins_p)
-{
- struct window *w = XWINDOW (window);
- struct buffer *b = XBUFFER (buffer);
- int count = SPECPDL_INDEX ();
- int samebuf = EQ (buffer, w->buffer);
-
- w->buffer = buffer;
-
- if (EQ (window, selected_window))
- BVAR (b, last_selected_window) = window;
-
- /* Let redisplay errors through. */
- b->display_error_modiff = 0;