/* Window creation, deletion and examination for GNU Emacs.
Does not include redisplay.
- Copyright (C) 1985,86,87,93,94,95,96,97,1998,2000
+ Copyright (C) 1985,86,87,93,94,95,96,97,1998,2000, 2001
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#define max(a, b) ((a) < (b) ? (b) : (a))
#endif
+/* Values returned from coordinates_in_window. */
+
+enum window_part
+{
+ ON_NOTHING,
+ ON_TEXT,
+ ON_MODE_LINE,
+ ON_VERTICAL_BORDER,
+ ON_HEADER_LINE,
+ ON_LEFT_FRINGE,
+ ON_RIGHT_FRINGE
+};
+
Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p;
-Lisp_Object Qwindow_size_fixed, Qleft_bitmap_area, Qright_bitmap_area;
+Lisp_Object Qwindow_size_fixed, Qleft_fringe, Qright_fringe;
extern Lisp_Object Qheight, Qwidth;
static struct window *decode_window P_ ((Lisp_Object));
void *));
static Lisp_Object window_list_1 P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
+/* The value of `window-size-fixed'. */
+
+int window_size_fixed;
+
/* This is the window in which the terminal's cursor should
be left when nothing is being done with it. This must
always be a leaf window, and its buffer is selected by
(object)
Lisp_Object object;
{
- return (WINDOWP (object) && ! NILP (XWINDOW (object)->buffer) ? Qt : Qnil);
+ return WINDOW_LIVE_P (object) ? Qt : Qnil;
}
Lisp_Object
if (XINT (w->hscroll) != hscroll)
XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
- w->hscroll = w->min_hscroll = make_number (hscroll);
+ w->hscroll = make_number (hscroll);
return ncol;
}
X and Y are frame relative pixel coordinates. */
-static int
+static enum window_part
coordinates_in_window (w, x, y)
register struct window *w;
register int *x, *y;
{
/* Let's make this a global enum later, instead of using numbers
everywhere. */
- enum {ON_NOTHING, ON_TEXT, ON_MODE_LINE, ON_VERTICAL_BORDER,
- ON_HEADER_LINE, ON_LEFT_FRINGE, ON_RIGHT_FRINGE};
-
struct frame *f = XFRAME (WINDOW_FRAME (w));
int left_x, right_x, top_y, bottom_y;
int flags_area_width = FRAME_LEFT_FLAGS_AREA_WIDTH (f);
- int part;
+ enum window_part part;
int ux = CANON_X_UNIT (f), uy = CANON_Y_UNIT (f);
int x0 = XFASTINT (w->left) * ux;
int x1 = x0 + XFASTINT (w->width) * ux;
+ /* The width of the area where the vertical line can be dragged.
+ (Between mode lines for instance. */
+ int grabbable_width = ux;
if (*x < x0 || *x >= x1)
return ON_NOTHING;
if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
{
- if (abs (*x - x0) < ux / 2)
+ if (abs (*x - x0) < grabbable_width)
part = ON_VERTICAL_BORDER;
}
- else if (!WINDOW_RIGHTMOST_P (w) && abs (*x - x1) < ux / 2)
+ else if (!WINDOW_RIGHTMOST_P (w) && abs (*x - x1) < grabbable_width)
part = ON_VERTICAL_BORDER;
}
else if (WINDOW_WANTS_HEADER_LINE_P (w)
if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
{
- if (abs (*x - x0) < ux / 2)
+ if (abs (*x - x0) < grabbable_width)
part = ON_VERTICAL_BORDER;
}
- else if (!WINDOW_RIGHTMOST_P (w) && abs (*x - x1) < ux / 2)
+ else if (!WINDOW_RIGHTMOST_P (w) && abs (*x - x1) < grabbable_width)
part = ON_VERTICAL_BORDER;
}
/* Outside anything interesting? */
|| *x < (left_x
- flags_area_width
- FRAME_LEFT_SCROLL_BAR_WIDTH (f) * ux)
- || *x > right_x + flags_area_width)
+ || *x > (right_x
+ + flags_area_width
+ + FRAME_RIGHT_SCROLL_BAR_WIDTH (f) * ux))
{
part = ON_NOTHING;
}
if (!w->pseudo_window_p
&& !FRAME_HAS_VERTICAL_SCROLL_BARS (f)
&& !WINDOW_RIGHTMOST_P (w)
- && (abs (*x - right_x - flags_area_width) < ux / 2))
+ && (abs (*x - right_x - flags_area_width) < grabbable_width))
{
part = ON_VERTICAL_BORDER;
}
"Return non-nil if COORDINATES are in WINDOW.\n\
COORDINATES is a cons of the form (X . Y), X and Y being distances\n\
measured in characters from the upper-left corner of the frame.\n\
-(0 . 0) denotes the character in the upper left corner of the\n\
+\(0 . 0) denotes the character in the upper left corner of the\n\
frame.\n\
If COORDINATES are in the text portion of WINDOW,\n\
the coordinates relative to the window are returned.\n\
If they are in the mode line of WINDOW, `mode-line' is returned.\n\
If they are in the top mode line of WINDOW, `header-line' is returned.\n\
-If they are in the bitmap-area to the left of the window,\n\
- `left-bitmap-area' is returned, if they are in the area on the right of\n\
- the window, `right-bitmap-area' is returned.\n\
+If they are in the fringe to the left of the window,\n\
+ `left-fringe' is returned, if they are in the area on the right of\n\
+ the window, `right-fringe' is returned.\n\
If they are on the border between WINDOW and its right sibling,\n\
`vertical-line' is returned.")
(coordinates, window)
switch (coordinates_in_window (w, &x, &y))
{
- case 0: /* NOT in window at all. */
+ case ON_NOTHING:
return Qnil;
- case 1: /* In text part of window. */
- /* X and Y are now window relative pixel coordinates.
- Convert them to canonical char units before returning
- them. */
+ case ON_TEXT:
+ /* X and Y are now window relative pixel coordinates. Convert
+ them to canonical char units before returning them. */
return Fcons (CANON_X_FROM_PIXEL_X (f, x),
CANON_Y_FROM_PIXEL_Y (f, y));
- case 2: /* In mode line of window. */
+ case ON_MODE_LINE:
return Qmode_line;
- case 3: /* On right border of window. */
+ case ON_VERTICAL_BORDER:
return Qvertical_line;
- case 4:
+ case ON_HEADER_LINE:
return Qheader_line;
- case 5:
- return Qleft_bitmap_area;
+ case ON_LEFT_FRINGE:
+ return Qleft_fringe;
- case 6:
- return Qright_bitmap_area;
+ case ON_RIGHT_FRINGE:
+ return Qright_fringe;
default:
abort ();
void *user_data;
{
struct check_window_data *cw = (struct check_window_data *) user_data;
- int found;
+ enum window_part found;
+ int continue_p = 1;
found = coordinates_in_window (w, cw->x, cw->y);
- if (found)
+ if (found != ON_NOTHING)
{
*cw->part = found - 1;
XSETWINDOW (*cw->window, w);
+ continue_p = 0;
}
- return !found;
+ return continue_p;
}
&& tool_bar_p
&& WINDOWP (f->tool_bar_window)
&& XINT (XWINDOW (f->tool_bar_window)->height) > 0
- && coordinates_in_window (XWINDOW (f->tool_bar_window), &x, &y))
+ && (coordinates_in_window (XWINDOW (f->tool_bar_window), &x, &y)
+ != ON_NOTHING))
{
*part = 0;
window = f->tool_bar_window;
(frame, minibuf, window)
Lisp_Object frame, minibuf, window;
{
-
if (NILP (window))
window = selected_window;
if (NILP (frame))
else
window = FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
- /* Figure out the last window we're going to mess with. Since
- Fnext_window, given the same options, is guaranteed to go in a
- ring, we can just use Fprevious_window to find the last one.
-
- We can't just wait until we hit the first window again, because
- it might be deleted. */
-
windows = window_list_1 (window, mini ? Qt : Qnil, frame_arg);
GCPRO1 (windows);
best_window = Qnil;
? EQ (window, minibuf_window)
: 1))
{
- UNGCPRO;
- return window;
+ if (NILP (best_window))
+ best_window = window;
+ else if (EQ (window, selected_window))
+ /* For compatibility with 20.x, prefer to return
+ selected-window. */
+ best_window = window;
}
break;
sideward = &w->hchild;
forward = &w->vchild;
w->height = make_number (size);
+ w->orig_height = Qnil;
}
if (!NILP (*sideward))
XSETFASTINT (w->window_end_vpos, 0);
bzero (&w->last_cursor, sizeof w->last_cursor);
w->window_end_valid = Qnil;
- XSETFASTINT (w->hscroll, 0);
- XSETFASTINT (w->min_hscroll, 0);
+ w->hscroll = w->min_hscroll = make_number (0);
+ w->vscroll = make_number (0);
set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
set_marker_restricted (w->start,
make_number (b->last_window_start),
\f
DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p",
"Make current window ARG lines bigger.\n\
-From program, optional second arg non-nil means grow sideways ARG columns.")
+From program, optional second arg non-nil means grow sideways ARG columns.\n\
+Interactively, if an argument is not given, make the window one line bigger.")
(arg, side)
register Lisp_Object arg, side;
{
DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p",
"Make current window ARG lines smaller.\n\
-From program, optional second arg non-nil means shrink sideways arg columns.")
+From program, optional second arg non-nil means shrink sideways arg columns.\n\
+Interactively, if an argument is not given, make the window one line smaller.")
(arg, side)
register Lisp_Object arg, side;
{
}
else if (XFASTINT (w->height) > 1)
{
+ /* Distribute the additional lines of the mini-window
+ among the other windows. */
Lisp_Object window;
XSETWINDOW (window, w);
enlarge_window (window, 1 - XFASTINT (w->height), 0);
{
if (it.current_y + it.max_ascent + it.max_descent
> it.last_visible_y)
- /* The last line was only partially visible, make it fully
- visible. */
- w->vscroll = (it.last_visible_y
- - it.current_y + it.max_ascent + it.max_descent);
+ {
+ /* The last line was only partially visible, make it fully
+ visible. */
+ w->vscroll = (it.last_visible_y
+ - it.current_y + it.max_ascent + it.max_descent);
+ adjust_glyphs (it.f);
+ }
else if (noerror)
return;
else
(arg)
register Lisp_Object arg;
{
-
+ Lisp_Object result;
+ int hscroll;
+ struct window *w = XWINDOW (selected_window);
+
if (NILP (arg))
- XSETFASTINT (arg, window_internal_width (XWINDOW (selected_window)) - 2);
+ XSETFASTINT (arg, window_internal_width (w) - 2);
else
arg = Fprefix_numeric_value (arg);
- return
- Fset_window_hscroll (selected_window,
- make_number (XINT (XWINDOW (selected_window)->hscroll)
- + XINT (arg)));
+ hscroll = XINT (w->hscroll) + XINT (arg);
+ result = Fset_window_hscroll (selected_window, make_number (hscroll));
+
+ if (interactive_p (0))
+ w->min_hscroll = w->hscroll;
+
+ return result;
}
DEFUN ("scroll-right", Fscroll_right, Sscroll_right, 0, 1, "P",
(arg)
register Lisp_Object arg;
{
+ Lisp_Object result;
+ int hscroll;
+ struct window *w = XWINDOW (selected_window);
+
if (NILP (arg))
- XSETFASTINT (arg, window_internal_width (XWINDOW (selected_window)) - 2);
+ XSETFASTINT (arg, window_internal_width (w) - 2);
else
arg = Fprefix_numeric_value (arg);
- return
- Fset_window_hscroll (selected_window,
- make_number (XINT (XWINDOW (selected_window)->hscroll)
- - XINT (arg)));
+ hscroll = XINT (w->hscroll) - XINT (arg);
+ result = Fset_window_hscroll (selected_window, make_number (hscroll));
+
+ if (interactive_p (0))
+ w->min_hscroll = w->hscroll;
+
+ return result;
}
/* Value is the number of lines actually displayed in window W,
SET_TEXT_POS_FROM_MARKER (start, w->start);
start_display (&it, w, start);
move_it_vertically (&it, height);
-
- if (old_buffer)
- set_buffer_internal (old_buffer);
-
- bottom_y = it.current_y + it.max_ascent + it.max_descent;
-
- if (bottom_y > it.current_y && bottom_y <= it.last_visible_y)
- /* Hit a line without a terminating newline. */
- it.vpos++;
+ bottom_y = line_bottom_y (&it);
/* Add in empty lines at the bottom of the window. */
if (bottom_y < height)
{
- struct frame *f = XFRAME (w->frame);
- int rest = height - bottom_y;
- int lines = rest / CANON_Y_UNIT (f);
- it.vpos += lines;
+ int uy = CANON_Y_UNIT (it.f);
+ it.vpos += (height - bottom_y + uy - 1) / uy;
}
+ if (old_buffer)
+ set_buffer_internal (old_buffer);
+
return it.vpos;
}
XSETINT (arg, XINT (arg) + lines);
}
+ /* Skip past a partially visible first line. */
if (w->vscroll)
- /* Skip past a partially visible first line. */
XSETINT (arg, XINT (arg) + 1);
return Fvertical_motion (arg, window);
void
syms_of_window ()
{
- Qleft_bitmap_area = intern ("left-bitmap-area");
- staticpro (&Qleft_bitmap_area);
- Qright_bitmap_area = intern ("right-bitmap-area");
- staticpro (&Qright_bitmap_area);
+ Qleft_fringe = intern ("left-fringe");
+ staticpro (&Qleft_fringe);
+ Qright_fringe = intern ("right-fringe");
+ staticpro (&Qright_fringe);
Qwindow_size_fixed = intern ("window-size-fixed");
staticpro (&Qwindow_size_fixed);
DEFVAR_LISP ("scroll-preserve-screen-position",
&Vscroll_preserve_screen_position,
- "*Nonzero means scroll commands move point to keep its screen line unchanged.");
+ "*Non-nil means scroll commands move point to keep its screen line unchanged.");
Vscroll_preserve_screen_position = Qnil;
DEFVAR_LISP ("window-configuration-change-hook",
The selected frame is the one whose configuration has changed.");
Vwindow_configuration_change_hook = Qnil;
+ DEFVAR_BOOL ("window-size-fixed", &window_size_fixed,
+ "Non-nil in a buffer means windows displaying the buffer are fixed-size.\n\
+Emacs won't change the size of any window displaying that buffer,\n\
+unless you explicitly change the size, or Emacs has no other choice.\n\
+This variable automatically becomes buffer-local when set.");
+ Fmake_variable_buffer_local (Qwindow_size_fixed);
+ window_size_fixed = 0;
+
defsubr (&Sselected_window);
defsubr (&Sminibuffer_window);
defsubr (&Swindow_minibuffer_p);