#include "font.h"
#include "fontset.h"
#include "blockinput.h"
-
-#ifdef HAVE_X_WINDOWS
-#include "xterm.h"
-#endif
-#ifdef HAVE_NTGUI
-#include "w32term.h"
-#endif
-#ifdef HAVE_NS
-#include "nsterm.h"
-#endif
-#ifdef USE_GTK
-#include "gtkutil.h"
-#endif
+#ifdef HAVE_WINDOW_SYSTEM
+#include TERM_HEADER
+#endif /* HAVE_WINDOW_SYSTEM */
#ifndef FRAME_X_OUTPUT
#define FRAME_X_OUTPUT(f) ((f)->output_data.x)
int windows_or_buffers_changed;
-/* Nonzero means a frame's cursor type has been changed. */
-
-int cursor_type_changed;
-
/* Nonzero after display_mode_line if %l was used and it displayed a
line number. */
int help_echo_showing_p;
-/* If >= 0, computed, exact values of mode-line and header-line height
- to use in the macros CURRENT_MODE_LINE_HEIGHT and
- CURRENT_HEADER_LINE_HEIGHT. */
-
-int current_mode_line_height, current_header_line_height;
-
/* The maximum distance to look ahead for text properties. Values
that are too small let us call compute_char_face and similar
functions too often which is expensive. Values that are too large
/* Platform-independent portion of hourglass implementation. */
+#ifdef HAVE_WINDOW_SYSTEM
+
/* Non-zero means an hourglass cursor is currently shown. */
int hourglass_shown_p;
an hourglass cursor on all frames. */
struct atimer *hourglass_atimer;
+#endif /* HAVE_WINDOW_SYSTEM */
+
/* Name of the face used to display glyphless characters. */
Lisp_Object Qglyphless_char;
/* Method symbols for Vglyphless_char_display. */
static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
-/* Default pixel width of `thin-space' display method. */
-#define THIN_SPACE_WIDTH 1
-
/* Default number of seconds to wait before displaying an hourglass
cursor. */
#define DEFAULT_HOURGLASS_DELAY 1
-\f
+#ifdef HAVE_WINDOW_SYSTEM
+
+/* Default pixel width of `thin-space' display method. */
+#define THIN_SPACE_WIDTH 1
+
+#endif /* HAVE_WINDOW_SYSTEM */
+
/* Function prototypes. */
static void setup_for_ellipsis (struct it *, int);
return height;
}
-/* Return the pixel width of display area AREA of window W. AREA < 0
- means return the total width of W, not including fringes to
- the left and right of the window. */
+/* Return the pixel width of display area AREA of window W.
+ ANY_AREA means return the total width of W, not including
+ fringes to the left and right of the window. */
int
-window_box_width (struct window *w, int area)
+window_box_width (struct window *w, enum glyph_row_area area)
{
int cols = w->total_cols;
int pixels = 0;
if (area == TEXT_AREA)
{
- if (INTEGERP (w->left_margin_cols))
- cols -= XFASTINT (w->left_margin_cols);
- if (INTEGERP (w->right_margin_cols))
- cols -= XFASTINT (w->right_margin_cols);
+ cols -= max (0, w->left_margin_cols);
+ cols -= max (0, w->right_margin_cols);
pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
}
else if (area == LEFT_MARGIN_AREA)
{
- cols = (INTEGERP (w->left_margin_cols)
- ? XFASTINT (w->left_margin_cols) : 0);
+ cols = max (0, w->left_margin_cols);
pixels = 0;
}
else if (area == RIGHT_MARGIN_AREA)
{
- cols = (INTEGERP (w->right_margin_cols)
- ? XFASTINT (w->right_margin_cols) : 0);
+ cols = max (0, w->right_margin_cols);
pixels = 0;
}
}
}
/* Return the window-relative coordinate of the left edge of display
- area AREA of window W. AREA < 0 means return the left edge of the
+ area AREA of window W. ANY_AREA means return the left edge of the
whole window, to the right of the left fringe of W. */
int
-window_box_left_offset (struct window *w, int area)
+window_box_left_offset (struct window *w, enum glyph_row_area area)
{
int x;
/* Return the window-relative coordinate of the right edge of display
- area AREA of window W. AREA < 0 means return the right edge of the
+ area AREA of window W. ANY_AREA means return the right edge of the
whole window, to the left of the right fringe of W. */
int
-window_box_right_offset (struct window *w, int area)
+window_box_right_offset (struct window *w, enum glyph_row_area area)
{
return window_box_left_offset (w, area) + window_box_width (w, area);
}
/* Return the frame-relative coordinate of the left edge of display
- area AREA of window W. AREA < 0 means return the left edge of the
+ area AREA of window W. ANY_AREA means return the left edge of the
whole window, to the right of the left fringe of W. */
int
-window_box_left (struct window *w, int area)
+window_box_left (struct window *w, enum glyph_row_area area)
{
struct frame *f = XFRAME (w->frame);
int x;
/* Return the frame-relative coordinate of the right edge of display
- area AREA of window W. AREA < 0 means return the right edge of the
+ area AREA of window W. ANY_AREA means return the right edge of the
whole window, to the left of the right fringe of W. */
int
-window_box_right (struct window *w, int area)
+window_box_right (struct window *w, enum glyph_row_area area)
{
return window_box_left (w, area) + window_box_width (w, area);
}
/* Get the bounding box of the display area AREA of window W, without
- mode lines, in frame-relative coordinates. AREA < 0 means the
+ mode lines, in frame-relative coordinates. ANY_AREA means the
whole window, not including the left and right fringes of
the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
coordinates of the upper-left corner of the box. Return in
*BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
void
-window_box (struct window *w, int area, int *box_x, int *box_y,
- int *box_width, int *box_height)
+window_box (struct window *w, enum glyph_row_area area, int *box_x,
+ int *box_y, int *box_width, int *box_height)
{
if (box_width)
*box_width = window_box_width (w, area);
}
}
+#ifdef HAVE_WINDOW_SYSTEM
/* Get the bounding box of the display area AREA of window W, without
- mode lines. AREA < 0 means the whole window, not including the
- left and right fringe of the window. Return in *TOP_LEFT_X
+ mode lines and both fringes of the window. Return in *TOP_LEFT_X
and TOP_LEFT_Y the frame-relative pixel coordinates of the
upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
*BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
box. */
static void
-window_box_edges (struct window *w, int area, int *top_left_x, int *top_left_y,
- int *bottom_right_x, int *bottom_right_y)
+window_box_edges (struct window *w, int *top_left_x, int *top_left_y,
+ int *bottom_right_x, int *bottom_right_y)
{
- window_box (w, area, top_left_x, top_left_y, bottom_right_x,
- bottom_right_y);
+ window_box (w, ANY_AREA, top_left_x, top_left_y,
+ bottom_right_x, bottom_right_y);
*bottom_right_x += *top_left_x;
*bottom_right_y += *top_left_y;
}
+#endif /* HAVE_WINDOW_SYSTEM */
-\f
/***********************************************************************
Utilities
***********************************************************************/
/* Compute exact mode line heights. */
if (WINDOW_WANTS_MODELINE_P (w))
- current_mode_line_height
+ w->mode_line_height
= display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
BVAR (current_buffer, mode_line_format));
if (WINDOW_WANTS_HEADER_LINE_P (w))
- current_header_line_height
+ w->header_line_height
= display_mode_line (w, HEADER_LINE_FACE_ID,
BVAR (current_buffer, header_line_format));
if (old_buffer)
set_buffer_internal_1 (old_buffer);
- current_header_line_height = current_mode_line_height = -1;
-
if (visible_p && w->hscroll > 0)
*x -=
window_hscroll_limited (w, WINDOW_XFRAME (w))
#endif /* HAVE_WINDOW_SYSTEM */
-\f
+static void
+adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
+{
+ eassert (w);
+ w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
+ w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
+ w->window_end_vpos
+ = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
+}
+
/***********************************************************************
Lisp form evaluation
***********************************************************************/
if (!MINI_WINDOW_P (w) && w->window_end_valid)
{
struct glyph_row *row;
- eassert ((row = MATRIX_ROW (w->current_matrix,
- XFASTINT (w->window_end_vpos)),
+ eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
!row->enabled_p
|| MATRIX_ROW_DISPLAYS_TEXT_P (row)
|| MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
/* For strings from a `display' property, use the face at
IT's current buffer position as the base face to merge
with, so that overlay strings appear in the same face as
- surrounding text, unless they specify their own
- faces. */
+ surrounding text, unless they specify their own faces.
+ For strings from wrap-prefix and line-prefix properties,
+ use the default face, possibly remapped via
+ Vface_remapping_alist. */
base_face_id = it->string_from_prefix_prop_p
- ? DEFAULT_FACE_ID
+ ? (!NILP (Vface_remapping_alist)
+ ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
+ : DEFAULT_FACE_ID)
: underlying_face_id (it);
}
return glyphless_method;
}
-/* Load IT's display element fields with information about the next
- display element from the current position of IT. Value is zero if
- end of buffer (or C string) is reached. */
+/* Merge escape glyph face and cache the result. */
static struct frame *last_escape_glyph_frame = NULL;
static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
static int last_escape_glyph_merged_face_id = 0;
-struct frame *last_glyphless_glyph_frame = NULL;
-int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
-int last_glyphless_glyph_merged_face_id = 0;
+static int
+merge_escape_glyph_face (struct it *it)
+{
+ int face_id;
+
+ if (it->f == last_escape_glyph_frame
+ && it->face_id == last_escape_glyph_face_id)
+ face_id = last_escape_glyph_merged_face_id;
+ else
+ {
+ /* Merge the `escape-glyph' face into the current face. */
+ face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id);
+ last_escape_glyph_frame = it->f;
+ last_escape_glyph_face_id = it->face_id;
+ last_escape_glyph_merged_face_id = face_id;
+ }
+ return face_id;
+}
+
+/* Likewise for glyphless glyph face. */
+
+static struct frame *last_glyphless_glyph_frame = NULL;
+static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
+static int last_glyphless_glyph_merged_face_id = 0;
+
+int
+merge_glyphless_glyph_face (struct it *it)
+{
+ int face_id;
+
+ if (it->f == last_glyphless_glyph_frame
+ && it->face_id == last_glyphless_glyph_face_id)
+ face_id = last_glyphless_glyph_merged_face_id;
+ else
+ {
+ /* Merge the `glyphless-char' face into the current face. */
+ face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
+ last_glyphless_glyph_frame = it->f;
+ last_glyphless_glyph_face_id = it->face_id;
+ last_glyphless_glyph_merged_face_id = face_id;
+ }
+ return face_id;
+}
+
+/* Load IT's display element fields with information about the next
+ display element from the current position of IT. Value is zero if
+ end of buffer (or C string) is reached. */
static int
get_next_display_element (struct it *it)
g = GLYPH_CODE_CHAR (gc);
lface_id = GLYPH_CODE_FACE (gc);
}
- if (lface_id)
- {
- face_id = merge_faces (it->f, Qt, lface_id, it->face_id);
- }
- else if (it->f == last_escape_glyph_frame
- && it->face_id == last_escape_glyph_face_id)
- {
- face_id = last_escape_glyph_merged_face_id;
- }
- else
- {
- /* Merge the escape-glyph face into the current face. */
- face_id = merge_faces (it->f, Qescape_glyph, 0,
- it->face_id);
- last_escape_glyph_frame = it->f;
- last_escape_glyph_face_id = it->face_id;
- last_escape_glyph_merged_face_id = face_id;
- }
+
+ face_id = (lface_id
+ ? merge_faces (it->f, Qt, lface_id, it->face_id)
+ : merge_escape_glyph_face (it));
XSETINT (it->ctl_chars[0], g);
XSETINT (it->ctl_chars[1], c ^ 0100);
escape_glyph = GLYPH_CODE_CHAR (gc);
lface_id = GLYPH_CODE_FACE (gc);
}
- if (lface_id)
- {
- /* The display table specified a face.
- Merge it into face_id and also into escape_glyph. */
- face_id = merge_faces (it->f, Qt, lface_id,
- it->face_id);
- }
- else if (it->f == last_escape_glyph_frame
- && it->face_id == last_escape_glyph_face_id)
- {
- face_id = last_escape_glyph_merged_face_id;
- }
- else
- {
- /* Merge the escape-glyph face into the current face. */
- face_id = merge_faces (it->f, Qescape_glyph, 0,
- it->face_id);
- last_escape_glyph_frame = it->f;
- last_escape_glyph_face_id = it->face_id;
- last_escape_glyph_merged_face_id = face_id;
- }
+
+ face_id = (lface_id
+ ? merge_faces (it->f, Qt, lface_id, it->face_id)
+ : merge_escape_glyph_face (it));
/* Draw non-ASCII hyphen with just highlighting: */
}
}
}
- else
+ /* next_element_from_display_vector sets this flag according to
+ faces of the display vector glyphs, see there. */
+ else if (it->method != GET_FROM_DISPLAY_VECTOR)
{
int face_id = face_after_it_pos (it);
it->end_of_box_run_p
next_element_from_display_vector (struct it *it)
{
Lisp_Object gc;
+ int prev_face_id = it->face_id;
+ int next_face_id;
/* Precondition. */
eassert (it->dpvec && it->current.dpvec_index >= 0);
if (GLYPH_CODE_P (gc))
{
+ struct face *this_face, *prev_face, *next_face;
+
it->c = GLYPH_CODE_CHAR (gc);
it->len = CHAR_BYTES (it->c);
it->face_id = merge_faces (it->f, Qt, lface_id,
it->saved_face_id);
}
+
+ /* Glyphs in the display vector could have the box face, so we
+ need to set the related flags in the iterator, as
+ appropriate. */
+ this_face = FACE_FROM_ID (it->f, it->face_id);
+ prev_face = FACE_FROM_ID (it->f, prev_face_id);
+
+ /* Is this character the first character of a box-face run? */
+ it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
+ && (!prev_face
+ || prev_face->box == FACE_NO_BOX));
+
+ /* For the last character of the box-face run, we need to look
+ either at the next glyph from the display vector, or at the
+ face we saw before the display vector. */
+ next_face_id = it->saved_face_id;
+ if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
+ {
+ if (it->dpvec_face_id >= 0)
+ next_face_id = it->dpvec_face_id;
+ else
+ {
+ int lface_id =
+ GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
+
+ if (lface_id > 0)
+ next_face_id = merge_faces (it->f, Qt, lface_id,
+ it->saved_face_id);
+ }
+ }
+ next_face = FACE_FROM_ID (it->f, next_face_id);
+ it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
+ && (!next_face
+ || next_face->box == FACE_NO_BOX));
+ it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
}
else
/* Display table entry is invalid. Return a space. */
&& it->current_x == it->last_visible_x - 1
&& it->c != '\n'
&& it->c != '\t'
- && it->vpos < XFASTINT (it->w->window_end_vpos))
+ && it->vpos < it->w->window_end_vpos)
{
it->continuation_lines_width += it->current_x;
it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
return hooks_run;
}
-
-\f
-/***********************************************************************
- Output Cursor
- ***********************************************************************/
-
-#ifdef HAVE_WINDOW_SYSTEM
-
-/* EXPORT:
- Nominal cursor position -- where to draw output.
- HPOS and VPOS are window relative glyph matrix coordinates.
- X and Y are window relative pixel coordinates. */
-
-struct cursor_pos output_cursor;
-
-
-/* EXPORT:
- Set the global variable output_cursor to CURSOR. All cursor
- positions are relative to currently updated window. */
-
-void
-set_output_cursor (struct cursor_pos *cursor)
-{
- output_cursor.hpos = cursor->hpos;
- output_cursor.vpos = cursor->vpos;
- output_cursor.x = cursor->x;
- output_cursor.y = cursor->y;
-}
-
-
-/* EXPORT for RIF:
- Set a nominal cursor position.
-
- HPOS and VPOS are column/row positions in a window glyph matrix.
- X and Y are window text area relative pixel positions.
-
- This is always done during window update, so the position is the
- future output cursor position for currently updated window W.
- NOTE: W is used only to check whether this function is called
- in a consistent manner via the redisplay interface. */
-
-void
-x_cursor_to (struct window *w, int vpos, int hpos, int y, int x)
-{
- eassert (w);
-
- /* Set the output cursor. */
- output_cursor.hpos = hpos;
- output_cursor.vpos = vpos;
- output_cursor.x = x;
- output_cursor.y = y;
-}
-
-#endif /* HAVE_WINDOW_SYSTEM */
-
-\f
/***********************************************************************
Tool-bars
***********************************************************************/
if (WINDOW_TOTAL_LINES (w) != old_height)
{
clear_glyph_matrix (w->desired_matrix);
- fonts_changed_p = 1;
+ f->fonts_changed = 1;
return 1;
}
}
{
clear_glyph_matrix (w->desired_matrix);
f->n_tool_bar_rows = nrows;
- fonts_changed_p = 1;
+ f->fonts_changed = 1;
return 1;
}
}
hlinfo->mouse_face_beg_col = hpos;
hlinfo->mouse_face_beg_row = vpos;
hlinfo->mouse_face_beg_x = x;
- hlinfo->mouse_face_beg_y = row->y;
hlinfo->mouse_face_past_end = 0;
hlinfo->mouse_face_end_col = hpos + 1;
hlinfo->mouse_face_end_row = vpos;
hlinfo->mouse_face_end_x = x + glyph->pixel_width;
- hlinfo->mouse_face_end_y = row->y;
hlinfo->mouse_face_window = window;
hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
last_glyphless_glyph_frame = NULL;
last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
- /* If new fonts have been loaded that make a glyph matrix adjustment
- necessary, do it. */
- if (fonts_changed_p)
- {
- adjust_glyphs (NULL);
- ++windows_or_buffers_changed;
- fonts_changed_p = 0;
- }
-
/* If face_change_count is non-zero, init_iterator will free all
realized faces, which includes the faces referenced from current
matrices. So, we can't reuse current matrices in this case. */
struct frame *f = XFRAME (frame);
if (FRAME_VISIBLE_P (f))
- ++number_of_visible_frames;
+ {
+ ++number_of_visible_frames;
+ /* Adjust matrices for visible frames only. */
+ if (f->fonts_changed)
+ {
+ adjust_frame_glyphs (f);
+ f->fonts_changed = 0;
+ }
+ /* If cursor type has been changed on the frame
+ other than selected, consider all frames. */
+ if (f != sf && f->cursor_type_changed)
+ update_mode_lines++;
+ }
clear_desired_matrices (f);
}
}
consider_all_windows_p = (update_mode_lines
- || buffer_shared_and_changed ()
- || cursor_type_changed);
+ || buffer_shared_and_changed ());
/* If specs for an arrow have changed, do thorough redisplay
to ensure we remove any arrow that should no longer exist. */
if (!display_last_displayed_message_p)
message_cleared_p = 0;
- if (fonts_changed_p)
- goto retry;
- else if (window_height_changed_p)
+ if (window_height_changed_p)
{
consider_all_windows_p = 1;
++update_mode_lines;
&& !current_buffer->prevent_redisplay_optimizations_p
&& FRAME_VISIBLE_P (XFRAME (w->frame))
&& !FRAME_OBSCURED_P (XFRAME (w->frame))
+ && !XFRAME (w->frame)->cursor_type_changed
/* Make sure recorded data applies to current buffer, etc. */
&& this_line_buffer == current_buffer
&& match_p
adjusted. */
if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
{
- if (XFASTINT (w->window_end_vpos) < this_line_vpos)
- wset_window_end_vpos (w, make_number (this_line_vpos));
+ if (w->window_end_vpos < this_line_vpos)
+ w->window_end_vpos = this_line_vpos;
}
- else if (XFASTINT (w->window_end_vpos) == this_line_vpos
+ else if (w->window_end_vpos == this_line_vpos
&& this_line_vpos > 0)
- wset_window_end_vpos (w, make_number (this_line_vpos - 1));
+ w->window_end_vpos = this_line_vpos - 1;
w->window_end_valid = 0;
/* Update hint: No need to try to scroll in update_window. */
&& !EQ (FRAME_TTY (f)->top_frame, frame))
continue;
+ retry_frame:
+
if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
{
/* Mark all the scroll bars to be removed; we'll redeem
if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
- /* If fonts changed, display again. */
- /* ??? rms: I suspect it is a mistake to jump all the way
- back to retry here. It should just retry this frame. */
- if (fonts_changed_p)
- goto retry;
-
if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
{
+ /* If fonts changed on visible frame, display again. */
+ if (f->fonts_changed)
+ {
+ adjust_frame_glyphs (f);
+ f->fonts_changed = 0;
+ goto retry_frame;
+ }
+
/* See if we have to hscroll. */
if (!f->already_hscrolled_p)
{
f->already_hscrolled_p = 1;
if (hscroll_windows (f->root_window))
- goto retry;
+ goto retry_frame;
}
/* Prevent various kinds of signals during display
/* Update the display. */
set_window_update_flags (XWINDOW (f->root_window), 1);
pending |= update_frame (f, 0, 0);
+ f->cursor_type_changed = 0;
f->updated_p = 1;
}
}
update:
/* If fonts changed, display again. */
- if (fonts_changed_p)
+ if (sf->fonts_changed)
goto retry;
/* Prevent various kinds of signals during display update.
XWINDOW (selected_window)->must_be_updated_p = 1;
pending = update_frame (sf, 0, 0);
+ sf->cursor_type_changed = 0;
}
/* We may have called echo_area_display at the top of this
{
XWINDOW (mini_window)->must_be_updated_p = 1;
pending |= update_frame (mini_frame, 0, 0);
+ mini_frame->cursor_type_changed = 0;
if (!pending && hscroll_windows (mini_window))
goto retry;
}
update_mode_lines = 0;
windows_or_buffers_changed = 0;
- cursor_type_changed = 0;
}
/* Start SIGIO interrupts coming again. Having them off during the
w->current_matrix->begv = BUF_BEGV (b);
w->current_matrix->zv = BUF_ZV (b);
- w->last_cursor = w->cursor;
+ w->last_cursor_vpos = w->cursor.vpos;
w->last_cursor_off_p = w->cursor_off_p;
if (w == XWINDOW (selected_window))
{
min_distance = distance;
pos = it.current.pos;
- move_it_by_lines (&it, 1);
+ if (it.line_wrap == WORD_WRAP)
+ {
+ /* Under WORD_WRAP, move_it_by_lines is likely to
+ overshoot and stop not at the first, but the
+ second character from the left margin. So in
+ that case, we need a more tight control on the X
+ coordinate of the iterator than move_it_by_lines
+ promises in its contract. The method is to first
+ go to the last (rightmost) visible character of a
+ line, then move to the leftmost character on the
+ next line in a separate call. */
+ move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
+ MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
+ move_it_to (&it, ZV, 0,
+ it.current_y + it.max_ascent + it.max_descent, -1,
+ MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
+ }
+ else
+ move_it_by_lines (&it, 1);
}
/* Set the window start there. */
if-statement below. Now, this field is converted to
ptrdiff_t, thus zero means invalid position in a buffer. */
eassert (w->last_point > 0);
+ /* Likewise there was a check whether window_end_vpos is nil or larger
+ than the window. Now window_end_vpos is int and so never nil, but
+ let's leave eassert to check whether it fits in the window. */
+ eassert (w->window_end_vpos < w->current_matrix->nrows);
/* Handle case where text has not changed, only point, and it has
not moved off the frame. */
cases. */
&& !update_mode_lines
&& !windows_or_buffers_changed
- && !cursor_type_changed
+ && !f->cursor_type_changed
/* Can't use this case if highlighting a region. When a
region exists, cursor movement has to do more than just
set the cursor. */
since the handling of this_line_start_pos, etc., in redisplay
handles the same cases. */
&& !EQ (window, minibuf_window)
- /* When splitting windows or for new windows, it happens that
- redisplay is called with a nil window_end_vpos or one being
- larger than the window. This should really be fixed in
- window.c. I don't have this on my list, now, so we do
- approximately the same as the old redisplay code. --gerd. */
- && INTEGERP (w->window_end_vpos)
- && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
&& (FRAME_WINDOW_P (f)
|| !overlay_arrow_in_current_buffer_p ()))
{
/* Start with the row the cursor was displayed during the last
not paused redisplay. Give up if that row is not valid. */
- if (w->last_cursor.vpos < 0
- || w->last_cursor.vpos >= w->current_matrix->nrows)
+ if (w->last_cursor_vpos < 0
+ || w->last_cursor_vpos >= w->current_matrix->nrows)
rc = CURSOR_MOVEMENT_MUST_SCROLL;
else
{
- row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
+ row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
if (row->mode_line_p)
++row;
if (!row->enabled_p)
start = marker_position (w->start) - BUF_BEGV (buf);
/* I don't think this is guaranteed to be right. For the
moment, we'll pretend it is. */
- end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
+ end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
if (end < start)
end = start;
/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
selected_window is redisplayed.
- We can return without actually redisplaying the window if
- fonts_changed_p. In that case, redisplay_internal will
- retry. */
+ We can return without actually redisplaying the window if fonts has been
+ changed on window's frame. In that case, redisplay_internal will retry. */
static void
redisplay_window (Lisp_Object window, int just_this_one_p)
&& !current_buffer->clip_changed
&& !window_outdated (w));
- /* When windows_or_buffers_changed is non-zero, we can't rely on
- the window end being valid, so set it to nil there. */
+ /* When windows_or_buffers_changed is non-zero, we can't rely
+ on the window end being valid, so set it to zero there. */
if (windows_or_buffers_changed)
{
/* If window starts on a continuation line, maybe adjust the
compute_window_start_on_continuation_line (w);
w->window_end_valid = 0;
+ /* 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;
}
/* Some sanity checks. */
debug_method_add (w, "try_window_id %d", tem);
#endif
- if (fonts_changed_p)
+ if (f->fonts_changed)
goto need_larger_matrices;
if (tem > 0)
goto done;
IF_DEBUG (debug_method_add (w, "1"));
if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
/* -1 means we need to scroll.
- 0 means we need new matrices, but fonts_changed_p
+ 0 means we need new matrices, but fonts_changed
is set in that case, so we will detect it below. */
goto try_to_scroll;
}
- if (fonts_changed_p)
+ if (f->fonts_changed)
goto need_larger_matrices;
if (w->cursor.vpos >= 0)
/* Redisplay the window. */
if (!current_matrix_up_to_date_p
|| windows_or_buffers_changed
- || cursor_type_changed
+ || f->cursor_type_changed
/* Don't use try_window_reusing_current_matrix in this case
because it can have changed the buffer. */
|| !NILP (Vwindow_scroll_functions)
/* If new fonts have been loaded (due to fontsets), give up. We
have to start a new redisplay since we need to re-adjust glyph
matrices. */
- if (fonts_changed_p)
+ if (f->fonts_changed)
goto need_larger_matrices;
/* If cursor did not appear assume that the middle of the window is
line.) */
if (w->cursor.vpos < 0)
{
- if (w->window_end_valid && PT >= Z - XFASTINT (w->window_end_pos))
+ if (w->window_end_valid && PT >= Z - w->window_end_pos)
{
clear_glyph_matrix (w->desired_matrix);
move_it_by_lines (&it, 1);
if (WINDOW_WANTS_MODELINE_P (w)
&& CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
{
- fonts_changed_p = 1;
+ f->fonts_changed = 1;
+ w->mode_line_height = -1;
MATRIX_MODE_LINE_ROW (w->current_matrix)->height
= DESIRED_MODE_LINE_HEIGHT (w);
}
if (WINDOW_WANTS_HEADER_LINE_P (w)
&& CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
{
- fonts_changed_p = 1;
+ f->fonts_changed = 1;
+ w->header_line_height = -1;
MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
= DESIRED_HEADER_LINE_HEIGHT (w);
}
- if (fonts_changed_p)
+ if (f->fonts_changed)
goto need_larger_matrices;
}
}
#endif /* HAVE_WINDOW_SYSTEM */
- /* We go to this label, with fonts_changed_p set,
- if it is necessary to try again using larger glyph matrices.
+ /* We go to this label, with fonts_changed set, if it is
+ necessary to try again using larger glyph matrices.
We have to redeem the scroll bar even in this case,
because the loop in redisplay_internal expects that. */
need_larger_matrices:
{
if (display_line (&it))
last_text_row = it.glyph_row - 1;
- if (fonts_changed_p && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
+ if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
return 0;
}
}
/* If bottom moved off end of frame, change mode line percentage. */
- if (XFASTINT (w->window_end_pos) <= 0
- && Z != IT_CHARPOS (it))
+ if (w->window_end_pos <= 0 && Z != IT_CHARPOS (it))
w->update_mode_line = 1;
/* Set window_end_pos to the offset of the last character displayed
if (last_text_row)
{
eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
- w->window_end_bytepos
- = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
- wset_window_end_pos
- (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
- wset_window_end_vpos
- (w, make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix)));
+ adjust_window_ends (w, last_text_row, 0);
eassert
(MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
- XFASTINT (w->window_end_vpos))));
+ w->window_end_vpos)));
}
else
{
w->window_end_bytepos = Z_BYTE - ZV_BYTE;
- wset_window_end_pos (w, make_number (Z - ZV));
- wset_window_end_vpos (w, make_number (0));
+ w->window_end_pos = Z - ZV;
+ w->window_end_vpos = 0;
}
/* But that is not valid info until redisplay finishes. */
/* Don't try to reuse the display if windows have been split
or such. */
|| windows_or_buffers_changed
- || cursor_type_changed)
+ || f->cursor_type_changed)
return 0;
/* Can't do this if region may have changed. */
w->cursor.vpos = -1;
last_text_row = last_reused_text_row = NULL;
- while (it.current_y < it.last_visible_y
- && !fonts_changed_p)
+ while (it.current_y < it.last_visible_y && !f->fonts_changed)
{
/* If we have reached into the characters in the START row,
that means the line boundaries have changed. So we
The value of last_text_row is the last displayed line
containing text. */
if (last_reused_text_row)
- {
- w->window_end_bytepos
- = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
- wset_window_end_pos
- (w, make_number (Z
- - MATRIX_ROW_END_CHARPOS (last_reused_text_row)));
- wset_window_end_vpos
- (w, make_number (MATRIX_ROW_VPOS (last_reused_text_row,
- w->current_matrix)));
- }
+ adjust_window_ends (w, last_reused_text_row, 1);
else if (last_text_row)
- {
- w->window_end_bytepos
- = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
- wset_window_end_pos
- (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
- wset_window_end_vpos
- (w, make_number (MATRIX_ROW_VPOS (last_text_row,
- w->desired_matrix)));
- }
+ adjust_window_ends (w, last_text_row, 0);
else
{
/* This window must be completely empty. */
w->window_end_bytepos = Z_BYTE - ZV_BYTE;
- wset_window_end_pos (w, make_number (Z - ZV));
- wset_window_end_vpos (w, make_number (0));
+ w->window_end_pos = Z - ZV;
+ w->window_end_vpos = 0;
}
w->window_end_valid = 0;
if (pt_row == NULL)
w->cursor.vpos = -1;
last_text_row = NULL;
- while (it.current_y < it.last_visible_y && !fonts_changed_p)
+ while (it.current_y < it.last_visible_y && !f->fonts_changed)
if (display_line (&it))
last_text_row = it.glyph_row - 1;
the window end is in reused rows which in turn means that
only its vpos can have changed. */
if (last_text_row)
- {
- w->window_end_bytepos
- = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
- wset_window_end_pos
- (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
- wset_window_end_vpos
- (w, make_number (MATRIX_ROW_VPOS (last_text_row,
- w->desired_matrix)));
- }
+ adjust_window_ends (w, last_text_row, 0);
else
- {
- wset_window_end_vpos
- (w, make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled));
- }
+ w->window_end_vpos -= nrows_scrolled;
w->window_end_valid = 0;
w->desired_matrix->no_scrolling_p = 1;
/* A value of window_end_pos >= END_UNCHANGED means that the window
end is in the range of changed text. If so, there is no
unchanged row at the end of W's current matrix. */
- if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
+ if (w->window_end_pos >= END_UNCHANGED)
return NULL;
/* Set row to the last row in W's current matrix displaying text. */
- row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
+ row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
/* If matrix is entirely empty, no unchanged row exists. */
if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
buffer positions in the current matrix to current buffer
positions for characters not in changed text. */
ptrdiff_t Z_old =
- MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
+ MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
ptrdiff_t Z_BYTE_old =
MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
GIVE_UP (1);
/* This flag is used to prevent redisplay optimizations. */
- if (windows_or_buffers_changed || cursor_type_changed)
+ if (windows_or_buffers_changed || f->cursor_type_changed)
GIVE_UP (2);
/* Verify that narrowing has not changed.
This case happens with stealth-fontification. Note that although
the display is unchanged, glyph positions in the matrix have to
be adjusted, of course. */
- row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
+ row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
&& ((last_changed_charpos < CHARPOS (start)
&& CHARPOS (start) == BEGV)
/* Compute how many chars/bytes have been added to or removed
from the buffer. */
- Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
+ Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
Z_delta = Z - Z_old;
Z_delta_bytes = Z_BYTE - Z_BYTE_old;
{
/* We have to compute the window end anew since text
could have been added/removed after it. */
- wset_window_end_pos
- (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
- w->window_end_bytepos
- = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
+ w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
+ w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
/* Set the cursor. */
row = row_containing_pos (w, PT, r0, NULL, 0);
/* Give up if the window ends in strings. Overlay strings
at the end are difficult to handle, so don't try. */
- row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
+ row = MATRIX_ROW (current_matrix, w->window_end_vpos);
if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
GIVE_UP (20);
last_text_row = NULL;
overlay_arrow_seen = 0;
while (it.current_y < it.last_visible_y
- && !fonts_changed_p
+ && !f->fonts_changed
&& (first_unchanged_at_end_row == NULL
|| IT_CHARPOS (it) < stop_pos))
{
last_text_row = it.glyph_row - 1;
}
- if (fonts_changed_p)
+ if (f->fonts_changed)
return -1;
/* Set last_row to the glyph row in the current matrix where the
window end line is found. It has been moved up or down in
the matrix by dvpos. */
- int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
+ int last_vpos = w->window_end_vpos + dvpos;
struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
/* If last_row is the window end line, it should display text. */
/* Display the rest of the lines at the window end. */
it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
- while (it.current_y < it.last_visible_y
- && !fonts_changed_p)
+ while (it.current_y < it.last_visible_y && !f->fonts_changed)
{
/* Is it always sure that the display agrees with lines in
the current matrix? I don't think so, so we mark rows
}
/* Update window_end_pos and window_end_vpos. */
- if (first_unchanged_at_end_row
- && !last_text_row_at_end)
+ if (first_unchanged_at_end_row && !last_text_row_at_end)
{
/* Window end line if one of the preserved rows from the current
matrix. Set row to the last row displaying text in current
row = find_last_row_displaying_text (w->current_matrix, &it,
first_unchanged_at_end_row);
eassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
-
- wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
- w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
- wset_window_end_vpos
- (w, make_number (MATRIX_ROW_VPOS (row, w->current_matrix)));
+ adjust_window_ends (w, row, 1);
eassert (w->window_end_bytepos >= 0);
IF_DEBUG (debug_method_add (w, "A"));
}
else if (last_text_row_at_end)
{
- wset_window_end_pos
- (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end)));
- w->window_end_bytepos
- = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
- wset_window_end_vpos
- (w, make_number (MATRIX_ROW_VPOS (last_text_row_at_end,
- desired_matrix)));
+ adjust_window_ends (w, last_text_row_at_end, 0);
eassert (w->window_end_bytepos >= 0);
IF_DEBUG (debug_method_add (w, "B"));
}
/* We have displayed either to the end of the window or at the
end of the window, i.e. the last row with text is to be found
in the desired matrix. */
- wset_window_end_pos
- (w, make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row)));
- w->window_end_bytepos
- = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
- wset_window_end_vpos
- (w, make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix)));
+ adjust_window_ends (w, last_text_row, 0);
eassert (w->window_end_bytepos >= 0);
}
else if (first_unchanged_at_end_row == NULL
/* Displayed to end of window, but no line containing text was
displayed. Lines were deleted at the end of the window. */
int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
- int vpos = XFASTINT (w->window_end_vpos);
+ int vpos = w->window_end_vpos;
struct glyph_row *current_row = current_matrix->rows + vpos;
struct glyph_row *desired_row = desired_matrix->rows + vpos;
}
eassert (row != NULL);
- wset_window_end_vpos (w, make_number (vpos + 1));
- wset_window_end_pos (w, make_number (Z - MATRIX_ROW_END_CHARPOS (row)));
+ w->window_end_vpos = vpos + 1;
+ w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
eassert (w->window_end_bytepos >= 0);
IF_DEBUG (debug_method_add (w, "C"));
else
emacs_abort ();
- IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
- debug_end_vpos = XFASTINT (w->window_end_vpos));
+ IF_DEBUG (debug_end_pos = w->window_end_pos;
+ debug_end_vpos = w->window_end_vpos);
/* Record that display has not been completed. */
w->window_end_valid = 0;
>= it->w->desired_matrix->nrows)
{
it->w->nrows_scale_factor++;
- fonts_changed_p = 1;
+ it->f->fonts_changed = 1;
return 0;
}
{
struct text_pos pt;
- SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
- if (CHARPOS (pt) < BEGV)
- TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
- else if (CHARPOS (pt) > (ZV - 1))
- TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
- else
- TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
+ CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
+ TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
}
/* Display mode lines. */
ptrdiff_t pos = marker_position (w->start);
ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
- if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
+ if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b))
{
if (pos <= BUF_BEGV (b))
return "All";
case 'P':
{
ptrdiff_t toppos = marker_position (w->start);
- ptrdiff_t botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
+ ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b);
if (botpos >= BUF_ZV (b))
#define IT_EXPAND_MATRIX_WIDTH(it, area) \
{ \
- if (!fonts_changed_p \
+ if (!it->f->fonts_changed \
&& (it->glyph_row->glyphs[area] \
< it->glyph_row->glyphs[area + 1])) \
{ \
it->w->ncols_scale_factor++; \
- fonts_changed_p = 1; \
+ it->f->fonts_changed = 1; \
} \
}
base_height = it->ascent + it->descent;
base_width = font->average_width;
- /* Get a face ID for the glyph by utilizing a cache (the same way as
- done for `escape-glyph' in get_next_display_element). */
- if (it->f == last_glyphless_glyph_frame
- && it->face_id == last_glyphless_glyph_face_id)
- {
- face_id = last_glyphless_glyph_merged_face_id;
- }
- else
- {
- /* Merge the `glyphless-char' face into the current face. */
- face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
- last_glyphless_glyph_frame = it->f;
- last_glyphless_glyph_face_id = it->face_id;
- last_glyphless_glyph_merged_face_id = face_id;
- }
+ face_id = merge_glyphless_glyph_face (it);
if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
{
/* EXPORT for RIF:
Output LEN glyphs starting at START at the nominal cursor position.
- Advance the nominal cursor over the text. The global variable
- updated_row is the glyph row being updated, and updated_area is the
- area of that row being updated. */
+ Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
+ being updated, and UPDATED_AREA is the area of that row being updated. */
void
-x_write_glyphs (struct window *w, struct glyph *start, int len)
+x_write_glyphs (struct window *w, struct glyph_row *updated_row,
+ struct glyph *start, enum glyph_row_area updated_area, int len)
{
int x, hpos, chpos = w->phys_cursor.hpos;
/* Write glyphs. */
hpos = start - updated_row->glyphs[updated_area];
- x = draw_glyphs (w, output_cursor.x,
+ x = draw_glyphs (w, w->output_cursor.x,
updated_row, updated_area,
hpos, hpos + len,
DRAW_NORMAL_TEXT, 0);
/* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
if (updated_area == TEXT_AREA
&& w->phys_cursor_on_p
- && w->phys_cursor.vpos == output_cursor.vpos
+ && w->phys_cursor.vpos == w->output_cursor.vpos
&& chpos >= hpos
&& chpos < hpos + len)
w->phys_cursor_on_p = 0;
unblock_input ();
/* Advance the output cursor. */
- output_cursor.hpos += len;
- output_cursor.x = x;
+ w->output_cursor.hpos += len;
+ w->output_cursor.x = x;
}
Insert LEN glyphs from START at the nominal cursor position. */
void
-x_insert_glyphs (struct window *w, struct glyph *start, int len)
+x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
+ struct glyph *start, enum glyph_row_area updated_area, int len)
{
struct frame *f;
int line_height, shift_by_width, shifted_region_width;
/* Get the width of the region to shift right. */
shifted_region_width = (window_box_width (w, updated_area)
- - output_cursor.x
+ - w->output_cursor.x
- shift_by_width);
/* Shift right. */
- frame_x = window_box_left (w, updated_area) + output_cursor.x;
- frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
+ frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
+ frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
line_height, shift_by_width);
/* Write the glyphs. */
hpos = start - row->glyphs[updated_area];
- draw_glyphs (w, output_cursor.x, row, updated_area,
+ draw_glyphs (w, w->output_cursor.x, row, updated_area,
hpos, hpos + len,
DRAW_NORMAL_TEXT, 0);
/* Advance the output cursor. */
- output_cursor.hpos += len;
- output_cursor.x += shift_by_width;
+ w->output_cursor.hpos += len;
+ w->output_cursor.x += shift_by_width;
unblock_input ();
}
(inclusive) to pixel column TO_X (exclusive). The idea is that
everything from TO_X onward is already erased.
- TO_X is a pixel position relative to updated_area of currently
+ TO_X is a pixel position relative to UPDATED_AREA of currently
updated window W. TO_X == -1 means clear to the end of this area. */
void
-x_clear_end_of_line (struct window *w, int to_x)
+x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
+ enum glyph_row_area updated_area, int to_x)
{
struct frame *f;
int max_x, min_y, max_y;
else
to_x = min (to_x, max_x);
- to_y = min (max_y, output_cursor.y + updated_row->height);
+ to_y = min (max_y, w->output_cursor.y + updated_row->height);
/* Notice if the cursor will be cleared by this operation. */
if (!updated_row->full_width_p)
notice_overwritten_cursor (w, updated_area,
- output_cursor.x, -1,
+ w->output_cursor.x, -1,
updated_row->y,
MATRIX_ROW_BOTTOM_Y (updated_row));
- from_x = output_cursor.x;
+ from_x = w->output_cursor.x;
/* Translate to frame coordinates. */
if (updated_row->full_width_p)
}
min_y = WINDOW_HEADER_LINE_HEIGHT (w);
- from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
+ from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
/* Prevent inadvertently clearing to end of the X window. */
}
else
FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
+
+ /* Make sure the cursor gets redrawn. */
+ f->cursor_type_changed = 1;
}
where to put the cursor is specified by HPOS, VPOS, X and Y. */
void
-display_and_set_cursor (struct window *w, int on,
+display_and_set_cursor (struct window *w, bool on,
int hpos, int vpos, int x, int y)
{
struct frame *f = XFRAME (w->frame);
of ON. */
static void
-update_window_cursor (struct window *w, int on)
+update_window_cursor (struct window *w, bool on)
{
/* Don't update cursor in windows whose frame is in the process
of being deleted. */
in the window tree rooted at W. */
static void
-update_cursor_in_window_tree (struct window *w, int on_p)
+update_cursor_in_window_tree (struct window *w, bool on_p)
{
while (w)
{
Don't change the cursor's position. */
void
-x_update_cursor (struct frame *f, int on_p)
+x_update_cursor (struct frame *f, bool on_p)
{
update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
}
cleared = 1;
}
- 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;
+ reset_mouse_highlight (hlinfo);
return cleared;
}
/* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
if (r1 == NULL)
- r1 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
+ r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
/* If the before-string or display-string contains newlines,
rows_from_pos_range skips to its last row. Move back. */
if (!NILP (before_string) || !NILP (disp_string))
}
if (r2 == NULL)
{
- r2 = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
+ r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
hlinfo->mouse_face_past_end = 1;
}
else if (!NILP (after_string))
/* If the after-string has newlines, advance to its last row. */
struct glyph_row *next;
struct glyph_row *last
- = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
+ = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
for (next = r2 + 1;
next <= last
r1 = tem;
}
- hlinfo->mouse_face_beg_y = r1->y;
hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
- hlinfo->mouse_face_end_y = r2->y;
hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
/* For a bidi-reordered row, the positions of BEFORE_STRING,
{
hlinfo->mouse_face_beg_row
= MATRIX_ROW_VPOS (r, w->current_matrix);
- hlinfo->mouse_face_beg_y = r->y;
hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
hlinfo->mouse_face_beg_x = gx;
found = 1;
{
hlinfo->mouse_face_beg_row
= MATRIX_ROW_VPOS (r, w->current_matrix);
- hlinfo->mouse_face_beg_y = r->y;
hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
gx += g1->pixel_width;
/* The highlighted region ends on the previous row. */
r--;
- /* Set the end row and its vertical pixel coordinate. */
+ /* Set the end row. */
hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
- hlinfo->mouse_face_end_y = r->y;
/* Compute and set the end column and the end column's horizontal
pixel coordinate. */
hlinfo->mouse_face_beg_row = vpos;
hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
- hlinfo->mouse_face_beg_y = 0;
- hlinfo->mouse_face_end_y = 0;
hlinfo->mouse_face_past_end = 0;
hlinfo->mouse_face_window = window;
: Qnil;
Lisp_Object lim2 =
NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
- ? make_number (BUF_Z (XBUFFER (buffer))
- - XFASTINT (w->window_end_pos))
+ ? make_number (BUF_Z (XBUFFER (buffer)) - w->window_end_pos)
: Qnil;
if (NILP (overlay))
window = hlinfo->mouse_face_window;
if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
- {
- 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;
- }
+ reset_mouse_highlight (hlinfo);
}
{
int x0, x1, y0, y1;
- window_box_edges (w, -1, &x0, &y0, &x1, &y1);
+ window_box_edges (w, &x0, &y0, &x1, &y1);
y1 -= 1;
if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
{
int x0, x1, y0, y1;
- window_box_edges (w, -1, &x0, &y0, &x1, &y1);
+ window_box_edges (w, &x0, &y0, &x1, &y1);
y1 -= 1;
if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
+#ifdef HAVE_WINDOW_SYSTEM
hourglass_atimer = NULL;
hourglass_shown_p = 0;
+#endif /* HAVE_WINDOW_SYSTEM */
DEFSYM (Qglyphless_char, "glyphless-char");
DEFSYM (Qhex_code, "hex-code");
DEFSYM (Qzero_width, "zero-width");
DEFSYM (Qglyphless_char_display, "glyphless-char-display");
- /* Intern this now in case it isn't already done.
- Setting this variable twice is harmless.
- But don't staticpro it here--that is done in alloc.c. */
- Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
void
init_xdisp (void)
{
- current_header_line_height = current_mode_line_height = -1;
-
CHARPOS (this_line_start_pos) = 0;
if (!noninteractive)
help_echo_showing_p = 0;
}
+#ifdef HAVE_WINDOW_SYSTEM
+
/* Platform-independent portion of hourglass implementation. */
/* Cancel a currently active hourglass timer, and start a new one. */
void
start_hourglass (void)
{
-#if defined (HAVE_WINDOW_SYSTEM)
- EMACS_TIME delay;
+ struct timespec delay;
cancel_hourglass ();
if (INTEGERP (Vhourglass_delay)
&& XINT (Vhourglass_delay) > 0)
- delay = make_emacs_time (min (XINT (Vhourglass_delay),
+ delay = make_timespec (min (XINT (Vhourglass_delay),
TYPE_MAXIMUM (time_t)),
- 0);
+ 0);
else if (FLOATP (Vhourglass_delay)
&& XFLOAT_DATA (Vhourglass_delay) > 0)
- delay = EMACS_TIME_FROM_DOUBLE (XFLOAT_DATA (Vhourglass_delay));
+ delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
else
- delay = make_emacs_time (DEFAULT_HOURGLASS_DELAY, 0);
+ delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
#ifdef HAVE_NTGUI
{
hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
show_hourglass, NULL);
-#endif
}
void
cancel_hourglass (void)
{
-#if defined (HAVE_WINDOW_SYSTEM)
if (hourglass_atimer)
{
cancel_atimer (hourglass_atimer);
if (hourglass_shown_p)
hide_hourglass ();
-#endif
}
+
+#endif /* HAVE_WINDOW_SYSTEM */