/* Ascent and height of the last line processed by move_it_to. */
-static int last_height;
+static int last_max_ascent, last_height;
/* Non-zero if there's a help-echo in the echo area. */
/* Functions to mark elements as needing redisplay. */
enum { REDISPLAY_SOME = 2}; /* Arbitrary choice. */
-void redisplay_other_windows (void)
+void
+redisplay_other_windows (void)
{
if (!windows_or_buffers_changed)
windows_or_buffers_changed = REDISPLAY_SOME;
}
-void wset_redisplay (struct window *w)
+void
+wset_redisplay (struct window *w)
{
redisplay_other_windows ();
w->redisplay = true;
}
-void fset_redisplay (struct frame *f)
+void
+fset_redisplay (struct frame *f)
{
redisplay_other_windows ();
f->redisplay = true;
}
-void bset_redisplay (struct buffer *b)
+void
+bset_redisplay (struct buffer *b)
{
int count = buffer_window_count (b);
if (count > 0)
}
}
-extern void bset_update_mode_line (struct buffer *b)
+void
+bset_update_mode_line (struct buffer *b)
{
if (!update_mode_lines)
update_mode_lines = REDISPLAY_SOME;
static int display_prop_string_p (Lisp_Object, Lisp_Object);
static int row_for_charpos_p (struct glyph_row *, ptrdiff_t);
static int cursor_row_p (struct glyph_row *);
-static int redisplay_mode_lines (Lisp_Object, int);
+static int redisplay_mode_lines (Lisp_Object, bool);
static char *decode_mode_spec_coding (Lisp_Object, char *, int);
static Lisp_Object get_it_property (struct it *it, Lisp_Object prop);
static void redisplay_internal (void);
static int echo_area_display (int);
static void redisplay_windows (Lisp_Object);
-static void redisplay_window (Lisp_Object, int);
+static void redisplay_window (Lisp_Object, bool);
static Lisp_Object redisplay_window_error (Lisp_Object);
static Lisp_Object redisplay_window_0 (Lisp_Object);
static Lisp_Object redisplay_window_1 (Lisp_Object);
int
window_text_bottom_y (struct window *w)
{
- int height = WINDOW_TOTAL_HEIGHT (w);
+ int height = WINDOW_PIXEL_HEIGHT (w);
+
+ height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
if (WINDOW_WANTS_MODELINE_P (w))
height -= CURRENT_MODE_LINE_HEIGHT (w);
+
return height;
}
int
window_box_width (struct window *w, enum glyph_row_area area)
{
- int cols = w->total_cols;
- int pixels = 0;
+ int pixels = w->pixel_width;
if (!w->pseudo_window_p)
{
- cols -= WINDOW_SCROLL_BAR_COLS (w);
+ pixels -= WINDOW_SCROLL_BAR_AREA_WIDTH (w);
+ pixels -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
if (area == TEXT_AREA)
- {
- cols -= max (0, w->left_margin_cols);
- cols -= max (0, w->right_margin_cols);
- pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
- }
+ pixels -= (WINDOW_MARGINS_WIDTH (w)
+ + WINDOW_FRINGES_WIDTH (w));
else if (area == LEFT_MARGIN_AREA)
- {
- cols = max (0, w->left_margin_cols);
- pixels = 0;
- }
+ pixels = WINDOW_LEFT_MARGIN_WIDTH (w);
else if (area == RIGHT_MARGIN_AREA)
- {
- cols = max (0, w->right_margin_cols);
- pixels = 0;
- }
+ pixels = WINDOW_RIGHT_MARGIN_WIDTH (w);
}
- return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
+ return pixels;
}
window_box_height (struct window *w)
{
struct frame *f = XFRAME (w->frame);
- int height = WINDOW_TOTAL_HEIGHT (w);
+ int height = WINDOW_PIXEL_HEIGHT (w);
eassert (height >= 0);
+ height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
+
/* Note: the code below that determines the mode-line/header-line
height is essentially the same as that contained in the macro
CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
if (top_y < window_top_y)
visible_p = bottom_y > window_top_y;
else if (top_y < it.last_visible_y)
- visible_p = 1;
+ visible_p = true;
if (bottom_y >= it.last_visible_y
&& it.bidi_p && it.bidi_it.scan_dir == -1
&& IT_CHARPOS (it) < charpos)
if (charpos < IT_CHARPOS (it)
|| (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
{
- visible_p = 1;
+ visible_p = true;
RESTORE_IT (&it2, &it2, it2data);
move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
*x = it2.current_x;
FRAME_COLUMN_WIDTH (f) - 1,
FRAME_LINE_HEIGHT (f) - 1);
+ /* PXW: Should we clip pixelized before converting to
+ columns/lines ? */
if (!noclip)
{
if (pix_x < 0)
{
/* Draw full-width. X coordinates are relative to S->w->left_col. */
r.x = WINDOW_LEFT_EDGE_X (s->w);
- r.width = WINDOW_TOTAL_WIDTH (s->w);
+ if (s->row->mode_line_p)
+ r.width = WINDOW_PIXEL_WIDTH (s->w) - WINDOW_RIGHT_DIVIDER_WIDTH (s->w);
+ else
+ r.width = WINDOW_PIXEL_WIDTH (s->w);
/* Unless displaying a mode or menu bar line, which are always
fully visible, clip to the visible part of the row. */
/* Try to determine frame pixel position and size of the glyph under
frame pixel coordinates X/Y on frame F. */
- if (!f->glyphs_initialized_p
- || (window = window_from_coordinates (f, gx, gy, &part, 0),
- NILP (window)))
+ if (window_resize_pixelwise)
+ {
+ width = height = 1;
+ goto virtual_glyph;
+ }
+ else if (!f->glyphs_initialized_p
+ || (window = window_from_coordinates (f, gx, gy, &part, 0),
+ NILP (window)))
{
width = FRAME_SMALLEST_CHAR_WIDTH (f);
height = FRAME_SMALLEST_FONT_HEIGHT (f);
goto store_rect;
}
+ pixelwise:
gx += WINDOW_LEFT_EDGE_X (w);
gy += WINDOW_TOP_EDGE_Y (w);
&& ((!NILP (Vtruncate_partial_width_windows)
&& !INTEGERP (Vtruncate_partial_width_windows))
|| (INTEGERP (Vtruncate_partial_width_windows)
+ /* PXW: Shall we do something about this ? */
&& (WINDOW_TOTAL_COLS (it->w)
< XINT (Vtruncate_partial_width_windows))))))
it->line_wrap = TRUNCATE;
{
/* Mode lines, menu bar in terminal frames. */
it->first_visible_x = 0;
- it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
+ it->last_visible_x = WINDOW_PIXEL_WIDTH (w);
}
else
{
- it->first_visible_x =
- window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
+ it->first_visible_x
+ = window_hscroll_limited (it->w, it->f) * FRAME_COLUMN_WIDTH (it->f);
it->last_visible_x = (it->first_visible_x
+ window_box_width (w, TEXT_AREA));
with a left box line. */
face = FACE_FROM_ID (it->f, remapped_base_face_id);
if (face->box != FACE_NO_BOX)
- it->start_of_box_run_p = 1;
+ it->start_of_box_run_p = true;
}
/* If a buffer position was specified, set the iterator there,
pop_it (it);
else
{
- it->ignore_overlay_strings_at_pos_p = 1;
+ it->ignore_overlay_strings_at_pos_p = true;
it->string_from_display_prop_p = 0;
it->from_disp_prop_p = 0;
handle_overlay_change_p = 0;
prop = Fget_text_property (end_charpos, Qinvisible, it->string);
invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
if (invis_p == 2)
- display_ellipsis_p = 1;
+ display_ellipsis_p = true;
}
}
while (invis_p && endpos < len);
if (display_ellipsis_p)
- it->ellipsis_p = 1;
+ it->ellipsis_p = true;
if (endpos < len)
{
tem = next_stop;
/* If there are adjacent invisible texts, don't lose the
- second one's ellipsis. */
+ second one's ellipsis. */
if (invis_p == 2)
- display_ellipsis_p = 1;
+ display_ellipsis_p = true;
}
while (invis_p);
if (it->bidi_p)
{
ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
- int on_newline =
- bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
- int after_newline =
- newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
+ int on_newline
+ = bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
+ int after_newline
+ = newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
/* If the invisible text ends on a newline or on a
character after a newline, we can avoid the costly,
it->position.charpos = newpos - 1;
it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
}
- it->ellipsis_p = 1;
+ it->ellipsis_p = true;
/* Let the ellipsis display before
considering any properties of the following char.
Fixes jasonr@gnu.org 01 Oct 07 bug. */
it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
it->method = GET_FROM_DISPLAY_VECTOR;
- it->ellipsis_p = 1;
+ it->ellipsis_p = true;
}
it->method = GET_FROM_IMAGE;
it->from_overlay = Qnil;
it->face_id = face_id;
- it->from_disp_prop_p = 1;
+ it->from_disp_prop_p = true;
/* Say that we haven't consumed the characters with
`display' property yet. The call to pop_it in
when we are finished with the glyph property value. */
push_it (it, position);
it->from_overlay = overlay;
- it->from_disp_prop_p = 1;
+ it->from_disp_prop_p = true;
if (NILP (location))
it->area = TEXT_AREA;
it->stop_charpos = 0;
it->prev_stop = 0;
it->base_level_stop = 0;
- it->string_from_display_prop_p = 1;
+ it->string_from_display_prop_p = true;
/* Say that we haven't consumed the characters with
`display' property yet. The call to pop_it in
set_iterator_to_next will clean this up. */
processed the overlay strings there already, so that
next_element_from_buffer doesn't try it again. */
if (NILP (it->string) && IT_CHARPOS (*it) >= it->end_charpos)
- it->overlay_strings_at_end_processed_p = 1;
+ it->overlay_strings_at_end_processed_p = true;
}
else
{
if (bidi_it_prev)
*bidi_it_prev = bprev;
}
- *skipped_p = newline_found_p = 1;
+ *skipped_p = newline_found_p = true;
}
else
{
if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
{
if (c == 0xA0)
- nonascii_space_p = 1;
+ nonascii_space_p = true;
else if (c == 0xAD || c == 0x2010 || c == 0x2011)
- nonascii_hyphen_p = 1;
+ nonascii_hyphen_p = true;
}
/* Translate control characters into `\003' or `^C' form.
if (it->method == GET_FROM_STRING
&& it->current.overlay_string_index >= 0
&& it->n_overlay_strings > 0)
- it->ignore_overlay_strings_at_pos_p = 1;
+ it->ignore_overlay_strings_at_pos_p = true;
it->len = it->dpvec_char_len;
set_iterator_to_next (it, reseat_p);
}
- /* Maybe recheck faces after display vector */
+ /* Maybe recheck faces after display vector. */
if (recheck_faces)
it->stop_charpos = IT_CHARPOS (*it);
}
else
{
/* Not an overlay string. There could be padding, so test
- against it->end_charpos . */
+ against it->end_charpos. */
if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
goto consider_string_end;
}
static int
next_element_from_c_string (struct it *it)
{
- int success_p = 1;
+ bool success_p = true;
eassert (it->s);
eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
it->method = GET_FROM_BUFFER;
it->object = it->w->contents;
reseat_at_next_visible_line_start (it, 1);
- it->face_before_selective_p = 1;
+ it->face_before_selective_p = true;
}
return GET_NEXT_DISPLAY_ELEMENT (it);
it->prev_stop = it->stop_charpos;
else
it->prev_stop = BEGV;
- it->bidi_p = 1;
+ it->bidi_p = true;
it->current = save_current;
it->position = save_position;
it->stop_charpos = save_stop_pos;
}
while (charpos <= where_we_are);
- it->bidi_p = 1;
+ it->bidi_p = true;
it->current = save_current;
it->position = save_position;
next_stop = it->stop_charpos;
static int
next_element_from_buffer (struct it *it)
{
- int success_p = 1;
+ bool success_p = true;
eassert (IT_CHARPOS (*it) >= BEGV);
eassert (NILP (it->string) && !it->s);
overlay_strings_follow_p = 0;
else
{
- it->overlay_strings_at_end_processed_p = 1;
+ it->overlay_strings_at_end_processed_p = true;
overlay_strings_follow_p = get_overlay_strings (it, 0);
}
If TO_CHARPOS is in invisible text, e.g. a truncated part of a
screen line, this function will set IT to the next position that is
- displayed to the right of TO_CHARPOS on the screen. */
+ displayed to the right of TO_CHARPOS on the screen.
-void
+ Return the maximum pixel length of any line scanned but never more
+ than it.last_visible_x. */
+
+int
move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
{
enum move_it_result skip, skip2 = MOVE_X_REACHED;
int line_height, line_start_x = 0, reached = 0;
+ int max_current_x = 0;
void *backup_data = NULL;
for (;;)
if (to_y >= it->current_y
&& to_y < it->current_y + line_height)
{
+ if (to_y > it->current_y)
+ max_current_x = max (it->current_x, max_current_x);
+
/* When word-wrap is on, TO_X may lie past the end
of a wrapped line. Then it->current is the
character on the next line, so backtrack to the
skip = move_it_in_display_line_to
(it, -1, prev_x, MOVE_TO_X);
}
+
reached = 6;
}
}
if (reached)
- break;
+ {
+ max_current_x = max (it->current_x, max_current_x);
+ break;
+ }
}
else if (BUFFERP (it->object)
&& (it->method == GET_FROM_BUFFER
switch (skip)
{
case MOVE_POS_MATCH_OR_ZV:
+ max_current_x = max (it->current_x, max_current_x);
reached = 8;
goto out;
case MOVE_NEWLINE_OR_CR:
+ max_current_x = max (it->current_x, max_current_x);
set_iterator_to_next (it, 1);
it->continuation_lines_width = 0;
break;
case MOVE_LINE_TRUNCATED:
+ max_current_x = it->last_visible_x;
it->continuation_lines_width = 0;
reseat_at_next_visible_line_start (it, 0);
if ((op & MOVE_TO_POS) != 0
break;
case MOVE_LINE_CONTINUED:
+ max_current_x = it->last_visible_x;
/* For continued lines ending in a tab, some of the glyphs
associated with the tab are displayed on the current
line. Since it->current_x does not include these glyphs,
it->current_y += it->max_ascent + it->max_descent;
++it->vpos;
last_height = it->max_ascent + it->max_descent;
+ last_max_ascent = it->max_ascent;
it->max_ascent = it->max_descent = 0;
}
it->current_y += it->max_ascent + it->max_descent;
++it->vpos;
last_height = it->max_ascent + it->max_descent;
+ last_max_ascent = it->max_ascent;
}
if (backup_data)
bidi_unshelve_cache (backup_data, 1);
TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
+
+ return max_current_x;
}
&& it->dpvec + it->current.dpvec_index != it->dpend);
}
+DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
+ doc: /* Return the size of the text of WINDOW's buffer in pixels.
+WINDOW must be a live window and defaults to the selected one. The
+return value is a cons of the maximum pixel-width of any text line and
+the maximum pixel-height of all text lines.
+
+The optional argument FROM, if non-nil, specifies the first text
+position and defaults to the minimum accessible position of the buffer.
+If FROM is t, use the minimum accessible position that is not a newline
+character. TO, if non-nil, specifies the last text position and
+defaults to the maximum accessible position of the buffer. If TO is t,
+use the maximum accessible position that is not a newline character.
+
+The optional argument X_LIMIT, if non-nil, specifies the maximum text
+width that can be returned. X_LIMIT nil or omitted, means to use the
+pixel-width of WINDOW's body; use this if you do not intend to change
+the width of WINDOW. Use the maximum width WINDOW may assume if you
+intend to change WINDOW's width.
+
+The optional argument Y_LIMIT, if non-nil, specifies the maximum text
+height that can be returned. Text lines whose y-coordinate is beyond
+Y_LIMIT are ignored. Since calculating the text height of a large
+buffer can take some time, it makes sense to specify this argument if
+the size of the buffer is unknown.
+
+Optional argument MODE_AND_HEADER_LINE nil or omitted means do not
+include the height of the mode- or header-line of WINDOW in the return
+value. If it is either the symbol `mode-line' or `header-line', include
+only the height of that line, if present, in the return value. If t,
+include the height of any of these lines in the return value. */)
+ (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit, Lisp_Object y_limit,
+ Lisp_Object mode_and_header_line)
+{
+ struct window *w = decode_live_window (window);
+ Lisp_Object buf, value;
+ struct buffer *b;
+ struct it it;
+ struct buffer *old_buffer = NULL;
+ ptrdiff_t start, end, pos;
+ struct text_pos startp, endp;
+ void *itdata = NULL;
+ int c, max_y = -1, x = 0, y = 0;
+
+ buf = w->contents;
+ CHECK_BUFFER (buf);
+ b = XBUFFER (buf);
+
+ if (b != current_buffer)
+ {
+ old_buffer = current_buffer;
+ set_buffer_internal (b);
+ }
+
+ if (NILP (from))
+ start = BEGV;
+ else if (EQ (from, Qt))
+ {
+ start = pos = BEGV;
+ while ((pos++ < ZV) && (c = FETCH_CHAR (pos))
+ && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
+ start = pos;
+ while ((pos-- > BEGV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
+ start = pos;
+ }
+ else
+ {
+ CHECK_NUMBER_COERCE_MARKER (from);
+ start = min (max (XINT (from), BEGV), ZV);
+ }
+
+ if (NILP (to))
+ end = ZV;
+ else if (EQ (to, Qt))
+ {
+ end = pos = ZV;
+ while ((pos-- > BEGV) && (c = FETCH_CHAR (pos))
+ && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
+ end = pos;
+ while ((pos++ < ZV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
+ end = pos;
+ }
+ else
+ {
+ CHECK_NUMBER_COERCE_MARKER (to);
+ end = max (start, min (XINT (to), ZV));
+ }
+
+ if (!NILP (y_limit))
+ {
+ CHECK_NUMBER (y_limit);
+ max_y = XINT (y_limit);
+ }
+
+ itdata = bidi_shelve_cache ();
+ SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start));
+ start_display (&it, w, startp);
+
+ /** move_it_vertically_backward (&it, 0); **/
+ if (NILP (x_limit))
+ x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y);
+ else
+ {
+ CHECK_NUMBER (x_limit);
+ it.last_visible_x = XINT (x_limit);
+ /* Actually, we never want move_it_to stop at to_x. But to make
+ sure that move_it_in_display_line_to always moves far enough,
+ we set it to INT_MAX and specify MOVE_TO_X. */
+ x = move_it_to (&it, end, INT_MAX, max_y, -1,
+ MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
+ }
+
+ if (start == end)
+ y = it.current_y;
+ else
+ {
+ /* Count last line. */
+ last_height = 0;
+ y = line_bottom_y (&it); /* - y; */
+ }
+
+ if (!EQ (mode_and_header_line, Qheader_line)
+ && !EQ (mode_and_header_line, Qt))
+ /* Do not count the header-line which was counted automatically by
+ start_display. */
+ y = y - WINDOW_HEADER_LINE_HEIGHT (w);
+
+ if (EQ (mode_and_header_line, Qmode_line)
+ || EQ (mode_and_header_line, Qt))
+ /* Do count the mode-line which is not included automatically by
+ start_display. */
+ y = y + WINDOW_MODE_LINE_HEIGHT (w);
+
+ bidi_unshelve_cache (itdata, 0);
+
+ if (old_buffer)
+ set_buffer_internal (old_buffer);
+
+ return Fcons (make_number (x), make_number (y));
+}
\f
/***********************************************************************
Messages
struct gcpro gcpro1;
GCPRO1 (m);
- clear_message (1,1);
+ clear_message (true, true);
cancel_echoing ();
/* First flush out any partial line written with print. */
echo_message_buffer = Qnil;
}
else
- clear_message (1, 1);
+ clear_message (true, true);
do_pending_window_change (0);
echo_area_display (1);
else
{
this_one = 0, the_other = 1;
- clear_buffer_p = 1;
+ clear_buffer_p = true;
/* We need a fresh one in case the current echo buffer equals
the one containing the last displayed echo area message. */
= (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
? echo_buffer[the_other]
: echo_buffer[this_one]);
- clear_buffer_p = 1;
+ clear_buffer_p = true;
}
buffer = echo_area_buffer[this_one];
if (!FRAME_MINIBUF_ONLY_P (f))
{
struct it it;
- struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
- int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
- int height;
- EMACS_INT max_height;
+ int total_height = (WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)))
+ + WINDOW_PIXEL_HEIGHT (w));
int unit = FRAME_LINE_HEIGHT (f);
+ int height, max_height;
struct text_pos start;
struct buffer *old_current_buffer = NULL;
/* Compute the max. number of lines specified by the user. */
if (FLOATP (Vmax_mini_window_height))
- max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
+ max_height = XFLOATINT (Vmax_mini_window_height) * total_height;
else if (INTEGERP (Vmax_mini_window_height))
- max_height = XINT (Vmax_mini_window_height);
+ max_height = XINT (Vmax_mini_window_height) * unit;
else
max_height = total_height / 4;
/* Correct that max. height if it's bogus. */
- max_height = clip_to_bounds (1, max_height, total_height);
+ max_height = clip_to_bounds (unit, max_height, total_height);
/* Find out the height of the text in the window. */
if (it.line_wrap == TRUNCATE)
- height = 1;
+ height = unit;
else
{
last_height = 0;
else
height = it.current_y + it.max_ascent + it.max_descent;
height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
- height = (height + unit - 1) / unit;
}
/* Compute a suitable window start. */
{
height = max_height;
init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
- move_it_vertically_backward (&it, (height - 1) * unit);
+ move_it_vertically_backward (&it, height);
start = it.current.pos;
}
else
{
/* Let it grow only, until we display an empty message, in which
case the window shrinks again. */
- if (height > WINDOW_TOTAL_LINES (w))
+ if (height > WINDOW_PIXEL_HEIGHT (w))
{
- int old_height = WINDOW_TOTAL_LINES (w);
+ int old_height = WINDOW_PIXEL_HEIGHT (w);
FRAME_WINDOWS_FROZEN (f) = 1;
- grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
- window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
+ grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
+ window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
}
- else if (height < WINDOW_TOTAL_LINES (w)
+ else if (height < WINDOW_PIXEL_HEIGHT (w)
&& (exact_p || BEGV == ZV))
{
- int old_height = WINDOW_TOTAL_LINES (w);
+ int old_height = WINDOW_PIXEL_HEIGHT (w);
FRAME_WINDOWS_FROZEN (f) = 0;
- shrink_mini_window (w);
- window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
+ shrink_mini_window (w, 1);
+ window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
}
}
else
{
/* Always resize to exact size needed. */
- if (height > WINDOW_TOTAL_LINES (w))
+ if (height > WINDOW_PIXEL_HEIGHT (w))
{
- int old_height = WINDOW_TOTAL_LINES (w);
+ int old_height = WINDOW_PIXEL_HEIGHT (w);
FRAME_WINDOWS_FROZEN (f) = 1;
- grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
- window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
+ grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
+ window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
}
- else if (height < WINDOW_TOTAL_LINES (w))
+ else if (height < WINDOW_PIXEL_HEIGHT (w))
{
- int old_height = WINDOW_TOTAL_LINES (w);
+ int old_height = WINDOW_PIXEL_HEIGHT (w);
FRAME_WINDOWS_FROZEN (f) = 0;
- shrink_mini_window (w);
+ shrink_mini_window (w, 1);
if (height)
{
FRAME_WINDOWS_FROZEN (f) = 1;
- grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
+ grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), 1);
}
- window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
+ window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
}
}
last displayed. */
void
-clear_message (int current_p, int last_displayed_p)
+clear_message (bool current_p, bool last_displayed_p)
{
if (current_p)
{
echo_area_buffer[0] = Qnil;
- message_cleared_p = 1;
+ message_cleared_p = true;
}
if (last_displayed_p)
{
echo_area_window = mini_window;
window_height_changed_p = display_echo_area (w);
- w->must_be_updated_p = 1;
+ w->must_be_updated_p = true;
/* Update the display, unless called from redisplay_internal.
Also don't update the screen during redisplay itself. The
been called, so that mode lines above the echo area are
garbaged. This looks odd, so we prevent it here. */
if (!display_completed)
- n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
+ n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
if (window_height_changed_p
/* Don't do this if Emacs is shutting down. Redisplay
Menu Bars
***********************************************************************/
+/* Non-zero if we will not redisplay all visible windows. */
+#define REDISPLAY_SOME_P() \
+ ((windows_or_buffers_changed == 0 \
+ || windows_or_buffers_changed == REDISPLAY_SOME) \
+ && (update_mode_lines == 0 \
+ || update_mode_lines == REDISPLAY_SOME))
/* Prepare for redisplay by updating menu-bar item lists when
appropriate. This can call eval. */
prepare_menu_bars (void)
{
bool all_windows = windows_or_buffers_changed || update_mode_lines;
- bool some_windows
- = (windows_or_buffers_changed == 0
- || windows_or_buffers_changed == REDISPLAY_SOME)
- && (update_mode_lines == 0
- || update_mode_lines == REDISPLAY_SOME);
+ bool some_windows = REDISPLAY_SOME_P ();
struct gcpro gcpro1, gcpro2;
Lisp_Object tooltip_frame;
#if defined (USE_GTK) || defined (HAVE_NS)
int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
#else
- int do_update = WINDOWP (f->tool_bar_window)
- && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
+ int do_update = (WINDOWP (f->tool_bar_window)
+ && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0);
#endif
if (do_update)
}
-/* Max tool-bar height. */
+/* Max tool-bar height. Basically, this is what makes all other windows
+ disappear when the frame gets too small. Rethink this! */
#define MAX_FRAME_TOOL_BAR_HEIGHT(f) \
((FRAME_LINE_HEIGHT (f) * FRAME_LINES (f)))
returned in *N_ROWS if non-NULL. */
static int
-tool_bar_lines_needed (struct frame *f, int *n_rows)
+tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
{
struct window *w = XWINDOW (f->tool_bar_window);
struct it it;
- /* tool_bar_lines_needed is called from redisplay_tool_bar after building
+ /* tool_bar_height is called from redisplay_tool_bar after building
the desired matrix, so use (unused) mode-line row as temporary row to
avoid destroying the first tool-bar row. */
struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
F->desired_tool_bar_string in the tool-bar window of frame F. */
init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
it.first_visible_x = 0;
+ /* PXW: Use FRAME_PIXEL_WIDTH (f) here ? */
it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
it.paragraph_embedding = L2R;
if (n_rows)
*n_rows = it.vpos > 0 ? it.vpos : -1;
- return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
+ if (pixelwise)
+ return it.current_y;
+ else
+ return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
}
#endif /* !USE_GTK && !HAVE_NS */
EXFUN (Ftool_bar_lines_needed, 1) ATTRIBUTE_CONST;
#endif
-DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
- 0, 1, 0,
+DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
+ 0, 2, 0,
doc: /* Return the number of lines occupied by the tool bar of FRAME.
-If FRAME is nil or omitted, use the selected frame. */)
- (Lisp_Object frame)
+If FRAME is nil or omitted, use the selected frame. Optional argument
+PIXELWISE non-nil means return the height of the tool bar inpixels. */)
+ (Lisp_Object frame, Lisp_Object pixelwise)
{
- int nlines = 0;
-#if ! defined (USE_GTK) && ! defined (HAVE_NS)
struct frame *f = decode_any_frame (frame);
- struct window *w;
+ int height = 0;
+#if ! defined (USE_GTK) && ! defined (HAVE_NS)
if (WINDOWP (f->tool_bar_window)
- && (w = XWINDOW (f->tool_bar_window),
- WINDOW_TOTAL_LINES (w) > 0))
+ && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0)
{
update_tool_bar (f, 1);
if (f->n_tool_bar_items)
{
build_desired_tool_bar_string (f);
- nlines = tool_bar_lines_needed (f, NULL);
+ height = tool_bar_height (f, NULL, NILP (pixelwise) ? 0 : 1);
}
}
#endif
- return make_number (nlines);
+
+ return make_number (height);
}
can turn off tool-bars by specifying tool-bar-lines zero. */
if (!WINDOWP (f->tool_bar_window)
|| (w = XWINDOW (f->tool_bar_window),
- WINDOW_TOTAL_LINES (w) == 0))
+ WINDOW_PIXEL_HEIGHT (w) == 0))
return 0;
/* Set up an iterator for the tool-bar window. */
init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
it.first_visible_x = 0;
- it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
+ it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
row = it.glyph_row;
/* Build a string that represents the contents of the tool-bar. */
if (f->n_tool_bar_rows == 0)
{
- int nlines;
+ int new_height = tool_bar_height (f, &f->n_tool_bar_rows, 1);
- if ((nlines = tool_bar_lines_needed (f, &f->n_tool_bar_rows),
- nlines != WINDOW_TOTAL_LINES (w)))
+ if (new_height != WINDOW_PIXEL_HEIGHT (w))
{
Lisp_Object frame;
- int old_height = WINDOW_TOTAL_LINES (w);
+ int new_lines = ((new_height + FRAME_LINE_HEIGHT (f) - 1)
+ / FRAME_LINE_HEIGHT (f));
XSETFRAME (frame, f);
Fmodify_frame_parameters (frame,
list1 (Fcons (Qtool_bar_lines,
- make_number (nlines))));
- if (WINDOW_TOTAL_LINES (w) != old_height)
- {
- clear_glyph_matrix (w->desired_matrix);
- f->fonts_changed = 1;
- return 1;
- }
+ make_number (new_lines))));
+ /* Always do that now. */
+ clear_glyph_matrix (w->desired_matrix);
+ f->fonts_changed = 1;
+ return 1;
}
}
if (!NILP (Vauto_resize_tool_bars))
{
+ /* Do we really allow the toolbar to occupy the whole frame? */
int max_tool_bar_height = MAX_FRAME_TOOL_BAR_HEIGHT (f);
int change_height_p = 0;
if (change_height_p)
{
Lisp_Object frame;
- int old_height = WINDOW_TOTAL_LINES (w);
int nrows;
- int nlines = tool_bar_lines_needed (f, &nrows);
+ int new_height = tool_bar_height (f, &nrows, 1);
change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
&& !f->minimize_tool_bar_window_p)
- ? (nlines > old_height)
- : (nlines != old_height));
+ ? (new_height > WINDOW_PIXEL_HEIGHT (w))
+ : (new_height != WINDOW_PIXEL_HEIGHT (w)));
f->minimize_tool_bar_window_p = 0;
if (change_height_p)
{
+ int new_lines = ((new_height + FRAME_LINE_HEIGHT (f) - 1)
+ / FRAME_LINE_HEIGHT (f));
+
XSETFRAME (frame, f);
Fmodify_frame_parameters (frame,
list1 (Fcons (Qtool_bar_lines,
- make_number (nlines))));
- if (WINDOW_TOTAL_LINES (w) != old_height)
- {
- clear_glyph_matrix (w->desired_matrix);
- f->n_tool_bar_rows = nrows;
- f->fonts_changed = 1;
- return 1;
- }
+ make_number (new_lines))));
+ /* Always do that now. */
+ clear_glyph_matrix (w->desired_matrix);
+ f->n_tool_bar_rows = nrows;
+ f->fonts_changed = 1;
+ return 1;
}
}
}
/* For left-to-right rows, hscroll when cursor is either
(i) inside the right hscroll margin, or (ii) if it is
inside the left margin and the window is already
- hscrolled. */
+ hscrolled. */
&& ((!row_r2l_p
&& ((w->hscroll
&& w->cursor.x <= h_margin)
&& ((cursor_row->enabled_p
/* FIXME: It is confusing to set the
truncated_on_right_p flag when R2L rows
- are actually truncated on the left. */
+ are actually truncated on the left. */
&& cursor_row->truncated_on_right_p
&& w->cursor.x <= h_margin)
|| (w->hscroll
}
}
-void propagate_buffer_redisplay (void)
+static void
+propagate_buffer_redisplay (void)
{ /* Resetting b->text->redisplay is problematic!
We can't just reset it in the case that some window that displays
it has not been redisplayed; and such a window can stay
PT == w->last_point
/* Make sure the cursor was last displayed
in this window. Otherwise we have to reposition it. */
+
+ /* PXW: Must be pixelized, probably. */
&& 0 <= w->cursor.vpos
&& w->cursor.vpos < WINDOW_TOTAL_LINES (w))
{
{
bool gcscrollbars
/* Only GC scollbars when we redisplay the whole frame. */
- = f->redisplay || windows_or_buffers_changed != REDISPLAY_SOME;
+ = f->redisplay || !REDISPLAY_SOME_P ();
/* Mark all the scroll bars to be removed; we'll redeem
the ones we want when we redisplay their windows. */
if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
redisplay_windows (FRAME_ROOT_WINDOW (f));
+ /* Remember that the invisible frames need to be redisplayed next
+ time they're visible. */
+ else if (!REDISPLAY_SOME_P ())
+ f->redisplay = true;
/* The X error handler may have deleted that frame. */
if (!FRAME_LIVE_P (f))
/* Prevent various kinds of signals during display
update. stdio is not robust about handling
- signals, which can cause an apparent I/O
- error. */
+ signals, which can cause an apparent I/O error. */
if (interrupt_input)
unrequest_sigio ();
STOP_POLLING;
- /* Mark windows on frame F to update. If we decide to
- update all frames but windows_or_buffers_changed is
- zero, we assume that only the windows that shows
- current buffer should be really updated. */
- set_window_update_flags
- (XWINDOW (f->root_window),
- (windows_or_buffers_changed ? NULL : current_buffer), 1);
pending |= update_frame (f, 0, 0);
f->cursor_type_changed = 0;
f->updated_p = 1;
if (hscroll_windows (selected_window))
goto retry;
- XWINDOW (selected_window)->must_be_updated_p = 1;
+ XWINDOW (selected_window)->must_be_updated_p = true;
pending = update_frame (sf, 0, 0);
sf->cursor_type_changed = 0;
}
if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
{
- XWINDOW (mini_window)->must_be_updated_p = 1;
+ XWINDOW (mini_window)->must_be_updated_p = true;
pending |= update_frame (mini_frame, 0, 0);
mini_frame->cursor_type_changed = 0;
if (!pending && hscroll_windows (mini_window))
redisplay_window_0 (Lisp_Object window)
{
if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
- redisplay_window (window, 0);
+ redisplay_window (window, false);
return Qnil;
}
redisplay_window_1 (Lisp_Object window)
{
if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
- redisplay_window (window, 1);
+ redisplay_window (window, true);
return Qnil;
}
\f
/* If the line start is "too far" away from the window start,
say it takes too much time to compute a new window start. */
if (CHARPOS (start_pos) - IT_CHARPOS (it)
+ /* PXW: Do we need upper bounds here ? */
< WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
{
int min_distance, distance;
changed on window's frame. In that case, redisplay_internal will retry. */
static void
-redisplay_window (Lisp_Object window, int just_this_one_p)
+redisplay_window (Lisp_Object window, bool just_this_one_p)
{
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
int tem;
struct it it;
/* Record it now because it's overwritten. */
- int current_matrix_up_to_date_p = 0;
- int used_current_matrix_p = 0;
+ bool current_matrix_up_to_date_p = false;
+ bool used_current_matrix_p = false;
/* This is less strict than current_matrix_up_to_date_p.
It indicates that the buffer contents and narrowing are unchanged. */
- int buffer_unchanged_p = 0;
+ bool buffer_unchanged_p = false;
int temp_scroll_step = 0;
ptrdiff_t count = SPECPDL_INDEX ();
int rc;
#endif
if (!just_this_one_p
- && (update_mode_lines == REDISPLAY_SOME
- || update_mode_lines == 0)
- && (windows_or_buffers_changed == REDISPLAY_SOME
- || windows_or_buffers_changed == 0)
+ && REDISPLAY_SOME_P ()
&& !w->redisplay
&& !f->redisplay
&& !buffer->text->redisplay)
|| buffer->clip_changed
|| buffer->prevent_redisplay_optimizations_p);
+ if (!just_this_one_p)
+ /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
+ cleverly elsewhere. */
+ w->must_be_updated_p = true;
+
if (MINI_WINDOW_P (w))
{
if (w == XWINDOW (echo_area_window)
if (XMARKER (w->start)->buffer == current_buffer)
compute_window_start_on_continuation_line (w);
- w->window_end_valid = 0;
+ w->window_end_valid = false;
/* If so, we also can't rely on current matrix
and should not fool try_cursor_movement below. */
- current_matrix_up_to_date_p = 0;
+ current_matrix_up_to_date_p = false;
}
/* Some sanity checks. */
SET_TEXT_POS_FROM_MARKER (startp, w->start);
w->start_at_line_beg = (CHARPOS (startp) == BEGV
- || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
+ || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
/* Display the mode line, if we must. */
if ((update_mode_line
&& (WINDOW_WANTS_MODELINE_P (w)
|| WINDOW_WANTS_HEADER_LINE_P (w)))
{
+
display_mode_lines (w);
/* If mode line height has changed, arrange for a thorough
redisplay_tool_bar (f);
#else
if (WINDOWP (f->tool_bar_window)
- && (FRAME_TOOL_BAR_LINES (f) > 0
+ && (FRAME_TOOL_BAR_HEIGHT (f) > 0
|| !NILP (Vauto_resize_tool_bars))
&& redisplay_tool_bar (f))
ignore_mouse_drag_p = 1;
update_begin (f);
block_input ();
if (draw_window_fringes (w, 1))
- x_draw_vertical_border (w);
+ {
+ if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+ x_draw_right_divider (w);
+ else
+ x_draw_vertical_border (w);
+ }
unblock_input ();
update_end (f);
}
+
+ if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
+ x_draw_bottom_divider (w);
#endif /* HAVE_WINDOW_SYSTEM */
/* We go to this label, with fonts_changed set, if it is
set_buffer_internal_1 (old);
/* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
- shorter. This can be caused by log truncation in *Messages*. */
+ shorter. This can be caused by log truncation in *Messages*. */
if (CHARPOS (lpoint) <= ZV)
TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
eassert (!FRAME_WINDOW_P (f));
init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
it.first_visible_x = 0;
+ /* PXW: Use FRAME_PIXEL_WIDTH (f) here ? */
it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
#elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
if (FRAME_WINDOW_P (f))
init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
MENU_FACE_ID);
it.first_visible_x = 0;
+ /* PXW: Use FRAME_PIXEL_WIDTH (f) here ? */
it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
}
else
the number of windows whose mode lines were redisplayed. */
static int
-redisplay_mode_lines (Lisp_Object window, int force)
+redisplay_mode_lines (Lisp_Object window, bool force)
{
int nwindows = 0;
/* Display mode lines. */
clear_glyph_matrix (w->desired_matrix);
if (display_mode_lines (w))
- {
- ++nwindows;
- w->must_be_updated_p = 1;
- }
+ ++nwindows;
/* Restore old settings. */
set_buffer_internal_1 (old);
XFRAME (new_frame)->selected_window = old_frame_selected_window;
selected_frame = old_selected_frame;
selected_window = old_selected_window;
+ if (n > 0)
+ w->must_be_updated_p = true;
return n;
}
/* X is relative to the left edge of W, without scroll bars
or fringes. */
area_left = WINDOW_LEFT_EDGE_X (w);
- last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
+ last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
+ - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
}
else
{
f = XFRAME (w->frame);
if (updated_row->full_width_p)
- max_x = WINDOW_TOTAL_WIDTH (w);
+ max_x = (WINDOW_PIXEL_WIDTH (w)
+ - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
else
max_x = window_box_width (w, updated_area);
max_y = window_text_bottom_y (w);
cleared = 1;
}
- reset_mouse_highlight (hlinfo);
+ hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
+ hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
+ hlinfo->mouse_face_window = Qnil;
+ hlinfo->mouse_face_overlay = Qnil;
return cleared;
}
cursor = FRAME_X_OUTPUT (f)->text_cursor;
else if (EQ (pointer, intern ("hdrag")))
cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
+ else if (EQ (pointer, intern ("nhdrag")))
+ cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
#ifdef HAVE_X_WINDOWS
else if (EQ (pointer, intern ("vdrag")))
cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
help_echo_string = build_string ("drag-mouse-1: resize");
}
+ else if (part == ON_RIGHT_DIVIDER)
+ {
+ cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
+ help_echo_string = build_string ("drag-mouse-1: resize");
+ }
+ else if (part == ON_BOTTOM_DIVIDER)
+ {
+ cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
+ help_echo_string = build_string ("drag-mouse-1: resize");
+ }
else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
|| part == ON_SCROLL_BAR)
cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
do it for frames with vertical scroll bars because either the
right scroll bar of a window, or the left scroll bar of its
neighbor will suffice as a border. */
- if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
+ if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
return;
/* Note: It is necessary to redraw both the left and the right
FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
}
+
if (!WINDOW_LEFTMOST_P (w)
&& !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
{
}
+/* Draw window dividers for window W. */
+
+void
+x_draw_right_divider (struct window *w)
+{
+ struct frame *f = WINDOW_XFRAME (w);
+
+ if (w->mini || w->pseudo_window_p)
+ return;
+ else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+ {
+ int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
+ int x1 = WINDOW_RIGHT_EDGE_X (w);
+ int y0 = WINDOW_TOP_EDGE_Y (w);
+ int y1 = WINDOW_BOTTOM_EDGE_Y (w);
+
+ FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
+ }
+}
+
+void
+x_draw_bottom_divider (struct window *w)
+{
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
+
+ if (w->mini || w->pseudo_window_p)
+ return;
+ else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
+ {
+ int x0 = WINDOW_LEFT_EDGE_X (w);
+ int x1 = WINDOW_RIGHT_EDGE_X (w);
+ int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
+ int y1 = WINDOW_BOTTOM_EDGE_Y (w);
+
+ FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
+ }
+}
+
/* Redraw the part of window W intersection rectangle FR. Pixel
coordinates in FR are frame-relative. Call this function with
input blocked. Value is non-zero if the exposure overwrites
/* Frame-relative pixel rectangle of W. */
wr.x = WINDOW_LEFT_EDGE_X (w);
wr.y = WINDOW_TOP_EDGE_Y (w);
- wr.width = WINDOW_TOTAL_WIDTH (w);
- wr.height = WINDOW_TOTAL_HEIGHT (w);
+ wr.width = WINDOW_PIXEL_WIDTH (w);
+ wr.height = WINDOW_PIXEL_HEIGHT (w);
if (x_intersect_rectangles (fr, &wr, &r))
{
fr);
/* Draw border between windows. */
- x_draw_vertical_border (w);
+ if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
+ x_draw_right_divider (w);
+ else
+ x_draw_vertical_border (w);
+
+ if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
+ x_draw_bottom_divider (w);
/* Turn the cursor on again. */
if (cursor_cleared_p
defsubr (&Strace_to_stderr);
#endif
#ifdef HAVE_WINDOW_SYSTEM
- defsubr (&Stool_bar_lines_needed);
+ defsubr (&Stool_bar_height);
defsubr (&Slookup_image_map);
#endif
defsubr (&Sline_pixel_height);
defsubr (&Sformat_mode_line);
defsubr (&Sinvisible_p);
defsubr (&Scurrent_bidi_paragraph_direction);
+ defsubr (&Swindow_text_pixel_size);
defsubr (&Smove_point_visually);
DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
echo_area_window = minibuf_window;
r->top_line = FRAME_TOP_MARGIN (f);
- r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
+ r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
r->total_cols = FRAME_COLS (f);
+ r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
+ r->total_lines = FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
+ r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
m->top_line = FRAME_LINES (f) - 1;
- m->total_lines = 1;
+ m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
m->total_cols = FRAME_COLS (f);
+ m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
+ m->total_lines = 1;
+ m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
scratch_glyph_row.glyphs[TEXT_AREA + 1]