/* Window creation, deletion and examination for GNU Emacs.
Does not include redisplay.
Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
- 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Emacs.
XSETWINDOW (val, p);
XSETFASTINT (p->last_point, 0);
p->frozen_window_start_p = 0;
- p->height_fixed_p = 0;
p->last_cursor_off_p = p->cursor_off_p = 0;
p->left_margin_cols = Qnil;
p->right_margin_cols = Qnil;
/* Outside any interesting column? */
if (*x < left_x || *x > right_x)
- return ON_SCROLL_BAR;
+ {
+ *y -= top_y;
+ return ON_SCROLL_BAR;
+ }
lmargin_width = window_box_width (w, LEFT_MARGIN_AREA);
rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA);
? (*x < right_x - WINDOW_RIGHT_FRINGE_WIDTH (w))
: (*x >= right_x - rmargin_width)))
{
- *x -= right_x;
- if (!WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
- *x -= WINDOW_RIGHT_FRINGE_WIDTH (w);
+ *x -= right_x - rmargin_width;
+ if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
+ *x += WINDOW_RIGHT_FRINGE_WIDTH (w);
*y -= top_y;
return ON_RIGHT_MARGIN;
}
}
/* Everything special ruled out - must be on text area */
- *x -= left_x + WINDOW_LEFT_FRINGE_WIDTH (w);
+ *x -= text_left;
*y -= top_y;
return ON_TEXT;
}
if (! NILP (update)
&& ! (! NILP (w->window_end_valid)
- && XFASTINT (w->last_modified) >= MODIFF))
+ && XFASTINT (w->last_modified) >= MODIFF)
+ && !noninteractive)
{
struct text_pos startp;
struct it it;
}
else if (BUFFERP (w->buffer))
{
- if (w->height_fixed_p && !width_p)
- fixed_p = 1;
- else
- {
- struct buffer *old = current_buffer;
- Lisp_Object val;
+ struct buffer *old = current_buffer;
+ Lisp_Object val;
- current_buffer = XBUFFER (w->buffer);
- val = find_symbol_value (Qwindow_size_fixed);
- current_buffer = old;
+ 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);
+ 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;
- }
+ 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
{
struct position pos;
- iarg = XINT (arg);
iarg = max (iarg, this_scroll_margin);
pos = *vmotion (PT, -iarg, w);
int ht = window_internal_height (w);
if (center_p)
- iarg = make_number (ht / 2);
- else if (XINT (arg) < 0)
- iarg = XINT (arg) + ht;
- else
- iarg = XINT (arg);
+ iarg = ht / 2;
+ else if (iarg < 0)
+ iarg += ht;
/* Don't let it get into the margin at either top or bottom. */
iarg = max (iarg, this_scroll_margin);
Lisp_Object scroll_bar_width, vertical_scroll_bar_type;
};
-#define SAVED_WINDOW_VECTOR_SIZE 24 /* Arg to Fmake_vector */
-
#define SAVED_WINDOW_N(swv,n) \
((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
data->saved_windows = tem;
for (i = 0; i < n_windows; i++)
XVECTOR (tem)->contents[i]
- = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE), Qnil);
+ = Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil);
save_window_save (FRAME_ROOT_WINDOW (f), XVECTOR (tem), 0);
XSETWINDOW_CONFIGURATION (tem, data);
return (tem);
return unbind_to (count, val);
}
+
+\f
+/***********************************************************************
+ Window Split Tree
+ ***********************************************************************/
+
+static Lisp_Object
+window_tree (w)
+ struct window *w;
+{
+ Lisp_Object tail = Qnil;
+ Lisp_Object result = Qnil;
+
+ while (w)
+ {
+ Lisp_Object wn;
+
+ XSETWINDOW (wn, w);
+ if (!NILP (w->hchild))
+ wn = Fcons (Qnil, Fcons (Fwindow_edges (wn),
+ window_tree (XWINDOW (w->hchild))));
+ else if (!NILP (w->vchild))
+ wn = Fcons (Qt, Fcons (Fwindow_edges (wn),
+ window_tree (XWINDOW (w->vchild))));
+
+ if (NILP (result))
+ {
+ result = tail = Fcons (wn, Qnil);
+ }
+ else
+ {
+ XSETCDR (tail, Fcons (wn, Qnil));
+ tail = XCDR (tail);
+ }
+
+ w = NILP (w->next) ? 0 : XWINDOW (w->next);
+ }
+
+ return result;
+}
+
+
+
+DEFUN ("window-tree", Fwindow_tree, Swindow_tree,
+ 0, 1, 0,
+ doc: /* Return the window tree for frame FRAME.
+
+The return value is a list of the form (ROOT MINI), where ROOT
+represents the window tree of the frame's root window, and MINI
+is the frame's minibuffer window.
+
+If the root window is not split, ROOT is the root window itself.
+Otherwise, ROOT is a list (DIR EDGES W1 W2 ...) where DIR is nil for a
+horizontal split, and t for a vertical split, EDGES gives the combined
+size and position of the subwindows in the split, and the rest of the
+elements are the subwindows in the split. Each of the subwindows may
+again be a window or a list representing a window split, and so on.
+EDGES is a list \(LEFT TOP RIGHT BOTTOM) as returned by `window-edges'.
+
+If FRAME is nil or omitted, return information on the currently
+selected frame. */)
+ (frame)
+ Lisp_Object frame;
+{
+ FRAME_PTR f;
+
+ if (NILP (frame))
+ frame = selected_frame;
+
+ CHECK_FRAME (frame);
+ f = XFRAME (frame);
+
+ if (!FRAME_LIVE_P (f))
+ return Qnil;
+
+ return window_tree (XWINDOW (FRAME_ROOT_WINDOW (f)));
+}
+
\f
/***********************************************************************
Marginal Areas
reserve for the left marginal area. Optional third arg RIGHT-WIDTH
does the same for the right marginal area. A nil width parameter
means no margin. */)
- (window, left, right)
- Lisp_Object window, left, right;
+ (window, left_width, right_width)
+ Lisp_Object window, left_width, right_width;
{
struct window *w = decode_window (window);
/* Translate negative or zero widths to nil.
Margins that are too wide have to be checked elsewhere. */
- if (!NILP (left))
+ if (!NILP (left_width))
{
- CHECK_NUMBER (left);
- if (XINT (left) <= 0)
- left = Qnil;
+ CHECK_NUMBER (left_width);
+ if (XINT (left_width) <= 0)
+ left_width = Qnil;
}
- if (!NILP (right))
+ if (!NILP (right_width))
{
- CHECK_NUMBER (right);
- if (XINT (right) <= 0)
- right = Qnil;
+ CHECK_NUMBER (right_width);
+ if (XINT (right_width) <= 0)
+ right_width = Qnil;
}
- if (!EQ (w->left_margin_cols, left)
- || !EQ (w->right_margin_cols, right))
+ if (!EQ (w->left_margin_cols, left_width)
+ || !EQ (w->right_margin_cols, right_width))
{
- w->left_margin_cols = left;
- w->right_margin_cols = right;
+ w->left_margin_cols = left_width;
+ w->right_margin_cols = right_width;
adjust_window_margins (w);
If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes
outside of the display margins. By default, fringes are drawn between
display marginal areas and the text area. */)
- (window, left, right, outside_margins)
- Lisp_Object window, left, right, outside_margins;
+ (window, left_width, right_width, outside_margins)
+ Lisp_Object window, left_width, right_width, outside_margins;
{
struct window *w = decode_window (window);
- if (!NILP (left))
- CHECK_NATNUM (left);
- if (!NILP (right))
- CHECK_NATNUM (right);
+ if (!NILP (left_width))
+ CHECK_NATNUM (left_width);
+ if (!NILP (right_width))
+ CHECK_NATNUM (right_width);
- if (!EQ (w->left_fringe_width, left)
- || !EQ (w->right_fringe_width, right)
+ if (!EQ (w->left_fringe_width, left_width)
+ || !EQ (w->right_fringe_width, right_width)
|| !EQ (w->fringes_outside_margins, outside_margins))
{
- w->left_fringe_width = left;
- w->right_fringe_width = right;
+ w->left_fringe_width = left_width;
+ w->right_fringe_width = right_width;
w->fringes_outside_margins = outside_margins;
adjust_window_margins (w);
defsubr (&Sset_window_configuration);
defsubr (&Scurrent_window_configuration);
defsubr (&Ssave_window_excursion);
+ defsubr (&Swindow_tree);
defsubr (&Sset_window_margins);
defsubr (&Swindow_margins);
defsubr (&Sset_window_fringes);