X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/c0ece6a5c4c8dc87be1da6808289c88de19d8398..727e958ef0548f3d8ce02a4a971247f52cc548ce:/src/xdisp.c
diff --git a/src/xdisp.c b/src/xdisp.c
index 2a6e85732c..02467c7bed 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -254,7 +254,7 @@ along with GNU Emacs. If not, see . */
still left to right, i.e. the iterator "thinks" the first character
is at the leftmost pixel position. The iterator does not know that
PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
- delivers. This is important when functions from the the move_it_*
+ delivers. This is important when functions from the move_it_*
family are used to get to certain screen position or to match
screen coordinates with buffer coordinates: these functions use the
iterator geometry, which is left to right even in R2L paragraphs.
@@ -318,29 +318,31 @@ along with GNU Emacs. If not, see . */
Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
Lisp_Object Qwindow_scroll_functions;
-Lisp_Object Qwindow_text_change_functions;
-Lisp_Object Qredisplay_end_trigger_functions;
+static Lisp_Object Qwindow_text_change_functions;
+static Lisp_Object Qredisplay_end_trigger_functions;
Lisp_Object Qinhibit_point_motion_hooks;
-Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
-Lisp_Object Qfontified;
-Lisp_Object Qgrow_only;
-Lisp_Object Qinhibit_eval_during_redisplay;
-Lisp_Object Qbuffer_position, Qposition, Qobject;
-Lisp_Object Qright_to_left, Qleft_to_right;
+static Lisp_Object QCeval, QCpropertize;
+Lisp_Object QCfile, QCdata;
+static Lisp_Object Qfontified;
+static Lisp_Object Qgrow_only;
+static Lisp_Object Qinhibit_eval_during_redisplay;
+static Lisp_Object Qbuffer_position, Qposition, Qobject;
+static Lisp_Object Qright_to_left, Qleft_to_right;
/* Cursor shapes */
Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
/* Pointer shapes */
-Lisp_Object Qarrow, Qhand, Qtext;
+static Lisp_Object Qarrow, Qhand;
+Lisp_Object Qtext;
/* Holds the list (error). */
-Lisp_Object list_of_error;
+static Lisp_Object list_of_error;
-Lisp_Object Qfontification_functions;
+static Lisp_Object Qfontification_functions;
-Lisp_Object Qwrap_prefix;
-Lisp_Object Qline_prefix;
+static Lisp_Object Qwrap_prefix;
+static Lisp_Object Qline_prefix;
/* Non-nil means don't actually do any redisplay. */
@@ -350,12 +352,14 @@ Lisp_Object Qinhibit_redisplay;
Lisp_Object Qdisplay;
-Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
-Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
-Lisp_Object Qslice;
+Lisp_Object Qspace, QCalign_to;
+static Lisp_Object QCrelative_width, QCrelative_height;
+Lisp_Object Qleft_margin, Qright_margin;
+static Lisp_Object Qspace_width, Qraise;
+static Lisp_Object Qslice;
Lisp_Object Qcenter;
-Lisp_Object Qmargin, Qpointer;
-Lisp_Object Qline_height;
+static Lisp_Object Qmargin, Qpointer;
+static Lisp_Object Qline_height;
#ifdef HAVE_WINDOW_SYSTEM
@@ -383,15 +387,15 @@ Lisp_Object Qline_height;
/* Name of the face used to highlight trailing whitespace. */
-Lisp_Object Qtrailing_whitespace;
+static Lisp_Object Qtrailing_whitespace;
/* Name and number of the face used to highlight escape glyphs. */
-Lisp_Object Qescape_glyph;
+static Lisp_Object Qescape_glyph;
/* Name and number of the face used to highlight non-breaking spaces. */
-Lisp_Object Qnobreak_space;
+static Lisp_Object Qnobreak_space;
/* The symbol `image' which is the car of the lists used to represent
images in Lisp. Also a tool bar style. */
@@ -399,8 +403,9 @@ Lisp_Object Qnobreak_space;
Lisp_Object Qimage;
/* The image map types. */
-Lisp_Object QCmap, QCpointer;
-Lisp_Object Qrect, Qcircle, Qpoly;
+Lisp_Object QCmap;
+static Lisp_Object QCpointer;
+static Lisp_Object Qrect, Qcircle, Qpoly;
/* Tool bar styles */
Lisp_Object Qboth, Qboth_horiz, Qtext_image_horiz;
@@ -460,12 +465,12 @@ static struct buffer *this_line_buffer;
Voverlay_arrow_position is a marker, last-arrow-position is its
numerical position. */
-Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
+static Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
/* Alternative overlay-arrow-string and overlay-arrow-bitmap
properties on a symbol in overlay-arrow-variable-list. */
-Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
+static Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
Lisp_Object Qmenu_bar_update_hook;
@@ -494,12 +499,12 @@ Lisp_Object echo_area_window;
message_enable_multibyte on the stack, the function restore_message
pops the stack and displays MESSAGE again. */
-Lisp_Object Vmessage_stack;
+static Lisp_Object Vmessage_stack;
/* Nonzero means multibyte characters were enabled when the echo area
message was specified. */
-int message_enable_multibyte;
+static int message_enable_multibyte;
/* Nonzero if we should redraw the mode lines on the next redisplay. */
@@ -517,7 +522,7 @@ int cursor_type_changed;
/* Nonzero after display_mode_line if %l was used and it displayed a
line number. */
-int line_number_displayed;
+static int line_number_displayed;
/* The name of the *Messages* buffer, a string. */
@@ -544,12 +549,12 @@ static int display_last_displayed_message_p;
/* Nonzero if echo area is being used by print; zero if being used by
message. */
-int message_buf_print;
+static int message_buf_print;
/* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
-Lisp_Object Qinhibit_menubar_update;
-Lisp_Object Qmessage_truncate_lines;
+static Lisp_Object Qinhibit_menubar_update;
+static Lisp_Object Qmessage_truncate_lines;
/* Set to 1 in clear_message to make redisplay_internal aware
of an emptied echo area. */
@@ -560,7 +565,7 @@ static int message_cleared_p;
glyphs. Also used in direct_output_for_insert. */
#define MAX_SCRATCH_GLYPHS 100
-struct glyph_row scratch_glyph_row;
+static struct glyph_row scratch_glyph_row;
static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
/* Ascent and height of the last line processed by move_it_to. */
@@ -603,11 +608,11 @@ int trace_move;
#define TRACE_MOVE(x) (void) 0
#endif
-Lisp_Object Qauto_hscroll_mode;
+static Lisp_Object Qauto_hscroll_mode;
/* Buffer being redisplayed -- for redisplay_window_error. */
-struct buffer *displayed_buffer;
+static struct buffer *displayed_buffer;
/* Value returned from text property handlers (see below). */
@@ -708,7 +713,7 @@ static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
int redisplaying_p;
-Lisp_Object Qinhibit_free_realized_faces;
+static Lisp_Object Qinhibit_free_realized_faces;
/* If a string, XTread_socket generates an event to display that string.
(The display is done in read_char.) */
@@ -735,7 +740,7 @@ struct atimer *hourglass_atimer;
Lisp_Object Qglyphless_char;
/* Symbol for the purpose of Vglyphless_char_display. */
-Lisp_Object Qglyphless_char_display;
+static Lisp_Object Qglyphless_char_display;
/* Method symbols for Vglyphless_char_display. */
static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
@@ -751,6 +756,7 @@ static Lisp_Object Qhex_code, Qempty_box, Qthin_space, Qzero_width;
/* Function prototypes. */
static void setup_for_ellipsis (struct it *, int);
+static void set_iterator_to_next (struct it *, int);
static void mark_window_display_accurate_1 (struct window *, int);
static int single_display_spec_string_p (Lisp_Object, Lisp_Object);
static int display_prop_string_p (Lisp_Object, Lisp_Object);
@@ -773,7 +779,6 @@ static void store_mode_line_noprop_char (char);
static int store_mode_line_noprop (const char *, int, int);
static void handle_stop (struct it *);
static void handle_stop_backwards (struct it *, EMACS_INT);
-static int single_display_spec_intangible_p (Lisp_Object);
static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
static void ensure_echo_area_buffers (void);
static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
@@ -783,7 +788,9 @@ static int with_echo_area_buffer (struct window *, int,
EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
static void clear_garbaged_frames (void);
static int current_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static void pop_message (void);
static int truncate_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
+static void set_message (const char *, Lisp_Object, EMACS_INT, int);
static int set_message_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
static int display_echo_area (struct window *);
static int display_echo_area_1 (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT);
@@ -804,7 +811,7 @@ static int try_scrolling (Lisp_Object, int, EMACS_INT, EMACS_INT, int, int);
static int try_cursor_movement (Lisp_Object, struct text_pos, int *);
static int trailing_whitespace_p (EMACS_INT);
static unsigned long int message_log_check_duplicate (EMACS_INT, EMACS_INT);
-static void push_it (struct it *);
+static void push_it (struct it *, struct text_pos *);
static void pop_it (struct it *);
static void sync_frame_with_window_matrix_rows (struct window *);
static void select_frame_for_redisplay (Lisp_Object);
@@ -815,6 +822,9 @@ static void redisplay_window (Lisp_Object, int);
static Lisp_Object redisplay_window_error (Lisp_Object);
static Lisp_Object redisplay_window_0 (Lisp_Object);
static Lisp_Object redisplay_window_1 (Lisp_Object);
+static int set_cursor_from_row (struct window *, struct glyph_row *,
+ struct glyph_matrix *, EMACS_INT, EMACS_INT,
+ int, int);
static int update_menu_bar (struct frame *, int, int);
static int try_window_reusing_current_matrix (struct window *);
static int try_window_id (struct window *);
@@ -852,6 +862,7 @@ static int init_from_display_pos (struct it *, struct window *,
struct display_pos *);
static void reseat_to_string (struct it *, const char *,
Lisp_Object, EMACS_INT, EMACS_INT, int, int);
+static int get_next_display_element (struct it *);
static enum move_it_result
move_it_in_display_line_to (struct it *, EMACS_INT, int,
enum move_operation_enum);
@@ -872,9 +883,11 @@ static void compute_string_pos (struct text_pos *, struct text_pos,
Lisp_Object);
static int face_before_or_after_it_pos (struct it *, int);
static EMACS_INT next_overlay_change (EMACS_INT);
+static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
+ Lisp_Object, struct text_pos *, EMACS_INT, int);
static int handle_single_display_spec (struct it *, Lisp_Object,
Lisp_Object, Lisp_Object,
- struct text_pos *, int);
+ struct text_pos *, EMACS_INT, int, int);
static int underlying_face_id (struct it *);
static int in_ellipses_for_invisible_text_p (struct display_pos *,
struct window *);
@@ -899,6 +912,7 @@ static void append_stretch_glyph (struct it *, Lisp_Object,
#endif /* HAVE_WINDOW_SYSTEM */
+static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
static int coords_in_mouse_face_p (struct window *, int, int);
@@ -913,7 +927,7 @@ static int coords_in_mouse_face_p (struct window *, int, int);
This is the height of W minus the height of a mode line, if any. */
-INLINE int
+inline int
window_text_bottom_y (struct window *w)
{
int height = WINDOW_TOTAL_HEIGHT (w);
@@ -927,7 +941,7 @@ window_text_bottom_y (struct window *w)
means return the total width of W, not including fringes to
the left and right of the window. */
-INLINE int
+inline int
window_box_width (struct window *w, int area)
{
int cols = XFASTINT (w->total_cols);
@@ -966,7 +980,7 @@ window_box_width (struct window *w, int area)
/* Return the pixel height of the display area of window W, not
including mode lines of W, if any. */
-INLINE int
+inline int
window_box_height (struct window *w)
{
struct frame *f = XFRAME (w->frame);
@@ -1013,7 +1027,7 @@ window_box_height (struct window *w)
area AREA of window W. AREA < 0 means return the left edge of the
whole window, to the right of the left fringe of W. */
-INLINE int
+inline int
window_box_left_offset (struct window *w, int area)
{
int x;
@@ -1045,7 +1059,7 @@ window_box_left_offset (struct window *w, int area)
area AREA of window W. AREA < 0 means return the right edge of the
whole window, to the left of the right fringe of W. */
-INLINE int
+inline int
window_box_right_offset (struct window *w, int area)
{
return window_box_left_offset (w, area) + window_box_width (w, area);
@@ -1055,7 +1069,7 @@ window_box_right_offset (struct window *w, int area)
area AREA of window W. AREA < 0 means return the left edge of the
whole window, to the right of the left fringe of W. */
-INLINE int
+inline int
window_box_left (struct window *w, int area)
{
struct frame *f = XFRAME (w->frame);
@@ -1075,7 +1089,7 @@ window_box_left (struct window *w, int area)
area AREA of window W. AREA < 0 means return the right edge of the
whole window, to the left of the right fringe of W. */
-INLINE int
+inline int
window_box_right (struct window *w, int area)
{
return window_box_left (w, area) + window_box_width (w, area);
@@ -1088,7 +1102,7 @@ window_box_right (struct window *w, int area)
coordinates of the upper-left corner of the box. Return in
*BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
-INLINE void
+inline void
window_box (struct window *w, int area, int *box_x, int *box_y,
int *box_width, int *box_height)
{
@@ -1115,7 +1129,7 @@ window_box (struct window *w, int area, int *box_x, int *box_y,
*BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
box. */
-INLINE void
+static inline 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)
{
@@ -1315,7 +1329,7 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
returns an invalid character. If we find one, we return a `?', but
with the length of the invalid character. */
-static INLINE int
+static inline int
string_char_and_length (const unsigned char *str, int *len)
{
int c;
@@ -1363,7 +1377,7 @@ string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, EMACS_INT ncha
/* Value is the text position, i.e. character and byte position,
for character position CHARPOS in STRING. */
-static INLINE struct text_pos
+static inline struct text_pos
string_pos (EMACS_INT charpos, Lisp_Object string)
{
struct text_pos pos;
@@ -1533,61 +1547,6 @@ pixel_to_glyph_coords (FRAME_PTR f, register int pix_x, register int pix_y,
}
-/* Given HPOS/VPOS in the current matrix of W, return corresponding
- frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
- can't tell the positions because W's display is not up to date,
- return 0. */
-
-int
-glyph_to_pixel_coords (struct window *w, int hpos, int vpos,
- int *frame_x, int *frame_y)
-{
-#ifdef HAVE_WINDOW_SYSTEM
- if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
- {
- int success_p;
-
- xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
- xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
-
- if (display_completed)
- {
- struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
- struct glyph *glyph = row->glyphs[TEXT_AREA];
- struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
-
- hpos = row->x;
- vpos = row->y;
- while (glyph < end)
- {
- hpos += glyph->pixel_width;
- ++glyph;
- }
-
- /* If first glyph is partially visible, its first visible position is still 0. */
- if (hpos < 0)
- hpos = 0;
-
- success_p = 1;
- }
- else
- {
- hpos = vpos = 0;
- success_p = 0;
- }
-
- *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
- *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
- return success_p;
- }
-#endif
-
- *frame_x = hpos;
- *frame_y = vpos;
- return 1;
-}
-
-
/* Find the glyph under window-relative coordinates X/Y in window W.
Consider only glyphs from buffer text, i.e. no glyphs from overlay
strings. Return in *HPOS and *VPOS the row and column number of
@@ -1670,11 +1629,10 @@ x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
return glyph;
}
-/* EXPORT:
- Convert frame-relative x/y to coordinates relative to window W.
+/* Convert frame-relative x/y to coordinates relative to window W.
Takes pseudo-windows into account. */
-void
+static void
frame_to_window_pixel_xy (struct window *w, int *x, int *y)
{
if (w->pseudo_window_p)
@@ -2607,7 +2565,7 @@ init_iterator (struct it *it, struct window *w,
it->paragraph_embedding = R2L;
else
it->paragraph_embedding = NEUTRAL_DIR;
- bidi_init_it (charpos, bytepos, &it->bidi_it);
+ bidi_init_it (charpos, bytepos, FRAME_WINDOW_P (it->f), &it->bidi_it);
}
/* If a buffer position was specified, set the iterator there,
@@ -3128,6 +3086,82 @@ next_overlay_change (EMACS_INT pos)
return endpos;
}
+/* Return the character position of a display string at or after CHARPOS.
+ If no display string exists at or after CHARPOS, return ZV. A
+ display string is either an overlay with `display' property whose
+ value is a string, or a `display' text property whose value is a
+ string. FRAME_WINDOW_P is non-zero when we are displaying a window
+ on a GUI frame. */
+EMACS_INT
+compute_display_string_pos (EMACS_INT charpos, int frame_window_p)
+{
+ /* FIXME: Support display properties on strings (object = Qnil means
+ current buffer). */
+ Lisp_Object object = Qnil;
+ Lisp_Object pos, spec;
+ struct text_pos position;
+ EMACS_INT bufpos;
+
+ if (charpos >= ZV)
+ return ZV;
+
+ /* If the character at CHARPOS is where the display string begins,
+ return CHARPOS. */
+ pos = make_number (charpos);
+ CHARPOS (position) = charpos;
+ BYTEPOS (position) = CHAR_TO_BYTE (charpos);
+ bufpos = charpos; /* FIXME! support strings as well */
+ if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
+ && (charpos <= BEGV
+ || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
+ object),
+ spec))
+ && handle_display_spec (NULL, spec, object, Qnil, &position, bufpos,
+ frame_window_p))
+ return charpos;
+
+ /* Look forward for the first character with a `display' property
+ that will replace the underlying text when displayed. */
+ do {
+ pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
+ CHARPOS (position) = XFASTINT (pos);
+ BYTEPOS (position) = CHAR_TO_BYTE (CHARPOS (position));
+ if (CHARPOS (position) >= ZV)
+ break;
+ spec = Fget_char_property (pos, Qdisplay, object);
+ bufpos = CHARPOS (position); /* FIXME! support strings as well */
+ } while (NILP (spec)
+ || !handle_display_spec (NULL, spec, object, Qnil, &position, bufpos,
+ frame_window_p));
+
+ return CHARPOS (position);
+}
+
+/* Return the character position of the end of the display string that
+ started at CHARPOS. A display string is either an overlay with
+ `display' property whose value is a string or a `display' text
+ property whose value is a string. */
+EMACS_INT
+compute_display_string_end (EMACS_INT charpos)
+{
+ /* FIXME: Support display properties on strings (object = Qnil means
+ current buffer). */
+ Lisp_Object object = Qnil;
+ Lisp_Object pos = make_number (charpos);
+
+ if (charpos >= ZV)
+ return ZV;
+
+ if (NILP (Fget_char_property (pos, Qdisplay, object)))
+ abort ();
+
+ /* Look forward for the first character where the `display' property
+ changes. */
+ pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
+
+ return XFASTINT (pos);
+}
+
/***********************************************************************
@@ -3748,7 +3782,7 @@ setup_for_ellipsis (struct it *it, int len)
{
struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
it->dpvec = v->contents;
- it->dpend = v->contents + v->size;
+ it->dpend = v->contents + v->header.size;
}
else
{
@@ -3786,8 +3820,9 @@ setup_for_ellipsis (struct it *it, int len)
static enum prop_handled
handle_display_prop (struct it *it)
{
- Lisp_Object prop, object, overlay;
+ Lisp_Object propval, object, overlay;
struct text_pos *position;
+ EMACS_INT bufpos;
/* Nonzero if some property replaces the display of the text itself. */
int display_replaced_p = 0;
@@ -3795,11 +3830,13 @@ handle_display_prop (struct it *it)
{
object = it->string;
position = &it->current.string_pos;
+ bufpos = CHARPOS (it->current.pos);
}
else
{
XSETWINDOW (object, it->w);
position = &it->current.pos;
+ bufpos = CHARPOS (*position);
}
/* Reset those iterator values set from display property values. */
@@ -3814,9 +3851,9 @@ handle_display_prop (struct it *it)
if (!it->string_from_display_prop_p)
it->area = TEXT_AREA;
- prop = get_char_property_and_overlay (make_number (position->charpos),
- Qdisplay, object, &overlay);
- if (NILP (prop))
+ propval = get_char_property_and_overlay (make_number (position->charpos),
+ Qdisplay, object, &overlay);
+ if (NILP (propval))
return HANDLED_NORMALLY;
/* Now OVERLAY is the overlay that gave us this property, or nil
if it was a text property. */
@@ -3824,59 +3861,88 @@ handle_display_prop (struct it *it)
if (!STRINGP (it->string))
object = it->w->buffer;
- if (CONSP (prop)
- /* Simple properties. */
- && !EQ (XCAR (prop), Qimage)
- && !EQ (XCAR (prop), Qspace)
- && !EQ (XCAR (prop), Qwhen)
- && !EQ (XCAR (prop), Qslice)
- && !EQ (XCAR (prop), Qspace_width)
- && !EQ (XCAR (prop), Qheight)
- && !EQ (XCAR (prop), Qraise)
+ display_replaced_p = handle_display_spec (it, propval, object, overlay,
+ position, bufpos,
+ FRAME_WINDOW_P (it->f));
+
+ return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
+}
+
+/* Subroutine of handle_display_prop. Returns non-zero if the display
+ specification in SPEC is a replacing specification, i.e. it would
+ replace the text covered by `display' property with something else,
+ such as an image or a display string.
+
+ See handle_single_display_spec for documentation of arguments.
+ frame_window_p is non-zero if the window being redisplayed is on a
+ GUI frame; this argument is used only if IT is NULL, see below.
+
+ IT can be NULL, if this is called by the bidi reordering code
+ through compute_display_string_pos, which see. In that case, this
+ function only examines SPEC, but does not otherwise "handle" it, in
+ the sense that it doesn't set up members of IT from the display
+ spec. */
+static int
+handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
+ Lisp_Object overlay, struct text_pos *position,
+ EMACS_INT bufpos, int frame_window_p)
+{
+ int replacing_p = 0;
+
+ if (CONSP (spec)
+ /* Simple specerties. */
+ && !EQ (XCAR (spec), Qimage)
+ && !EQ (XCAR (spec), Qspace)
+ && !EQ (XCAR (spec), Qwhen)
+ && !EQ (XCAR (spec), Qslice)
+ && !EQ (XCAR (spec), Qspace_width)
+ && !EQ (XCAR (spec), Qheight)
+ && !EQ (XCAR (spec), Qraise)
/* Marginal area specifications. */
- && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
- && !EQ (XCAR (prop), Qleft_fringe)
- && !EQ (XCAR (prop), Qright_fringe)
- && !NILP (XCAR (prop)))
+ && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
+ && !EQ (XCAR (spec), Qleft_fringe)
+ && !EQ (XCAR (spec), Qright_fringe)
+ && !NILP (XCAR (spec)))
{
- for (; CONSP (prop); prop = XCDR (prop))
+ for (; CONSP (spec); spec = XCDR (spec))
{
- if (handle_single_display_spec (it, XCAR (prop), object, overlay,
- position, display_replaced_p))
+ if (handle_single_display_spec (it, XCAR (spec), object, overlay,
+ position, bufpos, replacing_p,
+ frame_window_p))
{
- display_replaced_p = 1;
+ replacing_p = 1;
/* If some text in a string is replaced, `position' no
longer points to the position of `object'. */
- if (STRINGP (object))
+ if (!it || STRINGP (object))
break;
}
}
}
- else if (VECTORP (prop))
+ else if (VECTORP (spec))
{
int i;
- for (i = 0; i < ASIZE (prop); ++i)
- if (handle_single_display_spec (it, AREF (prop, i), object, overlay,
- position, display_replaced_p))
+ for (i = 0; i < ASIZE (spec); ++i)
+ if (handle_single_display_spec (it, AREF (spec, i), object, overlay,
+ position, bufpos, replacing_p,
+ frame_window_p))
{
- display_replaced_p = 1;
+ replacing_p = 1;
/* If some text in a string is replaced, `position' no
longer points to the position of `object'. */
- if (STRINGP (object))
+ if (!it || STRINGP (object))
break;
}
}
else
{
- if (handle_single_display_spec (it, prop, object, overlay,
- position, 0))
- display_replaced_p = 1;
+ if (handle_single_display_spec (it, spec, object, overlay,
+ position, bufpos, 0, frame_window_p))
+ replacing_p = 1;
}
- return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
+ return replacing_p;
}
-
/* Value is the position of the end of the `display' property starting
at START_POS in OBJECT. */
@@ -3898,31 +3964,38 @@ display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
}
-/* Set up IT from a single `display' specification PROP. OBJECT
+/* Set up IT from a single `display' property specification SPEC. OBJECT
is the object in which the `display' property was found. *POSITION
- is the position at which it was found. DISPLAY_REPLACED_P non-zero
- means that we previously saw a display specification which already
- replaced text display with something else, for example an image;
- we ignore such properties after the first one has been processed.
+ is the position in OBJECT at which the `display' property was found.
+ BUFPOS is the buffer position of OBJECT (different from POSITION if
+ OBJECT is not a buffer). DISPLAY_REPLACED_P non-zero means that we
+ previously saw a display specification which already replaced text
+ display with something else, for example an image; we ignore such
+ properties after the first one has been processed.
OVERLAY is the overlay this `display' property came from,
or nil if it was a text property.
- If PROP is a `space' or `image' specification, and in some other
+ If SPEC is a `space' or `image' specification, and in some other
cases too, set *POSITION to the position where the `display'
property ends.
+ If IT is NULL, only examine the property specification in SPEC, but
+ don't set up IT. In that case, FRAME_WINDOW_P non-zero means SPEC
+ is intended to be displayed in a window on a GUI frame.
+
Value is non-zero if something was found which replaces the display
of buffer or string text. */
static int
handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
Lisp_Object overlay, struct text_pos *position,
- int display_replaced_before_p)
+ EMACS_INT bufpos, int display_replaced_p,
+ int frame_window_p)
{
Lisp_Object form;
Lisp_Object location, value;
- struct text_pos start_pos, save_pos;
+ struct text_pos start_pos = *position;
int valid_p;
/* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
@@ -3946,11 +4019,12 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
buffer or string. Bind `position' to the position in the
object where the property was found, and `buffer-position'
to the current position in the buffer. */
+
+ if (NILP (object))
+ XSETBUFFER (object, current_buffer);
specbind (Qobject, object);
specbind (Qposition, make_number (CHARPOS (*position)));
- specbind (Qbuffer_position,
- make_number (STRINGP (object)
- ? IT_CHARPOS (*it) : CHARPOS (*position)));
+ specbind (Qbuffer_position, make_number (bufpos));
GCPRO1 (form);
form = safe_eval (form);
UNGCPRO;
@@ -3965,63 +4039,66 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
&& EQ (XCAR (spec), Qheight)
&& CONSP (XCDR (spec)))
{
- if (!FRAME_WINDOW_P (it->f))
- return 0;
-
- it->font_height = XCAR (XCDR (spec));
- if (!NILP (it->font_height))
+ if (it)
{
- struct face *face = FACE_FROM_ID (it->f, it->face_id);
- int new_height = -1;
+ if (!FRAME_WINDOW_P (it->f))
+ return 0;
- if (CONSP (it->font_height)
- && (EQ (XCAR (it->font_height), Qplus)
- || EQ (XCAR (it->font_height), Qminus))
- && CONSP (XCDR (it->font_height))
- && INTEGERP (XCAR (XCDR (it->font_height))))
- {
- /* `(+ N)' or `(- N)' where N is an integer. */
- int steps = XINT (XCAR (XCDR (it->font_height)));
- if (EQ (XCAR (it->font_height), Qplus))
- steps = - steps;
- it->face_id = smaller_face (it->f, it->face_id, steps);
- }
- else if (FUNCTIONP (it->font_height))
+ it->font_height = XCAR (XCDR (spec));
+ if (!NILP (it->font_height))
{
- /* Call function with current height as argument.
- Value is the new height. */
- Lisp_Object height;
- height = safe_call1 (it->font_height,
- face->lface[LFACE_HEIGHT_INDEX]);
- if (NUMBERP (height))
- new_height = XFLOATINT (height);
- }
- else if (NUMBERP (it->font_height))
- {
- /* Value is a multiple of the canonical char height. */
- struct face *f;
+ struct face *face = FACE_FROM_ID (it->f, it->face_id);
+ int new_height = -1;
+
+ if (CONSP (it->font_height)
+ && (EQ (XCAR (it->font_height), Qplus)
+ || EQ (XCAR (it->font_height), Qminus))
+ && CONSP (XCDR (it->font_height))
+ && INTEGERP (XCAR (XCDR (it->font_height))))
+ {
+ /* `(+ N)' or `(- N)' where N is an integer. */
+ int steps = XINT (XCAR (XCDR (it->font_height)));
+ if (EQ (XCAR (it->font_height), Qplus))
+ steps = - steps;
+ it->face_id = smaller_face (it->f, it->face_id, steps);
+ }
+ else if (FUNCTIONP (it->font_height))
+ {
+ /* Call function with current height as argument.
+ Value is the new height. */
+ Lisp_Object height;
+ height = safe_call1 (it->font_height,
+ face->lface[LFACE_HEIGHT_INDEX]);
+ if (NUMBERP (height))
+ new_height = XFLOATINT (height);
+ }
+ else if (NUMBERP (it->font_height))
+ {
+ /* Value is a multiple of the canonical char height. */
+ struct face *f;
- f = FACE_FROM_ID (it->f,
- lookup_basic_face (it->f, DEFAULT_FACE_ID));
- new_height = (XFLOATINT (it->font_height)
- * XINT (f->lface[LFACE_HEIGHT_INDEX]));
- }
- else
- {
- /* Evaluate IT->font_height with `height' bound to the
- current specified height to get the new height. */
- int count = SPECPDL_INDEX ();
+ f = FACE_FROM_ID (it->f,
+ lookup_basic_face (it->f, DEFAULT_FACE_ID));
+ new_height = (XFLOATINT (it->font_height)
+ * XINT (f->lface[LFACE_HEIGHT_INDEX]));
+ }
+ else
+ {
+ /* Evaluate IT->font_height with `height' bound to the
+ current specified height to get the new height. */
+ int count = SPECPDL_INDEX ();
- specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
- value = safe_eval (it->font_height);
- unbind_to (count, Qnil);
+ specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
+ value = safe_eval (it->font_height);
+ unbind_to (count, Qnil);
- if (NUMBERP (value))
- new_height = XFLOATINT (value);
- }
+ if (NUMBERP (value))
+ new_height = XFLOATINT (value);
+ }
- if (new_height > 0)
- it->face_id = face_with_height (it->f, it->face_id, new_height);
+ if (new_height > 0)
+ it->face_id = face_with_height (it->f, it->face_id, new_height);
+ }
}
return 0;
@@ -4032,12 +4109,15 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
&& EQ (XCAR (spec), Qspace_width)
&& CONSP (XCDR (spec)))
{
- if (!FRAME_WINDOW_P (it->f))
- return 0;
+ if (it)
+ {
+ if (!FRAME_WINDOW_P (it->f))
+ return 0;
- value = XCAR (XCDR (spec));
- if (NUMBERP (value) && XFLOATINT (value) > 0)
- it->space_width = value;
+ value = XCAR (XCDR (spec));
+ if (NUMBERP (value) && XFLOATINT (value) > 0)
+ it->space_width = value;
+ }
return 0;
}
@@ -4048,20 +4128,23 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
{
Lisp_Object tem;
- if (!FRAME_WINDOW_P (it->f))
- return 0;
-
- if (tem = XCDR (spec), CONSP (tem))
+ if (it)
{
- it->slice.x = XCAR (tem);
- if (tem = XCDR (tem), CONSP (tem))
+ if (!FRAME_WINDOW_P (it->f))
+ return 0;
+
+ if (tem = XCDR (spec), CONSP (tem))
{
- it->slice.y = XCAR (tem);
+ it->slice.x = XCAR (tem);
if (tem = XCDR (tem), CONSP (tem))
{
- it->slice.width = XCAR (tem);
+ it->slice.y = XCAR (tem);
if (tem = XCDR (tem), CONSP (tem))
- it->slice.height = XCAR (tem);
+ {
+ it->slice.width = XCAR (tem);
+ if (tem = XCDR (tem), CONSP (tem))
+ it->slice.height = XCAR (tem);
+ }
}
}
}
@@ -4074,36 +4157,43 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
&& EQ (XCAR (spec), Qraise)
&& CONSP (XCDR (spec)))
{
- if (!FRAME_WINDOW_P (it->f))
- return 0;
+ if (it)
+ {
+ if (!FRAME_WINDOW_P (it->f))
+ return 0;
#ifdef HAVE_WINDOW_SYSTEM
- value = XCAR (XCDR (spec));
- if (NUMBERP (value))
- {
- struct face *face = FACE_FROM_ID (it->f, it->face_id);
- it->voffset = - (XFLOATINT (value)
- * (FONT_HEIGHT (face->font)));
- }
+ value = XCAR (XCDR (spec));
+ if (NUMBERP (value))
+ {
+ struct face *face = FACE_FROM_ID (it->f, it->face_id);
+ it->voffset = - (XFLOATINT (value)
+ * (FONT_HEIGHT (face->font)));
+ }
#endif /* HAVE_WINDOW_SYSTEM */
+ }
return 0;
}
/* Don't handle the other kinds of display specifications
inside a string that we got from a `display' property. */
- if (it->string_from_display_prop_p)
+ if (it && it->string_from_display_prop_p)
return 0;
/* Characters having this form of property are not displayed, so
we have to find the end of the property. */
- start_pos = *position;
- *position = display_prop_end (it, object, start_pos);
+ if (it)
+ {
+ start_pos = *position;
+ *position = display_prop_end (it, object, start_pos);
+ }
value = Qnil;
/* Stop the scan at that end position--we assume that all
text properties change there. */
- it->stop_charpos = position->charpos;
+ if (it)
+ it->stop_charpos = position->charpos;
/* Handle `(left-fringe BITMAP [FACE])'
and `(right-fringe BITMAP [FACE])'. */
@@ -4112,12 +4202,16 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
|| EQ (XCAR (spec), Qright_fringe))
&& CONSP (XCDR (spec)))
{
- int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
int fringe_bitmap;
- if (!FRAME_WINDOW_P (it->f))
- /* If we return here, POSITION has been advanced
- across the text with this property. */
+ if (it)
+ {
+ if (!FRAME_WINDOW_P (it->f))
+ /* If we return here, POSITION has been advanced
+ across the text with this property. */
+ return 0;
+ }
+ else if (!frame_window_p)
return 0;
#ifdef HAVE_WINDOW_SYSTEM
@@ -4128,46 +4222,47 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
across the text with this property. */
return 0;
- if (CONSP (XCDR (XCDR (spec))))
+ if (it)
{
- Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
- int face_id2 = lookup_derived_face (it->f, face_name,
- FRINGE_FACE_ID, 0);
- if (face_id2 >= 0)
- face_id = face_id2;
- }
+ int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);;
- /* Save current settings of IT so that we can restore them
- when we are finished with the glyph property value. */
+ if (CONSP (XCDR (XCDR (spec))))
+ {
+ Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
+ int face_id2 = lookup_derived_face (it->f, face_name,
+ FRINGE_FACE_ID, 0);
+ if (face_id2 >= 0)
+ face_id = face_id2;
+ }
- save_pos = it->position;
- it->position = *position;
- push_it (it);
- it->position = save_pos;
+ /* Save current settings of IT so that we can restore them
+ when we are finished with the glyph property value. */
+ push_it (it, position);
- it->area = TEXT_AREA;
- it->what = IT_IMAGE;
- it->image_id = -1; /* no image */
- it->position = start_pos;
- it->object = NILP (object) ? it->w->buffer : object;
- it->method = GET_FROM_IMAGE;
- it->from_overlay = Qnil;
- it->face_id = face_id;
+ it->area = TEXT_AREA;
+ it->what = IT_IMAGE;
+ it->image_id = -1; /* no image */
+ it->position = start_pos;
+ it->object = NILP (object) ? it->w->buffer : object;
+ it->method = GET_FROM_IMAGE;
+ it->from_overlay = Qnil;
+ it->face_id = face_id;
- /* 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. */
- *position = start_pos;
+ /* 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. */
+ *position = start_pos;
- if (EQ (XCAR (spec), Qleft_fringe))
- {
- it->left_user_fringe_bitmap = fringe_bitmap;
- it->left_user_fringe_face_id = face_id;
- }
- else
- {
- it->right_user_fringe_bitmap = fringe_bitmap;
- it->right_user_fringe_face_id = face_id;
+ if (EQ (XCAR (spec), Qleft_fringe))
+ {
+ it->left_user_fringe_bitmap = fringe_bitmap;
+ it->left_user_fringe_face_id = face_id;
+ }
+ else
+ {
+ it->right_user_fringe_bitmap = fringe_bitmap;
+ it->right_user_fringe_face_id = face_id;
+ }
}
#endif /* HAVE_WINDOW_SYSTEM */
return 1;
@@ -4210,18 +4305,19 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
valid_p = (STRINGP (value)
#ifdef HAVE_WINDOW_SYSTEM
- || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
+ || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
+ && valid_image_p (value))
#endif /* not HAVE_WINDOW_SYSTEM */
|| (CONSP (value) && EQ (XCAR (value), Qspace)));
- if (valid_p && !display_replaced_before_p)
+ if (valid_p && !display_replaced_p)
{
+ if (!it)
+ return 1;
+
/* Save current settings of IT so that we can restore them
when we are finished with the glyph property value. */
- save_pos = it->position;
- it->position = *position;
- push_it (it);
- it->position = save_pos;
+ push_it (it, position);
it->from_overlay = overlay;
if (NILP (location))
@@ -4278,83 +4374,31 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
return 0;
}
-
-/* Check if SPEC is a display sub-property value whose text should be
- treated as intangible. */
-
-static int
-single_display_spec_intangible_p (Lisp_Object prop)
-{
- /* Skip over `when FORM'. */
- if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
- {
- prop = XCDR (prop);
- if (!CONSP (prop))
- return 0;
- prop = XCDR (prop);
- }
-
- if (STRINGP (prop))
- return 1;
-
- if (!CONSP (prop))
- return 0;
-
- /* Skip over `margin LOCATION'. If LOCATION is in the margins,
- we don't need to treat text as intangible. */
- if (EQ (XCAR (prop), Qmargin))
- {
- prop = XCDR (prop);
- if (!CONSP (prop))
- return 0;
-
- prop = XCDR (prop);
- if (!CONSP (prop)
- || EQ (XCAR (prop), Qleft_margin)
- || EQ (XCAR (prop), Qright_margin))
- return 0;
- }
-
- return (CONSP (prop)
- && (EQ (XCAR (prop), Qimage)
- || EQ (XCAR (prop), Qspace)));
-}
-
-
/* Check if PROP is a display property value whose text should be
- treated as intangible. */
+ treated as intangible. OVERLAY is the overlay from which PROP
+ came, or nil if it came from a text property. CHARPOS and BYTEPOS
+ specify the buffer position covered by PROP. */
int
-display_prop_intangible_p (Lisp_Object prop)
+display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
+ EMACS_INT charpos, EMACS_INT bytepos)
{
- if (CONSP (prop)
- && CONSP (XCAR (prop))
- && !EQ (Qmargin, XCAR (XCAR (prop))))
- {
- /* A list of sub-properties. */
- while (CONSP (prop))
- {
- if (single_display_spec_intangible_p (XCAR (prop)))
- return 1;
- prop = XCDR (prop);
- }
- }
- else if (VECTORP (prop))
- {
- /* A vector of sub-properties. */
- int i;
- for (i = 0; i < ASIZE (prop); ++i)
- if (single_display_spec_intangible_p (AREF (prop, i)))
- return 1;
- }
- else
- return single_display_spec_intangible_p (prop);
+ int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
+ struct text_pos position;
- return 0;
+ SET_TEXT_POS (position, charpos, bytepos);
+ return handle_display_spec (NULL, prop, Qnil, overlay,
+ &position, charpos, frame_window_p);
}
-/* Return 1 if PROP is a display sub-property value containing STRING. */
+/* Return 1 if PROP is a display sub-property value containing STRING.
+
+ Implementation note: this and the following function are really
+ special cases of handle_display_spec and
+ handle_single_display_spec, and should ideally use the same code.
+ Until they do, these two pairs must be consistent and must be
+ modified in sync. */
static int
single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
@@ -4368,6 +4412,16 @@ single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
prop = XCDR (prop);
if (!CONSP (prop))
return 0;
+ /* Actually, the condition following `when' should be eval'ed,
+ like handle_single_display_spec does, and we should return
+ zero if it evaluates to nil. However, this function is
+ called only when the buffer was already displayed and some
+ glyph in the glyph matrix was found to come from a display
+ string. Therefore, the condition was already evaluated, and
+ the result was non-nil, otherwise the display string wouldn't
+ have been displayed and we would have never been called for
+ this property. Thus, we can skip the evaluation and assume
+ its result is non-nil. */
prop = XCDR (prop);
}
@@ -4384,7 +4438,7 @@ single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
return 0;
}
- return CONSP (prop) && EQ (XCAR (prop), string);
+ return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
}
@@ -4394,8 +4448,8 @@ static int
display_prop_string_p (Lisp_Object prop, Lisp_Object string)
{
if (CONSP (prop)
- && CONSP (XCAR (prop))
- && !EQ (Qmargin, XCAR (XCAR (prop))))
+ && !EQ (XCAR (prop), Qwhen)
+ && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
{
/* A list of sub-properties. */
while (CONSP (prop))
@@ -4895,7 +4949,7 @@ get_overlay_strings_1 (struct it *it, EMACS_INT charpos, int compute_stop_p)
/* When called from handle_stop, there might be an empty display
string loaded. In that case, don't bother saving it. */
if (!STRINGP (it->string) || SCHARS (it->string))
- push_it (it);
+ push_it (it, NULL);
/* Set up IT to deliver display elements from the first overlay
string. */
@@ -4937,10 +4991,11 @@ get_overlay_strings (struct it *it, EMACS_INT charpos)
/* Save current settings of IT on IT->stack. Called, for example,
before setting up IT for an overlay string, to be able to restore
IT's settings to what they were after the overlay string has been
- processed. */
+ processed. If POSITION is non-NULL, it is the position to save on
+ the stack instead of IT->position. */
static void
-push_it (struct it *it)
+push_it (struct it *it, struct text_pos *position)
{
struct iterator_stack_entry *p;
@@ -4967,7 +5022,7 @@ push_it (struct it *it)
p->u.stretch.object = it->object;
break;
}
- p->position = it->position;
+ p->position = position ? *position : it->position;
p->current = it->current;
p->end_charpos = it->end_charpos;
p->string_nchars = it->string_nchars;
@@ -5425,6 +5480,7 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
{
it->bidi_it.first_elt = 1;
it->bidi_it.paragraph_dir = NEUTRAL_DIR;
+ it->bidi_it.disp_pos = -1;
}
if (set_stop_p)
@@ -5583,9 +5639,19 @@ lookup_glyphless_char_display (int c, struct it *it)
if (CHAR_TABLE_P (Vglyphless_char_display)
&& CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
- glyphless_method = (c >= 0
- ? CHAR_TABLE_REF (Vglyphless_char_display, c)
- : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
+ {
+ if (c >= 0)
+ {
+ glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
+ if (CONSP (glyphless_method))
+ glyphless_method = FRAME_WINDOW_P (it->f)
+ ? XCAR (glyphless_method)
+ : XCDR (glyphless_method);
+ }
+ else
+ glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
+ }
+
retry:
if (NILP (glyphless_method))
{
@@ -5632,7 +5698,7 @@ struct frame *last_glyphless_glyph_frame = NULL;
unsigned last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
int last_glyphless_glyph_merged_face_id = 0;
-int
+static int
get_next_display_element (struct it *it)
{
/* Non-zero means that we found a display element. Zero means that
@@ -5692,11 +5758,11 @@ get_next_display_element (struct it *it)
/* Return the first character from the display table
entry, if not empty. If empty, don't display the
current character. */
- if (v->size)
+ if (v->header.size)
{
it->dpvec_char_len = it->len;
it->dpvec = v->contents;
- it->dpend = v->contents + v->size;
+ it->dpend = v->contents + v->header.size;
it->current.dpvec_index = 0;
it->dpvec_face_id = -1;
it->saved_face_id = it->face_id;
@@ -5904,7 +5970,6 @@ get_next_display_element (struct it *it)
}
}
-#ifdef HAVE_WINDOW_SYSTEM
/* Adjust face id for a multibyte character. There are no multibyte
character in unibyte text. */
if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
@@ -5924,14 +5989,25 @@ get_next_display_element (struct it *it)
else
{
EMACS_INT pos = (it->s ? -1
- : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
- : IT_CHARPOS (*it));
+ : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
+ : IT_CHARPOS (*it));
+ int c;
- it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos,
- it->string);
+ if (it->what == IT_CHARACTER)
+ c = it->char_to_display;
+ else
+ {
+ struct composition *cmp = composition_table[it->cmp_it.id];
+ int i;
+
+ c = ' ';
+ for (i = 0; i < cmp->glyph_len; i++)
+ if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
+ break;
+ }
+ it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
}
}
-#endif
done:
/* Is this character the last one of a run of characters with
@@ -8408,22 +8484,10 @@ vmessage (const char *m, va_list ap)
{
if (m)
{
- char *buf = FRAME_MESSAGE_BUF (f);
- size_t bufsize = FRAME_MESSAGE_BUF_SIZE (f);
- int len;
+ size_t len;
- memset (buf, 0, bufsize);
- len = vsnprintf (buf, bufsize, m, ap);
-
- /* Do any truncation at a character boundary. */
- if (! (0 <= len && len < bufsize))
- {
- char *end = memchr (buf, 0, bufsize);
- for (len = end ? end - buf : bufsize;
- len && ! CHAR_HEAD_P (buf[len - 1]);
- len--)
- continue;
- }
+ len = doprnt (FRAME_MESSAGE_BUF (f),
+ FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
message2 (FRAME_MESSAGE_BUF (f), len, 0);
}
@@ -8784,7 +8848,7 @@ display_echo_area (struct window *w)
window_height_changed_p
= with_echo_area_buffer (w, display_last_displayed_message_p,
display_echo_area_1,
- (EMACS_INT) w, Qnil, 0, 0);
+ (intptr_t) w, Qnil, 0, 0);
if (no_message_p)
echo_area_buffer[i] = Qnil;
@@ -8803,7 +8867,8 @@ display_echo_area (struct window *w)
static int
display_echo_area_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
{
- struct window *w = (struct window *) a1;
+ intptr_t i1 = a1;
+ struct window *w = (struct window *) i1;
Lisp_Object window;
struct text_pos start;
int window_height_changed_p = 0;
@@ -8845,7 +8910,8 @@ resize_echo_area_exactly (void)
resize_exactly = Qnil;
resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
- (EMACS_INT) w, resize_exactly, 0, 0);
+ (intptr_t) w, resize_exactly,
+ 0, 0);
if (resized_p)
{
++windows_or_buffers_changed;
@@ -8865,7 +8931,8 @@ resize_echo_area_exactly (void)
static int
resize_mini_window_1 (EMACS_INT a1, Lisp_Object exactly, EMACS_INT a3, EMACS_INT a4)
{
- return resize_mini_window ((struct window *) a1, !NILP (exactly));
+ intptr_t i1 = a1;
+ return resize_mini_window ((struct window *) i1, !NILP (exactly));
}
@@ -9031,7 +9098,7 @@ current_message (void)
else
{
with_echo_area_buffer (0, 0, current_message_1,
- (EMACS_INT) &msg, Qnil, 0, 0);
+ (intptr_t) &msg, Qnil, 0, 0);
if (NILP (msg))
echo_area_buffer[0] = Qnil;
}
@@ -9043,7 +9110,8 @@ current_message (void)
static int
current_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4)
{
- Lisp_Object *msg = (Lisp_Object *) a1;
+ intptr_t i1 = a1;
+ Lisp_Object *msg = (Lisp_Object *) i1;
if (Z > BEG)
*msg = make_buffer_string (BEG, Z, 1);
@@ -9095,7 +9163,7 @@ pop_message_unwind (Lisp_Object dummy)
/* Pop the top-most entry off Vmessage_stack. */
-void
+static void
pop_message (void)
{
xassert (CONSP (Vmessage_stack));
@@ -9165,7 +9233,7 @@ truncate_message_1 (EMACS_INT nchars, Lisp_Object a2, EMACS_INT a3, EMACS_INT a4
to t before calling set_message_1 (which calls insert).
*/
-void
+static void
set_message (const char *s, Lisp_Object string,
EMACS_INT nbytes, int multibyte_p)
{
@@ -9174,7 +9242,7 @@ set_message (const char *s, Lisp_Object string,
|| (STRINGP (string) && STRING_MULTIBYTE (string)));
with_echo_area_buffer (0, -1, set_message_1,
- (EMACS_INT) s, string, nbytes, multibyte_p);
+ (intptr_t) s, string, nbytes, multibyte_p);
message_buf_print = 0;
help_echo_showing_p = 0;
}
@@ -9188,7 +9256,8 @@ set_message (const char *s, Lisp_Object string,
static int
set_message_1 (EMACS_INT a1, Lisp_Object a2, EMACS_INT nbytes, EMACS_INT multibyte_p)
{
- const char *s = (const char *) a1;
+ intptr_t i1 = a1;
+ const char *s = (const char *) i1;
const unsigned char *msg = (const unsigned char *) s;
Lisp_Object string = a2;
@@ -11091,7 +11160,7 @@ debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
buffer position, END is given as a distance from Z. Used in
redisplay_internal for display optimization. */
-static INLINE int
+static inline int
text_outside_line_unchanged_p (struct window *w,
EMACS_INT start, EMACS_INT end)
{
@@ -11315,7 +11384,7 @@ overlay_arrow_at_row (struct it *it, struct glyph_row *row)
return 0. PREV_BUF and PREV_PT are the last point buffer and
position. BUF and PT are the current point buffer and position. */
-int
+static int
check_point_in_composition (struct buffer *prev_buf, EMACS_INT prev_pt,
struct buffer *buf, EMACS_INT pt)
{
@@ -11352,7 +11421,7 @@ check_point_in_composition (struct buffer *prev_buf, EMACS_INT prev_pt,
/* Reconsider the setting of B->clip_changed which is displayed
in window W. */
-static INLINE void
+static inline void
reconsider_clip_changes (struct window *w, struct buffer *b)
{
if (b->clip_changed
@@ -12402,7 +12471,7 @@ redisplay_window_1 (Lisp_Object window)
Return 0 if cursor is not on this row, 1 otherwise. */
-int
+static int
set_cursor_from_row (struct window *w, struct glyph_row *row,
struct glyph_matrix *matrix,
EMACS_INT delta, EMACS_INT delta_bytes,
@@ -12718,11 +12787,30 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
positioned between POS_BEFORE and POS_AFTER in the
buffer. */
- struct glyph *stop = glyph_after;
+ struct glyph *start, *stop;
EMACS_INT pos = pos_before;
x = -1;
- for (glyph = glyph_before + incr;
+
+ /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
+ correspond to POS_BEFORE and POS_AFTER, respectively. We
+ need START and STOP in the order that corresponds to the
+ row's direction as given by its reversed_p flag. If the
+ directionality of characters between POS_BEFORE and
+ POS_AFTER is the opposite of the row's base direction,
+ these characters will have been reordered for display,
+ and we need to reverse START and STOP. */
+ if (!row->reversed_p)
+ {
+ start = min (glyph_before, glyph_after);
+ stop = max (glyph_before, glyph_after);
+ }
+ else
+ {
+ start = max (glyph_before, glyph_after);
+ stop = min (glyph_before, glyph_after);
+ }
+ for (glyph = start + incr;
row->reversed_p ? glyph > stop : glyph < stop; )
{
@@ -12913,7 +13001,7 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
We assume that the window's buffer is really current. */
-static INLINE struct text_pos
+static inline struct text_pos
run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
{
struct window *w = XWINDOW (window);
@@ -13673,6 +13761,9 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp, int *scroll_ste
return rc;
}
+#if !defined USE_TOOLKIT_SCROLL_BARS || defined USE_GTK
+static
+#endif
void
set_vertical_scroll_bar (struct window *w)
{
@@ -14482,7 +14573,6 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
&& EQ (FRAME_SELECTED_WINDOW (f), window))
{
int redisplay_menu_p = 0;
- int redisplay_tool_bar_p = 0;
if (FRAME_WINDOW_P (f))
{
@@ -14503,17 +14593,15 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
if (FRAME_WINDOW_P (f))
{
#if defined (USE_GTK) || defined (HAVE_NS)
- redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
+ if (FRAME_EXTERNAL_TOOL_BAR (f))
+ redisplay_tool_bar (f);
#else
- redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
- && (FRAME_TOOL_BAR_LINES (f) > 0
- || !NILP (Vauto_resize_tool_bars));
+ if (WINDOWP (f->tool_bar_window)
+ && (FRAME_TOOL_BAR_LINES (f) > 0
+ || !NILP (Vauto_resize_tool_bars))
+ && redisplay_tool_bar (f))
+ ignore_mouse_drag_p = 1;
#endif
-
- if (redisplay_tool_bar_p && redisplay_tool_bar (f))
- {
- ignore_mouse_drag_p = 1;
- }
}
#endif
}
@@ -14859,7 +14947,8 @@ try_window_reusing_current_matrix (struct window *w)
row->visible_height -= min_y - row->y;
if (row->y + row->height > max_y)
row->visible_height -= row->y + row->height - max_y;
- row->redraw_fringe_bitmaps_p = 1;
+ if (row->fringe_bitmap_periodic_p)
+ row->redraw_fringe_bitmaps_p = 1;
it.current_y += row->height;
@@ -15021,7 +15110,8 @@ try_window_reusing_current_matrix (struct window *w)
row->visible_height -= min_y - row->y;
if (row->y + row->height > max_y)
row->visible_height -= row->y + row->height - max_y;
- row->redraw_fringe_bitmaps_p = 1;
+ if (row->fringe_bitmap_periodic_p)
+ row->redraw_fringe_bitmaps_p = 1;
}
/* Scroll the current matrix. */
@@ -16989,7 +17079,7 @@ trailing_whitespace_p (EMACS_INT charpos)
/* Highlight trailing whitespace, if any, in ROW. */
-void
+static void
highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
{
int used = row->used[TEXT_AREA];
@@ -17139,7 +17229,7 @@ cursor_row_p (struct glyph_row *row)
static int
push_display_prop (struct it *it, Lisp_Object prop)
{
- push_it (it);
+ push_it (it, NULL);
if (STRINGP (prop))
{
@@ -18068,6 +18158,8 @@ See also `bidi-paragraph-direction'. */)
bytepos--;
itb.charpos = pos;
itb.bytepos = bytepos;
+ itb.nchars = -1;
+ itb.frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ()); /* guesswork */
itb.first_elt = 1;
itb.separator_limit = -1;
itb.paragraph_dir = NEUTRAL_DIR;
@@ -18171,7 +18263,7 @@ display_menu_bar (struct window *w)
/* Display all items of the menu bar. */
items = FRAME_MENU_BAR_ITEMS (it.f);
- for (i = 0; i < XVECTOR (items)->size; i += 4)
+ for (i = 0; i < ASIZE (items); i += 4)
{
Lisp_Object string;
@@ -19609,7 +19701,7 @@ decode_mode_spec (struct window *w, register int c, int field_width,
so get us a 2-digit number that is close. */
if (total == 100)
total = 99;
- sprintf (decode_mode_spec_buf, "%2ld%%", (long)total);
+ sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
return decode_mode_spec_buf;
}
}
@@ -19640,9 +19732,9 @@ decode_mode_spec (struct window *w, register int c, int field_width,
if (total == 100)
total = 99;
if (toppos <= BUF_BEGV (b))
- sprintf (decode_mode_spec_buf, "Top%2ld%%", (long)total);
+ sprintf (decode_mode_spec_buf, "Top%2"pI"d%%", total);
else
- sprintf (decode_mode_spec_buf, "%2ld%%", (long)total);
+ sprintf (decode_mode_spec_buf, "%2"pI"d%%", total);
return decode_mode_spec_buf;
}
}
@@ -20445,7 +20537,7 @@ init_glyph_string (struct glyph_string *s,
/* Append the list of glyph strings with head H and tail T to the list
with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
-static INLINE void
+static inline void
append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
struct glyph_string *h, struct glyph_string *t)
{
@@ -20465,7 +20557,7 @@ append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tai
list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
result. */
-static INLINE void
+static inline void
prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
struct glyph_string *h, struct glyph_string *t)
{
@@ -20484,7 +20576,7 @@ prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **ta
/* Append glyph string S to the list with head *HEAD and tail *TAIL.
Set *HEAD and *TAIL to the resulting list. */
-static INLINE void
+static inline void
append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
struct glyph_string *s)
{
@@ -20499,7 +20591,7 @@ append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
Value is a pointer to a realized face that is ready for display if
DISPLAY_P is non-zero. */
-static INLINE struct face *
+static inline struct face *
get_char_face_and_encoding (struct frame *f, int c, int face_id,
XChar2b *char2b, int display_p)
{
@@ -20532,7 +20624,7 @@ get_char_face_and_encoding (struct frame *f, int c, int face_id,
The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
a pointer to a realized face that is ready for display. */
-static INLINE struct face *
+static inline struct face *
get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
XChar2b *char2b, int *two_byte_p)
{
@@ -20569,7 +20661,7 @@ get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
/* Get glyph code of character C in FONT in the two-byte form CHAR2B.
Retunr 1 if FONT has a glyph for C, otherwise return 0. */
-static INLINE int
+static inline int
get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
{
unsigned code;
@@ -21033,7 +21125,7 @@ right_overwriting (struct glyph_string *s)
first glyph following S. LAST_X is the right-most x-position + 1
in the drawing area. */
-static INLINE void
+static inline void
set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
{
/* If the face of this glyph string has to be drawn to the end of
@@ -21595,7 +21687,7 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
/* Store one glyph for IT->char_to_display in IT->glyph_row.
Called from x_produce_glyphs when IT->glyph_row is non-null. */
-static INLINE void
+static inline void
append_glyph (struct it *it)
{
struct glyph *glyph;
@@ -21669,7 +21761,7 @@ append_glyph (struct it *it)
IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
non-null. */
-static INLINE void
+static inline void
append_composite_glyph (struct it *it)
{
struct glyph *glyph;
@@ -21738,7 +21830,7 @@ append_composite_glyph (struct it *it)
/* Change IT->ascent and IT->height according to the setting of
IT->voffset. */
-static INLINE void
+static inline void
take_vertical_position_into_account (struct it *it)
{
if (it->voffset)
@@ -22360,6 +22452,8 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
{
if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
+ if (CONSP (acronym))
+ acronym = XCAR (acronym);
str = STRINGP (acronym) ? SSDATA (acronym) : "";
}
else
@@ -22755,7 +22849,7 @@ x_produce_glyphs (struct it *it)
int lbearing, rbearing;
int i, width, ascent, descent;
int left_padded = 0, right_padded = 0;
- int c;
+ int c IF_LINT (= 0); /* cmp->glyph_len can't be zero; see Bug#8512 */
XChar2b char2b;
struct font_metrics *pcm;
int font_not_found_p;
@@ -23931,7 +24025,7 @@ x_clear_cursor (struct window *w)
/* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
and MSDOS. */
-void
+static void
draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
int start_hpos, int end_hpos,
enum draw_glyphs_face draw)
@@ -23948,10 +24042,9 @@ draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
#endif
}
-/* EXPORT:
- Display the active region described by mouse_face_* according to DRAW. */
+/* Display the active region described by mouse_face_* according to DRAW. */
-void
+static void
show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
{
struct window *w = XWINDOW (hlinfo->mouse_face_window);
@@ -24862,7 +24955,7 @@ on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
{
struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
Lisp_Object *poly = v->contents;
- int n = v->size;
+ int n = v->header.size;
int i;
int inside = 0;
Lisp_Object lx, ly;
@@ -26295,7 +26388,7 @@ x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
{
result->x = right->x;
- /* The right end of the intersection is the minimum of the
+ /* The right end of the intersection is the minimum of
the right ends of left and right. */
result->width = (min (left->x + left->width, right->x + right->width)
- result->x);
@@ -26996,17 +27089,21 @@ cursor shapes. */);
Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
- doc: /* Char-table to control displaying of glyphless characters.
-Each element, if non-nil, is an ASCII acronym string (displayed in a box)
-or one of these symbols:
- hex-code: display the hexadecimal code of a character in a box
- empty-box: display as an empty box
- thin-space: display as 1-pixel width space
- zero-width: don't display
-
-It has one extra slot to control the display of a character for which
-no font is found. The value of the slot is `hex-code' or `empty-box'.
-The default is `empty-box'. */);
+ doc: /* Char-table defining glyphless characters.
+Each element, if non-nil, should be one of the following:
+ an ASCII acronym string: display this string in a box
+ `hex-code': display the hexadecimal code of a character in a box
+ `empty-box': display as an empty box
+ `thin-space': display as 1-pixel width space
+ `zero-width': don't display
+An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
+display method for graphical terminals and text terminals respectively.
+GRAPHICAL and TEXT should each have one of the values listed above.
+
+The char-table has one extra slot to control the display of a character for
+which no font is found. This slot only takes effect on graphical terminals.
+Its value should be an ASCII acronym string, `hex-code', `empty-box', or
+`thin-space'. The default is `empty-box'. */);
Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
Qempty_box);
@@ -27027,6 +27124,7 @@ init_xdisp (void)
mini_w = XWINDOW (minibuf_window);
root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
+ echo_area_window = minibuf_window;
if (!noninteractive)
{