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) {