Lisp_Object Qwindow_size_fixed, Qleft_fringe, Qright_fringe;
extern Lisp_Object Qheight, Qwidth;
+static int displayed_window_lines P_ ((struct window *));
static struct window *decode_window P_ ((Lisp_Object));
static Lisp_Object select_window_1 P_ ((Lisp_Object, int));
static int count_windows P_ ((struct window *));
}
-/* Return number of lines of text (not counting mode line) in W. */
+/* Return number of lines of text (not counting mode lines) in W. */
int
window_internal_height (w)
{
int ht = XFASTINT (w->height);
- if (MINI_WINDOW_P (w))
- return ht;
-
- if (!NILP (w->parent) || !NILP (w->vchild) || !NILP (w->hchild)
- || !NILP (w->next) || !NILP (w->prev)
- || FRAME_WANTS_MODELINE_P (XFRAME (WINDOW_FRAME (w))))
- return ht - 1;
+ if (!MINI_WINDOW_P (w))
+ {
+ if (!NILP (w->parent)
+ || !NILP (w->vchild)
+ || !NILP (w->hchild)
+ || !NILP (w->next)
+ || !NILP (w->prev)
+ || WINDOW_WANTS_MODELINE_P (w))
+ --ht;
+
+ if (WINDOW_WANTS_HEADER_LINE_P (w))
+ --ht;
+ }
return ht;
}
else
old_buffer = NULL;
- SET_TEXT_POS_FROM_MARKER (start, w->start);
+ /* In case W->start is out of the accessible range, do something
+ reasonable. This happens in Info mode when Info-scroll-down
+ calls (recenter -1) while W->start is 1. */
+ if (XMARKER (w->start)->charpos < BEGV)
+ SET_TEXT_POS (start, BEGV, BEGV_BYTE);
+ else if (XMARKER (w->start)->charpos > ZV)
+ SET_TEXT_POS (start, ZV, ZV_BYTE);
+ else
+ SET_TEXT_POS_FROM_MARKER (start, w->start);
+
start_display (&it, w, start);
move_it_vertically (&it, height);
bottom_y = line_bottom_y (&it);
set_buffer_internal (buf);
- /* Handle centering on a gfaphical frame specially. Such frames can
+ /* Handle centering on a graphical frame specially. Such frames can
have variable-height lines and centering point on the basis of
line counts would lead to strange effects. */
- if (center_p && FRAME_WINDOW_P (XFRAME (w->frame)))
+ if (FRAME_WINDOW_P (XFRAME (w->frame)))
{
- struct it it;
- struct text_pos pt;
-
- SET_TEXT_POS (pt, PT, PT_BYTE);
- start_display (&it, w, pt);
- move_it_vertically (&it, - it.last_visible_y / 2);
- charpos = IT_CHARPOS (it);
- bytepos = IT_BYTEPOS (it);
- }
- else
- {
- struct position pos;
-
if (center_p)
{
- int ht = displayed_window_lines (w);
- arg = make_number (ht / 2);
+ struct it it;
+ struct text_pos pt;
+
+ SET_TEXT_POS (pt, PT, PT_BYTE);
+ start_display (&it, w, pt);
+ move_it_vertically (&it, - it.last_visible_y / 2);
+ charpos = IT_CHARPOS (it);
+ bytepos = IT_BYTEPOS (it);
}
else if (XINT (arg) < 0)
{
- int ht = displayed_window_lines (w);
- XSETINT (arg, XINT (arg) + ht);
+ struct it it;
+ struct text_pos pt;
+ int y0, y1, h;
+
+ SET_TEXT_POS (pt, PT, PT_BYTE);
+ start_display (&it, w, pt);
+ y0 = it.current_y;
+
+ /* The amount of pixels we have to move hack is the window
+ height minus what's displayed in the line containing PT,
+ and the lines below. */
+ move_it_by_lines (&it, - XINT (arg) - 1, 1);
+ y1 = it.current_y - y0;
+ h = line_bottom_y (&it) - y1;
+ y0 = it.last_visible_y - y1 - h;
+
+ start_display (&it, w, pt);
+ move_it_vertically (&it, - y0);
+ charpos = IT_CHARPOS (it);
+ bytepos = IT_BYTEPOS (it);
+ }
+ else
+ {
+ struct position pos;
+ pos = *vmotion (PT, - XINT (arg), w);
+ charpos = pos.bufpos;
+ bytepos = pos.bytepos;
}
+ }
+ else
+ {
+ struct position pos;
+ int ht = window_internal_height (w);
+
+ if (center_p)
+ arg = make_number (ht / 2);
+ else if (XINT (arg) < 0)
+ arg = make_number (XINT (arg) + ht);
pos = *vmotion (PT, - XINT (arg), w);
charpos = pos.bufpos;
when the frame's old selected window has been deleted. */
if (f != selected_frame && FRAME_WINDOW_P (f))
do_switch_frame (WINDOW_FRAME (XWINDOW (data->root_window)),
- Qnil, 0);
+ 0, 0);
#endif
/* Set the screen height to the value it had before this function. */
Fselect_window above totally superfluous; it still sets f's
selected window. */
if (FRAME_LIVE_P (XFRAME (data->selected_frame)))
- do_switch_frame (data->selected_frame, Qnil, 0);
+ do_switch_frame (data->selected_frame, 0, 0);
if (! NILP (Vwindow_configuration_change_hook)
&& ! NILP (Vrun_hooks))