- return Qnil;
-}
-
-/* Replace BUFFER with some other buffer in all windows
- of all frames, even those on other keyboards. */
-
-void
-replace_buffer_in_all_windows (Lisp_Object buffer)
-{
- Lisp_Object tail, frame;
-
- /* A single call to window_loop won't do the job
- because it only considers frames on the current keyboard.
- So loop manually over frames, and handle each one. */
- FOR_EACH_FRAME (tail, frame)
- window_loop (UNSHOW_BUFFER, buffer, 1, frame);
-}
-\f
-/* Set the height of WINDOW and all its inferiors. */
-
-/* The smallest acceptable dimensions for a window. Anything smaller
- might crash Emacs. */
-
-#define MIN_SAFE_WINDOW_WIDTH (2)
-#define MIN_SAFE_WINDOW_HEIGHT (1)
-
-/* For wp non-zero the total number of columns of window w. Otherwise
- the total number of lines of w. */
-
-#define WINDOW_TOTAL_SIZE(w, wp) \
- (wp ? WINDOW_TOTAL_COLS (w) : WINDOW_TOTAL_LINES (w))
-
-/* If *ROWS or *COLS are too small a size for FRAME, set them to the
- minimum allowable size. */
-
-void
-check_frame_size (FRAME_PTR frame, int *rows, int *cols)
-{
- /* For height, we have to see:
- how many windows the frame has at minimum (one or two),
- and whether it has a menu bar or other special stuff at the top. */
- int min_height
- = ((FRAME_MINIBUF_ONLY_P (frame) || ! FRAME_HAS_MINIBUF_P (frame))
- ? MIN_SAFE_WINDOW_HEIGHT
- : 2 * MIN_SAFE_WINDOW_HEIGHT);
-
- if (FRAME_TOP_MARGIN (frame) > 0)
- min_height += FRAME_TOP_MARGIN (frame);
-
- if (*rows < min_height)
- *rows = min_height;
- if (*cols < MIN_SAFE_WINDOW_WIDTH)
- *cols = MIN_SAFE_WINDOW_WIDTH;
-}
-
-/* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
- check if W's width can be changed, otherwise check W's height.
- CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
- siblings, too. If none of the siblings is resizable, WINDOW isn't
- either. */
-
-static int
-window_fixed_size_p (struct window *w, int width_p, int check_siblings_p)
-{
- int fixed_p;
- struct window *c;
-
- if (!NILP (w->hchild))
- {
- c = XWINDOW (w->hchild);
-
- if (width_p)
- {
- /* A horizontal combination is fixed-width if all of if its
- children are. */
- while (c && window_fixed_size_p (c, width_p, 0))
- c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
- fixed_p = c == NULL;
- }
- else
- {
- /* A horizontal combination is fixed-height if one of if its
- children is. */
- while (c && !window_fixed_size_p (c, width_p, 0))
- c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
- fixed_p = c != NULL;
- }
- }
- else if (!NILP (w->vchild))
- {
- c = XWINDOW (w->vchild);
-
- if (width_p)
- {
- /* A vertical combination is fixed-width if one of if its
- children is. */
- while (c && !window_fixed_size_p (c, width_p, 0))
- c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
- fixed_p = c != NULL;
- }
- else
- {
- /* A vertical combination is fixed-height if all of if its
- children are. */
- while (c && window_fixed_size_p (c, width_p, 0))
- c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
- fixed_p = c == NULL;
- }
- }
- else if (BUFFERP (w->buffer))
- {
- struct buffer *old = current_buffer;
- Lisp_Object val;
-
- current_buffer = XBUFFER (w->buffer);
- val = find_symbol_value (Qwindow_size_fixed);
- current_buffer = old;
-
- fixed_p = 0;
- if (!EQ (val, Qunbound))
- {
- fixed_p = !NILP (val);
-
- if (fixed_p
- && ((EQ (val, Qheight) && width_p)
- || (EQ (val, Qwidth) && !width_p)))
- fixed_p = 0;
- }
-
- /* Can't tell if this one is resizable without looking at
- siblings. If all siblings are fixed-size this one is too. */
- if (!fixed_p && check_siblings_p && WINDOWP (w->parent))
- {
- Lisp_Object child;
-
- for (child = w->prev; WINDOWP (child); child = XWINDOW (child)->prev)
- if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
- break;
-
- if (NILP (child))
- for (child = w->next; WINDOWP (child); child = XWINDOW (child)->next)
- if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
- break;
-
- if (NILP (child))
- fixed_p = 1;
- }
- }
- else
- fixed_p = 1;
-
- return fixed_p;
-}
-
-/* Return minimum size of leaf window W. WIDTH_P non-zero means return
- the minimum width of W, WIDTH_P zero means return the minimum height
- of W. SAFE_P non-zero means ignore window-min-height|width but just
- return values that won't crash Emacs and don't hide components like
- fringes, scrollbars, or modelines. If WIDTH_P is zero and W is the
- minibuffer window, always return 1. */
-
-static int
-window_min_size_2 (struct window *w, int width_p, int safe_p)
-{
- /* We should consider buffer-local values of window_min_height and
- window_min_width here. */
- if (width_p)
- {
- int safe_size = (MIN_SAFE_WINDOW_WIDTH
- + WINDOW_FRINGE_COLS (w)
- + WINDOW_SCROLL_BAR_COLS (w));
-
- return safe_p ? safe_size : max (window_min_width, safe_size);
- }
- else if (MINI_WINDOW_P (w))
- return 1;
- else
- {
- int safe_size = (MIN_SAFE_WINDOW_HEIGHT
- + ((BUFFERP (w->buffer)
- && !NILP (BVAR (XBUFFER (w->buffer), mode_line_format)))
- ? 1 : 0));
-
- return safe_p ? safe_size : max (window_min_height, safe_size);
- }
-}
-
-/* Return minimum size of window W, not taking fixed-width windows into
- account. WIDTH_P non-zero means return the minimum width, otherwise
- return the minimum height. SAFE_P non-zero means ignore
- window-min-height|width but just return values that won't crash Emacs
- and don't hide components like fringes, scrollbars, or modelines. If
- W is a combination window, compute the minimum size from the minimum
- sizes of W's children. */
-
-static int
-window_min_size_1 (struct window *w, int width_p, int safe_p)
-{
- struct window *c;
- int size;
-
- if (!NILP (w->hchild))
- {
- /* W is a horizontal combination. */
- c = XWINDOW (w->hchild);
- size = 0;
-
- if (width_p)
- {
- /* The minimum width of a horizontal combination is the sum of
- the minimum widths of its children. */
- while (c)
- {
- size += window_min_size_1 (c, 1, safe_p);
- c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
- }
- }
- else
- {
- /* The minimum height of a horizontal combination is the
- maximum of the minimum heights of its children. */
- while (c)
- {
- size = max (window_min_size_1 (c, 0, safe_p), size);
- c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
- }
- }
- }
- else if (!NILP (w->vchild))
- {
- /* W is a vertical combination. */
- c = XWINDOW (w->vchild);
- size = 0;
-
- if (width_p)
- {
- /* The minimum width of a vertical combination is the maximum
- of the minimum widths of its children. */
- while (c)
- {
- size = max (window_min_size_1 (c, 1, safe_p), size);
- c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
- }
- }
- else
- {
- /* The minimum height of a vertical combination is the sum of
- the minimum height of its children. */
- while (c)
- {
- size += window_min_size_1 (c, 0, safe_p);
- c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
- }
- }
- }
- else
- /* W is a leaf window. */
- size = window_min_size_2 (w, width_p, safe_p);
-
- return size;
-}
-
-/* Return the minimum size of window W, taking fixed-size windows into
- account. WIDTH_P non-zero means return the minimum width, otherwise
- return the minimum height. SAFE_P non-zero means ignore
- window-min-height|width but just return values that won't crash Emacs
- and don't hide components like fringes, scrollbars, or modelines.
- IGNORE_FIXED_P non-zero means ignore if W is fixed-size. Set *FIXED
- to 1 if W is fixed-size unless FIXED is null. */
-
-static int
-window_min_size (struct window *w, int width_p, int safe_p, int ignore_fixed_p, int *fixed)
-{
- int size, fixed_p;
-
- if (ignore_fixed_p)
- fixed_p = 0;
- else
- fixed_p = window_fixed_size_p (w, width_p, 1);
-
- if (fixed)
- *fixed = fixed_p;
-
- if (fixed_p)
- size = WINDOW_TOTAL_SIZE (w, width_p);
- else
- size = window_min_size_1 (w, width_p, safe_p);
-
- return size;
-}
-
-
-/* Adjust the margins of window W if text area is too small.
- Return 1 if window width is ok after adjustment; 0 if window
- is still too narrow. */
-
-static int
-adjust_window_margins (struct window *w)
-{
- int box_cols = (WINDOW_TOTAL_COLS (w)
- - WINDOW_FRINGE_COLS (w)
- - WINDOW_SCROLL_BAR_COLS (w));
- int margin_cols = (WINDOW_LEFT_MARGIN_COLS (w)
- + WINDOW_RIGHT_MARGIN_COLS (w));
-
- if (box_cols - margin_cols >= MIN_SAFE_WINDOW_WIDTH)
- return 1;
-
- if (margin_cols < 0 || box_cols < MIN_SAFE_WINDOW_WIDTH)
- return 0;
-
- /* Window's text area is too narrow, but reducing the window
- margins will fix that. */
- margin_cols = box_cols - MIN_SAFE_WINDOW_WIDTH;
- if (WINDOW_RIGHT_MARGIN_COLS (w) > 0)
- {
- if (WINDOW_LEFT_MARGIN_COLS (w) > 0)
- w->left_margin_cols = w->right_margin_cols
- = make_number (margin_cols/2);
- else
- w->right_margin_cols = make_number (margin_cols);
- }
- else
- w->left_margin_cols = make_number (margin_cols);
- return 1;
-}
-
-/* Calculate new sizes for windows in the list FORWARD when their
- compound size goes from TOTAL to SIZE. TOTAL must be greater than
- SIZE. The number of windows in FORWARD is NCHILDREN, and the number
- that can shrink is SHRINKABLE. Fixed-size windows may be shrunk if
- and only if RESIZE_FIXED_P is non-zero. WIDTH_P non-zero means
- shrink columns, otherwise shrink lines.
-
- SAFE_P zero means windows may be sized down to window-min-height
- lines (window-min-window columns for WIDTH_P non-zero). SAFE_P
- non-zero means windows may be sized down to their minimum safe sizes
- taking into account the space needed to display modelines, fringes,
- and scrollbars.
-
- This function returns an allocated array of new sizes that the caller
- must free. A size -1 means the window is fixed and RESIZE_FIXED_P is
- zero. A size zero means the window shall be deleted. Array index 0
- refers to the first window in FORWARD, 1 to the second, and so on.
-
- This function resizes windows proportionally to their size. It also
- tries to preserve smaller windows by resizing larger windows before
- resizing any window to zero. If resize_proportionally is non-nil for
- a specific window, it will attempt to strictly resize that window
- proportionally, even at the expense of deleting smaller windows. */
-static int *
-shrink_windows (int total, int size, int nchildren, int shrinkable,
- int resize_fixed_p, Lisp_Object forward, int width_p, int safe_p)
-{
- int available_resize = 0;
- int *new_sizes, *min_sizes;
- struct window *c;
- Lisp_Object child;
- int smallest = total;
- int total_removed = 0;
- int total_shrink = total - size;
- int i;
-
- new_sizes = xmalloc (sizeof (*new_sizes) * nchildren);
- min_sizes = xmalloc (sizeof (*min_sizes) * nchildren);
-
- for (i = 0, child = forward; !NILP (child); child = c->next, ++i)
- {
- int child_size;
-
- c = XWINDOW (child);
- child_size = WINDOW_TOTAL_SIZE (c, width_p);
-
- if (!resize_fixed_p && window_fixed_size_p (c, width_p, 0))
- new_sizes[i] = -1;
- else
- {
- new_sizes[i] = child_size;
- min_sizes[i] = window_min_size_1 (c, width_p, safe_p);
- if (child_size > min_sizes[i]
- && NILP (c->resize_proportionally))
- available_resize += child_size - min_sizes[i];
- }
- }
- /* We might need to shrink some windows to zero. Find the smallest
- windows and set them to 0 until we can fulfil the new size. */
-
- while (shrinkable > 1 && size + available_resize < total)
- {
- for (i = 0; i < nchildren; ++i)
- if (new_sizes[i] > 0 && smallest > new_sizes[i])
- smallest = new_sizes[i];
-
- for (i = 0; i < nchildren; ++i)
- if (new_sizes[i] == smallest)
- {
- /* Resize this window down to zero. */
- new_sizes[i] = 0;
- if (smallest > min_sizes[i])
- available_resize -= smallest - min_sizes[i];
- available_resize += smallest;
- --shrinkable;
- total_removed += smallest;
-
- /* We don't know what the smallest is now. */
- smallest = total;
-
- /* Out of for, just remove one window at the time and
- check again if we have enough space. */
- break;
- }
- }
-
- /* Now, calculate the new sizes. Try to shrink each window
- proportional to its size. */
- for (i = 0; i < nchildren; ++i)
- {
- if (new_sizes[i] > min_sizes[i])
- {
- int to_shrink = total_shrink * new_sizes[i] / total;
-
- if (new_sizes[i] - to_shrink < min_sizes[i])
- to_shrink = new_sizes[i] - min_sizes[i];
- new_sizes[i] -= to_shrink;
- total_removed += to_shrink;
- }
- }
-
- /* Any reminder due to rounding, we just subtract from windows
- that are left and still can be shrunk. */
- while (total_shrink > total_removed)
- {
- int nonzero_sizes = 0;
-
- for (i = 0; i < nchildren; ++i)
- if (new_sizes[i] > 0)
- ++nonzero_sizes;
-
- for (i = 0; i < nchildren; ++i)
- if (new_sizes[i] > min_sizes[i])
- {
- --new_sizes[i];
- ++total_removed;
-
- /* Out of for, just shrink one window at the time and
- check again if we have enough space. */
- break;
- }
-
- /* Special case, only one window left. */
- if (nonzero_sizes == 1)
- break;
- }
-
- /* Any surplus due to rounding, we add to windows that are left. */
- while (total_shrink < total_removed)
- {
- for (i = 0; i < nchildren; ++i)
- {
- if (new_sizes[i] != 0 && total_shrink < total_removed)
- {
- ++new_sizes[i];
- --total_removed;
- break;
- }
- }
- }
-
- xfree (min_sizes);
-
- return new_sizes;
-}
-
-/* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
- WINDOW's width. Resize WINDOW's children, if any, so that they keep
- their proportionate size relative to WINDOW.
-
- If FIRST_ONLY is 1, change only the first of WINDOW's children when
- they are in series. If LAST_ONLY is 1, change only the last of
- WINDOW's children when they are in series.
-
- Propagate WINDOW's top or left edge position to children. Delete
- windows that become too small unless NODELETE_P is 1. When
- NODELETE_P equals 2 do not honor settings for window-min-height and
- window-min-width when resizing windows but use safe defaults instead.
- This should give better behavior when resizing frames. */
-
-static void
-size_window (Lisp_Object window, int size, int width_p, int nodelete_p, int first_only, int last_only)
-{
- struct window *w = XWINDOW (window);
- struct window *c;
- Lisp_Object child, *forward, *sideward;
- int old_size = WINDOW_TOTAL_SIZE (w, width_p);
-
- size = max (0, size);
-
- /* Delete WINDOW if it's too small. */
- if (nodelete_p != 1 && !NILP (w->parent)
- && size < window_min_size_1 (w, width_p, nodelete_p == 2))
- {
- delete_window (window);
- return;
- }
-
- /* Set redisplay hints. */
- w->last_modified = make_number (0);
- w->last_overlay_modified = make_number (0);
- windows_or_buffers_changed++;
- FRAME_WINDOW_SIZES_CHANGED (XFRAME (w->frame)) = 1;
-
- 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);
- }
- }